@agent-ui-kit/components 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-styles.css +8 -0
- package/dist/component-styles.css +147 -0
- package/dist/controls/_base/index.d.ts +3 -0
- package/dist/controls/_base/index.js +9 -0
- package/dist/controls/_base/indicator-element.d.ts +132 -0
- package/dist/controls/_base/indicator-element.js +158 -0
- package/dist/controls/_base/listbox-element.d.ts +70 -0
- package/dist/controls/_base/listbox-element.js +74 -0
- package/dist/controls/_base/range-element.d.ts +120 -0
- package/dist/controls/_base/range-element.js +158 -0
- package/dist/controls/_surface/container-box.css +301 -0
- package/dist/controls/_surface/container.css +156 -0
- package/dist/controls/_token-surface/token-surface.d.ts +35 -0
- package/dist/controls/_token-surface/token-surface.js +97 -0
- package/dist/controls/attachment/attachment-meta.d.ts +8 -0
- package/dist/controls/attachment/attachment-meta.js +84 -0
- package/dist/controls/attachment/attachment.css +91 -0
- package/dist/controls/attachment/attachment.d.ts +40 -0
- package/dist/controls/attachment/attachment.js +70 -0
- package/dist/controls/avatar/avatar-initials.d.ts +4 -0
- package/dist/controls/avatar/avatar-initials.js +30 -0
- package/dist/controls/avatar/avatar.css +87 -0
- package/dist/controls/avatar/avatar.d.ts +40 -0
- package/dist/controls/avatar/avatar.js +77 -0
- package/dist/controls/badge/badge.css +175 -0
- package/dist/controls/badge/badge.d.ts +36 -0
- package/dist/controls/badge/badge.js +71 -0
- package/dist/controls/bar-chart/bar-chart.css +110 -0
- package/dist/controls/bar-chart/bar-chart.d.ts +26 -0
- package/dist/controls/bar-chart/bar-chart.js +80 -0
- package/dist/controls/bar-chart/bar-math.d.ts +31 -0
- package/dist/controls/bar-chart/bar-math.js +106 -0
- package/dist/controls/button/button.css +263 -0
- package/dist/controls/button/button.d.ts +61 -0
- package/dist/controls/button/button.js +115 -0
- package/dist/controls/calendar/calendar.css +495 -0
- package/dist/controls/calendar/calendar.d.ts +161 -0
- package/dist/controls/calendar/calendar.js +1004 -0
- package/dist/controls/card/card-content.d.ts +24 -0
- package/dist/controls/card/card-content.js +133 -0
- package/dist/controls/card/card-footer.d.ts +3 -0
- package/dist/controls/card/card-footer.js +16 -0
- package/dist/controls/card/card-header.d.ts +3 -0
- package/dist/controls/card/card-header.js +18 -0
- package/dist/controls/card/card.css +445 -0
- package/dist/controls/card/card.d.ts +51 -0
- package/dist/controls/card/card.js +61 -0
- package/dist/controls/checkbox/checkbox.css +204 -0
- package/dist/controls/checkbox/checkbox.d.ts +114 -0
- package/dist/controls/checkbox/checkbox.js +130 -0
- package/dist/controls/code/code.css +72 -0
- package/dist/controls/code/code.d.ts +23 -0
- package/dist/controls/code/code.js +40 -0
- package/dist/controls/color-picker/color-picker.css +209 -0
- package/dist/controls/color-picker/color-picker.d.ts +84 -0
- package/dist/controls/color-picker/color-picker.js +545 -0
- package/dist/controls/color-picker/color.d.ts +40 -0
- package/dist/controls/color-picker/color.js +159 -0
- package/dist/controls/column/column.css +151 -0
- package/dist/controls/column/column.d.ts +107 -0
- package/dist/controls/column/column.js +57 -0
- package/dist/controls/combo-box/combo-box.css +397 -0
- package/dist/controls/combo-box/combo-box.d.ts +133 -0
- package/dist/controls/combo-box/combo-box.js +680 -0
- package/dist/controls/command-modal/command-modal.css +226 -0
- package/dist/controls/command-modal/command-modal.d.ts +42 -0
- package/dist/controls/command-modal/command-modal.js +315 -0
- package/dist/controls/disclosure/disclosure.css +162 -0
- package/dist/controls/disclosure/disclosure.d.ts +37 -0
- package/dist/controls/disclosure/disclosure.js +207 -0
- package/dist/controls/field/field.css +140 -0
- package/dist/controls/field/field.d.ts +27 -0
- package/dist/controls/field/field.js +228 -0
- package/dist/controls/form-provider/form-provider.css +40 -0
- package/dist/controls/form-provider/form-provider.d.ts +42 -0
- package/dist/controls/form-provider/form-provider.js +105 -0
- package/dist/controls/grid/grid.css +72 -0
- package/dist/controls/grid/grid.d.ts +60 -0
- package/dist/controls/grid/grid.js +56 -0
- package/dist/controls/icon/icon.css +37 -0
- package/dist/controls/icon/icon.d.ts +25 -0
- package/dist/controls/icon/icon.js +55 -0
- package/dist/controls/index.d.ts +57 -0
- package/dist/controls/index.js +136 -0
- package/dist/controls/ladder/ladder.css +89 -0
- package/dist/controls/ladder/ladder.d.ts +27 -0
- package/dist/controls/ladder/ladder.js +78 -0
- package/dist/controls/list/list.css +118 -0
- package/dist/controls/list/list.d.ts +84 -0
- package/dist/controls/list/list.js +48 -0
- package/dist/controls/menu/menu.css +195 -0
- package/dist/controls/menu/menu.d.ts +44 -0
- package/dist/controls/menu/menu.js +248 -0
- package/dist/controls/modal/modal.css +99 -0
- package/dist/controls/modal/modal.d.ts +61 -0
- package/dist/controls/modal/modal.js +155 -0
- package/dist/controls/popover/popover.css +83 -0
- package/dist/controls/popover/popover.d.ts +44 -0
- package/dist/controls/popover/popover.js +164 -0
- package/dist/controls/progress/progress.css +106 -0
- package/dist/controls/progress/progress.d.ts +28 -0
- package/dist/controls/progress/progress.js +80 -0
- package/dist/controls/radio/radio-group.css +84 -0
- package/dist/controls/radio/radio-group.d.ts +152 -0
- package/dist/controls/radio/radio-group.js +350 -0
- package/dist/controls/radio/radio.css +219 -0
- package/dist/controls/radio/radio.d.ts +19 -0
- package/dist/controls/radio/radio.js +75 -0
- package/dist/controls/ramp/ramp.css +75 -0
- package/dist/controls/ramp/ramp.d.ts +29 -0
- package/dist/controls/ramp/ramp.js +72 -0
- package/dist/controls/row/row.css +152 -0
- package/dist/controls/row/row.d.ts +95 -0
- package/dist/controls/row/row.js +45 -0
- package/dist/controls/segment/segment.css +66 -0
- package/dist/controls/segment/segment.d.ts +3 -0
- package/dist/controls/segment/segment.js +26 -0
- package/dist/controls/segmented-control/segmented-control.css +189 -0
- package/dist/controls/segmented-control/segmented-control.d.ts +20 -0
- package/dist/controls/segmented-control/segmented-control.js +64 -0
- package/dist/controls/select/select.css +467 -0
- package/dist/controls/select/select.d.ts +147 -0
- package/dist/controls/select/select.js +538 -0
- package/dist/controls/slider/slider.css +231 -0
- package/dist/controls/slider/slider.d.ts +111 -0
- package/dist/controls/slider/slider.js +60 -0
- package/dist/controls/slider-multi/slider-multi.css +197 -0
- package/dist/controls/slider-multi/slider-multi.d.ts +149 -0
- package/dist/controls/slider-multi/slider-multi.js +380 -0
- package/dist/controls/sparkline/sparkline-math.d.ts +23 -0
- package/dist/controls/sparkline/sparkline-math.js +79 -0
- package/dist/controls/sparkline/sparkline.css +61 -0
- package/dist/controls/sparkline/sparkline.d.ts +27 -0
- package/dist/controls/sparkline/sparkline.js +74 -0
- package/dist/controls/split/constrain.d.ts +44 -0
- package/dist/controls/split/constrain.js +126 -0
- package/dist/controls/split/split-pane.css +63 -0
- package/dist/controls/split/split-pane.d.ts +49 -0
- package/dist/controls/split/split-pane.js +42 -0
- package/dist/controls/split/split.css +127 -0
- package/dist/controls/split/split.d.ts +42 -0
- package/dist/controls/split/split.js +364 -0
- package/dist/controls/stat/stat-model.d.ts +22 -0
- package/dist/controls/stat/stat-model.js +69 -0
- package/dist/controls/stat/stat.css +101 -0
- package/dist/controls/stat/stat.d.ts +30 -0
- package/dist/controls/stat/stat.js +73 -0
- package/dist/controls/status-stream/status-stream.css +151 -0
- package/dist/controls/status-stream/status-stream.d.ts +108 -0
- package/dist/controls/status-stream/status-stream.js +417 -0
- package/dist/controls/swatch/swatch.css +66 -0
- package/dist/controls/swatch/swatch.d.ts +28 -0
- package/dist/controls/swatch/swatch.js +74 -0
- package/dist/controls/swiper/swiper-item.css +17 -0
- package/dist/controls/swiper/swiper-item.d.ts +31 -0
- package/dist/controls/swiper/swiper-item.js +47 -0
- package/dist/controls/swiper/swiper-label.css +10 -0
- package/dist/controls/swiper/swiper-label.d.ts +4 -0
- package/dist/controls/swiper/swiper-label.js +20 -0
- package/dist/controls/swiper/swiper-paddles.css +26 -0
- package/dist/controls/swiper/swiper-paddles.d.ts +10 -0
- package/dist/controls/swiper/swiper-paddles.js +62 -0
- package/dist/controls/swiper/swiper-pagination.css +60 -0
- package/dist/controls/swiper/swiper-pagination.d.ts +31 -0
- package/dist/controls/swiper/swiper-pagination.js +78 -0
- package/dist/controls/swiper/swiper.css +153 -0
- package/dist/controls/swiper/swiper.d.ts +158 -0
- package/dist/controls/swiper/swiper.js +659 -0
- package/dist/controls/switch/switch.css +194 -0
- package/dist/controls/switch/switch.d.ts +5 -0
- package/dist/controls/switch/switch.js +18 -0
- package/dist/controls/table/table-model.d.ts +43 -0
- package/dist/controls/table/table-model.js +124 -0
- package/dist/controls/table/table.css +90 -0
- package/dist/controls/table/table.d.ts +29 -0
- package/dist/controls/table/table.js +178 -0
- package/dist/controls/tabs/tab-panel.d.ts +10 -0
- package/dist/controls/tabs/tab-panel.js +89 -0
- package/dist/controls/tabs/tab.d.ts +26 -0
- package/dist/controls/tabs/tab.js +67 -0
- package/dist/controls/tabs/tabs.css +181 -0
- package/dist/controls/tabs/tabs.d.ts +61 -0
- package/dist/controls/tabs/tabs.js +176 -0
- package/dist/controls/text/href.d.ts +26 -0
- package/dist/controls/text/href.js +48 -0
- package/dist/controls/text/text.css +328 -0
- package/dist/controls/text/text.d.ts +85 -0
- package/dist/controls/text/text.js +273 -0
- package/dist/controls/text-field/text-field.css +498 -0
- package/dist/controls/text-field/text-field.d.ts +226 -0
- package/dist/controls/text-field/text-field.js +905 -0
- package/dist/controls/textarea/textarea.css +251 -0
- package/dist/controls/textarea/textarea.d.ts +136 -0
- package/dist/controls/textarea/textarea.js +312 -0
- package/dist/controls/theme-provider/theme-provider.css +48 -0
- package/dist/controls/theme-provider/theme-provider.d.ts +59 -0
- package/dist/controls/theme-provider/theme-provider.js +40 -0
- package/dist/controls/timeline/timeline.css +33 -0
- package/dist/controls/timeline/timeline.d.ts +39 -0
- package/dist/controls/timeline/timeline.js +52 -0
- package/dist/controls/timeline-item/timeline-item.css +495 -0
- package/dist/controls/timeline-item/timeline-item.d.ts +79 -0
- package/dist/controls/timeline-item/timeline-item.js +360 -0
- package/dist/controls/toast/toast-region.css +56 -0
- package/dist/controls/toast/toast-region.d.ts +20 -0
- package/dist/controls/toast/toast-region.js +113 -0
- package/dist/controls/toast/toast.css +96 -0
- package/dist/controls/toast/toast.d.ts +28 -0
- package/dist/controls/toast/toast.js +191 -0
- package/dist/controls/toolbar/toolbar.css +125 -0
- package/dist/controls/toolbar/toolbar.d.ts +108 -0
- package/dist/controls/toolbar/toolbar.js +68 -0
- package/dist/controls/tooltip/tooltip.css +80 -0
- package/dist/controls/tooltip/tooltip.d.ts +57 -0
- package/dist/controls/tooltip/tooltip.js +205 -0
- package/dist/descriptor/component-descriptor.d.ts +112 -0
- package/dist/descriptor/component-descriptor.js +492 -0
- package/dist/descriptor/index.d.ts +1 -0
- package/dist/descriptor/index.js +5 -0
- package/dist/dom/container.d.ts +45 -0
- package/dist/dom/container.js +60 -0
- package/dist/dom/element.d.ts +98 -0
- package/dist/dom/element.js +221 -0
- package/dist/dom/form.d.ts +240 -0
- package/dist/dom/form.js +399 -0
- package/dist/dom/index.d.ts +10 -0
- package/dist/dom/index.js +31 -0
- package/dist/dom/props.d.ts +56 -0
- package/dist/dom/props.js +231 -0
- package/dist/dom/repeat.d.ts +10 -0
- package/dist/dom/repeat.js +202 -0
- package/dist/dom/template.d.ts +161 -0
- package/dist/dom/template.js +634 -0
- package/dist/dom/watch.d.ts +11 -0
- package/dist/dom/watch.js +82 -0
- package/dist/foundation-styles.css +9 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/reactive/graph.d.ts +65 -0
- package/dist/reactive/graph.js +310 -0
- package/dist/reactive/index.d.ts +3 -0
- package/dist/reactive/index.js +4 -0
- package/dist/reactive/scheduler.d.ts +13 -0
- package/dist/reactive/scheduler.js +49 -0
- package/dist/traits/area-drag.d.ts +12 -0
- package/dist/traits/area-drag.js +70 -0
- package/dist/traits/form-registry.d.ts +36 -0
- package/dist/traits/form-registry.js +108 -0
- package/dist/traits/index.d.ts +24 -0
- package/dist/traits/index.js +19 -0
- package/dist/traits/overlay.d.ts +50 -0
- package/dist/traits/overlay.js +277 -0
- package/dist/traits/pane-resize.d.ts +26 -0
- package/dist/traits/pane-resize.js +103 -0
- package/dist/traits/press-activation.d.ts +11 -0
- package/dist/traits/press-activation.js +55 -0
- package/dist/traits/roving-focus.d.ts +52 -0
- package/dist/traits/roving-focus.js +214 -0
- package/dist/traits/scroll-fade.d.ts +28 -0
- package/dist/traits/scroll-fade.js +120 -0
- package/dist/traits/selection-commit.d.ts +30 -0
- package/dist/traits/selection-commit.js +146 -0
- package/dist/traits/tabbable.d.ts +12 -0
- package/dist/traits/tabbable.js +59 -0
- package/dist/traits/track-user-invalid.d.ts +36 -0
- package/dist/traits/track-user-invalid.js +52 -0
- package/dist/traits/value-codec.d.ts +120 -0
- package/dist/traits/value-codec.js +497 -0
- package/dist/traits/value-drag.d.ts +18 -0
- package/dist/traits/value-drag.js +84 -0
- package/package.json +263 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/* combo-box.css — ui-combo-box, the single-file component stylesheet (ADR-0003).
|
|
2
|
+
* Two clearly-SECTIONED blocks, mirroring popover.css / text-field.css:
|
|
3
|
+
*
|
|
4
|
+
* [1] TOKEN BLOCK — `:where(ui-combo-box)` (specificity 0,0,0) declares the `--ui-combo-box-*`
|
|
5
|
+
* chain from the colour roles (`--md-sys-color-{family}-{role}`) and the dimensional ramp
|
|
6
|
+
* (`--md-sys-height-md` / `--md-sys-shape-corner-base`). Raw `--md-sys-color-*` roles enter ONLY
|
|
7
|
+
* here; `@scope` never reads them. This is the "Geometry-by-part" three-class pattern
|
|
8
|
+
* from the decomp: the editor is Control-class, the panel is Container/surface, and the
|
|
9
|
+
* option rows are the legacy item-pad (ROV-C5 / §4.6/5.1).
|
|
10
|
+
* [2] STYLES BLOCK — `@scope (ui-combo-box)` CONSUMES only `--ui-combo-box-*` for its OWN
|
|
11
|
+
* tokens plus the shared fleet constants (`--md-sys-color-focus-ring`, `--ui-motion-*`).
|
|
12
|
+
* The host is `display: inline-grid` with a `min-inline-size` floor (ADR-0021: entry-
|
|
13
|
+
* control frame law; the same trap that collapsed ui-text-field + ui-slider). The editor
|
|
14
|
+
* part is Control-class: `block-size` off `--ui-combo-box-height`; inline text inset = h/2
|
|
15
|
+
* (the fleet Control-class value-edge standard, matching text-field/select). The listbox
|
|
16
|
+
* panel is Container/surface: `--ui-container-bg` equivalent, `--md-sys-shape-corner-base` rounding.
|
|
17
|
+
* Options use the item-pad row model. `[data-active]` highlights the active-descendant
|
|
18
|
+
* option without moving DOM focus.
|
|
19
|
+
* (2026-07-06) The item-pad's numbers are DERIVED off the editor's own height/font
|
|
20
|
+
* (`--ui-combo-box-height`/`-font`/`-padding-inline`) instead of fixed `--md-sys-space-*` px, so
|
|
21
|
+
* option text aligns under the editor's text and the option row height matches the editor's
|
|
22
|
+
* — the same size-carrying model as ui-select's listbox, applied to combo-box's single
|
|
23
|
+
* (currently size-less) register; see the token-block comment for the exact derivation.
|
|
24
|
+
* (2026-07-06, follow-up) `--ui-combo-box-padding-inline` itself is now h/2 (was the fixed
|
|
25
|
+
* `--md-sys-space-sm`) — the editor was the lone entry-control outlier off the fleet h/2 value-
|
|
26
|
+
* edge law; the item-pad derivation above already read this token, so options auto-followed
|
|
27
|
+
* (h/4 + h/4 = h/2), now byte-identical in model to ui-select's trigger/listbox pairing.
|
|
28
|
+
*
|
|
29
|
+
* Standalone stylesheet — NOT injected from combo-box.ts (behaviour-only `.ts`, plan §2).
|
|
30
|
+
* Linked via the component-styles barrel (wave-4 integration slice). The panel's `[popover]`
|
|
31
|
+
* attribute gives it `display:none` until `showPopover()` opens it into the top layer.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/* ════════════════ [1] TOKEN BLOCK — :where(ui-combo-box) ════════════════ */
|
|
35
|
+
|
|
36
|
+
:where(ui-combo-box) {
|
|
37
|
+
/* ── Editor (Control-class) ─────────────────────────────────────────── */
|
|
38
|
+
/* Geometry: control height off the md-scale ramp (the combo-box trigger is the editor). */
|
|
39
|
+
--ui-combo-box-height: var(--md-sys-height-md);
|
|
40
|
+
--ui-combo-box-font: var(--md-sys-font-md);
|
|
41
|
+
/* (2026-07-06) h/2 — the fleet Control-class value-edge standard (text-field.css:119,
|
|
42
|
+
select.css trigger padding-inline-start), replacing the earlier fixed --md-sys-space-sm.
|
|
43
|
+
The editor was the lone entry-control outlier still anchored to a space token instead
|
|
44
|
+
of the frame-law h/2 inset; this brings it into line. */
|
|
45
|
+
--ui-combo-box-padding-inline: calc(var(--ui-combo-box-height) / 2);
|
|
46
|
+
|
|
47
|
+
/* Frame — Kim's filled/container state law (TKT-0062), SUPERSEDING the earlier border-only
|
|
48
|
+
channel: THREE channels now repoint per state (background, border, text-ink), keyed off five
|
|
49
|
+
states — default (empty, idle) / filled (has a value, idle) / hover / focus / disabled.
|
|
50
|
+
user-invalid is UNCHANGED — its own border-only danger channel (below) layers on top of
|
|
51
|
+
whichever bg/ink this table already picked; it never touches bg.
|
|
52
|
+
state | bg | border | ink
|
|
53
|
+
default | container-low | transparent | neutral
|
|
54
|
+
filled | container | transparent | on-surface-variant
|
|
55
|
+
hover | container | outline-variant | on-surface-variant
|
|
56
|
+
focus | container-low | transparent (ring)| on-surface
|
|
57
|
+
disabled | container-low | transparent | neutral-low
|
|
58
|
+
"filled" reads `[data-part='editor']:not([data-empty])` DIRECTLY (no :has() indirection needed
|
|
59
|
+
— unlike text-field/textarea, whose editor is a SEPARATE part inside :scope, combo-box's
|
|
60
|
+
`[data-part='editor']` IS both the frame and the value surface); see @scope's selector below.
|
|
61
|
+
Declared here, consumed at the matching pseudo-/attribute selector in @scope (so @scope reads
|
|
62
|
+
only --ui-combo-box-*, never a role). */
|
|
63
|
+
--ui-combo-box-bg: var(--md-sys-color-neutral-container-low); /* default */
|
|
64
|
+
--ui-combo-box-bg-filled: var(--md-sys-color-neutral-container);
|
|
65
|
+
--ui-combo-box-bg-hover: var(--md-sys-color-neutral-container);
|
|
66
|
+
--ui-combo-box-bg-focus: var(--md-sys-color-neutral-container-low);
|
|
67
|
+
--ui-combo-box-border: transparent; /* default — the ring is the interactive indicator, not the border */
|
|
68
|
+
--ui-combo-box-border-hover: var(--md-sys-color-neutral-outline-variant); /* :hover — the ONE visible-border state */
|
|
69
|
+
--ui-combo-box-border-focus: transparent; /* sole focus indicator = shared outline ring */
|
|
70
|
+
/* user-invalid (ADR-0051) — the danger border, appearing only AFTER the first interaction (the
|
|
71
|
+
trackUserInvalid controller owns that timing; combo-box.ts toggles :state(user-invalid)).
|
|
72
|
+
UNCHANGED/orthogonal to the table above — never touches bg. */
|
|
73
|
+
--ui-combo-box-border-invalid: var(--md-sys-color-danger);
|
|
74
|
+
--ui-combo-box-border-invalid-hover: var(--md-sys-color-danger-high);
|
|
75
|
+
--ui-combo-box-ink: var(--md-sys-color-neutral); /* default — empty, idle */
|
|
76
|
+
--ui-combo-box-ink-filled: var(--md-sys-color-neutral-on-surface-variant);
|
|
77
|
+
--ui-combo-box-ink-hover: var(--md-sys-color-neutral-on-surface-variant);
|
|
78
|
+
--ui-combo-box-ink-focus: var(--md-sys-color-neutral-on-surface);
|
|
79
|
+
--ui-combo-box-placeholder: var(--ui-combo-box-ink); /* tracks the SAME default-state ink role dynamically (Kim's table has no separate placeholder row) — re-resolves live off whatever --ui-combo-box-ink cascades to, so the disabled repoint below reaches it for free */
|
|
80
|
+
|
|
81
|
+
/* Disabled state (TKT-0062's disabled row) — an indirection layer of -disabled-suffixed tokens
|
|
82
|
+
fed to the base bg/border/ink trio by the [disabled] block below (keeps the TKT-0047 shape). */
|
|
83
|
+
--ui-combo-box-border-disabled: transparent;
|
|
84
|
+
--ui-combo-box-bg-disabled: var(--md-sys-color-neutral-container-low);
|
|
85
|
+
--ui-combo-box-ink-disabled: var(--md-sys-color-neutral-low);
|
|
86
|
+
|
|
87
|
+
/* Frame shape */
|
|
88
|
+
--ui-combo-box-radius: var(--md-sys-shape-corner-base);
|
|
89
|
+
|
|
90
|
+
/* Min-inline-size floor (ADR-0021 entry-control lesson — must NOT be 0 or the editor
|
|
91
|
+
collapses to a zero-width typing target in a flex row, just like text-field #74). */
|
|
92
|
+
--ui-combo-box-min-inline-size: 20ch;
|
|
93
|
+
|
|
94
|
+
/* ── Listbox panel (Container/surface-class) ────────────────────────── */
|
|
95
|
+
--ui-combo-box-panel-bg: var(--md-sys-color-neutral-surface);
|
|
96
|
+
--ui-combo-box-panel-ink: var(--md-sys-color-neutral-on-surface);
|
|
97
|
+
--ui-combo-box-panel-outline: var(--md-sys-color-neutral-outline-variant);
|
|
98
|
+
--ui-combo-box-panel-radius: var(--md-sys-shape-corner-base);
|
|
99
|
+
--ui-combo-box-panel-min-inline-size: 12rem; /* prevent empty-panel collapse (ADR-0021) */
|
|
100
|
+
/* Panel-edge inset (feeds --ui-box-inset below, same mechanism as ui-select, 2026-07-06):
|
|
101
|
+
DERIVED off the editor's OWN inline text-pad (--ui-combo-box-padding-inline), which is now
|
|
102
|
+
itself the fleet h/2 standard (2026-07-06 follow-up — see the token comment above), so
|
|
103
|
+
panel-inset + option-inline (below) sum to h/2 exactly — the SAME alignment law as ui-select's
|
|
104
|
+
trigger (listbox-padding + option-inline == h/2): option text lines up under the editor's text
|
|
105
|
+
at the identical inline offset. Split evenly (h/4 + h/4), same as ui-select. NOTE: ui-combo-box
|
|
106
|
+
has no `[size]` attribute yet (a structural divergence from ui-select — flagged, not forced);
|
|
107
|
+
this is still worth deriving off the ramp now so a future `[size]` addition (its own ADR/decomp,
|
|
108
|
+
a new-attribute contract change) would make this repoint for free, same as ui-select. */
|
|
109
|
+
--ui-combo-box-listbox-padding: calc(var(--ui-combo-box-padding-inline) / 2);
|
|
110
|
+
|
|
111
|
+
/* Panel max-block-size (TKT-0027) — public dial, default min(50vh, 12 real option rows), same
|
|
112
|
+
shape as ui-select's listbox dial (the family precedent — combo-box's option row height IS
|
|
113
|
+
--ui-combo-box-height exactly, by the same row-height law: (height−font)/2 padding × 2 + font
|
|
114
|
+
== height). 12 rows = 12 option boxes + 13 inset margins (leading + 11 collapsed inter-row +
|
|
115
|
+
trailing — the panel is `[data-box]`, a BFC collapsing adjacent siblings' margins to ONE
|
|
116
|
+
inset); --ui-combo-box-listbox-padding is the value fed to --ui-box-inset below, read here
|
|
117
|
+
directly (not the DOM-positional --ui-box-inset itself). Density-invariant (height is a frame
|
|
118
|
+
quantity, geometry.md). + 2px — the panel's border-box: max-block-size caps the BORDER box
|
|
119
|
+
(box-sizing: border-box below), but the row math above computed the CONTENT box (12 rows + 13
|
|
120
|
+
insets, no border term) — without this the 12th row would overflow its own cap by exactly the
|
|
121
|
+
1px+1px border width (FIXED 2026-07-12, TKT-0027 browser-leg finding, same shape as ui-menu). */
|
|
122
|
+
--ui-combo-box-panel-max-block-size: min(50vh, calc(12 * var(--ui-combo-box-height) + 13 * var(--ui-combo-box-listbox-padding) + 2px));
|
|
123
|
+
|
|
124
|
+
/* ── Option rows (legacy item-pad — ROV-C5 / §4.6/5.1) — DERIVED (2026-07-06), same model as
|
|
125
|
+
ui-select: block-pad = (editor height − option font)/2 (the row's rendered height == the
|
|
126
|
+
editor's own height); inline-pad pairs with --ui-combo-box-listbox-padding above to total the
|
|
127
|
+
editor's own inline pad (the alignment law). Supersedes the earlier fixed --md-sys-space-xs/sm px. */
|
|
128
|
+
--ui-combo-box-option-padding-block: calc((var(--ui-combo-box-height) - var(--ui-combo-box-font)) / 2);
|
|
129
|
+
--ui-combo-box-option-padding-inline: calc(var(--ui-combo-box-padding-inline) / 2);
|
|
130
|
+
--ui-combo-box-option-font: var(--ui-combo-box-font); /* options were size-blind on FONT too (bug fix) */
|
|
131
|
+
--ui-combo-box-option-active-bg: var(--md-sys-color-neutral-tint-dim); /* active-descendant highlight — 5% neutral overlay (was the undefined -tint-5) */
|
|
132
|
+
--ui-combo-box-option-active-ink: var(--md-sys-color-neutral-on-surface);
|
|
133
|
+
--ui-combo-box-option-selected-bg: var(--md-sys-color-primary-container-low); /* selected-value row — matches ui-select's AA-safe pairing (was the undefined -tint-5) */
|
|
134
|
+
--ui-combo-box-option-selected-ink: var(--md-sys-color-primary-high);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* ── disabled → muted neutral roles (TKT-0047, the select.css precedent) ──────────────────────── */
|
|
138
|
+
/* TKT-0063: widened to `:is([disabled], :state(disabled))` — the own `[disabled]` attribute ALONE
|
|
139
|
+
missed the effective-disabled case (own || ancestor <fieldset disabled>/form-provider); combo-box.ts's
|
|
140
|
+
effectiveDisabled() effect now also sets :state(disabled), mirroring text-field.ts's own precedent. */
|
|
141
|
+
:where(ui-combo-box:is([disabled], :state(disabled))) {
|
|
142
|
+
--ui-combo-box-border: var(--ui-combo-box-border-disabled);
|
|
143
|
+
--ui-combo-box-bg: var(--ui-combo-box-bg-disabled);
|
|
144
|
+
--ui-combo-box-ink: var(--ui-combo-box-ink-disabled);
|
|
145
|
+
--ui-combo-box-placeholder: var(--ui-combo-box-ink-disabled);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* ════════════════ [2] STYLES BLOCK — @scope (ui-combo-box) ════════════════ */
|
|
149
|
+
|
|
150
|
+
@scope (ui-combo-box) {
|
|
151
|
+
/* Host: inline-grid so width is the layout's job, but a min-inline-size floor prevents
|
|
152
|
+
collapse (the ADR-0021 entry-control law; same pattern as text-field + slider). */
|
|
153
|
+
:scope {
|
|
154
|
+
display: inline-grid;
|
|
155
|
+
min-inline-size: var(--ui-combo-box-min-inline-size);
|
|
156
|
+
grid-template-columns: 1fr;
|
|
157
|
+
position: relative; /* stacking context for any decorative caret pseudo */
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* ── Editor part (Control-class) ──────────────────────────────────────── */
|
|
161
|
+
|
|
162
|
+
:scope > [data-part='editor'] {
|
|
163
|
+
box-sizing: border-box;
|
|
164
|
+
/* Re-declare the placeholder alias AT THE EDITOR (TKT-0065 F13, second half of the fix): a custom
|
|
165
|
+
property resolves at computed-value time ON THE ELEMENT THAT DECLARES IT — the host-level
|
|
166
|
+
`--ui-combo-box-placeholder: var(--ui-combo-box-ink)` locks in the HOST's ink and inherits down
|
|
167
|
+
as a resolved value, so the state rules' editor-level ink repoints below never reached the
|
|
168
|
+
placeholder ::before (proven by the F13 regression test: hover/focus repainted the typed text but
|
|
169
|
+
the placeholder stayed frozen). Declaring the same alias here re-resolves it against the EDITOR's
|
|
170
|
+
own (state-repointed) ink. Own-chain read — @scope hygiene holds. Unlike text-field, whose state
|
|
171
|
+
rules live on the host itself, combo-box's frame IS the editor part, so the alias must live here. */
|
|
172
|
+
--ui-combo-box-placeholder: var(--ui-combo-box-ink);
|
|
173
|
+
/* Control-class height (block-size off the ramp, not a content-height).
|
|
174
|
+
line-height: 1 + padding-block: 0 = the text fills the box without double-spacing
|
|
175
|
+
(matches --md-sys-control-line-height, ADR-0036). */
|
|
176
|
+
min-block-size: var(--ui-combo-box-height);
|
|
177
|
+
line-height: 1;
|
|
178
|
+
padding-block: 0;
|
|
179
|
+
padding-inline: var(--ui-combo-box-padding-inline);
|
|
180
|
+
|
|
181
|
+
display: flex;
|
|
182
|
+
align-items: center;
|
|
183
|
+
|
|
184
|
+
/* FIXED (2026-07-06, found by the option-font trip-wire): `font: var(--ui-combo-box-font)` was
|
|
185
|
+
an INVALID `font` shorthand (a single value — the shorthand requires font-size AND
|
|
186
|
+
font-family at minimum), so the whole declaration was dropped and the editor silently fell
|
|
187
|
+
back to the UA default (16px) instead of the --md-sys-font-md ramp (14px). `font-size` is the
|
|
188
|
+
correct longhand — this is the same class of bug the option font-size fix below closes. */
|
|
189
|
+
font-size: var(--ui-combo-box-font);
|
|
190
|
+
background-color: var(--ui-combo-box-bg);
|
|
191
|
+
color: var(--ui-combo-box-ink);
|
|
192
|
+
border: 1px solid var(--ui-combo-box-border);
|
|
193
|
+
border-radius: var(--ui-combo-box-radius);
|
|
194
|
+
cursor: text;
|
|
195
|
+
outline: none; /* focus ring handled via :focus-visible outline on this element */
|
|
196
|
+
|
|
197
|
+
/* Prevent collapsing inline when empty — the 1fr grid column already handles host width,
|
|
198
|
+
but the editor cell can collapse its OWN inline-size if content is absent.
|
|
199
|
+
min-inline-size: 0 here (the floor is on the HOST, not the editor cell). */
|
|
200
|
+
min-inline-size: 0;
|
|
201
|
+
|
|
202
|
+
/* SINGLE-LINE (2026-07-07 fix — the initial-caret visual bug root cause): a `contenteditable`'s
|
|
203
|
+
OWN UA default is `white-space: pre-wrap` (it wraps by default — unlike a plain block/inline
|
|
204
|
+
element). Every other single-line Control-class entry field in the fleet overrides this
|
|
205
|
+
explicitly (text-field.css's editor sets the identical pair), but it was missing here. Without
|
|
206
|
+
it, the placeholder (`::before` `content: attr(data-placeholder)`) — or any typed text — wraps
|
|
207
|
+
onto a second line the moment it exceeds the field's width, growing the box past its fixed
|
|
208
|
+
`--ui-combo-box-height` (min-block-size is a floor, not a cap) and visually displacing the caret
|
|
209
|
+
relative to a now multi-line, oddly-centered placeholder block: the "caret sits oddly relative
|
|
210
|
+
to the placeholder" defect (browser-confirmed: an unconstrained-width editor with a long
|
|
211
|
+
placeholder/value silently grows taller and wraps instead of staying single-line). `overflow:
|
|
212
|
+
hidden` clips the (now guaranteed single-line) content that exceeds the box; the editor
|
|
213
|
+
self-scrolls horizontally to keep the caret in view on overflow, matching text-field. */
|
|
214
|
+
white-space: nowrap;
|
|
215
|
+
overflow: hidden;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Placeholder via ::before + attr(data-placeholder) (text-field pattern):
|
|
219
|
+
the [data-empty] attribute is toggled by TS when editor.textContent is empty. */
|
|
220
|
+
:scope > [data-part='editor'][data-empty]::before {
|
|
221
|
+
content: attr(data-placeholder);
|
|
222
|
+
color: var(--ui-combo-box-placeholder);
|
|
223
|
+
pointer-events: none;
|
|
224
|
+
user-select: none;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* The filled/container state ladder (TKT-0062, Kim's ruling — supersedes the earlier border-only
|
|
228
|
+
channel) — repoints background/border-color/color together from the per-state tokens declared
|
|
229
|
+
in the :where() block (the geometry law is untouched). "filled" = the editor itself carries a
|
|
230
|
+
value (`:not([data-empty])`, the SAME emptiness signal the placeholder ::before above already
|
|
231
|
+
keys off) — read DIRECTLY on `[data-part='editor']` (no `:has()` indirection: combo-box's
|
|
232
|
+
editor IS both the frame and the value surface, unlike text-field/textarea's separate
|
|
233
|
+
editor-inside-host split).
|
|
234
|
+
|
|
235
|
+
Precedence is enforced by MUTUAL EXCLUSION (`:not()`), not source-order/specificity — the SAME
|
|
236
|
+
lesson text-field's law was fixed under (a `:not(:is(disabled))`-guarded `:hover` was measured
|
|
237
|
+
to OUTRANK an unguarded `:focus-within` by specificity, so clicking to focus — which also
|
|
238
|
+
leaves the pointer hovering — kept the hover border instead of stepping transparent, a live
|
|
239
|
+
regression that history was caught fixing). Making each rule EXPLICITLY exclude every state
|
|
240
|
+
that should outrank it removes the ambiguity regardless of computed specificity: filled
|
|
241
|
+
excludes hover/focus/disabled; hover excludes focus/disabled (fill state doesn't matter — hover
|
|
242
|
+
overrides regardless); focus is checked last (the `:not([aria-disabled='true'])` guard there is
|
|
243
|
+
defensive — `contenteditable="false"` already makes a disabled editor non-focusable,
|
|
244
|
+
combo-box.ts — so it should never actually engage). user-invalid's border-only override still
|
|
245
|
+
layers on top of whichever bg/ink row above resolved, untouched. */
|
|
246
|
+
/* NOTE (TKT-0065 lateral review, fixed — the text-field.css precedent): repointing the
|
|
247
|
+
--ui-combo-box-ink TOKEN itself, NOT a direct color: declaration — the placeholder ::before above
|
|
248
|
+
carries its own `color: var(--ui-combo-box-placeholder)`, which ALIASES the ink token; a property
|
|
249
|
+
repoint on the editor never reached it, so an EMPTY combo-box's placeholder stayed at the default
|
|
250
|
+
ink under hover/focus while text-field's repainted (proven frozen in a real Chromium+WebKit probe
|
|
251
|
+
before this fix — the exact TKT-0062 mechanic-[b] regression, one consumer over). */
|
|
252
|
+
:scope > [data-part='editor']:not(:hover):not(:focus):not([aria-disabled='true']):not([data-empty]) {
|
|
253
|
+
background-color: var(--ui-combo-box-bg-filled);
|
|
254
|
+
--ui-combo-box-ink: var(--ui-combo-box-ink-filled);
|
|
255
|
+
}
|
|
256
|
+
:scope > [data-part='editor']:not(:focus):not([aria-disabled='true']):hover {
|
|
257
|
+
background-color: var(--ui-combo-box-bg-hover);
|
|
258
|
+
border-color: var(--ui-combo-box-border-hover);
|
|
259
|
+
--ui-combo-box-ink: var(--ui-combo-box-ink-hover);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* Focus: the shared outline ring is the SOLE indicator (matches text-field's transparent
|
|
263
|
+
border-focus approach — a coloured border-focus would double with the ring). Focus's bg/ink
|
|
264
|
+
(TKT-0062) override filled/hover unconditionally — a focused-and-filled editor still shows the
|
|
265
|
+
FOCUS row (container-low bg, on-surface ink), not filled's. */
|
|
266
|
+
:scope > [data-part='editor']:not([aria-disabled='true']):focus {
|
|
267
|
+
background-color: var(--ui-combo-box-bg-focus);
|
|
268
|
+
border-color: var(--ui-combo-box-border-focus);
|
|
269
|
+
--ui-combo-box-ink: var(--ui-combo-box-ink-focus);
|
|
270
|
+
outline: var(--md-sys-state-focus-ring-width) solid var(--md-sys-color-focus-ring);
|
|
271
|
+
outline-offset: var(--md-sys-state-focus-ring-offset);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* user-invalid (ADR-0051) — the danger border, appearing only AFTER the first interaction. */
|
|
275
|
+
:scope:state(user-invalid) > [data-part='editor'] {
|
|
276
|
+
border-color: var(--ui-combo-box-border-invalid);
|
|
277
|
+
}
|
|
278
|
+
:scope:state(user-invalid) > [data-part='editor']:hover {
|
|
279
|
+
border-color: var(--ui-combo-box-border-invalid-hover);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* Disabled — TKT-0047: converges on the fleet's dominant mechanism (token-repoint, not opacity).
|
|
283
|
+
The :where(ui-combo-box[disabled]) block above already repoints --ui-combo-box-border/-bg/-ink
|
|
284
|
+
(this rule's own base declarations already read those tokens) — no opacity needed. */
|
|
285
|
+
:scope > [data-part='editor'][aria-disabled='true'] {
|
|
286
|
+
cursor: default;
|
|
287
|
+
pointer-events: none;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* ── Listbox panel (Container/surface in the top layer) ──────────────── */
|
|
291
|
+
|
|
292
|
+
:scope > [data-part='listbox'] {
|
|
293
|
+
box-sizing: border-box;
|
|
294
|
+
margin: 0; /* JS positioning controller sets position:fixed + top/left; no UA margin */
|
|
295
|
+
min-inline-size: var(--ui-combo-box-panel-min-inline-size);
|
|
296
|
+
|
|
297
|
+
background-color: var(--ui-combo-box-panel-bg);
|
|
298
|
+
color: var(--ui-combo-box-panel-ink);
|
|
299
|
+
border: 1px solid var(--ui-combo-box-panel-outline);
|
|
300
|
+
border-radius: var(--ui-combo-box-panel-radius);
|
|
301
|
+
|
|
302
|
+
/* No panel padding — options have their own padding-inline to align the ink edge */
|
|
303
|
+
padding: 0;
|
|
304
|
+
max-block-size: var(--ui-combo-box-panel-max-block-size); /* TKT-0027 — public dial, default min(50vh, 12 option rows) */
|
|
305
|
+
overflow-y: auto; /* still clips options to the panel radius (an `auto` axis clips like `hidden`, just scrollably) */
|
|
306
|
+
list-style: none;
|
|
307
|
+
/* Repoint the shared container-box.css inset LOCALLY to the size-derived value (the panel
|
|
308
|
+
carries [data-box], combo-box.ts — same mechanism as ui-select, 2026-07-06). */
|
|
309
|
+
--ui-box-inset: var(--ui-combo-box-listbox-padding);
|
|
310
|
+
font-size: var(--ui-combo-box-option-font); /* was unset (inherited ambient) — options now read the ramp */
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/* ── Option rows (legacy item-pad) ───────────────────────────────────── */
|
|
314
|
+
|
|
315
|
+
:scope [role='option'] {
|
|
316
|
+
display: block;
|
|
317
|
+
margin: var(--ui-box-inset, 0.375rem); /* the box-model inset — repointed above to the size-derived value */
|
|
318
|
+
padding-block: var(--ui-combo-box-option-padding-block);
|
|
319
|
+
padding-inline: var(--ui-combo-box-option-padding-inline);
|
|
320
|
+
/* line-height: 1 makes the (height−font)/2 block-pad math exact (matches ui-select's row-height law) */
|
|
321
|
+
line-height: 1;
|
|
322
|
+
/* nested-radius (ADR-0018): the highlight corner inset from the panel by the box margin */
|
|
323
|
+
border-radius: calc(var(--ui-combo-box-panel-radius) - var(--ui-box-inset, 0.375rem));
|
|
324
|
+
cursor: pointer;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/* Active-descendant highlight: [data-active] is set by TS on the highlighted option.
|
|
328
|
+
This is the CSS face of the aria-activedescendant visual highlight — NOT :focus (focus
|
|
329
|
+
stays on the editor) but a dedicated attribute-driven style. */
|
|
330
|
+
:scope [role='option'][data-active] {
|
|
331
|
+
background-color: var(--ui-combo-box-option-active-bg);
|
|
332
|
+
color: var(--ui-combo-box-option-active-ink);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/* Selected option (aria-selected="true", set by the selection-commit pattern on prior commits) */
|
|
336
|
+
:scope [role='option'][aria-selected='true'] {
|
|
337
|
+
background-color: var(--ui-combo-box-option-selected-bg);
|
|
338
|
+
color: var(--ui-combo-box-option-selected-ink);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/* ── "No matches" row (2026-07-07 fix) ────────────────────────────────
|
|
342
|
+
Shares the option rows' EXACT geometry (margin/padding-block/line-height/radius) so the panel's
|
|
343
|
+
row-height law still holds when this is the panel's ONLY visible child — this is what gives the
|
|
344
|
+
empty panel a real, deliberate height instead of collapsing to its own border (the "stray line"
|
|
345
|
+
bug). Muted ink (the same token text-field/combo-box use for placeholder text — a neutral,
|
|
346
|
+
informational read, not an actionable row): non-interactive (`cursor: default`, no hover/active/
|
|
347
|
+
selected states — it never carries `[role=option]`, so the click/keyboard commit paths already
|
|
348
|
+
skip it structurally; `pointer-events: none` here is a defensive belt-and-suspenders). */
|
|
349
|
+
:scope [data-part='empty']:not([hidden]) {
|
|
350
|
+
display: block;
|
|
351
|
+
margin: var(--ui-box-inset, 0.375rem);
|
|
352
|
+
padding-block: var(--ui-combo-box-option-padding-block);
|
|
353
|
+
padding-inline: var(--ui-combo-box-option-padding-inline);
|
|
354
|
+
line-height: 1;
|
|
355
|
+
border-radius: calc(var(--ui-combo-box-panel-radius) - var(--ui-box-inset, 0.375rem));
|
|
356
|
+
color: var(--ui-combo-box-placeholder);
|
|
357
|
+
cursor: default;
|
|
358
|
+
pointer-events: none;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/* Hidden options (filtered out): the `hidden` HTML attribute already gives display:none
|
|
362
|
+
in the UA stylesheet — no extra rule needed. The `[hidden]` selector here is purely
|
|
363
|
+
defensive in case a UA omits the base `[hidden]` rule. */
|
|
364
|
+
:scope [role='option'][hidden] {
|
|
365
|
+
display: none;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/* ── Forced colors (WHCM) ─────────────────────────────────────────────── */
|
|
369
|
+
/* The editor frame, ink, and panel stay visible as system colours.
|
|
370
|
+
forced-color-adjust: none is NOT used — the system palette handles the field
|
|
371
|
+
correctly without it. The active-descendant highlight (Highlight/HighlightText)
|
|
372
|
+
and the focus ring (Highlight) must survive. */
|
|
373
|
+
@media (forced-colors: active) {
|
|
374
|
+
:scope > [data-part='editor'] {
|
|
375
|
+
background-color: Field;
|
|
376
|
+
color: FieldText;
|
|
377
|
+
border-color: FieldText;
|
|
378
|
+
forced-color-adjust: none;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
:scope > [data-part='editor']:focus {
|
|
382
|
+
outline-color: Highlight;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
:scope > [data-part='listbox'] {
|
|
386
|
+
background-color: Canvas;
|
|
387
|
+
color: CanvasText;
|
|
388
|
+
border-color: CanvasText;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
:scope [role='option'][data-active] {
|
|
392
|
+
background-color: Highlight;
|
|
393
|
+
color: HighlightText;
|
|
394
|
+
forced-color-adjust: none;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { type ReactiveProps } from '../../dom/index.js';
|
|
2
|
+
import { UIFormElement, type FormValue, type ValidityResult, type FieldLabelling } from '../../dom/form.js';
|
|
3
|
+
import { type OverlayHandle } from '../../traits/overlay.js';
|
|
4
|
+
declare const props: {
|
|
5
|
+
value: import("../../index.js").PropConfig<string>;
|
|
6
|
+
label: {
|
|
7
|
+
reflect: true;
|
|
8
|
+
type: import("../../index.js").PropType<string>;
|
|
9
|
+
default: string;
|
|
10
|
+
attribute?: string | false;
|
|
11
|
+
};
|
|
12
|
+
open: {
|
|
13
|
+
reflect: true;
|
|
14
|
+
type: import("../../index.js").PropType<boolean>;
|
|
15
|
+
default: boolean;
|
|
16
|
+
attribute?: string | false;
|
|
17
|
+
};
|
|
18
|
+
strict: {
|
|
19
|
+
reflect: true;
|
|
20
|
+
type: import("../../index.js").PropType<boolean>;
|
|
21
|
+
default: boolean;
|
|
22
|
+
attribute?: string | false;
|
|
23
|
+
};
|
|
24
|
+
placeholder: import("../../index.js").PropConfig<string>;
|
|
25
|
+
name: {
|
|
26
|
+
reflect: true;
|
|
27
|
+
type: import("../../index.js").PropType<string>;
|
|
28
|
+
default: string;
|
|
29
|
+
attribute?: string | false;
|
|
30
|
+
};
|
|
31
|
+
disabled: {
|
|
32
|
+
reflect: true;
|
|
33
|
+
type: import("../../index.js").PropType<boolean>;
|
|
34
|
+
default: boolean;
|
|
35
|
+
attribute?: string | false;
|
|
36
|
+
};
|
|
37
|
+
required: {
|
|
38
|
+
reflect: true;
|
|
39
|
+
type: import("../../index.js").PropType<boolean>;
|
|
40
|
+
default: boolean;
|
|
41
|
+
attribute?: string | false;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
export interface UIComboBoxElement extends ReactiveProps<typeof props> {
|
|
45
|
+
}
|
|
46
|
+
export declare class UIComboBoxElement extends UIFormElement {
|
|
47
|
+
#private;
|
|
48
|
+
static props: {
|
|
49
|
+
value: import("../../index.js").PropConfig<string>;
|
|
50
|
+
label: {
|
|
51
|
+
reflect: true;
|
|
52
|
+
type: import("../../index.js").PropType<string>;
|
|
53
|
+
default: string;
|
|
54
|
+
attribute?: string | false;
|
|
55
|
+
};
|
|
56
|
+
open: {
|
|
57
|
+
reflect: true;
|
|
58
|
+
type: import("../../index.js").PropType<boolean>;
|
|
59
|
+
default: boolean;
|
|
60
|
+
attribute?: string | false;
|
|
61
|
+
};
|
|
62
|
+
strict: {
|
|
63
|
+
reflect: true;
|
|
64
|
+
type: import("../../index.js").PropType<boolean>;
|
|
65
|
+
default: boolean;
|
|
66
|
+
attribute?: string | false;
|
|
67
|
+
};
|
|
68
|
+
placeholder: import("../../index.js").PropConfig<string>;
|
|
69
|
+
name: {
|
|
70
|
+
reflect: true;
|
|
71
|
+
type: import("../../index.js").PropType<string>;
|
|
72
|
+
default: string;
|
|
73
|
+
attribute?: string | false;
|
|
74
|
+
};
|
|
75
|
+
disabled: {
|
|
76
|
+
reflect: true;
|
|
77
|
+
type: import("../../index.js").PropType<boolean>;
|
|
78
|
+
default: boolean;
|
|
79
|
+
attribute?: string | false;
|
|
80
|
+
};
|
|
81
|
+
required: {
|
|
82
|
+
reflect: true;
|
|
83
|
+
type: import("../../index.js").PropType<boolean>;
|
|
84
|
+
default: boolean;
|
|
85
|
+
attribute?: string | false;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
/** Protected overlay handle — used for the C10 cleanup probe. */
|
|
89
|
+
protected _overlayHandle: OverlayHandle | null;
|
|
90
|
+
focus(options?: FocusOptions): void;
|
|
91
|
+
protected connected(): void;
|
|
92
|
+
/**
|
|
93
|
+
* The value this combo-box contributes to its form.
|
|
94
|
+
* '' (nothing committed) → null (no form entry submitted, matching the native <select> convention).
|
|
95
|
+
*/
|
|
96
|
+
protected formValue(): FormValue;
|
|
97
|
+
/**
|
|
98
|
+
* The validity verdict:
|
|
99
|
+
* - disabled → always valid (native parity: disabled controls bypass constraint validation).
|
|
100
|
+
* - required && value==='' → valueMissing.
|
|
101
|
+
* - strict && value!=='' && no matching option → typeMismatch (the typed value is not in the set).
|
|
102
|
+
*/
|
|
103
|
+
protected formValidity(): ValidityResult;
|
|
104
|
+
/** Form reset → restore value ← defaultValue, clear the editor, reset filter + active. */
|
|
105
|
+
protected formReset(): void;
|
|
106
|
+
protected disconnected(): void;
|
|
107
|
+
/** Feeds `FormConnectDetail.userInvalid` (ADR-0050) — the `trackUserInvalid` tracker IS the one
|
|
108
|
+
* timing source; this override just exposes its gate. */
|
|
109
|
+
protected formUserInvalid(): boolean;
|
|
110
|
+
/** Restore value after navigation / autofill. */
|
|
111
|
+
protected formStateRestore(state: File | string | FormData | null): void;
|
|
112
|
+
/**
|
|
113
|
+
* The part-role override (ADR-0085 cl.3 · text-field.ts:662 precedent) — the combobox role rides the
|
|
114
|
+
* light-DOM editor PART, not `internals.role`, so the base's guarded internals-reflection default
|
|
115
|
+
* (dom/form.ts) never fires; id-reference the editor directly instead.
|
|
116
|
+
*
|
|
117
|
+
* `aria-labelledby` is this method's own, exclusive concern in both directions: set from `refs.label`
|
|
118
|
+
* when present, removed when `null` (matching text-field exactly).
|
|
119
|
+
*
|
|
120
|
+
* `aria-describedby` is ALSO this method's exclusive concern in both directions here — UNLIKE
|
|
121
|
+
* text-field, this control has no internal validity-MESSAGE node/effect competing for the
|
|
122
|
+
* attribute (the ADR-0051 user-invalid leg below writes only `:state(user-invalid)` +
|
|
123
|
+
* `aria-invalid`, never `aria-describedby`), so there is no dual-writer race to avoid by leaving
|
|
124
|
+
* it untouched on dissociation; it is written from `[refs.description, refs.error]` when fielded
|
|
125
|
+
* and cleared when not, in both branches below.
|
|
126
|
+
*
|
|
127
|
+
* Guards a not-yet-created editor (the LLD-C2 override contract) — cannot happen in practice
|
|
128
|
+
* (`#ensureParts()` runs synchronously at the top of `connected()`, before the base's forwarding effect
|
|
129
|
+
* installs), but the guard costs nothing and documents the contract.
|
|
130
|
+
*/
|
|
131
|
+
protected applyFieldLabelling(refs: FieldLabelling | null): void;
|
|
132
|
+
}
|
|
133
|
+
export {};
|