@particle-academy/react-fancy 6.1.0 → 6.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/breadcrumbs.cjs +2 -2
  3. package/dist/breadcrumbs.js +1 -1
  4. package/dist/{chunk-YUNOVQQJ.js → chunk-3S5ED522.js} +12 -2
  5. package/dist/chunk-3S5ED522.js.map +1 -0
  6. package/dist/{chunk-35S5BTZH.cjs → chunk-EWE776WI.cjs} +35 -4
  7. package/dist/chunk-EWE776WI.cjs.map +1 -0
  8. package/dist/{chunk-IU5WQUUC.js → chunk-FR4RHVPR.js} +34 -6
  9. package/dist/chunk-FR4RHVPR.js.map +1 -0
  10. package/dist/{chunk-MTDOFZIB.js → chunk-JY2RC6I4.js} +37 -7
  11. package/dist/chunk-JY2RC6I4.js.map +1 -0
  12. package/dist/{chunk-IB673TEG.cjs → chunk-KOAMRCSC.cjs} +12 -2
  13. package/dist/chunk-KOAMRCSC.cjs.map +1 -0
  14. package/dist/{chunk-GK7IGL7N.cjs → chunk-KOTUFZJ6.cjs} +37 -7
  15. package/dist/chunk-KOTUFZJ6.cjs.map +1 -0
  16. package/dist/{chunk-CQ54H7DZ.cjs → chunk-RZUYCZ5D.cjs} +33 -5
  17. package/dist/chunk-RZUYCZ5D.cjs.map +1 -0
  18. package/dist/{chunk-A67EDGC7.js → chunk-WJHPZS3U.js} +35 -4
  19. package/dist/chunk-WJHPZS3U.js.map +1 -0
  20. package/dist/index.cjs +10 -10
  21. package/dist/index.js +4 -4
  22. package/dist/inputs.cjs +2 -2
  23. package/dist/inputs.js +1 -1
  24. package/dist/multi-switch.cjs +2 -2
  25. package/dist/multi-switch.js +1 -1
  26. package/dist/sidebar.cjs +7 -3
  27. package/dist/sidebar.d.cts +20 -1
  28. package/dist/sidebar.d.ts +20 -1
  29. package/dist/sidebar.js +5 -1
  30. package/dist/tabs.cjs +4 -3
  31. package/dist/tabs.js +2 -1
  32. package/docs/Sidebar.md +54 -0
  33. package/package.json +1 -1
  34. package/dist/chunk-35S5BTZH.cjs.map +0 -1
  35. package/dist/chunk-A67EDGC7.js.map +0 -1
  36. package/dist/chunk-CQ54H7DZ.cjs.map +0 -1
  37. package/dist/chunk-GK7IGL7N.cjs.map +0 -1
  38. package/dist/chunk-IB673TEG.cjs.map +0 -1
  39. package/dist/chunk-IU5WQUUC.js.map +0 -1
  40. package/dist/chunk-MTDOFZIB.js.map +0 -1
  41. package/dist/chunk-YUNOVQQJ.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -11,6 +11,62 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [6.2.0] - 2026-11-01
15
+
16
+ ### Added
17
+
18
+ - **`Sidebar.Item` `dotTooltip`: the dot's words for sighted users.**
19
+ `dotLabel` reached screen readers only, and the item sets its own collapsed
20
+ `title`, so a consumer could not show those words. `dotTooltip` shows
21
+ `dotLabel` in a Fancy `Tooltip` to the right of the item on hover and
22
+ keyboard focus. It reuses `dotLabel` rather than taking separate text, so the
23
+ two audiences cannot be told different things. On a collapsed item it
24
+ replaces the native `title` (one bubble, not two) and shows the label above
25
+ the words. The bubble is `aria-hidden` and not wired as a description, since
26
+ the words are already in the accessible name. Inert without `dot` and
27
+ `dotLabel`. Handle: `data-react-fancy-sidebar-tooltip`.
28
+ - **`Sidebar.Item` `badgeLabel`: words for the badge.** A bare count ("2")
29
+ means nothing on its own to a screen reader. With `badgeLabel="2 agents"` the
30
+ visible badge gets `aria-hidden` and the label is added to the item's
31
+ accessible name as visually hidden text after a comma: "tynn, 2 agents". It
32
+ works expanded and on a collapsed rail with `collapsedBadge`, and composes
33
+ with `dotLabel` ("tynn needs you, 2 agents"). It is ignored while the badge is
34
+ not rendered. Handle: `data-react-fancy-sidebar-badge-label`.
35
+
36
+ ### Fixed
37
+
38
+ - **`Sidebar.Item`: an expanded item's label and badge ran together in the
39
+ accessible name ("tynn2").** A visually hidden space now separates them
40
+ ("tynn 2"). This adds one `<span class="sr-only"> </span>` before the badge
41
+ of an expanded item that has a `badge`; nothing changes visually, and items
42
+ without a badge render byte-identical markup. No consumer action needed,
43
+ unless you snapshot Sidebar markup, in which case expect that one element.
44
+
45
+ ## [6.1.1] - 2026-11-01
46
+
47
+ ### Fixed
48
+
49
+ - **`Breadcrumbs`: the collapsed (below `md`) dropdown dropped `onClick`
50
+ crumbs.** It rebuilt each item from `href` alone, so a crumb that navigates
51
+ by callback, which `Breadcrumbs.Item` supports, became a dead `<span>` on a
52
+ narrow window. It is now a `<button type="button">` that calls the handler and
53
+ closes the menu. A crumb with `as` now renders through that component in the
54
+ dropdown too (it was a plain `<a>`, or nothing clickable without `href`), and
55
+ a link crumb's `onClick` now fires there as it does on the desktop trail. The
56
+ active crumb stays inert. No consumer action needed.
57
+ - **`MultiSwitch`: the thumb did not follow the selected option's size.** It was
58
+ measured only when the selection changed, so a selected label that changed
59
+ width ("Changed 4" to "Changed 12") left the thumb at its old width. The
60
+ selected option and the container are now watched with a `ResizeObserver`
61
+ and the thumb re-measures. Where `ResizeObserver` does not exist (SSR, older
62
+ jsdom) it measures on selection only, as before. No consumer action needed.
63
+ - **`Tabs`: no tab was keyboard-reachable when the controlled value matched
64
+ none.** `Tabs.Tab` set `tabIndex` to 0 only on the active tab, so an
65
+ `activeTab` naming no tab (a route showing a view with no tab) left every tab
66
+ at -1. The first enabled tab in the tablist now takes the tab stop in that
67
+ case; when a tab is active it alone holds the stop, as before. `Tabs.Tab` now
68
+ also forwards a caller's `ref` alongside its own. No consumer action needed.
69
+
14
70
  ## [6.1.0] - 2026-11-01
15
71
 
16
72
  ### Added
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk35S5BTZH_cjs = require('./chunk-35S5BTZH.cjs');
3
+ var chunkEWE776WI_cjs = require('./chunk-EWE776WI.cjs');
4
4
  require('./chunk-57FQGQJK.cjs');
5
5
  require('./chunk-OUYC6EIL.cjs');
6
6
  require('./chunk-ZU5Q77OT.cjs');
@@ -9,7 +9,7 @@ require('./chunk-ZU5Q77OT.cjs');
9
9
 
10
10
  Object.defineProperty(exports, "Breadcrumbs", {
11
11
  enumerable: true,
12
- get: function () { return chunk35S5BTZH_cjs.Breadcrumbs; }
12
+ get: function () { return chunkEWE776WI_cjs.Breadcrumbs; }
13
13
  });
14
14
  //# sourceMappingURL=breadcrumbs.cjs.map
15
15
  //# sourceMappingURL=breadcrumbs.cjs.map
@@ -1,4 +1,4 @@
1
- export { Breadcrumbs } from './chunk-A67EDGC7.js';
1
+ export { Breadcrumbs } from './chunk-WJHPZS3U.js';
2
2
  import './chunk-RGANGU7X.js';
3
3
  import './chunk-YX6FTJ6N.js';
4
4
  import './chunk-MMW2JGKZ.js';
