Files
livewire-material/tests/Feature/Components/BadgeTest.php
T
Andreas Reinhold / reiniandClaude Opus 5 e6f4357a2a Add a solid status label to the badge
A status label came tonal (the colour's container) or outlined; a label that
has to stand out in the colour itself fell back to the filled count, which is
16px and hidden from screen readers. solid draws the label shape in the
colour's filled pair and is spoken like the others.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RHoXZSHc8gGpZjFmA5fPc2
2026-09-13 21:08:55 +02:00

93 lines
5.7 KiB
PHP

<?php
it('is M3\'s small badge without a value', function () {
expect((string) $this->blade('<x-badge />'))
->toContain('size-1.5 rounded-corner-full')
->toContain('bg-error text-on-error')
->toContain('aria-hidden="true"');
});
it('is M3\'s large badge with a count, capped by max', function () {
expect((string) $this->blade('<x-badge value="4" />'))->toContain('h-4 min-w-4')->toContain('>4</span>')
->and((string) $this->blade('<x-badge value="1204" max="999" />'))->toContain('>999+</span>')
->and((string) $this->blade('<x-badge value="12" max="999" color="primary" />'))->toContain('>12</span>')->toContain('bg-primary text-on-primary');
});
it('pins itself to the corner of an icon when floating', function () {
expect((string) $this->blade('<x-badge floating />'))->toContain('absolute top-0.5 end-0.5')
->and((string) $this->blade('<x-badge value="3" floating label="3 new messages" />'))
->toContain('absolute -top-1')
->toContain('aria-label="3 new messages"')
->not->toContain('aria-hidden');
});
it('draws a status label in a container or an outline', function () {
expect((string) $this->blade('<x-badge value="Active" tone="success" tonal />'))
->toContain('h-6 gap-1 rounded-corner-sm px-2 type-label-md')
->toContain('bg-success-container text-on-success-container')
->not->toContain('aria-hidden')
->and((string) $this->blade('<x-badge value="Pro" outline />'))
->toContain('border border-outline-variant text-on-surface-variant')
->not->toContain('bg-error');
});
it('renders its slot as HTML, and is a dot while the slot holds nothing but comments', function () {
$html = (string) $this->blade('<x-badge tonal><x-icon name="bolt" class="size-3" /> Pro</x-badge>');
expect($html)
->toContain('h-6 gap-1 rounded-corner-sm')
->toContain('<svg')
->toContain(' Pro</span>')
->not->toContain('&lt;svg')
->and((string) $this->blade('<x-badge value="<b>4</b>" />'))->toContain('&lt;b&gt;4&lt;/b&gt;')
->and((string) $this->blade("<x-badge tonal>\n <!-- nothing yet -->\n</x-badge>"))->toContain('size-1.5 rounded-corner-full')
->and((string) $this->blade('<x-badge max="99">120</x-badge>'))->toContain('>99+</span>');
});
it('draws neutral ink on every variant', function () {
expect((string) $this->blade('<x-badge color="neutral" />'))->toContain('size-1.5 rounded-corner-full bg-on-surface-variant text-surface')
->and((string) $this->blade('<x-badge value="7" color="neutral" />'))->toContain('tabular-nums bg-on-surface-variant text-surface')
->and((string) $this->blade('<x-badge value="Draft" tone="neutral" tonal />'))->toContain('type-label-md bg-surface-container-high text-on-surface-variant')
->and((string) $this->blade('<x-badge value="Draft" color="neutral" outline />'))->toContain('type-label-md border border-outline-variant text-on-surface-variant');
});
it('leaves a plain badge to the caller\'s colour classes', function (string $badge, string $shape) {
$html = (string) $this->blade($badge);
preg_match('/class="([^"]*)"/', $html, $class);
expect($class[1])
->toContain($shape)
->toEndWith('bg-tertiary-container text-on-tertiary-container')
->and(preg_replace('/bg-tertiary-container text-on-tertiary-container$/', '', $class[1]))->not->toMatch('/(^|\s)(bg|text|border)-/');
})->with([
'dot' => ['<x-badge color="plain" class="bg-tertiary-container text-on-tertiary-container" />', 'size-1.5 rounded-corner-full'],
'count' => ['<x-badge value="3" color="plain" class="bg-tertiary-container text-on-tertiary-container" />', 'h-4 min-w-4 rounded-corner-full px-1 type-label-sm tabular-nums'],
'tonal' => ['<x-badge value="Run" color="plain" tonal class="bg-tertiary-container text-on-tertiary-container" />', 'h-6 gap-1 rounded-corner-sm px-2 type-label-md'],
'outline' => ['<x-badge value="Run" color="plain" outline class="bg-tertiary-container text-on-tertiary-container" />', 'h-6 gap-1 rounded-corner-sm px-2 type-label-md border'],
]);
it('keeps its default colours, and falls back to error on a colour it does not know', function () {
expect((string) $this->blade('<x-badge value="4" />'))
->toContain('class="inline-flex shrink-0 items-center justify-center whitespace-nowrap h-4 min-w-4 rounded-corner-full px-1 type-label-sm tabular-nums bg-error text-on-error"')
->and((string) $this->blade('<x-badge value="Active" tonal />'))
->toContain('class="inline-flex shrink-0 items-center justify-center whitespace-nowrap h-6 gap-1 rounded-corner-sm px-2 type-label-md bg-error-container text-on-error-container"')
->and((string) $this->blade('<x-badge value="Pro" outline color="success" />'))
->toContain('class="inline-flex shrink-0 items-center justify-center whitespace-nowrap h-6 gap-1 rounded-corner-sm px-2 type-label-md border border-outline-variant text-on-surface-variant"')
->and((string) $this->blade('<x-badge value="3" color="sport-run" />'))->toContain('bg-error text-on-error');
});
it('draws a solid status label in the colour itself, spoken like any label', function () {
$html = (string) $this->blade('<x-badge value="Built in" solid color="primary" />');
expect($html)
->toContain('bg-primary text-on-primary')
->toContain('h-6 gap-1 rounded-corner-sm px-2 type-label-md')
->not->toContain('aria-hidden')
->toContain('>Built in<')
->and((string) $this->blade('<x-badge value="Draft" solid color="neutral" />'))
->toContain('bg-on-surface-variant text-surface')
->and((string) $this->blade('<x-badge solid />'))
->toContain('size-1.5');
});