beez-ui 0.10.0 → 2.0.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 (58) hide show
  1. package/CHANGELOG.md +40 -1
  2. package/README.md +63 -16
  3. package/THIRD_PARTY_NOTICES.md +31 -0
  4. package/assets/fonts/ibmplexmono-LICENSE.txt +93 -93
  5. package/assets/fonts/{poppins-LICENSE.txt → inter-LICENSE.txt} +2 -2
  6. package/assets/fonts/inter-latin-variable.woff2 +0 -0
  7. package/dist/components/account-menu.d.ts +5 -2
  8. package/dist/components/account-menu.js +150 -145
  9. package/dist/components/alert-dialog.d.ts +4 -2
  10. package/dist/components/alert-dialog.js +78 -66
  11. package/dist/components/animated-collapse.js +106 -36
  12. package/dist/components/button-interaction.d.ts +23 -0
  13. package/dist/components/button-interaction.js +22 -0
  14. package/dist/components/button-label.d.ts +8 -0
  15. package/dist/components/button-label.js +322 -0
  16. package/dist/components/button.d.ts +23 -10
  17. package/dist/components/button.js +111 -64
  18. package/dist/components/calendar.d.ts +2 -2
  19. package/dist/components/calendar.js +4 -4
  20. package/dist/components/carousel.d.ts +3 -3
  21. package/dist/components/carousel.js +3 -3
  22. package/dist/components/control-button.d.ts +16 -0
  23. package/dist/components/control-button.js +215 -0
  24. package/dist/components/data-table.js +7 -7
  25. package/dist/components/dialog.js +3 -2
  26. package/dist/components/dropdown-menu.js +1 -1
  27. package/dist/components/file-upload.js +5 -5
  28. package/dist/components/filter-presets-bar.js +6 -6
  29. package/dist/components/filter-query-bar.js +2 -2
  30. package/dist/components/input-group.d.ts +2 -2
  31. package/dist/components/input-group.js +2 -2
  32. package/dist/components/pagination.d.ts +2 -2
  33. package/dist/components/pagination.js +2 -2
  34. package/dist/components/reaction-button.js +2 -2
  35. package/dist/components/rich-link-editor.js +7 -7
  36. package/dist/components/rich-text-content.js +1 -1
  37. package/dist/components/sheet.js +2 -2
  38. package/dist/components/sidebar-panel-context.d.ts +17 -0
  39. package/dist/components/sidebar-panel-context.js +14 -0
  40. package/dist/components/sidebar.d.ts +40 -3
  41. package/dist/components/sidebar.js +259 -103
  42. package/dist/components/typing-animation.js +1 -1
  43. package/dist/constants/button.d.ts +16 -0
  44. package/dist/constants/button.js +16 -0
  45. package/dist/hooks/use-sidebar-persistence.d.ts +1 -1
  46. package/dist/hooks/use-sidebar-persistence.js +2 -2
  47. package/dist/motion/arc-press.d.ts +6 -0
  48. package/dist/motion/arc-press.js +59 -0
  49. package/dist/motion/arc-tokens.d.ts +32 -0
  50. package/dist/motion/arc-tokens.js +42 -0
  51. package/dist/providers/beez-ui-provider.d.ts +1 -1
  52. package/dist/providers/beez-ui-provider.js +6 -1
  53. package/dist/styles.css +1 -1
  54. package/fonts.css +5 -5
  55. package/package.json +3 -2
  56. package/styles.css +4 -4
  57. package/theme.css +248 -87
  58. package/assets/fonts/poppins-latin-600.woff2 +0 -0
@@ -9,18 +9,21 @@ import { c as _c } from "react/compiler-runtime";
9
9
  */
10
10
  import * as React from "react";
11
11
  import { ChevronRight, PanelLeftIcon } from "lucide-react";
12
+ import { Slot } from "radix-ui";
12
13
  import { AnimatePresence, motion } from "motion/react";
13
14
  import { createPortal } from "react-dom";
14
15
  import { useIsHydrated } from "../hooks/use-is-hydrated.js";
15
16
  import { useIsMobile } from "../hooks/use-mobile.js";
16
17
  import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
17
18
  import { saveSidebarCookie, saveSidebarPreference, useSidebarPersistence } from "../hooks/use-sidebar-persistence.js";
19
+ import { SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME } from "../constants/sidebar.js";
18
20
  import { cn } from "../lib/utils.js";
19
21
  import { MotionSlot } from "../motion/motion-slot.js";
20
22
  import { SharedLayoutBg } from "../motion/shared-layout-bg.js";
