Files
livewire-material/resources/css/components/select.css
T
Andreas Reinhold / reiniandClaude Opus 5 029c78d301 Keep a focused field's focus edge under the pointer
The hover rule's `:not(:has([data-md-field-control]:disabled))` weighs
as much as its argument, so hover weighed (0,5,0) against focus's
(0,2,0), and the error's hover (0,6,0) against the error's focus
(0,4,0): a focused field with the pointer on it drew a 2px on-surface
edge instead of primary, a field in error on-error-container instead of
error, in both variants. A customizable select with its menu open lost
the same way, since focus is then on an option in the top layer and
only select.css's `:open` rule (0,3,1) draws the focus edge. M3 layers
focus over hover. The disabled condition is now weightless inside
`:where()`, still keeping hover off a disabled field, and the focus
rule gains the field ancestor: focus (0,3,0) outweighs hover (0,2,0),
the error's focus (0,4,0) the error's hover (0,3,0), and the open
select both. An open select in error drew primary, not error, and now
draws error. A browser test hovers and clicks an outlined, a filled and
an invalid field and opens a select and a select in error, comparing
each edge with its role; it fails without the change (the error select
without select.css's rule).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 05:29:29 +02:00

83 lines
3.3 KiB
CSS

/*
* <x-select>: the native <select> in the text field's chrome, drawn as M3's exposed dropdown menu
* (resources/views/components/select.blade.php).
*
* The chrome is the field's (components/field.css); this file is what a <select> changes in it. The
* select covers its whole field, so a press anywhere opens it and the list the browser anchors to
* it is the field's width. Where the browser has the customizable select (`appearance:
* base-select`), the closed select loses the button chrome that brings, the field reads as focused
* while the list is open, and the arrow turns over. The open list itself is M3's menu, drawn by
* components/menu.css.
*
* The field's root carries `data-md-select`.
*/
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
@import './field.css';
@import './icon.css';
@import './menu.css';
@layer material.components {
/* A select covers its whole field — out over the padding and the leading icon at
the start, under the arrow to the end — and its own padding puts the value back
where it was. So a press anywhere on the field opens it, and the list, which
the browser anchors to the select, is the field's width (components/menu.css). */
select[data-md-field-control] {
--field-end: calc(var(--field-icon) + var(--field-gap) + var(--field-pad));
appearance: none;
cursor: pointer;
margin-inline: calc(-1 * var(--field-start)) calc(-1 * var(--field-end));
padding-inline: var(--field-start) var(--field-end);
}
select[data-md-field-control]:disabled {
cursor: default;
}
/* Where the browser has a customizable select, the closed select is its own
button: without the border, padding and arrow that button brings, it is the
same field as before. While its list is open the field reads as focused —
said from `:open`, because focus inside the list is in the top layer — in
the error colour when the field is in error, as a focused one is — and the
arrow turns over, as the searchable choices' does. Both outweigh field.css's
hover, so the pointer left on the field does not take the focus edge away. */
@supports (appearance: base-select) {
select[data-md-field-control] {
appearance: base-select;
display: flex;
align-items: center;
border: 0;
padding-block: 0;
border-radius: 0;
background: transparent;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
select[data-md-field-control]::picker-icon {
display: none;
}
[data-md-field-box]:has(select[data-md-field-control]:open) {
--field-edge: var(--md-sys-color-primary);
--field-ink: var(--md-sys-color-primary);
[data-md-field-outline] {
border-width: 2px;
}
}
[data-md-field][data-md-invalid] [data-md-field-box]:has(select[data-md-field-control]:open) {
--field-edge: var(--md-sys-color-error);
--field-ink: var(--md-sys-color-error);
}
[data-md-field]:has(select[data-md-field-control]:open) [data-md-field-arrow] {
rotate: 180deg;
}
}
}