@@ -99,6 +99,16 @@ function MultiSwitch({
99
99
  useEffect(() => {
100
100
  updateIndicator();
101
101
  }, [updateIndicator]);
102
+ useEffect(() => {
103
+ if (typeof ResizeObserver === "undefined") return;
104
+ const container = containerRef.current;
105
+ const activeItem = itemRefs.current[selectedIndex];
106
+ if (!container || !activeItem) return;
107
+ const observer = new ResizeObserver(() => updateIndicator());
108
+ observer.observe(container);
109
+ observer.observe(activeItem);
110
+ return () => observer.disconnect();
111
+ }, [updateIndicator, selectedIndex, showControl]);
102
112
  const control = !showControl ? /* @__PURE__ */ jsx(DisplayValue, { size, interactive, onActivate: enterEdit, children: resolvedOptions.find((o) => o.value === value)?.label }) : /* @__PURE__ */ jsxs(
103
113
  "div",
104
114
  {
@@ -186,5 +196,5 @@ function MultiSwitch({
186
196
  MultiSwitch.displayName = "MultiSwitch";
187
197
 
188
198
  export { MultiSwitch };
189
- //# sourceMappingURL=chunk-YUNOVQQJ.js.map
190
- //# sourceMappingURL=chunk-YUNOVQQJ.js.map
199
+ //# sourceMappingURL=chunk-3S5ED522.js.map
200
+ //# sourceMappingURL=chunk-3S5ED522.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/inputs/MultiSwitch/MultiSwitch.colors.ts","../src/components/inputs/MultiSwitch/MultiSwitch.tsx"],"names":[],"mappings":"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","file":"chunk-3S5ED522.js","sourcesContent":["// Literal Tailwind class strings for every color in the v4 palette so the\n// scanner can detect them in the published dist (template-built names are\n// invisible to Tailwind's JIT). Shades follow badgeSolid: 600 / dark 500 for\n// the thumb, with dark label text on the light hues (amber, yellow, lime).\nimport type { Color } from \"../../../utils/types\";\n\nexport type MultiSwitchColorClasses = {\n /** The selected thumb's fill. */\n thumb: string;\n /** The selected option's label, readable on the thumb. */\n text: string;\n /** The container border while this option is selected. */\n border: string;\n};\n\nexport const multiSwitchColorClasses: Record<Color, MultiSwitchColorClasses> = {\n // The host's colour, from CSS variables -- no dark: variant, because a\n // host that themes per mode scopes the variables themselves.\n brand: { thumb: \"bg-brand\", text: \"text-brand-contrast\", border: \"border-brand\" },\n slate: { thumb: \"bg-slate-600 dark:bg-slate-500\", text: \"text-white\", border: \"border-slate-500 dark:border-slate-400\" },\n gray: { thumb: \"bg-gray-600 dark:bg-gray-500\", text: \"text-white\", border: \"border-gray-500 dark:border-gray-400\" },\n zinc: { thumb: \"bg-zinc-600 dark:bg-zinc-500\", text: \"text-white\", border: \"border-zinc-500 dark:border-zinc-400\" },\n neutral: { thumb: \"bg-neutral-600 dark:bg-neutral-500\", text: \"text-white\", border: \"border-neutral-500 dark:border-neutral-400\" },\n stone: { thumb: \"bg-stone-600 dark:bg-stone-500\", text: \"text-white\", border: \"border-stone-500 dark:border-stone-400\" },\n red: { thumb: \"bg-red-600 dark:bg-red-500\", text: \"text-white\", border: \"border-red-500 dark:border-red-400\" },\n orange: { thumb: \"bg-orange-600 dark:bg-orange-500\", text: \"text-white\", border: \"border-orange-500 dark:border-orange-400\" },\n amber: { thumb: \"bg-amber-400 dark:bg-amber-300\", text: \"text-amber-950\", border: \"border-amber-500 dark:border-amber-400\" },\n yellow: { thumb: \"bg-yellow-400 dark:bg-yellow-300\", text: \"text-yellow-950\", border: \"border-yellow-500 dark:border-yellow-400\" },\n lime: { thumb: \"bg-lime-400 dark:bg-lime-300\", text: \"text-lime-950\", border: \"border-lime-500 dark:border-lime-400\" },\n green: { thumb: \"bg-green-600 dark:bg-green-500\", text: \"text-white\", border: \"border-green-500 dark:border-green-400\" },\n emerald: { thumb: \"bg-emerald-600 dark:bg-emerald-500\", text: \"text-white\", border: \"border-emerald-500 dark:border-emerald-400\" },\n teal: { thumb: \"bg-teal-600 dark:bg-teal-500\", text: \"text-white\", border: \"border-teal-500 dark:border-teal-400\" },\n cyan: { thumb: \"bg-cyan-600 dark:bg-cyan-500\", text: \"text-white\", border: \"border-cyan-500 dark:border-cyan-400\" },\n sky: { thumb: \"bg-sky-600 dark:bg-sky-500\", text: \"text-white\", border: \"border-sky-500 dark:border-sky-400\" },\n blue: { thumb: \"bg-blue-600 dark:bg-blue-500\", text: \"text-white\", border: \"border-blue-500 dark:border-blue-400\" },\n indigo: { thumb: \"bg-indigo-600 dark:bg-indigo-500\", text: \"text-white\", border: \"border-indigo-500 dark:border-indigo-400\" },\n violet: { thumb: \"bg-violet-600 dark:bg-violet-500\", text: \"text-white\", border: \"border-violet-500 dark:border-violet-400\" },\n purple: { thumb: \"bg-purple-600 dark:bg-purple-500\", text: \"text-white\", border: \"border-purple-500 dark:border-purple-400\" },\n fuchsia: { thumb: \"bg-fuchsia-600 dark:bg-fuchsia-500\", text: \"text-white\", border: \"border-fuchsia-500 dark:border-fuchsia-400\" },\n pink: { thumb: \"bg-pink-600 dark:bg-pink-500\", text: \"text-white\", border: \"border-pink-500 dark:border-pink-400\" },\n rose: { thumb: \"bg-rose-600 dark:bg-rose-500\", text: \"text-white\", border: \"border-rose-500 dark:border-rose-400\" },\n};\n","import { useRef, useState, useEffect, useCallback, useId, useMemo, type Ref } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport { composeRefs } from \"../../../utils/compose-refs\";\nimport { useControllableState } from \"../../../hooks/use-controllable-state\";\nimport { Field } from \"../Field\";\nimport { useFieldMode } from \"../mode/FieldMode.context\";\nimport { DisplayValue } from \"../mode/DisplayValue\";\nimport { useInlineEdit } from \"../mode/useInlineEdit\";\nimport { resolveOption } from \"../inputs.utils\";\nimport type { Color, Size } from \"../../../utils/types\";\nimport type { MultiSwitchProps } from \"./MultiSwitch.types\";\nimport { multiSwitchColorClasses } from \"./MultiSwitch.colors\";\n\nconst BORDER_DEFAULT =\n \"border-[color:var(--fancy-border-strong,var(--color-zinc-300))] dark:border-[color:var(--fancy-border-strong-dark,var(--color-zinc-700))]\";\n\nconst sizeClasses: Record<Size, string> = {\n xs: \"px-2 py-1 text-xs\",\n sm: \"px-2.5 py-1.5 text-sm\",\n md: \"px-3 py-2 text-sm\",\n lg: \"px-4 py-2.5 text-base\",\n xl: \"px-5 py-3 text-lg\",\n};\n\nexport function MultiSwitch<V = string>({\n size = \"md\",\n dirty,\n error,\n label,\n labelHidden,\n description,\n required,\n disabled,\n className,\n id,\n name,\n list,\n value: controlledValue,\n defaultValue,\n onValueChange,\n linear,\n mode,\n ...rest\n}: MultiSwitchProps<V>) {\n const reactId = useId();\n // A `<label for>` cannot name a div[role=\"radiogroup\"], so the group points at\n // the label instead. Needs an id the label and the group both agree on.\n const labelId = label ? `${id ?? reactId}-label` : undefined;\n\n // resolveOption hands an object option back as-is, so `color` survives it.\n const resolvedOptions = list.map(resolveOption) as Array<\n ReturnType<typeof resolveOption<V>> & { color?: Color }\n >;\n const fallback = defaultValue ?? resolvedOptions[0]?.value;\n const resolvedMode = useFieldMode(mode);\n const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);\n const [value, setValue] = useControllableState(controlledValue, fallback as V, onValueChange);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const externalRef = (rest as { ref?: Ref<HTMLDivElement> }).ref;\n const containerSetRef = useMemo(() => composeRefs(externalRef, containerRef), [externalRef]);\n const itemRefs = useRef<(HTMLButtonElement | null)[]>([]);\n const [indicator, setIndicator] = useState<{ left: number; width: number } | null>(null);\n\n const selectedIndex = resolvedOptions.findIndex(\n (o) => o.value === value,\n );\n const selectedColor = resolvedOptions[selectedIndex]?.color;\n const colorClasses = selectedColor ? multiSwitchColorClasses[selectedColor] : undefined;\n\n const updateIndicator = useCallback(() => {\n const container = containerRef.current;\n const activeItem = itemRefs.current[selectedIndex];\n if (!container || !activeItem) {\n setIndicator(null);\n return;\n }\n const containerRect = container.getBoundingClientRect();\n const itemRect = activeItem.getBoundingClientRect();\n setIndicator({\n left: itemRect.left - containerRect.left,\n width: itemRect.width,\n });\n }, [selectedIndex]);\n\n useEffect(() => {\n updateIndicator();\n }, [updateIndicator]);\n\n // The selected option can change size without the selection changing: a\n // label carrying a live count (\"Changed 4\" -> \"Changed 12\"), a font loading\n // late, the container reflowing. Watch the selected option and the container\n // and re-measure. Without ResizeObserver (SSR, older jsdom) the thumb is\n // measured on selection only, as it always was.\n useEffect(() => {\n if (typeof ResizeObserver === \"undefined\") return;\n const container = containerRef.current;\n const activeItem = itemRefs.current[selectedIndex];\n if (!container || !activeItem) return;\n const observer = new ResizeObserver(() => updateIndicator());\n observer.observe(container);\n observer.observe(activeItem);\n return () => observer.disconnect();\n }, [updateIndicator, selectedIndex, showControl]);\n\n const control = !showControl ? (\n <DisplayValue size={size} interactive={interactive} onActivate={enterEdit}>\n {resolvedOptions.find((o) => o.value === value)?.label}\n </DisplayValue>\n ) : (\n <div\n {...rest}\n // React 19 passes `ref` to a function component as a plain prop, so a\n // caller's ref (Tooltip's anchor, or anyone's) arrives in `rest`. Spread\n // after `ref={containerRef}` it REPLACED the ref the thumb is measured\n // from, and the selected thumb never rendered. Feed both instead.\n ref={containerSetRef}\n data-react-fancy-multi-switch=\"\"\n role=\"radiogroup\"\n id={id}\n aria-labelledby={labelId}\n onBlur={(e) => {\n if (interactive && !e.currentTarget.contains(e.relatedTarget as Node)) exitEdit();\n }}\n className={cn(\n \"relative inline-flex rounded-lg border bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n colorClasses ? colorClasses.border : BORDER_DEFAULT,\n dirty && \"ring-2 ring-amber-400/50\",\n error && \"ring-2 ring-red-500/50\",\n disabled && \"opacity-50 cursor-not-allowed\",\n className,\n )}\n >\n {indicator && (\n <span\n data-react-fancy-multi-switch-thumb=\"\"\n data-color={selectedColor}\n className={\n colorClasses\n ? `absolute top-0 bottom-0 rounded-lg ${colorClasses.thumb} transition-all duration-200 ease-out`\n : \"absolute top-0 bottom-0 rounded-lg bg-blue-600 transition-all duration-200 ease-out\"\n }\n style={{ left: indicator.left, width: indicator.width }}\n />\n )}\n {resolvedOptions.map((option, index) => {\n const isSelected = option.value === value;\n return (\n <button\n key={String(option.value)}\n ref={(el) => { itemRefs.current[index] = el; }}\n type=\"button\"\n role=\"radio\"\n aria-checked={isSelected}\n disabled={disabled || option.disabled}\n autoFocus={interactive && (selectedIndex === -1 ? index === 0 : isSelected)}\n onClick={() => {\n if (linear) {\n const nextIndex = (selectedIndex + 1) % resolvedOptions.length;\n setValue(resolvedOptions[nextIndex].value as V);\n } else {\n setValue(option.value as V);\n }\n }}\n className={cn(\n \"relative z-10 font-medium transition-colors duration-200\",\n sizeClasses[size],\n isSelected\n ? (colorClasses?.text ?? \"text-white\")\n : \"text-[color:var(--fancy-text-subtle,var(--color-zinc-600))] hover:text-[color:var(--fancy-text,var(--color-zinc-900))] dark:text-[color:var(--fancy-text-subtle-dark,var(--color-zinc-400))] dark:hover:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\",\n (disabled || option.disabled) && \"cursor-not-allowed\",\n )}\n >\n {option.label}\n </button>\n );\n })}\n {name && <input type=\"hidden\" name={name} value={String(value)} />}\n </div>\n );\n\n if (label || error || description) {\n return (\n <Field\n label={label}\n labelHidden={labelHidden}\n labelId={labelId}\n description={description}\n error={error}\n required={required}\n htmlFor={id}\n size={size}\n >\n {control}\n </Field>\n );\n }\n\n return control;\n}\n\nMultiSwitch.displayName = \"MultiSwitch\";\n"]}
@@ -74,8 +74,37 @@ function BreadcrumbsDropdown({ items, activeLabel }) {
74
74
  "block w-full px-3 py-1.5 text-left text-sm",
75
75
  item.active ? "font-medium text-zinc-900 dark:text-white" : "text-[color:var(--fancy-text-muted,var(--color-zinc-500))] hover:bg-zinc-50 hover:text-[color:var(--fancy-text-soft,var(--color-zinc-700))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))] dark:hover:bg-zinc-800 dark:hover:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))]"
76
76
  );
77
- if (item.href && !item.active) {
78
- return /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.href, className: cls, onClick: () => setOpen(false), children: item.label }, i);
77
+ if ((item.href || item.as) && !item.active) {
78
+ const Link = item.as ?? "a";
79
+ return /* @__PURE__ */ jsxRuntime.jsx(
80
+ Link,
81
+ {
82
+ ...item.href ? { href: item.href } : {},
83
+ className: cls,
84
+ onClick: () => {
85
+ item.onClick?.();
86
+ setOpen(false);
87
+ },
88
+ children: item.label
89
+ },
90
+ i
91
+ );
92
+ }
93
+ if (item.onClick && !item.active) {
94
+ const onClick = item.onClick;
95
+ return /* @__PURE__ */ jsxRuntime.jsx(
96
+ "button",
97
+ {
98
+ type: "button",
99
+ className: chunkZU5Q77OT_cjs.cn(cls, "cursor-pointer border-0 bg-transparent"),
100
+ onClick: () => {
101
+ onClick();
102
+ setOpen(false);
103
+ },
104
+ children: item.label
105
+ },
106
+ i
107
+ );
79
108
  }
80
109
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cls, children: item.label }, i);
81
110
  }) })
