@omnitron-dev/prism 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/README.md +68 -2
  2. package/THIRD-PARTY-NOTICES.txt +26 -0
  3. package/dist/accessibility/index.js +2 -0
  4. package/dist/accessibility/index.js.map +1 -1
  5. package/dist/auth/index.d.ts +4 -0
  6. package/dist/auth/index.d.ts.map +1 -0
  7. package/dist/auth/index.js +4 -0
  8. package/dist/auth/index.js.map +1 -0
  9. package/dist/blocks/auth-block/guards.d.ts +3 -2
  10. package/dist/blocks/auth-block/guards.d.ts.map +1 -1
  11. package/dist/blocks/dashboard-block/dashboard-block.d.ts.map +1 -1
  12. package/dist/blocks/dashboard-block/types.d.ts +4 -2
  13. package/dist/blocks/dashboard-block/types.d.ts.map +1 -1
  14. package/dist/blocks/dashboard-block/use-dashboard-block.d.ts +2 -2
  15. package/dist/blocks/dashboard-block/use-dashboard-block.d.ts.map +1 -1
  16. package/dist/blocks/data-grid-block/data-grid-block.d.ts.map +1 -1
  17. package/dist/blocks/data-grid-block/types.d.ts +3 -0
  18. package/dist/blocks/data-grid-block/types.d.ts.map +1 -1
  19. package/dist/blocks/index.js +80 -255
  20. package/dist/blocks/index.js.map +1 -1
  21. package/dist/chunk-2AB7VGPW.js +447 -0
  22. package/dist/chunk-2AB7VGPW.js.map +1 -0
  23. package/dist/{chunk-LOY2NPCO.js → chunk-2E67PQ4T.js} +3 -3
  24. package/dist/{chunk-LOY2NPCO.js.map → chunk-2E67PQ4T.js.map} +1 -1
  25. package/dist/chunk-2KG2NI73.js +84 -0
  26. package/dist/chunk-2KG2NI73.js.map +1 -0
  27. package/dist/chunk-2UYRW6X3.js +44 -0
  28. package/dist/chunk-2UYRW6X3.js.map +1 -0
  29. package/dist/chunk-36C5H56C.js +208 -0
  30. package/dist/chunk-36C5H56C.js.map +1 -0
  31. package/dist/chunk-36FOXX25.js +73 -0
  32. package/dist/chunk-36FOXX25.js.map +1 -0
  33. package/dist/{chunk-52PQL67Q.js → chunk-3VSM7NZG.js} +18 -15
  34. package/dist/chunk-3VSM7NZG.js.map +1 -0
  35. package/dist/{chunk-GUGTDURV.js → chunk-4B2LTPK2.js} +2 -2
  36. package/dist/{chunk-GUGTDURV.js.map → chunk-4B2LTPK2.js.map} +1 -1
  37. package/dist/chunk-4HUGZJKU.js +108 -0
  38. package/dist/chunk-4HUGZJKU.js.map +1 -0
  39. package/dist/{chunk-PXXPLHIY.js → chunk-4Q5L7LDG.js} +3 -3
  40. package/dist/{chunk-PXXPLHIY.js.map → chunk-4Q5L7LDG.js.map} +1 -1
  41. package/dist/{chunk-BRDWQVRT.js → chunk-4R7EZ7GQ.js} +3 -2
  42. package/dist/chunk-4R7EZ7GQ.js.map +1 -0
  43. package/dist/chunk-6IANOSMD.js +185 -0
  44. package/dist/chunk-6IANOSMD.js.map +1 -0
  45. package/dist/{chunk-YHE7HXSG.js → chunk-7ATBURW2.js} +3 -3
  46. package/dist/{chunk-YHE7HXSG.js.map → chunk-7ATBURW2.js.map} +1 -1
  47. package/dist/{chunk-7G5D5PTC.js → chunk-AATAOOSF.js} +4 -4
  48. package/dist/{chunk-7G5D5PTC.js.map → chunk-AATAOOSF.js.map} +1 -1
  49. package/dist/chunk-AKLRKCYH.js +128 -0
  50. package/dist/chunk-AKLRKCYH.js.map +1 -0
  51. package/dist/chunk-CT46KJOR.js +133 -0
  52. package/dist/chunk-CT46KJOR.js.map +1 -0
  53. package/dist/{chunk-LSPFFEJT.js → chunk-D4GFAJAZ.js} +298 -3900
  54. package/dist/chunk-D4GFAJAZ.js.map +1 -0
  55. package/dist/{chunk-BJE2AKD4.js → chunk-D5J3KW6Q.js} +3 -2
  56. package/dist/chunk-D5J3KW6Q.js.map +1 -0
  57. package/dist/chunk-DEPJRTVT.js +3 -0
  58. package/dist/{chunk-FU52GL2E.js.map → chunk-DEPJRTVT.js.map} +1 -1
  59. package/dist/{chunk-472SOF76.js → chunk-DHTYHUYI.js} +85 -107
  60. package/dist/chunk-DHTYHUYI.js.map +1 -0
  61. package/dist/{chunk-FF5RF32O.js → chunk-E7WM2RXA.js} +3 -2
  62. package/dist/chunk-E7WM2RXA.js.map +1 -0
  63. package/dist/chunk-F6RZ7LW6.js +1271 -0
  64. package/dist/chunk-F6RZ7LW6.js.map +1 -0
  65. package/dist/chunk-FOGY3HA4.js +217 -0
  66. package/dist/chunk-FOGY3HA4.js.map +1 -0
  67. package/dist/chunk-G2GANYMW.js +139 -0
  68. package/dist/chunk-G2GANYMW.js.map +1 -0
  69. package/dist/chunk-I6DILPFE.js +293 -0
  70. package/dist/chunk-I6DILPFE.js.map +1 -0
  71. package/dist/{chunk-HOXFSQUV.js → chunk-IRYU3NTG.js} +2 -2
  72. package/dist/{chunk-HOXFSQUV.js.map → chunk-IRYU3NTG.js.map} +1 -1
  73. package/dist/chunk-JTIUGPW5.js +284 -0
  74. package/dist/chunk-JTIUGPW5.js.map +1 -0
  75. package/dist/{chunk-GUFHFEPZ.js → chunk-JZBSPDED.js} +2 -2
  76. package/dist/{chunk-GUFHFEPZ.js.map → chunk-JZBSPDED.js.map} +1 -1
  77. package/dist/{chunk-PFT2BNYO.js → chunk-KPY7TA4D.js} +5 -5
  78. package/dist/{chunk-PFT2BNYO.js.map → chunk-KPY7TA4D.js.map} +1 -1
  79. package/dist/{chunk-GMIE6III.js → chunk-LFWKGNCX.js} +50 -623
  80. package/dist/chunk-LFWKGNCX.js.map +1 -0
  81. package/dist/chunk-LH4ZZZYB.js +37 -0
  82. package/dist/chunk-LH4ZZZYB.js.map +1 -0
  83. package/dist/chunk-NFJ7CPG3.js +13 -0
  84. package/dist/chunk-NFJ7CPG3.js.map +1 -0
  85. package/dist/chunk-NFPOIHD4.js +3 -0
  86. package/dist/{chunk-JSQTYDPG.js.map → chunk-NFPOIHD4.js.map} +1 -1
  87. package/dist/{chunk-XIXSSI3B.js → chunk-NJM5AVBM.js} +3 -2
  88. package/dist/chunk-NJM5AVBM.js.map +1 -0
  89. package/dist/{chunk-4Z5DE5GK.js → chunk-NSNM53WI.js} +133 -115
  90. package/dist/chunk-NSNM53WI.js.map +1 -0
  91. package/dist/chunk-NTREGTG7.js +31 -0
  92. package/dist/chunk-NTREGTG7.js.map +1 -0
  93. package/dist/{chunk-ADG4HZEP.js → chunk-OKJA6SJM.js} +4 -4
  94. package/dist/chunk-OKJA6SJM.js.map +1 -0
  95. package/dist/{chunk-SU3LVQ7N.js → chunk-Q6JDNFSG.js} +11 -226
  96. package/dist/chunk-Q6JDNFSG.js.map +1 -0
  97. package/dist/chunk-RPOGINR5.js +115 -0
  98. package/dist/chunk-RPOGINR5.js.map +1 -0
  99. package/dist/{chunk-KQ67XB6T.js → chunk-RSWVYIXK.js} +151 -114
  100. package/dist/chunk-RSWVYIXK.js.map +1 -0
  101. package/dist/chunk-SSEHL5VP.js +110 -0
  102. package/dist/chunk-SSEHL5VP.js.map +1 -0
  103. package/dist/chunk-TEIGUOWN.js +523 -0
  104. package/dist/chunk-TEIGUOWN.js.map +1 -0
  105. package/dist/{chunk-AYYFMTMI.js → chunk-TJ7DHXUX.js} +2 -2
  106. package/dist/{chunk-AYYFMTMI.js.map → chunk-TJ7DHXUX.js.map} +1 -1
  107. package/dist/{chunk-75FQ5IW3.js → chunk-TZHWYT34.js} +3 -3
  108. package/dist/{chunk-75FQ5IW3.js.map → chunk-TZHWYT34.js.map} +1 -1
  109. package/dist/chunk-TZWHELY4.js +45 -0
  110. package/dist/chunk-TZWHELY4.js.map +1 -0
  111. package/dist/{chunk-OKTLA23Q.js → chunk-UEINJFLS.js} +6 -6
  112. package/dist/chunk-UEINJFLS.js.map +1 -0
  113. package/dist/chunk-URFQX3I6.js +129 -0
  114. package/dist/chunk-URFQX3I6.js.map +1 -0
  115. package/dist/chunk-VG6FOMOH.js +187 -0
  116. package/dist/chunk-VG6FOMOH.js.map +1 -0
  117. package/dist/{chunk-PGHEP4JD.js → chunk-VQVVHMPG.js} +3 -3
  118. package/dist/{chunk-PGHEP4JD.js.map → chunk-VQVVHMPG.js.map} +1 -1
  119. package/dist/{chunk-DRFNMZLG.js → chunk-VUKOT432.js} +3 -2
  120. package/dist/chunk-VUKOT432.js.map +1 -0
  121. package/dist/chunk-WD4N72DL.js +315 -0
  122. package/dist/chunk-WD4N72DL.js.map +1 -0
  123. package/dist/chunk-XBYMG4QK.js +119 -0
  124. package/dist/chunk-XBYMG4QK.js.map +1 -0
  125. package/dist/chunk-YHM6GIHV.js +3 -0
  126. package/dist/chunk-YHM6GIHV.js.map +1 -0
  127. package/dist/{chunk-SNZK5X6F.js → chunk-Z2AN43YU.js} +4 -2
  128. package/dist/chunk-Z2AN43YU.js.map +1 -0
  129. package/dist/chunk-ZNWHMQRM.js +171 -0
  130. package/dist/chunk-ZNWHMQRM.js.map +1 -0
  131. package/dist/{chunk-YSIG2XYH.js → chunk-ZRJYQN6Y.js} +2 -2
  132. package/dist/{chunk-YSIG2XYH.js.map → chunk-ZRJYQN6Y.js.map} +1 -1
  133. package/dist/{chunk-AD4W7HYC.js → chunk-ZYI3MHLE.js} +3 -2
  134. package/dist/chunk-ZYI3MHLE.js.map +1 -0
  135. package/dist/cli/index.js +59 -421
  136. package/dist/cli/index.js.map +1 -1
  137. package/dist/components/admin-filters/admin-data-table.d.ts +7 -1
  138. package/dist/components/admin-filters/admin-data-table.d.ts.map +1 -1
  139. package/dist/components/admin-filters/filter-toolbar.d.ts.map +1 -1
  140. package/dist/components/admin-filters/index.js +8 -0
  141. package/dist/components/admin-filters/index.js.map +1 -0
  142. package/dist/components/alert/alert.d.ts.map +1 -1
  143. package/dist/components/alert/index.js +5 -0
  144. package/dist/components/alert/index.js.map +1 -0
  145. package/dist/components/animate/index.js +5 -0
  146. package/dist/components/animate/index.js.map +1 -0
  147. package/dist/components/breadcrumbs/breadcrumbs.d.ts.map +1 -1
  148. package/dist/components/breadcrumbs/index.js +4 -0
  149. package/dist/components/breadcrumbs/index.js.map +1 -0
  150. package/dist/components/card/index.js +4 -0
  151. package/dist/components/card/index.js.map +1 -0
  152. package/dist/components/chart/chart.d.ts.map +1 -1
  153. package/dist/components/chart/index.css +52 -0
  154. package/dist/components/chart/index.css.map +1 -0
  155. package/dist/components/chart/index.js +5 -0
  156. package/dist/components/chart/index.js.map +1 -0
  157. package/dist/components/chart/types.d.ts +3 -1
  158. package/dist/components/chart/types.d.ts.map +1 -1
  159. package/dist/components/chart/use-chart.d.ts.map +1 -1
  160. package/dist/components/command-palette/command-palette.d.ts +3 -1
  161. package/dist/components/command-palette/command-palette.d.ts.map +1 -1
  162. package/dist/components/command-palette/index.js +4 -0
  163. package/dist/components/command-palette/index.js.map +1 -0
  164. package/dist/components/confirm-dialog/index.js +4 -0
  165. package/dist/components/confirm-dialog/index.js.map +1 -0
  166. package/dist/components/date-input/date-input.d.ts +1 -0
  167. package/dist/components/date-input/date-input.d.ts.map +1 -1
  168. package/dist/components/date-input/index.d.ts +0 -1
  169. package/dist/components/date-input/index.d.ts.map +1 -1
  170. package/dist/components/doc-layout/index.js +5 -4
  171. package/dist/components/doc-layout/index.js.map +1 -1
  172. package/dist/components/editor/index.js +4 -3
  173. package/dist/components/editor/index.js.map +1 -1
  174. package/dist/components/emoji-picker/index.js +2 -1
  175. package/dist/components/emoji-picker/index.js.map +1 -1
  176. package/dist/components/empty-content/empty-content.d.ts.map +1 -1
  177. package/dist/components/empty-content/index.js +4 -0
  178. package/dist/components/empty-content/index.js.map +1 -0
  179. package/dist/components/error-boundary/index.js +6 -0
  180. package/dist/components/error-boundary/index.js.map +1 -0
  181. package/dist/components/index.css +13 -10
  182. package/dist/components/index.css.map +1 -1
  183. package/dist/components/index.d.ts +1 -0
  184. package/dist/components/index.d.ts.map +1 -1
  185. package/dist/components/index.js +47 -21
  186. package/dist/components/index.js.map +1 -1
  187. package/dist/components/knowledge-graph/edge-labels.d.ts.map +1 -1
  188. package/dist/components/knowledge-graph/index.js +18 -16
  189. package/dist/components/knowledge-graph/index.js.map +1 -1
  190. package/dist/components/label/index.js +5 -0
  191. package/dist/components/label/index.js.map +1 -0
  192. package/dist/components/label/label.d.ts.map +1 -1
  193. package/dist/components/loading-screen/index.js +4 -0
  194. package/dist/components/loading-screen/index.js.map +1 -0
  195. package/dist/components/map/MapPointPicker.d.ts.map +1 -1
  196. package/dist/components/map/index.js +2 -1
  197. package/dist/components/map/index.js.map +1 -1
  198. package/dist/components/navigation-progress/index.js +4 -0
  199. package/dist/components/navigation-progress/index.js.map +1 -0
  200. package/dist/components/page-content/index.js +4 -0
  201. package/dist/components/page-content/index.js.map +1 -0
  202. package/dist/components/popover/index.js +4 -0
  203. package/dist/components/popover/index.js.map +1 -0
  204. package/dist/components/research/diagram.d.ts.map +1 -1
  205. package/dist/components/research/index.js +6 -4
  206. package/dist/components/research/index.js.map +1 -1
  207. package/dist/components/research-editor/extensions.d.ts +1 -1
  208. package/dist/components/research-editor/index.js +11 -10
  209. package/dist/components/research-editor/index.js.map +1 -1
  210. package/dist/components/research-editor/math-navigation.d.ts +2 -2
  211. package/dist/components/research-editor/math-navigation.d.ts.map +1 -1
  212. package/dist/components/scroll-to-top/index.js +4 -0
  213. package/dist/components/scroll-to-top/index.js.map +1 -0
  214. package/dist/components/search-input/index.js +7 -0
  215. package/dist/components/search-input/index.js.map +1 -0
  216. package/dist/components/search-input/search-input.d.ts +3 -1
  217. package/dist/components/search-input/search-input.d.ts.map +1 -1
  218. package/dist/components/skeleton/index.js +4 -0
  219. package/dist/components/skeleton/index.js.map +1 -0
  220. package/dist/components/snackbar/index.js +6 -0
  221. package/dist/components/snackbar/index.js.map +1 -0
  222. package/dist/components/stepper/index.js +4 -0
  223. package/dist/components/stepper/index.js.map +1 -0
  224. package/dist/components/table/index.d.ts +1 -0
  225. package/dist/components/table/index.d.ts.map +1 -1
  226. package/dist/components/table/index.js +5 -0
  227. package/dist/components/table/index.js.map +1 -0
  228. package/dist/components/table/table-viewport.d.ts +13 -0
  229. package/dist/components/table/table-viewport.d.ts.map +1 -0
  230. package/dist/components/table/table.d.ts +3 -1
  231. package/dist/components/table/table.d.ts.map +1 -1
  232. package/dist/components/tabs/index.js +6 -0
  233. package/dist/components/tabs/index.js.map +1 -0
  234. package/dist/components/tabs/tabs.d.ts +12 -1
  235. package/dist/components/tabs/tabs.d.ts.map +1 -1
  236. package/dist/core/index.js +12 -10
  237. package/dist/core/index.js.map +1 -1
  238. package/dist/forms/index.js +2 -0
  239. package/dist/forms/index.js.map +1 -1
  240. package/dist/hooks/index.js +14 -12
  241. package/dist/hooks/index.js.map +1 -1
  242. package/dist/hooks/use-config-from-query.d.ts +2 -0
  243. package/dist/hooks/use-config-from-query.d.ts.map +1 -1
  244. package/dist/hooks/use-image-dimensions.d.ts.map +1 -1
  245. package/dist/hooks/use-keyboard-shortcut.d.ts.map +1 -1
  246. package/dist/hooks/use-scroll-position.d.ts.map +1 -1
  247. package/dist/hooks/use-window-size.d.ts.map +1 -1
  248. package/dist/icons/context.d.ts.map +1 -1
  249. package/dist/icons/index.js +3 -2
  250. package/dist/icons/index.js.map +1 -1
  251. package/dist/index.css +13 -10
  252. package/dist/index.css.map +1 -1
  253. package/dist/index.js +57 -31
  254. package/dist/index.js.map +1 -1
  255. package/dist/internal/research-parser.js +3 -0
  256. package/dist/internal/research-parser.js.map +1 -0
  257. package/dist/layouts/core/header-section.d.ts +1 -0
  258. package/dist/layouts/core/header-section.d.ts.map +1 -1
  259. package/dist/layouts/dashboard/layout.d.ts +3 -1
  260. package/dist/layouts/dashboard/layout.d.ts.map +1 -1
  261. package/dist/layouts/dashboard/sidenav.d.ts.map +1 -1
  262. package/dist/layouts/index.js +9 -8
  263. package/dist/layouts/index.js.map +1 -1
  264. package/dist/netron/index.js +2 -1
  265. package/dist/netron/index.js.map +1 -1
  266. package/dist/registry/index.js +1 -1
  267. package/dist/state/create-store.d.ts.map +1 -1
  268. package/dist/state/index.js +3 -2
  269. package/dist/state/index.js.map +1 -1
  270. package/dist/state/settings-version.d.ts.map +1 -1
  271. package/dist/theme/components/Chip.d.ts.map +1 -1
  272. package/dist/theme/components/Dialog.d.ts.map +1 -1
  273. package/dist/theme/components/TextField.d.ts.map +1 -1
  274. package/dist/theme/components/index.d.ts.map +1 -1
  275. package/dist/theme/components/theme-utils.d.ts +2 -2
  276. package/dist/theme/components/theme-utils.d.ts.map +1 -1
  277. package/dist/theme/index.js +8 -6
  278. package/dist/theme/index.js.map +1 -1
  279. package/dist/theme/palette/overrides.d.ts +1 -0
  280. package/dist/theme/palette/overrides.d.ts.map +1 -1
  281. package/dist/theme/semantic-surface.d.ts +8 -0
  282. package/dist/theme/semantic-surface.d.ts.map +1 -0
  283. package/dist/types/index.js +2 -2
  284. package/dist/ui/index.js +6 -5
  285. package/dist/ui/index.js.map +1 -1
  286. package/dist/utils/async-lock.d.ts.map +1 -1
  287. package/package.json +143 -37
  288. package/dist/chunk-472SOF76.js.map +0 -1
  289. package/dist/chunk-4Z5DE5GK.js.map +0 -1
  290. package/dist/chunk-52PQL67Q.js.map +0 -1
  291. package/dist/chunk-AD4W7HYC.js.map +0 -1
  292. package/dist/chunk-ADG4HZEP.js.map +0 -1
  293. package/dist/chunk-BJE2AKD4.js.map +0 -1
  294. package/dist/chunk-BRDWQVRT.js.map +0 -1
  295. package/dist/chunk-DRFNMZLG.js.map +0 -1
  296. package/dist/chunk-FF5RF32O.js.map +0 -1
  297. package/dist/chunk-FU52GL2E.js +0 -3
  298. package/dist/chunk-GMIE6III.js.map +0 -1
  299. package/dist/chunk-JSQTYDPG.js +0 -3
  300. package/dist/chunk-KQ67XB6T.js.map +0 -1
  301. package/dist/chunk-LSPFFEJT.js.map +0 -1
  302. package/dist/chunk-OKTLA23Q.js.map +0 -1
  303. package/dist/chunk-SNZK5X6F.js.map +0 -1
  304. package/dist/chunk-SU3LVQ7N.js.map +0 -1
  305. package/dist/chunk-XIXSSI3B.js.map +0 -1
