@hyunsdev/ui 0.1.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 (340) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +89 -0
  3. package/SKILL.md +38 -0
  4. package/dist/WindowContext-DybYtZJa.d.ts +50 -0
  5. package/dist/_styles-BbTx89aX.d.ts +3 -0
  6. package/dist/chunk-23KUNTRD.js +49 -0
  7. package/dist/chunk-23KUNTRD.js.map +1 -0
  8. package/dist/chunk-3RTSANKB.js +51 -0
  9. package/dist/chunk-3RTSANKB.js.map +1 -0
  10. package/dist/chunk-4QIWBOF4.js +129 -0
  11. package/dist/chunk-4QIWBOF4.js.map +1 -0
  12. package/dist/chunk-5JCWC7IU.js +293 -0
  13. package/dist/chunk-5JCWC7IU.js.map +1 -0
  14. package/dist/chunk-6ANDNGHD.js +33 -0
  15. package/dist/chunk-6ANDNGHD.js.map +1 -0
  16. package/dist/chunk-7W7QZHEZ.js +42 -0
  17. package/dist/chunk-7W7QZHEZ.js.map +1 -0
  18. package/dist/chunk-BHO4WT2N.js +51 -0
  19. package/dist/chunk-BHO4WT2N.js.map +1 -0
  20. package/dist/chunk-BI3KKBIC.js +11 -0
  21. package/dist/chunk-BI3KKBIC.js.map +1 -0
  22. package/dist/chunk-D3SP7GL3.js +55 -0
  23. package/dist/chunk-D3SP7GL3.js.map +1 -0
  24. package/dist/chunk-D7W4RSQX.js +115 -0
  25. package/dist/chunk-D7W4RSQX.js.map +1 -0
  26. package/dist/chunk-DN2AEEA2.js +11 -0
  27. package/dist/chunk-DN2AEEA2.js.map +1 -0
  28. package/dist/chunk-ETTKFCO6.js +84 -0
  29. package/dist/chunk-ETTKFCO6.js.map +1 -0
  30. package/dist/chunk-GJT7TDBS.js +66 -0
  31. package/dist/chunk-GJT7TDBS.js.map +1 -0
  32. package/dist/chunk-HZT6RQYZ.js +109 -0
  33. package/dist/chunk-HZT6RQYZ.js.map +1 -0
  34. package/dist/chunk-JB2QZV7K.js +60 -0
  35. package/dist/chunk-JB2QZV7K.js.map +1 -0
  36. package/dist/chunk-KJJB2PVC.js +21 -0
  37. package/dist/chunk-KJJB2PVC.js.map +1 -0
  38. package/dist/chunk-NE3IVPMO.js +31 -0
  39. package/dist/chunk-NE3IVPMO.js.map +1 -0
  40. package/dist/chunk-O2BG2KSY.js +23 -0
  41. package/dist/chunk-O2BG2KSY.js.map +1 -0
  42. package/dist/chunk-OUFGNJ3V.js +1726 -0
  43. package/dist/chunk-OUFGNJ3V.js.map +1 -0
  44. package/dist/chunk-PLZMCJSL.js +351 -0
  45. package/dist/chunk-PLZMCJSL.js.map +1 -0
  46. package/dist/chunk-POG5DZBT.js +104 -0
  47. package/dist/chunk-POG5DZBT.js.map +1 -0
  48. package/dist/chunk-SECZM6JE.js +170 -0
  49. package/dist/chunk-SECZM6JE.js.map +1 -0
  50. package/dist/chunk-T64WPXSC.js +48 -0
  51. package/dist/chunk-T64WPXSC.js.map +1 -0
  52. package/dist/chunk-TU5CYBB4.js +90 -0
  53. package/dist/chunk-TU5CYBB4.js.map +1 -0
  54. package/dist/chunk-UVAI2U6X.js +153 -0
  55. package/dist/chunk-UVAI2U6X.js.map +1 -0
  56. package/dist/chunk-UXCBLYG6.js +142 -0
  57. package/dist/chunk-UXCBLYG6.js.map +1 -0
  58. package/dist/chunk-VUR4MQMH.js +53 -0
  59. package/dist/chunk-VUR4MQMH.js.map +1 -0
  60. package/dist/chunk-WIEKNG4S.js +26 -0
  61. package/dist/chunk-WIEKNG4S.js.map +1 -0
  62. package/dist/chunk-WIZ4OLOB.js +23 -0
  63. package/dist/chunk-WIZ4OLOB.js.map +1 -0
  64. package/dist/chunk-WJRJBMFN.js +21 -0
  65. package/dist/chunk-WJRJBMFN.js.map +1 -0
  66. package/dist/chunk-YUPLJP3F.js +33 -0
  67. package/dist/chunk-YUPLJP3F.js.map +1 -0
  68. package/dist/chunk-Z7ITPSUF.js +184 -0
  69. package/dist/chunk-Z7ITPSUF.js.map +1 -0
  70. package/dist/chunk-ZC76ALSI.js +75 -0
  71. package/dist/chunk-ZC76ALSI.js.map +1 -0
  72. package/dist/code-block-core-xkE94Rk5.d.ts +30 -0
  73. package/dist/components/accordion.d.ts +9 -0
  74. package/dist/components/accordion.js +98 -0
  75. package/dist/components/accordion.js.map +1 -0
  76. package/dist/components/alert-dialog.d.ts +26 -0
  77. package/dist/components/alert-dialog.js +341 -0
  78. package/dist/components/alert-dialog.js.map +1 -0
  79. package/dist/components/alert.d.ts +13 -0
  80. package/dist/components/alert.js +76 -0
  81. package/dist/components/alert.js.map +1 -0
  82. package/dist/components/aspect-ratio.d.ts +6 -0
  83. package/dist/components/aspect-ratio.js +12 -0
  84. package/dist/components/aspect-ratio.js.map +1 -0
  85. package/dist/components/avatar.d.ts +13 -0
  86. package/dist/components/avatar.js +19 -0
  87. package/dist/components/avatar.js.map +1 -0
  88. package/dist/components/badge.d.ts +12 -0
  89. package/dist/components/badge.js +11 -0
  90. package/dist/components/badge.js.map +1 -0
  91. package/dist/components/breadcrumb.d.ts +13 -0
  92. package/dist/components/breadcrumb.js +102 -0
  93. package/dist/components/breadcrumb.js.map +1 -0
  94. package/dist/components/button-group.d.ts +16 -0
  95. package/dist/components/button-group.js +15 -0
  96. package/dist/components/button-group.js.map +1 -0
  97. package/dist/components/button.d.ts +14 -0
  98. package/dist/components/button.js +11 -0
  99. package/dist/components/button.js.map +1 -0
  100. package/dist/components/calendar.d.ts +14 -0
  101. package/dist/components/calendar.js +13 -0
  102. package/dist/components/calendar.js.map +1 -0
  103. package/dist/components/card.d.ts +13 -0
  104. package/dist/components/card.js +21 -0
  105. package/dist/components/card.js.map +1 -0
  106. package/dist/components/carousel.d.ts +32 -0
  107. package/dist/components/carousel.js +196 -0
  108. package/dist/components/carousel.js.map +1 -0
  109. package/dist/components/chart.d.ts +46 -0
  110. package/dist/components/chart.js +254 -0
  111. package/dist/components/chart.js.map +1 -0
  112. package/dist/components/checkbox.d.ts +6 -0
  113. package/dist/components/checkbox.js +41 -0
  114. package/dist/components/checkbox.js.map +1 -0
  115. package/dist/components/code-block-core.d.ts +3 -0
  116. package/dist/components/code-block-core.js +13 -0
  117. package/dist/components/code-block-core.js.map +1 -0
  118. package/dist/components/code-block-custom.d.ts +20 -0
  119. package/dist/components/code-block-custom.js +16 -0
  120. package/dist/components/code-block-custom.js.map +1 -0
  121. package/dist/components/code-block-shiki.d.ts +13 -0
  122. package/dist/components/code-block-shiki.js +15 -0
  123. package/dist/components/code-block-shiki.js.map +1 -0
  124. package/dist/components/code-block.d.ts +5 -0
  125. package/dist/components/code-block.js +14 -0
  126. package/dist/components/code-block.js.map +1 -0
  127. package/dist/components/collapsible.d.ts +8 -0
  128. package/dist/components/collapsible.js +24 -0
  129. package/dist/components/collapsible.js.map +1 -0
  130. package/dist/components/collection.d.ts +63 -0
  131. package/dist/components/collection.js +598 -0
  132. package/dist/components/collection.js.map +1 -0
  133. package/dist/components/color-dot.d.ts +19 -0
  134. package/dist/components/color-dot.js +41 -0
  135. package/dist/components/color-dot.js.map +1 -0
  136. package/dist/components/color-picker.d.ts +12 -0
  137. package/dist/components/color-picker.js +142 -0
  138. package/dist/components/color-picker.js.map +1 -0
  139. package/dist/components/combobox.d.ts +74 -0
  140. package/dist/components/combobox.js +610 -0
  141. package/dist/components/combobox.js.map +1 -0
  142. package/dist/components/command.d.ts +21 -0
  143. package/dist/components/command.js +31 -0
  144. package/dist/components/command.js.map +1 -0
  145. package/dist/components/date-picker.d.ts +43 -0
  146. package/dist/components/date-picker.js +235 -0
  147. package/dist/components/date-picker.js.map +1 -0
  148. package/dist/components/dialog.d.ts +25 -0
  149. package/dist/components/dialog.js +31 -0
  150. package/dist/components/dialog.js.map +1 -0
  151. package/dist/components/drawer.d.ts +15 -0
  152. package/dist/components/drawer.js +124 -0
  153. package/dist/components/drawer.js.map +1 -0
  154. package/dist/components/dropdown-menu.d.ts +34 -0
  155. package/dist/components/dropdown-menu.js +248 -0
  156. package/dist/components/dropdown-menu.js.map +1 -0
  157. package/dist/components/empty.d.ts +15 -0
  158. package/dist/components/empty.js +104 -0
  159. package/dist/components/empty.js.map +1 -0
  160. package/dist/components/field.d.ts +29 -0
  161. package/dist/components/field.js +214 -0
  162. package/dist/components/field.js.map +1 -0
  163. package/dist/components/format-bytes.d.ts +12 -0
  164. package/dist/components/format-bytes.js +30 -0
  165. package/dist/components/format-bytes.js.map +1 -0
  166. package/dist/components/format-number.d.ts +12 -0
  167. package/dist/components/format-number.js +30 -0
  168. package/dist/components/format-number.js.map +1 -0
  169. package/dist/components/gauge.d.ts +11 -0
  170. package/dist/components/gauge.js +82 -0
  171. package/dist/components/gauge.js.map +1 -0
  172. package/dist/components/hover-card.d.ts +8 -0
  173. package/dist/components/hover-card.js +45 -0
  174. package/dist/components/hover-card.js.map +1 -0
  175. package/dist/components/input-group.d.ts +24 -0
  176. package/dist/components/input-group.js +23 -0
  177. package/dist/components/input-group.js.map +1 -0
  178. package/dist/components/input-otp.d.ts +20 -0
  179. package/dist/components/input-otp.js +95 -0
  180. package/dist/components/input-otp.js.map +1 -0
  181. package/dist/components/input.d.ts +9 -0
  182. package/dist/components/input.js +9 -0
  183. package/dist/components/input.js.map +1 -0
  184. package/dist/components/item.d.ts +27 -0
  185. package/dist/components/item.js +182 -0
  186. package/dist/components/item.js.map +1 -0
  187. package/dist/components/kbd.d.ts +6 -0
  188. package/dist/components/kbd.js +34 -0
  189. package/dist/components/kbd.js.map +1 -0
  190. package/dist/components/label.d.ts +6 -0
  191. package/dist/components/label.js +9 -0
  192. package/dist/components/label.js.map +1 -0
  193. package/dist/components/loading-bar.d.ts +8 -0
  194. package/dist/components/loading-bar.js +127 -0
  195. package/dist/components/loading-bar.js.map +1 -0
  196. package/dist/components/loading-dots.d.ts +5 -0
  197. package/dist/components/loading-dots.js +45 -0
  198. package/dist/components/loading-dots.js.map +1 -0
  199. package/dist/components/main-provider.d.ts +7 -0
  200. package/dist/components/main-provider.js +12 -0
  201. package/dist/components/main-provider.js.map +1 -0
  202. package/dist/components/mark.d.ts +11 -0
  203. package/dist/components/mark.js +44 -0
  204. package/dist/components/mark.js.map +1 -0
  205. package/dist/components/pagination.d.ts +21 -0
  206. package/dist/components/pagination.js +114 -0
  207. package/dist/components/pagination.js.map +1 -0
  208. package/dist/components/popover.d.ts +12 -0
  209. package/dist/components/popover.js +22 -0
  210. package/dist/components/popover.js.map +1 -0
  211. package/dist/components/prev-next-navigation.d.ts +15 -0
  212. package/dist/components/prev-next-navigation.js +85 -0
  213. package/dist/components/prev-next-navigation.js.map +1 -0
  214. package/dist/components/progress.d.ts +6 -0
  215. package/dist/components/progress.js +38 -0
  216. package/dist/components/progress.js.map +1 -0
  217. package/dist/components/radio-group.d.ts +7 -0
  218. package/dist/components/radio-group.js +57 -0
  219. package/dist/components/radio-group.js.map +1 -0
  220. package/dist/components/relative-time.d.ts +16 -0
  221. package/dist/components/relative-time.js +75 -0
  222. package/dist/components/relative-time.js.map +1 -0
  223. package/dist/components/resizable.d.ts +10 -0
  224. package/dist/components/resizable.js +45 -0
  225. package/dist/components/resizable.js.map +1 -0
  226. package/dist/components/scroll-area.d.ts +7 -0
  227. package/dist/components/scroll-area.js +11 -0
  228. package/dist/components/scroll-area.js.map +1 -0
  229. package/dist/components/select.d.ts +20 -0
  230. package/dist/components/select.js +189 -0
  231. package/dist/components/select.js.map +1 -0
  232. package/dist/components/separator.d.ts +6 -0
  233. package/dist/components/separator.js +9 -0
  234. package/dist/components/separator.js.map +1 -0
  235. package/dist/components/sheet.d.ts +16 -0
  236. package/dist/components/sheet.js +25 -0
  237. package/dist/components/sheet.js.map +1 -0
  238. package/dist/components/show-more.d.ts +15 -0
  239. package/dist/components/show-more.js +79 -0
  240. package/dist/components/show-more.js.map +1 -0
  241. package/dist/components/skeleton.d.ts +5 -0
  242. package/dist/components/skeleton.js +8 -0
  243. package/dist/components/skeleton.js.map +1 -0
  244. package/dist/components/slider.d.ts +6 -0
  245. package/dist/components/slider.js +65 -0
  246. package/dist/components/slider.js.map +1 -0
  247. package/dist/components/snippet.d.ts +13 -0
  248. package/dist/components/snippet.js +135 -0
  249. package/dist/components/snippet.js.map +1 -0
  250. package/dist/components/sonner.d.ts +6 -0
  251. package/dist/components/sonner.js +10 -0
  252. package/dist/components/sonner.js.map +1 -0
  253. package/dist/components/spinner.d.ts +5 -0
  254. package/dist/components/spinner.js +8 -0
  255. package/dist/components/spinner.js.map +1 -0
  256. package/dist/components/stat.d.ts +17 -0
  257. package/dist/components/stat.js +71 -0
  258. package/dist/components/stat.js.map +1 -0
  259. package/dist/components/steps.d.ts +17 -0
  260. package/dist/components/steps.js +133 -0
  261. package/dist/components/steps.js.map +1 -0
  262. package/dist/components/switch.d.ts +8 -0
  263. package/dist/components/switch.js +44 -0
  264. package/dist/components/switch.js.map +1 -0
  265. package/dist/components/table.d.ts +12 -0
  266. package/dist/components/table.js +101 -0
  267. package/dist/components/table.js.map +1 -0
  268. package/dist/components/tabs.d.ts +14 -0
  269. package/dist/components/tabs.js +88 -0
  270. package/dist/components/tabs.js.map +1 -0
  271. package/dist/components/textarea.d.ts +5 -0
  272. package/dist/components/textarea.js +9 -0
  273. package/dist/components/textarea.js.map +1 -0
  274. package/dist/components/theme-provider.d.ts +10 -0
  275. package/dist/components/theme-provider.js +14 -0
  276. package/dist/components/theme-provider.js.map +1 -0
  277. package/dist/components/time-picker.d.ts +17 -0
  278. package/dist/components/time-picker.js +219 -0
  279. package/dist/components/time-picker.js.map +1 -0
  280. package/dist/components/timeline.d.ts +17 -0
  281. package/dist/components/timeline.js +138 -0
  282. package/dist/components/timeline.js.map +1 -0
  283. package/dist/components/toggle-group.d.ts +14 -0
  284. package/dist/components/toggle-group.js +82 -0
  285. package/dist/components/toggle-group.js.map +1 -0
  286. package/dist/components/toggle.d.ts +12 -0
  287. package/dist/components/toggle.js +11 -0
  288. package/dist/components/toggle.js.map +1 -0
  289. package/dist/components/tooltip.d.ts +9 -0
  290. package/dist/components/tooltip.js +15 -0
  291. package/dist/components/tooltip.js.map +1 -0
  292. package/dist/components/typography.d.ts +17 -0
  293. package/dist/components/typography.js +91 -0
  294. package/dist/components/typography.js.map +1 -0
  295. package/dist/hooks/use-mobile.d.ts +3 -0
  296. package/dist/hooks/use-mobile.js +7 -0
  297. package/dist/hooks/use-mobile.js.map +1 -0
  298. package/dist/hooks/use-theme.d.ts +3 -0
  299. package/dist/hooks/use-theme.js +8 -0
  300. package/dist/hooks/use-theme.js.map +1 -0
  301. package/dist/index.d.ts +7 -0
  302. package/dist/index.js +27 -0
  303. package/dist/index.js.map +1 -0
  304. package/dist/layouts/center/index.d.ts +18 -0
  305. package/dist/layouts/center/index.js +73 -0
  306. package/dist/layouts/center/index.js.map +1 -0
  307. package/dist/layouts/chat/index.d.ts +42 -0
  308. package/dist/layouts/chat/index.js +191 -0
  309. package/dist/layouts/chat/index.js.map +1 -0
  310. package/dist/layouts/command/index.d.ts +2 -0
  311. package/dist/layouts/command/index.js +1 -0
  312. package/dist/layouts/command/index.js.map +1 -0
  313. package/dist/layouts/panel/index.d.ts +55 -0
  314. package/dist/layouts/panel/index.js +513 -0
  315. package/dist/layouts/panel/index.js.map +1 -0
  316. package/dist/layouts/presentation/index.d.ts +14 -0
  317. package/dist/layouts/presentation/index.js +100 -0
  318. package/dist/layouts/presentation/index.js.map +1 -0
  319. package/dist/layouts/site/index.d.ts +17 -0
  320. package/dist/layouts/site/index.js +82 -0
  321. package/dist/layouts/site/index.js.map +1 -0
  322. package/dist/layouts/window/index.d.ts +223 -0
  323. package/dist/layouts/window/index.js +127 -0
  324. package/dist/layouts/window/index.js.map +1 -0
  325. package/dist/layouts/workbench/index.d.ts +281 -0
  326. package/dist/layouts/workbench/index.js +2457 -0
  327. package/dist/layouts/workbench/index.js.map +1 -0
  328. package/dist/lib/format.d.ts +15 -0
  329. package/dist/lib/format.js +9 -0
  330. package/dist/lib/format.js.map +1 -0
  331. package/dist/lib/theme.d.ts +22 -0
  332. package/dist/lib/theme.js +25 -0
  333. package/dist/lib/theme.js.map +1 -0
  334. package/dist/lib/utils.d.ts +5 -0
  335. package/dist/lib/utils.js +7 -0
  336. package/dist/lib/utils.js.map +1 -0
  337. package/dist/styles/fonts.css +1 -0
  338. package/dist/styles/globals.css +717 -0
  339. package/dist/styles/tokens.css +693 -0
  340. package/package.json +137 -0
