@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,251 @@
|
|
|
1
|
+
/* textarea.css — ui-textarea, the single-file component stylesheet (ADR-0003). Two clearly-SECTIONED
|
|
2
|
+
* blocks, mirroring text-field.css:
|
|
3
|
+
*
|
|
4
|
+
* [1] TOKEN BLOCK — `:where(ui-textarea)` (specificity 0,0,0) DECLARES the `--ui-textarea-*` chain from the
|
|
5
|
+
* colour roles (`--md-sys-color-{family}-{role}`; family = neutral, the text-field field-frame map reused
|
|
6
|
+
* verbatim) and the `--md-sys-font-{size}` dimensional ramp. The state channel is Kim's filled/container
|
|
7
|
+
* state law (TKT-0062) — THREE channels repoint per state (background, border, text-ink), keyed off
|
|
8
|
+
* five states (default/filled/hover/focus/disabled), the text-field precedent reused verbatim. `[size]`
|
|
9
|
+
* repoints ONLY the font — padding-block/padding-inline/the per-row line-box all DERIVE from font via
|
|
10
|
+
* calc(), so one repoint cascades through all three (ADR-0134's "[size] repoints font + block-padding +
|
|
11
|
+
* per-row line-box").
|
|
12
|
+
* [2] STYLES BLOCK — `@scope (ui-textarea)` CONSUMES only `--ui-textarea-*` for its OWN tokens (the one
|
|
13
|
+
* fleet exception: the shared focus-ring + motion constants, read DIRECTLY, the text-field precedent).
|
|
14
|
+
* ui-textarea declares its OWN multi-line geometry law (ADR-0134) — NOT the single-line Control-class
|
|
15
|
+
* `(scale × size) → §1-row` lookup ui-text-field rides (geometry.md / ADR-0038/0036): `min-block-size`
|
|
16
|
+
* is a GROWABLE minimum (`rows × line-box + 2·block-padding`), never a fixed height; real
|
|
17
|
+
* `padding-block` (never 0); top-left text placement via normal BLOCK flow — `display: block`, no
|
|
18
|
+
* `align-items` rule at all, deliberately (textarea-geometry.test.ts documents the choice; simpler
|
|
19
|
+
* than a flex `align-items: start` for a single block-axis child, same visual result); a prose
|
|
20
|
+
* `line-height` (never the single-line `line-height: 1`); `resize: vertical` (native `<textarea>`
|
|
21
|
+
* parity) + `overflow-y: auto`. The filled/container state ladder, `:focus-within` ring, forced-colors,
|
|
22
|
+
* and reduced-motion are inherited verbatim from the text-field precedent (the field-frame pattern is
|
|
23
|
+
* shape-independent — ADR-0134 "The multi-line geometry law").
|
|
24
|
+
*
|
|
25
|
+
* Standalone stylesheet — linked via the host page / component-styles barrel; NEVER injected from textarea.ts
|
|
26
|
+
* (behaviour-only `.ts`, no runtime style injection — plan §2).
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/* ════════════════ [1] TOKEN BLOCK — :where(ui-textarea) declares --ui-textarea-* ════════════════ */
|
|
30
|
+
|
|
31
|
+
:where(ui-textarea) {
|
|
32
|
+
/* Field-frame colour channel (family = neutral) — Kim's filled/container state law (TKT-0062),
|
|
33
|
+
SUPERSEDING the old border-only channel: THREE channels now repoint per state (background, border,
|
|
34
|
+
text-ink), keyed off five states — default (empty, idle) / filled (has a value, idle) / hover / focus /
|
|
35
|
+
disabled. user-invalid is UNCHANGED — its own border-only danger channel (below) layers on top of
|
|
36
|
+
whichever bg/ink this table already picked; it never touches bg. The text-field precedent reused
|
|
37
|
+
verbatim (a multi-line surface is the SAME entry-control kin as a single-line one, only the box shape
|
|
38
|
+
differs):
|
|
39
|
+
state | bg | border | ink
|
|
40
|
+
default | container-low | transparent | neutral
|
|
41
|
+
filled | container | transparent | on-surface-variant
|
|
42
|
+
hover | container | outline-variant | on-surface-variant
|
|
43
|
+
focus | container-low | transparent (ring)| on-surface
|
|
44
|
+
disabled | container-low | transparent | neutral-low
|
|
45
|
+
"filled" reads `[data-part='editor']:not([data-empty])` (the SAME emptiness signal the placeholder
|
|
46
|
+
::before already keys off) — see @scope's `:has()` selector below. Declared here, consumed at the
|
|
47
|
+
matching pseudo-/state selector in @scope (so @scope reads only --ui-textarea-*, never a role). */
|
|
48
|
+
--ui-textarea-bg: var(--md-sys-color-neutral-container-low); /* default */
|
|
49
|
+
--ui-textarea-bg-filled: var(--md-sys-color-neutral-container);
|
|
50
|
+
--ui-textarea-bg-hover: var(--md-sys-color-neutral-container);
|
|
51
|
+
--ui-textarea-bg-focus: var(--md-sys-color-neutral-container-low);
|
|
52
|
+
--ui-textarea-border: transparent; /* default — the ring is the interactive indicator, not the border */
|
|
53
|
+
--ui-textarea-border-hover: var(--md-sys-color-neutral-outline-variant); /* :hover — the ONE visible-border state */
|
|
54
|
+
--ui-textarea-border-focus: transparent; /* :focus-within — TRANSPARENT: the shared outline ring is the SOLE focus indicator (a --md-sys-color-focus-ring border-color step doubled with the ring into a visible double border; text-field ADR-0014 dev#1 precedent). Transparent holds the box geometry (the 1px frame still occupies its track — no layout shift). */
|
|
55
|
+
--ui-textarea-border-invalid: var(--md-sys-color-danger); /* :state(user-invalid) — UNCHANGED, orthogonal to the table above */
|
|
56
|
+
--ui-textarea-border-invalid-hover: var(--md-sys-color-danger-high); /* user-invalid + :hover — UNCHANGED */
|
|
57
|
+
--ui-textarea-ink: var(--md-sys-color-neutral); /* default — empty, idle (== the placeholder ink, below) */
|
|
58
|
+
--ui-textarea-ink-filled: var(--md-sys-color-neutral-on-surface-variant);
|
|
59
|
+
--ui-textarea-ink-hover: var(--md-sys-color-neutral-on-surface-variant);
|
|
60
|
+
--ui-textarea-ink-focus: var(--md-sys-color-neutral-on-surface);
|
|
61
|
+
--ui-textarea-placeholder: var(--ui-textarea-ink); /* tracks the SAME default-state ink role (Kim's table has no separate placeholder row) — re-resolves live off whatever --ui-textarea-ink cascades to for this element, so the disabled repoint below reaches it for free */
|
|
62
|
+
|
|
63
|
+
/* Geometry — the MULTI-LINE law (ADR-0134), not the single-line ramp. Font is the ONE sizing lever that
|
|
64
|
+
[size] repoints; padding-block/padding-inline/line-box all DERIVE from it via calc() below, so a single
|
|
65
|
+
repoint cascades through all three — the growable box has no fixed §1 height row. */
|
|
66
|
+
--ui-textarea-font: var(--md-sys-font-md);
|
|
67
|
+
--ui-textarea-line-height: 1.5; /* prose line-height — NEVER the single-line control's line-height:1 (geometry.md) */
|
|
68
|
+
--ui-textarea-line-box: calc(var(--ui-textarea-font) * var(--ui-textarea-line-height)); /* one rendered text row */
|
|
69
|
+
--ui-textarea-padding-block: calc(var(--ui-textarea-font) * 0.5); /* a comfortable text inset (ADR-0134) — never 0 */
|
|
70
|
+
--ui-textarea-padding-inline: calc(var(--ui-textarea-font) * 0.75);
|
|
71
|
+
--ui-textarea-rows: 3; /* the JS-set --ui-textarea-rows inline custom property overrides this per-instance (textarea.ts) */
|
|
72
|
+
--ui-textarea-min-block-size: calc(var(--ui-textarea-rows) * var(--ui-textarea-line-box) + 2 * var(--ui-textarea-padding-block));
|
|
73
|
+
|
|
74
|
+
/* Size-INVARIANT frame quantities — the entry-control class referents (geometry.md "Frame quantities that
|
|
75
|
+
split by control class"), the SAME fleet tokens ui-text-field's #71/#21 amendments introduced. */
|
|
76
|
+
--ui-textarea-radius: var(--md-sys-shape-corner-base); /* fixed rounded-rect — the container-fleet referent, not the action h/2 pill */
|
|
77
|
+
--ui-textarea-min-inline-size: 20ch; /* the entry-control typing-width floor (ADR-0021), native <textarea> parity */
|
|
78
|
+
|
|
79
|
+
/* Visible inline-validation message tokens (ADR-0029 A1, the text-field precedent) — the .ui-textarea-message
|
|
80
|
+
node (control-managed, aria-describedby target) becomes VISIBLE when non-empty under :state(user-invalid). */
|
|
81
|
+
--ui-textarea-message-font: var(--md-sys-font-sm);
|
|
82
|
+
--ui-textarea-message-ink: var(--md-sys-color-danger-on-surface-variant); /* AA-gated on-surface danger text ink */
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* size → the ONE sizing lever (font); padding-block/padding-inline/line-box all derive from it via calc() above. */
|
|
86
|
+
:where(ui-textarea[size='sm']) {
|
|
87
|
+
--ui-textarea-font: var(--md-sys-font-sm);
|
|
88
|
+
}
|
|
89
|
+
:where(ui-textarea[size='lg']) {
|
|
90
|
+
--ui-textarea-font: var(--md-sys-font-lg);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* disabled → a role-REPOINT (NOT opacity, tokens.md canon; TKT-0062's disabled row). Matches BOTH the
|
|
94
|
+
own/reflected [disabled] AND the effective :state(disabled) (own || form-disabled). Declared LAST so it
|
|
95
|
+
wins the specificity-0 cascade for the BASE `--ui-textarea-{bg,border,ink}` tokens the unconditional
|
|
96
|
+
`:scope` rule reads. Only the base trio needs repointing — @scope's `filled`/`hover` selectors are
|
|
97
|
+
explicitly guarded with `:not(:is([disabled], :state(disabled)))` (a genuinely new hazard the old
|
|
98
|
+
border-only law never had: "filled" is a content-based `:has()` selector, not an interaction
|
|
99
|
+
pseudo-class, so it WOULD still match a disabled-but-non-empty field without that guard — unlike
|
|
100
|
+
`:hover`/`:focus-within`, which a pointer-inert, non-focusable disabled host can never really trigger).
|
|
101
|
+
user-invalid cannot co-occur (a disabled textarea does not willValidate — textarea.ts gates it), so the
|
|
102
|
+
danger border is left untouched. The text-field precedent reused verbatim. */
|
|
103
|
+
:where(ui-textarea:is([disabled], :state(disabled))) {
|
|
104
|
+
--ui-textarea-bg: var(--md-sys-color-neutral-container-low);
|
|
105
|
+
--ui-textarea-border: transparent;
|
|
106
|
+
--ui-textarea-ink: var(--md-sys-color-neutral-low);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* ════════════════ [2] STYLES BLOCK — @scope (ui-textarea) consumes ONLY --ui-textarea-* ════════════════ */
|
|
110
|
+
|
|
111
|
+
@scope (ui-textarea) {
|
|
112
|
+
:scope {
|
|
113
|
+
display: block; /* no adornment slots (ADR-0134: no leading/trailing machinery) — the host IS the resizable box */
|
|
114
|
+
box-sizing: border-box;
|
|
115
|
+
|
|
116
|
+
/* the MULTI-LINE geometry law (ADR-0134) — a GROWABLE minimum, never a fixed §1-row height. */
|
|
117
|
+
min-block-size: var(--ui-textarea-min-block-size);
|
|
118
|
+
min-inline-size: var(--ui-textarea-min-inline-size); /* the entry-control typing-width floor (ADR-0021 parity) */
|
|
119
|
+
padding-block: var(--ui-textarea-padding-block); /* REAL block padding — the inversion of the single-line law's 0 */
|
|
120
|
+
padding-inline: var(--ui-textarea-padding-inline);
|
|
121
|
+
overflow-y: auto; /* content past min-block-size scrolls rather than growing the box unbounded */
|
|
122
|
+
resize: vertical; /* native <textarea> parity — user-draggable (requires overflow != visible, satisfied above) */
|
|
123
|
+
|
|
124
|
+
font-size: var(--ui-textarea-font);
|
|
125
|
+
line-height: var(--ui-textarea-line-height); /* prose line-height — NEVER the single-line control's line-height:1 */
|
|
126
|
+
background: var(--ui-textarea-bg);
|
|
127
|
+
color: var(--ui-textarea-ink);
|
|
128
|
+
|
|
129
|
+
border: 1px solid var(--ui-textarea-border);
|
|
130
|
+
border-radius: var(--ui-textarea-radius);
|
|
131
|
+
cursor: text;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
:scope > [data-part='editor'] {
|
|
135
|
+
display: block;
|
|
136
|
+
min-inline-size: 0;
|
|
137
|
+
min-block-size: 100%;
|
|
138
|
+
font-size: var(--ui-textarea-font);
|
|
139
|
+
line-height: var(--ui-textarea-line-height);
|
|
140
|
+
color: var(--ui-textarea-ink);
|
|
141
|
+
outline: none; /* the focus ring is on the HOST frame, never the editor child */
|
|
142
|
+
white-space: pre-wrap; /* multi-line — newlines + wrapping both render (the ADR-0134 inversion of nowrap) */
|
|
143
|
+
overflow-wrap: break-word;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* the placeholder — a control-toggled `data-empty` attr keys generated content (the text-field precedent
|
|
147
|
+
verbatim; NOT `:empty` — a cleared contenteditable can carry a bogus trailing <br>, ADR-0014). */
|
|
148
|
+
:scope > [data-part='editor'][data-empty]::before {
|
|
149
|
+
content: attr(data-placeholder);
|
|
150
|
+
color: var(--ui-textarea-placeholder);
|
|
151
|
+
pointer-events: none;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* The filled/container state ladder (TKT-0062, Kim's ruling — supersedes the old border-only channel,
|
|
155
|
+
the text-field precedent reused verbatim) — repoints `background`/`border-color`/`color` together
|
|
156
|
+
from the per-state tokens declared in the :where() block (the geometry law is untouched). "filled" =
|
|
157
|
+
the editor carries a value (`:not([data-empty])`, the SAME emptiness signal the placeholder ::before
|
|
158
|
+
already keys off) — a CONTENT-based selector, not an interaction pseudo-class, so unlike :hover/
|
|
159
|
+
:focus-within it WOULD still match a disabled-but-non-empty field.
|
|
160
|
+
|
|
161
|
+
Precedence is enforced by MUTUAL EXCLUSION (`:not()`), not source-order/specificity: `:has()`/
|
|
162
|
+
`:not()` combinators contribute REAL specificity in a plain (non-:where()) selector — unlike the old
|
|
163
|
+
border-only law's bare single-pseudo-class rules, source order alone can no longer be trusted to pick
|
|
164
|
+
a winner (a `:not(:is(disabled))`-guarded `:hover` was measured to OUTRANK an unguarded
|
|
165
|
+
`:focus-within` by specificity in ui-text-field, so clicking to focus — which also leaves the pointer
|
|
166
|
+
hovering — kept the hover border instead of stepping transparent; a live regression this exact history
|
|
167
|
+
was caught fixing). Making each rule EXPLICITLY exclude every state that should outrank it removes the
|
|
168
|
+
ambiguity regardless of computed specificity: filled excludes hover/focus/disabled; hover excludes
|
|
169
|
+
focus/disabled; focus is checked last and excludes nothing (a disabled field is never focusable, so no
|
|
170
|
+
guard is needed there, matching the old law). user-invalid's border-only override still layers on top
|
|
171
|
+
of whichever bg/ink row above resolved, untouched. */
|
|
172
|
+
/* NOTE (code-reviewer HIGH finding, fixed — the text-field.css precedent): repointing the
|
|
173
|
+
--ui-textarea-ink TOKEN itself here, NOT a direct color: declaration on :scope — the editor part
|
|
174
|
+
carries its own color declaration reading that same token, so a host-only color: override never
|
|
175
|
+
reached the visible typed text or the placeholder (proven red in a real browser gate before this
|
|
176
|
+
fix). Repointing the token cascades to every consumer for free. */
|
|
177
|
+
:scope:not(:hover):not(:focus-within):not(:is([disabled], :state(disabled))):has(> [data-part='editor']:not([data-empty])) {
|
|
178
|
+
background: var(--ui-textarea-bg-filled);
|
|
179
|
+
--ui-textarea-ink: var(--ui-textarea-ink-filled);
|
|
180
|
+
}
|
|
181
|
+
:scope:not(:focus-within):not(:is([disabled], :state(disabled))):hover {
|
|
182
|
+
background: var(--ui-textarea-bg-hover);
|
|
183
|
+
border-color: var(--ui-textarea-border-hover);
|
|
184
|
+
--ui-textarea-ink: var(--ui-textarea-ink-hover);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Focus (the text-field ADR-0014 dev#1 precedent, reused verbatim) — the shared `outline` ring is the
|
|
188
|
+
SOLE interactive-frame indicator; the frame border steps to TRANSPARENT (a colour-step border here
|
|
189
|
+
would double with the ring). :focus-within (ALL focus, native text-input parity), not :focus-visible —
|
|
190
|
+
the focusable element is the editor child. Focus's bg/ink (TKT-0062) override filled/hover
|
|
191
|
+
unconditionally — a focused-and-filled field still shows the FOCUS row (container-low bg, on-surface
|
|
192
|
+
ink), not filled's. A disabled field is never focusable, so no guard is needed here (matching the old
|
|
193
|
+
law). */
|
|
194
|
+
:scope:focus-within {
|
|
195
|
+
background: var(--ui-textarea-bg-focus);
|
|
196
|
+
border-color: var(--ui-textarea-border-focus);
|
|
197
|
+
--ui-textarea-ink: var(--ui-textarea-ink-focus);
|
|
198
|
+
outline: var(--md-sys-state-focus-ring-width) solid var(--md-sys-color-focus-ring);
|
|
199
|
+
outline-offset: var(--md-sys-state-focus-ring-offset);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
:scope:state(user-invalid) {
|
|
203
|
+
border-color: var(--ui-textarea-border-invalid);
|
|
204
|
+
}
|
|
205
|
+
:scope:state(user-invalid):hover {
|
|
206
|
+
border-color: var(--ui-textarea-border-invalid-hover);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* Visible inline-validation message (ADR-0029 A1, the text-field precedent verbatim). */
|
|
210
|
+
:scope:state(user-invalid) > .ui-textarea-message {
|
|
211
|
+
display: block;
|
|
212
|
+
font-size: var(--ui-textarea-message-font);
|
|
213
|
+
color: var(--ui-textarea-message-ink);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
:scope:is([disabled], :state(disabled)) {
|
|
217
|
+
pointer-events: none;
|
|
218
|
+
cursor: default;
|
|
219
|
+
resize: none; /* a disabled surface is not user-resizable */
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* Motion (ADR-0008 / interaction-states standard, reused verbatim) — state-PAINT properties only, never
|
|
223
|
+
geometry (a resize/rows change must SNAP). Gated behind :state(ready), zeroed under reduced-motion. */
|
|
224
|
+
:scope:state(ready) {
|
|
225
|
+
transition:
|
|
226
|
+
border-color var(--md-sys-motion-duration-fast) var(--md-sys-motion-easing-standard),
|
|
227
|
+
background-color var(--md-sys-motion-duration-fast) var(--md-sys-motion-easing-standard),
|
|
228
|
+
color var(--md-sys-motion-duration-fast) var(--md-sys-motion-easing-standard);
|
|
229
|
+
}
|
|
230
|
+
@media (prefers-reduced-motion: reduce) {
|
|
231
|
+
:scope:state(ready) {
|
|
232
|
+
transition: none;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* forced-colors — keep the frame border + ink + placeholder VISIBLE (the text-field precedent verbatim).
|
|
237
|
+
The focus ring survives for free via --md-sys-color-focus-ring → Highlight. */
|
|
238
|
+
@media (forced-colors: active) {
|
|
239
|
+
:scope {
|
|
240
|
+
border-color: CanvasText;
|
|
241
|
+
color: CanvasText;
|
|
242
|
+
}
|
|
243
|
+
:scope > [data-part='editor'][data-empty]::before {
|
|
244
|
+
color: CanvasText;
|
|
245
|
+
}
|
|
246
|
+
:scope:is([disabled], :state(disabled)) {
|
|
247
|
+
border-color: GrayText;
|
|
248
|
+
color: GrayText;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { type ReactiveProps } from '../../dom/index.js';
|
|
2
|
+
import { UIFormElement, type FormValue, type ValidityResult, type FieldLabelling } from '../../dom/form.js';
|
|
3
|
+
declare const props: {
|
|
4
|
+
value: import("../../index.js").PropConfig<string>;
|
|
5
|
+
label: {
|
|
6
|
+
reflect: true;
|
|
7
|
+
type: import("../../index.js").PropType<string>;
|
|
8
|
+
default: string;
|
|
9
|
+
attribute?: string | false;
|
|
10
|
+
};
|
|
11
|
+
placeholder: import("../../index.js").PropConfig<string>;
|
|
12
|
+
rows: {
|
|
13
|
+
reflect: true;
|
|
14
|
+
type: import("../../index.js").PropType<number | null>;
|
|
15
|
+
default: number | null;
|
|
16
|
+
attribute?: string | false;
|
|
17
|
+
};
|
|
18
|
+
size: {
|
|
19
|
+
reflect: true;
|
|
20
|
+
type: import("../../index.js").PropType<"sm" | "md" | "lg">;
|
|
21
|
+
default: "sm" | "md" | "lg";
|
|
22
|
+
attribute?: string | false;
|
|
23
|
+
};
|
|
24
|
+
readonly: {
|
|
25
|
+
reflect: true;
|
|
26
|
+
type: import("../../index.js").PropType<boolean>;
|
|
27
|
+
default: boolean;
|
|
28
|
+
attribute?: string | false;
|
|
29
|
+
};
|
|
30
|
+
name: {
|
|
31
|
+
reflect: true;
|
|
32
|
+
type: import("../../index.js").PropType<string>;
|
|
33
|
+
default: string;
|
|
34
|
+
attribute?: string | false;
|
|
35
|
+
};
|
|
36
|
+
disabled: {
|
|
37
|
+
reflect: true;
|
|
38
|
+
type: import("../../index.js").PropType<boolean>;
|
|
39
|
+
default: boolean;
|
|
40
|
+
attribute?: string | false;
|
|
41
|
+
};
|
|
42
|
+
required: {
|
|
43
|
+
reflect: true;
|
|
44
|
+
type: import("../../index.js").PropType<boolean>;
|
|
45
|
+
default: boolean;
|
|
46
|
+
attribute?: string | false;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
export interface UITextareaElement extends ReactiveProps<typeof props> {
|
|
50
|
+
}
|
|
51
|
+
export declare class UITextareaElement extends UIFormElement {
|
|
52
|
+
#private;
|
|
53
|
+
static props: {
|
|
54
|
+
value: import("../../index.js").PropConfig<string>;
|
|
55
|
+
label: {
|
|
56
|
+
reflect: true;
|
|
57
|
+
type: import("../../index.js").PropType<string>;
|
|
58
|
+
default: string;
|
|
59
|
+
attribute?: string | false;
|
|
60
|
+
};
|
|
61
|
+
placeholder: import("../../index.js").PropConfig<string>;
|
|
62
|
+
rows: {
|
|
63
|
+
reflect: true;
|
|
64
|
+
type: import("../../index.js").PropType<number | null>;
|
|
65
|
+
default: number | null;
|
|
66
|
+
attribute?: string | false;
|
|
67
|
+
};
|
|
68
|
+
size: {
|
|
69
|
+
reflect: true;
|
|
70
|
+
type: import("../../index.js").PropType<"sm" | "md" | "lg">;
|
|
71
|
+
default: "sm" | "md" | "lg";
|
|
72
|
+
attribute?: string | false;
|
|
73
|
+
};
|
|
74
|
+
readonly: {
|
|
75
|
+
reflect: true;
|
|
76
|
+
type: import("../../index.js").PropType<boolean>;
|
|
77
|
+
default: boolean;
|
|
78
|
+
attribute?: string | false;
|
|
79
|
+
};
|
|
80
|
+
name: {
|
|
81
|
+
reflect: true;
|
|
82
|
+
type: import("../../index.js").PropType<string>;
|
|
83
|
+
default: string;
|
|
84
|
+
attribute?: string | false;
|
|
85
|
+
};
|
|
86
|
+
disabled: {
|
|
87
|
+
reflect: true;
|
|
88
|
+
type: import("../../index.js").PropType<boolean>;
|
|
89
|
+
default: boolean;
|
|
90
|
+
attribute?: string | false;
|
|
91
|
+
};
|
|
92
|
+
required: {
|
|
93
|
+
reflect: true;
|
|
94
|
+
type: import("../../index.js").PropType<boolean>;
|
|
95
|
+
default: boolean;
|
|
96
|
+
attribute?: string | false;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
protected connected(): void;
|
|
100
|
+
protected disconnected(): void;
|
|
101
|
+
/** Forward host focus to the editor PART (label-association + native `.focus()` parity). */
|
|
102
|
+
focus(options?: FocusOptions): void;
|
|
103
|
+
/**
|
|
104
|
+
* Focus the editor and move the caret to the END of its text (a `ui-textarea`-friendly equivalent of the
|
|
105
|
+
* native `<textarea>.setSelectionRange(len, len)` a contenteditable host does not expose — the ADR-0134
|
|
106
|
+
* migration seam `entry-list.ts` uses to restore an in-progress edit after a re-render). A no-op before
|
|
107
|
+
* the editor part exists (guards a not-yet-connected control, mirroring `focus()`'s own guard above).
|
|
108
|
+
*/
|
|
109
|
+
selectToEnd(): void;
|
|
110
|
+
/** The value contributed to the owning form (FACE — the base publishes it via internals.setFormValue). */
|
|
111
|
+
protected formValue(): FormValue;
|
|
112
|
+
/**
|
|
113
|
+
* The validity verdict: `required && value === ''` → `valueMissing`; valid otherwise. No codec/type
|
|
114
|
+
* validation — plain multi-line text has no value-shape to mismatch (ADR-0134). A disabled field is barred
|
|
115
|
+
* from constraint validation (native parity).
|
|
116
|
+
*/
|
|
117
|
+
protected formValidity(): ValidityResult;
|
|
118
|
+
/**
|
|
119
|
+
* Form reset → value ← the initial `value` attribute (native-parity defaultValue) + clear the touched
|
|
120
|
+
* state (so a required-empty field does not show `:state(user-invalid)` until the user re-interacts).
|
|
121
|
+
*/
|
|
122
|
+
protected formReset(): void;
|
|
123
|
+
/** Restore the value after navigation/autofill (FACE state restore). */
|
|
124
|
+
protected formStateRestore(state: File | string | FormData | null): void;
|
|
125
|
+
/**
|
|
126
|
+
* The part-role override (ADR-0051 cl.2) — the editor's `role=textbox` rides a light-DOM PART, not
|
|
127
|
+
* `internals.role`, so the base's guarded internals-reflection default never fires here; id-reference the
|
|
128
|
+
* editor directly instead. See text-field.ts's own doc for the full ordering rationale (reused verbatim —
|
|
129
|
+
* `aria-describedby` is only WRITTEN here on association; on dissociation the user-invalid/message effect
|
|
130
|
+
* above stays the exclusive owner, avoiding a two-effect write race).
|
|
131
|
+
*/
|
|
132
|
+
protected applyFieldLabelling(refs: FieldLabelling | null): void;
|
|
133
|
+
/** Feeds `FormConnectDetail.userInvalid` (ADR-0050) — the `trackUserInvalid` tracker IS the timing source. */
|
|
134
|
+
protected formUserInvalid(): boolean;
|
|
135
|
+
}
|
|
136
|
+
export {};
|