21
23
  import { MOTION_EASE, MOTION_EASE_DRAWER, MOTION_LIST_ITEM_DISTANCE, MOTION_TIMING, SPRING_LAYOUT } from "../motion/tokens.js";
22
24
  import { Link } from "./link.js";
23
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
25
+ import { SidebarPanelContext } from "./sidebar-panel-context.js";
26
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
24
27
  import { createElement as _createElement } from "react";
25
28
  const SIDEBAR_WIDTH = "16rem";
26
29
  const SIDEBAR_WIDTH_ICON = "4.25rem";
@@ -109,7 +112,6 @@ const FOCUSABLE_SELECTOR = [
109
112
  "[tabindex]:not([tabindex='-1'])"
110
113
  ].join(",");
111
114
  const SidebarContext = React.createContext(null);
112
- const SidebarPanelContext = React.createContext(null);
113
115
  /**
114
116
  * Reads the sidebar state shared by `SidebarProvider`.
115
117
  * @returns Open state for desktop and mobile, viewport and motion flags, and state setters.
@@ -121,20 +123,26 @@ function useSidebar() {
121
123
  }
122
124
  return context;
123
125
  }
126
+ /**
127
+ * Reads the state of the enclosing `Sidebar` panel, so product content can adapt to the icon rail
128
+ * without depending on its DOM attributes.
129
+ * @returns Whether the panel is collapsed to its icon rail (always false in the mobile sheet), its
130
+ * collapse mode and its side.
131
+ */
124
132
  function useSidebarPanel() {
125
133
  const context = React.use(SidebarPanelContext);
126
134
  if (!context) {
127
- throw new Error("Sidebar parts must be used within an Sidebar.");
135
+ throw new Error("useSidebarPanel must be used within a Sidebar.");
128
136
  }
129
137
  return context;
130
138
  }
131
139
  /**
132
140
  * Owns the open state of the sidebar, the ⌘B / Ctrl+B shortcut and the layout wrapper.
133
- * @param props - Controlled or default state for both viewports, persistence key and wrapper attributes.
141
+ * @param props - Controlled or default state for both viewports, persistence options and wrapper attributes.
134
142
  * @returns The wrapper that lays out the sidebar next to its inset.
135
143
  */
