eidotter 0.36.0 → 0.37.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 (328) hide show
  1. package/README.md +19 -0
  2. package/dist/components/AIText/components/AIText.d.ts +0 -1
  3. package/dist/components/AIText/components/AIText.js +23 -0
  4. package/dist/components/AIText/components/index.d.ts +2 -2
  5. package/dist/components/AIText/components/index.js +1 -0
  6. package/dist/components/AIText/index.d.ts +2 -2
  7. package/dist/components/AIText/index.js +1 -0
  8. package/dist/components/Accordion/components/AccordionFill.d.ts +0 -1
  9. package/dist/components/Accordion/components/AccordionFill.js +12 -0
  10. package/dist/components/Accordion/components/Section.d.ts +0 -1
  11. package/dist/components/Accordion/components/Section.js +22 -0
  12. package/dist/components/Accordion/components/index.d.ts +4 -4
  13. package/dist/components/Accordion/components/index.js +2 -0
  14. package/dist/components/Accordion/index.d.ts +1 -1
  15. package/dist/components/Accordion/index.js +1 -0
  16. package/dist/components/Alert/components/Alert.d.ts +0 -1
  17. package/dist/components/Alert/components/Alert.js +51 -0
  18. package/dist/components/Alert/components/index.d.ts +2 -2
  19. package/dist/components/Alert/components/index.js +1 -0
  20. package/dist/components/Alert/index.d.ts +1 -1
  21. package/dist/components/Alert/index.js +1 -0
  22. package/dist/components/Badge/components/Badge.d.ts +0 -1
  23. package/dist/components/Badge/components/Badge.js +31 -0
  24. package/dist/components/Badge/components/index.d.ts +2 -2
  25. package/dist/components/Badge/components/index.js +1 -0
  26. package/dist/components/Badge/index.d.ts +2 -2
  27. package/dist/components/Badge/index.js +1 -0
  28. package/dist/components/Brand/components/BrandLockup.js +14 -0
  29. package/dist/components/Brand/components/Logo.d.ts +0 -1
  30. package/dist/components/Brand/components/Logo.js +22 -0
  31. package/dist/components/Brand/components/Wordmark.d.ts +0 -1
  32. package/dist/components/Brand/components/Wordmark.js +13 -0
  33. package/dist/components/Brand/components/index.d.ts +6 -6
  34. package/dist/components/Brand/components/index.js +3 -0
  35. package/dist/components/Brand/index.d.ts +1 -1
  36. package/dist/components/Brand/index.js +1 -0
  37. package/dist/components/Breadcrumb/components/Breadcrumb.d.ts +0 -1
  38. package/dist/components/Breadcrumb/components/Breadcrumb.js +29 -0
  39. package/dist/components/Breadcrumb/components/index.d.ts +2 -2
  40. package/dist/components/Breadcrumb/components/index.js +1 -0
  41. package/dist/components/Breadcrumb/index.d.ts +2 -2
  42. package/dist/components/Breadcrumb/index.js +1 -0
  43. package/dist/components/Button/components/Button.d.ts +0 -2
  44. package/dist/components/Button/components/Button.js +49 -0
  45. package/dist/components/Button/components/index.d.ts +2 -2
  46. package/dist/components/Button/components/index.js +1 -0
  47. package/dist/components/Button/index.d.ts +2 -2
  48. package/dist/components/Button/index.js +1 -0
  49. package/dist/components/Card/components/Card.d.ts +0 -1
  50. package/dist/components/Card/components/Card.js +16 -0
  51. package/dist/components/Card/components/index.d.ts +2 -2
  52. package/dist/components/Card/components/index.js +1 -0
  53. package/dist/components/Card/index.d.ts +2 -2
  54. package/dist/components/Card/index.js +1 -0
  55. package/dist/components/Chat/components/ChatContainer.d.ts +1 -1
  56. package/dist/components/Chat/components/ChatContainer.js +20 -0
  57. package/dist/components/Chat/components/ChatHistory.d.ts +0 -1
  58. package/dist/components/Chat/components/ChatHistory.js +27 -0
  59. package/dist/components/Chat/components/ChatInput.d.ts +0 -2
  60. package/dist/components/Chat/components/ChatInput.js +37 -0
  61. package/dist/components/Chat/components/ChatMessage.d.ts +0 -2
  62. package/dist/components/Chat/components/ChatMessage.js +18 -0
  63. package/dist/components/Chat/components/index.d.ts +8 -8
  64. package/dist/components/Chat/components/index.js +4 -0
  65. package/dist/components/Chat/index.d.ts +2 -2
  66. package/dist/components/Chat/index.js +1 -0
  67. package/dist/components/Checkbox/components/Checkbox.d.ts +0 -2
  68. package/dist/components/Checkbox/components/Checkbox.js +11 -0
  69. package/dist/components/Checkbox/components/index.d.ts +2 -2
  70. package/dist/components/Checkbox/components/index.js +1 -0
  71. package/dist/components/Checkbox/index.d.ts +2 -2
  72. package/dist/components/Checkbox/index.js +1 -0
  73. package/dist/components/ChecklistRow/components/ChecklistRow.js +18 -0
  74. package/dist/components/ChecklistRow/components/index.d.ts +2 -2
  75. package/dist/components/ChecklistRow/components/index.js +1 -0
  76. package/dist/components/ChecklistRow/index.d.ts +2 -2
  77. package/dist/components/ChecklistRow/index.js +1 -0
  78. package/dist/components/CmdPalette/components/CmdPalette.d.ts +0 -2
  79. package/dist/components/CmdPalette/components/CmdPalette.js +169 -0
  80. package/dist/components/CmdPalette/components/index.d.ts +2 -2
  81. package/dist/components/CmdPalette/components/index.js +1 -0
  82. package/dist/components/CmdPalette/index.d.ts +2 -2
  83. package/dist/components/CmdPalette/index.js +1 -0
  84. package/dist/components/CommandPrompt/components/CommandPrompt.d.ts +0 -2
  85. package/dist/components/CommandPrompt/components/CommandPrompt.js +34 -0
  86. package/dist/components/CommandPrompt/components/index.d.ts +2 -2
  87. package/dist/components/CommandPrompt/components/index.js +1 -0
  88. package/dist/components/CommandPrompt/index.d.ts +1 -1
  89. package/dist/components/CommandPrompt/index.js +1 -0
  90. package/dist/components/CopyButton/components/CopyButton.js +50 -0
  91. package/dist/components/CopyButton/components/index.d.ts +2 -2
  92. package/dist/components/CopyButton/components/index.js +1 -0
  93. package/dist/components/CopyButton/index.d.ts +2 -2
  94. package/dist/components/CopyButton/index.js +1 -0
  95. package/dist/components/DosFigure/components/DosFigure.d.ts +0 -1
  96. package/dist/components/DosFigure/components/DosFigure.js +26 -0
  97. package/dist/components/DosFigure/components/index.d.ts +2 -2
  98. package/dist/components/DosFigure/components/index.js +1 -0
  99. package/dist/components/DosFigure/index.d.ts +2 -2
  100. package/dist/components/DosFigure/index.js +1 -0
  101. package/dist/components/EmptyState/components/EmptyState.js +18 -0
  102. package/dist/components/EmptyState/components/index.d.ts +2 -2
  103. package/dist/components/EmptyState/components/index.js +1 -0
  104. package/dist/components/EmptyState/index.d.ts +2 -2
  105. package/dist/components/EmptyState/index.js +1 -0
  106. package/dist/components/FilterBar/components/FilterBar.d.ts +0 -1
  107. package/dist/components/FilterBar/components/FilterBar.js +120 -0
  108. package/dist/components/FilterBar/components/index.d.ts +2 -2
  109. package/dist/components/FilterBar/components/index.js +1 -0
  110. package/dist/components/FilterBar/index.d.ts +2 -2
  111. package/dist/components/FilterBar/index.js +1 -0
  112. package/dist/components/Footer/components/Footer.d.ts +0 -1
  113. package/dist/components/Footer/components/Footer.js +18 -0
  114. package/dist/components/Footer/components/index.d.ts +2 -2
  115. package/dist/components/Footer/components/index.js +1 -0
  116. package/dist/components/Footer/index.d.ts +2 -2
  117. package/dist/components/Footer/index.js +1 -0
  118. package/dist/components/Header/components/Header.d.ts +1 -2
  119. package/dist/components/Header/components/Header.js +13 -0
  120. package/dist/components/Header/components/index.d.ts +2 -2
  121. package/dist/components/Header/components/index.js +1 -0
  122. package/dist/components/Header/index.d.ts +2 -2
  123. package/dist/components/Header/index.js +1 -0
  124. package/dist/components/Icon/components/Icon.d.ts +0 -1
  125. package/dist/components/Icon/components/Icon.js +78 -0
  126. package/dist/components/Icon/components/index.d.ts +2 -2
  127. package/dist/components/Icon/components/index.js +1 -0
  128. package/dist/components/Icon/index.d.ts +1 -1
  129. package/dist/components/Icon/index.js +1 -0
  130. package/dist/components/InlineExpand/components/InlineExpand.d.ts +0 -1
  131. package/dist/components/InlineExpand/components/InlineExpand.js +50 -0
  132. package/dist/components/InlineExpand/components/index.d.ts +2 -2
  133. package/dist/components/InlineExpand/components/index.js +1 -0
  134. package/dist/components/InlineExpand/index.d.ts +2 -2
  135. package/dist/components/InlineExpand/index.js +1 -0
  136. package/dist/components/InlineLink/components/InlineLink.d.ts +0 -1
  137. package/dist/components/InlineLink/components/InlineLink.js +61 -0
  138. package/dist/components/InlineLink/components/index.d.ts +2 -2
  139. package/dist/components/InlineLink/components/index.js +1 -0
  140. package/dist/components/InlineLink/index.d.ts +2 -2
  141. package/dist/components/InlineLink/index.js +1 -0
  142. package/dist/components/Input/components/Input.d.ts +0 -1
  143. package/dist/components/Input/components/Input.js +18 -0
  144. package/dist/components/Input/components/index.d.ts +2 -2
  145. package/dist/components/Input/components/index.js +1 -0
  146. package/dist/components/Input/index.d.ts +1 -1
  147. package/dist/components/Input/index.js +1 -0
  148. package/dist/components/LabeledProgress/components/LabeledProgress.d.ts +0 -1
  149. package/dist/components/LabeledProgress/components/LabeledProgress.js +16 -0
  150. package/dist/components/LabeledProgress/components/index.d.ts +2 -2
  151. package/dist/components/LabeledProgress/components/index.js +1 -0
  152. package/dist/components/LabeledProgress/index.d.ts +2 -2
  153. package/dist/components/LabeledProgress/index.js +1 -0
  154. package/dist/components/LedgerRow/components/LedgerRow.js +15 -0
  155. package/dist/components/LedgerRow/components/index.d.ts +2 -2
  156. package/dist/components/LedgerRow/components/index.js +1 -0
  157. package/dist/components/LedgerRow/index.d.ts +2 -2
  158. package/dist/components/LedgerRow/index.js +1 -0
  159. package/dist/components/LegalPage/components/LegalPage.d.ts +0 -1
  160. package/dist/components/LegalPage/components/LegalPage.js +11 -0
  161. package/dist/components/LegalPage/components/clauses.js +28 -0
  162. package/dist/components/LegalPage/components/index.d.ts +4 -4
  163. package/dist/components/LegalPage/components/index.js +2 -0
  164. package/dist/components/LegalPage/index.d.ts +2 -2
  165. package/dist/components/LegalPage/index.js +1 -0
  166. package/dist/components/Lightbox/components/Lightbox.d.ts +1 -3
  167. package/dist/components/Lightbox/components/Lightbox.js +97 -0
  168. package/dist/components/Lightbox/components/index.d.ts +2 -2
  169. package/dist/components/Lightbox/components/index.js +1 -0
  170. package/dist/components/Lightbox/index.d.ts +2 -2
  171. package/dist/components/Lightbox/index.js +1 -0
  172. package/dist/components/Modal/components/Modal.d.ts +0 -2
  173. package/dist/components/Modal/components/Modal.js +37 -0
  174. package/dist/components/Modal/components/index.d.ts +2 -2
  175. package/dist/components/Modal/components/index.js +1 -0
  176. package/dist/components/Modal/index.d.ts +2 -2
  177. package/dist/components/Modal/index.js +1 -0
  178. package/dist/components/Nav/components/Nav.d.ts +0 -1
  179. package/dist/components/Nav/components/Nav.js +69 -0
  180. package/dist/components/Nav/components/index.d.ts +2 -2
  181. package/dist/components/Nav/components/index.js +1 -0
  182. package/dist/components/Nav/index.d.ts +2 -2
  183. package/dist/components/Nav/index.js +1 -0
  184. package/dist/components/Notification/components/Notification.d.ts +1 -2
  185. package/dist/components/Notification/components/Notification.js +34 -0
  186. package/dist/components/Notification/components/index.d.ts +2 -2
  187. package/dist/components/Notification/components/index.js +1 -0
  188. package/dist/components/Notification/index.d.ts +1 -1
  189. package/dist/components/Notification/index.js +1 -0
  190. package/dist/components/Progress/components/Progress.d.ts +0 -1
  191. package/dist/components/Progress/components/Progress.js +72 -0
  192. package/dist/components/Progress/components/index.d.ts +2 -2
  193. package/dist/components/Progress/components/index.js +1 -0
  194. package/dist/components/Progress/index.d.ts +2 -2
  195. package/dist/components/Progress/index.js +1 -0
  196. package/dist/components/RetroEffects/components/RetroEffects.d.ts +0 -1
  197. package/dist/components/RetroEffects/components/RetroEffects.js +163 -0
  198. package/dist/components/RetroEffects/components/index.d.ts +2 -2
  199. package/dist/components/RetroEffects/components/index.js +1 -0
  200. package/dist/components/RetroEffects/index.d.ts +2 -2
  201. package/dist/components/RetroEffects/index.js +1 -0
  202. package/dist/components/SectionHeading/components/SectionHeading.js +18 -0
  203. package/dist/components/SectionHeading/components/index.d.ts +2 -2
  204. package/dist/components/SectionHeading/components/index.js +1 -0
  205. package/dist/components/SectionHeading/index.d.ts +2 -2
  206. package/dist/components/SectionHeading/index.js +1 -0
  207. package/dist/components/Select/components/Select.js +14 -0
  208. package/dist/components/Select/components/index.d.ts +2 -2
  209. package/dist/components/Select/components/index.js +1 -0
  210. package/dist/components/Select/index.d.ts +2 -2
  211. package/dist/components/Select/index.js +1 -0
  212. package/dist/components/Separator/components/Separator.d.ts +0 -1
  213. package/dist/components/Separator/components/Separator.js +11 -0
  214. package/dist/components/Separator/components/index.d.ts +2 -2
  215. package/dist/components/Separator/components/index.js +1 -0
  216. package/dist/components/Separator/index.d.ts +2 -2
  217. package/dist/components/Separator/index.js +1 -0
  218. package/dist/components/Skeleton/components/Skeleton.d.ts +0 -1
  219. package/dist/components/Skeleton/components/Skeleton.js +52 -0
  220. package/dist/components/Skeleton/components/index.d.ts +2 -2
  221. package/dist/components/Skeleton/components/index.js +1 -0
  222. package/dist/components/Skeleton/index.d.ts +2 -2
  223. package/dist/components/Skeleton/index.js +1 -0
  224. package/dist/components/Stat/components/Stat.d.ts +0 -1
  225. package/dist/components/Stat/components/Stat.js +42 -0
  226. package/dist/components/Stat/components/index.d.ts +2 -2
  227. package/dist/components/Stat/components/index.js +1 -0
  228. package/dist/components/Stat/index.d.ts +2 -2
  229. package/dist/components/Stat/index.js +1 -0
  230. package/dist/components/Switch/components/Switch.d.ts +0 -1
  231. package/dist/components/Switch/components/Switch.js +11 -0
  232. package/dist/components/Switch/components/index.d.ts +2 -2
  233. package/dist/components/Switch/components/index.js +1 -0
  234. package/dist/components/Switch/index.d.ts +2 -2
  235. package/dist/components/Switch/index.js +1 -0
  236. package/dist/components/Tabs/components/Tabs.d.ts +0 -1
  237. package/dist/components/Tabs/components/Tabs.js +54 -0
  238. package/dist/components/Tabs/components/index.d.ts +2 -2
  239. package/dist/components/Tabs/components/index.js +1 -0
  240. package/dist/components/Tabs/index.d.ts +2 -2
  241. package/dist/components/Tabs/index.js +1 -0
  242. package/dist/components/Tag/components/Tag.d.ts +0 -1
  243. package/dist/components/Tag/components/Tag.js +46 -0
  244. package/dist/components/Tag/components/TagGroup.js +15 -0
  245. package/dist/components/Tag/components/index.d.ts +4 -4
  246. package/dist/components/Tag/components/index.js +2 -0
  247. package/dist/components/Tag/index.d.ts +2 -2
  248. package/dist/components/Tag/index.js +1 -0
  249. package/dist/components/Terminal/components/Terminal.d.ts +0 -2
  250. package/dist/components/Terminal/components/Terminal.js +43 -0
  251. package/dist/components/Terminal/components/index.d.ts +2 -2
  252. package/dist/components/Terminal/components/index.js +1 -0
  253. package/dist/components/Terminal/index.d.ts +1 -1
  254. package/dist/components/Terminal/index.js +1 -0
  255. package/dist/components/TextScramble/components/TextScramble.d.ts +0 -1
  256. package/dist/components/TextScramble/components/TextScramble.js +14 -0
  257. package/dist/components/TextScramble/components/index.d.ts +2 -2
  258. package/dist/components/TextScramble/components/index.js +1 -0
  259. package/dist/components/TextScramble/index.d.ts +1 -1
  260. package/dist/components/TextScramble/index.js +1 -0
  261. package/dist/components/TimelineContainer/components/MasterDetailLayout.d.ts +1 -3
  262. package/dist/components/TimelineContainer/components/MasterDetailLayout.js +77 -0
  263. package/dist/components/TimelineContainer/components/TimelineAxis.d.ts +0 -1
  264. package/dist/components/TimelineContainer/components/TimelineAxis.js +8 -0
  265. package/dist/components/TimelineContainer/components/TimelineContainer.d.ts +1 -3
  266. package/dist/components/TimelineContainer/components/TimelineContainer.js +218 -0
  267. package/dist/components/TimelineContainer/components/TimelineContent.d.ts +1 -1
  268. package/dist/components/TimelineContainer/components/TimelineContent.js +23 -0
  269. package/dist/components/TimelineContainer/components/TimelineEntryCard.d.ts +1 -2
  270. package/dist/components/TimelineContainer/components/TimelineEntryCard.js +50 -0
  271. package/dist/components/TimelineContainer/components/ZoomControls.d.ts +2 -3
  272. package/dist/components/TimelineContainer/components/ZoomControls.js +16 -0
  273. package/dist/components/TimelineContainer/components/index.d.ts +5 -5
  274. package/dist/components/TimelineContainer/components/index.js +2 -0
  275. package/dist/components/TimelineContainer/components/timelineUtils.d.ts +1 -1
  276. package/dist/components/TimelineContainer/components/timelineUtils.js +185 -0
  277. package/dist/components/TimelineContainer/components/types.js +7 -0
  278. package/dist/components/TimelineContainer/components/useDrillDown.d.ts +1 -1
  279. package/dist/components/TimelineContainer/components/useDrillDown.js +83 -0
  280. package/dist/components/TimelineContainer/components/useSelection.js +51 -0
  281. package/dist/components/TimelineContainer/components/useZoom.d.ts +1 -1
  282. package/dist/components/TimelineContainer/components/useZoom.js +54 -0
  283. package/dist/components/TimelineContainer/components/variants/TimelineEntryCardGallery.d.ts +1 -2
  284. package/dist/components/TimelineContainer/components/variants/TimelineEntryCardGallery.js +67 -0
  285. package/dist/components/TimelineContainer/components/variants/TimelineEntryCardImage.d.ts +1 -2
  286. package/dist/components/TimelineContainer/components/variants/TimelineEntryCardImage.js +31 -0
  287. package/dist/components/TimelineContainer/components/views/DayView.d.ts +1 -1
  288. package/dist/components/TimelineContainer/components/views/DayView.js +20 -0
  289. package/dist/components/TimelineContainer/components/views/HourView.d.ts +1 -1
  290. package/dist/components/TimelineContainer/components/views/HourView.js +22 -0
  291. package/dist/components/TimelineContainer/components/views/MonthView.d.ts +1 -1
  292. package/dist/components/TimelineContainer/components/views/MonthView.js +18 -0
  293. package/dist/components/TimelineContainer/components/views/YearView.d.ts +1 -1
  294. package/dist/components/TimelineContainer/components/views/YearView.js +13 -0
  295. package/dist/components/TimelineContainer/components/views/index.d.ts +4 -4
  296. package/dist/components/TimelineContainer/components/views/index.js +4 -0
  297. package/dist/components/TimelineContainer/index.d.ts +3 -3
  298. package/dist/components/TimelineContainer/index.js +2 -0
  299. package/dist/components/TimelineNode/components/TimelineNode.d.ts +0 -1
  300. package/dist/components/TimelineNode/components/TimelineNode.js +49 -0
  301. package/dist/components/TimelineNode/components/index.d.ts +2 -2
  302. package/dist/components/TimelineNode/components/index.js +1 -0
  303. package/dist/components/TimelineNode/index.d.ts +2 -2
  304. package/dist/components/TimelineNode/index.js +1 -0
  305. package/dist/components/registry.js +247 -0
  306. package/dist/eidotter.css +1 -1
  307. package/dist/hooks/index.d.ts +4 -0
  308. package/dist/hooks/index.js +3 -0
  309. package/dist/hooks/useAnimatedDismiss.d.ts +15 -0
  310. package/dist/hooks/useAnimatedDismiss.js +29 -0
  311. package/dist/hooks/useTextScramble.d.ts +21 -0
  312. package/dist/hooks/useTextScramble.js +91 -0
  313. package/dist/hooks/useTextScramble.test.d.ts +1 -0
  314. package/dist/hooks/useThemePortal.d.ts +12 -0
  315. package/dist/hooks/useThemePortal.js +62 -0
  316. package/dist/hooks/useThemePortal.test.d.ts +1 -0
  317. package/dist/utils/cn.d.ts +9 -0
  318. package/dist/utils/cn.js +12 -0
  319. package/dist/utils/index.d.ts +2 -0
  320. package/dist/utils/index.js +2 -0
  321. package/dist/utils/isSafeHref.d.ts +1 -0
  322. package/dist/utils/isSafeHref.js +22 -0
  323. package/dist/utils/isSafeUrl.d.ts +8 -0
  324. package/dist/utils/isSafeUrl.js +18 -0
  325. package/dist/utils/isSafeUrl.test.d.ts +1 -0
  326. package/dist/utils/prefersReducedMotion.d.ts +5 -0
  327. package/dist/utils/prefersReducedMotion.js +8 -0
  328. package/package.json +9 -2