@@ -0,0 +1,1726 @@
1
+ import {
2
+ sidedockFocusClass,
3
+ sidedockOutlineStrokeClass,
4
+ sidedockShellClass
5
+ } from "./chunk-BI3KKBIC.js";
6
+ import {
7
+ Skeleton
8
+ } from "./chunk-KJJB2PVC.js";
9
+ import {
10
+ ScrollArea,
11
+ ScrollBar
12
+ } from "./chunk-GJT7TDBS.js";
13
+ import {
14
+ Dialog,
15
+ DialogClose,
16
+ DialogContent,
17
+ DialogDescription,
18
+ DialogHeader,
19
+ DialogTitle
20
+ } from "./chunk-PLZMCJSL.js";
21
+ import {
22
+ Input
23
+ } from "./chunk-YUPLJP3F.js";
24
+ import {
25
+ Separator
26
+ } from "./chunk-6ANDNGHD.js";
27
+ import {
28
+ Tooltip,
29
+ TooltipContent,
30
+ TooltipTrigger
31
+ } from "./chunk-D3SP7GL3.js";
32
+ import {
33
+ Button
34
+ } from "./chunk-TU5CYBB4.js";
35
+ import {
36
+ cn
37
+ } from "./chunk-DN2AEEA2.js";
38
+
39
+ // src/layouts/window/components/WindowRow.tsx
40
+ import * as Slot from "@radix-ui/react-slot";
41
+ import { jsx } from "react/jsx-runtime";
42
+ function WindowGroup({ className, ...props }) {
43
+ return /* @__PURE__ */ jsx(
44
+ "div",
45
+ {
46
+ "data-slot": "window-group",
47
+ className: cn("relative mt-4 flex w-full min-w-0 flex-col px-2 py-2 md:px-8", className),
48
+ ...props
49
+ }
50
+ );
51
+ }
52
+ function WindowGroupLabel({
53
+ className,
54
+ asChild = false,
55
+ ...props
56
+ }) {
57
+ const Comp = asChild ? Slot.Root : "div";
58
+ return /* @__PURE__ */ jsx(
59
+ Comp,
60
+ {
61
+ "data-slot": "window-group-label",
62
+ "data-sidebar": "group-label",
63
+ className: cn(
64
+ "text-text-muted focus-visible:ring-focus-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
65
+ className
66
+ ),
67
+ ...props
68
+ }
69
+ );
70
+ }
71
+ function WindowGroupContent({ className, ...props }) {
72
+ return /* @__PURE__ */ jsx(
73
+ "div",
74
+ {
75
+ "data-slot": "window-group-content",
76
+ className: cn("relative flex w-full min-w-0 flex-col px-2 py-2", className),
77
+ ...props
78
+ }
79
+ );
80
+ }
81
+ function WindowRow({ className, ...props }) {
82
+ return /* @__PURE__ */ jsx(
83
+ "div",
84
+ {
85
+ "data-slot": "window-row",
86
+ className: cn(
87
+ "relative flex w-full min-w-0 justify-between gap-2 py-3 first:pt-0 last:pb-0",
88
+ className
89
+ ),
90
+ ...props
91
+ }
92
+ );
93
+ }
94
+ function WindowRowContent({ className, ...props }) {
95
+ return /* @__PURE__ */ jsx(
96
+ "div",
97
+ {
98
+ "data-slot": "window-row-content",
99
+ className: cn("relative flex w-full min-w-0 flex-col", className),
100
+ ...props
101
+ }
102
+ );
103
+ }
104
+ function WindowRowTitle({ className, ...props }) {
105
+ return /* @__PURE__ */ jsx("div", { "data-slot": "window-row-title", className: cn("text text-base", className), ...props });
106
+ }
107
+ function WindowRowDescription({ className, ...props }) {
108
+ return /* @__PURE__ */ jsx(
109
+ "div",
110
+ {
111
+ "data-slot": "window-row-description",
112
+ className: cn("text-text-muted text-xs", className),
113
+ ...props
114
+ }
115
+ );
116
+ }
117
+ function WindowRowActions({ className, ...props }) {
118
+ return /* @__PURE__ */ jsx(
119
+ "div",
120
+ {
121
+ "data-slot": "window-row-actions",
122
+ className: cn("relative flex shrink-0 items-center gap-1", className),
123
+ ...props
124
+ }
125
+ );
126
+ }
127
+ function WindowRowSeparator({
128
+ className,
129
+ ...props
130
+ }) {
131
+ return /* @__PURE__ */ jsx(
132
+ Separator,
133
+ {
134
+ "data-slot": "window-row-separator",
135
+ "data-sidebar": "separator",
136
+ className: cn("bg-window-border w-auto", className),
137
+ ...props
138
+ }
139
+ );
140
+ }
141
+
142
+ // src/layouts/window/core/Window.tsx
143
+ import * as React3 from "react";
144
+ import { XIcon } from "lucide-react";
145
+ import { motion } from "motion/react";
146
+
147
+ // src/layouts/window/WindowManager.tsx
148
+ import * as React2 from "react";
149
+
150
+ // src/layouts/window/core/WindowContext.tsx
151
+ import React from "react";
152
+ import { jsx as jsx2 } from "react/jsx-runtime";
153
+ var WindowStateContext = React.createContext(null);
154
+ function WindowStateProvider({
155
+ children,
156
+ value
157
+ }) {
158
+ return /* @__PURE__ */ jsx2(WindowStateContext.Provider, { value, children });
159
+ }
160
+ function useWindow() {
161
+ const context = React.useContext(WindowStateContext);
162
+ if (!context) {
163
+ throw new Error("useWindow must be used within a WindowProvider.");
164
+ }
165
+ return context;
166
+ }
167
+ function resolveOpenState(currentOpen, nextOpen) {
168
+ return typeof nextOpen === "function" ? nextOpen(currentOpen) : nextOpen;
169
+ }
170
+ function WindowProvider({
171
+ children,
172
+ defaultOpen = false,
173
+ onCloseRequest,
174
+ onOpenChange,
175
+ open
176
+ }) {
177
+ const [blockedInteractionCount, setBlockedInteractionCount] = React.useState(0);
178
+ const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);
179
+ const isControlled = open !== void 0;
180
+ const isOpen = isControlled ? open : uncontrolledOpen;
181
+ const isOpenRef = React.useRef(isOpen);
182
+ const closeRequestVersionRef = React.useRef(0);
183
+ React.useEffect(() => {
184
+ isOpenRef.current = isOpen;
185
+ }, [isOpen]);
186
+ const forceSetOpen = React.useCallback(
187
+ (nextOpen) => {
188
+ const resolvedOpen = resolveOpenState(isOpen, nextOpen);
189
+ if (!isControlled) {
190
+ setUncontrolledOpen(resolvedOpen);
191
+ }
192
+ onOpenChange?.(resolvedOpen);
193
+ },
194
+ [isControlled, isOpen, onOpenChange]
195
+ );
196
+ const openWindow = React.useCallback(() => {
197
+ closeRequestVersionRef.current += 1;
198
+ forceSetOpen(true);
199
+ }, [forceSetOpen]);
200
+ const forceCloseWindow = React.useCallback(() => {
201
+ forceSetOpen(false);
202
+ }, [forceSetOpen]);
203
+ const indicateBlockedInteraction = React.useCallback(() => {
204
+ setBlockedInteractionCount((currentCount) => currentCount + 1);
205
+ }, []);
206
+ const closeWindow = React.useCallback(
207
+ async (reason) => {
208
+ if (!isOpenRef.current) {
209
+ return true;
210
+ }
211
+ const closeRequestVersion = closeRequestVersionRef.current + 1;
212
+ closeRequestVersionRef.current = closeRequestVersion;
213
+ const closeAllowed = await onCloseRequest?.(reason) ?? true;
214
+ if (!closeAllowed) {
215
+ return false;
216
+ }
217
+ if (closeRequestVersion !== closeRequestVersionRef.current) {
218
+ return false;
219
+ }
220
+ forceCloseWindow();
221
+ return true;
222
+ },
223
+ [forceCloseWindow, onCloseRequest]
224
+ );
225
+ const toggleWindow = React.useCallback(() => {
226
+ if (isOpenRef.current) {
227
+ void closeWindow("programmatic").catch((error) => {
228
+ console.error("Failed to toggle window closed.", error);
229
+ });
230
+ return;
231
+ }
232
+ openWindow();
233
+ }, [closeWindow, openWindow]);
234
+ const contextValue = React.useMemo(
235
+ () => ({
236
+ blockedInteractionCount,
237
+ close: closeWindow,
238
+ forceClose: forceCloseWindow,
239
+ indicateBlockedInteraction,
240
+ isOpen,
241
+ open: openWindow,
242
+ toggle: toggleWindow
243
+ }),
244
+ [
245
+ blockedInteractionCount,
246
+ closeWindow,
247
+ forceCloseWindow,
248
+ indicateBlockedInteraction,
249
+ isOpen,
250
+ openWindow,
251
+ toggleWindow
252
+ ]
253
+ );
254
+ return /* @__PURE__ */ jsx2(WindowStateProvider, { value: contextValue, children });
255
+ }
256
+
257
+ // src/layouts/window/WindowManager.tsx
258
+ import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
259
+ var WindowManagerContext = React2.createContext(null);
260
+ function defineWindow(definition) {
261
+ return definition;
262
+ }
263
+ function WindowManagerProvider({
264
+ children,
265
+ defaultActiveWindowId = null,
266
+ windows
267
+ }) {
268
+ const windowMap = React2.useMemo(() => {
269
+ const nextWindowMap = /* @__PURE__ */ new Map();
270
+ windows.forEach((windowDefinition) => {
271
+ if (nextWindowMap.has(windowDefinition.id)) {
272
+ throw new Error(`Duplicate Window id "${windowDefinition.id}" is not allowed.`);
273
+ }
274
+ nextWindowMap.set(windowDefinition.id, windowDefinition);
275
+ });
276
+ return nextWindowMap;
277
+ }, [windows]);
278
+ if (defaultActiveWindowId !== null && !windowMap.has(defaultActiveWindowId)) {
279
+ throw new Error(
280
+ `WindowManagerProvider could not find a registered window for "${defaultActiveWindowId}".`
281
+ );
282
+ }
283
+ const [activeWindowId, setActiveWindowId] = React2.useState(defaultActiveWindowId);
284
+ const activeWindowIdRef = React2.useRef(activeWindowId);
285
+ const windowControllersRef = React2.useRef(/* @__PURE__ */ new Map());
286
+ React2.useEffect(() => {
287
+ activeWindowIdRef.current = activeWindowId;
288
+ }, [activeWindowId]);
289
+ const getWindow = React2.useCallback((id) => windowMap.get(id), [windowMap]);
290
+ const isOpen = React2.useCallback((id) => activeWindowId === id, [activeWindowId]);
291
+ const registerWindowController = React2.useCallback(
292
+ (id, controller) => {
293
+ windowControllersRef.current.set(id, controller);
294
+ return () => {
295
+ const registeredController = windowControllersRef.current.get(id);
296
+ if (registeredController === controller) {
297
+ windowControllersRef.current.delete(id);
298
+ }
299
+ };
300
+ },
301
+ []
302
+ );
303
+ const closeActiveWindow = React2.useCallback(async () => {
304
+ const currentActiveWindowId = activeWindowIdRef.current;
305
+ if (!currentActiveWindowId) {
306
+ return true;
307
+ }
308
+ const activeWindowController = windowControllersRef.current.get(currentActiveWindowId);
309
+ if (!activeWindowController) {
310
+ throw new Error(
311
+ `WindowManagerProvider could not find a controller for "${currentActiveWindowId}".`
312
+ );
313
+ }
314
+ return activeWindowController.close("programmatic");
315
+ }, []);
316
+ const openWindow = React2.useCallback(
317
+ async (id) => {
318
+ if (!windowMap.has(id)) {
319
+ throw new Error(`WindowManagerProvider could not find a registered window for "${id}".`);
320
+ }
321
+ const currentActiveWindowId = activeWindowIdRef.current;
322
+ if (currentActiveWindowId === id) {
323
+ return true;
324
+ }
325
+ if (currentActiveWindowId) {
326
+ const activeWindowController = windowControllersRef.current.get(currentActiveWindowId);
327
+ if (!activeWindowController) {
328
+ throw new Error(
329
+ `WindowManagerProvider could not find a controller for "${currentActiveWindowId}".`
330
+ );
331
+ }
332
+ const closeSucceeded = await activeWindowController.close("window-switch");
333
+ if (!closeSucceeded) {
334
+ return false;
335
+ }
336
+ }
337
+ setActiveWindowId(id);
338
+ return true;
339
+ },
340
+ [windowMap]
341
+ );
342
+ const setWindowOpenState = React2.useCallback((id, open) => {
343
+ setActiveWindowId((currentActiveWindowId) => {
344
+ if (open) {
345
+ return id;
346
+ }
347
+ if (currentActiveWindowId === id) {
348
+ return null;
349
+ }
350
+ return currentActiveWindowId;
351
+ });
352
+ }, []);
353
+ const contextValue = React2.useMemo(
354
+ () => ({
355
+ activeWindowId,
356
+ closeActiveWindow,
357
+ getWindow,
358
+ isOpen,
359
+ openWindow,
360
+ registerWindowController,
361
+ setWindowOpenState,
362
+ windows
363
+ }),
364
+ [
365
+ activeWindowId,
366
+ closeActiveWindow,
367
+ getWindow,
368
+ isOpen,
369
+ openWindow,
370
+ registerWindowController,
371
+ setWindowOpenState,
372
+ windows
373
+ ]
374
+ );
375
+ return /* @__PURE__ */ jsx3(WindowManagerContext.Provider, { value: contextValue, children });
376
+ }
377
+ function useWindowManager() {
378
+ const context = React2.useContext(WindowManagerContext);
379
+ if (!context) {
380
+ throw new Error("useWindowManager must be used within a WindowManagerProvider.");
381
+ }
382
+ return context;
383
+ }
384
+ function ManagedWindowControllerBridge({ id }) {
385
+ const { close } = useWindow();
386
+ const { registerWindowController } = useWindowManager();
387
+ React2.useEffect(
388
+ () => registerWindowController(id, { close }),
389
+ [close, id, registerWindowController]
390
+ );
391
+ return null;
392
+ }
393
+ function ManagedWindowInstance({
394
+ definition,
395
+ isOpen
396
+ }) {
397
+ const { setWindowOpenState } = useWindowManager();
398
+ return /* @__PURE__ */ jsxs(
399
+ WindowProvider,
400
+ {
401
+ open: isOpen,
402
+ onCloseRequest: definition.onCloseRequest,
403
+ onOpenChange: (nextOpen) => {
404
+ setWindowOpenState(definition.id, nextOpen);
405
+ },
406
+ children: [
407
+ /* @__PURE__ */ jsx3(ManagedWindowControllerBridge, { id: definition.id }),
408
+ definition.render()
409
+ ]
410
+ }
411
+ );
412
+ }
413
+ function WindowHost() {
414
+ const { activeWindowId, windows } = useWindowManager();
415
+ return /* @__PURE__ */ jsx3(Fragment, { children: windows.map((windowDefinition) => /* @__PURE__ */ jsx3(
416
+ ManagedWindowInstance,
417
+ {
418
+ definition: windowDefinition,
419
+ isOpen: activeWindowId === windowDefinition.id
420
+ },
421
+ windowDefinition.id
422
+ )) });
423
+ }
424
+
425
+ // src/layouts/window/core/Window.tsx
426
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
427
+ var MotionDialogContent = motion.create(DialogContent);
428
+ var WindowSizeContext = React3.createContext(null);
429
+ var DEFAULT_WINDOW_SIZE_CLASS = "h-[min(90vh,48rem)] w-[min(1120px,calc(100%-1rem))] max-w-280 sm:max-w-280";
430
+ function getWindowSizeClass(size) {
431
+ if (size === void 0 || size === "default") {
432
+ return DEFAULT_WINDOW_SIZE_CLASS;
433
+ }
434
+ return "max-w-[calc(100%-1rem)] sm:max-w-[calc(100%-1rem)]";
435
+ }
436
+ function getWindowSizeStyle(size) {
437
+ if (size === void 0 || size === "default") {
438
+ return void 0;
439
+ }
440
+ if (size === "content") {
441
+ return {
442
+ height: "fit-content",
443
+ maxHeight: "min(90vh, 48rem)",
444
+ maxWidth: "min(1120px, calc(100% - 1rem))",
445
+ width: "fit-content"
446
+ };
447
+ }
448
+ return {
449
+ maxHeight: "min(90vh, 48rem)",
450
+ maxWidth: "min(1120px, calc(100% - 1rem))",
451
+ ...size
452
+ };
453
+ }
454
+ function WindowCloseButton({
455
+ className,
456
+ onClick,
457
+ type = "button",
458
+ ...props
459
+ }) {
460
+ return /* @__PURE__ */ jsx4(DialogClose, { asChild: true, children: /* @__PURE__ */ jsxs2(
461
+ Button,
462
+ {
463
+ "data-slot": "window-close-button",
464
+ variant: "ghost",
465
+ size: "icon-sm",
466
+ type,
467
+ className: cn("absolute top-2 right-2 z-10", className),
468
+ onClick,
469
+ ...props,
470
+ children: [
471
+ /* @__PURE__ */ jsx4(XIcon, {}),
472
+ /* @__PURE__ */ jsx4("span", { className: "sr-only", children: "Close" })
473
+ ]
474
+ }
475
+ ) });
476
+ }
477
+ function WindowLayout({
478
+ children,
479
+ className,
480
+ forceMount: forceMountProp,
481
+ showCloseButton = true,
482
+ size
483
+ }) {
484
+ const windowManager = React3.useContext(WindowManagerContext);
485
+ const { blockedInteractionCount, close, forceClose, isOpen, open } = useWindow();
486
+ const [sizeRequest, setSizeRequest] = React3.useState(null);
487
+ const forceMount = forceMountProp ?? windowManager !== null;
488
+ const resolvedSize = sizeRequest?.size ?? size;
489
+ const sizeContextValue = React3.useMemo(
490
+ () => ({
491
+ requestSize: (token, nextSize) => {
492
+ setSizeRequest((currentRequest) => {
493
+ if (nextSize === void 0) {
494
+ return currentRequest?.token === token ? null : currentRequest;
495
+ }
496
+ return {
497
+ size: nextSize,
498
+ token
499
+ };
500
+ });
501
+ }
502
+ }),
503
+ []
504
+ );
505
+ const handleOpenChange = React3.useCallback(
506
+ (nextOpen) => {
507
+ if (nextOpen) {
508
+ open();
509
+ return;
510
+ }
511
+ forceClose();
512
+ },
513
+ [forceClose, open]
514
+ );
515
+ const windowSizeStyle = getWindowSizeStyle(resolvedSize);
516
+ return /* @__PURE__ */ jsx4(Dialog, { open: isOpen, onCloseRequest: close, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs2(
517
+ MotionDialogContent,
518
+ {
519
+ layout: "size",
520
+ blockedInteractionCount,
521
+ ...forceMount === true ? { forceMount: true } : {},
522
+ showCloseButton: false,
523
+ ...windowSizeStyle !== void 0 ? { style: windowSizeStyle } : {},
524
+ transition: {
525
+ layout: {
526
+ duration: 0.18,
527
+ ease: [0, 0.5, 0, 1]
528
+ }
529
+ },
530
+ className: cn(
531
+ "border-window-border bg-window-background text-window-text shadow-window overflow-hidden rounded-[var(--radius-window)] p-0",
532
+ getWindowSizeClass(resolvedSize),
533
+ "flex gap-0",
534
+ className
535
+ ),
536
+ children: [
537
+ /* @__PURE__ */ jsxs2(DialogHeader, { className: "sr-only", children: [
538
+ /* @__PURE__ */ jsx4(DialogTitle, { children: "Window Layout" }),
539
+ /* @__PURE__ */ jsx4(DialogDescription, { children: "Displays a modal window with a navigation sidebar and context content." })
540
+ ] }),
541
+ /* @__PURE__ */ jsx4(WindowSizeContext.Provider, { value: sizeContextValue, children: /* @__PURE__ */ jsxs2(
542
+ "div",
543
+ {
544
+ "data-slot": "window-layout",
545
+ className: "relative flex min-h-0 min-w-0 flex-auto overflow-hidden",
546
+ children: [
547
+ showCloseButton && /* @__PURE__ */ jsx4(WindowCloseButton, {}),
548
+ /* @__PURE__ */ jsx4("div", { className: "pointer-events-none absolute inset-x-0 top-0 h-px bg-white/50 dark:bg-white/10" }),
549
+ /* @__PURE__ */ jsx4("div", { className: "flex min-h-0 min-w-0 flex-auto flex-col md:flex-row", children })
550
+ ]
551
+ }
552
+ ) })
553
+ ]
554
+ }
555
+ ) });
556
+ }
557
+ function useWindowSizeRequest(size) {
558
+ const context = React3.useContext(WindowSizeContext);
559
+ React3.useLayoutEffect(() => {
560
+ if (!context) {
561
+ return;
562
+ }
563
+ const token = /* @__PURE__ */ Symbol("window-size-request");
564
+ context.requestSize(token, size);
565
+ return () => {
566
+ context.requestSize(token, void 0);
567
+ };
568
+ }, [context, size]);
569
+ }
570
+
571
+ // src/layouts/window/core/WindowContent.tsx
572
+ import "react";
573
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
574
+ function WindowContent({
575
+ children,
576
+ className,
577
+ ...props
578
+ }) {
579
+ return /* @__PURE__ */ jsxs3(
580
+ ScrollArea,
581
+ {
582
+ "data-slot": "window-layout-content",
583
+ className: cn(
584
+ "bg-window-background relative flex min-h-0 w-full min-w-0 flex-1 flex-col overflow-auto",
585
+ className
586
+ ),
587
+ ...props,
588
+ children: [
589
+ children,
590
+ /* @__PURE__ */ jsx5(ScrollBar, {})
591
+ ]
592
+ }
593
+ );
594
+ }
595
+
596
+ // src/layouts/window/core/WindowSidebar.tsx
597
+ import React5 from "react";
598
+ import * as Slot2 from "@radix-ui/react-slot";
599
+ import { cva } from "class-variance-authority";
600
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
601
+ function WindowSidebar({ className, ...props }) {
602
+ return /* @__PURE__ */ jsx6(
603
+ "aside",
604
+ {
605
+ "data-slot": "window-layout-sidebar",
606
+ className: cn(
607
+ "border-sidedock-border relative flex max-h-[min(20rem,40vh)] min-h-48 w-full shrink-0 flex-col overflow-auto border-b md:border-r md:border-b-0",
608
+ sidedockShellClass,
609
+ "md:h-full md:max-h-none md:w-64",
610
+ className
611
+ ),
612
+ ...props
613
+ }
614
+ );
615
+ }
616
+ function WindowSidebarInput({ className, ...props }) {
617
+ return /* @__PURE__ */ jsx6(
618
+ Input,
619
+ {
620
+ "data-slot": "sidebar-input",
621
+ "data-sidebar": "input",
622
+ className: cn("h-8 w-full shadow-none", className),
623
+ ...props
624
+ }
625
+ );
626
+ }
627
+ function WindowSidebarHeader({ className, ...props }) {
628
+ return /* @__PURE__ */ jsx6(
629
+ "div",
630
+ {
631
+ "data-slot": "sidebar-header",
632
+ "data-sidebar": "header",
633
+ className: cn("flex flex-col gap-2 p-2", className),
634
+ ...props
635
+ }
636
+ );
637
+ }
638
+ function WindowSidebarFooter({ className, ...props }) {
639
+ return /* @__PURE__ */ jsx6(
640
+ "div",
641
+ {
642
+ "data-slot": "sidebar-footer",
643
+ "data-sidebar": "footer",
644
+ className: cn("flex flex-col gap-2 p-2", className),
645
+ ...props
646
+ }
647
+ );
648
+ }
649
+ function WindowSidebarContent({
650
+ children,
651
+ className,
652
+ ...props
653
+ }) {
654
+ return /* @__PURE__ */ jsxs4(
655
+ ScrollArea,
656
+ {
657
+ "data-slot": "sidebar-content",
658
+ "data-sidebar": "content",
659
+ className: cn(
660
+ "no-scrollbar flex min-h-0 flex-1 flex-col gap-0 group-data-[collapsible=icon]:overflow-hidden",
661
+ className
662
+ ),
663
+ ...props,
664
+ children: [
665
+ children,
666
+ /* @__PURE__ */ jsx6(ScrollBar, {})
667
+ ]
668
+ }
669
+ );
670
+ }
671
+ function WindowSidebarGroup({ className, ...props }) {
672
+ return /* @__PURE__ */ jsx6(
673
+ "div",
674
+ {
675
+ "data-slot": "sidebar-group",
676
+ "data-sidebar": "group",
677
+ className: cn("relative flex w-full min-w-0 flex-col p-2", className),
678
+ ...props
679
+ }
680
+ );
681
+ }
682
+ function WindowSidebarGroupLabel({
683
+ className,
684
+ asChild = false,
685
+ ...props
686
+ }) {
687
+ const Comp = asChild ? Slot2.Root : "div";
688
+ return /* @__PURE__ */ jsx6(
689
+ Comp,
690
+ {
691
+ "data-slot": "sidebar-group-label",
692
+ "data-sidebar": "group-label",
693
+ className: cn(
694
+ "text-sidedock-label flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 [&>svg]:size-4 [&>svg]:shrink-0",
695
+ sidedockFocusClass,
696
+ className
697
+ ),
698
+ ...props
699
+ }
700
+ );
701
+ }
702
+ function WindowSidebarGroupAction({
703
+ className,
704
+ asChild = false,
705
+ ...props
706
+ }) {
707
+ const Comp = asChild ? Slot2.Root : "button";
708
+ return /* @__PURE__ */ jsx6(
709
+ Comp,
710
+ {
711
+ "data-slot": "sidebar-group-action",
712
+ "data-sidebar": "group-action",
713
+ className: cn(
714
+ "text-sidedock-text hover:bg-sidedock-hover-background hover:text-sidedock-text-hover absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
715
+ sidedockFocusClass,
716
+ className
717
+ ),
718
+ ...props
719
+ }
720
+ );
721
+ }
722
+ function WindowSidebarGroupContent({ className, ...props }) {
723
+ return /* @__PURE__ */ jsx6(
724
+ "div",
725
+ {
726
+ "data-slot": "sidebar-group-content",
727
+ "data-sidebar": "group-content",
728
+ className: cn("w-full text-sm", className),
729
+ ...props
730
+ }
731
+ );
732
+ }
733
+ function WindowSidebarMenu({ className, ...props }) {
734
+ return /* @__PURE__ */ jsx6(
735
+ "ul",
736
+ {
737
+ "data-slot": "sidebar-menu",
738
+ "data-sidebar": "menu",
739
+ className: cn("flex w-full min-w-0 flex-col gap-0.5", className),
740
+ ...props
741
+ }
742
+ );
743
+ }
744
+ function WindowSidebarMenuItem({ className, ...props }) {
745
+ return /* @__PURE__ */ jsx6(
746
+ "li",
747
+ {
748
+ "data-slot": "sidebar-menu-item",
749
+ "data-sidebar": "menu-item",
750
+ className: cn("group/menu-item relative", className),
751
+ ...props
752
+ }
753
+ );
754
+ }
755
+ var sidebarMenuButtonVariants = cva(
756
+ cn(
757
+ "cursor-pointer peer/menu-button group/menu-button text-sidedock-text flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidedock-hover-background hover:text-sidedock-text-hover active:bg-sidedock-active-background active:text-sidedock-text-active disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidedock-hover-background data-open:hover:text-sidedock-text-hover data-active:bg-sidedock-active-background data-active:text-sidedock-text-active data-active:font-medium [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
758
+ sidedockFocusClass
759
+ ),
760
+ {
761
+ variants: {
762
+ variant: {
763
+ default: "",
764
+ outline: cn("bg-background-primary text-text-normal", sidedockOutlineStrokeClass)
765
+ },
766
+ size: {
767
+ default: "h-7 text-sm",
768
+ sm: "h-6 text-xs",
769
+ lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!"
770
+ }
771
+ },
772
+ defaultVariants: {
773
+ variant: "default",
774
+ size: "default"
775
+ }
776
+ }
777
+ );
778
+ function WindowSidebarMenuButton({
779
+ asChild = false,
780
+ isActive = false,
781
+ variant = "default",
782
+ size = "default",
783
+ tooltip,
784
+ leadingVisual,
785
+ trailingVisual,
786
+ trailingVisualVisibility = "always",
787
+ className,
788
+ children,
789
+ ...props
790
+ }) {
791
+ const Comp = asChild ? Slot2.Root : "button";
792
+ const { isOpen } = useWindow();
793
+ const button = /* @__PURE__ */ jsxs4(
794
+ Comp,
795
+ {
796
+ "data-slot": "sidebar-menu-button",
797
+ "data-sidebar": "menu-button",
798
+ "data-size": size,
799
+ "data-active": isActive,
800
+ className: cn(sidebarMenuButtonVariants({ variant, size }), className),
801
+ ...props,
802
+ children: [
803
+ leadingVisual ? /* @__PURE__ */ jsx6(
804
+ "span",
805
+ {
806
+ "data-slot": "sidebar-menu-button-leading-visual",
807
+ className: "flex shrink-0 items-center justify-center",
808
+ children: leadingVisual
809
+ }
810
+ ) : null,
811
+ /* @__PURE__ */ jsx6(Slot2.Slottable, { children: /* @__PURE__ */ jsx6("span", { "data-slot": "sidebar-menu-button-label", className: "flex min-w-0 flex-1 truncate", children }) }),
812
+ trailingVisual ? /* @__PURE__ */ jsx6(
813
+ "span",
814
+ {
815
+ "data-slot": "sidebar-menu-button-trailing-visual",
816
+ className: cn(
817
+ "ml-auto flex shrink-0 items-center justify-center",
818
+ trailingVisualVisibility === "hover" && "invisible opacity-0 group-hover/menu-button:visible group-hover/menu-button:opacity-100 group-focus-visible/menu-button:visible group-focus-visible/menu-button:opacity-100"
819
+ ),
820
+ children: trailingVisual
821
+ }
822
+ ) : null
823
+ ]
824
+ }
825
+ );
826
+ if (!tooltip) {
827
+ return button;
828
+ }
829
+ if (typeof tooltip === "string") {
830
+ tooltip = {
831
+ children: tooltip
832
+ };
833
+ }
834
+ return /* @__PURE__ */ jsxs4(Tooltip, { children: [
835
+ /* @__PURE__ */ jsx6(TooltipTrigger, { asChild: true, children: button }),
836
+ /* @__PURE__ */ jsx6(TooltipContent, { side: "right", align: "center", hidden: !isOpen, ...tooltip })
837
+ ] });
838
+ }
839
+ function WindowSidebarMenuAction({
840
+ className,
841
+ asChild = false,
842
+ showOnHover = false,
843
+ ...props
844
+ }) {
845
+ const Comp = asChild ? Slot2.Root : "button";
846
+ return /* @__PURE__ */ jsx6(
847
+ Comp,
848
+ {
849
+ "data-slot": "sidebar-menu-action",
850
+ "data-sidebar": "menu-action",
851
+ className: cn(
852
+ "text-sidedock-text peer-hover/menu-button:text-sidedock-text-hover hover:bg-sidedock-hover-background hover:text-sidedock-text-hover absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
853
+ sidedockFocusClass,
854
+ showOnHover && "peer-data-active/menu-button:text-sidedock-text-active group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 aria-expanded:opacity-100 md:opacity-0",
855
+ className
856
+ ),
857
+ ...props
858
+ }
859
+ );
860
+ }
861
+ function WindowSidebarMenuBadge({ className, ...props }) {
862
+ return /* @__PURE__ */ jsx6(
863
+ "div",
864
+ {
865
+ "data-slot": "sidebar-menu-badge",
866
+ "data-sidebar": "menu-badge",
867
+ className: cn(
868
+ "text-sidedock-text peer-hover/menu-button:text-sidedock-text-hover peer-data-active/menu-button:text-sidedock-text-active pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none group-data-[collapsible=icon]:hidden peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1",
869
+ className
870
+ ),
871
+ ...props
872
+ }
873
+ );
874
+ }
875
+ function WindowSidebarMenuSkeleton({
876
+ className,
877
+ showIcon = false,
878
+ ...props
879
+ }) {
880
+ const [width] = React5.useState(() => {
881
+ return `${Math.floor(Math.random() * 40) + 50}%`;
882
+ });
883
+ const skeletonStyle = {
884
+ "--skeleton-width": width
885
+ };
886
+ return /* @__PURE__ */ jsxs4(
887
+ "div",
888
+ {
889
+ "data-slot": "sidebar-menu-skeleton",
890
+ "data-sidebar": "menu-skeleton",
891
+ className: cn("flex h-8 items-center gap-2 rounded-md px-2", className),
892
+ ...props,
893
+ children: [
894
+ showIcon && /* @__PURE__ */ jsx6(Skeleton, { className: "size-4 rounded-md", "data-sidebar": "menu-skeleton-icon" }),
895
+ /* @__PURE__ */ jsx6(
896
+ Skeleton,
897
+ {
898
+ className: "h-4 max-w-(--skeleton-width) flex-1",
899
+ "data-sidebar": "menu-skeleton-text",
900
+ style: skeletonStyle
901
+ }
902
+ )
903
+ ]
904
+ }
905
+ );
906
+ }
907
+
908
+ // src/layouts/window/WindowFlow.tsx
909
+ import * as React7 from "react";
910
+ import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react";
911
+ import { AnimatePresence, motion as motion2 } from "motion/react";
912
+
913
+ // src/layouts/window/WindowFlowContext.tsx
914
+ import * as React6 from "react";
915
+ import { jsx as jsx7 } from "react/jsx-runtime";
916
+ var WindowFlowContext = React6.createContext(null);
917
+ function defineWindowFlowStep(definition) {
918
+ return definition;
919
+ }
920
+ function WindowFlowProvider({
921
+ children,
922
+ defaultStep,
923
+ onStepChangeRequest,
924
+ onStepChange,
925
+ step,
926
+ steps
927
+ }) {
928
+ const windowContext = React6.useContext(WindowStateContext);
929
+ const stepMap = React6.useMemo(() => {
930
+ const nextStepMap = /* @__PURE__ */ new Map();
931
+ steps.forEach((stepDefinition) => {
932
+ if (nextStepMap.has(stepDefinition.id)) {
933
+ throw new Error(`Duplicate WindowFlow step id "${stepDefinition.id}" is not allowed.`);
934
+ }
935
+ nextStepMap.set(stepDefinition.id, stepDefinition);
936
+ });
937
+ return nextStepMap;
938
+ }, [steps]);
939
+ const initialStep = step ?? defaultStep;
940
+ if (initialStep === void 0) {
941
+ throw new Error("WindowFlowProvider requires a step or defaultStep.");
942
+ }
943
+ if (!stepMap.has(initialStep)) {
944
+ throw new Error(`WindowFlowProvider could not find a registered step for "${initialStep}".`);
945
+ }
946
+ const [uncontrolledStep, setUncontrolledStep] = React6.useState(initialStep);
947
+ const [direction, setDirection] = React6.useState("none");
948
+ const isControlled = step !== void 0;
949
+ const activeStep = isControlled ? step : uncontrolledStep;
950
+ const activeStepRef = React6.useRef(activeStep);
951
+ const stepChangeRequestVersionRef = React6.useRef(0);
952
+ const indicateBlockedInteraction = windowContext?.indicateBlockedInteraction;
953
+ const activeStepIndex = steps.findIndex((stepDefinition) => stepDefinition.id === activeStep);
954
+ if (activeStepIndex === -1) {
955
+ throw new Error(`WindowFlowProvider could not find a registered step for "${activeStep}".`);
956
+ }
957
+ React6.useEffect(() => {
958
+ activeStepRef.current = activeStep;
959
+ }, [activeStep]);
960
+ const getStep = React6.useCallback(
961
+ (targetStep) => stepMap.get(targetStep),
962
+ [stepMap]
963
+ );
964
+ const setFlowStep = React6.useCallback(
965
+ async (nextStep2, reason = "programmatic") => {
966
+ const currentStep = activeStepRef.current;
967
+ if (nextStep2 === currentStep) {
968
+ return true;
969
+ }
970
+ if (!stepMap.has(nextStep2)) {
971
+ throw new Error(`WindowFlowProvider could not find a registered step for "${nextStep2}".`);
972
+ }
973
+ const currentStepIndex = steps.findIndex(
974
+ (stepDefinition) => stepDefinition.id === currentStep
975
+ );
976
+ const nextStepIndex = steps.findIndex((stepDefinition) => stepDefinition.id === nextStep2);
977
+ const nextDirection = nextStepIndex > currentStepIndex ? "next" : nextStepIndex < currentStepIndex ? "previous" : "none";
978
+ const stepChangeRequestVersion = stepChangeRequestVersionRef.current + 1;
979
+ stepChangeRequestVersionRef.current = stepChangeRequestVersion;
980
+ const stepChangeAllowed = await onStepChangeRequest?.({
981
+ from: currentStep,
982
+ reason,
983
+ to: nextStep2
984
+ }) ?? true;
985
+ if (!stepChangeAllowed) {
986
+ indicateBlockedInteraction?.();
987
+ return false;
988
+ }
989
+ if (stepChangeRequestVersion !== stepChangeRequestVersionRef.current) {
990
+ return false;
991
+ }
992
+ setDirection(nextDirection);
993
+ if (!isControlled) {
994
+ setUncontrolledStep(nextStep2);
995
+ }
996
+ onStepChange?.(nextStep2);
997
+ return true;
998
+ },
999
+ [indicateBlockedInteraction, isControlled, onStepChange, onStepChangeRequest, stepMap, steps]
1000
+ );
1001
+ const previousStep = React6.useCallback(
1002
+ (reason = "programmatic") => {
1003
+ const currentStepIndex = steps.findIndex(
1004
+ (stepDefinition) => stepDefinition.id === activeStepRef.current
1005
+ );
1006
+ const previousStepDefinition = steps[currentStepIndex - 1];
1007
+ if (!previousStepDefinition) {
1008
+ return Promise.resolve(false);
1009
+ }
1010
+ return setFlowStep(previousStepDefinition.id, reason);
1011
+ },
1012
+ [setFlowStep, steps]
1013
+ );
1014
+ const nextStep = React6.useCallback(
1015
+ (reason = "programmatic") => {
1016
+ const currentStepIndex = steps.findIndex(
1017
+ (stepDefinition) => stepDefinition.id === activeStepRef.current
1018
+ );
1019
+ const nextStepDefinition = steps[currentStepIndex + 1];
1020
+ if (!nextStepDefinition) {
1021
+ return Promise.resolve(false);
1022
+ }
1023
+ return setFlowStep(nextStepDefinition.id, reason);
1024
+ },
1025
+ [setFlowStep, steps]
1026
+ );
1027
+ const contextValue = React6.useMemo(
1028
+ () => ({
1029
+ canGoNext: activeStepIndex < steps.length - 1,
1030
+ canGoPrevious: activeStepIndex > 0,
1031
+ direction,
1032
+ getStep,
1033
+ isFirstStep: activeStepIndex === 0,
1034
+ isLastStep: activeStepIndex === steps.length - 1,
1035
+ nextStep,
1036
+ previousStep,
1037
+ setStep: setFlowStep,
1038
+ step: activeStep,
1039
+ stepIndex: activeStepIndex,
1040
+ steps
1041
+ }),
1042
+ [activeStep, activeStepIndex, direction, getStep, nextStep, previousStep, setFlowStep, steps]
1043
+ );
1044
+ return /* @__PURE__ */ jsx7(WindowFlowContext.Provider, { value: contextValue, children });
1045
+ }
1046
+ function useWindowFlow() {
1047
+ const context = React6.useContext(WindowFlowContext);
1048
+ if (!context) {
1049
+ throw new Error("useWindowFlow must be used within a WindowFlowProvider.");
1050
+ }
1051
+ return context;
1052
+ }
1053
+
1054
+ // src/layouts/window/WindowFlow.tsx
1055
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1056
+ function WindowFlowLayout({ className, ...props }) {
1057
+ const { getStep, step } = useWindowFlow();
1058
+ const activeStep = getStep(step);
1059
+ const windowSize = React7.useMemo(
1060
+ () => getFlowStepWindowSize(activeStep?.windowSize),
1061
+ [activeStep?.windowSize]
1062
+ );
1063
+ useWindowSizeRequest(windowSize);
1064
+ return /* @__PURE__ */ jsx8(
1065
+ "div",
1066
+ {
1067
+ "data-slot": "window-flow-layout",
1068
+ className: cn("flex min-h-0 min-w-0 flex-auto flex-col", className),
1069
+ ...props
1070
+ }
1071
+ );
1072
+ }
1073
+ function WindowFlowHeader({ className, ...props }) {
1074
+ return /* @__PURE__ */ jsx8(
1075
+ "div",
1076
+ {
1077
+ "data-slot": "window-flow-header",
1078
+ className: cn(
1079
+ "border-window-border flex shrink-0 flex-col gap-3 border-b px-6 py-5",
1080
+ className
1081
+ ),
1082
+ ...props
1083
+ }
1084
+ );
1085
+ }
1086
+ function WindowFlowContent({ className, ...props }) {
1087
+ return /* @__PURE__ */ jsx8(
1088
+ "div",
1089
+ {
1090
+ "data-slot": "window-flow-content",
1091
+ className: cn("relative flex min-h-0 min-w-0 flex-auto flex-col overflow-hidden", className),
1092
+ ...props
1093
+ }
1094
+ );
1095
+ }
1096
+ function WindowFlowFooter({ className, ...props }) {
1097
+ return /* @__PURE__ */ jsx8(
1098
+ "div",
1099
+ {
1100
+ "data-slot": "window-flow-footer",
1101
+ className: cn(
1102
+ "border-window-border flex shrink-0 items-center justify-between gap-3 border-t px-6 py-4",
1103
+ className
1104
+ ),
1105
+ ...props
1106
+ }
1107
+ );
1108
+ }
1109
+ var WINDOW_FLOW_EXIT_TRANSITION_DURATION_SECONDS = 0.08;
1110
+ var WINDOW_FLOW_ENTER_TRANSITION_DURATION_SECONDS = 0.16;
1111
+ var WINDOW_FLOW_ENTER_TRANSITION_DELAY_SECONDS = 0.04;
1112
+ var WINDOW_FLOW_EXIT_TRANSITION_OFFSET_PX = 24;
1113
+ var WINDOW_FLOW_ENTER_TRANSITION_OFFSET_PX = 48;
1114
+ var WINDOW_FLOW_EXIT_X_TRANSITION_EASE = [0, 0.5, 0, 1];
1115
+ var WINDOW_FLOW_ENTER_X_TRANSITION_EASE = [0, 0.5, 0, 1];
1116
+ var WINDOW_FLOW_EXIT_OPACITY_TRANSITION_EASE = [
1117
+ 0.35,
1118
+ 0.35,
1119
+ 0.65,
1120
+ 0.65
1121
+ ];
1122
+ var WINDOW_FLOW_ENTER_OPACITY_TRANSITION_EASE = [
1123
+ 0.35,
1124
+ 0.35,
1125
+ 0.65,
1126
+ 0.65
1127
+ ];
1128
+ function getFlowPosition(stepIndex, activeStepIndex) {
1129
+ if (stepIndex < activeStepIndex) {
1130
+ return "previous";
1131
+ }
1132
+ if (stepIndex > activeStepIndex) {
1133
+ return "next";
1134
+ }
1135
+ return "active";
1136
+ }
1137
+ function getFlowEnterAnimation(direction) {
1138
+ if (direction === "next") {
1139
+ return {
1140
+ x: WINDOW_FLOW_ENTER_TRANSITION_OFFSET_PX,
1141
+ opacity: 0
1142
+ };
1143
+ }
1144
+ if (direction === "previous") {
1145
+ return {
1146
+ x: -WINDOW_FLOW_ENTER_TRANSITION_OFFSET_PX,
1147
+ opacity: 0
1148
+ };
1149
+ }
1150
+ return {
1151
+ x: 0,
1152
+ opacity: 1
1153
+ };
1154
+ }
1155
+ function getFlowAnimateState(direction) {
1156
+ const delay = direction === "none" ? 0 : WINDOW_FLOW_ENTER_TRANSITION_DELAY_SECONDS;
1157
+ return {
1158
+ x: 0,
1159
+ opacity: 1,
1160
+ transition: {
1161
+ x: {
1162
+ delay,
1163
+ duration: WINDOW_FLOW_ENTER_TRANSITION_DURATION_SECONDS,
1164
+ ease: WINDOW_FLOW_ENTER_X_TRANSITION_EASE
1165
+ },
1166
+ opacity: {
1167
+ delay,
1168
+ duration: WINDOW_FLOW_ENTER_TRANSITION_DURATION_SECONDS,
1169
+ ease: WINDOW_FLOW_ENTER_OPACITY_TRANSITION_EASE
1170
+ }
1171
+ }
1172
+ };
1173
+ }
1174
+ function getFlowExitAnimation(direction) {
1175
+ if (direction === "next") {
1176
+ return {
1177
+ x: -WINDOW_FLOW_EXIT_TRANSITION_OFFSET_PX,
1178
+ opacity: 0,
1179
+ transition: {
1180
+ x: {
1181
+ duration: WINDOW_FLOW_EXIT_TRANSITION_DURATION_SECONDS,
1182
+ ease: WINDOW_FLOW_EXIT_X_TRANSITION_EASE
1183
+ },
1184
+ opacity: {
1185
+ duration: WINDOW_FLOW_EXIT_TRANSITION_DURATION_SECONDS,
1186
+ ease: WINDOW_FLOW_EXIT_OPACITY_TRANSITION_EASE
1187
+ }
1188
+ }
1189
+ };
1190
+ }
1191
+ if (direction === "previous") {
1192
+ return {
1193
+ x: WINDOW_FLOW_EXIT_TRANSITION_OFFSET_PX,
1194
+ opacity: 0,
1195
+ transition: {
1196
+ x: {
1197
+ duration: WINDOW_FLOW_EXIT_TRANSITION_DURATION_SECONDS,
1198
+ ease: WINDOW_FLOW_EXIT_X_TRANSITION_EASE
1199
+ },
1200
+ opacity: {
1201
+ duration: WINDOW_FLOW_EXIT_TRANSITION_DURATION_SECONDS,
1202
+ ease: WINDOW_FLOW_EXIT_OPACITY_TRANSITION_EASE
1203
+ }
1204
+ }
1205
+ };
1206
+ }
1207
+ return {
1208
+ x: 0,
1209
+ opacity: 0,
1210
+ transition: {
1211
+ x: {
1212
+ duration: WINDOW_FLOW_EXIT_TRANSITION_DURATION_SECONDS,
1213
+ ease: WINDOW_FLOW_EXIT_X_TRANSITION_EASE
1214
+ },
1215
+ opacity: {
1216
+ duration: WINDOW_FLOW_EXIT_TRANSITION_DURATION_SECONDS,
1217
+ ease: WINDOW_FLOW_EXIT_OPACITY_TRANSITION_EASE
1218
+ }
1219
+ }
1220
+ };
1221
+ }
1222
+ var windowFlowViewVariants = {
1223
+ center: getFlowAnimateState,
1224
+ enter: getFlowEnterAnimation,
1225
+ exit: getFlowExitAnimation
1226
+ };
1227
+ function getFlowInitialState(direction) {
1228
+ return direction === "none" ? false : "enter";
1229
+ }
1230
+ function getFlowStepWindowSize(size) {
1231
+ if (typeof size === "object" && size.height === void 0 && size.minHeight !== void 0) {
1232
+ return {
1233
+ ...size,
1234
+ height: size.minHeight
1235
+ };
1236
+ }
1237
+ return size;
1238
+ }
1239
+ function shouldMeasureFlowStepSize(size) {
1240
+ if (size === "content") {
1241
+ return true;
1242
+ }
1243
+ return typeof size === "object" && size.height === void 0;
1244
+ }
1245
+ function useElementHeight() {
1246
+ const elementRef = React7.useRef(null);
1247
+ const resizeObserverRef = React7.useRef(null);
1248
+ const [height, setHeight] = React7.useState(null);
1249
+ const updateHeight = React7.useCallback((element) => {
1250
+ const nextHeight = element ? element.getBoundingClientRect().height : null;
1251
+ setHeight((currentHeight) => currentHeight === nextHeight ? currentHeight : nextHeight);
1252
+ }, []);
1253
+ const ref = React7.useCallback(
1254
+ (element) => {
1255
+ resizeObserverRef.current?.disconnect();
1256
+ resizeObserverRef.current = null;
1257
+ elementRef.current = element;
1258
+ if (!element) {
1259
+ return;
1260
+ }
1261
+ updateHeight(element);
1262
+ if (element && typeof ResizeObserver !== "undefined") {
1263
+ resizeObserverRef.current = new ResizeObserver(([entry]) => {
1264
+ if (!entry) {
1265
+ return;
1266
+ }
1267
+ setHeight(entry.contentRect.height);
1268
+ });
1269
+ resizeObserverRef.current.observe(element);
1270
+ }
1271
+ },
1272
+ [updateHeight]
1273
+ );
1274
+ React7.useEffect(() => {
1275
+ return () => {
1276
+ resizeObserverRef.current?.disconnect();
1277
+ };
1278
+ }, []);
1279
+ React7.useLayoutEffect(() => {
1280
+ updateHeight(elementRef.current);
1281
+ });
1282
+ return [ref, height];
1283
+ }
1284
+ function getFlowViewLayoutClass(measuredSize, activeViewHeight) {
1285
+ if (!measuredSize) {
1286
+ return "absolute inset-0";
1287
+ }
1288
+ if (activeViewHeight === null) {
1289
+ return "relative w-full";
1290
+ }
1291
+ return "absolute inset-x-0 top-0";
1292
+ }
1293
+ function WindowFlowView({
1294
+ children,
1295
+ className,
1296
+ direction: directionProp,
1297
+ pageIndex,
1298
+ step,
1299
+ ...props
1300
+ }) {
1301
+ const { direction, stepIndex, steps } = useWindowFlow();
1302
+ const ownStepIndex = pageIndex ?? steps.findIndex((stepDefinition) => stepDefinition.id === step);
1303
+ const active = ownStepIndex === stepIndex;
1304
+ const position = getFlowPosition(ownStepIndex, stepIndex);
1305
+ const resolvedDirection = directionProp ?? direction;
1306
+ return /* @__PURE__ */ jsx8(
1307
+ motion2.div,
1308
+ {
1309
+ "data-slot": "window-flow-view",
1310
+ "data-active": active,
1311
+ "data-flow-direction": resolvedDirection,
1312
+ "data-flow-position": position,
1313
+ "data-step": step,
1314
+ "aria-hidden": !active,
1315
+ className: cn(
1316
+ "min-h-0 min-w-0 overflow-auto motion-reduce:transform-none!",
1317
+ active ? "pointer-events-auto" : "pointer-events-none",
1318
+ className
1319
+ ),
1320
+ custom: resolvedDirection,
1321
+ variants: windowFlowViewVariants,
1322
+ initial: getFlowInitialState(resolvedDirection),
1323
+ animate: "center",
1324
+ exit: "exit",
1325
+ ...props,
1326
+ children
1327
+ }
1328
+ );
1329
+ }
1330
+ function WindowFlowViews({ children, className, style, ...props }) {
1331
+ const { direction, getStep, step, steps } = useWindowFlow();
1332
+ if (steps.length === 0) {
1333
+ throw new Error("WindowFlowViews requires registered steps on WindowFlowProvider.");
1334
+ }
1335
+ const activeStep = getStep(step);
1336
+ if (!activeStep) {
1337
+ throw new Error(`WindowFlowViews could not find a registered step for "${step}".`);
1338
+ }
1339
+ const activeWindowSize = getFlowStepWindowSize(activeStep.windowSize);
1340
+ const [activeViewRef, activeViewHeight] = useElementHeight();
1341
+ const measuredSize = shouldMeasureFlowStepSize(activeWindowSize);
1342
+ return /* @__PURE__ */ jsxs5(
1343
+ motion2.div,
1344
+ {
1345
+ "data-slot": "window-flow-views",
1346
+ "data-flow-direction": direction,
1347
+ className: cn("relative flex min-h-0 min-w-0 flex-auto overflow-hidden", className),
1348
+ style: {
1349
+ ...style,
1350
+ ...measuredSize && activeViewHeight !== null ? { height: activeViewHeight } : null
1351
+ },
1352
+ ...props,
1353
+ children: [
1354
+ children,
1355
+ /* @__PURE__ */ jsx8(AnimatePresence, { custom: direction, initial: false, children: /* @__PURE__ */ jsx8(
1356
+ motion2.div,
1357
+ {
1358
+ custom: direction,
1359
+ "data-slot": "window-flow-view",
1360
+ "data-active": true,
1361
+ "data-flow-direction": direction,
1362
+ "data-flow-position": "active",
1363
+ "data-step": activeStep.id,
1364
+ ref: activeViewRef,
1365
+ className: cn(
1366
+ "min-h-0 min-w-0 overflow-auto motion-reduce:transform-none!",
1367
+ getFlowViewLayoutClass(measuredSize, activeViewHeight)
1368
+ ),
1369
+ variants: windowFlowViewVariants,
1370
+ initial: getFlowInitialState(direction),
1371
+ animate: "center",
1372
+ exit: "exit",
1373
+ children: activeStep.render()
1374
+ },
1375
+ activeStep.id
1376
+ ) })
1377
+ ]
1378
+ }
1379
+ );
1380
+ }
1381
+ function WindowFlowPreviousButton({
1382
+ children = "Back",
1383
+ disabled,
1384
+ onClick,
1385
+ type = "button",
1386
+ variant = "outline",
1387
+ ...props
1388
+ }) {
1389
+ const { canGoPrevious, previousStep } = useWindowFlow();
1390
+ return /* @__PURE__ */ jsxs5(
1391
+ Button,
1392
+ {
1393
+ disabled: disabled ?? !canGoPrevious,
1394
+ onClick: (event) => {
1395
+ onClick?.(event);
1396
+ if (!event.defaultPrevented) {
1397
+ void previousStep("previous-button").catch((error) => {
1398
+ console.error("Failed to move to the previous window flow step.", error);
1399
+ });
1400
+ }
1401
+ },
1402
+ type,
1403
+ variant,
1404
+ ...props,
1405
+ children: [
1406
+ /* @__PURE__ */ jsx8(ArrowLeftIcon, {}),
1407
+ children
1408
+ ]
1409
+ }
1410
+ );
1411
+ }
1412
+ function WindowFlowNextButton({
1413
+ children,
1414
+ disabled,
1415
+ onClick,
1416
+ type = "button",
1417
+ variant = "accent",
1418
+ ...props
1419
+ }) {
1420
+ const { canGoNext, isLastStep, nextStep } = useWindowFlow();
1421
+ return /* @__PURE__ */ jsxs5(
1422
+ Button,
1423
+ {
1424
+ disabled: disabled ?? !canGoNext,
1425
+ onClick: (event) => {
1426
+ onClick?.(event);
1427
+ if (!event.defaultPrevented) {
1428
+ void nextStep("next-button").catch((error) => {
1429
+ console.error("Failed to move to the next window flow step.", error);
1430
+ });
1431
+ }
1432
+ },
1433
+ type,
1434
+ variant,
1435
+ ...props,
1436
+ children: [
1437
+ children ?? (isLastStep ? "Done" : "Next"),
1438
+ /* @__PURE__ */ jsx8(ArrowRightIcon, {})
1439
+ ]
1440
+ }
1441
+ );
1442
+ }
1443
+ function WindowFlowProgress({ className, ...props }) {
1444
+ const { stepIndex, steps } = useWindowFlow();
1445
+ return /* @__PURE__ */ jsx8(
1446
+ "div",
1447
+ {
1448
+ "data-slot": "window-flow-progress",
1449
+ className: cn("flex w-full items-center gap-1.5", className),
1450
+ ...props,
1451
+ children: steps.map((stepDefinition, index) => /* @__PURE__ */ jsx8(
1452
+ "div",
1453
+ {
1454
+ "data-active": index === stepIndex,
1455
+ "data-complete": index < stepIndex,
1456
+ "data-slot": "window-flow-progress-segment",
1457
+ className: cn(
1458
+ "bg-background-tertiary h-1.5 min-w-0 flex-1 rounded-full transition-colors",
1459
+ index <= stepIndex && "bg-interactive-accent"
1460
+ )
1461
+ },
1462
+ stepDefinition.id
1463
+ ))
1464
+ }
1465
+ );
1466
+ }
1467
+
1468
+ // src/layouts/window/WindowPage.tsx
1469
+ import "react";
1470
+
1471
+ // src/layouts/window/WindowPageContext.tsx
1472
+ import * as React8 from "react";
1473
+ import { jsx as jsx9 } from "react/jsx-runtime";
1474
+ var WindowPageContext = React8.createContext(null);
1475
+ function defineWindowPage(definition) {
1476
+ return definition;
1477
+ }
1478
+ function WindowPageProvider({
1479
+ children,
1480
+ defaultPage,
1481
+ onPageChangeRequest,
1482
+ onPageChange,
1483
+ pages = [],
1484
+ page
1485
+ }) {
1486
+ const windowContext = React8.useContext(WindowStateContext);
1487
+ const pageMap = React8.useMemo(() => {
1488
+ const nextPageMap = /* @__PURE__ */ new Map();
1489
+ pages.forEach((pageDefinition) => {
1490
+ if (nextPageMap.has(pageDefinition.id)) {
1491
+ throw new Error(`Duplicate WindowPage id "${pageDefinition.id}" is not allowed.`);
1492
+ }
1493
+ nextPageMap.set(pageDefinition.id, pageDefinition);
1494
+ });
1495
+ return nextPageMap;
1496
+ }, [pages]);
1497
+ const initialPage = page ?? defaultPage;
1498
+ if (initialPage === void 0) {
1499
+ throw new Error("WindowPageProvider requires a page or defaultPage.");
1500
+ }
1501
+ if (pages.length > 0 && !pageMap.has(initialPage)) {
1502
+ throw new Error(`WindowPageProvider could not find a registered page for "${initialPage}".`);
1503
+ }
1504
+ const [uncontrolledPage, setUncontrolledPage] = React8.useState(initialPage);
1505
+ const isControlled = page !== void 0;
1506
+ const activePage = isControlled ? page : uncontrolledPage;
1507
+ const activePageRef = React8.useRef(activePage);
1508
+ const pageChangeRequestVersionRef = React8.useRef(0);
1509
+ const indicateBlockedInteraction = windowContext?.indicateBlockedInteraction;
1510
+ if (pages.length > 0 && !pageMap.has(activePage)) {
1511
+ throw new Error(`WindowPageProvider could not find a registered page for "${activePage}".`);
1512
+ }
1513
+ React8.useEffect(() => {
1514
+ activePageRef.current = activePage;
1515
+ }, [activePage]);
1516
+ const getPage = React8.useCallback(
1517
+ (targetPage) => pageMap.get(targetPage),
1518
+ [pageMap]
1519
+ );
1520
+ const setPage = React8.useCallback(
1521
+ async (nextPage, reason = "programmatic") => {
1522
+ const currentPage = activePageRef.current;
1523
+ if (nextPage === currentPage) {
1524
+ return true;
1525
+ }
1526
+ if (pages.length > 0 && !pageMap.has(nextPage)) {
1527
+ throw new Error(`WindowPageProvider could not find a registered page for "${nextPage}".`);
1528
+ }
1529
+ const pageChangeRequestVersion = pageChangeRequestVersionRef.current + 1;
1530
+ pageChangeRequestVersionRef.current = pageChangeRequestVersion;
1531
+ const pageChangeAllowed = await onPageChangeRequest?.({
1532
+ from: currentPage,
1533
+ reason,
1534
+ to: nextPage
1535
+ }) ?? true;
1536
+ if (!pageChangeAllowed) {
1537
+ indicateBlockedInteraction?.();
1538
+ return false;
1539
+ }
1540
+ if (pageChangeRequestVersion !== pageChangeRequestVersionRef.current) {
1541
+ return false;
1542
+ }
1543
+ if (!isControlled) {
1544
+ setUncontrolledPage(nextPage);
1545
+ }
1546
+ onPageChange?.(nextPage);
1547
+ return true;
1548
+ },
1549
+ [
1550
+ indicateBlockedInteraction,
1551
+ isControlled,
1552
+ onPageChange,
1553
+ onPageChangeRequest,
1554
+ pageMap,
1555
+ pages.length
1556
+ ]
1557
+ );
1558
+ const isActive = React8.useCallback(
1559
+ (targetPage) => activePage === targetPage,
1560
+ [activePage]
1561
+ );
1562
+ const contextValue = React8.useMemo(
1563
+ () => ({
1564
+ getPage,
1565
+ isActive,
1566
+ pages,
1567
+ page: activePage,
1568
+ setPage
1569
+ }),
1570
+ [activePage, getPage, isActive, pages, setPage]
1571
+ );
1572
+ return /* @__PURE__ */ jsx9(WindowPageContext.Provider, { value: contextValue, children });
1573
+ }
1574
+ function useWindowPage() {
1575
+ const context = React8.useContext(WindowPageContext);
1576
+ if (!context) {
1577
+ throw new Error("useWindowPage must be used within a WindowPageProvider.");
1578
+ }
1579
+ return context;
1580
+ }
1581
+
1582
+ // src/layouts/window/WindowPage.tsx
1583
+ import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1584
+ function WindowPageNavButton({ onClick, page, ...props }) {
1585
+ const { isActive, setPage } = useWindowPage();
1586
+ return /* @__PURE__ */ jsx10(
1587
+ WindowSidebarMenuButton,
1588
+ {
1589
+ "data-slot": "window-page-nav-button",
1590
+ isActive: isActive(page),
1591
+ onClick: (event) => {
1592
+ onClick?.(event);
1593
+ if (!event.defaultPrevented) {
1594
+ void setPage(page, "nav-button").catch((error) => {
1595
+ console.error("Failed to change window page from nav button.", error);
1596
+ });
1597
+ }
1598
+ },
1599
+ ...props
1600
+ }
1601
+ );
1602
+ }
1603
+ function useRegisteredWindowPages() {
1604
+ const context = useWindowPage();
1605
+ if (context.pages.length === 0) {
1606
+ throw new Error(
1607
+ "WindowPageList and WindowPageViews require registered pages on WindowPageProvider."
1608
+ );
1609
+ }
1610
+ return context;
1611
+ }
1612
+ function WindowPageView({
1613
+ children,
1614
+ className,
1615
+ keepMounted = false,
1616
+ page,
1617
+ ...props
1618
+ }) {
1619
+ const { isActive } = useWindowPage();
1620
+ const active = isActive(page);
1621
+ if (!keepMounted && !active) {
1622
+ return null;
1623
+ }
1624
+ return /* @__PURE__ */ jsx10(
1625
+ "div",
1626
+ {
1627
+ "data-slot": "window-page-view",
1628
+ "data-active": active,
1629
+ "data-page": page,
1630
+ "aria-hidden": !active,
1631
+ hidden: !active,
1632
+ className: cn(className),
1633
+ ...props,
1634
+ children
1635
+ }
1636
+ );
1637
+ }
1638
+ function WindowPageList({ className, ...props }) {
1639
+ const { pages } = useRegisteredWindowPages();
1640
+ return /* @__PURE__ */ jsx10(WindowSidebarMenu, { "data-slot": "window-page-list", className: cn(className), ...props, children: pages.map((pageDefinition) => {
1641
+ const Icon = pageDefinition.icon;
1642
+ return /* @__PURE__ */ jsx10(WindowSidebarMenuItem, { children: /* @__PURE__ */ jsx10(
1643
+ WindowPageNavButton,
1644
+ {
1645
+ page: pageDefinition.id,
1646
+ leadingVisual: Icon ? /* @__PURE__ */ jsx10(Icon, { className: "size-4" }) : void 0,
1647
+ children: pageDefinition.label
1648
+ }
1649
+ ) }, pageDefinition.id);
1650
+ }) });
1651
+ }
1652
+ function WindowPageViews({ children, className, ...props }) {
1653
+ const { pages } = useRegisteredWindowPages();
1654
+ return /* @__PURE__ */ jsxs6("div", { "data-slot": "window-page-views", className: cn(className), ...props, children: [
1655
+ children,
1656
+ pages.map((pageDefinition) => /* @__PURE__ */ jsx10(
1657
+ WindowPageView,
1658
+ {
1659
+ page: pageDefinition.id,
1660
+ keepMounted: pageDefinition.keepMounted,
1661
+ children: pageDefinition.render()
1662
+ },
1663
+ pageDefinition.id
1664
+ ))
1665
+ ] });
1666
+ }
1667
+
1668
+ export {
1669
+ WindowGroup,
1670
+ WindowGroupLabel,
1671
+ WindowGroupContent,
1672
+ WindowRow,
1673
+ WindowRowContent,
1674
+ WindowRowTitle,
1675
+ WindowRowDescription,
1676
+ WindowRowActions,
1677
+ WindowRowSeparator,
1678
+ WindowStateContext,
1679
+ WindowStateProvider,
1680
+ useWindow,
1681
+ WindowProvider,
1682
+ WindowManagerContext,
1683
+ defineWindow,
1684
+ WindowManagerProvider,
1685
+ useWindowManager,
1686
+ WindowHost,
1687
+ WindowCloseButton,
1688
+ WindowLayout,
1689
+ useWindowSizeRequest,
1690
+ WindowContent,
1691
+ WindowSidebar,
1692
+ WindowSidebarInput,
1693
+ WindowSidebarHeader,
1694
+ WindowSidebarFooter,
1695
+ WindowSidebarContent,
1696
+ WindowSidebarGroup,
1697
+ WindowSidebarGroupLabel,
1698
+ WindowSidebarGroupAction,
1699
+ WindowSidebarGroupContent,
1700
+ WindowSidebarMenu,
1701
+ WindowSidebarMenuItem,
1702
+ WindowSidebarMenuButton,
1703
+ WindowSidebarMenuAction,
1704
+ WindowSidebarMenuBadge,
1705
+ WindowSidebarMenuSkeleton,
1706
+ defineWindowFlowStep,
1707
+ WindowFlowProvider,
1708
+ useWindowFlow,
1709
+ WindowFlowLayout,
1710
+ WindowFlowHeader,
1711
+ WindowFlowContent,
1712
+ WindowFlowFooter,
1713
+ WindowFlowView,
1714
+ WindowFlowViews,
1715
+ WindowFlowPreviousButton,
1716
+ WindowFlowNextButton,
1717
+ WindowFlowProgress,
1718
+ defineWindowPage,
1719
+ WindowPageProvider,
1720
+ useWindowPage,
1721
+ WindowPageNavButton,
1722
+ WindowPageView,
1723
+ WindowPageList,
1724
+ WindowPageViews
1725
+ };
1726
+ //# sourceMappingURL=chunk-OUFGNJ3V.js.map