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.
84 lines
1.9 KiB
CSS
84 lines
1.9 KiB
CSS
/* <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);
|
|
}
|