@zendir/ui 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +640 -631
  3. package/dist/_virtual/_rolldown/runtime.js +13 -0
  4. package/dist/index.js +17 -221
  5. package/dist/react/3d/CesiumCaptureSource.d.ts +0 -1
  6. package/dist/react/3d/CesiumCaptureSource.js +364 -283
  7. package/dist/react/3d/CesiumCaptureSource.js.map +1 -1
  8. package/dist/react/3d/ZenSpace3D.d.ts +2 -3
  9. package/dist/react/3d/ZenSpace3D.js +1681 -1237
  10. package/dist/react/3d/ZenSpace3D.js.map +1 -1
  11. package/dist/react/3d/ZenSpace3DCesium.d.ts +0 -1
  12. package/dist/react/3d/ZenSpace3DCesium.js +513 -560
  13. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -1
  14. package/dist/react/3d/ZenSpace3DShaders.js +61 -66
  15. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -1
  16. package/dist/react/3d/ZenSpace3DTypes.d.ts +19 -20
  17. package/dist/react/3d/ZenSpace3DUtils.d.ts +0 -1
  18. package/dist/react/3d/ZenSpace3DUtils.js +37 -24
  19. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -1
  20. package/dist/react/3d/capturePngAnalysis.js +42 -36
  21. package/dist/react/3d/capturePngAnalysis.js.map +1 -1
  22. package/dist/react/3d/index.d.ts +3 -3
  23. package/dist/react/3d/index.js +5 -53
  24. package/dist/react/3d/threeLoader.d.ts +1 -1
  25. package/dist/react/3d/threeLoader.js +23 -18
  26. package/dist/react/3d/threeLoader.js.map +1 -1
  27. package/dist/react/astro/ClassificationBanner.d.ts +2 -3
  28. package/dist/react/astro/ClassificationBanner.js +95 -79
  29. package/dist/react/astro/ClassificationBanner.js.map +1 -1
  30. package/dist/react/astro/GlobalStatusBar.d.ts +0 -1
  31. package/dist/react/astro/GlobalStatusBar.js +157 -163
  32. package/dist/react/astro/GlobalStatusBar.js.map +1 -1
  33. package/dist/react/astro/MissionClock.d.ts +7 -8
  34. package/dist/react/astro/MissionClock.js +377 -400
  35. package/dist/react/astro/MissionClock.js.map +1 -1
  36. package/dist/react/astro/MonitoringIcon.d.ts +1 -2
  37. package/dist/react/astro/MonitoringIcon.js +422 -358
  38. package/dist/react/astro/MonitoringIcon.js.map +1 -1
  39. package/dist/react/astro/Notification.d.ts +1 -2
  40. package/dist/react/astro/Notification.js +229 -126
  41. package/dist/react/astro/Notification.js.map +1 -1
  42. package/dist/react/astro/Progress.d.ts +0 -1
  43. package/dist/react/astro/Progress.js +199 -141
  44. package/dist/react/astro/Progress.js.map +1 -1
  45. package/dist/react/astro/SimulationControls.d.ts +3 -4
  46. package/dist/react/astro/SimulationControls.js +596 -650
  47. package/dist/react/astro/SimulationControls.js.map +1 -1
  48. package/dist/react/astro/StatusIndicator.d.ts +0 -1
  49. package/dist/react/astro/StatusIndicator.js +236 -170
  50. package/dist/react/astro/StatusIndicator.js.map +1 -1
  51. package/dist/react/astro/UnifiedTimeline.d.ts +9 -10
  52. package/dist/react/astro/UnifiedTimeline.js +2345 -2392
  53. package/dist/react/astro/UnifiedTimeline.js.map +1 -1
  54. package/dist/react/astro/index.d.ts +5 -5
  55. package/dist/react/astro/index.js +1 -25
  56. package/dist/react/cards/AccessCard.d.ts +0 -1
  57. package/dist/react/cards/AccessCard.js +471 -405
  58. package/dist/react/cards/AccessCard.js.map +1 -1
  59. package/dist/react/cards/OrbitCard.d.ts +0 -1
  60. package/dist/react/cards/OrbitCard.js +487 -364
  61. package/dist/react/cards/OrbitCard.js.map +1 -1
  62. package/dist/react/cards/SpacecraftCard.d.ts +0 -1
  63. package/dist/react/cards/SpacecraftCard.js +813 -925
  64. package/dist/react/cards/SpacecraftCard.js.map +1 -1
  65. package/dist/react/cards/TelemetryCard.d.ts +0 -1
  66. package/dist/react/cards/TelemetryCard.js +1055 -732
  67. package/dist/react/cards/TelemetryCard.js.map +1 -1
  68. package/dist/react/cards/TelemetryStreamCard.d.ts +0 -1
  69. package/dist/react/cards/TelemetryStreamCard.js +323 -297
  70. package/dist/react/cards/TelemetryStreamCard.js.map +1 -1
  71. package/dist/react/cards/index.d.ts +1 -1
  72. package/dist/react/cards/index.js +1 -8
  73. package/dist/react/charts/GroundTrackMap.d.ts +6 -7
  74. package/dist/react/charts/GroundTrackMap.js +1377 -1256
  75. package/dist/react/charts/GroundTrackMap.js.map +1 -1
  76. package/dist/react/charts/GroundTrackMapLeaflet.d.ts +1 -2
  77. package/dist/react/charts/GroundTrackMapLeaflet.js +1065 -987
  78. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -1
  79. package/dist/react/charts/groundTrackMapLeafletTiles.js +34 -25
  80. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -1
  81. package/dist/react/charts/groundTrackMapLeafletUtils.js +70 -61
  82. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -1
  83. package/dist/react/charts/index.d.ts +1 -1
  84. package/dist/react/charts/index.js +7 -100
  85. package/dist/react/charts/unified/AstroChart.d.ts +1 -2
  86. package/dist/react/charts/unified/AstroChart.js +1331 -1411
  87. package/dist/react/charts/unified/AstroChart.js.map +1 -1
  88. package/dist/react/charts/unified/PowerOverviewChart.d.ts +3 -3
  89. package/dist/react/charts/unified/PowerOverviewChart.js +495 -478
  90. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -1
  91. package/dist/react/charts/unified/domain.d.ts +12 -13
  92. package/dist/react/charts/unified/domain.js +3999 -3145
  93. package/dist/react/charts/unified/domain.js.map +1 -1
  94. package/dist/react/charts/unified/generators.d.ts +3 -4
  95. package/dist/react/charts/unified/generators.js +561 -498
  96. package/dist/react/charts/unified/generators.js.map +1 -1
  97. package/dist/react/charts/unified/index.d.ts +1 -1
  98. package/dist/react/charts/unified/presets.d.ts +14 -15
  99. package/dist/react/charts/unified/presets.js +857 -994
  100. package/dist/react/charts/unified/presets.js.map +1 -1
  101. package/dist/react/charts/unified/sync.d.ts +2 -3
  102. package/dist/react/charts/unified/sync.js +229 -195
  103. package/dist/react/charts/unified/sync.js.map +1 -1
  104. package/dist/react/charts/unified/theme.d.ts +11 -12
  105. package/dist/react/charts/unified/theme.js +606 -642
  106. package/dist/react/charts/unified/theme.js.map +1 -1
  107. package/dist/react/charts/unified/types.d.ts +32 -33
  108. package/dist/react/charts/unified/useChartStream.d.ts +1 -2
  109. package/dist/react/charts/unified/useChartStream.js +203 -216
  110. package/dist/react/charts/unified/useChartStream.js.map +1 -1
  111. package/dist/react/chatgpt/AppCard.d.ts +1 -2
  112. package/dist/react/chatgpt/index.d.ts +7 -7
  113. package/dist/react/chatgpt/index.js +160 -139
  114. package/dist/react/chatgpt/index.js.map +1 -1
  115. package/dist/react/context/CategoryContext.d.ts +0 -1
  116. package/dist/react/context/CategoryContext.js +78 -29
  117. package/dist/react/context/CategoryContext.js.map +1 -1
  118. package/dist/react/context/DisplaySettingsContext.d.ts +1 -2
  119. package/dist/react/context/DisplaySettingsContext.js +205 -156
  120. package/dist/react/context/DisplaySettingsContext.js.map +1 -1
  121. package/dist/react/context/SpatialSelectionContext.d.ts +0 -1
  122. package/dist/react/context/SpatialSelectionContext.js +36 -7
  123. package/dist/react/context/SpatialSelectionContext.js.map +1 -1
  124. package/dist/react/core/data/DataTable.d.ts +3 -4
  125. package/dist/react/core/data/DataTable.js +473 -440
  126. package/dist/react/core/data/DataTable.js.map +1 -1
  127. package/dist/react/core/data/DataValue.d.ts +4 -5
  128. package/dist/react/core/data/DataValue.js +605 -538
  129. package/dist/react/core/data/DataValue.js.map +1 -1
  130. package/dist/react/core/data/propertyConfig.d.ts +1 -2
  131. package/dist/react/core/data/propertyConfig.js +446 -382
  132. package/dist/react/core/data/propertyConfig.js.map +1 -1
  133. package/dist/react/core/display/AstroIcon.d.ts +4 -5
  134. package/dist/react/core/display/AstroIcon.js +339 -429
  135. package/dist/react/core/display/AstroIcon.js.map +1 -1
  136. package/dist/react/core/display/Badge.d.ts +2 -3
  137. package/dist/react/core/display/Badge.js +131 -131
  138. package/dist/react/core/display/Badge.js.map +1 -1
  139. package/dist/react/core/display/CardHeader.d.ts +0 -1
  140. package/dist/react/core/display/CardHeader.js +398 -311
  141. package/dist/react/core/display/CardHeader.js.map +1 -1
  142. package/dist/react/core/display/Container.d.ts +2 -3
  143. package/dist/react/core/display/Container.js +640 -668
  144. package/dist/react/core/display/Container.js.map +1 -1
  145. package/dist/react/core/display/CopyButton.d.ts +1 -2
  146. package/dist/react/core/display/CopyButton.js +158 -101
  147. package/dist/react/core/display/CopyButton.js.map +1 -1
  148. package/dist/react/core/display/GlassCard.d.ts +3 -4
  149. package/dist/react/core/display/GlassCard.js +416 -369
  150. package/dist/react/core/display/GlassCard.js.map +1 -1
  151. package/dist/react/core/display/HeaderIconWithStatus.d.ts +0 -1
  152. package/dist/react/core/display/HeaderIconWithStatus.js +152 -152
  153. package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -1
  154. package/dist/react/core/display/Icon.d.ts +2 -3
  155. package/dist/react/core/display/Icon.js +172 -143
  156. package/dist/react/core/display/Icon.js.map +1 -1
  157. package/dist/react/core/display/Typography.d.ts +24 -25
  158. package/dist/react/core/display/Typography.js +360 -178
  159. package/dist/react/core/display/Typography.js.map +1 -1
  160. package/dist/react/core/feedback/ConfirmDialog.d.ts +1 -2
  161. package/dist/react/core/feedback/ConfirmDialog.js +343 -304
  162. package/dist/react/core/feedback/ConfirmDialog.js.map +1 -1
  163. package/dist/react/core/feedback/Dialog.d.ts +2 -3
  164. package/dist/react/core/feedback/Dialog.js +189 -197
  165. package/dist/react/core/feedback/Dialog.js.map +1 -1
  166. package/dist/react/core/feedback/Toast.d.ts +2 -3
  167. package/dist/react/core/feedback/Toast.js +346 -207
  168. package/dist/react/core/feedback/Toast.js.map +1 -1
  169. package/dist/react/core/index.d.ts +26 -26
  170. package/dist/react/core/index.js +7 -119
  171. package/dist/react/core/inputs/Button.d.ts +2 -3
  172. package/dist/react/core/inputs/Button.js +281 -304
  173. package/dist/react/core/inputs/Button.js.map +1 -1
  174. package/dist/react/core/inputs/Checkbox.d.ts +2 -3
  175. package/dist/react/core/inputs/Checkbox.js +139 -127
  176. package/dist/react/core/inputs/Checkbox.js.map +1 -1
  177. package/dist/react/core/inputs/Input.d.ts +3 -4
  178. package/dist/react/core/inputs/Input.js +277 -285
  179. package/dist/react/core/inputs/Input.js.map +1 -1
  180. package/dist/react/core/inputs/LimitsBar.d.ts +1 -2
  181. package/dist/react/core/inputs/LimitsBar.js +271 -196
  182. package/dist/react/core/inputs/LimitsBar.js.map +1 -1
  183. package/dist/react/core/inputs/NumberInput.d.ts +2 -3
  184. package/dist/react/core/inputs/NumberInput.js +531 -503
  185. package/dist/react/core/inputs/NumberInput.js.map +1 -1
  186. package/dist/react/core/inputs/PinInput.d.ts +2 -3
  187. package/dist/react/core/inputs/PinInput.js +224 -207
  188. package/dist/react/core/inputs/PinInput.js.map +1 -1
  189. package/dist/react/core/inputs/Select.d.ts +1 -2
  190. package/dist/react/core/inputs/Select.js +298 -299
  191. package/dist/react/core/inputs/Select.js.map +1 -1
  192. package/dist/react/core/inputs/Toggle.d.ts +2 -3
  193. package/dist/react/core/inputs/Toggle.js +142 -148
  194. package/dist/react/core/inputs/Toggle.js.map +1 -1
  195. package/dist/react/core/layout/Box.d.ts +3 -4
  196. package/dist/react/core/layout/Box.js +118 -122
  197. package/dist/react/core/layout/Box.js.map +1 -1
  198. package/dist/react/core/layout/Center.d.ts +0 -1
  199. package/dist/react/core/layout/Center.js +45 -32
  200. package/dist/react/core/layout/Center.js.map +1 -1
  201. package/dist/react/core/layout/Divider.d.ts +1 -2
  202. package/dist/react/core/layout/Divider.js +112 -106
  203. package/dist/react/core/layout/Divider.js.map +1 -1
  204. package/dist/react/core/layout/Flex.d.ts +4 -5
  205. package/dist/react/core/layout/Flex.js +120 -124
  206. package/dist/react/core/layout/Flex.js.map +1 -1
  207. package/dist/react/core/layout/Grid.d.ts +5 -6
  208. package/dist/react/core/layout/Grid.js +131 -138
  209. package/dist/react/core/layout/Grid.js.map +1 -1
  210. package/dist/react/core/layout/Spacer.d.ts +0 -1
  211. package/dist/react/core/layout/Spacer.js +36 -29
  212. package/dist/react/core/layout/Spacer.js.map +1 -1
  213. package/dist/react/core/layout/Stack.d.ts +4 -5
  214. package/dist/react/core/layout/Stack.js +127 -70
  215. package/dist/react/core/layout/Stack.js.map +1 -1
  216. package/dist/react/core/layout/responsive.d.ts +1 -2
  217. package/dist/react/core/layout/responsive.js +25 -19
  218. package/dist/react/core/layout/responsive.js.map +1 -1
  219. package/dist/react/core/layout/useBreakpoint.d.ts +1 -1
  220. package/dist/react/core/layout/useBreakpoint.js +119 -66
  221. package/dist/react/core/layout/useBreakpoint.js.map +1 -1
  222. package/dist/react/core/navigation/AppBar.d.ts +1 -2
  223. package/dist/react/core/navigation/AppBar.js +827 -805
  224. package/dist/react/core/navigation/AppBar.js.map +1 -1
  225. package/dist/react/core/navigation/Pagination.d.ts +2 -3
  226. package/dist/react/core/navigation/Pagination.js +207 -187
  227. package/dist/react/core/navigation/Pagination.js.map +1 -1
  228. package/dist/react/core/navigation/SideNav.d.ts +11 -5
  229. package/dist/react/core/navigation/SideNav.js +857 -602
  230. package/dist/react/core/navigation/SideNav.js.map +1 -1
  231. package/dist/react/core/navigation/Tabs.d.ts +0 -1
  232. package/dist/react/core/navigation/Tabs.js +113 -119
  233. package/dist/react/core/navigation/Tabs.js.map +1 -1
  234. package/dist/react/core/overlays/Popover.d.ts +2 -3
  235. package/dist/react/core/overlays/Popover.js +303 -282
  236. package/dist/react/core/overlays/Popover.js.map +1 -1
  237. package/dist/react/core/overlays/SidePanel.d.ts +1 -2
  238. package/dist/react/core/overlays/SidePanel.js +217 -212
  239. package/dist/react/core/overlays/SidePanel.js.map +1 -1
  240. package/dist/react/core/overlays/Tooltip.d.ts +1 -2
  241. package/dist/react/core/overlays/Tooltip.js +170 -176
  242. package/dist/react/core/overlays/Tooltip.js.map +1 -1
  243. package/dist/react/core/widgets/ActivityPlanner.d.ts +0 -1
  244. package/dist/react/core/widgets/ActivityPlanner.js +855 -517
  245. package/dist/react/core/widgets/ActivityPlanner.js.map +1 -1
  246. package/dist/react/core/widgets/Capture.d.ts +2 -3
  247. package/dist/react/core/widgets/Capture.js +965 -779
  248. package/dist/react/core/widgets/Capture.js.map +1 -1
  249. package/dist/react/core/widgets/ChatPanel.d.ts +16 -17
  250. package/dist/react/core/widgets/ChatPanel.js +1734 -1034
  251. package/dist/react/core/widgets/ChatPanel.js.map +1 -1
  252. package/dist/react/core/widgets/ColorPickerPanel.d.ts +0 -1
  253. package/dist/react/core/widgets/ColorPickerPanel.js +298 -287
  254. package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -1
  255. package/dist/react/core/widgets/CommandBuilder.d.ts +2 -3
  256. package/dist/react/core/widgets/CommandBuilder.js +624 -516
  257. package/dist/react/core/widgets/CommandBuilder.js.map +1 -1
  258. package/dist/react/core/widgets/ConnectionForm.d.ts +2 -3
  259. package/dist/react/core/widgets/ConnectionForm.js +528 -492
  260. package/dist/react/core/widgets/ConnectionForm.js.map +1 -1
  261. package/dist/react/core/widgets/FileExplorer.d.ts +3 -4
  262. package/dist/react/core/widgets/FileExplorer.js +617 -505
  263. package/dist/react/core/widgets/FileExplorer.js.map +1 -1
  264. package/dist/react/core/widgets/HexViewer.d.ts +2 -3
  265. package/dist/react/core/widgets/HexViewer.js +1353 -1091
  266. package/dist/react/core/widgets/HexViewer.js.map +1 -1
  267. package/dist/react/core/widgets/ImageFrame.d.ts +1 -2
  268. package/dist/react/core/widgets/ImageFrame.js +230 -193
  269. package/dist/react/core/widgets/ImageFrame.js.map +1 -1
  270. package/dist/react/core/widgets/ImageGallery.d.ts +2 -1
  271. package/dist/react/core/widgets/ImageGallery.js +380 -314
  272. package/dist/react/core/widgets/ImageGallery.js.map +1 -1
  273. package/dist/react/core/widgets/ImagePanel.d.ts +0 -1
  274. package/dist/react/core/widgets/ImagePanel.js +110 -101
  275. package/dist/react/core/widgets/ImagePanel.js.map +1 -1
  276. package/dist/react/core/widgets/LogViewer.d.ts +2 -3
  277. package/dist/react/core/widgets/LogViewer.js +711 -607
  278. package/dist/react/core/widgets/LogViewer.js.map +1 -1
  279. package/dist/react/core/widgets/MessageStream.d.ts +3 -4
  280. package/dist/react/core/widgets/MessageStream.js +514 -444
  281. package/dist/react/core/widgets/MessageStream.js.map +1 -1
  282. package/dist/react/core/widgets/MissionCalendar.d.ts +3 -4
  283. package/dist/react/core/widgets/MissionCalendar.js +1488 -1020
  284. package/dist/react/core/widgets/MissionCalendar.js.map +1 -1
  285. package/dist/react/core/widgets/PacketViewer.d.ts +2 -3
  286. package/dist/react/core/widgets/PacketViewer.js +550 -421
  287. package/dist/react/core/widgets/PacketViewer.js.map +1 -1
  288. package/dist/react/core/widgets/capture-placeholder.png.js +6 -5
  289. package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -1
  290. package/dist/react/hooks/index.d.ts +5 -5
  291. package/dist/react/hooks/useAccessWindows.d.ts +0 -1
  292. package/dist/react/hooks/useCompactMode.d.ts +1 -1
  293. package/dist/react/hooks/useCompactMode.js +104 -58
  294. package/dist/react/hooks/useCompactMode.js.map +1 -1
  295. package/dist/react/hooks/useGroundTrackHistory.d.ts +0 -1
  296. package/dist/react/hooks/useSimulationScene.d.ts +1 -2
  297. package/dist/react/hooks/useSimulationScene.js +481 -374
  298. package/dist/react/hooks/useSimulationScene.js.map +1 -1
  299. package/dist/react/index.d.ts +3 -3
  300. package/dist/react/panels/LayerControlPanel.d.ts +1 -2
  301. package/dist/react/panels/LayerControlPanel.js +223 -180
  302. package/dist/react/panels/LayerControlPanel.js.map +1 -1
  303. package/dist/react/panels/ObjectInventoryPanel.d.ts +2 -3
  304. package/dist/react/panels/ObjectInventoryPanel.js +315 -250
  305. package/dist/react/panels/ObjectInventoryPanel.js.map +1 -1
  306. package/dist/react/panels/index.d.ts +1 -1
  307. package/dist/react/panels/index.js +1 -6
  308. package/dist/react/shared/ErrorBoundary.d.ts +1 -2
  309. package/dist/react/shared/ErrorBoundary.js +170 -139
  310. package/dist/react/shared/ErrorBoundary.js.map +1 -1
  311. package/dist/react/shared/Skeleton.d.ts +1 -2
  312. package/dist/react/shared/Skeleton.js +300 -301
  313. package/dist/react/shared/Skeleton.js.map +1 -1
  314. package/dist/react/theme/ThemeProvider.d.ts +2 -321
  315. package/dist/react/theme/ThemeProvider.js +312 -939
  316. package/dist/react/theme/ThemeProvider.js.map +1 -1
  317. package/dist/react/theme/cardAccent.d.ts +1 -2
  318. package/dist/react/theme/cardAccent.js +196 -126
  319. package/dist/react/theme/cardAccent.js.map +1 -1
  320. package/dist/react/theme/config.d.ts +0 -1
  321. package/dist/react/theme/config.js +47 -25
  322. package/dist/react/theme/config.js.map +1 -1
  323. package/dist/react/theme/index.d.ts +2 -2
  324. package/dist/react/theme/index.js +1 -16
  325. package/dist/react/theme/types.d.ts +332 -0
  326. package/dist/react/theme/types.js +39 -0
  327. package/dist/react/theme/types.js.map +1 -0
  328. package/dist/react/types.d.ts +8 -8
  329. package/dist/react/types.js +147 -47
  330. package/dist/react/types.js.map +1 -1
  331. package/dist/react/utils/categoryPalette.d.ts +0 -1
  332. package/dist/react/utils/categoryPalette.js +91 -102
  333. package/dist/react/utils/categoryPalette.js.map +1 -1
  334. package/dist/react/utils/index.d.ts +5 -5
  335. package/dist/react/utils/index.js +457 -371
  336. package/dist/react/utils/index.js.map +1 -1
  337. package/dist/react/visualizations/EclipseTimerCard.d.ts +0 -1
  338. package/dist/react/visualizations/LinkBudgetCard.d.ts +0 -1
  339. package/dist/react/visualizations/NavBallCard.d.ts +0 -1
  340. package/dist/react/visualizations/PropulsionCard.d.ts +1 -2
  341. package/dist/react/visualizations/SensorFootprintCard.d.ts +1 -2
  342. package/dist/react/visualizations/ThermalHeatmapCard.d.ts +0 -1
  343. package/dist/react/visualizations/index.d.ts +3 -3
  344. package/dist/react.d.ts +2 -1
  345. package/dist/react.js +17 -221
  346. package/dist/shaders/atmosphere.frag.js +6 -5
  347. package/dist/shaders/atmosphere.frag.js.map +1 -1
  348. package/dist/shaders/atmosphere.vert.js +6 -5
  349. package/dist/shaders/atmosphere.vert.js.map +1 -1
  350. package/dist/shaders/stars.frag.js +6 -5
  351. package/dist/shaders/stars.frag.js.map +1 -1
  352. package/dist/shaders/stars.vert.js +6 -5
  353. package/dist/shaders/stars.vert.js.map +1 -1
  354. package/dist/style.css +217 -194
  355. package/dist/tokens/core.d.ts +159 -0
  356. package/dist/tokens/core.js +144 -0
  357. package/dist/tokens/core.js.map +1 -0
  358. package/dist/tokens/css-vars.d.ts +213 -2
  359. package/dist/tokens/css-vars.js +590 -227
  360. package/dist/tokens/css-vars.js.map +1 -1
  361. package/dist/tokens/index.d.ts +31 -228
  362. package/dist/tokens/index.js +281 -366
  363. package/dist/tokens/index.js.map +1 -1
  364. package/dist/tokens/palettes/astro.d.ts +129 -0
  365. package/dist/tokens/palettes/astro.js +112 -0
  366. package/dist/tokens/palettes/astro.js.map +1 -0
  367. package/dist/tokens/palettes/index.d.ts +288 -0
  368. package/dist/tokens/palettes/index.js +35 -0
  369. package/dist/tokens/palettes/index.js.map +1 -0
  370. package/dist/tokens/palettes/tailwind.d.ts +324 -0
  371. package/dist/tokens/palettes/tailwind.js +201 -0
  372. package/dist/tokens/palettes/tailwind.js.map +1 -0
  373. package/dist/tokens/palettes/zendir.d.ts +126 -0
  374. package/dist/tokens/palettes/zendir.js +92 -0
  375. package/dist/tokens/palettes/zendir.js.map +1 -0
  376. package/dist/tokens/themes.d.ts +30 -0
  377. package/dist/tokens/themes.js +704 -0
  378. package/dist/tokens/themes.js.map +1 -0
  379. package/dist/tokens/tokens.css +419 -41
  380. package/dist/types/index.d.ts +2 -2
  381. package/package.json +310 -313
  382. package/dist/index.js.map +0 -1
  383. package/dist/react/3d/index.js.map +0 -1
  384. package/dist/react/astro/index.js.map +0 -1
  385. package/dist/react/cards/index.js.map +0 -1
  386. package/dist/react/charts/index.js.map +0 -1
  387. package/dist/react/core/index.js.map +0 -1
  388. package/dist/react/panels/index.js.map +0 -1
  389. package/dist/react/theme/astro-tokens.d.ts +0 -153
  390. package/dist/react/theme/index.js.map +0 -1
  391. package/dist/react.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmDialog.js","sources":["../../../../src/react/core/feedback/ConfirmDialog.tsx"],"sourcesContent":["/**\n * @zendir/ui - Confirmation Dialog\n * \n * Convenience wrapper over Dialog for confirm/cancel actions.\n * Provides both a component API and a `useConfirm()` hook for imperative usage.\n * \n * Astro UX Compliance:\n * - Status-based alert colors\n * - Focus trap, escape to close\n * - Primary button on right (Astro convention)\n * \n * @example\n * ```tsx\n * // Hook API (imperative)\n * const confirm = useConfirm();\n * const ok = await confirm({\n * title: 'Reset Component',\n * message: 'This will reboot the spacecraft and suspend commands for 120 seconds.',\n * status: 'caution',\n * confirmLabel: 'Reset',\n * destructive: true,\n * });\n * if (ok) doReset();\n * \n * // Component API (declarative)\n * <ConfirmDialog\n * open={isOpen}\n * onClose={() => setOpen(false)}\n * onConfirm={handleReset}\n * title=\"Delete All Data?\"\n * message=\"This cannot be undone.\"\n * status=\"critical\"\n * destructive\n * />\n * ```\n */\n\nimport React, { memo, useState, useCallback, useRef, useEffect, useId, createContext, useContext } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useTheme } from '../../theme';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type ConfirmStatus = 'normal' | 'caution' | 'serious' | 'critical';\n\nexport interface ConfirmOptions {\n /** Dialog title */\n title: string;\n /** Description text (string or React node) */\n message?: React.ReactNode;\n /** Status level (determines icon/border color) */\n status?: ConfirmStatus;\n /** Confirm button label (default: \"Confirm\") */\n confirmLabel?: string;\n /** Cancel button label (default: \"Cancel\") */\n cancelLabel?: string;\n /** Destructive action styling (red confirm button) */\n destructive?: boolean;\n}\n\nexport interface ConfirmDialogProps extends ConfirmOptions {\n /** Open state */\n open: boolean;\n /** Close handler */\n onClose: () => void;\n /** Confirm handler */\n onConfirm: () => void;\n}\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const ConfirmDialog = memo(function ConfirmDialog({\n open,\n onClose,\n onConfirm,\n title,\n message,\n status,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n destructive = false,\n}: ConfirmDialogProps): React.ReactElement | null {\n const { tokens, theme } = useTheme();\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const dialogRef = useRef<HTMLDivElement>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n const titleId = useId();\n const messageId = useId();\n const CONFIRM_DIALOG_Z_INDEX = 2147483200;\n\n useEffect(() => {\n if (!open) return;\n\n previousActiveElement.current = document.activeElement as HTMLElement;\n document.body.style.overflow = 'hidden';\n\n const handleKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') {\n e.preventDefault();\n onClose();\n return;\n }\n\n if (e.key !== 'Tab') return;\n const root = dialogRef.current;\n if (!root) return;\n\n const focusableElements = root.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const focusable = Array.from(focusableElements).filter((el) => !el.hasAttribute('disabled'));\n if (focusable.length === 0) return;\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement as HTMLElement | null;\n\n if (e.shiftKey && active === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n const focusTimer = window.setTimeout(() => {\n confirmRef.current?.focus();\n }, 0);\n\n return () => {\n window.clearTimeout(focusTimer);\n document.removeEventListener('keydown', handleKeyDown);\n document.body.style.overflow = '';\n previousActiveElement.current?.focus();\n };\n }, [open, onClose]);\n\n if (!open) return null;\n if (typeof document === 'undefined') return null;\n \n const statusColors: Record<string, string> = {\n normal: tokens.colors.status.normal,\n caution: tokens.colors.status.caution,\n serious: tokens.colors.status.serious,\n critical: tokens.colors.status.critical,\n };\n \n const accentColor = status ? statusColors[status] : tokens.colors.accent.primary;\n const confirmBg = destructive ? tokens.colors.status.critical : tokens.colors.accent.primary;\n \n // Status icon shapes (Astro UX dual-coded)\n const statusIcon = status && (() => {\n const s = 32;\n const innerIcon = (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke={accentColor} strokeWidth=\"2.5\" strokeLinecap=\"round\">\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n const baseStyle: React.CSSProperties = {\n width: s,\n height: s,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n };\n switch (status) {\n case 'critical':\n // Triangle (using clip-path)\n return (\n <div style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n clipPath: 'polygon(50% 0%, 0% 100%, 100% 100%)',\n paddingTop: 8,\n }}>\n {innerIcon}\n </div>\n );\n case 'serious':\n // Diamond (rotated square)\n return (\n <div style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n transform: 'rotate(45deg)',\n }}>\n <div style={{ transform: 'rotate(-45deg)' }}>{innerIcon}</div>\n </div>\n );\n case 'caution':\n // Square (rounded)\n return (\n <div style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n borderRadius: '4px',\n }}>\n {innerIcon}\n </div>\n );\n default:\n // Circle (normal, standby, off)\n return (\n <div style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n borderRadius: '50%',\n }}>\n {innerIcon}\n </div>\n );\n }\n })();\n \n return createPortal((\n <>\n {/* Backdrop */}\n <div\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: CONFIRM_DIALOG_Z_INDEX,\n backgroundColor: isTransparentTheme ? `${tokens.colors.background.base}80` : `${tokens.colors.background.base}B3`,\n backdropFilter: 'blur(6px)',\n WebkitBackdropFilter: 'blur(6px)',\n animation: `zendir-confirm-backdrop 200ms ${tokens.animation.easing.default}`,\n }}\n onClick={onClose}\n />\n \n {/* Dialog */}\n <div\n ref={dialogRef}\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={message ? messageId : undefined}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: CONFIRM_DIALOG_Z_INDEX + 1,\n width: '100%',\n maxWidth: 'min(440px, calc(100vw - 32px))',\n backgroundColor: isTransparentTheme\n ? 'rgba(15, 12, 30, 0.9)'\n : tokens.colors.background.surface,\n border: `1px solid ${tokens.colors.border.default}`,\n borderRadius: tokens.borderRadius.lg,\n boxShadow: tokens.shadows.xl,\n fontFamily: tokens.typography.fontFamily.primary,\n animation: `zendir-confirm-enter 250ms ${tokens.animation.easing.default}`,\n overflow: 'hidden',\n ...(isTransparentTheme ? {\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n } : {}),\n }}\n >\n {/* Status accent bar */}\n {status && (\n <div style={{\n height: 3,\n backgroundColor: accentColor,\n width: '100%',\n }} />\n )}\n \n {/* Content */}\n <div style={{ padding: `${tokens.spacing.lg} ${tokens.spacing.lg} ${tokens.spacing.md}` }}>\n <div style={{ display: 'flex', gap: tokens.spacing.md, alignItems: 'flex-start' }}>\n {statusIcon}\n <div style={{ flex: 1 }}>\n <div\n id={titleId}\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.semibold,\n color: tokens.colors.text.primary,\n lineHeight: tokens.typography.lineHeight.tight,\n }}\n >\n {title}\n </div>\n {message && (\n <div\n id={messageId}\n style={{\n fontSize: tokens.typography.fontSize.sm,\n color: tokens.colors.text.secondary,\n marginTop: tokens.spacing.sm,\n lineHeight: tokens.typography.lineHeight.normal,\n }}\n >\n {message}\n </div>\n )}\n </div>\n </div>\n </div>\n \n {/* Actions — Astro UX: primary on right */}\n <div style={{\n display: 'flex',\n justifyContent: 'flex-end',\n gap: tokens.spacing.sm,\n padding: `${tokens.spacing.md} ${tokens.spacing.lg} ${tokens.spacing.lg}`,\n borderTop: tokens.borders.divider,\n }}>\n <button\n onClick={onClose}\n style={{\n padding: `0 ${tokens.spacing.md}`,\n minHeight: tokens.elementSize.lg,\n fontSize: tokens.typography.fontSize.sm,\n fontWeight: tokens.typography.fontWeight.medium,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.primary,\n backgroundColor: tokens.colors.background.base,\n border: `1px solid ${tokens.colors.border.muted}`,\n borderRadius: tokens.borderRadius.md,\n cursor: 'pointer',\n transition: tokens.animation.fast,\n }}\n >\n {cancelLabel}\n </button>\n <button\n ref={confirmRef}\n onClick={() => { onConfirm(); onClose(); }}\n style={{\n padding: `0 ${tokens.spacing.md}`,\n minHeight: tokens.elementSize.lg,\n fontSize: tokens.typography.fontSize.sm,\n fontWeight: tokens.typography.fontWeight.semibold,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.inverse || '#fff',\n backgroundColor: confirmBg,\n border: 'none',\n borderRadius: tokens.borderRadius.md,\n cursor: 'pointer',\n transition: tokens.animation.fast,\n boxShadow: `0 2px 8px ${confirmBg}40`,\n }}\n >\n {confirmLabel}\n </button>\n </div>\n </div>\n \n <style>{`\n @keyframes zendir-confirm-backdrop { from { opacity: 0; } to { opacity: 1; } }\n @keyframes zendir-confirm-enter {\n from { opacity: 0; transform: translate(-50%, -50%) scale(0.95); }\n to { opacity: 1; transform: translate(-50%, -50%) scale(1); }\n }\n `}</style>\n </>\n ), document.body);\n});\n\n// ─── useConfirm Hook ─────────────────────────────────────────────────────────\n\ninterface ConfirmState extends ConfirmOptions {\n resolve: (value: boolean) => void;\n}\n\nconst ConfirmContext = createContext<{\n requestConfirm: (options: ConfirmOptions) => Promise<boolean>;\n} | null>(null);\n\n/**\n * Imperative confirmation hook.\n * Must be used within `<ConfirmProvider>`.\n * \n * @example\n * ```tsx\n * const confirm = useConfirm();\n * const ok = await confirm({ title: 'Delete?', status: 'critical', destructive: true });\n * ```\n */\nexport function useConfirm(): (options: ConfirmOptions) => Promise<boolean> {\n const ctx = useContext(ConfirmContext);\n if (!ctx) throw new Error('useConfirm must be used within <ConfirmProvider>');\n return ctx.requestConfirm;\n}\n\n/**\n * Provider for the useConfirm() hook.\n * Renders the confirmation dialog as needed.\n */\nexport const ConfirmProvider = memo(function ConfirmProvider({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactElement {\n const [state, setState] = useState<ConfirmState | null>(null);\n \n const requestConfirm = useCallback((options: ConfirmOptions): Promise<boolean> => {\n return new Promise<boolean>((resolve) => {\n setState({ ...options, resolve });\n });\n }, []);\n \n const handleClose = useCallback(() => {\n state?.resolve(false);\n setState(null);\n }, [state]);\n \n const handleConfirm = useCallback(() => {\n state?.resolve(true);\n setState(null);\n }, [state]);\n \n return (\n <ConfirmContext.Provider value={{ requestConfirm }}>\n {children}\n {state && (\n <ConfirmDialog\n open={true}\n onClose={handleClose}\n onConfirm={handleConfirm}\n title={state.title}\n message={state.message}\n status={state.status}\n confirmLabel={state.confirmLabel}\n cancelLabel={state.cancelLabel}\n destructive={state.destructive}\n />\n )}\n </ConfirmContext.Provider>\n );\n});\n\nexport default ConfirmDialog;\n"],"names":["ConfirmDialog","ConfirmProvider"],"mappings":"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"}
1
+ {"version":3,"file":"ConfirmDialog.js","names":[],"sources":["../../../../src/react/core/feedback/ConfirmDialog.tsx"],"sourcesContent":["/**\n * @zendir/ui - Confirmation Dialog\n *\n * Convenience wrapper over Dialog for confirm/cancel actions.\n * Provides both a component API and a `useConfirm()` hook for imperative usage.\n *\n * Astro UX Compliance:\n * - Status-based alert colors\n * - Focus trap, escape to close\n * - Primary button on right (Astro convention)\n *\n * @example\n * ```tsx\n * // Hook API (imperative)\n * const confirm = useConfirm();\n * const ok = await confirm({\n * title: 'Reset Component',\n * message: 'This will reboot the spacecraft and suspend commands for 120 seconds.',\n * status: 'caution',\n * confirmLabel: 'Reset',\n * destructive: true,\n * });\n * if (ok) doReset();\n *\n * // Component API (declarative)\n * <ConfirmDialog\n * open={isOpen}\n * onClose={() => setOpen(false)}\n * onConfirm={handleReset}\n * title=\"Delete All Data?\"\n * message=\"This cannot be undone.\"\n * status=\"critical\"\n * destructive\n * />\n * ```\n */\n\nimport React, {\n memo,\n useState,\n useCallback,\n useRef,\n useEffect,\n useId,\n createContext,\n useContext,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useTheme } from \"../../theme\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type ConfirmStatus = \"normal\" | \"caution\" | \"serious\" | \"critical\";\n\nexport interface ConfirmOptions {\n /** Dialog title */\n title: string;\n /** Description text (string or React node) */\n message?: React.ReactNode;\n /** Status level (determines icon/border color) */\n status?: ConfirmStatus;\n /** Confirm button label (default: \"Confirm\") */\n confirmLabel?: string;\n /** Cancel button label (default: \"Cancel\") */\n cancelLabel?: string;\n /** Destructive action styling (red confirm button) */\n destructive?: boolean;\n}\n\nexport interface ConfirmDialogProps extends ConfirmOptions {\n /** Open state */\n open: boolean;\n /** Close handler */\n onClose: () => void;\n /** Confirm handler */\n onConfirm: () => void;\n}\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const ConfirmDialog = memo(function ConfirmDialog({\n open,\n onClose,\n onConfirm,\n title,\n message,\n status,\n confirmLabel = \"Confirm\",\n cancelLabel = \"Cancel\",\n destructive = false,\n}: ConfirmDialogProps): React.ReactElement | null {\n const { tokens, theme } = useTheme();\n const isTransparentTheme =\n theme === \"transparent\" ||\n theme === \"transparent-bold\" ||\n theme === \"transparent-minimal\";\n const dialogRef = useRef<HTMLDivElement>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n const titleId = useId();\n const messageId = useId();\n const CONFIRM_DIALOG_Z_INDEX = 2147483200;\n\n useEffect(() => {\n if (!open) return;\n\n previousActiveElement.current = document.activeElement as HTMLElement;\n document.body.style.overflow = \"hidden\";\n\n const handleKeyDown = (e: KeyboardEvent): void => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onClose();\n return;\n }\n\n if (e.key !== \"Tab\") return;\n const root = dialogRef.current;\n if (!root) return;\n\n const focusableElements = root.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n const focusable = Array.from(focusableElements).filter(\n (el) => !el.hasAttribute(\"disabled\"),\n );\n if (focusable.length === 0) return;\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement as HTMLElement | null;\n\n if (e.shiftKey && active === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n const focusTimer = window.setTimeout(() => {\n confirmRef.current?.focus();\n }, 0);\n\n return () => {\n window.clearTimeout(focusTimer);\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.body.style.overflow = \"\";\n previousActiveElement.current?.focus();\n };\n }, [open, onClose]);\n\n if (!open) return null;\n if (typeof document === \"undefined\") return null;\n\n const statusColors: Record<string, string> = {\n normal: tokens.colors.status.normal,\n caution: tokens.colors.status.caution,\n serious: tokens.colors.status.serious,\n critical: tokens.colors.status.critical,\n };\n\n const accentColor = status\n ? statusColors[status]\n : tokens.colors.accent.primary;\n const confirmBg = destructive\n ? tokens.colors.status.critical\n : tokens.colors.accent.primary;\n\n // Status icon shapes (Astro UX dual-coded)\n const statusIcon =\n status &&\n (() => {\n const s = 32;\n const innerIcon = (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={accentColor}\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n >\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n const baseStyle: React.CSSProperties = {\n width: s,\n height: s,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n };\n switch (status) {\n case \"critical\":\n // Triangle (using clip-path)\n return (\n <div\n style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n clipPath: \"polygon(50% 0%, 0% 100%, 100% 100%)\",\n paddingTop: 8,\n }}\n >\n {innerIcon}\n </div>\n );\n case \"serious\":\n // Diamond (rotated square)\n return (\n <div\n style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n transform: \"rotate(45deg)\",\n }}\n >\n <div style={{ transform: \"rotate(-45deg)\" }}>{innerIcon}</div>\n </div>\n );\n case \"caution\":\n // Square (rounded)\n return (\n <div\n style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n borderRadius: \"4px\",\n }}\n >\n {innerIcon}\n </div>\n );\n default:\n // Circle (normal, standby, off)\n return (\n <div\n style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n borderRadius: \"50%\",\n }}\n >\n {innerIcon}\n </div>\n );\n }\n })();\n\n return createPortal(\n <>\n {/* Backdrop */}\n <div\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: CONFIRM_DIALOG_Z_INDEX,\n backgroundColor: isTransparentTheme\n ? `${tokens.colors.background.base}80`\n : `${tokens.colors.background.base}B3`,\n backdropFilter: \"blur(6px)\",\n WebkitBackdropFilter: \"blur(6px)\",\n animation: `zendir-confirm-backdrop 200ms ${tokens.animation.easing.default}`,\n }}\n onClick={onClose}\n />\n\n {/* Dialog */}\n <div\n ref={dialogRef}\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={message ? messageId : undefined}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: \"fixed\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n zIndex: CONFIRM_DIALOG_Z_INDEX + 1,\n width: \"100%\",\n maxWidth: \"min(440px, calc(100vw - 32px))\",\n backgroundColor: isTransparentTheme\n ? \"rgba(15, 12, 30, 0.9)\"\n : tokens.colors.background.surface,\n border: `1px solid ${tokens.colors.border.default}`,\n borderRadius: tokens.borderRadius.lg,\n boxShadow: tokens.shadows.xl,\n fontFamily: tokens.typography.fontFamily.primary,\n animation: `zendir-confirm-enter 250ms ${tokens.animation.easing.default}`,\n overflow: \"hidden\",\n ...(isTransparentTheme\n ? {\n backdropFilter: \"blur(20px)\",\n WebkitBackdropFilter: \"blur(20px)\",\n }\n : {}),\n }}\n >\n {/* Status accent bar */}\n {status && (\n <div\n style={{\n height: 3,\n backgroundColor: accentColor,\n width: \"100%\",\n }}\n />\n )}\n\n {/* Content */}\n <div\n style={{\n padding: `${tokens.spacing.lg} ${tokens.spacing.lg} ${tokens.spacing.md}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n gap: tokens.spacing.md,\n alignItems: \"flex-start\",\n }}\n >\n {statusIcon}\n <div style={{ flex: 1 }}>\n <div\n id={titleId}\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.semibold,\n color: tokens.colors.text.primary,\n lineHeight: tokens.typography.lineHeight.tight,\n }}\n >\n {title}\n </div>\n {message && (\n <div\n id={messageId}\n style={{\n fontSize: tokens.typography.fontSize.sm,\n color: tokens.colors.text.secondary,\n marginTop: tokens.spacing.sm,\n lineHeight: tokens.typography.lineHeight.normal,\n }}\n >\n {message}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Actions — Astro UX: primary on right */}\n <div\n style={{\n display: \"flex\",\n justifyContent: \"flex-end\",\n gap: tokens.spacing.sm,\n padding: `${tokens.spacing.md} ${tokens.spacing.lg} ${tokens.spacing.lg}`,\n borderTop: tokens.borders.divider,\n }}\n >\n <button\n onClick={onClose}\n style={{\n padding: `0 ${tokens.spacing.md}`,\n minHeight: tokens.elementSize.lg,\n fontSize: tokens.typography.fontSize.sm,\n fontWeight: tokens.typography.fontWeight.medium,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.primary,\n backgroundColor: tokens.colors.background.base,\n border: `1px solid ${tokens.colors.border.muted}`,\n borderRadius: tokens.borderRadius.md,\n cursor: \"pointer\",\n transition: tokens.animation.fast,\n }}\n >\n {cancelLabel}\n </button>\n <button\n ref={confirmRef}\n onClick={() => {\n onConfirm();\n onClose();\n }}\n style={{\n padding: `0 ${tokens.spacing.md}`,\n minHeight: tokens.elementSize.lg,\n fontSize: tokens.typography.fontSize.sm,\n fontWeight: tokens.typography.fontWeight.semibold,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.inverse || \"#fff\",\n backgroundColor: confirmBg,\n border: \"none\",\n borderRadius: tokens.borderRadius.md,\n cursor: \"pointer\",\n transition: tokens.animation.fast,\n boxShadow: `0 2px 8px ${confirmBg}40`,\n }}\n >\n {confirmLabel}\n </button>\n </div>\n </div>\n\n <style>{`\n @keyframes zendir-confirm-backdrop { from { opacity: 0; } to { opacity: 1; } }\n @keyframes zendir-confirm-enter {\n from { opacity: 0; transform: translate(-50%, -50%) scale(0.95); }\n to { opacity: 1; transform: translate(-50%, -50%) scale(1); }\n }\n `}</style>\n </>,\n document.body,\n );\n});\n\n// ─── useConfirm Hook ─────────────────────────────────────────────────────────\n\ninterface ConfirmState extends ConfirmOptions {\n resolve: (value: boolean) => void;\n}\n\nconst ConfirmContext = createContext<{\n requestConfirm: (options: ConfirmOptions) => Promise<boolean>;\n} | null>(null);\n\n/**\n * Imperative confirmation hook.\n * Must be used within `<ConfirmProvider>`.\n *\n * @example\n * ```tsx\n * const confirm = useConfirm();\n * const ok = await confirm({ title: 'Delete?', status: 'critical', destructive: true });\n * ```\n */\nexport function useConfirm(): (options: ConfirmOptions) => Promise<boolean> {\n const ctx = useContext(ConfirmContext);\n if (!ctx) throw new Error(\"useConfirm must be used within <ConfirmProvider>\");\n return ctx.requestConfirm;\n}\n\n/**\n * Provider for the useConfirm() hook.\n * Renders the confirmation dialog as needed.\n */\nexport const ConfirmProvider = memo(function ConfirmProvider({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactElement {\n const [state, setState] = useState<ConfirmState | null>(null);\n\n const requestConfirm = useCallback(\n (options: ConfirmOptions): Promise<boolean> => {\n return new Promise<boolean>((resolve) => {\n setState({ ...options, resolve });\n });\n },\n [],\n );\n\n const handleClose = useCallback(() => {\n state?.resolve(false);\n setState(null);\n }, [state]);\n\n const handleConfirm = useCallback(() => {\n state?.resolve(true);\n setState(null);\n }, [state]);\n\n return (\n <ConfirmContext.Provider value={{ requestConfirm }}>\n {children}\n {state && (\n <ConfirmDialog\n open={true}\n onClose={handleClose}\n onConfirm={handleConfirm}\n title={state.title}\n message={state.message}\n status={state.status}\n confirmLabel={state.confirmLabel}\n cancelLabel={state.cancelLabel}\n destructive={state.destructive}\n />\n )}\n </ConfirmContext.Provider>\n );\n});\n\nexport default ConfirmDialog;\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { default as React } from 'react';
2
-
3
- export type DialogSize = 'small' | 'medium' | 'large' | 'fullscreen';
2
+ export type DialogSize = "small" | "medium" | "large" | "fullscreen";
4
3
  export interface DialogProps {
5
4
  /** Open state */
6
5
  open: boolean;
@@ -23,7 +22,7 @@ export interface DialogProps {
23
22
  }
24
23
  export interface DialogActionsProps {
25
24
  children: React.ReactNode;
26
- align?: 'left' | 'center' | 'right';
25
+ align?: "left" | "center" | "right";
27
26
  }
28
27
  declare const DialogActions: React.NamedExoticComponent<DialogActionsProps>;
29
28
  export declare const Dialog: React.NamedExoticComponent<DialogProps> & {
@@ -1,204 +1,196 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { memo, useRef, useId, useCallback, useEffect } from "react";
3
- import { createPortal } from "react-dom";
4
1
  import { useTheme } from "../../theme/ThemeProvider.js";
5
2
  import { classNames } from "../../utils/index.js";
6
- const DialogActions = memo(function DialogActions2({
7
- children,
8
- align = "right"
9
- }) {
10
- const { tokens } = useTheme();
11
- return /* @__PURE__ */ jsx(
12
- "div",
13
- {
14
- style: {
15
- display: "flex",
16
- justifyContent: align === "left" ? "flex-start" : align === "right" ? "flex-end" : "center",
17
- gap: tokens.spacing.sm,
18
- marginTop: tokens.spacing.lg,
19
- paddingTop: tokens.spacing.md,
20
- borderTop: tokens.borders.divider
21
- },
22
- children
23
- }
24
- );
3
+ import { memo, useCallback, useEffect, useId, useRef } from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { createPortal } from "react-dom";
6
+ //#region src/react/core/feedback/Dialog.tsx
7
+ /**
8
+ * @zendir/ui - Dialog/Modal Component
9
+ *
10
+ * Modal dialog following Astro UX Design System.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * <Dialog
15
+ * open={isOpen}
16
+ * onClose={() => setIsOpen(false)}
17
+ * title="Confirm Action"
18
+ * >
19
+ * <p>Are you sure you want to proceed?</p>
20
+ * <Dialog.Actions>
21
+ * <Button variant="secondary" onClick={() => setIsOpen(false)}>Cancel</Button>
22
+ * <Button onClick={handleConfirm}>Confirm</Button>
23
+ * </Dialog.Actions>
24
+ * </Dialog>
25
+ * ```
26
+ */
27
+ var DialogActions = memo(function DialogActions({ children, align = "right" }) {
28
+ const { tokens } = useTheme();
29
+ return /* @__PURE__ */ jsx("div", {
30
+ style: {
31
+ display: "flex",
32
+ justifyContent: align === "left" ? "flex-start" : align === "right" ? "flex-end" : "center",
33
+ gap: tokens.spacing.sm,
34
+ marginTop: tokens.spacing.lg,
35
+ paddingTop: tokens.spacing.md,
36
+ borderTop: tokens.borders.divider
37
+ },
38
+ children
39
+ });
25
40
  });
26
- const Dialog = memo(function Dialog2({
27
- open,
28
- onClose,
29
- title,
30
- size = "medium",
31
- showCloseButton = true,
32
- closeOnBackdropClick = true,
33
- closeOnEscape = true,
34
- children,
35
- className = ""
36
- }) {
37
- const { tokens, theme } = useTheme();
38
- const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
39
- const dialogRef = useRef(null);
40
- const previousActiveElement = useRef(null);
41
- const titleId = useId();
42
- const DIALOG_Z_INDEX = 2147483e3;
43
- const sizeConfig = {
44
- small: { width: "min(360px, calc(100vw - 32px))", maxHeight: "80vh" },
45
- medium: { width: "min(540px, calc(100vw - 32px))", maxHeight: "80vh" },
46
- large: { width: "min(800px, calc(100vw - 32px))", maxHeight: "90vh" },
47
- fullscreen: { width: "100vw", maxHeight: "100vh" }
48
- };
49
- const config = sizeConfig[size];
50
- const handleKeyDown = useCallback((e) => {
51
- if (closeOnEscape && e.key === "Escape") {
52
- onClose();
53
- }
54
- }, [closeOnEscape, onClose]);
55
- const handleKeyDownRef = useRef(handleKeyDown);
56
- handleKeyDownRef.current = handleKeyDown;
57
- useEffect(() => {
58
- if (!open) return void 0;
59
- previousActiveElement.current = document.activeElement;
60
- document.body.style.overflow = "hidden";
61
- const onKeyDown = (e) => handleKeyDownRef.current(e);
62
- document.addEventListener("keydown", onKeyDown);
63
- const focusTimer = setTimeout(() => {
64
- var _a, _b;
65
- if ((_a = dialogRef.current) == null ? void 0 : _a.contains(document.activeElement)) return;
66
- const focusable = (_b = dialogRef.current) == null ? void 0 : _b.querySelector(
67
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
68
- );
69
- focusable == null ? void 0 : focusable.focus();
70
- }, 0);
71
- return () => {
72
- var _a;
73
- clearTimeout(focusTimer);
74
- document.body.style.overflow = "";
75
- document.removeEventListener("keydown", onKeyDown);
76
- (_a = previousActiveElement.current) == null ? void 0 : _a.focus();
77
- };
78
- }, [open]);
79
- if (!open) return null;
80
- if (typeof document === "undefined") return null;
81
- return createPortal(/* @__PURE__ */ jsxs(
82
- "div",
83
- {
84
- className: classNames("zendir-dialog-backdrop", className),
85
- onClick: closeOnBackdropClick ? onClose : void 0,
86
- style: {
87
- position: "fixed",
88
- inset: 0,
89
- backgroundColor: isTransparentTheme ? `${tokens.colors.background.base}66` : `${tokens.colors.background.base}99`,
90
- backdropFilter: isTransparentTheme ? "blur(4px)" : void 0,
91
- WebkitBackdropFilter: isTransparentTheme ? "blur(4px)" : void 0,
92
- display: "flex",
93
- alignItems: size === "fullscreen" ? "stretch" : "center",
94
- justifyContent: "center",
95
- zIndex: DIALOG_Z_INDEX,
96
- animation: `zendir-dialog-backdrop ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default} both`
97
- },
98
- children: [
99
- /* @__PURE__ */ jsxs(
100
- "div",
101
- {
102
- ref: dialogRef,
103
- role: "dialog",
104
- "aria-modal": "true",
105
- "aria-labelledby": title ? titleId : void 0,
106
- className: "zendir-dialog",
107
- onClick: (e) => e.stopPropagation(),
108
- style: {
109
- width: config.width,
110
- maxWidth: size === "fullscreen" ? "100vw" : "calc(100vw - 32px)",
111
- maxHeight: config.maxHeight,
112
- backgroundColor: isTransparentTheme ? "rgba(139, 92, 246, 0.08)" : tokens.colors.background.surface,
113
- ...isTransparentTheme && { backdropFilter: "blur(16px)", WebkitBackdropFilter: "blur(16px)", border: "1px solid rgba(139, 92, 246, 0.2)" },
114
- borderRadius: size === "fullscreen" ? 0 : tokens.borderRadius.lg,
115
- boxShadow: tokens.shadows.xl,
116
- display: "flex",
117
- flexDirection: "column",
118
- overflow: "hidden",
119
- animation: `zendir-dialog-panel ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default} both`
120
- },
121
- children: [
122
- (title || showCloseButton) && /* @__PURE__ */ jsxs(
123
- "div",
124
- {
125
- style: {
126
- display: "flex",
127
- alignItems: "center",
128
- justifyContent: "space-between",
129
- padding: `${tokens.spacing.md} ${tokens.spacing.lg}`,
130
- borderBottom: tokens.borders.divider
131
- },
132
- children: [
133
- title && /* @__PURE__ */ jsx(
134
- "h2",
135
- {
136
- id: titleId,
137
- style: {
138
- margin: 0,
139
- fontSize: tokens.typography.fontSize.lg,
140
- fontWeight: tokens.typography.fontWeight.semibold,
141
- color: tokens.colors.text.primary
142
- },
143
- children: title
144
- }
145
- ),
146
- showCloseButton && /* @__PURE__ */ jsx(
147
- "button",
148
- {
149
- type: "button",
150
- onClick: onClose,
151
- "aria-label": "Close dialog",
152
- style: {
153
- padding: tokens.spacing.sm,
154
- minWidth: 44,
155
- minHeight: 44,
156
- backgroundColor: "transparent",
157
- border: "none",
158
- borderRadius: tokens.borderRadius.sm,
159
- cursor: "pointer",
160
- color: tokens.colors.text.muted ?? tokens.colors.text.tertiary,
161
- display: "flex",
162
- alignItems: "center",
163
- justifyContent: "center",
164
- transition: `color ${tokens.animation.fast}`
165
- },
166
- onMouseEnter: (e) => {
167
- e.currentTarget.style.color = tokens.colors.text.primary;
168
- },
169
- onMouseLeave: (e) => {
170
- e.currentTarget.style.color = tokens.colors.text.muted ?? tokens.colors.text.tertiary;
171
- },
172
- children: /* @__PURE__ */ jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) })
173
- }
174
- )
175
- ]
176
- }
177
- ),
178
- /* @__PURE__ */ jsx(
179
- "div",
180
- {
181
- style: {
182
- flex: 1,
183
- padding: tokens.spacing.lg,
184
- overflow: "auto"
185
- },
186
- children
187
- }
188
- )
189
- ]
190
- }
191
- ),
192
- /* @__PURE__ */ jsx("style", { children: `
41
+ var Dialog = memo(function Dialog({ open, onClose, title, size = "medium", showCloseButton = true, closeOnBackdropClick = true, closeOnEscape = true, children, className = "" }) {
42
+ const { tokens, theme } = useTheme();
43
+ const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
44
+ const dialogRef = useRef(null);
45
+ const previousActiveElement = useRef(null);
46
+ const titleId = useId();
47
+ const DIALOG_Z_INDEX = 2147483e3;
48
+ const config = {
49
+ small: {
50
+ width: "min(360px, calc(100vw - 32px))",
51
+ maxHeight: "80vh"
52
+ },
53
+ medium: {
54
+ width: "min(540px, calc(100vw - 32px))",
55
+ maxHeight: "80vh"
56
+ },
57
+ large: {
58
+ width: "min(800px, calc(100vw - 32px))",
59
+ maxHeight: "90vh"
60
+ },
61
+ fullscreen: {
62
+ width: "100vw",
63
+ maxHeight: "100vh"
64
+ }
65
+ }[size];
66
+ const handleKeyDown = useCallback((e) => {
67
+ if (closeOnEscape && e.key === "Escape") onClose();
68
+ }, [closeOnEscape, onClose]);
69
+ const handleKeyDownRef = useRef(handleKeyDown);
70
+ handleKeyDownRef.current = handleKeyDown;
71
+ useEffect(() => {
72
+ if (!open) return void 0;
73
+ previousActiveElement.current = document.activeElement;
74
+ document.body.style.overflow = "hidden";
75
+ const onKeyDown = (e) => handleKeyDownRef.current(e);
76
+ document.addEventListener("keydown", onKeyDown);
77
+ const focusTimer = setTimeout(() => {
78
+ if (dialogRef.current?.contains(document.activeElement)) return;
79
+ (dialogRef.current?.querySelector("button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])"))?.focus();
80
+ }, 0);
81
+ return () => {
82
+ clearTimeout(focusTimer);
83
+ document.body.style.overflow = "";
84
+ document.removeEventListener("keydown", onKeyDown);
85
+ previousActiveElement.current?.focus();
86
+ };
87
+ }, [open]);
88
+ if (!open) return null;
89
+ if (typeof document === "undefined") return null;
90
+ return createPortal(/* @__PURE__ */ jsxs("div", {
91
+ className: classNames("zendir-dialog-backdrop", className),
92
+ onClick: closeOnBackdropClick ? onClose : void 0,
93
+ style: {
94
+ position: "fixed",
95
+ inset: 0,
96
+ backgroundColor: isTransparentTheme ? `${tokens.colors.background.base}66` : `${tokens.colors.background.base}99`,
97
+ backdropFilter: isTransparentTheme ? "blur(4px)" : void 0,
98
+ WebkitBackdropFilter: isTransparentTheme ? "blur(4px)" : void 0,
99
+ display: "flex",
100
+ alignItems: size === "fullscreen" ? "stretch" : "center",
101
+ justifyContent: "center",
102
+ zIndex: DIALOG_Z_INDEX,
103
+ animation: `zendir-dialog-backdrop ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default} both`
104
+ },
105
+ children: [/* @__PURE__ */ jsxs("div", {
106
+ ref: dialogRef,
107
+ role: "dialog",
108
+ "aria-modal": "true",
109
+ "aria-labelledby": title ? titleId : void 0,
110
+ className: "zendir-dialog",
111
+ onClick: (e) => e.stopPropagation(),
112
+ style: {
113
+ width: config.width,
114
+ maxWidth: size === "fullscreen" ? "100vw" : "calc(100vw - 32px)",
115
+ maxHeight: config.maxHeight,
116
+ backgroundColor: isTransparentTheme ? `${tokens.colors.accent.primary}14` : tokens.colors.background.surface,
117
+ ...isTransparentTheme && {
118
+ backdropFilter: "blur(16px)",
119
+ WebkitBackdropFilter: "blur(16px)",
120
+ border: `1px solid ${tokens.colors.accent.primary}33`
121
+ },
122
+ borderRadius: size === "fullscreen" ? 0 : tokens.borderRadius.lg,
123
+ boxShadow: tokens.shadows.xl,
124
+ display: "flex",
125
+ flexDirection: "column",
126
+ overflow: "hidden",
127
+ animation: `zendir-dialog-panel ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default} both`
128
+ },
129
+ children: [(title || showCloseButton) && /* @__PURE__ */ jsxs("div", {
130
+ style: {
131
+ display: "flex",
132
+ alignItems: "center",
133
+ justifyContent: "space-between",
134
+ padding: `${tokens.spacing.md} ${tokens.spacing.lg}`,
135
+ borderBottom: tokens.borders.divider
136
+ },
137
+ children: [title && /* @__PURE__ */ jsx("h2", {
138
+ id: titleId,
139
+ style: {
140
+ margin: 0,
141
+ fontSize: tokens.typography.fontSize.lg,
142
+ fontWeight: tokens.typography.fontWeight.semibold,
143
+ color: tokens.colors.text.primary
144
+ },
145
+ children: title
146
+ }), showCloseButton && /* @__PURE__ */ jsx("button", {
147
+ type: "button",
148
+ onClick: onClose,
149
+ "aria-label": "Close dialog",
150
+ style: {
151
+ padding: tokens.spacing.sm,
152
+ minWidth: 44,
153
+ minHeight: 44,
154
+ backgroundColor: "transparent",
155
+ border: "none",
156
+ borderRadius: tokens.borderRadius.sm,
157
+ cursor: "pointer",
158
+ color: tokens.colors.text.muted ?? tokens.colors.text.tertiary,
159
+ display: "flex",
160
+ alignItems: "center",
161
+ justifyContent: "center",
162
+ transition: `color ${tokens.animation.fast}`
163
+ },
164
+ onMouseEnter: (e) => {
165
+ e.currentTarget.style.color = tokens.colors.text.primary;
166
+ },
167
+ onMouseLeave: (e) => {
168
+ e.currentTarget.style.color = tokens.colors.text.muted ?? tokens.colors.text.tertiary;
169
+ },
170
+ children: /* @__PURE__ */ jsx("svg", {
171
+ width: "24",
172
+ height: "24",
173
+ viewBox: "0 0 24 24",
174
+ fill: "currentColor",
175
+ children: /* @__PURE__ */ jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })
176
+ })
177
+ })]
178
+ }), /* @__PURE__ */ jsx("div", {
179
+ style: {
180
+ flex: 1,
181
+ padding: tokens.spacing.lg,
182
+ overflow: "auto"
183
+ },
184
+ children
185
+ })]
186
+ }), /* @__PURE__ */ jsx("style", { children: `
193
187
  @keyframes zendir-dialog-backdrop { from { opacity: 0; } to { opacity: 1; } }
194
188
  @keyframes zendir-dialog-panel { from { transform: scale(0.96); opacity: 0; } to { transform: scale(1); opacity: 1; } }
195
- ` })
196
- ]
197
- }
198
- ), document.body);
189
+ ` })]
190
+ }), document.body);
199
191
  });
200
192
  Dialog.Actions = DialogActions;
201
- export {
202
- Dialog
203
- };
204
- //# sourceMappingURL=Dialog.js.map
193
+ //#endregion
194
+ export { Dialog, Dialog as default };
195
+
196
+ //# sourceMappingURL=Dialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.js","sources":["../../../../src/react/core/feedback/Dialog.tsx"],"sourcesContent":["/**\n * @zendir/ui - Dialog/Modal Component\n * \n * Modal dialog following Astro UX Design System.\n * \n * @example\n * ```tsx\n * <Dialog\n * open={isOpen}\n * onClose={() => setIsOpen(false)}\n * title=\"Confirm Action\"\n * >\n * <p>Are you sure you want to proceed?</p>\n * <Dialog.Actions>\n * <Button variant=\"secondary\" onClick={() => setIsOpen(false)}>Cancel</Button>\n * <Button onClick={handleConfirm}>Confirm</Button>\n * </Dialog.Actions>\n * </Dialog>\n * ```\n */\n\nimport React, { memo, useEffect, useRef, useCallback, useId } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useTheme } from '../../theme';\nimport { classNames } from '../../utils';\n\nexport type DialogSize = 'small' | 'medium' | 'large' | 'fullscreen';\n\nexport interface DialogProps {\n /** Open state */\n open: boolean;\n /** Close handler */\n onClose: () => void;\n /** Dialog title */\n title?: string;\n /** Size variant */\n size?: DialogSize;\n /** Show close button */\n showCloseButton?: boolean;\n /** Close on backdrop click */\n closeOnBackdropClick?: boolean;\n /** Close on escape key */\n closeOnEscape?: boolean;\n /** Children */\n children: React.ReactNode;\n /** Custom className */\n className?: string;\n}\n\nexport interface DialogActionsProps {\n children: React.ReactNode;\n align?: 'left' | 'center' | 'right';\n}\n\nconst DialogActions = memo(function DialogActions({\n children,\n align = 'right',\n}: DialogActionsProps): React.ReactElement {\n const { tokens } = useTheme();\n \n return (\n <div\n style={{\n display: 'flex',\n justifyContent: align === 'left' ? 'flex-start' : align === 'right' ? 'flex-end' : 'center',\n gap: tokens.spacing.sm,\n marginTop: tokens.spacing.lg,\n paddingTop: tokens.spacing.md,\n borderTop: tokens.borders.divider,\n }}\n >\n {children}\n </div>\n );\n});\n\nexport const Dialog = memo(function Dialog({\n open,\n onClose,\n title,\n size = 'medium',\n showCloseButton = true,\n closeOnBackdropClick = true,\n closeOnEscape = true,\n children,\n className = '',\n}: DialogProps): React.ReactElement | null {\n const { tokens, theme } = useTheme();\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const dialogRef = useRef<HTMLDivElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n const titleId = useId();\n const DIALOG_Z_INDEX = 2147483000;\n \n const sizeConfig = {\n small: { width: 'min(360px, calc(100vw - 32px))', maxHeight: '80vh' },\n medium: { width: 'min(540px, calc(100vw - 32px))', maxHeight: '80vh' },\n large: { width: 'min(800px, calc(100vw - 32px))', maxHeight: '90vh' },\n fullscreen: { width: '100vw', maxHeight: '100vh' },\n };\n const config = sizeConfig[size];\n \n // Handle escape key. Kept in a ref so the focus-trap effect below can\n // depend on `open` ALONE: if the effect re-ran whenever `onClose` changed\n // identity (e.g. a parent passing an inline arrow that re-renders on a\n // status poll), it would re-fire the focus() call on every render and pull\n // focus out of whatever the user was typing — making inputs untypable.\n const handleKeyDown = useCallback((e: KeyboardEvent) => {\n if (closeOnEscape && e.key === 'Escape') {\n onClose();\n }\n }, [closeOnEscape, onClose]);\n const handleKeyDownRef = useRef(handleKeyDown);\n handleKeyDownRef.current = handleKeyDown;\n\n // Focus trap and escape key — runs only on open/close transitions.\n useEffect(() => {\n if (!open) return undefined;\n\n previousActiveElement.current = document.activeElement as HTMLElement;\n document.body.style.overflow = 'hidden';\n const onKeyDown = (e: KeyboardEvent) => handleKeyDownRef.current(e);\n document.addEventListener('keydown', onKeyDown);\n\n // Move focus into the dialog once — but honour a child that already\n // grabbed it (e.g. an Input with autoFocus). Without this guard we'd\n // override the intended initial focus and land on the first focusable,\n // which is usually the close button.\n const focusTimer = setTimeout(() => {\n if (dialogRef.current?.contains(document.activeElement)) return;\n const focusable = dialogRef.current?.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n focusable?.focus();\n }, 0);\n\n return () => {\n clearTimeout(focusTimer);\n document.body.style.overflow = '';\n document.removeEventListener('keydown', onKeyDown);\n previousActiveElement.current?.focus();\n };\n }, [open]);\n \n if (!open) return null;\n if (typeof document === 'undefined') return null;\n\n return createPortal((\n <div\n className={classNames('zendir-dialog-backdrop', className)}\n onClick={closeOnBackdropClick ? onClose : undefined}\n style={{\n position: 'fixed',\n inset: 0,\n backgroundColor: isTransparentTheme ? `${tokens.colors.background.base}66` : `${tokens.colors.background.base}99`,\n backdropFilter: isTransparentTheme ? 'blur(4px)' : undefined,\n WebkitBackdropFilter: isTransparentTheme ? 'blur(4px)' : undefined,\n display: 'flex',\n alignItems: size === 'fullscreen' ? 'stretch' : 'center',\n justifyContent: 'center',\n zIndex: DIALOG_Z_INDEX,\n animation: `zendir-dialog-backdrop ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default} both`,\n }}\n >\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n className=\"zendir-dialog\"\n onClick={(e) => e.stopPropagation()}\n style={{\n width: config.width,\n maxWidth: size === 'fullscreen' ? '100vw' : 'calc(100vw - 32px)',\n maxHeight: config.maxHeight,\n backgroundColor: isTransparentTheme ? 'rgba(139, 92, 246, 0.08)' : tokens.colors.background.surface,\n ...(isTransparentTheme && { backdropFilter: 'blur(16px)', WebkitBackdropFilter: 'blur(16px)', border: '1px solid rgba(139, 92, 246, 0.2)' }),\n borderRadius: size === 'fullscreen' ? 0 : tokens.borderRadius.lg,\n boxShadow: tokens.shadows.xl,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n animation: `zendir-dialog-panel ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default} both`,\n }}\n >\n {/* Header */}\n {(title || showCloseButton) && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: `${tokens.spacing.md} ${tokens.spacing.lg}`,\n borderBottom: tokens.borders.divider,\n }}\n >\n {title && (\n <h2\n id={titleId}\n style={{\n margin: 0,\n fontSize: tokens.typography.fontSize.lg,\n fontWeight: tokens.typography.fontWeight.semibold,\n color: tokens.colors.text.primary,\n }}\n >\n {title}\n </h2>\n )}\n {showCloseButton && (\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close dialog\"\n style={{\n padding: tokens.spacing.sm,\n minWidth: 44,\n minHeight: 44,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: tokens.borderRadius.sm,\n cursor: 'pointer',\n color: tokens.colors.text.muted ?? tokens.colors.text.tertiary,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: `color ${tokens.animation.fast}`,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.color = tokens.colors.text.primary;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.color = tokens.colors.text.muted ?? tokens.colors.text.tertiary;\n }}\n >\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />\n </svg>\n </button>\n )}\n </div>\n )}\n \n {/* Content */}\n <div\n style={{\n flex: 1,\n padding: tokens.spacing.lg,\n overflow: 'auto',\n }}\n >\n {children}\n </div>\n </div>\n \n <style>\n {`\n @keyframes zendir-dialog-backdrop { from { opacity: 0; } to { opacity: 1; } }\n @keyframes zendir-dialog-panel { from { transform: scale(0.96); opacity: 0; } to { transform: scale(1); opacity: 1; } }\n `}\n </style>\n </div>\n ), document.body);\n}) as React.NamedExoticComponent<DialogProps> & {\n Actions: typeof DialogActions;\n};\n\n// Attach subcomponent\n(Dialog as any).Actions = DialogActions;\n\nexport default Dialog;\n"],"names":["DialogActions","Dialog"],"mappings":"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"}
1
+ {"version":3,"file":"Dialog.js","names":[],"sources":["../../../../src/react/core/feedback/Dialog.tsx"],"sourcesContent":["/**\n * @zendir/ui - Dialog/Modal Component\n *\n * Modal dialog following Astro UX Design System.\n *\n * @example\n * ```tsx\n * <Dialog\n * open={isOpen}\n * onClose={() => setIsOpen(false)}\n * title=\"Confirm Action\"\n * >\n * <p>Are you sure you want to proceed?</p>\n * <Dialog.Actions>\n * <Button variant=\"secondary\" onClick={() => setIsOpen(false)}>Cancel</Button>\n * <Button onClick={handleConfirm}>Confirm</Button>\n * </Dialog.Actions>\n * </Dialog>\n * ```\n */\n\nimport React, { memo, useEffect, useRef, useCallback, useId } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useTheme } from \"../../theme\";\nimport { classNames } from \"../../utils\";\n\nexport type DialogSize = \"small\" | \"medium\" | \"large\" | \"fullscreen\";\n\nexport interface DialogProps {\n /** Open state */\n open: boolean;\n /** Close handler */\n onClose: () => void;\n /** Dialog title */\n title?: string;\n /** Size variant */\n size?: DialogSize;\n /** Show close button */\n showCloseButton?: boolean;\n /** Close on backdrop click */\n closeOnBackdropClick?: boolean;\n /** Close on escape key */\n closeOnEscape?: boolean;\n /** Children */\n children: React.ReactNode;\n /** Custom className */\n className?: string;\n}\n\nexport interface DialogActionsProps {\n children: React.ReactNode;\n align?: \"left\" | \"center\" | \"right\";\n}\n\nconst DialogActions = memo(function DialogActions({\n children,\n align = \"right\",\n}: DialogActionsProps): React.ReactElement {\n const { tokens } = useTheme();\n\n return (\n <div\n style={{\n display: \"flex\",\n justifyContent:\n align === \"left\"\n ? \"flex-start\"\n : align === \"right\"\n ? \"flex-end\"\n : \"center\",\n gap: tokens.spacing.sm,\n marginTop: tokens.spacing.lg,\n paddingTop: tokens.spacing.md,\n borderTop: tokens.borders.divider,\n }}\n >\n {children}\n </div>\n );\n});\n\nexport const Dialog = memo(function Dialog({\n open,\n onClose,\n title,\n size = \"medium\",\n showCloseButton = true,\n closeOnBackdropClick = true,\n closeOnEscape = true,\n children,\n className = \"\",\n}: DialogProps): React.ReactElement | null {\n const { tokens, theme } = useTheme();\n const isTransparentTheme =\n theme === \"transparent\" ||\n theme === \"transparent-bold\" ||\n theme === \"transparent-minimal\";\n const dialogRef = useRef<HTMLDivElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n const titleId = useId();\n const DIALOG_Z_INDEX = 2147483000;\n\n const sizeConfig = {\n small: { width: \"min(360px, calc(100vw - 32px))\", maxHeight: \"80vh\" },\n medium: { width: \"min(540px, calc(100vw - 32px))\", maxHeight: \"80vh\" },\n large: { width: \"min(800px, calc(100vw - 32px))\", maxHeight: \"90vh\" },\n fullscreen: { width: \"100vw\", maxHeight: \"100vh\" },\n };\n const config = sizeConfig[size];\n\n // Handle escape key. Kept in a ref so the focus-trap effect below can\n // depend on `open` ALONE: if the effect re-ran whenever `onClose` changed\n // identity (e.g. a parent passing an inline arrow that re-renders on a\n // status poll), it would re-fire the focus() call on every render and pull\n // focus out of whatever the user was typing — making inputs untypable.\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (closeOnEscape && e.key === \"Escape\") {\n onClose();\n }\n },\n [closeOnEscape, onClose],\n );\n const handleKeyDownRef = useRef(handleKeyDown);\n handleKeyDownRef.current = handleKeyDown;\n\n // Focus trap and escape key — runs only on open/close transitions.\n useEffect(() => {\n if (!open) return undefined;\n\n previousActiveElement.current = document.activeElement as HTMLElement;\n document.body.style.overflow = \"hidden\";\n const onKeyDown = (e: KeyboardEvent) => handleKeyDownRef.current(e);\n document.addEventListener(\"keydown\", onKeyDown);\n\n // Move focus into the dialog once — but honour a child that already\n // grabbed it (e.g. an Input with autoFocus). Without this guard we'd\n // override the intended initial focus and land on the first focusable,\n // which is usually the close button.\n const focusTimer = setTimeout(() => {\n if (dialogRef.current?.contains(document.activeElement)) return;\n const focusable = dialogRef.current?.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n focusable?.focus();\n }, 0);\n\n return () => {\n clearTimeout(focusTimer);\n document.body.style.overflow = \"\";\n document.removeEventListener(\"keydown\", onKeyDown);\n previousActiveElement.current?.focus();\n };\n }, [open]);\n\n if (!open) return null;\n if (typeof document === \"undefined\") return null;\n\n return createPortal(\n <div\n className={classNames(\"zendir-dialog-backdrop\", className)}\n onClick={closeOnBackdropClick ? onClose : undefined}\n style={{\n position: \"fixed\",\n inset: 0,\n backgroundColor: isTransparentTheme\n ? `${tokens.colors.background.base}66`\n : `${tokens.colors.background.base}99`,\n backdropFilter: isTransparentTheme ? \"blur(4px)\" : undefined,\n WebkitBackdropFilter: isTransparentTheme ? \"blur(4px)\" : undefined,\n display: \"flex\",\n alignItems: size === \"fullscreen\" ? \"stretch\" : \"center\",\n justifyContent: \"center\",\n zIndex: DIALOG_Z_INDEX,\n animation: `zendir-dialog-backdrop ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default} both`,\n }}\n >\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n className=\"zendir-dialog\"\n onClick={(e) => e.stopPropagation()}\n style={{\n width: config.width,\n maxWidth: size === \"fullscreen\" ? \"100vw\" : \"calc(100vw - 32px)\",\n maxHeight: config.maxHeight,\n backgroundColor: isTransparentTheme\n ? `${tokens.colors.accent.primary}14`\n : tokens.colors.background.surface,\n ...(isTransparentTheme && {\n backdropFilter: \"blur(16px)\",\n WebkitBackdropFilter: \"blur(16px)\",\n border: `1px solid ${tokens.colors.accent.primary}33`,\n }),\n borderRadius: size === \"fullscreen\" ? 0 : tokens.borderRadius.lg,\n boxShadow: tokens.shadows.xl,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n animation: `zendir-dialog-panel ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default} both`,\n }}\n >\n {/* Header */}\n {(title || showCloseButton) && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: `${tokens.spacing.md} ${tokens.spacing.lg}`,\n borderBottom: tokens.borders.divider,\n }}\n >\n {title && (\n <h2\n id={titleId}\n style={{\n margin: 0,\n fontSize: tokens.typography.fontSize.lg,\n fontWeight: tokens.typography.fontWeight.semibold,\n color: tokens.colors.text.primary,\n }}\n >\n {title}\n </h2>\n )}\n {showCloseButton && (\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close dialog\"\n style={{\n padding: tokens.spacing.sm,\n minWidth: 44,\n minHeight: 44,\n backgroundColor: \"transparent\",\n border: \"none\",\n borderRadius: tokens.borderRadius.sm,\n cursor: \"pointer\",\n color:\n tokens.colors.text.muted ?? tokens.colors.text.tertiary,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: `color ${tokens.animation.fast}`,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.color = tokens.colors.text.primary;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.color =\n tokens.colors.text.muted ?? tokens.colors.text.tertiary;\n }}\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />\n </svg>\n </button>\n )}\n </div>\n )}\n\n {/* Content */}\n <div\n style={{\n flex: 1,\n padding: tokens.spacing.lg,\n overflow: \"auto\",\n }}\n >\n {children}\n </div>\n </div>\n\n <style>\n {`\n @keyframes zendir-dialog-backdrop { from { opacity: 0; } to { opacity: 1; } }\n @keyframes zendir-dialog-panel { from { transform: scale(0.96); opacity: 0; } to { transform: scale(1); opacity: 1; } }\n `}\n </style>\n </div>,\n document.body,\n );\n}) as React.NamedExoticComponent<DialogProps> & {\n Actions: typeof DialogActions;\n};\n\n// Attach subcomponent\n(Dialog as any).Actions = DialogActions;\n\nexport default Dialog;\n"],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  import { default as React } from 'react';
2
-
3
- export type ToastStatus = 'normal' | 'standby' | 'caution' | 'serious' | 'critical' | 'off';
4
- export type ToastPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';
2
+ export type ToastStatus = "normal" | "standby" | "caution" | "serious" | "critical" | "off";
3
+ export type ToastPosition = "top-right" | "top-left" | "bottom-right" | "bottom-left" | "top-center" | "bottom-center";
5
4
  export interface ToastOptions {
6
5
  /** Status level (determines color) */
7
6
  status?: ToastStatus;