@@ -97,6 +126,8 @@ function BreadcrumbsRoot({
97
126
  return {
98
127
  label: el.props?.children,
99
128
  href: el.props?.href,
129
+ as: el.props?.as,
130
+ onClick: el.props?.onClick,
100
131
  active: el.props?.active
101
132
  };
102
133
  });
@@ -137,5 +168,5 @@ var Breadcrumbs = Object.assign(BreadcrumbsRoot, {
137
168
  });
138
169
 
139
170
  exports.Breadcrumbs = Breadcrumbs;
140
- //# sourceMappingURL=chunk-35S5BTZH.cjs.map
141
- //# sourceMappingURL=chunk-35S5BTZH.cjs.map
171
+ //# sourceMappingURL=chunk-EWE776WI.cjs.map
172
+ //# sourceMappingURL=chunk-EWE776WI.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Breadcrumbs/BreadcrumbsItem.tsx","../src/components/Breadcrumbs/BreadcrumbsDropdown.tsx","../src/components/Breadcrumbs/Breadcrumbs.tsx"],"names":["cn","jsx","useState","useRef","useOutsideClick","useEscapeKey","jsxs","ChevronDown","Children","ChevronRight","Fragment"],"mappings":"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","file":"chunk-EWE776WI.cjs","sourcesContent":["import type { ElementType } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport type { BreadcrumbsItemProps } from \"./Breadcrumbs.types\";\n\nexport function BreadcrumbsItem({\n children,\n href,\n as: As,\n active = false,\n onClick,\n className,\n ...rest\n}: BreadcrumbsItemProps) {\n const baseClass = cn(\n \"text-sm\",\n active\n ? \"font-medium text-zinc-900 dark:text-white\"\n : \"text-[color:var(--fancy-text-muted,var(--color-zinc-500))] hover:text-[color:var(--fancy-text-soft,var(--color-zinc-700))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))] dark:hover:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))]\",\n className,\n );\n\n // The CURRENT crumb stays a <span> even with `as`: it is the page you are on,\n // so a link to it is a link to nowhere, and `aria-current=\"page\"` is the point.\n if ((href || As) && !active) {\n const Link = (As ?? \"a\") as ElementType;\n\n return (\n <Link\n data-react-fancy-breadcrumbs-item=\"\"\n {...(href ? { href } : {})}\n onClick={onClick}\n className={baseClass}\n {...rest}\n >\n {children}\n </Link>\n );\n }\n\n // A crumb that navigates through a callback rather than a URL. Controlled\n // components own their navigation and have no href to give — a repository\n // browser walking directories, a wizard stepping back — and until this\n // existed the only way to make such a crumb clickable was to nest a button\n // inside the span below, which is interactive content inside a non-\n // interactive element.\n if (onClick && !active) {\n return (\n <button\n type=\"button\"\n data-react-fancy-breadcrumbs-item=\"\"\n onClick={onClick}\n className={cn(baseClass, \"cursor-pointer border-0 bg-transparent p-0\")}\n {...rest}\n >\n {children}\n </button>\n );\n }\n\n return (\n <span data-react-fancy-breadcrumbs-item=\"\" className={baseClass} aria-current={active ? \"page\" : undefined} {...rest}>\n {children}\n </span>\n );\n}\n\nBreadcrumbsItem.displayName = \"BreadcrumbsItem\";\n","import { useState, useRef, type ElementType, type ReactNode } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useOutsideClick } from \"../../hooks/use-outside-click\";\nimport { useEscapeKey } from \"../../hooks/use-escape-key\";\n\ninterface BreadcrumbsDropdownItem {\n label: ReactNode;\n href?: string;\n as?: ElementType;\n onClick?: () => void;\n active?: boolean;\n}\n\ninterface BreadcrumbsDropdownProps {\n items: BreadcrumbsDropdownItem[];\n activeLabel: ReactNode;\n}\n\nexport function BreadcrumbsDropdown({ items, activeLabel }: BreadcrumbsDropdownProps) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useOutsideClick(ref, () => setOpen(false), open);\n useEscapeKey(() => setOpen(false), open);\n\n return (\n <div ref={ref} data-react-fancy-breadcrumbs-dropdown=\"\" className=\"relative flex md:hidden\">\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"flex items-center gap-1 rounded-lg px-2 py-1 text-sm font-medium text-zinc-900 hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:text-white dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\"\n >\n {activeLabel}\n <ChevronDown size={14} className={cn(\"transition-transform\", open && \"rotate-180\")} />\n </button>\n {open && (\n <div className=\"absolute top-full left-0 z-50 mt-1 min-w-[180px] rounded-lg border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] py-1 shadow-lg dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\">\n {items.map((item, i) => {\n const cls = cn(\n \"block w-full px-3 py-1.5 text-left text-sm\",\n item.active\n ? \"font-medium text-zinc-900 dark:text-white\"\n : \"text-[color:var(--fancy-text-muted,var(--color-zinc-500))] hover:bg-zinc-50 hover:text-[color:var(--fancy-text-soft,var(--color-zinc-700))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))] dark:hover:bg-zinc-800 dark:hover:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))]\",\n );\n\n // Mirrors BreadcrumbsItem: href / `as` wins, then onClick, and the\n // active crumb stays inert whatever it carries.\n if ((item.href || item.as) && !item.active) {\n const Link = (item.as ?? \"a\") as ElementType;\n return (\n <Link\n key={i}\n {...(item.href ? { href: item.href } : {})}\n className={cls}\n onClick={() => {\n item.onClick?.();\n setOpen(false);\n }}\n >\n {item.label}\n </Link>\n );\n }\n\n if (item.onClick && !item.active) {\n const onClick = item.onClick;\n return (\n <button\n key={i}\n type=\"button\"\n className={cn(cls, \"cursor-pointer border-0 bg-transparent\")}\n onClick={() => {\n onClick();\n setOpen(false);\n }}\n >\n {item.label}\n </button>\n );\n }\n\n return (\n <span key={i} className={cls}>\n {item.label}\n </span>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\nBreadcrumbsDropdown.displayName = \"BreadcrumbsDropdown\";\n","import { Children, Fragment, useState, type ReactElement } from \"react\";\nimport { ChevronRight } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { BreadcrumbsItem } from \"./BreadcrumbsItem\";\nimport { BreadcrumbsDropdown } from \"./BreadcrumbsDropdown\";\nimport type { BreadcrumbsProps, BreadcrumbsItemProps } from \"./Breadcrumbs.types\";\n\nfunction BreadcrumbsRoot({\n children,\n separator,\n shrink,\n className,\n}: BreadcrumbsProps) {\n const items = Children.toArray(children);\n const [expanded, setExpanded] = useState(false);\n\n const sep = separator ?? (\n <ChevronRight size={12} className=\"text-zinc-400\" />\n );\n\n const lastItem = items[items.length - 1];\n\n // Extract info from children for mobile dropdown\n const dropdownItems = items.map((child) => {\n const el = child as ReactElement<BreadcrumbsItemProps>;\n return {\n label: el.props?.children,\n href: el.props?.href,\n as: el.props?.as,\n onClick: el.props?.onClick,\n active: el.props?.active,\n };\n });\n\n const activeLabel = dropdownItems[dropdownItems.length - 1]?.label ?? \"Menu\";\n\n const showShrunk = shrink && !expanded && items.length > 1;\n\n return (\n <>\n {/* Desktop trail */}\n <nav\n data-react-fancy-breadcrumbs=\"\"\n aria-label=\"Breadcrumb\"\n className={cn(\"hidden items-center gap-2 md:flex\", className)}\n onMouseLeave={() => shrink && setExpanded(false)}\n >\n {showShrunk ? (\n <>\n <button\n type=\"button\"\n onClick={() => setExpanded(true)}\n onMouseEnter={() => setExpanded(true)}\n className=\"text-sm text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300\"\n >\n ...\n </button>\n <span aria-hidden=\"true\">{sep}</span>\n {lastItem}\n </>\n ) : (\n items.map((child, i) => (\n <Fragment key={i}>\n {i > 0 && <span aria-hidden=\"true\">{sep}</span>}\n {child}\n </Fragment>\n ))\n )}\n </nav>\n\n {/* Mobile dropdown */}\n <BreadcrumbsDropdown items={dropdownItems} activeLabel={activeLabel} />\n </>\n );\n}\n\nexport const Breadcrumbs = Object.assign(BreadcrumbsRoot, {\n Item: BreadcrumbsItem,\n});\n"]}
@@ -1,9 +1,11 @@
1
+ import { composeRefs } from './chunk-SV5BW3IA.js';
1
2
  import { useControllableState } from './chunk-EDYAXGUM.js';
