@particle-academy/react-fancy 6.2.0 → 6.3.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/CHANGELOG.md +34 -0
- package/README.md +1 -0
- package/dist/breadcrumbs.cjs +2 -2
- package/dist/breadcrumbs.d.cts +13 -2
- package/dist/breadcrumbs.d.ts +13 -2
- package/dist/breadcrumbs.js +1 -1
- package/dist/chunk-5EW47IH7.js +194 -0
- package/dist/chunk-5EW47IH7.js.map +1 -0
- package/dist/{chunk-WJHPZS3U.js → chunk-GTS3QA7M.js} +11 -4
- package/dist/chunk-GTS3QA7M.js.map +1 -0
- package/dist/{chunk-EWE776WI.cjs → chunk-SKMORSBO.cjs} +11 -4
- package/dist/chunk-SKMORSBO.cjs.map +1 -0
- package/dist/chunk-Y3QAEF2P.cjs +196 -0
- package/dist/chunk-Y3QAEF2P.cjs.map +1 -0
- package/dist/index.cjs +13 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/inputs.cjs +5 -5
- package/dist/inputs.js +1 -1
- package/dist/stepper.cjs +14 -0
- package/dist/stepper.cjs.map +1 -0
- package/dist/stepper.d.cts +72 -0
- package/dist/stepper.d.ts +72 -0
- package/dist/stepper.js +5 -0
- package/dist/stepper.js.map +1 -0
- package/docs/Breadcrumbs.md +10 -1
- package/docs/Stepper.md +124 -0
- package/package.json +11 -1
- package/dist/chunk-EWE776WI.cjs.map +0 -1
- package/dist/chunk-WJHPZS3U.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [6.3.0] - 2026-11-01
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`Stepper`: ordered steps with states (requested by Prism).** An `<ol>` of
|
|
19
|
+
steps, each with a title, optional description and rich content, in one of
|
|
20
|
+
`upcoming` / `current` / `complete` / `error`. Data-driven through a JSON-
|
|
21
|
+
friendly `steps` array, or compound with `Stepper.Step` (read as data, so both
|
|
22
|
+
forms render identically). Controlled (`current` + `onChange`) or
|
|
23
|
+
uncontrolled (`defaultCurrent`); a step's own `state` overrides the derived
|
|
24
|
+
one, which is how `error` is shown. **Pure content by default: no button,
|
|
25
|
+
input or form element at all.** `clickable` opts in to step buttons, with
|
|
26
|
+
arrow-key / Home / End focus movement. `aria-current="step"` on the current
|
|
27
|
+
step; each state is in visually hidden text and in the indicator's glyph,
|
|
28
|
+
never colour alone; `stateLabels` translates the words. Vertical by default,
|
|
29
|
+
`orientation="horizontal"` for short content; `showContent="current"` shows
|
|
30
|
+
only the current step's body. Server-renders without DOM globals. Handles:
|
|
31
|
+
`data-react-fancy-stepper`, `data-react-fancy-stepper-step` with `data-state`,
|
|
32
|
+
`data-index` and `data-step-id`. Subpath: `@particle-academy/react-fancy/stepper`.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- **`BreadcrumbsItemProps` now accepts the element's HTML attributes.**
|
|
37
|
+
`Breadcrumbs.Item` always forwarded `title`, `id`, `aria-*`, `style` and
|
|
38
|
+
handlers to the element it renders, but the type listed its keys by hand and
|
|
39
|
+
rejected them, so a consumer titling a truncated crumb had to cast. It now
|
|
40
|
+
extends `HTMLAttributes<HTMLElement>` (the attributes valid on every element a
|
|
41
|
+
crumb can be: `<a>`, the `as` component, `<button>`, `<span>`), with
|
|
42
|
+
`onClick` kept at its existing `() => void` signature. The collapsed (below
|
|
43
|
+
`md`) dropdown now carries a crumb's `title` onto its menu entry; other
|
|
44
|
+
attributes stay on the trail, because both trails are in the DOM at once and
|
|
45
|
+
an `id` or `data-*` handle would be duplicated. **No action needed:** this
|
|
46
|
+
only adds accepted props, and every existing usage type-checks unchanged.
|
|
47
|
+
|
|
14
48
|
## [6.2.0] - 2026-11-01
|
|
15
49
|
|
|
16
50
|
### Added
|
package/README.md
CHANGED
|
@@ -130,6 +130,7 @@ npx vite build # Build demo app (verifies imports work)
|
|
|
130
130
|
| Card | Container with Header, Body, Footer compound slots | [docs](docs/Card.md) |
|
|
131
131
|
| Callout | Alert/info box with icon, color, and dismissible support | [docs](docs/Callout.md) |
|
|
132
132
|
| Timeline | Stacked, alternating, and horizontal timeline with data-driven or compound API | [docs](docs/Timeline.md) |
|
|
133
|
+
| Stepper | Ordered steps with upcoming / current / complete / error states; pure content by default, opt-in clickable steps | [docs](docs/Stepper.md) |
|
|
133
134
|
| Marquee | Auto-scrolling ticker strip with seamless wrap, px/s speed, fade edges, reduced-motion gate | [docs](docs/Marquee.md) |
|
|
134
135
|
|
|
135
136
|
### Overlay & Floating
|
package/dist/breadcrumbs.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkSKMORSBO_cjs = require('./chunk-SKMORSBO.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
|
|
12
|
+
get: function () { return chunkSKMORSBO_cjs.Breadcrumbs; }
|
|
13
13
|
});
|
|
14
14
|
//# sourceMappingURL=breadcrumbs.cjs.map
|
|
15
15
|
//# sourceMappingURL=breadcrumbs.cjs.map
|
package/dist/breadcrumbs.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import { ReactNode, HTMLAttributes } from 'react';
|
|
3
3
|
import { N as NavigableProps } from './types-DJI492iY.cjs';
|
|
4
4
|
|
|
5
5
|
interface BreadcrumbsProps {
|
|
@@ -8,7 +8,18 @@ interface BreadcrumbsProps {
|
|
|
8
8
|
shrink?: boolean;
|
|
9
9
|
className?: string;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* A crumb accepts the HTML attributes common to every element it can render as
|
|
13
|
+
* (`<a>`, the `as` component, `<button>` or `<span>`), so `title`, `id`,
|
|
14
|
+
* `aria-*`, `style` and handlers are typed as well as forwarded. Typed against
|
|
15
|
+
* `HTMLElement` rather than one element because the crumb's element depends on
|
|
16
|
+
* its props; anchor-only attributes such as `target` are not offered, since the
|
|
17
|
+
* same crumb renders as a `<span>` once it is `active`.
|
|
18
|
+
*
|
|
19
|
+
* `onClick` is omitted from the element's attributes and redeclared below with
|
|
20
|
+
* its existing `() => void` signature.
|
|
21
|
+
*/
|
|
22
|
+
interface BreadcrumbsItemProps extends NavigableProps, Omit<HTMLAttributes<HTMLElement>, "onClick" | "children"> {
|
|
12
23
|
children: ReactNode;
|
|
13
24
|
active?: boolean;
|
|
14
25
|
/**
|
package/dist/breadcrumbs.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import { ReactNode, HTMLAttributes } from 'react';
|
|
3
3
|
import { N as NavigableProps } from './types-DJI492iY.js';
|
|
4
4
|
|
|
5
5
|
interface BreadcrumbsProps {
|
|
@@ -8,7 +8,18 @@ interface BreadcrumbsProps {
|
|
|
8
8
|
shrink?: boolean;
|
|
9
9
|
className?: string;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* A crumb accepts the HTML attributes common to every element it can render as
|
|
13
|
+
* (`<a>`, the `as` component, `<button>` or `<span>`), so `title`, `id`,
|
|
14
|
+
* `aria-*`, `style` and handlers are typed as well as forwarded. Typed against
|
|
15
|
+
* `HTMLElement` rather than one element because the crumb's element depends on
|
|
16
|
+
* its props; anchor-only attributes such as `target` are not offered, since the
|
|
17
|
+
* same crumb renders as a `<span>` once it is `active`.
|
|
18
|
+
*
|
|
19
|
+
* `onClick` is omitted from the element's attributes and redeclared below with
|
|
20
|
+
* its existing `() => void` signature.
|
|
21
|
+
*/
|
|
22
|
+
interface BreadcrumbsItemProps extends NavigableProps, Omit<HTMLAttributes<HTMLElement>, "onClick" | "children"> {
|
|
12
23
|
children: ReactNode;
|
|
13
24
|
active?: boolean;
|
|
14
25
|
/**
|
package/dist/breadcrumbs.js
CHANGED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { useControllableState } from './chunk-EDYAXGUM.js';
|
|
2
|
+
import { cn } from './chunk-MMW2JGKZ.js';
|
|
3
|
+
import { forwardRef, Children, isValidElement } from 'react';
|
|
4
|
+
import { Check } from 'lucide-react';
|
|
5
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var DEFAULT_STATE_LABELS = {
|
|
8
|
+
upcoming: "Not started",
|
|
9
|
+
current: "Current",
|
|
10
|
+
complete: "Completed",
|
|
11
|
+
error: "Error"
|
|
12
|
+
};
|
|
13
|
+
function StepperStep(_props) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
StepperStep.displayName = "StepperStep";
|
|
17
|
+
function stepsFromChildren(children) {
|
|
18
|
+
const out = [];
|
|
19
|
+
for (const child of Children.toArray(children)) {
|
|
20
|
+
if (!isValidElement(child) || child.type !== StepperStep) continue;
|
|
21
|
+
const { children: content, ...rest } = child.props;
|
|
22
|
+
out.push({ ...rest, content });
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
var indicatorClass = {
|
|
27
|
+
complete: "border-transparent bg-zinc-900 text-white dark:bg-white dark:text-zinc-900",
|
|
28
|
+
current: "border-2 border-zinc-900 bg-[color:var(--fancy-surface,var(--color-white))] text-zinc-900 ring-4 ring-zinc-900/10 dark:border-white dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))] dark:text-white dark:ring-white/15",
|
|
29
|
+
upcoming: "border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]",
|
|
30
|
+
error: "border-transparent bg-red-600 text-white dark:bg-red-500"
|
|
31
|
+
};
|
|
32
|
+
var titleClass = {
|
|
33
|
+
complete: "font-medium text-zinc-900 dark:text-white",
|
|
34
|
+
current: "font-semibold text-zinc-900 dark:text-white",
|
|
35
|
+
upcoming: "font-medium text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]",
|
|
36
|
+
error: "font-semibold text-red-700 dark:text-red-400"
|
|
37
|
+
};
|
|
38
|
+
function Indicator({ state, index }) {
|
|
39
|
+
return /* @__PURE__ */ jsx(
|
|
40
|
+
"span",
|
|
41
|
+
{
|
|
42
|
+
"aria-hidden": "true",
|
|
43
|
+
"data-react-fancy-stepper-indicator": "",
|
|
44
|
+
className: cn(
|
|
45
|
+
"relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-full border text-sm font-semibold",
|
|
46
|
+
indicatorClass[state]
|
|
47
|
+
),
|
|
48
|
+
children: state === "complete" ? /* @__PURE__ */ jsx(Check, { size: 16, strokeWidth: 3 }) : state === "error" ? "!" : index + 1
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
var StepperRoot = forwardRef(
|
|
53
|
+
({
|
|
54
|
+
steps: stepsProp,
|
|
55
|
+
children,
|
|
56
|
+
current: currentProp,
|
|
57
|
+
defaultCurrent = 0,
|
|
58
|
+
onChange,
|
|
59
|
+
orientation = "vertical",
|
|
60
|
+
clickable = false,
|
|
61
|
+
showContent = "all",
|
|
62
|
+
stateLabels,
|
|
63
|
+
className,
|
|
64
|
+
onKeyDown,
|
|
65
|
+
...rest
|
|
66
|
+
}, ref) => {
|
|
67
|
+
const [current, setCurrent] = useControllableState(currentProp, defaultCurrent, onChange);
|
|
68
|
+
const steps = stepsProp ?? stepsFromChildren(children);
|
|
69
|
+
const labels = { ...DEFAULT_STATE_LABELS, ...stateLabels };
|
|
70
|
+
const horizontal = orientation === "horizontal";
|
|
71
|
+
const handleKeyDown = (e) => {
|
|
72
|
+
onKeyDown?.(e);
|
|
73
|
+
if (!clickable || e.defaultPrevented) return;
|
|
74
|
+
const prevKey = horizontal ? "ArrowLeft" : "ArrowUp";
|
|
75
|
+
const nextKey = horizontal ? "ArrowRight" : "ArrowDown";
|
|
76
|
+
if (![prevKey, nextKey, "Home", "End"].includes(e.key)) return;
|
|
77
|
+
const list = e.currentTarget;
|
|
78
|
+
const target = e.target.closest("[data-react-fancy-stepper-trigger]");
|
|
79
|
+
if (!target || target.closest("[data-react-fancy-stepper]") !== list) return;
|
|
80
|
+
const buttons = Array.from(
|
|
81
|
+
list.querySelectorAll("[data-react-fancy-stepper-trigger]")
|
|
82
|
+
).filter((b) => b.closest("[data-react-fancy-stepper]") === list && !b.disabled);
|
|
83
|
+
const at = buttons.indexOf(target);
|
|
84
|
+
let next;
|
|
85
|
+
if (e.key === "Home") next = buttons[0];
|
|
86
|
+
else if (e.key === "End") next = buttons[buttons.length - 1];
|
|
87
|
+
else if (e.key === nextKey) next = buttons[at + 1] ?? target;
|
|
88
|
+
else next = at > 0 ? buttons[at - 1] : target;
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
next?.focus();
|
|
91
|
+
};
|
|
92
|
+
return /* @__PURE__ */ jsx(
|
|
93
|
+
"ol",
|
|
94
|
+
{
|
|
95
|
+
ref,
|
|
96
|
+
"data-react-fancy-stepper": "",
|
|
97
|
+
"data-orientation": orientation,
|
|
98
|
+
"data-current": current,
|
|
99
|
+
className: cn(horizontal ? "flex items-start" : "flex flex-col", className),
|
|
100
|
+
onKeyDown: handleKeyDown,
|
|
101
|
+
...rest,
|
|
102
|
+
children: steps.map((step, index) => {
|
|
103
|
+
const derived = index < current ? "complete" : index === current ? "current" : "upcoming";
|
|
104
|
+
const state = step.state ?? derived;
|
|
105
|
+
const isCurrent = index === current;
|
|
106
|
+
const isLast = index === steps.length - 1;
|
|
107
|
+
const showBody = step.content != null && (showContent === "all" || isCurrent);
|
|
108
|
+
const headerInner = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
109
|
+
/* @__PURE__ */ jsx(Indicator, { state, index }),
|
|
110
|
+
/* @__PURE__ */ jsxs("span", { className: "sr-only", "data-react-fancy-stepper-state": "", children: [
|
|
111
|
+
labels[state],
|
|
112
|
+
":",
|
|
113
|
+
" "
|
|
114
|
+
] }),
|
|
115
|
+
/* @__PURE__ */ jsx("span", { "data-react-fancy-stepper-title": "", className: cn("text-sm", titleClass[state]), children: step.title })
|
|
116
|
+
] });
|
|
117
|
+
const headerClass = horizontal ? "flex flex-col items-center gap-2 text-center" : "flex items-center gap-x-4 text-left";
|
|
118
|
+
const header = clickable ? /* @__PURE__ */ jsx(
|
|
119
|
+
"button",
|
|
120
|
+
{
|
|
121
|
+
type: "button",
|
|
122
|
+
"data-react-fancy-stepper-trigger": "",
|
|
123
|
+
disabled: step.disabled,
|
|
124
|
+
onClick: () => {
|
|
125
|
+
if (index !== current) setCurrent(index);
|
|
126
|
+
},
|
|
127
|
+
className: cn(
|
|
128
|
+
headerClass,
|
|
129
|
+
"cursor-pointer rounded-md border-0 bg-transparent p-0",
|
|
130
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
|
|
131
|
+
"focus-visible:ring-[color:var(--fancy-focus,var(--color-blue-500))] focus-visible:ring-offset-[color:var(--fancy-surface,var(--color-white))]",
|
|
132
|
+
"dark:focus-visible:ring-[color:var(--fancy-focus-dark,var(--color-blue-400))] dark:focus-visible:ring-offset-[color:var(--fancy-surface-dark,var(--color-zinc-900))]",
|
|
133
|
+
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
134
|
+
),
|
|
135
|
+
children: headerInner
|
|
136
|
+
}
|
|
137
|
+
) : /* @__PURE__ */ jsx("div", { className: headerClass, children: headerInner });
|
|
138
|
+
return /* @__PURE__ */ jsxs(
|
|
139
|
+
"li",
|
|
140
|
+
{
|
|
141
|
+
"data-react-fancy-stepper-step": "",
|
|
142
|
+
"data-state": state,
|
|
143
|
+
"data-index": index,
|
|
144
|
+
"data-step-id": step.id,
|
|
145
|
+
"data-disabled": step.disabled ? "true" : void 0,
|
|
146
|
+
"aria-current": isCurrent ? "step" : void 0,
|
|
147
|
+
className: cn("relative", horizontal ? "min-w-0 flex-1" : !isLast && "pb-8"),
|
|
148
|
+
children: [
|
|
149
|
+
!isLast && /* @__PURE__ */ jsx(
|
|
150
|
+
"span",
|
|
151
|
+
{
|
|
152
|
+
"aria-hidden": "true",
|
|
153
|
+
"data-react-fancy-stepper-connector": "",
|
|
154
|
+
className: cn(
|
|
155
|
+
"absolute",
|
|
156
|
+
horizontal ? "top-4 left-[calc(50%+1.5rem)] h-px w-[calc(100%-3rem)]" : "top-10 bottom-2 left-4 w-px -translate-x-1/2",
|
|
157
|
+
index < current ? "bg-zinc-900 dark:bg-white" : "bg-[color:var(--fancy-border,var(--color-zinc-200))] dark:bg-[color:var(--fancy-border-dark,var(--color-zinc-700))]"
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
),
|
|
161
|
+
header,
|
|
162
|
+
(step.description != null || showBody) && /* @__PURE__ */ jsxs("div", { className: horizontal ? "mt-1 px-2 text-center" : "pl-12", children: [
|
|
163
|
+
step.description != null && /* @__PURE__ */ jsx(
|
|
164
|
+
"div",
|
|
165
|
+
{
|
|
166
|
+
"data-react-fancy-stepper-description": "",
|
|
167
|
+
className: "text-sm text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]",
|
|
168
|
+
children: step.description
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
showBody && /* @__PURE__ */ jsx(
|
|
172
|
+
"div",
|
|
173
|
+
{
|
|
174
|
+
"data-react-fancy-stepper-content": "",
|
|
175
|
+
className: "mt-2 text-sm text-[color:var(--fancy-text-subtle,var(--color-zinc-600))] dark:text-[color:var(--fancy-text-subtle-dark,var(--color-zinc-400))]",
|
|
176
|
+
children: step.content
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
] })
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
step.id ?? index
|
|
183
|
+
);
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
StepperRoot.displayName = "Stepper";
|
|
190
|
+
var Stepper = Object.assign(StepperRoot, { Step: StepperStep });
|
|
191
|
+
|
|
192
|
+
export { Stepper };
|
|
193
|
+
//# sourceMappingURL=chunk-5EW47IH7.js.map
|
|
194
|
+
//# sourceMappingURL=chunk-5EW47IH7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Stepper/Stepper.tsx"],"names":[],"mappings":"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","file":"chunk-5EW47IH7.js","sourcesContent":["import {\n Children,\n forwardRef,\n isValidElement,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { Check } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport type {\n StepperProps,\n StepperStep as StepperStepData,\n StepperStepProps,\n StepperStepState,\n} from \"./Stepper.types\";\n\nconst DEFAULT_STATE_LABELS: Record<StepperStepState, string> = {\n upcoming: \"Not started\",\n current: \"Current\",\n complete: \"Completed\",\n error: \"Error\",\n};\n\n/**\n * Declarative step. Renders nothing itself: `Stepper` reads its props as data\n * and renders it through the same path as an entry in `steps`, so the two forms\n * cannot drift apart in markup, states or handles. Its children are the step's\n * content. It must be a DIRECT child of `Stepper` (not wrapped in another\n * component) for the same reason `Breadcrumbs.Item` must.\n */\nfunction StepperStep(_props: StepperStepProps): null {\n return null;\n}\nStepperStep.displayName = \"StepperStep\";\n\nfunction stepsFromChildren(children: ReactNode): StepperStepData[] {\n const out: StepperStepData[] = [];\n for (const child of Children.toArray(children)) {\n if (!isValidElement<StepperStepProps>(child) || child.type !== StepperStep) continue;\n const { children: content, ...rest } = child.props;\n out.push({ ...rest, content });\n }\n return out;\n}\n\nconst indicatorClass: Record<StepperStepState, string> = {\n complete:\n \"border-transparent bg-zinc-900 text-white dark:bg-white dark:text-zinc-900\",\n current:\n \"border-2 border-zinc-900 bg-[color:var(--fancy-surface,var(--color-white))] text-zinc-900 ring-4 ring-zinc-900/10 dark:border-white dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))] dark:text-white dark:ring-white/15\",\n upcoming:\n \"border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\",\n error: \"border-transparent bg-red-600 text-white dark:bg-red-500\",\n};\n\nconst titleClass: Record<StepperStepState, string> = {\n complete: \"font-medium text-zinc-900 dark:text-white\",\n current: \"font-semibold text-zinc-900 dark:text-white\",\n upcoming:\n \"font-medium text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\",\n error: \"font-semibold text-red-700 dark:text-red-400\",\n};\n\n/** The glyph differs per state, so state reads without colour: number, tick, \"!\". */\nfunction Indicator({ state, index }: { state: StepperStepState; index: number }) {\n return (\n <span\n aria-hidden=\"true\"\n data-react-fancy-stepper-indicator=\"\"\n className={cn(\n \"relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-full border text-sm font-semibold\",\n indicatorClass[state],\n )}\n >\n {state === \"complete\" ? <Check size={16} strokeWidth={3} /> : state === \"error\" ? \"!\" : index + 1}\n </span>\n );\n}\n\nconst StepperRoot = forwardRef<HTMLOListElement, StepperProps>(\n (\n {\n steps: stepsProp,\n children,\n current: currentProp,\n defaultCurrent = 0,\n onChange,\n orientation = \"vertical\",\n clickable = false,\n showContent = \"all\",\n stateLabels,\n className,\n onKeyDown,\n ...rest\n },\n ref,\n ) => {\n const [current, setCurrent] = useControllableState(currentProp, defaultCurrent, onChange);\n const steps = stepsProp ?? stepsFromChildren(children);\n const labels = { ...DEFAULT_STATE_LABELS, ...stateLabels };\n const horizontal = orientation === \"horizontal\";\n\n // Arrow keys move focus between step buttons; Enter / Space activate them\n // natively. Focus only -- the current step changes on activation, never on\n // arrowing past it. DOM is read in the handler, never during render.\n const handleKeyDown = (e: KeyboardEvent<HTMLOListElement>) => {\n onKeyDown?.(e);\n if (!clickable || e.defaultPrevented) return;\n\n const prevKey = horizontal ? \"ArrowLeft\" : \"ArrowUp\";\n const nextKey = horizontal ? \"ArrowRight\" : \"ArrowDown\";\n if (![prevKey, nextKey, \"Home\", \"End\"].includes(e.key)) return;\n\n const list = e.currentTarget;\n const target = (e.target as HTMLElement).closest<HTMLButtonElement>(\"[data-react-fancy-stepper-trigger]\");\n if (!target || target.closest(\"[data-react-fancy-stepper]\") !== list) return;\n\n // Only this stepper's own buttons: a stepper nested in step content is\n // its own list.\n const buttons = Array.from(\n list.querySelectorAll<HTMLButtonElement>(\"[data-react-fancy-stepper-trigger]\"),\n ).filter((b) => b.closest(\"[data-react-fancy-stepper]\") === list && !b.disabled);\n const at = buttons.indexOf(target);\n\n let next: HTMLButtonElement | undefined;\n if (e.key === \"Home\") next = buttons[0];\n else if (e.key === \"End\") next = buttons[buttons.length - 1];\n else if (e.key === nextKey) next = buttons[at + 1] ?? target;\n else next = at > 0 ? buttons[at - 1] : target;\n\n e.preventDefault();\n next?.focus();\n };\n\n return (\n <ol\n ref={ref}\n data-react-fancy-stepper=\"\"\n data-orientation={orientation}\n data-current={current}\n className={cn(horizontal ? \"flex items-start\" : \"flex flex-col\", className)}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n {steps.map((step, index) => {\n const derived: StepperStepState =\n index < current ? \"complete\" : index === current ? \"current\" : \"upcoming\";\n const state = step.state ?? derived;\n const isCurrent = index === current;\n const isLast = index === steps.length - 1;\n const showBody = step.content != null && (showContent === \"all\" || isCurrent);\n\n const headerInner = (\n <>\n <Indicator state={state} index={index} />\n {/* State in words, before the title so it is read first. A\n sibling of the title, so the title handle reads the title. */}\n <span className=\"sr-only\" data-react-fancy-stepper-state=\"\">\n {labels[state]}:{\" \"}\n </span>\n <span data-react-fancy-stepper-title=\"\" className={cn(\"text-sm\", titleClass[state])}>\n {step.title}\n </span>\n </>\n );\n\n const headerClass = horizontal\n ? \"flex flex-col items-center gap-2 text-center\"\n : \"flex items-center gap-x-4 text-left\";\n\n const header = clickable ? (\n <button\n type=\"button\"\n data-react-fancy-stepper-trigger=\"\"\n disabled={step.disabled}\n onClick={() => {\n if (index !== current) setCurrent(index);\n }}\n className={cn(\n headerClass,\n \"cursor-pointer rounded-md border-0 bg-transparent p-0\",\n \"focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2\",\n \"focus-visible:ring-[color:var(--fancy-focus,var(--color-blue-500))] focus-visible:ring-offset-[color:var(--fancy-surface,var(--color-white))]\",\n \"dark:focus-visible:ring-[color:var(--fancy-focus-dark,var(--color-blue-400))] dark:focus-visible:ring-offset-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n )}\n >\n {headerInner}\n </button>\n ) : (\n <div className={headerClass}>{headerInner}</div>\n );\n\n return (\n <li\n key={step.id ?? index}\n data-react-fancy-stepper-step=\"\"\n data-state={state}\n data-index={index}\n data-step-id={step.id}\n data-disabled={step.disabled ? \"true\" : undefined}\n aria-current={isCurrent ? \"step\" : undefined}\n className={cn(\"relative\", horizontal ? \"min-w-0 flex-1\" : !isLast && \"pb-8\")}\n >\n {!isLast && (\n <span\n aria-hidden=\"true\"\n data-react-fancy-stepper-connector=\"\"\n className={cn(\n \"absolute\",\n horizontal\n ? \"top-4 left-[calc(50%+1.5rem)] h-px w-[calc(100%-3rem)]\"\n : \"top-10 bottom-2 left-4 w-px -translate-x-1/2\",\n index < current\n ? \"bg-zinc-900 dark:bg-white\"\n : \"bg-[color:var(--fancy-border,var(--color-zinc-200))] dark:bg-[color:var(--fancy-border-dark,var(--color-zinc-700))]\",\n )}\n />\n )}\n {header}\n {(step.description != null || showBody) && (\n <div className={horizontal ? \"mt-1 px-2 text-center\" : \"pl-12\"}>\n {step.description != null && (\n <div\n data-react-fancy-stepper-description=\"\"\n className=\"text-sm text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\"\n >\n {step.description}\n </div>\n )}\n {showBody && (\n <div\n data-react-fancy-stepper-content=\"\"\n className=\"mt-2 text-sm text-[color:var(--fancy-text-subtle,var(--color-zinc-600))] dark:text-[color:var(--fancy-text-subtle-dark,var(--color-zinc-400))]\"\n >\n {step.content}\n </div>\n )}\n </div>\n )}\n </li>\n );\n })}\n </ol>\n );\n },\n);\n\nStepperRoot.displayName = \"Stepper\";\n\nexport const Stepper = Object.assign(StepperRoot, { Step: StepperStep });\n"]}
|
|
@@ -78,6 +78,7 @@ function BreadcrumbsDropdown({ items, activeLabel }) {
|
|
|
78
78
|
Link,
|
|
79
79
|
{
|
|
80
80
|
...item.href ? { href: item.href } : {},
|
|
81
|
+
title: item.title,
|
|
81
82
|
className: cls,
|
|
82
83
|
onClick: () => {
|
|
83
84
|
item.onClick?.();
|
|
@@ -94,6 +95,7 @@ function BreadcrumbsDropdown({ items, activeLabel }) {
|
|
|
94
95
|
"button",
|
|
95
96
|
{
|
|
96
97
|
type: "button",
|
|
98
|
+
title: item.title,
|
|
97
99
|
className: cn(cls, "cursor-pointer border-0 bg-transparent"),
|
|
98
100
|
onClick: () => {
|
|
99
101
|
onClick();
|
|
@@ -104,7 +106,7 @@ function BreadcrumbsDropdown({ items, activeLabel }) {
|
|
|
104
106
|
i
|
|
105
107
|
);
|
|
106
108
|
}
|
|
107
|
-
return /* @__PURE__ */ jsx("span", { className: cls, children: item.label }, i);
|
|
109
|
+
return /* @__PURE__ */ jsx("span", { title: item.title, className: cls, children: item.label }, i);
|
|
108
110
|
}) })
|
|
109
111
|
] });
|
|
110
112
|
}
|
|
@@ -126,7 +128,12 @@ function BreadcrumbsRoot({
|
|
|
126
128
|
href: el.props?.href,
|
|
127
129
|
as: el.props?.as,
|
|
128
130
|
onClick: el.props?.onClick,
|
|
129
|
-
active: el.props?.active
|
|
131
|
+
active: el.props?.active,
|
|
132
|
+
// Only `title` crosses into the menu. It is the full text of a crumb the
|
|
133
|
+
// consumer truncated, and the narrow menu is where labels get cut. Other
|
|
134
|
+
// attributes stay on the trail: both trails are in the DOM at once (CSS
|
|
135
|
+
// hides one), so an `id` or a `data-*` handle would be duplicated.
|
|
136
|
+
title: el.props?.title
|
|
130
137
|
};
|
|
131
138
|
});
|
|
132
139
|
const activeLabel = dropdownItems[dropdownItems.length - 1]?.label ?? "Menu";
|
|
@@ -166,5 +173,5 @@ var Breadcrumbs = Object.assign(BreadcrumbsRoot, {
|
|
|
166
173
|
});
|
|
167
174
|
|
|
168
175
|
export { Breadcrumbs };
|
|
169
|
-
//# sourceMappingURL=chunk-
|
|
170
|
-
//# sourceMappingURL=chunk-
|
|
176
|
+
//# sourceMappingURL=chunk-GTS3QA7M.js.map
|
|
177
|
+
//# sourceMappingURL=chunk-GTS3QA7M.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Breadcrumbs/BreadcrumbsItem.tsx","../src/components/Breadcrumbs/BreadcrumbsDropdown.tsx","../src/components/Breadcrumbs/Breadcrumbs.tsx"],"names":["jsx","useState","jsxs","Fragment"],"mappings":"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","file":"chunk-GTS3QA7M.js","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 title?: string;\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 title={item.title}\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 title={item.title}\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} title={item.title} 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 // Only `title` crosses into the menu. It is the full text of a crumb the\n // consumer truncated, and the narrow menu is where labels get cut. Other\n // attributes stay on the trail: both trails are in the DOM at once (CSS\n // hides one), so an `id` or a `data-*` handle would be duplicated.\n title: el.props?.title,\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"]}
|
|
@@ -80,6 +80,7 @@ function BreadcrumbsDropdown({ items, activeLabel }) {
|
|
|
80
80
|
Link,
|
|
81
81
|
{
|
|
82
82
|
...item.href ? { href: item.href } : {},
|
|
83
|
+
title: item.title,
|
|
83
84
|
className: cls,
|
|
84
85
|
onClick: () => {
|
|
85
86
|
item.onClick?.();
|
|
@@ -96,6 +97,7 @@ function BreadcrumbsDropdown({ items, activeLabel }) {
|
|
|
96
97
|
"button",
|
|
97
98
|
{
|
|
98
99
|
type: "button",
|
|
100
|
+
title: item.title,
|
|
99
101
|
className: chunkZU5Q77OT_cjs.cn(cls, "cursor-pointer border-0 bg-transparent"),
|
|
100
102
|
onClick: () => {
|
|
101
103
|
onClick();
|
|
@@ -106,7 +108,7 @@ function BreadcrumbsDropdown({ items, activeLabel }) {
|
|
|
106
108
|
i
|
|
107
109
|
);
|
|
108
110
|
}
|
|
109
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cls, children: item.label }, i);
|
|
111
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { title: item.title, className: cls, children: item.label }, i);
|
|
110
112
|
}) })
|
|
111
113
|
] });
|
|
112
114
|
}
|
|
@@ -128,7 +130,12 @@ function BreadcrumbsRoot({
|
|
|
128
130
|
href: el.props?.href,
|
|
129
131
|
as: el.props?.as,
|
|
130
132
|
onClick: el.props?.onClick,
|
|
131
|
-
active: el.props?.active
|
|
133
|
+
active: el.props?.active,
|
|
134
|
+
// Only `title` crosses into the menu. It is the full text of a crumb the
|
|
135
|
+
// consumer truncated, and the narrow menu is where labels get cut. Other
|
|
136
|
+
// attributes stay on the trail: both trails are in the DOM at once (CSS
|
|
137
|
+
// hides one), so an `id` or a `data-*` handle would be duplicated.
|
|
138
|
+
title: el.props?.title
|
|
132
139
|
};
|
|
133
140
|
});
|
|
134
141
|
const activeLabel = dropdownItems[dropdownItems.length - 1]?.label ?? "Menu";
|
|
@@ -168,5 +175,5 @@ var Breadcrumbs = Object.assign(BreadcrumbsRoot, {
|
|
|
168
175
|
});
|
|
169
176
|
|
|
170
177
|
exports.Breadcrumbs = Breadcrumbs;
|
|
171
|
-
//# sourceMappingURL=chunk-
|
|
172
|
-
//# sourceMappingURL=chunk-
|
|
178
|
+
//# sourceMappingURL=chunk-SKMORSBO.cjs.map
|
|
179
|
+
//# sourceMappingURL=chunk-SKMORSBO.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":";;;;;;;;;AAIO,SAAS,eAAA,CAAgB;AAAA,EAC9B,QAAA;AAAA,EACA,IAAA;AAAA,EACA,EAAA,EAAI,EAAA;AAAA,EACJ,MAAA,GAAS,KAAA;AAAA,EACT,OAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAyB;AACvB,EAAA,MAAM,SAAA,GAAYA,oBAAA;AAAA,IAChB,SAAA;AAAA,IACA,SACI,2CAAA,GACA,2QAAA;AAAA,IACJ;AAAA,GACF;AAIA,EAAA,IAAA,CAAK,IAAA,IAAQ,EAAA,KAAO,CAAC,MAAA,EAAQ;AAC3B,IAAA,MAAM,OAAQ,EAAA,IAAM,GAAA;AAEpB,IAAA,uBACEC,cAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,mCAAA,EAAkC,EAAA;AAAA,QACjC,GAAI,IAAA,GAAO,EAAE,IAAA,KAAS,EAAC;AAAA,QACxB,OAAA;AAAA,QACA,SAAA,EAAW,SAAA;AAAA,QACV,GAAG,IAAA;AAAA,QAEH;AAAA;AAAA,KACH;AAAA,EAEJ;AAQA,EAAA,IAAI,OAAA,IAAW,CAAC,MAAA,EAAQ;AACtB,IAAA,uBACEA,cAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,mCAAA,EAAkC,EAAA;AAAA,QAClC,OAAA;AAAA,QACA,SAAA,EAAWD,oBAAA,CAAG,SAAA,EAAW,4CAA4C,CAAA;AAAA,QACpE,GAAG,IAAA;AAAA,QAEH;AAAA;AAAA,KACH;AAAA,EAEJ;AAEA,EAAA,uBACEC,cAAA,CAAC,MAAA,EAAA,EAAK,mCAAA,EAAkC,EAAA,EAAG,SAAA,EAAW,SAAA,EAAW,cAAA,EAAc,MAAA,GAAS,MAAA,GAAS,MAAA,EAAY,GAAG,IAAA,EAC7G,QAAA,EACH,CAAA;AAEJ;AAEA,eAAA,CAAgB,WAAA,GAAc,iBAAA;AC9CvB,SAAS,mBAAA,CAAoB,EAAE,KAAA,EAAO,WAAA,EAAY,EAA6B;AACpF,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIC,eAAS,KAAK,CAAA;AACtC,EAAA,MAAM,GAAA,GAAMC,aAAuB,IAAI,CAAA;AAEvC,EAAAC,iCAAA,CAAgB,GAAA,EAAK,MAAM,OAAA,CAAQ,KAAK,GAAG,IAAI,CAAA;AAC/C,EAAAC,8BAAA,CAAa,MAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,IAAI,CAAA;AAEvC,EAAA,uCACG,KAAA,EAAA,EAAI,GAAA,EAAU,uCAAA,EAAsC,EAAA,EAAG,WAAU,yBAAA,EAChE,QAAA,EAAA;AAAA,oBAAAC,eAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAS,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,QAChC,SAAA,EAAU,8OAAA;AAAA,QAET,QAAA,EAAA;AAAA,UAAA,WAAA;AAAA,0BACDL,cAAAA,CAACM,uBAAA,EAAA,EAAY,IAAA,EAAM,EAAA,EAAI,WAAWP,oBAAA,CAAG,sBAAA,EAAwB,IAAA,IAAQ,YAAY,CAAA,EAAG;AAAA;AAAA;AAAA,KACtF;AAAA,IACC,IAAA,oBACCC,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oUACZ,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KAAM;AACtB,MAAA,MAAM,GAAA,GAAMD,oBAAA;AAAA,QACV,4CAAA;AAAA,QACA,IAAA,CAAK,SACD,2CAAA,GACA;AAAA,OACN;AAIA,MAAA,IAAA,CAAK,KAAK,IAAA,IAAQ,IAAA,CAAK,EAAA,KAAO,CAAC,KAAK,MAAA,EAAQ;AAC1C,QAAA,MAAM,IAAA,GAAQ,KAAK,EAAA,IAAM,GAAA;AACzB,QAAA,uBACEC,cAAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YAEE,GAAI,KAAK,IAAA,GAAO,EAAE,MAAM,IAAA,CAAK,IAAA,KAAS,EAAC;AAAA,YACxC,OAAO,IAAA,CAAK,KAAA;AAAA,YACZ,SAAA,EAAW,GAAA;AAAA,YACX,SAAS,MAAM;AACb,cAAA,IAAA,CAAK,OAAA,IAAU;AACf,cAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,YACf,CAAA;AAAA,YAEC,QAAA,EAAA,IAAA,CAAK;AAAA,WAAA;AAAA,UATD;AAAA,SAUP;AAAA,MAEJ;AAEA,MAAA,IAAI,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,MAAA,EAAQ;AAChC,QAAA,MAAM,UAAU,IAAA,CAAK,OAAA;AACrB,QAAA,uBACEA,cAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAK,QAAA;AAAA,YACL,OAAO,IAAA,CAAK,KAAA;AAAA,YACZ,SAAA,EAAWD,oBAAA,CAAG,GAAA,EAAK,wCAAwC,CAAA;AAAA,YAC3D,SAAS,MAAM;AACb,cAAA,OAAA,EAAQ;AACR,cAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,YACf,CAAA;AAAA,YAEC,QAAA,EAAA,IAAA,CAAK;AAAA,WAAA;AAAA,UATD;AAAA,SAUP;AAAA,MAEJ;AAEA,MAAA,uBACEC,cAAAA,CAAC,MAAA,EAAA,EAAa,KAAA,EAAO,IAAA,CAAK,OAAO,SAAA,EAAW,GAAA,EACzC,QAAA,EAAA,IAAA,CAAK,KAAA,EAAA,EADG,CAEX,CAAA;AAAA,IAEJ,CAAC,CAAA,EACH;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAEA,mBAAA,CAAoB,WAAA,GAAc,qBAAA;AC1FlC,SAAS,eAAA,CAAgB;AAAA,EACvB,QAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,KAAA,GAAQO,cAAA,CAAS,OAAA,CAAQ,QAAQ,CAAA;AACvC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIN,eAAS,KAAK,CAAA;AAE9C,EAAA,MAAM,GAAA,GAAM,6BACVD,cAAAA,CAACQ,4BAAa,IAAA,EAAM,EAAA,EAAI,WAAU,eAAA,EAAgB,CAAA;AAGpD,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AAGvC,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,GAAA,CAAI,CAAC,KAAA,KAAU;AACzC,IAAA,MAAM,EAAA,GAAK,KAAA;AACX,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,GAAG,KAAA,EAAO,QAAA;AAAA,MACjB,IAAA,EAAM,GAAG,KAAA,EAAO,IAAA;AAAA,MAChB,EAAA,EAAI,GAAG,KAAA,EAAO,EAAA;AAAA,MACd,OAAA,EAAS,GAAG,KAAA,EAAO,OAAA;AAAA,MACnB,MAAA,EAAQ,GAAG,KAAA,EAAO,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAKlB,KAAA,EAAO,GAAG,KAAA,EAAO;AAAA,KACnB;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,cAAc,aAAA,CAAc,aAAA,CAAc,MAAA,GAAS,CAAC,GAAG,KAAA,IAAS,MAAA;AAEtE,EAAA,MAAM,UAAA,GAAa,MAAA,IAAU,CAAC,QAAA,IAAY,MAAM,MAAA,GAAS,CAAA;AAEzD,EAAA,uBACEH,eAAAA,CAAAI,mBAAAA,EAAA,EAEE,QAAA,EAAA;AAAA,oBAAAT,cAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,8BAAA,EAA6B,EAAA;AAAA,QAC7B,YAAA,EAAW,YAAA;AAAA,QACX,SAAA,EAAWD,oBAAA,CAAG,mCAAA,EAAqC,SAAS,CAAA;AAAA,QAC5D,YAAA,EAAc,MAAM,MAAA,IAAU,WAAA,CAAY,KAAK,CAAA;AAAA,QAE9C,QAAA,EAAA,UAAA,mBACCM,eAAAA,CAAAI,mBAAAA,EAAA,EACE,QAAA,EAAA;AAAA,0BAAAT,cAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,OAAA,EAAS,MAAM,WAAA,CAAY,IAAI,CAAA;AAAA,cAC/B,YAAA,EAAc,MAAM,WAAA,CAAY,IAAI,CAAA;AAAA,cACpC,SAAA,EAAU,oEAAA;AAAA,cACX,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,QAAQ,QAAA,EAAA,GAAA,EAAI,CAAA;AAAA,UAC7B;AAAA,SAAA,EACH,CAAA,GAEA,MAAM,GAAA,CAAI,CAAC,OAAO,CAAA,qBAChBK,gBAACI,cAAA,EAAA,EACE,QAAA,EAAA;AAAA,UAAA,CAAA,GAAI,qBAAKT,cAAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,QAAQ,QAAA,EAAA,GAAA,EAAI,CAAA;AAAA,UACvC;AAAA,SAAA,EAAA,EAFY,CAGf,CACD;AAAA;AAAA,KAEL;AAAA,oBAGAA,cAAAA,CAAC,mBAAA,EAAA,EAAoB,KAAA,EAAO,eAAe,WAAA,EAA0B;AAAA,GAAA,EACvE,CAAA;AAEJ;AAEO,IAAM,WAAA,GAAc,MAAA,CAAO,MAAA,CAAO,eAAA,EAAiB;AAAA,EACxD,IAAA,EAAM;AACR,CAAC","file":"chunk-SKMORSBO.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 title?: string;\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 title={item.title}\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 title={item.title}\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} title={item.title} 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 // Only `title` crosses into the menu. It is the full text of a crumb the\n // consumer truncated, and the narrow menu is where labels get cut. Other\n // attributes stay on the trail: both trails are in the DOM at once (CSS\n // hides one), so an `id` or a `data-*` handle would be duplicated.\n title: el.props?.title,\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"]}
|