@teamblind-chorus/ui 1.0.1 → 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/AGENTS.md +4 -6
- package/agents/DESIGN.md +2 -0
- package/agents/LOVABLE.md +167 -373
- package/agents/anti-patterns.md +2 -2
- package/agents/catalog.md +12 -6
- package/agents/components/avatar-rail/avatar-rail.md +2 -0
- package/agents/components/avatar-rail/avatar-rail.spec.json +19 -0
- package/agents/components/badge/badge.md +2 -0
- package/agents/components/badge/role.md +2 -0
- package/agents/components/badge/update.md +2 -0
- package/agents/components/banner/banner.family.json +3 -1
- package/agents/components/banner/banner.md +125 -9
- package/agents/components/banner/banner.spec.json +64 -3
- package/agents/components/bottom-sheet/bottom-sheet.md +2 -0
- package/agents/components/bubble/bubble.md +2 -0
- package/agents/components/button/button.family.json +8 -2
- package/agents/components/button/button.md +2 -0
- package/agents/components/button/check.md +2 -0
- package/agents/components/button/check.spec.json +19 -0
- package/agents/components/button/fab.md +2 -0
- package/agents/components/button/fab.spec.json +19 -0
- package/agents/components/button/group.spec.json +65 -0
- package/agents/components/button/icon.md +2 -0
- package/agents/components/button/icon.spec.json +19 -0
- package/agents/components/button/standard.md +45 -19
- package/agents/components/button/standard.spec.json +19 -0
- package/agents/components/button/text.md +2 -0
- package/agents/components/button/text.spec.json +19 -0
- package/agents/components/button/toggle.md +2 -0
- package/agents/components/button/toggle.spec.json +19 -0
- package/agents/components/button/toolbar.md +2 -0
- package/agents/components/carousel/carousel.md +2 -0
- package/agents/components/carousel/post.md +5 -3
- package/agents/components/carousel/post.spec.json +4 -6
- package/agents/components/carousel/profile.md +4 -2
- package/agents/components/carousel/profile.spec.json +4 -6
- package/agents/components/chip/chip.md +2 -0
- package/agents/components/chip/filter.md +2 -0
- package/agents/components/chip/filter.spec.json +19 -0
- package/agents/components/chip/tag.md +2 -0
- package/agents/components/chip/tag.spec.json +19 -0
- package/agents/components/dialog/dialog.md +2 -0
- package/agents/components/directory-list/directory-list.md +2 -0
- package/agents/components/divider/divider.md +2 -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/feed/ad.md +2 -0
- package/agents/components/feed/feed.md +2 -0
- package/agents/components/feed/post.md +2 -0
- package/agents/components/form-field/form-field.md +3 -1
- package/agents/components/form-field/input.md +2 -0
- package/agents/components/form-field/input.spec.json +10 -2
- package/agents/components/form-field/search.md +2 -0
- package/agents/components/form-field/search.spec.json +10 -2
- package/agents/components/form-field/select.md +2 -0
- package/agents/components/form-field/select.spec.json +9 -1
- package/agents/components/form-field/textarea.md +2 -0
- package/agents/components/form-field/textarea.spec.json +10 -2
- package/agents/components/header/header.md +2 -0
- package/agents/components/header/main.md +2 -0
- package/agents/components/header/sub.md +2 -0
- package/agents/components/list/accordion.md +2 -0
- package/agents/components/list/accordion.spec.json +9 -0
- package/agents/components/list/entry.md +2 -0
- package/agents/components/list/entry.spec.json +21 -1
- package/agents/components/list/list.md +3 -1
- package/agents/components/list/radio.md +2 -0
- package/agents/components/list/radio.spec.json +19 -0
- package/agents/components/list/standard.md +48 -0
- package/agents/components/list/standard.spec.json +39 -3
- package/agents/components/metadata/compact.md +13 -7
- package/agents/components/metadata/compact.spec.json +19 -6
- package/agents/components/metadata/metadata.family.json +3 -3
- package/agents/components/metadata/metadata.md +4 -2
- package/agents/components/metadata/standard.md +24 -0
- package/agents/components/nav-card/nav-card.md +2 -0
- package/agents/components/nav-card/nav-card.spec.json +9 -0
- package/agents/components/nav-list/nav-list.md +2 -0
- package/agents/components/navigation-bar/main.md +2 -0
- package/agents/components/navigation-bar/navigation-bar.md +2 -0
- package/agents/components/navigation-bar/search.md +2 -0
- package/agents/components/navigation-bar/sub.md +2 -0
- package/agents/components/page-shell/page-shell.family.json +1 -1
- package/agents/components/page-shell/page-shell.md +35 -0
- package/agents/components/page-shell/page-shell.spec.json +85 -0
- package/agents/components/pagination/pagination.family.json +26 -0
- package/agents/components/pagination/pagination.md +40 -0
- package/agents/components/pagination/pagination.spec.json +54 -0
- package/agents/components/profile-header/profile-header.md +2 -0
- package/agents/components/progress/progress.md +2 -0
- package/agents/components/side-sheet/side-sheet.md +2 -0
- package/agents/components/skeleton/skeleton.md +2 -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/status-tag/status-tag.md +2 -0
- package/agents/components/suggestion-list/suggestion-list.md +2 -0
- package/agents/components/switch/switch.md +2 -0
- package/agents/components/switch/switch.spec.json +9 -0
- package/agents/components/tab-bar/tab-bar.md +2 -0
- package/agents/components/tab-bar/tab-bar.spec.json +16 -0
- package/agents/components/tabs/rounded.md +2 -0
- package/agents/components/tabs/rounded.spec.json +19 -0
- package/agents/components/tabs/segmented.md +2 -0
- package/agents/components/tabs/tabs.md +2 -0
- package/agents/components/tabs/underline.md +2 -0
- package/agents/components/tabs/underline.spec.json +19 -0
- package/agents/components/thumbnail/thumbnail.md +2 -0
- package/agents/components/toast/toast.md +2 -0
- package/agents/components/tooltip/tooltip.md +2 -0
- package/agents/compose.md +3 -3
- package/agents/manifest.json +9 -6
- package/agents/patterns/README.md +2 -0
- package/agents/patterns/actions.md +2 -0
- package/agents/patterns/browsing.md +2 -0
- package/agents/patterns/communications.md +2 -0
- package/agents/patterns/layout.md +2 -0
- package/agents/patterns/modals.md +2 -0
- package/agents/patterns/visual.md +2 -0
- package/agents/usage.json +27 -3
- package/dist/index.cjs +433 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -3
- package/dist/index.d.ts +74 -3
- package/dist/index.js +430 -98
- package/dist/index.js.map +1 -1
- package/dist/styles.css +365 -41
- package/package.json +1 -2
- package/agents/reconstruct.md +0 -55
- package/agents/scoped-adoption.md +0 -111
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) {
|
|
@@ -237,9 +237,14 @@ function useFullBleedGuard(ref, name) {
|
|
|
237
237
|
}
|
|
238
238
|
function Banner({
|
|
239
239
|
appearance = "default",
|
|
240
|
+
outlined = false,
|
|
241
|
+
neutralBody = false,
|
|
242
|
+
title,
|
|
240
243
|
icon,
|
|
241
244
|
thumbnail,
|
|
242
245
|
action,
|
|
246
|
+
trailingAction,
|
|
247
|
+
trailingIcon,
|
|
243
248
|
children,
|
|
244
249
|
className,
|
|
245
250
|
...rest
|
|
@@ -250,13 +255,20 @@ function Banner({
|
|
|
250
255
|
"div",
|
|
251
256
|
{
|
|
252
257
|
ref,
|
|
253
|
-
className: joinClasses(
|
|
258
|
+
className: joinClasses(
|
|
259
|
+
"chorus-banner",
|
|
260
|
+
`chorus-banner--${appearance}`,
|
|
261
|
+
outlined && "chorus-banner--outlined",
|
|
262
|
+
neutralBody && "chorus-banner--neutral-body",
|
|
263
|
+
className
|
|
264
|
+
),
|
|
254
265
|
role: "note",
|
|
255
266
|
...rest,
|
|
256
267
|
children: [
|
|
257
268
|
thumbnail ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-banner__thumbnail", "aria-hidden": "true", children: thumbnail }) : null,
|
|
258
269
|
!thumbnail && icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-banner__icon", "aria-hidden": "true", children: icon }) : null,
|
|
259
270
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "chorus-banner__content", children: [
|
|
271
|
+
title ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "chorus-banner__title", children: title }) : null,
|
|
260
272
|
children ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "chorus-banner__body", children }) : null,
|
|
261
273
|
action ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
262
274
|
"a",
|
|
@@ -267,7 +279,8 @@ function Banner({
|
|
|
267
279
|
children: action.label
|
|
268
280
|
}
|
|
269
281
|
) : null
|
|
270
|
-
] })
|
|
282
|
+
] }),
|
|
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
|
|
271
284
|
]
|
|
272
285
|
}
|
|
273
286
|
);
|
|
@@ -364,16 +377,16 @@ var standard_spec_default = {
|
|
|
364
377
|
insetColor: "sys.color.focusInset"
|
|
365
378
|
}}};
|
|
366
379
|
function sizeStyle(size) {
|
|
367
|
-
const
|
|
380
|
+
const s2 = standard_spec_default.sizes[size] ?? standard_spec_default.sizes[standard_spec_default.props.size.default];
|
|
368
381
|
return {
|
|
369
|
-
"--button-standard-padding-block": tokenToCss(
|
|
370
|
-
"--button-standard-padding-inline": tokenToCss(
|
|
371
|
-
"--button-standard-gap": tokenToCss(
|
|
372
|
-
"--button-standard-min-height": tokenToCss(
|
|
373
|
-
"--button-standard-min-width": tokenToCss(
|
|
374
|
-
"--button-standard-radius": tokenToCss(
|
|
375
|
-
"--button-standard-icon-size": tokenToCss(
|
|
376
|
-
...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)
|
|
377
390
|
};
|
|
378
391
|
}
|
|
379
392
|
function appearanceStyle2(appearance) {
|
|
@@ -480,8 +493,7 @@ var fab_spec_default = {
|
|
|
480
493
|
overlay: {
|
|
481
494
|
opacity: "sys.state.pressed"
|
|
482
495
|
}
|
|
483
|
-
}
|
|
484
|
-
},
|
|
496
|
+
}},
|
|
485
497
|
focusIndicator: {
|
|
486
498
|
overlay: {
|
|
487
499
|
opacity: "sys.state.focus"
|
|
@@ -1581,6 +1593,25 @@ var filter_spec_default = {
|
|
|
1581
1593
|
opacity: "sys.state.pressed"
|
|
1582
1594
|
}
|
|
1583
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
|
+
},
|
|
1584
1615
|
disabled: {
|
|
1585
1616
|
overlay: null,
|
|
1586
1617
|
containerOpacity: "sys.state.disabled",
|
|
@@ -1688,6 +1719,25 @@ var tag_spec_default = {
|
|
|
1688
1719
|
opacity: "sys.state.pressed"
|
|
1689
1720
|
}
|
|
1690
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
|
+
},
|
|
1691
1741
|
disabled: {
|
|
1692
1742
|
overlay: null,
|
|
1693
1743
|
containerOpacity: "sys.state.disabled",
|
|
@@ -1813,6 +1863,25 @@ var toggle_spec_default = {
|
|
|
1813
1863
|
opacity: "sys.state.pressed"
|
|
1814
1864
|
}
|
|
1815
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
|
+
},
|
|
1816
1885
|
disabled: {
|
|
1817
1886
|
overlay: null,
|
|
1818
1887
|
containerOpacity: "sys.state.disabled",
|
|
@@ -1847,7 +1916,7 @@ var FORCEABLE_STATES3 = /* @__PURE__ */ new Set(["hovered", "pressed", "focused"
|
|
|
1847
1916
|
var SPECS = {
|
|
1848
1917
|
filter: filter_spec_default,
|
|
1849
1918
|
tag: tag_spec_default,
|
|
1850
|
-
|
|
1919
|
+
toggle: toggle_spec_default
|
|
1851
1920
|
};
|
|
1852
1921
|
function pickAppearance(spec, appearance) {
|
|
1853
1922
|
const appearances = spec.appearances || {};
|
|
@@ -1989,16 +2058,56 @@ function ButtonToggle({ active = false, ...rest }) {
|
|
|
1989
2058
|
}
|
|
1990
2059
|
var VARIANTS = {
|
|
1991
2060
|
fab: ButtonFab,
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
2061
|
+
icon: ButtonIcon,
|
|
2062
|
+
text: ButtonText,
|
|
2063
|
+
check: ButtonCheck,
|
|
2064
|
+
toolbar: ButtonToolbar,
|
|
2065
|
+
toggle: ButtonToggle
|
|
1997
2066
|
};
|
|
1998
2067
|
var Button = react.forwardRef(function Button2({ variant, ...rest }, ref) {
|
|
1999
2068
|
const Impl = variant && VARIANTS[variant] || ButtonStandard;
|
|
2000
2069
|
return /* @__PURE__ */ jsxRuntime.jsx(Impl, { ref, ...rest });
|
|
2001
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
|
+
}
|
|
2002
2111
|
function useBodyScrollLock(locked) {
|
|
2003
2112
|
react.useEffect(() => {
|
|
2004
2113
|
if (!locked) return void 0;
|
|
@@ -2038,6 +2147,7 @@ function BottomSheet({
|
|
|
2038
2147
|
const lastFocusedRef = react.useRef(null);
|
|
2039
2148
|
const [overflowing, setOverflowing] = react.useState(false);
|
|
2040
2149
|
useBodyScrollLock(open && !inline);
|
|
2150
|
+
useFocusTrap(cardRef, open && !inline);
|
|
2041
2151
|
react.useEffect(() => {
|
|
2042
2152
|
if (!open || inline) return void 0;
|
|
2043
2153
|
const vv = typeof window !== "undefined" ? window.visualViewport : null;
|
|
@@ -2101,6 +2211,7 @@ function BottomSheet({
|
|
|
2101
2211
|
className: "chorus-bottom-sheet__card",
|
|
2102
2212
|
role: "dialog",
|
|
2103
2213
|
"aria-modal": "true",
|
|
2214
|
+
tabIndex: -1,
|
|
2104
2215
|
"aria-label": ariaLabel ?? title,
|
|
2105
2216
|
onClick: (e) => e.stopPropagation(),
|
|
2106
2217
|
...rest,
|
|
@@ -2155,6 +2266,35 @@ function Bubble({
|
|
|
2155
2266
|
}
|
|
2156
2267
|
);
|
|
2157
2268
|
}
|
|
2269
|
+
function ButtonGroup({
|
|
2270
|
+
variant = "inline",
|
|
2271
|
+
orientation = "horizontal",
|
|
2272
|
+
label,
|
|
2273
|
+
children,
|
|
2274
|
+
className,
|
|
2275
|
+
"aria-label": ariaLabel,
|
|
2276
|
+
...rest
|
|
2277
|
+
}) {
|
|
2278
|
+
const docked = variant === "docked";
|
|
2279
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2280
|
+
"div",
|
|
2281
|
+
{
|
|
2282
|
+
className: joinClasses(
|
|
2283
|
+
"chorus-button-group",
|
|
2284
|
+
docked && "chorus-button-group--docked",
|
|
2285
|
+
orientation === "vertical" && "chorus-button-group--vertical",
|
|
2286
|
+
className
|
|
2287
|
+
),
|
|
2288
|
+
role: "group",
|
|
2289
|
+
"aria-label": ariaLabel,
|
|
2290
|
+
...rest,
|
|
2291
|
+
children: [
|
|
2292
|
+
label != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "chorus-button-group__label", children: label }) : null,
|
|
2293
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "chorus-button-group__row", children })
|
|
2294
|
+
]
|
|
2295
|
+
}
|
|
2296
|
+
);
|
|
2297
|
+
}
|
|
2158
2298
|
|
|
2159
2299
|
// ../../schema/components/header/main.spec.json
|
|
2160
2300
|
var main_spec_default = {
|
|
@@ -2315,6 +2455,7 @@ function EntryRow({
|
|
|
2315
2455
|
"span",
|
|
2316
2456
|
{
|
|
2317
2457
|
className: "chorus-entry-row__trailing",
|
|
2458
|
+
"data-nested-action": "",
|
|
2318
2459
|
onClick: (e) => e.stopPropagation(),
|
|
2319
2460
|
onKeyDown: (e) => e.stopPropagation(),
|
|
2320
2461
|
children: trailing
|
|
@@ -2389,6 +2530,26 @@ function List({
|
|
|
2389
2530
|
if (isRadio) onChange == null ? void 0 : onChange(item.value);
|
|
2390
2531
|
(_a = item.onClick) == null ? void 0 : _a.call(item);
|
|
2391
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
|
+
] });
|
|
2392
2553
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2393
2554
|
"div",
|
|
2394
2555
|
{
|
|
@@ -2423,25 +2584,26 @@ function List({
|
|
|
2423
2584
|
description: item.description,
|
|
2424
2585
|
trailing: item.trailingIcon
|
|
2425
2586
|
}
|
|
2426
|
-
) :
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
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
|
|
2445
2607
|
},
|
|
2446
2608
|
item.value ?? idx
|
|
2447
2609
|
);
|
|
@@ -2701,6 +2863,7 @@ function Dialog({
|
|
|
2701
2863
|
const cardRef = react.useRef(null);
|
|
2702
2864
|
const lastFocusedRef = react.useRef(null);
|
|
2703
2865
|
useBodyScrollLock(open && !inline);
|
|
2866
|
+
useFocusTrap(cardRef, open && !inline);
|
|
2704
2867
|
react.useEffect(() => {
|
|
2705
2868
|
var _a;
|
|
2706
2869
|
if (!open) return void 0;
|
|
@@ -2746,6 +2909,7 @@ function Dialog({
|
|
|
2746
2909
|
className: joinClasses("chorus-dialog__card", image && "chorus-dialog__card--with-image"),
|
|
2747
2910
|
role: "dialog",
|
|
2748
2911
|
"aria-modal": "true",
|
|
2912
|
+
tabIndex: -1,
|
|
2749
2913
|
"aria-label": ariaLabel ?? title,
|
|
2750
2914
|
onClick: (e) => e.stopPropagation(),
|
|
2751
2915
|
...rest,
|
|
@@ -2779,6 +2943,80 @@ function Divider({
|
|
|
2779
2943
|
}
|
|
2780
2944
|
);
|
|
2781
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
|
+
}
|
|
2782
3020
|
var TabsContext = react.createContext({
|
|
2783
3021
|
variant: "underline",
|
|
2784
3022
|
value: null,
|
|
@@ -2901,19 +3139,19 @@ function TabsUnderline({ className, style, children, ...rest }) {
|
|
|
2901
3139
|
useScrollOverflow(ref);
|
|
2902
3140
|
useSlidingIndicator(ref, indicatorRef, value);
|
|
2903
3141
|
useFullBleedGuard(ref, "Tabs");
|
|
2904
|
-
const
|
|
3142
|
+
const s2 = underline_spec_default.sizing;
|
|
2905
3143
|
const composedStyle = {
|
|
2906
|
-
"--tabs-container-padding-inline": tokenToCss(
|
|
2907
|
-
"--tabs-tab-min-height": tokenToCss(
|
|
2908
|
-
"--tabs-tab-padding-block": tokenToCss(
|
|
2909
|
-
"--tabs-tab-padding-inline": tokenToCss(
|
|
2910
|
-
"--tabs-inter-tab-gap": tokenToCss(
|
|
2911
|
-
"--tabs-slot-gap": tokenToCss(
|
|
2912
|
-
"--tabs-icon-size": tokenToCss(
|
|
2913
|
-
"--tabs-indicator-height": tokenToCss(
|
|
2914
|
-
"--tabs-divider-width": tokenToCss(
|
|
2915
|
-
"--tabs-divider-color": tokenToCss(
|
|
2916
|
-
"--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),
|
|
2917
3155
|
"--tabs-label-unselected": tokenToCss(underline_spec_default.selectionStates.unselected.label),
|
|
2918
3156
|
"--tabs-label-selected": tokenToCss(underline_spec_default.selectionStates.selected.label),
|
|
2919
3157
|
"--tabs-indicator-color": tokenToCss(underline_spec_default.selectionStates.selected.indicator),
|
|
@@ -2925,7 +3163,7 @@ function TabsUnderline({ className, style, children, ...rest }) {
|
|
|
2925
3163
|
"--tabs-focus-outer-color": tokenToCss(underline_spec_default.focusIndicator.ring.outerColor),
|
|
2926
3164
|
"--tabs-focus-inset-width": tokenToCss(underline_spec_default.focusIndicator.ring.insetWidth),
|
|
2927
3165
|
"--tabs-focus-inset-color": tokenToCss(underline_spec_default.focusIndicator.ring.insetColor),
|
|
2928
|
-
...typoStyles(
|
|
3166
|
+
...typoStyles(s2.labelTypo),
|
|
2929
3167
|
...style
|
|
2930
3168
|
};
|
|
2931
3169
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2987,12 +3225,12 @@ function TabsSegmented({ className, style, children, ...rest }) {
|
|
|
2987
3225
|
const ref = react.useRef(null);
|
|
2988
3226
|
useScrollOverflow(ref);
|
|
2989
3227
|
useFullBleedGuard(ref, "Tabs");
|
|
2990
|
-
const
|
|
3228
|
+
const s2 = segmented_spec_default.sizing;
|
|
2991
3229
|
const composedStyle = {
|
|
2992
|
-
"--tabs-container-padding-block": tokenToCss(
|
|
2993
|
-
"--tabs-container-padding-inline": tokenToCss(
|
|
2994
|
-
"--tabs-inter-segment-gap": tokenToCss(
|
|
2995
|
-
"--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),
|
|
2996
3234
|
...style
|
|
2997
3235
|
};
|
|
2998
3236
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3189,13 +3427,13 @@ function Metadata({
|
|
|
3189
3427
|
const hasMeta = Array.isArray(meta) && meta.length > 0;
|
|
3190
3428
|
const hasSubtitle = !hasMeta && subtitle != null && subtitle !== "";
|
|
3191
3429
|
if (variant === "compact") {
|
|
3192
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-metadata__timestamp", children: timestamp })
|
|
3197
|
-
] })
|
|
3198
|
-
] })
|
|
3430
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: joinClasses("chorus-metadata", "chorus-metadata--compact", className), ...rest, children: [
|
|
3431
|
+
avatar ? /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { size: 32, ...avatar }) : null,
|
|
3432
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "chorus-metadata__meta", children: [
|
|
3433
|
+
hasMeta ? metaParts(meta) : null,
|
|
3434
|
+
timestamp ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "chorus-metadata__timestamp", children: timestamp }) : null
|
|
3435
|
+
] })
|
|
3436
|
+
] });
|
|
3199
3437
|
}
|
|
3200
3438
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: joinClasses("chorus-metadata", className), ...rest, children: [
|
|
3201
3439
|
/* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { size: 32, ...avatar ?? { alt: typeof name === "string" ? name : "" } }),
|
|
@@ -3486,6 +3724,33 @@ function FeedAd({
|
|
|
3486
3724
|
) : null
|
|
3487
3725
|
] });
|
|
3488
3726
|
}
|
|
3727
|
+
function Pagination({
|
|
3728
|
+
count = 0,
|
|
3729
|
+
activeIndex = 0,
|
|
3730
|
+
className,
|
|
3731
|
+
...rest
|
|
3732
|
+
}) {
|
|
3733
|
+
if (count < 2) return null;
|
|
3734
|
+
const active = Math.max(0, Math.min(count - 1, activeIndex));
|
|
3735
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3736
|
+
"span",
|
|
3737
|
+
{
|
|
3738
|
+
className: joinClasses("chorus-pagination", className),
|
|
3739
|
+
"aria-hidden": "true",
|
|
3740
|
+
...rest,
|
|
3741
|
+
children: Array.from({ length: count }, (_, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3742
|
+
"span",
|
|
3743
|
+
{
|
|
3744
|
+
className: joinClasses(
|
|
3745
|
+
"chorus-pagination__dot",
|
|
3746
|
+
idx === active && "chorus-pagination__dot--active"
|
|
3747
|
+
)
|
|
3748
|
+
},
|
|
3749
|
+
idx
|
|
3750
|
+
))
|
|
3751
|
+
}
|
|
3752
|
+
);
|
|
3753
|
+
}
|
|
3489
3754
|
var MAX_CARDS = 5;
|
|
3490
3755
|
function PostCarousel({
|
|
3491
3756
|
items = [],
|
|
@@ -3546,16 +3811,7 @@ function PostCarousel({
|
|
|
3546
3811
|
))
|
|
3547
3812
|
}
|
|
3548
3813
|
),
|
|
3549
|
-
|
|
3550
|
-
"span",
|
|
3551
|
-
{
|
|
3552
|
-
className: joinClasses(
|
|
3553
|
-
"chorus-post-carousel__dot",
|
|
3554
|
-
idx === activeIndex && "chorus-post-carousel__dot--active"
|
|
3555
|
-
)
|
|
3556
|
-
},
|
|
3557
|
-
idx
|
|
3558
|
-
)) }) : null
|
|
3814
|
+
/* @__PURE__ */ jsxRuntime.jsx(Pagination, { count: cards.length, activeIndex })
|
|
3559
3815
|
]
|
|
3560
3816
|
}
|
|
3561
3817
|
);
|
|
@@ -3706,16 +3962,7 @@ function ProfileCarousel({
|
|
|
3706
3962
|
))
|
|
3707
3963
|
}
|
|
3708
3964
|
),
|
|
3709
|
-
|
|
3710
|
-
"span",
|
|
3711
|
-
{
|
|
3712
|
-
className: joinClasses(
|
|
3713
|
-
"chorus-profile-carousel__dot",
|
|
3714
|
-
idx === activeIndex && "chorus-profile-carousel__dot--active"
|
|
3715
|
-
)
|
|
3716
|
-
},
|
|
3717
|
-
idx
|
|
3718
|
-
)) }) : null
|
|
3965
|
+
/* @__PURE__ */ jsxRuntime.jsx(Pagination, { count: cards.length, activeIndex })
|
|
3719
3966
|
]
|
|
3720
3967
|
}
|
|
3721
3968
|
);
|
|
@@ -4319,15 +4566,23 @@ var input_spec_default = {
|
|
|
4319
4566
|
overlay: {
|
|
4320
4567
|
color: "text",
|
|
4321
4568
|
opacity: "sys.state.pressed"
|
|
4322
|
-
}
|
|
4569
|
+
},
|
|
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."
|
|
4323
4571
|
},
|
|
4324
4572
|
active: {
|
|
4573
|
+
isFocusState: true,
|
|
4325
4574
|
overlay: null,
|
|
4326
4575
|
border: "borderActive",
|
|
4327
4576
|
strokeWeight: "activeStrokeWeight",
|
|
4328
4577
|
caret: "visible",
|
|
4329
4578
|
showsClearWhenValue: true,
|
|
4330
|
-
|
|
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)."
|
|
4331
4586
|
},
|
|
4332
4587
|
disabled: {
|
|
4333
4588
|
overlay: null,
|
|
@@ -4505,14 +4760,22 @@ var textarea_spec_default = {
|
|
|
4505
4760
|
hovered: { overlay: null, border: "borderHover" },
|
|
4506
4761
|
pressed: {
|
|
4507
4762
|
border: "borderHover",
|
|
4508
|
-
overlay: { color: "text", opacity: "sys.state.pressed" }
|
|
4763
|
+
overlay: { color: "text", opacity: "sys.state.pressed" },
|
|
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."
|
|
4509
4765
|
},
|
|
4510
4766
|
active: {
|
|
4767
|
+
isFocusState: true,
|
|
4511
4768
|
overlay: null,
|
|
4512
4769
|
border: "borderActive",
|
|
4513
4770
|
strokeWeight: "activeStrokeWeight",
|
|
4514
4771
|
caret: "visible",
|
|
4515
|
-
|
|
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."
|
|
4516
4779
|
},
|
|
4517
4780
|
disabled: {
|
|
4518
4781
|
overlay: null,
|
|
@@ -4642,15 +4905,23 @@ var search_spec_default = {
|
|
|
4642
4905
|
overlay: {
|
|
4643
4906
|
color: "text",
|
|
4644
4907
|
opacity: "sys.state.pressed"
|
|
4645
|
-
}
|
|
4908
|
+
},
|
|
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."
|
|
4646
4910
|
},
|
|
4647
4911
|
active: {
|
|
4912
|
+
isFocusState: true,
|
|
4648
4913
|
overlay: null,
|
|
4649
4914
|
border: "borderActive",
|
|
4650
4915
|
strokeWeight: "activeStrokeWeight",
|
|
4651
4916
|
caret: "visible",
|
|
4652
4917
|
showsClearWhenValue: true,
|
|
4653
|
-
|
|
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)."
|
|
4654
4925
|
},
|
|
4655
4926
|
disabled: {
|
|
4656
4927
|
overlay: null,
|
|
@@ -4837,9 +5108,17 @@ var select_spec_default = {
|
|
|
4837
5108
|
}
|
|
4838
5109
|
},
|
|
4839
5110
|
active: {
|
|
5111
|
+
isFocusState: true,
|
|
4840
5112
|
overlay: null,
|
|
4841
5113
|
border: "borderActive",
|
|
4842
|
-
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)."
|
|
4843
5122
|
},
|
|
4844
5123
|
disabled: {
|
|
4845
5124
|
overlay: null,
|
|
@@ -5013,6 +5292,7 @@ function FormFieldBox({
|
|
|
5013
5292
|
{
|
|
5014
5293
|
type: "button",
|
|
5015
5294
|
className: "chorus-field__clear",
|
|
5295
|
+
"data-nested-action": "",
|
|
5016
5296
|
"aria-label": "Clear",
|
|
5017
5297
|
onClick: handleClear,
|
|
5018
5298
|
children: /* @__PURE__ */ jsxRuntime.jsx(XCircleFillIcon, {})
|
|
@@ -5107,7 +5387,7 @@ var FormFieldSelect = Select;
|
|
|
5107
5387
|
var VARIANTS3 = {
|
|
5108
5388
|
input: FormFieldInput,
|
|
5109
5389
|
textarea: FormFieldTextarea,
|
|
5110
|
-
|
|
5390
|
+
search: FormFieldSearchBar,
|
|
5111
5391
|
select: FormFieldSelect
|
|
5112
5392
|
};
|
|
5113
5393
|
function FormField({ variant = "input", ...rest }) {
|
|
@@ -5459,6 +5739,58 @@ function SkeletonGroup({
|
|
|
5459
5739
|
}
|
|
5460
5740
|
);
|
|
5461
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
|
+
}
|
|
5462
5794
|
function StatusTag({
|
|
5463
5795
|
appearance = "neutral",
|
|
5464
5796
|
children,
|
|
@@ -5855,6 +6187,7 @@ exports.BottomNav = TabBar;
|
|
|
5855
6187
|
exports.BottomSheet = BottomSheet;
|
|
5856
6188
|
exports.Bubble = Bubble;
|
|
5857
6189
|
exports.Button = Button;
|
|
6190
|
+
exports.ButtonGroup = ButtonGroup;
|
|
5858
6191
|
exports.Carousel = Carousel;
|
|
5859
6192
|
exports.ChannelList = SuggestionList;
|
|
5860
6193
|
exports.ChannelRail = AvatarRail;
|
|
@@ -5863,6 +6196,7 @@ exports.Dialog = Dialog;
|
|
|
5863
6196
|
exports.DirectoryList = DirectoryList;
|
|
5864
6197
|
exports.Divider = Divider;
|
|
5865
6198
|
exports.Drawer = BottomSheet;
|
|
6199
|
+
exports.EmptyState = EmptyState;
|
|
5866
6200
|
exports.Feed = Feed;
|
|
5867
6201
|
exports.FeedAd = FeedAd;
|
|
5868
6202
|
exports.FeedGroup = FeedGroup;
|
|
@@ -5877,6 +6211,7 @@ exports.NavCardGroup = NavCardGroup;
|
|
|
5877
6211
|
exports.NavList = NavList;
|
|
5878
6212
|
exports.NavigationBar = NavigationBar;
|
|
5879
6213
|
exports.PageShell = PageShell;
|
|
6214
|
+
exports.Pagination = Pagination;
|
|
5880
6215
|
exports.PostCarousel = PostCarousel;
|
|
5881
6216
|
exports.ProfileCarousel = ProfileCarousel;
|
|
5882
6217
|
exports.ProfileHeader = ProfileHeader;
|
|
@@ -5890,6 +6225,7 @@ exports.SideSheet = SideSheet;
|
|
|
5890
6225
|
exports.SideSheetGroup = SideSheetGroup;
|
|
5891
6226
|
exports.Skeleton = Skeleton;
|
|
5892
6227
|
exports.SkeletonGroup = SkeletonGroup;
|
|
6228
|
+
exports.Spinner = Spinner;
|
|
5893
6229
|
exports.StatusTag = StatusTag;
|
|
5894
6230
|
exports.SubHeader = SubHeader;
|
|
5895
6231
|
exports.SuggestionList = SuggestionList;
|