@@ -0,0 +1,84 @@
1
+ import TableContainer from '@mui/material/TableContainer';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
4
+ // src/components/table/table-viewport.tsx
5
+ var rowControls = 'input,textarea,select,button,a,[contenteditable="true"],[role="button"],[role="checkbox"]';
6
+ function isRowActionTarget(target) {
7
+ return target instanceof Element && !target.closest(rowControls);
8
+ }
9
+ function browseRows(event) {
10
+ if (event.defaultPrevented || event.nativeEvent.isComposing || event.ctrlKey || event.metaKey || event.altKey) return;
11
+ const target = event.target;
12
+ if (!isRowActionTarget(target)) return;
13
+ const viewport = event.currentTarget;
14
+ const rows = Array.from(viewport.querySelectorAll("tbody > tr")).filter(
15
+ (row2) => !row2.querySelector('[role="progressbar"],.MuiSkeleton-root')
16
+ );
17
+ const row = target.closest("tbody > tr");
18
+ const index = row ? rows.indexOf(row) : -1;
19
+ const page = Math.max(1, Math.floor(viewport.clientHeight / (row?.getBoundingClientRect().height || 40)) || 10);
20
+ const movement = {
21
+ ArrowDown: index + 1,
22
+ ArrowUp: index < 0 ? rows.length - 1 : index - 1,
23
+ Home: 0,
24
+ End: rows.length - 1,
25
+ PageDown: index + page,
26
+ PageUp: index - page
27
+ };
28
+ if (event.key in movement && rows.length) {
29
+ event.preventDefault();
30
+ const next = rows[Math.max(0, Math.min(rows.length - 1, movement[event.key]))];
31
+ next.tabIndex = -1;
32
+ next.focus({ preventScroll: true });
33
+ next.scrollIntoView?.({ block: "nearest" });
34
+ } else if (event.key === "Escape" && row) {
35
+ event.preventDefault();
36
+ event.stopPropagation();
37
+ viewport.focus({ preventScroll: true });
38
+ } else if (row && (event.key === "Enter" || event.key === " ")) {
39
+ const selection = event.key === " " ? row.querySelector('input[type="checkbox"]:not(:disabled)') : null;
40
+ if (selection || event.key === "Enter" || row.hasAttribute("data-row-action")) {
41
+ event.preventDefault();
42
+ (selection ?? row).click();
43
+ }
44
+ }
45
+ }
46
+ function TableViewport({
47
+ label = "Table",
48
+ maxHeight,
49
+ keyboardNavigation = true,
50
+ onKeyDown,
51
+ sx,
52
+ ...props
53
+ }) {
54
+ return /* @__PURE__ */ jsx(
55
+ TableContainer,
56
+ {
57
+ role: "region",
58
+ "aria-label": label,
59
+ tabIndex: 0,
60
+ "data-keyboard-region": keyboardNavigation ? label : void 0,
61
+ onKeyDown: (event) => {
62
+ onKeyDown?.(event);
63
+ if (keyboardNavigation) browseRows(event);
64
+ },
65
+ ...props,
66
+ sx: [
67
+ {
68
+ minWidth: 0,
69
+ maxWidth: "100%",
70
+ maxHeight,
71
+ overflow: "auto",
72
+ overscrollBehaviorX: "contain",
73
+ "&:focus-visible": { outline: "2px solid", outlineColor: "primary.main", outlineOffset: -2 },
74
+ "& tbody > tr:focus-visible": { outline: "2px solid", outlineColor: "primary.main", outlineOffset: -2 }
75
+ },
76
+ ...Array.isArray(sx) ? sx : [sx]
77
+ ]
78
+ }
79
+ );
80
+ }
81
+
82
+ export { TableViewport, isRowActionTarget };
83
+ //# sourceMappingURL=chunk-2KG2NI73.js.map
84
+ //# sourceMappingURL=chunk-2KG2NI73.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/table/table-viewport.tsx"],"names":["row"],"mappings":"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","file":"chunk-2KG2NI73.js","sourcesContent":["'use client';\n\nimport TableContainer from '@mui/material/TableContainer';\nimport type { TableContainerProps } from '@mui/material/TableContainer';\nimport type { KeyboardEvent } from 'react';\n\nexport interface TableViewportProps extends TableContainerProps {\n /** Accessible name of the keyboard-scrollable table region. */\n label?: string;\n /** Constrain the rows, keeping pagination outside the scroll region. */\n maxHeight?: number | string;\n /** Arrow/Home/End/Page keys browse rows; Escape returns to the viewport. */\n keyboardNavigation?: boolean;\n}\n\nconst rowControls = 'input,textarea,select,button,a,[contenteditable=\"true\"],[role=\"button\"],[role=\"checkbox\"]';\n\nexport function isRowActionTarget(target: EventTarget) {\n return target instanceof Element && !target.closest(rowControls);\n}\n\nfunction browseRows(event: KeyboardEvent<HTMLDivElement>): void {\n if (event.defaultPrevented || event.nativeEvent.isComposing || event.ctrlKey || event.metaKey || event.altKey) return;\n const target = event.target as HTMLElement;\n if (!isRowActionTarget(target)) return;\n const viewport = event.currentTarget;\n const rows = Array.from(viewport.querySelectorAll<HTMLElement>('tbody > tr')).filter(\n (row) => !row.querySelector('[role=\"progressbar\"],.MuiSkeleton-root')\n );\n const row = target.closest('tbody > tr') as HTMLElement | null;\n const index = row ? rows.indexOf(row) : -1;\n const page = Math.max(1, Math.floor(viewport.clientHeight / (row?.getBoundingClientRect().height || 40)) || 10);\n const movement: Record<string, number> = {\n ArrowDown: index + 1,\n ArrowUp: index < 0 ? rows.length - 1 : index - 1,\n Home: 0,\n End: rows.length - 1,\n PageDown: index + page,\n PageUp: index - page,\n };\n if (event.key in movement && rows.length) {\n event.preventDefault();\n const next = rows[Math.max(0, Math.min(rows.length - 1, movement[event.key]!))]!;\n next.tabIndex = -1;\n next.focus({ preventScroll: true });\n next.scrollIntoView?.({ block: 'nearest' });\n } else if (event.key === 'Escape' && row) {\n event.preventDefault();\n event.stopPropagation();\n viewport.focus({ preventScroll: true });\n } else if (row && (event.key === 'Enter' || event.key === ' ')) {\n const selection = event.key === ' ' ? row.querySelector<HTMLInputElement>('input[type=\"checkbox\"]:not(:disabled)') : null;\n if (selection || event.key === 'Enter' || row.hasAttribute('data-row-action')) {\n event.preventDefault();\n (selection ?? row).click();\n }\n }\n}\n\n/** A bounded, keyboard-accessible viewport for wide or tall native MUI tables. */\nexport function TableViewport({\n label = 'Table',\n maxHeight,\n keyboardNavigation = true,\n onKeyDown,\n sx,\n ...props\n}: TableViewportProps) {\n return (\n <TableContainer\n role=\"region\"\n aria-label={label}\n tabIndex={0}\n data-keyboard-region={keyboardNavigation ? label : undefined}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (keyboardNavigation) browseRows(event);\n }}\n {...props}\n sx={[\n {\n minWidth: 0,\n maxWidth: '100%',\n maxHeight,\n overflow: 'auto',\n overscrollBehaviorX: 'contain',\n '&:focus-visible': { outline: '2px solid', outlineColor: 'primary.main', outlineOffset: -2 },\n '& tbody > tr:focus-visible': { outline: '2px solid', outlineColor: 'primary.main', outlineOffset: -2 },\n },\n ...(Array.isArray(sx) ? sx : [sx]),\n ]}\n />\n );\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import { Children } from 'react';
2
+ import Stack from '@mui/material/Stack';
3
+ import Grid from '@mui/material/Grid';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ // src/components/page-content/page-content.tsx
7
+ var PAGE_GAP = 3;
8
+ var GRID_GAP = 3;
9
+ function PageContent({
10
+ children,
11
+ gap = PAGE_GAP,
12
+ fill,
13
+ sx,
14
+ ref,
15
+ ...rest
16
+ }) {
17
+ return /* @__PURE__ */ jsx(
18
+ Stack,
19
+ {
20
+ ref,
21
+ spacing: gap,
22
+ sx: { ...fill && { flex: 1 }, ...sx },
23
+ ...rest,
24
+ children
25
+ }
26
+ );
27
+ }
28
+ var COLUMN_SIZE = {
29
+ 1: { xs: 12, md: 12 },
30
+ 2: { xs: 12, md: 6 },
31
+ 3: { xs: 12, sm: 6, md: 4 },
32
+ 4: { xs: 12, sm: 6, md: 3 }
33
+ };
34
+ function CardGrid({ children, columns = 2, gap = GRID_GAP, sx }) {
35
+ const size = COLUMN_SIZE[columns] ?? COLUMN_SIZE[2];
36
+ return /* @__PURE__ */ jsx(Grid, { container: true, spacing: gap, sx, children: Children.map(
37
+ children,
38
+ (child) => child != null ? /* @__PURE__ */ jsx(Grid, { size, sx: { display: "flex" }, children: child }) : null
39
+ ) });
40
+ }
41
+
42
+ export { CardGrid, PageContent };
43
+ //# sourceMappingURL=chunk-2UYRW6X3.js.map
44
+ //# sourceMappingURL=chunk-2UYRW6X3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/page-content/page-content.tsx"],"names":[],"mappings":";;;;;;AAgCA,IAAM,QAAA,GAAW,CAAA;AAGjB,IAAM,QAAA,GAAW,CAAA;AAqBV,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,GAAA,GAAM,QAAA;AAAA,EACN,IAAA;AAAA,EACA,EAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAqD;AACnD,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,OAAA,EAAS,GAAA;AAAA,MACT,EAAA,EAAI,EAAE,GAAI,IAAA,IAAQ,EAAE,IAAA,EAAM,CAAA,EAAE,EAAI,GAAG,EAAA,EAAU;AAAA,MAC5C,GAAG,IAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAeA,IAAM,WAAA,GAAuE;AAAA,EAC3E,CAAA,EAAG,EAAE,EAAA,EAAI,EAAA,EAAI,IAAI,EAAA,EAAG;AAAA,EACpB,CAAA,EAAG,EAAE,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,EAAE;AAAA,EACnB,GAAG,EAAE,EAAA,EAAI,IAAI,EAAA,EAAI,CAAA,EAAG,IAAI,CAAA,EAAE;AAAA,EAC1B,GAAG,EAAE,EAAA,EAAI,IAAI,EAAA,EAAI,CAAA,EAAG,IAAI,CAAA;AAC1B,CAAA;AAUO,SAAS,QAAA,CAAS,EAAE,QAAA,EAAU,OAAA,GAAU,GAAG,GAAA,GAAM,QAAA,EAAU,IAAG,EAAkB;AACrF,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,OAAO,CAAA,IAAK,YAAY,CAAC,CAAA;AAElD,EAAA,2BACG,IAAA,EAAA,EAAK,SAAA,EAAS,MAAC,OAAA,EAAS,GAAA,EAAK,IAC3B,QAAA,EAAA,QAAA,CAAS,GAAA;AAAA,IAAI,QAAA;AAAA,IAAU,CAAC,KAAA,KACvB,KAAA,IAAS,IAAA,mBACP,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAY,EAAA,EAAI,EAAE,OAAA,EAAS,MAAA,EAAO,EACrC,iBACH,CAAA,GACE;AAAA,GACN,EACF,CAAA;AAEJ","file":"chunk-2UYRW6X3.js","sourcesContent":["'use client';\n\n/**\n * PageContent — Unified page layout primitives\n *\n * Provides consistent spacing across all pages:\n * - PageContent: vertical stack with standardized gap\n * - PageContent.CardGrid: responsive grid for cards with equal height\n *\n * @example\n * <PageContent>\n * <Breadcrumbs ... />\n * <PageContent.CardGrid columns={2}>\n * <Card>...</Card>\n * <Card>...</Card>\n * </PageContent.CardGrid>\n * </PageContent>\n *\n * @module components/page-content\n */\n\nimport type { ReactNode, Ref } from 'react';\nimport { Children } from 'react';\nimport Stack from '@mui/material/Stack';\nimport Grid from '@mui/material/Grid';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/** Default spacing between top-level page sections (theme spacing units) */\nconst PAGE_GAP = 3;\n\n/** Default spacing between grid items (theme spacing units) */\nconst GRID_GAP = 3;\n\n// =============================================================================\n// PageContent\n// =============================================================================\n\nexport interface PageContentProps {\n children: ReactNode;\n /** Override gap between sections. Default: 3 (24px). */\n gap?: number;\n /** Stretch to fill available height (for centered empty states). */\n fill?: boolean;\n sx?: SxProps<Theme>;\n}\n\n/**\n * Page-level vertical layout with consistent spacing.\n *\n * Wraps children in a `Stack` with standardized gap.\n * Use `fill` to stretch for empty-state centering.\n */\nexport function PageContent({\n children,\n gap = PAGE_GAP,\n fill,\n sx,\n ref,\n ...rest\n}: PageContentProps & { ref?: Ref<HTMLDivElement> }) {\n return (\n <Stack\n ref={ref}\n spacing={gap}\n sx={{ ...(fill && { flex: 1 }), ...sx as any }}\n {...rest}\n >\n {children}\n </Stack>\n );\n}\n\n// =============================================================================\n// CardGrid\n// =============================================================================\n\nexport interface CardGridProps {\n children: ReactNode;\n /** Number of columns at `md` breakpoint. Default: 2. */\n columns?: 1 | 2 | 3 | 4;\n /** Override gap between cards. Default: 3 (24px). */\n gap?: number;\n sx?: SxProps<Theme>;\n}\n\nconst COLUMN_SIZE: Record<number, { xs: number; sm?: number; md: number }> = {\n 1: { xs: 12, md: 12 },\n 2: { xs: 12, md: 6 },\n 3: { xs: 12, sm: 6, md: 4 },\n 4: { xs: 12, sm: 6, md: 3 },\n};\n\n/**\n * Responsive card grid with equal-height items.\n *\n * Each direct child is wrapped in a Grid cell sized by `columns`.\n * Cards should use `height: '100%'` or be wrapped in a full-height container.\n * (MUI v9 unified Grid — sizing is via `size={{ xs, sm, md, ... }}` rather\n * than the deprecated `<Grid item>` shorthand from v1.)\n */\nexport function CardGrid({ children, columns = 2, gap = GRID_GAP, sx }: CardGridProps) {\n const size = COLUMN_SIZE[columns] ?? COLUMN_SIZE[2];\n\n return (\n <Grid container spacing={gap} sx={sx}>\n {Children.map(children, (child) =>\n child != null ? (\n <Grid size={size} sx={{ display: 'flex' }}>\n {child}\n </Grid>\n ) : null,\n )}\n </Grid>\n );\n}\n"]}
@@ -0,0 +1,208 @@
1
+ import { createClasses } from './chunk-LH4ZZZYB.js';
2
+ import { useRef, useState, useEffect } from 'react';
3
+ import { LazyMotion, domMax, useMotionValue, useAnimationFrame, useTransform, useMotionTemplate, m } from 'framer-motion';
4
+ import Box from '@mui/material/Box';
5
+ import { useTheme } from '@mui/material/styles';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ var animateBorderClasses = {
9
+ root: createClasses("animate__border__root"),
10
+ primaryBorder: createClasses("animate__border__primary"),
11
+ secondaryBorder: createClasses("animate__border__secondary"),
12
+ svgWrapper: createClasses("animate__border__svg__wrapper"),
13
+ movingShape: createClasses("animate__border__moving__shape")
14
+ };
15
+ function borderGradient(props) {
16
+ const { color, padding = "2px" } = props ?? {};
17
+ return {
18
+ padding,
19
+ inset: 0,
20
+ width: "100%",
21
+ content: '""',
22
+ height: "100%",
23
+ margin: "auto",
24
+ position: "absolute",
25
+ borderRadius: "inherit",
26
+ mask: "linear-gradient(#FFF 0 0) content-box, linear-gradient(#FFF 0 0)",
27
+ WebkitMask: "linear-gradient(#FFF 0 0) content-box, linear-gradient(#FFF 0 0)",
28
+ maskComposite: "exclude",
29
+ WebkitMaskComposite: "xor",
30
+ ...color && { background: color }
31
+ };
32
+ }
33
+ function AnimateBorder({ sx, children, duration, slotProps, className, ...other }) {
34
+ const theme = useTheme();
35
+ const rootRef = useRef(null);
36
+ const primaryBorderRef = useRef(null);
37
+ const [isHidden, setIsHidden] = useState(false);
38
+ const secondaryBorderStyles = useComputedElementStyles(theme, primaryBorderRef);
39
+ useEffect(() => {
40
+ const handleVisibility = () => {
41
+ if (rootRef.current) {
42
+ const displayStyle = getComputedStyle(rootRef.current).display;
43
+ setIsHidden(displayStyle === "none");
44
+ }
45
+ };
46
+ handleVisibility();
47
+ window.addEventListener("resize", handleVisibility);
48
+ return () => {
49
+ window.removeEventListener("resize", handleVisibility);
50
+ };
51
+ }, []);
52
+ const outlineColor = typeof slotProps?.outlineColor === "function" ? slotProps?.outlineColor(theme) : slotProps?.outlineColor;
53
+ const borderProps = {
54
+ duration,
55
+ isHidden,
56
+ rx: slotProps?.svgSettings?.rx,
57
+ ry: slotProps?.svgSettings?.ry
58
+ };
59
+ const renderPrimaryBorder = () => /* @__PURE__ */ jsx(
60
+ MovingBorder,
61
+ {
62
+ ...borderProps,
63
+ ref: primaryBorderRef,
64
+ size: slotProps?.primaryBorder?.size,
65
+ sx: [
66
+ {
67
+ ...borderGradient({ padding: slotProps?.primaryBorder?.width })
68
+ },
69
+ ...Array.isArray(slotProps?.primaryBorder?.sx) ? slotProps.primaryBorder.sx : [slotProps?.primaryBorder?.sx]
70
+ ]
71
+ }
72
+ );
73
+ const renderSecondaryBorder = () => slotProps?.secondaryBorder && /* @__PURE__ */ jsx(
74
+ MovingBorder,
75
+ {
76
+ ...borderProps,
77
+ size: slotProps?.secondaryBorder?.size ?? slotProps?.primaryBorder?.size,
78
+ sx: [
79
+ {
80
+ ...borderGradient({
81
+ padding: slotProps?.secondaryBorder?.width ?? secondaryBorderStyles.padding
82
+ }),
83
+ borderRadius: secondaryBorderStyles.borderRadius,
84
+ transform: "scale(-1, -1)"
85
+ },
86
+ ...Array.isArray(slotProps?.secondaryBorder?.sx) ? slotProps.secondaryBorder.sx : [slotProps?.secondaryBorder?.sx]
87
+ ]
88
+ }
89
+ );
90
+ return /* @__PURE__ */ jsxs(
91
+ Box,
92
+ {
93
+ dir: "ltr",
94
+ ref: rootRef,
95
+ className: [animateBorderClasses.root, className].filter(Boolean).join(" "),
96
+ sx: [
97
+ {
98
+ minWidth: 40,
99
+ minHeight: 40,
100
+ overflow: "hidden",
101
+ position: "relative",
102
+ width: "fit-content",
103
+ "&::before": borderGradient({
104
+ color: outlineColor,
105
+ padding: slotProps?.primaryBorder?.width
106
+ }),
107
+ ...!!children && {
108
+ minWidth: "unset",
109
+ minHeight: "unset"
110
+ }
111
+ },
112
+ ...Array.isArray(sx) ? sx : [sx]
113
+ ],
114
+ ...other,
115
+ children: [
116
+ renderPrimaryBorder(),
117
+ renderSecondaryBorder(),
118
+ children
119
+ ]
120
+ }
121
+ );
122
+ }
123
+ function MovingBorder({ sx, size, isHidden, rx = "30%", ry = "30%", duration = 8, ...other }) {
124
+ const svgRectRef = useRef(null);
125
+ const progress = useMotionValue(0);
126
+ const updateAnimationFrame = (time) => {
127
+ if (!svgRectRef.current) return;
128
+ try {
129
+ const pathLength = svgRectRef.current.getTotalLength();
130
+ const pixelsPerMs = pathLength / (duration * 1e3);
131
+ progress.set(time * pixelsPerMs % pathLength);
132
+ } catch {
133
+ return;
134
+ }
135
+ };
136
+ const calculateTransform = (val) => {
137
+ if (!svgRectRef.current) return { x: 0, y: 0 };
138
+ try {
139
+ const point = svgRectRef.current.getPointAtLength(val);
140
+ return point ? { x: point.x, y: point.y } : { x: 0, y: 0 };
141
+ } catch {
142
+ return { x: 0, y: 0 };
143
+ }
144
+ };
145
+ useAnimationFrame((time) => !isHidden ? updateAnimationFrame(time) : void 0);
146
+ const x = useTransform(progress, (val) => calculateTransform(val).x);
147
+ const y = useTransform(progress, (val) => calculateTransform(val).y);
148
+ const transform = useMotionTemplate`translateX(${x}px) translateY(${y}px) translateX(-50%) translateY(-50%)`;
149
+ return /* @__PURE__ */ jsxs(Box, { component: "span", sx: [{ textAlign: "initial" }, ...Array.isArray(sx) ? sx : [sx]], ...other, children: [
150
+ /* @__PURE__ */ jsx(
151
+ "svg",
152
+ {
153
+ xmlns: "http://www.w3.org/2000/svg",
154
+ preserveAspectRatio: "none",
155
+ width: "100%",
156
+ height: "100%",
157
+ className: animateBorderClasses.svgWrapper,
158
+ style: { position: "absolute" },
159
+ children: /* @__PURE__ */ jsx("rect", { ref: svgRectRef, fill: "none", width: "100%", height: "100%", rx, ry })
160
+ }
161
+ ),
162
+ /* @__PURE__ */ jsx(
163
+ Box,
164
+ {
165
+ component: m.span,
166
+ style: { transform },
167
+ className: animateBorderClasses.movingShape,
168
+ sx: {
169
+ width: size,
170
+ height: size,
171
+ filter: "blur(8px)",
172
+ position: "absolute",
173
+ background: "radial-gradient(currentColor 40%, transparent 80%)"
174
+ }
175
+ }
176
+ )
177
+ ] });
178
+ }
179
+ function useComputedElementStyles(theme, ref) {
180
+ const [computedStyles, setComputedStyles] = useState(null);
181
+ const isRtl = theme.direction === "rtl";
182
+ useEffect(() => {
183
+ if (ref.current) {
184
+ const style = getComputedStyle(ref.current);
185
+ setComputedStyles({
186
+ paddingTop: style.paddingBottom,
187
+ paddingBottom: style.paddingTop,
188
+ paddingLeft: isRtl ? style.paddingLeft : style.paddingRight,
189
+ paddingRight: isRtl ? style.paddingRight : style.paddingLeft,
190
+ borderTopLeftRadius: isRtl ? style.borderBottomLeftRadius : style.borderBottomRightRadius,
191
+ borderTopRightRadius: isRtl ? style.borderBottomRightRadius : style.borderBottomLeftRadius,
192
+ borderBottomLeftRadius: isRtl ? style.borderTopLeftRadius : style.borderTopRightRadius,
193
+ borderBottomRightRadius: isRtl ? style.borderTopRightRadius : style.borderTopLeftRadius
194
+ });
195
+ }
196
+ }, [ref, isRtl]);
197
+ return {
198
+ padding: `${computedStyles?.paddingTop} ${computedStyles?.paddingRight} ${computedStyles?.paddingBottom} ${computedStyles?.paddingLeft}`,
199
+ borderRadius: `${computedStyles?.borderTopLeftRadius} ${computedStyles?.borderTopRightRadius} ${computedStyles?.borderBottomRightRadius} ${computedStyles?.borderBottomLeftRadius}`
200
+ };
201
+ }
202
+ function MotionLazy({ children }) {
203
+ return /* @__PURE__ */ jsx(LazyMotion, { strict: true, features: domMax, children });
204
+ }
205
+
206
+ export { AnimateBorder, MotionLazy, animateBorderClasses };
207
+ //# sourceMappingURL=chunk-36C5H56C.js.map
208
+ //# sourceMappingURL=chunk-36C5H56C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/animate/animate-border.tsx","../src/components/animate/motion-lazy.tsx"],"names":["jsx"],"mappings":";;;;;;;AAaO,IAAM,oBAAA,GAAuB;AAAA,EAClC,IAAA,EAAM,cAAc,uBAAuB,CAAA;AAAA,EAC3C,aAAA,EAAe,cAAc,0BAA0B,CAAA;AAAA,EACvD,eAAA,EAAiB,cAAc,4BAA4B,CAAA;AAAA,EAC3D,UAAA,EAAY,cAAc,+BAA+B,CAAA;AAAA,EACzD,WAAA,EAAa,cAAc,gCAAgC;AAC7D;AASA,SAAS,eAAe,KAAA,EAAyD;AAC/E,EAAA,MAAM,EAAE,KAAA,EAAO,OAAA,GAAU,KAAA,EAAM,GAAI,SAAS,EAAC;AAE7C,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,KAAA,EAAO,CAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,OAAA,EAAS,IAAA;AAAA,IACT,MAAA,EAAQ,MAAA;AAAA,IACR,MAAA,EAAQ,MAAA;AAAA,IACR,QAAA,EAAU,UAAA;AAAA,IACV,YAAA,EAAc,SAAA;AAAA,IACd,IAAA,EAAM,kEAAA;AAAA,IACN,UAAA,EAAY,kEAAA;AAAA,IACZ,aAAA,EAAe,SAAA;AAAA,IACf,mBAAA,EAAqB,KAAA;AAAA,IACrB,GAAI,KAAA,IAAS,EAAE,UAAA,EAAY,KAAA;AAAM,GACnC;AACF;AA6BO,SAAS,aAAA,CAAc,EAAE,EAAA,EAAI,QAAA,EAAU,UAAU,SAAA,EAAW,SAAA,EAAW,GAAG,KAAA,EAAM,EAAuB;AAC5G,EAAA,MAAM,QAAQ,QAAA,EAAS;AAEvB,EAAA,MAAM,OAAA,GAAU,OAAuB,IAAI,CAAA;AAC3C,EAAA,MAAM,gBAAA,GAAmB,OAAwB,IAAI,CAAA;AAErD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAE9C,EAAA,MAAM,qBAAA,GAAwB,wBAAA,CAAyB,KAAA,EAAO,gBAAgB,CAAA;AAE9E,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,mBAAmB,MAAM;AAC7B,MAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,QAAA,MAAM,YAAA,GAAe,gBAAA,CAAiB,OAAA,CAAQ,OAAO,CAAA,CAAE,OAAA;AACvD,QAAA,WAAA,CAAY,iBAAiB,MAAM,CAAA;AAAA,MACrC;AAAA,IACF,CAAA;AAEA,IAAA,gBAAA,EAAiB;AAEjB,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,gBAAgB,CAAA;AAElD,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,UAAU,gBAAgB,CAAA;AAAA,IACvD,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,YAAA,GACJ,OAAO,SAAA,EAAW,YAAA,KAAiB,aAAa,SAAA,EAAW,YAAA,CAAa,KAAK,CAAA,GAAI,SAAA,EAAW,YAAA;AAE9F,EAAA,MAAM,WAAA,GAAc;AAAA,IAClB,QAAA;AAAA,IACA,QAAA;AAAA,IACA,EAAA,EAAI,WAAW,WAAA,EAAa,EAAA;AAAA,IAC5B,EAAA,EAAI,WAAW,WAAA,EAAa;AAAA,GAC9B;AAEA,EAAA,MAAM,sBAAsB,sBAC1B,GAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACE,GAAG,WAAA;AAAA,MACJ,GAAA,EAAK,gBAAA;AAAA,MACL,IAAA,EAAM,WAAW,aAAA,EAAe,IAAA;AAAA,MAChC,EAAA,EAAI;AAAA,QACF;AAAA,UACE,GAAG,cAAA,CAAe,EAAE,SAAS,SAAA,EAAW,aAAA,EAAe,OAAO;AAAA,SAChE;AAAA,QACA,GAAI,KAAA,CAAM,OAAA,CAAQ,SAAA,EAAW,aAAA,EAAe,EAAE,CAAA,GACzC,SAAA,CAAW,aAAA,CAAe,EAAA,GAC3B,CAAC,SAAA,EAAW,eAAe,EAAE;AAAA;AACnC;AAAA,GACF;AAGF,EAAA,MAAM,qBAAA,GAAwB,MAC5B,SAAA,EAAW,eAAA,oBACT,GAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACE,GAAG,WAAA;AAAA,MACJ,IAAA,EAAM,SAAA,EAAW,eAAA,EAAiB,IAAA,IAAQ,WAAW,aAAA,EAAe,IAAA;AAAA,MACpE,EAAA,EAAI;AAAA,QACF;AAAA,UACE,GAAG,cAAA,CAAe;AAAA,YAChB,OAAA,EAAS,SAAA,EAAW,eAAA,EAAiB,KAAA,IAAS,qBAAA,CAAsB;AAAA,WACrE,CAAA;AAAA,UACD,cAAc,qBAAA,CAAsB,YAAA;AAAA,UACpC,SAAA,EAAW;AAAA,SACb;AAAA,QACA,GAAI,KAAA,CAAM,OAAA,CAAQ,SAAA,EAAW,eAAA,EAAiB,EAAE,CAAA,GAC3C,SAAA,CAAW,eAAA,CAAiB,EAAA,GAC7B,CAAC,SAAA,EAAW,iBAAiB,EAAE;AAAA;AACrC;AAAA,GACF;AAGJ,EAAA,uBACE,IAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAI,KAAA;AAAA,MACJ,GAAA,EAAK,OAAA;AAAA,MACL,SAAA,EAAW,CAAC,oBAAA,CAAqB,IAAA,EAAM,SAAS,EAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,MAC1E,EAAA,EAAI;AAAA,QACF;AAAA,UACE,QAAA,EAAU,EAAA;AAAA,UACV,SAAA,EAAW,EAAA;AAAA,UACX,QAAA,EAAU,QAAA;AAAA,UACV,QAAA,EAAU,UAAA;AAAA,UACV,KAAA,EAAO,aAAA;AAAA,UACP,aAAa,cAAA,CAAe;AAAA,YAC1B,KAAA,EAAO,YAAA;AAAA,YACP,OAAA,EAAS,WAAW,aAAA,EAAe;AAAA,WACpC,CAAA;AAAA,UACD,GAAI,CAAC,CAAC,QAAA,IAAY;AAAA,YAChB,QAAA,EAAU,OAAA;AAAA,YACV,SAAA,EAAW;AAAA;AACb,SACF;AAAA,QACA,GAAI,KAAA,CAAM,OAAA,CAAQ,EAAE,CAAA,GAAI,EAAA,GAAK,CAAC,EAAE;AAAA,OAClC;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,mBAAA,EAAoB;AAAA,QACpB,qBAAA,EAAsB;AAAA,QACtB;AAAA;AAAA;AAAA,GACH;AAEJ;AAYA,SAAS,YAAA,CAAa,EAAE,EAAA,EAAI,IAAA,EAAM,QAAA,EAAU,EAAA,GAAK,KAAA,EAAO,EAAA,GAAK,KAAA,EAAO,QAAA,GAAW,CAAA,EAAG,GAAG,OAAM,EAAsB;AAC/G,EAAA,MAAM,UAAA,GAAa,OAAuB,IAAI,CAAA;AAC9C,EAAA,MAAM,QAAA,GAAW,eAAuB,CAAC,CAAA;AAEzC,EAAA,MAAM,oBAAA,GAAuB,CAAC,IAAA,KAAiB;AAC7C,IAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACzB,IAAA,IAAI;AACF,MAAA,MAAM,UAAA,GAAa,UAAA,CAAW,OAAA,CAAQ,cAAA,EAAe;AACrD,MAAA,MAAM,WAAA,GAAc,cAAc,QAAA,GAAW,GAAA,CAAA;AAC7C,MAAA,QAAA,CAAS,GAAA,CAAK,IAAA,GAAO,WAAA,GAAe,UAAU,CAAA;AAAA,IAChD,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,kBAAA,GAAqB,CAAC,GAAA,KAAgB;AAC1C,IAAA,IAAI,CAAC,WAAW,OAAA,EAAS,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AAC7C,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,OAAA,CAAQ,gBAAA,CAAiB,GAAG,CAAA;AACrD,MAAA,OAAO,KAAA,GAAQ,EAAE,CAAA,EAAG,KAAA,CAAM,CAAA,EAAG,CAAA,EAAG,KAAA,CAAM,CAAA,EAAE,GAAI,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AAAA,IAC3D,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AAAA,IACtB;AAAA,EACF,CAAA;AAEA,EAAA,iBAAA,CAAkB,CAAC,IAAA,KAAU,CAAC,WAAW,oBAAA,CAAqB,IAAI,IAAI,MAAU,CAAA;AAEhF,EAAA,MAAM,CAAA,GAAI,aAAa,QAAA,EAAU,CAAC,QAAQ,kBAAA,CAAmB,GAAG,EAAE,CAAC,CAAA;AACnE,EAAA,MAAM,CAAA,GAAI,aAAa,QAAA,EAAU,CAAC,QAAQ,kBAAA,CAAmB,GAAG,EAAE,CAAC,CAAA;AACnE,EAAA,MAAM,SAAA,GAAY,iBAAA,CAAA,WAAA,EAA+B,CAAC,CAAA,eAAA,EAAkB,CAAC,CAAA,qCAAA,CAAA;AAErE,EAAA,uBACE,IAAA,CAAC,OAAI,SAAA,EAAU,MAAA,EAAO,IAAI,CAAC,EAAE,WAAW,SAAA,EAAU,EAAG,GAAI,KAAA,CAAM,OAAA,CAAQ,EAAE,CAAA,GAAI,EAAA,GAAK,CAAC,EAAE,CAAE,CAAA,EAAI,GAAG,KAAA,EAC5F,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,4BAAA;AAAA,QACN,mBAAA,EAAoB,MAAA;AAAA,QACpB,KAAA,EAAM,MAAA;AAAA,QACN,MAAA,EAAO,MAAA;AAAA,QACP,WAAW,oBAAA,CAAqB,UAAA;AAAA,QAChC,KAAA,EAAO,EAAE,QAAA,EAAU,UAAA,EAAW;AAAA,QAE9B,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,GAAA,EAAK,UAAA,EAAY,IAAA,EAAK,MAAA,EAAO,KAAA,EAAM,MAAA,EAAO,MAAA,EAAO,MAAA,EAAO,EAAA,EAAQ,EAAA,EAAQ;AAAA;AAAA,KAChF;AAAA,oBAEA,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,WAAW,CAAA,CAAE,IAAA;AAAA,QACb,KAAA,EAAO,EAAE,SAAA,EAAU;AAAA,QACnB,WAAW,oBAAA,CAAqB,WAAA;AAAA,QAChC,EAAA,EAAI;AAAA,UACF,KAAA,EAAO,IAAA;AAAA,UACP,MAAA,EAAQ,IAAA;AAAA,UACR,MAAA,EAAQ,WAAA;AAAA,UACR,QAAA,EAAU,UAAA;AAAA,UACV,UAAA,EAAY;AAAA;AACd;AAAA;AACF,GAAA,EACF,CAAA;AAEJ;AAIA,SAAS,wBAAA,CAAyB,OAAc,GAAA,EAA8C;AAC5F,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAA2B,IAAI,CAAA;AAE3E,EAAA,MAAM,KAAA,GAAQ,MAAM,SAAA,KAAc,KAAA;AAElC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAI,OAAA,EAAS;AACf,MAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,GAAA,CAAI,OAAO,CAAA;AAC1C,MAAA,iBAAA,CAAkB;AAAA,QAChB,YAAY,KAAA,CAAM,aAAA;AAAA,QAClB,eAAe,KAAA,CAAM,UAAA;AAAA,QACrB,WAAA,EAAa,KAAA,GAAQ,KAAA,CAAM,WAAA,GAAc,KAAA,CAAM,YAAA;AAAA,QAC/C,YAAA,EAAc,KAAA,GAAQ,KAAA,CAAM,YAAA,GAAe,KAAA,CAAM,WAAA;AAAA,QACjD,mBAAA,EAAqB,KAAA,GAAQ,KAAA,CAAM,sBAAA,GAAyB,KAAA,CAAM,uBAAA;AAAA,QAClE,oBAAA,EAAsB,KAAA,GAAQ,KAAA,CAAM,uBAAA,GAA0B,KAAA,CAAM,sBAAA;AAAA,QACpE,sBAAA,EAAwB,KAAA,GAAQ,KAAA,CAAM,mBAAA,GAAsB,KAAA,CAAM,oBAAA;AAAA,QAClE,uBAAA,EAAyB,KAAA,GAAQ,KAAA,CAAM,oBAAA,GAAuB,KAAA,CAAM;AAAA,OACrE,CAAA;AAAA,IACH;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,KAAK,CAAC,CAAA;AAEf,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,CAAA,EAAG,cAAA,EAAgB,UAAU,CAAA,CAAA,EAAI,cAAA,EAAgB,YAAY,CAAA,CAAA,EAAI,cAAA,EAAgB,aAAa,CAAA,CAAA,EAAI,cAAA,EAAgB,WAAW,CAAA,CAAA;AAAA,IACtI,YAAA,EAAc,CAAA,EAAG,cAAA,EAAgB,mBAAmB,CAAA,CAAA,EAAI,cAAA,EAAgB,oBAAoB,CAAA,CAAA,EAAI,cAAA,EAAgB,uBAAuB,CAAA,CAAA,EAAI,cAAA,EAAgB,sBAAsB,CAAA;AAAA,GACnL;AACF;AC7QO,SAAS,UAAA,CAAW,EAAE,QAAA,EAAS,EAAoB;AACxD,EAAA,uBACEA,GAAAA,CAAC,UAAA,EAAA,EAAW,QAAM,IAAA,EAAC,QAAA,EAAU,QAC1B,QAAA,EACH,CAAA;AAEJ","file":"chunk-36C5H56C.js","sourcesContent":["import type { BoxProps } from '@mui/material/Box';\nimport type { Theme, SxProps, CSSObject } from '@mui/material/styles';\n\nimport { useRef, useState, useEffect } from 'react';\nimport { m, useTransform, useMotionValue, useAnimationFrame, useMotionTemplate } from 'framer-motion';\n\nimport Box from '@mui/material/Box';\nimport { useTheme } from '@mui/material/styles';\n\nimport { createClasses } from '../../utils/create-classes.js';\n\n// ----------------------------------------------------------------------\n\nexport const animateBorderClasses = {\n root: createClasses('animate__border__root'),\n primaryBorder: createClasses('animate__border__primary'),\n secondaryBorder: createClasses('animate__border__secondary'),\n svgWrapper: createClasses('animate__border__svg__wrapper'),\n movingShape: createClasses('animate__border__moving__shape'),\n};\n\n// ----------------------------------------------------------------------\n\n/**\n * Portal-old compatible borderGradient mixin.\n * Uses CSS mask to create a ring from the padding area.\n * `currentColor` controls the ring color when no explicit color is given.\n */\nfunction borderGradient(props?: { color?: string; padding?: string }): CSSObject {\n const { color, padding = '2px' } = props ?? {};\n\n return {\n padding,\n inset: 0,\n width: '100%',\n content: '\"\"',\n height: '100%',\n margin: 'auto',\n position: 'absolute',\n borderRadius: 'inherit',\n mask: 'linear-gradient(#FFF 0 0) content-box, linear-gradient(#FFF 0 0)',\n WebkitMask: 'linear-gradient(#FFF 0 0) content-box, linear-gradient(#FFF 0 0)',\n maskComposite: 'exclude',\n WebkitMaskComposite: 'xor',\n ...(color && { background: color }),\n };\n}\n\n// ----------------------------------------------------------------------\n\ntype BorderStyleProps = {\n /** Border stroke width as CSS string (e.g. '1px', '2px'). Default '2px'. */\n width?: string;\n /** Size (px) of the radial gradient glow that moves along the border. */\n size?: number;\n sx?: SxProps<Theme>;\n};\n\nexport type AnimateBorderProps = BoxProps & {\n /** Animation duration in seconds. Default 8. */\n duration?: number;\n slotProps?: {\n primaryBorder?: BorderStyleProps;\n secondaryBorder?: BorderStyleProps;\n /** Static outline color behind the animation. */\n outlineColor?: string | ((theme: Theme) => string);\n svgSettings?: {\n rx?: string;\n ry?: string;\n };\n };\n};\n\n// ----------------------------------------------------------------------\n\nexport function AnimateBorder({ sx, children, duration, slotProps, className, ...other }: AnimateBorderProps) {\n const theme = useTheme();\n\n const rootRef = useRef<HTMLDivElement>(null);\n const primaryBorderRef = useRef<HTMLSpanElement>(null);\n\n const [isHidden, setIsHidden] = useState(false);\n\n const secondaryBorderStyles = useComputedElementStyles(theme, primaryBorderRef);\n\n useEffect(() => {\n const handleVisibility = () => {\n if (rootRef.current) {\n const displayStyle = getComputedStyle(rootRef.current).display;\n setIsHidden(displayStyle === 'none');\n }\n };\n\n handleVisibility();\n\n window.addEventListener('resize', handleVisibility);\n\n return () => {\n window.removeEventListener('resize', handleVisibility);\n };\n }, []);\n\n const outlineColor =\n typeof slotProps?.outlineColor === 'function' ? slotProps?.outlineColor(theme) : slotProps?.outlineColor;\n\n const borderProps = {\n duration,\n isHidden,\n rx: slotProps?.svgSettings?.rx,\n ry: slotProps?.svgSettings?.ry,\n };\n\n const renderPrimaryBorder = () => (\n <MovingBorder\n {...borderProps}\n ref={primaryBorderRef}\n size={slotProps?.primaryBorder?.size}\n sx={[\n {\n ...borderGradient({ padding: slotProps?.primaryBorder?.width }),\n },\n ...(Array.isArray(slotProps?.primaryBorder?.sx)\n ? (slotProps!.primaryBorder!.sx as any[])\n : [slotProps?.primaryBorder?.sx]),\n ]}\n />\n );\n\n const renderSecondaryBorder = () =>\n slotProps?.secondaryBorder && (\n <MovingBorder\n {...borderProps}\n size={slotProps?.secondaryBorder?.size ?? slotProps?.primaryBorder?.size}\n sx={[\n {\n ...borderGradient({\n padding: slotProps?.secondaryBorder?.width ?? secondaryBorderStyles.padding,\n }),\n borderRadius: secondaryBorderStyles.borderRadius,\n transform: 'scale(-1, -1)',\n },\n ...(Array.isArray(slotProps?.secondaryBorder?.sx)\n ? (slotProps!.secondaryBorder!.sx as any[])\n : [slotProps?.secondaryBorder?.sx]),\n ]}\n />\n );\n\n return (\n <Box\n dir=\"ltr\"\n ref={rootRef}\n className={[animateBorderClasses.root, className].filter(Boolean).join(' ')}\n sx={[\n {\n minWidth: 40,\n minHeight: 40,\n overflow: 'hidden',\n position: 'relative',\n width: 'fit-content',\n '&::before': borderGradient({\n color: outlineColor,\n padding: slotProps?.primaryBorder?.width,\n }),\n ...(!!children && {\n minWidth: 'unset',\n minHeight: 'unset',\n }),\n },\n ...(Array.isArray(sx) ? sx : [sx]),\n ]}\n {...other}\n >\n {renderPrimaryBorder()}\n {renderSecondaryBorder()}\n {children}\n </Box>\n );\n}\n\n// ----------------------------------------------------------------------\n\ntype MovingBorderProps = BoxProps<'span'> & {\n rx?: string;\n ry?: string;\n duration?: number;\n isHidden?: boolean;\n size?: BorderStyleProps['size'];\n};\n\nfunction MovingBorder({ sx, size, isHidden, rx = '30%', ry = '30%', duration = 8, ...other }: MovingBorderProps) {\n const svgRectRef = useRef<SVGRectElement>(null);\n const progress = useMotionValue<number>(0);\n\n const updateAnimationFrame = (time: number) => {\n if (!svgRectRef.current) return;\n try {\n const pathLength = svgRectRef.current.getTotalLength();\n const pixelsPerMs = pathLength / (duration * 1000);\n progress.set((time * pixelsPerMs) % pathLength);\n } catch {\n return;\n }\n };\n\n const calculateTransform = (val: number) => {\n if (!svgRectRef.current) return { x: 0, y: 0 };\n try {\n const point = svgRectRef.current.getPointAtLength(val);\n return point ? { x: point.x, y: point.y } : { x: 0, y: 0 };\n } catch {\n return { x: 0, y: 0 };\n }\n };\n\n useAnimationFrame((time) => (!isHidden ? updateAnimationFrame(time) : undefined));\n\n const x = useTransform(progress, (val) => calculateTransform(val).x);\n const y = useTransform(progress, (val) => calculateTransform(val).y);\n const transform = useMotionTemplate`translateX(${x}px) translateY(${y}px) translateX(-50%) translateY(-50%)`;\n\n return (\n <Box component=\"span\" sx={[{ textAlign: 'initial' }, ...(Array.isArray(sx) ? sx : [sx])]} {...other}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n preserveAspectRatio=\"none\"\n width=\"100%\"\n height=\"100%\"\n className={animateBorderClasses.svgWrapper}\n style={{ position: 'absolute' }}\n >\n <rect ref={svgRectRef} fill=\"none\" width=\"100%\" height=\"100%\" rx={rx} ry={ry} />\n </svg>\n\n <Box\n component={m.span}\n style={{ transform }}\n className={animateBorderClasses.movingShape}\n sx={{\n width: size,\n height: size,\n filter: 'blur(8px)',\n position: 'absolute',\n background: 'radial-gradient(currentColor 40%, transparent 80%)',\n }}\n />\n </Box>\n );\n}\n\n// ----------------------------------------------------------------------\n\nfunction useComputedElementStyles(theme: Theme, ref: React.RefObject<HTMLSpanElement | null>) {\n const [computedStyles, setComputedStyles] = useState<CSSObject | null>(null);\n\n const isRtl = theme.direction === 'rtl';\n\n useEffect(() => {\n if (ref.current) {\n const style = getComputedStyle(ref.current);\n setComputedStyles({\n paddingTop: style.paddingBottom,\n paddingBottom: style.paddingTop,\n paddingLeft: isRtl ? style.paddingLeft : style.paddingRight,\n paddingRight: isRtl ? style.paddingRight : style.paddingLeft,\n borderTopLeftRadius: isRtl ? style.borderBottomLeftRadius : style.borderBottomRightRadius,\n borderTopRightRadius: isRtl ? style.borderBottomRightRadius : style.borderBottomLeftRadius,\n borderBottomLeftRadius: isRtl ? style.borderTopLeftRadius : style.borderTopRightRadius,\n borderBottomRightRadius: isRtl ? style.borderTopRightRadius : style.borderTopLeftRadius,\n });\n }\n }, [ref, isRtl]);\n\n return {\n padding: `${computedStyles?.paddingTop} ${computedStyles?.paddingRight} ${computedStyles?.paddingBottom} ${computedStyles?.paddingLeft}`,\n borderRadius: `${computedStyles?.borderTopLeftRadius} ${computedStyles?.borderTopRightRadius} ${computedStyles?.borderBottomRightRadius} ${computedStyles?.borderBottomLeftRadius}`,\n };\n}\n","import { domMax, LazyMotion } from 'framer-motion';\n\n// ----------------------------------------------------------------------\n\nexport type MotionLazyProps = {\n children: React.ReactNode;\n};\n\nexport function MotionLazy({ children }: MotionLazyProps) {\n return (\n <LazyMotion strict features={domMax}>\n {children}\n </LazyMotion>\n );\n}\n"]}
@@ -0,0 +1,73 @@
1
+ import { useId, useState } from 'react';
2
+ import Dialog from '@mui/material/Dialog';
3
+ import DialogTitle from '@mui/material/DialogTitle';
4
+ import DialogContent from '@mui/material/DialogContent';
5
+ import DialogContentText from '@mui/material/DialogContentText';
6
+ import DialogActions from '@mui/material/DialogActions';
7
+ import Button from '@mui/material/Button';
8
+ import { jsxs, jsx } from 'react/jsx-runtime';
9
+
10
+ // src/components/confirm-dialog/confirm-dialog.tsx
11
+ function ConfirmDialog({
12
+ open,
13
+ onClose,
14
+ onConfirm,
15
+ title = "Confirm",
16
+ content,
17
+ confirmLabel = "Confirm",
18
+ cancelLabel = "Cancel",
19
+ confirmColor = "primary",
20
+ loading = false,
21
+ disabled = false,
22
+ maxWidth = "xs",
23
+ sx
24
+ }) {
25
+ const titleId = useId();
26
+ const descriptionId = useId();
27
+ const [confirming, setConfirming] = useState(false);
28
+ const busy = loading || confirming;
29
+ const handleConfirm = () => {
30
+ if (busy) return;
31
+ const result = onConfirm();
32
+ if (!(result instanceof Promise)) return;
33
+ setConfirming(true);
34
+ result.catch(() => {
35
+ }).finally(() => setConfirming(false));
36
+ };
37
+ return /* @__PURE__ */ jsxs(
38
+ Dialog,
39
+ {
40
+ open,
41
+ onClose: busy ? void 0 : onClose,
42
+ maxWidth,
43
+ fullWidth: true,
44
+ "aria-labelledby": titleId,
45
+ "aria-describedby": content ? descriptionId : void 0,
46
+ sx,
47
+ children: [
48
+ /* @__PURE__ */ jsx(DialogTitle, { id: titleId, children: title }),
49
+ content && /* @__PURE__ */ jsx(DialogContent, { children: typeof content === "string" ? /* @__PURE__ */ jsx(DialogContentText, { id: descriptionId, children: content }) : /* @__PURE__ */ jsx("div", { id: descriptionId, children: content }) }),
50
+ /* @__PURE__ */ jsxs(DialogActions, { sx: { px: 3, pb: 2 }, children: [
51
+ /* @__PURE__ */ jsx(Button, { onClick: onClose, color: "inherit", disabled: busy, variant: "outlined", children: cancelLabel }),
52
+ /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, color: confirmColor, variant: "contained", loading: busy, disabled, children: confirmLabel })
53
+ ] })
54
+ ]
55
+ }
56
+ );
57
+ }
58
+ function DeleteDialog({ itemName, content, ...props }) {
59
+ return /* @__PURE__ */ jsx(
60
+ ConfirmDialog,
61
+ {
62
+ title: itemName ? `Delete "${itemName}"?` : "Delete item?",
63
+ content: content ?? "This action cannot be undone. Are you sure you want to proceed?",
64
+ confirmLabel: "Delete",
65
+ confirmColor: "error",
66
+ ...props
67
+ }
68
+ );
69
+ }
70
+
71
+ export { ConfirmDialog, DeleteDialog };
72
+ //# sourceMappingURL=chunk-36FOXX25.js.map
73
+ //# sourceMappingURL=chunk-36FOXX25.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/confirm-dialog/confirm-dialog.tsx"],"names":[],"mappings":";;;;;;;;;;AAwFO,SAAS,aAAA,CAAc;AAAA,EAC5B,IAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA,GAAQ,SAAA;AAAA,EACR,OAAA;AAAA,EACA,YAAA,GAAe,SAAA;AAAA,EACf,WAAA,GAAc,QAAA;AAAA,EACd,YAAA,GAAe,SAAA;AAAA,EACf,OAAA,GAAU,KAAA;AAAA,EACV,QAAA,GAAW,KAAA;AAAA,EACX,QAAA,GAAW,IAAA;AAAA,EACX;AACF,CAAA,EAAkC;AAChC,EAAA,MAAM,UAAU,KAAA,EAAM;AACtB,EAAA,MAAM,gBAAgB,KAAA,EAAM;AAW5B,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,KAAK,CAAA;AAClD,EAAA,MAAM,OAAO,OAAA,IAAW,UAAA;AAExB,EAAA,MAAM,gBAAgB,MAAM;AAC1B,IAAA,IAAI,IAAA,EAAM;AAEV,IAAA,MAAM,SAAS,SAAA,EAAU;AACzB,IAAA,IAAI,EAAE,kBAAkB,OAAA,CAAA,EAAU;AAElC,IAAA,aAAA,CAAc,IAAI,CAAA;AAClB,IAAA,MAAA,CACG,MAAM,MAAM;AAAA,IAKb,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM,aAAA,CAAc,KAAK,CAAC,CAAA;AAAA,EACvC,CAAA;AAEA,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,OAAA,EAAS,OAAO,MAAA,GAAY,OAAA;AAAA,MAC5B,QAAA;AAAA,MACA,SAAA,EAAS,IAAA;AAAA,MACT,iBAAA,EAAiB,OAAA;AAAA,MACjB,kBAAA,EAAkB,UAAU,aAAA,GAAgB,MAAA;AAAA,MAC5C,EAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,EAAA,EAAI,OAAA,EAAU,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QAEhC,2BACC,GAAA,CAAC,aAAA,EAAA,EACE,QAAA,EAAA,OAAO,OAAA,KAAY,2BAClB,GAAA,CAAC,iBAAA,EAAA,EAAkB,EAAA,EAAI,aAAA,EAAgB,mBAAQ,CAAA,mBAE/C,GAAA,CAAC,SAAI,EAAA,EAAI,aAAA,EAAgB,mBAAQ,CAAA,EAErC,CAAA;AAAA,wBAGF,IAAA,CAAC,iBAAc,EAAA,EAAI,EAAE,IAAI,CAAA,EAAG,EAAA,EAAI,GAAE,EAChC,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,MAAA,EAAA,EAAO,SAAS,OAAA,EAAS,KAAA,EAAM,WAAU,QAAA,EAAU,IAAA,EAAM,OAAA,EAAQ,UAAA,EAC/D,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,0BAEA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAS,aAAA,EAAe,KAAA,EAAO,YAAA,EAAc,OAAA,EAAQ,WAAA,EAAY,OAAA,EAAS,IAAA,EAAM,QAAA,EACrF,QAAA,EAAA,YAAA,EACH;AAAA,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AAwBO,SAAS,aAAa,EAAE,QAAA,EAAU,OAAA,EAAS,GAAG,OAAM,EAAiC;AAC1F,EAAA,uBACE,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,QAAA,GAAW,CAAA,QAAA,EAAW,QAAQ,CAAA,EAAA,CAAA,GAAO,cAAA;AAAA,MAC5C,SAAS,OAAA,IAAW,iEAAA;AAAA,MACpB,YAAA,EAAa,QAAA;AAAA,MACb,YAAA,EAAa,OAAA;AAAA,MACZ,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-36FOXX25.js","sourcesContent":["'use client';\n\n/**\n * Confirm Dialog Component\n *\n * Reusable confirmation dialog with customizable actions.\n * Implements WCAG 2.1 accessibility with proper ARIA attributes.\n *\n * @module components/confirm-dialog\n */\n\nimport { useId, useState, type ReactNode } from 'react';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogContentText from '@mui/material/DialogContentText';\nimport DialogActions from '@mui/material/DialogActions';\nimport Button from '@mui/material/Button';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface ConfirmDialogProps {\n /** Whether the dialog is open */\n open: boolean;\n /** Called when dialog should close */\n onClose: () => void;\n /** Called when user confirms */\n onConfirm: () => void | Promise<void>;\n /** Dialog title */\n title?: string;\n /** Dialog content/message */\n content?: ReactNode;\n /** Confirm button text */\n confirmLabel?: string;\n /** Cancel button text */\n cancelLabel?: string;\n /** Confirm button color */\n confirmColor?: 'primary' | 'secondary' | 'error' | 'warning' | 'info' | 'success';\n /** Loading state for async confirm */\n loading?: boolean;\n /** Disable confirm button */\n disabled?: boolean;\n /** Maximum width of dialog */\n maxWidth?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | false;\n /** Additional styles for dialog */\n sx?: SxProps<Theme>;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\n/**\n * ConfirmDialog - Reusable confirmation dialog.\n *\n * @example\n * ```tsx\n * const [open, setOpen] = useState(false);\n *\n * <ConfirmDialog\n * open={open}\n * onClose={() => setOpen(false)}\n * onConfirm={handleDelete}\n * title=\"Delete item?\"\n * content=\"This action cannot be undone.\"\n * confirmColor=\"error\"\n * confirmLabel=\"Delete\"\n * />\n * ```\n *\n * @example\n * ```tsx\n * // With async confirm\n * <ConfirmDialog\n * open={open}\n * onClose={() => setOpen(false)}\n * onConfirm={async () => {\n * await deleteItem();\n * setOpen(false);\n * }}\n * loading={isDeleting}\n * title=\"Confirm deletion\"\n * />\n * ```\n */\nexport function ConfirmDialog({\n open,\n onClose,\n onConfirm,\n title = 'Confirm',\n content,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n confirmColor = 'primary',\n loading = false,\n disabled = false,\n maxWidth = 'xs',\n sx,\n}: ConfirmDialogProps): ReactNode {\n const titleId = useId();\n const descriptionId = useId();\n\n // Re-entry guard for the destructive action.\n //\n // The only thing standing between a double-click and two deletions used to\n // be the caller's `loading` prop — and most callers don't thread one\n // through, because the dialog's own example doesn't. An impatient operator\n // clicking twice fired `onConfirm` twice.\n //\n // Tracked here rather than relying on the caller: this component knows when\n // the action it started is still running.\n const [confirming, setConfirming] = useState(false);\n const busy = loading || confirming;\n\n const handleConfirm = () => {\n if (busy) return;\n\n const result = onConfirm();\n if (!(result instanceof Promise)) return;\n\n setConfirming(true);\n result\n .catch(() => {\n // The parent owns error reporting; the dialog only owns the button\n // state. Swallowing here prevents an unhandled rejection, and the\n // `finally` below makes sure a failure leaves the operator able to\n // retry instead of stuck behind a spinner.\n })\n .finally(() => setConfirming(false));\n };\n\n return (\n <Dialog\n open={open}\n onClose={busy ? undefined : onClose}\n maxWidth={maxWidth}\n fullWidth\n aria-labelledby={titleId}\n aria-describedby={content ? descriptionId : undefined}\n sx={sx}\n >\n <DialogTitle id={titleId}>{title}</DialogTitle>\n\n {content && (\n <DialogContent>\n {typeof content === 'string' ? (\n <DialogContentText id={descriptionId}>{content}</DialogContentText>\n ) : (\n <div id={descriptionId}>{content}</div>\n )}\n </DialogContent>\n )}\n\n <DialogActions sx={{ px: 3, pb: 2 }}>\n <Button onClick={onClose} color=\"inherit\" disabled={busy} variant=\"outlined\">\n {cancelLabel}\n </Button>\n\n <Button onClick={handleConfirm} color={confirmColor} variant=\"contained\" loading={busy} disabled={disabled}>\n {confirmLabel}\n </Button>\n </DialogActions>\n </Dialog>\n );\n}\n\n// =============================================================================\n// DELETE DIALOG\n// =============================================================================\n\nexport interface DeleteDialogProps extends Omit<ConfirmDialogProps, 'title' | 'confirmLabel' | 'confirmColor'> {\n /** Name of the item being deleted */\n itemName?: string;\n}\n\n/**\n * DeleteDialog - Specialized confirmation for delete actions.\n *\n * @example\n * ```tsx\n * <DeleteDialog\n * open={open}\n * onClose={() => setOpen(false)}\n * onConfirm={handleDelete}\n * itemName=\"Project Alpha\"\n * />\n * ```\n */\nexport function DeleteDialog({ itemName, content, ...props }: DeleteDialogProps): ReactNode {\n return (\n <ConfirmDialog\n title={itemName ? `Delete \"${itemName}\"?` : 'Delete item?'}\n content={content ?? 'This action cannot be undone. Are you sure you want to proceed?'}\n confirmLabel=\"Delete\"\n confirmColor=\"error\"\n {...props}\n />\n );\n}\n"]}
@@ -7,6 +7,7 @@ import { addProtocol } from 'maplibre-gl';
7
7
  import { Protocol } from 'pmtiles';
