@adia-ai/web-components 0.5.12 → 0.5.14
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/CHANGELOG.md +117 -0
- package/color/index.d.ts +16 -0
- package/color/index.js +61 -8
- package/components/action-list/action-list.css +1 -1
- package/components/calendar-picker/calendar-picker.css +1 -1
- package/components/chat-thread/chat-input.css +3 -3
- package/components/check/check.css +1 -1
- package/components/color-input/class.js +42 -7
- package/components/color-input/color-input.a2ui.json +46 -0
- package/components/color-input/color-input.d.ts +16 -0
- package/components/color-input/color-input.yaml +43 -0
- package/components/heatmap/class.js +4 -0
- package/components/input/input.css +3 -3
- package/components/menu/menu.css +2 -2
- package/components/nav-group/nav-group.css +6 -6
- package/components/option-card/option-card.css +2 -1
- package/components/otp-input/class.js +4 -1
- package/components/otp-input/otp-input.a2ui.json +9 -0
- package/components/otp-input/otp-input.d.ts +3 -0
- package/components/otp-input/otp-input.yaml +6 -0
- package/components/pagination/pagination.css +3 -1
- package/components/radio/radio.css +1 -1
- package/components/search/class.js +2 -0
- package/components/search/search.a2ui.json +9 -0
- package/components/search/search.d.ts +2 -0
- package/components/search/search.yaml +6 -0
- package/components/segment/segment.css +3 -3
- package/components/select/select.css +10 -9
- package/components/swatch/class.js +20 -0
- package/components/swatch/swatch.a2ui.json +4 -1
- package/components/swatch/swatch.yaml +14 -1
- package/components/switch/switch.css +1 -1
- package/components/tabs/tabs.css +1 -1
- package/components/textarea/textarea.css +6 -2
- package/components/upload/upload.css +2 -1
- package/package.json +9 -1
- package/styles/typography.css +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,123 @@ runtime ships in the sibling `@adia-ai/a2ui-runtime` package
|
|
|
11
11
|
|
|
12
12
|
_No pending changes._
|
|
13
13
|
|
|
14
|
+
## [0.5.14] - 2026-05-15
|
|
15
|
+
|
|
16
|
+
### v0.5.14 — Form-control hover-fg token unification (precursor to §315; commit `178418525`)
|
|
17
|
+
|
|
18
|
+
Form-control primitives diverged on hover-text token routing. `button-ui` correctly used `--a-ui-text-hover` (resolves to `--a-fg-strong` — canonical hover-lift for form-control text); every other form-control primitive used the generic `--a-fg` (no actual lift from default `--a-canvas-text`) — so "hover" had zero text-color effect on `input`/`textarea`/`segment`, and `select-ui`'s listbox/caret hover paths bypassed the `--select-*` token layer entirely with raw `--a-fg-*` references.
|
|
19
|
+
|
|
20
|
+
#### Fixed — `components/{input,textarea,segment,select}/`
|
|
21
|
+
|
|
22
|
+
- `input-ui`: `--input-fg-hover: var(--a-fg)` → `var(--a-ui-text-hover)`; `--input-affix-fg-hover: var(--a-fg-subtle)` → `var(--a-ui-text-subtle)`.
|
|
23
|
+
- `textarea-ui`: matching routing on hover/affix-hover.
|
|
24
|
+
- `segment-ui`: same routing change.
|
|
25
|
+
- `select-ui`: listbox + caret + option-hover tokens previously raw `--a-fg-*` references now route through their `--select-*` semantic layer (which itself anchors at `--a-ui-text-*` family).
|
|
26
|
+
|
|
27
|
+
Net effect: hover-text colors now consistent across all form-control primitives + theme designers can swap them all by changing one semantic token (`--a-ui-text-hover`) at the `--a-ui-*` family root in `semantics.css`.
|
|
28
|
+
|
|
29
|
+
### v0.5.14 §315 — Drift-class sweep follow-up (`ui-audit-coherence` + `maintain-tokens` + `analyze-css` triple-pass)
|
|
30
|
+
|
|
31
|
+
Three parallel skill-driven audits surfaced 7 mechanical drift-classes; landed as a single sweep in one commit (`025a981db`). Follow-up to the form-control hover-fg unification at `178418525` — same bug shape (component CSS bypassing its own semantic-layer routing through raw global tokens), broader scope.
|
|
32
|
+
|
|
33
|
+
#### Fixed — `components/select/`, `components/nav-group/`, `components/chat-thread/chat-input.css`
|
|
34
|
+
|
|
35
|
+
- `select.css:254,286,293,300` — 4 raw `var(--a-fg-*)` callsites routed through `--select-fg-{muted,fg,muted,muted}` (semantic layer already existed but was bypassed).
|
|
36
|
+
- `nav-group.css:225,234,244,253,286,298` — 6 raw `var(--a-fg-{muted,subtle,strong})` callsites routed through `--nav-group-fg-{muted,muted,hover,selected,muted,muted}`.
|
|
37
|
+
- `chat-input.css:40,50,58` — placeholder/hover/disabled tokens routed through the canonical `--a-ui-text-{placeholder,hover,disabled}` field-family chain instead of the generic `--a-fg-*` family. Continues the v0.5.13 hover-fg unification arc.
|
|
38
|
+
|
|
39
|
+
#### Fixed — `components/{check,radio,switch,tabs,action-list,calendar-picker,menu}/`
|
|
40
|
+
|
|
41
|
+
- 6 form-adjacent primitives' `--{comp}-fg-disabled` token routed through canonical `--a-ui-text-disabled` instead of `--a-fg-muted` (the disabled-text version of the v0.5.13 hover-fg drift class).
|
|
42
|
+
- `menu.css:96,99` also fixed `--menu-item-fg-disabled` + `--menu-item-icon-disabled` (the third variant `--a-fg-disabled` shape; same canonical target).
|
|
43
|
+
|
|
44
|
+
#### Added — `components/otp-input/`, `components/search/`
|
|
45
|
+
|
|
46
|
+
- `<otp-input-ui>` + `<search-ui>` now dispatch `change` alongside `input` on every value-altering event. Both primitives previously emitted only `input` (the sole exceptions across all UIFormElement-bearing primitives). Closes consumer event-binding gap — `@change=${handler}` now works against every form-bearing tag uniformly.
|
|
47
|
+
- `.d.ts` files gain `OtpInputChangeEvent` + `SearchChangeEvent` type exports (reuse existing detail interfaces; matches v0.5.10 `check-form-bearing-dts` audit convention).
|
|
48
|
+
- yaml `events:` blocks declare the new `change` event with `detail.value`.
|
|
49
|
+
|
|
50
|
+
#### Fixed — `styles/typography.css`
|
|
51
|
+
|
|
52
|
+
- `:where(mark)` background reference fixed: `var(--a-highlight-default)` → `var(--a-highlight)` (`--a-highlight-default` token does not exist; pre-fix `<mark>` silently fell back to UA-default highlight). Single-line typo discovered via `maintain-tokens` skill sweep.
|
|
53
|
+
|
|
54
|
+
#### Fixed — `components/{textarea,upload,option-card,pagination}/` transition consistency
|
|
55
|
+
|
|
56
|
+
- `textarea.css:76` transition list expanded from `border-color` only → `background + border-color + color + box-shadow` (matches `input-ui`'s 4-property parity; pre-fix hover/focus slammed in instead of easing).
|
|
57
|
+
- `upload.css:64-67` + `option-card.css:102-104` + `pagination.css:71-73` each gain `box-shadow` (and `border-color` for pagination) so focus-ring eases in alongside the other state changes. Cross-primitive hover/focus polish parity restored.
|
|
58
|
+
|
|
59
|
+
#### Fixed — `components/input/`, `components/select/` `-active` token routing
|
|
60
|
+
|
|
61
|
+
- `--input-fg-focus: var(--a-fg-strong)` → `var(--a-ui-text-active)` (closes orphan: `--a-ui-text-active` semantic-layer alias existed at `semantics.css:552` with zero consumers).
|
|
62
|
+
- `--select-option-fg-active: var(--a-fg)` → `var(--a-ui-text-active)` (same routing; cross-primitive form-control consistency).
|
|
63
|
+
|
|
64
|
+
#### Fixed — `components/heatmap/`
|
|
65
|
+
|
|
66
|
+
- `class.js:disconnected()` now cancels `#raf` via `cancelAnimationFrame()`. Pre-fix the `requestAnimationFrame` handle was stored but never cleaned up on detach — minor memory leak in scroll-heavy demos. ~3 LOC.
|
|
67
|
+
|
|
68
|
+
## [0.5.13] - 2026-05-15
|
|
69
|
+
|
|
70
|
+
### v0.5.13 §310 — `apcaContrast` soft-clamp constant fix (FEEDBACK-35; P2 correctness)
|
|
71
|
+
|
|
72
|
+
`@adia-ai/web-components/color`'s `apcaContrast()` was using `APCA_LO_CLAMP = 0.06` for the soft-clamp threshold where the canonical APCA spec (`apca-w3@0.1.9`'s `SAPC_BLACK_THRESHOLD`) calls for `0.022`. The cubic-root soft-clamp `Math.pow(threshold - Y, 1.414)` operating on the wrong threshold lifted near-black luminance too aggressively. Pre-fix `apcaContrast('#000','#fff')` returned 99.49; post-fix returns 106.04 — matches canonical reference within ±0.01 Lc across all 8 reference pairs. Consumers using `<swatch-ui auto-contrast>` (which transitively calls `pickContrastingFg → apcaContrast`) silently got wrong contrast verdicts for any swatch with `Y < 0.06`.
|
|
73
|
+
|
|
74
|
+
#### Fixed — `color/`
|
|
75
|
+
|
|
76
|
+
- `color/index.js` `apcaContrast()` soft-clamp now uses `APCA_LO_FG`/`APCA_LO_BG = 0.022` (declared correctly since v0.5.12 but never read). Dead constants (`APCA_NORM_L`, `APCA_REVERSE_FACTOR`, `APCA_NORM_FACTOR`, `APCA_LO_CLAMP`, `APCA_RESCALE`) removed; new `APCA_BLACK_CLAMP = 1.414` factored out for readability.
|
|
77
|
+
|
|
78
|
+
### v0.5.13 §311 — `@adia-ai/web-components/color` P3 helpers (FEEDBACK-31)
|
|
79
|
+
|
|
80
|
+
`@adia-ai/web-components/color` (v0.5.12 §301) shipped sRGB-only gamut helpers; the v0.6.0 §301 plan-doc spec lines 121-126 committed both sRGB AND Display-P3. v0.5.13 §311 closes the gap.
|
|
81
|
+
|
|
82
|
+
#### Added — `color/`
|
|
83
|
+
|
|
84
|
+
- `inP3Gamut(L, C, H): boolean` — returns true if the OKLCH triple is inside Display-P3 gamut (tolerance `0.001`).
|
|
85
|
+
- `gamutMapChromaP3(L, C, H): number` — 8-iteration chroma bisection in P3 (matches `gamutMapChroma`'s shape).
|
|
86
|
+
- Internal `linearSrgbToLinearP3()` matrix sourced from CSS Color 4 § 12.3 (D65 → D65; no Bradford chromatic adaptation needed).
|
|
87
|
+
- `color/index.d.ts` ships matching declarations.
|
|
88
|
+
|
|
89
|
+
### v0.5.13 §312 — `<stat-ui>` explicit exports map entries (FEEDBACK-32)
|
|
90
|
+
|
|
91
|
+
v0.5.12 §253a hand-authored `stat-ui.d.ts` on disk but the package.json wildcard `./components/*` expanded `./components/stat` → `./components/stat/stat.js` (non-existent; actual file is `stat-ui.js`). Consumer TS imports failed at the package-export layer with `TS2882` even though the file exists + Vite resolved at runtime.
|
|
92
|
+
|
|
93
|
+
#### Changed — `package.json`
|
|
94
|
+
|
|
95
|
+
- `exports` map adds 2 explicit entries: `./components/stat` + `./components/stat/stat-ui.js` both pointing at `stat-ui.{d.ts,js}`.
|
|
96
|
+
- **Drops at v0.6.0 §303** when the `git mv stat-ui.{js,css,d.ts} → stat.{js,css,d.ts}` rename normalizes the filename + the wildcard naturally covers `stat.{js,d.ts}`.
|
|
97
|
+
|
|
98
|
+
### v0.5.13 §313 — `<color-input-ui>` constraint pass-through + parsed-detail forwarding (FEEDBACK-33)
|
|
99
|
+
|
|
100
|
+
`<color-input-ui>` (v0.5.12 §302) composed `<color-picker-ui>` but dropped 5 generation-constraint props (`maxChroma` / `maxL` / `minL` / `hueDriftMax` / `baseHue`) and 3 parsed-OKLCH-channel-scalars (`{l, c, h}`) from the re-emitted event detail. Consumers using L-range constraints or OKLCH-native logic (Tokens Studio's `defaults.Lmin`/`Lmax`) couldn't migrate to `<color-input-ui>` without a UX regression.
|
|
101
|
+
|
|
102
|
+
#### Added — `components/color-input/`
|
|
103
|
+
|
|
104
|
+
- `class.js` adds 5 generation-constraint props to `static properties` + sets them on inner picker at `#mount()` + diff-detect re-set on `render()` (Object.is handles NaN-equality for `baseHue`/`hueDriftMax`).
|
|
105
|
+
- `#commit()` re-emits with all 6 detail fields including parsed scalars `l: detail.l, c: detail.c, h: detail.h`.
|
|
106
|
+
- `color-input.yaml` declares the 5 props + 3 new detail fields per `change`/`input` events.
|
|
107
|
+
- `color-input.d.ts` `ColorInputChangeEventDetail` interface gains `l: number; c: number; h: number;` fields; class gains 5 typed prop declarations.
|
|
108
|
+
|
|
109
|
+
### v0.5.13 §314 — `<swatch-ui>` `[slot="chrome"]` named slot (FEEDBACK-34)
|
|
110
|
+
|
|
111
|
+
`<swatch-ui>`'s `#stamp()` lifecycle wiped `innerHTML` then funneled surviving children into `#labelEl`. Consumer chrome positioned absolutely against the swatch tile (gamut badges + override/tracked dots per C1.3 dogfood) landed inside the label's text bbox where `position: absolute; top/right/bottom/left` anchored to the small label geometry instead of the tile. v0.5.13 §314 adds a `[slot="chrome"]` named slot whose children survive stamping as direct host siblings of `#tileEl`.
|
|
112
|
+
|
|
113
|
+
#### Added — `components/swatch/`
|
|
114
|
+
|
|
115
|
+
- `class.js` `#stamp()` extracts `[slot="chrome"]` children BEFORE the wipe; re-attaches them as direct host siblings IMMEDIATELY after `#tileEl`. The host's `position: relative` anchor (when `shape="block"`) lets consumer absolute-positioning anchor to the tile's geometry.
|
|
116
|
+
- `swatch.yaml` `slots:` block declares the `chrome` named slot + clarifies `default` slot's funnel-into-label behavior.
|
|
117
|
+
|
|
118
|
+
#### Migration
|
|
119
|
+
|
|
120
|
+
```diff
|
|
121
|
+
<swatch-ui shape="block" label-position="overlay" selectable>
|
|
122
|
+
- <badge-ui class="dts-gamut-badge" ...>P3</badge-ui>
|
|
123
|
+
- <span class="dts-override-dot"></span>
|
|
124
|
+
+ <badge-ui slot="chrome" class="dts-gamut-badge" ...>P3</badge-ui>
|
|
125
|
+
+ <span slot="chrome" class="dts-override-dot"></span>
|
|
126
|
+
</swatch-ui>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Single `slot="chrome"` attribute on each chrome element. Existing absolute-positioning CSS unchanged.
|
|
130
|
+
|
|
14
131
|
## [0.5.12] - 2026-05-15
|
|
15
132
|
|
|
16
133
|
### v0.5.12 §252 — `package.json` `files` array completion (FB-28 close-out)
|
package/color/index.d.ts
CHANGED
|
@@ -87,6 +87,22 @@ export function isOklchInGamut(L: number, C: number, H: number): boolean;
|
|
|
87
87
|
*/
|
|
88
88
|
export function gamutMapChroma(L: number, C: number, H: number): number;
|
|
89
89
|
|
|
90
|
+
// ── Display-P3 gamut (v0.5.13 §-TBD, FB-31) ──────────────────────────────
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Returns true if the OKLCH triple is inside Display-P3 gamut (tolerance
|
|
94
|
+
* `0.001`). sRGB-linear → P3-linear conversion uses the CSS Color 4 § 12.3
|
|
95
|
+
* matrix (D65 → D65; no Bradford adaptation needed).
|
|
96
|
+
*/
|
|
97
|
+
export function inP3Gamut(L: number, C: number, H: number): boolean;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Bisect chroma to find the largest value that keeps `(L, _, H)` in
|
|
101
|
+
* Display-P3 gamut. 8 bisection iterations — same shape as the sRGB
|
|
102
|
+
* `gamutMapChroma`. Used by P3-aware design tooling.
|
|
103
|
+
*/
|
|
104
|
+
export function gamutMapChromaP3(L: number, C: number, H: number): number;
|
|
105
|
+
|
|
90
106
|
// ── APCA (advanced perceptual contrast algorithm) ─────────────────────────
|
|
91
107
|
|
|
92
108
|
/**
|
package/color/index.js
CHANGED
|
@@ -154,15 +154,67 @@ export function gamutMapChroma(L, C, H) {
|
|
|
154
154
|
return lo;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
// ── Display-P3 gamut ──────────────────────────────────────────────────────
|
|
158
|
+
//
|
|
159
|
+
// v0.5.13 §-TBD (FB-31). The v0.6.0 §301 plan-doc spec committed
|
|
160
|
+
// `inP3Gamut(o)` + `gamutMapOklch(o, 'p3')`; the v0.5.12 §301 ship dropped
|
|
161
|
+
// both (sRGB-only surface). FB-31 closes the gap with explicit P3 helpers
|
|
162
|
+
// matching the existing scalar-channels signature shape.
|
|
163
|
+
//
|
|
164
|
+
// sRGB-linear → Display-P3-linear matrix sourced from CSS Color 4 § 12.3
|
|
165
|
+
// (assumes both spaces share the D65 white point, which is true post-2018
|
|
166
|
+
// browser implementations; no Bradford chromatic adaptation needed).
|
|
167
|
+
|
|
168
|
+
function linearSrgbToLinearP3(r, g, b) {
|
|
169
|
+
return [
|
|
170
|
+
0.8224621 * r + 0.1775380 * g + 0.0000000 * b,
|
|
171
|
+
0.0331941 * r + 0.9668058 * g + 0.0000001 * b,
|
|
172
|
+
0.0170827 * r + 0.0723974 * g + 0.9105199 * b,
|
|
173
|
+
];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** Returns true if the OKLCH triple is inside Display-P3 gamut (tolerance `0.001`). */
|
|
177
|
+
export function inP3Gamut(L, C, H) {
|
|
178
|
+
const { a, b } = oklchToOklab(L, C, H);
|
|
179
|
+
const [lr, lg, lb] = oklabToLinearSrgb(L, a, b);
|
|
180
|
+
const [p3r, p3g, p3b] = linearSrgbToLinearP3(lr, lg, lb);
|
|
181
|
+
return isInGamut(linearToSrgb(p3r), linearToSrgb(p3g), linearToSrgb(p3b));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Bisect chroma to find the largest value that keeps `(L, _, H)` in
|
|
186
|
+
* Display-P3 gamut. 8 bisection iterations — same shape as the sRGB
|
|
187
|
+
* `gamutMapChroma`. Used by P3-aware design tooling (Tokens Studio,
|
|
188
|
+
* theme designers targeting P3-display laptops + iPads).
|
|
189
|
+
*/
|
|
190
|
+
export function gamutMapChromaP3(L, C, H) {
|
|
191
|
+
if (inP3Gamut(L, C, H)) return C;
|
|
192
|
+
let lo = 0, hi = C;
|
|
193
|
+
for (let i = 0; i < 8; i++) {
|
|
194
|
+
const mid = (lo + hi) / 2;
|
|
195
|
+
if (inP3Gamut(L, mid, H)) lo = mid;
|
|
196
|
+
else hi = mid;
|
|
197
|
+
}
|
|
198
|
+
return lo;
|
|
199
|
+
}
|
|
200
|
+
|
|
157
201
|
// ── APCA (advanced perceptual contrast algorithm) ─────────────────────────
|
|
202
|
+
//
|
|
203
|
+
// Source of truth: Andrew Somers' SACAM specification + apca-w3@0.1.9 (the
|
|
204
|
+
// W3C-pinned reference impl). The soft-clamp threshold is `0.022` for both
|
|
205
|
+
// fg + bg luminance values (per `SAPC_BLACK_THRESHOLD` in apca-w3 source).
|
|
206
|
+
// The 1.414 exponent is the APCA "BLACK_CLAMP" rescale constant.
|
|
207
|
+
//
|
|
208
|
+
// v0.5.13 §-TBD (FB-35): corrected the soft-clamp constant. v0.5.12 ship
|
|
209
|
+
// used 0.06 (declared as APCA_LO_CLAMP) by mistake, producing Lc 99.49 for
|
|
210
|
+
// black-on-white where canonical is 106.04 (-6.5pt bias for any pair
|
|
211
|
+
// involving near-black). Constants APCA_LO_FG / APCA_LO_BG were declared
|
|
212
|
+
// correctly but never read; the 0.06 constant was a stray from an earlier
|
|
213
|
+
// draft. apcaSrgbY() unchanged.
|
|
158
214
|
|
|
159
|
-
const APCA_NORM_L = 0.027;
|
|
160
215
|
const APCA_LO_BG = 0.022;
|
|
161
216
|
const APCA_LO_FG = 0.022;
|
|
162
|
-
const
|
|
163
|
-
const APCA_NORM_FACTOR = 1.14;
|
|
164
|
-
const APCA_LO_CLAMP = 0.06;
|
|
165
|
-
const APCA_RESCALE = 1.14;
|
|
217
|
+
const APCA_BLACK_CLAMP = 1.414;
|
|
166
218
|
|
|
167
219
|
function apcaSrgbY(rNorm, gNorm, bNorm) {
|
|
168
220
|
// sRGB → relative luminance via APCA Y (different coefficients than WCAG).
|
|
@@ -201,9 +253,10 @@ export function apcaContrast(fgHex, bgHex) {
|
|
|
201
253
|
let Yfg = apcaSrgbY(fg.r, fg.g, fg.b);
|
|
202
254
|
let Ybg = apcaSrgbY(bg.r, bg.g, bg.b);
|
|
203
255
|
|
|
204
|
-
// Soft clamp near black per APCA.
|
|
205
|
-
|
|
206
|
-
if (
|
|
256
|
+
// Soft clamp near black per APCA spec — threshold 0.022 per SACAM /
|
|
257
|
+
// apca-w3@0.1.9 (`SAPC_BLACK_THRESHOLD`).
|
|
258
|
+
if (Yfg < APCA_LO_FG) Yfg += Math.pow(APCA_LO_FG - Yfg, APCA_BLACK_CLAMP);
|
|
259
|
+
if (Ybg < APCA_LO_BG) Ybg += Math.pow(APCA_LO_BG - Ybg, APCA_BLACK_CLAMP);
|
|
207
260
|
|
|
208
261
|
let Lc;
|
|
209
262
|
if (Ybg > Yfg) {
|
|
@@ -39,7 +39,7 @@ action-item-ui:hover [slot="icon"] {
|
|
|
39
39
|
--action-item-fg: var(--a-fg-subtle);
|
|
40
40
|
--action-item-fg-hover: var(--a-fg-strong);
|
|
41
41
|
--action-item-bg-hover: var(--a-bg-muted);
|
|
42
|
-
--action-item-fg-disabled: var(--a-
|
|
42
|
+
--action-item-fg-disabled: var(--a-ui-text-disabled);
|
|
43
43
|
--action-item-icon-fg: var(--a-fg-muted);
|
|
44
44
|
--action-item-icon-fg-hover: var(--a-fg);
|
|
45
45
|
--action-item-danger-fg: var(--a-danger-bg);
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
--calendar-picker-day-bg-selected: var(--a-accent);
|
|
69
69
|
--calendar-picker-day-fg-selected: var(--a-accent-fg);
|
|
70
70
|
--calendar-picker-day-fg-outside: var(--a-fg-muted);
|
|
71
|
-
--calendar-picker-day-fg-disabled: var(--a-
|
|
71
|
+
--calendar-picker-day-fg-disabled: var(--a-ui-text-disabled);
|
|
72
72
|
--calendar-picker-day-today-border: var(--a-accent);
|
|
73
73
|
--calendar-picker-day-today-dot-size: var(--a-space-0-5);
|
|
74
74
|
--calendar-picker-day-today-dot-offset: var(--a-space-1);
|
|
@@ -37,7 +37,7 @@ chat-input-ui textarea-ui:not([disabled]) [slot="text"]:hover {
|
|
|
37
37
|
--chat-input-fg: var(--a-fg);
|
|
38
38
|
--chat-input-border: var(--a-border-subtle);
|
|
39
39
|
--chat-input-caret-color: var(--a-fg-subtle);
|
|
40
|
-
--chat-input-placeholder-fg: var(--a-
|
|
40
|
+
--chat-input-placeholder-fg: var(--a-ui-text-placeholder);
|
|
41
41
|
|
|
42
42
|
/* Hover — matches input-ui's affordance (subtle alpha lift on the
|
|
43
43
|
canvas surface + slightly stronger border + brightened fg). The
|
|
@@ -47,7 +47,7 @@ chat-input-ui textarea-ui:not([disabled]) [slot="text"]:hover {
|
|
|
47
47
|
doesn't compound. */
|
|
48
48
|
--chat-input-bg-hover: var(--a-ui-bg-hover);
|
|
49
49
|
--chat-input-border-hover: var(--a-ui-border-hover);
|
|
50
|
-
--chat-input-fg-hover: var(--a-
|
|
50
|
+
--chat-input-fg-hover: var(--a-ui-text-hover);
|
|
51
51
|
|
|
52
52
|
/* Disabled — host-level chrome (background, border, pointer-events)
|
|
53
53
|
lives on `:scope[disabled]` below. Inner-text disabled color is
|
|
@@ -55,7 +55,7 @@ chat-input-ui textarea-ui:not([disabled]) [slot="text"]:hover {
|
|
|
55
55
|
leak through. */
|
|
56
56
|
--chat-input-bg-disabled: transparent;
|
|
57
57
|
--chat-input-border-disabled: var(--a-border-subtle);
|
|
58
|
-
--chat-input-fg-disabled: var(--a-
|
|
58
|
+
--chat-input-fg-disabled: var(--a-ui-text-disabled);
|
|
59
59
|
|
|
60
60
|
/* Canonical focus ring — chat-input is a *nested-control host*.
|
|
61
61
|
See semantics.css FOCUS block + the nested-control pattern
|
|
@@ -60,7 +60,7 @@ check-ui[indeterminate] {
|
|
|
60
60
|
--check-bg-checked-hover: var(--a-primary-hover);
|
|
61
61
|
|
|
62
62
|
/* ── State: disabled ── */
|
|
63
|
-
--check-fg-disabled: var(--a-
|
|
63
|
+
--check-fg-disabled: var(--a-ui-text-disabled);
|
|
64
64
|
|
|
65
65
|
/* ── Check icon (CSS border trick, no SVG) ── */
|
|
66
66
|
--_icon-w: 0;
|
|
@@ -40,10 +40,20 @@ export class UIColorInput extends UIFormElement {
|
|
|
40
40
|
static get properties() {
|
|
41
41
|
return {
|
|
42
42
|
...UIFormElement.properties,
|
|
43
|
-
value:
|
|
44
|
-
format:
|
|
45
|
-
placement:
|
|
46
|
-
open:
|
|
43
|
+
value: { type: String, default: '#3b82f6', reflect: true },
|
|
44
|
+
format: { type: String, default: 'hex', reflect: true },
|
|
45
|
+
placement: { type: String, default: 'bottom-start', reflect: true },
|
|
46
|
+
open: { type: Boolean, default: false, reflect: true },
|
|
47
|
+
// Generation-constraint props forwarded to the inner <color-picker-ui>.
|
|
48
|
+
// v0.5.13 §-TBD (FB-33 §1) — full parity with color-picker's 5 constraint
|
|
49
|
+
// props (`maxChroma` / `maxL` / `minL` / `hueDriftMax` / `baseHue`) so
|
|
50
|
+
// <color-input-ui> adoption doesn't force a UX regression on consumers
|
|
51
|
+
// already using L-range / chroma / hue-drift constraints.
|
|
52
|
+
maxChroma: { type: Number, default: Infinity, reflect: true },
|
|
53
|
+
maxL: { type: Number, default: 1, reflect: true },
|
|
54
|
+
minL: { type: Number, default: 0, reflect: true },
|
|
55
|
+
hueDriftMax: { type: Number, default: NaN, reflect: true },
|
|
56
|
+
baseHue: { type: Number, default: NaN, reflect: true },
|
|
47
57
|
};
|
|
48
58
|
}
|
|
49
59
|
|
|
@@ -66,8 +76,16 @@ export class UIColorInput extends UIFormElement {
|
|
|
66
76
|
if (this.#popover && this.#popover.open !== this.open) {
|
|
67
77
|
this.#popover.open = this.open;
|
|
68
78
|
}
|
|
69
|
-
if (this.#picker
|
|
70
|
-
this.#picker.format = this.format;
|
|
79
|
+
if (this.#picker) {
|
|
80
|
+
if (this.#picker.format !== this.format) this.#picker.format = this.format;
|
|
81
|
+
// Forward live changes to the 5 generation-constraint props (FB-33 §1).
|
|
82
|
+
// Object.is handles the NaN-equality case correctly so `baseHue`/
|
|
83
|
+
// `hueDriftMax` don't reassign on every render.
|
|
84
|
+
if (!Object.is(this.#picker.maxChroma, this.maxChroma)) this.#picker.maxChroma = this.maxChroma;
|
|
85
|
+
if (!Object.is(this.#picker.maxL, this.maxL)) this.#picker.maxL = this.maxL;
|
|
86
|
+
if (!Object.is(this.#picker.minL, this.minL)) this.#picker.minL = this.minL;
|
|
87
|
+
if (!Object.is(this.#picker.hueDriftMax, this.hueDriftMax)) this.#picker.hueDriftMax = this.hueDriftMax;
|
|
88
|
+
if (!Object.is(this.#picker.baseHue, this.baseHue)) this.#picker.baseHue = this.baseHue;
|
|
71
89
|
}
|
|
72
90
|
if (this.#button) {
|
|
73
91
|
if (this.disabled) this.#button.setAttribute('disabled', '');
|
|
@@ -115,6 +133,13 @@ export class UIColorInput extends UIFormElement {
|
|
|
115
133
|
picker.setAttribute('slot', 'content');
|
|
116
134
|
picker.setAttribute('format', this.format);
|
|
117
135
|
picker.setAttribute('value', this.value);
|
|
136
|
+
// Set generation-constraint props directly (numeric — attribute-reflection
|
|
137
|
+
// would round-trip but properties cover NaN/Infinity correctly).
|
|
138
|
+
picker.maxChroma = this.maxChroma;
|
|
139
|
+
picker.maxL = this.maxL;
|
|
140
|
+
picker.minL = this.minL;
|
|
141
|
+
picker.hueDriftMax = this.hueDriftMax;
|
|
142
|
+
picker.baseHue = this.baseHue;
|
|
118
143
|
|
|
119
144
|
popover.append(button, picker);
|
|
120
145
|
this.append(popover);
|
|
@@ -162,10 +187,20 @@ export class UIColorInput extends UIFormElement {
|
|
|
162
187
|
this.syncValue(next);
|
|
163
188
|
}
|
|
164
189
|
this.#syncFromValue();
|
|
190
|
+
// Forward the inner picker's parsed OKLCH channel scalars (v0.5.13 §-TBD,
|
|
191
|
+
// FB-33 §1-adjacent). Consumers writing OKLCH-native logic get the parsed
|
|
192
|
+
// {l, c, h} for free, matching <color-picker-ui>'s detail shape.
|
|
165
193
|
this.dispatchEvent(new CustomEvent(kind, {
|
|
166
194
|
bubbles: true,
|
|
167
195
|
composed: true,
|
|
168
|
-
detail: {
|
|
196
|
+
detail: {
|
|
197
|
+
value: next ?? this.value,
|
|
198
|
+
hex: detail.hex,
|
|
199
|
+
oklch: detail.oklch,
|
|
200
|
+
l: detail.l,
|
|
201
|
+
c: detail.c,
|
|
202
|
+
h: detail.h,
|
|
203
|
+
},
|
|
169
204
|
}));
|
|
170
205
|
}
|
|
171
206
|
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"properties": {
|
|
16
|
+
"baseHue": {
|
|
17
|
+
"description": "Reference hue (degrees) for the hueDriftMax constraint, forwarded to inner picker. Default NaN — picker falls back to its hue at first commit.",
|
|
18
|
+
"type": "number",
|
|
19
|
+
"default": "NaN"
|
|
20
|
+
},
|
|
16
21
|
"component": {
|
|
17
22
|
"const": "ColorInput"
|
|
18
23
|
},
|
|
@@ -30,6 +35,26 @@
|
|
|
30
35
|
],
|
|
31
36
|
"default": "hex"
|
|
32
37
|
},
|
|
38
|
+
"hueDriftMax": {
|
|
39
|
+
"description": "Generation constraint forwarded to inner picker — maximum allowed signed-shortest-path hue deviation (degrees) from baseHue. Default NaN (no constraint).",
|
|
40
|
+
"type": "number",
|
|
41
|
+
"default": "NaN"
|
|
42
|
+
},
|
|
43
|
+
"maxChroma": {
|
|
44
|
+
"description": "Generation constraint forwarded to the inner `<color-picker-ui>` (v0.5.13\n§-TBD, FB-33 §1). Clamp the OKLCH chroma channel to at most this value.\nDefault Infinity (no constraint).\n",
|
|
45
|
+
"type": "number",
|
|
46
|
+
"default": "Infinity"
|
|
47
|
+
},
|
|
48
|
+
"maxL": {
|
|
49
|
+
"description": "Generation constraint forwarded to inner picker — clamp OKLCH lightness to at most this value (0..1). Default 1.",
|
|
50
|
+
"type": "number",
|
|
51
|
+
"default": 1
|
|
52
|
+
},
|
|
53
|
+
"minL": {
|
|
54
|
+
"description": "Generation constraint forwarded to inner picker — clamp OKLCH lightness to at least this value (0..1). Default 0.",
|
|
55
|
+
"type": "number",
|
|
56
|
+
"default": 0
|
|
57
|
+
},
|
|
33
58
|
"name": {
|
|
34
59
|
"description": "Form field name.",
|
|
35
60
|
"type": "string",
|
|
@@ -77,10 +102,22 @@
|
|
|
77
102
|
"change": {
|
|
78
103
|
"description": "Fired when the color is committed (pointerup / Enter / picker close). Bubbles from inner picker.",
|
|
79
104
|
"detail": {
|
|
105
|
+
"c": {
|
|
106
|
+
"description": "Parsed OKLCH chroma scalar.",
|
|
107
|
+
"type": "number"
|
|
108
|
+
},
|
|
109
|
+
"h": {
|
|
110
|
+
"description": "Parsed OKLCH hue scalar (degrees, NaN ok for achromatic).",
|
|
111
|
+
"type": "number"
|
|
112
|
+
},
|
|
80
113
|
"hex": {
|
|
81
114
|
"description": "Hex form (`#rrggbb`).",
|
|
82
115
|
"type": "string"
|
|
83
116
|
},
|
|
117
|
+
"l": {
|
|
118
|
+
"description": "Parsed OKLCH lightness scalar (0..1). v0.5.13 §-TBD (FB-33 §1-adjacent).",
|
|
119
|
+
"type": "number"
|
|
120
|
+
},
|
|
84
121
|
"oklch": {
|
|
85
122
|
"description": "OKLCH string (`oklch(L C H)`).",
|
|
86
123
|
"type": "string"
|
|
@@ -94,9 +131,18 @@
|
|
|
94
131
|
"input": {
|
|
95
132
|
"description": "Fired during continuous drag of the inner picker. Bubbles from inner picker.",
|
|
96
133
|
"detail": {
|
|
134
|
+
"c": {
|
|
135
|
+
"type": "number"
|
|
136
|
+
},
|
|
137
|
+
"h": {
|
|
138
|
+
"type": "number"
|
|
139
|
+
},
|
|
97
140
|
"hex": {
|
|
98
141
|
"type": "string"
|
|
99
142
|
},
|
|
143
|
+
"l": {
|
|
144
|
+
"type": "number"
|
|
145
|
+
},
|
|
100
146
|
"oklch": {
|
|
101
147
|
"type": "string"
|
|
102
148
|
},
|
|
@@ -38,6 +38,12 @@ export interface ColorInputChangeEventDetail {
|
|
|
38
38
|
hex: string;
|
|
39
39
|
/** OKLCH string (`oklch(L C H)`, fixed precision). */
|
|
40
40
|
oklch: string;
|
|
41
|
+
/** Parsed OKLCH lightness (0..1). v0.5.13 §-TBD (FB-33 §1-adjacent). */
|
|
42
|
+
l: number;
|
|
43
|
+
/** Parsed OKLCH chroma. */
|
|
44
|
+
c: number;
|
|
45
|
+
/** Parsed OKLCH hue (degrees, NaN ok for achromatic). */
|
|
46
|
+
h: number;
|
|
41
47
|
}
|
|
42
48
|
export type ColorInputChangeEvent = CustomEvent<ColorInputChangeEventDetail>;
|
|
43
49
|
export type ColorInputInputEvent = CustomEvent<ColorInputChangeEventDetail>;
|
|
@@ -55,6 +61,16 @@ export class UIColorInput extends UIFormElement {
|
|
|
55
61
|
placement: 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end';
|
|
56
62
|
/** Reflects the inner popover's open state. Set programmatically to open/close without a click. */
|
|
57
63
|
open: boolean;
|
|
64
|
+
/** Generation constraint forwarded to inner picker: clamp OKLCH chroma to at most this value. `Infinity` = unconstrained. v0.5.13 §-TBD (FB-33 §1). */
|
|
65
|
+
maxChroma: number;
|
|
66
|
+
/** Generation constraint forwarded to inner picker: clamp OKLCH lightness to at most this value (0..1). `1` = unconstrained. */
|
|
67
|
+
maxL: number;
|
|
68
|
+
/** Generation constraint forwarded to inner picker: clamp OKLCH lightness to at least this value (0..1). `0` = unconstrained. */
|
|
69
|
+
minL: number;
|
|
70
|
+
/** Generation constraint forwarded to inner picker: maximum allowed signed-shortest-path hue drift in degrees from `baseHue`. `NaN` = unconstrained. */
|
|
71
|
+
hueDriftMax: number;
|
|
72
|
+
/** Reference hue (degrees) for `hueDriftMax`, forwarded to inner picker. `NaN` = picker falls back to its hue at first commit. */
|
|
73
|
+
baseHue: number;
|
|
58
74
|
|
|
59
75
|
/** Open the picker programmatically. */
|
|
60
76
|
showPicker(): void;
|
|
@@ -61,6 +61,34 @@ props:
|
|
|
61
61
|
type: boolean
|
|
62
62
|
default: false
|
|
63
63
|
reflect: true
|
|
64
|
+
maxChroma:
|
|
65
|
+
description: |
|
|
66
|
+
Generation constraint forwarded to the inner `<color-picker-ui>` (v0.5.13
|
|
67
|
+
§-TBD, FB-33 §1). Clamp the OKLCH chroma channel to at most this value.
|
|
68
|
+
Default Infinity (no constraint).
|
|
69
|
+
type: number
|
|
70
|
+
default: Infinity
|
|
71
|
+
reflect: true
|
|
72
|
+
maxL:
|
|
73
|
+
description: Generation constraint forwarded to inner picker — clamp OKLCH lightness to at most this value (0..1). Default 1.
|
|
74
|
+
type: number
|
|
75
|
+
default: 1
|
|
76
|
+
reflect: true
|
|
77
|
+
minL:
|
|
78
|
+
description: Generation constraint forwarded to inner picker — clamp OKLCH lightness to at least this value (0..1). Default 0.
|
|
79
|
+
type: number
|
|
80
|
+
default: 0
|
|
81
|
+
reflect: true
|
|
82
|
+
hueDriftMax:
|
|
83
|
+
description: Generation constraint forwarded to inner picker — maximum allowed signed-shortest-path hue deviation (degrees) from baseHue. Default NaN (no constraint).
|
|
84
|
+
type: number
|
|
85
|
+
default: NaN
|
|
86
|
+
reflect: true
|
|
87
|
+
baseHue:
|
|
88
|
+
description: Reference hue (degrees) for the hueDriftMax constraint, forwarded to inner picker. Default NaN — picker falls back to its hue at first commit.
|
|
89
|
+
type: number
|
|
90
|
+
default: NaN
|
|
91
|
+
reflect: true
|
|
64
92
|
events:
|
|
65
93
|
change:
|
|
66
94
|
description: Fired when the color is committed (pointerup / Enter / picker close). Bubbles from inner picker.
|
|
@@ -74,6 +102,15 @@ events:
|
|
|
74
102
|
oklch:
|
|
75
103
|
type: string
|
|
76
104
|
description: OKLCH string (`oklch(L C H)`).
|
|
105
|
+
l:
|
|
106
|
+
type: number
|
|
107
|
+
description: Parsed OKLCH lightness scalar (0..1). v0.5.13 §-TBD (FB-33 §1-adjacent).
|
|
108
|
+
c:
|
|
109
|
+
type: number
|
|
110
|
+
description: Parsed OKLCH chroma scalar.
|
|
111
|
+
h:
|
|
112
|
+
type: number
|
|
113
|
+
description: Parsed OKLCH hue scalar (degrees, NaN ok for achromatic).
|
|
77
114
|
input:
|
|
78
115
|
description: Fired during continuous drag of the inner picker. Bubbles from inner picker.
|
|
79
116
|
detail:
|
|
@@ -84,6 +121,12 @@ events:
|
|
|
84
121
|
type: string
|
|
85
122
|
oklch:
|
|
86
123
|
type: string
|
|
124
|
+
l:
|
|
125
|
+
type: number
|
|
126
|
+
c:
|
|
127
|
+
type: number
|
|
128
|
+
h:
|
|
129
|
+
type: number
|
|
87
130
|
slots: {}
|
|
88
131
|
states:
|
|
89
132
|
- name: idle
|
|
@@ -86,6 +86,10 @@ export class UIHeatmap extends UIElement {
|
|
|
86
86
|
this.removeEventListener('pointerleave', this.#onLeave);
|
|
87
87
|
this.removeEventListener('click', this.#onClick);
|
|
88
88
|
this.#bound = false;
|
|
89
|
+
if (this.#raf != null) {
|
|
90
|
+
cancelAnimationFrame(this.#raf);
|
|
91
|
+
this.#raf = null;
|
|
92
|
+
}
|
|
89
93
|
}
|
|
90
94
|
|
|
91
95
|
#raf = null;
|
|
@@ -37,9 +37,9 @@ input-ui:not([disabled]) [slot="field"]:hover [slot="suffix"] {
|
|
|
37
37
|
|
|
38
38
|
/* ── State: hover/focus ── */
|
|
39
39
|
--input-bg-hover: var(--a-ui-bg-hover);
|
|
40
|
-
--input-fg-hover: var(--a-
|
|
41
|
-
--input-affix-fg-hover: var(--a-
|
|
42
|
-
--input-fg-focus: var(--a-
|
|
40
|
+
--input-fg-hover: var(--a-ui-text-hover);
|
|
41
|
+
--input-affix-fg-hover: var(--a-ui-text-subtle);
|
|
42
|
+
--input-fg-focus: var(--a-ui-text-active);
|
|
43
43
|
|
|
44
44
|
/* ── State: disabled ── */
|
|
45
45
|
--input-bg-disabled: var(--a-ui-bg-disabled);
|
package/components/menu/menu.css
CHANGED
|
@@ -93,10 +93,10 @@ menu-item-ui[variant="danger"]:hover [slot="icon"] {
|
|
|
93
93
|
--menu-item-fg: var(--a-fg-subtle);
|
|
94
94
|
--menu-item-fg-hover: var(--a-fg);
|
|
95
95
|
--menu-item-bg-hover: var(--a-bg-muted);
|
|
96
|
-
--menu-item-fg-disabled: var(--a-
|
|
96
|
+
--menu-item-fg-disabled: var(--a-ui-text-disabled);
|
|
97
97
|
--menu-item-icon-fg: var(--a-fg-muted);
|
|
98
98
|
--menu-item-icon-fg-hover: var(--a-fg);
|
|
99
|
-
--menu-item-icon-disabled: var(--a-
|
|
99
|
+
--menu-item-icon-disabled: var(--a-ui-text-disabled);
|
|
100
100
|
--menu-item-danger-fg: var(--a-danger-bg);
|
|
101
101
|
--menu-item-danger-bg: var(--a-danger-muted);
|
|
102
102
|
|
|
@@ -222,7 +222,7 @@ nav-group-ui [slot="popover"] {
|
|
|
222
222
|
nav-group-ui [slot="popover-label"] {
|
|
223
223
|
padding: var(--a-space-1) var(--a-space-2);
|
|
224
224
|
font-weight: var(--a-weight-medium);
|
|
225
|
-
color: var(--
|
|
225
|
+
color: var(--nav-group-fg-muted);
|
|
226
226
|
font-size: var(--a-ui-tiny);
|
|
227
227
|
text-transform: uppercase;
|
|
228
228
|
letter-spacing: 0.06em;
|
|
@@ -231,7 +231,7 @@ nav-group-ui [slot="popover-label"] {
|
|
|
231
231
|
nav-group-ui [slot="popover"] [role="option"] {
|
|
232
232
|
padding: var(--a-space-1) var(--a-space-2);
|
|
233
233
|
border-radius: var(--a-radius);
|
|
234
|
-
color: var(--
|
|
234
|
+
color: var(--nav-group-fg-muted);
|
|
235
235
|
cursor: pointer;
|
|
236
236
|
white-space: nowrap;
|
|
237
237
|
transition:
|
|
@@ -241,7 +241,7 @@ nav-group-ui [slot="popover"] [role="option"] {
|
|
|
241
241
|
|
|
242
242
|
nav-group-ui [slot="popover"] [role="option"]:hover {
|
|
243
243
|
background: var(--a-bg-hover);
|
|
244
|
-
color: var(--
|
|
244
|
+
color: var(--nav-group-fg-hover);
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
/* Selected / current option — mirrors the main rail's nav-item selection:
|
|
@@ -250,7 +250,7 @@ nav-group-ui [slot="popover"] [role="option"][aria-current="page"],
|
|
|
250
250
|
nav-group-ui [slot="popover"] [role="option"][aria-selected="true"] {
|
|
251
251
|
position: relative;
|
|
252
252
|
background: var(--a-bg-hover);
|
|
253
|
-
color: var(--
|
|
253
|
+
color: var(--nav-group-fg-selected);
|
|
254
254
|
font-weight: var(--a-weight-medium);
|
|
255
255
|
}
|
|
256
256
|
|
|
@@ -283,7 +283,7 @@ nav-ui[variant="section"] > nav-group-ui:not([variant]) > [slot="header"] {
|
|
|
283
283
|
padding: var(--a-space-3) var(--a-space-2) var(--a-space-1);
|
|
284
284
|
font-size: var(--a-kicker-sm, var(--a-ui-tiny));
|
|
285
285
|
font-weight: var(--a-weight-medium);
|
|
286
|
-
color: var(--
|
|
286
|
+
color: var(--nav-group-fg-muted);
|
|
287
287
|
text-transform: uppercase;
|
|
288
288
|
letter-spacing: 0.06em;
|
|
289
289
|
cursor: default;
|
|
@@ -295,7 +295,7 @@ nav-group-ui[variant="section"] > [slot="header"]:focus-visible,
|
|
|
295
295
|
nav-ui[variant="section"] > nav-group-ui:not([variant]) > [slot="header"]:hover,
|
|
296
296
|
nav-ui[variant="section"] > nav-group-ui:not([variant]) > [slot="header"]:focus-visible {
|
|
297
297
|
background: transparent;
|
|
298
|
-
color: var(--
|
|
298
|
+
color: var(--nav-group-fg-muted);
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
nav-group-ui[variant="section"] > [slot="header"] [slot="caret"],
|
|
@@ -101,7 +101,8 @@ option-card-ui[checked] > [slot="icon"] {
|
|
|
101
101
|
outline: none;
|
|
102
102
|
transition:
|
|
103
103
|
background var(--option-card-duration) var(--option-card-easing),
|
|
104
|
-
border-color var(--option-card-duration) var(--option-card-easing)
|
|
104
|
+
border-color var(--option-card-duration) var(--option-card-easing),
|
|
105
|
+
box-shadow var(--option-card-duration) var(--option-card-easing);
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
/* When an icon slot is present, insert a third column for it
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* Each digit gets its own input — auto-advances on entry,
|
|
19
19
|
* backs up on delete, distributes pasted values.
|
|
20
20
|
*
|
|
21
|
-
* Events: 'complete' (detail: {value}), 'input'
|
|
21
|
+
* Events: 'complete' (detail: {value}), 'input' (detail: {value}), 'change' (detail: {value})
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { UIFormElement } from '../../core/form.js';
|
|
@@ -107,6 +107,7 @@ export class UIOtpInput extends UIFormElement {
|
|
|
107
107
|
|
|
108
108
|
this.#syncCombined();
|
|
109
109
|
this.dispatchEvent(new CustomEvent('input', { bubbles: true, detail: { value: this.value } }));
|
|
110
|
+
this.dispatchEvent(new CustomEvent('change', { bubbles: true, detail: { value: this.value } }));
|
|
110
111
|
|
|
111
112
|
if (input.value && index < this.#inputs.length - 1) {
|
|
112
113
|
this.#inputs[index + 1].focus();
|
|
@@ -121,6 +122,7 @@ export class UIOtpInput extends UIFormElement {
|
|
|
121
122
|
this.#inputs[index - 1].value = '';
|
|
122
123
|
this.#syncCombined();
|
|
123
124
|
this.dispatchEvent(new CustomEvent('input', { bubbles: true, detail: { value: this.value } }));
|
|
125
|
+
this.dispatchEvent(new CustomEvent('change', { bubbles: true, detail: { value: this.value } }));
|
|
124
126
|
}
|
|
125
127
|
}
|
|
126
128
|
|
|
@@ -132,6 +134,7 @@ export class UIOtpInput extends UIFormElement {
|
|
|
132
134
|
}
|
|
133
135
|
this.#syncCombined();
|
|
134
136
|
this.dispatchEvent(new CustomEvent('input', { bubbles: true, detail: { value: this.value } }));
|
|
137
|
+
this.dispatchEvent(new CustomEvent('change', { bubbles: true, detail: { value: this.value } }));
|
|
135
138
|
|
|
136
139
|
// Focus last filled or first empty
|
|
137
140
|
const firstEmpty = this.#inputs.findIndex(inp => !inp.value);
|
|
@@ -46,6 +46,15 @@
|
|
|
46
46
|
"category": "input",
|
|
47
47
|
"composes": [],
|
|
48
48
|
"events": {
|
|
49
|
+
"change": {
|
|
50
|
+
"description": "Fired alongside `input` on every digit change. Provides form-bearing-primitive event-shape parity (every UIFormElement emits `change` with `detail.value`).",
|
|
51
|
+
"detail": {
|
|
52
|
+
"value": {
|
|
53
|
+
"description": "Combined digits at the moment of the change.",
|
|
54
|
+
"type": "string"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
49
58
|
"complete": {
|
|
50
59
|
"description": "Fired exactly once when the user fills the last digit slot. detail.value is the combined string.",
|
|
51
60
|
"detail": {
|
|
@@ -11,6 +11,8 @@ export interface OtpInputEventDetail {
|
|
|
11
11
|
value: string;
|
|
12
12
|
}
|
|
13
13
|
export type OtpInputEvent = CustomEvent<OtpInputEventDetail>;
|
|
14
|
+
export type OtpInputInputEvent = CustomEvent<OtpInputEventDetail>;
|
|
15
|
+
export type OtpInputChangeEvent = CustomEvent<OtpInputEventDetail>;
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Detail payload for the `complete` event — fired exactly once when the
|
|
@@ -32,5 +34,6 @@ export class UIOtpInput extends UIFormElement {
|
|
|
32
34
|
options?: boolean | AddEventListenerOptions,
|
|
33
35
|
): void;
|
|
34
36
|
addEventListener(type: 'input', listener: (ev: OtpInputEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
37
|
+
addEventListener(type: 'change', listener: (ev: OtpInputEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
35
38
|
addEventListener(type: 'complete', listener: (ev: OtpInputCompleteEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
36
39
|
}
|
|
@@ -36,6 +36,12 @@ events:
|
|
|
36
36
|
value:
|
|
37
37
|
type: string
|
|
38
38
|
description: Combined digits at the moment of the change.
|
|
39
|
+
change:
|
|
40
|
+
description: Fired alongside `input` on every digit change. Provides form-bearing-primitive event-shape parity (every UIFormElement emits `change` with `detail.value`).
|
|
41
|
+
detail:
|
|
42
|
+
value:
|
|
43
|
+
type: string
|
|
44
|
+
description: Combined digits at the moment of the change.
|
|
39
45
|
slots:
|
|
40
46
|
field:
|
|
41
47
|
description: Container for the digit input boxes and optional separator
|
|
@@ -70,7 +70,9 @@
|
|
|
70
70
|
line-height: 1;
|
|
71
71
|
transition:
|
|
72
72
|
background var(--pagination-duration) var(--pagination-easing),
|
|
73
|
-
color var(--pagination-duration) var(--pagination-easing)
|
|
73
|
+
border-color var(--pagination-duration) var(--pagination-easing),
|
|
74
|
+
color var(--pagination-duration) var(--pagination-easing),
|
|
75
|
+
box-shadow var(--pagination-duration) var(--pagination-easing);
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
[slot="nav"] button:not([disabled]):hover {
|
|
@@ -39,7 +39,7 @@ radio-ui[checked] [slot="dot"]::after {
|
|
|
39
39
|
--radio-bg-checked-hover: var(--a-primary-hover);
|
|
40
40
|
|
|
41
41
|
/* ── State: disabled ── */
|
|
42
|
-
--radio-fg-disabled: var(--a-
|
|
42
|
+
--radio-fg-disabled: var(--a-ui-text-disabled);
|
|
43
43
|
|
|
44
44
|
/* ── State: focus ── */
|
|
45
45
|
--radio-focus-ring: var(--a-focus-ring);
|
|
@@ -76,6 +76,7 @@ export class UISearch extends UIFormElement {
|
|
|
76
76
|
this.value = this.#inputEl.value;
|
|
77
77
|
this.syncValue(this.value);
|
|
78
78
|
this.dispatchEvent(new CustomEvent('input', { bubbles: true, detail: { value: this.value } }));
|
|
79
|
+
this.dispatchEvent(new CustomEvent('change', { bubbles: true, detail: { value: this.value } }));
|
|
79
80
|
|
|
80
81
|
clearTimeout(this.#timer);
|
|
81
82
|
this.#timer = setTimeout(() => {
|
|
@@ -106,6 +107,7 @@ export class UISearch extends UIFormElement {
|
|
|
106
107
|
this.syncValue('');
|
|
107
108
|
this.setAttribute('value', '');
|
|
108
109
|
this.dispatchEvent(new CustomEvent('input', { bubbles: true, detail: { value: this.value } }));
|
|
110
|
+
this.dispatchEvent(new CustomEvent('change', { bubbles: true, detail: { value: this.value } }));
|
|
109
111
|
this.dispatchEvent(new CustomEvent('search', {
|
|
110
112
|
bubbles: true,
|
|
111
113
|
detail: { value: '' },
|
|
@@ -56,6 +56,15 @@
|
|
|
56
56
|
"category": "input",
|
|
57
57
|
"composes": [],
|
|
58
58
|
"events": {
|
|
59
|
+
"change": {
|
|
60
|
+
"description": "Fired alongside `input` on every keystroke + on clear. Provides form-bearing-primitive event-shape parity (every UIFormElement emits `change` with `detail.value`).",
|
|
61
|
+
"detail": {
|
|
62
|
+
"value": {
|
|
63
|
+
"description": "Current search-input value.",
|
|
64
|
+
"type": "string"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
59
68
|
"clear": {
|
|
60
69
|
"description": "Fired when the clear button is clicked"
|
|
61
70
|
},
|
|
@@ -10,6 +10,7 @@ export interface SearchInputEventDetail {
|
|
|
10
10
|
value: string;
|
|
11
11
|
}
|
|
12
12
|
export type SearchInputEvent = CustomEvent<SearchInputEventDetail>;
|
|
13
|
+
export type SearchChangeEvent = CustomEvent<SearchInputEventDetail>;
|
|
13
14
|
|
|
14
15
|
export interface SearchEventDetail {
|
|
15
16
|
value: string;
|
|
@@ -31,5 +32,6 @@ export class UISearch extends UIFormElement {
|
|
|
31
32
|
options?: boolean | AddEventListenerOptions,
|
|
32
33
|
): void;
|
|
33
34
|
addEventListener(type: 'input', listener: (ev: SearchInputEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
35
|
+
addEventListener(type: 'change', listener: (ev: SearchInputEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
34
36
|
addEventListener(type: 'search', listener: (ev: SearchEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
35
37
|
}
|
|
@@ -39,6 +39,12 @@ events:
|
|
|
39
39
|
description: Fired when the clear button is clicked
|
|
40
40
|
input:
|
|
41
41
|
description: "Fired on each input change during typing."
|
|
42
|
+
change:
|
|
43
|
+
description: Fired alongside `input` on every keystroke + on clear. Provides form-bearing-primitive event-shape parity (every UIFormElement emits `change` with `detail.value`).
|
|
44
|
+
detail:
|
|
45
|
+
value:
|
|
46
|
+
type: string
|
|
47
|
+
description: Current search-input value.
|
|
42
48
|
search:
|
|
43
49
|
description: Debounced CustomEvent with detail.query containing the search string
|
|
44
50
|
slots:
|
|
@@ -20,10 +20,10 @@ segment-ui[selected] {
|
|
|
20
20
|
--segment-font-weight: var(--a-ui-weight);
|
|
21
21
|
|
|
22
22
|
/* ── Colors ── */
|
|
23
|
-
--segment-fg: var(--a-
|
|
24
|
-
--segment-fg-hover: var(--a-
|
|
23
|
+
--segment-fg: var(--a-ui-text-subtle);
|
|
24
|
+
--segment-fg-hover: var(--a-ui-text-hover);
|
|
25
25
|
--segment-fg-selected: var(--a-chrome-dark);
|
|
26
|
-
--segment-fg-disabled: var(--a-
|
|
26
|
+
--segment-fg-disabled: var(--a-ui-text-disabled);
|
|
27
27
|
|
|
28
28
|
/* ── Transition ── */
|
|
29
29
|
--segment-duration: var(--a-duration-fast);
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
--select-placeholder-fg: var(--a-ui-text-placeholder);
|
|
25
25
|
--select-caret-fg: var(--a-ui-text-muted);
|
|
26
26
|
--select-fg: var(--a-ui-text);
|
|
27
|
+
--select-fg-hover: var(--a-ui-text-hover);
|
|
27
28
|
--select-fg-selected: var(--a-ui-text-selected);
|
|
28
29
|
--select-fg-subtle: var(--a-ui-text-subtle);
|
|
29
30
|
--select-fg-muted: var(--a-ui-text-muted);
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
--select-option-px: var(--a-ui-px);
|
|
39
40
|
--select-option-py: var(--a-ui-py);
|
|
40
41
|
--select-option-bg-hover: var(--a-bg-hover);
|
|
41
|
-
--select-option-fg-active: var(--a-
|
|
42
|
+
--select-option-fg-active: var(--a-ui-text-active);
|
|
42
43
|
--select-option-fg-disabled: var(--a-ui-text-disabled);
|
|
43
44
|
--select-group-label-size: var(--a-ui-size);
|
|
44
45
|
}
|
|
@@ -223,7 +224,7 @@ select-ui [role="option"] {
|
|
|
223
224
|
padding: var(--a-space-1) var(--a-ui-px);
|
|
224
225
|
border-radius: var(--a-radius-sm);
|
|
225
226
|
white-space: nowrap;
|
|
226
|
-
color: var(--
|
|
227
|
+
color: var(--select-fg-subtle);
|
|
227
228
|
cursor: pointer;
|
|
228
229
|
transition:
|
|
229
230
|
background var(--a-duration-fast) var(--a-easing),
|
|
@@ -231,8 +232,8 @@ select-ui [role="option"] {
|
|
|
231
232
|
}
|
|
232
233
|
select-ui [role="option"]:hover,
|
|
233
234
|
select-ui [role="option"][data-focused] {
|
|
234
|
-
background: var(--
|
|
235
|
-
color: var(--
|
|
235
|
+
background: var(--select-option-bg-hover);
|
|
236
|
+
color: var(--select-fg-hover);
|
|
236
237
|
}
|
|
237
238
|
select-ui [role="option"][aria-selected="true"] {
|
|
238
239
|
color: var(--select-fg-selected);
|
|
@@ -240,7 +241,7 @@ select-ui [role="option"][aria-selected="true"] {
|
|
|
240
241
|
font-weight: var(--a-ui-weight);
|
|
241
242
|
}
|
|
242
243
|
select-ui [role="option"][aria-disabled="true"] {
|
|
243
|
-
color: var(--
|
|
244
|
+
color: var(--select-option-fg-disabled);
|
|
244
245
|
cursor: not-allowed;
|
|
245
246
|
}
|
|
246
247
|
select-ui [role="option"][aria-disabled="true"]:hover {
|
|
@@ -250,7 +251,7 @@ select-ui [role="option"][aria-disabled="true"]:hover {
|
|
|
250
251
|
/* Option with icon */
|
|
251
252
|
select-ui [role="option"] icon-ui {
|
|
252
253
|
--a-icon-size: var(--a-ui-size);
|
|
253
|
-
color: var(--
|
|
254
|
+
color: var(--select-fg-muted);
|
|
254
255
|
margin-inline-end: var(--a-space-1);
|
|
255
256
|
vertical-align: -0.125em;
|
|
256
257
|
}
|
|
@@ -282,21 +283,21 @@ select-ui [data-menu-header] img {
|
|
|
282
283
|
select-ui [data-menu-header] strong {
|
|
283
284
|
display: block;
|
|
284
285
|
font-weight: var(--a-weight-medium);
|
|
285
|
-
color: var(--
|
|
286
|
+
color: var(--select-fg);
|
|
286
287
|
font-size: var(--a-ui-size);
|
|
287
288
|
}
|
|
288
289
|
|
|
289
290
|
select-ui [data-menu-header] span {
|
|
290
291
|
display: block;
|
|
291
292
|
font-size: var(--a-ui-sm);
|
|
292
|
-
color: var(--
|
|
293
|
+
color: var(--select-fg-muted);
|
|
293
294
|
}
|
|
294
295
|
|
|
295
296
|
select-ui [role="group"] [slot="group-label"] {
|
|
296
297
|
padding: var(--a-space-1) var(--a-ui-px);
|
|
297
298
|
font-size: var(--a-ui-tiny);
|
|
298
299
|
font-weight: var(--a-ui-weight);
|
|
299
|
-
color: var(--
|
|
300
|
+
color: var(--select-fg-muted);
|
|
300
301
|
text-transform: uppercase;
|
|
301
302
|
letter-spacing: 0.05em;
|
|
302
303
|
white-space: nowrap;
|
|
@@ -212,8 +212,20 @@ export class UISwatch extends UIElement {
|
|
|
212
212
|
|
|
213
213
|
#stamp() {
|
|
214
214
|
if (this.#stamped) return;
|
|
215
|
+
|
|
216
|
+
// v0.5.13 §-TBD (FB-34 §1) — `[slot="chrome"]` children are sibling-of-tile
|
|
217
|
+
// chrome (gamut badges, override/tracked dots, custom indicators) that must
|
|
218
|
+
// survive stamping as direct host siblings, NOT funnel into #labelEl where
|
|
219
|
+
// absolute-positioning anchors against the label text bbox. Pull them out
|
|
220
|
+
// FIRST so the innerHTML='' wipe below doesn't lose them.
|
|
221
|
+
const chromeSlot = Array.from(this.children).filter(
|
|
222
|
+
n => n.getAttribute && n.getAttribute('slot') === 'chrome'
|
|
223
|
+
);
|
|
224
|
+
for (const n of chromeSlot) n.remove();
|
|
225
|
+
|
|
215
226
|
// Capture pre-existing default-slot content so consumer-authored
|
|
216
227
|
// children (e.g. <swatch-ui>Forecast</swatch-ui>) survive stamping.
|
|
228
|
+
// `[slot="chrome"]` children are already removed above, so won't appear here.
|
|
217
229
|
const slotted = Array.from(this.childNodes).filter(n =>
|
|
218
230
|
!(n.nodeType === 1 && n.dataset && (
|
|
219
231
|
n.dataset.tile !== undefined ||
|
|
@@ -230,6 +242,14 @@ export class UISwatch extends UIElement {
|
|
|
230
242
|
this.#tileEl.setAttribute('aria-hidden', 'true');
|
|
231
243
|
this.appendChild(this.#tileEl);
|
|
232
244
|
|
|
245
|
+
// Chrome-slot children re-attach IMMEDIATELY after the tile so they can
|
|
246
|
+
// position absolutely against the host (host carries position: relative
|
|
247
|
+
// when shape="block" + label-position="overlay" per swatch.css). Keeping
|
|
248
|
+
// them sibling-of-tile (not descendant-of-tile) lets consumer CSS use
|
|
249
|
+
// `position: absolute; top: 2px; right: 2px` and anchor against the host's
|
|
250
|
+
// padding-box, which matches the tile's geometry in the block layout.
|
|
251
|
+
for (const n of chromeSlot) this.appendChild(n);
|
|
252
|
+
|
|
233
253
|
// Badge container — holds one or more <span data-badge-variant="..."> children.
|
|
234
254
|
// Multi-badge support added in v0.4.9 §92 (FEEDBACK-04 follow-up).
|
|
235
255
|
this.#badgeEl = document.createElement('span');
|
|
@@ -149,7 +149,10 @@
|
|
|
149
149
|
],
|
|
150
150
|
"slots": {
|
|
151
151
|
"default": {
|
|
152
|
-
"description": "Optional rich label content. When present, replaces the [label]
|
|
152
|
+
"description": "Optional rich label content. When present, replaces the [label]\nattribute's text. Consumer chrome positioned absolutely against the\nswatch tile should use `[slot=\"chrome\"]` instead — default-slot\nchildren are funneled into the label region.\n"
|
|
153
|
+
},
|
|
154
|
+
"chrome": {
|
|
155
|
+
"description": "§-TBD (v0.5.13, FB-34 §1). Sibling-of-tile chrome — gamut badges,\noverride/tracked dots, custom indicators — that survives stamping as\na direct host sibling rather than being funneled into the label. Pair\nwith consumer-authored CSS `position: absolute` against the host\n(the host carries `position: relative` when `shape=\"block\"`, so\n`top/right/bottom/left` offsets anchor to the tile's geometry).\nCloses the C1.3 dogfood chrome-overlay composition gap.\n"
|
|
153
156
|
}
|
|
154
157
|
},
|
|
155
158
|
"states": [
|
|
@@ -119,7 +119,20 @@ events:
|
|
|
119
119
|
description: The [label] attribute value.
|
|
120
120
|
slots:
|
|
121
121
|
default:
|
|
122
|
-
description:
|
|
122
|
+
description: |
|
|
123
|
+
Optional rich label content. When present, replaces the [label]
|
|
124
|
+
attribute's text. Consumer chrome positioned absolutely against the
|
|
125
|
+
swatch tile should use `[slot="chrome"]` instead — default-slot
|
|
126
|
+
children are funneled into the label region.
|
|
127
|
+
chrome:
|
|
128
|
+
description: |
|
|
129
|
+
§-TBD (v0.5.13, FB-34 §1). Sibling-of-tile chrome — gamut badges,
|
|
130
|
+
override/tracked dots, custom indicators — that survives stamping as
|
|
131
|
+
a direct host sibling rather than being funneled into the label. Pair
|
|
132
|
+
with consumer-authored CSS `position: absolute` against the host
|
|
133
|
+
(the host carries `position: relative` when `shape="block"`, so
|
|
134
|
+
`top/right/bottom/left` offsets anchor to the tile's geometry).
|
|
135
|
+
Closes the C1.3 dogfood chrome-overlay composition gap.
|
|
123
136
|
states:
|
|
124
137
|
- name: idle
|
|
125
138
|
description: Default, ready for display.
|
|
@@ -59,7 +59,7 @@ switch-ui[checked] [slot="thumb"] {
|
|
|
59
59
|
--switch-thumb-travel: calc(var(--switch-track-width) - var(--switch-thumb-size) - 2 * var(--switch-thumb-inset) - 2px);
|
|
60
60
|
|
|
61
61
|
/* ── State: disabled ── */
|
|
62
|
-
--switch-fg-disabled: var(--a-
|
|
62
|
+
--switch-fg-disabled: var(--a-ui-text-disabled);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
:scope {
|
package/components/tabs/tabs.css
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
--tabs-fg: var(--a-fg-subtle);
|
|
14
14
|
--tabs-fg-hover: var(--a-fg);
|
|
15
15
|
--tabs-fg-active: var(--a-fg-selected);
|
|
16
|
-
--tabs-fg-disabled: var(--a-
|
|
16
|
+
--tabs-fg-disabled: var(--a-ui-text-disabled);
|
|
17
17
|
|
|
18
18
|
/* ── Spacing ── */
|
|
19
19
|
--tabs-vertical-gap: var(--a-space-4);
|
|
@@ -32,7 +32,7 @@ textarea-ui:not([disabled]) [slot="text"]:hover {
|
|
|
32
32
|
|
|
33
33
|
/* ── State ── */
|
|
34
34
|
--textarea-bg-hover: var(--a-ui-bg-hover);
|
|
35
|
-
--textarea-fg-hover: var(--a-
|
|
35
|
+
--textarea-fg-hover: var(--a-ui-text-hover);
|
|
36
36
|
--textarea-label-fg-focus: var(--a-fg-subtle);
|
|
37
37
|
--textarea-bg-disabled: var(--a-ui-bg-disabled);
|
|
38
38
|
--textarea-fg-disabled: var(--a-ui-text-disabled);
|
|
@@ -73,7 +73,11 @@ textarea-ui:not([disabled]) [slot="text"]:hover {
|
|
|
73
73
|
overflow-y: auto;
|
|
74
74
|
cursor: text;
|
|
75
75
|
outline: none;
|
|
76
|
-
transition:
|
|
76
|
+
transition:
|
|
77
|
+
background var(--textarea-duration) var(--textarea-easing),
|
|
78
|
+
border-color var(--textarea-duration) var(--textarea-easing),
|
|
79
|
+
color var(--textarea-duration) var(--textarea-easing),
|
|
80
|
+
box-shadow var(--textarea-duration) var(--textarea-easing);
|
|
77
81
|
}
|
|
78
82
|
/* hover rule moved outside @scope — see Safari 17.x bug note at top. */
|
|
79
83
|
:scope:not([disabled]) [slot="text"]:focus {
|
|
@@ -64,7 +64,8 @@
|
|
|
64
64
|
transition:
|
|
65
65
|
border-color var(--upload-duration) var(--upload-easing),
|
|
66
66
|
background var(--upload-duration) var(--upload-easing),
|
|
67
|
-
color var(--upload-duration) var(--upload-easing)
|
|
67
|
+
color var(--upload-duration) var(--upload-easing),
|
|
68
|
+
box-shadow var(--upload-duration) var(--upload-easing);
|
|
68
69
|
}
|
|
69
70
|
[data-dropzone]:hover {
|
|
70
71
|
border-color: var(--upload-border-hover);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adia-ai/web-components",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.14",
|
|
4
4
|
"description": "AdiaUI web components — vanilla custom elements. A2UI runtime (renderer, registry, streams, wiring) lives in @adia-ai/a2ui-runtime.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -23,6 +23,14 @@
|
|
|
23
23
|
"types": "./components/*/*.d.ts",
|
|
24
24
|
"default": "./components/*/*.js"
|
|
25
25
|
},
|
|
26
|
+
"./components/stat": {
|
|
27
|
+
"types": "./components/stat/stat-ui.d.ts",
|
|
28
|
+
"default": "./components/stat/stat-ui.js"
|
|
29
|
+
},
|
|
30
|
+
"./components/stat/stat-ui.js": {
|
|
31
|
+
"types": "./components/stat/stat-ui.d.ts",
|
|
32
|
+
"default": "./components/stat/stat-ui.js"
|
|
33
|
+
},
|
|
26
34
|
"./components/*/class": {
|
|
27
35
|
"types": "./components/*/*.d.ts",
|
|
28
36
|
"default": "./components/*/class.js"
|
package/styles/typography.css
CHANGED