@zendir/ui 0.5.0 → 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 +20 -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 -571
  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 +5 -6
  229. package/dist/react/core/navigation/SideNav.js +855 -629
  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":"Button.js","sources":["../../../../src/react/core/inputs/Button.tsx"],"sourcesContent":["/**\n * @zendir/ui - Button Component\n * \n * Enterprise-grade button following Astro UX Design System with Zendir purple accents.\n * \n * Astro UX Compliance:\n * - Three visual variants: primary, secondary, borderless\n * - Size variants: small, medium, large\n * - Sentence case capitalization\n * - Focus ring for accessibility (WCAG 2.1 AA)\n * - Right-align in button groups (primary on right)\n * \n * Zendir Enhancements:\n * - Purple accent colors\n * - Smooth micro-interactions\n * - Subtle glow effects\n * - Modern glassmorphism hover states\n * \n * @example\n * ```tsx\n * <Button>Primary Action</Button>\n * <Button variant=\"secondary\">Cancel</Button>\n * <Button variant=\"borderless\" icon={<Icon name=\"settings\" />}>Settings</Button>\n * <Button loading>Saving...</Button>\n * ```\n */\n\nimport React, { memo, forwardRef, useState, useMemo, useRef, useLayoutEffect, useCallback } from 'react';\nimport ReactDOM from 'react-dom';\nimport { useTheme } from '../../theme';\nimport { classNames, safeAccentText } from '../../utils';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'borderless';\nexport type ButtonSize = 'small' | 'medium' | 'large';\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual variant */\n variant?: ButtonVariant;\n /** Size variant */\n size?: ButtonSize;\n /** Icon to display before text */\n icon?: React.ReactNode;\n /** Icon to display after text */\n iconEnd?: React.ReactNode;\n /** Show loading spinner */\n loading?: boolean;\n /** Full width button */\n fullWidth?: boolean;\n /** Tooltip text (shows on hover) */\n tooltip?: string;\n /** Custom className */\n className?: string;\n /** Children */\n children?: React.ReactNode;\n}\n\nexport const Button = memo(forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n variant = 'primary',\n size = 'medium',\n icon,\n iconEnd,\n loading = false,\n fullWidth = false,\n tooltip,\n disabled,\n className = '',\n children,\n style,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n ...rest\n },\n ref\n): React.ReactElement {\n const { tokens, theme } = useTheme();\n \n // Spin keyframe is used by loading spinner only (injected there)\n\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const [isHovered, setIsHovered] = useState(false);\n const [isActive, setIsActive] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [showTooltip, setShowTooltip] = useState(false);\n \n const isDisabled = disabled || loading;\n const transparentDefault = tokens.colors.interactive.transparentDefault;\n const transparentHover = tokens.colors.interactive.transparentHover;\n\n // WCAG AA: compute a button-safe background from accent.primary\n // If white text (#fff) on the accent bg doesn't meet 4.5:1, darken it proportionally.\n const safeAccentBg = useMemo(() => {\n const hex = tokens.colors.accent.primary.replace('#', '');\n if (hex.length < 6) return tokens.colors.accent.primary;\n const toLinear = (c: number) => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n const r = parseInt(hex.slice(0, 2), 16) / 255;\n const g = parseInt(hex.slice(2, 4), 16) / 255;\n const b = parseInt(hex.slice(4, 6), 16) / 255;\n const L = 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n if ((1.05 / (L + 0.05)) >= 4.5) return tokens.colors.accent.primary;\n // Darken just enough: target L for ~4.7:1 contrast with white\n const factor = 0.88;\n const dr = Math.min(255, Math.round(r * 255 * factor));\n const dg = Math.min(255, Math.round(g * 255 * factor));\n const db = Math.min(255, Math.round(b * 255 * factor));\n return `#${dr.toString(16).padStart(2, '0')}${dg.toString(16).padStart(2, '0')}${db.toString(16).padStart(2, '0')}`;\n }, [tokens.colors.accent.primary]);\n\n // WCAG AA safe accent for use as foreground text on dark backgrounds\n const safeAccentFg = useMemo(() => safeAccentText(tokens.colors.accent.primary), [tokens.colors.accent.primary]);\n \n const sizeConfig = {\n small: {\n padding: `${tokens.spacing.xxs} ${tokens.spacing.smd}`,\n fontSize: tokens.typography.fontSize.xs,\n height: '24px',\n gap: tokens.spacing.xs,\n iconSize: 13,\n borderRadius: tokens.borderRadius.sm,\n },\n medium: {\n padding: `${tokens.spacing.xxs} ${tokens.spacing.md}`,\n fontSize: tokens.typography.fontSize.sm,\n height: '28px',\n gap: tokens.spacing.xs,\n iconSize: 15,\n borderRadius: tokens.borderRadius.md,\n },\n large: {\n padding: `${tokens.spacing.xs} ${tokens.spacing.lg}`,\n fontSize: tokens.typography.fontSize.base,\n height: '34px',\n gap: tokens.spacing.sm,\n iconSize: 17,\n borderRadius: tokens.borderRadius.md,\n },\n };\n \n const config = sizeConfig[size];\n \n // Variant base styles (transparent theme: purple-hue transparent bg, smooth fade on hover)\n const getVariantStyles = (): React.CSSProperties => {\n const baseTransition = `${tokens.animation.normal}, opacity ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default}`;\n \n if (isTransparentTheme && transparentDefault && transparentHover) {\n switch (variant) {\n case 'primary':\n return {\n backgroundColor: isHovered && !isDisabled ? transparentHover : transparentDefault,\n color: tokens.colors.text.primary,\n border: `1px solid ${isHovered && !isDisabled ? 'rgba(139, 92, 246, 0.5)' : 'rgba(139, 92, 246, 0.25)'}`,\n boxShadow: isHovered && !isDisabled ? '0 0 10px rgba(139, 92, 246, 0.15)' : 'none',\n transition: baseTransition,\n backdropFilter: 'blur(8px)',\n WebkitBackdropFilter: 'blur(8px)',\n };\n case 'secondary':\n return {\n backgroundColor: isHovered && !isDisabled \n ? `${tokens.colors.accent.primary}15` // Use accent color with opacity instead of transparentHover\n : transparentDefault,\n color: safeAccentFg,\n border: `1px solid ${isHovered && !isDisabled ? `${tokens.colors.accent.primary}70` : `${tokens.colors.accent.primary}30`}`,\n boxShadow: 'none',\n transition: baseTransition,\n backdropFilter: 'blur(8px)',\n WebkitBackdropFilter: 'blur(8px)',\n };\n case 'borderless':\n return {\n backgroundColor: isHovered && !isDisabled ? transparentHover : transparentDefault,\n color: safeAccentFg,\n border: 'none',\n boxShadow: 'none',\n transition: baseTransition,\n backdropFilter: 'blur(6px)',\n WebkitBackdropFilter: 'blur(6px)',\n };\n }\n }\n \n switch (variant) {\n case 'primary':\n return {\n backgroundColor: isHovered && !isDisabled\n ? tokens.colors.interactive.hover\n : safeAccentBg,\n color: '#ffffff',\n border: 'none',\n boxShadow: isHovered && !isDisabled\n ? `0 2px 8px -2px ${tokens.colors.accent.primary}35`\n : 'none',\n transition: baseTransition,\n };\n \n case 'secondary':\n return {\n backgroundColor: isHovered && !isDisabled\n ? `${tokens.colors.accent.primary}12`\n : 'transparent',\n color: isHovered && !isDisabled ? safeAccentFg : safeAccentFg,\n border: `${tokens.borders.width.medium} solid ${isHovered && !isDisabled ? tokens.colors.accent.primary : `${tokens.colors.accent.primary}80`}`,\n boxShadow: 'none',\n transition: baseTransition,\n };\n \n case 'borderless':\n return {\n backgroundColor: isHovered && !isDisabled\n ? `${tokens.colors.accent.primary}10`\n : 'transparent',\n color: safeAccentFg,\n border: `${tokens.borders.width.medium} solid transparent`,\n boxShadow: 'none',\n transition: baseTransition,\n };\n }\n };\n \n const focusStyles: React.CSSProperties = isFocused ? {\n outline: 'none',\n boxShadow: tokens.borders.focusRing.button,\n } : {};\n\n const activeStyles: React.CSSProperties = isActive && !isDisabled ? {\n filter: 'brightness(0.85)',\n transform: 'scale(0.98)',\n boxShadow: 'none',\n } : {};\n \n const baseStyle: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: config.gap,\n padding: config.padding,\n height: config.height,\n fontSize: config.fontSize,\n fontWeight: 400,\n fontFamily: tokens.typography.fontFamily.primary,\n letterSpacing: '0.02em',\n borderRadius: config.borderRadius,\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n opacity: isDisabled ? 0.5 : 1,\n outline: 'none',\n textDecoration: 'none',\n whiteSpace: 'nowrap',\n userSelect: 'none',\n width: fullWidth ? '100%' : 'auto',\n position: 'relative',\n ...getVariantStyles(),\n ...focusStyles,\n ...activeStyles,\n ...style,\n };\n \n // Loading spinner with smooth animation\n const spinner = (\n <svg\n width={config.iconSize}\n height={config.iconSize}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n style={{\n animation: 'zendir-spin 0.8s cubic-bezier(0.4, 0, 0.6, 1) infinite',\n }}\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeDasharray=\"31.4 31.4\"\n strokeDashoffset=\"10\"\n opacity=\"0.9\"\n />\n <style>\n {`@keyframes zendir-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }`}\n </style>\n </svg>\n );\n \n // Portal-based tooltip: position fixed relative to viewport, never clipped\n const internalRef = useRef<HTMLButtonElement>(null);\n const tooltipNodeRef = useRef<HTMLDivElement>(null);\n const [tooltipPos, setTooltipPos] = useState<{ top: number; left: number } | null>(null);\n\n const mergedRef = useCallback((node: HTMLButtonElement | null) => {\n (internalRef as React.MutableRefObject<HTMLButtonElement | null>).current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLButtonElement | null>).current = node;\n }, [ref]);\n\n useLayoutEffect(() => {\n if (!showTooltip || !tooltip || !internalRef.current) {\n setTooltipPos(null);\n return;\n }\n const btn = internalRef.current.getBoundingClientRect();\n const gap = 8;\n let top = btn.top - gap;\n let left = btn.left + btn.width / 2;\n // Adjust after tooltip renders so we can measure its width\n if (tooltipNodeRef.current) {\n const tt = tooltipNodeRef.current.getBoundingClientRect();\n top = btn.top - tt.height - gap;\n left = btn.left + (btn.width - tt.width) / 2;\n if (left < 8) left = 8;\n if (left + tt.width > window.innerWidth - 8) left = window.innerWidth - tt.width - 8;\n if (top < 8) top = btn.bottom + gap; // flip below if no room above\n }\n setTooltipPos({ top, left });\n }, [showTooltip, tooltip]);\n\n const tooltipPortal = tooltip && showTooltip && ReactDOM.createPortal(\n <div\n ref={tooltipNodeRef}\n role=\"tooltip\"\n style={{\n position: 'fixed',\n top: tooltipPos ? tooltipPos.top : -9999,\n left: tooltipPos ? tooltipPos.left : -9999,\n padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`,\n fontSize: '0.75rem',\n fontWeight: 500,\n color: tokens.colors.text.primary,\n backgroundColor: tokens.colors.background.elevated,\n border: tokens.borders.divider,\n borderRadius: tokens.borderRadius.md,\n boxShadow: tokens.shadows.md,\n whiteSpace: 'nowrap',\n zIndex: 2147483100,\n pointerEvents: 'none',\n opacity: tooltipPos ? 1 : 0,\n animation: tooltipPos ? `zendir-btn-tip ${tokens.animation.duration.fast}ms ${tokens.animation.easing.default} both` : 'none',\n }}\n >\n {tooltip}\n <style>\n {`@keyframes zendir-btn-tip { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }`}\n </style>\n </div>,\n document.body\n );\n\n return (\n <>\n <button\n ref={mergedRef}\n type=\"button\"\n disabled={isDisabled}\n className={classNames('zendir-button', `zendir-button--${variant}`, `zendir-button--${size}`, className)}\n style={baseStyle}\n title={tooltip && !showTooltip ? tooltip : undefined}\n onMouseDown={() => setIsActive(true)}\n onMouseUp={() => setIsActive(false)}\n onMouseEnter={(e) => {\n setIsHovered(true);\n setShowTooltip(true);\n onMouseEnter?.(e);\n }}\n onMouseLeave={(e) => {\n setIsHovered(false);\n setIsActive(false);\n setShowTooltip(false);\n onMouseLeave?.(e);\n }}\n onFocus={(e) => {\n setIsFocused(true);\n onFocus?.(e);\n }}\n onBlur={(e) => {\n setIsFocused(false);\n onBlur?.(e);\n }}\n {...rest}\n >\n {loading ? spinner : icon}\n {children && <span>{children}</span>}\n {iconEnd && !loading && iconEnd}\n </button>\n {tooltipPortal}\n </>\n );\n}));\n\nexport default Button;\n"],"names":["Button"],"mappings":";;;;;AAwDO,MAAM,SAAS,KAAK,WAA2C,SAASA,QAC7E;AAAA,EACE,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GACA,KACoB;AACpB,QAAM,EAAE,QAAQ,MAAA,IAAU,SAAA;AAI1B,QAAM,qBAAqB,UAAU,iBAAiB,UAAU,sBAAsB,UAAU;AAChG,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AAEpD,QAAM,aAAa,YAAY;AAC/B,QAAM,qBAAqB,OAAO,OAAO,YAAY;AACrD,QAAM,mBAAmB,OAAO,OAAO,YAAY;AAInD,QAAM,eAAe,QAAQ,MAAM;AACjC,UAAM,MAAM,OAAO,OAAO,OAAO,QAAQ,QAAQ,KAAK,EAAE;AACxD,QAAI,IAAI,SAAS,EAAG,QAAO,OAAO,OAAO,OAAO;AAChD,UAAM,WAAW,CAAC,MAAc,KAAK,UAAU,IAAI,QAAQ,KAAK,KAAK,IAAI,SAAS,OAAO,GAAG;AAC5F,UAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI;AAC1C,UAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI;AAC1C,UAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI;AAC1C,UAAM,IAAI,SAAS,SAAS,CAAC,IAAI,SAAS,SAAS,CAAC,IAAI,SAAS,SAAS,CAAC;AAC3E,QAAK,QAAQ,IAAI,SAAU,IAAK,QAAO,OAAO,OAAO,OAAO;AAE5D,UAAM,SAAS;AACf,UAAM,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,MAAM,MAAM,CAAC;AACrD,UAAM,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,MAAM,MAAM,CAAC;AACrD,UAAM,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,MAAM,MAAM,CAAC;AACrD,WAAO,IAAI,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,EACnH,GAAG,CAAC,OAAO,OAAO,OAAO,OAAO,CAAC;AAGjC,QAAM,eAAe,QAAQ,MAAM,eAAe,OAAO,OAAO,OAAO,OAAO,GAAG,CAAC,OAAO,OAAO,OAAO,OAAO,CAAC;AAE/G,QAAM,aAAa;AAAA,IACjB,OAAO;AAAA,MACL,SAAS,GAAG,OAAO,QAAQ,GAAG,IAAI,OAAO,QAAQ,GAAG;AAAA,MACpD,UAAU,OAAO,WAAW,SAAS;AAAA,MACrC,QAAQ;AAAA,MACR,KAAK,OAAO,QAAQ;AAAA,MACpB,UAAU;AAAA,MACV,cAAc,OAAO,aAAa;AAAA,IAAA;AAAA,IAEpC,QAAQ;AAAA,MACN,SAAS,GAAG,OAAO,QAAQ,GAAG,IAAI,OAAO,QAAQ,EAAE;AAAA,MACnD,UAAU,OAAO,WAAW,SAAS;AAAA,MACrC,QAAQ;AAAA,MACR,KAAK,OAAO,QAAQ;AAAA,MACpB,UAAU;AAAA,MACV,cAAc,OAAO,aAAa;AAAA,IAAA;AAAA,IAEpC,OAAO;AAAA,MACL,SAAS,GAAG,OAAO,QAAQ,EAAE,IAAI,OAAO,QAAQ,EAAE;AAAA,MAClD,UAAU,OAAO,WAAW,SAAS;AAAA,MACrC,QAAQ;AAAA,MACR,KAAK,OAAO,QAAQ;AAAA,MACpB,UAAU;AAAA,MACV,cAAc,OAAO,aAAa;AAAA,IAAA;AAAA,EACpC;AAGF,QAAM,SAAS,WAAW,IAAI;AAG9B,QAAM,mBAAmB,MAA2B;AAClD,UAAM,iBAAiB,GAAG,OAAO,UAAU,MAAM,aAAa,OAAO,UAAU,SAAS,MAAM,MAAM,OAAO,UAAU,OAAO,OAAO;AAEnI,QAAI,sBAAsB,sBAAsB,kBAAkB;AAChE,cAAQ,SAAA;AAAA,QACN,KAAK;AACH,iBAAO;AAAA,YACL,iBAAiB,aAAa,CAAC,aAAa,mBAAmB;AAAA,YAC/D,OAAO,OAAO,OAAO,KAAK;AAAA,YAC1B,QAAQ,aAAa,aAAa,CAAC,aAAa,4BAA4B,0BAA0B;AAAA,YACtG,WAAW,aAAa,CAAC,aAAa,sCAAsC;AAAA,YAC5E,YAAY;AAAA,YACZ,gBAAgB;AAAA,YAChB,sBAAsB;AAAA,UAAA;AAAA,QAE1B,KAAK;AACH,iBAAO;AAAA,YACL,iBAAiB,aAAa,CAAC,aAC3B,GAAG,OAAO,OAAO,OAAO,OAAO,OAC/B;AAAA,YACJ,OAAO;AAAA,YACP,QAAQ,aAAa,aAAa,CAAC,aAAa,GAAG,OAAO,OAAO,OAAO,OAAO,OAAO,GAAG,OAAO,OAAO,OAAO,OAAO,IAAI;AAAA,YACzH,WAAW;AAAA,YACX,YAAY;AAAA,YACZ,gBAAgB;AAAA,YAChB,sBAAsB;AAAA,UAAA;AAAA,QAE1B,KAAK;AACH,iBAAO;AAAA,YACL,iBAAiB,aAAa,CAAC,aAAa,mBAAmB;AAAA,YAC/D,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,WAAW;AAAA,YACX,YAAY;AAAA,YACZ,gBAAgB;AAAA,YAChB,sBAAsB;AAAA,UAAA;AAAA,MACxB;AAAA,IAEN;AAEA,YAAQ,SAAA;AAAA,MACN,KAAK;AACH,eAAO;AAAA,UACL,iBAAiB,aAAa,CAAC,aAC3B,OAAO,OAAO,YAAY,QAC1B;AAAA,UACJ,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,WAAW,aAAa,CAAC,aACrB,kBAAkB,OAAO,OAAO,OAAO,OAAO,OAC9C;AAAA,UACJ,YAAY;AAAA,QAAA;AAAA,MAGhB,KAAK;AACH,eAAO;AAAA,UACL,iBAAiB,aAAa,CAAC,aAC3B,GAAG,OAAO,OAAO,OAAO,OAAO,OAC/B;AAAA,UACJ,OAAO,aAAa,CAAC,aAAa,eAAe;AAAA,UACjD,QAAQ,GAAG,OAAO,QAAQ,MAAM,MAAM,UAAU,aAAa,CAAC,aAAa,OAAO,OAAO,OAAO,UAAU,GAAG,OAAO,OAAO,OAAO,OAAO,IAAI;AAAA,UAC7I,WAAW;AAAA,UACX,YAAY;AAAA,QAAA;AAAA,MAGhB,KAAK;AACH,eAAO;AAAA,UACL,iBAAiB,aAAa,CAAC,aAC3B,GAAG,OAAO,OAAO,OAAO,OAAO,OAC/B;AAAA,UACJ,OAAO;AAAA,UACP,QAAQ,GAAG,OAAO,QAAQ,MAAM,MAAM;AAAA,UACtC,WAAW;AAAA,UACX,YAAY;AAAA,QAAA;AAAA,IACd;AAAA,EAEN;AAEA,QAAM,cAAmC,YAAY;AAAA,IACnD,SAAS;AAAA,IACT,WAAW,OAAO,QAAQ,UAAU;AAAA,EAAA,IAClC,CAAA;AAEJ,QAAM,eAAoC,YAAY,CAAC,aAAa;AAAA,IAClE,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,EAAA,IACT,CAAA;AAEJ,QAAM,YAAiC;AAAA,IACrC,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,KAAK,OAAO;AAAA,IACZ,SAAS,OAAO;AAAA,IAChB,QAAQ,OAAO;AAAA,IACf,UAAU,OAAO;AAAA,IACjB,YAAY;AAAA,IACZ,YAAY,OAAO,WAAW,WAAW;AAAA,IACzC,eAAe;AAAA,IACf,cAAc,OAAO;AAAA,IACrB,QAAQ,aAAa,gBAAgB;AAAA,IACrC,SAAS,aAAa,MAAM;AAAA,IAC5B,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,OAAO,YAAY,SAAS;AAAA,IAC5B,UAAU;AAAA,IACV,GAAG,iBAAA;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EAAA;AAIL,QAAM,UACJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO;AAAA,MACf,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAO;AAAA,QACL,WAAW;AAAA,MAAA;AAAA,MAGb,UAAA;AAAA,QAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,IAAG;AAAA,YACH,GAAE;AAAA,YACF,QAAO;AAAA,YACP,aAAY;AAAA,YACZ,eAAc;AAAA,YACd,iBAAgB;AAAA,YAChB,kBAAiB;AAAA,YACjB,SAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,QAEV,oBAAC,WACE,UAAA,iGAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAKJ,QAAM,cAAc,OAA0B,IAAI;AAClD,QAAM,iBAAiB,OAAuB,IAAI;AAClD,QAAM,CAAC,YAAY,aAAa,IAAI,SAA+C,IAAI;AAEvF,QAAM,YAAY,YAAY,CAAC,SAAmC;AAC/D,gBAAiE,UAAU;AAC5E,QAAI,OAAO,QAAQ,WAAY,KAAI,IAAI;AAAA,aAC9B,IAAM,KAAyD,UAAU;AAAA,EACpF,GAAG,CAAC,GAAG,CAAC;AAER,kBAAgB,MAAM;AACpB,QAAI,CAAC,eAAe,CAAC,WAAW,CAAC,YAAY,SAAS;AACpD,oBAAc,IAAI;AAClB;AAAA,IACF;AACA,UAAM,MAAM,YAAY,QAAQ,sBAAA;AAChC,UAAM,MAAM;AACZ,QAAI,MAAM,IAAI,MAAM;AACpB,QAAI,OAAO,IAAI,OAAO,IAAI,QAAQ;AAElC,QAAI,eAAe,SAAS;AAC1B,YAAM,KAAK,eAAe,QAAQ,sBAAA;AAClC,YAAM,IAAI,MAAM,GAAG,SAAS;AAC5B,aAAO,IAAI,QAAQ,IAAI,QAAQ,GAAG,SAAS;AAC3C,UAAI,OAAO,EAAG,QAAO;AACrB,UAAI,OAAO,GAAG,QAAQ,OAAO,aAAa,EAAG,QAAO,OAAO,aAAa,GAAG,QAAQ;AACnF,UAAI,MAAM,EAAG,OAAM,IAAI,SAAS;AAAA,IAClC;AACA,kBAAc,EAAE,KAAK,MAAM;AAAA,EAC7B,GAAG,CAAC,aAAa,OAAO,CAAC;AAEzB,QAAM,gBAAgB,WAAW,eAAe,SAAS;AAAA,IACvD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK,aAAa,WAAW,MAAM;AAAA,UACnC,MAAM,aAAa,WAAW,OAAO;AAAA,UACrC,SAAS,GAAG,OAAO,QAAQ,EAAE,IAAI,OAAO,QAAQ,GAAG;AAAA,UACnD,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,OAAO,OAAO,OAAO,KAAK;AAAA,UAC1B,iBAAiB,OAAO,OAAO,WAAW;AAAA,UAC1C,QAAQ,OAAO,QAAQ;AAAA,UACvB,cAAc,OAAO,aAAa;AAAA,UAClC,WAAW,OAAO,QAAQ;AAAA,UAC1B,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,eAAe;AAAA,UACf,SAAS,aAAa,IAAI;AAAA,UAC1B,WAAW,aAAa,kBAAkB,OAAO,UAAU,SAAS,IAAI,MAAM,OAAO,UAAU,OAAO,OAAO,UAAU;AAAA,QAAA;AAAA,QAGxH,UAAA;AAAA,UAAA;AAAA,UACD,oBAAC,WACE,UAAA,8HAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAEF,SAAS;AAAA,EAAA;AAGX,SACE,qBAAA,UAAA,EACE,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,UAAU;AAAA,QACV,WAAW,WAAW,iBAAiB,kBAAkB,OAAO,IAAI,kBAAkB,IAAI,IAAI,SAAS;AAAA,QACvG,OAAO;AAAA,QACP,OAAO,WAAW,CAAC,cAAc,UAAU;AAAA,QAC3C,aAAa,MAAM,YAAY,IAAI;AAAA,QACnC,WAAW,MAAM,YAAY,KAAK;AAAA,QAClC,cAAc,CAAC,MAAM;AACnB,uBAAa,IAAI;AACjB,yBAAe,IAAI;AACnB,uDAAe;AAAA,QACjB;AAAA,QACA,cAAc,CAAC,MAAM;AACnB,uBAAa,KAAK;AAClB,sBAAY,KAAK;AACjB,yBAAe,KAAK;AACpB,uDAAe;AAAA,QACjB;AAAA,QACA,SAAS,CAAC,MAAM;AACd,uBAAa,IAAI;AACjB,6CAAU;AAAA,QACZ;AAAA,QACA,QAAQ,CAAC,MAAM;AACb,uBAAa,KAAK;AAClB,2CAAS;AAAA,QACX;AAAA,QACC,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,UAAU,UAAU;AAAA,UACpB,YAAY,oBAAC,QAAA,EAAM,SAAA,CAAS;AAAA,UAC5B,WAAW,CAAC,WAAW;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAEzB;AAAA,EAAA,GACH;AAEJ,CAAC,CAAC;"}
1
+ {"version":3,"file":"Button.js","names":[],"sources":["../../../../src/react/core/inputs/Button.tsx"],"sourcesContent":["/**\n * @zendir/ui - Button Component\n *\n * Enterprise-grade button following Astro UX Design System with Zendir purple accents.\n *\n * Astro UX Compliance:\n * - Three visual variants: primary, secondary, borderless\n * - Size variants: small, medium, large\n * - Sentence case capitalization\n * - Focus ring for accessibility (WCAG 2.1 AA)\n * - Right-align in button groups (primary on right)\n *\n * Zendir Enhancements:\n * - Purple accent colors\n * - Smooth micro-interactions\n * - Subtle glow effects\n * - Modern glassmorphism hover states\n *\n * @example\n * ```tsx\n * <Button>Primary Action</Button>\n * <Button variant=\"secondary\">Cancel</Button>\n * <Button variant=\"borderless\" icon={<Icon name=\"settings\" />}>Settings</Button>\n * <Button loading>Saving...</Button>\n * ```\n */\n\nimport React, {\n memo,\n forwardRef,\n useState,\n useMemo,\n useRef,\n useLayoutEffect,\n useCallback,\n} from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { useTheme } from \"../../theme\";\nimport { classNames, safeAccentText } from \"../../utils\";\n\nexport type ButtonVariant = \"primary\" | \"secondary\" | \"borderless\";\nexport type ButtonSize = \"small\" | \"medium\" | \"large\";\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual variant */\n variant?: ButtonVariant;\n /** Size variant */\n size?: ButtonSize;\n /** Icon to display before text */\n icon?: React.ReactNode;\n /** Icon to display after text */\n iconEnd?: React.ReactNode;\n /** Show loading spinner */\n loading?: boolean;\n /** Full width button */\n fullWidth?: boolean;\n /** Tooltip text (shows on hover) */\n tooltip?: string;\n /** Custom className */\n className?: string;\n /** Children */\n children?: React.ReactNode;\n}\n\nexport const Button = memo(\n forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n variant = \"primary\",\n size = \"medium\",\n icon,\n iconEnd,\n loading = false,\n fullWidth = false,\n tooltip,\n disabled,\n className = \"\",\n children,\n style,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n ...rest\n },\n ref,\n ): React.ReactElement {\n const { tokens, theme } = useTheme();\n\n // Spin keyframe is used by loading spinner only (injected there)\n\n const isTransparentTheme =\n theme === \"transparent\" ||\n theme === \"transparent-bold\" ||\n theme === \"transparent-minimal\";\n const [isHovered, setIsHovered] = useState(false);\n const [isActive, setIsActive] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [showTooltip, setShowTooltip] = useState(false);\n\n const isDisabled = disabled || loading;\n const transparentDefault = tokens.colors.interactive.transparentDefault;\n const transparentHover = tokens.colors.interactive.transparentHover;\n\n // WCAG AA: compute a button-safe background from accent.primary\n // If white text (#fff) on the accent bg doesn't meet 4.5:1, darken it proportionally.\n const safeAccentBg = useMemo(() => {\n const hex = tokens.colors.accent.primary.replace(\"#\", \"\");\n if (hex.length < 6) return tokens.colors.accent.primary;\n const toLinear = (c: number) =>\n c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n const r = parseInt(hex.slice(0, 2), 16) / 255;\n const g = parseInt(hex.slice(2, 4), 16) / 255;\n const b = parseInt(hex.slice(4, 6), 16) / 255;\n const L =\n 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n if (1.05 / (L + 0.05) >= 4.5) return tokens.colors.accent.primary;\n // Darken just enough: target L for ~4.7:1 contrast with white\n const factor = 0.88;\n const dr = Math.min(255, Math.round(r * 255 * factor));\n const dg = Math.min(255, Math.round(g * 255 * factor));\n const db = Math.min(255, Math.round(b * 255 * factor));\n return `#${dr.toString(16).padStart(2, \"0\")}${dg.toString(16).padStart(2, \"0\")}${db.toString(16).padStart(2, \"0\")}`;\n }, [tokens.colors.accent.primary]);\n\n // WCAG AA safe accent for use as foreground text on dark backgrounds\n const safeAccentFg = useMemo(\n () => safeAccentText(tokens.colors.accent.primary),\n [tokens.colors.accent.primary],\n );\n\n const sizeConfig = {\n small: {\n padding: `${tokens.spacing.xxs} ${tokens.spacing.smd}`,\n fontSize: tokens.typography.fontSize.xs,\n height: \"24px\",\n gap: tokens.spacing.xs,\n iconSize: 13,\n borderRadius: tokens.borderRadius.sm,\n },\n medium: {\n padding: `${tokens.spacing.xxs} ${tokens.spacing.md}`,\n fontSize: tokens.typography.fontSize.sm,\n height: \"28px\",\n gap: tokens.spacing.xs,\n iconSize: 15,\n borderRadius: tokens.borderRadius.md,\n },\n large: {\n padding: `${tokens.spacing.xs} ${tokens.spacing.lg}`,\n fontSize: tokens.typography.fontSize.base,\n height: \"34px\",\n gap: tokens.spacing.sm,\n iconSize: 17,\n borderRadius: tokens.borderRadius.md,\n },\n };\n\n const config = sizeConfig[size];\n\n // Variant base styles (transparent theme: purple-hue transparent bg, smooth fade on hover)\n const getVariantStyles = (): React.CSSProperties => {\n const baseTransition = `${tokens.animation.normal}, opacity ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default}`;\n\n if (isTransparentTheme && transparentDefault && transparentHover) {\n switch (variant) {\n case \"primary\":\n return {\n backgroundColor:\n isHovered && !isDisabled\n ? transparentHover\n : transparentDefault,\n color: tokens.colors.text.primary,\n border: `1px solid ${isHovered && !isDisabled ? `${tokens.colors.accent.primary}80` : `${tokens.colors.accent.primary}40`}`,\n boxShadow:\n isHovered && !isDisabled\n ? `0 0 10px ${tokens.colors.accent.primary}26`\n : \"none\",\n transition: baseTransition,\n backdropFilter: \"blur(8px)\",\n WebkitBackdropFilter: \"blur(8px)\",\n };\n case \"secondary\":\n return {\n backgroundColor:\n isHovered && !isDisabled\n ? `${tokens.colors.accent.primary}15` // Use accent color with opacity instead of transparentHover\n : transparentDefault,\n color: safeAccentFg,\n border: `1px solid ${isHovered && !isDisabled ? `${tokens.colors.accent.primary}70` : `${tokens.colors.accent.primary}30`}`,\n boxShadow: \"none\",\n transition: baseTransition,\n backdropFilter: \"blur(8px)\",\n WebkitBackdropFilter: \"blur(8px)\",\n };\n case \"borderless\":\n return {\n backgroundColor:\n isHovered && !isDisabled\n ? transparentHover\n : transparentDefault,\n color: safeAccentFg,\n border: \"none\",\n boxShadow: \"none\",\n transition: baseTransition,\n backdropFilter: \"blur(6px)\",\n WebkitBackdropFilter: \"blur(6px)\",\n };\n }\n }\n\n switch (variant) {\n case \"primary\":\n return {\n backgroundColor:\n isHovered && !isDisabled\n ? tokens.colors.interactive.hover\n : safeAccentBg,\n color: \"#ffffff\",\n border: \"none\",\n boxShadow:\n isHovered && !isDisabled\n ? `0 2px 8px -2px ${tokens.colors.accent.primary}35`\n : \"none\",\n transition: baseTransition,\n };\n\n case \"secondary\":\n return {\n backgroundColor:\n isHovered && !isDisabled\n ? `${tokens.colors.accent.primary}12`\n : \"transparent\",\n color: isHovered && !isDisabled ? safeAccentFg : safeAccentFg,\n border: `${tokens.borders.width.medium} solid ${isHovered && !isDisabled ? tokens.colors.accent.primary : `${tokens.colors.accent.primary}80`}`,\n boxShadow: \"none\",\n transition: baseTransition,\n };\n\n case \"borderless\":\n return {\n backgroundColor:\n isHovered && !isDisabled\n ? `${tokens.colors.accent.primary}10`\n : \"transparent\",\n color: safeAccentFg,\n border: `${tokens.borders.width.medium} solid transparent`,\n boxShadow: \"none\",\n transition: baseTransition,\n };\n }\n };\n\n const focusStyles: React.CSSProperties = isFocused\n ? {\n outline: \"none\",\n boxShadow: tokens.borders.focusRing.button,\n }\n : {};\n\n const activeStyles: React.CSSProperties =\n isActive && !isDisabled\n ? {\n filter: \"brightness(0.85)\",\n transform: \"scale(0.98)\",\n boxShadow: \"none\",\n }\n : {};\n\n const baseStyle: React.CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: config.gap,\n padding: config.padding,\n height: config.height,\n fontSize: config.fontSize,\n fontWeight: 400,\n fontFamily: tokens.typography.fontFamily.primary,\n letterSpacing: \"0.02em\",\n borderRadius: config.borderRadius,\n cursor: isDisabled ? \"not-allowed\" : \"pointer\",\n opacity: isDisabled ? 0.5 : 1,\n outline: \"none\",\n textDecoration: \"none\",\n whiteSpace: \"nowrap\",\n userSelect: \"none\",\n width: fullWidth ? \"100%\" : \"auto\",\n position: \"relative\",\n ...getVariantStyles(),\n ...focusStyles,\n ...activeStyles,\n ...style,\n };\n\n // Loading spinner with smooth animation\n const spinner = (\n <svg\n width={config.iconSize}\n height={config.iconSize}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n style={{\n animation: \"zendir-spin 0.8s cubic-bezier(0.4, 0, 0.6, 1) infinite\",\n }}\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeDasharray=\"31.4 31.4\"\n strokeDashoffset=\"10\"\n opacity=\"0.9\"\n />\n <style>\n {`@keyframes zendir-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }`}\n </style>\n </svg>\n );\n\n // Portal-based tooltip: position fixed relative to viewport, never clipped\n const internalRef = useRef<HTMLButtonElement>(null);\n const tooltipNodeRef = useRef<HTMLDivElement>(null);\n const [tooltipPos, setTooltipPos] = useState<{\n top: number;\n left: number;\n } | null>(null);\n\n const mergedRef = useCallback(\n (node: HTMLButtonElement | null) => {\n (\n internalRef as React.MutableRefObject<HTMLButtonElement | null>\n ).current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref)\n (ref as React.MutableRefObject<HTMLButtonElement | null>).current =\n node;\n },\n [ref],\n );\n\n useLayoutEffect(() => {\n if (!showTooltip || !tooltip || !internalRef.current) {\n setTooltipPos(null);\n return;\n }\n const btn = internalRef.current.getBoundingClientRect();\n const gap = 8;\n let top = btn.top - gap;\n let left = btn.left + btn.width / 2;\n // Adjust after tooltip renders so we can measure its width\n if (tooltipNodeRef.current) {\n const tt = tooltipNodeRef.current.getBoundingClientRect();\n top = btn.top - tt.height - gap;\n left = btn.left + (btn.width - tt.width) / 2;\n if (left < 8) left = 8;\n if (left + tt.width > window.innerWidth - 8)\n left = window.innerWidth - tt.width - 8;\n if (top < 8) top = btn.bottom + gap; // flip below if no room above\n }\n setTooltipPos({ top, left });\n }, [showTooltip, tooltip]);\n\n const tooltipPortal =\n tooltip &&\n showTooltip &&\n ReactDOM.createPortal(\n <div\n ref={tooltipNodeRef}\n role=\"tooltip\"\n style={{\n position: \"fixed\",\n top: tooltipPos ? tooltipPos.top : -9999,\n left: tooltipPos ? tooltipPos.left : -9999,\n padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`,\n fontSize: \"0.75rem\",\n fontWeight: 500,\n color: tokens.colors.text.primary,\n backgroundColor: tokens.colors.background.elevated,\n border: tokens.borders.divider,\n borderRadius: tokens.borderRadius.md,\n boxShadow: tokens.shadows.md,\n whiteSpace: \"nowrap\",\n zIndex: 2147483100,\n pointerEvents: \"none\",\n opacity: tooltipPos ? 1 : 0,\n animation: tooltipPos\n ? `zendir-btn-tip ${tokens.animation.duration.fast}ms ${tokens.animation.easing.default} both`\n : \"none\",\n }}\n >\n {tooltip}\n <style>\n {`@keyframes zendir-btn-tip { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }`}\n </style>\n </div>,\n document.body,\n );\n\n return (\n <>\n <button\n ref={mergedRef}\n type=\"button\"\n disabled={isDisabled}\n className={classNames(\n \"zendir-button\",\n `zendir-button--${variant}`,\n `zendir-button--${size}`,\n className,\n )}\n style={baseStyle}\n title={tooltip && !showTooltip ? tooltip : undefined}\n onMouseDown={() => setIsActive(true)}\n onMouseUp={() => setIsActive(false)}\n onMouseEnter={(e) => {\n setIsHovered(true);\n setShowTooltip(true);\n onMouseEnter?.(e);\n }}\n onMouseLeave={(e) => {\n setIsHovered(false);\n setIsActive(false);\n setShowTooltip(false);\n onMouseLeave?.(e);\n }}\n onFocus={(e) => {\n setIsFocused(true);\n onFocus?.(e);\n }}\n onBlur={(e) => {\n setIsFocused(false);\n onBlur?.(e);\n }}\n {...rest}\n >\n {loading ? spinner : icon}\n {children && <span>{children}</span>}\n {iconEnd && !loading && iconEnd}\n </button>\n {tooltipPortal}\n </>\n );\n }),\n);\n\nexport default Button;\n"],"mappings":"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"}
@@ -1,8 +1,7 @@
1
1
  import { default as React } from 'react';
2
-
3
2
  export interface CheckboxProps {
4
3
  /** Checkbox or radio */
5
- type?: 'checkbox' | 'radio';
4
+ type?: "checkbox" | "radio";
6
5
  /** Checked state */
7
6
  checked?: boolean;
8
7
  /** Change handler */
@@ -18,7 +17,7 @@ export interface CheckboxProps {
18
17
  /** Indeterminate state (checkbox only) */
19
18
  indeterminate?: boolean;
20
19
  /** Size variant */
21
- size?: 'small' | 'medium';
20
+ size?: "small" | "medium";
22
21
  /** Custom className */
23
22
  className?: string;
24
23
  }
@@ -1,130 +1,142 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { memo, forwardRef, useState, useId } from "react";
3
1
  import { useTheme } from "../../theme/ThemeProvider.js";
4
2
  import { classNames } from "../../utils/index.js";
5
- const Checkbox = memo(forwardRef(function Checkbox2({
6
- type = "checkbox",
7
- checked = false,
8
- onChange,
9
- label,
10
- value,
11
- name,
12
- disabled = false,
13
- indeterminate = false,
14
- size = "medium",
15
- className = ""
16
- }, ref) {
17
- const { tokens, theme } = useTheme();
18
- const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
19
- const transparentDefault = tokens.colors.interactive.transparentDefault;
20
- const [focused, setFocused] = useState(false);
21
- const [hovered, setHovered] = useState(false);
22
- const id = useId();
23
- const sizeConfig = {
24
- small: { boxSize: 18, iconSize: 12, targetSize: 24 },
25
- medium: { boxSize: 20, iconSize: 14, targetSize: 24 }
26
- };
27
- const config = sizeConfig[size];
28
- const isRadio = type === "radio";
29
- const borderRadius = isRadio ? "50%" : tokens.borderRadius.md;
30
- const boxStyle = {
31
- width: config.boxSize,
32
- height: config.boxSize,
33
- border: `${tokens.borders.width.thick} solid ${checked ? tokens.colors.accent.primary : hovered && !disabled ? `${tokens.colors.accent.primary}60` : tokens.colors.border.muted}`,
34
- borderRadius,
35
- backgroundColor: checked ? tokens.colors.accent.primary : isTransparentTheme && transparentDefault ? transparentDefault : "transparent",
36
- display: "flex",
37
- alignItems: "center",
38
- justifyContent: "center",
39
- transition: `${tokens.animation.normal}, opacity ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default}`,
40
- flexShrink: 0,
41
- boxShadow: checked ? `0 0 12px ${tokens.colors.accent.primary}40` : focused ? tokens.borders.focusRing.subtle : "none",
42
- transform: checked ? "scale(1)" : hovered && !disabled ? "scale(1.05)" : "scale(1)"
43
- };
44
- const checkIcon = /* @__PURE__ */ jsx(
45
- "svg",
46
- {
47
- width: config.iconSize,
48
- height: config.iconSize,
49
- viewBox: "0 0 24 24",
50
- fill: "none",
51
- stroke: "#ffffff",
52
- strokeWidth: "3",
53
- strokeLinecap: "round",
54
- strokeLinejoin: "round",
55
- children: indeterminate ? /* @__PURE__ */ jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }) : /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
56
- }
57
- );
58
- const radioIcon = /* @__PURE__ */ jsx(
59
- "div",
60
- {
61
- style: {
62
- width: config.iconSize - 4,
63
- height: config.iconSize - 4,
64
- borderRadius: "50%",
65
- backgroundColor: "#ffffff"
66
- }
67
- }
68
- );
69
- return /* @__PURE__ */ jsxs(
70
- "label",
71
- {
72
- htmlFor: id,
73
- className: classNames("zendir-checkbox", className),
74
- onMouseEnter: () => setHovered(true),
75
- onMouseLeave: () => setHovered(false),
76
- style: {
77
- display: "inline-flex",
78
- alignItems: "center",
79
- gap: tokens.spacing.sm,
80
- cursor: disabled ? "not-allowed" : "pointer",
81
- opacity: disabled ? 0.5 : 1
82
- },
83
- children: [
84
- /* @__PURE__ */ jsx("div", { style: {
85
- display: "flex",
86
- alignItems: "center",
87
- justifyContent: "center",
88
- minWidth: config.targetSize,
89
- minHeight: config.targetSize
90
- }, children: /* @__PURE__ */ jsx("div", { style: boxStyle, children: checked && (isRadio ? radioIcon : checkIcon) }) }),
91
- /* @__PURE__ */ jsx(
92
- "input",
93
- {
94
- ref,
95
- type,
96
- id,
97
- name,
98
- value,
99
- checked,
100
- disabled,
101
- onChange: (e) => onChange == null ? void 0 : onChange(e.target.checked),
102
- onFocus: () => setFocused(true),
103
- onBlur: () => setFocused(false),
104
- style: {
105
- position: "absolute",
106
- opacity: 0,
107
- width: 0,
108
- height: 0
109
- }
110
- }
111
- ),
112
- label && /* @__PURE__ */ jsx(
113
- "span",
114
- {
115
- style: {
116
- fontSize: "0.875rem",
117
- color: tokens.colors.text.primary,
118
- transition: tokens.animation.fast
119
- },
120
- children: label
121
- }
122
- )
123
- ]
124
- }
125
- );
3
+ import { forwardRef, memo, useId, useState } from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/react/core/inputs/Checkbox.tsx
6
+ /**
7
+ * @zendir/ui - Checkbox Component
8
+ *
9
+ * Checkbox and Radio button following Astro UX Design System with Zendir purple accents.
10
+ *
11
+ * Astro UX Compliance:
12
+ * - Clear visual states
13
+ * - Accessible keyboard support
14
+ * - Indeterminate state for checkbox
15
+ *
16
+ * Zendir Enhancements:
17
+ * - Purple accent when checked
18
+ * - Glow effect on focus
19
+ * - Smooth spring animation
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <Checkbox checked={agreed} onChange={setAgreed} label="I agree to terms" />
24
+ * <Checkbox type="radio" name="priority" value="high" label="High Priority" />
25
+ * ```
26
+ */
27
+ var Checkbox = memo(forwardRef(function Checkbox({ type = "checkbox", checked = false, onChange, label, value, name, disabled = false, indeterminate = false, size = "medium", className = "" }, ref) {
28
+ const { tokens, theme } = useTheme();
29
+ const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
30
+ const transparentDefault = tokens.colors.interactive.transparentDefault;
31
+ const [focused, setFocused] = useState(false);
32
+ const [hovered, setHovered] = useState(false);
33
+ const id = useId();
34
+ const config = {
35
+ small: {
36
+ boxSize: 18,
37
+ iconSize: 12,
38
+ targetSize: 24
39
+ },
40
+ medium: {
41
+ boxSize: 20,
42
+ iconSize: 14,
43
+ targetSize: 24
44
+ }
45
+ }[size];
46
+ const isRadio = type === "radio";
47
+ const borderRadius = isRadio ? "50%" : tokens.borderRadius.md;
48
+ const boxStyle = {
49
+ width: config.boxSize,
50
+ height: config.boxSize,
51
+ border: `${tokens.borders.width.thick} solid ${checked ? tokens.colors.accent.primary : hovered && !disabled ? `${tokens.colors.accent.primary}60` : tokens.colors.border.muted}`,
52
+ borderRadius,
53
+ backgroundColor: checked ? tokens.colors.accent.primary : isTransparentTheme && transparentDefault ? transparentDefault : "transparent",
54
+ display: "flex",
55
+ alignItems: "center",
56
+ justifyContent: "center",
57
+ transition: `${tokens.animation.normal}, opacity ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default}`,
58
+ flexShrink: 0,
59
+ boxShadow: checked ? `0 0 12px ${tokens.colors.accent.primary}40` : focused ? tokens.borders.focusRing.subtle : "none",
60
+ transform: checked ? "scale(1)" : hovered && !disabled ? "scale(1.05)" : "scale(1)"
61
+ };
62
+ const checkIcon = /* @__PURE__ */ jsx("svg", {
63
+ width: config.iconSize,
64
+ height: config.iconSize,
65
+ viewBox: "0 0 24 24",
66
+ fill: "none",
67
+ stroke: "#ffffff",
68
+ strokeWidth: "3",
69
+ strokeLinecap: "round",
70
+ strokeLinejoin: "round",
71
+ children: indeterminate ? /* @__PURE__ */ jsx("line", {
72
+ x1: "5",
73
+ y1: "12",
74
+ x2: "19",
75
+ y2: "12"
76
+ }) : /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
77
+ });
78
+ const radioIcon = /* @__PURE__ */ jsx("div", { style: {
79
+ width: config.iconSize - 4,
80
+ height: config.iconSize - 4,
81
+ borderRadius: "50%",
82
+ backgroundColor: "#ffffff"
83
+ } });
84
+ return /* @__PURE__ */ jsxs("label", {
85
+ htmlFor: id,
86
+ className: classNames("zendir-checkbox", className),
87
+ onMouseEnter: () => setHovered(true),
88
+ onMouseLeave: () => setHovered(false),
89
+ style: {
90
+ display: "inline-flex",
91
+ alignItems: "center",
92
+ gap: tokens.spacing.sm,
93
+ cursor: disabled ? "not-allowed" : "pointer",
94
+ opacity: disabled ? .5 : 1
95
+ },
96
+ children: [
97
+ /* @__PURE__ */ jsx("div", {
98
+ style: {
99
+ display: "flex",
100
+ alignItems: "center",
101
+ justifyContent: "center",
102
+ minWidth: config.targetSize,
103
+ minHeight: config.targetSize
104
+ },
105
+ children: /* @__PURE__ */ jsx("div", {
106
+ style: boxStyle,
107
+ children: checked && (isRadio ? radioIcon : checkIcon)
108
+ })
109
+ }),
110
+ /* @__PURE__ */ jsx("input", {
111
+ ref,
112
+ type,
113
+ id,
114
+ name,
115
+ value,
116
+ checked,
117
+ disabled,
118
+ onChange: (e) => onChange?.(e.target.checked),
119
+ onFocus: () => setFocused(true),
120
+ onBlur: () => setFocused(false),
121
+ style: {
122
+ position: "absolute",
123
+ opacity: 0,
124
+ width: 0,
125
+ height: 0
126
+ }
127
+ }),
128
+ label && /* @__PURE__ */ jsx("span", {
129
+ style: {
130
+ fontSize: "0.875rem",
131
+ color: tokens.colors.text.primary,
132
+ transition: tokens.animation.fast
133
+ },
134
+ children: label
135
+ })
136
+ ]
137
+ });
126
138
  }));
127
- export {
128
- Checkbox
129
- };
130
- //# sourceMappingURL=Checkbox.js.map
139
+ //#endregion
140
+ export { Checkbox, Checkbox as default };
141
+
142
+ //# sourceMappingURL=Checkbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.js","sources":["../../../../src/react/core/inputs/Checkbox.tsx"],"sourcesContent":["/**\n * @zendir/ui - Checkbox Component\n * \n * Checkbox and Radio button following Astro UX Design System with Zendir purple accents.\n * \n * Astro UX Compliance:\n * - Clear visual states\n * - Accessible keyboard support\n * - Indeterminate state for checkbox\n * \n * Zendir Enhancements:\n * - Purple accent when checked\n * - Glow effect on focus\n * - Smooth spring animation\n * \n * @example\n * ```tsx\n * <Checkbox checked={agreed} onChange={setAgreed} label=\"I agree to terms\" />\n * <Checkbox type=\"radio\" name=\"priority\" value=\"high\" label=\"High Priority\" />\n * ```\n */\n\nimport React, { memo, forwardRef, useId, useState } from 'react';\nimport { useTheme } from '../../theme';\nimport { classNames } from '../../utils';\n\nexport interface CheckboxProps {\n /** Checkbox or radio */\n type?: 'checkbox' | 'radio';\n /** Checked state */\n checked?: boolean;\n /** Change handler */\n onChange?: (checked: boolean) => void;\n /** Label text */\n label?: string;\n /** Value (for radio groups) */\n value?: string;\n /** Name (for radio groups) */\n name?: string;\n /** Disabled state */\n disabled?: boolean;\n /** Indeterminate state (checkbox only) */\n indeterminate?: boolean;\n /** Size variant */\n size?: 'small' | 'medium';\n /** Custom className */\n className?: string;\n}\n\nexport const Checkbox = memo(forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(\n {\n type = 'checkbox',\n checked = false,\n onChange,\n label,\n value,\n name,\n disabled = false,\n indeterminate = false,\n size = 'medium',\n className = '',\n },\n ref\n): React.ReactElement {\n const { tokens, theme } = useTheme();\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const transparentDefault = tokens.colors.interactive.transparentDefault;\n const [focused, setFocused] = useState(false);\n const [hovered, setHovered] = useState(false);\n const id = useId();\n \n // WCAG 2.5.8: minimum 24×24 CSS px target size\n const sizeConfig = {\n small: { boxSize: 18, iconSize: 12, targetSize: 24 },\n medium: { boxSize: 20, iconSize: 14, targetSize: 24 },\n };\n const config = sizeConfig[size];\n \n const isRadio = type === 'radio';\n const borderRadius = isRadio ? '50%' : tokens.borderRadius.md;\n \n const boxStyle: React.CSSProperties = {\n width: config.boxSize,\n height: config.boxSize,\n border: `${tokens.borders.width.thick} solid ${checked ? tokens.colors.accent.primary : hovered && !disabled ? `${tokens.colors.accent.primary}60` : tokens.colors.border.muted}`,\n borderRadius,\n backgroundColor: checked ? tokens.colors.accent.primary : (isTransparentTheme && transparentDefault ? transparentDefault : 'transparent'),\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: `${tokens.animation.normal}, opacity ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default}`,\n flexShrink: 0,\n boxShadow: checked \n ? `0 0 12px ${tokens.colors.accent.primary}40` \n : focused \n ? tokens.borders.focusRing.subtle\n : 'none',\n transform: checked ? 'scale(1)' : hovered && !disabled ? 'scale(1.05)' : 'scale(1)',\n };\n \n // Check mark for checkbox\n const checkIcon = (\n <svg\n width={config.iconSize}\n height={config.iconSize}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#ffffff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n {indeterminate ? (\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n ) : (\n <polyline points=\"20 6 9 17 4 12\" />\n )}\n </svg>\n );\n \n // Dot for radio\n const radioIcon = (\n <div\n style={{\n width: config.iconSize - 4,\n height: config.iconSize - 4,\n borderRadius: '50%',\n backgroundColor: '#ffffff',\n }}\n />\n );\n \n return (\n <label\n htmlFor={id}\n className={classNames('zendir-checkbox', className)}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: tokens.spacing.sm,\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n }}\n >\n {/* Touch target wrapper — ensures WCAG 2.5.8 24px minimum */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minWidth: config.targetSize,\n minHeight: config.targetSize,\n }}>\n <div style={boxStyle}>\n {checked && (isRadio ? radioIcon : checkIcon)}\n </div>\n </div>\n \n <input\n ref={ref}\n type={type}\n id={id}\n name={name}\n value={value}\n checked={checked}\n disabled={disabled}\n onChange={(e) => onChange?.(e.target.checked)}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n style={{\n position: 'absolute',\n opacity: 0,\n width: 0,\n height: 0,\n }}\n />\n \n {label && (\n <span\n style={{\n fontSize: '0.875rem',\n color: tokens.colors.text.primary,\n transition: tokens.animation.fast,\n }}\n >\n {label}\n </span>\n )}\n </label>\n );\n}));\n\nexport default Checkbox;\n"],"names":["Checkbox"],"mappings":"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"}
1
+ {"version":3,"file":"Checkbox.js","names":[],"sources":["../../../../src/react/core/inputs/Checkbox.tsx"],"sourcesContent":["/**\n * @zendir/ui - Checkbox Component\n *\n * Checkbox and Radio button following Astro UX Design System with Zendir purple accents.\n *\n * Astro UX Compliance:\n * - Clear visual states\n * - Accessible keyboard support\n * - Indeterminate state for checkbox\n *\n * Zendir Enhancements:\n * - Purple accent when checked\n * - Glow effect on focus\n * - Smooth spring animation\n *\n * @example\n * ```tsx\n * <Checkbox checked={agreed} onChange={setAgreed} label=\"I agree to terms\" />\n * <Checkbox type=\"radio\" name=\"priority\" value=\"high\" label=\"High Priority\" />\n * ```\n */\n\nimport React, { memo, forwardRef, useId, useState } from \"react\";\nimport { useTheme } from \"../../theme\";\nimport { classNames } from \"../../utils\";\n\nexport interface CheckboxProps {\n /** Checkbox or radio */\n type?: \"checkbox\" | \"radio\";\n /** Checked state */\n checked?: boolean;\n /** Change handler */\n onChange?: (checked: boolean) => void;\n /** Label text */\n label?: string;\n /** Value (for radio groups) */\n value?: string;\n /** Name (for radio groups) */\n name?: string;\n /** Disabled state */\n disabled?: boolean;\n /** Indeterminate state (checkbox only) */\n indeterminate?: boolean;\n /** Size variant */\n size?: \"small\" | \"medium\";\n /** Custom className */\n className?: string;\n}\n\nexport const Checkbox = memo(\n forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(\n {\n type = \"checkbox\",\n checked = false,\n onChange,\n label,\n value,\n name,\n disabled = false,\n indeterminate = false,\n size = \"medium\",\n className = \"\",\n },\n ref,\n ): React.ReactElement {\n const { tokens, theme } = useTheme();\n const isTransparentTheme =\n theme === \"transparent\" ||\n theme === \"transparent-bold\" ||\n theme === \"transparent-minimal\";\n const transparentDefault = tokens.colors.interactive.transparentDefault;\n const [focused, setFocused] = useState(false);\n const [hovered, setHovered] = useState(false);\n const id = useId();\n\n // WCAG 2.5.8: minimum 24×24 CSS px target size\n const sizeConfig = {\n small: { boxSize: 18, iconSize: 12, targetSize: 24 },\n medium: { boxSize: 20, iconSize: 14, targetSize: 24 },\n };\n const config = sizeConfig[size];\n\n const isRadio = type === \"radio\";\n const borderRadius = isRadio ? \"50%\" : tokens.borderRadius.md;\n\n const boxStyle: React.CSSProperties = {\n width: config.boxSize,\n height: config.boxSize,\n border: `${tokens.borders.width.thick} solid ${checked ? tokens.colors.accent.primary : hovered && !disabled ? `${tokens.colors.accent.primary}60` : tokens.colors.border.muted}`,\n borderRadius,\n backgroundColor: checked\n ? tokens.colors.accent.primary\n : isTransparentTheme && transparentDefault\n ? transparentDefault\n : \"transparent\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n transition: `${tokens.animation.normal}, opacity ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default}`,\n flexShrink: 0,\n boxShadow: checked\n ? `0 0 12px ${tokens.colors.accent.primary}40`\n : focused\n ? tokens.borders.focusRing.subtle\n : \"none\",\n transform: checked\n ? \"scale(1)\"\n : hovered && !disabled\n ? \"scale(1.05)\"\n : \"scale(1)\",\n };\n\n // Check mark for checkbox\n const checkIcon = (\n <svg\n width={config.iconSize}\n height={config.iconSize}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#ffffff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n {indeterminate ? (\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n ) : (\n <polyline points=\"20 6 9 17 4 12\" />\n )}\n </svg>\n );\n\n // Dot for radio\n const radioIcon = (\n <div\n style={{\n width: config.iconSize - 4,\n height: config.iconSize - 4,\n borderRadius: \"50%\",\n backgroundColor: \"#ffffff\",\n }}\n />\n );\n\n return (\n <label\n htmlFor={id}\n className={classNames(\"zendir-checkbox\", className)}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: tokens.spacing.sm,\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n opacity: disabled ? 0.5 : 1,\n }}\n >\n {/* Touch target wrapper — ensures WCAG 2.5.8 24px minimum */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minWidth: config.targetSize,\n minHeight: config.targetSize,\n }}\n >\n <div style={boxStyle}>\n {checked && (isRadio ? radioIcon : checkIcon)}\n </div>\n </div>\n\n <input\n ref={ref}\n type={type}\n id={id}\n name={name}\n value={value}\n checked={checked}\n disabled={disabled}\n onChange={(e) => onChange?.(e.target.checked)}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n style={{\n position: \"absolute\",\n opacity: 0,\n width: 0,\n height: 0,\n }}\n />\n\n {label && (\n <span\n style={{\n fontSize: \"0.875rem\",\n color: tokens.colors.text.primary,\n transition: tokens.animation.fast,\n }}\n >\n {label}\n </span>\n )}\n </label>\n );\n }),\n);\n\nexport default Checkbox;\n"],"mappings":"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"}
@@ -1,10 +1,9 @@
1
1
  import { default as React } from 'react';
2
2
  import { StatusLevel } from '../../utils';
3
-
4
- export type InputSize = 'small' | 'medium' | 'large';
3
+ export type InputSize = "small" | "medium" | "large";
5
4
  /** Label placement relative to the input field */
6
- export type LabelPlacement = 'above' | 'outlined';
7
- export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
5
+ export type LabelPlacement = "above" | "outlined";
6
+ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {
8
7
  /** Label text or ReactNode (supports rich content like tooltip icons) */
9
8
  label?: React.ReactNode;
10
9
  /** Helper text below input */