@devalok/shilp-sutra 0.57.0 → 0.59.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 (258) hide show
  1. package/MIGRATION.md +91 -0
  2. package/dist/_chunks/badge-group.js +75 -188
  3. package/dist/_chunks/badge-group.js.map +1 -1
  4. package/dist/_chunks/chat.js +244 -243
  5. package/dist/_chunks/chat.js.map +1 -1
  6. package/dist/_chunks/image-preview.js +71 -70
  7. package/dist/_chunks/image-preview.js.map +1 -1
  8. package/dist/_chunks/motion-preference.js +15 -0
  9. package/dist/_chunks/motion-preference.js.map +1 -0
  10. package/dist/_chunks/motion-provider.js +1 -1
  11. package/dist/_chunks/motion-provider.js.map +1 -1
  12. package/dist/_chunks/popover.js +50 -49
  13. package/dist/_chunks/popover.js.map +1 -1
  14. package/dist/_chunks/primitives-internal.js +29 -29
  15. package/dist/_chunks/primitives-internal.js.map +1 -1
  16. package/dist/_chunks/shared.js +48 -47
  17. package/dist/_chunks/shared.js.map +1 -1
  18. package/dist/_chunks/success.js +34 -34
  19. package/dist/_chunks/tree-view.js +1 -1
  20. package/dist/_chunks/tree-view.js.map +1 -1
  21. package/dist/ai/block-renderer.js +8 -8
  22. package/dist/ai/command-bar.js +65 -65
  23. package/dist/ai/command-bar.js.map +1 -1
  24. package/dist/ai/conversation.js +35 -35
  25. package/dist/ai/conversation.js.map +1 -1
  26. package/dist/ai/index.js +4 -4
  27. package/dist/composed/activity-feed.d.ts.map +1 -1
  28. package/dist/composed/activity-feed.js +108 -107
  29. package/dist/composed/activity-feed.js.map +1 -1
  30. package/dist/composed/command-palette.js +137 -137
  31. package/dist/composed/command-palette.js.map +1 -1
  32. package/dist/composed/content-card.js +1 -1
  33. package/dist/composed/content-card.js.map +1 -1
  34. package/dist/composed/date-picker/index.js +5 -5
  35. package/dist/composed/date-picker/index.js.map +1 -1
  36. package/dist/composed/empty-state.js +4 -4
  37. package/dist/composed/file-preview/image-preview.d.ts.map +1 -1
  38. package/dist/composed/file-preview/shared.d.ts.map +1 -1
  39. package/dist/composed/file-preview/video-preview.d.ts.map +1 -1
  40. package/dist/composed/file-preview.js +151 -150
  41. package/dist/composed/file-preview.js.map +1 -1
  42. package/dist/composed/filter-bar.d.ts.map +1 -1
  43. package/dist/composed/filter-bar.js +53 -52
  44. package/dist/composed/filter-bar.js.map +1 -1
  45. package/dist/composed/form-section.d.ts.map +1 -1
  46. package/dist/composed/form-section.js +38 -37
  47. package/dist/composed/form-section.js.map +1 -1
  48. package/dist/composed/master-detail.d.ts.map +1 -1
  49. package/dist/composed/master-detail.js +1 -1
  50. package/dist/composed/master-detail.js.map +1 -1
  51. package/dist/composed/multi-select-popover.d.ts.map +1 -1
  52. package/dist/composed/multi-select-popover.js +109 -108
  53. package/dist/composed/multi-select-popover.js.map +1 -1
  54. package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
  55. package/dist/composed/rich-chat-input/reply-banner.d.ts.map +1 -1
  56. package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -1
  57. package/dist/composed/rich-chat-input.d.ts.map +1 -1
  58. package/dist/composed/rich-chat-input.js +467 -466
  59. package/dist/composed/rich-chat-input.js.map +1 -1
  60. package/dist/composed/rich-text-editor.js +3 -3
  61. package/dist/composed/rich-text-editor.js.map +1 -1
  62. package/dist/composed/schedule-view.js +2 -2
  63. package/dist/composed/schedule-view.js.map +1 -1
  64. package/dist/composed/status-badge.d.ts.map +1 -1
  65. package/dist/composed/status-badge.js +29 -28
  66. package/dist/composed/status-badge.js.map +1 -1
  67. package/dist/motion/index.d.ts +1 -0
  68. package/dist/motion/index.d.ts.map +1 -1
  69. package/dist/motion/index.js +2 -15
  70. package/dist/motion/motion-preference.d.ts +36 -0
  71. package/dist/motion/motion-preference.d.ts.map +1 -0
  72. package/dist/motion/motion-provider.d.ts +2 -1
  73. package/dist/motion/motion-provider.d.ts.map +1 -1
  74. package/dist/motion/primitives-index.js +103 -102
  75. package/dist/motion/primitives-index.js.map +1 -1
  76. package/dist/motion/primitives.d.ts.map +1 -1
  77. package/dist/shell/bottom-navbar.js +19 -19
  78. package/dist/shell/bottom-navbar.js.map +1 -1
  79. package/dist/shell/index.d.ts +1 -1
  80. package/dist/shell/index.d.ts.map +1 -1
  81. package/dist/shell/notification-center.d.ts +17 -0
  82. package/dist/shell/notification-center.d.ts.map +1 -1
  83. package/dist/shell/notification-center.js +109 -104
  84. package/dist/shell/notification-center.js.map +1 -1
  85. package/dist/shell/notification-preferences.js +1 -1
  86. package/dist/shell/notification-preferences.js.map +1 -1
  87. package/dist/shell/top-bar.js +1 -1
  88. package/dist/shell/top-bar.js.map +1 -1
  89. package/dist/tokens/index.css +1 -0
  90. package/dist/tokens/palettes.css +292 -0
  91. package/dist/tokens/semantic.css +72 -8
  92. package/dist/tokens/shilp-sutra.css +1 -0
  93. package/dist/tokens/utilities.css +10 -7
  94. package/dist/ui/accordion.d.ts.map +1 -1
  95. package/dist/ui/accordion.js +27 -26
  96. package/dist/ui/accordion.js.map +1 -1
  97. package/dist/ui/alert-dialog.d.ts.map +1 -1
  98. package/dist/ui/alert-dialog.js +60 -59
  99. package/dist/ui/alert-dialog.js.map +1 -1
  100. package/dist/ui/alert.d.ts.map +1 -1
  101. package/dist/ui/alert.js +55 -113
  102. package/dist/ui/alert.js.map +1 -1
  103. package/dist/ui/autocomplete.js +80 -80
  104. package/dist/ui/autocomplete.js.map +1 -1
  105. package/dist/ui/avatar.d.ts.map +1 -1
  106. package/dist/ui/avatar.js +69 -68
  107. package/dist/ui/avatar.js.map +1 -1
  108. package/dist/ui/badge-indicator.d.ts +4 -8
  109. package/dist/ui/badge-indicator.d.ts.map +1 -1
  110. package/dist/ui/badge-indicator.js +3 -8
  111. package/dist/ui/badge-indicator.js.map +1 -1
  112. package/dist/ui/badge.d.ts +8 -1
  113. package/dist/ui/badge.d.ts.map +1 -1
  114. package/dist/ui/banner.d.ts.map +1 -1
  115. package/dist/ui/banner.js +42 -40
  116. package/dist/ui/banner.js.map +1 -1
  117. package/dist/ui/button-group.d.ts.map +1 -1
  118. package/dist/ui/button-group.js +3 -23
  119. package/dist/ui/button-group.js.map +1 -1
  120. package/dist/ui/button.d.ts +10 -1
  121. package/dist/ui/button.d.ts.map +1 -1
  122. package/dist/ui/button.js +79 -212
  123. package/dist/ui/button.js.map +1 -1
  124. package/dist/ui/card.d.ts.map +1 -1
  125. package/dist/ui/card.js +75 -72
  126. package/dist/ui/card.js.map +1 -1
  127. package/dist/ui/charts/radar-chart.d.ts.map +1 -1
  128. package/dist/ui/charts/radar-chart.js +1 -1
  129. package/dist/ui/charts/radar-chart.js.map +1 -1
  130. package/dist/ui/chat/message-list.d.ts.map +1 -1
  131. package/dist/ui/chat/message.d.ts.map +1 -1
  132. package/dist/ui/chat/typing-indicator.d.ts.map +1 -1
  133. package/dist/ui/code.js +1 -1
  134. package/dist/ui/code.js.map +1 -1
  135. package/dist/ui/color-input.d.ts.map +1 -1
  136. package/dist/ui/color-input.js +151 -150
  137. package/dist/ui/color-input.js.map +1 -1
  138. package/dist/ui/combobox.d.ts +14 -0
  139. package/dist/ui/combobox.d.ts.map +1 -1
  140. package/dist/ui/combobox.js +152 -148
  141. package/dist/ui/combobox.js.map +1 -1
  142. package/dist/ui/context-menu.d.ts.map +1 -1
  143. package/dist/ui/context-menu.js +70 -69
  144. package/dist/ui/context-menu.js.map +1 -1
  145. package/dist/ui/data-table-body.js +2 -2
  146. package/dist/ui/data-table-body.js.map +1 -1
  147. package/dist/ui/data-table-context.js +2 -2
  148. package/dist/ui/data-table-context.js.map +1 -1
  149. package/dist/ui/data-table-header.d.ts.map +1 -1
  150. package/dist/ui/data-table-header.js +41 -40
  151. package/dist/ui/data-table-header.js.map +1 -1
  152. package/dist/ui/data-table-pagination.js +2 -2
  153. package/dist/ui/data-table-pagination.js.map +1 -1
  154. package/dist/ui/dialog.d.ts.map +1 -1
  155. package/dist/ui/dialog.js +61 -60
  156. package/dist/ui/dialog.js.map +1 -1
  157. package/dist/ui/dot.d.ts.map +1 -1
  158. package/dist/ui/dot.js +10 -41
  159. package/dist/ui/dot.js.map +1 -1
  160. package/dist/ui/dropdown-menu.d.ts.map +1 -1
  161. package/dist/ui/dropdown-menu.js +79 -78
  162. package/dist/ui/dropdown-menu.js.map +1 -1
  163. package/dist/ui/file-upload.d.ts.map +1 -1
  164. package/dist/ui/file-upload.js +116 -115
  165. package/dist/ui/file-upload.js.map +1 -1
  166. package/dist/ui/form.d.ts.map +1 -1
  167. package/dist/ui/form.js +27 -26
  168. package/dist/ui/form.js.map +1 -1
  169. package/dist/ui/hover-card.d.ts.map +1 -1
  170. package/dist/ui/hover-card.js +26 -25
  171. package/dist/ui/hover-card.js.map +1 -1
  172. package/dist/ui/icon.js +7 -7
  173. package/dist/ui/index.d.ts +2 -2
  174. package/dist/ui/index.d.ts.map +1 -1
  175. package/dist/ui/index.js +3 -3
  176. package/dist/ui/index.js.map +1 -1
  177. package/dist/ui/input.js +1 -1
  178. package/dist/ui/input.js.map +1 -1
  179. package/dist/ui/menubar.d.ts.map +1 -1
  180. package/dist/ui/menubar.js +73 -72
  181. package/dist/ui/menubar.js.map +1 -1
  182. package/dist/ui/navigation-menu.d.ts.map +1 -1
  183. package/dist/ui/navigation-menu.js +80 -79
  184. package/dist/ui/navigation-menu.js.map +1 -1
  185. package/dist/ui/popover.d.ts.map +1 -1
  186. package/dist/ui/progress.d.ts.map +1 -1
  187. package/dist/ui/progress.js +72 -68
  188. package/dist/ui/progress.js.map +1 -1
  189. package/dist/ui/radio.d.ts.map +1 -1
  190. package/dist/ui/radio.js +32 -31
  191. package/dist/ui/radio.js.map +1 -1
  192. package/dist/ui/search-input.d.ts.map +1 -1
  193. package/dist/ui/search-input.js +28 -27
  194. package/dist/ui/search-input.js.map +1 -1
  195. package/dist/ui/select.d.ts.map +1 -1
  196. package/dist/ui/select.js +64 -63
  197. package/dist/ui/select.js.map +1 -1
  198. package/dist/ui/sidebar.d.ts.map +1 -1
  199. package/dist/ui/sidebar.js +4 -4
  200. package/dist/ui/sidebar.js.map +1 -1
  201. package/dist/ui/slider.d.ts +63 -9
  202. package/dist/ui/slider.d.ts.map +1 -1
  203. package/dist/ui/slider.js +74 -32
  204. package/dist/ui/slider.js.map +1 -1
  205. package/dist/ui/split-button.d.ts +8 -2
  206. package/dist/ui/split-button.d.ts.map +1 -1
  207. package/dist/ui/split-button.js +49 -95
  208. package/dist/ui/split-button.js.map +1 -1
  209. package/dist/ui/stat-card.d.ts.map +1 -1
  210. package/dist/ui/stat-card.js +89 -88
  211. package/dist/ui/stat-card.js.map +1 -1
  212. package/dist/ui/stat-flash.js +16 -16
  213. package/dist/ui/stepper.d.ts.map +1 -1
  214. package/dist/ui/stepper.js +63 -62
  215. package/dist/ui/stepper.js.map +1 -1
  216. package/dist/ui/table.js +3 -3
  217. package/dist/ui/table.js.map +1 -1
  218. package/dist/ui/tabs.d.ts.map +1 -1
  219. package/dist/ui/tabs.js +67 -66
  220. package/dist/ui/tabs.js.map +1 -1
  221. package/dist/ui/textarea.js +1 -1
  222. package/dist/ui/textarea.js.map +1 -1
  223. package/dist/ui/toast.d.ts.map +1 -1
  224. package/dist/ui/toast.js +195 -194
  225. package/dist/ui/toast.js.map +1 -1
  226. package/dist/ui/toggle.d.ts.map +1 -1
  227. package/dist/ui/toggle.js +24 -22
  228. package/dist/ui/toggle.js.map +1 -1
  229. package/dist/ui/tooltip.d.ts.map +1 -1
  230. package/dist/ui/tooltip.js +37 -36
  231. package/dist/ui/tooltip.js.map +1 -1
  232. package/dist/ui/tree-view/tree-item.d.ts.map +1 -1
  233. package/docs/recipes/customize-brand.md +58 -0
  234. package/docs/recipes/install-astro.md +1 -1
  235. package/docs/recipes/install-next-app-router.md +1 -1
  236. package/docs/recipes/install-next-pages.md +22 -1
  237. package/docs/recipes/install-remix.md +1 -1
  238. package/docs/recipes/install-tanstack-start.md +1 -1
  239. package/docs/recipes/install-vite.md +2 -1
  240. package/docs/recipes/server-components.md +7 -4
  241. package/docs/recipes/troubleshoot.md +1 -0
  242. package/llms.txt +1 -1
  243. package/mcp-manifest.json +9 -4
  244. package/package.json +3 -2
  245. package/skill/SKILL.md +1 -1
  246. package/skill/references/components.md +1 -1
  247. package/skill/references/customize-brand.md +58 -0
  248. package/skill/references/server-components.md +7 -4
  249. package/skill/references/setup-astro.md +1 -1
  250. package/skill/references/setup-next-app-router.md +1 -1
  251. package/skill/references/setup-next-pages.md +22 -1
  252. package/skill/references/setup-remix.md +1 -1
  253. package/skill/references/setup-tanstack-start.md +1 -1
  254. package/skill/references/setup-vite.md +2 -1
  255. package/skill/references/troubleshoot.md +1 -0
  256. package/dist/motion/check-motion-provider.d.ts +0 -2
  257. package/dist/motion/check-motion-provider.d.ts.map +0 -1
  258. package/dist/motion/index.js.map +0 -1
