@devalok/shilp-sutra 0.49.0 → 0.49.2

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 (162) hide show
  1. package/dist/_chunks/badge-group.js +41 -41
  2. package/dist/_chunks/badge-group.js.map +1 -1
  3. package/dist/_chunks/block-shell.js +1 -1
  4. package/dist/_chunks/chart-container.js +1 -1
  5. package/dist/_chunks/chat.js +6 -15
  6. package/dist/_chunks/chat.js.map +1 -1
  7. package/dist/_chunks/colors.js +2 -2
  8. package/dist/_chunks/document-preview.js +4 -4
  9. package/dist/_chunks/emoji-suggestion.js +5 -5
  10. package/dist/_chunks/emoji-suggestion.js.map +1 -1
  11. package/dist/_chunks/emoji.js +1 -1
  12. package/dist/_chunks/field-state.js +1 -1
  13. package/dist/_chunks/grid-lines.js +1 -1
  14. package/dist/_chunks/image-preview.js +7 -7
  15. package/dist/_chunks/keybinding.js +1 -1
  16. package/dist/_chunks/link-context.js +1 -1
  17. package/dist/_chunks/mention-suggestion.js +2 -2
  18. package/dist/_chunks/mention.js +1 -1
  19. package/dist/_chunks/motion-provider.js +1 -1
  20. package/dist/_chunks/normalize-icon.js +1 -1
  21. package/dist/_chunks/oauth-button.js +2 -2
  22. package/dist/_chunks/popover.js +17 -17
  23. package/dist/_chunks/primitives.js +1 -1
  24. package/dist/_chunks/shared.js +5 -5
  25. package/dist/_chunks/success.js +5 -8
  26. package/dist/_chunks/success.js.map +1 -1
  27. package/dist/_chunks/tiptap.js +11 -11
  28. package/dist/_chunks/tooltip.js +1 -1
  29. package/dist/_chunks/tree-view.js +2 -2
  30. package/dist/_chunks/use-calendar.js +1 -1
  31. package/dist/_chunks/use-controllable-open.js +1 -1
  32. package/dist/_chunks/vendor-client.js +1 -1
  33. package/dist/_chunks/vendor-utils.js +1 -1
  34. package/dist/ai/block-renderer.js +8 -11
  35. package/dist/ai/block-renderer.js.map +1 -1
  36. package/dist/ai/blocks/error.js +1 -1
  37. package/dist/ai/blocks/index.js +2 -2
  38. package/dist/ai/blocks/text.js +1 -1
  39. package/dist/ai/command-bar.d.ts.map +1 -1
  40. package/dist/ai/command-bar.js +8 -39
  41. package/dist/ai/command-bar.js.map +1 -1
  42. package/dist/ai/conversation.js +4 -10
  43. package/dist/ai/conversation.js.map +1 -1
  44. package/dist/ai/devadoot-icon.d.ts.map +1 -1
  45. package/dist/ai/index.js +10 -41
  46. package/dist/ai/index.js.map +1 -1
  47. package/dist/composed/activity-feed.js +3 -3
  48. package/dist/composed/activity-feed.js.map +1 -1
  49. package/dist/composed/avatar-group.js +3 -3
  50. package/dist/composed/avatar-group.js.map +1 -1
  51. package/dist/composed/bulk-action-bar.js +1 -1
  52. package/dist/composed/command-palette.js +6 -6
  53. package/dist/composed/content-card.js +1 -1
  54. package/dist/composed/date-picker/index.js +10 -10
  55. package/dist/composed/emoji-picker.js +4 -4
  56. package/dist/composed/empty-state.d.ts.map +1 -1
  57. package/dist/composed/empty-state.js +23 -33
  58. package/dist/composed/empty-state.js.map +1 -1
  59. package/dist/composed/extensions/emoji-node.js +1 -1
  60. package/dist/composed/extensions/emoji-suggestion.js +1 -1
  61. package/dist/composed/file-preview.js +14 -14
  62. package/dist/composed/filter-bar.js +1 -1
  63. package/dist/composed/multi-select-popover.js +3 -3
  64. package/dist/composed/priority-indicator.js +1 -1
  65. package/dist/composed/responsive-modal.js +21 -21
  66. package/dist/composed/rich-chat-input.js +445 -445
  67. package/dist/composed/rich-chat-input.js.map +1 -1
  68. package/dist/composed/rich-text-editor.js +28 -28
  69. package/dist/composed/schedule-view.js +1 -1
  70. package/dist/composed/schedule-view.js.map +1 -1
  71. package/dist/composed/status-badge.js +1 -1
  72. package/dist/motion/index.js +2 -2
  73. package/dist/shell/bottom-navbar.js +3 -3
  74. package/dist/shell/bottom-navbar.js.map +1 -1
  75. package/dist/shell/index.js +2 -2
  76. package/dist/shell/link-context.js +2 -2
  77. package/dist/shell/notification-center.js +3 -3
  78. package/dist/shell/sidebar.js +2 -2
  79. package/dist/shell/top-bar.js +1 -1
  80. package/dist/ui/accordion.js +14 -14
  81. package/dist/ui/alert-dialog.js +31 -31
  82. package/dist/ui/alert.js +1 -1
  83. package/dist/ui/aspect-ratio.js +1 -1
  84. package/dist/ui/autocomplete.js +7 -7
  85. package/dist/ui/avatar.d.ts.map +1 -1
  86. package/dist/ui/avatar.js +52 -67
  87. package/dist/ui/avatar.js.map +1 -1
  88. package/dist/ui/badge-group.js +1 -1
  89. package/dist/ui/badge.d.ts +2 -0
  90. package/dist/ui/badge.d.ts.map +1 -1
  91. package/dist/ui/badge.js +1 -1
  92. package/dist/ui/banner.js +1 -1
  93. package/dist/ui/breadcrumb.js +1 -1
  94. package/dist/ui/button.js +9 -9
  95. package/dist/ui/button.js.map +1 -1
  96. package/dist/ui/card.js +1 -1
  97. package/dist/ui/charts/area-chart.js +6 -6
  98. package/dist/ui/charts/bar-chart.js +6 -6
  99. package/dist/ui/charts/chart-container.js +1 -1
  100. package/dist/ui/charts/gauge-chart.js +2 -2
  101. package/dist/ui/charts/index.js +2 -2
  102. package/dist/ui/charts/line-chart.js +6 -6
  103. package/dist/ui/charts/pie-chart.js +5 -5
  104. package/dist/ui/charts/radar-chart.js +5 -5
  105. package/dist/ui/charts/sparkline.js +2 -2
  106. package/dist/ui/chat/index.js +2 -2
  107. package/dist/ui/checkbox.js +5 -5
  108. package/dist/ui/collapsible.js +4 -4
  109. package/dist/ui/color-input.js +4 -4
  110. package/dist/ui/combobox.js +8 -8
  111. package/dist/ui/combobox.js.map +1 -1
  112. package/dist/ui/context-menu.js +41 -41
  113. package/dist/ui/dialog.js +25 -25
  114. package/dist/ui/dot.d.ts.map +1 -1
  115. package/dist/ui/dot.js +24 -32
  116. package/dist/ui/dot.js.map +1 -1
  117. package/dist/ui/dropdown-menu.js +51 -51
  118. package/dist/ui/hover-card.js +9 -9
  119. package/dist/ui/icon-button.js +1 -1
  120. package/dist/ui/index.js +6 -6
  121. package/dist/ui/input.js +2 -2
  122. package/dist/ui/label.js +1 -1
  123. package/dist/ui/lib/utils.js +4 -4
  124. package/dist/ui/link.js +1 -1
  125. package/dist/ui/menubar.js +53 -53
  126. package/dist/ui/navigation-menu.js +27 -27
  127. package/dist/ui/number-input.js +2 -2
  128. package/dist/ui/oauth-button/index.js +2 -2
  129. package/dist/ui/pagination.js +1 -1
  130. package/dist/ui/popover.js +2 -2
  131. package/dist/ui/progress.js +2 -2
  132. package/dist/ui/radio.js +2 -2
  133. package/dist/ui/segmented-control.js +1 -1
  134. package/dist/ui/select.js +35 -35
  135. package/dist/ui/separator.js +1 -1
  136. package/dist/ui/sheet.js +22 -22
  137. package/dist/ui/sidebar.js +2 -2
  138. package/dist/ui/skeleton.js +1 -1
  139. package/dist/ui/slider.js +8 -8
  140. package/dist/ui/slider.js.map +1 -1
  141. package/dist/ui/split-button.js +3 -3
  142. package/dist/ui/stat-card.d.ts +2 -0
  143. package/dist/ui/stat-card.d.ts.map +1 -1
  144. package/dist/ui/stat-card.js +94 -126
  145. package/dist/ui/stat-card.js.map +1 -1
  146. package/dist/ui/stat-flash.js +1 -1
  147. package/dist/ui/stepper.js +1 -1
  148. package/dist/ui/surface.js +2 -2
  149. package/dist/ui/switch.js +2 -2
  150. package/dist/ui/table-row-link.js +1 -1
  151. package/dist/ui/tabs.js +13 -13
  152. package/dist/ui/text.js +1 -1
  153. package/dist/ui/textarea.js +2 -2
  154. package/dist/ui/toggle-group.js +1 -1
  155. package/dist/ui/toggle.js +2 -2
  156. package/dist/ui/tooltip.js +16 -16
  157. package/dist/ui/tree-view/index.js +2 -2
  158. package/llms.txt +1 -1
  159. package/mcp-manifest.json +1 -1
  160. package/package.json +1 -1
  161. package/skill/SKILL.md +1 -1
  162. package/skill/references/components.md +1 -1