8
8
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
9
 
10
+ // src/components/map/Map.tsx
10
11
  var protocol = new Protocol();
11
12
  addProtocol("pmtiles", protocol.tile);
12
13
  var messages = {
@@ -52,7 +53,7 @@ var Map = forwardRef(function MapView({
52
53
  [forwardedRef]
53
54
  );
54
55
  useEffect(() => {
55
- if (!host.current || typeof ResizeObserver === "undefined") return;
56
+ if (!host.current || typeof ResizeObserver === "undefined") return void 0;
56
57
  const observer = new ResizeObserver(() => map.current?.resize());
57
58
  observer.observe(host.current);
58
59
  return () => observer.disconnect();
@@ -221,15 +222,17 @@ function MapPointPicker({
221
222
  ...initialViewport
222
223
  }));
223
224
  const [loaded, setLoaded] = useState(false);
225
+ const longitude = valid?.lng;
226
+ const latitude = valid?.lat;
224
227
  useEffect(() => {
225
- if (value && isMapPoint(value))
228
+ if (longitude !== void 0 && latitude !== void 0)
226
229
  setCamera((old) => ({
227
230
  ...old,
228
- longitude: value.lng,
229
- latitude: mapCameraLatitude(value.lat),
231
+ longitude,
232
+ latitude: mapCameraLatitude(latitude),
230
233
  zoom: Math.max(old.zoom, selectionZoom)
231
234
  }));
232
- }, [value?.lng, value?.lat, selectionZoom]);
235
+ }, [longitude, latitude, selectionZoom]);
233
236
  function choose(lng, lat) {
234
237
  const point = normalizeMapPoint(lng, lat);
235
238
  if (point && !readOnly) onChange(point);
@@ -411,12 +414,12 @@ function MapPlaceSearch({
411
414
  const provider = useRef(search);
412
415
  provider.current = search;
413
416
  const validQuery = query.trim().length >= minLength && query.length <= 200;
414
- function cancel() {
417
+ const cancel = useCallback(() => {
415
418
  generation.current++;
416
419
  active.current?.abort();
417
420
  active.current = null;
418
- }
419
- async function run() {
421
+ }, []);
422
+ const run = useCallback(async () => {
420
423
  cancel();
421
424
  if (!validQuery || disabled) return;
422
425
  const id = generation.current;
@@ -448,20 +451,20 @@ function MapPlaceSearch({
448
451
  } finally {
449
452
  if (id === generation.current) setLoading(false);
450
453
  }
451
- }
454
+ }, [cancel, validQuery, disabled, query, limit]);
452
455
  useEffect(() => {
453
- if (mode !== "autocomplete" || !validQuery || disabled || selected) return;
456
+ if (mode !== "autocomplete" || !validQuery || disabled || selected) return void 0;
454
457
  const timer = setTimeout(() => void run(), debounceMs);
455
458
  return () => clearTimeout(timer);
456
- }, [query, mode, debounceMs, disabled, selected]);
459
+ }, [run, validQuery, mode, debounceMs, disabled, selected]);
457
460
  useEffect(() => {
458
461
  if (disabled) {
459
462
  cancel();
460
463
  setLoading(false);
461
464
  setOpen(false);
462
465
  }
463
- }, [disabled]);
464
- useEffect(() => () => cancel(), []);
466
+ }, [disabled, cancel]);
467
+ useEffect(() => () => cancel(), [cancel]);
465
468
  function input(value) {
466
469
  cancel();
467
470
  setQuery(value);
@@ -555,5 +558,5 @@ function MapPlaceSearch({
555
558
  }
556
559
 
557
560
  export { Map, MapCoverageLayer, MapMarker, MapPlaceSearch, MapPointPicker, isMapPoint, normalizeMapPoint };
558
- //# sourceMappingURL=chunk-52PQL67Q.js.map
559
- //# sourceMappingURL=chunk-52PQL67Q.js.map
561
+ //# sourceMappingURL=chunk-3VSM7NZG.js.map
562
+ //# sourceMappingURL=chunk-3VSM7NZG.js.map