@@ -0,0 +1,36 @@
1
+ import * as React from 'react';
2
+ type MotionPreferenceProps = {
3
+ children: React.ReactNode;
4
+ };
5
+ /**
6
+ * Makes the OS `prefers-reduced-motion` setting the DEFAULT for a component's
7
+ * animations, instead of something the consumer has to opt into.
8
+ *
9
+ * Framer Motion's `MotionConfigContext` defaults to `reducedMotion: "never"` —
10
+ * meaning every `motion.*` element ignores the OS setting until some ancestor
11
+ * says otherwise. Our only ancestor that says otherwise is `<MotionProvider>`,
12
+ * which consumers are not required to mount, so out of the box the whole
13
+ * library animated straight through a reduced-motion preference.
14
+ *
15
+ * Wrapping a component's root in this fixes that for the subtree. Under
16
+ * `"user"`, Framer suppresses exactly the positional keys — width, height,
17
+ * top/left/right/bottom and every transform — and leaves opacity, colour and
18
+ * filter animating normally. That is the behaviour WCAG 2.3.3 asks for: kill
19
+ * the movement, keep the fade.
20
+ *
21
+ * It renders no DOM, and defers to anything that has already made the call:
22
+ *
23
+ * - a mounted `<MotionProvider>` owns the decision, including the deliberate
24
+ * `reducedMotion={false}` "animate regardless" override;
25
+ * - a bare `<MotionConfig>` that has moved off the default was set on purpose;
26
+ * - nesting is self-cancelling — the outermost wrapper configures the context,
27
+ * and every one below it sees a non-default value and passes straight through.
28
+ *
29
+ * The one case it cannot read is a consumer who mounts `<MotionConfig
30
+ * reducedMotion="never">` by hand to force animation on. That is
31
+ * indistinguishable from the framework default, so this wrapper overrides it.
32
+ * `<MotionProvider reducedMotion={false}>` is the supported way to express it.
33
+ */
34
+ declare function MotionPreference({ children }: MotionPreferenceProps): React.JSX.Element;
35
+ export { MotionPreference, type MotionPreferenceProps };
36
+ //# sourceMappingURL=motion-preference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motion-preference.d.ts","sourceRoot":"","sources":["../../src/motion/motion-preference.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,iBAAS,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE,qBAAqB,qBAQ5D;AAED,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,CAAA"}
@@ -6,6 +6,7 @@ type MotionContextValue = {
6
6
  tweens: typeof tweens;
7
7
  reducedMotion: boolean;
8
8
  };
