@brycks/core-front 0.3.2 → 0.3.4

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 (48) hide show
  1. package/dist/components/feedback/Alert/Alert.cjs +1 -1
  2. package/dist/components/feedback/Alert/Alert.cjs.map +1 -1
  3. package/dist/components/feedback/Alert/Alert.js +52 -177
  4. package/dist/components/feedback/Alert/Alert.js.map +1 -1
  5. package/dist/components/feedback/Modal/Modal.cjs +1 -1
  6. package/dist/components/feedback/Modal/Modal.cjs.map +1 -1
  7. package/dist/components/feedback/Modal/Modal.js +7 -6
  8. package/dist/components/feedback/Modal/Modal.js.map +1 -1
  9. package/dist/components/form/Checkbox/Checkbox.cjs +1 -1
  10. package/dist/components/form/Checkbox/Checkbox.js +12 -12
  11. package/dist/components/form/Input/Input.cjs +1 -1
  12. package/dist/components/form/Input/Input.js +13 -13
  13. package/dist/components/form/Slider/Slider.cjs +1 -1
  14. package/dist/components/form/Slider/Slider.js +1 -1
  15. package/dist/components/form/Switch/Switch.cjs +1 -1
  16. package/dist/components/form/Switch/Switch.cjs.map +1 -1
  17. package/dist/components/form/Switch/Switch.js +70 -105
  18. package/dist/components/form/Switch/Switch.js.map +1 -1
  19. package/dist/components/layout/Card/Card.cjs +1 -1
  20. package/dist/components/layout/Card/Card.cjs.map +1 -1
  21. package/dist/components/layout/Card/Card.js +59 -121
  22. package/dist/components/layout/Card/Card.js.map +1 -1
  23. package/dist/components/navigation/Dropdown/Dropdown.cjs +1 -6
  24. package/dist/components/navigation/Dropdown/Dropdown.cjs.map +1 -1
  25. package/dist/components/navigation/Dropdown/Dropdown.js +118 -183
  26. package/dist/components/navigation/Dropdown/Dropdown.js.map +1 -1
  27. package/dist/components/navigation/Menu/Menu.cjs +1 -1
  28. package/dist/components/navigation/Menu/Menu.js +5 -5
  29. package/dist/components/navigation/Tabs/Tabs.cjs +1 -6
  30. package/dist/components/navigation/Tabs/Tabs.cjs.map +1 -1
  31. package/dist/components/navigation/Tabs/Tabs.js +92 -162
  32. package/dist/components/navigation/Tabs/Tabs.js.map +1 -1
  33. package/dist/components/primitives/Button/Button.cjs +1 -1
  34. package/dist/components/primitives/Button/Button.cjs.map +1 -1
  35. package/dist/components/primitives/Button/Button.js +72 -96
  36. package/dist/components/primitives/Button/Button.js.map +1 -1
  37. package/dist/components/primitives/Button/Button.styles.cjs +1 -1
  38. package/dist/components/primitives/Button/Button.styles.cjs.map +1 -1
  39. package/dist/components/primitives/Button/Button.styles.js +8 -317
  40. package/dist/components/primitives/Button/Button.styles.js.map +1 -1
  41. package/dist/components/utility/Badge/Badge.cjs +1 -1
  42. package/dist/components/utility/Badge/Badge.cjs.map +1 -1
  43. package/dist/components/utility/Badge/Badge.js +23 -80
  44. package/dist/components/utility/Badge/Badge.js.map +1 -1
  45. package/dist/feedback.d.ts +1 -1
  46. package/dist/index.d.ts +1 -1
  47. package/dist/styles.css +1 -1
  48. package/package.json +1 -1
