@teamblind-chorus/ui 1.1.0 → 1.2.0
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/agents/catalog.md +6 -4
- package/agents/components/avatar-rail/avatar-rail.spec.json +19 -0
- package/agents/components/banner/banner.family.json +3 -1
- package/agents/components/banner/banner.md +54 -1
- package/agents/components/banner/banner.spec.json +24 -1
- package/agents/components/button/check.spec.json +19 -0
- package/agents/components/button/fab.spec.json +19 -0
- package/agents/components/button/icon.spec.json +19 -0
- package/agents/components/button/standard.spec.json +19 -0
- package/agents/components/button/text.spec.json +19 -0
- package/agents/components/button/toggle.spec.json +19 -0
- package/agents/components/chip/filter.spec.json +19 -0
- package/agents/components/chip/tag.spec.json +19 -0
- package/agents/components/empty-state/empty-state.family.json +28 -0
- package/agents/components/empty-state/empty-state.md +69 -0
- package/agents/components/empty-state/empty-state.spec.json +87 -0
- package/agents/components/form-field/input.spec.json +8 -1
- package/agents/components/form-field/search.spec.json +8 -1
- package/agents/components/form-field/select.spec.json +9 -1
- package/agents/components/form-field/textarea.spec.json +8 -1
- package/agents/components/list/accordion.spec.json +9 -0
- package/agents/components/list/entry.spec.json +19 -0
- package/agents/components/list/radio.spec.json +19 -0
- package/agents/components/list/standard.md +46 -0
- package/agents/components/list/standard.spec.json +37 -2
- package/agents/components/nav-card/nav-card.spec.json +9 -0
- package/agents/components/page-shell/page-shell.family.json +1 -1
- package/agents/components/page-shell/page-shell.md +33 -0
- package/agents/components/page-shell/page-shell.spec.json +85 -0
- package/agents/components/spinner/spinner.family.json +27 -0
- package/agents/components/spinner/spinner.md +98 -0
- package/agents/components/spinner/spinner.spec.json +82 -0
- package/agents/components/switch/switch.spec.json +9 -0
- package/agents/components/tab-bar/tab-bar.spec.json +16 -0
- package/agents/components/tabs/rounded.spec.json +19 -0
- package/agents/components/tabs/underline.spec.json +19 -0
- package/agents/manifest.json +8 -6
- package/agents/usage.json +12 -0
- package/dist/index.cjs +340 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -2
- package/dist/index.d.ts +46 -2
- package/dist/index.js +339 -61
- package/dist/index.js.map +1 -1
- package/dist/styles.css +182 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -108,13 +108,13 @@ function formatCount(value) {
|
|
|
108
108
|
return String(Math.floor(value));
|
|
109
109
|
}
|
|
110
110
|
function sizingStyle(spec, size) {
|
|
111
|
-
const
|
|
111
|
+
const s2 = spec.sizes[size] ?? spec.sizes.medium;
|
|
112
112
|
return {
|
|
113
|
-
"--badge-min-height": tokenToCss(
|
|
114
|
-
"--badge-min-width": tokenToCss(
|
|
115
|
-
"--badge-padding-block": tokenToCss(
|
|
116
|
-
"--badge-padding-inline": tokenToCss(
|
|
117
|
-
...
|
|
113
|
+
"--badge-min-height": tokenToCss(s2.minHeight),
|
|
114
|
+
"--badge-min-width": tokenToCss(s2.minWidth),
|
|
115
|
+
"--badge-padding-block": tokenToCss(s2.paddingBlock),
|
|
116
|
+
"--badge-padding-inline": tokenToCss(s2.paddingInline),
|
|
117
|
+
...s2.labelTypo ? typoStyles(s2.labelTypo) : null
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
function appearanceStyle(spec) {
|
|
@@ -238,10 +238,12 @@ function useFullBleedGuard(ref, name) {
|
|
|
238
238
|
function Banner({
|
|
239
239
|
appearance = "default",
|
|
240
240
|
outlined = false,
|
|
241
|
+
neutralBody = false,
|
|
241
242
|
title,
|
|
242
243
|
icon,
|
|
243
244
|
thumbnail,
|
|
244
245
|
action,
|
|
246
|
+
trailingAction,
|
|
245
247
|
trailingIcon,
|
|
246
248
|
children,
|
|
247
249
|
className,
|
|
@@ -257,6 +259,7 @@ function Banner({
|
|
|
257
259
|
"chorus-banner",
|
|
258
260
|
`chorus-banner--${appearance}`,
|
|
259
261
|
outlined && "chorus-banner--outlined",
|
|
262
|
+
neutralBody && "chorus-banner--neutral-body",
|
|
260
263
|
className
|
|
261
264
|
),
|
|
262
265
|
role: "note",
|
|
@@ -277,7 +280,7 @@ function Banner({
|
|
|
277
280
|
}
|
|
278
281
|
) : null
|
|
279
282
|
] }),
|
|
280
|
-
trailingIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-banner__trailing-icon", "aria-hidden": "true", children: trailingIcon }) : null
|
|
283
|
+
trailingAction ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-banner__trailing-action", children: trailingAction }) : trailingIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-banner__trailing-icon", "aria-hidden": "true", children: trailingIcon }) : null
|
|
281
284
|
]
|
|
282
285
|
}
|
|
283
286
|
);
|
|
@@ -374,16 +377,16 @@ var standard_spec_default = {
|
|
|
374
377
|
insetColor: "sys.color.focusInset"
|
|
375
378
|
}}};
|
|
376
379
|
function sizeStyle(size) {
|
|
377
|
-
const
|
|
380
|
+
const s2 = standard_spec_default.sizes[size] ?? standard_spec_default.sizes[standard_spec_default.props.size.default];
|
|
378
381
|
return {
|
|
379
|
-
"--button-standard-padding-block": tokenToCss(
|
|
380
|
-
"--button-standard-padding-inline": tokenToCss(
|
|
381
|
-
"--button-standard-gap": tokenToCss(
|
|
382
|
-
"--button-standard-min-height": tokenToCss(
|
|
383
|
-
"--button-standard-min-width": tokenToCss(
|
|
384
|
-
"--button-standard-radius": tokenToCss(
|
|
385
|
-
"--button-standard-icon-size": tokenToCss(
|
|
386
|
-
...typoStyles(
|
|
382
|
+
"--button-standard-padding-block": tokenToCss(s2.paddingBlock),
|
|
383
|
+
"--button-standard-padding-inline": tokenToCss(s2.paddingInline),
|
|
384
|
+
"--button-standard-gap": tokenToCss(s2.gap),
|
|
385
|
+
"--button-standard-min-height": tokenToCss(s2.minHeight),
|
|
386
|
+
"--button-standard-min-width": tokenToCss(s2.minWidth),
|
|
387
|
+
"--button-standard-radius": tokenToCss(s2.radius),
|
|
388
|
+
"--button-standard-icon-size": tokenToCss(s2.iconSize),
|
|
389
|
+
...typoStyles(s2.labelTypo)
|
|
387
390
|
};
|
|
388
391
|
}
|
|
389
392
|
function appearanceStyle2(appearance) {
|
|
@@ -490,8 +493,7 @@ var fab_spec_default = {
|
|
|
490
493
|
overlay: {
|
|
491
494
|
opacity: "sys.state.pressed"
|
|
492
495
|
}
|
|
493
|
-
}
|
|
494
|
-
},
|
|
496
|
+
}},
|
|
495
497
|
focusIndicator: {
|
|
496
498
|
overlay: {
|
|
497
499
|
opacity: "sys.state.focus"
|
|
@@ -1591,6 +1593,25 @@ var filter_spec_default = {
|
|
|
1591
1593
|
opacity: "sys.state.pressed"
|
|
1592
1594
|
}
|
|
1593
1595
|
},
|
|
1596
|
+
focused: {
|
|
1597
|
+
overlay: {
|
|
1598
|
+
color: "label",
|
|
1599
|
+
opacity: "sys.state.focus"
|
|
1600
|
+
},
|
|
1601
|
+
focusRing: {
|
|
1602
|
+
composition: "outward",
|
|
1603
|
+
layer: "::after overlay \u2014 position:absolute, inset:0, no reflow (DESIGN.md Focus ring composition)",
|
|
1604
|
+
innerCounterRing: {
|
|
1605
|
+
width: "sys.borderWidth.hairline",
|
|
1606
|
+
color: "sys.color.focusInset"
|
|
1607
|
+
},
|
|
1608
|
+
outerRing: {
|
|
1609
|
+
width: "sys.borderWidth.thin",
|
|
1610
|
+
color: "sys.color.focus"
|
|
1611
|
+
}
|
|
1612
|
+
},
|
|
1613
|
+
note: "Keyboard-focus (:focus-visible) visual. Mirrors the `focusIndicator` block (the external-reader contract); kept here so spec-only renderers see focus in the states map. Composes over the lifecycle state the chip is in; never via plain mouse click."
|
|
1614
|
+
},
|
|
1594
1615
|
disabled: {
|
|
1595
1616
|
overlay: null,
|
|
1596
1617
|
containerOpacity: "sys.state.disabled",
|
|
@@ -1698,6 +1719,25 @@ var tag_spec_default = {
|
|
|
1698
1719
|
opacity: "sys.state.pressed"
|
|
1699
1720
|
}
|
|
1700
1721
|
},
|
|
1722
|
+
focused: {
|
|
1723
|
+
overlay: {
|
|
1724
|
+
color: "label",
|
|
1725
|
+
opacity: "sys.state.focus"
|
|
1726
|
+
},
|
|
1727
|
+
focusRing: {
|
|
1728
|
+
composition: "outward",
|
|
1729
|
+
layer: "::after overlay \u2014 position:absolute, inset:0, no reflow (DESIGN.md Focus ring composition)",
|
|
1730
|
+
innerCounterRing: {
|
|
1731
|
+
width: "sys.borderWidth.hairline",
|
|
1732
|
+
color: "sys.color.focusInset"
|
|
1733
|
+
},
|
|
1734
|
+
outerRing: {
|
|
1735
|
+
width: "sys.borderWidth.thin",
|
|
1736
|
+
color: "sys.color.focus"
|
|
1737
|
+
}
|
|
1738
|
+
},
|
|
1739
|
+
note: "Keyboard-focus (:focus-visible) visual. Mirrors the `focusIndicator` block (the external-reader contract); kept here so spec-only renderers see focus in the states map. Composes over the lifecycle state the chip is in; never via plain mouse click."
|
|
1740
|
+
},
|
|
1701
1741
|
disabled: {
|
|
1702
1742
|
overlay: null,
|
|
1703
1743
|
containerOpacity: "sys.state.disabled",
|
|
@@ -1823,6 +1863,25 @@ var toggle_spec_default = {
|
|
|
1823
1863
|
opacity: "sys.state.pressed"
|
|
1824
1864
|
}
|
|
1825
1865
|
},
|
|
1866
|
+
focused: {
|
|
1867
|
+
overlay: {
|
|
1868
|
+
color: "label",
|
|
1869
|
+
opacity: "sys.state.focus"
|
|
1870
|
+
},
|
|
1871
|
+
focusRing: {
|
|
1872
|
+
composition: "outward",
|
|
1873
|
+
layer: "::after overlay \u2014 position:absolute, inset:0, no reflow (DESIGN.md Focus ring composition)",
|
|
1874
|
+
innerCounterRing: {
|
|
1875
|
+
width: "sys.borderWidth.hairline",
|
|
1876
|
+
color: "sys.color.focusInset"
|
|
1877
|
+
},
|
|
1878
|
+
outerRing: {
|
|
1879
|
+
width: "sys.borderWidth.thin",
|
|
1880
|
+
color: "sys.color.focus"
|
|
1881
|
+
}
|
|
1882
|
+
},
|
|
1883
|
+
note: "Keyboard-focus (:focus-visible) visual. Mirrors the `focusIndicator` block (the external-reader contract); kept here so spec-only renderers see focus in the states map. Composes over the lifecycle state the button is in; never via plain mouse click."
|
|
1884
|
+
},
|
|
1826
1885
|
disabled: {
|
|
1827
1886
|
overlay: null,
|
|
1828
1887
|
containerOpacity: "sys.state.disabled",
|
|
@@ -2009,6 +2068,46 @@ var Button = react.forwardRef(function Button2({ variant, ...rest }, ref) {
|
|
|
2009
2068
|
const Impl = variant && VARIANTS[variant] || ButtonStandard;
|
|
2010
2069
|
return /* @__PURE__ */ jsxRuntime.jsx(Impl, { ref, ...rest });
|
|
2011
2070
|
});
|
|
2071
|
+
var FOCUSABLE_SELECTOR = [
|
|
2072
|
+
"a[href]",
|
|
2073
|
+
"button",
|
|
2074
|
+
"input",
|
|
2075
|
+
"select",
|
|
2076
|
+
"textarea",
|
|
2077
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
2078
|
+
].join(",");
|
|
2079
|
+
function useFocusTrap(ref, active) {
|
|
2080
|
+
react.useEffect(() => {
|
|
2081
|
+
if (!active) return void 0;
|
|
2082
|
+
const onKey = (e) => {
|
|
2083
|
+
if (e.key !== "Tab") return;
|
|
2084
|
+
const container = ref.current;
|
|
2085
|
+
if (!container) return;
|
|
2086
|
+
const focusable = Array.from(
|
|
2087
|
+
container.querySelectorAll(FOCUSABLE_SELECTOR)
|
|
2088
|
+
).filter((el) => !el.disabled && el.offsetParent !== null);
|
|
2089
|
+
if (focusable.length === 0) {
|
|
2090
|
+
e.preventDefault();
|
|
2091
|
+
container.focus({ preventScroll: true });
|
|
2092
|
+
return;
|
|
2093
|
+
}
|
|
2094
|
+
const first = focusable[0];
|
|
2095
|
+
const last = focusable[focusable.length - 1];
|
|
2096
|
+
const activeEl = document.activeElement;
|
|
2097
|
+
if (e.shiftKey) {
|
|
2098
|
+
if (activeEl === first || !container.contains(activeEl)) {
|
|
2099
|
+
e.preventDefault();
|
|
2100
|
+
last.focus({ preventScroll: true });
|
|
2101
|
+
}
|
|
2102
|
+
} else if (activeEl === last || !container.contains(activeEl)) {
|
|
2103
|
+
e.preventDefault();
|
|
2104
|
+
first.focus({ preventScroll: true });
|
|
2105
|
+
}
|
|
2106
|
+
};
|
|
2107
|
+
document.addEventListener("keydown", onKey);
|
|
2108
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
2109
|
+
}, [ref, active]);
|
|
2110
|
+
}
|
|
2012
2111
|
function useBodyScrollLock(locked) {
|
|
2013
2112
|
react.useEffect(() => {
|
|
2014
2113
|
if (!locked) return void 0;
|
|
@@ -2048,6 +2147,7 @@ function BottomSheet({
|
|
|
2048
2147
|
const lastFocusedRef = react.useRef(null);
|
|
2049
2148
|
const [overflowing, setOverflowing] = react.useState(false);
|
|
2050
2149
|
useBodyScrollLock(open && !inline);
|
|
2150
|
+
useFocusTrap(cardRef, open && !inline);
|
|
2051
2151
|
react.useEffect(() => {
|
|
2052
2152
|
if (!open || inline) return void 0;
|
|
2053
2153
|
const vv = typeof window !== "undefined" ? window.visualViewport : null;
|
|
@@ -2111,6 +2211,7 @@ function BottomSheet({
|
|
|
2111
2211
|
className: "chorus-bottom-sheet__card",
|
|
2112
2212
|
role: "dialog",
|
|
2113
2213
|
"aria-modal": "true",
|
|
2214
|
+
tabIndex: -1,
|
|
2114
2215
|
"aria-label": ariaLabel ?? title,
|
|
2115
2216
|
onClick: (e) => e.stopPropagation(),
|
|
2116
2217
|
...rest,
|
|
@@ -2429,6 +2530,26 @@ function List({
|
|
|
2429
2530
|
if (isRadio) onChange == null ? void 0 : onChange(item.value);
|
|
2430
2531
|
(_a = item.onClick) == null ? void 0 : _a.call(item);
|
|
2431
2532
|
};
|
|
2533
|
+
const rowMain = isEntry ? null : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2534
|
+
isRadio ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-list__leading", children: /* @__PURE__ */ jsxRuntime.jsx(RadioIndicator, { selected }) }) : item.thumbnail ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-list__leading chorus-list__leading--image", children: /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { size: 40, ...item.thumbnail }) }) : item.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-list__leading chorus-list__leading--icon", "aria-hidden": "true", children: item.icon }) : null,
|
|
2535
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "chorus-list__label-col", children: [
|
|
2536
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "chorus-list__primary-row", children: [
|
|
2537
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-list__label", children: item.label }),
|
|
2538
|
+
item.count != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-list__count", children: item.count }) : null
|
|
2539
|
+
] }),
|
|
2540
|
+
item.supportingText ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-list__supporting", children: item.supportingText }) : null
|
|
2541
|
+
] }),
|
|
2542
|
+
item.nav && !item.trailingIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-list__trailing chorus-list__nav-chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { size: 16 }) }) : item.trailingIcon ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2543
|
+
"span",
|
|
2544
|
+
{
|
|
2545
|
+
className: "chorus-list__trailing",
|
|
2546
|
+
"data-nested-action": "",
|
|
2547
|
+
onClick: (e) => e.stopPropagation(),
|
|
2548
|
+
onKeyDown: (e) => e.stopPropagation(),
|
|
2549
|
+
children: item.trailingIcon
|
|
2550
|
+
}
|
|
2551
|
+
) : null
|
|
2552
|
+
] });
|
|
2432
2553
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2433
2554
|
"div",
|
|
2434
2555
|
{
|
|
@@ -2463,26 +2584,26 @@ function List({
|
|
|
2463
2584
|
description: item.description,
|
|
2464
2585
|
trailing: item.trailingIcon
|
|
2465
2586
|
}
|
|
2466
|
-
) :
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
)
|
|
2485
|
-
|
|
2587
|
+
) : item.banner ? (
|
|
2588
|
+
// Embedded-Banner row — the text group stacks over a Banner
|
|
2589
|
+
// that spans the row's full content width, 8px (stack.xs)
|
|
2590
|
+
// below. The Banner is a nested action region: its own
|
|
2591
|
+
// controls never commit the row, and the row's hover/press
|
|
2592
|
+
// overlay is suppressed over it (see styles.css).
|
|
2593
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "chorus-list__stack", children: [
|
|
2594
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-list__row-main", children: rowMain }),
|
|
2595
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2596
|
+
"span",
|
|
2597
|
+
{
|
|
2598
|
+
className: "chorus-list__banner",
|
|
2599
|
+
"data-nested-action": "",
|
|
2600
|
+
onClick: (e) => e.stopPropagation(),
|
|
2601
|
+
onKeyDown: (e) => e.stopPropagation(),
|
|
2602
|
+
children: item.banner
|
|
2603
|
+
}
|
|
2604
|
+
)
|
|
2605
|
+
] })
|
|
2606
|
+
) : rowMain
|
|
2486
2607
|
},
|
|
2487
2608
|
item.value ?? idx
|
|
2488
2609
|
);
|
|
@@ -2742,6 +2863,7 @@ function Dialog({
|
|
|
2742
2863
|
const cardRef = react.useRef(null);
|
|
2743
2864
|
const lastFocusedRef = react.useRef(null);
|
|
2744
2865
|
useBodyScrollLock(open && !inline);
|
|
2866
|
+
useFocusTrap(cardRef, open && !inline);
|
|
2745
2867
|
react.useEffect(() => {
|
|
2746
2868
|
var _a;
|
|
2747
2869
|
if (!open) return void 0;
|
|
@@ -2787,6 +2909,7 @@ function Dialog({
|
|
|
2787
2909
|
className: joinClasses("chorus-dialog__card", image && "chorus-dialog__card--with-image"),
|
|
2788
2910
|
role: "dialog",
|
|
2789
2911
|
"aria-modal": "true",
|
|
2912
|
+
tabIndex: -1,
|
|
2790
2913
|
"aria-label": ariaLabel ?? title,
|
|
2791
2914
|
onClick: (e) => e.stopPropagation(),
|
|
2792
2915
|
...rest,
|
|
@@ -2820,6 +2943,80 @@ function Divider({
|
|
|
2820
2943
|
}
|
|
2821
2944
|
);
|
|
2822
2945
|
}
|
|
2946
|
+
|
|
2947
|
+
// ../../schema/components/empty-state/empty-state.spec.json
|
|
2948
|
+
var empty_state_spec_default = {
|
|
2949
|
+
sizing: {
|
|
2950
|
+
illustrationSize: "ref.space.600",
|
|
2951
|
+
illustrationColor: "sys.color.onSurfaceVariant",
|
|
2952
|
+
illustrationGap: "sys.layout.stack.sm",
|
|
2953
|
+
headlineTypo: "sys.typo.heading.sm",
|
|
2954
|
+
headlineColor: "sys.color.onSurface",
|
|
2955
|
+
bodyTypo: "sys.typo.body.sm",
|
|
2956
|
+
bodyColor: "sys.color.onSurfaceVariant",
|
|
2957
|
+
bodyGap: "sys.layout.stack.2xs",
|
|
2958
|
+
actionGap: "sys.layout.stack.md"
|
|
2959
|
+
}};
|
|
2960
|
+
var s = empty_state_spec_default.sizing;
|
|
2961
|
+
var CONTAINER_STYLE = {
|
|
2962
|
+
"--empty-state-illustration-gap": tokenToCss(s.illustrationGap),
|
|
2963
|
+
"--empty-state-body-gap": tokenToCss(s.bodyGap),
|
|
2964
|
+
"--empty-state-action-gap": tokenToCss(s.actionGap)
|
|
2965
|
+
};
|
|
2966
|
+
var ILLUSTRATION_STYLE = {
|
|
2967
|
+
"--empty-state-illustration-size": tokenToCss(s.illustrationSize),
|
|
2968
|
+
"--empty-state-illustration-color": tokenToCss(s.illustrationColor)
|
|
2969
|
+
};
|
|
2970
|
+
var HEADLINE_STYLE = {
|
|
2971
|
+
"--empty-state-headline-color": tokenToCss(s.headlineColor),
|
|
2972
|
+
...typoStyles(s.headlineTypo)
|
|
2973
|
+
};
|
|
2974
|
+
var BODY_STYLE = {
|
|
2975
|
+
"--empty-state-body-color": tokenToCss(s.bodyColor),
|
|
2976
|
+
...typoStyles(s.bodyTypo)
|
|
2977
|
+
};
|
|
2978
|
+
function EmptyState({
|
|
2979
|
+
illustration,
|
|
2980
|
+
headline,
|
|
2981
|
+
body,
|
|
2982
|
+
action,
|
|
2983
|
+
className,
|
|
2984
|
+
style,
|
|
2985
|
+
...rest
|
|
2986
|
+
}) {
|
|
2987
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2988
|
+
"div",
|
|
2989
|
+
{
|
|
2990
|
+
role: "status",
|
|
2991
|
+
className: joinClasses("chorus-empty-state", className),
|
|
2992
|
+
style: { ...CONTAINER_STYLE, ...style },
|
|
2993
|
+
...rest,
|
|
2994
|
+
children: [
|
|
2995
|
+
illustration ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2996
|
+
"span",
|
|
2997
|
+
{
|
|
2998
|
+
className: "chorus-empty-state__illustration",
|
|
2999
|
+
"aria-hidden": "true",
|
|
3000
|
+
style: ILLUSTRATION_STYLE,
|
|
3001
|
+
children: illustration
|
|
3002
|
+
}
|
|
3003
|
+
) : null,
|
|
3004
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "chorus-empty-state__headline", style: HEADLINE_STYLE, children: headline }),
|
|
3005
|
+
body ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "chorus-empty-state__body", style: BODY_STYLE, children: body }) : null,
|
|
3006
|
+
action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "chorus-empty-state__action", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3007
|
+
Button,
|
|
3008
|
+
{
|
|
3009
|
+
appearance: "primary",
|
|
3010
|
+
onClick: action.onClick ?? (action.href ? () => {
|
|
3011
|
+
window.location.assign(action.href);
|
|
3012
|
+
} : void 0),
|
|
3013
|
+
children: action.label
|
|
3014
|
+
}
|
|
3015
|
+
) }) : null
|
|
3016
|
+
]
|
|
3017
|
+
}
|
|
3018
|
+
);
|
|
3019
|
+
}
|
|
2823
3020
|
var TabsContext = react.createContext({
|
|
2824
3021
|
variant: "underline",
|
|
2825
3022
|
value: null,
|
|
@@ -2942,19 +3139,19 @@ function TabsUnderline({ className, style, children, ...rest }) {
|
|
|
2942
3139
|
useScrollOverflow(ref);
|
|
2943
3140
|
useSlidingIndicator(ref, indicatorRef, value);
|
|
2944
3141
|
useFullBleedGuard(ref, "Tabs");
|
|
2945
|
-
const
|
|
3142
|
+
const s2 = underline_spec_default.sizing;
|
|
2946
3143
|
const composedStyle = {
|
|
2947
|
-
"--tabs-container-padding-inline": tokenToCss(
|
|
2948
|
-
"--tabs-tab-min-height": tokenToCss(
|
|
2949
|
-
"--tabs-tab-padding-block": tokenToCss(
|
|
2950
|
-
"--tabs-tab-padding-inline": tokenToCss(
|
|
2951
|
-
"--tabs-inter-tab-gap": tokenToCss(
|
|
2952
|
-
"--tabs-slot-gap": tokenToCss(
|
|
2953
|
-
"--tabs-icon-size": tokenToCss(
|
|
2954
|
-
"--tabs-indicator-height": tokenToCss(
|
|
2955
|
-
"--tabs-divider-width": tokenToCss(
|
|
2956
|
-
"--tabs-divider-color": tokenToCss(
|
|
2957
|
-
"--tabs-fade-width": tokenToCss(
|
|
3144
|
+
"--tabs-container-padding-inline": tokenToCss(s2.containerPaddingInline),
|
|
3145
|
+
"--tabs-tab-min-height": tokenToCss(s2.minHeight),
|
|
3146
|
+
"--tabs-tab-padding-block": tokenToCss(s2.paddingBlock),
|
|
3147
|
+
"--tabs-tab-padding-inline": tokenToCss(s2.paddingInline),
|
|
3148
|
+
"--tabs-inter-tab-gap": tokenToCss(s2.interTabGap),
|
|
3149
|
+
"--tabs-slot-gap": tokenToCss(s2.slotGap),
|
|
3150
|
+
"--tabs-icon-size": tokenToCss(s2.iconSize),
|
|
3151
|
+
"--tabs-indicator-height": tokenToCss(s2.indicatorHeight),
|
|
3152
|
+
"--tabs-divider-width": tokenToCss(s2.dividerWidth),
|
|
3153
|
+
"--tabs-divider-color": tokenToCss(s2.dividerColor),
|
|
3154
|
+
"--tabs-fade-width": tokenToCss(s2.fadeWidth),
|
|
2958
3155
|
"--tabs-label-unselected": tokenToCss(underline_spec_default.selectionStates.unselected.label),
|
|
2959
3156
|
"--tabs-label-selected": tokenToCss(underline_spec_default.selectionStates.selected.label),
|
|
2960
3157
|
"--tabs-indicator-color": tokenToCss(underline_spec_default.selectionStates.selected.indicator),
|
|
@@ -2966,7 +3163,7 @@ function TabsUnderline({ className, style, children, ...rest }) {
|
|
|
2966
3163
|
"--tabs-focus-outer-color": tokenToCss(underline_spec_default.focusIndicator.ring.outerColor),
|
|
2967
3164
|
"--tabs-focus-inset-width": tokenToCss(underline_spec_default.focusIndicator.ring.insetWidth),
|
|
2968
3165
|
"--tabs-focus-inset-color": tokenToCss(underline_spec_default.focusIndicator.ring.insetColor),
|
|
2969
|
-
...typoStyles(
|
|
3166
|
+
...typoStyles(s2.labelTypo),
|
|
2970
3167
|
...style
|
|
2971
3168
|
};
|
|
2972
3169
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -3028,12 +3225,12 @@ function TabsSegmented({ className, style, children, ...rest }) {
|
|
|
3028
3225
|
const ref = react.useRef(null);
|
|
3029
3226
|
useScrollOverflow(ref);
|
|
3030
3227
|
useFullBleedGuard(ref, "Tabs");
|
|
3031
|
-
const
|
|
3228
|
+
const s2 = segmented_spec_default.sizing;
|
|
3032
3229
|
const composedStyle = {
|
|
3033
|
-
"--tabs-container-padding-block": tokenToCss(
|
|
3034
|
-
"--tabs-container-padding-inline": tokenToCss(
|
|
3035
|
-
"--tabs-inter-segment-gap": tokenToCss(
|
|
3036
|
-
"--tabs-fade-width": tokenToCss(
|
|
3230
|
+
"--tabs-container-padding-block": tokenToCss(s2.containerPaddingBlock),
|
|
3231
|
+
"--tabs-container-padding-inline": tokenToCss(s2.containerPaddingInline),
|
|
3232
|
+
"--tabs-inter-segment-gap": tokenToCss(s2.interSegmentGap),
|
|
3233
|
+
"--tabs-fade-width": tokenToCss(s2.fadeWidth),
|
|
3037
3234
|
...style
|
|
3038
3235
|
};
|
|
3039
3236
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4373,12 +4570,19 @@ var input_spec_default = {
|
|
|
4373
4570
|
nestedActionScope: "The pressed overlay (and hover stroke) is suppressed while the pointer presses / hovers the trailing clear button \u2014 that '\xD7' is an independent nested action, so the small control owns the state and the large field does not also read as pressed. The visual-state boundary matches the action boundary."
|
|
4374
4571
|
},
|
|
4375
4572
|
active: {
|
|
4573
|
+
isFocusState: true,
|
|
4376
4574
|
overlay: null,
|
|
4377
4575
|
border: "borderActive",
|
|
4378
4576
|
strokeWeight: "activeStrokeWeight",
|
|
4379
4577
|
caret: "visible",
|
|
4380
4578
|
showsClearWhenValue: true,
|
|
4381
|
-
|
|
4579
|
+
focusRing: {
|
|
4580
|
+
composition: "outward",
|
|
4581
|
+
layer: "::after overlay \u2014 position:absolute, inset:0, no reflow (DESIGN.md Focus ring composition)",
|
|
4582
|
+
innerCounterRing: { width: "sys.borderWidth.hairline", color: "sys.color.focusInset" },
|
|
4583
|
+
outerRing: { width: "sys.borderWidth.thin", color: "sys.color.focus" }
|
|
4584
|
+
},
|
|
4585
|
+
note: "This IS the field's keyboard/input-focus state \u2014 `active` (caret visible, input engaged) and `:focus-visible` coincide for a text field, so there is no separate `focused` state; the focus ring described here (and in the parallel `focusIndicator` block) is the focus affordance. The stroke steps from its rest `hairline` (1px) to `activeStrokeWeight` (2px) and re-tones to `borderActive` \u2014 but it is an inset `box-shadow`, not a `border`, so the box model is untouched: the field's footprint, caret, and text position are pixel-stable as it goes active. Nothing reflows. The clear button is shown only in this state (and only when the value is non-empty)."
|
|
4382
4586
|
},
|
|
4383
4587
|
disabled: {
|
|
4384
4588
|
overlay: null,
|
|
@@ -4560,11 +4764,18 @@ var textarea_spec_default = {
|
|
|
4560
4764
|
nestedActionScope: "The pressed overlay (and hover stroke) is suppressed while the pointer presses / hovers the trailing clear button \u2014 that '\xD7' is an independent nested action, so the small control owns the state and the large field does not also read as pressed. The visual-state boundary matches the action boundary."
|
|
4561
4765
|
},
|
|
4562
4766
|
active: {
|
|
4767
|
+
isFocusState: true,
|
|
4563
4768
|
overlay: null,
|
|
4564
4769
|
border: "borderActive",
|
|
4565
4770
|
strokeWeight: "activeStrokeWeight",
|
|
4566
4771
|
caret: "visible",
|
|
4567
|
-
|
|
4772
|
+
focusRing: {
|
|
4773
|
+
composition: "outward",
|
|
4774
|
+
layer: "::after overlay \u2014 position:absolute, inset:0, no reflow (DESIGN.md Focus ring composition)",
|
|
4775
|
+
innerCounterRing: { width: "sys.borderWidth.hairline", color: "sys.color.focusInset" },
|
|
4776
|
+
outerRing: { width: "sys.borderWidth.thin", color: "sys.color.focus" }
|
|
4777
|
+
},
|
|
4778
|
+
note: "This IS the field's keyboard/input-focus state \u2014 `active` (caret visible, input engaged) and `:focus-visible` coincide for a text field, so there is no separate `focused` state; the focus ring described here (and in the parallel `focusIndicator` block) is the focus affordance. Stroke steps from `hairline` (1px) to `activeStrokeWeight` (2px) as an inset box-shadow \u2014 same pixel-stable contract as input."
|
|
4568
4779
|
},
|
|
4569
4780
|
disabled: {
|
|
4570
4781
|
overlay: null,
|
|
@@ -4698,12 +4909,19 @@ var search_spec_default = {
|
|
|
4698
4909
|
nestedActionScope: "The pressed overlay (and hover stroke) is suppressed while the pointer presses / hovers the trailing clear button \u2014 that '\xD7' is an independent nested action, so the small control owns the state and the large field does not also read as pressed. The visual-state boundary matches the action boundary."
|
|
4699
4910
|
},
|
|
4700
4911
|
active: {
|
|
4912
|
+
isFocusState: true,
|
|
4701
4913
|
overlay: null,
|
|
4702
4914
|
border: "borderActive",
|
|
4703
4915
|
strokeWeight: "activeStrokeWeight",
|
|
4704
4916
|
caret: "visible",
|
|
4705
4917
|
showsClearWhenValue: true,
|
|
4706
|
-
|
|
4918
|
+
focusRing: {
|
|
4919
|
+
composition: "outward",
|
|
4920
|
+
layer: "::after overlay \u2014 position:absolute, inset:0, no reflow (DESIGN.md Focus ring composition)",
|
|
4921
|
+
innerCounterRing: { width: "sys.borderWidth.hairline", color: "sys.color.focusInset" },
|
|
4922
|
+
outerRing: { width: "sys.borderWidth.thin", color: "sys.color.focus" }
|
|
4923
|
+
},
|
|
4924
|
+
note: "This IS the field's keyboard/input-focus state \u2014 `active` (caret visible, input engaged) and `:focus-visible` coincide for a text field, so there is no separate `focused` state; the focus ring described here (and in the parallel `focusIndicator` block) is the focus affordance. The stroke steps from its rest `hairline` (1px) to `activeStrokeWeight` (2px) and re-tones to `borderActive` \u2014 but it is an inset `box-shadow`, not a `border`, so the box model is untouched: the field's footprint, caret, and text position are pixel-stable as it goes active. Nothing reflows. The clear button is shown only in this state (and only when the value is non-empty)."
|
|
4707
4925
|
},
|
|
4708
4926
|
disabled: {
|
|
4709
4927
|
overlay: null,
|
|
@@ -4890,9 +5108,17 @@ var select_spec_default = {
|
|
|
4890
5108
|
}
|
|
4891
5109
|
},
|
|
4892
5110
|
active: {
|
|
5111
|
+
isFocusState: true,
|
|
4893
5112
|
overlay: null,
|
|
4894
5113
|
border: "borderActive",
|
|
4895
|
-
strokeWeight: "activeStrokeWeight"
|
|
5114
|
+
strokeWeight: "activeStrokeWeight",
|
|
5115
|
+
focusRing: {
|
|
5116
|
+
composition: "outward",
|
|
5117
|
+
layer: "::after overlay \u2014 position:absolute, inset:0, no reflow (DESIGN.md Focus ring composition)",
|
|
5118
|
+
innerCounterRing: { width: "sys.borderWidth.hairline", color: "sys.color.focusInset" },
|
|
5119
|
+
outerRing: { width: "sys.borderWidth.thin", color: "sys.color.focus" }
|
|
5120
|
+
},
|
|
5121
|
+
note: "This IS the trigger's keyboard-focus / open state \u2014 `:focus-visible` and the engaged (open) state coincide for the select trigger, so there is no separate `focused` state; the focus ring described here (and in the parallel `focusIndicator` block) is the focus affordance. The stroke re-tones to `borderActive` at `activeStrokeWeight` (2px) as an inset box-shadow, pixel-stable (no reflow)."
|
|
4896
5122
|
},
|
|
4897
5123
|
disabled: {
|
|
4898
5124
|
overlay: null,
|
|
@@ -5513,6 +5739,58 @@ function SkeletonGroup({
|
|
|
5513
5739
|
}
|
|
5514
5740
|
);
|
|
5515
5741
|
}
|
|
5742
|
+
|
|
5743
|
+
// ../../schema/components/spinner/spinner.spec.json
|
|
5744
|
+
var spinner_spec_default = {
|
|
5745
|
+
sizes: {
|
|
5746
|
+
medium: {
|
|
5747
|
+
diameter: "sys.icon.lg",
|
|
5748
|
+
labelTypo: "sys.typo.body.sm",
|
|
5749
|
+
gap: "sys.layout.inline.sm"
|
|
5750
|
+
},
|
|
5751
|
+
small: {
|
|
5752
|
+
diameter: "sys.icon.md",
|
|
5753
|
+
labelTypo: "sys.typo.body.sm",
|
|
5754
|
+
gap: "sys.layout.inline.sm"
|
|
5755
|
+
}
|
|
5756
|
+
}};
|
|
5757
|
+
function sizingStyle4(spec, size) {
|
|
5758
|
+
const s2 = spec.sizes[size] ?? spec.sizes.medium;
|
|
5759
|
+
return {
|
|
5760
|
+
"--spinner-diameter": tokenToCss(s2.diameter),
|
|
5761
|
+
"--spinner-gap": tokenToCss(s2.gap)
|
|
5762
|
+
};
|
|
5763
|
+
}
|
|
5764
|
+
function Spinner({
|
|
5765
|
+
size = "medium",
|
|
5766
|
+
label,
|
|
5767
|
+
className,
|
|
5768
|
+
style,
|
|
5769
|
+
"aria-label": ariaLabel,
|
|
5770
|
+
...rest
|
|
5771
|
+
}) {
|
|
5772
|
+
var _a;
|
|
5773
|
+
const labelTypo = ((_a = spinner_spec_default.sizes[size]) == null ? void 0 : _a.labelTypo) ?? spinner_spec_default.sizes.medium.labelTypo;
|
|
5774
|
+
const a11yLabel = label != null ? void 0 : ariaLabel ?? "Loading";
|
|
5775
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5776
|
+
"span",
|
|
5777
|
+
{
|
|
5778
|
+
role: "status",
|
|
5779
|
+
"aria-label": a11yLabel,
|
|
5780
|
+
className: joinClasses(
|
|
5781
|
+
"chorus-spinner",
|
|
5782
|
+
`chorus-spinner--${size}`,
|
|
5783
|
+
className
|
|
5784
|
+
),
|
|
5785
|
+
style: { ...sizingStyle4(spinner_spec_default, size), ...style },
|
|
5786
|
+
...rest,
|
|
5787
|
+
children: [
|
|
5788
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-spinner__arc", "aria-hidden": "true" }),
|
|
5789
|
+
label != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-spinner__label", style: typoStyles(labelTypo), children: label }) : null
|
|
5790
|
+
]
|
|
5791
|
+
}
|
|
5792
|
+
);
|
|
5793
|
+
}
|
|
5516
5794
|
function StatusTag({
|
|
5517
5795
|
appearance = "neutral",
|
|
5518
5796
|
children,
|
|
@@ -5918,6 +6196,7 @@ exports.Dialog = Dialog;
|
|
|
5918
6196
|
exports.DirectoryList = DirectoryList;
|
|
5919
6197
|
exports.Divider = Divider;
|
|
5920
6198
|
exports.Drawer = BottomSheet;
|
|
6199
|
+
exports.EmptyState = EmptyState;
|
|
5921
6200
|
exports.Feed = Feed;
|
|
5922
6201
|
exports.FeedAd = FeedAd;
|
|
5923
6202
|
exports.FeedGroup = FeedGroup;
|
|
@@ -5946,6 +6225,7 @@ exports.SideSheet = SideSheet;
|
|
|
5946
6225
|
exports.SideSheetGroup = SideSheetGroup;
|
|
5947
6226
|
exports.Skeleton = Skeleton;
|
|
5948
6227
|
exports.SkeletonGroup = SkeletonGroup;
|
|
6228
|
+
exports.Spinner = Spinner;
|
|
5949
6229
|
exports.StatusTag = StatusTag;
|
|
5950
6230
|
exports.SubHeader = SubHeader;
|
|
5951
6231
|
exports.SuggestionList = SuggestionList;
|