9
+ declare const MotionContext: React.Context<MotionContextValue | null>;
9
10
  type MotionProviderProps = {
10
11
  children: React.ReactNode;
11
12
  /** 'user' = detect OS preference, true = force off, false = force on */
@@ -13,5 +14,5 @@ type MotionProviderProps = {
13
14
  };
14
15
  declare function MotionProvider({ children, reducedMotion }: MotionProviderProps): React.JSX.Element;
15
16
  declare function useMotion(): MotionContextValue;
16
- export { MotionProvider, type MotionProviderProps, useMotion };
17
+ export { MotionContext, MotionProvider, type MotionProviderProps, useMotion };
17
18
  //# sourceMappingURL=motion-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"motion-provider.d.ts","sourceRoot":"","sources":["../../src/motion/motion-provider.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAElD,KAAK,iBAAiB,GAAG,MAAM,GAAG,OAAO,CAAA;AAEzC,KAAK,kBAAkB,GAAG;IACxB,OAAO,EAAE,OAAO,OAAO,CAAA;IACvB,MAAM,EAAE,OAAO,MAAM,CAAA;IACrB,aAAa,EAAE,OAAO,CAAA;CACvB,CAAA;AAOD,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,wEAAwE;IACxE,aAAa,CAAC,EAAE,iBAAiB,CAAA;CAClC,CAAA;AAED,iBAAS,cAAc,CAAC,EAAE,QAAQ,EAAE,aAAsB,EAAE,EAAE,mBAAmB,qBAgBhF;AAED,iBAAS,SAAS,IAAI,kBAAkB,CAMvC;AAED,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAC,SAAS,EAAE,CAAA"}
1
+ {"version":3,"file":"motion-provider.d.ts","sourceRoot":"","sources":["../../src/motion/motion-provider.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAElD,KAAK,iBAAiB,GAAG,MAAM,GAAG,OAAO,CAAA;AAEzC,KAAK,kBAAkB,GAAG;IACxB,OAAO,EAAE,OAAO,OAAO,CAAA;IACvB,MAAM,EAAE,OAAO,MAAM,CAAA;IACrB,aAAa,EAAE,OAAO,CAAA;CACvB,CAAA;AAKD,QAAA,MAAM,aAAa,0CAAuD,CAAA;AAE1E,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,wEAAwE;IACxE,aAAa,CAAC,EAAE,iBAAiB,CAAA;CAClC,CAAA;AAED,iBAAS,cAAc,CAAC,EAAE,QAAQ,EAAE,aAAsB,EAAE,EAAE,mBAAmB,qBAgBhF;AAED,iBAAS,SAAS,IAAI,kBAAkB,CAMvC;AAED,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAC,SAAS,EAAE,CAAA"}
@@ -1,45 +1,46 @@
1
1
  "use client";
2
2
  import { springs as e, tweens as t } from "../ui/lib/motion.js";
3
- import { cn as n } from "../ui/lib/utils.js";
4
- import * as r from "react";
5
- import { jsx as i } from "react/jsx-runtime";
6
- import { AnimatePresence as a, motion as o } from "framer-motion";
3
+ import { MotionPreference as n } from "../_chunks/motion-preference.js";
4
+ import { cn as r } from "../ui/lib/utils.js";
5
+ import * as i from "react";
6
+ import { jsx as a } from "react/jsx-runtime";
7
+ import { AnimatePresence as o, motion as s } from "framer-motion";
7
8
  //#region src/motion/primitives.tsx
8
- var s = r.forwardRef(({ show: e, children: r, className: s, layout: c, layoutId: l, whileInView: u, viewportOnce: d = !0, viewportMargin: f = "-50px", ...p }, m) => {
9
- let h = u ? {
9
+ var c = i.forwardRef(({ show: e, children: i, className: c, layout: l, layoutId: u, whileInView: d, viewportOnce: f = !0, viewportMargin: p = "-50px", ...m }, h) => {
10
+ let g = d ? {
10
11
  initial: "hidden",
11
12
  whileInView: "visible",
12
13
  viewport: {
13
- once: d,
14
- margin: f
14
+ once: f,
15
+ margin: p
15
16
  }
16
17
  } : {};
17
- return /* @__PURE__ */ i(a, { children: e && /* @__PURE__ */ i(o.div, {
18
- ref: m,
18
+ return /* @__PURE__ */ a(n, { children: /* @__PURE__ */ a(o, { children: e && /* @__PURE__ */ a(s.div, {
19
+ ref: h,
19
20
  initial: { opacity: 0 },
20
21
  animate: { opacity: 1 },
21
22
  exit: { opacity: 0 },
22
23
  transition: t.fade,
23
- className: n(s),
24
- layout: c,
25
- layoutId: l,
26
- ...h,
27
- ...p,
28
- children: r
29
- }) });
24
+ className: r(c),
25
+ layout: l,
26
+ layoutId: u,
27
+ ...g,
28
+ ...m,
29
+ children: i
30
+ }) }) });
30
31
  });
31
- s.displayName = "MotionFade";
32
- var c = r.forwardRef(({ show: r, children: s, className: c, preset: l = "snappy", layout: u, layoutId: d, whileInView: f, viewportOnce: p = !0, viewportMargin: m = "-50px", ...h }, g) => {
33
- let _ = e[l], v = f ? {
32
+ c.displayName = "MotionFade";
33
+ var l = i.forwardRef(({ show: i, children: c, className: l, preset: u = "snappy", layout: d, layoutId: f, whileInView: p, viewportOnce: m = !0, viewportMargin: h = "-50px", ...g }, _) => {
34
+ let v = e[u], y = p ? {
34
35
  initial: "hidden",
35
36
  whileInView: "visible",
36
37
  viewport: {
37
- once: p,
38
- margin: m
38
+ once: m,
39
+ margin: h
39
40
  }
40
41
  } : {};
41
- return /* @__PURE__ */ i(a, { children: r && /* @__PURE__ */ i(o.div, {
42
- ref: g,
42
+ return /* @__PURE__ */ a(n, { children: /* @__PURE__ */ a(o, { children: i && /* @__PURE__ */ a(s.div, {
43
+ ref: _,
43
44
  initial: {
44
45
  opacity: 0,
45
46
  scale: .96
@@ -53,29 +54,29 @@ var c = r.forwardRef(({ show: r, children: s, className: c, preset: l = "snappy"
53
54
  scale: .96
54
55
  },
55
56
  transition: {
56
- ..._,
57
+ ...v,
57
58
  opacity: t.fade
58
59
  },
59
- className: n(c),
60
- layout: u,
61
- layoutId: d,
62
- ...v,
63
- ...h,
64
- children: s
65
- }) });
60
+ className: r(l),
61
+ layout: d,
62
+ layoutId: f,
63
+ ...y,
64
+ ...g,
65
+ children: c
66
+ }) }) });
66
67
  });
67
- c.displayName = "MotionScale";
68
- var l = r.forwardRef(({ show: r, children: s, className: c, preset: l = "bouncy", layout: u, layoutId: d, whileInView: f, viewportOnce: p = !0, viewportMargin: m = "-50px", ...h }, g) => {
69
- let _ = e[l], v = f ? {
68
+ l.displayName = "MotionScale";
69
+ var u = i.forwardRef(({ show: i, children: c, className: l, preset: u = "bouncy", layout: d, layoutId: f, whileInView: p, viewportOnce: m = !0, viewportMargin: h = "-50px", ...g }, _) => {
70
+ let v = e[u], y = p ? {
70
71
  initial: "hidden",
71
72
  whileInView: "visible",
72
73
  viewport: {
73
- once: p,
74
- margin: m
74
+ once: m,
75
+ margin: h
75
76
  }
76
77
  } : {};
77
- return /* @__PURE__ */ i(a, { children: r && /* @__PURE__ */ i(o.div, {
78
- ref: g,
78
+ return /* @__PURE__ */ a(n, { children: /* @__PURE__ */ a(o, { children: i && /* @__PURE__ */ a(s.div, {
79
+ ref: _,
79
80
  initial: {
80
81
  opacity: 0,
81
82
  scale: .5
@@ -89,37 +90,37 @@ var l = r.forwardRef(({ show: r, children: s, className: c, preset: l = "bouncy"
89
90
  scale: .5
90
91
  },
91
92
  transition: {
92
- ..._,
93
+ ...v,
93
94
  opacity: t.fade
94
95
  },
95
- className: n(c),
96
- layout: u,
97
- layoutId: d,
98
- ...v,
99
- ...h,
100
- children: s
101
- }) });
96
+ className: r(l),
97
+ layout: d,
98
+ layoutId: f,
99
+ ...y,
100
+ ...g,
101
+ children: c
102
+ }) }) });
102
103
  });
103
- l.displayName = "MotionPop";
104
- var u = r.forwardRef(({ show: r, children: s, className: c, preset: l = "smooth", direction: u = "up", layout: d, layoutId: f, whileInView: p, viewportOnce: m = !0, viewportMargin: h = "-50px", ...g }, _) => {
105
- let v = e[l], y = {
104
+ u.displayName = "MotionPop";
105
+ var d = i.forwardRef(({ show: i, children: c, className: l, preset: u = "smooth", direction: d = "up", layout: f, layoutId: p, whileInView: m, viewportOnce: h = !0, viewportMargin: g = "-50px", ..._ }, v) => {
106
+ let y = e[u], b = {
106
107
  up: { y: 16 },
107
108
  down: { y: -16 },
108
109
  left: { x: 16 },
109
110
  right: { x: -16 }
110
- }[u], b = p ? {
111
+ }[d], x = m ? {
111
112
  initial: "hidden",
112
113
  whileInView: "visible",
113
114
  viewport: {
114
- once: m,
115
- margin: h
115
+ once: h,
116
+ margin: g
116
117
  }
117
118
  } : {};
118
- return /* @__PURE__ */ i(a, { children: r && /* @__PURE__ */ i(o.div, {
119
- ref: _,
119
+ return /* @__PURE__ */ a(n, { children: /* @__PURE__ */ a(o, { children: i && /* @__PURE__ */ a(s.div, {
120
+ ref: v,
120
121
  initial: {
121
122
  opacity: 0,
122
- ...y
123
+ ...b
123
124
  },
124
125
  animate: {
125
126
  opacity: 1,
@@ -128,27 +129,27 @@ var u = r.forwardRef(({ show: r, children: s, className: c, preset: l = "smooth"
128
129
  },
129
130
  exit: {
130
131
  opacity: 0,
131
- ...y
132
+ ...b
132
133
  },
133
134
  transition: {
134
- ...v,
135
+ ...y,
135
136
  opacity: t.fade
136
137
  },
137
- className: n(c),
138
- layout: d,
139
- layoutId: f,
140
- ...b,
141
- ...g,
142
- children: s
143
- }) });
138
+ className: r(l),
139
+ layout: f,
140
+ layoutId: p,
141
+ ...x,
142
+ ..._,
143
+ children: c
144
+ }) }) });
144
145
  });
145
- u.displayName = "MotionSlide";
146
- var d = r.forwardRef(({ show: r, children: s, className: c, preset: l = "gentle", layout: u, layoutId: d, ...f }, p) => {
147
- let m = e[l];
148
- return /* @__PURE__ */ i(a, {
146
+ d.displayName = "MotionSlide";
147
+ var f = i.forwardRef(({ show: i, children: c, className: l, preset: u = "gentle", layout: d, layoutId: f, ...p }, m) => {
148
+ let h = e[u];
149
+ return /* @__PURE__ */ a(n, { children: /* @__PURE__ */ a(o, {
149
150
  initial: !1,
150
- children: r && /* @__PURE__ */ i(o.div, {
151
- ref: p,
151
+ children: i && /* @__PURE__ */ a(s.div, {
152
+ ref: m,
152
153
  initial: {
153
154
  height: 0,
154
155
  opacity: 0,
@@ -165,44 +166,44 @@ var d = r.forwardRef(({ show: r, children: s, className: c, preset: l = "gentle"
165
166
  overflow: "hidden"
166
167
  },
167
168
  transition: {
168
- ...m,
169
+ ...h,
169
170
  opacity: t.fade
170
171
  },
171
- className: n(c),
172
- layout: u,
173
- layoutId: d,
174
- ...f,
175
- children: s
172
+ className: r(l),
173
+ layout: d,
174
+ layoutId: f,
175
+ ...p,
176
+ children: c
176
177
  })
177
- });
178
+ }) });
178
179
  });
179
- d.displayName = "MotionCollapse";
180
- var f = r.forwardRef(({ children: e, className: t, delay: r = .04, whileInView: a, viewportOnce: s = !0, viewportMargin: c = "-50px", ...l }, u) => {
181
- let d = {
180
+ f.displayName = "MotionCollapse";
181
+ var p = i.forwardRef(({ children: e, className: t, delay: i = .04, whileInView: o, viewportOnce: c = !0, viewportMargin: l = "-50px", ...u }, d) => {
182
+ let f = {
182
183
  hidden: {},
183
- visible: { transition: { staggerChildren: r } }
184
- }, f = a ? {
184
+ visible: { transition: { staggerChildren: i } }
185
+ }, p = o ? {
185
186
  initial: "hidden",
186
187
  whileInView: "visible",
187
188
  viewport: {
188
- once: s,
189
- margin: c
189
+ once: c,
190
+ margin: l
190
191
  }
191
192
  } : {
192
193
  initial: "hidden",
193
194
  animate: "visible"
194
195
  };
195
- return /* @__PURE__ */ i(o.div, {
196
- ref: u,
197
- variants: d,
198
- className: n(t),
199
- ...f,
200
- ...l,
196
+ return /* @__PURE__ */ a(n, { children: /* @__PURE__ */ a(s.div, {
197
+ ref: d,
198
+ variants: f,
199
+ className: r(t),
200
+ ...p,
201
+ ...u,
201
202
  children: e
202
- });
203
+ }) });
203
204
  });
204
- f.displayName = "MotionStagger";
205
- var p = {
205
+ p.displayName = "MotionStagger";
206
+ var m = {
206
207
  hidden: {
207
208
  opacity: 0,
208
209
  y: 8
@@ -215,13 +216,13 @@ var p = {
215
216
  opacity: t.fade
216
217
  }
217
218
  }
218
- }, m = r.forwardRef(({ children: e, className: t, ...r }, a) => /* @__PURE__ */ i(o.div, {
219
- ref: a,
220
- variants: p,
221
- className: n(t),
222
- ...r,
219
+ }, h = i.forwardRef(({ children: e, className: t, ...i }, o) => /* @__PURE__ */ a(n, { children: /* @__PURE__ */ a(s.div, {
220
+ ref: o,
221
+ variants: m,
222
+ className: r(t),
223
+ ...i,
223
224
  children: e
224
- }));
225
- m.displayName = "MotionStaggerItem";
225
+ }) }));
226
+ h.displayName = "MotionStaggerItem";
226
227
  //#endregion
227
- export { d as MotionCollapse, s as MotionFade, l as MotionPop, c as MotionScale, u as MotionSlide, f as MotionStagger, m as MotionStaggerItem };
228
+ export { f as MotionCollapse, c as MotionFade, u as MotionPop, l as MotionScale, d as MotionSlide, p as MotionStagger, h as MotionStaggerItem };
@@ -1 +1 @@
1
- {"version":3,"file":"primitives-index.js","names":[],"sources":["../../src/motion/primitives.tsx"],"sourcesContent":["'use client'\n\nimport { AnimatePresence, type HTMLMotionProps,motion, type Transition, type Variants } from 'framer-motion'\nimport * as React from 'react'\n\nimport type { SpringPreset } from '../ui/lib/motion'\nimport { springs, tweens } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\n\n// ── Shared types ──\n\ntype MotionDivProps = Omit<HTMLMotionProps<'div'>, 'ref'>\n\ntype MotionPrimitiveProps = {\n show: boolean\n children: React.ReactNode\n className?: string\n preset?: SpringPreset\n layout?: boolean | 'position' | 'size' | 'preserve-aspect'\n layoutId?: string\n whileInView?: boolean\n viewportOnce?: boolean\n viewportMargin?: string\n}\n\n// ── MotionFade ──\n// Default: fade tween only (no spring needed for pure opacity)\n\nconst MotionFade = React.forwardRef<HTMLDivElement, MotionPrimitiveProps & MotionDivProps>(\n ({ show, children, className, layout, layoutId, whileInView, viewportOnce = true, viewportMargin = '-50px', ...rest }, ref) => {\n const inViewProps = whileInView ? {\n initial: 'hidden',\n whileInView: 'visible',\n viewport: { once: viewportOnce, margin: viewportMargin },\n } : {}\n\n return (\n <AnimatePresence>\n {show && (\n <motion.div\n ref={ref}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={tweens.fade}\n className={cn(className)}\n layout={layout}\n layoutId={layoutId}\n {...inViewProps}\n {...rest}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n )\n },\n)\nMotionFade.displayName = 'MotionFade'\n\n// ── MotionScale ──\n// Default: snappy spring for scale + fade tween for opacity\n\nconst MotionScale = React.forwardRef<HTMLDivElement, MotionPrimitiveProps & MotionDivProps>(\n ({ show, children, className, preset = 'snappy', layout, layoutId, whileInView, viewportOnce = true, viewportMargin = '-50px', ...rest }, ref) => {\n const spring = springs[preset]\n const inViewProps = whileInView ? {\n initial: 'hidden',\n whileInView: 'visible',\n viewport: { once: viewportOnce, margin: viewportMargin },\n } : {}\n\n return (\n <AnimatePresence>\n {show && (\n <motion.div\n ref={ref}\n initial={{ opacity: 0, scale: 0.96 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.96 }}\n transition={{ ...spring, opacity: tweens.fade }}\n className={cn(className)}\n layout={layout}\n layoutId={layoutId}\n {...inViewProps}\n {...rest}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n )\n },\n)\nMotionScale.displayName = 'MotionScale'\n\n// ── MotionPop ──\n// Default: bouncy spring with overshoot for scale + fade\n\nconst MotionPop = React.forwardRef<HTMLDivElement, MotionPrimitiveProps & MotionDivProps>(\n ({ show, children, className, preset = 'bouncy', layout, layoutId, whileInView, viewportOnce = true, viewportMargin = '-50px', ...rest }, ref) => {\n const spring = springs[preset]\n const inViewProps = whileInView ? {\n initial: 'hidden',\n whileInView: 'visible',\n viewport: { once: viewportOnce, margin: viewportMargin },\n } : {}\n\n return (\n <AnimatePresence>\n {show && (\n <motion.div\n ref={ref}\n initial={{ opacity: 0, scale: 0.5 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.5 }}\n transition={{ ...spring, opacity: tweens.fade }}\n className={cn(className)}\n layout={layout}\n layoutId={layoutId}\n {...inViewProps}\n {...rest}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n )\n },\n)\nMotionPop.displayName = 'MotionPop'\n\n// ── MotionSlide ──\n// Default: smooth spring for translate + fade\n\nconst MotionSlide = React.forwardRef<\n HTMLDivElement,\n MotionPrimitiveProps & { direction?: 'up' | 'down' | 'left' | 'right' } & MotionDivProps\n>(\n ({ show, children, className, preset = 'smooth', direction = 'up', layout, layoutId, whileInView, viewportOnce = true, viewportMargin = '-50px', ...rest }, ref) => {\n const spring = springs[preset]\n const offsets = {\n up: { y: 16 },\n down: { y: -16 },\n left: { x: 16 },\n right: { x: -16 },\n }\n const offset = offsets[direction]\n const inViewProps = whileInView ? {\n initial: 'hidden',\n whileInView: 'visible',\n viewport: { once: viewportOnce, margin: viewportMargin },\n } : {}\n\n return (\n <AnimatePresence>\n {show && (\n <motion.div\n ref={ref}\n initial={{ opacity: 0, ...offset }}\n animate={{ opacity: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, ...offset }}\n transition={{ ...spring, opacity: tweens.fade }}\n className={cn(className)}\n layout={layout}\n layoutId={layoutId}\n {...inViewProps}\n {...rest}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n )\n },\n)\nMotionSlide.displayName = 'MotionSlide'\n\n// ── MotionCollapse ──\n// Default: gentle spring for height + fade\n// Uses height: \"auto\" — Framer Motion handles this natively\n\nconst MotionCollapse = React.forwardRef<HTMLDivElement, MotionPrimitiveProps & MotionDivProps>(\n ({ show, children, className, preset = 'gentle', layout, layoutId, ...rest }, ref) => {\n const spring = springs[preset]\n\n return (\n <AnimatePresence initial={false}>\n {show && (\n <motion.div\n ref={ref}\n initial={{ height: 0, opacity: 0, overflow: 'hidden' }}\n animate={{ height: 'auto', opacity: 1, overflow: 'hidden' }}\n exit={{ height: 0, opacity: 0, overflow: 'hidden' }}\n transition={{ ...spring, opacity: tweens.fade }}\n className={cn(className)}\n layout={layout}\n layoutId={layoutId}\n {...rest}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n )\n },\n)\nMotionCollapse.displayName = 'MotionCollapse'\n\n// ── MotionStagger + MotionStaggerItem ──\n// Parent orchestrates children with staggerChildren\n\ntype MotionStaggerProps = {\n children: React.ReactNode\n className?: string\n delay?: number\n whileInView?: boolean\n viewportOnce?: boolean\n viewportMargin?: string\n}\n\nconst MotionStagger = React.forwardRef<HTMLDivElement, MotionStaggerProps & MotionDivProps>(\n ({ children, className, delay = 0.04, whileInView, viewportOnce = true, viewportMargin = '-50px', ...rest }, ref) => {\n const variants: Variants = {\n hidden: {},\n visible: {\n transition: { staggerChildren: delay },\n },\n }\n\n const viewProps = whileInView\n ? { initial: 'hidden' as const, whileInView: 'visible' as const, viewport: { once: viewportOnce, margin: viewportMargin } }\n : { initial: 'hidden' as const, animate: 'visible' as const }\n\n return (\n <motion.div\n ref={ref}\n variants={variants}\n className={cn(className)}\n {...viewProps}\n {...rest}\n >\n {children}\n </motion.div>\n )\n },\n)\nMotionStagger.displayName = 'MotionStagger'\n\nconst itemVariants: Variants = {\n hidden: { opacity: 0, y: 8 },\n visible: {\n opacity: 1,\n y: 0,\n transition: { ...springs.smooth, opacity: tweens.fade },\n },\n}\n\nconst MotionStaggerItem = React.forwardRef<HTMLDivElement, { children: React.ReactNode; className?: string } & MotionDivProps>(\n ({ children, className, ...rest }, ref) => {\n return (\n <motion.div\n ref={ref}\n variants={itemVariants}\n className={cn(className)}\n {...rest}\n >\n {children}\n </motion.div>\n )\n },\n)\nMotionStaggerItem.displayName = 'MotionStaggerItem'\n\nexport {\n MotionCollapse,\n MotionFade,\n MotionPop,\n type MotionPrimitiveProps,\n MotionScale,\n MotionSlide,\n MotionStagger,\n MotionStaggerItem,\n type MotionStaggerProps,\n}\n"],"mappings":";;;;;;AA4BA,IAAM,IAAa,EAAM,YACtB,EAAE,SAAM,aAAU,cAAW,WAAQ,aAAU,gBAAa,kBAAe,IAAM,oBAAiB,SAAS,GAAG,KAAQ,MAAQ;CAC7H,IAAM,IAAc,IAAc;EAChC,SAAS;EACT,aAAa;EACb,UAAU;GAAE,MAAM;GAAc,QAAQ;EAAe;CACzD,IAAI,CAAC;CAEL,OACE,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,EAAO,KAAR;EACO;EACL,SAAS,EAAE,SAAS,EAAE;EACtB,SAAS,EAAE,SAAS,EAAE;EACtB,MAAM,EAAE,SAAS,EAAE;EACnB,YAAY,EAAO;EACnB,WAAW,EAAG,CAAS;EACf;EACE;EACV,GAAI;EACJ,GAAI;EAEH;CACS,CAAA,EAEC,CAAA;AAErB,CACF;AACA,EAAW,cAAc;AAKzB,IAAM,IAAc,EAAM,YACvB,EAAE,SAAM,aAAU,cAAW,YAAS,UAAU,WAAQ,aAAU,gBAAa,kBAAe,IAAM,oBAAiB,SAAS,GAAG,KAAQ,MAAQ;CAChJ,IAAM,IAAS,EAAQ,IACjB,IAAc,IAAc;EAChC,SAAS;EACT,aAAa;EACb,UAAU;GAAE,MAAM;GAAc,QAAQ;EAAe;CACzD,IAAI,CAAC;CAEL,OACE,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,EAAO,KAAR;EACO;EACL,SAAS;GAAE,SAAS;GAAG,OAAO;EAAK;EACnC,SAAS;GAAE,SAAS;GAAG,OAAO;EAAE;EAChC,MAAM;GAAE,SAAS;GAAG,OAAO;EAAK;EAChC,YAAY;GAAE,GAAG;GAAQ,SAAS,EAAO;EAAK;EAC9C,WAAW,EAAG,CAAS;EACf;EACE;EACV,GAAI;EACJ,GAAI;EAEH;CACS,CAAA,EAEC,CAAA;AAErB,CACF;AACA,EAAY,cAAc;AAK1B,IAAM,IAAY,EAAM,YACrB,EAAE,SAAM,aAAU,cAAW,YAAS,UAAU,WAAQ,aAAU,gBAAa,kBAAe,IAAM,oBAAiB,SAAS,GAAG,KAAQ,MAAQ;CAChJ,IAAM,IAAS,EAAQ,IACjB,IAAc,IAAc;EAChC,SAAS;EACT,aAAa;EACb,UAAU;GAAE,MAAM;GAAc,QAAQ;EAAe;CACzD,IAAI,CAAC;CAEL,OACE,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,EAAO,KAAR;EACO;EACL,SAAS;GAAE,SAAS;GAAG,OAAO;EAAI;EAClC,SAAS;GAAE,SAAS;GAAG,OAAO;EAAE;EAChC,MAAM;GAAE,SAAS;GAAG,OAAO;EAAI;EAC/B,YAAY;GAAE,GAAG;GAAQ,SAAS,EAAO;EAAK;EAC9C,WAAW,EAAG,CAAS;EACf;EACE;EACV,GAAI;EACJ,GAAI;EAEH;CACS,CAAA,EAEC,CAAA;AAErB,CACF;AACA,EAAU,cAAc;AAKxB,IAAM,IAAc,EAAM,YAIvB,EAAE,SAAM,aAAU,cAAW,YAAS,UAAU,eAAY,MAAM,WAAQ,aAAU,gBAAa,kBAAe,IAAM,oBAAiB,SAAS,GAAG,KAAQ,MAAQ;CAClK,IAAM,IAAS,EAAQ,IAOjB,IAAS;EALb,IAAI,EAAE,GAAG,GAAG;EACZ,MAAM,EAAE,GAAG,IAAI;EACf,MAAM,EAAE,GAAG,GAAG;EACd,OAAO,EAAE,GAAG,IAAI;CAEH,EAAQ,IACjB,IAAc,IAAc;EAChC,SAAS;EACT,aAAa;EACb,UAAU;GAAE,MAAM;GAAc,QAAQ;EAAe;CACzD,IAAI,CAAC;CAEL,OACE,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,EAAO,KAAR;EACO;EACL,SAAS;GAAE,SAAS;GAAG,GAAG;EAAO;EACjC,SAAS;GAAE,SAAS;GAAG,GAAG;GAAG,GAAG;EAAE;EAClC,MAAM;GAAE,SAAS;GAAG,GAAG;EAAO;EAC9B,YAAY;GAAE,GAAG;GAAQ,SAAS,EAAO;EAAK;EAC9C,WAAW,EAAG,CAAS;EACf;EACE;EACV,GAAI;EACJ,GAAI;EAEH;CACS,CAAA,EAEC,CAAA;AAErB,CACF;AACA,EAAY,cAAc;AAM1B,IAAM,IAAiB,EAAM,YAC1B,EAAE,SAAM,aAAU,cAAW,YAAS,UAAU,WAAQ,aAAU,GAAG,KAAQ,MAAQ;CACpF,IAAM,IAAS,EAAQ;CAEvB,OACE,kBAAC,GAAD;EAAiB,SAAS;YACvB,KACC,kBAAC,EAAO,KAAR;GACO;GACL,SAAS;IAAE,QAAQ;IAAG,SAAS;IAAG,UAAU;GAAS;GACrD,SAAS;IAAE,QAAQ;IAAQ,SAAS;IAAG,UAAU;GAAS;GAC1D,MAAM;IAAE,QAAQ;IAAG,SAAS;IAAG,UAAU;GAAS;GAClD,YAAY;IAAE,GAAG;IAAQ,SAAS,EAAO;GAAK;GAC9C,WAAW,EAAG,CAAS;GACf;GACE;GACV,GAAI;GAEH;EACS,CAAA;CAEC,CAAA;AAErB,CACF;AACA,EAAe,cAAc;AAc7B,IAAM,IAAgB,EAAM,YACzB,EAAE,aAAU,cAAW,WAAQ,KAAM,gBAAa,kBAAe,IAAM,oBAAiB,SAAS,GAAG,KAAQ,MAAQ;CACnH,IAAM,IAAqB;EACzB,QAAQ,CAAC;EACT,SAAS,EACP,YAAY,EAAE,iBAAiB,EAAM,EACvC;CACF,GAEM,IAAY,IACd;EAAE,SAAS;EAAmB,aAAa;EAAoB,UAAU;GAAE,MAAM;GAAc,QAAQ;EAAe;CAAE,IACxH;EAAE,SAAS;EAAmB,SAAS;CAAmB;CAE9D,OACE,kBAAC,EAAO,KAAR;EACO;EACK;EACV,WAAW,EAAG,CAAS;EACvB,GAAI;EACJ,GAAI;EAEH;CACS,CAAA;AAEhB,CACF;AACA,EAAc,cAAc;AAE5B,IAAM,IAAyB;CAC7B,QAAQ;EAAE,SAAS;EAAG,GAAG;CAAE;CAC3B,SAAS;EACP,SAAS;EACT,GAAG;EACH,YAAY;GAAE,GAAG,EAAQ;GAAQ,SAAS,EAAO;EAAK;CACxD;AACF,GAEM,IAAoB,EAAM,YAC7B,EAAE,aAAU,cAAW,GAAG,KAAQ,MAE/B,kBAAC,EAAO,KAAR;CACO;CACL,UAAU;CACV,WAAW,EAAG,CAAS;CACvB,GAAI;CAEH;AACS,CAAA,CAGlB;AACA,EAAkB,cAAc"}
1
+ {"version":3,"file":"primitives-index.js","names":[],"sources":["../../src/motion/primitives.tsx"],"sourcesContent":["'use client'\n\nimport { AnimatePresence, type HTMLMotionProps,motion, type Transition, type Variants } from 'framer-motion'\nimport * as React from 'react'\n\nimport type { SpringPreset } from '../ui/lib/motion'\nimport { springs, tweens } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\nimport { MotionPreference } from './motion-preference'\n\n// ── Shared types ──\n\ntype MotionDivProps = Omit<HTMLMotionProps<'div'>, 'ref'>\n\ntype MotionPrimitiveProps = {\n show: boolean\n children: React.ReactNode\n className?: string\n preset?: SpringPreset\n layout?: boolean | 'position' | 'size' | 'preserve-aspect'\n layoutId?: string\n whileInView?: boolean\n viewportOnce?: boolean\n viewportMargin?: string\n}\n\n// ── MotionFade ──\n// Default: fade tween only (no spring needed for pure opacity)\n\nconst MotionFade = React.forwardRef<HTMLDivElement, MotionPrimitiveProps & MotionDivProps>(\n ({ show, children, className, layout, layoutId, whileInView, viewportOnce = true, viewportMargin = '-50px', ...rest }, ref) => {\n const inViewProps = whileInView ? {\n initial: 'hidden',\n whileInView: 'visible',\n viewport: { once: viewportOnce, margin: viewportMargin },\n } : {}\n\n return (\n <MotionPreference>\n <AnimatePresence>\n {show && (\n <motion.div\n ref={ref}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={tweens.fade}\n className={cn(className)}\n layout={layout}\n layoutId={layoutId}\n {...inViewProps}\n {...rest}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n </MotionPreference>\n )\n },\n)\nMotionFade.displayName = 'MotionFade'\n\n// ── MotionScale ──\n// Default: snappy spring for scale + fade tween for opacity\n\nconst MotionScale = React.forwardRef<HTMLDivElement, MotionPrimitiveProps & MotionDivProps>(\n ({ show, children, className, preset = 'snappy', layout, layoutId, whileInView, viewportOnce = true, viewportMargin = '-50px', ...rest }, ref) => {\n const spring = springs[preset]\n const inViewProps = whileInView ? {\n initial: 'hidden',\n whileInView: 'visible',\n viewport: { once: viewportOnce, margin: viewportMargin },\n } : {}\n\n return (\n <MotionPreference>\n <AnimatePresence>\n {show && (\n <motion.div\n ref={ref}\n initial={{ opacity: 0, scale: 0.96 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.96 }}\n transition={{ ...spring, opacity: tweens.fade }}\n className={cn(className)}\n layout={layout}\n layoutId={layoutId}\n {...inViewProps}\n {...rest}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n </MotionPreference>\n )\n },\n)\nMotionScale.displayName = 'MotionScale'\n\n// ── MotionPop ──\n// Default: bouncy spring with overshoot for scale + fade\n\nconst MotionPop = React.forwardRef<HTMLDivElement, MotionPrimitiveProps & MotionDivProps>(\n ({ show, children, className, preset = 'bouncy', layout, layoutId, whileInView, viewportOnce = true, viewportMargin = '-50px', ...rest }, ref) => {\n const spring = springs[preset]\n const inViewProps = whileInView ? {\n initial: 'hidden',\n whileInView: 'visible',\n viewport: { once: viewportOnce, margin: viewportMargin },\n } : {}\n\n return (\n <MotionPreference>\n <AnimatePresence>\n {show && (\n <motion.div\n ref={ref}\n initial={{ opacity: 0, scale: 0.5 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.5 }}\n transition={{ ...spring, opacity: tweens.fade }}\n className={cn(className)}\n layout={layout}\n layoutId={layoutId}\n {...inViewProps}\n {...rest}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n </MotionPreference>\n )\n },\n)\nMotionPop.displayName = 'MotionPop'\n\n// ── MotionSlide ──\n// Default: smooth spring for translate + fade\n\nconst MotionSlide = React.forwardRef<\n HTMLDivElement,\n MotionPrimitiveProps & { direction?: 'up' | 'down' | 'left' | 'right' } & MotionDivProps\n>(\n ({ show, children, className, preset = 'smooth', direction = 'up', layout, layoutId, whileInView, viewportOnce = true, viewportMargin = '-50px', ...rest }, ref) => {\n const spring = springs[preset]\n const offsets = {\n up: { y: 16 },\n down: { y: -16 },\n left: { x: 16 },\n right: { x: -16 },\n }\n const offset = offsets[direction]\n const inViewProps = whileInView ? {\n initial: 'hidden',\n whileInView: 'visible',\n viewport: { once: viewportOnce, margin: viewportMargin },\n } : {}\n\n return (\n <MotionPreference>\n <AnimatePresence>\n {show && (\n <motion.div\n ref={ref}\n initial={{ opacity: 0, ...offset }}\n animate={{ opacity: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, ...offset }}\n transition={{ ...spring, opacity: tweens.fade }}\n className={cn(className)}\n layout={layout}\n layoutId={layoutId}\n {...inViewProps}\n {...rest}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n </MotionPreference>\n )\n },\n)\nMotionSlide.displayName = 'MotionSlide'\n\n// ── MotionCollapse ──\n// Default: gentle spring for height + fade\n// Uses height: \"auto\" — Framer Motion handles this natively\n\nconst MotionCollapse = React.forwardRef<HTMLDivElement, MotionPrimitiveProps & MotionDivProps>(\n ({ show, children, className, preset = 'gentle', layout, layoutId, ...rest }, ref) => {\n const spring = springs[preset]\n\n return (\n <MotionPreference>\n <AnimatePresence initial={false}>\n {show && (\n <motion.div\n ref={ref}\n initial={{ height: 0, opacity: 0, overflow: 'hidden' }}\n animate={{ height: 'auto', opacity: 1, overflow: 'hidden' }}\n exit={{ height: 0, opacity: 0, overflow: 'hidden' }}\n transition={{ ...spring, opacity: tweens.fade }}\n className={cn(className)}\n layout={layout}\n layoutId={layoutId}\n {...rest}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n </MotionPreference>\n )\n },\n)\nMotionCollapse.displayName = 'MotionCollapse'\n\n// ── MotionStagger + MotionStaggerItem ──\n// Parent orchestrates children with staggerChildren\n\ntype MotionStaggerProps = {\n children: React.ReactNode\n className?: string\n delay?: number\n whileInView?: boolean\n viewportOnce?: boolean\n viewportMargin?: string\n}\n\nconst MotionStagger = React.forwardRef<HTMLDivElement, MotionStaggerProps & MotionDivProps>(\n ({ children, className, delay = 0.04, whileInView, viewportOnce = true, viewportMargin = '-50px', ...rest }, ref) => {\n const variants: Variants = {\n hidden: {},\n visible: {\n transition: { staggerChildren: delay },\n },\n }\n\n const viewProps = whileInView\n ? { initial: 'hidden' as const, whileInView: 'visible' as const, viewport: { once: viewportOnce, margin: viewportMargin } }\n : { initial: 'hidden' as const, animate: 'visible' as const }\n\n return (\n <MotionPreference>\n <motion.div\n ref={ref}\n variants={variants}\n className={cn(className)}\n {...viewProps}\n {...rest}\n >\n {children}\n </motion.div>\n </MotionPreference>\n )\n },\n)\nMotionStagger.displayName = 'MotionStagger'\n\nconst itemVariants: Variants = {\n hidden: { opacity: 0, y: 8 },\n visible: {\n opacity: 1,\n y: 0,\n transition: { ...springs.smooth, opacity: tweens.fade },\n },\n}\n\nconst MotionStaggerItem = React.forwardRef<HTMLDivElement, { children: React.ReactNode; className?: string } & MotionDivProps>(\n ({ children, className, ...rest }, ref) => {\n return (\n <MotionPreference>\n <motion.div\n ref={ref}\n variants={itemVariants}\n className={cn(className)}\n {...rest}\n >\n {children}\n </motion.div>\n </MotionPreference>\n )\n },\n)\nMotionStaggerItem.displayName = 'MotionStaggerItem'\n\nexport {\n MotionCollapse,\n MotionFade,\n MotionPop,\n type MotionPrimitiveProps,\n MotionScale,\n MotionSlide,\n MotionStagger,\n MotionStaggerItem,\n type MotionStaggerProps,\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/motion/primitives.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,eAAe,EAAyC,MAAM,eAAe,CAAA;AAC5G,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAMpD,KAAK,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;AAEzD,KAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,iBAAiB,CAAA;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAKD,QAAA,MAAM,UAAU,8GA6Bf,CAAA;AAMD,QAAA,MAAM,WAAW,8GA8BhB,CAAA;AAMD,QAAA,MAAM,SAAS,8GA8Bd,CAAA;AAMD,QAAA,MAAM,WAAW;gBAEsB,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO;yDAsCtE,CAAA;AAOD,QAAA,MAAM,cAAc,8GAwBnB,CAAA;AAMD,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,QAAA,MAAM,aAAa,4GAyBlB,CAAA;AAYD,QAAA,MAAM,iBAAiB;cAAgD,KAAK,CAAC,SAAS;gBAAc,MAAM;yDAazG,CAAA;AAGD,OAAO,EACL,cAAc,EACd,UAAU,EACV,SAAS,EACT,KAAK,oBAAoB,EACzB,WAAW,EACX,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,KAAK,kBAAkB,GACxB,CAAA"}
1
+ {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/motion/primitives.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,eAAe,EAAyC,MAAM,eAAe,CAAA;AAC5G,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAOpD,KAAK,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;AAEzD,KAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,iBAAiB,CAAA;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAKD,QAAA,MAAM,UAAU,8GA+Bf,CAAA;AAMD,QAAA,MAAM,WAAW,8GAgChB,CAAA;AAMD,QAAA,MAAM,SAAS,8GAgCd,CAAA;AAMD,QAAA,MAAM,WAAW;gBAEsB,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO;yDAwCtE,CAAA;AAOD,QAAA,MAAM,cAAc,8GA0BnB,CAAA;AAMD,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,QAAA,MAAM,aAAa,4GA2BlB,CAAA;AAYD,QAAA,MAAM,iBAAiB;cAAgD,KAAK,CAAC,SAAS;gBAAc,MAAM;yDAezG,CAAA;AAGD,OAAO,EACL,cAAc,EACd,UAAU,EACV,SAAS,EACT,KAAK,oBAAoB,EACzB,WAAW,EACX,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,KAAK,kBAAkB,GACxB,CAAA"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { IconProvider as e } from "../ui/icon-context.js";
3
- import { springs as t } from "../ui/lib/motion.js";
2
+ import { springs as e } from "../ui/lib/motion.js";
3
+ import { IconProvider as t } from "../ui/icon-context.js";
4
4
  import { cn as n } from "../ui/lib/utils.js";
5
5
  import { Icon as r } from "../ui/icon.js";
6
6
  import { normalizeIcon as i } from "../_chunks/normalize-icon.js";
@@ -29,24 +29,24 @@ function b({ count: e }) {
29
29
  children: t
30
30
  });
31
31
  }
32
- function x({ indicator: e, layoutId: n, reduced: r }) {
33
- if (e === "none") return null;
32
+ function x({ indicator: t, layoutId: n, reduced: r }) {
33
+ if (t === "none") return null;
34
34
  let i = {
35
35
  layoutId: n,
36
36
  "aria-hidden": !0,
37
- transition: r ? { duration: 0 } : t.snappy,
37
+ transition: r ? { duration: 0 } : e.snappy,
38
38
  initial: !r && { opacity: 0 },
39
39
  animate: { opacity: 1 }
40
40
  };
41
- return e === "underline" ? /* @__PURE__ */ m(_.span, {
41
+ return t === "underline" ? /* @__PURE__ */ m(_.span, {
42
42
  ...i,
43
43
  className: "absolute top-0 h-[3px] w-full rounded-b-control-inner bg-accent-9"
44
- }) : e === "tint" ? /* @__PURE__ */ m(_.span, {
44
+ }) : t === "tint" ? /* @__PURE__ */ m(_.span, {
45
45
  ...i,
46
- className: "absolute inset-0 rounded-control bg-accent-3"
46
+ className: "absolute inset-0 rounded-control bg-accent-4"
47
47
  }) : /* @__PURE__ */ m(_.span, {
48
48
  ...i,
49
- className: "absolute inset-0 rounded-pill bg-accent-3"
49
+ className: "absolute inset-0 rounded-pill bg-accent-4"
50
50
  });
51
51
  }
52
52
  var S = "relative flex h-16 w-full min-w-0 cursor-pointer flex-col items-center justify-center gap-ds-02 px-ds-01 pt-0 text-body-sm transition-colors duration-fast-02 ease-productive-standard";
@@ -54,7 +54,7 @@ function C({ item: r, isActive: a, indicator: o, indicatorId: s, showLabel: c, r
54
54
  let u = d();
55
55
  return /* @__PURE__ */ m(_.div, {
56
56
  whileTap: l ? void 0 : { scale: .96 },
57
- transition: l ? { duration: 0 } : t.snappy,
57
+ transition: l ? { duration: 0 } : e.snappy,
58
58
  className: "flex min-w-0 flex-1 basis-0",
59
59
  children: /* @__PURE__ */ h(u, {
60
60
  href: r.href,
@@ -84,7 +84,7 @@ function C({ item: r, isActive: a, indicator: o, indicatorId: s, showLabel: c, r
84
84
  /* @__PURE__ */ m("span", {
85
85
  className: "relative [&>svg]:h-ico-md [&>svg]:w-ico-md",
86
86
  "aria-hidden": "true",
87
- children: /* @__PURE__ */ m(e, {
87
+ children: /* @__PURE__ */ m(t, {
88
88
  size: "md",
89
89
  children: i(a && r.activeIcon ? r.activeIcon : r.icon)
90
90
  })
@@ -124,7 +124,7 @@ var w = f.forwardRef(({ currentPath: a = "/", user: b = null, primaryItems: w =
124
124
  type: "button",
125
125
  "aria-label": "More navigation options",
126
126
  whileTap: M ? void 0 : { scale: .96 },
127
- transition: M ? { duration: 0 } : t.snappy,
127
+ transition: M ? { duration: 0 } : e.snappy,
128
128
  className: n(S, "min-w-0 flex-1 basis-0", B ? "font-semibold text-accent-11" : "text-surface-fg-subtle"),
129
129
  children: [B && E === "tint" && /* @__PURE__ */ m(x, {
130
130
  indicator: "tint",
@@ -158,25 +158,25 @@ var w = f.forwardRef(({ currentPath: a = "/", user: b = null, primaryItems: w =
158
158
  className: "rounded-t-bubble",
159
159
  children: [/* @__PURE__ */ m(c, { children: /* @__PURE__ */ m(l, { children: "More" }) }), /* @__PURE__ */ m("div", {
160
160
  className: "grid grid-cols-[repeat(auto-fit,minmax(72px,1fr))] gap-ds-03 pt-ds-04",
161
- children: R.map((t) => {
162
- let r = I(t.href, t.exact);
161
+ children: R.map((e) => {
162
+ let r = I(e.href, e.exact);
163
163
  return /* @__PURE__ */ h(j, {
164
- href: t.href,
164
+ href: e.href,
165
165
  onClick: () => P(!1),
166
166
  "aria-current": r ? "page" : void 0,
167
167
  className: n("flex min-w-0 flex-col items-center gap-ds-02b rounded-overlay-lg p-ds-04 text-body-sm transition-colors ease-productive-standard", r ? "bg-surface-panel-hover text-accent-11" : "text-surface-fg-subtle hover:bg-surface-panel-hover"),
168
168
  children: [/* @__PURE__ */ m("span", {
169
169
  className: "[&>svg]:h-ico-md [&>svg]:w-ico-md",
170
170
  "aria-hidden": "true",
171
- children: /* @__PURE__ */ m(e, {
171
+ children: /* @__PURE__ */ m(t, {
172
172
  size: "md",
173
- children: i(t.icon)
173
+ children: i(e.icon)
174
174
  })
175
175
  }), /* @__PURE__ */ m("span", {
176
176
  className: "max-w-full truncate text-center",
177
- children: t.title
177
+ children: e.title
178
178
  })]
179
- }, t.href);
179
+ }, e.href);
180
180
  })
181
181
  })]
182
182
  })]
@@ -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 (currentPath / user / items) and router-agnostic via `useLink`.\n * The \"More\" overflow uses the DS `Sheet` primitive, so it inherits focus trap,\n * scroll lock, return-focus, `aria-modal`, and trigger↔panel ARIA wiring.\n */\nimport { IconDots } from '@tabler/icons-react'\nimport { motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\nimport { useState } from 'react'\n\nimport { Badge } from '../ui/badge'\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 { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '../ui/sheet'\nimport { useLink } from './link-context'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface BottomNavbarUser {\n name: string\n role?: string\n}\n\nexport interface BottomNavItem {\n title: string\n href: string\n /** Icon for this nav item. Accepts any `IconInput`. */\n icon: IconInput\n /** Icon shown when the item is active — e.g. a filled variant. Falls back to `icon`. */\n activeIcon?: 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 * Roles allowed to see this item, matched against `user.role`. Omit to show\n * it to everyone. For arbitrary logic, use `canView` instead.\n */\n roles?: string[]\n /**\n * Visibility predicate — full control over whether this item renders.\n * Receives the current `user` (or `null`). Takes precedence over `roles`.\n */\n canView?: (user: BottomNavbarUser | null) => boolean\n}\n\n/**\n * Active-item indicator, animated between items on selection:\n * - `pill` (default) — Material-3 tonal pill behind the icon\n * - `underline` — top accent bar (Material-2 tab style)\n * - `tint` — subtle background tint on the whole active cell\n * - `none` — no shape; rely on the filled `activeIcon` + accent color (iOS)\n */\nexport type BottomNavIndicator = 'pill' | 'underline' | 'tint' | 'none'\n/** Show labels always (default) or only for the selected item (narrow viewports). */\nexport type BottomNavLabelVisibility = 'always' | 'selected'\n\nexport interface BottomNavbarProps extends React.HTMLAttributes<HTMLElement> {\n /** Currently active pathname */\n currentPath?: string\n /** Current user. Drives per-item role gating via `item.roles` / `item.canView`. */\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 sheet */\n moreItems?: BottomNavItem[]\n /** Active-indicator style. @default 'pill' */\n indicator?: BottomNavIndicator\n /** Label visibility. @default 'always' */\n labelVisibility?: BottomNavLabelVisibility\n /** Additional className for the nav element */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------\n\n/** Per-item role/visibility gate. `canView` wins; else `roles` matched against user.role; else visible. */\nfunction itemVisible(item: BottomNavItem, user: BottomNavbarUser | null): boolean {\n if (item.canView) return item.canView(user)\n if (item.roles && item.roles.length > 0) {\n return !!user?.role && item.roles.includes(user.role)\n }\n return true\n}\n\n// -----------------------------------------------------------------------\n// NavBadge (composes Badge)\n// -----------------------------------------------------------------------\n\nfunction NavBadge({ count }: { count: number }) {\n if (!count || count <= 0) return null\n const display = count > 99 ? '99+' : String(count)\n return (\n <Badge\n color=\"error\"\n variant=\"solid\"\n size=\"xs\"\n aria-label={`${count} notifications`}\n className=\"pointer-events-none absolute -end-1 -top-1 justify-center px-ds-01 tabular-nums motion-safe:animate-in motion-safe:zoom-in-75\"\n >\n {display}\n </Badge>\n )\n}\n\n// -----------------------------------------------------------------------\n// Active indicator (shared-element)\n// -----------------------------------------------------------------------\n\n/**\n * The active-item indicator. A single shared-element (`layoutId`) that SLIDES\n * to the selected item and fades in on first appearance. `none` renders\n * nothing (the filled `activeIcon` + accent color carry the state).\n */\nfunction ActiveIndicator({\n indicator,\n layoutId,\n reduced,\n}: {\n indicator: BottomNavIndicator\n layoutId: string\n reduced: boolean\n}) {\n if (indicator === 'none') return null\n const common = {\n layoutId,\n 'aria-hidden': true as const,\n transition: reduced ? { duration: 0 } : springs.snappy,\n initial: reduced ? false : { opacity: 0 },\n animate: { opacity: 1 },\n }\n if (indicator === 'underline') {\n return <motion.span {...common} className=\"absolute top-0 h-[3px] w-full rounded-b-control-inner bg-accent-9\" />\n }\n if (indicator === 'tint') {\n return <motion.span {...common} className=\"absolute inset-0 rounded-control bg-accent-3\" />\n }\n // pill (default) — Material-3 tonal pill behind the icon\n return <motion.span {...common} className=\"absolute inset-0 rounded-pill bg-accent-3\" />\n}\n\n// -----------------------------------------------------------------------\n// BottomNavLink (internal)\n// -----------------------------------------------------------------------\n\nconst itemClass =\n 'relative flex h-16 w-full min-w-0 cursor-pointer flex-col items-center justify-center gap-ds-02 px-ds-01 pt-0 text-body-sm transition-colors duration-fast-02 ease-productive-standard'\n\nfunction BottomNavLink({\n item,\n isActive,\n indicator,\n indicatorId,\n showLabel,\n reduced,\n}: {\n item: BottomNavItem\n isActive: boolean\n indicator: BottomNavIndicator\n indicatorId: string\n showLabel: boolean\n reduced: boolean\n}) {\n const Link = useLink()\n return (\n <motion.div\n whileTap={reduced ? undefined : { scale: 0.96 }}\n transition={reduced ? { duration: 0 } : springs.snappy}\n className=\"flex min-w-0 flex-1 basis-0\"\n >\n <Link\n href={item.href}\n aria-label={item.title}\n aria-current={isActive ? 'page' : undefined}\n className={cn(itemClass, isActive ? 'font-semibold text-accent-11' : 'text-surface-fg-subtle')}\n >\n {/* tint covers the whole cell — sits behind the content */}\n {isActive && indicator === 'tint' && (\n <ActiveIndicator indicator=\"tint\" layoutId={indicatorId} reduced={reduced} />\n )}\n <div className=\"relative flex w-full min-w-0 flex-col items-center gap-ds-02\">\n {isActive && indicator === 'underline' && (\n <ActiveIndicator indicator=\"underline\" layoutId={indicatorId} reduced={reduced} />\n )}\n <div className=\"relative px-ds-04 py-ds-01\">\n {isActive && indicator === 'pill' && (\n <ActiveIndicator indicator=\"pill\" layoutId={indicatorId} reduced={reduced} />\n )}\n <span className=\"relative [&>svg]:h-ico-md [&>svg]:w-ico-md\" aria-hidden=\"true\">\n <IconProvider size=\"md\">\n {normalizeIcon(isActive && item.activeIcon ? item.activeIcon : item.icon)}\n </IconProvider>\n </span>\n {item.badge != null && <NavBadge count={item.badge} />}\n </div>\n {showLabel && <span className=\"max-w-full truncate 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 = null,\n primaryItems = [],\n moreItems = [],\n indicator = 'pill',\n labelVisibility = 'always',\n className,\n ...props\n },\n ref,\n ) => {\n const Link = useLink()\n const reduced = useReducedMotion() ?? false\n const [showMore, setShowMore] = useState(false)\n // Scope the shared-element layoutId per instance so two navbars don't animate into each other.\n const instanceId = React.useId()\n const indicatorId = `${instanceId}-nav-indicator`\n\n const isActive = (path: string, exact = false) => {\n if (exact || path === '/') return currentPath === path\n return currentPath.startsWith(path)\n }\n\n // Role/visibility gating\n const visiblePrimary = primaryItems.filter((item) => itemVisible(item, user))\n const visibleMore = moreItems.filter((item) => itemVisible(item, user))\n\n const isMoreActive = visibleMore.some((item) => isActive(item.href, item.exact))\n const moreSelected = showMore || isMoreActive\n const showMoreLabel = labelVisibility === 'always' || moreSelected\n\n return (\n <nav\n {...props}\n ref={ref}\n aria-label=\"Mobile navigation\"\n className={cn(\n 'fixed bottom-0 start-0 end-0 z-sticky flex w-full flex-row items-stretch justify-between border-t border-surface-border-strong bg-surface-base px-ds-05 pb-safe pt-0 md:hidden',\n className,\n )}\n >\n {visiblePrimary.map((item) => (\n <BottomNavLink\n key={item.href}\n item={item}\n isActive={isActive(item.href, item.exact)}\n indicator={indicator}\n indicatorId={indicatorId}\n showLabel={labelVisibility === 'always' || isActive(item.href, item.exact)}\n reduced={reduced}\n />\n ))}\n\n {visibleMore.length > 0 && (\n <Sheet open={showMore} onOpenChange={setShowMore}>\n <SheetTrigger asChild>\n <motion.button\n type=\"button\"\n aria-label=\"More navigation options\"\n whileTap={reduced ? undefined : { scale: 0.96 }}\n transition={reduced ? { duration: 0 } : springs.snappy}\n className={cn(\n itemClass,\n 'min-w-0 flex-1 basis-0',\n moreSelected ? 'font-semibold text-accent-11' : 'text-surface-fg-subtle',\n )}\n >\n {moreSelected && indicator === 'tint' && (\n <ActiveIndicator indicator=\"tint\" layoutId={indicatorId} reduced={reduced} />\n )}\n <div className=\"relative flex w-full min-w-0 flex-col items-center gap-ds-02\">\n {moreSelected && indicator === 'underline' && (\n <ActiveIndicator indicator=\"underline\" layoutId={indicatorId} reduced={reduced} />\n )}\n <div className=\"relative px-ds-04 py-ds-01\">\n {moreSelected && indicator === 'pill' && (\n <ActiveIndicator indicator=\"pill\" layoutId={indicatorId} reduced={reduced} />\n )}\n <Icon icon={IconDots} />\n </div>\n {showMoreLabel && <span className=\"max-w-full truncate text-center\">More</span>}\n </div>\n </motion.button>\n </SheetTrigger>\n\n <SheetContent side=\"bottom\" className=\"rounded-t-bubble\">\n <SheetHeader>\n <SheetTitle>More</SheetTitle>\n </SheetHeader>\n <div className=\"grid grid-cols-[repeat(auto-fit,minmax(72px,1fr))] gap-ds-03 pt-ds-04\">\n {visibleMore.map((item) => {\n const active = isActive(item.href, item.exact)\n return (\n <Link\n key={item.href}\n href={item.href}\n onClick={() => setShowMore(false)}\n aria-current={active ? 'page' : undefined}\n className={cn(\n 'flex min-w-0 flex-col items-center gap-ds-02b rounded-overlay-lg p-ds-04 text-body-sm transition-colors ease-productive-standard',\n active\n ? 'bg-surface-panel-hover text-accent-11'\n : 'text-surface-fg-subtle hover:bg-surface-panel-hover',\n )}\n >\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md\" aria-hidden=\"true\">\n <IconProvider size=\"md\">{normalizeIcon(item.icon)}</IconProvider>\n </span>\n <span className=\"max-w-full truncate text-center\">{item.title}</span>\n </Link>\n )\n })}\n </div>\n </SheetContent>\n </Sheet>\n )}\n </nav>\n )\n },\n)\nBottomNavbar.displayName = 'BottomNavbar'\n\nexport { BottomNavbar }\n"],"mappings":";;;;;;;;;;;;;;;;AAyFA,SAAS,EAAY,GAAqB,GAAwC;CAKhF,OAJI,EAAK,UAAgB,EAAK,QAAQ,CAAI,IACtC,EAAK,SAAS,EAAK,MAAM,SAAS,IAC7B,CAAC,CAAC,GAAM,QAAQ,EAAK,MAAM,SAAS,EAAK,IAAI,IAE/C;AACT;AAMA,SAAS,EAAS,EAAE,YAA4B;CAC9C,IAAI,CAAC,KAAS,KAAS,GAAG,OAAO;CACjC,IAAM,IAAU,IAAQ,KAAK,QAAQ,OAAO,CAAK;CACjD,OACE,kBAAC,GAAD;EACE,OAAM;EACN,SAAQ;EACR,MAAK;EACL,cAAY,GAAG,EAAM;EACrB,WAAU;YAET;CACI,CAAA;AAEX;AAWA,SAAS,EAAgB,EACvB,cACA,aACA,cAKC;CACD,IAAI,MAAc,QAAQ,OAAO;CACjC,IAAM,IAAS;EACb;EACA,eAAe;EACf,YAAY,IAAU,EAAE,UAAU,EAAE,IAAI,EAAQ;EAChD,SAAS,MAAkB,EAAE,SAAS,EAAE;EACxC,SAAS,EAAE,SAAS,EAAE;CACxB;CAQA,OAPI,MAAc,cACT,kBAAC,EAAO,MAAR;EAAa,GAAI;EAAQ,WAAU;CAAqE,CAAA,IAE7G,MAAc,SACT,kBAAC,EAAO,MAAR;EAAa,GAAI;EAAQ,WAAU;CAAgD,CAAA,IAGrF,kBAAC,EAAO,MAAR;EAAa,GAAI;EAAQ,WAAU;CAA6C,CAAA;AACzF;AAMA,IAAM,IACJ;AAEF,SAAS,EAAc,EACrB,SACA,aACA,cACA,gBACA,cACA,cAQC;CACD,IAAM,IAAO,EAAQ;CACrB,OACE,kBAAC,EAAO,KAAR;EACE,UAAU,IAAU,KAAA,IAAY,EAAE,OAAO,IAAK;EAC9C,YAAY,IAAU,EAAE,UAAU,EAAE,IAAI,EAAQ;EAChD,WAAU;YAEV,kBAAC,GAAD;GACE,MAAM,EAAK;GACX,cAAY,EAAK;GACjB,gBAAc,IAAW,SAAS,KAAA;GAClC,WAAW,EAAG,GAAW,IAAW,iCAAiC,wBAAwB;aAJ/F,CAOG,KAAY,MAAc,UACzB,kBAAC,GAAD;IAAiB,WAAU;IAAO,UAAU;IAAsB;GAAU,CAAA,GAE9E,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,KAAY,MAAc,eACzB,kBAAC,GAAD;MAAiB,WAAU;MAAY,UAAU;MAAsB;KAAU,CAAA;KAEnF,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACG,KAAY,MAAc,UACzB,kBAAC,GAAD;QAAiB,WAAU;QAAO,UAAU;QAAsB;OAAU,CAAA;OAE9E,kBAAC,QAAD;QAAM,WAAU;QAA6C,eAAY;kBACvE,kBAAC,GAAD;SAAc,MAAK;mBAChB,EAAc,KAAY,EAAK,aAAa,EAAK,aAAa,EAAK,IAAI;QAC5D,CAAA;OACV,CAAA;OACL,EAAK,SAAS,QAAQ,kBAAC,GAAD,EAAU,OAAO,EAAK,MAAQ,CAAA;MAClD;;KACJ,KAAa,kBAAC,QAAD;MAAM,WAAU;gBAAmC,EAAK;KAAY,CAAA;IAC/E;KACD;;CACI,CAAA;AAEhB;AAMA,IAAM,IAAe,EAAM,YAEvB,EACE,iBAAc,KACd,UAAO,MACP,kBAAe,CAAC,GAChB,eAAY,CAAC,GACb,eAAY,QACZ,qBAAkB,UAClB,cACA,GAAG,KAEL,MACG;CACH,IAAM,IAAO,EAAQ,GACf,IAAU,EAAiB,KAAK,IAChC,CAAC,GAAU,KAAe,EAAS,EAAK,GAGxC,IAAc,GADD,EAAM,MACF,EAAW,iBAE5B,KAAY,GAAc,IAAQ,OAClC,KAAS,MAAS,MAAY,MAAgB,IAC3C,EAAY,WAAW,CAAI,GAI9B,IAAiB,EAAa,QAAQ,MAAS,EAAY,GAAM,CAAI,CAAC,GACtE,IAAc,EAAU,QAAQ,MAAS,EAAY,GAAM,CAAI,CAAC,GAEhE,IAAe,EAAY,MAAM,MAAS,EAAS,EAAK,MAAM,EAAK,KAAK,CAAC,GACzE,IAAe,KAAY,GAC3B,IAAgB,MAAoB,YAAY;CAEtD,OACE,kBAAC,OAAD;EACE,GAAI;EACC;EACL,cAAW;EACX,WAAW,EACT,kLACA,CACF;YAPF,CASG,EAAe,KAAK,MACnB,kBAAC,GAAD;GAEQ;GACN,UAAU,EAAS,EAAK,MAAM,EAAK,KAAK;GAC7B;GACE;GACb,WAAW,MAAoB,YAAY,EAAS,EAAK,MAAM,EAAK,KAAK;GAChE;EACV,GAPM,EAAK,IAOX,CACF,GAEA,EAAY,SAAS,KACpB,kBAAC,GAAD;GAAO,MAAM;GAAU,cAAc;aAArC,CACE,kBAAC,GAAD;IAAc,SAAA;cACZ,kBAAC,EAAO,QAAR;KACE,MAAK;KACL,cAAW;KACX,UAAU,IAAU,KAAA,IAAY,EAAE,OAAO,IAAK;KAC9C,YAAY,IAAU,EAAE,UAAU,EAAE,IAAI,EAAQ;KAChD,WAAW,EACT,GACA,0BACA,IAAe,iCAAiC,wBAClD;eATF,CAWG,KAAgB,MAAc,UAC7B,kBAAC,GAAD;MAAiB,WAAU;MAAO,UAAU;MAAsB;KAAU,CAAA,GAE9E,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACG,KAAgB,MAAc,eAC7B,kBAAC,GAAD;QAAiB,WAAU;QAAY,UAAU;QAAsB;OAAU,CAAA;OAEnF,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACG,KAAgB,MAAc,UAC7B,kBAAC,GAAD;SAAiB,WAAU;SAAO,UAAU;SAAsB;QAAU,CAAA,GAE9E,kBAAC,GAAD,EAAM,MAAM,EAAW,CAAA,CACpB;;OACJ,KAAiB,kBAAC,QAAD;QAAM,WAAU;kBAAkC;OAAU,CAAA;MAC3E;OACQ;;GACH,CAAA,GAEd,kBAAC,GAAD;IAAc,MAAK;IAAS,WAAU;cAAtC,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAY,OAAgB,CAAA,EACjB,CAAA,GACb,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAY,KAAK,MAAS;MACzB,IAAM,IAAS,EAAS,EAAK,MAAM,EAAK,KAAK;MAC7C,OACE,kBAAC,GAAD;OAEE,MAAM,EAAK;OACX,eAAe,EAAY,EAAK;OAChC,gBAAc,IAAS,SAAS,KAAA;OAChC,WAAW,EACT,oIACA,IACI,0CACA,qDACN;iBAVF,CAYE,kBAAC,QAAD;QAAM,WAAU;QAAoC,eAAY;kBAC9D,kBAAC,GAAD;SAAc,MAAK;mBAAM,EAAc,EAAK,IAAI;QAAgB,CAAA;OAC5D,CAAA,GACN,kBAAC,QAAD;QAAM,WAAU;kBAAmC,EAAK;OAAY,CAAA,CAChE;SAfC,EAAK,IAeN;KAEV,CAAC;IACE,CAAA,CACO;KACT;IAEN;;AAET,CACF;AACA,EAAa,cAAc"}
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 (currentPath / user / items) and router-agnostic via `useLink`.\n * The \"More\" overflow uses the DS `Sheet` primitive, so it inherits focus trap,\n * scroll lock, return-focus, `aria-modal`, and trigger↔panel ARIA wiring.\n */\nimport { IconDots } from '@tabler/icons-react'\nimport { motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\nimport { useState } from 'react'\n\nimport { Badge } from '../ui/badge'\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 { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '../ui/sheet'\nimport { useLink } from './link-context'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface BottomNavbarUser {\n name: string\n role?: string\n}\n\nexport interface BottomNavItem {\n title: string\n href: string\n /** Icon for this nav item. Accepts any `IconInput`. */\n icon: IconInput\n /** Icon shown when the item is active — e.g. a filled variant. Falls back to `icon`. */\n activeIcon?: 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 * Roles allowed to see this item, matched against `user.role`. Omit to show\n * it to everyone. For arbitrary logic, use `canView` instead.\n */\n roles?: string[]\n /**\n * Visibility predicate — full control over whether this item renders.\n * Receives the current `user` (or `null`). Takes precedence over `roles`.\n */\n canView?: (user: BottomNavbarUser | null) => boolean\n}\n\n/**\n * Active-item indicator, animated between items on selection:\n * - `pill` (default) — Material-3 tonal pill behind the icon\n * - `underline` — top accent bar (Material-2 tab style)\n * - `tint` — subtle background tint on the whole active cell\n * - `none` — no shape; rely on the filled `activeIcon` + accent color (iOS)\n */\nexport type BottomNavIndicator = 'pill' | 'underline' | 'tint' | 'none'\n/** Show labels always (default) or only for the selected item (narrow viewports). */\nexport type BottomNavLabelVisibility = 'always' | 'selected'\n\nexport interface BottomNavbarProps extends React.HTMLAttributes<HTMLElement> {\n /** Currently active pathname */\n currentPath?: string\n /** Current user. Drives per-item role gating via `item.roles` / `item.canView`. */\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 sheet */\n moreItems?: BottomNavItem[]\n /** Active-indicator style. @default 'pill' */\n indicator?: BottomNavIndicator\n /** Label visibility. @default 'always' */\n labelVisibility?: BottomNavLabelVisibility\n /** Additional className for the nav element */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------\n\n/** Per-item role/visibility gate. `canView` wins; else `roles` matched against user.role; else visible. */\nfunction itemVisible(item: BottomNavItem, user: BottomNavbarUser | null): boolean {\n if (item.canView) return item.canView(user)\n if (item.roles && item.roles.length > 0) {\n return !!user?.role && item.roles.includes(user.role)\n }\n return true\n}\n\n// -----------------------------------------------------------------------\n// NavBadge (composes Badge)\n// -----------------------------------------------------------------------\n\nfunction NavBadge({ count }: { count: number }) {\n if (!count || count <= 0) return null\n const display = count > 99 ? '99+' : String(count)\n return (\n <Badge\n color=\"error\"\n variant=\"solid\"\n size=\"xs\"\n aria-label={`${count} notifications`}\n className=\"pointer-events-none absolute -end-1 -top-1 justify-center px-ds-01 tabular-nums motion-safe:animate-in motion-safe:zoom-in-75\"\n >\n {display}\n </Badge>\n )\n}\n\n// -----------------------------------------------------------------------\n// Active indicator (shared-element)\n// -----------------------------------------------------------------------\n\n/**\n * The active-item indicator. A single shared-element (`layoutId`) that SLIDES\n * to the selected item and fades in on first appearance. `none` renders\n * nothing (the filled `activeIcon` + accent color carry the state).\n */\nfunction ActiveIndicator({\n indicator,\n layoutId,\n reduced,\n}: {\n indicator: BottomNavIndicator\n layoutId: string\n reduced: boolean\n}) {\n if (indicator === 'none') return null\n const common = {\n layoutId,\n 'aria-hidden': true as const,\n transition: reduced ? { duration: 0 } : springs.snappy,\n initial: reduced ? false : { opacity: 0 },\n animate: { opacity: 1 },\n }\n if (indicator === 'underline') {\n return <motion.span {...common} className=\"absolute top-0 h-[3px] w-full rounded-b-control-inner bg-accent-9\" />\n }\n if (indicator === 'tint') {\n return <motion.span {...common} className=\"absolute inset-0 rounded-control bg-accent-4\" />\n }\n // pill (default) — Material-3 tonal pill behind the icon\n return <motion.span {...common} className=\"absolute inset-0 rounded-pill bg-accent-4\" />\n}\n\n// -----------------------------------------------------------------------\n// BottomNavLink (internal)\n// -----------------------------------------------------------------------\n\nconst itemClass =\n 'relative flex h-16 w-full min-w-0 cursor-pointer flex-col items-center justify-center gap-ds-02 px-ds-01 pt-0 text-body-sm transition-colors duration-fast-02 ease-productive-standard'\n\nfunction BottomNavLink({\n item,\n isActive,\n indicator,\n indicatorId,\n showLabel,\n reduced,\n}: {\n item: BottomNavItem\n isActive: boolean\n indicator: BottomNavIndicator\n indicatorId: string\n showLabel: boolean\n reduced: boolean\n}) {\n const Link = useLink()\n return (\n <motion.div\n whileTap={reduced ? undefined : { scale: 0.96 }}\n transition={reduced ? { duration: 0 } : springs.snappy}\n className=\"flex min-w-0 flex-1 basis-0\"\n >\n <Link\n href={item.href}\n aria-label={item.title}\n aria-current={isActive ? 'page' : undefined}\n className={cn(itemClass, isActive ? 'font-semibold text-accent-11' : 'text-surface-fg-subtle')}\n >\n {/* tint covers the whole cell — sits behind the content */}\n {isActive && indicator === 'tint' && (\n <ActiveIndicator indicator=\"tint\" layoutId={indicatorId} reduced={reduced} />\n )}\n <div className=\"relative flex w-full min-w-0 flex-col items-center gap-ds-02\">\n {isActive && indicator === 'underline' && (\n <ActiveIndicator indicator=\"underline\" layoutId={indicatorId} reduced={reduced} />\n )}\n <div className=\"relative px-ds-04 py-ds-01\">\n {isActive && indicator === 'pill' && (\n <ActiveIndicator indicator=\"pill\" layoutId={indicatorId} reduced={reduced} />\n )}\n <span className=\"relative [&>svg]:h-ico-md [&>svg]:w-ico-md\" aria-hidden=\"true\">\n <IconProvider size=\"md\">\n {normalizeIcon(isActive && item.activeIcon ? item.activeIcon : item.icon)}\n </IconProvider>\n </span>\n {item.badge != null && <NavBadge count={item.badge} />}\n </div>\n {showLabel && <span className=\"max-w-full truncate 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 = null,\n primaryItems = [],\n moreItems = [],\n indicator = 'pill',\n labelVisibility = 'always',\n className,\n ...props\n },\n ref,\n ) => {\n const Link = useLink()\n const reduced = useReducedMotion() ?? false\n const [showMore, setShowMore] = useState(false)\n // Scope the shared-element layoutId per instance so two navbars don't animate into each other.\n const instanceId = React.useId()\n const indicatorId = `${instanceId}-nav-indicator`\n\n const isActive = (path: string, exact = false) => {\n if (exact || path === '/') return currentPath === path\n return currentPath.startsWith(path)\n }\n\n // Role/visibility gating\n const visiblePrimary = primaryItems.filter((item) => itemVisible(item, user))\n const visibleMore = moreItems.filter((item) => itemVisible(item, user))\n\n const isMoreActive = visibleMore.some((item) => isActive(item.href, item.exact))\n const moreSelected = showMore || isMoreActive\n const showMoreLabel = labelVisibility === 'always' || moreSelected\n\n return (\n <nav\n {...props}\n ref={ref}\n aria-label=\"Mobile navigation\"\n className={cn(\n 'fixed bottom-0 start-0 end-0 z-sticky flex w-full flex-row items-stretch justify-between border-t border-surface-border-strong bg-surface-base px-ds-05 pb-safe pt-0 md:hidden',\n className,\n )}\n >\n {visiblePrimary.map((item) => (\n <BottomNavLink\n key={item.href}\n item={item}\n isActive={isActive(item.href, item.exact)}\n indicator={indicator}\n indicatorId={indicatorId}\n showLabel={labelVisibility === 'always' || isActive(item.href, item.exact)}\n reduced={reduced}\n />\n ))}\n\n {visibleMore.length > 0 && (\n <Sheet open={showMore} onOpenChange={setShowMore}>\n <SheetTrigger asChild>\n <motion.button\n type=\"button\"\n aria-label=\"More navigation options\"\n whileTap={reduced ? undefined : { scale: 0.96 }}\n transition={reduced ? { duration: 0 } : springs.snappy}\n className={cn(\n itemClass,\n 'min-w-0 flex-1 basis-0',\n moreSelected ? 'font-semibold text-accent-11' : 'text-surface-fg-subtle',\n )}\n >\n {moreSelected && indicator === 'tint' && (\n <ActiveIndicator indicator=\"tint\" layoutId={indicatorId} reduced={reduced} />\n )}\n <div className=\"relative flex w-full min-w-0 flex-col items-center gap-ds-02\">\n {moreSelected && indicator === 'underline' && (\n <ActiveIndicator indicator=\"underline\" layoutId={indicatorId} reduced={reduced} />\n )}\n <div className=\"relative px-ds-04 py-ds-01\">\n {moreSelected && indicator === 'pill' && (\n <ActiveIndicator indicator=\"pill\" layoutId={indicatorId} reduced={reduced} />\n )}\n <Icon icon={IconDots} />\n </div>\n {showMoreLabel && <span className=\"max-w-full truncate text-center\">More</span>}\n </div>\n </motion.button>\n </SheetTrigger>\n\n <SheetContent side=\"bottom\" className=\"rounded-t-bubble\">\n <SheetHeader>\n <SheetTitle>More</SheetTitle>\n </SheetHeader>\n <div className=\"grid grid-cols-[repeat(auto-fit,minmax(72px,1fr))] gap-ds-03 pt-ds-04\">\n {visibleMore.map((item) => {\n const active = isActive(item.href, item.exact)\n return (\n <Link\n key={item.href}\n href={item.href}\n onClick={() => setShowMore(false)}\n aria-current={active ? 'page' : undefined}\n className={cn(\n 'flex min-w-0 flex-col items-center gap-ds-02b rounded-overlay-lg p-ds-04 text-body-sm transition-colors ease-productive-standard',\n active\n ? 'bg-surface-panel-hover text-accent-11'\n : 'text-surface-fg-subtle hover:bg-surface-panel-hover',\n )}\n >\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md\" aria-hidden=\"true\">\n <IconProvider size=\"md\">{normalizeIcon(item.icon)}</IconProvider>\n </span>\n <span className=\"max-w-full truncate text-center\">{item.title}</span>\n </Link>\n )\n })}\n </div>\n </SheetContent>\n </Sheet>\n )}\n </nav>\n )\n },\n)\nBottomNavbar.displayName = 'BottomNavbar'\n\nexport { BottomNavbar }\n"],"mappings":";;;;;;;;;;;;;;;;AAyFA,SAAS,EAAY,GAAqB,GAAwC;CAKhF,OAJI,EAAK,UAAgB,EAAK,QAAQ,CAAI,IACtC,EAAK,SAAS,EAAK,MAAM,SAAS,IAC7B,CAAC,CAAC,GAAM,QAAQ,EAAK,MAAM,SAAS,EAAK,IAAI,IAE/C;AACT;AAMA,SAAS,EAAS,EAAE,YAA4B;CAC9C,IAAI,CAAC,KAAS,KAAS,GAAG,OAAO;CACjC,IAAM,IAAU,IAAQ,KAAK,QAAQ,OAAO,CAAK;CACjD,OACE,kBAAC,GAAD;EACE,OAAM;EACN,SAAQ;EACR,MAAK;EACL,cAAY,GAAG,EAAM;EACrB,WAAU;YAET;CACI,CAAA;AAEX;AAWA,SAAS,EAAgB,EACvB,cACA,aACA,cAKC;CACD,IAAI,MAAc,QAAQ,OAAO;CACjC,IAAM,IAAS;EACb;EACA,eAAe;EACf,YAAY,IAAU,EAAE,UAAU,EAAE,IAAI,EAAQ;EAChD,SAAS,MAAkB,EAAE,SAAS,EAAE;EACxC,SAAS,EAAE,SAAS,EAAE;CACxB;CAQA,OAPI,MAAc,cACT,kBAAC,EAAO,MAAR;EAAa,GAAI;EAAQ,WAAU;CAAqE,CAAA,IAE7G,MAAc,SACT,kBAAC,EAAO,MAAR;EAAa,GAAI;EAAQ,WAAU;CAAgD,CAAA,IAGrF,kBAAC,EAAO,MAAR;EAAa,GAAI;EAAQ,WAAU;CAA6C,CAAA;AACzF;AAMA,IAAM,IACJ;AAEF,SAAS,EAAc,EACrB,SACA,aACA,cACA,gBACA,cACA,cAQC;CACD,IAAM,IAAO,EAAQ;CACrB,OACE,kBAAC,EAAO,KAAR;EACE,UAAU,IAAU,KAAA,IAAY,EAAE,OAAO,IAAK;EAC9C,YAAY,IAAU,EAAE,UAAU,EAAE,IAAI,EAAQ;EAChD,WAAU;YAEV,kBAAC,GAAD;GACE,MAAM,EAAK;GACX,cAAY,EAAK;GACjB,gBAAc,IAAW,SAAS,KAAA;GAClC,WAAW,EAAG,GAAW,IAAW,iCAAiC,wBAAwB;aAJ/F,CAOG,KAAY,MAAc,UACzB,kBAAC,GAAD;IAAiB,WAAU;IAAO,UAAU;IAAsB;GAAU,CAAA,GAE9E,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,KAAY,MAAc,eACzB,kBAAC,GAAD;MAAiB,WAAU;MAAY,UAAU;MAAsB;KAAU,CAAA;KAEnF,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACG,KAAY,MAAc,UACzB,kBAAC,GAAD;QAAiB,WAAU;QAAO,UAAU;QAAsB;OAAU,CAAA;OAE9E,kBAAC,QAAD;QAAM,WAAU;QAA6C,eAAY;kBACvE,kBAAC,GAAD;SAAc,MAAK;mBAChB,EAAc,KAAY,EAAK,aAAa,EAAK,aAAa,EAAK,IAAI;QAC5D,CAAA;OACV,CAAA;OACL,EAAK,SAAS,QAAQ,kBAAC,GAAD,EAAU,OAAO,EAAK,MAAQ,CAAA;MAClD;;KACJ,KAAa,kBAAC,QAAD;MAAM,WAAU;gBAAmC,EAAK;KAAY,CAAA;IAC/E;KACD;;CACI,CAAA;AAEhB;AAMA,IAAM,IAAe,EAAM,YAEvB,EACE,iBAAc,KACd,UAAO,MACP,kBAAe,CAAC,GAChB,eAAY,CAAC,GACb,eAAY,QACZ,qBAAkB,UAClB,cACA,GAAG,KAEL,MACG;CACH,IAAM,IAAO,EAAQ,GACf,IAAU,EAAiB,KAAK,IAChC,CAAC,GAAU,KAAe,EAAS,EAAK,GAGxC,IAAc,GADD,EAAM,MACF,EAAW,iBAE5B,KAAY,GAAc,IAAQ,OAClC,KAAS,MAAS,MAAY,MAAgB,IAC3C,EAAY,WAAW,CAAI,GAI9B,IAAiB,EAAa,QAAQ,MAAS,EAAY,GAAM,CAAI,CAAC,GACtE,IAAc,EAAU,QAAQ,MAAS,EAAY,GAAM,CAAI,CAAC,GAEhE,IAAe,EAAY,MAAM,MAAS,EAAS,EAAK,MAAM,EAAK,KAAK,CAAC,GACzE,IAAe,KAAY,GAC3B,IAAgB,MAAoB,YAAY;CAEtD,OACE,kBAAC,OAAD;EACE,GAAI;EACC;EACL,cAAW;EACX,WAAW,EACT,kLACA,CACF;YAPF,CASG,EAAe,KAAK,MACnB,kBAAC,GAAD;GAEQ;GACN,UAAU,EAAS,EAAK,MAAM,EAAK,KAAK;GAC7B;GACE;GACb,WAAW,MAAoB,YAAY,EAAS,EAAK,MAAM,EAAK,KAAK;GAChE;EACV,GAPM,EAAK,IAOX,CACF,GAEA,EAAY,SAAS,KACpB,kBAAC,GAAD;GAAO,MAAM;GAAU,cAAc;aAArC,CACE,kBAAC,GAAD;IAAc,SAAA;cACZ,kBAAC,EAAO,QAAR;KACE,MAAK;KACL,cAAW;KACX,UAAU,IAAU,KAAA,IAAY,EAAE,OAAO,IAAK;KAC9C,YAAY,IAAU,EAAE,UAAU,EAAE,IAAI,EAAQ;KAChD,WAAW,EACT,GACA,0BACA,IAAe,iCAAiC,wBAClD;eATF,CAWG,KAAgB,MAAc,UAC7B,kBAAC,GAAD;MAAiB,WAAU;MAAO,UAAU;MAAsB;KAAU,CAAA,GAE9E,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACG,KAAgB,MAAc,eAC7B,kBAAC,GAAD;QAAiB,WAAU;QAAY,UAAU;QAAsB;OAAU,CAAA;OAEnF,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACG,KAAgB,MAAc,UAC7B,kBAAC,GAAD;SAAiB,WAAU;SAAO,UAAU;SAAsB;QAAU,CAAA,GAE9E,kBAAC,GAAD,EAAM,MAAM,EAAW,CAAA,CACpB;;OACJ,KAAiB,kBAAC,QAAD;QAAM,WAAU;kBAAkC;OAAU,CAAA;MAC3E;OACQ;;GACH,CAAA,GAEd,kBAAC,GAAD;IAAc,MAAK;IAAS,WAAU;cAAtC,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAY,OAAgB,CAAA,EACjB,CAAA,GACb,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAY,KAAK,MAAS;MACzB,IAAM,IAAS,EAAS,EAAK,MAAM,EAAK,KAAK;MAC7C,OACE,kBAAC,GAAD;OAEE,MAAM,EAAK;OACX,eAAe,EAAY,EAAK;OAChC,gBAAc,IAAS,SAAS,KAAA;OAChC,WAAW,EACT,oIACA,IACI,0CACA,qDACN;iBAVF,CAYE,kBAAC,QAAD;QAAM,WAAU;QAAoC,eAAY;kBAC9D,kBAAC,GAAD;SAAc,MAAK;mBAAM,EAAc,EAAK,IAAI;QAAgB,CAAA;OAC5D,CAAA,GACN,kBAAC,QAAD;QAAM,WAAU;kBAAmC,EAAK;OAAY,CAAA,CAChE;SAfC,EAAK,IAeN;KAEV,CAAC;IACE,CAAA,CACO;KACT;IAEN;;AAET,CACF;AACA,EAAa,cAAc"}