2
3
  import { cn } from './chunk-MMW2JGKZ.js';
3
- import { createContext, useMemo, useRef, useCallback, useContext } from 'react';
4
+ import { createContext, useMemo, useContext, useState, useLayoutEffect, useRef, useCallback } from 'react';
4
5
  import { jsx } from 'react/jsx-runtime';
5
6
 
6
7
  var TabsContext = createContext(null);
8
+ var TabsListContext = createContext(null);
7
9
  function useTabs() {
8
10
  const ctx = useContext(TabsContext);
9
11
  if (!ctx) {
@@ -12,8 +14,23 @@ function useTabs() {
12
14
  return ctx;
13
15
  }
14
16
  function TabsList({ children, className }) {
15
- const { variant } = useTabs();
17
+ const { variant, activeTab } = useTabs();
16
18
  const listRef = useRef(null);
19
+ const [fallback, setFallback] = useState(null);
20
+ const refresh = useCallback(() => {
21
+ const list = listRef.current;
22
+ if (!list) return;
23
+ const own = Array.from(list.querySelectorAll('[role="tab"]')).filter(
24
+ (el) => el.closest('[role="tablist"]') === list
25
+ );
26
+ const anyActive = own.some((el) => el.getAttribute("aria-selected") === "true");
27
+ const next = anyActive ? null : own.find((el) => !el.disabled) ?? null;
28
+ setFallback((prev) => prev === next ? prev : next);
29
+ }, []);
30
+ useLayoutEffect(() => {
31
+ refresh();
32
+ }, [refresh, activeTab, children]);
33
+ const listCtx = useMemo(() => ({ fallback, refresh }), [fallback, refresh]);
17
34
  const handleKeyDown = useCallback((e) => {
18
35
  const buttons = listRef.current?.querySelectorAll(
19
36
  '[role="tab"]:not([disabled])'
@@ -47,7 +64,7 @@ function TabsList({ children, className }) {
47
64
  variant === "boxed" && "gap-0 rounded-lg bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] p-1 dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]",
48
65
  className
49
66
  ),
50
- children
67
+ children: /* @__PURE__ */ jsx(TabsListContext.Provider, { value: listCtx, children })
51
68
  }
52
69
  );
53
70
  }
@@ -61,7 +78,17 @@ function TabsTab({
61
78
  ...rest
62
79
  }) {
63
80
  const { activeTab, setActiveTab, variant } = useTabs();
81
+ const list = useContext(TabsListContext);
64
82
  const isActive = activeTab === value;
83
+ const [node, setNode] = useState(null);
84
+ const externalRef = rest.ref;
85
+ const setRef = useMemo(() => composeRefs(externalRef, setNode), [externalRef]);
86
+ const refresh = list?.refresh;
87
+ useLayoutEffect(() => {
88
+ refresh?.();
89
+ return () => refresh?.();
90
+ }, [refresh, disabled, value]);
91
+ const isStop = isActive || node !== null && list?.fallback === node;
65
92
  return /* @__PURE__ */ jsx(
66
93
  "button",
67
94
  {
@@ -70,12 +97,13 @@ function TabsTab({
70
97
  role: "tab",
71
98
  disabled,
72
99
  "aria-selected": isActive,
73
- tabIndex: isActive ? 0 : -1,
100
+ tabIndex: isStop ? 0 : -1,
74
101
  onClick: (e) => {
75
102
  if (!disabled) setActiveTab(value);
76
103
  onClick?.(e);
77
104
  },
78
105
  ...rest,
106
+ ref: setRef,
79
107
  className: cn(
80
108
  "text-sm font-medium transition-colors",
81
109
  disabled && "cursor-not-allowed opacity-50",
@@ -135,5 +163,5 @@ var Tabs = Object.assign(TabsRoot, {
135
163
  });
136
164
 
137
165
  export { Tabs, useTabs };
138
- //# sourceMappingURL=chunk-IU5WQUUC.js.map
139
- //# sourceMappingURL=chunk-IU5WQUUC.js.map
166
+ //# sourceMappingURL=chunk-FR4RHVPR.js.map
167
+ //# sourceMappingURL=chunk-FR4RHVPR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Tabs/Tabs.context.ts","../src/components/Tabs/TabsList.tsx","../src/components/Tabs/TabsTab.tsx","../src/components/Tabs/TabsPanels.tsx","../src/components/Tabs/TabsPanel.tsx","../src/components/Tabs/Tabs.tsx"],"names":["useContext","useState","useMemo","useLayoutEffect","jsx"],"mappings":"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","file":"chunk-FR4RHVPR.js","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { TabsContextValue } from \"./Tabs.types\";\n\nexport const TabsContext = createContext<TabsContextValue | null>(null);\n\n/**\n * What a `Tabs.List` tells its tabs about the roving tab stop.\n *\n * `fallback` is the tab that takes `tabIndex=0` when NO tab is active (the\n * controlled value matches none), so the tablist stays reachable by keyboard.\n * `refresh` lets a tab ask the list to re-derive it when the tab changes in a\n * way the list did not render for (disabled toggled, mounted, unmounted).\n */\nexport interface TabsListContextValue {\n fallback: HTMLElement | null;\n refresh: () => void;\n}\n\nexport const TabsListContext = createContext<TabsListContextValue | null>(null);\n\nexport function useTabs(): TabsContextValue {\n const ctx = useContext(TabsContext);\n if (!ctx) {\n throw new Error(\"Tabs compound components must be used within <Tabs>\");\n }\n return ctx;\n}\n","import { useCallback, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { TabsListContext, useTabs } from \"./Tabs.context\";\nimport type { TabsListProps } from \"./Tabs.types\";\n\nexport function TabsList({ children, className }: TabsListProps) {\n const { variant, activeTab } = useTabs();\n const listRef = useRef<HTMLDivElement>(null);\n const [fallback, setFallback] = useState<HTMLElement | null>(null);\n\n // Which tab holds the stop when none is active. Read from the rendered\n // tablist, the same source the arrow keys use, so \"first\" means first in\n // the DOM whatever wraps the tabs. Tabs of a nested tablist are skipped.\n const refresh = useCallback(() => {\n const list = listRef.current;\n if (!list) return;\n const own = Array.from(list.querySelectorAll<HTMLElement>('[role=\"tab\"]')).filter(\n (el) => el.closest('[role=\"tablist\"]') === list,\n );\n const anyActive = own.some((el) => el.getAttribute(\"aria-selected\") === \"true\");\n const next = anyActive\n ? null\n : (own.find((el) => !(el as HTMLButtonElement).disabled) ?? null);\n setFallback((prev) => (prev === next ? prev : next));\n }, []);\n\n useLayoutEffect(() => {\n refresh();\n }, [refresh, activeTab, children]);\n\n const listCtx = useMemo(() => ({ fallback, refresh }), [fallback, refresh]);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n const buttons = listRef.current?.querySelectorAll<HTMLButtonElement>(\n '[role=\"tab\"]:not([disabled])',\n );\n if (!buttons?.length) return;\n\n const items = Array.from(buttons);\n const currentIndex = items.indexOf(document.activeElement as HTMLButtonElement);\n\n if (e.key === \"ArrowRight\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n const next = currentIndex < items.length - 1 ? currentIndex + 1 : 0;\n items[next].focus();\n items[next].click();\n } else if (e.key === \"ArrowLeft\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n const prev = currentIndex > 0 ? currentIndex - 1 : items.length - 1;\n items[prev].focus();\n items[prev].click();\n }\n }, []);\n\n return (\n <div\n data-react-fancy-tabs-list=\"\"\n ref={listRef}\n role=\"tablist\"\n onKeyDown={handleKeyDown}\n className={cn(\n \"flex\",\n variant === \"underline\" && \"gap-0 border-b border-[color:var(--fancy-border,var(--color-zinc-200))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))]\",\n variant === \"pills\" && \"gap-0 rounded-lg bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] p-1 dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n variant === \"boxed\" &&\n \"gap-0 rounded-lg bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] p-1 dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n className,\n )}\n >\n <TabsListContext.Provider value={listCtx}>{children}</TabsListContext.Provider>\n </div>\n );\n}\n\nTabsList.displayName = \"TabsList\";\n","import { useContext, useLayoutEffect, useMemo, useState, type Ref } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { composeRefs } from \"../../utils/compose-refs\";\nimport { TabsListContext, useTabs } from \"./Tabs.context\";\nimport type { TabsTabProps } from \"./Tabs.types\";\n\nexport function TabsTab({\n children,\n value,\n disabled = false,\n className,\n onClick,\n ...rest\n}: TabsTabProps) {\n const { activeTab, setActiveTab, variant } = useTabs();\n const list = useContext(TabsListContext);\n const isActive = activeTab === value;\n\n // The node lives in state, not a ref, so comparing it to the list's\n // fallback during render is a pure read.\n const [node, setNode] = useState<HTMLButtonElement | null>(null);\n const externalRef = (rest as { ref?: Ref<HTMLButtonElement> }).ref;\n const setRef = useMemo(() => composeRefs(externalRef, setNode), [externalRef]);\n\n // Re-derive the fallback when this tab changes in a way the list may not\n // have rendered for, and when it leaves.\n const refresh = list?.refresh;\n useLayoutEffect(() => {\n refresh?.();\n return () => refresh?.();\n }, [refresh, disabled, value]);\n\n // Roving tabindex: the active tab holds the stop. When no tab is active the\n // list names the first enabled one, so the tablist is never unreachable.\n const isStop = isActive || (node !== null && list?.fallback === node);\n\n return (\n <button\n data-react-fancy-tabs-tab=\"\"\n type=\"button\"\n role=\"tab\"\n disabled={disabled}\n aria-selected={isActive}\n tabIndex={isStop ? 0 : -1}\n onClick={(e) => { if (!disabled) setActiveTab(value); onClick?.(e); }}\n {...rest}\n ref={setRef}\n className={cn(\n \"text-sm font-medium transition-colors\",\n disabled && \"cursor-not-allowed opacity-50\",\n variant === \"underline\" && [\n \"border-b-2 px-4 py-2.5\",\n isActive\n ? \"border-zinc-900 text-zinc-900 dark:border-white dark:text-white\"\n : \"border-transparent text-[color:var(--fancy-text-muted,var(--color-zinc-500))] hover:border-zinc-300 hover:text-[color:var(--fancy-text-soft,var(--color-zinc-700))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))] dark:hover:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))]\",\n ],\n variant === \"pills\" && [\n \"rounded-md px-4 py-1.5\",\n isActive\n ? \"bg-[color:var(--fancy-surface,var(--color-white))] text-zinc-900 shadow-sm dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))] dark:text-white\"\n : \"text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\",\n ],\n variant === \"boxed\" && [\n \"flex-1 rounded-md px-4 py-1.5\",\n isActive\n ? \"bg-[color:var(--fancy-surface,var(--color-white))] text-zinc-900 shadow-sm dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))] dark:text-white\"\n : \"text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\",\n ],\n className,\n )}\n >\n {children}\n </button>\n );\n}\n\nTabsTab.displayName = \"TabsTab\";\n","import { cn } from \"../../utils/cn\";\nimport type { TabsPanelsProps } from \"./Tabs.types\";\n\nexport function TabsPanels({ children, className }: TabsPanelsProps) {\n return <div data-react-fancy-tabs-panels=\"\" className={cn(\"mt-4\", className)}>{children}</div>;\n}\n\nTabsPanels.displayName = \"TabsPanels\";\n","import { cn } from \"../../utils/cn\";\nimport { useTabs } from \"./Tabs.context\";\nimport type { TabsPanelProps } from \"./Tabs.types\";\n\nexport function TabsPanel({ children, value, className }: TabsPanelProps) {\n const { activeTab } = useTabs();\n\n if (activeTab !== value) return null;\n\n return (\n <div data-react-fancy-tabs-panel=\"\" role=\"tabpanel\" className={cn(\"fancy-fade-in\", className)}>\n {children}\n </div>\n );\n}\n\nTabsPanel.displayName = \"TabsPanel\";\n","import { useMemo } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport { TabsContext } from \"./Tabs.context\";\nimport { TabsList } from \"./TabsList\";\nimport { TabsTab } from \"./TabsTab\";\nimport { TabsPanels } from \"./TabsPanels\";\nimport { TabsPanel } from \"./TabsPanel\";\nimport type { TabsProps } from \"./Tabs.types\";\n\nfunction TabsRoot({\n children,\n defaultTab = \"\",\n activeTab: controlledTab,\n onTabChange,\n variant = \"underline\",\n className,\n}: TabsProps) {\n const [activeTab, setActiveTab] = useControllableState(\n controlledTab,\n defaultTab,\n onTabChange,\n );\n\n const ctx = useMemo(\n () => ({ activeTab, setActiveTab, variant }),\n [activeTab, setActiveTab, variant],\n );\n\n return (\n <TabsContext.Provider value={ctx}>\n <div data-react-fancy-tabs=\"\" className={cn(className)}>{children}</div>\n </TabsContext.Provider>\n );\n}\n\nexport const Tabs = Object.assign(TabsRoot, {\n List: TabsList,\n Tab: TabsTab,\n Panels: TabsPanels,\n Panel: TabsPanel,\n});\n"]}
@@ -1,3 +1,4 @@
1
+ import { Tooltip } from './chunk-GR2WKBER.js';
1
2
  import { badgeDot } from './chunk-S53A6JIE.js';
2
3
  import { useControllableState } from './chunk-EDYAXGUM.js';
3
4
  import { cn } from './chunk-MMW2JGKZ.js';
@@ -118,9 +119,11 @@ function SidebarItem({
118
119
  active = false,
119
120
  disabled = false,
120
121
  badge,
122
+ badgeLabel,
121
123
  collapsedBadge = false,
122
124
  dot,
123
125
  dotLabel,
126
+ dotTooltip = false,
124
127
  onClick,
125
128
  className,
126
129
  ...rest
@@ -135,13 +138,19 @@ function SidebarItem({
135
138
  const dotColor = dot === true ? "red" : dot || null;
136
139
  const showCollapsedBadge = collapsed && collapsedBadge && Boolean(badge);
137
140
  const hasMarks = dotColor !== null || showCollapsedBadge;
141
+ const badgeShown = Boolean(badge) && (!collapsed || showCollapsedBadge);
142
+ const badgeLabelEl = badgeShown && badgeLabel ? (
143
+ // The comma is the separator, so whatever renders before this must not
144
+ // end in a space ("tynn , 2 agents"); see the two trailing spaces below.
145
+ /* @__PURE__ */ jsx("span", { className: "sr-only", "data-react-fancy-sidebar-badge-label": "", children: `, ${badgeLabel}` })
146
+ ) : null;
138
147
  const dotLabelEl = dotColor && dotLabel ? (
139
148
  // The spaces are load-bearing: adjacent inline elements concatenate in
140
149
  // the accessible name, so without them it reads "Inbox3 unread".
141
150
  /* @__PURE__ */ jsxs("span", { className: "sr-only", "data-react-fancy-sidebar-dot-label": "", children: [
142
151
  " ",
143
152
  dotLabel,
144
- " "
153
+ badgeLabelEl ? null : " "
145
154
  ] })
146
155
  ) : null;
147
156
  const needsHiddenLabel = collapsed && (dotLabelEl !== null || showCollapsedBadge);
@@ -150,6 +159,7 @@ function SidebarItem({
150
159
  "span",
151
160
  {
152
161
  "data-react-fancy-sidebar-badge": "",
162
+ "aria-hidden": badgeLabelEl ? "true" : void 0,
153
163
  className: "pointer-events-none absolute -right-3 -top-2.5 whitespace-nowrap",
154
164
  children: badge
155
165
  }
@@ -173,7 +183,8 @@ function SidebarItem({
173
183
  "flex h-5 w-5 shrink-0 items-center justify-center",
174
184
  hasMarks && "relative"
175
185
  );
176
- return /* @__PURE__ */ jsxs(
186
+ const showDotTooltip = dotTooltip && dotLabelEl !== null;
187
+ const node = /* @__PURE__ */ jsxs(
177
188
  Tag,
178
189
  {
179
190
  ...tagProps,
@@ -182,7 +193,7 @@ function SidebarItem({
182
193
  "data-active": active || void 0,
183
194
  "aria-current": active ? "page" : void 0,
184
195
  "aria-disabled": disabled || void 0,
185
- title: collapsed ? title : void 0,
196
+ title: collapsed && !showDotTooltip ? title : void 0,
186
197
  className: cn(
187
198
  // `w-full` matters when the Tag is a <button>: form controls size to
188
199
  // FIT-CONTENT, not to their parent, so a long label made the item wider
@@ -203,9 +214,10 @@ function SidebarItem({
203
214
  children: [
204
215
  needsHiddenLabel && /* @__PURE__ */ jsxs("span", { className: "sr-only", "data-react-fancy-sidebar-label": "", children: [
205
216
  children,
206
- " "
217
+ badgeLabelEl && !dotLabelEl ? null : " "
207
218
  ] }),
208
219
  collapsed && dotLabelEl,
220
+ collapsed && badgeLabelEl,
209
221
  showIconOnly && /* @__PURE__ */ jsxs("span", { className: iconClass, children: [
210
222
  icon,
211
223
  renderMarks(false)
@@ -229,11 +241,29 @@ function SidebarItem({
229
241
  !icon && renderMarks(true),
230
242
  /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left", children }),
231
243
  dotLabelEl,
232
- badge && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: badge })
244
+ badge && (badgeLabelEl ?? /* @__PURE__ */ jsx("span", { className: "sr-only", children: " " })),
245
+ badge && /* @__PURE__ */ jsx("span", { className: "shrink-0", "aria-hidden": badgeLabelEl ? "true" : void 0, children: badge })
233
246
  ] })
234
247
  ]
235
248
  }
236
249
  );
250
+ if (!showDotTooltip) return node;
251
+ return /* @__PURE__ */ jsx(
252
+ Tooltip,
253
+ {
254
+ placement: "right",
255
+ content: (
256
+ // aria-hidden, and deliberately NOT linked with aria-describedby:
257
+ // the same words are already in the item's accessible name via
258
+ // `dotLabel`, so exposing the bubble would read them twice.
259
+ /* @__PURE__ */ jsxs("span", { "aria-hidden": "true", "data-react-fancy-sidebar-tooltip": "", children: [
260
+ collapsed && /* @__PURE__ */ jsx("span", { className: "block font-medium", "data-react-fancy-sidebar-tooltip-label": "", children }),
261
+ dotLabel
262
+ ] })
263
+ ),
264
+ children: node
265
+ }
266
+ );
237
267
  }
238
268
  SidebarItem.displayName = "SidebarItem";
239
269
  function SidebarGroup({ children, label, className }) {
@@ -403,5 +433,5 @@ var Sidebar = Object.assign(SidebarRoot, {
403
433
  });
404
434
 
405
435
  export { Sidebar, useSidebar };
406
- //# sourceMappingURL=chunk-MTDOFZIB.js.map
407
- //# sourceMappingURL=chunk-MTDOFZIB.js.map
436
+ //# sourceMappingURL=chunk-JY2RC6I4.js.map
437
+ //# sourceMappingURL=chunk-JY2RC6I4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Sidebar/Sidebar.context.ts","../src/components/Sidebar/Sidebar.keyboard.ts","../src/components/Sidebar/SidebarItem.tsx","../src/components/Sidebar/SidebarGroup.tsx","../src/components/Sidebar/SidebarSubmenu.tsx","../src/components/Sidebar/SidebarToggle.tsx","../src/components/Sidebar/Sidebar.tsx"],"names":["jsxs","jsx","getLetters"],"mappings":"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","file":"chunk-JY2RC6I4.js","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { SidebarContextValue } from \"./Sidebar.types\";\n\nexport const SidebarContext = createContext<SidebarContextValue | null>(null);\n\nexport function useSidebar(): SidebarContextValue {\n const ctx = useContext(SidebarContext);\n if (!ctx) {\n throw new Error(\"useSidebar must be used within a <Sidebar> component\");\n }\n return ctx;\n}\n","import { useCallback, useEffect, type KeyboardEvent, type RefObject } from \"react\";\n\n/**\n * What arrow keys move between: every `Sidebar.Item`, plus an EXPANDED\n * `Sidebar.Submenu`'s trigger button. (A collapsed submenu renders a plain\n * `<div>`, which is not focusable, so there is nothing to move to.)\n *\n * Selected by the handles the components already render, so `keyboardNav`\n * adds no markup to a Sidebar that does not use it.\n */\nconst ITEM_SELECTOR =\n \"[data-react-fancy-sidebar-item], [data-react-fancy-sidebar-submenu] > button\";\n\nconst NAV_KEYS = new Set([\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"]);\n\n/**\n * Inside a closed submenu — the panel is collapsed to zero height but its\n * items are still mounted, so without this they would be focusable while\n * invisible. `SidebarSubmenu` sets `aria-expanded` on its trigger only when\n * `keyboardNav` is on; a submenu's OWN trigger is not inside its panel.\n */\nfunction inClosedSubmenu(el: HTMLElement, root: HTMLElement): boolean {\n let sub = el.parentElement?.closest<HTMLElement>(\"[data-react-fancy-sidebar-submenu]\");\n while (sub && root.contains(sub)) {\n const trigger = sub.querySelector<HTMLElement>(\":scope > button\");\n if (trigger && trigger !== el && trigger.getAttribute(\"aria-expanded\") === \"false\") {\n return true;\n }\n sub = sub.parentElement?.closest<HTMLElement>(\"[data-react-fancy-sidebar-submenu]\");\n }\n return false;\n}\n\nfunction isNavigable(el: HTMLElement, root: HTMLElement): boolean {\n if (el.getAttribute(\"aria-disabled\") === \"true\") return false;\n if ((el as HTMLButtonElement).disabled) return false;\n return !inClosedSubmenu(el, root);\n}\n\nfunction allItems(root: HTMLElement): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(ITEM_SELECTOR));\n}\n\n/**\n * Roving tabindex + ArrowUp / ArrowDown / Home / End for `Sidebar keyboardNav`.\n *\n * The tab stop is kept on the DOM rather than in React state because items\n * can mount from anywhere below the root (a consumer's own component, a\n * submenu opening) without the root re-rendering. A MutationObserver re-applies\n * it when the set of items, or their disabled / expanded / current state,\n * changes; focus moving onto an item (by click, Tab or arrow) makes that item\n * the stop. Turning `keyboardNav` off removes every tabindex it set.\n *\n * React never renders a `tabIndex` on these items itself, so writing the\n * attribute does not fight reconciliation. (A consumer who passes `tabIndex`\n * to an item while `keyboardNav` is on is overriding the roving stop, and\n * React will reassert theirs on its next render of that item.)\n */\nexport function useSidebarKeyboardNav(\n rootRef: RefObject<HTMLElement | null>,\n enabled: boolean,\n): ((event: KeyboardEvent<HTMLElement>) => void) | undefined {\n useEffect(() => {\n const root = rootRef.current;\n if (!enabled || !root) return;\n\n const touched = new Set<HTMLElement>();\n let current: HTMLElement | null = null;\n\n const apply = () => {\n const items = allItems(root);\n const navigable = items.filter((el) => isNavigable(el, root));\n if (!current || !navigable.includes(current)) {\n current =\n navigable.find((el) => el.getAttribute(\"aria-current\") === \"page\") ??\n navigable[0] ??\n null;\n }\n for (const el of items) {\n const want = el === current ? \"0\" : \"-1\";\n if (el.getAttribute(\"tabindex\") !== want) el.setAttribute(\"tabindex\", want);\n touched.add(el);\n }\n };\n\n const onFocusIn = (event: FocusEvent) => {\n const target = event.target as HTMLElement | null;\n if (!target || !target.matches(ITEM_SELECTOR) || !root.contains(target)) return;\n if (!isNavigable(target, root)) return;\n current = target;\n apply();\n };\n\n apply();\n root.addEventListener(\"focusin\", onFocusIn);\n const observer = new MutationObserver(apply);\n observer.observe(root, {\n childList: true,\n subtree: true,\n attributes: true,\n // NOT tabindex: that is what `apply` writes.\n attributeFilter: [\"aria-disabled\", \"aria-expanded\", \"aria-current\", \"disabled\"],\n });\n\n return () => {\n observer.disconnect();\n root.removeEventListener(\"focusin\", onFocusIn);\n for (const el of touched) el.removeAttribute(\"tabindex\");\n };\n }, [rootRef, enabled]);\n\n const onKeyDown = useCallback(\n (event: KeyboardEvent<HTMLElement>) => {\n const root = rootRef.current;\n if (!root || !NAV_KEYS.has(event.key)) return;\n if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;\n // Only when an ITEM has focus. An input, textarea, select or\n // contenteditable inside the sidebar (a filter box, say) keeps its keys:\n // it does not match the item selector, so it never gets here.\n const target = event.target as HTMLElement;\n if (!target.matches(ITEM_SELECTOR)) return;\n\n const items = allItems(root);\n const navigable = items.filter((el) => isNavigable(el, root));\n if (navigable.length === 0) return;\n\n let next: HTMLElement | undefined;\n if (event.key === \"Home\") next = navigable[0];\n else if (event.key === \"End\") next = navigable[navigable.length - 1];\n else {\n // Walk from the target's position among ALL items, so a focused item\n // that is itself not navigable (disabled while focused) still moves.\n const from = items.indexOf(target);\n const step = event.key === \"ArrowDown\" ? 1 : -1;\n for (let i = from + step; i >= 0 && i < items.length; i += step) {\n if (navigable.includes(items[i])) {\n next = items[i];\n break;\n }\n }\n }\n\n // Handled either way: an arrow at the end of the list must not scroll\n // the page instead. No wrap, matching a list rather than a menu.\n event.preventDefault();\n next?.focus();\n },\n [rootRef],\n );\n\n return enabled ? onKeyDown : undefined;\n}\n","import type { ElementType, ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { badgeDot } from \"../Badge/Badge.colors\";\nimport { Tooltip } from \"../Tooltip\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarDotColor, SidebarItemProps } from \"./Sidebar.types\";\n\n/**\n * The surface-coloured ring separates the dot from whatever it sits on (an\n * icon, the active-row fill) in both modes.\n */\nconst DOT_BASE =\n \"pointer-events-none absolute h-2 w-2 rounded-full ring-2 ring-[color:var(--fancy-surface,var(--color-white))] dark:ring-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\";\n\n/** Extract first 3 characters from a ReactNode if it's a string. */\nfunction getLetters(children: React.ReactNode): string {\n if (typeof children === \"string\") return children.slice(0, 3);\n return \"...\";\n}\n\nexport function SidebarItem({\n children,\n href,\n as: As,\n icon,\n active = false,\n disabled = false,\n badge,\n badgeLabel,\n collapsedBadge = false,\n dot,\n dotLabel,\n dotTooltip = false,\n onClick,\n className,\n ...rest\n}: SidebarItemProps) {\n const { collapsed, collapseMode } = useSidebar();\n\n // Link mode engages on `href` OR `as` — a `to`-based router (TanStack Router,\n // React Router) passes no href, and would otherwise render a <button> that\n // navigates nowhere. `onClick` now rides along in link mode instead of being\n // dropped: an item that both navigates and closes a drawer is the common case.\n const isLink = Boolean(href || As);\n const Tag = isLink ? ((As ?? \"a\") as ElementType) : \"button\";\n const tagProps = isLink\n ? { ...(href ? { href } : {}), onClick }\n : { type: \"button\" as const, onClick };\n\n const showIconOnly = collapsed && collapseMode === \"icons\" && icon;\n const showLetters = collapsed && (collapseMode === \"letters\" || (collapseMode === \"icons\" && !icon));\n\n const title = typeof children === \"string\" ? children : undefined;\n\n // --- Attention marks (6.1.0). All of this is inert unless `dot` or\n // `collapsedBadge` is passed, so an item without them renders exactly the\n // markup it always did.\n const dotColor: SidebarDotColor | null = dot === true ? \"red\" : dot || null;\n const showCollapsedBadge = collapsed && collapsedBadge && Boolean(badge);\n const hasMarks = dotColor !== null || showCollapsedBadge;\n // `badgeLabel` (6.2.0) is read in place of the visible badge, so it only\n // exists while the badge is actually rendered: always expanded, and\n // collapsed only with `collapsedBadge`.\n const badgeShown = Boolean(badge) && (!collapsed || showCollapsedBadge);\n const badgeLabelEl =\n badgeShown && badgeLabel ? (\n // The comma is the separator, so whatever renders before this must not\n // end in a space (\"tynn , 2 agents\"); see the two trailing spaces below.\n <span className=\"sr-only\" data-react-fancy-sidebar-badge-label=\"\">\n {`, ${badgeLabel}`}\n </span>\n ) : null;\n const dotLabelEl =\n dotColor && dotLabel ? (\n // The spaces are load-bearing: adjacent inline elements concatenate in\n // the accessible name, so without them it reads \"Inbox3 unread\".\n <span className=\"sr-only\" data-react-fancy-sidebar-dot-label=\"\">\n {\" \"}\n {dotLabel}\n {badgeLabelEl ? null : \" \"}\n </span>\n ) : null;\n // Collapsed, the item's visible content is only an icon (or an\n // abbreviation), and its name came from `title`. But accname takes CONTENT\n // over `title`, so a dot label or a badge count would become the item's\n // whole name (\"3 unread\" instead of \"Inbox\"). A visually hidden copy of the\n // label keeps the name first.\n const needsHiddenLabel = collapsed && (dotLabelEl !== null || showCollapsedBadge);\n\n const renderMarks = (anchoredToItem: boolean): ReactNode => (\n <>\n {showCollapsedBadge && (\n <span\n data-react-fancy-sidebar-badge=\"\"\n aria-hidden={badgeLabelEl ? \"true\" : undefined}\n className=\"pointer-events-none absolute -right-3 -top-2.5 whitespace-nowrap\"\n >\n {badge}\n </span>\n )}\n {dotColor && (\n <span\n aria-hidden=\"true\"\n data-react-fancy-sidebar-dot=\"\"\n data-color={dotColor}\n // A collapsed badge takes the top corner; the dot moves to the\n // bottom one rather than hiding under it.\n data-position={showCollapsedBadge ? \"bottom\" : \"top\"}\n className={cn(\n DOT_BASE,\n badgeDot[dotColor],\n anchoredToItem\n ? \"right-1.5 top-1.5\"\n : showCollapsedBadge\n ? \"-bottom-0.5 -right-0.5\"\n : \"-right-0.5 -top-0.5\",\n )}\n />\n )}\n </>\n );\n // Marks sit at the icon's corner when there is an icon, at the letters'\n // corner on a lettered rail, and at the item's own corner otherwise.\n const iconClass = cn(\n \"flex h-5 w-5 shrink-0 items-center justify-center\",\n hasMarks && \"relative\",\n );\n\n // `dotTooltip` (6.2.0) shows the dot's words to sighted users too. It needs\n // words to show, so it is inert without both `dot` and `dotLabel`.\n const showDotTooltip = dotTooltip && dotLabelEl !== null;\n\n const node = (\n <Tag\n {...tagProps}\n {...rest}\n data-react-fancy-sidebar-item=\"\"\n data-active={active || undefined}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={disabled || undefined}\n // With a dot tooltip the native `title` would be a second bubble over\n // the first, so the tooltip takes over and carries the label itself.\n // The name does not depend on it: a collapsed item with a dot label\n // already has the visually hidden label copy.\n title={collapsed && !showDotTooltip ? title : undefined}\n className={cn(\n // `w-full` matters when the Tag is a <button>: form controls size to\n // FIT-CONTENT, not to their parent, so a long label made the item wider\n // than the sidebar and an ancestor clipped the overflow — which reads as\n // a label cut off mid-word rather than an ellipsis. Without this,\n // `min-w-0` on the label below can never engage, because the item is\n // never under width pressure in the first place.\n \"flex w-full items-center rounded-md text-sm font-medium transition-colors\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-blue-500\",\n collapsed ? \"justify-center px-2 py-2\" : \"gap-2 px-3 py-2\",\n active\n ? \"bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] text-[color:var(--fancy-text,var(--color-zinc-900))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\"\n : \"text-[color:var(--fancy-text-subtle,var(--color-zinc-600))] hover:bg-[color:var(--fancy-surface-hover,var(--color-zinc-50))] hover:text-[color:var(--fancy-text,var(--color-zinc-900))] dark:text-[color:var(--fancy-text-subtle-dark,var(--color-zinc-400))] dark:hover:bg-[color:var(--fancy-surface-hover-dark,color-mix(in_oklab,var(--color-zinc-800)_50%,transparent))] dark:hover:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\",\n disabled && \"pointer-events-none opacity-50\",\n // Containing block for the visually hidden labels, and for a dot that\n // has no icon to sit on.\n hasMarks && \"relative\",\n className,\n )}\n >\n {needsHiddenLabel && (\n <span className=\"sr-only\" data-react-fancy-sidebar-label=\"\">\n {children}\n {badgeLabelEl && !dotLabelEl ? null : \" \"}\n </span>\n )}\n {collapsed && dotLabelEl}\n {collapsed && badgeLabelEl}\n {showIconOnly && (\n <span className={iconClass}>\n {icon}\n {renderMarks(false)}\n </span>\n )}\n {showLetters && (\n <span\n className={cn(\"text-xs font-semibold uppercase\", hasMarks && \"relative\")}\n // The abbreviation would otherwise read as part of the name (\"Inb\").\n aria-hidden={needsHiddenLabel || undefined}\n >\n {getLetters(children)}\n {renderMarks(false)}\n </span>\n )}\n {!collapsed && (\n <>\n {icon && (\n <span className={iconClass}>\n {icon}\n {renderMarks(false)}\n </span>\n )}\n {!icon && renderMarks(true)}\n {/*\n `min-w-0` is load-bearing, not tidiness. A flex item defaults to\n `min-width: auto`, which resolves to its MIN-CONTENT width — so with\n `truncate` alone the span refuses to shrink below the full label,\n and the item grows wider than the sidebar instead of ellipsing.\n The overflow then gets clipped by an ancestor, which looks like a\n mid-word cut rather than a truncation.\n\n Only shows up with labels longer than the sidebar is wide, which is\n why it survived: short nav labels never trigger it.\n */}\n <span className=\"min-w-0 flex-1 truncate text-left\">{children}</span>\n {dotLabelEl}\n {/*\n Label and badge are adjacent elements, and adjacent elements\n concatenate in a layout-unaware accessible name: \"tynn2\". A visually\n hidden space separates them (6.2.0); with `badgeLabel`, the label is\n read instead and the badge itself is hidden from assistive tech.\n */}\n {badge && (badgeLabelEl ?? <span className=\"sr-only\"> </span>)}\n {badge && (\n <span className=\"shrink-0\" aria-hidden={badgeLabelEl ? \"true\" : undefined}>\n {badge}\n </span>\n )}\n </>\n )}\n </Tag>\n );\n\n if (!showDotTooltip) return node;\n\n return (\n <Tooltip\n placement=\"right\"\n content={\n // aria-hidden, and deliberately NOT linked with aria-describedby:\n // the same words are already in the item's accessible name via\n // `dotLabel`, so exposing the bubble would read them twice.\n <span aria-hidden=\"true\" data-react-fancy-sidebar-tooltip=\"\">\n {collapsed && (\n <span className=\"block font-medium\" data-react-fancy-sidebar-tooltip-label=\"\">\n {children}\n </span>\n )}\n {dotLabel}\n </span>\n }\n >\n {node}\n </Tooltip>\n );\n}\n\nSidebarItem.displayName = \"SidebarItem\";\n","import { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarGroupProps } from \"./Sidebar.types\";\n\nexport function SidebarGroup({ children, label, className }: SidebarGroupProps) {\n const { collapsed } = useSidebar();\n\n return (\n <div data-react-fancy-sidebar-group=\"\" className={cn(\"py-1\", className)}>\n {label && !collapsed && (\n <p className=\"mb-1 px-3 text-xs font-semibold uppercase tracking-wider text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\">\n {label}\n </p>\n )}\n {label && collapsed && (\n <div className=\"mx-auto mb-1 h-px w-6 bg-[color:var(--fancy-border,var(--color-zinc-200))] dark:bg-[color:var(--fancy-border-dark,var(--color-zinc-700))]\" />\n )}\n {children}\n </div>\n );\n}\n\nSidebarGroup.displayName = \"SidebarGroup\";\n","import { useState } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarSubmenuProps } from \"./Sidebar.types\";\n\n/** Extract first 3 characters from a string. */\nfunction getLetters(label: string): string {\n return label.slice(0, 3);\n}\n\nexport function SidebarSubmenu({\n children,\n label,\n icon,\n defaultOpen = false,\n className,\n}: SidebarSubmenuProps) {\n const [open, setOpen] = useState(defaultOpen);\n const { collapsed, collapseMode, keyboardNav } = useSidebar();\n\n const showIconOnly = collapsed && collapseMode === \"icons\" && icon;\n const showLetters = collapsed && (collapseMode === \"letters\" || (collapseMode === \"icons\" && !icon));\n\n // When collapsed, just show the icon/letters as a simple item (no expand)\n if (collapsed) {\n return (\n <div\n data-react-fancy-sidebar-submenu=\"\"\n title={label}\n className={cn(\n \"flex items-center justify-center rounded-md px-2 py-2 text-sm font-medium transition-colors\",\n \"text-[color:var(--fancy-text-subtle,var(--color-zinc-600))] hover:bg-[color:var(--fancy-surface-hover,var(--color-zinc-50))] hover:text-[color:var(--fancy-text,var(--color-zinc-900))]\",\n \"dark:text-[color:var(--fancy-text-subtle-dark,var(--color-zinc-400))] dark:hover:bg-[color:var(--fancy-surface-hover-dark,color-mix(in_oklab,var(--color-zinc-800)_50%,transparent))] dark:hover:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\",\n className,\n )}\n >\n {showIconOnly && (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>\n )}\n {showLetters && (\n <span className=\"text-xs font-semibold uppercase\">{getLetters(label)}</span>\n )}\n </div>\n );\n }\n\n return (\n <div data-react-fancy-sidebar-submenu=\"\" className={className}>\n <button\n type=\"button\"\n // Only with `keyboardNav`, which reads it to skip a closed panel's\n // still-mounted items; without it the markup is unchanged from 6.0.\n aria-expanded={keyboardNav ? open : undefined}\n onClick={() => setOpen((v) => !v)}\n className={cn(\n \"flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors\",\n \"text-[color:var(--fancy-text-subtle,var(--color-zinc-600))] hover:bg-[color:var(--fancy-surface-hover,var(--color-zinc-50))] hover:text-[color:var(--fancy-text,var(--color-zinc-900))]\",\n \"dark:text-[color:var(--fancy-text-subtle-dark,var(--color-zinc-400))] dark:hover:bg-[color:var(--fancy-surface-hover-dark,color-mix(in_oklab,var(--color-zinc-800)_50%,transparent))] dark:hover:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\",\n )}\n >\n {icon && <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>}\n <span className=\"flex-1 text-left\">{label}</span>\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 opacity-60 transition-transform duration-200\",\n open && \"rotate-180\",\n )}\n />\n </button>\n <div\n className={cn(\n \"grid transition-[grid-template-rows] duration-200\",\n open ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\",\n )}\n >\n <div className=\"overflow-hidden\">\n <div className=\"ml-4 border-l border-[color:var(--fancy-border,var(--color-zinc-200))] pl-2 pt-1 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))]\">\n {children}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nSidebarSubmenu.displayName = \"SidebarSubmenu\";\n","import { PanelLeftClose, PanelLeftOpen } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarToggleProps } from \"./Sidebar.types\";\n\nexport function SidebarToggle({ className }: SidebarToggleProps) {\n const { collapsed, setCollapsed } = useSidebar();\n\n return (\n <button\n type=\"button\"\n data-react-fancy-sidebar-toggle=\"\"\n onClick={() => setCollapsed(!collapsed)}\n title={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className={cn(\n \"flex items-center justify-center rounded-md p-1.5 text-zinc-400 transition-colors\",\n \"hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] hover:text-zinc-600 dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))] dark:hover:text-zinc-300\",\n className,\n )}\n >\n {collapsed ? (\n <PanelLeftOpen className=\"h-4 w-4\" />\n ) : (\n <PanelLeftClose className=\"h-4 w-4\" />\n )}\n </button>\n );\n}\n\nSidebarToggle.displayName = \"SidebarToggle\";\n","import { useRef } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks\";\nimport { SidebarContext } from \"./Sidebar.context\";\nimport { useSidebarKeyboardNav } from \"./Sidebar.keyboard\";\nimport { SidebarItem } from \"./SidebarItem\";\nimport { SidebarGroup } from \"./SidebarGroup\";\nimport { SidebarSubmenu } from \"./SidebarSubmenu\";\nimport { SidebarToggle } from \"./SidebarToggle\";\nimport type { SidebarProps } from \"./Sidebar.types\";\n\nfunction SidebarRoot({\n children,\n collapsed: controlledCollapsed,\n defaultCollapsed = false,\n onCollapsedChange,\n collapseMode = \"icons\",\n embedded = false,\n navLabel,\n keyboardNav = false,\n className,\n}: SidebarProps) {\n const [collapsed, setCollapsed] = useControllableState(\n controlledCollapsed,\n defaultCollapsed,\n onCollapsedChange,\n );\n const rootRef = useRef<HTMLElement>(null);\n const onKeyDown = useSidebarKeyboardNav(rootRef, keyboardNav);\n\n return (\n <SidebarContext.Provider value={{ collapsed, collapseMode, setCollapsed, keyboardNav }}>\n <aside\n ref={rootRef}\n onKeyDown={onKeyDown}\n data-react-fancy-sidebar=\"\"\n data-collapsed={collapsed || undefined}\n data-embedded={embedded || undefined}\n className={cn(\n \"flex flex-col gap-0.5 transition-[width] duration-200\",\n // The app-shell chrome. Correct for the rail this is usually used as,\n // and actively wrong inside a container that already draws its own —\n // a 240px rail in a 300px card puts its right border 240px in, which\n // reads as a stray line slicing the panel rather than an edge.\n !embedded && \"border-r border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n // Collapsed is a fixed icon rail either way; only the expanded width\n // defers to the container.\n collapsed ? \"w-16\" : embedded ? \"w-full\" : \"w-60\",\n className,\n )}\n >\n {navLabel ? (\n // The <aside> is a complementary landmark, not a navigation one, so\n // without this a screen reader's landmark list shows no navigation.\n // Opt-in: an element between the <aside> and its children is a DOM\n // change a consumer's CSS (`aside > a`) or tests may depend on. The\n // <nav> takes over the column layout and fills the rail, so a footer\n // pushed down with `mt-auto` still reaches the bottom.\n <nav\n data-react-fancy-sidebar-nav=\"\"\n aria-label={navLabel}\n className=\"flex min-h-0 flex-1 flex-col gap-0.5\"\n >\n {children}\n </nav>\n ) : (\n children\n )}\n </aside>\n </SidebarContext.Provider>\n );\n}\n\nexport const Sidebar = Object.assign(SidebarRoot, {\n Item: SidebarItem,\n Group: SidebarGroup,\n Submenu: SidebarSubmenu,\n Toggle: SidebarToggle,\n});\n"]}
@@ -101,6 +101,16 @@ function MultiSwitch({
101
101
  react.useEffect(() => {
102
102
  updateIndicator();
103
103
  }, [updateIndicator]);
104
+ react.useEffect(() => {
105
+ if (typeof ResizeObserver === "undefined") return;
106
+ const container = containerRef.current;
107
+ const activeItem = itemRefs.current[selectedIndex];
108
+ if (!container || !activeItem) return;
109
+ const observer = new ResizeObserver(() => updateIndicator());
110
+ observer.observe(container);
111
+ observer.observe(activeItem);
112
+ return () => observer.disconnect();
113
+ }, [updateIndicator, selectedIndex, showControl]);
104
114
  const control = !showControl ? /* @__PURE__ */ jsxRuntime.jsx(chunkP53432AK_cjs.DisplayValue, { size, interactive, onActivate: enterEdit, children: resolvedOptions.find((o) => o.value === value)?.label }) : /* @__PURE__ */ jsxRuntime.jsxs(
105
115
  "div",
106
116
  {
@@ -188,5 +198,5 @@ function MultiSwitch({
188
198
  MultiSwitch.displayName = "MultiSwitch";
189
199
 
190
200
  exports.MultiSwitch = MultiSwitch;
191
- //# sourceMappingURL=chunk-IB673TEG.cjs.map
192
- //# sourceMappingURL=chunk-IB673TEG.cjs.map
201
+ //# sourceMappingURL=chunk-KOAMRCSC.cjs.map
202
+ //# sourceMappingURL=chunk-KOAMRCSC.cjs.map