@zendir/ui 0.2.21 → 0.3.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 (261) hide show
  1. package/CHANGELOG.md +183 -1
  2. package/README.md +70 -28
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +51 -42
  5. package/dist/index.js.map +1 -1
  6. package/dist/react/3d/CesiumCaptureSource.d.ts +1 -1
  7. package/dist/react/3d/CesiumCaptureSource.js +1 -1
  8. package/dist/react/3d/CesiumCaptureSource.js.map +1 -1
  9. package/dist/react/3d/ZenSpace3D.js +1253 -0
  10. package/dist/react/3d/ZenSpace3D.js.map +1 -0
  11. package/dist/react/3d/ZenSpace3DCesium.js +579 -0
  12. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
  13. package/dist/react/3d/ZenSpace3DTypes.d.ts +28 -1
  14. package/dist/react/3d/ZenSpace3DUtils.d.ts +17 -173
  15. package/dist/react/3d/ZenSpace3DUtils.js +20 -1
  16. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -1
  17. package/dist/react/3d/index.d.ts +6 -12
  18. package/dist/react/3d/threeLoader.js +18 -0
  19. package/dist/react/3d/threeLoader.js.map +1 -0
  20. package/dist/react/astro/MonitoringIcon.js +1 -1
  21. package/dist/react/astro/MonitoringIcon.js.map +1 -1
  22. package/dist/react/astro/SimulationControls.js +2 -2
  23. package/dist/react/astro/SimulationControls.js.map +1 -1
  24. package/dist/react/astro/UnifiedTimeline.js +4 -4
  25. package/dist/react/astro/UnifiedTimeline.js.map +1 -1
  26. package/dist/react/charts/GroundTrackMap.d.ts +2 -15
  27. package/dist/react/charts/GroundTrackMap.js +1 -1
  28. package/dist/react/charts/GroundTrackMap.js.map +1 -1
  29. package/dist/react/charts/unified/AstroChart.js +34 -13
  30. package/dist/react/charts/unified/AstroChart.js.map +1 -1
  31. package/dist/react/chatgpt/AppCard.d.ts +0 -4
  32. package/dist/react/chatgpt/index.d.ts +0 -19
  33. package/dist/react/context/SpatialSelectionContext.d.ts +40 -0
  34. package/dist/react/context/SpatialSelectionContext.js +10 -0
  35. package/dist/react/context/SpatialSelectionContext.js.map +1 -0
  36. package/dist/react/context/index.d.ts +2 -0
  37. package/dist/react/core/{DataTable.d.ts → data/DataTable.d.ts} +1 -1
  38. package/dist/react/core/{DataTable.js → data/DataTable.js} +4 -4
  39. package/dist/react/core/data/DataTable.js.map +1 -0
  40. package/dist/react/core/{DataValue.d.ts → data/DataValue.d.ts} +2 -2
  41. package/dist/react/core/{DataValue.js → data/DataValue.js} +2 -2
  42. package/dist/react/core/data/DataValue.js.map +1 -0
  43. package/dist/react/core/{propertyConfig.d.ts → data/propertyConfig.d.ts} +2 -2
  44. package/dist/react/core/data/propertyConfig.js.map +1 -0
  45. package/dist/react/core/{AstroIcon.js → display/AstroIcon.js} +1 -1
  46. package/dist/react/core/display/AstroIcon.js.map +1 -0
  47. package/dist/react/core/{Badge.d.ts → display/Badge.d.ts} +1 -1
  48. package/dist/react/core/{Badge.js → display/Badge.js} +2 -2
  49. package/dist/react/core/display/Badge.js.map +1 -0
  50. package/dist/react/core/{CardHeader.d.ts → display/CardHeader.d.ts} +1 -1
  51. package/dist/react/core/{CardHeader.js → display/CardHeader.js} +2 -2
  52. package/dist/react/core/display/CardHeader.js.map +1 -0
  53. package/dist/react/core/{Container.d.ts → display/Container.d.ts} +1 -1
  54. package/dist/react/core/{Container.js → display/Container.js} +3 -3
  55. package/dist/react/core/display/Container.js.map +1 -0
  56. package/dist/react/core/{CopyButton.js → display/CopyButton.js} +1 -1
  57. package/dist/react/core/display/CopyButton.js.map +1 -0
  58. package/dist/react/core/{GlassCard.d.ts → display/GlassCard.d.ts} +1 -1
  59. package/dist/react/core/{GlassCard.js → display/GlassCard.js} +2 -2
  60. package/dist/react/core/display/GlassCard.js.map +1 -0
  61. package/dist/react/core/{HeaderIconWithStatus.d.ts → display/HeaderIconWithStatus.d.ts} +1 -1
  62. package/dist/react/core/{HeaderIconWithStatus.js → display/HeaderIconWithStatus.js} +1 -1
  63. package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -0
  64. package/dist/react/core/{Icon.d.ts → display/Icon.d.ts} +1 -1
  65. package/dist/react/core/{Icon.js → display/Icon.js} +1 -1
  66. package/dist/react/core/display/Icon.js.map +1 -0
  67. package/dist/react/core/{Typography.d.ts → display/Typography.d.ts} +13 -4
  68. package/dist/react/core/{Typography.js → display/Typography.js} +1 -1
  69. package/dist/react/core/display/Typography.js.map +1 -0
  70. package/dist/react/core/{ConfirmDialog.js → feedback/ConfirmDialog.js} +1 -1
  71. package/dist/react/core/feedback/ConfirmDialog.js.map +1 -0
  72. package/dist/react/core/{Dialog.js → feedback/Dialog.js} +2 -2
  73. package/dist/react/core/feedback/Dialog.js.map +1 -0
  74. package/dist/react/core/{Toast.js → feedback/Toast.js} +3 -3
  75. package/dist/react/core/feedback/Toast.js.map +1 -0
  76. package/dist/react/core/index.d.ts +85 -85
  77. package/dist/react/core/{Button.js → inputs/Button.js} +2 -2
  78. package/dist/react/core/inputs/Button.js.map +1 -0
  79. package/dist/react/core/{Checkbox.js → inputs/Checkbox.js} +2 -2
  80. package/dist/react/core/inputs/Checkbox.js.map +1 -0
  81. package/dist/react/core/{Input.d.ts → inputs/Input.d.ts} +1 -1
  82. package/dist/react/core/{Input.js → inputs/Input.js} +3 -3
  83. package/dist/react/core/inputs/Input.js.map +1 -0
  84. package/dist/react/core/{LimitsBar.js → inputs/LimitsBar.js} +1 -1
  85. package/dist/react/core/inputs/LimitsBar.js.map +1 -0
  86. package/dist/react/core/{NumberInput.d.ts → inputs/NumberInput.d.ts} +2 -2
  87. package/dist/react/core/{NumberInput.js → inputs/NumberInput.js} +3 -3
  88. package/dist/react/core/inputs/NumberInput.js.map +1 -0
  89. package/dist/react/core/{PinInput.js → inputs/PinInput.js} +2 -2
  90. package/dist/react/core/inputs/PinInput.js.map +1 -0
  91. package/dist/react/core/{Select.js → inputs/Select.js} +3 -3
  92. package/dist/react/core/inputs/Select.js.map +1 -0
  93. package/dist/react/core/{Toggle.js → inputs/Toggle.js} +2 -2
  94. package/dist/react/core/inputs/Toggle.js.map +1 -0
  95. package/dist/react/core/{AppBar.d.ts → navigation/AppBar.d.ts} +1 -1
  96. package/dist/react/core/{AppBar.js → navigation/AppBar.js} +7 -7
  97. package/dist/react/core/navigation/AppBar.js.map +1 -0
  98. package/dist/react/core/{Pagination.js → navigation/Pagination.js} +2 -2
  99. package/dist/react/core/navigation/Pagination.js.map +1 -0
  100. package/dist/react/core/{SideNav.d.ts → navigation/SideNav.d.ts} +1 -1
  101. package/dist/react/core/{SideNav.js → navigation/SideNav.js} +3 -3
  102. package/dist/react/core/navigation/SideNav.js.map +1 -0
  103. package/dist/react/core/{Tabs.js → navigation/Tabs.js} +2 -2
  104. package/dist/react/core/navigation/Tabs.js.map +1 -0
  105. package/dist/react/core/{Popover.js → overlays/Popover.js} +1 -1
  106. package/dist/react/core/overlays/Popover.js.map +1 -0
  107. package/dist/react/core/{SidePanel.js → overlays/SidePanel.js} +3 -3
  108. package/dist/react/core/overlays/SidePanel.js.map +1 -0
  109. package/dist/react/core/{Tooltip.js → overlays/Tooltip.js} +2 -2
  110. package/dist/react/core/overlays/Tooltip.js.map +1 -0
  111. package/dist/react/core/{ActivityPlanner.js → widgets/ActivityPlanner.js} +1 -1
  112. package/dist/react/core/widgets/ActivityPlanner.js.map +1 -0
  113. package/dist/react/core/{Capture.js → widgets/Capture.js} +3 -3
  114. package/dist/react/core/widgets/Capture.js.map +1 -0
  115. package/dist/react/core/{ChatPanel.d.ts → widgets/ChatPanel.d.ts} +1 -1
  116. package/dist/react/core/{ChatPanel.js → widgets/ChatPanel.js} +2 -2
  117. package/dist/react/core/widgets/ChatPanel.js.map +1 -0
  118. package/dist/react/core/{ColorPickerPanel.d.ts → widgets/ColorPickerPanel.d.ts} +1 -1
  119. package/dist/react/core/{ColorPickerPanel.js → widgets/ColorPickerPanel.js} +3 -3
  120. package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -0
  121. package/dist/react/core/{CommandBuilder.js → widgets/CommandBuilder.js} +1 -1
  122. package/dist/react/core/widgets/CommandBuilder.js.map +1 -0
  123. package/dist/react/core/{ConnectionForm.d.ts → widgets/ConnectionForm.d.ts} +1 -1
  124. package/dist/react/core/{ConnectionForm.js → widgets/ConnectionForm.js} +2 -2
  125. package/dist/react/core/widgets/ConnectionForm.js.map +1 -0
  126. package/dist/react/core/{FileExplorer.js → widgets/FileExplorer.js} +2 -2
  127. package/dist/react/core/widgets/FileExplorer.js.map +1 -0
  128. package/dist/react/core/{HexViewer.js → widgets/HexViewer.js} +1 -1
  129. package/dist/react/core/widgets/HexViewer.js.map +1 -0
  130. package/dist/react/core/{ImageGallery.d.ts → widgets/ImageGallery.d.ts} +1 -1
  131. package/dist/react/core/{ImageGallery.js → widgets/ImageGallery.js} +3 -3
  132. package/dist/react/core/widgets/ImageGallery.js.map +1 -0
  133. package/dist/react/core/{LogViewer.d.ts → widgets/LogViewer.d.ts} +13 -3
  134. package/dist/react/core/{LogViewer.js → widgets/LogViewer.js} +28 -8
  135. package/dist/react/core/widgets/LogViewer.js.map +1 -0
  136. package/dist/react/core/{MessageStream.d.ts → widgets/MessageStream.d.ts} +2 -2
  137. package/dist/react/core/{MessageStream.js → widgets/MessageStream.js} +4 -4
  138. package/dist/react/core/widgets/MessageStream.js.map +1 -0
  139. package/dist/react/core/{MissionCalendar.js → widgets/MissionCalendar.js} +2 -2
  140. package/dist/react/core/widgets/MissionCalendar.js.map +1 -0
  141. package/dist/react/core/{PacketViewer.js → widgets/PacketViewer.js} +1 -1
  142. package/dist/react/core/widgets/PacketViewer.js.map +1 -0
  143. package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -0
  144. package/dist/react/hooks/index.d.ts +9 -11
  145. package/dist/react/hooks/useAccessWindows.d.ts +15 -19
  146. package/dist/react/hooks/useGroundTrackHistory.d.ts +34 -0
  147. package/dist/react/hooks/useSimulationScene.d.ts +141 -0
  148. package/dist/react/hooks/useSimulationScene.js +401 -0
  149. package/dist/react/hooks/useSimulationScene.js.map +1 -0
  150. package/dist/react/hooks/useZendirSession.d.ts +44 -69
  151. package/dist/react/index.d.ts +7 -3
  152. package/dist/react/panels/LayerControlPanel.d.ts +54 -0
  153. package/dist/react/panels/LayerControlPanel.js +184 -0
  154. package/dist/react/panels/LayerControlPanel.js.map +1 -0
  155. package/dist/react/panels/ObjectInventoryPanel.d.ts +57 -0
  156. package/dist/react/panels/ObjectInventoryPanel.js +261 -0
  157. package/dist/react/panels/ObjectInventoryPanel.js.map +1 -0
  158. package/dist/react/panels/index.d.ts +15 -0
  159. package/dist/react/theme/ThemeProvider.d.ts +2 -0
  160. package/dist/react/theme/ThemeProvider.js +50 -72
  161. package/dist/react/theme/ThemeProvider.js.map +1 -1
  162. package/dist/react/types.d.ts +32 -3
  163. package/dist/react/types.js.map +1 -1
  164. package/dist/react.js +51 -42
  165. package/dist/react.js.map +1 -1
  166. package/dist/shaders/atmosphere.frag.js +5 -0
  167. package/dist/shaders/atmosphere.frag.js.map +1 -0
  168. package/dist/shaders/atmosphere.vert.js +5 -0
  169. package/dist/shaders/atmosphere.vert.js.map +1 -0
  170. package/dist/shaders/stars.frag.js +5 -0
  171. package/dist/shaders/stars.frag.js.map +1 -0
  172. package/dist/shaders/stars.vert.js +5 -0
  173. package/dist/shaders/stars.vert.js.map +1 -0
  174. package/dist/style.css +6 -4
  175. package/dist/tokens/css-vars.d.ts +91 -0
  176. package/dist/tokens/css-vars.js +228 -0
  177. package/dist/tokens/css-vars.js.map +1 -0
  178. package/dist/tokens/index.d.ts +71 -18
  179. package/dist/tokens/index.js +206 -97
  180. package/dist/tokens/index.js.map +1 -1
  181. package/dist/tokens/tokens.css +50 -50
  182. package/package.json +26 -22
  183. package/sdk-stub.js +10 -5
  184. package/dist/react/3d/EarthViewer.d.ts +0 -46
  185. package/dist/react/3d/SolarSystemViewer.d.ts +0 -43
  186. package/dist/react/chatgpt/ChatGPTCard.d.ts +0 -6
  187. package/dist/react/core/ActivityPlanner.js.map +0 -1
  188. package/dist/react/core/AppBar.js.map +0 -1
  189. package/dist/react/core/AstroIcon.js.map +0 -1
  190. package/dist/react/core/Badge.js.map +0 -1
  191. package/dist/react/core/Button.js.map +0 -1
  192. package/dist/react/core/Capture.js.map +0 -1
  193. package/dist/react/core/CardHeader.js.map +0 -1
  194. package/dist/react/core/ChatPanel.js.map +0 -1
  195. package/dist/react/core/Checkbox.js.map +0 -1
  196. package/dist/react/core/ColorPickerPanel.js.map +0 -1
  197. package/dist/react/core/CommandBuilder.js.map +0 -1
  198. package/dist/react/core/ConfirmDialog.js.map +0 -1
  199. package/dist/react/core/ConnectionForm.js.map +0 -1
  200. package/dist/react/core/Container.js.map +0 -1
  201. package/dist/react/core/CopyButton.js.map +0 -1
  202. package/dist/react/core/DataTable.js.map +0 -1
  203. package/dist/react/core/DataValue.js.map +0 -1
  204. package/dist/react/core/Dialog.js.map +0 -1
  205. package/dist/react/core/FileExplorer.js.map +0 -1
  206. package/dist/react/core/GlassCard.js.map +0 -1
  207. package/dist/react/core/HeaderIconWithStatus.js.map +0 -1
  208. package/dist/react/core/HexViewer.js.map +0 -1
  209. package/dist/react/core/Icon.js.map +0 -1
  210. package/dist/react/core/ImageGallery.js.map +0 -1
  211. package/dist/react/core/Input.js.map +0 -1
  212. package/dist/react/core/LimitsBar.js.map +0 -1
  213. package/dist/react/core/LogViewer.js.map +0 -1
  214. package/dist/react/core/MessageStream.js.map +0 -1
  215. package/dist/react/core/MissionCalendar.js.map +0 -1
  216. package/dist/react/core/NumberInput.js.map +0 -1
  217. package/dist/react/core/PacketViewer.js.map +0 -1
  218. package/dist/react/core/Pagination.js.map +0 -1
  219. package/dist/react/core/PinInput.js.map +0 -1
  220. package/dist/react/core/Popover.js.map +0 -1
  221. package/dist/react/core/Select.js.map +0 -1
  222. package/dist/react/core/SideNav.js.map +0 -1
  223. package/dist/react/core/SidePanel.js.map +0 -1
  224. package/dist/react/core/Tabs.js.map +0 -1
  225. package/dist/react/core/Toast.js.map +0 -1
  226. package/dist/react/core/Toggle.js.map +0 -1
  227. package/dist/react/core/Tooltip.js.map +0 -1
  228. package/dist/react/core/Typography.js.map +0 -1
  229. package/dist/react/core/capture-placeholder.png.js.map +0 -1
  230. package/dist/react/core/propertyConfig.js.map +0 -1
  231. package/dist/react/hooks/useSimulationTime.d.ts +0 -61
  232. package/dist/react/hooks/useSpacecraftPosition.d.ts +0 -50
  233. package/dist/react/hooks/useTelemetry.d.ts +0 -55
  234. package/dist/types.d.ts +0 -1
  235. package/dist/types.js +0 -2
  236. package/dist/types.js.map +0 -1
  237. /package/dist/react/core/{propertyConfig.js → data/propertyConfig.js} +0 -0
  238. /package/dist/react/core/{AstroIcon.d.ts → display/AstroIcon.d.ts} +0 -0
  239. /package/dist/react/core/{CopyButton.d.ts → display/CopyButton.d.ts} +0 -0
  240. /package/dist/react/core/{ConfirmDialog.d.ts → feedback/ConfirmDialog.d.ts} +0 -0
  241. /package/dist/react/core/{Dialog.d.ts → feedback/Dialog.d.ts} +0 -0
  242. /package/dist/react/core/{Toast.d.ts → feedback/Toast.d.ts} +0 -0
  243. /package/dist/react/core/{Button.d.ts → inputs/Button.d.ts} +0 -0
  244. /package/dist/react/core/{Checkbox.d.ts → inputs/Checkbox.d.ts} +0 -0
  245. /package/dist/react/core/{LimitsBar.d.ts → inputs/LimitsBar.d.ts} +0 -0
  246. /package/dist/react/core/{PinInput.d.ts → inputs/PinInput.d.ts} +0 -0
  247. /package/dist/react/core/{Select.d.ts → inputs/Select.d.ts} +0 -0
  248. /package/dist/react/core/{Toggle.d.ts → inputs/Toggle.d.ts} +0 -0
  249. /package/dist/react/core/{Pagination.d.ts → navigation/Pagination.d.ts} +0 -0
  250. /package/dist/react/core/{Tabs.d.ts → navigation/Tabs.d.ts} +0 -0
  251. /package/dist/react/core/{Popover.d.ts → overlays/Popover.d.ts} +0 -0
  252. /package/dist/react/core/{SidePanel.d.ts → overlays/SidePanel.d.ts} +0 -0
  253. /package/dist/react/core/{Tooltip.d.ts → overlays/Tooltip.d.ts} +0 -0
  254. /package/dist/react/core/{ActivityPlanner.d.ts → widgets/ActivityPlanner.d.ts} +0 -0
  255. /package/dist/react/core/{Capture.d.ts → widgets/Capture.d.ts} +0 -0
  256. /package/dist/react/core/{CommandBuilder.d.ts → widgets/CommandBuilder.d.ts} +0 -0
  257. /package/dist/react/core/{FileExplorer.d.ts → widgets/FileExplorer.d.ts} +0 -0
  258. /package/dist/react/core/{HexViewer.d.ts → widgets/HexViewer.d.ts} +0 -0
  259. /package/dist/react/core/{MissionCalendar.d.ts → widgets/MissionCalendar.d.ts} +0 -0
  260. /package/dist/react/core/{PacketViewer.d.ts → widgets/PacketViewer.d.ts} +0 -0
  261. /package/dist/react/core/{capture-placeholder.png.js → widgets/capture-placeholder.png.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Typography.js","sources":["../../../../src/react/core/display/Typography.tsx"],"sourcesContent":["/**\n * @zendir/ui - Typography Component\n * \n * AstroUXDS-compliant typography component providing consistent text styling\n * across the design system. All sizing uses rem units per Astro specifications.\n * \n * Typography Scale (Astro UX Design System):\n * - Display: Large hero text (display1, display2)\n * - Heading: Section headers (h1-h6)\n * - Body: Content text (body1, body2, body3)\n * - Control: UI element labels\n * - Mono: Tabular/code data\n * \n * @see https://www.astrouxds.com/foundations/typography/\n */\n\nimport React from 'react';\nimport { useTheme } from '../../theme/ThemeProvider';\n\n// ============================================================================\n// Typography Variants (AstroUXDS Compliant)\n// ============================================================================\n\n/**\n * Typography variant following Astro UX Design System\n * Maps directly to official Astro typography tokens\n */\nexport type TypographyVariant =\n // Display - Large hero text\n | 'display1'\n | 'display2'\n // Headings\n | 'h1'\n | 'h1Bold'\n | 'h2'\n | 'h3'\n | 'h4'\n | 'h5'\n | 'h6'\n // Body text\n | 'body1'\n | 'body1Bold'\n | 'body2'\n | 'body2Bold'\n | 'body3'\n | 'body3Bold'\n // Control (UI labels)\n | 'control1'\n | 'control1Bold'\n // Compact variants for dense UIs (cards, badges)\n | 'compact' // 10px - for tight spaces\n | 'compactBold'\n | 'micro' // 9px - for very tight spaces\n | 'microBold'\n // Monospace for data/code\n | 'mono'\n | 'monoSmall'\n | 'monoCompact';\n\n/**\n * Semantic element to render\n */\nexport type TypographyElement =\n | 'h1'\n | 'h2'\n | 'h3'\n | 'h4'\n | 'h5'\n | 'h6'\n | 'p'\n | 'span'\n | 'div'\n | 'label'\n | 'code'\n | 'pre';\n\n/**\n * Text color variants\n */\nexport type TypographyColor =\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'muted'\n | 'inverse'\n | 'inherit'\n // Status colors\n | 'normal'\n | 'standby'\n | 'caution'\n | 'serious'\n | 'critical'\n | 'off';\n\nexport interface TypographyProps {\n /** Typography variant (required) */\n variant: TypographyVariant;\n /** HTML element to render */\n as?: TypographyElement;\n /** Text color */\n color?: TypographyColor;\n /** Enable tabular figures for numeric alignment */\n tabular?: boolean;\n /** Truncate with ellipsis */\n truncate?: boolean;\n /** Text alignment */\n align?: 'left' | 'center' | 'right';\n /** Disable text wrapping */\n noWrap?: boolean;\n /** Transform text case */\n transform?: 'none' | 'uppercase' | 'lowercase' | 'capitalize';\n /** Additional CSS styles */\n style?: React.CSSProperties;\n /** Additional CSS class */\n className?: string;\n /** Children */\n children?: React.ReactNode;\n /** Test ID */\n 'data-testid'?: string;\n}\n\n// ============================================================================\n// Font stacks\n// ============================================================================\n\n/**\n * Primary body font stack used by all components.\n *\n * Public Sans is the lead face for body text; Roboto is the fallback that\n * activates when web fonts fail to load (Public Sans is not installed\n * locally on most machines, but Roboto is on Android by default — and\n * AstroUXDS specifies Roboto as the canonical engineering-grade fallback).\n * Below that, the OS-native system fonts complete the chain so the UI\n * never falls through to Times.\n *\n * Read by `var(--font-family-primary)` so consumers can override at the\n * `:root` level (set by `<ThemeProvider>` from `tokens.typography.fontFamily.primary`).\n */\nexport const FONT_FAMILY_PRIMARY = 'var(--font-family-primary, \"Public Sans\", \"Roboto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif)';\n\n/**\n * Monospace stack for tabular data, code, and numeric readouts.\n * Roboto Mono leads (AstroUXDS canonical), then OS-native mono fonts.\n */\nexport const FONT_FAMILY_MONO = '\"Roboto Mono\", \"SF Mono\", \"Consolas\", \"Liberation Mono\", monospace';\n\n// ============================================================================\n// AstroUXDS Font Weights\n// Official weights: 300 (Light), 400 (Regular), 500 (Medium), 700 (Bold)\n// Note: Astro does NOT use 600 (semibold) - use 500 or 700 instead\n// ============================================================================\n\nexport const FONT_WEIGHTS = {\n light: 300,\n regular: 400,\n medium: 500,\n bold: 700,\n} as const;\n\n// ============================================================================\n// Typography Style Definitions\n// ============================================================================\n\ninterface TypographyStyleDef {\n fontSize: string;\n fontWeight: number;\n lineHeight: string;\n letterSpacing: string;\n fontFamily?: string;\n}\n\n/**\n * Get typography styles for a variant\n * All sizes in rem for Astro compliance\n */\nfunction getTypographyStyles(variant: TypographyVariant): TypographyStyleDef {\n const styles: Record<TypographyVariant, TypographyStyleDef> = {\n // Display variants\n display1: { fontSize: '3.75rem', fontWeight: 300, lineHeight: '4.375rem', letterSpacing: '-0.5px', fontFamily: 'var(--font-family-heading, \"Sora\", \"Roboto\", sans-serif)' },\n display2: { fontSize: '3rem', fontWeight: 400, lineHeight: '3.5rem', letterSpacing: '0', fontFamily: 'var(--font-family-heading, \"Sora\", \"Roboto\", sans-serif)' },\n \n // Heading variants\n h1: { fontSize: '2.125rem', fontWeight: 400, lineHeight: '2.5rem', letterSpacing: '0.25px', fontFamily: 'var(--font-family-heading, \"Sora\", \"Roboto\", sans-serif)' },\n h1Bold: { fontSize: '2.125rem', fontWeight: 700, lineHeight: '2.5rem', letterSpacing: '0.25px', fontFamily: 'var(--font-family-heading, \"Sora\", \"Roboto\", sans-serif)' },\n h2: { fontSize: '1.5rem', fontWeight: 400, lineHeight: '1.75rem', letterSpacing: '0', fontFamily: 'var(--font-family-heading, \"Sora\", \"Roboto\", sans-serif)' },\n h3: { fontSize: '1.25rem', fontWeight: 500, lineHeight: '1.5rem', letterSpacing: '0.15px', fontFamily: 'var(--font-family-heading, \"Sora\", \"Roboto\", sans-serif)' },\n h4: { fontSize: '1.25rem', fontWeight: 300, lineHeight: '1.5rem', letterSpacing: '0.15px', fontFamily: 'var(--font-family-heading, \"Sora\", \"Roboto\", sans-serif)' },\n h5: { fontSize: '1.125rem', fontWeight: 400, lineHeight: '1.5rem', letterSpacing: '0', fontFamily: 'var(--font-family-heading, \"Sora\", \"Roboto\", sans-serif)' },\n h6: { fontSize: '1.125rem', fontWeight: 300, lineHeight: '1.5rem', letterSpacing: '0', fontFamily: 'var(--font-family-heading, \"Sora\", \"Roboto\", sans-serif)' },\n \n // Body variants\n body1: { fontSize: '1rem', fontWeight: 400, lineHeight: '1.5rem', letterSpacing: '0.5px' },\n body1Bold: { fontSize: '1rem', fontWeight: 700, lineHeight: '1.5rem', letterSpacing: '0.5px' },\n body2: { fontSize: '0.875rem', fontWeight: 400, lineHeight: '1.25rem', letterSpacing: '0.5px' },\n body2Bold: { fontSize: '0.875rem', fontWeight: 700, lineHeight: '1.25rem', letterSpacing: '0.5px' },\n body3: { fontSize: '0.75rem', fontWeight: 400, lineHeight: '1rem', letterSpacing: '0' },\n body3Bold: { fontSize: '0.75rem', fontWeight: 700, lineHeight: '1rem', letterSpacing: '0' },\n \n // Control variants (UI labels)\n control1: { fontSize: '1rem', fontWeight: 400, lineHeight: '1.25rem', letterSpacing: '0.5px' },\n control1Bold: { fontSize: '1rem', fontWeight: 700, lineHeight: '1.25rem', letterSpacing: '0.5px' },\n \n // Compact variants for dense UIs (cards, badges, data labels)\n compact: { fontSize: '0.625rem', fontWeight: 400, lineHeight: '0.875rem', letterSpacing: '0' }, // 10px\n compactBold: { fontSize: '0.625rem', fontWeight: 500, lineHeight: '0.875rem', letterSpacing: '0' },\n micro: { fontSize: '0.5625rem', fontWeight: 400, lineHeight: '0.75rem', letterSpacing: '0' }, // 9px\n microBold: { fontSize: '0.5625rem', fontWeight: 500, lineHeight: '0.75rem', letterSpacing: '0' },\n \n // Monospace variants for data/code\n mono: { fontSize: '0.875rem', fontWeight: 400, lineHeight: '1.25rem', letterSpacing: '0', fontFamily: FONT_FAMILY_MONO },\n monoSmall: { fontSize: '0.75rem', fontWeight: 400, lineHeight: '1rem', letterSpacing: '0', fontFamily: FONT_FAMILY_MONO },\n monoCompact: { fontSize: '0.625rem', fontWeight: 400, lineHeight: '0.875rem', letterSpacing: '0', fontFamily: FONT_FAMILY_MONO },\n };\n \n return styles[variant];\n}\n\n/**\n * Get default HTML element for variant\n */\nfunction getDefaultElement(variant: TypographyVariant): TypographyElement {\n if (variant.startsWith('display')) return 'h1';\n if (variant.startsWith('h1')) return 'h1';\n if (variant.startsWith('h2')) return 'h2';\n if (variant.startsWith('h3')) return 'h3';\n if (variant.startsWith('h4')) return 'h4';\n if (variant.startsWith('h5')) return 'h5';\n if (variant.startsWith('h6')) return 'h6';\n if (variant.startsWith('mono')) return 'code';\n if (variant.startsWith('control')) return 'label';\n return 'span';\n}\n\n// ============================================================================\n// Typography Component\n// ============================================================================\n\n/**\n * Typography component providing AstroUXDS-compliant text styling.\n * \n * @example\n * ```tsx\n * // Heading\n * <Typography variant=\"h3\">Section Title</Typography>\n * \n * // Body text\n * <Typography variant=\"body1\" color=\"secondary\">Description text</Typography>\n * \n * // Monospace data with tabular figures\n * <Typography variant=\"mono\" tabular>123.456</Typography>\n * \n * // Compact label for cards\n * <Typography variant=\"compact\" color=\"tertiary\">LABEL</Typography>\n * ```\n */\nexport const Typography: React.FC<TypographyProps> = ({\n variant,\n as,\n color = 'primary',\n tabular = false,\n truncate = false,\n align,\n noWrap = false,\n transform,\n style,\n className,\n children,\n 'data-testid': testId,\n}) => {\n const { tokens } = useTheme();\n \n const typographyStyles = getTypographyStyles(variant);\n const Element = as || getDefaultElement(variant);\n \n // Resolve color\n const getColor = (): string | undefined => {\n if (color === 'inherit') return 'inherit';\n if (color === 'primary') return tokens.colors.text.primary;\n if (color === 'secondary') return tokens.colors.text.secondary;\n if (color === 'tertiary') return tokens.colors.text.tertiary;\n if (color === 'muted') return tokens.colors.text.muted || tokens.colors.text.tertiary;\n if (color === 'inverse') return tokens.colors.text.inverse;\n // Status colors\n if (color === 'normal') return tokens.colors.status.normal;\n if (color === 'standby') return tokens.colors.status.standby;\n if (color === 'caution') return tokens.colors.status.caution;\n if (color === 'serious') return tokens.colors.status.serious;\n if (color === 'critical') return tokens.colors.status.critical;\n if (color === 'off') return tokens.colors.status.off;\n return undefined;\n };\n \n const combinedStyle: React.CSSProperties = {\n fontFamily: typographyStyles.fontFamily || FONT_FAMILY_PRIMARY,\n fontSize: typographyStyles.fontSize,\n fontWeight: typographyStyles.fontWeight,\n lineHeight: typographyStyles.lineHeight,\n letterSpacing: typographyStyles.letterSpacing,\n color: getColor(),\n margin: 0,\n padding: 0,\n // Tabular figures for numeric alignment\n ...(tabular && {\n fontVariantNumeric: 'tabular-nums',\n fontFeatureSettings: '\"tnum\"',\n }),\n // Truncation\n ...(truncate && {\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }),\n // No wrap\n ...(noWrap && !truncate && {\n whiteSpace: 'nowrap',\n }),\n // Text alignment\n ...(align && { textAlign: align }),\n // Text transform\n ...(transform && { textTransform: transform }),\n // Custom styles (can override defaults)\n ...style,\n };\n \n return (\n <Element\n className={className}\n style={combinedStyle}\n data-testid={testId}\n >\n {children}\n </Element>\n );\n};\n\n// ============================================================================\n// Convenience Components\n// ============================================================================\n\n/** Display 1 - Largest display text */\nexport const Display1: React.FC<Omit<TypographyProps, 'variant'>> = (props) => (\n <Typography variant=\"display1\" {...props} />\n);\n\n/** Display 2 - Large display text */\nexport const Display2: React.FC<Omit<TypographyProps, 'variant'>> = (props) => (\n <Typography variant=\"display2\" {...props} />\n);\n\n/** Heading 1 */\nexport const H1: React.FC<Omit<TypographyProps, 'variant'> & { bold?: boolean }> = ({ bold, ...props }) => (\n <Typography variant={bold ? 'h1Bold' : 'h1'} {...props} />\n);\n\n/** Heading 2 */\nexport const H2: React.FC<Omit<TypographyProps, 'variant'>> = (props) => (\n <Typography variant=\"h2\" {...props} />\n);\n\n/** Heading 3 */\nexport const H3: React.FC<Omit<TypographyProps, 'variant'>> = (props) => (\n <Typography variant=\"h3\" {...props} />\n);\n\n/** Heading 4 */\nexport const H4: React.FC<Omit<TypographyProps, 'variant'>> = (props) => (\n <Typography variant=\"h4\" {...props} />\n);\n\n/** Heading 5 */\nexport const H5: React.FC<Omit<TypographyProps, 'variant'>> = (props) => (\n <Typography variant=\"h5\" {...props} />\n);\n\n/** Heading 6 */\nexport const H6: React.FC<Omit<TypographyProps, 'variant'>> = (props) => (\n <Typography variant=\"h6\" {...props} />\n);\n\n/** Body text level 1 (16px) */\nexport const Body1: React.FC<Omit<TypographyProps, 'variant'> & { bold?: boolean }> = ({ bold, ...props }) => (\n <Typography variant={bold ? 'body1Bold' : 'body1'} {...props} />\n);\n\n/** Body text level 2 (14px) */\nexport const Body2: React.FC<Omit<TypographyProps, 'variant'> & { bold?: boolean }> = ({ bold, ...props }) => (\n <Typography variant={bold ? 'body2Bold' : 'body2'} {...props} />\n);\n\n/** Body text level 3 (12px) */\nexport const Body3: React.FC<Omit<TypographyProps, 'variant'> & { bold?: boolean }> = ({ bold, ...props }) => (\n <Typography variant={bold ? 'body3Bold' : 'body3'} {...props} />\n);\n\n/** Compact text for dense UIs (10px) */\nexport const Compact: React.FC<Omit<TypographyProps, 'variant'> & { bold?: boolean }> = ({ bold, ...props }) => (\n <Typography variant={bold ? 'compactBold' : 'compact'} {...props} />\n);\n\n/** Micro text for very tight spaces (9px) */\nexport const Micro: React.FC<Omit<TypographyProps, 'variant'> & { bold?: boolean }> = ({ bold, ...props }) => (\n <Typography variant={bold ? 'microBold' : 'micro'} {...props} />\n);\n\n/** Monospace text for data/code */\nexport const Mono: React.FC<Omit<TypographyProps, 'variant'> & { size?: 'normal' | 'small' | 'compact' }> = ({ \n size = 'normal', \n tabular = true, // Default to tabular for mono\n ...props \n}) => {\n const variant = size === 'compact' ? 'monoCompact' : size === 'small' ? 'monoSmall' : 'mono';\n return <Typography variant={variant} tabular={tabular} {...props} />;\n};\n\n/** Data value text - monospace with tabular figures (for numeric displays) */\nexport const DataText: React.FC<Omit<TypographyProps, 'variant' | 'tabular'> & { \n size?: 'large' | 'normal' | 'small' | 'compact';\n}> = ({ size = 'normal', ...props }) => {\n const variantMap: Record<string, TypographyVariant> = {\n large: 'mono',\n normal: 'mono',\n small: 'monoSmall',\n compact: 'monoCompact',\n };\n return <Typography variant={variantMap[size]} tabular {...props} />;\n};\n\n/** Label text for form controls and card headers */\nexport const Label: React.FC<Omit<TypographyProps, 'variant'> & { bold?: boolean }> = ({ bold, ...props }) => (\n <Typography variant={bold ? 'control1Bold' : 'control1'} as=\"label\" {...props} />\n);\n\nexport default Typography;\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import { memo, useRef, useId, useEffect, useState, useCallback, useContext, createContext } from "react";
3
3
  import { createPortal } from "react-dom";
4
- import { useTheme } from "../theme/ThemeProvider.js";
4
+ import { useTheme } from "../../theme/ThemeProvider.js";
5
5
  const ConfirmDialog = memo(function ConfirmDialog2({
6
6
  open,
7
7
  onClose,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmDialog.js","sources":["../../../../src/react/core/feedback/ConfirmDialog.tsx"],"sourcesContent":["/**\n * @zendir/ui - Confirmation Dialog\n * \n * Convenience wrapper over Dialog for confirm/cancel actions.\n * Provides both a component API and a `useConfirm()` hook for imperative usage.\n * \n * Astro UX Compliance:\n * - Status-based alert colors\n * - Focus trap, escape to close\n * - Primary button on right (Astro convention)\n * \n * @example\n * ```tsx\n * // Hook API (imperative)\n * const confirm = useConfirm();\n * const ok = await confirm({\n * title: 'Reset Component',\n * message: 'This will reboot the spacecraft and suspend commands for 120 seconds.',\n * status: 'caution',\n * confirmLabel: 'Reset',\n * destructive: true,\n * });\n * if (ok) doReset();\n * \n * // Component API (declarative)\n * <ConfirmDialog\n * open={isOpen}\n * onClose={() => setOpen(false)}\n * onConfirm={handleReset}\n * title=\"Delete All Data?\"\n * message=\"This cannot be undone.\"\n * status=\"critical\"\n * destructive\n * />\n * ```\n */\n\nimport React, { memo, useState, useCallback, useRef, useEffect, useId, createContext, useContext } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useTheme } from '../../theme';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type ConfirmStatus = 'normal' | 'caution' | 'serious' | 'critical';\n\nexport interface ConfirmOptions {\n /** Dialog title */\n title: string;\n /** Description text (string or React node) */\n message?: React.ReactNode;\n /** Status level (determines icon/border color) */\n status?: ConfirmStatus;\n /** Confirm button label (default: \"Confirm\") */\n confirmLabel?: string;\n /** Cancel button label (default: \"Cancel\") */\n cancelLabel?: string;\n /** Destructive action styling (red confirm button) */\n destructive?: boolean;\n}\n\nexport interface ConfirmDialogProps extends ConfirmOptions {\n /** Open state */\n open: boolean;\n /** Close handler */\n onClose: () => void;\n /** Confirm handler */\n onConfirm: () => void;\n}\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const ConfirmDialog = memo(function ConfirmDialog({\n open,\n onClose,\n onConfirm,\n title,\n message,\n status,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n destructive = false,\n}: ConfirmDialogProps): React.ReactElement | null {\n const { tokens, theme } = useTheme();\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const dialogRef = useRef<HTMLDivElement>(null);\n const confirmRef = useRef<HTMLButtonElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n const titleId = useId();\n const messageId = useId();\n const CONFIRM_DIALOG_Z_INDEX = 2147483200;\n\n useEffect(() => {\n if (!open) return;\n\n previousActiveElement.current = document.activeElement as HTMLElement;\n document.body.style.overflow = 'hidden';\n\n const handleKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') {\n e.preventDefault();\n onClose();\n return;\n }\n\n if (e.key !== 'Tab') return;\n const root = dialogRef.current;\n if (!root) return;\n\n const focusableElements = root.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const focusable = Array.from(focusableElements).filter((el) => !el.hasAttribute('disabled'));\n if (focusable.length === 0) return;\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement as HTMLElement | null;\n\n if (e.shiftKey && active === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n const focusTimer = window.setTimeout(() => {\n confirmRef.current?.focus();\n }, 0);\n\n return () => {\n window.clearTimeout(focusTimer);\n document.removeEventListener('keydown', handleKeyDown);\n document.body.style.overflow = '';\n previousActiveElement.current?.focus();\n };\n }, [open, onClose]);\n\n if (!open) return null;\n if (typeof document === 'undefined') return null;\n \n const statusColors: Record<string, string> = {\n normal: tokens.colors.status.normal,\n caution: tokens.colors.status.caution,\n serious: tokens.colors.status.serious,\n critical: tokens.colors.status.critical,\n };\n \n const accentColor = status ? statusColors[status] : tokens.colors.accent.primary;\n const confirmBg = destructive ? tokens.colors.status.critical : tokens.colors.accent.primary;\n \n // Status icon shapes (Astro UX dual-coded)\n const statusIcon = status && (() => {\n const s = 32;\n const innerIcon = (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke={accentColor} strokeWidth=\"2.5\" strokeLinecap=\"round\">\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n const baseStyle: React.CSSProperties = {\n width: s,\n height: s,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n };\n switch (status) {\n case 'critical':\n // Triangle (using clip-path)\n return (\n <div style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n clipPath: 'polygon(50% 0%, 0% 100%, 100% 100%)',\n paddingTop: 8,\n }}>\n {innerIcon}\n </div>\n );\n case 'serious':\n // Diamond (rotated square)\n return (\n <div style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n transform: 'rotate(45deg)',\n }}>\n <div style={{ transform: 'rotate(-45deg)' }}>{innerIcon}</div>\n </div>\n );\n case 'caution':\n // Square (rounded)\n return (\n <div style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n borderRadius: '4px',\n }}>\n {innerIcon}\n </div>\n );\n default:\n // Circle (normal, standby, off)\n return (\n <div style={{\n ...baseStyle,\n backgroundColor: `${accentColor}20`,\n border: `2px solid ${accentColor}`,\n borderRadius: '50%',\n }}>\n {innerIcon}\n </div>\n );\n }\n })();\n \n return createPortal((\n <>\n {/* Backdrop */}\n <div\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: CONFIRM_DIALOG_Z_INDEX,\n backgroundColor: isTransparentTheme ? `${tokens.colors.background.base}80` : `${tokens.colors.background.base}B3`,\n backdropFilter: 'blur(6px)',\n WebkitBackdropFilter: 'blur(6px)',\n animation: `zendir-confirm-backdrop 200ms ${tokens.animation.easing.default}`,\n }}\n onClick={onClose}\n />\n \n {/* Dialog */}\n <div\n ref={dialogRef}\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={message ? messageId : undefined}\n onClick={(e) => e.stopPropagation()}\n style={{\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: CONFIRM_DIALOG_Z_INDEX + 1,\n width: '100%',\n maxWidth: 'min(440px, calc(100vw - 32px))',\n backgroundColor: isTransparentTheme\n ? 'rgba(15, 12, 30, 0.9)'\n : tokens.colors.background.surface,\n border: `1px solid ${tokens.colors.border.default}`,\n borderRadius: tokens.borderRadius.lg,\n boxShadow: tokens.shadows.xl,\n fontFamily: tokens.typography.fontFamily.primary,\n animation: `zendir-confirm-enter 250ms ${tokens.animation.easing.default}`,\n overflow: 'hidden',\n ...(isTransparentTheme ? {\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n } : {}),\n }}\n >\n {/* Status accent bar */}\n {status && (\n <div style={{\n height: 3,\n backgroundColor: accentColor,\n width: '100%',\n }} />\n )}\n \n {/* Content */}\n <div style={{ padding: `${tokens.spacing.lg} ${tokens.spacing.lg} ${tokens.spacing.md}` }}>\n <div style={{ display: 'flex', gap: tokens.spacing.md, alignItems: 'flex-start' }}>\n {statusIcon}\n <div style={{ flex: 1 }}>\n <div\n id={titleId}\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.semibold,\n color: tokens.colors.text.primary,\n lineHeight: tokens.typography.lineHeight.tight,\n }}\n >\n {title}\n </div>\n {message && (\n <div\n id={messageId}\n style={{\n fontSize: tokens.typography.fontSize.sm,\n color: tokens.colors.text.secondary,\n marginTop: tokens.spacing.sm,\n lineHeight: tokens.typography.lineHeight.normal,\n }}\n >\n {message}\n </div>\n )}\n </div>\n </div>\n </div>\n \n {/* Actions — Astro UX: primary on right */}\n <div style={{\n display: 'flex',\n justifyContent: 'flex-end',\n gap: tokens.spacing.sm,\n padding: `${tokens.spacing.md} ${tokens.spacing.lg} ${tokens.spacing.lg}`,\n borderTop: tokens.borders.divider,\n }}>\n <button\n onClick={onClose}\n style={{\n padding: `0 ${tokens.spacing.md}`,\n minHeight: tokens.elementSize.lg,\n fontSize: tokens.typography.fontSize.sm,\n fontWeight: tokens.typography.fontWeight.medium,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.primary,\n backgroundColor: tokens.colors.background.base,\n border: `1px solid ${tokens.colors.border.muted}`,\n borderRadius: tokens.borderRadius.md,\n cursor: 'pointer',\n transition: tokens.animation.fast,\n }}\n >\n {cancelLabel}\n </button>\n <button\n ref={confirmRef}\n onClick={() => { onConfirm(); onClose(); }}\n style={{\n padding: `0 ${tokens.spacing.md}`,\n minHeight: tokens.elementSize.lg,\n fontSize: tokens.typography.fontSize.sm,\n fontWeight: tokens.typography.fontWeight.semibold,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.inverse || '#fff',\n backgroundColor: confirmBg,\n border: 'none',\n borderRadius: tokens.borderRadius.md,\n cursor: 'pointer',\n transition: tokens.animation.fast,\n boxShadow: `0 2px 8px ${confirmBg}40`,\n }}\n >\n {confirmLabel}\n </button>\n </div>\n </div>\n \n <style>{`\n @keyframes zendir-confirm-backdrop { from { opacity: 0; } to { opacity: 1; } }\n @keyframes zendir-confirm-enter {\n from { opacity: 0; transform: translate(-50%, -50%) scale(0.95); }\n to { opacity: 1; transform: translate(-50%, -50%) scale(1); }\n }\n `}</style>\n </>\n ), document.body);\n});\n\n// ─── useConfirm Hook ─────────────────────────────────────────────────────────\n\ninterface ConfirmState extends ConfirmOptions {\n resolve: (value: boolean) => void;\n}\n\nconst ConfirmContext = createContext<{\n requestConfirm: (options: ConfirmOptions) => Promise<boolean>;\n} | null>(null);\n\n/**\n * Imperative confirmation hook.\n * Must be used within `<ConfirmProvider>`.\n * \n * @example\n * ```tsx\n * const confirm = useConfirm();\n * const ok = await confirm({ title: 'Delete?', status: 'critical', destructive: true });\n * ```\n */\nexport function useConfirm(): (options: ConfirmOptions) => Promise<boolean> {\n const ctx = useContext(ConfirmContext);\n if (!ctx) throw new Error('useConfirm must be used within <ConfirmProvider>');\n return ctx.requestConfirm;\n}\n\n/**\n * Provider for the useConfirm() hook.\n * Renders the confirmation dialog as needed.\n */\nexport const ConfirmProvider = memo(function ConfirmProvider({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactElement {\n const [state, setState] = useState<ConfirmState | null>(null);\n \n const requestConfirm = useCallback((options: ConfirmOptions): Promise<boolean> => {\n return new Promise<boolean>((resolve) => {\n setState({ ...options, resolve });\n });\n }, []);\n \n const handleClose = useCallback(() => {\n state?.resolve(false);\n setState(null);\n }, [state]);\n \n const handleConfirm = useCallback(() => {\n state?.resolve(true);\n setState(null);\n }, [state]);\n \n return (\n <ConfirmContext.Provider value={{ requestConfirm }}>\n {children}\n {state && (\n <ConfirmDialog\n open={true}\n onClose={handleClose}\n onConfirm={handleConfirm}\n title={state.title}\n message={state.message}\n status={state.status}\n confirmLabel={state.confirmLabel}\n cancelLabel={state.cancelLabel}\n destructive={state.destructive}\n />\n )}\n </ConfirmContext.Provider>\n );\n});\n\nexport default ConfirmDialog;\n"],"names":["ConfirmDialog","ConfirmProvider"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { memo, useRef, useId, useCallback, useEffect } from "react";
3
3
  import { createPortal } from "react-dom";
4
- import { classNames } from "../utils/index.js";
5
- import { useTheme } from "../theme/ThemeProvider.js";
4
+ import { classNames } from "../../utils/index.js";
5
+ import { useTheme } from "../../theme/ThemeProvider.js";
6
6
  const DialogActions = memo(function DialogActions2({
7
7
  children,
8
8
  align = "right"
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dialog.js","sources":["../../../../src/react/core/feedback/Dialog.tsx"],"sourcesContent":["/**\n * @zendir/ui - Dialog/Modal Component\n * \n * Modal dialog following Astro UX Design System.\n * \n * @example\n * ```tsx\n * <Dialog\n * open={isOpen}\n * onClose={() => setIsOpen(false)}\n * title=\"Confirm Action\"\n * >\n * <p>Are you sure you want to proceed?</p>\n * <Dialog.Actions>\n * <Button variant=\"secondary\" onClick={() => setIsOpen(false)}>Cancel</Button>\n * <Button onClick={handleConfirm}>Confirm</Button>\n * </Dialog.Actions>\n * </Dialog>\n * ```\n */\n\nimport React, { memo, useEffect, useRef, useCallback, useId } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useTheme } from '../../theme';\nimport { classNames } from '../../utils';\n\nexport type DialogSize = 'small' | 'medium' | 'large' | 'fullscreen';\n\nexport interface DialogProps {\n /** Open state */\n open: boolean;\n /** Close handler */\n onClose: () => void;\n /** Dialog title */\n title?: string;\n /** Size variant */\n size?: DialogSize;\n /** Show close button */\n showCloseButton?: boolean;\n /** Close on backdrop click */\n closeOnBackdropClick?: boolean;\n /** Close on escape key */\n closeOnEscape?: boolean;\n /** Children */\n children: React.ReactNode;\n /** Custom className */\n className?: string;\n}\n\nexport interface DialogActionsProps {\n children: React.ReactNode;\n align?: 'left' | 'center' | 'right';\n}\n\nconst DialogActions = memo(function DialogActions({\n children,\n align = 'right',\n}: DialogActionsProps): React.ReactElement {\n const { tokens } = useTheme();\n \n return (\n <div\n style={{\n display: 'flex',\n justifyContent: align === 'left' ? 'flex-start' : align === 'right' ? 'flex-end' : 'center',\n gap: tokens.spacing.sm,\n marginTop: tokens.spacing.lg,\n paddingTop: tokens.spacing.md,\n borderTop: tokens.borders.divider,\n }}\n >\n {children}\n </div>\n );\n});\n\nexport const Dialog = memo(function Dialog({\n open,\n onClose,\n title,\n size = 'medium',\n showCloseButton = true,\n closeOnBackdropClick = true,\n closeOnEscape = true,\n children,\n className = '',\n}: DialogProps): React.ReactElement | null {\n const { tokens, theme } = useTheme();\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const dialogRef = useRef<HTMLDivElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n const titleId = useId();\n const DIALOG_Z_INDEX = 2147483000;\n \n const sizeConfig = {\n small: { width: 'min(360px, calc(100vw - 32px))', maxHeight: '80vh' },\n medium: { width: 'min(540px, calc(100vw - 32px))', maxHeight: '80vh' },\n large: { width: 'min(800px, calc(100vw - 32px))', maxHeight: '90vh' },\n fullscreen: { width: '100vw', maxHeight: '100vh' },\n };\n const config = sizeConfig[size];\n \n // Handle escape key\n const handleKeyDown = useCallback((e: KeyboardEvent) => {\n if (closeOnEscape && e.key === 'Escape') {\n onClose();\n }\n }, [closeOnEscape, onClose]);\n \n // Focus trap and escape key\n useEffect(() => {\n if (open) {\n previousActiveElement.current = document.activeElement as HTMLElement;\n document.body.style.overflow = 'hidden';\n document.addEventListener('keydown', handleKeyDown);\n \n // Focus first focusable element\n const focusTimer = setTimeout(() => {\n const focusable = dialogRef.current?.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n focusable?.focus();\n }, 0);\n \n return () => {\n clearTimeout(focusTimer);\n document.body.style.overflow = '';\n document.removeEventListener('keydown', handleKeyDown);\n previousActiveElement.current?.focus();\n };\n }\n }, [open, handleKeyDown]);\n \n if (!open) return null;\n if (typeof document === 'undefined') return null;\n\n return createPortal((\n <div\n className={classNames('zendir-dialog-backdrop', className)}\n onClick={closeOnBackdropClick ? onClose : undefined}\n style={{\n position: 'fixed',\n inset: 0,\n backgroundColor: isTransparentTheme ? `${tokens.colors.background.base}66` : `${tokens.colors.background.base}99`,\n backdropFilter: isTransparentTheme ? 'blur(4px)' : undefined,\n WebkitBackdropFilter: isTransparentTheme ? 'blur(4px)' : undefined,\n display: 'flex',\n alignItems: size === 'fullscreen' ? 'stretch' : 'center',\n justifyContent: 'center',\n zIndex: DIALOG_Z_INDEX,\n animation: `zendir-dialog-backdrop ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default} both`,\n }}\n >\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n className=\"zendir-dialog\"\n onClick={(e) => e.stopPropagation()}\n style={{\n width: config.width,\n maxWidth: size === 'fullscreen' ? '100vw' : 'calc(100vw - 32px)',\n maxHeight: config.maxHeight,\n backgroundColor: isTransparentTheme ? 'rgba(139, 92, 246, 0.08)' : tokens.colors.background.surface,\n ...(isTransparentTheme && { backdropFilter: 'blur(16px)', WebkitBackdropFilter: 'blur(16px)', border: '1px solid rgba(139, 92, 246, 0.2)' }),\n borderRadius: size === 'fullscreen' ? 0 : tokens.borderRadius.lg,\n boxShadow: tokens.shadows.xl,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n animation: `zendir-dialog-panel ${tokens.animation.duration.normal}ms ${tokens.animation.easing.default} both`,\n }}\n >\n {/* Header */}\n {(title || showCloseButton) && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: `${tokens.spacing.md} ${tokens.spacing.lg}`,\n borderBottom: tokens.borders.divider,\n }}\n >\n {title && (\n <h2\n id={titleId}\n style={{\n margin: 0,\n fontSize: tokens.typography.fontSize.lg,\n fontWeight: tokens.typography.fontWeight.semibold,\n color: tokens.colors.text.primary,\n }}\n >\n {title}\n </h2>\n )}\n {showCloseButton && (\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close dialog\"\n style={{\n padding: tokens.spacing.sm,\n minWidth: 44,\n minHeight: 44,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: tokens.borderRadius.sm,\n cursor: 'pointer',\n color: tokens.colors.text.muted ?? tokens.colors.text.tertiary,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: `color ${tokens.animation.fast}`,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.color = tokens.colors.text.primary;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.color = tokens.colors.text.muted ?? tokens.colors.text.tertiary;\n }}\n >\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />\n </svg>\n </button>\n )}\n </div>\n )}\n \n {/* Content */}\n <div\n style={{\n flex: 1,\n padding: tokens.spacing.lg,\n overflow: 'auto',\n }}\n >\n {children}\n </div>\n </div>\n \n <style>\n {`\n @keyframes zendir-dialog-backdrop { from { opacity: 0; } to { opacity: 1; } }\n @keyframes zendir-dialog-panel { from { transform: scale(0.96); opacity: 0; } to { transform: scale(1); opacity: 1; } }\n `}\n </style>\n </div>\n ), document.body);\n}) as React.NamedExoticComponent<DialogProps> & {\n Actions: typeof DialogActions;\n};\n\n// Attach subcomponent\n(Dialog as any).Actions = DialogActions;\n\nexport default Dialog;\n"],"names":["DialogActions","Dialog"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { memo, useState, useRef, useCallback, useContext, createContext, useEffect } from "react";
3
- import { safeAccentText } from "../utils/index.js";
4
- import { useBreakpoint } from "./layout/useBreakpoint.js";
5
- import { useTheme } from "../theme/ThemeProvider.js";
3
+ import { safeAccentText } from "../../utils/index.js";
4
+ import { useBreakpoint } from "../layout/useBreakpoint.js";
5
+ import { useTheme } from "../../theme/ThemeProvider.js";
6
6
  const ToastContext = createContext(null);
7
7
  function useToast() {
8
8
  const ctx = useContext(ToastContext);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toast.js","sources":["../../../../src/react/core/feedback/Toast.tsx"],"sourcesContent":["/**\r\n * @zendir/ui - Toast / Notification System\r\n * \r\n * Contextual toast notifications with queue management, auto-dismiss,\r\n * and Astro UX status colors. Essential for operator dashboards surfacing\r\n * connection events, command results, and system alerts.\r\n * \r\n * Astro UX Compliance:\r\n * - 6-level status colors (off, standby, normal, caution, serious, critical)\r\n * - Positioned top-right (operator dashboard convention)\r\n * - Reduced motion support\r\n * - ARIA live region for screen readers\r\n * \r\n * @example\r\n * ```tsx\r\n * // Wrap app in ToastProvider\r\n * <ToastProvider>\r\n * <App />\r\n * </ToastProvider>\r\n * \r\n * // Use in any component\r\n * const toast = useToast();\r\n * toast({ status: 'normal', title: 'Connected', message: 'MQTT link established' });\r\n * toast({ status: 'caution', title: 'SAFE Mode', message: 'Spacecraft entered SAFE mode', duration: 0 });\r\n * toast({ status: 'critical', title: 'Link Lost', message: 'Downlink signal below threshold' });\r\n * ```\r\n */\r\n\r\nimport React, { memo, createContext, useContext, useState, useCallback, useRef, useEffect } from 'react';\r\nimport { useTheme } from '../../theme';\r\nimport { safeAccentText } from '../../utils';\r\nimport { useBreakpoint } from '../layout/useBreakpoint';\r\n\r\n// ─── Types ───────────────────────────────────────────────────────────────────\r\n\r\nexport type ToastStatus = 'normal' | 'standby' | 'caution' | 'serious' | 'critical' | 'off';\r\nexport type ToastPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';\r\n\r\nexport interface ToastOptions {\r\n /** Status level (determines color) */\r\n status?: ToastStatus;\r\n /** Title text (bold) */\r\n title: string;\r\n /** Description text */\r\n message?: string;\r\n /** Auto-dismiss duration in ms (0 = persistent, default 5000) */\r\n duration?: number;\r\n /** Dismissible by user click (default true) */\r\n dismissible?: boolean;\r\n /** Icon override */\r\n icon?: React.ReactNode;\r\n /** Action button */\r\n action?: {\r\n label: string;\r\n onClick: () => void;\r\n };\r\n}\r\n\r\ninterface ToastInstance extends ToastOptions {\r\n id: string;\r\n createdAt: number;\r\n}\r\n\r\n// ─── Context ─────────────────────────────────────────────────────────────────\r\n\r\ntype ToastFn = (options: ToastOptions) => string;\r\n\r\ninterface ToastContextValue {\r\n toast: ToastFn;\r\n dismiss: (id: string) => void;\r\n dismissAll: () => void;\r\n}\r\n\r\nconst ToastContext = createContext<ToastContextValue | null>(null);\r\n\r\n// ─── Hook ────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Hook to show toast notifications.\r\n * Must be used within a `<ToastProvider>`.\r\n * \r\n * @example\r\n * ```tsx\r\n * const toast = useToast();\r\n * toast({ status: 'normal', title: 'Success', message: 'Command sent' });\r\n * ```\r\n */\r\nexport function useToast(): ToastFn {\r\n const ctx = useContext(ToastContext);\r\n if (!ctx) throw new Error('useToast must be used within <ToastProvider>');\r\n return ctx.toast;\r\n}\r\n\r\n/**\r\n * Hook to access full toast API (toast, dismiss, dismissAll).\r\n */\r\nexport function useToastManager(): ToastContextValue {\r\n const ctx = useContext(ToastContext);\r\n if (!ctx) throw new Error('useToastManager must be used within <ToastProvider>');\r\n return ctx;\r\n}\r\n\r\n// ─── Toast Item ──────────────────────────────────────────────────────────────\r\n\r\nconst ToastItem = memo(function ToastItem({\r\n toast: t,\r\n onDismiss,\r\n}: {\r\n toast: ToastInstance;\r\n onDismiss: (id: string) => void;\r\n}): React.ReactElement {\r\n const { tokens } = useTheme();\r\n const [exiting, setExiting] = useState(false);\r\n const dismissTimeoutRef = useRef<ReturnType<typeof setTimeout>>();\r\n \r\n // Cleanup dismiss timeout on unmount\r\n useEffect(() => {\r\n return () => { clearTimeout(dismissTimeoutRef.current); };\r\n }, []);\r\n \r\n const statusColors: Record<string, string> = {\r\n normal: tokens.colors.status.normal,\r\n standby: tokens.colors.status.standby,\r\n caution: tokens.colors.status.caution,\r\n serious: tokens.colors.status.serious,\r\n critical: tokens.colors.status.critical,\r\n off: tokens.colors.status.off,\r\n };\r\n \r\n const color = statusColors[t.status || 'off'] || tokens.colors.status.off;\r\n \r\n const handleDismiss = useCallback(() => {\r\n setExiting(true);\r\n dismissTimeoutRef.current = setTimeout(() => onDismiss(t.id), 200);\r\n }, [t.id, onDismiss]);\r\n \r\n // Auto-dismiss\r\n useEffect(() => {\r\n const dur = t.duration ?? 5000;\r\n if (dur <= 0) return;\r\n const timer = setTimeout(handleDismiss, dur);\r\n return () => clearTimeout(timer);\r\n }, [t.duration, handleDismiss]);\r\n \r\n // Status icon — Astro UX dual-coded shapes\r\n const statusIcon = (() => {\r\n const s = 10;\r\n const h = s / 2;\r\n const status = t.status || 'off';\r\n const sharedStyle: React.CSSProperties = { flexShrink: 0, marginTop: '3px' };\r\n switch (status) {\r\n case 'critical':\r\n return (\r\n <svg width={s} height={s} viewBox={`0 0 ${s} ${s}`} style={sharedStyle}>\r\n <polygon points={`${h},${s} 0,0 ${s},0`} fill={color} />\r\n </svg>\r\n );\r\n case 'serious':\r\n return (\r\n <svg width={s} height={s} viewBox={`0 0 ${s} ${s}`} style={sharedStyle}>\r\n <polygon points={`${h},0 ${s},${h} ${h},${s} 0,${h}`} fill={color} />\r\n </svg>\r\n );\r\n case 'caution':\r\n return (\r\n <svg width={s} height={s} viewBox={`0 0 ${s} ${s}`} style={sharedStyle}>\r\n <rect width={s} height={s} fill={color} />\r\n </svg>\r\n );\r\n case 'standby':\r\n return (\r\n <svg width={s} height={s} viewBox=\"0 0 12 12\" style={sharedStyle}>\r\n <circle cx=\"6\" cy=\"6\" r=\"3.5\" fill=\"none\" stroke={color} strokeWidth=\"2\" />\r\n </svg>\r\n );\r\n case 'off':\r\n return (\r\n <svg width={s} height={s} viewBox=\"0 0 12 12\" style={sharedStyle}>\r\n <circle cx=\"6\" cy=\"6\" r=\"3\" fill={color} />\r\n </svg>\r\n );\r\n default: // normal\r\n return (\r\n <svg width={s} height={s} viewBox={`0 0 ${s} ${s}`} style={sharedStyle}>\r\n <circle cx={h} cy={h} r={h} fill={color} />\r\n </svg>\r\n );\r\n }\r\n })();\r\n \r\n return (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n display: 'flex',\r\n gap: tokens.spacing.sm,\r\n padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,\r\n backgroundColor: tokens.colors.background.elevated,\r\n border: `1px solid ${color}30`,\r\n borderLeft: `3px solid ${color}`,\r\n borderRadius: tokens.borderRadius.md,\r\n boxShadow: `${tokens.shadows.lg}, 0 0 20px ${color}15`,\r\n maxWidth: 'min(400px, calc(100vw - 32px))',\r\n minWidth: 'min(280px, calc(100vw - 32px))',\r\n fontFamily: tokens.typography.fontFamily.primary,\r\n animation: exiting\r\n ? `zendir-toast-exit 200ms ${tokens.animation.easing.default} forwards`\r\n : `zendir-toast-enter 300ms ${tokens.animation.easing.default}`,\r\n transition: tokens.animation.normal,\r\n }}\r\n >\r\n {t.icon || statusIcon}\r\n \r\n <div style={{ flex: 1, minWidth: 0 }}>\r\n <div style={{\r\n fontSize: tokens.typography.fontSize.sm,\r\n fontWeight: tokens.typography.fontWeight.semibold,\r\n color: tokens.colors.text.primary,\r\n lineHeight: tokens.typography.lineHeight.tight,\r\n }}>\r\n {t.title}\r\n </div>\r\n {t.message && (\r\n <div style={{\r\n fontSize: tokens.typography.fontSize.xs,\r\n color: tokens.colors.text.secondary,\r\n marginTop: '2px',\r\n lineHeight: tokens.typography.lineHeight.normal,\r\n }}>\r\n {t.message}\r\n </div>\r\n )}\r\n {t.action && (\r\n <button\r\n onClick={t.action.onClick}\r\n style={{\r\n marginTop: tokens.spacing.xs,\r\n fontSize: tokens.typography.fontSize.xs,\r\n fontWeight: tokens.typography.fontWeight.semibold,\r\n color: safeAccentText(tokens.colors.accent.primary),\r\n background: 'none',\r\n border: 'none',\r\n padding: 0,\r\n cursor: 'pointer',\r\n fontFamily: tokens.typography.fontFamily.primary,\r\n }}\r\n >\r\n {t.action.label}\r\n </button>\r\n )}\r\n </div>\r\n \r\n {(t.dismissible !== false) && (\r\n <button\r\n aria-label=\"Dismiss notification\"\r\n onClick={handleDismiss}\r\n style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n width: 44,\r\n height: 44,\r\n border: 'none',\r\n background: 'none',\r\n color: tokens.colors.text.tertiary,\r\n cursor: 'pointer',\r\n borderRadius: tokens.borderRadius.sm,\r\n padding: tokens.spacing.xs,\r\n flexShrink: 0,\r\n transition: tokens.animation.fast,\r\n }}\r\n >\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n )}\r\n </div>\r\n );\r\n});\r\n\r\n// ─── Provider ────────────────────────────────────────────────────────────────\r\n\r\nexport interface ToastProviderProps {\r\n /** Toast position (default: top-right) */\r\n position?: ToastPosition;\r\n /** Maximum visible toasts (default: 5) */\r\n maxVisible?: number;\r\n /** Default duration in ms (default: 5000) */\r\n defaultDuration?: number;\r\n /** Children */\r\n children: React.ReactNode;\r\n}\r\n\r\nexport const ToastProvider = memo(function ToastProvider({\r\n position = 'top-right',\r\n maxVisible = 5,\r\n defaultDuration = 5000,\r\n children,\r\n}: ToastProviderProps): React.ReactElement {\r\n const { tokens } = useTheme();\r\n const { isMobile } = useBreakpoint();\r\n const [toasts, setToasts] = useState<ToastInstance[]>([]);\r\n const idCounter = useRef(0);\r\n \r\n const toast = useCallback((options: ToastOptions): string => {\r\n const id = `toast-${++idCounter.current}-${Date.now()}`;\r\n const instance: ToastInstance = {\r\n ...options,\r\n id,\r\n createdAt: Date.now(),\r\n duration: options.duration ?? defaultDuration,\r\n };\r\n setToasts(prev => [...prev, instance].slice(-maxVisible * 2)); // Keep buffer\r\n return id;\r\n }, [defaultDuration, maxVisible]);\r\n \r\n const dismiss = useCallback((id: string) => {\r\n setToasts(prev => prev.filter(t => t.id !== id));\r\n }, []);\r\n \r\n const dismissAll = useCallback(() => {\r\n setToasts([]);\r\n }, []);\r\n \r\n // Position styles\r\n const inset = isMobile ? tokens.spacing.sm : tokens.spacing.md;\r\n const positionStyles: Record<ToastPosition, React.CSSProperties> = {\r\n 'top-right': { top: inset, right: inset },\r\n 'top-left': { top: inset, left: inset },\r\n 'bottom-right': { bottom: inset, right: inset },\r\n 'bottom-left': { bottom: inset, left: inset },\r\n 'top-center': { top: inset, left: '50%', transform: 'translateX(-50%)' },\r\n 'bottom-center': { bottom: inset, left: '50%', transform: 'translateX(-50%)' },\r\n };\r\n \r\n const isBottom = position.startsWith('bottom');\r\n const visibleToasts = toasts.slice(-maxVisible);\r\n \r\n return (\r\n <ToastContext.Provider value={{ toast, dismiss, dismissAll }}>\r\n {children}\r\n \r\n {/* Toast container */}\r\n {visibleToasts.length > 0 && (\r\n <div\r\n aria-live={visibleToasts.some(t => t.status === 'critical' || t.status === 'serious') ? 'assertive' : 'polite'}\r\n aria-atomic=\"false\"\r\n style={{\r\n position: 'fixed',\r\n zIndex: 9999,\r\n display: 'flex',\r\n flexDirection: isBottom ? 'column-reverse' : 'column',\r\n gap: tokens.spacing.sm,\r\n pointerEvents: 'none',\r\n ...positionStyles[position],\r\n }}\r\n >\r\n {visibleToasts.map(t => (\r\n <div key={t.id} style={{ pointerEvents: 'auto' }}>\r\n <ToastItem toast={t} onDismiss={dismiss} />\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n \r\n <style>{`\r\n @keyframes zendir-toast-enter {\r\n from { opacity: 0; transform: translateX(20px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n }\r\n @keyframes zendir-toast-exit {\r\n from { opacity: 1; transform: translateX(0); }\r\n to { opacity: 0; transform: translateX(20px); }\r\n }\r\n @media (prefers-reduced-motion: reduce) {\r\n @keyframes zendir-toast-enter { from { opacity: 0; } to { opacity: 1; } }\r\n @keyframes zendir-toast-exit { from { opacity: 1; } to { opacity: 0; } }\r\n }\r\n `}</style>\r\n </ToastContext.Provider>\r\n );\r\n});\r\n\r\nexport default ToastProvider;\r\n"],"names":["ToastItem","ToastProvider"],"mappings":"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"}
@@ -4,57 +4,57 @@
4
4
  * Foundational UI components following Astro UX Design System.
5
5
  * These are the building blocks for creating space operations interfaces.
6
6
  */
7
- export { Icon, getIconNames, isValidIconName } from './Icon';
8
- export type { IconProps, IconName } from './Icon';
9
- export type { AstroIconProps, AstroIconName, AstroIconSize } from './AstroIcon';
10
- export { Button } from './Button';
11
- export type { ButtonProps, ButtonVariant, ButtonSize } from './Button';
12
- export { Input } from './Input';
13
- export type { InputProps, InputSize, LabelPlacement } from './Input';
14
- export { Select } from './Select';
15
- export type { SelectProps, SelectOption } from './Select';
16
- export { Toggle } from './Toggle';
17
- export type { ToggleProps } from './Toggle';
18
- export { Checkbox } from './Checkbox';
19
- export type { CheckboxProps } from './Checkbox';
20
- export { Tooltip } from './Tooltip';
21
- export type { TooltipProps, TooltipPlacement } from './Tooltip';
22
- export { Dialog } from './Dialog';
23
- export type { DialogProps, DialogActionsProps, DialogSize } from './Dialog';
24
- export { Badge } from './Badge';
25
- export type { BadgeProps, BadgeVariant, BadgeSize } from './Badge';
26
- export { Tabs } from './Tabs';
27
- export type { TabsProps, TabsListProps, TabProps, TabsPanelProps } from './Tabs';
28
- export { Container } from './Container';
29
- export type { ContainerProps, ContainerVariant, ContainerPadding } from './Container';
30
- export { GlassCard, GLASS_COLOR_OVERLAYS } from './GlassCard';
31
- export type { GlassCardProps, GlassColorOverlay, GlassAccentPosition } from './GlassCard';
32
- export { Pagination } from './Pagination';
33
- export type { PaginationProps } from './Pagination';
34
- export { DataValue, DataValueGroup } from './DataValue';
35
- export type { DataValueProps, DataValueGroupProps, DataValueVariant, DataValueSize } from './DataValue';
36
- export { HeaderIconWithStatus } from './HeaderIconWithStatus';
37
- export type { HeaderIconWithStatusProps } from './HeaderIconWithStatus';
38
- export { CardHeader } from './CardHeader';
39
- export type { CardHeaderProps } from './CardHeader';
40
- export { getPropertyConfig, formatPropertyLabel, deriveStatus, deriveBatteryStatus, formatPropertyValue, createPropertyConfig, getPropertiesByCategory, PROPERTY_PRESETS, CATEGORY_ICONS, CATEGORY_LABELS, } from './propertyConfig';
41
- export type { PropertyConfig, PropertyKey, PropertyCategory, StatusThresholds, } from './propertyConfig';
42
- export { MessageStream } from './MessageStream';
43
- export type { MessageStreamProps, StreamMessage } from './MessageStream';
44
- export { AppBar } from './AppBar';
45
- export type { AppBarProps, AppBarBranding } from './AppBar';
46
- export { ColorPickerPanel } from './ColorPickerPanel';
47
- export type { ColorPickerPanelProps } from './ColorPickerPanel';
48
- export { Typography, Display1, Display2, H1, H2, H3, H4, H5, H6, Body1, Body2, Body3, Compact, Micro, Mono, DataText, Label, FONT_FAMILY_PRIMARY, FONT_FAMILY_MONO, FONT_WEIGHTS, } from './Typography';
49
- export type { TypographyProps, TypographyVariant, TypographyElement, TypographyColor, } from './Typography';
50
- export { NumberInput } from './NumberInput';
51
- export type { NumberInputProps, NumberInputSize, SliderStatus } from './NumberInput';
52
- export { SideNav, SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX } from './SideNav';
53
- export type { SideNavProps, SideNavHeaderProps, SideNavItemProps, SideNavSectionProps, SideNavFooterProps } from './SideNav';
54
- export { ToastProvider, useToast, useToastManager } from './Toast';
55
- export type { ToastOptions, ToastStatus, ToastPosition, ToastProviderProps } from './Toast';
56
- export { Popover, Menu } from './Popover';
57
- export type { PopoverProps, PopoverPlacement, MenuProps, MenuItemProps } from './Popover';
7
+ export { Icon, getIconNames, isValidIconName } from './display/Icon';
8
+ export type { IconProps, IconName } from './display/Icon';
9
+ export type { AstroIconProps, AstroIconName, AstroIconSize } from './display/AstroIcon';
10
+ export { Button } from './inputs/Button';
11
+ export type { ButtonProps, ButtonVariant, ButtonSize } from './inputs/Button';
12
+ export { Input } from './inputs/Input';
13
+ export type { InputProps, InputSize, LabelPlacement } from './inputs/Input';
14
+ export { Select } from './inputs/Select';
15
+ export type { SelectProps, SelectOption } from './inputs/Select';
16
+ export { Toggle } from './inputs/Toggle';
17
+ export type { ToggleProps } from './inputs/Toggle';
18
+ export { Checkbox } from './inputs/Checkbox';
19
+ export type { CheckboxProps } from './inputs/Checkbox';
20
+ export { Tooltip } from './overlays/Tooltip';
21
+ export type { TooltipProps, TooltipPlacement } from './overlays/Tooltip';
22
+ export { Dialog } from './feedback/Dialog';
23
+ export type { DialogProps, DialogActionsProps, DialogSize } from './feedback/Dialog';
24
+ export { Badge } from './display/Badge';
25
+ export type { BadgeProps, BadgeVariant, BadgeSize } from './display/Badge';
26
+ export { Tabs } from './navigation/Tabs';
27
+ export type { TabsProps, TabsListProps, TabProps, TabsPanelProps } from './navigation/Tabs';
28
+ export { Container } from './display/Container';
29
+ export type { ContainerProps, ContainerVariant, ContainerPadding } from './display/Container';
30
+ export { GlassCard, GLASS_COLOR_OVERLAYS } from './display/GlassCard';
31
+ export type { GlassCardProps, GlassColorOverlay, GlassAccentPosition } from './display/GlassCard';
32
+ export { Pagination } from './navigation/Pagination';
33
+ export type { PaginationProps } from './navigation/Pagination';
34
+ export { DataValue, DataValueGroup } from './data/DataValue';
35
+ export type { DataValueProps, DataValueGroupProps, DataValueVariant, DataValueSize } from './data/DataValue';
36
+ export { HeaderIconWithStatus } from './display/HeaderIconWithStatus';
37
+ export type { HeaderIconWithStatusProps } from './display/HeaderIconWithStatus';
38
+ export { CardHeader } from './display/CardHeader';
39
+ export type { CardHeaderProps } from './display/CardHeader';
40
+ export { getPropertyConfig, formatPropertyLabel, deriveStatus, deriveBatteryStatus, formatPropertyValue, createPropertyConfig, getPropertiesByCategory, PROPERTY_PRESETS, CATEGORY_ICONS, CATEGORY_LABELS, } from './data/propertyConfig';
41
+ export type { PropertyConfig, PropertyKey, PropertyCategory, StatusThresholds, } from './data/propertyConfig';
42
+ export { MessageStream } from './widgets/MessageStream';
43
+ export type { MessageStreamProps, StreamMessage } from './widgets/MessageStream';
44
+ export { AppBar } from './navigation/AppBar';
45
+ export type { AppBarProps, AppBarBranding } from './navigation/AppBar';
46
+ export { ColorPickerPanel } from './widgets/ColorPickerPanel';
47
+ export type { ColorPickerPanelProps } from './widgets/ColorPickerPanel';
48
+ export { Typography, Display1, Display2, H1, H2, H3, H4, H5, H6, Body1, Body2, Body3, Compact, Micro, Mono, DataText, Label, FONT_FAMILY_PRIMARY, FONT_FAMILY_MONO, FONT_WEIGHTS, } from './display/Typography';
49
+ export type { TypographyProps, TypographyVariant, TypographyElement, TypographyColor, } from './display/Typography';
50
+ export { NumberInput } from './inputs/NumberInput';
51
+ export type { NumberInputProps, NumberInputSize, SliderStatus } from './inputs/NumberInput';
52
+ export { SideNav, SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX } from './navigation/SideNav';
53
+ export type { SideNavProps, SideNavHeaderProps, SideNavItemProps, SideNavSectionProps, SideNavFooterProps } from './navigation/SideNav';
54
+ export { ToastProvider, useToast, useToastManager } from './feedback/Toast';
55
+ export type { ToastOptions, ToastStatus, ToastPosition, ToastProviderProps } from './feedback/Toast';
56
+ export { Popover, Menu } from './overlays/Popover';
57
+ export type { PopoverProps, PopoverPlacement, MenuProps, MenuItemProps } from './overlays/Popover';
58
58
  export { Box } from './layout/Box';
59
59
  export type { BoxProps } from './layout/Box';
60
60
  export { Flex } from './layout/Flex';
@@ -73,37 +73,37 @@ export { useBreakpoint, BREAKPOINTS } from './layout/useBreakpoint';
73
73
  export type { Breakpoint, ResponsiveValue } from './layout/useBreakpoint';
74
74
  export { resolveResponsive, resolveSpacing } from './layout/responsive';
75
75
  export type { SpacingToken } from './layout/responsive';
76
- export { ConfirmDialog, ConfirmProvider, useConfirm } from './ConfirmDialog';
77
- export type { ConfirmDialogProps, ConfirmOptions, ConfirmStatus } from './ConfirmDialog';
78
- export { PinInput } from './PinInput';
79
- export type { PinInputProps } from './PinInput';
80
- export { CopyButton, useCopyToClipboard } from './CopyButton';
81
- export type { CopyButtonProps, UseCopyToClipboardReturn } from './CopyButton';
82
- export { DataTable, DataTableRowDetail } from './DataTable';
83
- export type { DataTableProps, DataTableColumn, DataTableRowDetailProps, DataTableRowDetailField } from './DataTable';
84
- export { ImageGallery } from './ImageGallery';
85
- export type { ImageGalleryProps, GalleryImage } from './ImageGallery';
86
- export { ChatPanel, parseChatResponse, createChatResponseParser, parseMcpToolResult, CHAT_RESPONSE_TOOL_SCHEMA, CHAT_RESPONSE_MCP_TOOL, CHAT_RESPONSE_JSON_PROMPT, CHAT_RESPONSE_YAML_PROMPT, CHAT_STATUS_RULES_PROMPT } from './ChatPanel';
87
- export type { ChatPanelProps, ChatMessage, ChatBlock, ChatBlockEvent, ChatBlockAlert, ChatBlockTelemetry, ChatBlockProgress, ChatBlockTable, ChatBlockActions, ChatBlockChoice, ChatBlockConfirm, ChatBlockCommand, ChatBlockKV, ChatResponseFormat, ChatResponsePayload, ChatResponseParserOptions, McpToolContent, McpToolResult } from './ChatPanel';
88
- export { ConnectionForm } from './ConnectionForm';
89
- export type { ConnectionFormProps, ConnectionConfig } from './ConnectionForm';
90
- export { SidePanel } from './SidePanel';
91
- export type { SidePanelProps, SidePanelPosition } from './SidePanel';
92
- export { HexViewer, REGION_COLORS, REGION_BORDER_COLORS } from './HexViewer';
93
- export type { HexViewerProps, HexHighlight, HexRegion, DecodedField, PacketHeaderEntry, ByteGrouping, OffsetBase, Endianness } from './HexViewer';
94
- export { LimitsBar } from './LimitsBar';
95
- export type { LimitsBarProps, LimitsState } from './LimitsBar';
96
- export { LogViewer } from './LogViewer';
97
- export type { LogViewerProps, LogEntry, LogSeverity } from './LogViewer';
98
- export { PacketViewer } from './PacketViewer';
99
- export type { PacketViewerProps, PacketItem, PacketItemLimits, PacketItemLimitsState, PacketViewMode } from './PacketViewer';
100
- export { CommandBuilder } from './CommandBuilder';
101
- export type { CommandBuilderProps, CommandParameter, CommandParamType, CommandHistoryEntry } from './CommandBuilder';
102
- export { FileExplorer } from './FileExplorer';
103
- export type { FileExplorerProps, FileNode, FileViewMode, FileSortBy } from './FileExplorer';
104
- export { MissionCalendar } from './MissionCalendar';
105
- export type { MissionCalendarProps, CalendarEvent, CalendarTimeline, CalendarViewMode, ActivityStatus, ActivityType, } from './MissionCalendar';
106
- export { ActivityPlanner } from './ActivityPlanner';
107
- export type { ActivityPlannerProps, ActivityFormData, } from './ActivityPlanner';
108
- export { Capture, useCapture, loadCapturePlaceholderImage } from './Capture';
109
- export type { CaptureProps, CaptureHandle, CaptureRequest, CaptureArgs, CapturedImage, UseCaptureOptions, UseCaptureResult, } from './Capture';
76
+ export { ConfirmDialog, ConfirmProvider, useConfirm } from './feedback/ConfirmDialog';
77
+ export type { ConfirmDialogProps, ConfirmOptions, ConfirmStatus } from './feedback/ConfirmDialog';
78
+ export { PinInput } from './inputs/PinInput';
79
+ export type { PinInputProps } from './inputs/PinInput';
80
+ export { CopyButton, useCopyToClipboard } from './display/CopyButton';
81
+ export type { CopyButtonProps, UseCopyToClipboardReturn } from './display/CopyButton';
82
+ export { DataTable, DataTableRowDetail } from './data/DataTable';
83
+ export type { DataTableProps, DataTableColumn, DataTableRowDetailProps, DataTableRowDetailField } from './data/DataTable';
84
+ export { ImageGallery } from './widgets/ImageGallery';
85
+ export type { ImageGalleryProps, GalleryImage } from './widgets/ImageGallery';
86
+ export { ChatPanel, parseChatResponse, createChatResponseParser, parseMcpToolResult, CHAT_RESPONSE_TOOL_SCHEMA, CHAT_RESPONSE_MCP_TOOL, CHAT_RESPONSE_JSON_PROMPT, CHAT_RESPONSE_YAML_PROMPT, CHAT_STATUS_RULES_PROMPT } from './widgets/ChatPanel';
87
+ export type { ChatPanelProps, ChatMessage, ChatBlock, ChatBlockEvent, ChatBlockAlert, ChatBlockTelemetry, ChatBlockProgress, ChatBlockTable, ChatBlockActions, ChatBlockChoice, ChatBlockConfirm, ChatBlockCommand, ChatBlockKV, ChatResponseFormat, ChatResponsePayload, ChatResponseParserOptions, McpToolContent, McpToolResult } from './widgets/ChatPanel';
88
+ export { ConnectionForm } from './widgets/ConnectionForm';
89
+ export type { ConnectionFormProps, ConnectionConfig } from './widgets/ConnectionForm';
90
+ export { SidePanel } from './overlays/SidePanel';
91
+ export type { SidePanelProps, SidePanelPosition } from './overlays/SidePanel';
92
+ export { HexViewer, REGION_COLORS, REGION_BORDER_COLORS } from './widgets/HexViewer';
93
+ export type { HexViewerProps, HexHighlight, HexRegion, DecodedField, PacketHeaderEntry, ByteGrouping, OffsetBase, Endianness } from './widgets/HexViewer';
94
+ export { LimitsBar } from './inputs/LimitsBar';
95
+ export type { LimitsBarProps, LimitsState } from './inputs/LimitsBar';
96
+ export { LogViewer } from './widgets/LogViewer';
97
+ export type { LogViewerProps, LogEntry, LogSeverity } from './widgets/LogViewer';
98
+ export { PacketViewer } from './widgets/PacketViewer';
99
+ export type { PacketViewerProps, PacketItem, PacketItemLimits, PacketItemLimitsState, PacketViewMode } from './widgets/PacketViewer';
100
+ export { CommandBuilder } from './widgets/CommandBuilder';
101
+ export type { CommandBuilderProps, CommandParameter, CommandParamType, CommandHistoryEntry } from './widgets/CommandBuilder';
102
+ export { FileExplorer } from './widgets/FileExplorer';
103
+ export type { FileExplorerProps, FileNode, FileViewMode, FileSortBy } from './widgets/FileExplorer';
104
+ export { MissionCalendar } from './widgets/MissionCalendar';
105
+ export type { MissionCalendarProps, CalendarEvent, CalendarTimeline, CalendarViewMode, ActivityStatus, ActivityType, } from './widgets/MissionCalendar';
106
+ export { ActivityPlanner } from './widgets/ActivityPlanner';
107
+ export type { ActivityPlannerProps, ActivityFormData, } from './widgets/ActivityPlanner';
108
+ export { Capture, useCapture, loadCapturePlaceholderImage } from './widgets/Capture';
109
+ export type { CaptureProps, CaptureHandle, CaptureRequest, CaptureArgs, CapturedImage, UseCaptureOptions, UseCaptureResult, } from './widgets/Capture';
@@ -1,8 +1,8 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { memo, forwardRef, useState, useMemo, useRef, useCallback, useLayoutEffect } from "react";
3
3
  import ReactDOM from "react-dom";
4
- import { safeAccentText, classNames } from "../utils/index.js";
5
- import { useTheme } from "../theme/ThemeProvider.js";
4
+ import { safeAccentText, classNames } from "../../utils/index.js";
5
+ import { useTheme } from "../../theme/ThemeProvider.js";
6
6
  const Button = memo(forwardRef(function Button2({
7
7
  variant = "primary",
8
8
  size = "medium",
@@ -0,0 +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":"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"}
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { memo, forwardRef, useState, useId } from "react";
3
- import { classNames } from "../utils/index.js";
4
- import { useTheme } from "../theme/ThemeProvider.js";
3
+ import { classNames } from "../../utils/index.js";
4
+ import { useTheme } from "../../theme/ThemeProvider.js";
5
5
  const Checkbox = memo(forwardRef(function Checkbox2({
6
6
  type = "checkbox",
7
7
  checked = false,
@@ -0,0 +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,5 +1,5 @@
1
1
  import { default as React } from 'react';
2
- import { StatusLevel } from '../utils';
2
+ import { StatusLevel } from '../../utils';
3
3
 
4
4
  export type InputSize = 'small' | 'medium' | 'large';
5
5
  /** Label placement relative to the input field */
@@ -1,8 +1,8 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import { memo, forwardRef, useState, useId } from "react";
3
- import { safeAccentText, classNames } from "../utils/index.js";
4
- import { useBreakpoint } from "./layout/useBreakpoint.js";
5
- import { useTheme } from "../theme/ThemeProvider.js";
3
+ import { safeAccentText, classNames } from "../../utils/index.js";
4
+ import { useBreakpoint } from "../layout/useBreakpoint.js";
5
+ import { useTheme } from "../../theme/ThemeProvider.js";
6
6
  const Input = memo(forwardRef(function Input2({
7
7
  label,
8
8
  helperText,