@@ -2,11 +2,11 @@
2
2
  import { cn as e } from "../ui/lib/utils.js";
3
3
  import { Icon as t } from "../ui/icon.js";
4
4
  import { Button as n } from "../ui/button.js";
5
- import { t as r } from "../_chunks/mention.js";
6
- import { a as i, c as a, d as o, f as s, h as c, l, m as u, n as d, r as f, t as p } from "../_chunks/tiptap.js";
5
+ import { MENTION_TOKEN_CLASS as r } from "../_chunks/mention.js";
6
+ import { EditorContent as i, ListKit as a, Placeholder as o, index_default as s, index_default$1 as c, index_default$2 as l, index_default$4 as u, index_default$5 as d, useEditor as f, useEditorState as p } from "../_chunks/tiptap.js";
7
7
  import { EmojiNode as m } from "./extensions/emoji-node.js";
8
- import { t as h } from "../_chunks/emoji-suggestion.js";
9
- import { n as g, t as _ } from "../_chunks/mention-suggestion.js";
8
+ import { createEmojiSuggestion as h } from "../_chunks/emoji-suggestion.js";
9
+ import { FileAttachment as g, createSuggestionRenderer as _ } from "../_chunks/mention-suggestion.js";
10
10
  import * as v from "react";
11
11
  import { jsx as y, jsxs as b } from "react/jsx-runtime";
12
12
  import { IconAlignCenter as x, IconAlignLeft as S, IconAlignRight as C, IconArrowBackUp as w, IconArrowForwardUp as T, IconBlockquote as E, IconBold as D, IconCode as O, IconH2 as k, IconH3 as A, IconHighlight as j, IconItalic as M, IconLineDashed as N, IconLink as P, IconList as F, IconListCheck as I, IconListNumbers as L, IconMoodSmile as R, IconPaperclip as z, IconPhoto as B, IconStrikethrough as V, IconUnderline as H } from "@tabler/icons-react";
@@ -43,7 +43,7 @@ function W({ onClick: t, isActive: n = !1, disabled: r = !1, title: i, children:
43
43
  });
44
44
  }