@@ -1,263 +1,198 @@
1
- import { jsx as u, jsxs as A, Fragment as ee } from "react/jsx-runtime";
2
- import { forwardRef as v, useState as k, useRef as j, useEffect as g, useCallback as R, cloneElement as re, createContext as te, useContext as oe } from "react";
3
- import { createPortal as ne } from "react-dom";
4
- import { cx as h } from "../../../utils/styles.js";
5
- import { componentPaddingY as G, componentPaddingX as T, componentGap as se, iconSizes as B } from "../../../design-system/primitives/sizing.js";
6
- import { durations as H, easings as U } from "../../../design-system/tokens/motion.js";
7
- import { spacing as K } from "../../../design-system/tokens/spacing.js";
8
- import { fontSizes as Y } from "../../../design-system/tokens/typography.js";
9
- const J = te(null);
10
- function ae() {
11
- const f = oe(J);
12
- if (!f)
1
+ import { jsx as u, jsxs as O } from "react/jsx-runtime";
2
+ import { forwardRef as k, useState as b, useRef as z, useEffect as v, useCallback as P, cloneElement as G, createContext as J, useContext as Q } from "react";
3
+ import { createPortal as T } from "react-dom";
4
+ import { cx as y } from "../../../utils/styles.js";
5
+ const X = J(null);
6
+ function V() {
7
+ const p = Q(X);
8
+ if (!p)
13
9
  throw new Error("Dropdown components must be used within a Dropdown");
14
- return f;
10
+ return p;
15
11
  }
16
- const ie = v(function({
12
+ const Z = k(function({
17
13
  trigger: r,
18
- isOpen: a,
19
- defaultOpen: c = !1,
20
- onOpenChange: i,
14
+ isOpen: o,
15
+ defaultOpen: i = !1,
16
+ onOpenChange: c,
21
17
  placement: s = "bottom-start",
22
- offset: p = 4,
23
- closeOnSelect: D = !0,
24
- className: x,
25
- style: C,
26
- children: S,
27
- testId: E,
28
- ...I
29
- }, L) {
30
- const [$, z] = k(c), [t, Q] = k({ top: 0, left: 0 }), [m, y] = k(-1), [N, O] = k(!1), b = j(null), w = j(null), o = a ?? $;
31
- g(() => (O(!0), () => O(!1)), []);
32
- const d = R(
18
+ offset: f = 4,
19
+ closeOnSelect: h = !0,
20
+ className: g,
21
+ style: x,
22
+ children: E,
23
+ testId: N,
24
+ ...C
25
+ }, I) {
26
+ const [Y, B] = b(i), [L, H] = b({ top: 0, left: 0 }), [l, m] = b(-1), [_, R] = b(!1), w = z(null), D = z(null), t = o ?? Y;
27
+ v(() => (R(!0), () => R(!1)), []);
28
+ const a = P(
33
29
  (e) => {
34
- a === void 0 && z(e), i?.(e), e || y(-1);
30
+ o === void 0 && B(e), c?.(e), e || m(-1);
35
31
  },
36
- [a, i]
37
- ), V = R(() => d(!1), [d]);
38
- g(() => {
39
- if (!o || !b.current || !N) return;
32
+ [o, c]
33
+ ), M = P(() => a(!1), [a]);
34
+ v(() => {
35
+ if (!t || !w.current || !_) return;
40
36
  const e = () => {
41
- const n = b.current;
37
+ const n = w.current;
42
38
  if (!n) return;
43
- const l = n.getBoundingClientRect(), M = window.scrollX, X = window.scrollY;
44
- let W = 0, P = 0;
45
- s.startsWith("bottom") ? W = l.bottom + X + p : W = l.top + X - p, s.endsWith("start") ? P = l.left + M : P = l.right + M, Q({ top: W, left: P });
39
+ const d = n.getBoundingClientRect(), j = window.scrollX, q = window.scrollY;
40
+ let W = 0, A = 0;
41
+ s.startsWith("bottom") ? W = d.bottom + q + f : W = d.top + q - f, s.endsWith("start") ? A = d.left + j : A = d.right + j, H({ top: W, left: A });
46
42
  };
47
43
  return e(), window.addEventListener("resize", e), window.addEventListener("scroll", e, !0), () => {
48
44
  window.removeEventListener("resize", e), window.removeEventListener("scroll", e, !0);
49
45
  };
50
- }, [o, s, p, N]), g(() => {
51
- if (!o) return;
46
+ }, [t, s, f, _]), v(() => {
47
+ if (!t) return;
52
48
  const e = (n) => {
53
- b.current?.contains(n.target) || w.current?.contains(n.target) || d(!1);
49
+ w.current?.contains(n.target) || D.current?.contains(n.target) || a(!1);
54
50
  };
55
51
  return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
56
- }, [o, d]);
57
- const q = R(
52
+ }, [t, a]);
53
+ const K = P(
58
54
  (e) => {
59
- if (!o) {
60
- (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") && (e.preventDefault(), d(!0));
55
+ if (!t) {
56
+ (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") && (e.preventDefault(), a(!0));
61
57
  return;
62
58
  }
63
- const n = w.current?.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])');
59
+ const n = D.current?.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])');
64
60
  if (n?.length)
65
61
  switch (e.key) {
66
62
  case "ArrowDown":
67
- e.preventDefault(), y((l) => (l + 1) % n.length);
63
+ e.preventDefault(), m((d) => (d + 1) % n.length);
68
64
  break;
69
65
  case "ArrowUp":
70
- e.preventDefault(), y((l) => (l - 1 + n.length) % n.length);
66
+ e.preventDefault(), m((d) => (d - 1 + n.length) % n.length);
71
67
  break;
72
68
  case "Home":
73
- e.preventDefault(), y(0);
69
+ e.preventDefault(), m(0);
74
70
  break;
75
71
  case "End":
76
- e.preventDefault(), y(n.length - 1);
72
+ e.preventDefault(), m(n.length - 1);
77
73
  break;
78
74
  case "Escape":
79
- e.preventDefault(), d(!1), b.current?.focus();
75
+ e.preventDefault(), a(!1), w.current?.focus();
80
76
  break;
81
77
  case "Enter":
82
78
  case " ":
83
- e.preventDefault(), m >= 0 && n[m]?.click();
79
+ e.preventDefault(), l >= 0 && n[l]?.click();
84
80
  break;
85
81
  }
86
82
  },
87
- [o, m, d]
83
+ [t, l, a]
88
84
  );
89
- g(() => {
90
- if (!o || m < 0) return;
91
- w.current?.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])')?.[m]?.focus();
92
- }, [o, m]);
93
- const F = r.props, Z = re(r, {
94
- ref: b,
85
+ v(() => {
86
+ if (!t || l < 0) return;
87
+ D.current?.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])')?.[l]?.focus();
88
+ }, [t, l]);
89
+ const S = r.props, U = G(r, {
90
+ ref: w,
95
91
  "aria-haspopup": "menu",
96
- "aria-expanded": o,
92
+ "aria-expanded": t,
97
93
  onClick: (e) => {
98
- F.onClick?.(e), d(!o);
94
+ S.onClick?.(e), a(!t);
99
95
  },
100
96
  onKeyDown: (e) => {
101
- F.onKeyDown?.(e), q(e);
97
+ S.onKeyDown?.(e), K(e);
102
98
  }
103
- }), _ = {
99
+ }), F = {
104
100
  position: "absolute",
105
- top: t.top,
106
- left: s.endsWith("end") ? "auto" : t.left,
107
- right: s.endsWith("end") ? window.innerWidth - t.left : "auto",
108
- zIndex: "var(--brycks-z-dropdown)",
109
- minWidth: b.current?.offsetWidth ?? 160,
110
- backgroundColor: "var(--brycks-background-elevated)",
111
- border: "1px solid var(--brycks-border-default)",
112
- borderRadius: "var(--brycks-radius-lg)",
113
- boxShadow: "var(--brycks-shadow-lg)",
114
- padding: K[1],
115
- animation: `brycks-dropdown-in ${H.quick}ms ${U.easeOut}`,
116
- outline: "none",
117
- ...C
101
+ top: L.top,
102
+ left: s.endsWith("end") ? "auto" : L.left,
103
+ right: s.endsWith("end") ? window.innerWidth - L.left : "auto",
104
+ minWidth: w.current?.offsetWidth ?? 160,
105
+ ...x
118
106
  };
119
- return /* @__PURE__ */ u(J.Provider, { value: { isOpen: o, close: D ? V : () => {
120
- }, activeIndex: m, setActiveIndex: y }, children: /* @__PURE__ */ A(
107
+ return /* @__PURE__ */ u(X.Provider, { value: { isOpen: t, close: h ? M : () => {
108
+ }, activeIndex: l, setActiveIndex: m }, children: /* @__PURE__ */ O(
121
109
  "div",
122
110
  {
123
- ref: L,
124
- className: h("brycks-dropdown", x),
125
- style: { display: "inline-block" },
126
- "data-testid": E,
127
- ...I,
111
+ ref: I,
112
+ className: y("brycks-dropdown", g),
113
+ "data-testid": N,
114
+ ...C,
128
115
  children: [
129
- Z,
130
- o && N && ne(
131
- /* @__PURE__ */ A(ee, { children: [
132
- /* @__PURE__ */ u("style", { children: `
133
- @keyframes brycks-dropdown-in {
134
- from { opacity: 0; transform: translateY(-4px); }
135
- to { opacity: 1; transform: translateY(0); }
136
- }
137
- ` }),
138
- /* @__PURE__ */ u(
139
- "div",
140
- {
141
- ref: w,
142
- role: "menu",
143
- style: _,
144
- onKeyDown: q,
145
- tabIndex: -1,
146
- children: S
147
- }
148
- )
149
- ] }),
116
+ U,
117
+ t && _ && T(
118
+ /* @__PURE__ */ u(
119
+ "div",
120
+ {
121
+ ref: D,
122
+ role: "menu",
123
+ className: "brycks-dropdown__menu",
124
+ style: F,
125
+ onKeyDown: K,
126
+ tabIndex: -1,
127
+ children: E
128
+ }
129
+ ),
150
130
  document.body
151
131
  )
152
132
  ]
153
133
  }
154
134
  ) });
155
135
  });
156
- ie.displayName = "Dropdown";
157
- const ce = v(function({ disabled: r = !1, icon: a, shortcut: c, destructive: i = !1, className: s, style: p, children: D, onClick: x, ...C }, S) {
158
- const { close: E } = ae(), I = (t) => {
159
- r || (x?.(t), E());
160
- }, L = {
161
- display: "flex",
162
- alignItems: "center",
163
- gap: se.lg,
164
- padding: `${G.md}px ${T.sm}px`,
165
- fontSize: Y.base,
166
- color: r ? "var(--brycks-foreground-disabled)" : i ? "var(--brycks-error-default)" : "var(--brycks-foreground-default)",
167
- backgroundColor: "transparent",
168
- borderRadius: "var(--brycks-radius-md)",
169
- cursor: r ? "not-allowed" : "pointer",
170
- transition: `background-color ${H.fast}ms ${U.easeOut}`,
171
- outline: "none",
172
- ...p
173
- }, $ = {
174
- width: B.sm,
175
- height: B.sm,
176
- color: r ? "var(--brycks-foreground-disabled)" : i ? "var(--brycks-error-default)" : "var(--brycks-foreground-muted)",
177
- flexShrink: 0
178
- }, z = {
179
- marginLeft: "auto",
180
- fontSize: Y.sm,
181
- color: "var(--brycks-foreground-muted)",
182
- fontFamily: "var(--brycks-font-mono)"
136
+ Z.displayName = "Dropdown";
137
+ const $ = k(function({ disabled: r = !1, icon: o, shortcut: i, destructive: c = !1, className: s, style: f, children: h, onClick: g, ...x }, E) {
138
+ const { close: N } = V(), C = (I) => {
139
+ r || (g?.(I), N());
183
140
  };
184
- return /* @__PURE__ */ A(
141
+ return /* @__PURE__ */ O(
185
142
  "div",
186
143
  {
187
- ref: S,
144
+ ref: E,
188
145
  role: "menuitem",
189
146
  "aria-disabled": r,
190
147
  tabIndex: r ? -1 : 0,
191
- className: h("brycks-dropdown-item", r && "brycks-dropdown-item--disabled", s),
192
- style: L,
193
- onClick: I,
194
- onMouseEnter: (t) => {
195
- r || (t.currentTarget.style.backgroundColor = "var(--brycks-background-muted)");
196
- },
197
- onMouseLeave: (t) => {
198
- t.currentTarget.style.backgroundColor = "transparent";
199
- },
200
- onFocus: (t) => {
201
- t.currentTarget.style.backgroundColor = "var(--brycks-background-muted)";
202
- },
203
- onBlur: (t) => {
204
- t.currentTarget.style.backgroundColor = "transparent";
205
- },
206
- ...C,
148
+ className: y(
149
+ "brycks-dropdown-item",
150
+ r && "brycks-dropdown-item--disabled",
151
+ c && "brycks-dropdown-item--destructive",
152
+ s
153
+ ),
154
+ style: f,
155
+ onClick: C,
156
+ ...x,
207
157
  children: [
208
- a && /* @__PURE__ */ u("span", { style: $, children: a }),
209
- /* @__PURE__ */ u("span", { style: { flex: 1 }, children: D }),
210
- c && /* @__PURE__ */ u("span", { style: z, children: c })
158
+ o && /* @__PURE__ */ u("span", { className: "brycks-dropdown-item__icon", children: o }),
159
+ /* @__PURE__ */ u("span", { className: "brycks-dropdown-item__label", children: h }),
160
+ i && /* @__PURE__ */ u("span", { className: "brycks-dropdown-item__shortcut", children: i })
211
161
  ]
212
162
  }
213
163
  );
214
164
  });
215
- ce.displayName = "DropdownItem";
216
- const de = v(function({ className: r, style: a, ...c }, i) {
217
- const s = {
218
- height: 1,
219
- backgroundColor: "var(--brycks-border-muted)",
220
- margin: `${K[1]}px 0`,
221
- ...a
222
- };
165
+ $.displayName = "DropdownItem";
166
+ const ee = k(function({ className: r, style: o, ...i }, c) {
223
167
  return /* @__PURE__ */ u(
224
168
  "div",
225
169
  {
226
- ref: i,
170
+ ref: c,
227
171
  role: "separator",
228
- className: h("brycks-dropdown-divider", r),
229
- style: s,
230
- ...c
172
+ className: y("brycks-dropdown-divider", r),
173
+ style: o,
174
+ ...i
231
175
  }
232
176
  );
233
177
  });
234
- de.displayName = "DropdownDivider";
235
- const le = v(function({ className: r, style: a, children: c, ...i }, s) {
236
- const p = {
237
- padding: `${G.md}px ${T.sm}px ${K[1]}px ${T.sm}px`,
238
- fontSize: Y.xs,
239
- fontWeight: 600,
240
- color: "var(--brycks-foreground-muted)",
241
- textTransform: "uppercase",
242
- letterSpacing: "0.05em",
243
- ...a
244
- };
178
+ ee.displayName = "DropdownDivider";
179
+ const te = k(function({ className: r, style: o, children: i, ...c }, s) {
245
180
  return /* @__PURE__ */ u(
246
181
  "div",
247
182
  {
248
183
  ref: s,
249
- className: h("brycks-dropdown-label", r),
250
- style: p,
251
- ...i,
252
- children: c
184
+ className: y("brycks-dropdown-label", r),
185
+ style: o,
186
+ ...c,
187
+ children: i
253
188
  }
254
189
  );
255
190
  });
256
- le.displayName = "DropdownLabel";
191
+ te.displayName = "DropdownLabel";
257
192
  export {
258
- ie as Dropdown,
259
- de as DropdownDivider,
260
- ce as DropdownItem,
261
- le as DropdownLabel
193
+ Z as Dropdown,
194
+ ee as DropdownDivider,
195
+ $ as DropdownItem,
196
+ te as DropdownLabel
262
197
  };
263
198
  //# sourceMappingURL=Dropdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.js","sources":["../../../../src/components/navigation/Dropdown/Dropdown.tsx"],"sourcesContent":["/**\n * Dropdown Component\n *\n * A dropdown menu with keyboard navigation support.\n * Can be used for actions, navigation, or selection.\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useEffect,\n cloneElement,\n createContext,\n useContext,\n type CSSProperties,\n type ReactNode,\n type ReactElement,\n type HTMLAttributes,\n type KeyboardEvent,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentGap, componentPaddingX, componentPaddingY, iconSizes } from '../../../design-system/primitives'\n\nexport type DropdownPlacement = 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end'\n\ninterface DropdownContextValue {\n isOpen: boolean\n close: () => void\n activeIndex: number\n setActiveIndex: (index: number) => void\n}\n\nconst DropdownContext = createContext<DropdownContextValue | null>(null)\n\nfunction useDropdownContext() {\n const context = useContext(DropdownContext)\n if (!context) {\n throw new Error('Dropdown components must be used within a Dropdown')\n }\n return context\n}\n\nexport interface DropdownProps extends HTMLAttributes<HTMLDivElement> {\n /** Trigger element */\n trigger: ReactElement\n /** Whether the dropdown is open (controlled) */\n isOpen?: boolean\n /** Default open state (uncontrolled) */\n defaultOpen?: boolean\n /** Callback when open state changes */\n onOpenChange?: (isOpen: boolean) => void\n /** Dropdown placement */\n placement?: DropdownPlacement\n /** Offset from trigger */\n offset?: number\n /** Whether to close on item select */\n closeOnSelect?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(function Dropdown(\n {\n trigger,\n isOpen: controlledIsOpen,\n defaultOpen = false,\n onOpenChange,\n placement = 'bottom-start',\n offset = 4,\n closeOnSelect = true,\n className,\n style,\n children,\n testId,\n ...props\n },\n ref\n) {\n const [internalIsOpen, setInternalIsOpen] = useState(defaultOpen)\n const [position, setPosition] = useState({ top: 0, left: 0 })\n const [activeIndex, setActiveIndex] = useState(-1)\n const [mounted, setMounted] = useState(false)\n const triggerRef = useRef<HTMLElement>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n\n const isOpen = controlledIsOpen ?? internalIsOpen\n\n useEffect(() => {\n setMounted(true)\n return () => setMounted(false)\n }, [])\n\n const setIsOpen = useCallback(\n (open: boolean) => {\n if (controlledIsOpen === undefined) {\n setInternalIsOpen(open)\n }\n onOpenChange?.(open)\n if (!open) {\n setActiveIndex(-1)\n }\n },\n [controlledIsOpen, onOpenChange]\n )\n\n const close = useCallback(() => setIsOpen(false), [setIsOpen])\n\n // Calculate position\n useEffect(() => {\n if (!isOpen || !triggerRef.current || !mounted) return\n\n const updatePosition = () => {\n const trigger = triggerRef.current\n if (!trigger) return\n\n const rect = trigger.getBoundingClientRect()\n const scrollX = window.scrollX\n const scrollY = window.scrollY\n\n let top = 0\n let left = 0\n\n if (placement.startsWith('bottom')) {\n top = rect.bottom + scrollY + offset\n } else {\n top = rect.top + scrollY - offset\n }\n\n if (placement.endsWith('start')) {\n left = rect.left + scrollX\n } else {\n left = rect.right + scrollX\n }\n\n setPosition({ top, left })\n }\n\n updatePosition()\n window.addEventListener('resize', updatePosition)\n window.addEventListener('scroll', updatePosition, true)\n\n return () => {\n window.removeEventListener('resize', updatePosition)\n window.removeEventListener('scroll', updatePosition, true)\n }\n }, [isOpen, placement, offset, mounted])\n\n // Close on outside click\n useEffect(() => {\n if (!isOpen) return\n\n const handleClick = (e: MouseEvent) => {\n if (\n triggerRef.current?.contains(e.target as Node) ||\n menuRef.current?.contains(e.target as Node)\n ) {\n return\n }\n setIsOpen(false)\n }\n\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [isOpen, setIsOpen])\n\n // Keyboard navigation\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (!isOpen) {\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n setIsOpen(true)\n }\n return\n }\n\n const items = menuRef.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])')\n if (!items?.length) return\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n setActiveIndex((prev) => (prev + 1) % items.length)\n break\n case 'ArrowUp':\n e.preventDefault()\n setActiveIndex((prev) => (prev - 1 + items.length) % items.length)\n break\n case 'Home':\n e.preventDefault()\n setActiveIndex(0)\n break\n case 'End':\n e.preventDefault()\n setActiveIndex(items.length - 1)\n break\n case 'Escape':\n e.preventDefault()\n setIsOpen(false)\n triggerRef.current?.focus()\n break\n case 'Enter':\n case ' ':\n e.preventDefault()\n if (activeIndex >= 0) {\n items[activeIndex]?.click()\n }\n break\n }\n },\n [isOpen, activeIndex, setIsOpen]\n )\n\n // Focus active item\n useEffect(() => {\n if (!isOpen || activeIndex < 0) return\n const items = menuRef.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])')\n items?.[activeIndex]?.focus()\n }, [isOpen, activeIndex])\n\n const triggerProps = trigger.props as Record<string, unknown>\n const triggerElement = cloneElement(trigger as ReactElement<Record<string, unknown>>, {\n ref: triggerRef,\n 'aria-haspopup': 'menu',\n 'aria-expanded': isOpen,\n onClick: (e: React.MouseEvent) => {\n (triggerProps.onClick as ((e: React.MouseEvent) => void) | undefined)?.(e)\n setIsOpen(!isOpen)\n },\n onKeyDown: (e: KeyboardEvent) => {\n (triggerProps.onKeyDown as ((e: KeyboardEvent) => void) | undefined)?.(e)\n handleKeyDown(e)\n },\n })\n\n const menuStyle: CSSProperties = {\n position: 'absolute',\n top: position.top,\n left: placement.endsWith('end') ? 'auto' : position.left,\n right: placement.endsWith('end') ? window.innerWidth - position.left : 'auto',\n zIndex: 'var(--brycks-z-dropdown)' as unknown as number,\n minWidth: triggerRef.current?.offsetWidth ?? 160,\n backgroundColor: 'var(--brycks-background-elevated)',\n border: '1px solid var(--brycks-border-default)',\n borderRadius: 'var(--brycks-radius-lg)',\n boxShadow: 'var(--brycks-shadow-lg)',\n padding: spacing[1],\n animation: `brycks-dropdown-in ${durations.quick}ms ${easings.easeOut}`,\n outline: 'none',\n ...style,\n }\n\n return (\n <DropdownContext.Provider value={{ isOpen, close: closeOnSelect ? close : () => {}, activeIndex, setActiveIndex }}>\n <div\n ref={ref}\n className={cx('brycks-dropdown', className)}\n style={{ display: 'inline-block' }}\n data-testid={testId}\n {...props}\n >\n {triggerElement}\n {isOpen && mounted && createPortal(\n <>\n <style>\n {`\n @keyframes brycks-dropdown-in {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `}\n </style>\n <div\n ref={menuRef}\n role=\"menu\"\n style={menuStyle}\n onKeyDown={handleKeyDown}\n tabIndex={-1}\n >\n {children}\n </div>\n </>,\n document.body\n )}\n </div>\n </DropdownContext.Provider>\n )\n})\n\nDropdown.displayName = 'Dropdown'\n\n// DropdownItem\nexport interface DropdownItemProps extends HTMLAttributes<HTMLDivElement> {\n /** Whether the item is disabled */\n disabled?: boolean\n /** Icon before the label */\n icon?: ReactNode\n /** Shortcut text */\n shortcut?: string\n /** Whether the item is destructive */\n destructive?: boolean\n /** Custom class name */\n className?: string\n}\n\nexport const DropdownItem = forwardRef<HTMLDivElement, DropdownItemProps>(function DropdownItem(\n { disabled = false, icon, shortcut, destructive = false, className, style, children, onClick, ...props },\n ref\n) {\n const { close } = useDropdownContext()\n\n const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) return\n onClick?.(e)\n close()\n }\n\n const itemStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: componentGap.lg,\n padding: `${componentPaddingY.md}px ${componentPaddingX.sm}px`,\n fontSize: fontSizes.base,\n color: disabled\n ? 'var(--brycks-foreground-disabled)'\n : destructive\n ? 'var(--brycks-error-default)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: 'transparent',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n transition: `background-color ${durations.fast}ms ${easings.easeOut}`,\n outline: 'none',\n ...style,\n }\n\n const iconStyle: CSSProperties = {\n width: iconSizes.sm,\n height: iconSizes.sm,\n color: disabled\n ? 'var(--brycks-foreground-disabled)'\n : destructive\n ? 'var(--brycks-error-default)'\n : 'var(--brycks-foreground-muted)',\n flexShrink: 0,\n }\n\n const shortcutStyle: CSSProperties = {\n marginLeft: 'auto',\n fontSize: fontSizes.sm,\n color: 'var(--brycks-foreground-muted)',\n fontFamily: 'var(--brycks-font-mono)',\n }\n\n return (\n <div\n ref={ref}\n role=\"menuitem\"\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n className={cx('brycks-dropdown-item', disabled && 'brycks-dropdown-item--disabled', className)}\n style={itemStyle}\n onClick={handleClick}\n onMouseEnter={(e) => {\n if (!disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n onFocus={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }}\n onBlur={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n {...props}\n >\n {icon && <span style={iconStyle}>{icon}</span>}\n <span style={{ flex: 1 }}>{children}</span>\n {shortcut && <span style={shortcutStyle}>{shortcut}</span>}\n </div>\n )\n})\n\nDropdownItem.displayName = 'DropdownItem'\n\n// DropdownDivider\nexport interface DropdownDividerProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const DropdownDivider = forwardRef<HTMLDivElement, DropdownDividerProps>(function DropdownDivider(\n { className, style, ...props },\n ref\n) {\n const dividerStyle: CSSProperties = {\n height: 1,\n backgroundColor: 'var(--brycks-border-muted)',\n margin: `${spacing[1]}px 0`,\n ...style,\n }\n\n return (\n <div\n ref={ref}\n role=\"separator\"\n className={cx('brycks-dropdown-divider', className)}\n style={dividerStyle}\n {...props}\n />\n )\n})\n\nDropdownDivider.displayName = 'DropdownDivider'\n\n// DropdownLabel\nexport interface DropdownLabelProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const DropdownLabel = forwardRef<HTMLDivElement, DropdownLabelProps>(function DropdownLabel(\n { className, style, children, ...props },\n ref\n) {\n const labelStyle: CSSProperties = {\n padding: `${componentPaddingY.md}px ${componentPaddingX.sm}px ${spacing[1]}px ${componentPaddingX.sm}px`,\n fontSize: fontSizes.xs,\n fontWeight: 600,\n color: 'var(--brycks-foreground-muted)',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n ...style,\n }\n\n return (\n <div\n ref={ref}\n className={cx('brycks-dropdown-label', className)}\n style={labelStyle}\n {...props}\n >\n {children}\n </div>\n )\n})\n\nDropdownLabel.displayName = 'DropdownLabel'\n"],"names":["DropdownContext","createContext","useDropdownContext","context","useContext","Dropdown","forwardRef","trigger","controlledIsOpen","defaultOpen","onOpenChange","placement","offset","closeOnSelect","className","style","children","testId","props","ref","internalIsOpen","setInternalIsOpen","useState","position","setPosition","activeIndex","setActiveIndex","mounted","setMounted","triggerRef","useRef","menuRef","isOpen","useEffect","setIsOpen","useCallback","open","close","updatePosition","rect","scrollX","scrollY","top","left","handleClick","e","handleKeyDown","items","prev","triggerProps","triggerElement","cloneElement","menuStyle","spacing","durations","easings","jsx","jsxs","cx","createPortal","Fragment","DropdownItem","disabled","icon","shortcut","destructive","onClick","itemStyle","componentGap","componentPaddingY","componentPaddingX","fontSizes","iconStyle","iconSizes","shortcutStyle","DropdownDivider","dividerStyle","DropdownLabel","labelStyle"],"mappings":"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"}
1
+ {"version":3,"file":"Dropdown.js","sources":["../../../../src/components/navigation/Dropdown/Dropdown.tsx"],"sourcesContent":["/**\n * Dropdown Component\n *\n * A dropdown menu with keyboard navigation support.\n * Can be used for actions, navigation, or selection.\n *\n * All color styles are handled via CSS classes for easy customization.\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useEffect,\n cloneElement,\n createContext,\n useContext,\n type CSSProperties,\n type ReactNode,\n type ReactElement,\n type HTMLAttributes,\n type KeyboardEvent,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { cx } from '../../../utils/styles'\n\nexport type DropdownPlacement = 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end'\n\ninterface DropdownContextValue {\n isOpen: boolean\n close: () => void\n activeIndex: number\n setActiveIndex: (index: number) => void\n}\n\nconst DropdownContext = createContext<DropdownContextValue | null>(null)\n\nfunction useDropdownContext() {\n const context = useContext(DropdownContext)\n if (!context) {\n throw new Error('Dropdown components must be used within a Dropdown')\n }\n return context\n}\n\nexport interface DropdownProps extends HTMLAttributes<HTMLDivElement> {\n /** Trigger element */\n trigger: ReactElement\n /** Whether the dropdown is open (controlled) */\n isOpen?: boolean\n /** Default open state (uncontrolled) */\n defaultOpen?: boolean\n /** Callback when open state changes */\n onOpenChange?: (isOpen: boolean) => void\n /** Dropdown placement */\n placement?: DropdownPlacement\n /** Offset from trigger */\n offset?: number\n /** Whether to close on item select */\n closeOnSelect?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(function Dropdown(\n {\n trigger,\n isOpen: controlledIsOpen,\n defaultOpen = false,\n onOpenChange,\n placement = 'bottom-start',\n offset = 4,\n closeOnSelect = true,\n className,\n style,\n children,\n testId,\n ...props\n },\n ref\n) {\n const [internalIsOpen, setInternalIsOpen] = useState(defaultOpen)\n const [position, setPosition] = useState({ top: 0, left: 0 })\n const [activeIndex, setActiveIndex] = useState(-1)\n const [mounted, setMounted] = useState(false)\n const triggerRef = useRef<HTMLElement>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n\n const isOpen = controlledIsOpen ?? internalIsOpen\n\n useEffect(() => {\n setMounted(true)\n return () => setMounted(false)\n }, [])\n\n const setIsOpen = useCallback(\n (open: boolean) => {\n if (controlledIsOpen === undefined) {\n setInternalIsOpen(open)\n }\n onOpenChange?.(open)\n if (!open) {\n setActiveIndex(-1)\n }\n },\n [controlledIsOpen, onOpenChange]\n )\n\n const close = useCallback(() => setIsOpen(false), [setIsOpen])\n\n // Calculate position\n useEffect(() => {\n if (!isOpen || !triggerRef.current || !mounted) return\n\n const updatePosition = () => {\n const trigger = triggerRef.current\n if (!trigger) return\n\n const rect = trigger.getBoundingClientRect()\n const scrollX = window.scrollX\n const scrollY = window.scrollY\n\n let top = 0\n let left = 0\n\n if (placement.startsWith('bottom')) {\n top = rect.bottom + scrollY + offset\n } else {\n top = rect.top + scrollY - offset\n }\n\n if (placement.endsWith('start')) {\n left = rect.left + scrollX\n } else {\n left = rect.right + scrollX\n }\n\n setPosition({ top, left })\n }\n\n updatePosition()\n window.addEventListener('resize', updatePosition)\n window.addEventListener('scroll', updatePosition, true)\n\n return () => {\n window.removeEventListener('resize', updatePosition)\n window.removeEventListener('scroll', updatePosition, true)\n }\n }, [isOpen, placement, offset, mounted])\n\n // Close on outside click\n useEffect(() => {\n if (!isOpen) return\n\n const handleClick = (e: MouseEvent) => {\n if (\n triggerRef.current?.contains(e.target as Node) ||\n menuRef.current?.contains(e.target as Node)\n ) {\n return\n }\n setIsOpen(false)\n }\n\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [isOpen, setIsOpen])\n\n // Keyboard navigation\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (!isOpen) {\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n setIsOpen(true)\n }\n return\n }\n\n const items = menuRef.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])')\n if (!items?.length) return\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n setActiveIndex((prev) => (prev + 1) % items.length)\n break\n case 'ArrowUp':\n e.preventDefault()\n setActiveIndex((prev) => (prev - 1 + items.length) % items.length)\n break\n case 'Home':\n e.preventDefault()\n setActiveIndex(0)\n break\n case 'End':\n e.preventDefault()\n setActiveIndex(items.length - 1)\n break\n case 'Escape':\n e.preventDefault()\n setIsOpen(false)\n triggerRef.current?.focus()\n break\n case 'Enter':\n case ' ':\n e.preventDefault()\n if (activeIndex >= 0) {\n items[activeIndex]?.click()\n }\n break\n }\n },\n [isOpen, activeIndex, setIsOpen]\n )\n\n // Focus active item\n useEffect(() => {\n if (!isOpen || activeIndex < 0) return\n const items = menuRef.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])')\n items?.[activeIndex]?.focus()\n }, [isOpen, activeIndex])\n\n const triggerProps = trigger.props as Record<string, unknown>\n const triggerElement = cloneElement(trigger as ReactElement<Record<string, unknown>>, {\n ref: triggerRef,\n 'aria-haspopup': 'menu',\n 'aria-expanded': isOpen,\n onClick: (e: React.MouseEvent) => {\n (triggerProps.onClick as ((e: React.MouseEvent) => void) | undefined)?.(e)\n setIsOpen(!isOpen)\n },\n onKeyDown: (e: KeyboardEvent) => {\n (triggerProps.onKeyDown as ((e: KeyboardEvent) => void) | undefined)?.(e)\n handleKeyDown(e)\n },\n })\n\n // Only layout-related inline styles (position is dynamic)\n const menuStyle: CSSProperties = {\n position: 'absolute',\n top: position.top,\n left: placement.endsWith('end') ? 'auto' : position.left,\n right: placement.endsWith('end') ? window.innerWidth - position.left : 'auto',\n minWidth: triggerRef.current?.offsetWidth ?? 160,\n ...style,\n }\n\n return (\n <DropdownContext.Provider value={{ isOpen, close: closeOnSelect ? close : () => {}, activeIndex, setActiveIndex }}>\n <div\n ref={ref}\n className={cx('brycks-dropdown', className)}\n data-testid={testId}\n {...props}\n >\n {triggerElement}\n {isOpen && mounted && createPortal(\n <div\n ref={menuRef}\n role=\"menu\"\n className=\"brycks-dropdown__menu\"\n style={menuStyle}\n onKeyDown={handleKeyDown}\n tabIndex={-1}\n >\n {children}\n </div>,\n document.body\n )}\n </div>\n </DropdownContext.Provider>\n )\n})\n\nDropdown.displayName = 'Dropdown'\n\n// DropdownItem\nexport interface DropdownItemProps extends HTMLAttributes<HTMLDivElement> {\n /** Whether the item is disabled */\n disabled?: boolean\n /** Icon before the label */\n icon?: ReactNode\n /** Shortcut text */\n shortcut?: string\n /** Whether the item is destructive */\n destructive?: boolean\n /** Custom class name */\n className?: string\n}\n\nexport const DropdownItem = forwardRef<HTMLDivElement, DropdownItemProps>(function DropdownItem(\n { disabled = false, icon, shortcut, destructive = false, className, style, children, onClick, ...props },\n ref\n) {\n const { close } = useDropdownContext()\n\n const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) return\n onClick?.(e)\n close()\n }\n\n return (\n <div\n ref={ref}\n role=\"menuitem\"\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n className={cx(\n 'brycks-dropdown-item',\n disabled && 'brycks-dropdown-item--disabled',\n destructive && 'brycks-dropdown-item--destructive',\n className\n )}\n style={style}\n onClick={handleClick}\n {...props}\n >\n {icon && <span className=\"brycks-dropdown-item__icon\">{icon}</span>}\n <span className=\"brycks-dropdown-item__label\">{children}</span>\n {shortcut && <span className=\"brycks-dropdown-item__shortcut\">{shortcut}</span>}\n </div>\n )\n})\n\nDropdownItem.displayName = 'DropdownItem'\n\n// DropdownDivider\nexport interface DropdownDividerProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const DropdownDivider = forwardRef<HTMLDivElement, DropdownDividerProps>(function DropdownDivider(\n { className, style, ...props },\n ref\n) {\n return (\n <div\n ref={ref}\n role=\"separator\"\n className={cx('brycks-dropdown-divider', className)}\n style={style}\n {...props}\n />\n )\n})\n\nDropdownDivider.displayName = 'DropdownDivider'\n\n// DropdownLabel\nexport interface DropdownLabelProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const DropdownLabel = forwardRef<HTMLDivElement, DropdownLabelProps>(function DropdownLabel(\n { className, style, children, ...props },\n ref\n) {\n return (\n <div\n ref={ref}\n className={cx('brycks-dropdown-label', className)}\n style={style}\n {...props}\n >\n {children}\n </div>\n )\n})\n\nDropdownLabel.displayName = 'DropdownLabel'\n"],"names":["DropdownContext","createContext","useDropdownContext","context","useContext","Dropdown","forwardRef","trigger","controlledIsOpen","defaultOpen","onOpenChange","placement","offset","closeOnSelect","className","style","children","testId","props","ref","internalIsOpen","setInternalIsOpen","useState","position","setPosition","activeIndex","setActiveIndex","mounted","setMounted","triggerRef","useRef","menuRef","isOpen","useEffect","setIsOpen","useCallback","open","close","updatePosition","rect","scrollX","scrollY","top","left","handleClick","e","handleKeyDown","items","prev","triggerProps","triggerElement","cloneElement","menuStyle","jsx","jsxs","cx","createPortal","DropdownItem","disabled","icon","shortcut","destructive","onClick","DropdownDivider","DropdownLabel"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),r=require("react"),j=require("../../../utils/styles.cjs"),m=require("../../../design-system/tokens/spacing.cjs"),N=require("../../../design-system/tokens/motion.cjs"),i=require("../../../design-system/primitives/sizing.cjs"),C=require("../../../design-system/tokens/typography.cjs"),A=r.createContext(null);function G(){const f=r.useContext(A);if(!f)throw new Error("Menu components must be used within a Menu");return f}const H=r.forwardRef(function({activeItem:t,onChange:u,size:c="md",collapsed:s=!1,className:p,style:b,children:S,testId:g,...v},y){const[D,R]=r.useState(null),[x,o]=r.useState(-1),k=r.useRef([]),I=r.useRef(null),q=t!==void 0?t:D,l=e=>{t===void 0&&R(e),u?.(e)},d=r.useCallback(e=>{const n=k.current.indexOf(e);return n===-1?(k.current.push(e),k.current.length-1):n},[]),M=r.useCallback(e=>{const n=I.current?.querySelectorAll('[role="menuitem"]:not(:disabled)');if(!n?.length)return;const z=x>=0?x:0;switch(e.key){case"ArrowDown":e.preventDefault();const w=(z+1)%n.length;o(w),n[w]?.focus();break;case"ArrowUp":e.preventDefault();const h=(z-1+n.length)%n.length;o(h),n[h]?.focus();break;case"Home":e.preventDefault(),o(0),n[0]?.focus();break;case"End":e.preventDefault(),o(n.length-1),n[n.length-1]?.focus();break}},[x]),$={display:"flex",flexDirection:"column",gap:m.spacing[.5],padding:m.spacing[2],...b};return a.jsx(A.Provider,{value:{size:c,activeItem:q,setActiveItem:l,collapsed:s,focusedIndex:x,setFocusedIndex:o,registerItem:d},children:a.jsx("nav",{ref:e=>{I.current=e,typeof y=="function"?y(e):y&&(y.current=e)},role:"menu",className:j.cx("brycks-menu",`brycks-menu--${c}`,s&&"brycks-menu--collapsed",p),style:$,onKeyDown:M,"data-testid":g,...v,children:S})})});H.displayName="Menu";const E={sm:{height:i.componentHeights.sm,fontSize:C.fontSizes.base-1,iconSize:i.iconSizes.sm,padding:i.componentGap.lg},md:{height:i.componentHeights.md,fontSize:C.fontSizes.base,iconSize:i.iconSizes.md-2,padding:i.componentPaddingX.sm},lg:{height:i.componentHeights.lg,fontSize:C.fontSizes.md,iconSize:i.iconSizes.md,padding:m.spacing[3.5]}},F=r.forwardRef(function({value:t,icon:u,badge:c,disabled:s=!1,onClick:p,className:b,style:S,children:g,...v},y){const{size:D,activeItem:R,setActiveItem:x,collapsed:o,focusedIndex:k,setFocusedIndex:I,registerItem:q}=G(),l=R===t,d=E[D],M=q(t),$=()=>{s||(x(t),p?.(t))},e=()=>{I(M)},n={display:"flex",alignItems:"center",gap:i.componentGap.lg,width:"100%",minHeight:d.height,padding:o?d.padding:`0 ${d.padding}px`,fontSize:d.fontSize,fontWeight:l?600:500,color:s?"var(--brycks-foreground-disabled)":l?"var(--brycks-primary-default)":"var(--brycks-foreground-default)",backgroundColor:l?"var(--brycks-primary-50)":"transparent",border:"none",borderRadius:"var(--brycks-radius-md)",cursor:s?"not-allowed":"pointer",transition:`all ${N.durations.quick}ms ${N.easings.easeOut}`,textAlign:"left",outline:"none",justifyContent:o?"center":"flex-start",...S},z={width:d.iconSize,height:d.iconSize,flexShrink:0,display:"flex",alignItems:"center",justifyContent:"center"},w={marginLeft:"auto"};return a.jsxs("button",{ref:y,type:"button",role:"menuitem",disabled:s,tabIndex:k===M?0:-1,className:j.cx("brycks-menu-item",l&&"brycks-menu-item--active",b),style:n,onClick:$,onFocus:e,onMouseEnter:h=>{!s&&!l&&(h.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:h=>{l||(h.currentTarget.style.backgroundColor="transparent")},title:o?String(g):void 0,...v,children:[u&&a.jsx("span",{style:z,children:u}),!o&&a.jsx("span",{style:{flex:1},children:g}),!o&&c&&a.jsx("span",{style:w,children:c})]})});F.displayName="MenuItem";const P=r.forwardRef(function({label:t,className:u,style:c,children:s,...p},b){const{collapsed:S}=G(),g={display:"flex",flexDirection:"column",gap:m.spacing[.5],...c},v={padding:`${m.spacing[3]}px ${m.spacing[3]}px ${i.componentPaddingY.sm}px ${m.spacing[3]}px`,fontSize:C.fontSizes.xs,fontWeight:600,color:"var(--brycks-foreground-muted)",textTransform:"uppercase",letterSpacing:"0.05em"};return a.jsxs("div",{ref:b,className:j.cx("brycks-menu-group",u),style:g,...p,children:[t&&!S&&a.jsx("div",{style:v,children:t}),s]})});P.displayName="MenuGroup";const T=r.forwardRef(function({className:t,style:u,...c},s){const p={height:1,backgroundColor:"var(--brycks-border-muted)",margin:`${m.spacing[2]}px 0`,...u};return a.jsx("div",{ref:s,role:"separator",className:j.cx("brycks-menu-divider",t),style:p,...c})});T.displayName="MenuDivider";exports.Menu=H;exports.MenuDivider=T;exports.MenuGroup=P;exports.MenuItem=F;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),r=require("react"),j=require("../../../utils/styles.cjs"),i=require("../../../design-system/primitives/sizing.cjs"),m=require("../../../design-system/tokens/spacing.cjs"),N=require("../../../design-system/tokens/motion.cjs"),C=require("../../../design-system/tokens/typography.cjs"),A=r.createContext(null);function G(){const f=r.useContext(A);if(!f)throw new Error("Menu components must be used within a Menu");return f}const H=r.forwardRef(function({activeItem:t,onChange:u,size:c="md",collapsed:s=!1,className:p,style:b,children:S,testId:g,...v},y){const[D,R]=r.useState(null),[x,o]=r.useState(-1),k=r.useRef([]),I=r.useRef(null),q=t!==void 0?t:D,l=e=>{t===void 0&&R(e),u?.(e)},d=r.useCallback(e=>{const n=k.current.indexOf(e);return n===-1?(k.current.push(e),k.current.length-1):n},[]),M=r.useCallback(e=>{const n=I.current?.querySelectorAll('[role="menuitem"]:not(:disabled)');if(!n?.length)return;const z=x>=0?x:0;switch(e.key){case"ArrowDown":e.preventDefault();const w=(z+1)%n.length;o(w),n[w]?.focus();break;case"ArrowUp":e.preventDefault();const h=(z-1+n.length)%n.length;o(h),n[h]?.focus();break;case"Home":e.preventDefault(),o(0),n[0]?.focus();break;case"End":e.preventDefault(),o(n.length-1),n[n.length-1]?.focus();break}},[x]),$={display:"flex",flexDirection:"column",gap:m.spacing[.5],padding:m.spacing[2],...b};return a.jsx(A.Provider,{value:{size:c,activeItem:q,setActiveItem:l,collapsed:s,focusedIndex:x,setFocusedIndex:o,registerItem:d},children:a.jsx("nav",{ref:e=>{I.current=e,typeof y=="function"?y(e):y&&(y.current=e)},role:"menu",className:j.cx("brycks-menu",`brycks-menu--${c}`,s&&"brycks-menu--collapsed",p),style:$,onKeyDown:M,"data-testid":g,...v,children:S})})});H.displayName="Menu";const E={sm:{height:i.componentHeights.sm,fontSize:C.fontSizes.base-1,iconSize:i.iconSizes.sm,padding:i.componentGap.lg},md:{height:i.componentHeights.md,fontSize:C.fontSizes.base,iconSize:i.iconSizes.md-2,padding:i.componentPaddingX.sm},lg:{height:i.componentHeights.lg,fontSize:C.fontSizes.md,iconSize:i.iconSizes.md,padding:m.spacing[3.5]}},F=r.forwardRef(function({value:t,icon:u,badge:c,disabled:s=!1,onClick:p,className:b,style:S,children:g,...v},y){const{size:D,activeItem:R,setActiveItem:x,collapsed:o,focusedIndex:k,setFocusedIndex:I,registerItem:q}=G(),l=R===t,d=E[D],M=q(t),$=()=>{s||(x(t),p?.(t))},e=()=>{I(M)},n={display:"flex",alignItems:"center",gap:i.componentGap.lg,width:"100%",minHeight:d.height,padding:o?d.padding:`0 ${d.padding}px`,fontSize:d.fontSize,fontWeight:l?600:500,color:s?"var(--brycks-foreground-disabled)":l?"var(--brycks-primary-default)":"var(--brycks-foreground-default)",backgroundColor:l?"var(--brycks-primary-50)":"transparent",border:"none",borderRadius:"var(--brycks-radius-md)",cursor:s?"not-allowed":"pointer",transition:`all ${N.durations.quick}ms ${N.easings.easeOut}`,textAlign:"left",outline:"none",justifyContent:o?"center":"flex-start",...S},z={width:d.iconSize,height:d.iconSize,flexShrink:0,display:"flex",alignItems:"center",justifyContent:"center"},w={marginLeft:"auto"};return a.jsxs("button",{ref:y,type:"button",role:"menuitem",disabled:s,tabIndex:k===M?0:-1,className:j.cx("brycks-menu-item",l&&"brycks-menu-item--active",b),style:n,onClick:$,onFocus:e,onMouseEnter:h=>{!s&&!l&&(h.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:h=>{l||(h.currentTarget.style.backgroundColor="transparent")},title:o?String(g):void 0,...v,children:[u&&a.jsx("span",{style:z,children:u}),!o&&a.jsx("span",{style:{flex:1},children:g}),!o&&c&&a.jsx("span",{style:w,children:c})]})});F.displayName="MenuItem";const P=r.forwardRef(function({label:t,className:u,style:c,children:s,...p},b){const{collapsed:S}=G(),g={display:"flex",flexDirection:"column",gap:m.spacing[.5],...c},v={padding:`${m.spacing[3]}px ${m.spacing[3]}px ${i.componentPaddingY.sm}px ${m.spacing[3]}px`,fontSize:C.fontSizes.xs,fontWeight:600,color:"var(--brycks-foreground-muted)",textTransform:"uppercase",letterSpacing:"0.05em"};return a.jsxs("div",{ref:b,className:j.cx("brycks-menu-group",u),style:g,...p,children:[t&&!S&&a.jsx("div",{style:v,children:t}),s]})});P.displayName="MenuGroup";const T=r.forwardRef(function({className:t,style:u,...c},s){const p={height:1,backgroundColor:"var(--brycks-border-muted)",margin:`${m.spacing[2]}px 0`,...u};return a.jsx("div",{ref:s,role:"separator",className:j.cx("brycks-menu-divider",t),style:p,...c})});T.displayName="MenuDivider";exports.Menu=H;exports.MenuDivider=T;exports.MenuGroup=P;exports.MenuItem=F;
2
2
  //# sourceMappingURL=Menu.cjs.map
@@ -1,9 +1,9 @@
1
1
  import { jsx as d, jsxs as H } from "react/jsx-runtime";
2
2
  import { forwardRef as C, useState as F, useRef as G, useCallback as E, createContext as K, useContext as L } from "react";
3
3
  import { cx as w } from "../../../utils/styles.js";
4
+ import { iconSizes as R, componentHeights as j, componentPaddingX as O, componentGap as P, componentPaddingY as W } from "../../../design-system/primitives/sizing.js";
4
5
  import { spacing as u } from "../../../design-system/tokens/spacing.js";
5
- import { durations as O, easings as W } from "../../../design-system/tokens/motion.js";
6
- import { iconSizes as R, componentHeights as j, componentPaddingX as U, componentGap as P, componentPaddingY as X } from "../../../design-system/primitives/sizing.js";
6
+ import { durations as U, easings as X } from "../../../design-system/tokens/motion.js";
7
7
  import { fontSizes as z } from "../../../design-system/tokens/typography.js";
8
8
  const T = K(null);
9
9
  function q() {
@@ -76,7 +76,7 @@ const Y = C(function({
76
76
  Y.displayName = "Menu";
77
77
  const B = {
78
78
  sm: { height: j.sm, fontSize: z.base - 1, iconSize: R.sm, padding: P.lg },
79
- md: { height: j.md, fontSize: z.base, iconSize: R.md - 2, padding: U.sm },
79
+ md: { height: j.md, fontSize: z.base, iconSize: R.md - 2, padding: O.sm },
80
80
  lg: { height: j.lg, fontSize: z.md, iconSize: R.md, padding: u[3.5] }
81
81
  }, J = C(function({ value: n, icon: i, badge: s, disabled: r = !1, onClick: l, className: x, style: h, children: f, ...b }, p) {
82
82
  const { size: D, activeItem: $, setActiveItem: g, collapsed: o, focusedIndex: k, setFocusedIndex: v, registerItem: N } = q(), c = $ === n, a = B[D], S = N(n), A = () => {
@@ -97,7 +97,7 @@ const B = {
97
97
  border: "none",
98
98
  borderRadius: "var(--brycks-radius-md)",
99
99
  cursor: r ? "not-allowed" : "pointer",
100
- transition: `all ${O.quick}ms ${W.easeOut}`,
100
+ transition: `all ${U.quick}ms ${X.easeOut}`,
101
101
  textAlign: "left",
102
102
  outline: "none",
103
103
  justifyContent: o ? "center" : "flex-start",
@@ -148,7 +148,7 @@ const Q = C(function({ label: n, className: i, style: s, children: r, ...l }, x)
148
148
  gap: u[0.5],
149
149
  ...s
150
150
  }, b = {
151
- padding: `${u[3]}px ${u[3]}px ${X.sm}px ${u[3]}px`,
151
+ padding: `${u[3]}px ${u[3]}px ${W.sm}px ${u[3]}px`,
152
152
  fontSize: z.xs,
153
153
  fontWeight: 600,
154
154
  color: "var(--brycks-foreground-muted)",
@@ -1,7 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),u=require("react"),m=require("../../../utils/styles.cjs"),j=u.createContext(null);function R(){const y=u.useContext(j);if(!y)throw new Error("Tabs components must be used within a Tabs");return y}const z=u.forwardRef(function({value:n,defaultValue:r="",onChange:s,size:d="md",variant:i="line",orientation:e="horizontal",className:o,style:p,children:g,testId:T,...w},k){const[f,t]=u.useState(r),v=n??f,S=u.useCallback(x=>{n===void 0&&t(x),s?.(x)},[n,s]),C={display:"flex",flexDirection:e==="vertical"?"row":"column",gap:e==="vertical"?24:0,...p};return c.jsx(j.Provider,{value:{value:v,onChange:S,size:d,variant:i,orientation:e},children:c.jsx("div",{ref:k,className:m.cx("brycks-tabs",`brycks-tabs--${i}`,`brycks-tabs--${e}`,o),style:C,"data-testid":T,...w,children:g})})});z.displayName="Tabs";const N=u.forwardRef(function({className:n,style:r,children:s,...d},i){const{orientation:e,variant:o}=R(),p={display:"flex",flexDirection:e==="vertical"?"column":"row",gap:o==="enclosed"||e==="vertical"?4:0,borderBottom:o==="line"&&e==="horizontal"?"1px solid var(--brycks-border-muted)":void 0,borderRight:o==="line"&&e==="vertical"?"1px solid var(--brycks-border-muted)":void 0,paddingRight:e==="vertical"?16:void 0,backgroundColor:o==="enclosed"?"var(--brycks-background-muted)":void 0,padding:o==="enclosed"?4:void 0,borderRadius:o==="enclosed"?"var(--brycks-radius-lg)":void 0,flexShrink:0,...r};return c.jsx("div",{ref:i,role:"tablist","aria-orientation":e,className:m.cx("brycks-tab-list",n),style:p,...d,children:s})});N.displayName="TabList";const I={sm:{fontSize:13,padding:"6px 12px",height:32},md:{fontSize:14,padding:"8px 16px",height:40},lg:{fontSize:16,padding:"10px 20px",height:48}},P=u.forwardRef(function({value:n,disabled:r=!1,icon:s,className:d,style:i,children:e,...o},p){const{value:g,onChange:T,size:w,variant:k,orientation:f}=R(),t=g===n,v=I[w],S=()=>{r||T(n)},C=a=>{if(r)return;const l=Array.from(a.currentTarget.parentElement?.querySelectorAll('[role="tab"]:not([disabled])')??[]),h=l.indexOf(a.currentTarget);let b=null;f==="horizontal"?(a.key==="ArrowRight"&&(b=(h+1)%l.length),a.key==="ArrowLeft"&&(b=(h-1+l.length)%l.length)):(a.key==="ArrowDown"&&(b=(h+1)%l.length),a.key==="ArrowUp"&&(b=(h-1+l.length)%l.length)),a.key==="Home"&&(b=0),a.key==="End"&&(b=l.length-1),b!==null&&(a.preventDefault(),l[b]?.focus(),l[b]?.click())},x=()=>{const a={display:"inline-flex",alignItems:"center",justifyContent:"center",gap:8,fontSize:v.fontSize,fontWeight:500,padding:v.padding,minHeight:v.height,cursor:r?"not-allowed":"pointer",opacity:r?.5:1,transition:"all 150ms ease-out",outline:"none",border:"none",backgroundColor:"transparent",whiteSpace:"nowrap"};return k==="line"?{...a,color:t?"var(--brycks-primary-default)":"var(--brycks-foreground-muted)",borderBottom:f==="horizontal"?`2px solid ${t?"var(--brycks-primary-default)":"transparent"}`:void 0,borderRight:f==="vertical"?`2px solid ${t?"var(--brycks-primary-default)":"transparent"}`:void 0,marginBottom:f==="horizontal"?-1:void 0,marginRight:f==="vertical"?-1:void 0}:k==="enclosed"?{...a,color:t?"var(--brycks-foreground-default)":"var(--brycks-foreground-muted)",backgroundColor:t?"var(--brycks-background-elevated)":"transparent",borderRadius:"var(--brycks-radius-md)",boxShadow:t?"var(--brycks-shadow-sm)":void 0}:{...a,color:t?"var(--brycks-primary-default)":"var(--brycks-foreground-muted)",backgroundColor:t?"var(--brycks-primary-50)":"transparent",borderRadius:"var(--brycks-radius-md)"}};return c.jsxs("button",{ref:p,role:"tab",type:"button","aria-selected":t,"aria-disabled":r,disabled:r,tabIndex:t?0:-1,className:m.cx("brycks-tab",t&&"brycks-tab--selected",d),style:{...x(),...i},onClick:S,onKeyDown:C,...o,children:[s&&c.jsx("span",{className:"brycks-tab-icon",children:s}),e]})});P.displayName="Tab";const A=u.forwardRef(function({className:n,style:r,children:s,...d},i){const e={flex:1,...r};return c.jsx("div",{ref:i,className:m.cx("brycks-tab-panels",n),style:e,...d,children:s})});A.displayName="TabPanels";const D=u.forwardRef(function({value:n,className:r,style:s,children:d,...i},e){const{value:o}=R();if(!(o===n))return null;const g={padding:"16px 0",animation:"brycks-tab-panel-in 200ms ease-out",...s};return c.jsxs(c.Fragment,{children:[c.jsx("style",{children:`
2
- @keyframes brycks-tab-panel-in {
3
- from { opacity: 0; }
4
- to { opacity: 1; }
5
- }
6
- `}),c.jsx("div",{ref:e,role:"tabpanel",tabIndex:0,className:m.cx("brycks-tab-panel",r),style:g,...i,children:d})]})});D.displayName="TabPanel";exports.Tab=P;exports.TabList=N;exports.TabPanel=D;exports.TabPanels=A;exports.Tabs=z;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("react/jsx-runtime"),c=require("react"),T=require("../../../utils/styles.cjs"),v=c.createContext(null);function g(){const b=c.useContext(v);if(!b)throw new Error("Tabs components must be used within a Tabs");return b}const N=c.forwardRef(function({value:e,defaultValue:t="",onChange:n,size:r="md",variant:l="line",orientation:i="horizontal",className:d,style:x,children:h,testId:k,...m},y){const[p,w]=c.useState(t),s=e??p,a=c.useCallback(u=>{e===void 0&&w(u),n?.(u)},[e,n]);return f.jsx(v.Provider,{value:{value:s,onChange:a,size:r,variant:l,orientation:i},children:f.jsx("div",{ref:y,className:T.cx("brycks-tabs",`brycks-tabs--${l}`,`brycks-tabs--${i}`,`brycks-tabs--${r}`,d),style:x,"data-testid":k,...m,children:h})})});N.displayName="Tabs";const P=c.forwardRef(function({className:e,style:t,children:n,...r},l){const{orientation:i}=g();return f.jsx("div",{ref:l,role:"tablist","aria-orientation":i,className:T.cx("brycks-tab-list",e),style:t,...r,children:n})});P.displayName="TabList";const j=c.forwardRef(function({value:e,disabled:t=!1,icon:n,className:r,style:l,children:i,...d},x){const{value:h,onChange:k,orientation:m}=g(),y=h===e,p=()=>{t||k(e)},w=s=>{if(t)return;const a=Array.from(s.currentTarget.parentElement?.querySelectorAll('[role="tab"]:not([disabled])')??[]),u=a.indexOf(s.currentTarget);let o=null;m==="horizontal"?(s.key==="ArrowRight"&&(o=(u+1)%a.length),s.key==="ArrowLeft"&&(o=(u-1+a.length)%a.length)):(s.key==="ArrowDown"&&(o=(u+1)%a.length),s.key==="ArrowUp"&&(o=(u-1+a.length)%a.length)),s.key==="Home"&&(o=0),s.key==="End"&&(o=a.length-1),o!==null&&(s.preventDefault(),a[o]?.focus(),a[o]?.click())};return f.jsxs("button",{ref:x,role:"tab",type:"button","aria-selected":y,"aria-disabled":t,disabled:t,tabIndex:y?0:-1,className:T.cx("brycks-tab",y&&"brycks-tab--selected",r),style:l,onClick:p,onKeyDown:w,...d,children:[n&&f.jsx("span",{className:"brycks-tab__icon",children:n}),i]})});j.displayName="Tab";const C=c.forwardRef(function({className:e,style:t,children:n,...r},l){return f.jsx("div",{ref:l,className:T.cx("brycks-tab-panels",e),style:t,...r,children:n})});C.displayName="TabPanels";const R=c.forwardRef(function({value:e,className:t,style:n,children:r,...l},i){const{value:d}=g();return d===e?f.jsx("div",{ref:i,role:"tabpanel",tabIndex:0,className:T.cx("brycks-tab-panel",t),style:n,...l,children:r}):null});R.displayName="TabPanel";exports.Tab=j;exports.TabList=P;exports.TabPanel=R;exports.TabPanels=C;exports.Tabs=N;
7
2
  //# sourceMappingURL=Tabs.cjs.map