@flanksource/clicky-ui 0.2.19 → 0.2.20

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 (417) hide show
  1. package/dist/ai.cjs +26 -0
  2. package/dist/ai.cjs.map +1 -0
  3. package/dist/ai.d.ts +2 -0
  4. package/dist/ai.d.ts.map +1 -0
  5. package/dist/ai.js +26 -0
  6. package/dist/ai.js.map +1 -0
  7. package/dist/chat.cjs +7 -0
  8. package/dist/chat.cjs.map +1 -1
  9. package/dist/chat.js +7 -0
  10. package/dist/chat.js.map +1 -1
  11. package/dist/components/FilterBar.cjs +49 -18
  12. package/dist/components/FilterBar.cjs.map +1 -1
  13. package/dist/components/FilterBar.d.ts +0 -2
  14. package/dist/components/FilterBar.d.ts.map +1 -1
  15. package/dist/components/FilterBar.js +50 -19
  16. package/dist/components/FilterBar.js.map +1 -1
  17. package/dist/components/SearchInput.cjs +63 -0
  18. package/dist/components/SearchInput.cjs.map +1 -0
  19. package/dist/components/SearchInput.d.ts +31 -0
  20. package/dist/components/SearchInput.d.ts.map +1 -0
  21. package/dist/components/SearchInput.js +63 -0
  22. package/dist/components/SearchInput.js.map +1 -0
  23. package/dist/components/SegmentedControl.cjs +88 -0
  24. package/dist/components/SegmentedControl.cjs.map +1 -0
  25. package/dist/components/SegmentedControl.d.ts +38 -0
  26. package/dist/components/SegmentedControl.d.ts.map +1 -0
  27. package/dist/components/SegmentedControl.js +88 -0
  28. package/dist/components/SegmentedControl.js.map +1 -0
  29. package/dist/components/Switch.cjs +51 -0
  30. package/dist/components/Switch.cjs.map +1 -0
  31. package/dist/components/Switch.d.ts +23 -0
  32. package/dist/components/Switch.d.ts.map +1 -0
  33. package/dist/components/Switch.js +51 -0
  34. package/dist/components/Switch.js.map +1 -0
  35. package/dist/components/TimeRange.cjs +53 -45
  36. package/dist/components/TimeRange.cjs.map +1 -1
  37. package/dist/components/TimeRange.d.ts.map +1 -1
  38. package/dist/components/TimeRange.js +53 -45
  39. package/dist/components/TimeRange.js.map +1 -1
  40. package/dist/components/TreePickerField.cjs +5 -1
  41. package/dist/components/TreePickerField.cjs.map +1 -1
  42. package/dist/components/TreePickerField.d.ts.map +1 -1
  43. package/dist/components/TreePickerField.js +5 -1
  44. package/dist/components/TreePickerField.js.map +1 -1
  45. package/dist/components/filter-bar-utils.cjs +5 -0
  46. package/dist/components/filter-bar-utils.cjs.map +1 -1
  47. package/dist/components/filter-bar-utils.d.ts +2 -0
  48. package/dist/components/filter-bar-utils.d.ts.map +1 -1
  49. package/dist/components/filter-bar-utils.js +5 -0
  50. package/dist/components/filter-bar-utils.js.map +1 -1
  51. package/dist/components/json-schema-form-fields.cjs +8 -2
  52. package/dist/components/json-schema-form-fields.cjs.map +1 -1
  53. package/dist/components/json-schema-form-fields.d.ts.map +1 -1
  54. package/dist/components/json-schema-form-fields.js +8 -2
  55. package/dist/components/json-schema-form-fields.js.map +1 -1
  56. package/dist/components/json-schema-form-resolve.cjs +1 -1
  57. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  58. package/dist/components/json-schema-form-resolve.js +1 -1
  59. package/dist/components/json-schema-form-resolve.js.map +1 -1
  60. package/dist/components.cjs +15 -1
  61. package/dist/components.cjs.map +1 -1
  62. package/dist/components.d.ts +8 -1
  63. package/dist/components.d.ts.map +1 -1
  64. package/dist/components.js +15 -1
  65. package/dist/components.js.map +1 -1
  66. package/dist/data/Clicky.cjs +33 -44
  67. package/dist/data/Clicky.cjs.map +1 -1
  68. package/dist/data/Clicky.d.ts +0 -9
  69. package/dist/data/Clicky.d.ts.map +1 -1
  70. package/dist/data/Clicky.js +31 -42
  71. package/dist/data/Clicky.js.map +1 -1
  72. package/dist/data/DataTable.cjs +73 -50
  73. package/dist/data/DataTable.cjs.map +1 -1
  74. package/dist/data/DataTable.d.ts +4 -0
  75. package/dist/data/DataTable.d.ts.map +1 -1
  76. package/dist/data/DataTable.js +73 -50
  77. package/dist/data/DataTable.js.map +1 -1
  78. package/dist/data/Icon.cjs +2 -5
  79. package/dist/data/Icon.cjs.map +1 -1
  80. package/dist/data/Icon.d.ts +1 -21
  81. package/dist/data/Icon.d.ts.map +1 -1
  82. package/dist/data/Icon.js +3 -6
  83. package/dist/data/Icon.js.map +1 -1
  84. package/dist/data/MatrixTable.cjs +4 -4
  85. package/dist/data/MatrixTable.cjs.map +1 -1
  86. package/dist/data/MatrixTable.js +4 -4
  87. package/dist/data/MatrixTable.js.map +1 -1
  88. package/dist/data/RadialGauge.cjs +76 -0
  89. package/dist/data/RadialGauge.cjs.map +1 -0
  90. package/dist/data/RadialGauge.d.ts +24 -0
  91. package/dist/data/RadialGauge.d.ts.map +1 -0
  92. package/dist/data/RadialGauge.js +76 -0
  93. package/dist/data/RadialGauge.js.map +1 -0
  94. package/dist/data/StatusBreakdown.cjs +0 -4
  95. package/dist/data/StatusBreakdown.cjs.map +1 -1
  96. package/dist/data/StatusBreakdown.d.ts +0 -2
  97. package/dist/data/StatusBreakdown.d.ts.map +1 -1
  98. package/dist/data/StatusBreakdown.js +1 -5
  99. package/dist/data/StatusBreakdown.js.map +1 -1
  100. package/dist/data/Timeline.cjs +61 -0
  101. package/dist/data/Timeline.cjs.map +1 -0
  102. package/dist/data/Timeline.d.ts +36 -0
  103. package/dist/data/Timeline.d.ts.map +1 -0
  104. package/dist/data/Timeline.js +61 -0
  105. package/dist/data/Timeline.js.map +1 -0
  106. package/dist/data/TimeseriesCoreBars.cjs +2 -25
  107. package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
  108. package/dist/data/TimeseriesCoreBars.d.ts +0 -19
  109. package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
  110. package/dist/data/TimeseriesCoreBars.js +2 -25
  111. package/dist/data/TimeseriesCoreBars.js.map +1 -1
  112. package/dist/data/TimeseriesCoreBars.model.cjs +27 -0
  113. package/dist/data/TimeseriesCoreBars.model.cjs.map +1 -0
  114. package/dist/data/TimeseriesCoreBars.model.d.ts +20 -0
  115. package/dist/data/TimeseriesCoreBars.model.d.ts.map +1 -0
  116. package/dist/data/TimeseriesCoreBars.model.js +27 -0
  117. package/dist/data/TimeseriesCoreBars.model.js.map +1 -0
  118. package/dist/data/TimeseriesPanel.axes.cjs.map +1 -1
  119. package/dist/data/TimeseriesPanel.axes.d.ts +1 -1
  120. package/dist/data/TimeseriesPanel.axes.d.ts.map +1 -1
  121. package/dist/data/TimeseriesPanel.axes.js.map +1 -1
  122. package/dist/data/TimeseriesPanel.cjs +4 -54
  123. package/dist/data/TimeseriesPanel.cjs.map +1 -1
  124. package/dist/data/TimeseriesPanel.d.ts +2 -138
  125. package/dist/data/TimeseriesPanel.d.ts.map +1 -1
  126. package/dist/data/TimeseriesPanel.js +2 -52
  127. package/dist/data/TimeseriesPanel.js.map +1 -1
  128. package/dist/data/TimeseriesPanel.model.cjs +53 -0
  129. package/dist/data/TimeseriesPanel.model.cjs.map +1 -0
  130. package/dist/data/TimeseriesPanel.model.d.ts +88 -0
  131. package/dist/data/TimeseriesPanel.model.d.ts.map +1 -0
  132. package/dist/data/TimeseriesPanel.model.js +53 -0
  133. package/dist/data/TimeseriesPanel.model.js.map +1 -0
  134. package/dist/data/Tree.cjs +1 -1
  135. package/dist/data/Tree.cjs.map +1 -1
  136. package/dist/data/Tree.js +1 -1
  137. package/dist/data/Tree.js.map +1 -1
  138. package/dist/data/ai/ChatFab.cjs +29 -0
  139. package/dist/data/ai/ChatFab.cjs.map +1 -0
  140. package/dist/data/ai/ChatFab.d.ts +12 -0
  141. package/dist/data/ai/ChatFab.d.ts.map +1 -0
  142. package/dist/data/ai/ChatFab.js +29 -0
  143. package/dist/data/ai/ChatFab.js.map +1 -0
  144. package/dist/data/ai/ChatWindow.cjs +178 -0
  145. package/dist/data/ai/ChatWindow.cjs.map +1 -0
  146. package/dist/data/ai/ChatWindow.d.ts +38 -0
  147. package/dist/data/ai/ChatWindow.d.ts.map +1 -0
  148. package/dist/data/ai/ChatWindow.js +156 -0
  149. package/dist/data/ai/ChatWindow.js.map +1 -0
  150. package/dist/data/ai/ChatWindowManager.cjs +139 -0
  151. package/dist/data/ai/ChatWindowManager.cjs.map +1 -0
  152. package/dist/data/ai/ChatWindowManager.d.ts +12 -0
  153. package/dist/data/ai/ChatWindowManager.d.ts.map +1 -0
  154. package/dist/data/ai/ChatWindowManager.js +139 -0
  155. package/dist/data/ai/ChatWindowManager.js.map +1 -0
  156. package/dist/data/ai/ContextBadges.cjs +74 -0
  157. package/dist/data/ai/ContextBadges.cjs.map +1 -0
  158. package/dist/data/ai/ContextBadges.d.ts +16 -0
  159. package/dist/data/ai/ContextBadges.d.ts.map +1 -0
  160. package/dist/data/ai/ContextBadges.js +74 -0
  161. package/dist/data/ai/ContextBadges.js.map +1 -0
  162. package/dist/data/ai/ThreadPicker.cjs +148 -0
  163. package/dist/data/ai/ThreadPicker.cjs.map +1 -0
  164. package/dist/data/ai/ThreadPicker.d.ts +37 -0
  165. package/dist/data/ai/ThreadPicker.d.ts.map +1 -0
  166. package/dist/data/ai/ThreadPicker.js +148 -0
  167. package/dist/data/ai/ThreadPicker.js.map +1 -0
  168. package/dist/data/ai/ToolPreferences.cjs +80 -0
  169. package/dist/data/ai/ToolPreferences.cjs.map +1 -0
  170. package/dist/data/ai/ToolPreferences.d.ts +19 -0
  171. package/dist/data/ai/ToolPreferences.d.ts.map +1 -0
  172. package/dist/data/ai/ToolPreferences.js +80 -0
  173. package/dist/data/ai/ToolPreferences.js.map +1 -0
  174. package/dist/data/ai/chat-window-context.cjs +78 -0
  175. package/dist/data/ai/chat-window-context.cjs.map +1 -0
  176. package/dist/data/ai/chat-window-context.d.ts +57 -0
  177. package/dist/data/ai/chat-window-context.d.ts.map +1 -0
  178. package/dist/data/ai/chat-window-context.js +78 -0
  179. package/dist/data/ai/chat-window-context.js.map +1 -0
  180. package/dist/data/ai/context.cjs +43 -0
  181. package/dist/data/ai/context.cjs.map +1 -0
  182. package/dist/data/ai/context.d.ts +35 -0
  183. package/dist/data/ai/context.d.ts.map +1 -0
  184. package/dist/data/ai/context.js +43 -0
  185. package/dist/data/ai/context.js.map +1 -0
  186. package/dist/data/ai/index.d.ts +10 -0
  187. package/dist/data/ai/index.d.ts.map +1 -0
  188. package/dist/data/cache-browser/CacheDetailPanel.cjs +15 -0
  189. package/dist/data/cache-browser/CacheDetailPanel.cjs.map +1 -1
  190. package/dist/data/cache-browser/CacheDetailPanel.d.ts.map +1 -1
  191. package/dist/data/cache-browser/CacheDetailPanel.js +15 -0
  192. package/dist/data/cache-browser/CacheDetailPanel.js.map +1 -1
  193. package/dist/data/cache-browser/cache-browser.fixtures.d.ts +10 -0
  194. package/dist/data/cache-browser/cache-browser.fixtures.d.ts.map +1 -0
  195. package/dist/data/cache-browser/download.cjs +13 -0
  196. package/dist/data/cache-browser/download.cjs.map +1 -0
  197. package/dist/data/cache-browser/download.d.ts +3 -0
  198. package/dist/data/cache-browser/download.d.ts.map +1 -0
  199. package/dist/data/cache-browser/download.js +13 -0
  200. package/dist/data/cache-browser/download.js.map +1 -0
  201. package/dist/data/chat/Chat.cjs +40 -2
  202. package/dist/data/chat/Chat.cjs.map +1 -1
  203. package/dist/data/chat/Chat.d.ts +5 -2
  204. package/dist/data/chat/Chat.d.ts.map +1 -1
  205. package/dist/data/chat/Chat.fixtures.cjs +86 -0
  206. package/dist/data/chat/Chat.fixtures.cjs.map +1 -0
  207. package/dist/data/chat/Chat.fixtures.d.ts +4 -0
  208. package/dist/data/chat/Chat.fixtures.d.ts.map +1 -1
  209. package/dist/data/chat/Chat.fixtures.js +86 -0
  210. package/dist/data/chat/Chat.fixtures.js.map +1 -0
  211. package/dist/data/chat/Chat.js +41 -3
  212. package/dist/data/chat/Chat.js.map +1 -1
  213. package/dist/data/chat/ContextUsage.cjs +99 -0
  214. package/dist/data/chat/ContextUsage.cjs.map +1 -0
  215. package/dist/data/chat/ContextUsage.d.ts +19 -0
  216. package/dist/data/chat/ContextUsage.d.ts.map +1 -0
  217. package/dist/data/chat/ContextUsage.js +99 -0
  218. package/dist/data/chat/ContextUsage.js.map +1 -0
  219. package/dist/data/chat/ModelSelector.cjs +28 -14
  220. package/dist/data/chat/ModelSelector.cjs.map +1 -1
  221. package/dist/data/chat/ModelSelector.d.ts +5 -4
  222. package/dist/data/chat/ModelSelector.d.ts.map +1 -1
  223. package/dist/data/chat/ModelSelector.js +28 -14
  224. package/dist/data/chat/ModelSelector.js.map +1 -1
  225. package/dist/data/chat/clickyOperationsToTools.cjs +21 -1
  226. package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -1
  227. package/dist/data/chat/clickyOperationsToTools.d.ts +5 -4
  228. package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -1
  229. package/dist/data/chat/clickyOperationsToTools.js +21 -1
  230. package/dist/data/chat/clickyOperationsToTools.js.map +1 -1
  231. package/dist/data/chat/index.d.ts +4 -1
  232. package/dist/data/chat/index.d.ts.map +1 -1
  233. package/dist/data/chat/provider-icons.cjs +15 -0
  234. package/dist/data/chat/provider-icons.cjs.map +1 -0
  235. package/dist/data/chat/provider-icons.d.ts +7 -0
  236. package/dist/data/chat/provider-icons.d.ts.map +1 -0
  237. package/dist/data/chat/provider-icons.js +15 -0
  238. package/dist/data/chat/provider-icons.js.map +1 -0
  239. package/dist/data/chat/types.cjs.map +1 -1
  240. package/dist/data/chat/types.d.ts +41 -9
  241. package/dist/data/chat/types.d.ts.map +1 -1
  242. package/dist/data/chat/types.js.map +1 -1
  243. package/dist/data/clicky-parse.cjs +42 -0
  244. package/dist/data/clicky-parse.cjs.map +1 -0
  245. package/dist/data/clicky-parse.d.ts +11 -0
  246. package/dist/data/clicky-parse.d.ts.map +1 -0
  247. package/dist/data/clicky-parse.js +42 -0
  248. package/dist/data/clicky-parse.js.map +1 -0
  249. package/dist/data/diagnostics/FrameSourceWindow.cjs +0 -4
  250. package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
  251. package/dist/data/diagnostics/FrameSourceWindow.d.ts +1 -11
  252. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
  253. package/dist/data/diagnostics/FrameSourceWindow.js +1 -5
  254. package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
  255. package/dist/data/diagnostics/FrameSourceWindow.utils.cjs +7 -0
  256. package/dist/data/diagnostics/FrameSourceWindow.utils.cjs.map +1 -0
  257. package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts +12 -0
  258. package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts.map +1 -0
  259. package/dist/data/diagnostics/FrameSourceWindow.utils.js +7 -0
  260. package/dist/data/diagnostics/FrameSourceWindow.utils.js.map +1 -0
  261. package/dist/data/diagnostics/JvmStackTrace.cjs +2 -1
  262. package/dist/data/diagnostics/JvmStackTrace.cjs.map +1 -1
  263. package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
  264. package/dist/data/diagnostics/JvmStackTrace.js +2 -1
  265. package/dist/data/diagnostics/JvmStackTrace.js.map +1 -1
  266. package/dist/data/icon-fallback.cjs +12 -0
  267. package/dist/data/icon-fallback.cjs.map +1 -0
  268. package/dist/data/icon-fallback.d.ts +19 -0
  269. package/dist/data/icon-fallback.d.ts.map +1 -0
  270. package/dist/data/icon-fallback.js +12 -0
  271. package/dist/data/icon-fallback.js.map +1 -0
  272. package/dist/data/status-breakdown-utils.cjs +7 -0
  273. package/dist/data/status-breakdown-utils.cjs.map +1 -0
  274. package/dist/data/status-breakdown-utils.d.ts +4 -0
  275. package/dist/data/status-breakdown-utils.d.ts.map +1 -0
  276. package/dist/data/status-breakdown-utils.js +7 -0
  277. package/dist/data/status-breakdown-utils.js.map +1 -0
  278. package/dist/data/test-runner/TestRunSummary.cjs +36 -0
  279. package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
  280. package/dist/data/test-runner/TestRunSummary.d.ts +7 -1
  281. package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
  282. package/dist/data/test-runner/TestRunSummary.js +36 -0
  283. package/dist/data/test-runner/TestRunSummary.js.map +1 -1
  284. package/dist/data/test-runner/TestRunner.cjs +5 -3
  285. package/dist/data/test-runner/TestRunner.cjs.map +1 -1
  286. package/dist/data/test-runner/TestRunner.d.ts +13 -1
  287. package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
  288. package/dist/data/test-runner/TestRunner.js +5 -3
  289. package/dist/data/test-runner/TestRunner.js.map +1 -1
  290. package/dist/data/version-info.cjs +2 -2
  291. package/dist/data/version-info.js +2 -2
  292. package/dist/data.cjs +19 -6
  293. package/dist/data.cjs.map +1 -1
  294. package/dist/data.d.ts +13 -5
  295. package/dist/data.d.ts.map +1 -1
  296. package/dist/data.js +18 -5
  297. package/dist/data.js.map +1 -1
  298. package/dist/index.cjs +51 -7
  299. package/dist/index.cjs.map +1 -1
  300. package/dist/index.js +50 -6
  301. package/dist/index.js.map +1 -1
  302. package/dist/layout/AppShell.cjs +179 -29
  303. package/dist/layout/AppShell.cjs.map +1 -1
  304. package/dist/layout/AppShell.d.ts +5 -5
  305. package/dist/layout/AppShell.d.ts.map +1 -1
  306. package/dist/layout/AppShell.js +179 -29
  307. package/dist/layout/AppShell.js.map +1 -1
  308. package/dist/layout/AppSidebar.cjs +239 -0
  309. package/dist/layout/AppSidebar.cjs.map +1 -0
  310. package/dist/layout/AppSidebar.d.ts +62 -0
  311. package/dist/layout/AppSidebar.d.ts.map +1 -0
  312. package/dist/layout/AppSidebar.js +239 -0
  313. package/dist/layout/AppSidebar.js.map +1 -0
  314. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  315. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  316. package/dist/overlay/DropdownMenu.js.map +1 -1
  317. package/dist/overlay/Modal.cjs +4 -2
  318. package/dist/overlay/Modal.cjs.map +1 -1
  319. package/dist/overlay/Modal.d.ts +1 -1
  320. package/dist/overlay/Modal.d.ts.map +1 -1
  321. package/dist/overlay/Modal.js +4 -2
  322. package/dist/overlay/Modal.js.map +1 -1
  323. package/dist/overlay/Toast.cjs +89 -0
  324. package/dist/overlay/Toast.cjs.map +1 -0
  325. package/dist/overlay/Toast.d.ts +14 -0
  326. package/dist/overlay/Toast.d.ts.map +1 -0
  327. package/dist/overlay/Toast.js +89 -0
  328. package/dist/overlay/Toast.js.map +1 -0
  329. package/dist/overlay/toast-context.cjs +12 -0
  330. package/dist/overlay/toast-context.cjs.map +1 -0
  331. package/dist/overlay/toast-context.d.ts +24 -0
  332. package/dist/overlay/toast-context.d.ts.map +1 -0
  333. package/dist/overlay/toast-context.js +12 -0
  334. package/dist/overlay/toast-context.js.map +1 -0
  335. package/dist/rpc/AcceptPicker.cjs +81 -58
  336. package/dist/rpc/AcceptPicker.cjs.map +1 -1
  337. package/dist/rpc/AcceptPicker.d.ts.map +1 -1
  338. package/dist/rpc/AcceptPicker.js +81 -58
  339. package/dist/rpc/AcceptPicker.js.map +1 -1
  340. package/dist/rpc/CommandForm.cjs +5 -35
  341. package/dist/rpc/CommandForm.cjs.map +1 -1
  342. package/dist/rpc/CommandForm.d.ts +0 -3
  343. package/dist/rpc/CommandForm.d.ts.map +1 -1
  344. package/dist/rpc/CommandForm.js +2 -32
  345. package/dist/rpc/CommandForm.js.map +1 -1
  346. package/dist/rpc/CommandOutput.cjs +2 -1
  347. package/dist/rpc/CommandOutput.cjs.map +1 -1
  348. package/dist/rpc/CommandOutput.d.ts.map +1 -1
  349. package/dist/rpc/CommandOutput.js +2 -1
  350. package/dist/rpc/CommandOutput.js.map +1 -1
  351. package/dist/rpc/EntityExplorerApp.cjs +28 -83
  352. package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
  353. package/dist/rpc/EntityExplorerApp.d.ts +1 -4
  354. package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
  355. package/dist/rpc/EntityExplorerApp.js +13 -68
  356. package/dist/rpc/EntityExplorerApp.js.map +1 -1
  357. package/dist/rpc/OperationCatalog.cjs +2 -2
  358. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  359. package/dist/rpc/OperationCatalog.d.ts +1 -1
  360. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  361. package/dist/rpc/OperationCatalog.js +1 -1
  362. package/dist/rpc/OperationCatalog.js.map +1 -1
  363. package/dist/rpc/OperationCommandPage.cjs +6 -4
  364. package/dist/rpc/OperationCommandPage.cjs.map +1 -1
  365. package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
  366. package/dist/rpc/OperationCommandPage.js +3 -1
  367. package/dist/rpc/OperationCommandPage.js.map +1 -1
  368. package/dist/rpc/RouterProvider.cjs +10 -0
  369. package/dist/rpc/RouterProvider.cjs.map +1 -0
  370. package/dist/rpc/RouterProvider.d.ts +10 -0
  371. package/dist/rpc/RouterProvider.d.ts.map +1 -0
  372. package/dist/rpc/RouterProvider.js +10 -0
  373. package/dist/rpc/RouterProvider.js.map +1 -0
  374. package/dist/rpc/apiClient.cjs +4 -4
  375. package/dist/rpc/apiClient.cjs.map +1 -1
  376. package/dist/rpc/apiClient.js +4 -4
  377. package/dist/rpc/apiClient.js.map +1 -1
  378. package/dist/rpc/command-form-utils.cjs +43 -0
  379. package/dist/rpc/command-form-utils.cjs.map +1 -0
  380. package/dist/rpc/command-form-utils.d.ts +5 -0
  381. package/dist/rpc/command-form-utils.d.ts.map +1 -0
  382. package/dist/rpc/command-form-utils.js +43 -0
  383. package/dist/rpc/command-form-utils.js.map +1 -0
  384. package/dist/rpc/commandHref.cjs +62 -0
  385. package/dist/rpc/commandHref.cjs.map +1 -0
  386. package/dist/rpc/commandHref.d.ts +7 -0
  387. package/dist/rpc/commandHref.d.ts.map +1 -0
  388. package/dist/rpc/commandHref.js +62 -0
  389. package/dist/rpc/commandHref.js.map +1 -0
  390. package/dist/rpc/formMetadata.cjs +1 -1
  391. package/dist/rpc/formMetadata.cjs.map +1 -1
  392. package/dist/rpc/formMetadata.js +1 -1
  393. package/dist/rpc/formMetadata.js.map +1 -1
  394. package/dist/rpc/router.cjs +83 -0
  395. package/dist/rpc/router.cjs.map +1 -0
  396. package/dist/rpc/router.d.ts +24 -0
  397. package/dist/rpc/router.d.ts.map +1 -0
  398. package/dist/rpc/router.js +83 -0
  399. package/dist/rpc/router.js.map +1 -0
  400. package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts +3 -0
  401. package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts.map +1 -0
  402. package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts +3 -0
  403. package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts.map +1 -0
  404. package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts +24 -0
  405. package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts.map +1 -0
  406. package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts +3 -0
  407. package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts.map +1 -0
  408. package/dist/rpc/rpc-story.fixtures.d.ts +16 -0
  409. package/dist/rpc/rpc-story.fixtures.d.ts.map +1 -0
  410. package/dist/rpc.cjs +17 -0
  411. package/dist/rpc.cjs.map +1 -1
  412. package/dist/rpc.d.ts +5 -0
  413. package/dist/rpc.d.ts.map +1 -1
  414. package/dist/rpc.js +18 -1
  415. package/dist/rpc.js.map +1 -1
  416. package/dist/styles.css +1 -1
  417. package/package.json +11 -1
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const utils = require("../lib/utils.cjs");
6
+ const Icon = require("../data/Icon.cjs");
7
+ const router = require("../rpc/router.cjs");
8
+ const UiSidebar = require("../icons/components/UiSidebar.cjs");
9
+ const DEFAULT_COLLAPSE_KEY = "clicky-ui:app-sidebar:collapsed";
10
+ const DEFAULT_GROUP_COLLAPSE_KEY = "clicky-ui:app-sidebar:groups";
11
+ function defaultIsActive(pathname, to) {
12
+ if (to === "/") return pathname === "/";
13
+ return pathname === to || pathname.startsWith(`${to}/`);
14
+ }
15
+ function useCollapsed(storageKey) {
16
+ const [collapsed, setCollapsed] = react.useState(() => {
17
+ if (typeof window === "undefined") return false;
18
+ return window.localStorage.getItem(storageKey) === "true";
19
+ });
20
+ react.useEffect(() => {
21
+ if (typeof window === "undefined") return;
22
+ window.localStorage.setItem(storageKey, String(collapsed));
23
+ }, [collapsed, storageKey]);
24
+ return [collapsed, () => setCollapsed((c) => !c)];
25
+ }
26
+ function readGroupState(storageKey) {
27
+ if (typeof window === "undefined") return {};
28
+ try {
29
+ const raw = window.localStorage.getItem(storageKey);
30
+ if (!raw) return {};
31
+ const parsed = JSON.parse(raw);
32
+ return parsed && typeof parsed === "object" ? parsed : {};
33
+ } catch {
34
+ return {};
35
+ }
36
+ }
37
+ function useGroupCollapsed(storageKey) {
38
+ const [state, setState] = react.useState(() => readGroupState(storageKey));
39
+ react.useEffect(() => {
40
+ if (typeof window === "undefined") return;
41
+ try {
42
+ window.localStorage.setItem(storageKey, JSON.stringify(state));
43
+ } catch {
44
+ }
45
+ }, [state, storageKey]);
46
+ return {
47
+ isCollapsed: (key, fallback) => state[key] ?? fallback,
48
+ toggle: (key, fallback) => setState((prev) => ({ ...prev, [key]: !(prev[key] ?? fallback) }))
49
+ };
50
+ }
51
+ function flattenGroupItems(groups) {
52
+ const out = [];
53
+ for (const group of groups) {
54
+ if (group.items) out.push(...group.items);
55
+ if (group.groups) out.push(...flattenGroupItems(group.groups));
56
+ }
57
+ return out;
58
+ }
59
+ function AppSidebar({
60
+ sections,
61
+ pathname: pathnameProp,
62
+ renderLink: renderLinkProp,
63
+ header,
64
+ footer,
65
+ collapsedStorageKey = DEFAULT_COLLAPSE_KEY,
66
+ groupCollapsedStorageKey = DEFAULT_GROUP_COLLAPSE_KEY,
67
+ isActive = defaultIsActive,
68
+ className
69
+ }) {
70
+ const router$1 = router.useRouter();
71
+ const pathname = pathnameProp ?? router$1.pathname;
72
+ const renderLink = renderLinkProp ?? router$1.renderLink;
73
+ const [collapsed, toggleCollapsed] = useCollapsed(collapsedStorageKey);
74
+ const groupState = useGroupCollapsed(groupCollapsedStorageKey);
75
+ return /* @__PURE__ */ jsxRuntime.jsxs(
76
+ "nav",
77
+ {
78
+ className: utils.cn(
79
+ "flex shrink-0 flex-col overflow-hidden border-r border-border bg-muted/30 transition-[width] duration-200",
80
+ collapsed ? "w-16" : "w-64",
81
+ className
82
+ ),
83
+ children: [
84
+ /* @__PURE__ */ jsxRuntime.jsxs(
85
+ "div",
86
+ {
87
+ className: utils.cn(
88
+ "flex shrink-0 items-center border-b border-border py-3",
89
+ collapsed ? "justify-center px-2" : "justify-between px-4"
90
+ ),
91
+ children: [
92
+ !collapsed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: header }),
93
+ /* @__PURE__ */ jsxRuntime.jsx(
94
+ "button",
95
+ {
96
+ type: "button",
97
+ onClick: toggleCollapsed,
98
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
99
+ title: collapsed ? "Expand sidebar" : "Collapse sidebar",
100
+ className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
101
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiSidebar.UiSidebar, className: "h-4 w-4" })
102
+ }
103
+ )
104
+ ]
105
+ }
106
+ ),
107
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto py-2", collapsed ? "px-2" : "px-3"), children: sections.map((section, i) => {
108
+ var _a, _b;
109
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
110
+ section.label && /* @__PURE__ */ jsxRuntime.jsx(SectionLabel, { collapsed, children: section.label }),
111
+ (_a = section.items) == null ? void 0 : _a.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
112
+ SidebarItem,
113
+ {
114
+ item,
115
+ active: isActive(pathname, item.to),
116
+ collapsed,
117
+ renderLink
118
+ },
119
+ item.key
120
+ )),
121
+ (_b = section.groups) == null ? void 0 : _b.map(
122
+ (group) => collapsed ? flattenGroupItems([group]).map((item) => /* @__PURE__ */ jsxRuntime.jsx(
123
+ SidebarItem,
124
+ {
125
+ item,
126
+ active: isActive(pathname, item.to),
127
+ collapsed: true,
128
+ renderLink
129
+ },
130
+ item.key
131
+ )) : /* @__PURE__ */ jsxRuntime.jsx(
132
+ SidebarGroup,
133
+ {
134
+ group,
135
+ pathname,
136
+ isActive,
137
+ renderLink,
138
+ groupState
139
+ },
140
+ group.key
141
+ )
142
+ )
143
+ ] }, section.label ?? `section-${i}`);
144
+ }) }),
145
+ footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("mt-auto border-t border-border py-3", collapsed ? "px-2" : "px-4"), children: footer })
146
+ ]
147
+ }
148
+ );
149
+ }
150
+ function SidebarGroup({
151
+ group,
152
+ pathname,
153
+ isActive,
154
+ renderLink,
155
+ groupState
156
+ }) {
157
+ var _a, _b;
158
+ const fallback = group.defaultCollapsed ?? false;
159
+ const collapsed = groupState.isCollapsed(group.key, fallback);
160
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
161
+ /* @__PURE__ */ jsxRuntime.jsxs(
162
+ "button",
163
+ {
164
+ type: "button",
165
+ onClick: () => groupState.toggle(group.key, fallback),
166
+ "aria-expanded": !collapsed,
167
+ className: "flex items-center gap-2 rounded-md px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground transition-colors hover:bg-accent/40",
168
+ children: [
169
+ group.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: group.icon }),
170
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate text-left", children: group.label }),
171
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "text-[0.65rem] opacity-60", children: collapsed ? "▸" : "▾" })
172
+ ]
173
+ }
174
+ ),
175
+ !collapsed && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-2 mt-0.5 flex flex-col gap-0.5 border-l border-border/60 pl-2", children: [
176
+ (_a = group.items) == null ? void 0 : _a.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
177
+ SidebarItem,
178
+ {
179
+ item,
180
+ active: isActive(pathname, item.to),
181
+ collapsed: false,
182
+ renderLink
183
+ },
184
+ item.key
185
+ )),
186
+ (_b = group.groups) == null ? void 0 : _b.map((sub) => /* @__PURE__ */ jsxRuntime.jsx(
187
+ SidebarGroup,
188
+ {
189
+ group: sub,
190
+ pathname,
191
+ isActive,
192
+ renderLink,
193
+ groupState
194
+ },
195
+ sub.key
196
+ ))
197
+ ] })
198
+ ] });
199
+ }
200
+ function SidebarItem({
201
+ item,
202
+ active,
203
+ collapsed,
204
+ renderLink
205
+ }) {
206
+ const className = utils.cn(
207
+ "flex items-center gap-2.5 rounded-md px-3 py-1.5 text-[13px] text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
208
+ collapsed && "justify-center px-0",
209
+ active && "bg-accent font-medium text-accent-foreground"
210
+ );
211
+ const title = collapsed ? item.title : void 0;
212
+ const children = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
213
+ item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: item.icon }),
214
+ !collapsed && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: item.title }),
215
+ !collapsed && item.badge
216
+ ] });
217
+ if (item.external) {
218
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.to, className, title, target: "_blank", rel: "noopener noreferrer", children });
219
+ }
220
+ return renderLink({ key: item.key, to: item.to, className, children, ...title ? { title } : {} });
221
+ }
222
+ function SectionLabel({ children, collapsed }) {
223
+ if (collapsed) {
224
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-2 mb-1 mt-3 border-t border-border first:mt-2" });
225
+ }
226
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-0.5 mt-3 px-3 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground first:mt-2", children });
227
+ }
228
+ function AppLayout({ sidebar, header, children, className }) {
229
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("flex h-full min-h-0 w-full overflow-hidden bg-background", className), children: [
230
+ sidebar,
231
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
232
+ header,
233
+ /* @__PURE__ */ jsxRuntime.jsx("main", { className: "min-h-0 min-w-0 flex-1 overflow-y-auto", children })
234
+ ] })
235
+ ] });
236
+ }
237
+ exports.AppLayout = AppLayout;
238
+ exports.AppSidebar = AppSidebar;
239
+ //# sourceMappingURL=AppSidebar.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppSidebar.cjs","sources":["../../src/layout/AppSidebar.tsx"],"sourcesContent":["import { useEffect, useState, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiSidebar } from \"../icons\";\nimport type { RenderLink } from \"../rpc/EndpointList\";\nimport { useRouter } from \"../rpc/router\";\n\n// AppSidebar / AppLayout are a router-agnostic application shell: a collapsible\n// left navigation rail driven by declarative sections, plus a flex layout that\n// pairs it with an optional header and the routed content. Navigation and active\n// state come from the RouterAdapter (see ../rpc/router) — by default a plain\n// <a href={to}> browser adapter, or the host's react-router/memory adapter via\n// RouterProvider. The `pathname` and `renderLink` props still override the\n// adapter for cases where a rail's active state is independent of the URL.\n//\n// A section may carry flat `items` and/or collapsible `groups`. Groups are for\n// high-cardinality clusters (e.g. provider surfaces) that benefit from being\n// folded away; their open/closed state persists per `group.key`.\n\nexport interface AppNavItem {\n /** Stable key; also used as the React key. */\n key: string;\n title: string;\n /** Destination passed to renderLink (or href for external items). */\n to: string;\n icon?: ReactNode;\n /** Render a plain anchor (new-tab style) instead of a routed link. */\n external?: boolean;\n /** Optional trailing adornment (count, status dot, etc.). */\n badge?: ReactNode;\n}\n\nexport interface AppNavGroup {\n /** Stable key; also the persistence key for collapsed state. */\n key: string;\n label: string;\n icon?: ReactNode;\n /** Collapsed on first render until the user toggles it. */\n defaultCollapsed?: boolean;\n items?: AppNavItem[];\n /** Nested groups (one extra level, e.g. Providers > Xero). */\n groups?: AppNavGroup[];\n}\n\nexport interface AppNavSection {\n /** Section heading; omitted for the leading section. */\n label?: string;\n items?: AppNavItem[];\n /** Collapsible groups rendered after the flat items. */\n groups?: AppNavGroup[];\n}\n\nexport interface AppSidebarProps {\n sections: AppNavSection[];\n /** Current path for active-state. Defaults to the RouterAdapter's pathname. */\n pathname?: string;\n /** Render routed links. Defaults to the RouterAdapter's renderLink (a plain\n * <a href={to}> unless a RouterProvider supplies a router Link). */\n renderLink?: RenderLink;\n /** Branding shown at the top of the expanded rail (logo/title). */\n header?: ReactNode;\n /** Pinned to the bottom of the rail (theme switcher, version, etc.). */\n footer?: ReactNode;\n /** localStorage key persisting the rail collapsed state. */\n collapsedStorageKey?: string;\n /** localStorage key persisting per-group collapsed state. */\n groupCollapsedStorageKey?: string;\n /** Override the default prefix-match active test. */\n isActive?: (pathname: string, to: string) => boolean;\n className?: string;\n}\n\nconst DEFAULT_COLLAPSE_KEY = \"clicky-ui:app-sidebar:collapsed\";\nconst DEFAULT_GROUP_COLLAPSE_KEY = \"clicky-ui:app-sidebar:groups\";\n\nfunction defaultIsActive(pathname: string, to: string): boolean {\n if (to === \"/\") return pathname === \"/\";\n return pathname === to || pathname.startsWith(`${to}/`);\n}\n\nfunction useCollapsed(storageKey: string): [boolean, () => void] {\n const [collapsed, setCollapsed] = useState<boolean>(() => {\n if (typeof window === \"undefined\") return false;\n return window.localStorage.getItem(storageKey) === \"true\";\n });\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n window.localStorage.setItem(storageKey, String(collapsed));\n }, [collapsed, storageKey]);\n return [collapsed, () => setCollapsed((c) => !c)];\n}\n\ninterface GroupState {\n isCollapsed: (key: string, fallback: boolean) => boolean;\n toggle: (key: string, fallback: boolean) => void;\n}\n\nfunction readGroupState(storageKey: string): Record<string, boolean> {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (!raw) return {};\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === \"object\" ? (parsed as Record<string, boolean>) : {};\n } catch {\n return {};\n }\n}\n\nfunction useGroupCollapsed(storageKey: string): GroupState {\n const [state, setState] = useState<Record<string, boolean>>(() => readGroupState(storageKey));\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(state));\n } catch {\n // Sidebar state is a UX nicety; private-mode storage failures are safe to swallow.\n }\n }, [state, storageKey]);\n return {\n isCollapsed: (key, fallback) => state[key] ?? fallback,\n toggle: (key, fallback) => setState((prev) => ({ ...prev, [key]: !(prev[key] ?? fallback) })),\n };\n}\n\nfunction flattenGroupItems(groups: AppNavGroup[]): AppNavItem[] {\n const out: AppNavItem[] = [];\n for (const group of groups) {\n if (group.items) out.push(...group.items);\n if (group.groups) out.push(...flattenGroupItems(group.groups));\n }\n return out;\n}\n\nexport function AppSidebar({\n sections,\n pathname: pathnameProp,\n renderLink: renderLinkProp,\n header,\n footer,\n collapsedStorageKey = DEFAULT_COLLAPSE_KEY,\n groupCollapsedStorageKey = DEFAULT_GROUP_COLLAPSE_KEY,\n isActive = defaultIsActive,\n className,\n}: AppSidebarProps) {\n const router = useRouter();\n const pathname = pathnameProp ?? router.pathname;\n const renderLink = renderLinkProp ?? router.renderLink;\n const [collapsed, toggleCollapsed] = useCollapsed(collapsedStorageKey);\n const groupState = useGroupCollapsed(groupCollapsedStorageKey);\n return (\n <nav\n className={cn(\n \"flex shrink-0 flex-col overflow-hidden border-r border-border bg-muted/30 transition-[width] duration-200\",\n collapsed ? \"w-16\" : \"w-64\",\n className,\n )}\n >\n <div\n className={cn(\n \"flex shrink-0 items-center border-b border-border py-3\",\n collapsed ? \"justify-center px-2\" : \"justify-between px-4\",\n )}\n >\n {!collapsed && <div className=\"min-w-0 flex-1\">{header}</div>}\n <button\n type=\"button\"\n onClick={toggleCollapsed}\n aria-label={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n title={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\"\n >\n <Icon icon={UiSidebar} className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className={cn(\"flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto py-2\", collapsed ? \"px-2\" : \"px-3\")}>\n {sections.map((section, i) => (\n <div key={section.label ?? `section-${i}`} className=\"flex flex-col\">\n {section.label && <SectionLabel collapsed={collapsed}>{section.label}</SectionLabel>}\n {section.items?.map((item) => (\n <SidebarItem\n key={item.key}\n item={item}\n active={isActive(pathname, item.to)}\n collapsed={collapsed}\n renderLink={renderLink}\n />\n ))}\n {section.groups?.map((group) =>\n collapsed ? (\n flattenGroupItems([group]).map((item) => (\n <SidebarItem\n key={item.key}\n item={item}\n active={isActive(pathname, item.to)}\n collapsed\n renderLink={renderLink}\n />\n ))\n ) : (\n <SidebarGroup\n key={group.key}\n group={group}\n pathname={pathname}\n isActive={isActive}\n renderLink={renderLink}\n groupState={groupState}\n />\n ),\n )}\n </div>\n ))}\n </div>\n\n {footer && <div className={cn(\"mt-auto border-t border-border py-3\", collapsed ? \"px-2\" : \"px-4\")}>{footer}</div>}\n </nav>\n );\n}\n\nfunction SidebarGroup({\n group,\n pathname,\n isActive,\n renderLink,\n groupState,\n}: {\n group: AppNavGroup;\n pathname: string;\n isActive: (pathname: string, to: string) => boolean;\n renderLink: RenderLink;\n groupState: GroupState;\n}) {\n const fallback = group.defaultCollapsed ?? false;\n const collapsed = groupState.isCollapsed(group.key, fallback);\n return (\n <div className=\"flex flex-col\">\n <button\n type=\"button\"\n onClick={() => groupState.toggle(group.key, fallback)}\n aria-expanded={!collapsed}\n className=\"flex items-center gap-2 rounded-md px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground transition-colors hover:bg-accent/40\"\n >\n {group.icon && <span className=\"flex h-4 w-4 shrink-0 items-center justify-center\">{group.icon}</span>}\n <span className=\"flex-1 truncate text-left\">{group.label}</span>\n <span aria-hidden className=\"text-[0.65rem] opacity-60\">\n {collapsed ? \"▸\" : \"▾\"}\n </span>\n </button>\n {!collapsed && (\n <div className=\"ml-2 mt-0.5 flex flex-col gap-0.5 border-l border-border/60 pl-2\">\n {group.items?.map((item) => (\n <SidebarItem\n key={item.key}\n item={item}\n active={isActive(pathname, item.to)}\n collapsed={false}\n renderLink={renderLink}\n />\n ))}\n {group.groups?.map((sub) => (\n <SidebarGroup\n key={sub.key}\n group={sub}\n pathname={pathname}\n isActive={isActive}\n renderLink={renderLink}\n groupState={groupState}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction SidebarItem({\n item,\n active,\n collapsed,\n renderLink,\n}: {\n item: AppNavItem;\n active: boolean;\n collapsed: boolean;\n renderLink: RenderLink;\n}) {\n const className = cn(\n \"flex items-center gap-2.5 rounded-md px-3 py-1.5 text-[13px] text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\",\n collapsed && \"justify-center px-0\",\n active && \"bg-accent font-medium text-accent-foreground\",\n );\n const title = collapsed ? item.title : undefined;\n const children = (\n <>\n {item.icon && <span className=\"flex h-4 w-4 shrink-0 items-center justify-center\">{item.icon}</span>}\n {!collapsed && <span className=\"flex-1 truncate\">{item.title}</span>}\n {!collapsed && item.badge}\n </>\n );\n\n if (item.external) {\n return (\n <a href={item.to} className={className} title={title} target=\"_blank\" rel=\"noopener noreferrer\">\n {children}\n </a>\n );\n }\n return renderLink({ key: item.key, to: item.to, className, children, ...(title ? { title } : {}) });\n}\n\nfunction SectionLabel({ children, collapsed }: { children: ReactNode; collapsed: boolean }) {\n if (collapsed) {\n return <div className=\"mx-2 mb-1 mt-3 border-t border-border first:mt-2\" />;\n }\n return (\n <div className=\"mb-0.5 mt-3 px-3 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground first:mt-2\">\n {children}\n </div>\n );\n}\n\nexport interface AppLayoutProps {\n sidebar: ReactNode;\n header?: ReactNode;\n children: ReactNode;\n className?: string;\n}\n\n/** Flex shell pairing the sidebar rail with an optional header and the routed\n * content area. The content area scrolls independently of the rail. */\nexport function AppLayout({ sidebar, header, children, className }: AppLayoutProps) {\n return (\n <div className={cn(\"flex h-full min-h-0 w-full overflow-hidden bg-background\", className)}>\n {sidebar}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {header}\n <main className=\"min-h-0 min-w-0 flex-1 overflow-y-auto\">{children}</main>\n </div>\n </div>\n );\n}\n"],"names":["useState","useEffect","router","useRouter","jsxs","cn","jsx","Icon","UiSidebar","Fragment"],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { ReactNode } from 'react';
2
+ import { RenderLink } from '../rpc/EndpointList';
3
+ export interface AppNavItem {
4
+ /** Stable key; also used as the React key. */
5
+ key: string;
6
+ title: string;
7
+ /** Destination passed to renderLink (or href for external items). */
8
+ to: string;
9
+ icon?: ReactNode;
10
+ /** Render a plain anchor (new-tab style) instead of a routed link. */
11
+ external?: boolean;
12
+ /** Optional trailing adornment (count, status dot, etc.). */
13
+ badge?: ReactNode;
14
+ }
15
+ export interface AppNavGroup {
16
+ /** Stable key; also the persistence key for collapsed state. */
17
+ key: string;
18
+ label: string;
19
+ icon?: ReactNode;
20
+ /** Collapsed on first render until the user toggles it. */
21
+ defaultCollapsed?: boolean;
22
+ items?: AppNavItem[];
23
+ /** Nested groups (one extra level, e.g. Providers > Xero). */
24
+ groups?: AppNavGroup[];
25
+ }
26
+ export interface AppNavSection {
27
+ /** Section heading; omitted for the leading section. */
28
+ label?: string;
29
+ items?: AppNavItem[];
30
+ /** Collapsible groups rendered after the flat items. */
31
+ groups?: AppNavGroup[];
32
+ }
33
+ export interface AppSidebarProps {
34
+ sections: AppNavSection[];
35
+ /** Current path for active-state. Defaults to the RouterAdapter's pathname. */
36
+ pathname?: string;
37
+ /** Render routed links. Defaults to the RouterAdapter's renderLink (a plain
38
+ * <a href={to}> unless a RouterProvider supplies a router Link). */
39
+ renderLink?: RenderLink;
40
+ /** Branding shown at the top of the expanded rail (logo/title). */
41
+ header?: ReactNode;
42
+ /** Pinned to the bottom of the rail (theme switcher, version, etc.). */
43
+ footer?: ReactNode;
44
+ /** localStorage key persisting the rail collapsed state. */
45
+ collapsedStorageKey?: string;
46
+ /** localStorage key persisting per-group collapsed state. */
47
+ groupCollapsedStorageKey?: string;
48
+ /** Override the default prefix-match active test. */
49
+ isActive?: (pathname: string, to: string) => boolean;
50
+ className?: string;
51
+ }
52
+ export declare function AppSidebar({ sections, pathname: pathnameProp, renderLink: renderLinkProp, header, footer, collapsedStorageKey, groupCollapsedStorageKey, isActive, className, }: AppSidebarProps): import("react/jsx-runtime").JSX.Element;
53
+ export interface AppLayoutProps {
54
+ sidebar: ReactNode;
55
+ header?: ReactNode;
56
+ children: ReactNode;
57
+ className?: string;
58
+ }
59
+ /** Flex shell pairing the sidebar rail with an optional header and the routed
60
+ * content area. The content area scrolls independently of the rail. */
61
+ export declare function AppLayout({ sidebar, header, children, className }: AppLayoutProps): import("react/jsx-runtime").JSX.Element;
62
+ //# sourceMappingURL=AppSidebar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppSidebar.d.ts","sourceRoot":"","sources":["../../src/layout/AppSidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAetD,MAAM,WAAW,UAAU;IACzB,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,wDAAwD;IACxD,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;yEACqE;IACrE,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,mEAAmE;IACnE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,wEAAwE;IACxE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,4DAA4D;IAC5D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,6DAA6D;IAC7D,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,cAAc,EAC1B,MAAM,EACN,MAAM,EACN,mBAA0C,EAC1C,wBAAqD,EACrD,QAA0B,EAC1B,SAAS,GACV,EAAE,eAAe,2CA0EjB;AAwGD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;uEACuE;AACvE,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,2CAUjF"}
@@ -0,0 +1,239 @@
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { cn } from "../lib/utils.js";
4
+ import { Icon } from "../data/Icon.js";
5
+ import { useRouter } from "../rpc/router.js";
6
+ import { UiSidebar } from "../icons/components/UiSidebar.js";
7
+ const DEFAULT_COLLAPSE_KEY = "clicky-ui:app-sidebar:collapsed";
8
+ const DEFAULT_GROUP_COLLAPSE_KEY = "clicky-ui:app-sidebar:groups";
9
+ function defaultIsActive(pathname, to) {
10
+ if (to === "/") return pathname === "/";
11
+ return pathname === to || pathname.startsWith(`${to}/`);
12
+ }
13
+ function useCollapsed(storageKey) {
14
+ const [collapsed, setCollapsed] = useState(() => {
15
+ if (typeof window === "undefined") return false;
16
+ return window.localStorage.getItem(storageKey) === "true";
17
+ });
18
+ useEffect(() => {
19
+ if (typeof window === "undefined") return;
20
+ window.localStorage.setItem(storageKey, String(collapsed));
21
+ }, [collapsed, storageKey]);
22
+ return [collapsed, () => setCollapsed((c) => !c)];
23
+ }
24
+ function readGroupState(storageKey) {
25
+ if (typeof window === "undefined") return {};
26
+ try {
27
+ const raw = window.localStorage.getItem(storageKey);
28
+ if (!raw) return {};
29
+ const parsed = JSON.parse(raw);
30
+ return parsed && typeof parsed === "object" ? parsed : {};
31
+ } catch {
32
+ return {};
33
+ }
34
+ }
35
+ function useGroupCollapsed(storageKey) {
36
+ const [state, setState] = useState(() => readGroupState(storageKey));
37
+ useEffect(() => {
38
+ if (typeof window === "undefined") return;
39
+ try {
40
+ window.localStorage.setItem(storageKey, JSON.stringify(state));
41
+ } catch {
42
+ }
43
+ }, [state, storageKey]);
44
+ return {
45
+ isCollapsed: (key, fallback) => state[key] ?? fallback,
46
+ toggle: (key, fallback) => setState((prev) => ({ ...prev, [key]: !(prev[key] ?? fallback) }))
47
+ };
48
+ }
49
+ function flattenGroupItems(groups) {
50
+ const out = [];
51
+ for (const group of groups) {
52
+ if (group.items) out.push(...group.items);
53
+ if (group.groups) out.push(...flattenGroupItems(group.groups));
54
+ }
55
+ return out;
56
+ }
57
+ function AppSidebar({
58
+ sections,
59
+ pathname: pathnameProp,
60
+ renderLink: renderLinkProp,
61
+ header,
62
+ footer,
63
+ collapsedStorageKey = DEFAULT_COLLAPSE_KEY,
64
+ groupCollapsedStorageKey = DEFAULT_GROUP_COLLAPSE_KEY,
65
+ isActive = defaultIsActive,
66
+ className
67
+ }) {
68
+ const router = useRouter();
69
+ const pathname = pathnameProp ?? router.pathname;
70
+ const renderLink = renderLinkProp ?? router.renderLink;
71
+ const [collapsed, toggleCollapsed] = useCollapsed(collapsedStorageKey);
72
+ const groupState = useGroupCollapsed(groupCollapsedStorageKey);
73
+ return /* @__PURE__ */ jsxs(
74
+ "nav",
75
+ {
76
+ className: cn(
77
+ "flex shrink-0 flex-col overflow-hidden border-r border-border bg-muted/30 transition-[width] duration-200",
78
+ collapsed ? "w-16" : "w-64",
79
+ className
80
+ ),
81
+ children: [
82
+ /* @__PURE__ */ jsxs(
83
+ "div",
84
+ {
85
+ className: cn(
86
+ "flex shrink-0 items-center border-b border-border py-3",
87
+ collapsed ? "justify-center px-2" : "justify-between px-4"
88
+ ),
89
+ children: [
90
+ !collapsed && /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: header }),
91
+ /* @__PURE__ */ jsx(
92
+ "button",
93
+ {
94
+ type: "button",
95
+ onClick: toggleCollapsed,
96
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
97
+ title: collapsed ? "Expand sidebar" : "Collapse sidebar",
98
+ className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
99
+ children: /* @__PURE__ */ jsx(Icon, { icon: UiSidebar, className: "h-4 w-4" })
100
+ }
101
+ )
102
+ ]
103
+ }
104
+ ),
105
+ /* @__PURE__ */ jsx("div", { className: cn("flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto py-2", collapsed ? "px-2" : "px-3"), children: sections.map((section, i) => {
106
+ var _a, _b;
107
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
108
+ section.label && /* @__PURE__ */ jsx(SectionLabel, { collapsed, children: section.label }),
109
+ (_a = section.items) == null ? void 0 : _a.map((item) => /* @__PURE__ */ jsx(
110
+ SidebarItem,
111
+ {
112
+ item,
113
+ active: isActive(pathname, item.to),
114
+ collapsed,
115
+ renderLink
116
+ },
117
+ item.key
118
+ )),
119
+ (_b = section.groups) == null ? void 0 : _b.map(
120
+ (group) => collapsed ? flattenGroupItems([group]).map((item) => /* @__PURE__ */ jsx(
121
+ SidebarItem,
122
+ {
123
+ item,
124
+ active: isActive(pathname, item.to),
125
+ collapsed: true,
126
+ renderLink
127
+ },
128
+ item.key
129
+ )) : /* @__PURE__ */ jsx(
130
+ SidebarGroup,
131
+ {
132
+ group,
133
+ pathname,
134
+ isActive,
135
+ renderLink,
136
+ groupState
137
+ },
138
+ group.key
139
+ )
140
+ )
141
+ ] }, section.label ?? `section-${i}`);
142
+ }) }),
143
+ footer && /* @__PURE__ */ jsx("div", { className: cn("mt-auto border-t border-border py-3", collapsed ? "px-2" : "px-4"), children: footer })
144
+ ]
145
+ }
146
+ );
147
+ }
148
+ function SidebarGroup({
149
+ group,
150
+ pathname,
151
+ isActive,
152
+ renderLink,
153
+ groupState
154
+ }) {
155
+ var _a, _b;
156
+ const fallback = group.defaultCollapsed ?? false;
157
+ const collapsed = groupState.isCollapsed(group.key, fallback);
158
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
159
+ /* @__PURE__ */ jsxs(
160
+ "button",
161
+ {
162
+ type: "button",
163
+ onClick: () => groupState.toggle(group.key, fallback),
164
+ "aria-expanded": !collapsed,
165
+ className: "flex items-center gap-2 rounded-md px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground transition-colors hover:bg-accent/40",
166
+ children: [
167
+ group.icon && /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: group.icon }),
168
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-left", children: group.label }),
169
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "text-[0.65rem] opacity-60", children: collapsed ? "▸" : "▾" })
170
+ ]
171
+ }
172
+ ),
173
+ !collapsed && /* @__PURE__ */ jsxs("div", { className: "ml-2 mt-0.5 flex flex-col gap-0.5 border-l border-border/60 pl-2", children: [
174
+ (_a = group.items) == null ? void 0 : _a.map((item) => /* @__PURE__ */ jsx(
175
+ SidebarItem,
176
+ {
177
+ item,
178
+ active: isActive(pathname, item.to),
179
+ collapsed: false,
180
+ renderLink
181
+ },
182
+ item.key
183
+ )),
184
+ (_b = group.groups) == null ? void 0 : _b.map((sub) => /* @__PURE__ */ jsx(
185
+ SidebarGroup,
186
+ {
187
+ group: sub,
188
+ pathname,
189
+ isActive,
190
+ renderLink,
191
+ groupState
192
+ },
193
+ sub.key
194
+ ))
195
+ ] })
196
+ ] });
197
+ }
198
+ function SidebarItem({
199
+ item,
200
+ active,
201
+ collapsed,
202
+ renderLink
203
+ }) {
204
+ const className = cn(
205
+ "flex items-center gap-2.5 rounded-md px-3 py-1.5 text-[13px] text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
206
+ collapsed && "justify-center px-0",
207
+ active && "bg-accent font-medium text-accent-foreground"
208
+ );
209
+ const title = collapsed ? item.title : void 0;
210
+ const children = /* @__PURE__ */ jsxs(Fragment, { children: [
211
+ item.icon && /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: item.icon }),
212
+ !collapsed && /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.title }),
213
+ !collapsed && item.badge
214
+ ] });
215
+ if (item.external) {
216
+ return /* @__PURE__ */ jsx("a", { href: item.to, className, title, target: "_blank", rel: "noopener noreferrer", children });
217
+ }
218
+ return renderLink({ key: item.key, to: item.to, className, children, ...title ? { title } : {} });
219
+ }
220
+ function SectionLabel({ children, collapsed }) {
221
+ if (collapsed) {
222
+ return /* @__PURE__ */ jsx("div", { className: "mx-2 mb-1 mt-3 border-t border-border first:mt-2" });
223
+ }
224
+ return /* @__PURE__ */ jsx("div", { className: "mb-0.5 mt-3 px-3 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground first:mt-2", children });
225
+ }
226
+ function AppLayout({ sidebar, header, children, className }) {
227
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex h-full min-h-0 w-full overflow-hidden bg-background", className), children: [
228
+ sidebar,
229
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
230
+ header,
231
+ /* @__PURE__ */ jsx("main", { className: "min-h-0 min-w-0 flex-1 overflow-y-auto", children })
232
+ ] })
233
+ ] });
234
+ }
235
+ export {
236
+ AppLayout,
237
+ AppSidebar
238
+ };
239
+ //# sourceMappingURL=AppSidebar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppSidebar.js","sources":["../../src/layout/AppSidebar.tsx"],"sourcesContent":["import { useEffect, useState, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiSidebar } from \"../icons\";\nimport type { RenderLink } from \"../rpc/EndpointList\";\nimport { useRouter } from \"../rpc/router\";\n\n// AppSidebar / AppLayout are a router-agnostic application shell: a collapsible\n// left navigation rail driven by declarative sections, plus a flex layout that\n// pairs it with an optional header and the routed content. Navigation and active\n// state come from the RouterAdapter (see ../rpc/router) — by default a plain\n// <a href={to}> browser adapter, or the host's react-router/memory adapter via\n// RouterProvider. The `pathname` and `renderLink` props still override the\n// adapter for cases where a rail's active state is independent of the URL.\n//\n// A section may carry flat `items` and/or collapsible `groups`. Groups are for\n// high-cardinality clusters (e.g. provider surfaces) that benefit from being\n// folded away; their open/closed state persists per `group.key`.\n\nexport interface AppNavItem {\n /** Stable key; also used as the React key. */\n key: string;\n title: string;\n /** Destination passed to renderLink (or href for external items). */\n to: string;\n icon?: ReactNode;\n /** Render a plain anchor (new-tab style) instead of a routed link. */\n external?: boolean;\n /** Optional trailing adornment (count, status dot, etc.). */\n badge?: ReactNode;\n}\n\nexport interface AppNavGroup {\n /** Stable key; also the persistence key for collapsed state. */\n key: string;\n label: string;\n icon?: ReactNode;\n /** Collapsed on first render until the user toggles it. */\n defaultCollapsed?: boolean;\n items?: AppNavItem[];\n /** Nested groups (one extra level, e.g. Providers > Xero). */\n groups?: AppNavGroup[];\n}\n\nexport interface AppNavSection {\n /** Section heading; omitted for the leading section. */\n label?: string;\n items?: AppNavItem[];\n /** Collapsible groups rendered after the flat items. */\n groups?: AppNavGroup[];\n}\n\nexport interface AppSidebarProps {\n sections: AppNavSection[];\n /** Current path for active-state. Defaults to the RouterAdapter's pathname. */\n pathname?: string;\n /** Render routed links. Defaults to the RouterAdapter's renderLink (a plain\n * <a href={to}> unless a RouterProvider supplies a router Link). */\n renderLink?: RenderLink;\n /** Branding shown at the top of the expanded rail (logo/title). */\n header?: ReactNode;\n /** Pinned to the bottom of the rail (theme switcher, version, etc.). */\n footer?: ReactNode;\n /** localStorage key persisting the rail collapsed state. */\n collapsedStorageKey?: string;\n /** localStorage key persisting per-group collapsed state. */\n groupCollapsedStorageKey?: string;\n /** Override the default prefix-match active test. */\n isActive?: (pathname: string, to: string) => boolean;\n className?: string;\n}\n\nconst DEFAULT_COLLAPSE_KEY = \"clicky-ui:app-sidebar:collapsed\";\nconst DEFAULT_GROUP_COLLAPSE_KEY = \"clicky-ui:app-sidebar:groups\";\n\nfunction defaultIsActive(pathname: string, to: string): boolean {\n if (to === \"/\") return pathname === \"/\";\n return pathname === to || pathname.startsWith(`${to}/`);\n}\n\nfunction useCollapsed(storageKey: string): [boolean, () => void] {\n const [collapsed, setCollapsed] = useState<boolean>(() => {\n if (typeof window === \"undefined\") return false;\n return window.localStorage.getItem(storageKey) === \"true\";\n });\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n window.localStorage.setItem(storageKey, String(collapsed));\n }, [collapsed, storageKey]);\n return [collapsed, () => setCollapsed((c) => !c)];\n}\n\ninterface GroupState {\n isCollapsed: (key: string, fallback: boolean) => boolean;\n toggle: (key: string, fallback: boolean) => void;\n}\n\nfunction readGroupState(storageKey: string): Record<string, boolean> {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (!raw) return {};\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === \"object\" ? (parsed as Record<string, boolean>) : {};\n } catch {\n return {};\n }\n}\n\nfunction useGroupCollapsed(storageKey: string): GroupState {\n const [state, setState] = useState<Record<string, boolean>>(() => readGroupState(storageKey));\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(state));\n } catch {\n // Sidebar state is a UX nicety; private-mode storage failures are safe to swallow.\n }\n }, [state, storageKey]);\n return {\n isCollapsed: (key, fallback) => state[key] ?? fallback,\n toggle: (key, fallback) => setState((prev) => ({ ...prev, [key]: !(prev[key] ?? fallback) })),\n };\n}\n\nfunction flattenGroupItems(groups: AppNavGroup[]): AppNavItem[] {\n const out: AppNavItem[] = [];\n for (const group of groups) {\n if (group.items) out.push(...group.items);\n if (group.groups) out.push(...flattenGroupItems(group.groups));\n }\n return out;\n}\n\nexport function AppSidebar({\n sections,\n pathname: pathnameProp,\n renderLink: renderLinkProp,\n header,\n footer,\n collapsedStorageKey = DEFAULT_COLLAPSE_KEY,\n groupCollapsedStorageKey = DEFAULT_GROUP_COLLAPSE_KEY,\n isActive = defaultIsActive,\n className,\n}: AppSidebarProps) {\n const router = useRouter();\n const pathname = pathnameProp ?? router.pathname;\n const renderLink = renderLinkProp ?? router.renderLink;\n const [collapsed, toggleCollapsed] = useCollapsed(collapsedStorageKey);\n const groupState = useGroupCollapsed(groupCollapsedStorageKey);\n return (\n <nav\n className={cn(\n \"flex shrink-0 flex-col overflow-hidden border-r border-border bg-muted/30 transition-[width] duration-200\",\n collapsed ? \"w-16\" : \"w-64\",\n className,\n )}\n >\n <div\n className={cn(\n \"flex shrink-0 items-center border-b border-border py-3\",\n collapsed ? \"justify-center px-2\" : \"justify-between px-4\",\n )}\n >\n {!collapsed && <div className=\"min-w-0 flex-1\">{header}</div>}\n <button\n type=\"button\"\n onClick={toggleCollapsed}\n aria-label={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n title={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\"\n >\n <Icon icon={UiSidebar} className=\"h-4 w-4\" />\n </button>\n </div>\n\n <div className={cn(\"flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto py-2\", collapsed ? \"px-2\" : \"px-3\")}>\n {sections.map((section, i) => (\n <div key={section.label ?? `section-${i}`} className=\"flex flex-col\">\n {section.label && <SectionLabel collapsed={collapsed}>{section.label}</SectionLabel>}\n {section.items?.map((item) => (\n <SidebarItem\n key={item.key}\n item={item}\n active={isActive(pathname, item.to)}\n collapsed={collapsed}\n renderLink={renderLink}\n />\n ))}\n {section.groups?.map((group) =>\n collapsed ? (\n flattenGroupItems([group]).map((item) => (\n <SidebarItem\n key={item.key}\n item={item}\n active={isActive(pathname, item.to)}\n collapsed\n renderLink={renderLink}\n />\n ))\n ) : (\n <SidebarGroup\n key={group.key}\n group={group}\n pathname={pathname}\n isActive={isActive}\n renderLink={renderLink}\n groupState={groupState}\n />\n ),\n )}\n </div>\n ))}\n </div>\n\n {footer && <div className={cn(\"mt-auto border-t border-border py-3\", collapsed ? \"px-2\" : \"px-4\")}>{footer}</div>}\n </nav>\n );\n}\n\nfunction SidebarGroup({\n group,\n pathname,\n isActive,\n renderLink,\n groupState,\n}: {\n group: AppNavGroup;\n pathname: string;\n isActive: (pathname: string, to: string) => boolean;\n renderLink: RenderLink;\n groupState: GroupState;\n}) {\n const fallback = group.defaultCollapsed ?? false;\n const collapsed = groupState.isCollapsed(group.key, fallback);\n return (\n <div className=\"flex flex-col\">\n <button\n type=\"button\"\n onClick={() => groupState.toggle(group.key, fallback)}\n aria-expanded={!collapsed}\n className=\"flex items-center gap-2 rounded-md px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground transition-colors hover:bg-accent/40\"\n >\n {group.icon && <span className=\"flex h-4 w-4 shrink-0 items-center justify-center\">{group.icon}</span>}\n <span className=\"flex-1 truncate text-left\">{group.label}</span>\n <span aria-hidden className=\"text-[0.65rem] opacity-60\">\n {collapsed ? \"▸\" : \"▾\"}\n </span>\n </button>\n {!collapsed && (\n <div className=\"ml-2 mt-0.5 flex flex-col gap-0.5 border-l border-border/60 pl-2\">\n {group.items?.map((item) => (\n <SidebarItem\n key={item.key}\n item={item}\n active={isActive(pathname, item.to)}\n collapsed={false}\n renderLink={renderLink}\n />\n ))}\n {group.groups?.map((sub) => (\n <SidebarGroup\n key={sub.key}\n group={sub}\n pathname={pathname}\n isActive={isActive}\n renderLink={renderLink}\n groupState={groupState}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction SidebarItem({\n item,\n active,\n collapsed,\n renderLink,\n}: {\n item: AppNavItem;\n active: boolean;\n collapsed: boolean;\n renderLink: RenderLink;\n}) {\n const className = cn(\n \"flex items-center gap-2.5 rounded-md px-3 py-1.5 text-[13px] text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\",\n collapsed && \"justify-center px-0\",\n active && \"bg-accent font-medium text-accent-foreground\",\n );\n const title = collapsed ? item.title : undefined;\n const children = (\n <>\n {item.icon && <span className=\"flex h-4 w-4 shrink-0 items-center justify-center\">{item.icon}</span>}\n {!collapsed && <span className=\"flex-1 truncate\">{item.title}</span>}\n {!collapsed && item.badge}\n </>\n );\n\n if (item.external) {\n return (\n <a href={item.to} className={className} title={title} target=\"_blank\" rel=\"noopener noreferrer\">\n {children}\n </a>\n );\n }\n return renderLink({ key: item.key, to: item.to, className, children, ...(title ? { title } : {}) });\n}\n\nfunction SectionLabel({ children, collapsed }: { children: ReactNode; collapsed: boolean }) {\n if (collapsed) {\n return <div className=\"mx-2 mb-1 mt-3 border-t border-border first:mt-2\" />;\n }\n return (\n <div className=\"mb-0.5 mt-3 px-3 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground first:mt-2\">\n {children}\n </div>\n );\n}\n\nexport interface AppLayoutProps {\n sidebar: ReactNode;\n header?: ReactNode;\n children: ReactNode;\n className?: string;\n}\n\n/** Flex shell pairing the sidebar rail with an optional header and the routed\n * content area. The content area scrolls independently of the rail. */\nexport function AppLayout({ sidebar, header, children, className }: AppLayoutProps) {\n return (\n <div className={cn(\"flex h-full min-h-0 w-full overflow-hidden bg-background\", className)}>\n {sidebar}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {header}\n <main className=\"min-h-0 min-w-0 flex-1 overflow-y-auto\">{children}</main>\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}