@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,189 @@
|
|
|
1
|
+
/* segmented-control.css — ui-segmented-control, the joined-button single-select control stylesheet.
|
|
2
|
+
*
|
|
3
|
+
* ADR-0095 (authored from ADR-0092 §Alternatives-1; supersedes ADR-0086's `ui-radio-group[variant=
|
|
4
|
+
* 'segmented']` — a hard cutover, no alias). Every computed value ADR-0086's Acceptance enumerated carries
|
|
5
|
+
* over UNCHANGED, re-keyed onto the new tag/tokens: equal 1fr cells, `100%/count` indicator sizing,
|
|
6
|
+
* `transform`-only placement, `--md-sys-motion-duration-fast` + reduced-motion jump, the Control-height ramp with `h/2`
|
|
7
|
+
* inline pad and `line-height:1`, hover/active washes, `Highlight`/`HighlightText` forced-colors inversion.
|
|
8
|
+
* Since "segmented" IS this control's whole identity (not a variant gate), every selector below is
|
|
9
|
+
* UNCONDITIONAL — no `[variant='segmented']` qualifier anywhere (the ADR-0086 architecture's one CSS
|
|
10
|
+
* simplification: the tag itself is now the gate).
|
|
11
|
+
*
|
|
12
|
+
* Two sectioned blocks (ADR-0003):
|
|
13
|
+
* [1] TOKEN BLOCK — `:where(ui-segmented-control)` declares `--ui-segmented-control-*` (sole declarer,
|
|
14
|
+
* the family-coherence naming law) from the Pattern-class Control-height ramp + colour roles.
|
|
15
|
+
* [2] STYLES BLOCK — plain (non-`:where`) compound selectors — `ui-segmented-control` /
|
|
16
|
+
* `ui-segmented-control ui-segment` — deliberately OUTSIDE `@scope`, so their specificity
|
|
17
|
+
* ((0,1,0) / (0,1,1) / (0,1,2) for the `::before` pseudo-element forms) cleanly clears `ui-segment`'s
|
|
18
|
+
* own `@scope (ui-segment) { :scope … }` rules ((0,1,0) / (0,1,1)) without `!important` (the ADR-0086
|
|
19
|
+
* clause 2 mechanism, ported verbatim).
|
|
20
|
+
*
|
|
21
|
+
* Standalone stylesheet — linked via the component-styles barrel; NEVER injected from segmented-control.ts
|
|
22
|
+
* (behaviour-only `.ts`, no runtime style injection — plan §2). The `--ui-segmented-control-index`/`-count`
|
|
23
|
+
* custom properties consumed below are the ONE exception: reactive STATE written by segmented-control.ts
|
|
24
|
+
* (the `--value-pct` seam, range-element.ts:111), not injected style RULES.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/* ════════════ [1] TOKEN BLOCK — :where(ui-segmented-control) (specificity 0,0,0) ════════════ */
|
|
28
|
+
|
|
29
|
+
:where(ui-segmented-control) {
|
|
30
|
+
/* Geometry — the Pattern-class CONTROL-height ramp (geometry.md's `segmented-control` example,
|
|
31
|
+
geometry.md:133), NOT the Indicator's compact/widget ramp (ADR-0041, unused here). v1 ships the single
|
|
32
|
+
`md` register; an ancestor [scale] re-tables the row for free (ADR-0038). */
|
|
33
|
+
--ui-segmented-control-segment-height: var(--md-sys-height-md);
|
|
34
|
+
--ui-segmented-control-segment-font: var(--md-sys-font-md);
|
|
35
|
+
|
|
36
|
+
/* The outer rounded track (segments carry NO divider borders — Kim's ruling, see the styles block). */
|
|
37
|
+
--ui-segmented-control-track: var(--md-sys-color-neutral-outline);
|
|
38
|
+
--ui-segmented-control-radius: var(--md-sys-shape-corner-base);
|
|
39
|
+
|
|
40
|
+
/* The shared moving indicator's fill — the AA-safe accent role minted for the calendar (ADR-0048/0058),
|
|
41
|
+
reused here as the strongest fill-presence non-color signal (ADR-0057). */
|
|
42
|
+
--ui-segmented-control-fill: var(--md-sys-color-primary-selected);
|
|
43
|
+
|
|
44
|
+
/* Ink — selected (on the moving fill) vs unselected (text-channel neutral). */
|
|
45
|
+
--ui-segmented-control-ink-selected: var(--md-sys-color-primary-on-primary);
|
|
46
|
+
--ui-segmented-control-ink: var(--md-sys-color-neutral-on-surface-variant);
|
|
47
|
+
|
|
48
|
+
/* Unselected interaction washes — the text-channel hover/active ladder; the selected segment never reads
|
|
49
|
+
these (its fill is the stable moving indicator, not a hover affordance). */
|
|
50
|
+
--ui-segmented-control-bg-hover: var(--md-sys-color-primary-container-low);
|
|
51
|
+
--ui-segmented-control-bg-active: var(--md-sys-color-primary-container);
|
|
52
|
+
|
|
53
|
+
/* user-invalid (ADR-0051, inherited unchanged from UIRadioGroupElement — see segmented-control.ts's
|
|
54
|
+
header) — the danger track-border repoint. Appears only AFTER the first interaction (the
|
|
55
|
+
trackUserInvalid controller owns that timing; radio-group.ts's connected() toggles
|
|
56
|
+
:state(user-invalid) on this control's own internals). */
|
|
57
|
+
--ui-segmented-control-border-invalid: var(--md-sys-color-danger);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* ═══════════ [2] STYLES — plain compound selectors (deliberately NOT :where/@scope) ═══════════ */
|
|
61
|
+
|
|
62
|
+
/* The track — display:grid, equal cells, orientation-driven main axis. `position:relative` hosts the
|
|
63
|
+
shared `::before` indicator; NO `overflow:hidden` (would clip the focus ring). */
|
|
64
|
+
ui-segmented-control {
|
|
65
|
+
display: grid;
|
|
66
|
+
position: relative;
|
|
67
|
+
box-sizing: border-box;
|
|
68
|
+
border: 1px solid var(--ui-segmented-control-track);
|
|
69
|
+
border-radius: var(--ui-segmented-control-radius);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* user-invalid (ADR-0051) — the danger border, appearing only AFTER the first interaction. Unlike
|
|
73
|
+
ui-radio-group (no visual surface of its own), this control owns its own track border directly. */
|
|
74
|
+
ui-segmented-control:state(user-invalid) {
|
|
75
|
+
border-color: var(--ui-segmented-control-border-invalid);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Orientation-driven main axis. `repeat(var(--count), 1fr)` is NOT usable — repeat()'s count must be a
|
|
79
|
+
literal integer — so the count-agnostic auto-flow / auto-track mechanism is the grounded path. */
|
|
80
|
+
ui-segmented-control[orientation='horizontal'] {
|
|
81
|
+
grid-auto-flow: column;
|
|
82
|
+
grid-auto-columns: 1fr;
|
|
83
|
+
}
|
|
84
|
+
ui-segmented-control[orientation='vertical'] {
|
|
85
|
+
grid-auto-rows: 1fr;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* The shared moving indicator — ONE artifact (the host's own `::before`), never a per-segment background.
|
|
89
|
+
Sized to one cell via `--ui-segmented-control-count`; POSITIONED via `transform` (never grid-track
|
|
90
|
+
placement — grid-column/row snap, transform animates). Hidden until a selection exists. */
|
|
91
|
+
ui-segmented-control::before {
|
|
92
|
+
content: '';
|
|
93
|
+
position: absolute;
|
|
94
|
+
z-index: 0; /* behind the segment text + focus ring (z-index:1 below) */
|
|
95
|
+
inset-block-start: 0;
|
|
96
|
+
inset-inline-start: 0;
|
|
97
|
+
background: var(--ui-segmented-control-fill);
|
|
98
|
+
border-radius: calc(var(--ui-segmented-control-radius) - 1px); /* the inner radius; ends align to the track */
|
|
99
|
+
transition: transform var(--md-sys-motion-duration-fast) var(--md-sys-motion-easing-standard); /* consumed, not hardcoded */
|
|
100
|
+
}
|
|
101
|
+
@media (prefers-reduced-motion: reduce) {
|
|
102
|
+
ui-segmented-control::before {
|
|
103
|
+
transition: none; /* the indicator jumps instead of sliding */
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
ui-segmented-control[orientation='horizontal']::before {
|
|
107
|
+
inline-size: calc(100% / var(--ui-segmented-control-count, 1));
|
|
108
|
+
block-size: 100%;
|
|
109
|
+
transform: translateX(calc(var(--ui-segmented-control-index, 0) * 100%));
|
|
110
|
+
}
|
|
111
|
+
ui-segmented-control[orientation='vertical']::before {
|
|
112
|
+
inline-size: 100%;
|
|
113
|
+
block-size: calc(100% / var(--ui-segmented-control-count, 1));
|
|
114
|
+
transform: translateY(calc(var(--ui-segmented-control-index, 0) * 100%));
|
|
115
|
+
}
|
|
116
|
+
/* No segment checked → hide the indicator entirely (it appears instantly on the first selection and only
|
|
117
|
+
slides between subsequent ones). */
|
|
118
|
+
ui-segmented-control:not(:has(ui-segment[checked]))::before {
|
|
119
|
+
opacity: 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* Each `ui-segment` becomes a centered, full-cell segment button (its own base layout — display:inline-flex/
|
|
123
|
+
centering/cursor — lives in segment.css; this compound selector adds the GROUP-owned sizing). `z-index:1`
|
|
124
|
+
(+ the host's own `position:relative` stacking context) keeps the label + focus ring painting ABOVE the
|
|
125
|
+
moving indicator. */
|
|
126
|
+
ui-segmented-control ui-segment {
|
|
127
|
+
position: relative;
|
|
128
|
+
z-index: 1;
|
|
129
|
+
box-sizing: border-box;
|
|
130
|
+
|
|
131
|
+
block-size: var(--ui-segmented-control-segment-height); /* Control-height ramp */
|
|
132
|
+
padding-block: 0; /* block-size is the vertical lever */
|
|
133
|
+
padding-inline: calc(var(--ui-segmented-control-segment-height) / 2); /* slotless-edge pad, geometry.md */
|
|
134
|
+
font-size: var(--ui-segmented-control-segment-font);
|
|
135
|
+
line-height: var(--md-sys-control-line-height); /* single-line control standard, ADR-0036 */
|
|
136
|
+
color: var(--ui-segmented-control-ink);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* NO inter-segment dividers — Kim's ruling (2026-07-09): the outer track + the moving fill + the hover
|
|
140
|
+
washes already carry the segmentation; vertical divider lines between segments are visual noise. The
|
|
141
|
+
original collapsed-divider rules (a shared 1px border-inline/block-start per non-first segment) were
|
|
142
|
+
removed here; segments carry NO borders of their own, and a regression guard in
|
|
143
|
+
segmented-control.browser.test.ts pins the zero-divider rendering in both orientations. */
|
|
144
|
+
|
|
145
|
+
/* Selected ink — the checked segment's label sits on the moving fill. The plain `[checked]` attribute
|
|
146
|
+
selector alone is sufficient (no paired `:state(checked)`, unlike radio.css's own dot rule): `checked`
|
|
147
|
+
reflects via its own reflected prop (indicator-element.ts:24, `reflect:true`) in lockstep with the
|
|
148
|
+
`:state(checked)` custom state a sibling reactive effect publishes off the same `checked` write
|
|
149
|
+
(indicator-element.ts:125–135) — both track one source, so `[checked]` is always current, AND (unlike
|
|
150
|
+
`:state()`) it also works under jsdom, where CustomStateSet is absent. */
|
|
151
|
+
ui-segmented-control ui-segment:is([checked]) {
|
|
152
|
+
color: var(--ui-segmented-control-ink-selected);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* Interaction states — the TEXT-channel wash on UNSELECTED segments only; a checked segment cannot toggle
|
|
156
|
+
off, so the selected segment's fill holds (it never reads the hover/active tokens). */
|
|
157
|
+
ui-segmented-control ui-segment:not([checked]):hover {
|
|
158
|
+
background: var(--ui-segmented-control-bg-hover);
|
|
159
|
+
}
|
|
160
|
+
ui-segmented-control ui-segment:not([checked]):active {
|
|
161
|
+
background: var(--ui-segmented-control-bg-active);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* Disabled — holds at idle (matches segment.css's own disabled pointer-inertness + the group's disabled
|
|
165
|
+
change-swallow, radio-group.ts): the hover/active washes are suppressed entirely. */
|
|
166
|
+
ui-segmented-control[disabled] ui-segment:hover,
|
|
167
|
+
ui-segmented-control[disabled] ui-segment:active {
|
|
168
|
+
background: transparent;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* Forced colors (WHCM) — the indicator inverts to Highlight/HighlightText; the frame, dividers, and
|
|
172
|
+
unselected ink hold at ButtonText. `transform` still applies under forced-colors (the indicator still
|
|
173
|
+
POSITIONS on the right segment; only its fill/ink invert). */
|
|
174
|
+
@media (forced-colors: active) {
|
|
175
|
+
ui-segmented-control {
|
|
176
|
+
border-color: ButtonText;
|
|
177
|
+
}
|
|
178
|
+
ui-segmented-control::before {
|
|
179
|
+
forced-color-adjust: none;
|
|
180
|
+
background: Highlight;
|
|
181
|
+
}
|
|
182
|
+
ui-segmented-control ui-segment {
|
|
183
|
+
forced-color-adjust: none;
|
|
184
|
+
color: ButtonText;
|
|
185
|
+
}
|
|
186
|
+
ui-segmented-control ui-segment:is([checked]) {
|
|
187
|
+
color: HighlightText;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { UIRadioGroupElement } from '../radio/radio-group.js';
|
|
2
|
+
import { UIRadioElement } from '../radio/radio.js';
|
|
3
|
+
import type { RovingOrientation } from '../../traits/roving-focus.js';
|
|
4
|
+
import '../segment/segment.js';
|
|
5
|
+
export declare class UISegmentedControlElement extends UIRadioGroupElement {
|
|
6
|
+
/**
|
|
7
|
+
* ADR-0095 clause 1 — the class-derived default: a segmented control defaults to a HORIZONTAL row (the
|
|
8
|
+
* ADR-0086 "variant=segmented ⇒ horizontal" default, now class-derived instead of variant-derived). An
|
|
9
|
+
* author-set `orientation` attribute still wins (resolved by the PARENT's `connected()`).
|
|
10
|
+
*/
|
|
11
|
+
protected defaultOrientation(): RovingOrientation;
|
|
12
|
+
/**
|
|
13
|
+
* ADR-0095 clause 2 — the moving-indicator state seam. Writes the selected index + segment count as host
|
|
14
|
+
* CUSTOM PROPERTIES (the `--value-pct` precedent, range-element.ts:111 / slider-multi.ts:196–197 —
|
|
15
|
+
* reactive STATE, never a stylesheet injection), read by `segmented-control.css`'s `::before` to size +
|
|
16
|
+
* translate the shared moving fill. `index < 0` (nothing selected) writes `0` — the indicator itself is
|
|
17
|
+
* hidden by CSS whenever no segment is `[checked]`, so the fallback position is irrelevant while hidden.
|
|
18
|
+
*/
|
|
19
|
+
protected selectionChanged(radios: UIRadioElement[], index: number): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// segmented-control.ts — UISegmentedControlElement, the standalone joined-button single-select control
|
|
2
|
+
// (ADR-0095, authored from ADR-0092 §Alternatives-1; supersedes ADR-0086's
|
|
3
|
+
// `ui-radio-group[variant='segmented']` — a hard cutover, no alias).
|
|
4
|
+
//
|
|
5
|
+
// Extends UIRadioGroupElement DIRECTLY (~30 lines, per the ADR's own estimate): 100% of the single-select
|
|
6
|
+
// BEHAVIOR — exclusivity, roving focus, selection-follows-focus, the group form value + required→
|
|
7
|
+
// valueMissing validity, reset-coherence — lives once in the parent (radio-group.ts). This subclass buys
|
|
8
|
+
// only the tag IDENTITY (the T3 ruling's entire point) plus the two things ADR-0095 names as genuinely
|
|
9
|
+
// class-derived, both riding PROTECTED hooks the parent exposes for exactly this reuse:
|
|
10
|
+
//
|
|
11
|
+
// · `defaultOrientation()` (ADR-0095 clause 1) — this control defaults to a HORIZONTAL row (the parent
|
|
12
|
+
// base class defaults to 'vertical'). Resolved once at connect by the PARENT's `connected()`: an
|
|
13
|
+
// author-set `orientation` attribute still wins.
|
|
14
|
+
// · `selectionChanged(radios, index)` (ADR-0095 clause 2) — the moving-indicator state seam, renamed
|
|
15
|
+
// from ADR-0086's retired `--ui-radio-group-index`/`-count` to `--ui-segmented-control-index`/`-count`
|
|
16
|
+
// (the naming law: `--ui-{name}-*` is owned by the tag it's keyed to). Fired by the PARENT from all
|
|
17
|
+
// three sites its own doc comment names — connect (seed), every selection-apply (`#commit` AND the
|
|
18
|
+
// public `value` setter), and `formReset()` — so the seam tracks commit AND reset (the ADR-0086
|
|
19
|
+
// amendment this class inherits by construction: the call sites did not move).
|
|
20
|
+
//
|
|
21
|
+
// `#radios()` on the parent walks `instanceof UIRadioElement`, which `UISegmentElement` (below) satisfies
|
|
22
|
+
// by construction — no override needed for the group to find its own children. `role='radiogroup'` /
|
|
23
|
+
// `role='radio'`, roving-tabindex, `data-radio-group` group-detection: all INHERITED unchanged.
|
|
24
|
+
//
|
|
25
|
+
// `ui-segment extends UIRadioElement` (ADR-0095 clause 3, `controls/segment/segment.ts`): the naming win T3
|
|
26
|
+
// is about — a `ui-radio` child inside `<ui-segmented-control>` would leak "radio" into every consumer's
|
|
27
|
+
// markup. `radio.css`'s `@scope (ui-radio)` rules simply don't match the new tag (a feature — `ui-segment`
|
|
28
|
+
// needs no dot to suppress); it authors its own small CSS. `ui-segment` lives in its OWN sibling folder,
|
|
29
|
+
// NOT this one — the family-coherence naming trip-wire (`name === folder || name.startsWith(folder + '-')`,
|
|
30
|
+
// family-coherence.test.ts A4) accepts `radio-group` inside `radio/` (a real prefix match) but rejects
|
|
31
|
+
// `segment` inside `segmented-control/` (no prefix relationship: "segment" is not a prefix of "segmented-
|
|
32
|
+
// control", nor is "segmented-control-" a prefix of "segment") — a real constraint the radio/radio-group
|
|
33
|
+
// precedent's two-descriptors-one-folder shape cannot generalize to. `segmented-control.ts` imports
|
|
34
|
+
// `segment.ts` as a side effect below (the `ui-card`/`ui-tabs` compound precedent: a parent that REQUIRES
|
|
35
|
+
// its own sub-tag self-defines it too), so importing this ONE public entry self-defines both tags.
|
|
36
|
+
//
|
|
37
|
+
// Layer: controls/ — imports dom + controls/radio + controls/segment (inward-only ✓).
|
|
38
|
+
import { UIRadioGroupElement } from "../radio/radio-group.js";
|
|
39
|
+
import { UIRadioElement } from "../radio/radio.js";
|
|
40
|
+
import "../segment/segment.js"; // self-defines ui-segment — a segmented control is meaningless without it
|
|
41
|
+
export class UISegmentedControlElement extends UIRadioGroupElement {
|
|
42
|
+
/**
|
|
43
|
+
* ADR-0095 clause 1 — the class-derived default: a segmented control defaults to a HORIZONTAL row (the
|
|
44
|
+
* ADR-0086 "variant=segmented ⇒ horizontal" default, now class-derived instead of variant-derived). An
|
|
45
|
+
* author-set `orientation` attribute still wins (resolved by the PARENT's `connected()`).
|
|
46
|
+
*/
|
|
47
|
+
defaultOrientation() {
|
|
48
|
+
return 'horizontal';
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* ADR-0095 clause 2 — the moving-indicator state seam. Writes the selected index + segment count as host
|
|
52
|
+
* CUSTOM PROPERTIES (the `--value-pct` precedent, range-element.ts:111 / slider-multi.ts:196–197 —
|
|
53
|
+
* reactive STATE, never a stylesheet injection), read by `segmented-control.css`'s `::before` to size +
|
|
54
|
+
* translate the shared moving fill. `index < 0` (nothing selected) writes `0` — the indicator itself is
|
|
55
|
+
* hidden by CSS whenever no segment is `[checked]`, so the fallback position is irrelevant while hidden.
|
|
56
|
+
*/
|
|
57
|
+
selectionChanged(radios, index) {
|
|
58
|
+
this.style.setProperty('--ui-segmented-control-index', String(Math.max(0, index)));
|
|
59
|
+
this.style.setProperty('--ui-segmented-control-count', String(radios.length));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!customElements.get('ui-segmented-control')) {
|
|
63
|
+
customElements.define('ui-segmented-control', UISegmentedControlElement);
|
|
64
|
+
}
|