45
45
  function G({ editor: e }) {
46
- let [r, i] = v.useState(!1), [a, o] = v.useState(""), s = v.useRef(null), { isLink: c } = l({
46
+ let [r, i] = v.useState(!1), [a, o] = v.useState(""), s = v.useRef(null), { isLink: c } = p({
47
47
  editor: e,
48
48
  selector: ({ editor: e }) => ({ isLink: e.isActive("link") })
49
49
  });
@@ -92,7 +92,7 @@ function K() {
92
92
  return /* @__PURE__ */ y("div", { className: "mx-ds-02 h-ds-05 w-px bg-surface-border" });
93
93
  }
94
94
  function q({ editor: e, toolbar: n, onImageClick: r, onFileClick: i, onEmojiClick: a }) {
95
- let o = l({
95
+ let o = p({
96
96
  editor: e,
97
97
  selector: ({ editor: e }) => ({
98
98
  isBold: e.isActive("bold"),
@@ -114,7 +114,7 @@ function q({ editor: e, toolbar: n, onImageClick: r, onFileClick: i, onEmojiClic
114
114
  canUndo: e.can().undo(),
115
115
  canRedo: e.can().redo()
116
116
  })
117
- }), s = (e) => !n || n.includes(e), c = s("bold") || s("italic") || s("underline") || s("strike") || s("highlight"), u = s("h2") || s("h3") || s("blockquote"), d = s("bulletList") || s("orderedList") || s("taskList") || s("codeBlock"), f = s("link") || !!r && s("image") || !!i && s("file") || s("hr"), p = s("alignLeft") || s("alignCenter") || s("alignRight"), m = !!a && s("emoji"), h = s("undo") || s("redo");
117
+ }), s = (e) => !n || n.includes(e), c = s("bold") || s("italic") || s("underline") || s("strike") || s("highlight"), l = s("h2") || s("h3") || s("blockquote"), u = s("bulletList") || s("orderedList") || s("taskList") || s("codeBlock"), d = s("link") || !!r && s("image") || !!i && s("file") || s("hr"), f = s("alignLeft") || s("alignCenter") || s("alignRight"), m = !!a && s("emoji"), h = s("undo") || s("redo");
118
118
  return /* @__PURE__ */ b("div", {
119
119
  role: "toolbar",
120
120
  "aria-label": "Text formatting",
@@ -170,7 +170,7 @@ function q({ editor: e, toolbar: n, onImageClick: r, onFileClick: i, onEmojiClic
170
170
  stroke: "bold"
171
171
  })
172
172
  }),
173
- c && u && /* @__PURE__ */ y(K, {}),
173
+ c && l && /* @__PURE__ */ y(K, {}),
174
174
  s("h2") && /* @__PURE__ */ y(W, {
175
175
  onClick: () => e.chain().focus().toggleHeading({ level: 2 }).run(),
176
176
  isActive: o.isH2,
@@ -201,7 +201,7 @@ function q({ editor: e, toolbar: n, onImageClick: r, onFileClick: i, onEmojiClic
201
201
  stroke: "bold"
202
202
  })
203
203
  }),
204
- u && d && /* @__PURE__ */ y(K, {}),
204
+ l && u && /* @__PURE__ */ y(K, {}),
205
205
  s("bulletList") && /* @__PURE__ */ y(W, {
206
206
  onClick: () => e.chain().focus().toggleBulletList().run(),
207
207
  isActive: o.isBulletList,
@@ -242,7 +242,7 @@ function q({ editor: e, toolbar: n, onImageClick: r, onFileClick: i, onEmojiClic
242
242
  stroke: "bold"
243
243
  })
244
244
  }),
245
- d && f && /* @__PURE__ */ y(K, {}),
245
+ u && d && /* @__PURE__ */ y(K, {}),
246
246
  s("link") && /* @__PURE__ */ y(G, { editor: e }),
247
247
  r && s("image") && /* @__PURE__ */ y(W, {
248
248
  onClick: r,
@@ -268,7 +268,7 @@ function q({ editor: e, toolbar: n, onImageClick: r, onFileClick: i, onEmojiClic
268
268
  size: "sm"
269
269
  })
270
270
  }),
271
- f && p && /* @__PURE__ */ y(K, {}),
271
+ d && f && /* @__PURE__ */ y(K, {}),
272
272
  s("alignLeft") && /* @__PURE__ */ y(W, {
273
273
  onClick: () => e.chain().focus().setTextAlign("left").run(),
274
274
  isActive: o.isAlignLeft,
@@ -296,7 +296,7 @@ function q({ editor: e, toolbar: n, onImageClick: r, onFileClick: i, onEmojiClic
296
296
  size: "sm"
297
297
  })
298
298
  }),
299
- p && (m || h) && /* @__PURE__ */ y(K, {}),
299
+ f && (m || h) && /* @__PURE__ */ y(K, {}),
300
300
  a && s("emoji") && /* @__PURE__ */ y(W, {
301
301
  onClick: a,
302
302
  title: "Emoji",
@@ -340,7 +340,7 @@ function Y({ onSelect: e }) {
340
340
  children: /* @__PURE__ */ y(J, { onSelect: e })
341
341
  });
342
342
  }
343
- var X = v.forwardRef(function({ content: t = "", placeholder: n = "Start writing...", onChange: r, className: l, editable: x = !0, toolbar: S, onImageUpload: C, onFileUpload: w, mentions: T, onMentionSearch: E, onMentionSelect: D, emojiSet: O = "native", ...k }, A) {
343
+ var X = v.forwardRef(function({ content: t = "", placeholder: n = "Start writing...", onChange: r, className: p, editable: x = !0, toolbar: S, onImageUpload: C, onFileUpload: w, mentions: T, onMentionSearch: E, onMentionSelect: D, emojiSet: O = "native", ...k }, A) {
344
344
  let j = v.useRef(null), M = v.useRef(!1), [N, P] = v.useState(!1), F = v.useRef(null), I = v.useRef(null), L = v.useRef(null), R = async (e) => {
345
345
  let t = j.current;
346
346
  if (t) if (C) {
@@ -364,10 +364,10 @@ var X = v.forwardRef(function({ content: t = "", placeholder: n = "Start writing
364
364
  size: n.size
365
365
  }
366
366
  }).run();
367
- }, B = a({
367
+ }, B = f({
368
368
  immediatelyRender: !1,
369
369
  extensions: [
370
- d.configure({
370
+ c.configure({
371
371
  heading: { levels: [2, 3] },
372
372
  link: {
373
373
  openOnClick: !1,
@@ -387,8 +387,8 @@ var X = v.forwardRef(function({ content: t = "", placeholder: n = "Start writing
387
387
  placeholder: n,
388
388
  emptyEditorClass: "before:content-[attr(data-placeholder)] before:text-surface-fg-subtle before:float-left before:h-0 before:pointer-events-none"
389
389
  }),
390
- c.configure({ multicolor: !1 }),
391
- f.configure({
390
+ d.configure({ multicolor: !1 }),
391
+ a.configure({
392
392
  bulletList: !1,
393
393
  orderedList: !1,
394
394
  listItem: !1,
@@ -396,13 +396,13 @@ var X = v.forwardRef(function({ content: t = "", placeholder: n = "Start writing
396
396
  taskList: {},
397
397
  taskItem: { nested: !0 }
398
398
  }),
399
- p.configure({ types: ["heading", "paragraph"] }),
399
+ s.configure({ types: ["heading", "paragraph"] }),
400
400
  u.configure({
401
401
  allowBase64: !0,
402
402
  HTMLAttributes: { class: "max-w-full rounded-control" }
403
403
  }),
404
404
  g,
405
- ...T || E ? [s.configure({
405
+ ...T || E ? [l.configure({
406
406
  HTMLAttributes: { class: "mention" },
407
407
  suggestion: {
408
408
  items: async ({ query: e }) => E ? await E(e) : T ? T.filter((t) => t.label.toLowerCase().includes(e.toLowerCase())).slice(0, 8) : [],
@@ -445,7 +445,7 @@ var X = v.forwardRef(function({ content: t = "", placeholder: n = "Start writing
445
445
  }, [B, t]), B ? /* @__PURE__ */ b("div", {
446
446
  ref: A,
447
447
  ...k,
448
- className: e("relative", l),
448
+ className: e("relative", p),
449
449
  children: [N && /* @__PURE__ */ y("div", {
450
450
  ref: F,
451
451
  className: "absolute bottom-full right-0 z-popover mb-ds-02",
@@ -499,10 +499,10 @@ var X = v.forwardRef(function({ content: t = "", placeholder: n = "Start writing
499
499
  });
500
500
  X.displayName = "RichTextEditor";
501
501
  var Z = v.forwardRef(function({ content: t, className: n, ...r }, o) {
502
- let l = a({
502
+ let p = f({
503
503
  immediatelyRender: !1,
504
504
  extensions: [
505
- d.configure({
505
+ c.configure({
506
506
  heading: { levels: [2, 3] },
507
507
  link: {
508
508
  openOnClick: !0,
@@ -518,8 +518,8 @@ var Z = v.forwardRef(function({ content: t, className: n, ...r }, o) {
518
518
  }
519
519
  }
520
520
  }),
521
- c.configure({ multicolor: !1 }),
522
- f.configure({
521
+ d.configure({ multicolor: !1 }),
522
+ a.configure({
523
523
  bulletList: !1,
524
524
  orderedList: !1,
525
525
  listItem: !1,
@@ -527,23 +527,23 @@ var Z = v.forwardRef(function({ content: t, className: n, ...r }, o) {
527
527
  taskList: {},
528
528
  taskItem: { nested: !0 }
529
529
  }),
530
- p.configure({ types: ["heading", "paragraph"] }),
530
+ s.configure({ types: ["heading", "paragraph"] }),
531
531
  u.configure({
532
532
  allowBase64: !0,
533
533
  HTMLAttributes: { class: "max-w-full rounded-control" }
534
534
  }),
535
535
  g,
536
- s.configure({ HTMLAttributes: { class: "mention" } })
536
+ l.configure({ HTMLAttributes: { class: "mention" } })
537
537
  ],
538
538
  content: t,
539
539
  editable: !1,
540
540
  editorProps: { attributes: { class: e(...U) } }
541
541
  });
542
- return l ? /* @__PURE__ */ y("div", {
542
+ return p ? /* @__PURE__ */ y("div", {
543
543
  ref: o,
544
544
  ...r,
545
545
  className: n,
546
- children: /* @__PURE__ */ y(i, { editor: l })
546
+ children: /* @__PURE__ */ y(i, { editor: p })
547
547
  }) : null;
548
548
  });
549
549
  Z.displayName = "RichTextViewer";
@@ -79,7 +79,7 @@ function v({ date: n, events: a, startHour: o, endHour: f, slotDuration: h, onEv
79
79
  let n = g(t, o, f), a = t.color ?? "accent", c = p[a], l = m[a];
80
80
  return /* @__PURE__ */ r("button", {
81
81
  type: "button",
82
- className: e("absolute left-ds-01 right-ds-01 rounded-control-inner px-ds-02 py-ds-01", "text-left text-ds-xs font-medium overflow-hidden cursor-pointer", "hover:shadow-raised hover:scale-[1.02] transition-[box-shadow,transform] duration-fast-02 ease-productive-standard", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9", c),
82
+ className: e("absolute left-ds-01 right-ds-01 rounded-control-inner px-ds-02 py-ds-01", "text-left text-ds-xs font-medium overflow-hidden cursor-pointer", "hover:shadow-raised transition-[box-shadow] duration-fast-02 ease-productive-standard", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9", c),
83
83
  style: n,
84
84
  onClick: (e) => {
85
85
  e.stopPropagation(), _?.(t);
@@ -1 +1 @@
1
- {"version":3,"file":"schedule-view.js","names":[],"sources":["../../src/composed/schedule-view.tsx"],"sourcesContent":["'use client'\n\nimport {\n addDays,\n differenceInMinutes,\n format,\n getHours,\n getMinutes,\n isSameDay,\n isToday,\n startOfWeek,\n} from 'date-fns'\nimport * as React from 'react'\n\nimport { Dot } from '../ui/dot'\nimport { cn } from '../ui/lib/utils'\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport interface ScheduleEvent {\n id: string\n title: string\n start: Date\n end: Date\n color?: 'accent' | 'success' | 'warning' | 'error' | 'info' | 'neutral'\n}\n\n/**\n * A day/week calendar schedule grid. Renders time-slotted events with\n * proportional height, color coding, click handlers, and a current-time indicator.\n */\nexport interface ScheduleViewProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Display mode: single-day column or full-week (7 columns). */\n view: 'day' | 'week'\n /** Current day (day view) or any date within the target week (week view). */\n date: Date\n /** Events to display on the calendar grid. */\n events: ScheduleEvent[]\n /** Called when an event block is clicked. */\n onEventClick?: (event: ScheduleEvent) => void\n /** Called when an empty time slot is clicked, with the slot's start and end times. */\n onSlotClick?: (start: Date, end: Date) => void\n /** First visible hour (default 8). */\n startHour?: number\n /** Last visible hour -- exclusive (default 18). */\n endHour?: number\n /** Slot duration in minutes (default 30). */\n slotDuration?: number\n}\n\n/* ------------------------------------------------------------------ */\n/* Color map */\n/* ------------------------------------------------------------------ */\n\nconst eventColorMap: Record<\n NonNullable<ScheduleEvent['color']>,\n string\n> = {\n accent: 'bg-accent-2 text-accent-11',\n success: 'bg-success-3 text-success-11',\n warning: 'bg-warning-3 text-warning-11',\n error: 'bg-error-3 text-error-11',\n info: 'bg-info-3 text-info-11',\n neutral: 'bg-surface-raised text-surface-fg-muted',\n}\n\n// Solid category dot — the color-blind-safe, shape-based signal that replaces the\n// former left accent rail (the AI tell). Tint above carries the ambient color.\nconst eventDotMap: Record<\n NonNullable<ScheduleEvent['color']>,\n string\n> = {\n accent: 'bg-accent-9',\n success: 'bg-success-9',\n warning: 'bg-warning-9',\n error: 'bg-error-9',\n info: 'bg-info-9',\n neutral: 'bg-surface-fg-subtle',\n}\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction formatHourLabel(hour: number): string {\n if (hour === 0) return '12 AM'\n if (hour < 12) return `${hour} AM`\n if (hour === 12) return '12 PM'\n return `${hour - 12} PM`\n}\n\nfunction getEventStyle(\n event: ScheduleEvent,\n startHour: number,\n endHour: number,\n) {\n const totalMinutes = (endHour - startHour) * 60\n const eventStartMinutes =\n (getHours(event.start) - startHour) * 60 + getMinutes(event.start)\n const durationMinutes = differenceInMinutes(event.end, event.start)\n\n const top = (eventStartMinutes / totalMinutes) * 100\n const height = (durationMinutes / totalMinutes) * 100\n\n return {\n top: `${top}%`,\n height: `${height}%`,\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Sub-components */\n/* ------------------------------------------------------------------ */\n\ninterface TimeColumnProps {\n startHour: number\n endHour: number\n}\n\nfunction TimeColumn({ startHour, endHour }: TimeColumnProps) {\n const hours: number[] = []\n for (let h = startHour; h < endHour; h++) {\n hours.push(h)\n }\n const slotHeight = 100 / (endHour - startHour)\n\n return (\n <div\n className=\"relative shrink-0 w-[60px] border-r border-surface-border-strong\"\n aria-hidden=\"true\"\n >\n {hours.map((hour) => (\n <div\n key={hour}\n className=\"text-ds-xs text-surface-fg-muted pr-ds-02 text-right\"\n style={{ height: `${slotHeight}%` }}\n >\n {formatHourLabel(hour)}\n </div>\n ))}\n </div>\n )\n}\n\ninterface DayColumnProps {\n date: Date\n events: ScheduleEvent[]\n startHour: number\n endHour: number\n slotDuration: number\n onEventClick?: (event: ScheduleEvent) => void\n onSlotClick?: (start: Date, end: Date) => void\n showHeader?: boolean\n}\n\nfunction DayColumn({\n date,\n events,\n startHour,\n endHour,\n slotDuration,\n onEventClick,\n onSlotClick,\n showHeader,\n}: DayColumnProps) {\n const dayEvents = events.filter((e) => isSameDay(e.start, date))\n const totalMinutes = (endHour - startHour) * 60\n const slotCount = totalMinutes / slotDuration\n\n const slots: { start: Date; end: Date }[] = []\n for (let i = 0; i < slotCount; i++) {\n const slotStart = new Date(date)\n slotStart.setHours(startHour, i * slotDuration, 0, 0)\n const slotEnd = new Date(slotStart)\n slotEnd.setMinutes(slotEnd.getMinutes() + slotDuration)\n slots.push({ start: slotStart, end: slotEnd })\n }\n\n const todayInView = isToday(date)\n\n // Current time indicator position\n let nowIndicatorTop: number | null = null\n if (todayInView) {\n const now = new Date()\n const nowHour = getHours(now)\n const nowMin = getMinutes(now)\n if (nowHour >= startHour && nowHour < endHour) {\n const nowMinutes = (nowHour - startHour) * 60 + nowMin\n nowIndicatorTop = (nowMinutes / totalMinutes) * 100\n }\n }\n\n return (\n <div className=\"flex flex-1 flex-col min-w-ds-11\">\n {showHeader && (\n <div\n className={cn(\n 'text-center text-ds-sm font-semibold py-ds-02 border-b border-surface-border-strong',\n todayInView\n ? 'text-accent-11 bg-accent-2'\n : 'text-surface-fg bg-surface-raised',\n )}\n >\n {format(date, 'EEE d')}\n </div>\n )}\n <div className=\"relative flex-1\">\n {/* Slot grid lines */}\n {slots.map((slot, i) => (\n <button\n key={i}\n type=\"button\"\n className={cn(\n 'block w-full border-b border-surface-border hover:bg-surface-raised-hover transition-colors ease-productive-standard',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent-9',\n i % 2 === 0 ? 'border-surface-border-strong' : 'border-surface-border-subtle',\n )}\n style={{ height: `${100 / slotCount}%` }}\n onClick={() => onSlotClick?.(slot.start, slot.end)}\n aria-label={`${format(slot.start, 'h:mm a')} to ${format(slot.end, 'h:mm a')}`}\n />\n ))}\n\n {/* Events */}\n {dayEvents.map((event) => {\n const style = getEventStyle(event, startHour, endHour)\n const eventColor = event.color ?? 'accent'\n const colorClass = eventColorMap[eventColor]\n const dotClass = eventDotMap[eventColor]\n return (\n <button\n key={event.id}\n type=\"button\"\n className={cn(\n 'absolute left-ds-01 right-ds-01 rounded-control-inner px-ds-02 py-ds-01',\n 'text-left text-ds-xs font-medium overflow-hidden cursor-pointer',\n 'hover:shadow-raised hover:scale-[1.02] transition-[box-shadow,transform] duration-fast-02 ease-productive-standard',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9',\n colorClass,\n )}\n style={style}\n onClick={(e) => {\n e.stopPropagation()\n onEventClick?.(event)\n }}\n aria-label={`${event.title}, ${format(event.start, 'h:mm a')} to ${format(event.end, 'h:mm a')}`}\n >\n <span className=\"flex items-start gap-ds-02\">\n <span\n className={cn('mt-[3px] h-ds-03 w-ds-03 shrink-0 rounded-pill', dotClass)}\n aria-hidden=\"true\"\n />\n <span className=\"line-clamp-2\">{event.title}</span>\n </span>\n </button>\n )\n })}\n\n {/* Current time indicator */}\n {nowIndicatorTop != null && (\n <div\n className=\"absolute left-0 right-0 h-ds-01 bg-error-9 z-10 pointer-events-none\"\n style={{ top: `${nowIndicatorTop}%` }}\n aria-hidden=\"true\"\n >\n <Dot color=\"error\" size=\"lg\" pulse className=\"absolute -left-[5px] -top-[4px]\" />\n </div>\n )}\n </div>\n </div>\n )\n}\n\n/* ------------------------------------------------------------------ */\n/* ScheduleView */\n/* ------------------------------------------------------------------ */\n\nconst ScheduleView = React.forwardRef<HTMLDivElement, ScheduleViewProps>(\n (\n {\n view,\n date,\n events,\n onEventClick,\n onSlotClick,\n startHour = 8,\n endHour = 18,\n slotDuration = 30,\n className,\n ...props\n },\n ref,\n ) => {\n const days: Date[] = React.useMemo(() => {\n if (view === 'day') return [date]\n const weekStart = startOfWeek(date, { weekStartsOn: 1 }) // Monday\n return Array.from({ length: 7 }, (_, i) => addDays(weekStart, i))\n }, [view, date])\n\n return (\n <div\n ref={ref}\n role=\"region\"\n aria-label={\n view === 'day'\n ? `Schedule for ${format(date, 'EEEE, MMMM d, yyyy')}`\n : `Week schedule starting ${format(days[0], 'MMMM d, yyyy')}`\n }\n className={cn(\n 'flex rounded-control border border-surface-border-strong bg-surface-raised overflow-hidden',\n 'h-[480px]',\n className,\n )}\n {...props}\n >\n <TimeColumn startHour={startHour} endHour={endHour} />\n <div className=\"flex flex-1 divide-x divide-surface-border overflow-x-auto\">\n {days.map((day) => (\n <DayColumn\n key={day.toISOString()}\n date={day}\n events={events}\n startHour={startHour}\n endHour={endHour}\n slotDuration={slotDuration}\n onEventClick={onEventClick}\n onSlotClick={onSlotClick}\n showHeader={view === 'week'}\n />\n ))}\n </div>\n </div>\n )\n },\n)\nScheduleView.displayName = 'ScheduleView'\n\nexport { ScheduleView }\n"],"mappings":"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"}
1
+ {"version":3,"file":"schedule-view.js","names":[],"sources":["../../src/composed/schedule-view.tsx"],"sourcesContent":["'use client'\n\nimport {\n addDays,\n differenceInMinutes,\n format,\n getHours,\n getMinutes,\n isSameDay,\n isToday,\n startOfWeek,\n} from 'date-fns'\nimport * as React from 'react'\n\nimport { Dot } from '../ui/dot'\nimport { cn } from '../ui/lib/utils'\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport interface ScheduleEvent {\n id: string\n title: string\n start: Date\n end: Date\n color?: 'accent' | 'success' | 'warning' | 'error' | 'info' | 'neutral'\n}\n\n/**\n * A day/week calendar schedule grid. Renders time-slotted events with\n * proportional height, color coding, click handlers, and a current-time indicator.\n */\nexport interface ScheduleViewProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Display mode: single-day column or full-week (7 columns). */\n view: 'day' | 'week'\n /** Current day (day view) or any date within the target week (week view). */\n date: Date\n /** Events to display on the calendar grid. */\n events: ScheduleEvent[]\n /** Called when an event block is clicked. */\n onEventClick?: (event: ScheduleEvent) => void\n /** Called when an empty time slot is clicked, with the slot's start and end times. */\n onSlotClick?: (start: Date, end: Date) => void\n /** First visible hour (default 8). */\n startHour?: number\n /** Last visible hour -- exclusive (default 18). */\n endHour?: number\n /** Slot duration in minutes (default 30). */\n slotDuration?: number\n}\n\n/* ------------------------------------------------------------------ */\n/* Color map */\n/* ------------------------------------------------------------------ */\n\nconst eventColorMap: Record<\n NonNullable<ScheduleEvent['color']>,\n string\n> = {\n accent: 'bg-accent-2 text-accent-11',\n success: 'bg-success-3 text-success-11',\n warning: 'bg-warning-3 text-warning-11',\n error: 'bg-error-3 text-error-11',\n info: 'bg-info-3 text-info-11',\n neutral: 'bg-surface-raised text-surface-fg-muted',\n}\n\n// Solid category dot — the color-blind-safe, shape-based signal that replaces the\n// former left accent rail (the AI tell). Tint above carries the ambient color.\nconst eventDotMap: Record<\n NonNullable<ScheduleEvent['color']>,\n string\n> = {\n accent: 'bg-accent-9',\n success: 'bg-success-9',\n warning: 'bg-warning-9',\n error: 'bg-error-9',\n info: 'bg-info-9',\n neutral: 'bg-surface-fg-subtle',\n}\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction formatHourLabel(hour: number): string {\n if (hour === 0) return '12 AM'\n if (hour < 12) return `${hour} AM`\n if (hour === 12) return '12 PM'\n return `${hour - 12} PM`\n}\n\nfunction getEventStyle(\n event: ScheduleEvent,\n startHour: number,\n endHour: number,\n) {\n const totalMinutes = (endHour - startHour) * 60\n const eventStartMinutes =\n (getHours(event.start) - startHour) * 60 + getMinutes(event.start)\n const durationMinutes = differenceInMinutes(event.end, event.start)\n\n const top = (eventStartMinutes / totalMinutes) * 100\n const height = (durationMinutes / totalMinutes) * 100\n\n return {\n top: `${top}%`,\n height: `${height}%`,\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Sub-components */\n/* ------------------------------------------------------------------ */\n\ninterface TimeColumnProps {\n startHour: number\n endHour: number\n}\n\nfunction TimeColumn({ startHour, endHour }: TimeColumnProps) {\n const hours: number[] = []\n for (let h = startHour; h < endHour; h++) {\n hours.push(h)\n }\n const slotHeight = 100 / (endHour - startHour)\n\n return (\n <div\n className=\"relative shrink-0 w-[60px] border-r border-surface-border-strong\"\n aria-hidden=\"true\"\n >\n {hours.map((hour) => (\n <div\n key={hour}\n className=\"text-ds-xs text-surface-fg-muted pr-ds-02 text-right\"\n style={{ height: `${slotHeight}%` }}\n >\n {formatHourLabel(hour)}\n </div>\n ))}\n </div>\n )\n}\n\ninterface DayColumnProps {\n date: Date\n events: ScheduleEvent[]\n startHour: number\n endHour: number\n slotDuration: number\n onEventClick?: (event: ScheduleEvent) => void\n onSlotClick?: (start: Date, end: Date) => void\n showHeader?: boolean\n}\n\nfunction DayColumn({\n date,\n events,\n startHour,\n endHour,\n slotDuration,\n onEventClick,\n onSlotClick,\n showHeader,\n}: DayColumnProps) {\n const dayEvents = events.filter((e) => isSameDay(e.start, date))\n const totalMinutes = (endHour - startHour) * 60\n const slotCount = totalMinutes / slotDuration\n\n const slots: { start: Date; end: Date }[] = []\n for (let i = 0; i < slotCount; i++) {\n const slotStart = new Date(date)\n slotStart.setHours(startHour, i * slotDuration, 0, 0)\n const slotEnd = new Date(slotStart)\n slotEnd.setMinutes(slotEnd.getMinutes() + slotDuration)\n slots.push({ start: slotStart, end: slotEnd })\n }\n\n const todayInView = isToday(date)\n\n // Current time indicator position\n let nowIndicatorTop: number | null = null\n if (todayInView) {\n const now = new Date()\n const nowHour = getHours(now)\n const nowMin = getMinutes(now)\n if (nowHour >= startHour && nowHour < endHour) {\n const nowMinutes = (nowHour - startHour) * 60 + nowMin\n nowIndicatorTop = (nowMinutes / totalMinutes) * 100\n }\n }\n\n return (\n <div className=\"flex flex-1 flex-col min-w-ds-11\">\n {showHeader && (\n <div\n className={cn(\n 'text-center text-ds-sm font-semibold py-ds-02 border-b border-surface-border-strong',\n todayInView\n ? 'text-accent-11 bg-accent-2'\n : 'text-surface-fg bg-surface-raised',\n )}\n >\n {format(date, 'EEE d')}\n </div>\n )}\n <div className=\"relative flex-1\">\n {/* Slot grid lines */}\n {slots.map((slot, i) => (\n <button\n key={i}\n type=\"button\"\n className={cn(\n 'block w-full border-b border-surface-border hover:bg-surface-raised-hover transition-colors ease-productive-standard',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-accent-9',\n i % 2 === 0 ? 'border-surface-border-strong' : 'border-surface-border-subtle',\n )}\n style={{ height: `${100 / slotCount}%` }}\n onClick={() => onSlotClick?.(slot.start, slot.end)}\n aria-label={`${format(slot.start, 'h:mm a')} to ${format(slot.end, 'h:mm a')}`}\n />\n ))}\n\n {/* Events */}\n {dayEvents.map((event) => {\n const style = getEventStyle(event, startHour, endHour)\n const eventColor = event.color ?? 'accent'\n const colorClass = eventColorMap[eventColor]\n const dotClass = eventDotMap[eventColor]\n return (\n <button\n key={event.id}\n type=\"button\"\n className={cn(\n 'absolute left-ds-01 right-ds-01 rounded-control-inner px-ds-02 py-ds-01',\n 'text-left text-ds-xs font-medium overflow-hidden cursor-pointer',\n 'hover:shadow-raised transition-[box-shadow] duration-fast-02 ease-productive-standard',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9',\n colorClass,\n )}\n style={style}\n onClick={(e) => {\n e.stopPropagation()\n onEventClick?.(event)\n }}\n aria-label={`${event.title}, ${format(event.start, 'h:mm a')} to ${format(event.end, 'h:mm a')}`}\n >\n <span className=\"flex items-start gap-ds-02\">\n <span\n className={cn('mt-[3px] h-ds-03 w-ds-03 shrink-0 rounded-pill', dotClass)}\n aria-hidden=\"true\"\n />\n <span className=\"line-clamp-2\">{event.title}</span>\n </span>\n </button>\n )\n })}\n\n {/* Current time indicator */}\n {nowIndicatorTop != null && (\n <div\n className=\"absolute left-0 right-0 h-ds-01 bg-error-9 z-10 pointer-events-none\"\n style={{ top: `${nowIndicatorTop}%` }}\n aria-hidden=\"true\"\n >\n <Dot color=\"error\" size=\"lg\" pulse className=\"absolute -left-[5px] -top-[4px]\" />\n </div>\n )}\n </div>\n </div>\n )\n}\n\n/* ------------------------------------------------------------------ */\n/* ScheduleView */\n/* ------------------------------------------------------------------ */\n\nconst ScheduleView = React.forwardRef<HTMLDivElement, ScheduleViewProps>(\n (\n {\n view,\n date,\n events,\n onEventClick,\n onSlotClick,\n startHour = 8,\n endHour = 18,\n slotDuration = 30,\n className,\n ...props\n },\n ref,\n ) => {\n const days: Date[] = React.useMemo(() => {\n if (view === 'day') return [date]\n const weekStart = startOfWeek(date, { weekStartsOn: 1 }) // Monday\n return Array.from({ length: 7 }, (_, i) => addDays(weekStart, i))\n }, [view, date])\n\n return (\n <div\n ref={ref}\n role=\"region\"\n aria-label={\n view === 'day'\n ? `Schedule for ${format(date, 'EEEE, MMMM d, yyyy')}`\n : `Week schedule starting ${format(days[0], 'MMMM d, yyyy')}`\n }\n className={cn(\n 'flex rounded-control border border-surface-border-strong bg-surface-raised overflow-hidden',\n 'h-[480px]',\n className,\n )}\n {...props}\n >\n <TimeColumn startHour={startHour} endHour={endHour} />\n <div className=\"flex flex-1 divide-x divide-surface-border overflow-x-auto\">\n {days.map((day) => (\n <DayColumn\n key={day.toISOString()}\n date={day}\n events={events}\n startHour={startHour}\n endHour={endHour}\n slotDuration={slotDuration}\n onEventClick={onEventClick}\n onSlotClick={onSlotClick}\n showHeader={view === 'week'}\n />\n ))}\n </div>\n </div>\n )\n },\n)\nScheduleView.displayName = 'ScheduleView'\n\nexport { ScheduleView }\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { motionProps as e } from "../ui/lib/motion.js";
3
3
  import { Dot as t } from "../ui/dot.js";
4
- import { n } from "../_chunks/badge-group.js";
4
+ import { BadgeCompound as n } from "../_chunks/badge-group.js";
5
5
  import * as r from "react";
6
6
  import { jsx as i } from "react/jsx-runtime";
7
7
  import { IconChevronDown as a } from "@tabler/icons-react";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { motionProps as e, springs as t, stagger as n, tweens as r, withReducedMotion as i } from "../ui/lib/motion.js";
3
- import { n as a, t as o } from "../_chunks/motion-provider.js";
3
+ import { MotionProvider as a, useMotion as o } from "../_chunks/motion-provider.js";
4
4
  //#region src/motion/check-motion-provider.ts
5
5
  var s = !1;
6
6
  function c() {
@@ -15,4 +15,4 @@ function c() {
15
15
  //#region src/motion/index.ts
16
16
  c();
17
17
  //#endregion
18
- export { o as MotionProvider, e as motionProps, t as springs, n as stagger, r as tweens, a as useMotion, i as withReducedMotion };
18
+ export { a as MotionProvider, e as motionProps, t as springs, n as stagger, r as tweens, o as useMotion, i as withReducedMotion };
@@ -3,8 +3,8 @@ import { IconProvider as e } from "../ui/icon-context.js";
3
3
  import { springs as t } from "../ui/lib/motion.js";
4
4
  import { cn as n } from "../ui/lib/utils.js";
5
5
  import { Icon as r } from "../ui/icon.js";
6
- import { t as i } from "../_chunks/normalize-icon.js";
7
- import { n as a } from "../_chunks/link-context.js";
6
+ import { normalizeIcon as i } from "../_chunks/normalize-icon.js";
7
+ import { useLink as a } from "../_chunks/link-context.js";
8
8
  import "./link-context.js";
9
9
  import * as o from "react";
10
10
  import { useCallback as s, useEffect as c, useRef as l, useState as u } from "react";
@@ -24,7 +24,7 @@ function y({ count: e }) {
24
24
  function b({ item: r, isActive: o, onClick: s }) {
25
25
  let c = a(), l = v();
26
26
  return /* @__PURE__ */ f(_.div, {
27
- whileTap: l ? void 0 : { y: -2 },
27
+ whileTap: l ? void 0 : { scale: .96 },
28
28
  transition: l ? { duration: 0 } : t.snappy,
29
29
  className: "flex max-w-[70px] flex-1",
30
30
  children: /* @__PURE__ */ f(c, {
@@ -1 +1 @@
1
- {"version":3,"file":"bottom-navbar.js","names":[],"sources":["../../src/shell/bottom-navbar.tsx"],"sourcesContent":["'use client'\n\n/**\n * BottomNavbar -- Mobile bottom navigation bar.\n *\n * Props-driven: accepts currentPath, user, navItems instead of\n * reading from Remix hooks or Zustand stores.\n */\nimport { IconDots, IconX } from '@tabler/icons-react'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\nimport { useCallback,useEffect, useRef, useState } from 'react'\n\nimport { Icon } from '../ui/icon'\nimport { IconProvider } from '../ui/icon-context'\nimport type { IconInput } from '../ui/lib/icon-input'\nimport { springs } from '../ui/lib/motion'\nimport { normalizeIcon } from '../ui/lib/normalize-icon'\nimport { cn } from '../ui/lib/utils'\nimport { useLink } from './link-context'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface BottomNavItem {\n title: string\n href: string\n /** Icon for this nav item. Accepts any `IconInput`. */\n icon: IconInput\n /** When true, the route matches only when the path is exactly equal */\n exact?: boolean\n /** Notification badge count. 0 or undefined = hidden, 1–99 = shown, >99 = \"99+\" */\n badge?: number\n}\n\nexport interface BottomNavbarUser {\n name: string\n role?: string\n}\n\nexport interface BottomNavbarProps\n extends React.HTMLAttributes<HTMLElement> {\n /** Currently active pathname */\n currentPath?: string\n /** User information (used to determine admin status, presence) */\n user?: BottomNavbarUser | null\n /** Primary nav items shown directly in the bottom bar (max 4 recommended) */\n primaryItems?: BottomNavItem[]\n /** Additional items shown in the \"More\" overflow menu */\n moreItems?: BottomNavItem[]\n /** Additional className for the nav element */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// NavBadge (internal)\n// -----------------------------------------------------------------------\n\nfunction NavBadge({ count }: { count: number }) {\n if (!count || count <= 0) return null\n const display = count > 99 ? '99+' : String(count)\n const isMultiDigit = count >= 10\n return (\n <span\n aria-label={`${count} notifications`}\n className={cn(\n 'absolute -right-1 -top-0.5 flex h-4 min-w-4 items-center justify-center rounded-pill bg-error-9 text-[10px] font-semibold leading-none text-error-fg animate-in zoom-in-75',\n isMultiDigit ? 'px-0.5' : '',\n )}\n >\n {display}\n </span>\n )\n}\n\n// -----------------------------------------------------------------------\n// BottomNavLink (internal)\n// -----------------------------------------------------------------------\n\nfunction BottomNavLink({\n item,\n isActive,\n onClick,\n}: {\n item: BottomNavItem\n isActive: boolean\n onClick?: () => void\n}) {\n const Link = useLink()\n const prefersReducedMotion = useReducedMotion()\n return (\n <motion.div whileTap={prefersReducedMotion ? undefined : { y: -2 }} transition={prefersReducedMotion ? { duration: 0 } : springs.snappy} className=\"flex max-w-[70px] flex-1\">\n <Link\n href={item.href}\n onClick={onClick}\n aria-label={item.title}\n aria-current={isActive ? 'page' : undefined}\n className={cn(\n 'flex h-16 w-full cursor-pointer flex-col items-center gap-ds-02 p-ds-02 pt-0 text-ds-sm transition-colors duration-fast-02 ease-productive-standard',\n isActive\n ? 'font-semibold text-accent-11'\n : 'text-surface-fg-subtle',\n )}\n >\n <div className=\"relative flex w-full flex-col items-center gap-ds-02\">\n {isActive && (\n <motion.div\n layoutId=\"bottom-nav-indicator\"\n className=\"absolute top-0 h-[3px] w-full rounded-b-control-inner bg-accent-9 p-0\"\n aria-hidden=\"true\"\n transition={prefersReducedMotion ? { duration: 0 } : springs.snappy}\n />\n )}\n <div className=\"relative p-ds-03\">\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md\" aria-hidden=\"true\"><IconProvider size=\"md\">{normalizeIcon(item.icon)}</IconProvider></span>\n {item.badge != null && <NavBadge count={item.badge} />}\n </div>\n <span className=\"text-center\">{item.title}</span>\n </div>\n </Link>\n </motion.div>\n )\n}\n\n// -----------------------------------------------------------------------\n// BottomNavbar\n// -----------------------------------------------------------------------\n\nconst BottomNavbar = React.forwardRef<HTMLElement, BottomNavbarProps>(\n (\n {\n currentPath = '/',\n user: _user,\n primaryItems = [],\n moreItems = [],\n className,\n ...props\n },\n ref,\n ) => {\n const Link = useLink()\n const prefersReducedMotion = useReducedMotion()\n const [showMore, setShowMore] = useState(false)\n const overlayRef = useRef<HTMLDivElement>(null)\n\n const closeMore = useCallback(() => setShowMore(false), [])\n\n // Focus first focusable item when overlay opens\n useEffect(() => {\n if (showMore && overlayRef.current) {\n const firstFocusable = overlayRef.current.querySelector<HTMLElement>('a, button')\n firstFocusable?.focus()\n }\n }, [showMore])\n\n const isActive = (path: string, exact = false) => {\n if (exact || path === '/') {\n return currentPath === path\n }\n return currentPath.startsWith(path)\n }\n\n // Check if any \"more\" item is active\n const isMoreActive = moreItems.some((item) =>\n isActive(item.href, item.exact),\n )\n\n return (\n <>\n {/* More Menu Overlay */}\n <AnimatePresence>\n {showMore && (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events -- backdrop overlay, dismiss via mouse only; keyboard users close via Escape\n <div\n className=\"fixed inset-0 z-overlay md:hidden\"\n onClick={() => setShowMore(false)}\n >\n <div className=\"absolute inset-0 bg-overlay\" />\n { }\n <motion.div\n ref={overlayRef}\n role=\"dialog\"\n aria-label=\"More navigation\"\n initial={{ y: '100%' }}\n animate={{ y: 0 }}\n exit={{ y: '100%' }}\n transition={prefersReducedMotion ? { duration: 0 } : springs.smooth}\n className=\"absolute bottom-[72px] left-0 right-0 rounded-t-bubble border-t border-surface-border-strong bg-surface-overlay p-ds-05 pb-ds-03\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n e.stopPropagation()\n if (e.key === 'Escape') closeMore()\n }}\n >\n <div className=\"mb-ds-04 flex items-center justify-between\">\n <span className=\"text-ds-md font-semibold text-surface-fg\">\n More\n </span>\n <button\n onClick={() => setShowMore(false)}\n aria-label=\"Close more menu\"\n className=\"flex h-ds-sm w-ds-sm items-center justify-center rounded-pill hover:bg-surface-raised-hover\"\n >\n <Icon icon={IconX} size=\"sm\" className=\"text-surface-fg-muted\" />\n </button>\n </div>\n <div className=\"grid grid-cols-4 gap-ds-03\">\n {moreItems.map((item) => (\n <Link\n key={item.href}\n href={item.href}\n onClick={() => setShowMore(false)}\n className={cn(\n 'flex flex-col items-center gap-ds-02b rounded-overlay-lg p-ds-04 text-ds-sm transition-colors ease-productive-standard',\n isActive(item.href, item.exact)\n ? 'bg-surface-raised-hover text-accent-11'\n : 'text-surface-fg-subtle hover:bg-surface-raised-hover',\n )}\n >\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md\"><IconProvider size=\"md\">{normalizeIcon(item.icon)}</IconProvider></span>\n <span className=\"text-center\">\n {item.title}\n </span>\n </Link>\n ))}\n </div>\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n\n {/* Bottom Navigation Bar */}\n <nav\n {...props}\n ref={ref}\n aria-label=\"Mobile navigation\"\n className={cn(\n 'fixed bottom-0 left-0 right-0 z-sticky flex w-full flex-row items-start justify-between border-t border-surface-border-strong bg-surface-chrome px-ds-05 pb-safe pt-0 md:hidden',\n className,\n )}\n >\n {primaryItems.map((item) => (\n <BottomNavLink\n key={item.href}\n item={item}\n isActive={isActive(item.href, item.exact)}\n />\n ))}\n\n {/* More Button */}\n {moreItems.length > 0 && (\n <motion.button\n type=\"button\"\n onClick={() => setShowMore(!showMore)}\n aria-label=\"More navigation options\"\n aria-expanded={showMore}\n whileTap={prefersReducedMotion ? undefined : { y: -2 }}\n transition={prefersReducedMotion ? { duration: 0 } : springs.snappy}\n className={cn(\n 'flex h-16 max-w-[70px] flex-1 cursor-pointer flex-col items-center gap-ds-02 p-ds-02 pt-0 text-ds-sm',\n showMore || isMoreActive\n ? 'font-semibold text-accent-11'\n : 'text-surface-fg-subtle',\n )}\n >\n <div className=\"relative flex w-full flex-col items-center gap-ds-02\">\n {(showMore || isMoreActive) && (\n <motion.div\n layoutId=\"bottom-nav-indicator\"\n className=\"absolute top-0 h-[3px] w-full rounded-b-control-inner bg-accent-9 p-0\"\n aria-hidden=\"true\"\n transition={prefersReducedMotion ? { duration: 0 } : springs.snappy}\n />\n )}\n <div className=\"p-ds-03\">\n <Icon icon={IconDots} />\n </div>\n <span className=\"text-center\">More</span>\n </div>\n </motion.button>\n )}\n </nav>\n </>\n )\n },\n)\nBottomNavbar.displayName = 'BottomNavbar'\n\nexport { BottomNavbar }\n"],"mappings":"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"}
1
+ {"version":3,"file":"bottom-navbar.js","names":[],"sources":["../../src/shell/bottom-navbar.tsx"],"sourcesContent":["'use client'\n\n/**\n * BottomNavbar -- Mobile bottom navigation bar.\n *\n * Props-driven: accepts currentPath, user, navItems instead of\n * reading from Remix hooks or Zustand stores.\n */\nimport { IconDots, IconX } from '@tabler/icons-react'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\nimport { useCallback,useEffect, useRef, useState } from 'react'\n\nimport { Icon } from '../ui/icon'\nimport { IconProvider } from '../ui/icon-context'\nimport type { IconInput } from '../ui/lib/icon-input'\nimport { springs } from '../ui/lib/motion'\nimport { normalizeIcon } from '../ui/lib/normalize-icon'\nimport { cn } from '../ui/lib/utils'\nimport { useLink } from './link-context'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface BottomNavItem {\n title: string\n href: string\n /** Icon for this nav item. Accepts any `IconInput`. */\n icon: IconInput\n /** When true, the route matches only when the path is exactly equal */\n exact?: boolean\n /** Notification badge count. 0 or undefined = hidden, 1–99 = shown, >99 = \"99+\" */\n badge?: number\n}\n\nexport interface BottomNavbarUser {\n name: string\n role?: string\n}\n\nexport interface BottomNavbarProps\n extends React.HTMLAttributes<HTMLElement> {\n /** Currently active pathname */\n currentPath?: string\n /** User information (used to determine admin status, presence) */\n user?: BottomNavbarUser | null\n /** Primary nav items shown directly in the bottom bar (max 4 recommended) */\n primaryItems?: BottomNavItem[]\n /** Additional items shown in the \"More\" overflow menu */\n moreItems?: BottomNavItem[]\n /** Additional className for the nav element */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// NavBadge (internal)\n// -----------------------------------------------------------------------\n\nfunction NavBadge({ count }: { count: number }) {\n if (!count || count <= 0) return null\n const display = count > 99 ? '99+' : String(count)\n const isMultiDigit = count >= 10\n return (\n <span\n aria-label={`${count} notifications`}\n className={cn(\n 'absolute -right-1 -top-0.5 flex h-4 min-w-4 items-center justify-center rounded-pill bg-error-9 text-[10px] font-semibold leading-none text-error-fg animate-in zoom-in-75',\n isMultiDigit ? 'px-0.5' : '',\n )}\n >\n {display}\n </span>\n )\n}\n\n// -----------------------------------------------------------------------\n// BottomNavLink (internal)\n// -----------------------------------------------------------------------\n\nfunction BottomNavLink({\n item,\n isActive,\n onClick,\n}: {\n item: BottomNavItem\n isActive: boolean\n onClick?: () => void\n}) {\n const Link = useLink()\n const prefersReducedMotion = useReducedMotion()\n return (\n <motion.div whileTap={prefersReducedMotion ? undefined : { scale: 0.96 }} transition={prefersReducedMotion ? { duration: 0 } : springs.snappy} className=\"flex max-w-[70px] flex-1\">\n <Link\n href={item.href}\n onClick={onClick}\n aria-label={item.title}\n aria-current={isActive ? 'page' : undefined}\n className={cn(\n 'flex h-16 w-full cursor-pointer flex-col items-center gap-ds-02 p-ds-02 pt-0 text-ds-sm transition-colors duration-fast-02 ease-productive-standard',\n isActive\n ? 'font-semibold text-accent-11'\n : 'text-surface-fg-subtle',\n )}\n >\n <div className=\"relative flex w-full flex-col items-center gap-ds-02\">\n {isActive && (\n <motion.div\n layoutId=\"bottom-nav-indicator\"\n className=\"absolute top-0 h-[3px] w-full rounded-b-control-inner bg-accent-9 p-0\"\n aria-hidden=\"true\"\n transition={prefersReducedMotion ? { duration: 0 } : springs.snappy}\n />\n )}\n <div className=\"relative p-ds-03\">\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md\" aria-hidden=\"true\"><IconProvider size=\"md\">{normalizeIcon(item.icon)}</IconProvider></span>\n {item.badge != null && <NavBadge count={item.badge} />}\n </div>\n <span className=\"text-center\">{item.title}</span>\n </div>\n </Link>\n </motion.div>\n )\n}\n\n// -----------------------------------------------------------------------\n// BottomNavbar\n// -----------------------------------------------------------------------\n\nconst BottomNavbar = React.forwardRef<HTMLElement, BottomNavbarProps>(\n (\n {\n currentPath = '/',\n user: _user,\n primaryItems = [],\n moreItems = [],\n className,\n ...props\n },\n ref,\n ) => {\n const Link = useLink()\n const prefersReducedMotion = useReducedMotion()\n const [showMore, setShowMore] = useState(false)\n const overlayRef = useRef<HTMLDivElement>(null)\n\n const closeMore = useCallback(() => setShowMore(false), [])\n\n // Focus first focusable item when overlay opens\n useEffect(() => {\n if (showMore && overlayRef.current) {\n const firstFocusable = overlayRef.current.querySelector<HTMLElement>('a, button')\n firstFocusable?.focus()\n }\n }, [showMore])\n\n const isActive = (path: string, exact = false) => {\n if (exact || path === '/') {\n return currentPath === path\n }\n return currentPath.startsWith(path)\n }\n\n // Check if any \"more\" item is active\n const isMoreActive = moreItems.some((item) =>\n isActive(item.href, item.exact),\n )\n\n return (\n <>\n {/* More Menu Overlay */}\n <AnimatePresence>\n {showMore && (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events -- backdrop overlay, dismiss via mouse only; keyboard users close via Escape\n <div\n className=\"fixed inset-0 z-overlay md:hidden\"\n onClick={() => setShowMore(false)}\n >\n <div className=\"absolute inset-0 bg-overlay\" />\n { }\n <motion.div\n ref={overlayRef}\n role=\"dialog\"\n aria-label=\"More navigation\"\n initial={{ y: '100%' }}\n animate={{ y: 0 }}\n exit={{ y: '100%' }}\n transition={prefersReducedMotion ? { duration: 0 } : springs.smooth}\n className=\"absolute bottom-[72px] left-0 right-0 rounded-t-bubble border-t border-surface-border-strong bg-surface-overlay p-ds-05 pb-ds-03\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n e.stopPropagation()\n if (e.key === 'Escape') closeMore()\n }}\n >\n <div className=\"mb-ds-04 flex items-center justify-between\">\n <span className=\"text-ds-md font-semibold text-surface-fg\">\n More\n </span>\n <button\n onClick={() => setShowMore(false)}\n aria-label=\"Close more menu\"\n className=\"flex h-ds-sm w-ds-sm items-center justify-center rounded-pill hover:bg-surface-raised-hover\"\n >\n <Icon icon={IconX} size=\"sm\" className=\"text-surface-fg-muted\" />\n </button>\n </div>\n <div className=\"grid grid-cols-4 gap-ds-03\">\n {moreItems.map((item) => (\n <Link\n key={item.href}\n href={item.href}\n onClick={() => setShowMore(false)}\n className={cn(\n 'flex flex-col items-center gap-ds-02b rounded-overlay-lg p-ds-04 text-ds-sm transition-colors ease-productive-standard',\n isActive(item.href, item.exact)\n ? 'bg-surface-raised-hover text-accent-11'\n : 'text-surface-fg-subtle hover:bg-surface-raised-hover',\n )}\n >\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md\"><IconProvider size=\"md\">{normalizeIcon(item.icon)}</IconProvider></span>\n <span className=\"text-center\">\n {item.title}\n </span>\n </Link>\n ))}\n </div>\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n\n {/* Bottom Navigation Bar */}\n <nav\n {...props}\n ref={ref}\n aria-label=\"Mobile navigation\"\n className={cn(\n 'fixed bottom-0 left-0 right-0 z-sticky flex w-full flex-row items-start justify-between border-t border-surface-border-strong bg-surface-chrome px-ds-05 pb-safe pt-0 md:hidden',\n className,\n )}\n >\n {primaryItems.map((item) => (\n <BottomNavLink\n key={item.href}\n item={item}\n isActive={isActive(item.href, item.exact)}\n />\n ))}\n\n {/* More Button */}\n {moreItems.length > 0 && (\n <motion.button\n type=\"button\"\n onClick={() => setShowMore(!showMore)}\n aria-label=\"More navigation options\"\n aria-expanded={showMore}\n whileTap={prefersReducedMotion ? undefined : { y: -2 }}\n transition={prefersReducedMotion ? { duration: 0 } : springs.snappy}\n className={cn(\n 'flex h-16 max-w-[70px] flex-1 cursor-pointer flex-col items-center gap-ds-02 p-ds-02 pt-0 text-ds-sm',\n showMore || isMoreActive\n ? 'font-semibold text-accent-11'\n : 'text-surface-fg-subtle',\n )}\n >\n <div className=\"relative flex w-full flex-col items-center gap-ds-02\">\n {(showMore || isMoreActive) && (\n <motion.div\n layoutId=\"bottom-nav-indicator\"\n className=\"absolute top-0 h-[3px] w-full rounded-b-control-inner bg-accent-9 p-0\"\n aria-hidden=\"true\"\n transition={prefersReducedMotion ? { duration: 0 } : springs.snappy}\n />\n )}\n <div className=\"p-ds-03\">\n <Icon icon={IconDots} />\n </div>\n <span className=\"text-center\">More</span>\n </div>\n </motion.button>\n )}\n </nav>\n </>\n )\n },\n)\nBottomNavbar.displayName = 'BottomNavbar'\n\nexport { BottomNavbar }\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { n as e, t } from "../_chunks/link-context.js";
2
+ import { LinkProvider as e, useLink as t } from "../_chunks/link-context.js";
3
3
  import { CommandRegistryProvider as n, useCommandRegistry as r } from "./command-registry.js";
4
4
  import { AppCommandPalette as i } from "./app-command-palette.js";
5
5
  import "./link-context.js";
@@ -8,4 +8,4 @@ import { NotificationCenter as o } from "./notification-center.js";
8
8
  import { NotificationPreferences as s } from "./notification-preferences.js";
9
9
  import { AppSidebar as c } from "./sidebar.js";
10
10
  import { TopBar as l } from "./top-bar.js";
11
- export { i as AppCommandPalette, c as AppSidebar, a as BottomNavbar, n as CommandRegistryProvider, t as LinkProvider, o as NotificationCenter, s as NotificationPreferences, l as TopBar, r as useCommandRegistry, e as useLink };
11
+ export { i as AppCommandPalette, c as AppSidebar, a as BottomNavbar, n as CommandRegistryProvider, e as LinkProvider, o as NotificationCenter, s as NotificationPreferences, l as TopBar, r as useCommandRegistry, t as useLink };
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import { n as e, t } from "../_chunks/link-context.js";
3
- export { t as LinkProvider, e as useLink };
2
+ import { LinkProvider as e, useLink as t } from "../_chunks/link-context.js";
3
+ export { e as LinkProvider, t as useLink };
@@ -5,7 +5,7 @@ import { Spinner as n } from "../ui/spinner.js";
5
5
  import { Icon as r } from "../ui/icon.js";
6
6
  import { useIsMobile as i } from "../hooks/use-mobile.js";
7
7
  import { Button as a } from "../ui/button.js";
8
- import { i as o, r as s, t as c } from "../_chunks/popover.js";
8
+ import { Popover as o, PopoverContent as s, PopoverTrigger as c } from "../_chunks/popover.js";
9
9
  import { Tooltip as l, TooltipContent as u, TooltipTrigger as d } from "../ui/tooltip.js";
10
10
  import { TruncatedText as f } from "../ui/truncated-text.js";
11
11
  import { Sheet as p, SheetContent as ee, SheetTitle as m, SheetTrigger as h } from "../ui/sheet.js";
@@ -246,12 +246,12 @@ var M = _.forwardRef(({ notifications: a = [], unreadCount: f, open: g, onOpenCh
246
246
  children: "Notifications"
247
247
  }), Q]
248
248
  })]
249
- }) : /* @__PURE__ */ S(c, {
249
+ }) : /* @__PURE__ */ S(o, {
250
250
  open: g,
251
251
  onOpenChange: _,
252
252
  children: [/* @__PURE__ */ S(l, { children: [/* @__PURE__ */ x(d, {
253
253
  asChild: !0,
254
- children: /* @__PURE__ */ x(o, {
254
+ children: /* @__PURE__ */ x(c, {
255
255
  asChild: !0,
256
256
  children: $
257
257
  })
@@ -2,11 +2,11 @@
2
2
  import { IconProvider as e } from "../ui/icon-context.js";
3
3
  import { cn as t } from "../ui/lib/utils.js";
4
4
  import { Avatar as n, AvatarFallback as r, AvatarImage as i } from "../ui/avatar.js";
5
- import { t as a } from "../_chunks/normalize-icon.js";
5
+ import { normalizeIcon as a } from "../_chunks/normalize-icon.js";
6
6
  import { Button as o } from "../ui/button.js";
7
7
  import { Collapsible as s, CollapsibleContent as c, CollapsibleTrigger as l } from "../ui/collapsible.js";
8
8
  import { TruncatedText as u } from "../ui/truncated-text.js";
9
- import { n as d } from "../_chunks/link-context.js";
9
+ import { useLink as d } from "../_chunks/link-context.js";
10
10
  import { Sidebar as f, SidebarContent as p, SidebarFooter as m, SidebarGroup as h, SidebarGroupAction as g, SidebarGroupContent as _, SidebarGroupLabel as v, SidebarHeader as y, SidebarMenu as b, SidebarMenuBadge as x, SidebarMenuButton as S, SidebarMenuItem as C, SidebarMenuSub as w, SidebarMenuSubButton as T, SidebarMenuSubItem as E, SidebarSeparator as D } from "../ui/sidebar.js";
11
11
  import "./link-context.js";
12
12
  import * as O from "react";
@@ -3,7 +3,7 @@ import { IconProvider as e } from "../ui/icon-context.js";
3
3
  import { cn as t } from "../ui/lib/utils.js";
4
4
  import { Icon as n } from "../ui/icon.js";
5
5
  import { Avatar as r, AvatarFallback as i, AvatarImage as a } from "../ui/avatar.js";
6
- import { t as o } from "../_chunks/normalize-icon.js";
6
+ import { normalizeIcon as o } from "../_chunks/normalize-icon.js";
7
7
  import { DropdownMenu as s, DropdownMenuContent as c, DropdownMenuItem as l, DropdownMenuSeparator as u, DropdownMenuTrigger as d } from "../ui/dropdown-menu.js";
8
8
  import { Tooltip as f, TooltipContent as p, TooltipTrigger as m } from "../ui/tooltip.js";
9
9
  import { TruncatedText as h } from "../ui/truncated-text.js";
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { Fn as e, In as t, Ln as n, Nn as r, Pn as i } from "../_chunks/primitives.js";
2
+ import { Content2$8 as e, Header as t, Item$2 as n, Root2$10 as r, Trigger2$1 as i } from "../_chunks/primitives.js";
3
3
  import { tweens as a } from "./lib/motion.js";
4
4
  import { cn as o } from "./lib/utils.js";
5
5
  import { Icon as s } from "./icon.js";
@@ -8,47 +8,47 @@ import { jsx as l, jsxs as u } from "react/jsx-runtime";
8
8
  import { IconChevronDown as d } from "@tabler/icons-react";
9
9
  import { motion as f } from "framer-motion";
10
10
  //#region src/ui/accordion.tsx
11
- var p = t, m = c.forwardRef(({ className: t, ...n }, r) => /* @__PURE__ */ l(e, {
11
+ var p = r, m = c.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ l(n, {
12
12
  ref: r,
13
- className: o("border-b border-surface-border", t),
14
- ...n
13
+ className: o("border-b border-surface-border", e),
14
+ ...t
15
15
  }));
16
16
  m.displayName = "AccordionItem";
17
- var h = c.forwardRef(({ className: e, children: t, chevronPosition: r = "right", ...a }, c) => {
17
+ var h = c.forwardRef(({ className: e, children: n, chevronPosition: r = "right", ...a }, c) => {
18
18
  let f = /* @__PURE__ */ l(s, {
19
19
  icon: d,
20
20
  size: "sm",
21
21
  className: "shrink-0 text-surface-fg-muted transition-transform duration-moderate-02 ease-productive-standard group-data-[state=open]:rotate-180"
22
22
  });
23
- return /* @__PURE__ */ l(i, {
23
+ return /* @__PURE__ */ l(t, {
24
24
  className: "flex",
25
- children: /* @__PURE__ */ u(n, {
25
+ children: /* @__PURE__ */ u(i, {
26
26
  ref: c,
27
27
  className: o("group flex flex-1 items-center justify-between py-ds-05 text-left text-ds-md font-medium hover:bg-surface-raised rounded-control data-[state=open]:bg-surface-raised focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9", e),
28
28
  ...a,
29
29
  children: [
30
30
  r === "left" && f,
31
- t,
31
+ n,
32
32
  r === "right" && f
33
33
  ]
34
34
  })
35
35
  });
36
36
  });
37
- h.displayName = n.displayName;
38
- var g = c.forwardRef(({ className: e, children: t, ...n }, i) => /* @__PURE__ */ l(r, {
37
+ h.displayName = i.displayName;
38
+ var g = c.forwardRef(({ className: t, children: n, ...r }, i) => /* @__PURE__ */ l(e, {
39
39
  ref: i,
40
40
  className: "w-full overflow-hidden text-ds-md data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up",
41
- ...n,
41
+ ...r,
42
42
  children: /* @__PURE__ */ l(f.div, {
43
43
  initial: !1,
44
44
  animate: { opacity: 1 },
45
45
  transition: a.fade,
46
46
  children: /* @__PURE__ */ l("div", {
47
- className: o("pb-ds-05 pt-ds-02", e),
48
- children: t
47
+ className: o("pb-ds-05 pt-ds-02", t),
48
+ children: n
49
49
  })
50
50
  })
51
51
  }));
52
- g.displayName = r.displayName;
52
+ g.displayName = e.displayName;
53
53
  //#endregion
54
54
  export { p as Accordion, g as AccordionContent, m as AccordionItem, h as AccordionTrigger };