@brycks/core-front 0.3.6 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/components/data/List/List.cjs +1 -1
  2. package/dist/components/data/List/List.cjs.map +1 -1
  3. package/dist/components/data/List/List.js +68 -148
  4. package/dist/components/data/List/List.js.map +1 -1
  5. package/dist/components/data/Table/Table.cjs +1 -1
  6. package/dist/components/data/Table/Table.cjs.map +1 -1
  7. package/dist/components/data/Table/Table.js +148 -217
  8. package/dist/components/data/Table/Table.js.map +1 -1
  9. package/dist/components/data/TreeView/TreeView.cjs +1 -1
  10. package/dist/components/data/TreeView/TreeView.cjs.map +1 -1
  11. package/dist/components/data/TreeView/TreeView.js +141 -182
  12. package/dist/components/data/TreeView/TreeView.js.map +1 -1
  13. package/dist/components/data.cjs +1 -1
  14. package/dist/components/data.js +23 -21
  15. package/dist/components/feedback/Banner/Banner.cjs +2 -0
  16. package/dist/components/feedback/Banner/Banner.cjs.map +1 -0
  17. package/dist/components/feedback/Banner/Banner.js +77 -0
  18. package/dist/components/feedback/Banner/Banner.js.map +1 -0
  19. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.cjs +2 -0
  20. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.cjs.map +1 -0
  21. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.js +68 -0
  22. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.js.map +1 -0
  23. package/dist/components/feedback/Drawer/Drawer.cjs +1 -22
  24. package/dist/components/feedback/Drawer/Drawer.cjs.map +1 -1
  25. package/dist/components/feedback/Drawer/Drawer.js +84 -184
  26. package/dist/components/feedback/Drawer/Drawer.js.map +1 -1
  27. package/dist/components/feedback/Modal/Modal.cjs +1 -1
  28. package/dist/components/feedback/Modal/Modal.cjs.map +1 -1
  29. package/dist/components/feedback/Modal/Modal.js +73 -150
  30. package/dist/components/feedback/Modal/Modal.js.map +1 -1
  31. package/dist/components/feedback/Popover/Popover.cjs +2 -2
  32. package/dist/components/feedback/Popover/Popover.cjs.map +1 -1
  33. package/dist/components/feedback/Popover/Popover.js +43 -44
  34. package/dist/components/feedback/Popover/Popover.js.map +1 -1
  35. package/dist/components/feedback/Toast/Toast.cjs +1 -10
  36. package/dist/components/feedback/Toast/Toast.cjs.map +1 -1
  37. package/dist/components/feedback/Toast/Toast.js +94 -187
  38. package/dist/components/feedback/Toast/Toast.js.map +1 -1
  39. package/dist/components/feedback.cjs +1 -1
  40. package/dist/components/feedback.js +17 -13
  41. package/dist/components/feedback.js.map +1 -1
  42. package/dist/components/form/Checkbox/Checkbox.cjs +1 -1
  43. package/dist/components/form/Checkbox/Checkbox.js +11 -11
  44. package/dist/components/form/Combobox/Combobox.cjs +1 -6
  45. package/dist/components/form/Combobox/Combobox.cjs.map +1 -1
  46. package/dist/components/form/Combobox/Combobox.js +190 -266
  47. package/dist/components/form/Combobox/Combobox.js.map +1 -1
  48. package/dist/components/form/Input/Input.cjs +1 -1
  49. package/dist/components/form/Input/Input.cjs.map +1 -1
  50. package/dist/components/form/Input/Input.js +38 -133
  51. package/dist/components/form/Input/Input.js.map +1 -1
  52. package/dist/components/form/SearchInput/SearchInput.cjs +2 -0
  53. package/dist/components/form/SearchInput/SearchInput.cjs.map +1 -0
  54. package/dist/components/form/SearchInput/SearchInput.js +68 -0
  55. package/dist/components/form/SearchInput/SearchInput.js.map +1 -0
  56. package/dist/components/form/Select/Select.cjs +1 -1
  57. package/dist/components/form/Select/Select.cjs.map +1 -1
  58. package/dist/components/form/Select/Select.js +36 -82
  59. package/dist/components/form/Select/Select.js.map +1 -1
  60. package/dist/components/form/TagInput/TagInput.cjs +1 -1
  61. package/dist/components/form/TagInput/TagInput.js +8 -8
  62. package/dist/components/form/Textarea/Textarea.cjs +1 -1
  63. package/dist/components/form/Textarea/Textarea.cjs.map +1 -1
  64. package/dist/components/form/Textarea/Textarea.js +61 -95
  65. package/dist/components/form/Textarea/Textarea.js.map +1 -1
  66. package/dist/components/form.cjs +1 -1
  67. package/dist/components/form.js +15 -13
  68. package/dist/components/form.js.map +1 -1
  69. package/dist/components/layout/Card/Card.cjs +1 -1
  70. package/dist/components/layout/Card/Card.cjs.map +1 -1
  71. package/dist/components/layout/Card/Card.js +7 -5
  72. package/dist/components/layout/Card/Card.js.map +1 -1
  73. package/dist/components/navigation/ContextMenu/ContextMenu.cjs +1 -1
  74. package/dist/components/navigation/ContextMenu/ContextMenu.js +9 -9
  75. package/dist/components/navigation/Menu/Menu.cjs +1 -1
  76. package/dist/components/navigation/Menu/Menu.cjs.map +1 -1
  77. package/dist/components/navigation/Menu/Menu.js +70 -135
  78. package/dist/components/navigation/Menu/Menu.js.map +1 -1
  79. package/dist/components/navigation/Pagination/Pagination.cjs +1 -1
  80. package/dist/components/navigation/Pagination/Pagination.cjs.map +1 -1
  81. package/dist/components/navigation/Pagination/Pagination.js +87 -157
  82. package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
  83. package/dist/components/navigation/SegmentedControl/SegmentedControl.cjs +2 -0
  84. package/dist/components/navigation/SegmentedControl/SegmentedControl.cjs.map +1 -0
  85. package/dist/components/navigation/SegmentedControl/SegmentedControl.js +90 -0
  86. package/dist/components/navigation/SegmentedControl/SegmentedControl.js.map +1 -0
  87. package/dist/components/navigation.cjs +1 -1
  88. package/dist/components/navigation.js +25 -23
  89. package/dist/components/navigation.js.map +1 -1
  90. package/dist/components/utility/Avatar/Avatar.cjs +1 -1
  91. package/dist/components/utility/Avatar/Avatar.cjs.map +1 -1
  92. package/dist/components/utility/Avatar/Avatar.js +18 -18
  93. package/dist/components/utility/Avatar/Avatar.js.map +1 -1
  94. package/dist/components/utility/Badge/Badge.cjs +1 -1
  95. package/dist/components/utility/Badge/Badge.cjs.map +1 -1
  96. package/dist/components/utility/Badge/Badge.js +31 -23
  97. package/dist/components/utility/Badge/Badge.js.map +1 -1
  98. package/dist/components/utility/Kbd/Kbd.cjs +2 -0
  99. package/dist/components/utility/Kbd/Kbd.cjs.map +1 -0
  100. package/dist/components/utility/Kbd/Kbd.js +20 -0
  101. package/dist/components/utility/Kbd/Kbd.js.map +1 -0
  102. package/dist/components/utility/Logo/Logo.cjs +1 -1
  103. package/dist/components/utility/Logo/Logo.cjs.map +1 -1
  104. package/dist/components/utility/Logo/Logo.js +19 -19
  105. package/dist/components/utility/Logo/Logo.js.map +1 -1
  106. package/dist/components/utility.cjs +1 -1
  107. package/dist/components/utility.js +9 -7
  108. package/dist/components/utility.js.map +1 -1
  109. package/dist/data.d.ts +34 -1
  110. package/dist/feedback.d.ts +67 -2
  111. package/dist/form.d.ts +31 -0
  112. package/dist/index.cjs +1 -1
  113. package/dist/index.d.ts +184 -3
  114. package/dist/index.js +177 -165
  115. package/dist/index.js.map +1 -1
  116. package/dist/navigation.d.ts +39 -0
  117. package/dist/styles.css +1 -1
  118. package/dist/utility.d.ts +19 -0
  119. package/package.json +1 -1
