blade('')) ->toContain('role="group"') ->toContain('aria-label="Views"') ->toContain('data-button-group="standard"') ->toContain('data-size="md"') ->toContain('gap-2') ->and((string) $this->blade('')) ->toContain('gap-3'); }); it('connects buttons 2px apart', function () { expect((string) $this->blade('')) ->toContain('data-button-group="connected"') ->toContain('gap-0.5') ->not->toContain('flex-wrap'); }); it('marks icon buttons, which keep their width when a group is pressed', function () { expect((string) $this->blade(''))->toContain('data-icon-button') ->and((string) $this->blade(''))->not->toContain('data-icon-button'); }); it('draws a choice as connected radios', function () { $html = (string) $this->blade(<<<'BLADE' BLADE); expect($html) ->toContain('Theme') ->toContain('data-button-group="connected"') ->toContain('type="radio"') ->toContain('name="theme"') ->toContain('x-model="theme"') ->toContain('value="light"') ->toContain('has-checked:bg-secondary has-checked:text-on-secondary') ->toContain('disabled') ->and(substr_count($html, 'toBe(1); }); it('keeps a 48px target and a 48px minimum width on the smallest connected segments', function () { $options = [['id' => 'a', 'name' => 'A']]; expect((string) $this->blade('', ['options' => $options])) ->toContain('touch-target min-w-12') ->and((string) $this->blade('', ['options' => $options])) ->not->toContain('touch-target') ->toContain('min-w-0'); }); it('draws several choices as checkboxes', function () { expect((string) $this->blade('')) ->toContain('type="checkbox"') ->toContain('name="days[]"') ->toContain('has-checked:bg-inverse-surface'); }); it('binds to a Livewire property and shows its validation message', function () { $component = new class extends Component { public string $theme = 'dark'; public function save(): void { $this->validate(['theme' => 'in:light'], ['theme.in' => 'Pick light.']); } public function render(): string { return <<<'BLADE'
BLADE; } }; Livewire::test($component) ->assertSeeHtml('wire:model="theme"') ->assertSee('How it looks') ->set('theme', 'light') ->assertSet('theme', 'light') ->set('theme', 'dark') ->call('save') ->assertSee('Pick light.') ->assertDontSee('How it looks'); }); it('adds hint-class to the hint, which a validation message still replaces', function () { $options = [['id' => 'flat', 'name' => 'Flat'], ['id' => 'hilly', 'name' => 'Hilly']]; expect((string) $this->blade('', ['options' => $options])) ->toContain('

No elevation data here

') ->and((string) $this->blade('', ['options' => $options])) ->toContain('

No elevation data here

'); expect((string) $this->withViewErrors(['terrain' => 'Pick a terrain.'])->blade('', ['options' => $options])) ->toContain('

Pick a terrain.

') ->not->toContain('No elevation data here') ->not->toContain('text-warning'); });