@@ -0,0 +1 @@
1
+ export { Progress } from './Progress.js';
@@ -1,2 +1,2 @@
1
- export { Progress } from './components';
2
- export type { ProgressProps } from './components';
1
+ export { Progress } from './components/index.js';
2
+ export type { ProgressProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { Progress } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './RetroEffects.css';
3
2
  export type PowerState = 'on' | 'powering-on' | 'powering-off' | 'off';
4
3
  export interface RetroEffectsProps {
5
4
  /**
@@ -0,0 +1,163 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from 'react';
4
+ import { cn } from '../../../utils/cn.js';
5
+ import { prefersReducedMotion } from '../../../utils/prefersReducedMotion.js';
6
+ const DEFAULT_BOOT_STORAGE_KEY = 'eidotter:retro-boot';
7
+ const BOOT_FLAG_VALUE = '1';
8
+ /** Read a sessionStorage flag, swallowing access errors (private mode, SSR). */
9
+ const hasBootedThisSession = (key) => {
10
+ if (typeof window === 'undefined')
11
+ return false;
12
+ try {
13
+ return window.sessionStorage.getItem(key) === BOOT_FLAG_VALUE;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ };
19
+ /** Record the sessionStorage flag, swallowing access errors. */
20
+ const markBootedThisSession = (key) => {
21
+ if (typeof window === 'undefined')
22
+ return;
23
+ try {
24
+ window.sessionStorage.setItem(key, BOOT_FLAG_VALUE);
25
+ }
26
+ catch {
27
+ /* storage unavailable — boot still plays, just won't be remembered */
28
+ }
29
+ };
30
+ /**
31
+ * CRT Monitor Effects component for authentic DOS terminal aesthetics
32
+ *
33
+ * Features:
34
+ * - Scanline overlay (horizontal lines)
35
+ * - Glow vignette (phosphor edge darkening)
36
+ * - Subtle CRT flicker animation (WCAG 2.3.1 compliant)
37
+ * - Phosphor bloom effect (opt-in)
38
+ * - Power on/off animations
39
+ * - Configurable intensity
40
+ * - Respects reduced motion preferences
41
+ */
42
+ export const RetroEffects = ({ scanlines = true, glow = true, flicker = true, bloom = false, powered = true, boot = false, bootOnce = false, bootStorageKey = DEFAULT_BOOT_STORAGE_KEY, intensity = 1, className, onPowerStateChange, onPowerOn, onPowerOff, onBootComplete, }) => {
43
+ const prevPoweredRef = useRef(powered);
44
+ const [powerState, setPowerState] = useState(powered ? 'on' : 'off');
45
+ // Non-gated boot keeps its on-mount behavior; the gated (bootOnce) path starts
46
+ // un-booted and is decided post-mount so SSR/first paint never render a stale
47
+ // overlay (no hydration mismatch on reload when the flag is already set).
48
+ // (Non-gated boot is intentionally NOT SSR-gated — it plays on every mount.)
49
+ const [booting, setBooting] = useState(boot && !bootOnce);
50
+ // Boot completes exactly once per mount. Guards against the StrictMode dev
51
+ // double-invoke of effects and the (theoretical) animationend + safety-timeout
52
+ // race both calling through twice.
53
+ const bootSignaledRef = useRef(false);
54
+ // Pin the storage key to its mount-time value. The read (decision effect) and
55
+ // the write (completeBoot, recreated each render) must use the SAME key, or a
56
+ // consumer passing a changing key would write a different key than was checked
57
+ // and the next visit would replay. This makes the "read once on mount" contract
58
+ // structural rather than documentation-only.
59
+ const bootStorageKeyRef = useRef(bootStorageKey);
60
+ // Keep the latest onBootComplete without re-running the mount-only effects that
61
+ // call it (adding it to their deps would re-trigger the boot decision).
62
+ const onBootCompleteRef = useRef(onBootComplete);
63
+ useEffect(() => {
64
+ onBootCompleteRef.current = onBootComplete;
65
+ });
66
+ // One-shot completion signal: settle the layer, remember the session, notify.
67
+ const signalBootComplete = () => {
68
+ if (bootSignaledRef.current)
69
+ return;
70
+ bootSignaledRef.current = true;
71
+ onBootCompleteRef.current?.();
72
+ };
73
+ // Settle the boot layer and signal completion. For the gated path the session
74
+ // flag is recorded HERE (on completion) rather than at the play decision, so a
75
+ // discarded StrictMode dev double-mount doesn't pre-set the flag and suppress
76
+ // the real boot. The flag is only "remembered" once a boot has actually run.
77
+ const completeBoot = () => {
78
+ setBooting(false);
79
+ if (bootOnce)
80
+ markBootedThisSession(bootStorageKeyRef.current);
81
+ signalBootComplete();
82
+ };
83
+ // Gated boot: decide once on mount whether this tab session has already booted.
84
+ useEffect(() => {
85
+ if (!boot || !bootOnce)
86
+ return;
87
+ if (hasBootedThisSession(bootStorageKeyRef.current)) {
88
+ // Already shown this session — skip, but still signal completion so
89
+ // consumers sequencing boot text off onBootComplete don't stall.
90
+ signalBootComplete();
91
+ return;
92
+ }
93
+ setBooting(true);
94
+ // Mount-only: gating is a first-load decision, not reactive to prop churn.
95
+ // eslint-disable-next-line react-hooks/exhaustive-deps
96
+ }, []);
97
+ // Boot settles via the glow's animationend; reduced-motion (where the boot
98
+ // layer is display:none and never animates) and any missed event settle via
99
+ // this effect instead.
100
+ useEffect(() => {
101
+ if (!booting)
102
+ return;
103
+ if (prefersReducedMotion()) {
104
+ completeBoot();
105
+ return;
106
+ }
107
+ const safety = window.setTimeout(() => {
108
+ completeBoot();
109
+ }, 1200);
110
+ return () => window.clearTimeout(safety);
111
+ // eslint-disable-next-line react-hooks/exhaustive-deps
112
+ }, [booting]);
113
+ const handleBootAnimationEnd = (event) => {
114
+ if (event.animationName !== 'eidotter-retro-boot-glow')
115
+ return;
116
+ completeBoot();
117
+ };
118
+ // Track power state transitions (intentional: animation state machine requires
119
+ // syncing prop changes to transitional states, settled by onAnimationEnd)
120
+ useEffect(() => {
121
+ const prevPowered = prevPoweredRef.current;
122
+ prevPoweredRef.current = powered;
123
+ if (prevPowered !== powered) {
124
+ const newState = powered ? 'powering-on' : 'powering-off';
125
+ setPowerState(newState);
126
+ onPowerStateChange?.(newState);
127
+ }
128
+ }, [powered, onPowerStateChange]);
129
+ // Settle power state after animation/transition completes
130
+ const settlePowerState = () => {
131
+ if (powerState === 'powering-on') {
132
+ setPowerState('on');
133
+ onPowerStateChange?.('on');
134
+ onPowerOn?.();
135
+ }
136
+ else if (powerState === 'powering-off') {
137
+ setPowerState('off');
138
+ onPowerStateChange?.('off');
139
+ onPowerOff?.();
140
+ }
141
+ };
142
+ // Handle animation end to settle into final state
143
+ const handleAnimationEnd = (event) => {
144
+ // Only respond to power animations, ignore any other animations
145
+ if (event.animationName !== 'retro-power-on' && event.animationName !== 'retro-power-off') {
146
+ return;
147
+ }
148
+ settlePowerState();
149
+ };
150
+ // Handle transition end for reduced-motion mode where CSS replaces
151
+ // animations with opacity transitions
152
+ const handleTransitionEnd = (event) => {
153
+ if (event.propertyName !== 'opacity')
154
+ return;
155
+ if (powerState !== 'powering-on' && powerState !== 'powering-off')
156
+ return;
157
+ settlePowerState();
158
+ };
159
+ const opacityStyle = { '--retro-intensity': intensity };
160
+ // Don't render children when fully off
161
+ const isVisible = powerState !== 'off';
162
+ return (_jsxs("div", { className: cn('fixed inset-0 pointer-events-none z-[9999]', 'eidotter-retro-effects', powerState === 'powering-off' && 'eidotter-retro-effects--powering-off', powerState === 'powering-on' && 'eidotter-retro-effects--powering-on', powerState === 'off' && 'eidotter-retro-effects--off', className), style: opacityStyle, "aria-hidden": "true", onAnimationEnd: handleAnimationEnd, onTransitionEnd: handleTransitionEnd, children: [isVisible && (_jsxs(_Fragment, { children: [scanlines && _jsx("div", { className: "eidotter-retro-effects__scanlines" }), glow && _jsx("div", { className: "eidotter-retro-effects__glow" }), flicker && _jsx("div", { className: "eidotter-retro-effects__flicker" }), bloom && _jsx("div", { className: "eidotter-retro-effects__bloom" })] })), booting && (_jsxs("div", { className: "eidotter-retro-effects__boot", onAnimationEnd: handleBootAnimationEnd, children: [_jsx("div", { className: "eidotter-retro-effects__boot-panel eidotter-retro-effects__boot-panel--top" }), _jsx("div", { className: "eidotter-retro-effects__boot-panel eidotter-retro-effects__boot-panel--bottom" }), _jsx("div", { className: "eidotter-retro-effects__boot-line" }), _jsx("div", { className: "eidotter-retro-effects__boot-glow" })] }))] }));
163
+ };
@@ -1,2 +1,2 @@
1
- export { RetroEffects } from './RetroEffects';
2
- export type { RetroEffectsProps, PowerState } from './RetroEffects';
1
+ export { RetroEffects } from './RetroEffects.js';
2
+ export type { RetroEffectsProps, PowerState } from './RetroEffects.js';
@@ -0,0 +1 @@
1
+ export { RetroEffects } from './RetroEffects.js';
@@ -1,2 +1,2 @@
1
- export { RetroEffects } from './components';
2
- export type { RetroEffectsProps, PowerState } from './components';
1
+ export { RetroEffects } from './components/index.js';
2
+ export type { RetroEffectsProps, PowerState } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { RetroEffects } from './components/index.js';
@@ -0,0 +1,18 @@
1
+ import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../../../utils/cn.js';
3
+ const toneClasses = {
4
+ default: 'text-dos-text-primary',
5
+ error: 'text-dos-error',
6
+ warning: 'text-dos-warning',
7
+ info: 'text-dos-info',
8
+ };
9
+ /**
10
+ * DOS-styled section heading — an uppercase `<h3>` label with an optional
11
+ * trailing `(count)` and tone-driven colour. Pure presentational.
12
+ *
13
+ * Ported from Steuerdash (DMNC-855); the steuerdash version hardcoded
14
+ * `text-cga-*` — this routes tones through `text-dos-*` semantic roles instead
15
+ * so the heading re-themes and stays AA-safe under amber-mono.
16
+ */
17
+ export const SectionHeading = ({ title, count, tone = 'default', children, className, }) => (_jsxs("h3", { className: cn('eidotter-section-heading', 'font-dos uppercase tracking-wider mb-2 text-dos-text-sm', toneClasses[tone], className), children: [title, count !== undefined && ` (${count})`, children] }));
18
+ SectionHeading.displayName = 'SectionHeading';
@@ -1,2 +1,2 @@
1
- export { SectionHeading } from './SectionHeading';
2
- export type { SectionHeadingProps } from './SectionHeading';
1
+ export { SectionHeading } from './SectionHeading.js';
2
+ export type { SectionHeadingProps } from './SectionHeading.js';
@@ -0,0 +1 @@
1
+ export { SectionHeading } from './SectionHeading.js';
@@ -1,2 +1,2 @@
1
- export { SectionHeading } from './components';
2
- export type { SectionHeadingProps } from './components';
1
+ export { SectionHeading } from './components/index.js';
2
+ export type { SectionHeadingProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { SectionHeading } from './components/index.js';
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { cn } from '../../../utils/cn.js';
4
+ /**
5
+ * DOS-styled select — MVP wrapper around a native `<select>` (DMNC-860).
6
+ * Ported from Steuerdash.
7
+ *
8
+ * Font-size is set via inline style, not a `text-dos-*` class: Tailwind v4's
9
+ * Preflight form reset (`select { font-size: 100% }`) outranks utility classes
10
+ * on a native `<select>`, so the inline style is the reliable escape hatch
11
+ * (token-driven). Upstream component fix tracked at eidotter#349.
12
+ */
13
+ export const Select = ({ value, options, onChange, id, disabled, className, 'aria-label': ariaLabel, }) => (_jsx("select", { id: id, "aria-label": ariaLabel, value: value, disabled: disabled, onChange: (e) => onChange(e.target.value), style: { fontSize: 'var(--typography-font-size-text-xs)' }, className: cn('eidotter-select', 'min-w-[5rem] cursor-pointer font-dos px-2 py-1', 'bg-dos-bg-secondary text-dos-text-primary border border-dos-border-default', 'hover:border-dos-text-accent focus:border-dos-text-accent focus:outline-none', 'disabled:cursor-not-allowed disabled:opacity-50', className), children: options.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) }));
14
+ Select.displayName = 'Select';
@@ -1,2 +1,2 @@
1
- export { Select } from './Select';
2
- export type { SelectProps, SelectOption } from './Select';
1
+ export { Select } from './Select.js';
2
+ export type { SelectProps, SelectOption } from './Select.js';
@@ -0,0 +1 @@
1
+ export { Select } from './Select.js';
@@ -1,2 +1,2 @@
1
- export { Select } from './components';
2
- export type { SelectProps, SelectOption } from './components';
1
+ export { Select } from './components/index.js';
2
+ export type { SelectProps, SelectOption } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { Select } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './Separator.css';
3
2
  export interface SeparatorProps {
4
3
  /** Orientation of the separator line */
5
4
  orientation?: 'horizontal' | 'vertical';
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from '../../../utils/cn.js';
3
+ const orientationClasses = {
4
+ horizontal: 'h-px w-full',
5
+ vertical: 'w-px h-full',
6
+ };
7
+ /**
8
+ * DOS-styled Separator component for visual division of content.
9
+ * Pure presentational — no React Aria needed.
10
+ */
11
+ export const Separator = ({ orientation = 'horizontal', className, }) => (_jsx("div", { role: "separator", "aria-orientation": orientation, className: cn('shrink-0 bg-dos-border-default', 'eidotter-separator', orientationClasses[orientation], className) }));
@@ -1,2 +1,2 @@
1
- export { Separator } from './Separator';
2
- export type { SeparatorProps } from './Separator';
1
+ export { Separator } from './Separator.js';
2
+ export type { SeparatorProps } from './Separator.js';
@@ -0,0 +1 @@
1
+ export { Separator } from './Separator.js';
@@ -1,2 +1,2 @@
1
- export { Separator } from './components';
2
- export type { SeparatorProps } from './components';
1
+ export { Separator } from './components/index.js';
2
+ export type { SeparatorProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { Separator } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './Skeleton.css';
3
2
  export type SkeletonVariant = 'text' | 'card' | 'figure' | 'timeline';
4
3
  export interface SkeletonProps {
5
4
  /** Placeholder shape */
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../../../utils/cn.js';
3
+ /**
4
+ * DOS/CGA loading placeholder. Instead of the modern smooth gray shimmer,
5
+ * placeholder lines are rows of shade characters (░ ▒ ▓) — character-cell
6
+ * by character-cell, like a screenful of unrendered text mode — with a CRT
7
+ * hum-bar glow band rolling top→bottom over them, phosphor-decay tail
8
+ * trailing upward, the way the refresh beat rolls down a CGA monitor.
9
+ *
10
+ * Purely presentational: render it while real content loads, then swap it
11
+ * out. The band is compositor-only (transform). Under
12
+ * `prefers-reduced-motion` it is replaced by a gentle opacity breathing;
13
+ * `prefers-contrast: high` disables all animation.
14
+ *
15
+ * Glyph rows are `aria-hidden`; the wrapper announces `label` via
16
+ * `role="status"`.
17
+ */
18
+ // Deterministic shade textures — stable across renders/SSR, clipped by the
19
+ // container so any width works. Light texture reads as pending body text;
20
+ // the dense one as a pending heading / media area.
21
+ const TEXTURE_LIGHT = '░░░░▒░░░░░░░▒░░░▒▒░░░░░░▒░░░░░░░▒░░░░▒░░';
22
+ const TEXTURE_DENSE = '▒▒▓▒▒▒▒▓▒▒▒▒▒▓▒▒▒▒▒▒▓▒▒▒▒▓▒▒▒▒▒▓▒▒▒▒▒▓▒';
23
+ const REPEAT = 6; // 240 cells — wider than any realistic container
24
+ const DEFAULT_LINES = {
25
+ text: 3,
26
+ card: 3,
27
+ figure: 4,
28
+ timeline: 2,
29
+ };
30
+ const Line = ({ dense = false, width = 'full' }) => (_jsx("span", { className: cn('eidotter-skeleton__line', width === 'short' && 'eidotter-skeleton__line--short', width === 'meta' && 'eidotter-skeleton__line--meta'), children: (dense ? TEXTURE_DENSE : TEXTURE_LIGHT).repeat(REPEAT) }));
31
+ function renderLines(count, dense = false, shortenLast = true) {
32
+ return Array.from({ length: count }, (_, i) => (_jsx(Line, { dense: dense, width: shortenLast && i === count - 1 && count > 1 ? 'short' : 'full' }, i)));
33
+ }
34
+ export const Skeleton = ({ variant = 'text', lines, animated = true, label = 'Loading', className, }) => {
35
+ const lineCount = Math.max(1, lines ?? DEFAULT_LINES[variant]);
36
+ let glyphs;
37
+ switch (variant) {
38
+ case 'card':
39
+ glyphs = (_jsxs(_Fragment, { children: [_jsx(Line, { dense: true, width: "meta" }), renderLines(lineCount)] }));
40
+ break;
41
+ case 'figure':
42
+ glyphs = renderLines(lineCount, true, false);
43
+ break;
44
+ case 'timeline':
45
+ glyphs = (_jsxs(_Fragment, { children: [_jsx("span", { className: "eidotter-skeleton__marker border-2 border-dos-border-default" }), _jsxs("span", { className: "eidotter-skeleton__entry", children: [_jsx(Line, { width: "meta" }), renderLines(lineCount)] })] }));
46
+ break;
47
+ default:
48
+ glyphs = renderLines(lineCount);
49
+ }
50
+ return (_jsx("div", { role: "status", "aria-label": label, className: cn('eidotter-skeleton font-dos text-dos-text-muted', `eidotter-skeleton--${variant}`, animated && 'eidotter-skeleton--animated', variant === 'card' && 'border-2 border-dos-border-default bg-dos-bg-secondary p-4', variant === 'figure' && 'border-2 border-dos-border-default bg-dos-bg-secondary', className), children: _jsx("div", { "aria-hidden": "true", className: "eidotter-skeleton__glyphs", children: glyphs }) }));
51
+ };
52
+ Skeleton.displayName = 'Skeleton';
@@ -1,2 +1,2 @@
1
- export { Skeleton } from './Skeleton';
2
- export type { SkeletonProps, SkeletonVariant } from './Skeleton';
1
+ export { Skeleton } from './Skeleton.js';
2
+ export type { SkeletonProps, SkeletonVariant } from './Skeleton.js';
@@ -0,0 +1 @@
1
+ export { Skeleton } from './Skeleton.js';
@@ -1,2 +1,2 @@
1
- export { Skeleton } from './components';
2
- export type { SkeletonProps, SkeletonVariant } from './components';
1
+ export { Skeleton } from './components/index.js';
2
+ export type { SkeletonProps, SkeletonVariant } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { Skeleton } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './Stat.css';
3
2
  export interface StatProps {
4
3
  /** The label describing the metric */
5
4
  label: string;
@@ -0,0 +1,42 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { useTextScramble } from '../../../hooks/useTextScramble.js';
5
+ import { cn } from '../../../utils/cn.js';
6
+ const sizeClasses = {
7
+ sm: { root: 'gap-0.5', label: 'text-dos-text-xs', value: 'text-dos-display-xs', trend: 'text-dos-text-xs' },
8
+ md: { root: 'gap-1', label: 'text-dos-text-sm', value: 'text-dos-display-sm', trend: 'text-dos-text-sm' },
9
+ lg: { root: 'gap-1.5', label: 'text-dos-text-md', value: 'text-dos-display-md', trend: 'text-dos-text-md' },
10
+ small: { root: 'gap-0.5', label: 'text-dos-text-xs', value: 'text-dos-display-xs', trend: 'text-dos-text-xs' },
11
+ medium: { root: 'gap-1', label: 'text-dos-text-sm', value: 'text-dos-display-sm', trend: 'text-dos-text-sm' },
12
+ large: { root: 'gap-1.5', label: 'text-dos-text-md', value: 'text-dos-display-md', trend: 'text-dos-text-md' },
13
+ };
14
+ const trendColorClasses = {
15
+ up: 'text-dos-text-success',
16
+ down: 'text-dos-text-error',
17
+ neutral: 'text-dos-text-brand',
18
+ };
19
+ const trendIcons = {
20
+ up: '▲',
21
+ down: '▼',
22
+ neutral: '►',
23
+ };
24
+ const trendLabels = {
25
+ up: 'increasing',
26
+ down: 'decreasing',
27
+ neutral: 'unchanged',
28
+ };
29
+ /**
30
+ * DOS-styled Stat component for displaying metrics with optional trends.
31
+ * Pure presentational — no React Aria needed.
32
+ */
33
+ export const Stat = forwardRef(({ label, value, trend, trendValue, size = 'md', scramble = false, className, ...props }, ref) => {
34
+ const { text: scrambledValue } = useTextScramble(String(value), {
35
+ speed: 30,
36
+ enabled: scramble,
37
+ });
38
+ const displayValue = scramble ? scrambledValue : String(value);
39
+ const s = sizeClasses[size] || sizeClasses.md;
40
+ return (_jsxs("div", { ref: ref, className: cn('flex flex-col font-dos', 'eidotter-stat', s.root, className), ...props, children: [_jsx("span", { className: cn('text-dos-text-brand uppercase tracking-wider leading-tight', s.label), children: label }), _jsx("span", { className: cn('text-dos-text-accent font-bold leading-none tabular-nums', s.value), children: displayValue }), trend && (_jsxs("span", { className: cn('inline-flex items-center gap-1 leading-none', trendColorClasses[trend], s.trend), "aria-label": `Trend: ${trendLabels[trend]}${trendValue ? `, ${trendValue}` : ''}`, children: [_jsx("span", { className: "text-[0.8em]", "aria-hidden": "true", children: trendIcons[trend] }), trendValue && (_jsx("span", { className: "tabular-nums", children: trendValue }))] }))] }));
41
+ });
42
+ Stat.displayName = 'Stat';
@@ -1,2 +1,2 @@
1
- export { Stat } from './Stat';
2
- export type { StatProps } from './Stat';
1
+ export { Stat } from './Stat.js';
2
+ export type { StatProps } from './Stat.js';
@@ -0,0 +1 @@
1
+ export { Stat } from './Stat.js';
@@ -1,2 +1,2 @@
1
- export { Stat } from './components';
2
- export type { StatProps } from './components';
1
+ export { Stat } from './components/index.js';
2
+ export type { StatProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { Stat } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './Switch.css';
3
2
  export interface SwitchProps {
4
3
  /** Whether the switch is on (controlled) */
5
4
  checked?: boolean;
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { Switch as AriaSwitch } from 'react-aria-components';
5
+ import { cn } from '../../../utils/cn.js';
6
+ /**
7
+ * DOS-styled Switch with phosphor glow toggle effect.
8
+ * Built on React Aria for accessible toggle behavior.
9
+ */
10
+ export const Switch = forwardRef(({ checked, defaultChecked = false, onChange, onCheckedChange, disabled = false, size = 'md', type = 'default', label, name, value, className, ...props }, ref) => (_jsx(AriaSwitch, { ref: ref, isSelected: checked, defaultSelected: defaultChecked, onChange: onChange ?? onCheckedChange, isDisabled: disabled, name: name, value: value, className: cn('inline-flex items-center gap-2 cursor-pointer outline-none font-dos group', 'eidotter-switch', disabled && 'opacity-50 cursor-not-allowed', className), "data-size": size, "data-type": type, ...props, children: ({ isSelected }) => (_jsxs(_Fragment, { children: [_jsx("span", { className: cn('eidotter-switch__track', isSelected && 'eidotter-switch__track--checked', type === 'slim' && 'eidotter-switch__track--slim', size === 'sm' && 'eidotter-switch__track--sm'), children: _jsx("span", { className: "eidotter-switch__thumb" }) }), label && _jsx("span", { className: "text-[var(--color-cga-amber)]", children: label })] })) })));
11
+ Switch.displayName = 'Switch';
@@ -1,2 +1,2 @@
1
- export { Switch } from './Switch';
2
- export type { SwitchProps } from './Switch';
1
+ export { Switch } from './Switch.js';
2
+ export type { SwitchProps } from './Switch.js';
@@ -0,0 +1 @@
1
+ export { Switch } from './Switch.js';
@@ -1,2 +1,2 @@
1
- export { Switch } from './components';
2
- export type { SwitchProps } from './components';
1
+ export { Switch } from './components/index.js';
2
+ export type { SwitchProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { Switch } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './Tabs.css';
3
2
  export interface TabItem {
4
3
  /** Unique identifier for the tab */
5
4
  id: string;
@@ -0,0 +1,54 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useRef, useLayoutEffect, useCallback, forwardRef } from 'react';
4
+ import { Tabs as AriaTabs, TabList as AriaTabList, Tab as AriaTab, TabPanel as AriaTabPanel, } from 'react-aria-components';
5
+ import { cn } from '../../../utils/cn.js';
6
+ const sizeClasses = {
7
+ sm: 'eidotter-tabs--sm',
8
+ md: 'eidotter-tabs--md',
9
+ lg: 'eidotter-tabs--lg',
10
+ small: 'eidotter-tabs--sm',
11
+ medium: 'eidotter-tabs--md',
12
+ large: 'eidotter-tabs--lg',
13
+ };
14
+ const variantClasses = {
15
+ underline: 'eidotter-tabs--underline',
16
+ pills: 'eidotter-tabs--pills',
17
+ };
18
+ /**
19
+ * DOS-styled Tabs with React Aria keyboard navigation and phosphor indicator.
20
+ * React Aria handles arrow keys, Home, End, roving tabindex, and ARIA roles.
21
+ */
22
+ export const Tabs = forwardRef(({ tabs, variant = 'underline', size = 'md', activeTab, defaultActiveTab, onSelectionChange, onTabChange, className, ...props }, ref) => {
23
+ const tabListRef = useRef(null);
24
+ const prevTabRef = useRef(activeTab ?? defaultActiveTab ?? tabs[0]?.id ?? '');
25
+ // Track current selection for indicator repositioning in uncontrolled mode
26
+ const [internalKey, setInternalKey] = useState(activeTab ?? defaultActiveTab ?? tabs[0]?.id ?? '');
27
+ const changeHandler = onSelectionChange ?? onTabChange;
28
+ const handleSelectionChange = useCallback((key) => {
29
+ const newId = String(key);
30
+ const previous = activeTab ?? prevTabRef.current;
31
+ prevTabRef.current = newId;
32
+ setInternalKey(newId);
33
+ changeHandler?.(newId, previous);
34
+ }, [activeTab, changeHandler]);
35
+ // Reposition the underline indicator when selection or variant changes
36
+ useLayoutEffect(() => {
37
+ const container = tabListRef.current;
38
+ if (!container || variant !== 'underline')
39
+ return;
40
+ const updateIndicator = () => {
41
+ const btn = container.querySelector('[aria-selected="true"]');
42
+ if (btn) {
43
+ container.style.setProperty('--indicator-left', `${btn.offsetLeft}px`);
44
+ container.style.setProperty('--indicator-width', `${btn.offsetWidth}px`);
45
+ }
46
+ };
47
+ updateIndicator();
48
+ const observer = new ResizeObserver(updateIndicator);
49
+ observer.observe(container);
50
+ return () => observer.disconnect();
51
+ }, [activeTab, internalKey, variant]);
52
+ return (_jsxs(AriaTabs, { ref: ref, selectedKey: activeTab, defaultSelectedKey: defaultActiveTab ?? tabs[0]?.id, onSelectionChange: handleSelectionChange, className: cn('eidotter-tabs', variantClasses[variant], sizeClasses[size] || sizeClasses.md, className), children: [_jsxs("div", { ref: tabListRef, className: "relative", children: [_jsx(AriaTabList, { className: "inline-flex items-center font-dos eidotter-tabs__list", "aria-label": props['aria-label'], children: tabs.map((tab) => (_jsx(AriaTab, { id: tab.id, isDisabled: tab.disabled, className: ({ isSelected, isDisabled }) => cn('eidotter-tabs__tab', isSelected && 'eidotter-tabs__tab--active', isDisabled && 'eidotter-tabs__tab--disabled'), children: tab.label }, tab.id))) }), variant === 'underline' && _jsx("span", { className: "eidotter-tabs__indicator", "aria-hidden": "true" })] }), tabs.map((tab) => (_jsx(AriaTabPanel, { id: tab.id, className: "hidden" }, tab.id)))] }));
53
+ });
54
+ Tabs.displayName = 'Tabs';
@@ -1,2 +1,2 @@
1
- export { Tabs } from './Tabs';
2
- export type { TabsProps, TabItem } from './Tabs';
1
+ export { Tabs } from './Tabs.js';
2
+ export type { TabsProps, TabItem } from './Tabs.js';
@@ -0,0 +1 @@
1
+ export { Tabs } from './Tabs.js';
@@ -1,2 +1,2 @@
1
- export { Tabs } from './components';
2
- export type { TabsProps, TabItem } from './components';
1
+ export { Tabs } from './components/index.js';
2
+ export type { TabsProps, TabItem } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { Tabs } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './Tag.css';
3
2
  export interface TagProps {
4
3
  /** Tag display text */
5
4
  children: React.ReactNode;