diff --git a/resources/css/components.css b/resources/css/components.css index ccf4f998..e185a2bf 100644 --- a/resources/css/components.css +++ b/resources/css/components.css @@ -19,6 +19,7 @@ @import './components/input.css'; @import './components/password.css'; @import './components/textarea.css'; +@import './components/select.css'; /* Containment */ diff --git a/resources/css/components/field.css b/resources/css/components/field.css index 89648471..dc54b777 100644 --- a/resources/css/components/field.css +++ b/resources/css/components/field.css @@ -138,59 +138,6 @@ transition: background-color 604800s, color 604800s; } - /* 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 — and - the arrow turns over, as the searchable choices' does. */ - @supports (appearance: base-select) { - select[data-md-field-control] { - 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]:has(select[data-md-field-control]:open) [data-md-field-arrow] { - rotate: 180deg; - } - } - /* ``: the browser's own "No file chosen" line is transparent (the caller shows what was chosen), and its button is a tonal pill — the thing to press. */ input[type='file'][data-md-field-control] { diff --git a/resources/css/components/select.css b/resources/css/components/select.css new file mode 100644 index 00000000..c383f197 --- /dev/null +++ b/resources/css/components/select.css @@ -0,0 +1,74 @@ +/* + * : the native 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'; +/* TODO(step 36): @import './menu.css' once the menu leaves Tailwind (actions stream); its select rules draw the open list. */ + +@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 — and + the arrow turns over, as the searchable choices' does. */ + @supports (appearance: base-select) { + select[data-md-field-control] { + 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]:has(select[data-md-field-control]:open) [data-md-field-arrow] { + rotate: 180deg; + } + } +} diff --git a/resources/views/components/select.blade.php b/resources/views/components/select.blade.php index 16da2943..3f56a2d1 100644 --- a/resources/views/components/select.blade.php +++ b/resources/views/components/select.blade.php @@ -10,7 +10,8 @@ `options` as a list of `['id' => …, 'name' => …]` (`'disabled' => true` greys one out), `option-value` and `option-label` to read other keys, and a `placeholder` that becomes the first option, valued `placeholder-value` (empty by default). Or pass `