@@ -1,190 +1,125 @@
1
- import { jsx as m, jsxs as E } from "react/jsx-runtime";
2
- import { forwardRef as C, useState as F, useRef as G, useCallback as T, createContext as L, useContext as O } from "react";
3
- import { cx as w } from "../../../utils/styles.js";
4
- import { iconSizes as R, componentHeights as j, componentPaddingX as W, componentGap as H, componentPaddingY as U } from "../../../design-system/primitives/sizing.js";
5
- import { spacing as u } from "../../../design-system/tokens/spacing.js";
6
- import { durations as X, easings as Y } from "../../../design-system/tokens/motion.js";
7
- import { fontSizes as z } from "../../../design-system/tokens/typography.js";
8
- const P = L(null);
9
- function q() {
10
- const f = O(P);
11
- if (!f)
1
+ import { jsx as i, jsxs as R } from "react/jsx-runtime";
2
+ import { forwardRef as k, useState as C, useRef as A, useCallback as F, createContext as j, useContext as E } from "react";
3
+ import { cx as M } from "../../../utils/styles.js";
4
+ const S = j(null);
5
+ function G() {
6
+ const a = E(S);
7
+ if (!a)
12
8
  throw new Error("Menu components must be used within a Menu");
13
- return f;
9
+ return a;
14
10
  }
15
- const B = C(function({
11
+ const K = k(function({
16
12
  activeItem: n,
17
13
  onChange: c,
18
14
  size: s = "md",
19
15
  collapsed: r = !1,
20
16
  className: l,
21
- style: h,
22
- children: b,
23
- testId: p,
24
- ...k
25
- }, g) {
26
- const [D, S] = F(null), [y, o] = F(-1), x = G([]), I = G(null), $ = n !== void 0 ? n : D, i = (e) => {
27
- n === void 0 && S(e), c?.(e);
28
- }, a = T((e) => {
29
- const t = x.current.indexOf(e);
30
- return t === -1 ? (x.current.push(e), x.current.length - 1) : t;
31
- }, []), v = T((e) => {
17
+ style: d,
18
+ children: f,
19
+ testId: y,
20
+ ...g
21
+ }, m) {
22
+ const [v, N] = C(null), [o, u] = C(-1), p = A([]), I = A(null), h = n !== void 0 ? n : v, b = (e) => {
23
+ n === void 0 && N(e), c?.(e);
24
+ }, w = F((e) => {
25
+ const t = p.current.indexOf(e);
26
+ return t === -1 ? (p.current.push(e), p.current.length - 1) : t;
27
+ }, []), D = F((e) => {
32
28
  const t = I.current?.querySelectorAll('[role="menuitem"]:not(:disabled)');
33
29
  if (!t?.length) return;
34
- const M = y >= 0 ? y : 0;
30
+ const _ = o >= 0 ? o : 0;
35
31
  switch (e.key) {
36
32
  case "ArrowDown": {
37
33
  e.preventDefault();
38
- const d = (M + 1) % t.length;
39
- o(d), t[d]?.focus();
34
+ const x = (_ + 1) % t.length;
35
+ u(x), t[x]?.focus();
40
36
  break;
41
37
  }
42
38
  case "ArrowUp": {
43
39
  e.preventDefault();
44
- const d = (M - 1 + t.length) % t.length;
45
- o(d), t[d]?.focus();
40
+ const x = (_ - 1 + t.length) % t.length;
41
+ u(x), t[x]?.focus();
46
42
  break;
47
43
  }
48
44
  case "Home":
49
- e.preventDefault(), o(0), t[0]?.focus();
45
+ e.preventDefault(), u(0), t[0]?.focus();
50
46
  break;
51
47
  case "End":
52
- e.preventDefault(), o(t.length - 1), t[t.length - 1]?.focus();
48
+ e.preventDefault(), u(t.length - 1), t[t.length - 1]?.focus();
53
49
  break;
54
50
  }
55
- }, [y]), N = {
56
- display: "flex",
57
- flexDirection: "column",
58
- gap: u[0.5],
59
- padding: u[2],
60
- ...h
61
- };
62
- return /* @__PURE__ */ m(P.Provider, { value: { size: s, activeItem: $, setActiveItem: i, collapsed: r, focusedIndex: y, setFocusedIndex: o, registerItem: a }, children: /* @__PURE__ */ m(
51
+ }, [o]);
52
+ return /* @__PURE__ */ i(S.Provider, { value: { size: s, activeItem: h, setActiveItem: b, collapsed: r, focusedIndex: o, setFocusedIndex: u, registerItem: w }, children: /* @__PURE__ */ i(
63
53
  "nav",
64
54
  {
65
55
  ref: (e) => {
66
- I.current = e, typeof g == "function" ? g(e) : g && (g.current = e);
56
+ I.current = e, typeof m == "function" ? m(e) : m && (m.current = e);
67
57
  },
68
58
  role: "menu",
69
- className: w("brycks-menu", `brycks-menu--${s}`, r && "brycks-menu--collapsed", l),
70
- style: N,
71
- onKeyDown: v,
72
- "data-testid": p,
73
- ...k,
74
- children: b
59
+ className: M("brycks-menu", `brycks-menu--${s}`, r && "brycks-menu--collapsed", l),
60
+ style: d,
61
+ onKeyDown: D,
62
+ "data-testid": y,
63
+ ...g,
64
+ children: f
75
65
  }
76
66
  ) });
77
67
  });
78
- B.displayName = "Menu";
79
- const J = {
80
- sm: { height: j.sm, fontSize: z.base - 1, iconSize: R.sm, padding: H.lg },
81
- md: { height: j.md, fontSize: z.base, iconSize: R.md - 2, padding: W.sm },
82
- lg: { height: j.lg, fontSize: z.md, iconSize: R.md, padding: u[3.5] }
83
- }, Q = C(function({ value: n, icon: c, badge: s, disabled: r = !1, onClick: l, className: h, style: b, children: p, ...k }, g) {
84
- const { size: D, activeItem: S, setActiveItem: y, collapsed: o, focusedIndex: x, setFocusedIndex: I, registerItem: $ } = q(), i = S === n, a = J[D], v = $(n), N = () => {
85
- r || (y(n), l?.(n));
86
- }, e = () => {
87
- I(v);
88
- }, t = {
89
- display: "flex",
90
- alignItems: "center",
91
- gap: H.lg,
92
- width: "100%",
93
- minHeight: a.height,
94
- padding: o ? a.padding : `0 ${a.padding}px`,
95
- fontSize: a.fontSize,
96
- fontWeight: i ? 600 : 500,
97
- color: r ? "var(--brycks-foreground-disabled)" : i ? "var(--brycks-primary-default)" : "var(--brycks-foreground-default)",
98
- backgroundColor: i ? "var(--brycks-primary-muted)" : "transparent",
99
- border: "none",
100
- borderRadius: "var(--brycks-radius-md)",
101
- cursor: r ? "not-allowed" : "pointer",
102
- transition: `all ${X.quick}ms ${Y.easeOut}`,
103
- textAlign: "left",
104
- justifyContent: o ? "center" : "flex-start",
105
- ...b
106
- }, M = {
107
- width: a.iconSize,
108
- height: a.iconSize,
109
- flexShrink: 0,
110
- display: "flex",
111
- alignItems: "center",
112
- justifyContent: "center"
113
- }, d = {
114
- marginLeft: "auto"
115
- }, K = x >= 0 ? x === v : S ? i : v === 0;
116
- return /* @__PURE__ */ E(
68
+ K.displayName = "Menu";
69
+ const q = k(function({ value: n, icon: c, badge: s, disabled: r = !1, onClick: l, className: d, style: f, children: y, ...g }, m) {
70
+ const { activeItem: v, setActiveItem: N, collapsed: o, focusedIndex: u, setFocusedIndex: p, registerItem: I } = G(), h = v === n, b = I(n), w = () => {
71
+ r || (N(n), l?.(n));
72
+ }, D = () => {
73
+ p(b);
74
+ }, e = u >= 0 ? u === b : v ? h : b === 0;
75
+ return /* @__PURE__ */ R(
117
76
  "button",
118
77
  {
119
- ref: g,
78
+ ref: m,
120
79
  type: "button",
121
80
  role: "menuitem",
122
81
  disabled: r,
123
- tabIndex: K ? 0 : -1,
124
- className: w("brycks-menu-item", i && "brycks-menu-item--active", h),
125
- style: t,
126
- onClick: N,
127
- onFocus: e,
128
- onMouseEnter: (A) => {
129
- !r && !i && (A.currentTarget.style.backgroundColor = "var(--brycks-background-muted)");
130
- },
131
- onMouseLeave: (A) => {
132
- i || (A.currentTarget.style.backgroundColor = "transparent");
133
- },
134
- title: o ? String(p) : void 0,
135
- ...k,
82
+ tabIndex: e ? 0 : -1,
83
+ className: M("brycks-menu-item", h && "brycks-menu-item--active", d),
84
+ style: f,
85
+ onClick: w,
86
+ onFocus: D,
87
+ title: o ? String(y) : void 0,
88
+ ...g,
136
89
  children: [
137
- c && /* @__PURE__ */ m("span", { style: M, children: c }),
138
- !o && /* @__PURE__ */ m("span", { style: { flex: 1 }, children: p }),
139
- !o && s && /* @__PURE__ */ m("span", { style: d, children: s })
90
+ c && /* @__PURE__ */ i("span", { className: "brycks-menu-item__icon", children: c }),
91
+ !o && /* @__PURE__ */ i("span", { className: "brycks-menu-item__label", children: y }),
92
+ !o && s && /* @__PURE__ */ i("span", { className: "brycks-menu-item__badge", children: s })
140
93
  ]
141
94
  }
142
95
  );
143
96
  });
144
- Q.displayName = "MenuItem";
145
- const V = C(function({ label: n, className: c, style: s, children: r, ...l }, h) {
146
- const { collapsed: b } = q(), p = {
147
- display: "flex",
148
- flexDirection: "column",
149
- gap: u[0.5],
150
- ...s
151
- }, k = {
152
- padding: `${u[3]}px ${u[3]}px ${U.sm}px ${u[3]}px`,
153
- fontSize: z.xs,
154
- fontWeight: 600,
155
- color: "var(--brycks-foreground-muted)",
156
- textTransform: "uppercase",
157
- letterSpacing: "0.05em"
158
- };
159
- return /* @__PURE__ */ E("div", { ref: h, className: w("brycks-menu-group", c), style: p, ...l, children: [
160
- n && !b && /* @__PURE__ */ m("div", { style: k, children: n }),
97
+ q.displayName = "MenuItem";
98
+ const H = k(function({ label: n, className: c, style: s, children: r, ...l }, d) {
99
+ const { collapsed: f } = G();
100
+ return /* @__PURE__ */ R("div", { ref: d, className: M("brycks-menu-group", c), style: s, ...l, children: [
101
+ n && !f && /* @__PURE__ */ i("div", { className: "brycks-menu-group__label", children: n }),
161
102
  r
162
103
  ] });
163
104
  });
164
- V.displayName = "MenuGroup";
165
- const Z = C(function({ className: n, style: c, ...s }, r) {
166
- const l = {
167
- height: 1,
168
- backgroundColor: "var(--brycks-border-muted)",
169
- margin: `${u[2]}px 0`,
170
- ...c
171
- };
172
- return /* @__PURE__ */ m(
105
+ H.displayName = "MenuGroup";
106
+ const O = k(function({ className: n, style: c, ...s }, r) {
107
+ return /* @__PURE__ */ i(
173
108
  "div",
174
109
  {
175
110
  ref: r,
176
111
  role: "separator",
177
- className: w("brycks-menu-divider", n),
178
- style: l,
112
+ className: M("brycks-menu-divider", n),
113
+ style: c,
179
114
  ...s
180
115
  }
181
116
  );
182
117
  });
183
- Z.displayName = "MenuDivider";
118
+ O.displayName = "MenuDivider";
184
119
  export {
185
- B as Menu,
186
- Z as MenuDivider,
187
- V as MenuGroup,
188
- Q as MenuItem
120
+ K as Menu,
121
+ O as MenuDivider,
122
+ H as MenuGroup,
123
+ q as MenuItem
189
124
  };
190
125
  //# sourceMappingURL=Menu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.js","sources":["../../../../src/components/navigation/Menu/Menu.tsx"],"sourcesContent":["/**\n * Menu Component\n *\n * A vertical navigation menu with support for nested items.\n * Suitable for sidebars and navigation panels.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n createContext,\n useContext,\n type CSSProperties,\n type ReactNode,\n type HTMLAttributes,\n type KeyboardEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentHeights, componentGap, componentPaddingX, componentPaddingY, iconSizes } from '../../../design-system/primitives'\n\nexport type MenuSize = 'sm' | 'md' | 'lg'\n\ninterface MenuContextValue {\n size: MenuSize\n activeItem: string | null\n setActiveItem: (value: string | null) => void\n collapsed: boolean\n focusedIndex: number\n setFocusedIndex: (index: number) => void\n registerItem: (value: string) => number\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null)\n\nfunction useMenuContext() {\n const context = useContext(MenuContext)\n if (!context) {\n throw new Error('Menu components must be used within a Menu')\n }\n return context\n}\n\nexport interface MenuProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Currently active item */\n activeItem?: string | null\n /** Callback when active item changes */\n onChange?: (value: string | null) => void\n /** Menu size */\n size?: MenuSize\n /** Whether the menu is collapsed (icons only) */\n collapsed?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const Menu = forwardRef<HTMLElement, MenuProps>(function Menu(\n {\n activeItem: controlledActiveItem,\n onChange,\n size = 'md',\n collapsed = false,\n className,\n style,\n children,\n testId,\n ...props\n },\n ref\n) {\n const [internalActiveItem, setInternalActiveItem] = useState<string | null>(null)\n const [focusedIndex, setFocusedIndex] = useState(-1)\n const itemsRef = useRef<string[]>([])\n const menuRef = useRef<HTMLElement>(null)\n const activeItem = controlledActiveItem !== undefined ? controlledActiveItem : internalActiveItem\n\n const setActiveItem = (value: string | null) => {\n if (controlledActiveItem === undefined) {\n setInternalActiveItem(value)\n }\n onChange?.(value)\n }\n\n // Register items for keyboard navigation\n const registerItem = useCallback((value: string) => {\n const index = itemsRef.current.indexOf(value)\n if (index === -1) {\n itemsRef.current.push(value)\n return itemsRef.current.length - 1\n }\n return index\n }, [])\n\n // Keyboard navigation\n const handleKeyDown = useCallback((e: KeyboardEvent<HTMLElement>) => {\n const items = menuRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"menuitem\"]:not(:disabled)')\n if (!items?.length) return\n\n const currentIndex = focusedIndex >= 0 ? focusedIndex : 0\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n const nextIndex = (currentIndex + 1) % items.length\n setFocusedIndex(nextIndex)\n items[nextIndex]?.focus()\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n const prevIndex = (currentIndex - 1 + items.length) % items.length\n setFocusedIndex(prevIndex)\n items[prevIndex]?.focus()\n break\n }\n case 'Home':\n e.preventDefault()\n setFocusedIndex(0)\n items[0]?.focus()\n break\n case 'End':\n e.preventDefault()\n setFocusedIndex(items.length - 1)\n items[items.length - 1]?.focus()\n break\n }\n }, [focusedIndex])\n\n const menuStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: spacing[0.5],\n padding: spacing[2],\n ...style,\n }\n\n return (\n <MenuContext.Provider value={{ size, activeItem, setActiveItem, collapsed, focusedIndex, setFocusedIndex, registerItem }}>\n <nav\n ref={(node) => {\n (menuRef as React.MutableRefObject<HTMLElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLElement | null>).current = node\n }}\n role=\"menu\"\n className={cx('brycks-menu', `brycks-menu--${size}`, collapsed && 'brycks-menu--collapsed', className)}\n style={menuStyle}\n onKeyDown={handleKeyDown}\n data-testid={testId}\n {...props}\n >\n {children}\n </nav>\n </MenuContext.Provider>\n )\n})\n\nMenu.displayName = 'Menu'\n\n// MenuItem\nexport interface MenuItemProps extends Omit<HTMLAttributes<HTMLButtonElement>, 'onClick'> {\n /** Item value (unique identifier) */\n value: string\n /** Icon before the label */\n icon?: ReactNode\n /** Badge/count after the label */\n badge?: ReactNode\n /** Whether the item is disabled */\n disabled?: boolean\n /** Callback when clicked */\n onClick?: (value: string) => void\n /** Custom class name */\n className?: string\n}\n\nconst sizeConfig: Record<MenuSize, { height: number; fontSize: number; iconSize: number; padding: number }> = {\n sm: { height: componentHeights.sm, fontSize: fontSizes.base - 1, iconSize: iconSizes.sm, padding: componentGap.lg },\n md: { height: componentHeights.md, fontSize: fontSizes.base, iconSize: iconSizes.md - 2, padding: componentPaddingX.sm },\n lg: { height: componentHeights.lg, fontSize: fontSizes.md, iconSize: iconSizes.md, padding: spacing[3.5] },\n}\n\nexport const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>(function MenuItem(\n { value, icon, badge, disabled = false, onClick, className, style, children, ...props },\n ref\n) {\n const { size, activeItem, setActiveItem, collapsed, focusedIndex, setFocusedIndex, registerItem } = useMenuContext()\n const isActive = activeItem === value\n const config = sizeConfig[size]\n const itemIndex = registerItem(value)\n\n const handleClick = () => {\n if (disabled) return\n setActiveItem(value)\n onClick?.(value)\n }\n\n const handleFocus = () => {\n setFocusedIndex(itemIndex)\n }\n\n const itemStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: componentGap.lg,\n width: '100%',\n minHeight: config.height,\n padding: collapsed ? config.padding : `0 ${config.padding}px`,\n fontSize: config.fontSize,\n fontWeight: isActive ? 600 : 500,\n color: disabled\n ? 'var(--brycks-foreground-disabled)'\n : isActive\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isActive ? 'var(--brycks-primary-muted)' : 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n transition: `all ${durations.quick}ms ${easings.easeOut}`,\n textAlign: 'left',\n justifyContent: collapsed ? 'center' : 'flex-start',\n ...style,\n }\n\n const iconStyle: CSSProperties = {\n width: config.iconSize,\n height: config.iconSize,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }\n\n const badgeStyle: CSSProperties = {\n marginLeft: 'auto',\n }\n\n // Roving tabindex: before any item is focused (focusedIndex -1), Tab must\n // still be able to enter the menu through the active item or the first one.\n const isTabStop =\n focusedIndex >= 0 ? focusedIndex === itemIndex : activeItem ? isActive : itemIndex === 0\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n tabIndex={isTabStop ? 0 : -1}\n className={cx('brycks-menu-item', isActive && 'brycks-menu-item--active', className)}\n style={itemStyle}\n onClick={handleClick}\n onFocus={handleFocus}\n onMouseEnter={(e) => {\n if (!disabled && !isActive) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n title={collapsed ? String(children) : undefined}\n {...props}\n >\n {icon && <span style={iconStyle}>{icon}</span>}\n {!collapsed && <span style={{ flex: 1 }}>{children}</span>}\n {!collapsed && badge && <span style={badgeStyle}>{badge}</span>}\n </button>\n )\n})\n\nMenuItem.displayName = 'MenuItem'\n\n// MenuGroup\nexport interface MenuGroupProps extends HTMLAttributes<HTMLDivElement> {\n /** Group label */\n label?: string\n /** Custom class name */\n className?: string\n}\n\nexport const MenuGroup = forwardRef<HTMLDivElement, MenuGroupProps>(function MenuGroup(\n { label, className, style, children, ...props },\n ref\n) {\n const { collapsed } = useMenuContext()\n\n const groupStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: spacing[0.5],\n ...style,\n }\n\n const labelStyle: CSSProperties = {\n padding: `${spacing[3]}px ${spacing[3]}px ${componentPaddingY.sm}px ${spacing[3]}px`,\n fontSize: fontSizes.xs,\n fontWeight: 600,\n color: 'var(--brycks-foreground-muted)',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }\n\n return (\n <div ref={ref} className={cx('brycks-menu-group', className)} style={groupStyle} {...props}>\n {label && !collapsed && <div style={labelStyle}>{label}</div>}\n {children}\n </div>\n )\n})\n\nMenuGroup.displayName = 'MenuGroup'\n\n// MenuDivider\nexport interface MenuDividerProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const MenuDivider = forwardRef<HTMLDivElement, MenuDividerProps>(function MenuDivider(\n { className, style, ...props },\n ref\n) {\n const dividerStyle: CSSProperties = {\n height: 1,\n backgroundColor: 'var(--brycks-border-muted)',\n margin: `${spacing[2]}px 0`,\n ...style,\n }\n\n return (\n <div\n ref={ref}\n role=\"separator\"\n className={cx('brycks-menu-divider', className)}\n style={dividerStyle}\n {...props}\n />\n )\n})\n\nMenuDivider.displayName = 'MenuDivider'\n"],"names":["MenuContext","createContext","useMenuContext","context","useContext","Menu","forwardRef","controlledActiveItem","onChange","size","collapsed","className","style","children","testId","props","ref","internalActiveItem","setInternalActiveItem","useState","focusedIndex","setFocusedIndex","itemsRef","useRef","menuRef","activeItem","setActiveItem","value","registerItem","useCallback","index","handleKeyDown","items","currentIndex","nextIndex","prevIndex","menuStyle","spacing","jsx","node","cx","sizeConfig","componentHeights","fontSizes","iconSizes","componentGap","componentPaddingX","MenuItem","icon","badge","disabled","onClick","isActive","config","itemIndex","handleClick","handleFocus","itemStyle","durations","easings","iconStyle","badgeStyle","isTabStop","jsxs","e","MenuGroup","label","groupStyle","labelStyle","componentPaddingY","MenuDivider","dividerStyle"],"mappings":"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"}
1
+ {"version":3,"file":"Menu.js","sources":["../../../../src/components/navigation/Menu/Menu.tsx"],"sourcesContent":["/**\n * Menu Component\n *\n * A vertical navigation menu with support for nested items.\n * Suitable for sidebars and navigation panels.\n */\n\nimport {\n forwardRef,\n useState,\n useRef,\n useCallback,\n createContext,\n useContext,\n type ReactNode,\n type HTMLAttributes,\n type KeyboardEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type MenuSize = 'sm' | 'md' | 'lg'\n\ninterface MenuContextValue {\n size: MenuSize\n activeItem: string | null\n setActiveItem: (value: string | null) => void\n collapsed: boolean\n focusedIndex: number\n setFocusedIndex: (index: number) => void\n registerItem: (value: string) => number\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null)\n\nfunction useMenuContext() {\n const context = useContext(MenuContext)\n if (!context) {\n throw new Error('Menu components must be used within a Menu')\n }\n return context\n}\n\nexport interface MenuProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Currently active item */\n activeItem?: string | null\n /** Callback when active item changes */\n onChange?: (value: string | null) => void\n /** Menu size */\n size?: MenuSize\n /** Whether the menu is collapsed (icons only) */\n collapsed?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const Menu = forwardRef<HTMLElement, MenuProps>(function Menu(\n {\n activeItem: controlledActiveItem,\n onChange,\n size = 'md',\n collapsed = false,\n className,\n style,\n children,\n testId,\n ...props\n },\n ref\n) {\n const [internalActiveItem, setInternalActiveItem] = useState<string | null>(null)\n const [focusedIndex, setFocusedIndex] = useState(-1)\n const itemsRef = useRef<string[]>([])\n const menuRef = useRef<HTMLElement>(null)\n const activeItem = controlledActiveItem !== undefined ? controlledActiveItem : internalActiveItem\n\n const setActiveItem = (value: string | null) => {\n if (controlledActiveItem === undefined) {\n setInternalActiveItem(value)\n }\n onChange?.(value)\n }\n\n // Register items for keyboard navigation\n const registerItem = useCallback((value: string) => {\n const index = itemsRef.current.indexOf(value)\n if (index === -1) {\n itemsRef.current.push(value)\n return itemsRef.current.length - 1\n }\n return index\n }, [])\n\n // Keyboard navigation\n const handleKeyDown = useCallback((e: KeyboardEvent<HTMLElement>) => {\n const items = menuRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"menuitem\"]:not(:disabled)')\n if (!items?.length) return\n\n const currentIndex = focusedIndex >= 0 ? focusedIndex : 0\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n const nextIndex = (currentIndex + 1) % items.length\n setFocusedIndex(nextIndex)\n items[nextIndex]?.focus()\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n const prevIndex = (currentIndex - 1 + items.length) % items.length\n setFocusedIndex(prevIndex)\n items[prevIndex]?.focus()\n break\n }\n case 'Home':\n e.preventDefault()\n setFocusedIndex(0)\n items[0]?.focus()\n break\n case 'End':\n e.preventDefault()\n setFocusedIndex(items.length - 1)\n items[items.length - 1]?.focus()\n break\n }\n }, [focusedIndex])\n\n return (\n <MenuContext.Provider value={{ size, activeItem, setActiveItem, collapsed, focusedIndex, setFocusedIndex, registerItem }}>\n <nav\n ref={(node) => {\n (menuRef as React.MutableRefObject<HTMLElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLElement | null>).current = node\n }}\n role=\"menu\"\n className={cx('brycks-menu', `brycks-menu--${size}`, collapsed && 'brycks-menu--collapsed', className)}\n style={style}\n onKeyDown={handleKeyDown}\n data-testid={testId}\n {...props}\n >\n {children}\n </nav>\n </MenuContext.Provider>\n )\n})\n\nMenu.displayName = 'Menu'\n\n// MenuItem\nexport interface MenuItemProps extends Omit<HTMLAttributes<HTMLButtonElement>, 'onClick'> {\n /** Item value (unique identifier) */\n value: string\n /** Icon before the label */\n icon?: ReactNode\n /** Badge/count after the label */\n badge?: ReactNode\n /** Whether the item is disabled */\n disabled?: boolean\n /** Callback when clicked */\n onClick?: (value: string) => void\n /** Custom class name */\n className?: string\n}\n\nexport const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>(function MenuItem(\n { value, icon, badge, disabled = false, onClick, className, style, children, ...props },\n ref\n) {\n const { activeItem, setActiveItem, collapsed, focusedIndex, setFocusedIndex, registerItem } = useMenuContext()\n const isActive = activeItem === value\n const itemIndex = registerItem(value)\n\n const handleClick = () => {\n if (disabled) return\n setActiveItem(value)\n onClick?.(value)\n }\n\n const handleFocus = () => {\n setFocusedIndex(itemIndex)\n }\n\n // Roving tabindex: before any item is focused (focusedIndex -1), Tab must\n // still be able to enter the menu through the active item or the first one.\n const isTabStop =\n focusedIndex >= 0 ? focusedIndex === itemIndex : activeItem ? isActive : itemIndex === 0\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n tabIndex={isTabStop ? 0 : -1}\n className={cx('brycks-menu-item', isActive && 'brycks-menu-item--active', className)}\n style={style}\n onClick={handleClick}\n onFocus={handleFocus}\n title={collapsed ? String(children) : undefined}\n {...props}\n >\n {icon && <span className=\"brycks-menu-item__icon\">{icon}</span>}\n {!collapsed && <span className=\"brycks-menu-item__label\">{children}</span>}\n {!collapsed && badge && <span className=\"brycks-menu-item__badge\">{badge}</span>}\n </button>\n )\n})\n\nMenuItem.displayName = 'MenuItem'\n\n// MenuGroup\nexport interface MenuGroupProps extends HTMLAttributes<HTMLDivElement> {\n /** Group label */\n label?: string\n /** Custom class name */\n className?: string\n}\n\nexport const MenuGroup = forwardRef<HTMLDivElement, MenuGroupProps>(function MenuGroup(\n { label, className, style, children, ...props },\n ref\n) {\n const { collapsed } = useMenuContext()\n\n return (\n <div ref={ref} className={cx('brycks-menu-group', className)} style={style} {...props}>\n {label && !collapsed && <div className=\"brycks-menu-group__label\">{label}</div>}\n {children}\n </div>\n )\n})\n\nMenuGroup.displayName = 'MenuGroup'\n\n// MenuDivider\nexport interface MenuDividerProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const MenuDivider = forwardRef<HTMLDivElement, MenuDividerProps>(function MenuDivider(\n { className, style, ...props },\n ref\n) {\n return (\n <div\n ref={ref}\n role=\"separator\"\n className={cx('brycks-menu-divider', className)}\n style={style}\n {...props}\n />\n )\n})\n\nMenuDivider.displayName = 'MenuDivider'\n"],"names":["MenuContext","createContext","useMenuContext","context","useContext","Menu","forwardRef","controlledActiveItem","onChange","size","collapsed","className","style","children","testId","props","ref","internalActiveItem","setInternalActiveItem","useState","focusedIndex","setFocusedIndex","itemsRef","useRef","menuRef","activeItem","setActiveItem","value","registerItem","useCallback","index","handleKeyDown","items","currentIndex","nextIndex","prevIndex","jsx","node","cx","MenuItem","icon","badge","disabled","onClick","isActive","itemIndex","handleClick","handleFocus","isTabStop","jsxs","MenuGroup","label","MenuDivider"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),j=require("react"),B=require("../../../utils/styles.cjs"),u=require("../../../design-system/tokens/spacing.cjs"),y=require("../../../design-system/tokens/typography.cjs"),N=require("../../../design-system/primitives/sizing.cjs"),v=require("../../../design-system/tokens/motion.cjs"),O={navigation:"Pagination",first:"First page",previous:"Previous page",next:"Next page",last:"Last page",page:p=>`Page ${p}`,of:(p,e)=>`Page ${p} of ${e}`},G={sm:{height:u.spacing[7],fontSize:y.fontSizes.sm,gap:u.spacing[1],minWidth:u.spacing[7]},md:{height:u.spacing[9],fontSize:y.fontSizes.base,gap:N.componentGap.sm,minWidth:u.spacing[9]},lg:{height:u.spacing[11],fontSize:y.fontSizes.md,gap:u.spacing[2],minWidth:u.spacing[11]}};function F(){return r.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:r.jsx("path",{d:"M10 12L6 8l4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function H(){return r.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:r.jsx("path",{d:"M6 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function J(){return r.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:r.jsx("path",{d:"M11 12l-4-4 4-4M7 12l-4-4 4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function K(){return r.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:r.jsx("path",{d:"M5 4l4 4-4 4M9 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}const C=j.forwardRef(function({page:e,totalPages:t,onChange:M,size:k="md",variant:c="default",siblingCount:d=1,showFirstLast:m=!0,showPrevNext:b=!0,disabled:o=!1,labels:S,className:L,style:z,testId:W,...$},T){const s=G[k],l={...O,...S},q=j.useMemo(()=>{if(c==="minimal"||c==="simple")return[];const n=[],a=Math.max(e-d,1),h=Math.min(e+d,t),R=a>2,x=h<t-1;if(R)if(x){n.push(1),n.push("ellipsis");for(let i=a;i<=h;i++)n.push(i);n.push("ellipsis"),n.push(t)}else{n.push(1),n.push("ellipsis");for(let i=Math.max(t-2-d,1);i<=t;i++)n.push(i)}else{for(let i=1;i<=Math.min(3+d,t);i++)n.push(i);x&&(n.push("ellipsis"),n.push(t))}return n},[e,t,d,c]),w={display:"flex",alignItems:"center",gap:s.gap,...z},f=(n,a)=>({display:"inline-flex",alignItems:"center",justifyContent:"center",minWidth:s.minWidth,height:s.height,padding:`0 ${s.gap+4}px`,fontSize:s.fontSize,fontWeight:n?600:500,color:a?"var(--brycks-foreground-disabled)":n?"var(--brycks-primary-default)":"var(--brycks-foreground-default)",backgroundColor:n?"var(--brycks-primary-muted)":"transparent",border:"none",borderRadius:"var(--brycks-radius-md)",cursor:a?"not-allowed":"pointer",transition:`all ${v.durations.quick}ms ${v.easings.easeOut}`}),E={display:"flex",alignItems:"center",justifyContent:"center",minWidth:s.minWidth,height:s.height,color:"var(--brycks-foreground-muted)",fontSize:s.fontSize},I={fontSize:s.fontSize,color:"var(--brycks-foreground-muted)",padding:`0 ${s.gap}px`},g=n=>{n>=1&&n<=t&&n!==e&&!o&&M(n)};return r.jsxs("nav",{ref:T,role:"navigation","aria-label":l.navigation,className:B.cx("brycks-pagination",`brycks-pagination--${k}`,`brycks-pagination--${c}`,L),style:w,"data-testid":W,...$,children:[m&&c!=="minimal"&&r.jsx("button",{type:"button","aria-label":l.first,disabled:e===1||o,style:f(!1,e===1||o),onClick:()=>g(1),onMouseEnter:n=>{e!==1&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:r.jsx(J,{})}),b&&r.jsx("button",{type:"button","aria-label":l.previous,disabled:e===1||o,style:f(!1,e===1||o),onClick:()=>g(e-1),onMouseEnter:n=>{e!==1&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:r.jsx(F,{})}),c==="simple"||c==="minimal"?r.jsx("span",{style:I,children:c==="minimal"?`${e} / ${t}`:l.of(e,t)}):q.map((n,a)=>n==="ellipsis"?r.jsx("span",{style:E,children:"..."},`ellipsis-${a}`):r.jsx("button",{type:"button","aria-label":l.page(n),"aria-current":n===e?"page":void 0,disabled:o,style:f(n===e,o),onClick:()=>g(n),onMouseEnter:h=>{n!==e&&!o&&(h.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:h=>{n!==e&&(h.currentTarget.style.backgroundColor="transparent")},children:n},n)),b&&r.jsx("button",{type:"button","aria-label":l.next,disabled:e===t||o,style:f(!1,e===t||o),onClick:()=>g(e+1),onMouseEnter:n=>{e!==t&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:r.jsx(H,{})}),m&&c!=="minimal"&&r.jsx("button",{type:"button","aria-label":l.last,disabled:e===t||o,style:f(!1,e===t||o),onClick:()=>g(t),onMouseEnter:n=>{e!==t&&!o&&(n.currentTarget.style.backgroundColor="var(--brycks-background-muted)")},onMouseLeave:n=>{n.currentTarget.style.backgroundColor="transparent"},children:r.jsx(K,{})})]})});C.displayName="Pagination";exports.Pagination=C;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),k=require("react"),x=require("../../../utils/styles.cjs"),w={navigation:"Pagination",first:"First page",previous:"Previous page",next:"Next page",last:"Last page",page:u=>`Page ${u}`,of:(u,t)=>`Page ${u} of ${t}`};function R(){return n.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:n.jsx("path",{d:"M10 12L6 8l4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function B(){return n.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:n.jsx("path",{d:"M6 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function I(){return n.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:n.jsx("path",{d:"M11 12l-4-4 4-4M7 12l-4-4 4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function S(){return n.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:n.jsx("path",{d:"M5 4l4 4-4 4M9 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}const m=k.forwardRef(function({page:t,totalPages:e,onChange:j,size:y="md",variant:o="default",siblingCount:c=1,showFirstLast:p=!0,showPrevNext:d=!0,disabled:l=!1,labels:_,className:g,style:v,testId:L,...M},C){const r={...w,..._},N=k.useMemo(()=>{if(o==="minimal"||o==="simple")return[];const i=[],h=Math.max(t-c,1),b=Math.min(t+c,e),$=h>2,f=b<e-1;if($)if(f){i.push(1),i.push("ellipsis");for(let s=h;s<=b;s++)i.push(s);i.push("ellipsis"),i.push(e)}else{i.push(1),i.push("ellipsis");for(let s=Math.max(e-2-c,1);s<=e;s++)i.push(s)}else{for(let s=1;s<=Math.min(3+c,e);s++)i.push(s);f&&(i.push("ellipsis"),i.push(e))}return i},[t,e,c,o]),a=i=>{i>=1&&i<=e&&i!==t&&!l&&j(i)};return n.jsxs("nav",{ref:C,role:"navigation","aria-label":r.navigation,className:x.cx("brycks-pagination",`brycks-pagination--${y}`,`brycks-pagination--${o}`,g),style:v,"data-testid":L,...M,children:[p&&o!=="minimal"&&n.jsx("button",{type:"button","aria-label":r.first,disabled:t===1||l,className:"brycks-pagination__button",onClick:()=>a(1),children:n.jsx(I,{})}),d&&n.jsx("button",{type:"button","aria-label":r.previous,disabled:t===1||l,className:"brycks-pagination__button",onClick:()=>a(t-1),children:n.jsx(R,{})}),o==="simple"||o==="minimal"?n.jsx("span",{className:"brycks-pagination__info",children:o==="minimal"?`${t} / ${e}`:r.of(t,e)}):N.map((i,h)=>i==="ellipsis"?n.jsx("span",{className:"brycks-pagination__ellipsis",children:"..."},`ellipsis-${h}`):n.jsx("button",{type:"button","aria-label":r.page(i),"aria-current":i===t?"page":void 0,disabled:l,className:x.cx("brycks-pagination__button",i===t&&"brycks-pagination__button--active"),onClick:()=>a(i),children:i},i)),d&&n.jsx("button",{type:"button","aria-label":r.next,disabled:t===e||l,className:"brycks-pagination__button",onClick:()=>a(t+1),children:n.jsx(B,{})}),p&&o!=="minimal"&&n.jsx("button",{type:"button","aria-label":r.last,disabled:t===e||l,className:"brycks-pagination__button",onClick:()=>a(e),children:n.jsx(S,{})})]})});m.displayName="Pagination";exports.Pagination=m;
2
2
  //# sourceMappingURL=Pagination.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination.cjs","sources":["../../../../src/components/navigation/Pagination/Pagination.tsx"],"sourcesContent":["/**\n * Pagination Component\n *\n * A pagination control for navigating through pages.\n * Supports different sizes and display modes.\n */\n\nimport { forwardRef, useMemo, type CSSProperties, type HTMLAttributes } from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentGap } from '../../../design-system/primitives'\n\nexport type PaginationSize = 'sm' | 'md' | 'lg'\nexport type PaginationVariant = 'default' | 'simple' | 'minimal'\n\nexport interface PaginationLabels {\n /** aria-label of the nav landmark */\n navigation?: string\n /** aria-label of the first-page button */\n first?: string\n /** aria-label of the previous-page button */\n previous?: string\n /** aria-label of the next-page button */\n next?: string\n /** aria-label of the last-page button */\n last?: string\n /** aria-label of a numbered page button */\n page?: (page: number) => string\n /** Visible text of the `simple` variant */\n of?: (page: number, totalPages: number) => string\n}\n\nconst defaultLabels: Required<PaginationLabels> = {\n navigation: 'Pagination',\n first: 'First page',\n previous: 'Previous page',\n next: 'Next page',\n last: 'Last page',\n page: (page) => `Page ${page}`,\n of: (page, totalPages) => `Page ${page} of ${totalPages}`,\n}\n\nexport interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Current page (1-indexed) */\n page: number\n /** Total number of pages */\n totalPages: number\n /** Callback when page changes */\n onChange: (page: number) => void\n /** Pagination size */\n size?: PaginationSize\n /** Pagination variant */\n variant?: PaginationVariant\n /** Number of sibling pages to show on each side */\n siblingCount?: number\n /** Whether to show first/last buttons */\n showFirstLast?: boolean\n /** Whether to show prev/next buttons */\n showPrevNext?: boolean\n /** Whether the component is disabled */\n disabled?: boolean\n /** Localizable labels (merged over English defaults) */\n labels?: PaginationLabels\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<PaginationSize, { height: number; fontSize: number; gap: number; minWidth: number }> = {\n sm: { height: spacing[7], fontSize: fontSizes.sm, gap: spacing[1], minWidth: spacing[7] },\n md: { height: spacing[9], fontSize: fontSizes.base, gap: componentGap.sm, minWidth: spacing[9] },\n lg: { height: spacing[11], fontSize: fontSizes.md, gap: spacing[2], minWidth: spacing[11] },\n}\n\nfunction ChevronLeftIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M10 12L6 8l4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronRightIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M6 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronsLeftIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M11 12l-4-4 4-4M7 12l-4-4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronsRightIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M5 4l4 4-4 4M9 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nexport const Pagination = forwardRef<HTMLElement, PaginationProps>(function Pagination(\n {\n page,\n totalPages,\n onChange,\n size = 'md',\n variant = 'default',\n siblingCount = 1,\n showFirstLast = true,\n showPrevNext = true,\n disabled = false,\n labels,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const config = sizeConfig[size]\n const text = { ...defaultLabels, ...labels }\n\n // Generate page numbers to display\n const pages = useMemo(() => {\n if (variant === 'minimal' || variant === 'simple') {\n return []\n }\n\n const range: (number | 'ellipsis')[] = []\n const leftSibling = Math.max(page - siblingCount, 1)\n const rightSibling = Math.min(page + siblingCount, totalPages)\n\n const showLeftEllipsis = leftSibling > 2\n const showRightEllipsis = rightSibling < totalPages - 1\n\n if (!showLeftEllipsis) {\n for (let i = 1; i <= Math.min(3 + siblingCount, totalPages); i++) {\n range.push(i)\n }\n if (showRightEllipsis) {\n range.push('ellipsis')\n range.push(totalPages)\n }\n } else if (!showRightEllipsis) {\n range.push(1)\n range.push('ellipsis')\n for (let i = Math.max(totalPages - 2 - siblingCount, 1); i <= totalPages; i++) {\n range.push(i)\n }\n } else {\n range.push(1)\n range.push('ellipsis')\n for (let i = leftSibling; i <= rightSibling; i++) {\n range.push(i)\n }\n range.push('ellipsis')\n range.push(totalPages)\n }\n\n return range\n }, [page, totalPages, siblingCount, variant])\n\n const containerStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: config.gap,\n ...style,\n }\n\n const getButtonStyle = (isActive: boolean, isDisabled: boolean): CSSProperties => ({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: config.minWidth,\n height: config.height,\n padding: `0 ${config.gap + 4}px`,\n fontSize: config.fontSize,\n fontWeight: isActive ? 600 : 500,\n color: isDisabled\n ? 'var(--brycks-foreground-disabled)'\n : isActive\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isActive ? 'var(--brycks-primary-muted)' : 'transparent',\n border: 'none',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n transition: `all ${durations.quick}ms ${easings.easeOut}`,\n })\n\n const ellipsisStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: config.minWidth,\n height: config.height,\n color: 'var(--brycks-foreground-muted)',\n fontSize: config.fontSize,\n }\n\n const infoStyle: CSSProperties = {\n fontSize: config.fontSize,\n color: 'var(--brycks-foreground-muted)',\n padding: `0 ${config.gap}px`,\n }\n\n const handlePageChange = (newPage: number) => {\n if (newPage >= 1 && newPage <= totalPages && newPage !== page && !disabled) {\n onChange(newPage)\n }\n }\n\n return (\n <nav\n ref={ref}\n role=\"navigation\"\n aria-label={text.navigation}\n className={cx('brycks-pagination', `brycks-pagination--${size}`, `brycks-pagination--${variant}`, className)}\n style={containerStyle}\n data-testid={testId}\n {...props}\n >\n {showFirstLast && variant !== 'minimal' && (\n <button\n type=\"button\"\n aria-label={text.first}\n disabled={page === 1 || disabled}\n style={getButtonStyle(false, page === 1 || disabled)}\n onClick={() => handlePageChange(1)}\n onMouseEnter={(e) => {\n if (page !== 1 && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronsLeftIcon />\n </button>\n )}\n\n {showPrevNext && (\n <button\n type=\"button\"\n aria-label={text.previous}\n disabled={page === 1 || disabled}\n style={getButtonStyle(false, page === 1 || disabled)}\n onClick={() => handlePageChange(page - 1)}\n onMouseEnter={(e) => {\n if (page !== 1 && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronLeftIcon />\n </button>\n )}\n\n {variant === 'simple' || variant === 'minimal' ? (\n <span style={infoStyle}>\n {variant === 'minimal' ? `${page} / ${totalPages}` : text.of(page, totalPages)}\n </span>\n ) : (\n pages.map((p, index) =>\n p === 'ellipsis' ? (\n <span key={`ellipsis-${index}`} style={ellipsisStyle}>\n ...\n </span>\n ) : (\n <button\n key={p}\n type=\"button\"\n aria-label={text.page(p)}\n aria-current={p === page ? 'page' : undefined}\n disabled={disabled}\n style={getButtonStyle(p === page, disabled)}\n onClick={() => handlePageChange(p)}\n onMouseEnter={(e) => {\n if (p !== page && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (p !== page) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n >\n {p}\n </button>\n )\n )\n )}\n\n {showPrevNext && (\n <button\n type=\"button\"\n aria-label={text.next}\n disabled={page === totalPages || disabled}\n style={getButtonStyle(false, page === totalPages || disabled)}\n onClick={() => handlePageChange(page + 1)}\n onMouseEnter={(e) => {\n if (page !== totalPages && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronRightIcon />\n </button>\n )}\n\n {showFirstLast && variant !== 'minimal' && (\n <button\n type=\"button\"\n aria-label={text.last}\n disabled={page === totalPages || disabled}\n style={getButtonStyle(false, page === totalPages || disabled)}\n onClick={() => handlePageChange(totalPages)}\n onMouseEnter={(e) => {\n if (page !== totalPages && !disabled) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <ChevronsRightIcon />\n </button>\n )}\n </nav>\n )\n})\n\nPagination.displayName = 'Pagination'\n"],"names":["defaultLabels","page","totalPages","sizeConfig","spacing","fontSizes","componentGap","ChevronLeftIcon","jsx","ChevronRightIcon","ChevronsLeftIcon","ChevronsRightIcon","Pagination","forwardRef","onChange","size","variant","siblingCount","showFirstLast","showPrevNext","disabled","labels","className","style","testId","props","ref","config","text","pages","useMemo","range","leftSibling","rightSibling","showLeftEllipsis","showRightEllipsis","containerStyle","getButtonStyle","isActive","isDisabled","durations","easings","ellipsisStyle","infoStyle","handlePageChange","newPage","jsxs","cx","e","p","index"],"mappings":"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"}
1
+ {"version":3,"file":"Pagination.cjs","sources":["../../../../src/components/navigation/Pagination/Pagination.tsx"],"sourcesContent":["/**\n * Pagination Component\n *\n * A pagination control for navigating through pages.\n * Supports different sizes and display modes.\n */\n\nimport { forwardRef, useMemo, type HTMLAttributes } from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type PaginationSize = 'sm' | 'md' | 'lg'\nexport type PaginationVariant = 'default' | 'simple' | 'minimal'\n\nexport interface PaginationLabels {\n /** aria-label of the nav landmark */\n navigation?: string\n /** aria-label of the first-page button */\n first?: string\n /** aria-label of the previous-page button */\n previous?: string\n /** aria-label of the next-page button */\n next?: string\n /** aria-label of the last-page button */\n last?: string\n /** aria-label of a numbered page button */\n page?: (page: number) => string\n /** Visible text of the `simple` variant */\n of?: (page: number, totalPages: number) => string\n}\n\nconst defaultLabels: Required<PaginationLabels> = {\n navigation: 'Pagination',\n first: 'First page',\n previous: 'Previous page',\n next: 'Next page',\n last: 'Last page',\n page: (page) => `Page ${page}`,\n of: (page, totalPages) => `Page ${page} of ${totalPages}`,\n}\n\nexport interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Current page (1-indexed) */\n page: number\n /** Total number of pages */\n totalPages: number\n /** Callback when page changes */\n onChange: (page: number) => void\n /** Pagination size */\n size?: PaginationSize\n /** Pagination variant */\n variant?: PaginationVariant\n /** Number of sibling pages to show on each side */\n siblingCount?: number\n /** Whether to show first/last buttons */\n showFirstLast?: boolean\n /** Whether to show prev/next buttons */\n showPrevNext?: boolean\n /** Whether the component is disabled */\n disabled?: boolean\n /** Localizable labels (merged over English defaults) */\n labels?: PaginationLabels\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nfunction ChevronLeftIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M10 12L6 8l4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronRightIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M6 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronsLeftIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M11 12l-4-4 4-4M7 12l-4-4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ChevronsRightIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M5 4l4 4-4 4M9 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nexport const Pagination = forwardRef<HTMLElement, PaginationProps>(function Pagination(\n {\n page,\n totalPages,\n onChange,\n size = 'md',\n variant = 'default',\n siblingCount = 1,\n showFirstLast = true,\n showPrevNext = true,\n disabled = false,\n labels,\n className,\n style,\n testId,\n ...props\n },\n ref\n) {\n const text = { ...defaultLabels, ...labels }\n\n // Generate page numbers to display\n const pages = useMemo(() => {\n if (variant === 'minimal' || variant === 'simple') {\n return []\n }\n\n const range: (number | 'ellipsis')[] = []\n const leftSibling = Math.max(page - siblingCount, 1)\n const rightSibling = Math.min(page + siblingCount, totalPages)\n\n const showLeftEllipsis = leftSibling > 2\n const showRightEllipsis = rightSibling < totalPages - 1\n\n if (!showLeftEllipsis) {\n for (let i = 1; i <= Math.min(3 + siblingCount, totalPages); i++) {\n range.push(i)\n }\n if (showRightEllipsis) {\n range.push('ellipsis')\n range.push(totalPages)\n }\n } else if (!showRightEllipsis) {\n range.push(1)\n range.push('ellipsis')\n for (let i = Math.max(totalPages - 2 - siblingCount, 1); i <= totalPages; i++) {\n range.push(i)\n }\n } else {\n range.push(1)\n range.push('ellipsis')\n for (let i = leftSibling; i <= rightSibling; i++) {\n range.push(i)\n }\n range.push('ellipsis')\n range.push(totalPages)\n }\n\n return range\n }, [page, totalPages, siblingCount, variant])\n\n const handlePageChange = (newPage: number) => {\n if (newPage >= 1 && newPage <= totalPages && newPage !== page && !disabled) {\n onChange(newPage)\n }\n }\n\n return (\n <nav\n ref={ref}\n role=\"navigation\"\n aria-label={text.navigation}\n className={cx('brycks-pagination', `brycks-pagination--${size}`, `brycks-pagination--${variant}`, className)}\n style={style}\n data-testid={testId}\n {...props}\n >\n {showFirstLast && variant !== 'minimal' && (\n <button\n type=\"button\"\n aria-label={text.first}\n disabled={page === 1 || disabled}\n className=\"brycks-pagination__button\"\n onClick={() => handlePageChange(1)}\n >\n <ChevronsLeftIcon />\n </button>\n )}\n\n {showPrevNext && (\n <button\n type=\"button\"\n aria-label={text.previous}\n disabled={page === 1 || disabled}\n className=\"brycks-pagination__button\"\n onClick={() => handlePageChange(page - 1)}\n >\n <ChevronLeftIcon />\n </button>\n )}\n\n {variant === 'simple' || variant === 'minimal' ? (\n <span className=\"brycks-pagination__info\">\n {variant === 'minimal' ? `${page} / ${totalPages}` : text.of(page, totalPages)}\n </span>\n ) : (\n pages.map((p, index) =>\n p === 'ellipsis' ? (\n <span key={`ellipsis-${index}`} className=\"brycks-pagination__ellipsis\">\n ...\n </span>\n ) : (\n <button\n key={p}\n type=\"button\"\n aria-label={text.page(p)}\n aria-current={p === page ? 'page' : undefined}\n disabled={disabled}\n className={cx('brycks-pagination__button', p === page && 'brycks-pagination__button--active')}\n onClick={() => handlePageChange(p)}\n >\n {p}\n </button>\n )\n )\n )}\n\n {showPrevNext && (\n <button\n type=\"button\"\n aria-label={text.next}\n disabled={page === totalPages || disabled}\n className=\"brycks-pagination__button\"\n onClick={() => handlePageChange(page + 1)}\n >\n <ChevronRightIcon />\n </button>\n )}\n\n {showFirstLast && variant !== 'minimal' && (\n <button\n type=\"button\"\n aria-label={text.last}\n disabled={page === totalPages || disabled}\n className=\"brycks-pagination__button\"\n onClick={() => handlePageChange(totalPages)}\n >\n <ChevronsRightIcon />\n </button>\n )}\n </nav>\n )\n})\n\nPagination.displayName = 'Pagination'\n"],"names":["defaultLabels","page","totalPages","ChevronLeftIcon","jsx","ChevronRightIcon","ChevronsLeftIcon","ChevronsRightIcon","Pagination","forwardRef","onChange","size","variant","siblingCount","showFirstLast","showPrevNext","disabled","labels","className","style","testId","props","ref","text","pages","useMemo","range","leftSibling","rightSibling","showLeftEllipsis","showRightEllipsis","i","handlePageChange","newPage","jsxs","cx","p","index"],"mappings":"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"}