136
144
  function SidebarProvider(t0) {
137
- const $ = _c(53);
145
+ const $ = _c(57);
138
146
  let children;
139
147
  let className;
140
148
  let onOpenChange;
@@ -146,8 +154,10 @@ function SidebarProvider(t0) {
146
154
  let style;
147
155
  let t1;
148
156
  let t2;
157
+ let t3;
158
+ let t4;
149
159
  if ($[0] !== t0) {
150
- ({children, open: openProp, defaultOpen: t1, onOpenChange, openMobile: openMobileProp, defaultOpenMobile: t2, onOpenMobileChange, storageKey, className, style, ...props} = t0);
160
+ ({children, open: openProp, defaultOpen: t1, onOpenChange, openMobile: openMobileProp, defaultOpenMobile: t2, onOpenMobileChange, storageKey, cookieName: t3, cookieMaxAge: t4, className, style, ...props} = t0);
151
161
  $[0] = t0;
152
162
  $[1] = children;
153
163
  $[2] = className;
@@ -160,6 +170,8 @@ function SidebarProvider(t0) {
160
170
  $[9] = style;
161
171
  $[10] = t1;
162
172
  $[11] = t2;
173
+ $[12] = t3;
174
+ $[13] = t4;
163
175
  } else {
164
176
  children = $[1];
165
177
  className = $[2];
@@ -172,9 +184,13 @@ function SidebarProvider(t0) {
172
184
  style = $[9];
173
185
  t1 = $[10];
174
186
  t2 = $[11];
187
+ t3 = $[12];
188
+ t4 = $[13];
175
189
  }
176
190
  const defaultOpen = t1 === undefined ? true : t1;
177
191
  const defaultOpenMobile = t2 === undefined ? false : t2;
192
+ const cookieName = t3 === undefined ? SIDEBAR_COOKIE_NAME : t3;
193
+ const cookieMaxAge = t4 === undefined ? SIDEBAR_COOKIE_MAX_AGE : t4;
178
194
  const [internalOpen, setInternalOpen] = React.useState(null);
179
195
  const [internalOpenMobile, setInternalOpenMobile] = React.useState(defaultOpenMobile);
180
196
  const persistedOpen = useSidebarPersistence(storageKey);
@@ -186,64 +202,66 @@ function SidebarProvider(t0) {
186
202
  const openMobile = openMobileProp ?? internalOpenMobile;
187
203
  const state = open ? "expanded" : "collapsed";
188
204
  const mobileWidth = style?.["--sidebar-width-mobile"] ?? SIDEBAR_WIDTH_MOBILE;
189
- let t3;
190
- if ($[12] !== onOpenChange || $[13] !== openProp || $[14] !== storageKey) {
191
- t3 = (nextOpen) => {
205
+ let t5;
206
+ if ($[14] !== cookieMaxAge || $[15] !== cookieName || $[16] !== onOpenChange || $[17] !== openProp || $[18] !== storageKey) {
207
+ t5 = (nextOpen) => {
192
208
  if (openProp === undefined) {
193
209
  setInternalOpen(nextOpen);
194
210
  }
195
211
  onOpenChange?.(nextOpen);
196
212
  saveSidebarPreference(storageKey, nextOpen);
197
- saveSidebarCookie(nextOpen);
213
+ saveSidebarCookie(nextOpen, cookieName, cookieMaxAge);
198
214
  };
199
- $[12] = onOpenChange;
200
- $[13] = openProp;
201
- $[14] = storageKey;
202
- $[15] = t3;
215
+ $[14] = cookieMaxAge;
216
+ $[15] = cookieName;
217
+ $[16] = onOpenChange;
218
+ $[17] = openProp;
219
+ $[18] = storageKey;
220
+ $[19] = t5;
203
221
  } else {
204
- t3 = $[15];
222
+ t5 = $[19];
205
223
  }
206
- const setOpen = t3;
207
- let t4;
208
- if ($[16] !== onOpenMobileChange || $[17] !== openMobileProp) {
209
- t4 = (nextOpen_0) => {
224
+ const setOpen = t5;
225
+ let t6;
226
+ if ($[20] !== onOpenMobileChange || $[21] !== openMobileProp) {
227
+ t6 = (nextOpen_0) => {
210
228
  if (openMobileProp === undefined) {
211
229
  setInternalOpenMobile(nextOpen_0);
212
230
  }
213
231
  onOpenMobileChange?.(nextOpen_0);
214
232
  };
215
- $[16] = onOpenMobileChange;
216
- $[17] = openMobileProp;
217
- $[18] = t4;
233
+ $[20] = onOpenMobileChange;
234
+ $[21] = openMobileProp;
235
+ $[22] = t6;
218
236
  } else {
219
- t4 = $[18];
237
+ t6 = $[22];
220
238
  }
221
- const setOpenMobile = t4;
222
- let t5;
223
- if ($[19] !== isMobile || $[20] !== open || $[21] !== openMobile || $[22] !== setOpen || $[23] !== setOpenMobile) {
224
- t5 = () => {
239
+ const setOpenMobile = t6;
240
+ let t7;
241
+ if ($[23] !== isMobile || $[24] !== open || $[25] !== openMobile || $[26] !== setOpen || $[27] !== setOpenMobile) {
242
+ t7 = () => {
225
243
  if (isMobile) {
226
244
  setOpenMobile(!openMobile);
227
245
  } else {
228
246
  setOpen(!open);
229
247
  }
230
248
  };
231
- $[19] = isMobile;
232
- $[20] = open;
233
- $[21] = openMobile;
234
- $[22] = setOpen;
235
- $[23] = setOpenMobile;
236
- $[24] = t5;
249
+ $[23] = isMobile;
250
+ $[24] = open;
251
+ $[25] = openMobile;
252
+ $[26] = setOpen;
253
+ $[27] = setOpenMobile;
254
+ $[28] = t7;
237
255
  } else {
238
- t5 = $[24];
256
+ t7 = $[28];
239
257
  }
240
- const toggleSidebar = t5;
241
- let t6;
242
- let t7;
243
- if ($[25] !== toggleSidebar) {
244
- t6 = () => {
258
+ const toggleSidebar = t7;
259
+ let t8;
260
+ let t9;
261
+ if ($[29] !== toggleSidebar) {
262
+ t8 = () => {
245
263
  const handleShortcut = (event) => {
246
- if (event.key.toLowerCase() === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
264
+ if (typeof event.key === "string" && event.key.toLowerCase() === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
247
265
  event.preventDefault();
248
266
  toggleSidebar();
249
267
  }
@@ -251,21 +269,21 @@ function SidebarProvider(t0) {
251
269
  window.addEventListener("keydown", handleShortcut);
252
270
  return () => window.removeEventListener("keydown", handleShortcut);
253
271
  };
254
- t7 = [toggleSidebar];
255
- $[25] = toggleSidebar;
256
- $[26] = t6;
257
- $[27] = t7;
272
+ t9 = [toggleSidebar];
273
+ $[29] = toggleSidebar;
274
+ $[30] = t8;
275
+ $[31] = t9;
258
276
  } else {
259
- t6 = $[26];
260
- t7 = $[27];
277
+ t8 = $[30];
278
+ t9 = $[31];
261
279
  }
262
- React.useEffect(t6, t7);
263
- const t8 = `${generatedId}-active`;
264
- let t9;
265
- if ($[28] !== isMobile || $[29] !== mobileWidth || $[30] !== open || $[31] !== openMobile || $[32] !== reduce || $[33] !== setOpen || $[34] !== setOpenMobile || $[35] !== state || $[36] !== t8 || $[37] !== toggleSidebar) {
266
- t9 = {
280
+ React.useEffect(t8, t9);
281
+ const t10 = `${generatedId}-active`;
282
+ let t11;
283
+ if ($[32] !== isMobile || $[33] !== mobileWidth || $[34] !== open || $[35] !== openMobile || $[36] !== reduce || $[37] !== setOpen || $[38] !== setOpenMobile || $[39] !== state || $[40] !== t10 || $[41] !== toggleSidebar) {
284
+ t11 = {
267
285
  isMobile,
268
- layoutId: t8,
286
+ layoutId: t10,
269
287
  mobileWidth,
270
288
  open,
271
289
  openMobile,
@@ -276,75 +294,75 @@ function SidebarProvider(t0) {
276
294
  toggleSidebar,
277
295
  triggerRef
278
296
  };
279
- $[28] = isMobile;
280
- $[29] = mobileWidth;
281
- $[30] = open;
282
- $[31] = openMobile;
283
- $[32] = reduce;
284
- $[33] = setOpen;
285
- $[34] = setOpenMobile;
286
- $[35] = state;
287
- $[36] = t8;
288
- $[37] = toggleSidebar;
289
- $[38] = t9;
290
- } else {
291
- t9 = $[38];
292
- }
293
- const contextValue = t9;
294
- let t10;
295
- if ($[39] !== mobileWidth || $[40] !== style) {
296
- t10 = {
297
+ $[32] = isMobile;
298
+ $[33] = mobileWidth;
299
+ $[34] = open;
300
+ $[35] = openMobile;
301
+ $[36] = reduce;
302
+ $[37] = setOpen;
303
+ $[38] = setOpenMobile;
304
+ $[39] = state;
305
+ $[40] = t10;
306
+ $[41] = toggleSidebar;
307
+ $[42] = t11;
308
+ } else {
309
+ t11 = $[42];
310
+ }
311
+ const contextValue = t11;
312
+ let t12;
313
+ if ($[43] !== mobileWidth || $[44] !== style) {
314
+ t12 = {
297
315
  "--sidebar-width": SIDEBAR_WIDTH,
298
316
  "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
299
317
  "--sidebar-width-mobile": mobileWidth,
300
318
  ...style
301
319
  };
302
- $[39] = mobileWidth;
303
- $[40] = style;
304
- $[41] = t10;
320
+ $[43] = mobileWidth;
321
+ $[44] = style;
322
+ $[45] = t12;
305
323
  } else {
306
- t10 = $[41];
324
+ t12 = $[45];
307
325
  }
308
- let t11;
309
- if ($[42] !== className) {
310
- t11 = cn("group/sidebar-wrapper flex min-h-svh w-full min-w-0 has-data-[variant=inset]:bg-sidebar", className);
311
- $[42] = className;
312
- $[43] = t11;
326
+ let t13;
327
+ if ($[46] !== className) {
328
+ t13 = cn("group/sidebar-wrapper flex min-h-svh w-full min-w-0 has-data-[variant=inset]:bg-sidebar", className);
329
+ $[46] = className;
330
+ $[47] = t13;
313
331
  } else {
314
- t11 = $[43];
332
+ t13 = $[47];
315
333
  }
316
- let t12;
317
- if ($[44] !== children || $[45] !== props || $[46] !== state || $[47] !== t10 || $[48] !== t11) {
318
- t12 = /* @__PURE__ */ _jsx("div", {
334
+ let t14;
335
+ if ($[48] !== children || $[49] !== props || $[50] !== state || $[51] !== t12 || $[52] !== t13) {
336
+ t14 = /* @__PURE__ */ _jsx("div", {
319
337
  ...props,
320
338
  "data-slot": "sidebar-wrapper",
321
339
  "data-state": state,
322
- style: t10,
323
- className: t11,
340
+ style: t12,
341
+ className: t13,
324
342
  children
325
343
  });
326
- $[44] = children;
327
- $[45] = props;
328
- $[46] = state;
329
- $[47] = t10;
330
- $[48] = t11;
331
- $[49] = t12;
344
+ $[48] = children;
345
+ $[49] = props;
346
+ $[50] = state;
347
+ $[51] = t12;
348
+ $[52] = t13;
349
+ $[53] = t14;
332
350
  } else {
333
- t12 = $[49];
351
+ t14 = $[53];
334
352
  }
335
- let t13;
336
- if ($[50] !== contextValue || $[51] !== t12) {
337
- t13 = /* @__PURE__ */ _jsx(SidebarContext.Provider, {
353
+ let t15;
354
+ if ($[54] !== contextValue || $[55] !== t14) {
355
+ t15 = /* @__PURE__ */ _jsx(SidebarContext.Provider, {
338
356
  value: contextValue,
339
- children: t12
357
+ children: t14
340
358
  });
341
- $[50] = contextValue;
342
- $[51] = t12;
343
- $[52] = t13;
359
+ $[54] = contextValue;
360
+ $[55] = t14;
361
+ $[56] = t15;
344
362
  } else {
345
- t13 = $[52];
363
+ t15 = $[56];
346
364
  }
347
- return t13;
365
+ return t15;
348
366
  }
349
367
  /** Small-screen sheet: locks page scroll, traps focus and hands it back to the trigger on close. */
350
368
  function MobileSidebar(t0) {
@@ -1172,6 +1190,144 @@ function SidebarFooter(t0) {
1172
1190
  }
1173
1191
  return t2;
1174
1192
  }
1193
+ /**
1194
+ * Product text that only makes sense in the expanded sidebar, such as a workspace name or an empty
1195
+ * state: it leaves the layout while the panel is the icon rail and always shows in the mobile sheet.
1196
+ * @param props - Span attributes, or `asChild` to keep the child element.
1197
+ * @returns The content, or nothing in the icon rail.
1198
+ */
1199
+ function SidebarLabel(t0) {
1200
+ const $ = _c(6);
1201
+ let props;
1202
+ let t1;
1203
+ if ($[0] !== t0) {
1204
+ ({asChild: t1, ...props} = t0);
1205
+ $[0] = t0;
1206
+ $[1] = props;
1207
+ $[2] = t1;
1208
+ } else {
1209
+ props = $[1];
1210
+ t1 = $[2];
1211
+ }
1212
+ const asChild = t1 === undefined ? false : t1;
1213
+ const { collapsed } = useSidebarPanel();
1214
+ if (collapsed) {
1215
+ return null;
1216
+ }
1217
+ const Component = asChild ? Slot.Root : "span";
1218
+ let t2;
1219
+ if ($[3] !== Component || $[4] !== props) {
1220
+ t2 = /* @__PURE__ */ _jsx(Component, {
1221
+ "data-slot": "sidebar-label",
1222
+ ...props
1223
+ });
1224
+ $[3] = Component;
1225
+ $[4] = props;
1226
+ $[5] = t2;
1227
+ } else {
1228
+ t2 = $[5];
1229
+ }
1230
+ return t2;
1231
+ }
1232
+ /**
1233
+ * Header row that identifies the workspace, often the trigger of a workspace switcher. It forwards
1234
+ * its props and ref to the `button`, so it works as `DropdownMenuTrigger asChild`, and keeps its tile
1235
+ * on the menu icon column while the label and trailing content leave in the icon rail.
1236
+ * @param props - Tile, label, trailing content and native button attributes.
1237
+ * @returns The brand button.
1238
+ */
1239
+ function SidebarBrandButton(t0) {
1240
+ const $ = _c(23);
1241
+ let children;
1242
+ let className;
1243
+ let icon;
1244
+ let props;
1245
+ let t1;
1246
+ let trailing;
1247
+ if ($[0] !== t0) {
1248
+ ({icon, trailing, children, className, type: t1, ...props} = t0);
1249
+ $[0] = t0;
1250
+ $[1] = children;
1251
+ $[2] = className;
1252
+ $[3] = icon;
1253
+ $[4] = props;
1254
+ $[5] = t1;
1255
+ $[6] = trailing;
1256
+ } else {
1257
+ children = $[1];
1258
+ className = $[2];
1259
+ icon = $[3];
1260
+ props = $[4];
1261
+ t1 = $[5];
1262
+ trailing = $[6];
1263
+ }
1264
+ const type = t1 === undefined ? "button" : t1;
1265
+ const { collapsed } = useSidebarPanel();
1266
+ const textLabel = typeof children === "string" ? children : undefined;
1267
+ const t2 = collapsed ? textLabel : undefined;
1268
+ const t3 = collapsed ? textLabel : undefined;
1269
+ let t4;
1270
+ if ($[7] !== className) {
1271
+ t4 = cn("flex min-h-10 w-full min-w-0 items-center gap-3 rounded-xl px-2 py-1.5 text-left text-sm font-medium text-sidebar-foreground outline-none transition-colors", "hover:bg-sidebar-accent/70 focus-visible:bg-sidebar-accent/70 focus-visible:ring-2 focus-visible:ring-sidebar-ring data-[state=open]:bg-sidebar-accent/70", "disabled:cursor-not-allowed disabled:opacity-40", className);
1272
+ $[7] = className;
1273
+ $[8] = t4;
1274
+ } else {
1275
+ t4 = $[8];
1276
+ }
1277
+ let t5;
1278
+ if ($[9] !== icon) {
1279
+ t5 = /* @__PURE__ */ _jsx("span", {
1280
+ "aria-hidden": "true",
1281
+ "data-slot": "sidebar-brand-icon",
1282
+ className: "grid size-7 shrink-0 place-items-center overflow-hidden rounded-lg [&>img]:size-full [&>img]:object-cover",
1283
+ children: icon
1284
+ });
1285
+ $[9] = icon;
1286
+ $[10] = t5;
1287
+ } else {
1288
+ t5 = $[10];
1289
+ }
1290
+ let t6;
1291
+ if ($[11] !== children || $[12] !== collapsed || $[13] !== trailing) {
1292
+ t6 = collapsed ? null : /* @__PURE__ */ _jsxs(_Fragment, { children: [/* @__PURE__ */ _jsx("span", {
1293
+ className: "min-w-0 flex-1 truncate",
1294
+ children
1295
+ }), trailing ? /* @__PURE__ */ _jsx("span", {
1296
+ "aria-hidden": "true",
1297
+ className: "grid size-4 shrink-0 place-items-center text-sidebar-foreground/70 [&_svg]:size-3.5",
1298
+ children: trailing
1299
+ }) : null] });
1300
+ $[11] = children;
1301
+ $[12] = collapsed;
1302
+ $[13] = trailing;
1303
+ $[14] = t6;
1304
+ } else {
1305
+ t6 = $[14];
1306
+ }
1307
+ let t7;
1308
+ if ($[15] !== props || $[16] !== t2 || $[17] !== t3 || $[18] !== t4 || $[19] !== t5 || $[20] !== t6 || $[21] !== type) {
1309
+ t7 = /* @__PURE__ */ _jsxs("button", {
1310
+ "aria-label": t2,
1311
+ title: t3,
1312
+ ...props,
1313
+ type,
1314
+ "data-slot": "sidebar-brand-button",
1315
+ className: t4,
1316
+ children: [t5, t6]
1317
+ });
1318
+ $[15] = props;
1319
+ $[16] = t2;
1320
+ $[17] = t3;
1321
+ $[18] = t4;
1322
+ $[19] = t5;
1323
+ $[20] = t6;
1324
+ $[21] = type;
1325
+ $[22] = t7;
1326
+ } else {
1327
+ t7 = $[22];
1328
+ }
1329
+ return t7;
1330
+ }
1175
1331
  function SidebarGroup(t0) {
1176
1332
  const $ = _c(8);
1177
1333
  let className;
@@ -1226,7 +1382,7 @@ function SidebarGroupLabel(t0) {
1226
1382
  const t1 = collapsed ? "opacity-0" : "opacity-100";
1227
1383
  let t2;
1228
1384
  if ($[3] !== className || $[4] !== t1) {
1229
- t2 = cn("mb-1 h-7 overflow-hidden px-2 text-[10px] font-medium tracking-[0.14em] text-sidebar-foreground/70 uppercase transition-opacity", t1, className);
1385
+ t2 = cn("mb-1 h-7 overflow-hidden px-2 text-xs font-medium text-sidebar-foreground/70 transition-opacity", t1, className);
1230
1386
  $[3] = className;
1231
1387
  $[4] = t1;
1232
1388
  $[5] = t2;
@@ -1839,4 +1995,4 @@ function SidebarMenuButton(t0) {
1839
1995
  }
1840
1996
  return t19;
1841
1997
  }
1842
- export { Sidebar, SidebarClose, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarTrigger, useSidebar };
1998
+ export { Sidebar, SidebarBrandButton, SidebarClose, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarTrigger, useSidebar, useSidebarPanel };
@@ -332,7 +332,7 @@ export function TypingAnimation(t0) {
332
332
  t20 = $[52];
333
333
  }
334
334
  const getCursorChar = t20;
335
- const t21 = Component === "h1" && "text-3xl font-bold leading-tight md:text-4xl";
335
+ const t21 = Component === "h1" && "text-3xl font-medium leading-tight md:text-4xl";
336
336
  const t22 = Component === "span" && "inline-block";
337
337
  let t23;
338
338
  if ($[53] !== className || $[54] !== t21 || $[55] !== t22) {
@@ -0,0 +1,16 @@
1
+ /** Tuning shared by Button's Arc press feedback and label width morph. */
2
+ /** Buttons wider than this press a little less so large surfaces don't feel spongy. */
3
+ export declare const BUTTON_WIDE_THRESHOLD_PX = 220;
4
+ /** Buttons up to this width are icon-sized and press a little deeper. */
5
+ export declare const BUTTON_ICON_THRESHOLD_PX = 48;
6
+ /** Press scale for wide buttons. */
7
+ export declare const BUTTON_WIDE_PRESS_SCALE = 0.985;
8
+ /** Press scale for icon-sized buttons. */
9
+ export declare const BUTTON_ICON_PRESS_SCALE = 0.96;
10
+ /** Press scale for every other button. */
11
+ export declare const BUTTON_DEFAULT_PRESS_SCALE = 0.97;
12
+ /**
13
+ * After the label changes, resizes inside this window spring to the new width; later resizes
14
+ * (late web fonts, parent reflows) jump so nothing wobbles on first paint.
15
+ */
16
+ export declare const BUTTON_MORPH_WINDOW_MS = 700;
@@ -0,0 +1,16 @@
1
+ /** Tuning shared by Button's Arc press feedback and label width morph. */
2
+ /** Buttons wider than this press a little less so large surfaces don't feel spongy. */
3
+ export const BUTTON_WIDE_THRESHOLD_PX = 220;
4
+ /** Buttons up to this width are icon-sized and press a little deeper. */
5
+ export const BUTTON_ICON_THRESHOLD_PX = 48;
6
+ /** Press scale for wide buttons. */
7
+ export const BUTTON_WIDE_PRESS_SCALE = .985;
8
+ /** Press scale for icon-sized buttons. */
9
+ export const BUTTON_ICON_PRESS_SCALE = .96;
10
+ /** Press scale for every other button. */
11
+ export const BUTTON_DEFAULT_PRESS_SCALE = .97;
12
+ /**
13
+ * After the label changes, resizes inside this window spring to the new width; later resizes
14
+ * (late web fonts, parent reflows) jump so nothing wobbles on first paint.
15
+ */
16
+ export const BUTTON_MORPH_WINDOW_MS = 700;
@@ -3,4 +3,4 @@ export declare function useSidebarPersistence(storageKey?: string): boolean | nu
3
3
  /** Stores an optional preference while retaining usable navigation in private mode. */
4
4
  export declare function saveSidebarPreference(storageKey: string | undefined, open: boolean): void;
5
5
  /** Writes the cookie that server entrypoints read to render the sidebar in its last state. */
6
- export declare function saveSidebarCookie(open: boolean): void;
6
+ export declare function saveSidebarCookie(open: boolean, cookieName?: string, maxAgeSeconds?: number): void;
@@ -44,9 +44,9 @@ export function saveSidebarPreference(storageKey, open) {
44
44
  } catch {}
45
45
  }
46
46
  /** Writes the cookie that server entrypoints read to render the sidebar in its last state. */
47
- export function saveSidebarCookie(open) {
47
+ export function saveSidebarCookie(open, cookieName = SIDEBAR_COOKIE_NAME, maxAgeSeconds = SIDEBAR_COOKIE_MAX_AGE) {
48
48
  const value = open ? SIDEBAR_COOKIE_OPEN_VALUE : SIDEBAR_COOKIE_COLLAPSED_VALUE;
49
49
  try {
50
- document.cookie = `${SIDEBAR_COOKIE_NAME}=${value}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}; SameSite=Lax`;
50
+ document.cookie = `${cookieName}=${value}; path=/; max-age=${maxAgeSeconds}; SameSite=Lax`;
51
51
  } catch {}
52
52
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Scales the element down while pressed and springs it back on release.
3
+ * @param element - Rendered button, link or Slot child; nothing happens until it is attached.
4
+ * @param isEnabled - False skips the feedback, for reduced motion or variants that should not press.
5
+ */
6
+ export declare function useArcPress(element: HTMLElement | null, isEnabled: boolean): void;
@@ -0,0 +1,59 @@
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ /**
4
+ * Press feedback adapted from Arc (https://uiarc.dev), Copyright (c) 2026 Elia Kuratli, MIT License.
5
+ * The full license text ships in THIRD_PARTY_NOTICES.md. Works on whatever node a Slot or Base UI
6
+ * renders, so `asChild` links press exactly like native buttons.
7
+ */
8
+ import { useEffect } from "react";
9
+ import { animate, press } from "motion/react";
10
+ import { BUTTON_DEFAULT_PRESS_SCALE, BUTTON_ICON_PRESS_SCALE, BUTTON_ICON_THRESHOLD_PX, BUTTON_WIDE_PRESS_SCALE, BUTTON_WIDE_THRESHOLD_PX } from "../constants/button.js";
11
+ import { ARC_DURATION, ARC_EASE, ARC_SPRING_SNAPPY } from "./arc-tokens.js";
12
+ /** Matches triggers of menus, popovers and dialogs, which never scale: Radix measures them on pointerdown. */
13
+ const LAYER_ANCHOR_SELECTOR = "[aria-haspopup]:not([aria-haspopup=\"false\"]), [data-state], [role=\"combobox\"]";
14
+ /** Matches elements that ignore presses: disabled, busy or marked unavailable. */
15
+ const INERT_SELECTOR = ":disabled, [data-disabled], [aria-disabled=\"true\"], [aria-busy=\"true\"]";
16
+ /** Icon buttons press a little deeper and wide buttons a little less, so every size reads as the same push. */
17
+ function getPressScale(width) {
18
+ if (width > BUTTON_WIDE_THRESHOLD_PX) return BUTTON_WIDE_PRESS_SCALE;
19
+ if (width && width <= BUTTON_ICON_THRESHOLD_PX) return BUTTON_ICON_PRESS_SCALE;
20
+ return BUTTON_DEFAULT_PRESS_SCALE;
21
+ }
22
+ /**
23
+ * Scales the element down while pressed and springs it back on release.
24
+ * @param element - Rendered button, link or Slot child; nothing happens until it is attached.
25
+ * @param isEnabled - False skips the feedback, for reduced motion or variants that should not press.
26
+ */
27
+ export function useArcPress(element, isEnabled) {
28
+ const $ = _c(4);
29
+ let t0;
30
+ let t1;
31
+ if ($[0] !== element || $[1] !== isEnabled) {
32
+ t0 = () => {
33
+ if (!element || !isEnabled) {
34
+ return;
35
+ }
36
+ return press(element, () => {
37
+ if (element.matches(INERT_SELECTOR) || element.matches(LAYER_ANCHOR_SELECTOR)) {
38
+ return;
39
+ }
40
+ animate(element, { scale: getPressScale(element.offsetWidth) }, {
41
+ duration: ARC_DURATION.instant,
42
+ ease: [...ARC_EASE.standard]
43
+ });
44
+ return () => {
45
+ animate(element, { scale: 1 }, ARC_SPRING_SNAPPY);
46
+ };
47
+ });
48
+ };
49
+ t1 = [element, isEnabled];
50
+ $[0] = element;
51
+ $[1] = isEnabled;
52
+ $[2] = t0;
53
+ $[3] = t1;
54
+ } else {
55
+ t0 = $[2];
56
+ t1 = $[3];
57
+ }
58
+ useEffect(t0, t1);
59
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Motion presets adapted from Arc (https://uiarc.dev), Copyright (c) 2026 Elia Kuratli, MIT License.
3
+ * The full license text ships in THIRD_PARTY_NOTICES.md. Internal: only Arc-derived components use these.
4
+ */
5
+ /** Durations in seconds, from an instant color answer to a considered layout change. */
6
+ export declare const ARC_DURATION: {
7
+ readonly instant: 0.12;
8
+ readonly fast: 0.16;
9
+ readonly standard: 0.24;
10
+ };
11
+ /** Cubic-bezier curves for entrances and color or opacity tweens. */
12
+ export declare const ARC_EASE: {
13
+ readonly enter: readonly [0.16, 1, 0.3, 1];
14
+ readonly standard: readonly [0.22, 1, 0.36, 1];
15
+ };
16
+ /** Presses, toggles and small indicators: settles fast with a hint of life. */
17
+ export declare const ARC_SPRING_SNAPPY: {
18
+ readonly type: "spring";
19
+ readonly visualDuration: 0.26;
20
+ readonly bounce: 0.12;
21
+ };
22
+ /** Shape morphs and width changes that follow new content. */
23
+ export declare const ARC_SPRING_MORPH: {
24
+ readonly type: "spring";
25
+ readonly visualDuration: 0.42;
26
+ readonly bounce: 0.16;
27
+ };
28
+ /** Blur radii in pixels for brief content crossfades. */
29
+ export declare const ARC_BLUR: {
30
+ readonly subtle: 2;
31
+ readonly soft: 4;
32
+ };