@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,507 +1,535 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { memo, forwardRef, useState, useRef, useId, useMemo, useEffect, useCallback } from "react";
3
1
  import { useTheme } from "../../theme/ThemeProvider.js";
4
2
  import { deriveStatus } from "../data/propertyConfig.js";
5
3
  import { StatusIndicator } from "../../astro/StatusIndicator.js";
6
- const DEFAULT_DECIMAL_PLACES = 0;
7
- const NumberInput = memo(forwardRef(function NumberInput2({
8
- value,
9
- onChange,
10
- min,
11
- max,
12
- step = 1,
13
- precision,
14
- unit,
15
- label,
16
- helperText,
17
- error,
18
- slider = false,
19
- size = "medium",
20
- disabled = false,
21
- fullWidth = false,
22
- width,
23
- id,
24
- className,
25
- style,
26
- textAlign = "right",
27
- labelPlacement = "outlined",
28
- required,
29
- statusMode = false,
30
- status: statusOverride,
31
- statusThresholds,
32
- onStatusChange
33
- }, ref) {
34
- const { tokens, theme } = useTheme();
35
- const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
36
- const isOutlined = labelPlacement === "outlined";
37
- const decimalPlaces = precision ?? DEFAULT_DECIMAL_PLACES;
38
- const [isFocused, setIsFocused] = useState(false);
39
- const [isHovered, setIsHovered] = useState(false);
40
- const [isSliderActive, setIsSliderActive] = useState(false);
41
- const [localValue, setLocalValue] = useState(() => value.toFixed(decimalPlaces));
42
- const inputRef = useRef(null);
43
- const sliderContainerRef = useRef(null);
44
- const sliderId = useId().replace(/:/g, "");
45
- const resolvedStatus = useMemo(() => {
46
- if (!statusMode) return void 0;
47
- if (statusOverride) return statusOverride;
48
- return deriveStatus(value, statusThresholds);
49
- }, [statusMode, statusOverride, statusThresholds, value]);
50
- const prevStatusRef = useRef(void 0);
51
- useEffect(() => {
52
- if (resolvedStatus !== void 0 && resolvedStatus !== prevStatusRef.current) {
53
- prevStatusRef.current = resolvedStatus;
54
- onStatusChange == null ? void 0 : onStatusChange(resolvedStatus);
55
- }
56
- }, [resolvedStatus, onStatusChange]);
57
- const activeColor = useMemo(() => {
58
- if (resolvedStatus && tokens.colors.status[resolvedStatus]) {
59
- return tokens.colors.status[resolvedStatus];
60
- }
61
- return tokens.colors.accent.primary;
62
- }, [resolvedStatus, tokens.colors.status, tokens.colors.accent.primary]);
63
- useEffect(() => {
64
- if (!isFocused) {
65
- setLocalValue(value.toFixed(decimalPlaces));
66
- }
67
- }, [value, decimalPlaces, isFocused]);
68
- const clamp = useCallback((v) => {
69
- let result = v;
70
- if (min !== void 0) result = Math.max(min, result);
71
- if (max !== void 0) result = Math.min(max, result);
72
- result = Number(result.toFixed(decimalPlaces));
73
- return result;
74
- }, [min, max, decimalPlaces]);
75
- const handleInputChange = useCallback((e) => {
76
- const raw = e.target.value;
77
- setLocalValue(raw);
78
- const parsed = parseFloat(raw);
79
- if (!isNaN(parsed)) {
80
- onChange(clamp(parsed));
81
- }
82
- }, [onChange, clamp]);
83
- const handleBlur = useCallback(() => {
84
- setIsFocused(false);
85
- const parsed = parseFloat(localValue);
86
- if (isNaN(parsed)) {
87
- setLocalValue(value.toFixed(decimalPlaces));
88
- } else {
89
- const clamped = clamp(parsed);
90
- onChange(clamped);
91
- setLocalValue(clamped.toFixed(decimalPlaces));
92
- }
93
- }, [localValue, value, onChange, clamp, decimalPlaces]);
94
- const handleSliderChange = useCallback((e) => {
95
- const parsed = parseFloat(e.target.value);
96
- const clamped = clamp(parsed);
97
- onChange(clamped);
98
- setLocalValue(clamped.toFixed(decimalPlaces));
99
- }, [onChange, clamp, decimalPlaces]);
100
- const handleKeyDown = useCallback((e) => {
101
- if (e.key === "ArrowUp") {
102
- e.preventDefault();
103
- onChange(clamp(value + step));
104
- } else if (e.key === "ArrowDown") {
105
- e.preventDefault();
106
- onChange(clamp(value - step));
107
- }
108
- }, [value, step, onChange, clamp]);
109
- const handleWheel = useCallback((e) => {
110
- if (disabled || min === void 0 || max === void 0) return;
111
- e.preventDefault();
112
- const direction = e.deltaY < 0 ? 1 : -1;
113
- onChange(clamp(value + step * direction));
114
- }, [value, step, onChange, clamp, disabled, min, max]);
115
- useEffect(() => {
116
- const sliderContainer = sliderContainerRef.current;
117
- const inputElement = inputRef.current;
118
- if (min !== void 0 && max !== void 0) {
119
- if (slider && sliderContainer) {
120
- sliderContainer.addEventListener("wheel", handleWheel, { passive: false });
121
- }
122
- if (inputElement) {
123
- inputElement.addEventListener("wheel", handleWheel, { passive: false });
124
- }
125
- }
126
- return () => {
127
- if (sliderContainer) sliderContainer.removeEventListener("wheel", handleWheel);
128
- if (inputElement) inputElement.removeEventListener("wheel", handleWheel);
129
- };
130
- }, [handleWheel, slider, min, max]);
131
- useEffect(() => {
132
- if (!isSliderActive) return;
133
- const handleUp = () => setIsSliderActive(false);
134
- window.addEventListener("mouseup", handleUp);
135
- window.addEventListener("touchend", handleUp);
136
- return () => {
137
- window.removeEventListener("mouseup", handleUp);
138
- window.removeEventListener("touchend", handleUp);
139
- };
140
- }, [isSliderActive]);
141
- const [isUnitDragging, setIsUnitDragging] = useState(false);
142
- const dragStartValueRef = useRef(0);
143
- const dragStartYRef = useRef(0);
144
- const unitRef = useRef(null);
145
- const handleUnitMouseDown = useCallback((e) => {
146
- if (disabled) return;
147
- e.preventDefault();
148
- setIsUnitDragging(true);
149
- dragStartValueRef.current = value;
150
- dragStartYRef.current = e.clientY;
151
- if (document.body.requestPointerLock) {
152
- document.body.requestPointerLock();
153
- }
154
- }, [value, disabled]);
155
- const handleUnitMouseMove = useCallback((e) => {
156
- if (!isUnitDragging) return;
157
- const deltaY = document.pointerLockElement ? -e.movementY : dragStartYRef.current - e.clientY;
158
- if (deltaY === 0) return;
159
- let speedMultiplier = 1;
160
- if (e.shiftKey) speedMultiplier = 0.1;
161
- else if (e.ctrlKey || e.metaKey) speedMultiplier = 10;
162
- const sensitivity = document.pointerLockElement ? 1 : 0.5;
163
- const change = deltaY * sensitivity * (step || 1) * speedMultiplier;
164
- if (!document.pointerLockElement) {
165
- dragStartYRef.current = e.clientY;
166
- dragStartValueRef.current = clamp(value + change);
167
- onChange(clamp(value + change));
168
- } else {
169
- onChange(clamp(value + change));
170
- }
171
- }, [isUnitDragging, value, step, onChange, clamp]);
172
- const handleUnitMouseUp = useCallback(() => {
173
- if (isUnitDragging) {
174
- setIsUnitDragging(false);
175
- if (document.exitPointerLock) {
176
- document.exitPointerLock();
177
- }
178
- }
179
- }, [isUnitDragging]);
180
- useEffect(() => {
181
- if (isUnitDragging) {
182
- window.addEventListener("mousemove", handleUnitMouseMove);
183
- window.addEventListener("mouseup", handleUnitMouseUp);
184
- }
185
- return () => {
186
- window.removeEventListener("mousemove", handleUnitMouseMove);
187
- window.removeEventListener("mouseup", handleUnitMouseUp);
188
- };
189
- }, [isUnitDragging, handleUnitMouseMove, handleUnitMouseUp]);
190
- useEffect(() => {
191
- const unitEl = unitRef.current;
192
- if (unitEl && !disabled) {
193
- unitEl.addEventListener("wheel", handleWheel, { passive: false });
194
- }
195
- return () => {
196
- if (unitEl) unitEl.removeEventListener("wheel", handleWheel);
197
- };
198
- }, [handleWheel, disabled]);
199
- const sizeConfig = {
200
- small: { height: tokens.elementSize.sm, fontSize: tokens.typography.fontSize.xs, padding: `${tokens.spacing.xs} ${tokens.spacing.sm}`, sliderHeight: 3, inputPaddingLeft: 8 },
201
- medium: { height: tokens.elementSize.md, fontSize: tokens.typography.fontSize.sm, padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`, sliderHeight: 4, inputPaddingLeft: 12 },
202
- large: { height: tokens.elementSize.lg, fontSize: tokens.typography.fontSize.base, padding: `${tokens.spacing.sm} ${tokens.spacing.md}`, sliderHeight: 5, inputPaddingLeft: 16 }
203
- };
204
- const config = sizeConfig[size];
205
- const hasError = !!error;
206
- const errorMessage = typeof error === "string" ? error : void 0;
207
- const computedBorder = hasError ? tokens.borders.input.error : isFocused ? tokens.borders.input.focus : isHovered ? tokens.borders.input.hover : tokens.borders.input.default;
208
- const inputBg = isTransparentTheme ? tokens.colors.interactive.transparentInputBg || "rgba(139, 92, 246, 0.08)" : tokens.colors.background.surface;
209
- const sliderPercent = min !== void 0 && max !== void 0 ? (value - min) / (max - min) * 100 : 50;
210
- const inputId = id || (typeof label === "string" ? `zendir-number-${label.replace(/\s+/g, "-").toLowerCase()}` : void 0);
211
- const thumbWidth = 24;
212
- const thumbHeight = config.sliderHeight + 8;
213
- const trackH = config.sliderHeight;
214
- return /* @__PURE__ */ jsxs(
215
- "div",
216
- {
217
- className,
218
- style: {
219
- display: "inline-flex",
220
- flexDirection: "column",
221
- // No gap when slider is present — slider sits flush on the input bottom edge
222
- gap: slider ? 0 : tokens.spacing.xs,
223
- width: fullWidth ? "100%" : typeof width === "number" ? `${width}px` : width,
224
- fontFamily: tokens.typography.fontFamily.primary,
225
- ...style
226
- },
227
- children: [
228
- label && !isOutlined && /* @__PURE__ */ jsxs(
229
- "label",
230
- {
231
- htmlFor: inputId,
232
- style: {
233
- fontSize: tokens.typography.fontSize.xs,
234
- fontWeight: tokens.typography.fontWeight.medium,
235
- color: tokens.colors.text.secondary,
236
- letterSpacing: tokens.typography.letterSpacing.wide
237
- },
238
- children: [
239
- label,
240
- required && /* @__PURE__ */ jsx("span", { style: { color: tokens.colors.status.critical, marginLeft: "2px" }, children: "*" })
241
- ]
242
- }
243
- ),
244
- /* @__PURE__ */ jsxs(
245
- "div",
246
- {
247
- style: {
248
- position: "relative",
249
- display: "flex",
250
- alignItems: "center",
251
- height: config.height,
252
- backgroundColor: inputBg,
253
- border: computedBorder,
254
- borderRadius: tokens.borderRadius.md,
255
- transition: tokens.animation.fast,
256
- opacity: disabled ? 0.5 : 1,
257
- overflow: isOutlined ? "visible" : "hidden"
258
- },
259
- onMouseEnter: () => !disabled && setIsHovered(true),
260
- onMouseLeave: () => setIsHovered(false),
261
- children: [
262
- label && isOutlined && /* @__PURE__ */ jsxs(
263
- "label",
264
- {
265
- htmlFor: inputId,
266
- style: {
267
- position: "absolute",
268
- top: 0,
269
- left: `${config.inputPaddingLeft - 6}px`,
270
- transform: "translateY(-50%)",
271
- backgroundColor: isTransparentTheme ? tokens.colors.background.base : tokens.colors.background.surface,
272
- padding: "0 6px",
273
- fontSize: { small: "0.625rem", medium: "0.6875rem", large: "0.75rem" }[size],
274
- fontWeight: tokens.typography.fontWeight.medium,
275
- color: isFocused ? hasError ? tokens.colors.status.critical : tokens.colors.accent.primary : hasError ? tokens.colors.status.critical : tokens.colors.text.secondary,
276
- letterSpacing: tokens.typography.letterSpacing.wide,
277
- zIndex: 1,
278
- pointerEvents: "none",
279
- transition: tokens.animation.fast,
280
- lineHeight: 1.2,
281
- whiteSpace: "nowrap"
282
- },
283
- children: [
284
- label,
285
- required && /* @__PURE__ */ jsx("span", { style: { color: tokens.colors.status.critical, marginLeft: "2px" }, children: "*" })
286
- ]
287
- }
288
- ),
289
- /* @__PURE__ */ jsx(
290
- "input",
291
- {
292
- ref: ref || inputRef,
293
- id: inputId,
294
- type: "text",
295
- inputMode: "decimal",
296
- value: localValue,
297
- onChange: handleInputChange,
298
- onFocus: () => setIsFocused(true),
299
- onBlur: handleBlur,
300
- onKeyDown: handleKeyDown,
301
- disabled,
302
- "aria-invalid": hasError,
303
- "aria-describedby": errorMessage ? `${inputId}-error` : helperText ? `${inputId}-helper` : void 0,
304
- style: {
305
- flex: 1,
306
- height: "100%",
307
- padding: config.padding,
308
- fontSize: config.fontSize,
309
- fontWeight: tokens.typography.fontWeight.medium,
310
- fontFamily: tokens.typography.fontFamily.mono,
311
- fontVariantNumeric: "tabular-nums",
312
- color: tokens.colors.text.primary,
313
- backgroundColor: "transparent",
314
- border: "none",
315
- outline: "none",
316
- minWidth: 0,
317
- textAlign
318
- }
319
- }
320
- ),
321
- unit && /* @__PURE__ */ jsx(
322
- "span",
323
- {
324
- ref: unitRef,
325
- onMouseDown: handleUnitMouseDown,
326
- style: {
327
- padding: `0 ${tokens.spacing.sm}`,
328
- fontSize: tokens.typography.fontSize.xs,
329
- fontWeight: tokens.typography.fontWeight.medium,
330
- color: isUnitDragging ? activeColor : tokens.colors.text.tertiary,
331
- fontFamily: tokens.typography.fontFamily.primary,
332
- flexShrink: 0,
333
- borderLeft: tokens.borders.separator,
334
- height: "100%",
335
- display: "flex",
336
- alignItems: "center",
337
- backgroundColor: isTransparentTheme ? "rgba(139, 92, 246, 0.04)" : "rgba(0, 0, 0, 0.15)",
338
- cursor: disabled ? "not-allowed" : "ns-resize",
339
- userSelect: "none",
340
- transition: "color 0.2s ease"
341
- },
342
- title: disabled ? void 0 : "Drag to adjust value",
343
- children: unit
344
- }
345
- )
346
- ]
347
- }
348
- ),
349
- slider && min !== void 0 && max !== void 0 && (() => {
350
- const sliderH = thumbHeight;
351
- const cy = sliderH / 2;
352
- const pct = sliderPercent / 100;
353
- const thumbLeftCalc = `calc(${pct} * (100% - ${thumbWidth}px))`;
354
- const filledWidthCalc = `calc(${pct} * (100% - ${thumbWidth}px) + 1px)`;
355
- return /* @__PURE__ */ jsxs(
356
- "div",
357
- {
358
- ref: sliderContainerRef,
359
- style: {
360
- position: "relative",
361
- height: `${sliderH}px`,
362
- marginTop: `-${sliderH / 1.42}px`
363
- },
364
- children: [
365
- /* @__PURE__ */ jsx("div", { style: {
366
- position: "absolute",
367
- top: `${cy}px`,
368
- left: 0,
369
- right: 0,
370
- height: `${trackH}px`,
371
- transform: "translateY(-50%)",
372
- borderRadius: `${trackH / 2}px`,
373
- backgroundColor: `${tokens.colors.border.muted}60`
374
- } }),
375
- /* @__PURE__ */ jsx("div", { style: {
376
- position: "absolute",
377
- top: `${cy}px`,
378
- left: 0,
379
- width: filledWidthCalc,
380
- height: `${trackH}px`,
381
- transform: "translateY(-50%)",
382
- borderRadius: `${trackH / 2}px 0 0 ${trackH / 2}px`,
383
- background: activeColor,
384
- transition: "background 300ms ease"
385
- } }),
386
- /* @__PURE__ */ jsx(
387
- "input",
388
- {
389
- type: "range",
390
- className: `zendir-slider-${sliderId}`,
391
- min,
392
- max,
393
- step,
394
- value,
395
- onChange: handleSliderChange,
396
- onMouseDown: () => setIsSliderActive(true),
397
- onMouseUp: () => setIsSliderActive(false),
398
- onTouchStart: () => setIsSliderActive(true),
399
- onTouchEnd: () => setIsSliderActive(false),
400
- disabled,
401
- "aria-label": typeof label === "string" ? label : "Value slider",
402
- style: {
403
- position: "absolute",
404
- top: 0,
405
- left: 0,
406
- width: "100%",
407
- height: "100%",
408
- margin: 0,
409
- padding: 0,
410
- opacity: 0,
411
- cursor: disabled ? "not-allowed" : "pointer",
412
- zIndex: 2
413
- }
414
- }
415
- ),
416
- /* @__PURE__ */ jsx(
417
- "div",
418
- {
419
- style: {
420
- position: "absolute",
421
- top: `${cy}px`,
422
- left: thumbLeftCalc,
423
- width: `${thumbWidth}px`,
424
- height: `${thumbHeight}px`,
425
- transform: "translateY(-50%)",
426
- pointerEvents: "none",
427
- zIndex: 1
428
- },
429
- children: /* @__PURE__ */ jsx(
430
- "svg",
431
- {
432
- width: thumbWidth,
433
- height: thumbHeight,
434
- viewBox: `0 0 ${thumbWidth} ${thumbHeight}`,
435
- xmlns: "http://www.w3.org/2000/svg",
436
- style: { display: "block", overflow: "visible" },
437
- children: (() => {
438
- const w = thumbWidth;
439
- const h = thumbHeight;
440
- const svgCy = h / 2;
441
- const trackHalf = trackH / 2;
442
- const r = 2;
443
- const ltop = svgCy - trackHalf;
444
- const lbot = svgCy + trackHalf;
445
- const rtop = r;
446
- const rbot = h - r;
447
- const cp1x = w * 0.28;
448
- const cp2x = w * 0.48;
449
- const d = [
450
- `M 0 ${ltop}`,
451
- `C ${cp1x} ${ltop}, ${cp2x} ${rtop}, ${w - r} ${rtop}`,
452
- `A ${r} ${r} 0 0 1 ${w} ${rtop + r}`,
453
- `L ${w} ${rbot - r}`,
454
- `A ${r} ${r} 0 0 1 ${w - r} ${rbot}`,
455
- `C ${cp2x} ${rbot}, ${cp1x} ${lbot}, 0 ${lbot}`,
456
- `Z`
457
- ].join(" ");
458
- return /* @__PURE__ */ jsx("path", { d, fill: activeColor });
459
- })()
460
- }
461
- )
462
- }
463
- ),
464
- statusMode && resolvedStatus && /* @__PURE__ */ jsx(
465
- "div",
466
- {
467
- style: {
468
- position: "absolute",
469
- bottom: `-${size === "large" ? 10 : 8}px`,
470
- left: `calc(${pct} * (100% - ${thumbWidth}px) + ${thumbWidth / 2}px)`,
471
- transform: "translateX(-50%)",
472
- zIndex: 1,
473
- lineHeight: 0
474
- },
475
- children: /* @__PURE__ */ jsx(
476
- StatusIndicator,
477
- {
478
- status: resolvedStatus,
479
- small: true
480
- }
481
- )
482
- }
483
- )
484
- ]
485
- }
486
- );
487
- })(),
488
- (helperText || errorMessage) && /* @__PURE__ */ jsx(
489
- "div",
490
- {
491
- id: errorMessage ? `${inputId}-error` : `${inputId}-helper`,
492
- role: errorMessage ? "alert" : void 0,
493
- style: {
494
- fontSize: tokens.typography.fontSize.xs,
495
- color: hasError ? tokens.colors.status.critical : tokens.colors.text.tertiary
496
- },
497
- children: errorMessage || helperText
498
- }
499
- )
500
- ]
501
- }
502
- );
4
+ import { forwardRef, memo, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/react/core/inputs/NumberInput.tsx
7
+ /**
8
+ * @zendir/ui - NumberInput Component
9
+ *
10
+ * Numeric input with optional slider, min/max bounds, step, precision,
11
+ * and unit display. Essential for operator dashboards (frequency, power,
12
+ * aperture, field of view, etc.).
13
+ *
14
+ * Astro UX Compliance:
15
+ * - Consistent sizing with Input component (small/medium/large)
16
+ * - Focus ring for accessibility (WCAG 2.1 AA)
17
+ * - Status-based border colors
18
+ * - Tabular numbers for value alignment
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * // Each instance can set precision (decimal places); default is 2
23
+ * <NumberInput value={500} onChange={setFreq} min={300} max={900} unit="MHz" label="Frequency" />
24
+ * <NumberInput value={45.2} onChange={setPower} min={0.1} max={100} step={0.1} precision={1} unit="W" slider />
25
+ * <NumberInput value={1024} onChange={setRes} min={128} max={2048} step={128} precision={0} unit="px" label="Resolution" slider />
26
+ * // Status mode with automatic threshold-based coloring:
27
+ * <NumberInput value={temp} onChange={setTemp} min={0} max={100} unit="°C" slider
28
+ * statusMode statusThresholds={{ critical: 90, serious: 75, caution: 50, normal: 20, standby: 0 }} />
29
+ * ```
30
+ */
31
+ /** Default decimal places when precision is not specified: 0 = integer display. Set precision (e.g. 2) to show decimals. */
32
+ var DEFAULT_DECIMAL_PLACES = 0;
33
+ var NumberInput = memo(forwardRef(function NumberInput({ value, onChange, min, max, step = 1, precision, unit, label, helperText, error, slider = false, size = "medium", disabled = false, fullWidth = false, width, id, className, style, textAlign = "right", labelPlacement = "outlined", required, statusMode = false, status: statusOverride, statusThresholds, onStatusChange }, ref) {
34
+ const { tokens, theme } = useTheme();
35
+ const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
36
+ const isOutlined = labelPlacement === "outlined";
37
+ const decimalPlaces = precision ?? DEFAULT_DECIMAL_PLACES;
38
+ const [isFocused, setIsFocused] = useState(false);
39
+ const [isHovered, setIsHovered] = useState(false);
40
+ const [isSliderActive, setIsSliderActive] = useState(false);
41
+ const [localValue, setLocalValue] = useState(() => value.toFixed(decimalPlaces));
42
+ const inputRef = useRef(null);
43
+ const sliderContainerRef = useRef(null);
44
+ const sliderId = useId().replace(/:/g, "");
45
+ const resolvedStatus = useMemo(() => {
46
+ if (!statusMode) return void 0;
47
+ if (statusOverride) return statusOverride;
48
+ return deriveStatus(value, statusThresholds);
49
+ }, [
50
+ statusMode,
51
+ statusOverride,
52
+ statusThresholds,
53
+ value
54
+ ]);
55
+ const prevStatusRef = useRef(void 0);
56
+ useEffect(() => {
57
+ if (resolvedStatus !== void 0 && resolvedStatus !== prevStatusRef.current) {
58
+ prevStatusRef.current = resolvedStatus;
59
+ onStatusChange?.(resolvedStatus);
60
+ }
61
+ }, [resolvedStatus, onStatusChange]);
62
+ /** Resolve the active color: status color or accent */
63
+ const activeColor = useMemo(() => {
64
+ if (resolvedStatus && tokens.colors.status[resolvedStatus]) return tokens.colors.status[resolvedStatus];
65
+ return tokens.colors.accent.primary;
66
+ }, [
67
+ resolvedStatus,
68
+ tokens.colors.status,
69
+ tokens.colors.accent.primary
70
+ ]);
71
+ useEffect(() => {
72
+ if (!isFocused) setLocalValue(value.toFixed(decimalPlaces));
73
+ }, [
74
+ value,
75
+ decimalPlaces,
76
+ isFocused
77
+ ]);
78
+ const clamp = useCallback((v) => {
79
+ let result = v;
80
+ if (min !== void 0) result = Math.max(min, result);
81
+ if (max !== void 0) result = Math.min(max, result);
82
+ result = Number(result.toFixed(decimalPlaces));
83
+ return result;
84
+ }, [
85
+ min,
86
+ max,
87
+ decimalPlaces
88
+ ]);
89
+ const handleInputChange = useCallback((e) => {
90
+ const raw = e.target.value;
91
+ setLocalValue(raw);
92
+ const parsed = parseFloat(raw);
93
+ if (!isNaN(parsed)) onChange(clamp(parsed));
94
+ }, [onChange, clamp]);
95
+ const handleBlur = useCallback(() => {
96
+ setIsFocused(false);
97
+ const parsed = parseFloat(localValue);
98
+ if (isNaN(parsed)) setLocalValue(value.toFixed(decimalPlaces));
99
+ else {
100
+ const clamped = clamp(parsed);
101
+ onChange(clamped);
102
+ setLocalValue(clamped.toFixed(decimalPlaces));
103
+ }
104
+ }, [
105
+ localValue,
106
+ value,
107
+ onChange,
108
+ clamp,
109
+ decimalPlaces
110
+ ]);
111
+ const handleSliderChange = useCallback((e) => {
112
+ const parsed = parseFloat(e.target.value);
113
+ const clamped = clamp(parsed);
114
+ onChange(clamped);
115
+ setLocalValue(clamped.toFixed(decimalPlaces));
116
+ }, [
117
+ onChange,
118
+ clamp,
119
+ decimalPlaces
120
+ ]);
121
+ const handleKeyDown = useCallback((e) => {
122
+ if (e.key === "ArrowUp") {
123
+ e.preventDefault();
124
+ onChange(clamp(value + step));
125
+ } else if (e.key === "ArrowDown") {
126
+ e.preventDefault();
127
+ onChange(clamp(value - step));
128
+ }
129
+ }, [
130
+ value,
131
+ step,
132
+ onChange,
133
+ clamp
134
+ ]);
135
+ const handleWheel = useCallback((e) => {
136
+ if (disabled || min === void 0 || max === void 0) return;
137
+ e.preventDefault();
138
+ const direction = e.deltaY < 0 ? 1 : -1;
139
+ onChange(clamp(value + step * direction));
140
+ }, [
141
+ value,
142
+ step,
143
+ onChange,
144
+ clamp,
145
+ disabled,
146
+ min,
147
+ max
148
+ ]);
149
+ useEffect(() => {
150
+ const sliderContainer = sliderContainerRef.current;
151
+ const inputElement = inputRef.current;
152
+ if (min !== void 0 && max !== void 0) {
153
+ if (slider && sliderContainer) sliderContainer.addEventListener("wheel", handleWheel, { passive: false });
154
+ if (inputElement) inputElement.addEventListener("wheel", handleWheel, { passive: false });
155
+ }
156
+ return () => {
157
+ if (sliderContainer) sliderContainer.removeEventListener("wheel", handleWheel);
158
+ if (inputElement) inputElement.removeEventListener("wheel", handleWheel);
159
+ };
160
+ }, [
161
+ handleWheel,
162
+ slider,
163
+ min,
164
+ max
165
+ ]);
166
+ useEffect(() => {
167
+ if (!isSliderActive) return;
168
+ const handleUp = () => setIsSliderActive(false);
169
+ window.addEventListener("mouseup", handleUp);
170
+ window.addEventListener("touchend", handleUp);
171
+ return () => {
172
+ window.removeEventListener("mouseup", handleUp);
173
+ window.removeEventListener("touchend", handleUp);
174
+ };
175
+ }, [isSliderActive]);
176
+ const [isUnitDragging, setIsUnitDragging] = useState(false);
177
+ const dragStartValueRef = useRef(0);
178
+ const dragStartYRef = useRef(0);
179
+ const unitRef = useRef(null);
180
+ const handleUnitMouseDown = useCallback((e) => {
181
+ if (disabled) return;
182
+ e.preventDefault();
183
+ setIsUnitDragging(true);
184
+ dragStartValueRef.current = value;
185
+ dragStartYRef.current = e.clientY;
186
+ if (document.body.requestPointerLock) document.body.requestPointerLock();
187
+ }, [value, disabled]);
188
+ const handleUnitMouseMove = useCallback((e) => {
189
+ if (!isUnitDragging) return;
190
+ const deltaY = document.pointerLockElement ? -e.movementY : dragStartYRef.current - e.clientY;
191
+ if (deltaY === 0) return;
192
+ let speedMultiplier = 1;
193
+ if (e.shiftKey) speedMultiplier = .1;
194
+ else if (e.ctrlKey || e.metaKey) speedMultiplier = 10;
195
+ const change = deltaY * (document.pointerLockElement ? 1 : .5) * (step || 1) * speedMultiplier;
196
+ if (!document.pointerLockElement) {
197
+ dragStartYRef.current = e.clientY;
198
+ dragStartValueRef.current = clamp(value + change);
199
+ onChange(clamp(value + change));
200
+ } else onChange(clamp(value + change));
201
+ }, [
202
+ isUnitDragging,
203
+ value,
204
+ step,
205
+ onChange,
206
+ clamp
207
+ ]);
208
+ const handleUnitMouseUp = useCallback(() => {
209
+ if (isUnitDragging) {
210
+ setIsUnitDragging(false);
211
+ if (document.exitPointerLock) document.exitPointerLock();
212
+ }
213
+ }, [isUnitDragging]);
214
+ useEffect(() => {
215
+ if (isUnitDragging) {
216
+ window.addEventListener("mousemove", handleUnitMouseMove);
217
+ window.addEventListener("mouseup", handleUnitMouseUp);
218
+ }
219
+ return () => {
220
+ window.removeEventListener("mousemove", handleUnitMouseMove);
221
+ window.removeEventListener("mouseup", handleUnitMouseUp);
222
+ };
223
+ }, [
224
+ isUnitDragging,
225
+ handleUnitMouseMove,
226
+ handleUnitMouseUp
227
+ ]);
228
+ useEffect(() => {
229
+ const unitEl = unitRef.current;
230
+ if (unitEl && !disabled) unitEl.addEventListener("wheel", handleWheel, { passive: false });
231
+ return () => {
232
+ if (unitEl) unitEl.removeEventListener("wheel", handleWheel);
233
+ };
234
+ }, [handleWheel, disabled]);
235
+ const config = {
236
+ small: {
237
+ height: tokens.elementSize.sm,
238
+ fontSize: tokens.typography.fontSize.xs,
239
+ padding: `${tokens.spacing.xs} ${tokens.spacing.sm}`,
240
+ sliderHeight: 3,
241
+ inputPaddingLeft: 8
242
+ },
243
+ medium: {
244
+ height: tokens.elementSize.md,
245
+ fontSize: tokens.typography.fontSize.sm,
246
+ padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`,
247
+ sliderHeight: 4,
248
+ inputPaddingLeft: 12
249
+ },
250
+ large: {
251
+ height: tokens.elementSize.lg,
252
+ fontSize: tokens.typography.fontSize.base,
253
+ padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,
254
+ sliderHeight: 5,
255
+ inputPaddingLeft: 16
256
+ }
257
+ }[size];
258
+ const hasError = !!error;
259
+ const errorMessage = typeof error === "string" ? error : void 0;
260
+ const computedBorder = hasError ? tokens.borders.input.error : isFocused ? tokens.borders.input.focus : isHovered ? tokens.borders.input.hover : tokens.borders.input.default;
261
+ const inputBg = isTransparentTheme ? tokens.colors.interactive.transparentInputBg || "rgba(139, 92, 246, 0.08)" : tokens.colors.background.surface;
262
+ const sliderPercent = min !== void 0 && max !== void 0 ? (value - min) / (max - min) * 100 : 50;
263
+ const inputId = id || (typeof label === "string" ? `zendir-number-${label.replace(/\s+/g, "-").toLowerCase()}` : void 0);
264
+ const thumbWidth = 24;
265
+ const thumbHeight = config.sliderHeight + 8;
266
+ const trackH = config.sliderHeight;
267
+ return /* @__PURE__ */ jsxs("div", {
268
+ className,
269
+ style: {
270
+ display: "inline-flex",
271
+ flexDirection: "column",
272
+ gap: slider ? 0 : tokens.spacing.xs,
273
+ width: fullWidth ? "100%" : typeof width === "number" ? `${width}px` : width,
274
+ fontFamily: tokens.typography.fontFamily.primary,
275
+ ...style
276
+ },
277
+ children: [
278
+ label && !isOutlined && /* @__PURE__ */ jsxs("label", {
279
+ htmlFor: inputId,
280
+ style: {
281
+ fontSize: tokens.typography.fontSize.xs,
282
+ fontWeight: tokens.typography.fontWeight.medium,
283
+ color: tokens.colors.text.secondary,
284
+ letterSpacing: tokens.typography.letterSpacing.wide
285
+ },
286
+ children: [label, required && /* @__PURE__ */ jsx("span", {
287
+ style: {
288
+ color: tokens.colors.status.critical,
289
+ marginLeft: "2px"
290
+ },
291
+ children: "*"
292
+ })]
293
+ }),
294
+ /* @__PURE__ */ jsxs("div", {
295
+ style: {
296
+ position: "relative",
297
+ display: "flex",
298
+ alignItems: "center",
299
+ height: config.height,
300
+ backgroundColor: inputBg,
301
+ border: computedBorder,
302
+ borderRadius: tokens.borderRadius.md,
303
+ transition: tokens.animation.fast,
304
+ opacity: disabled ? .5 : 1,
305
+ overflow: isOutlined ? "visible" : "hidden"
306
+ },
307
+ onMouseEnter: () => !disabled && setIsHovered(true),
308
+ onMouseLeave: () => setIsHovered(false),
309
+ children: [
310
+ label && isOutlined && /* @__PURE__ */ jsxs("label", {
311
+ htmlFor: inputId,
312
+ style: {
313
+ position: "absolute",
314
+ top: 0,
315
+ left: `${config.inputPaddingLeft - 6}px`,
316
+ transform: "translateY(-50%)",
317
+ backgroundColor: isTransparentTheme ? tokens.colors.background.base : tokens.colors.background.surface,
318
+ padding: "0 6px",
319
+ fontSize: {
320
+ small: "0.625rem",
321
+ medium: "0.6875rem",
322
+ large: "0.75rem"
323
+ }[size],
324
+ fontWeight: tokens.typography.fontWeight.medium,
325
+ color: isFocused ? hasError ? tokens.colors.status.critical : tokens.colors.accent.primary : hasError ? tokens.colors.status.critical : tokens.colors.text.secondary,
326
+ letterSpacing: tokens.typography.letterSpacing.wide,
327
+ zIndex: 1,
328
+ pointerEvents: "none",
329
+ transition: tokens.animation.fast,
330
+ lineHeight: 1.2,
331
+ whiteSpace: "nowrap"
332
+ },
333
+ children: [label, required && /* @__PURE__ */ jsx("span", {
334
+ style: {
335
+ color: tokens.colors.status.critical,
336
+ marginLeft: "2px"
337
+ },
338
+ children: "*"
339
+ })]
340
+ }),
341
+ /* @__PURE__ */ jsx("input", {
342
+ ref: ref || inputRef,
343
+ id: inputId,
344
+ type: "text",
345
+ inputMode: "decimal",
346
+ value: localValue,
347
+ onChange: handleInputChange,
348
+ onFocus: () => setIsFocused(true),
349
+ onBlur: handleBlur,
350
+ onKeyDown: handleKeyDown,
351
+ disabled,
352
+ "aria-invalid": hasError,
353
+ "aria-describedby": errorMessage ? `${inputId}-error` : helperText ? `${inputId}-helper` : void 0,
354
+ style: {
355
+ flex: 1,
356
+ height: "100%",
357
+ padding: config.padding,
358
+ fontSize: config.fontSize,
359
+ fontWeight: tokens.typography.fontWeight.medium,
360
+ fontFamily: tokens.typography.fontFamily.mono,
361
+ fontVariantNumeric: "tabular-nums",
362
+ color: tokens.colors.text.primary,
363
+ backgroundColor: "transparent",
364
+ border: "none",
365
+ outline: "none",
366
+ minWidth: 0,
367
+ textAlign
368
+ }
369
+ }),
370
+ unit && /* @__PURE__ */ jsx("span", {
371
+ ref: unitRef,
372
+ onMouseDown: handleUnitMouseDown,
373
+ style: {
374
+ padding: `0 ${tokens.spacing.sm}`,
375
+ fontSize: tokens.typography.fontSize.xs,
376
+ fontWeight: tokens.typography.fontWeight.medium,
377
+ color: isUnitDragging ? activeColor : tokens.colors.text.tertiary,
378
+ fontFamily: tokens.typography.fontFamily.primary,
379
+ flexShrink: 0,
380
+ borderLeft: tokens.borders.separator,
381
+ height: "100%",
382
+ display: "flex",
383
+ alignItems: "center",
384
+ backgroundColor: isTransparentTheme ? `${tokens.colors.accent.primary}0a` : "rgba(0, 0, 0, 0.15)",
385
+ cursor: disabled ? "not-allowed" : "ns-resize",
386
+ userSelect: "none",
387
+ transition: "color 0.2s ease"
388
+ },
389
+ title: disabled ? void 0 : "Drag to adjust value",
390
+ children: unit
391
+ })
392
+ ]
393
+ }),
394
+ slider && min !== void 0 && max !== void 0 && (() => {
395
+ const sliderH = thumbHeight;
396
+ const cy = sliderH / 2;
397
+ const pct = sliderPercent / 100;
398
+ const thumbLeftCalc = `calc(${pct} * (100% - ${thumbWidth}px))`;
399
+ const filledWidthCalc = `calc(${pct} * (100% - ${thumbWidth}px) + 1px)`;
400
+ return /* @__PURE__ */ jsxs("div", {
401
+ ref: sliderContainerRef,
402
+ style: {
403
+ position: "relative",
404
+ height: `${sliderH}px`,
405
+ marginTop: `-${sliderH / 1.42}px`
406
+ },
407
+ children: [
408
+ /* @__PURE__ */ jsx("div", { style: {
409
+ position: "absolute",
410
+ top: `${cy}px`,
411
+ left: 0,
412
+ right: 0,
413
+ height: `${trackH}px`,
414
+ transform: "translateY(-50%)",
415
+ borderRadius: `${trackH / 2}px`,
416
+ backgroundColor: `${tokens.colors.border.muted}60`
417
+ } }),
418
+ /* @__PURE__ */ jsx("div", { style: {
419
+ position: "absolute",
420
+ top: `${cy}px`,
421
+ left: 0,
422
+ width: filledWidthCalc,
423
+ height: `${trackH}px`,
424
+ transform: "translateY(-50%)",
425
+ borderRadius: `${trackH / 2}px 0 0 ${trackH / 2}px`,
426
+ background: activeColor,
427
+ transition: "background 300ms ease"
428
+ } }),
429
+ /* @__PURE__ */ jsx("input", {
430
+ type: "range",
431
+ className: `zendir-slider-${sliderId}`,
432
+ min,
433
+ max,
434
+ step,
435
+ value,
436
+ onChange: handleSliderChange,
437
+ onMouseDown: () => setIsSliderActive(true),
438
+ onMouseUp: () => setIsSliderActive(false),
439
+ onTouchStart: () => setIsSliderActive(true),
440
+ onTouchEnd: () => setIsSliderActive(false),
441
+ disabled,
442
+ "aria-label": typeof label === "string" ? label : "Value slider",
443
+ style: {
444
+ position: "absolute",
445
+ top: 0,
446
+ left: 0,
447
+ width: "100%",
448
+ height: "100%",
449
+ margin: 0,
450
+ padding: 0,
451
+ opacity: 0,
452
+ cursor: disabled ? "not-allowed" : "pointer",
453
+ zIndex: 2
454
+ }
455
+ }),
456
+ /* @__PURE__ */ jsx("div", {
457
+ style: {
458
+ position: "absolute",
459
+ top: `${cy}px`,
460
+ left: thumbLeftCalc,
461
+ width: `${thumbWidth}px`,
462
+ height: `${thumbHeight}px`,
463
+ transform: "translateY(-50%)",
464
+ pointerEvents: "none",
465
+ zIndex: 1
466
+ },
467
+ children: /* @__PURE__ */ jsx("svg", {
468
+ width: thumbWidth,
469
+ height: thumbHeight,
470
+ viewBox: `0 0 ${thumbWidth} ${thumbHeight}`,
471
+ xmlns: "http://www.w3.org/2000/svg",
472
+ style: {
473
+ display: "block",
474
+ overflow: "visible"
475
+ },
476
+ children: (() => {
477
+ const w = thumbWidth;
478
+ const h = thumbHeight;
479
+ const svgCy = h / 2;
480
+ const trackHalf = trackH / 2;
481
+ const r = 2;
482
+ const ltop = svgCy - trackHalf;
483
+ const lbot = svgCy + trackHalf;
484
+ const rtop = r;
485
+ const rbot = h - r;
486
+ const cp1x = w * .28;
487
+ const cp2x = w * .48;
488
+ return /* @__PURE__ */ jsx("path", {
489
+ d: [
490
+ `M 0 ${ltop}`,
491
+ `C ${cp1x} ${ltop}, ${cp2x} ${rtop}, ${w - r} ${rtop}`,
492
+ `A ${r} ${r} 0 0 1 ${w} 4`,
493
+ `L ${w} ${rbot - r}`,
494
+ `A ${r} ${r} 0 0 1 ${w - r} ${rbot}`,
495
+ `C ${cp2x} ${rbot}, ${cp1x} ${lbot}, 0 ${lbot}`,
496
+ `Z`
497
+ ].join(" "),
498
+ fill: activeColor
499
+ });
500
+ })()
501
+ })
502
+ }),
503
+ statusMode && resolvedStatus && /* @__PURE__ */ jsx("div", {
504
+ style: {
505
+ position: "absolute",
506
+ bottom: `-${size === "large" ? 10 : 8}px`,
507
+ left: `calc(${pct} * (100% - ${thumbWidth}px) + ${thumbWidth / 2}px)`,
508
+ transform: "translateX(-50%)",
509
+ zIndex: 1,
510
+ lineHeight: 0
511
+ },
512
+ children: /* @__PURE__ */ jsx(StatusIndicator, {
513
+ status: resolvedStatus,
514
+ small: true
515
+ })
516
+ })
517
+ ]
518
+ });
519
+ })(),
520
+ (helperText || errorMessage) && /* @__PURE__ */ jsx("div", {
521
+ id: errorMessage ? `${inputId}-error` : `${inputId}-helper`,
522
+ role: errorMessage ? "alert" : void 0,
523
+ style: {
524
+ fontSize: tokens.typography.fontSize.xs,
525
+ color: hasError ? tokens.colors.status.critical : tokens.colors.text.tertiary
526
+ },
527
+ children: errorMessage || helperText
528
+ })
529
+ ]
530
+ });
503
531
  }));
504
- export {
505
- NumberInput
506
- };
507
- //# sourceMappingURL=NumberInput.js.map
532
+ //#endregion
533
+ export { NumberInput, NumberInput as default };
534
+
535
+ //# sourceMappingURL=NumberInput.js.map