swarm-ui: dropdowns open a themed list of their own instead of the browser's
SelectField and the refresh-interval picker are built on a new Listbox, a select-only combobox: a button that keeps focus and a listbox in the top layer, so it works the same in every current browser, is not clipped by a scrolling ancestor and shows above a modal dialog. Keys, type-ahead and placement are pure functions with tests. required becomes aria-required, as a button has no native form validation.
This commit is contained in:
parent
88053f437c
commit
a2e8a2bda0
1 changed files with 653 additions and 66 deletions
84
frontend/packages/swarm-ui/src/ui/select-field/Listbox.css
Normal file
84
frontend/packages/swarm-ui/src/ui/select-field/Listbox.css
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/* <Listbox>: the control is `.ui-form-control`'s box (FormField.css) laid out as
|
||||
value + chevron, and the list is a themed box in the top layer. */
|
||||
.ui-listbox {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.ui-select-trigger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.5em;
|
||||
text-align: start;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ui-select-trigger:disabled {
|
||||
cursor: default;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.ui-select-trigger[aria-expanded="true"] {
|
||||
border-color: var(--purple);
|
||||
}
|
||||
.ui-select-value {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ui-select-empty {
|
||||
color: var(--muted);
|
||||
}
|
||||
/* A chevron drawn with borders, so it takes the text colour and needs no glyph
|
||||
a font might lack. */
|
||||
.ui-select-chevron {
|
||||
flex: none;
|
||||
width: 0.45em;
|
||||
height: 0.45em;
|
||||
border-right: 2px solid currentColor;
|
||||
border-bottom: 2px solid currentColor;
|
||||
transform: translateY(-0.12em) rotate(45deg);
|
||||
opacity: 0.7;
|
||||
}
|
||||
.ui-select-trigger[aria-expanded="true"] .ui-select-chevron {
|
||||
transform: translateY(0.1em) rotate(225deg);
|
||||
}
|
||||
|
||||
/* A popover's own UA styles centre it with `inset: 0; margin: auto`; this puts
|
||||
it where `placePopup` says. */
|
||||
.ui-select-list {
|
||||
position: fixed;
|
||||
inset: auto;
|
||||
margin: 0;
|
||||
padding: 0.25em;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--purple-dim) transparent;
|
||||
list-style: none;
|
||||
background: var(--bg-elev);
|
||||
color: var(--fg);
|
||||
border: 1px solid var(--purple-dim);
|
||||
border-radius: 0.4em;
|
||||
box-shadow: 0 0.25em 0.75em rgba(0, 0, 0, 0.3);
|
||||
font: inherit;
|
||||
}
|
||||
.ui-select-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75em;
|
||||
min-height: 2.5em;
|
||||
padding: 0.3em 0.6em;
|
||||
border-radius: 0.3em;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ui-select-option-active {
|
||||
background: var(--bg);
|
||||
}
|
||||
.ui-select-option-selected {
|
||||
font-weight: 600;
|
||||
}
|
||||
.ui-select-option-selected::after {
|
||||
content: "✓";
|
||||
color: var(--purple);
|
||||
}
|
||||
Loading…
Reference in a new issue