eidotter 0.36.1 → 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 (327) 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/hooks/index.d.ts +4 -0
  307. package/dist/hooks/index.js +3 -0
  308. package/dist/hooks/useAnimatedDismiss.d.ts +15 -0
  309. package/dist/hooks/useAnimatedDismiss.js +29 -0
  310. package/dist/hooks/useTextScramble.d.ts +21 -0
  311. package/dist/hooks/useTextScramble.js +91 -0
  312. package/dist/hooks/useTextScramble.test.d.ts +1 -0
  313. package/dist/hooks/useThemePortal.d.ts +12 -0
  314. package/dist/hooks/useThemePortal.js +62 -0
  315. package/dist/hooks/useThemePortal.test.d.ts +1 -0
  316. package/dist/utils/cn.d.ts +9 -0
  317. package/dist/utils/cn.js +12 -0
  318. package/dist/utils/index.d.ts +2 -0
  319. package/dist/utils/index.js +2 -0
  320. package/dist/utils/isSafeHref.d.ts +1 -0
  321. package/dist/utils/isSafeHref.js +22 -0
  322. package/dist/utils/isSafeUrl.d.ts +8 -0
  323. package/dist/utils/isSafeUrl.js +18 -0
  324. package/dist/utils/isSafeUrl.test.d.ts +1 -0
  325. package/dist/utils/prefersReducedMotion.d.ts +5 -0
  326. package/dist/utils/prefersReducedMotion.js +8 -0
  327. package/package.json +9 -2
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { cn } from '../../../utils/cn.js';
4
+ import { ChatHistory } from './ChatHistory.js';
5
+ import { ChatInput } from './ChatInput.js';
6
+ /**
7
+ * Complete DOS-themed chat interface composing ChatHistory and ChatInput.
8
+ *
9
+ * Designed to be placed inside a Terminal component for the full DOS window
10
+ * experience, but works standalone too.
11
+ *
12
+ * ```tsx
13
+ * <Terminal title="ADOS Chat">
14
+ * <ChatContainer messages={messages} onSend={send} isStreaming={loading} />
15
+ * </Terminal>
16
+ * ```
17
+ */
18
+ export const ChatContainer = ({ messages, onSend, isStreaming = false, inputPrompt, userPrefix, assistantPrefix, placeholder, disabled = false, className, ...props }) => {
19
+ return (_jsxs("div", { className: cn('flex flex-col h-full min-h-0', className), ...props, children: [_jsx(ChatHistory, { className: "flex-1 min-h-0", messages: messages, isStreaming: isStreaming, userPrefix: userPrefix, assistantPrefix: assistantPrefix }), _jsx(ChatInput, { className: "shrink-0", onSend: onSend, prompt: inputPrompt, placeholder: placeholder, disabled: disabled })] }));
20
+ };
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './ChatHistory.css';
3
2
  /** Data shape for a single chat message */
4
3
  export interface ChatMessageEntry {
5
4
  /** Unique message identifier */
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useRef, useEffect } from 'react';
4
+ import { cn } from '../../../utils/cn.js';
5
+ import { ChatMessage } from './ChatMessage.js';
6
+ /**
7
+ * Scrollable chat message history with auto-scroll and screen reader support.
8
+ *
9
+ * Uses `role="log"` for accessible announcement of new messages.
10
+ * Follows the data-driven list pattern (TimelineList precedent).
11
+ */
12
+ export const ChatHistory = ({ messages, isStreaming = false, userPrefix, assistantPrefix, className, ...props }) => {
13
+ const bottomRef = useRef(null);
14
+ useEffect(() => {
15
+ bottomRef.current?.scrollIntoView?.({ behavior: 'smooth' });
16
+ }, [messages.length, isStreaming]);
17
+ const classes = cn('flex-1 overflow-y-auto font-dos p-2 min-h-0', 'eidotter-chat-history', className);
18
+ if (messages.length === 0) {
19
+ return (_jsx("div", { className: classes, role: "log", "aria-live": "polite", tabIndex: 0, ...props, children: _jsx("div", { className: "flex items-center justify-center h-full min-h-16", children: _jsx("span", { className: "text-dos-text-muted font-dos text-dos-text-md", children: "Awaiting input..." }) }) }));
20
+ }
21
+ return (_jsx("div", { className: classes, role: "log", "aria-live": "polite", tabIndex: 0, ...props, children: _jsxs("div", { className: "flex flex-col", children: [messages.map((msg, index) => {
22
+ const isLastAssistant = isStreaming &&
23
+ msg.role === 'assistant' &&
24
+ index === messages.length - 1;
25
+ return (_jsx(ChatMessage, { role: msg.role, content: msg.content, isStreaming: isLastAssistant, userPrefix: userPrefix, assistantPrefix: assistantPrefix }, msg.id));
26
+ }), _jsx("div", { ref: bottomRef })] }) }));
27
+ };
@@ -1,6 +1,4 @@
1
1
  import React from 'react';
2
- import '../../../styles/keyframes.css';
3
- import './ChatInput.css';
4
2
  export interface ChatInputProps {
5
3
  /** Called when the user sends a message */
6
4
  onSend: (message: string) => void;
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useRef, useLayoutEffect } from 'react';
4
+ import { cn } from '../../../utils/cn.js';
5
+ /**
6
+ * DOS-styled multiline chat input with Enter-to-send and Shift+Enter for newlines.
7
+ *
8
+ * Auto-grows as the user types, up to a max height. Shows a blinking cursor
9
+ * when not focused.
10
+ */
11
+ export const ChatInput = ({ onSend, prompt = '>', placeholder, disabled = false, className, ...props }) => {
12
+ const [value, setValue] = useState('');
13
+ const textareaRef = useRef(null);
14
+ useLayoutEffect(() => {
15
+ const textarea = textareaRef.current;
16
+ if (!textarea)
17
+ return;
18
+ textarea.style.height = 'auto';
19
+ textarea.style.height = `${textarea.scrollHeight}px`;
20
+ }, [value]);
21
+ const handleKeyDown = (e) => {
22
+ if (e.key === 'Enter' && !e.shiftKey && !disabled) {
23
+ e.preventDefault();
24
+ const trimmed = value.trim();
25
+ if (trimmed) {
26
+ onSend(trimmed);
27
+ setValue('');
28
+ }
29
+ }
30
+ };
31
+ const handleContainerClick = () => {
32
+ if (!disabled && textareaRef.current) {
33
+ textareaRef.current.focus();
34
+ }
35
+ };
36
+ return (_jsxs("div", { className: cn('flex items-start font-dos text-dos-text-md p-2 cursor-text', 'text-dos-text-brand', 'eidotter-chat-input', disabled && 'eidotter-chat-input--disabled', className), onClick: handleContainerClick, ...props, children: [_jsx("span", { className: "text-dos-text-brand mr-2 mt-0.5 whitespace-nowrap select-none", "aria-hidden": "true", children: prompt }), _jsxs("div", { className: "flex items-start flex-1 min-w-0", children: [_jsx("textarea", { ref: textareaRef, className: "eidotter-chat-input__textarea", value: value, onChange: (e) => setValue(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1, "aria-label": "Chat input" }), _jsx("span", { className: "eidotter-chat-input__cursor", "aria-hidden": "true", children: "\u2588" })] })] }));
37
+ };
@@ -1,6 +1,4 @@
1
1
  import React from 'react';
2
- import '../../../styles/keyframes.css';
3
- import './ChatMessage.css';
4
2
  export interface ChatMessageProps {
5
3
  /** The role of the message sender */
6
4
  role: 'user' | 'assistant' | 'system';
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../../../utils/cn.js';
3
+ const roleClasses = {
4
+ user: 'eidotter-chat-message--user',
5
+ assistant: 'eidotter-chat-message--assistant',
6
+ system: 'eidotter-chat-message--system',
7
+ };
8
+ /**
9
+ * A single chat message rendered in DOS terminal style.
10
+ *
11
+ * User messages display with a `>` prefix, assistant messages with `C:\>`,
12
+ * and system messages appear dimmed. When `isStreaming` is true, a blinking
13
+ * block cursor appears after the content.
14
+ */
15
+ export const ChatMessage = ({ role, content, isStreaming = false, userPrefix = '>', assistantPrefix = 'C:\\>', className, ...props }) => {
16
+ const prefix = role === 'user' ? userPrefix : role === 'assistant' ? assistantPrefix : '';
17
+ return (_jsxs("div", { className: cn('flex gap-2 font-dos text-dos-text-md leading-[1.4] py-1 whitespace-pre-wrap break-words', roleClasses[role], isStreaming && 'eidotter-chat-message--streaming', className), ...props, children: [prefix && (_jsx("span", { className: "shrink-0 select-none", "aria-hidden": "true", children: prefix })), _jsx("span", { className: "min-w-0", children: content }), isStreaming && (_jsx("span", { className: "eidotter-chat-message__cursor", "aria-hidden": "true", children: "\u2588" }))] }));
18
+ };
@@ -1,8 +1,8 @@
1
- export { ChatMessage } from './ChatMessage';
2
- export type { ChatMessageProps } from './ChatMessage';
3
- export { ChatHistory } from './ChatHistory';
4
- export type { ChatHistoryProps, ChatMessageEntry } from './ChatHistory';
5
- export { ChatInput } from './ChatInput';
6
- export type { ChatInputProps } from './ChatInput';
7
- export { ChatContainer } from './ChatContainer';
8
- export type { ChatContainerProps } from './ChatContainer';
1
+ export { ChatMessage } from './ChatMessage.js';
2
+ export type { ChatMessageProps } from './ChatMessage.js';
3
+ export { ChatHistory } from './ChatHistory.js';
4
+ export type { ChatHistoryProps, ChatMessageEntry } from './ChatHistory.js';
5
+ export { ChatInput } from './ChatInput.js';
6
+ export type { ChatInputProps } from './ChatInput.js';
7
+ export { ChatContainer } from './ChatContainer.js';
8
+ export type { ChatContainerProps } from './ChatContainer.js';
@@ -0,0 +1,4 @@
1
+ export { ChatMessage } from './ChatMessage.js';
2
+ export { ChatHistory } from './ChatHistory.js';
3
+ export { ChatInput } from './ChatInput.js';
4
+ export { ChatContainer } from './ChatContainer.js';
@@ -1,2 +1,2 @@
1
- export { ChatMessage, ChatHistory, ChatInput, ChatContainer } from './components';
2
- export type { ChatMessageProps, ChatHistoryProps, ChatMessageEntry, ChatInputProps, ChatContainerProps, } from './components';
1
+ export { ChatMessage, ChatHistory, ChatInput, ChatContainer } from './components/index.js';
2
+ export type { ChatMessageProps, ChatHistoryProps, ChatMessageEntry, ChatInputProps, ChatContainerProps, } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { ChatMessage, ChatHistory, ChatInput, ChatContainer } from './components/index.js';
@@ -1,6 +1,4 @@
1
1
  import React from 'react';
2
- import '../../../styles/keyframes.css';
3
- import './Checkbox.css';
4
2
  export interface CheckboxProps {
5
3
  /** Whether the checkbox is checked (controlled) */
6
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 { Checkbox as AriaCheckbox } from 'react-aria-components';
5
+ import { cn } from '../../../utils/cn.js';
6
+ /**
7
+ * DOS-styled Checkbox with bracket text indicator [ ] / [X].
8
+ * Built on React Aria for accessible keyboard/focus handling.
9
+ */
10
+ export const Checkbox = forwardRef(({ checked, defaultChecked, onChange, indeterminate = false, label, disabled = false, size = 'md', name, value, className, 'aria-label': ariaLabel, ...props }, ref) => (_jsx(AriaCheckbox, { ref: ref, isSelected: checked, defaultSelected: defaultChecked, isIndeterminate: indeterminate, onChange: onChange, isDisabled: disabled, name: name, value: value, "aria-label": ariaLabel || label, className: cn('inline-flex items-center gap-2 cursor-pointer select-none group', 'font-dos', size === 'sm' ? 'text-dos-text-xs' : 'text-dos-text-sm', 'eidotter-checkbox', disabled && 'opacity-60 cursor-not-allowed', className), "data-size": size, ...props, children: ({ isSelected, isIndeterminate: isIndet }) => (_jsxs(_Fragment, { children: [_jsx("span", { className: cn('eidotter-checkbox__box', isSelected && 'eidotter-checkbox__box--checked', isIndet && 'eidotter-checkbox__box--indeterminate'), children: isIndet ? '[-]' : isSelected ? '[X]' : '[ ]' }), label && _jsx("span", { className: "eidotter-checkbox__label", children: label })] })) })));
11
+ Checkbox.displayName = 'Checkbox';
@@ -1,2 +1,2 @@
1
- export { Checkbox } from './Checkbox';
2
- export type { CheckboxProps } from './Checkbox';
1
+ export { Checkbox } from './Checkbox.js';
2
+ export type { CheckboxProps } from './Checkbox.js';
@@ -0,0 +1 @@
1
+ export { Checkbox } from './Checkbox.js';
@@ -1,2 +1,2 @@
1
- export { Checkbox } from './components';
2
- export type { CheckboxProps } from './components';
1
+ export { Checkbox } from './components/index.js';
2
+ export type { CheckboxProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { Checkbox } from './components/index.js';
@@ -0,0 +1,18 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { cn } from '../../../utils/cn.js';
4
+ const labelToneClasses = {
5
+ default: 'text-dos-text-primary',
6
+ muted: 'text-dos-text-muted line-through',
7
+ error: 'text-dos-error',
8
+ };
9
+ /**
10
+ * DOS-styled checklist row — a `[x]`/`[ ]` toggle plus label, optional note,
11
+ * and leading/trailing slots. Ported from Steuerdash (DMNC-856).
12
+ *
13
+ * The toggle is a real `<button>` (keyboard + screen-reader operable); the
14
+ * `[x]`/`[ ]` glyph is the DOS checkbox aesthetic. Tones and the note route
15
+ * through `text-dos-*` semantic roles (not raw `cga-*`) so the row re-themes.
16
+ */
17
+ export const ChecklistRow = ({ checked, onToggle, disabled, pending, ariaLabel, labelTone = 'default', label, children, note, leading, trailing, className, }) => (_jsxs("div", { className: cn('eidotter-checklist-row', 'flex items-start gap-3 py-2 border-b border-dos-border-disabled', pending && 'opacity-50', className), children: [_jsx("button", { type: "button", role: "checkbox", "aria-checked": checked, onClick: onToggle, disabled: disabled, "aria-label": ariaLabel ?? (checked ? 'Mark as incomplete' : 'Mark as complete'), className: cn('shrink-0 pt-0.5 font-dos text-dos-text-sm', 'text-dos-text-primary hover:text-dos-text-accent', 'cursor-pointer disabled:cursor-not-allowed'), children: checked ? '[x]' : '[ ]' }), _jsxs("div", { className: "flex-1 min-w-0", children: [leading && _jsx("div", { className: "mb-1", children: leading }), label !== undefined && (_jsx("div", { className: cn('font-dos text-dos-text-sm', labelToneClasses[labelTone]), children: label })), children, note && _jsx("p", { className: "font-dos text-dos-text-xs text-dos-text-muted mt-0.5", children: note })] }), trailing && _jsx("div", { className: "flex items-center gap-2 shrink-0", children: trailing })] }));
18
+ ChecklistRow.displayName = 'ChecklistRow';
@@ -1,2 +1,2 @@
1
- export { ChecklistRow } from './ChecklistRow';
2
- export type { ChecklistRowProps } from './ChecklistRow';
1
+ export { ChecklistRow } from './ChecklistRow.js';
2
+ export type { ChecklistRowProps } from './ChecklistRow.js';
@@ -0,0 +1 @@
1
+ export { ChecklistRow } from './ChecklistRow.js';
@@ -1,2 +1,2 @@
1
- export { ChecklistRow } from './components';
2
- export type { ChecklistRowProps } from './components';
1
+ export { ChecklistRow } from './components/index.js';
2
+ export type { ChecklistRowProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { ChecklistRow } from './components/index.js';
@@ -1,6 +1,4 @@
1
1
  import React from 'react';
2
- import '../../../styles/keyframes.css';
3
- import './CmdPalette.css';
4
2
  export interface CmdPaletteItem {
5
3
  /** Stable identifier for React keys and `onSelect` lookups. */
6
4
  id: string;
@@ -0,0 +1,169 @@
1
+ 'use client';
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useCallback, useEffect, useId, useMemo, useRef, useState, } from 'react';
4
+ import { ModalOverlay as AriaModalOverlay, Modal as AriaModal, Dialog as AriaDialog, } from 'react-aria-components';
5
+ import { cn } from '../../../utils/cn.js';
6
+ const defaultFooterHint = (_jsx(_Fragment, { children: "\u2191/\u2193 NAVIGATE \u00B7 \u21B5 OPEN \u00B7 ESC CLOSE" }));
7
+ /** Split hotkey string like "mod+shift+p" into a predicate. */
8
+ function parseHotkey(hotkey) {
9
+ const parts = hotkey.toLowerCase().split('+').map(p => p.trim());
10
+ const key = parts[parts.length - 1];
11
+ const mod = parts.includes('mod');
12
+ const shift = parts.includes('shift');
13
+ const alt = parts.includes('alt');
14
+ return (e) => {
15
+ if (e.key.toLowerCase() !== key)
16
+ return false;
17
+ const isMac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform);
18
+ const modMatches = mod ? (isMac ? e.metaKey : e.ctrlKey) : !(e.metaKey || e.ctrlKey);
19
+ if (!modMatches)
20
+ return false;
21
+ if (shift !== e.shiftKey)
22
+ return false;
23
+ if (alt !== e.altKey)
24
+ return false;
25
+ return true;
26
+ };
27
+ }
28
+ /** Rank items: starts-with on label/keyword ranks first, then substring. */
29
+ function scoreItem(item, query) {
30
+ if (!query)
31
+ return 0;
32
+ const q = query.toLowerCase();
33
+ const label = item.label.toLowerCase();
34
+ const kw = (item.keywords || []).map(k => k.toLowerCase());
35
+ if (label.startsWith(q))
36
+ return 100;
37
+ if (kw.some(k => k.startsWith(q)))
38
+ return 80;
39
+ if (label.includes(q))
40
+ return 50;
41
+ if (kw.some(k => k.includes(q)))
42
+ return 30;
43
+ if ((item.type || '').toLowerCase().includes(q))
44
+ return 10;
45
+ return -1;
46
+ }
47
+ /**
48
+ * CmdPalette — ⌘K / Ctrl+K launcher overlay.
49
+ *
50
+ * Controlled component. Parent owns `open` and item list; CmdPalette handles
51
+ * search, keyboard navigation, focus management, and hotkey binding.
52
+ *
53
+ * Built on React Aria `ModalOverlay` + `Modal` + `Dialog` — same primitives
54
+ * as `<Modal>` — so focus trap, Esc-to-close, and backdrop dismissal are
55
+ * standard.
56
+ */
57
+ export const CmdPalette = forwardRef(({ open, onOpenChange, items, placeholder = 'SEARCH · TYPE · ▸', hotkey = 'mod+k', emptyMessage = 'NO MATCHES', footerHint = defaultFooterHint, renderItem, maxResults = 20, className, 'aria-label': ariaLabel = 'Command palette', }, ref) => {
58
+ const baseId = useId();
59
+ const listboxId = `${baseId}-listbox`;
60
+ const [query, setQuery] = useState('');
61
+ const [selected, setSelected] = useState(0);
62
+ const inputRef = useRef(null);
63
+ const listRef = useRef(null);
64
+ // While a keyboard-driven scrollIntoView is flushing, ignore the mouseenter
65
+ // that fires on the item now under the cursor — otherwise arrow keys and
66
+ // a still cursor oscillate the selection.
67
+ const suppressHoverRef = useRef(false);
68
+ // Ranked, filtered results
69
+ const results = useMemo(() => {
70
+ if (!query.trim())
71
+ return items.slice(0, maxResults);
72
+ const scored = items
73
+ .map(i => ({ item: i, score: scoreItem(i, query.trim()) }))
74
+ .filter(s => s.score >= 0)
75
+ .sort((a, b) => b.score - a.score)
76
+ .slice(0, maxResults)
77
+ .map(s => s.item);
78
+ return scored;
79
+ }, [items, query, maxResults]);
80
+ // Reset state when opened
81
+ useEffect(() => {
82
+ if (open) {
83
+ setQuery('');
84
+ setSelected(0);
85
+ }
86
+ }, [open]);
87
+ // Reset selection when the query changes
88
+ useEffect(() => {
89
+ setSelected(0);
90
+ }, [query]);
91
+ // Clamp the selected index when the results list shrinks (e.g. parent mutates
92
+ // `items` while the palette is open). Prevents aria-activedescendant pointing
93
+ // at a non-existent id and Enter becoming a no-op until the user touches an
94
+ // arrow key.
95
+ useEffect(() => {
96
+ setSelected(s => Math.min(s, Math.max(0, results.length - 1)));
97
+ }, [results.length]);
98
+ // Focus input when open (React Aria handles focus trap; we steer to input)
99
+ useEffect(() => {
100
+ if (open) {
101
+ const id = window.setTimeout(() => inputRef.current?.focus(), 10);
102
+ return () => window.clearTimeout(id);
103
+ }
104
+ }, [open]);
105
+ // Keep latest open/onOpenChange accessible without rebinding the global listener.
106
+ // Parents commonly pass an inline onOpenChange, which would otherwise re-attach
107
+ // the keydown listener on every render.
108
+ const openRef = useRef(open);
109
+ const onOpenChangeRef = useRef(onOpenChange);
110
+ useEffect(() => { openRef.current = open; }, [open]);
111
+ useEffect(() => { onOpenChangeRef.current = onOpenChange; }, [onOpenChange]);
112
+ // Global hotkey — rebinds only when `hotkey` itself changes.
113
+ useEffect(() => {
114
+ if (hotkey === false)
115
+ return;
116
+ const predicate = parseHotkey(hotkey);
117
+ const handler = (e) => {
118
+ if (predicate(e)) {
119
+ e.preventDefault();
120
+ onOpenChangeRef.current(!openRef.current);
121
+ }
122
+ };
123
+ window.addEventListener('keydown', handler);
124
+ return () => window.removeEventListener('keydown', handler);
125
+ }, [hotkey]);
126
+ // Keep the selected row scrolled into view
127
+ useEffect(() => {
128
+ if (!open || results.length === 0)
129
+ return;
130
+ const el = listRef.current?.querySelector(`[data-index="${selected}"]`);
131
+ // jsdom doesn't implement scrollIntoView — guard so tests don't throw.
132
+ if (el && typeof el.scrollIntoView === 'function') {
133
+ suppressHoverRef.current = true;
134
+ el.scrollIntoView({ block: 'nearest' });
135
+ const id = window.setTimeout(() => { suppressHoverRef.current = false; }, 0);
136
+ return () => window.clearTimeout(id);
137
+ }
138
+ }, [selected, results, open]);
139
+ const handleSelect = useCallback((item) => {
140
+ item.onSelect?.(item);
141
+ onOpenChange(false);
142
+ }, [onOpenChange]);
143
+ const handleKeyDown = (e) => {
144
+ if (e.key === 'ArrowDown') {
145
+ e.preventDefault();
146
+ setSelected(i => Math.min(i + 1, Math.max(0, results.length - 1)));
147
+ }
148
+ else if (e.key === 'ArrowUp') {
149
+ e.preventDefault();
150
+ setSelected(i => Math.max(0, i - 1));
151
+ }
152
+ else if (e.key === 'Enter') {
153
+ const item = results[selected];
154
+ if (item) {
155
+ e.preventDefault();
156
+ handleSelect(item);
157
+ }
158
+ }
159
+ };
160
+ return (_jsx(AriaModalOverlay, { isOpen: open, onOpenChange: onOpenChange, isDismissable: true, className: ({ isEntering, isExiting }) => cn('eidotter-cmdpal-overlay', isEntering && 'eidotter-cmdpal-overlay--entering', isExiting && 'eidotter-cmdpal-overlay--exiting'), children: _jsx(AriaModal, { className: ({ isEntering, isExiting }) => cn('eidotter-cmdpal', isEntering && 'eidotter-cmdpal--entering', isExiting && 'eidotter-cmdpal--exiting'), children: _jsxs(AriaDialog, { "aria-label": ariaLabel, className: cn('eidotter-cmdpal__container outline-none', className), ref: ref, children: [_jsxs("div", { className: "eidotter-cmdpal__head", "aria-hidden": "true", children: [_jsx("span", { children: "\u25B8 JUMP TO" }), _jsx("span", { className: "eidotter-cmdpal__blink", children: "_" })] }), _jsx("input", { ref: inputRef, type: "text", role: "combobox", "aria-controls": listboxId, "aria-expanded": true, "aria-autocomplete": "list", "aria-activedescendant": results[selected] ? `${baseId}-item-${results[selected].id}` : undefined, className: "eidotter-cmdpal__input", value: query, placeholder: placeholder, onChange: e => setQuery(e.target.value), onKeyDown: handleKeyDown }), _jsxs("ul", { ref: listRef, id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "eidotter-cmdpal__results", children: [results.length === 0 && (_jsx("li", { className: "eidotter-cmdpal__empty", role: "presentation", children: emptyMessage })), results.map((item, i) => {
161
+ const isSelected = i === selected;
162
+ return (_jsx("li", { id: `${baseId}-item-${item.id}`, role: "option", "aria-selected": isSelected, "data-index": i, className: cn('eidotter-cmdpal__item', isSelected && 'eidotter-cmdpal__item--selected'), onMouseMove: () => {
163
+ if (suppressHoverRef.current)
164
+ return;
165
+ setSelected(i);
166
+ }, onClick: () => handleSelect(item), children: renderItem ? renderItem(item, isSelected) : (_jsxs(_Fragment, { children: [_jsxs("span", { className: "eidotter-cmdpal__item-label", children: [_jsx("span", { className: "eidotter-cmdpal__item-caret", "aria-hidden": "true", children: isSelected ? '▸' : ' ' }), item.label] }), item.hint !== undefined && (_jsx("span", { className: "eidotter-cmdpal__item-hint", children: item.hint }))] })) }, item.id));
167
+ })] }), footerHint && (_jsx("div", { className: "eidotter-cmdpal__footer", "aria-hidden": "true", children: footerHint }))] }) }) }));
168
+ });
169
+ CmdPalette.displayName = 'CmdPalette';
@@ -1,2 +1,2 @@
1
- export { CmdPalette } from './CmdPalette';
2
- export type { CmdPaletteProps, CmdPaletteItem } from './CmdPalette';
1
+ export { CmdPalette } from './CmdPalette.js';
2
+ export type { CmdPaletteProps, CmdPaletteItem } from './CmdPalette.js';
@@ -0,0 +1 @@
1
+ export { CmdPalette } from './CmdPalette.js';
@@ -1,2 +1,2 @@
1
- export { CmdPalette } from './components';
2
- export type { CmdPaletteProps, CmdPaletteItem } from './components';
1
+ export { CmdPalette } from './components/index.js';
2
+ export type { CmdPaletteProps, CmdPaletteItem } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { CmdPalette } from './components/index.js';
@@ -1,6 +1,4 @@
1
1
  import React from 'react';
2
- import '../../../styles/keyframes.css';
3
- import './CommandPrompt.css';
4
2
  export interface CommandPromptProps {
5
3
  /**
6
4
  * The prompt string displayed before cursor
@@ -0,0 +1,34 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useRef, useEffect } from 'react';
4
+ /**
5
+ * DOS-styled CommandPrompt component with authentic terminal aesthetics
6
+ *
7
+ * Features:
8
+ * - Configurable prompt string (e.g., "C:\>", "$")
9
+ * - Enter key triggers onCommand callback
10
+ * - Blinking cursor for DOS feel
11
+ * - Auto-focus support
12
+ * - WCAG 2.1 AA compliant
13
+ */
14
+ export const CommandPrompt = ({ prompt = 'C:\\>', onCommand, autoFocus = false, className = '', placeholder, disabled = false, }) => {
15
+ const [value, setValue] = useState('');
16
+ const inputRef = useRef(null);
17
+ useEffect(() => {
18
+ if (autoFocus && inputRef.current) {
19
+ inputRef.current.focus();
20
+ }
21
+ }, [autoFocus]);
22
+ const handleKeyDown = (e) => {
23
+ if (e.key === 'Enter' && value.trim() && !disabled) {
24
+ onCommand(value.trim());
25
+ setValue('');
26
+ }
27
+ };
28
+ const handleContainerClick = () => {
29
+ if (!disabled && inputRef.current) {
30
+ inputRef.current.focus();
31
+ }
32
+ };
33
+ return (_jsxs("div", { className: `command-prompt ${disabled ? 'command-prompt--disabled' : ''} ${className}`.trim(), onClick: handleContainerClick, children: [_jsx("span", { className: "command-prompt__prompt", "aria-hidden": "true", children: prompt }), _jsxs("div", { className: "command-prompt__input-wrapper", children: [_jsx("input", { ref: inputRef, className: "command-prompt__input", value: value, onChange: (e) => setValue(e.target.value), onKeyDown: handleKeyDown, autoFocus: autoFocus, spellCheck: false, autoComplete: "off", autoCapitalize: "off", autoCorrect: "off", placeholder: placeholder, disabled: disabled, "aria-label": "Command input", size: value.length || 1 }), _jsx("span", { className: "command-prompt__cursor", "aria-hidden": "true", children: "\u2588" })] })] }));
34
+ };
@@ -1,2 +1,2 @@
1
- export { CommandPrompt } from './CommandPrompt';
2
- export type { CommandPromptProps } from './CommandPrompt';
1
+ export { CommandPrompt } from './CommandPrompt.js';
2
+ export type { CommandPromptProps } from './CommandPrompt.js';
@@ -0,0 +1 @@
1
+ export { CommandPrompt } from './CommandPrompt.js';
@@ -1 +1 @@
1
- export * from './components';
1
+ export * from './components/index.js';
@@ -0,0 +1 @@
1
+ export * from './components/index.js';
@@ -0,0 +1,50 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useCallback, useRef, useState } from 'react';
4
+ import { cn } from '../../../utils/cn.js';
5
+ /**
6
+ * DOS-styled copy-to-clipboard button — shows `[cp]`, flips to `[OK]` for ~1.5s
7
+ * after a successful copy. Uses the async Clipboard API with a `execCommand`
8
+ * fallback. Ported from Steuerdash (DMNC-858); English default labels (was
9
+ * German) and `text-dos-link` semantic roles.
10
+ */
11
+ export const CopyButton = ({ value, label = '[cp]', copiedLabel = '[OK]', title = 'Copy to clipboard', copiedTitle = 'Copied!', className, }) => {
12
+ const [copied, setCopied] = useState(false);
13
+ const timerRef = useRef(null);
14
+ const markCopied = useCallback(() => {
15
+ setCopied(true);
16
+ if (timerRef.current)
17
+ clearTimeout(timerRef.current);
18
+ timerRef.current = setTimeout(() => setCopied(false), 1500);
19
+ }, []);
20
+ const fallbackCopy = useCallback(() => {
21
+ const ta = document.createElement('textarea');
22
+ ta.value = value;
23
+ ta.style.position = 'fixed';
24
+ ta.style.opacity = '0';
25
+ document.body.appendChild(ta);
26
+ ta.select();
27
+ try {
28
+ const ok = document.execCommand('copy');
29
+ ta.remove();
30
+ return ok;
31
+ }
32
+ catch {
33
+ ta.remove();
34
+ return false;
35
+ }
36
+ }, [value]);
37
+ const copy = useCallback(() => {
38
+ if (navigator.clipboard?.writeText) {
39
+ navigator.clipboard.writeText(value).then(markCopied).catch(() => {
40
+ if (fallbackCopy())
41
+ markCopied();
42
+ });
43
+ }
44
+ else if (fallbackCopy()) {
45
+ markCopied();
46
+ }
47
+ }, [value, markCopied, fallbackCopy]);
48
+ return (_jsx("button", { type: "button", onClick: copy, title: copied ? copiedTitle : title, "aria-label": copied ? copiedTitle : title, className: cn('eidotter-copy-button', 'font-dos text-dos-text-xs px-1', 'text-dos-link hover:text-dos-link-hover cursor-pointer', className), children: copied ? copiedLabel : label }));
49
+ };
50
+ CopyButton.displayName = 'CopyButton';
@@ -1,2 +1,2 @@
1
- export { CopyButton } from './CopyButton';
2
- export type { CopyButtonProps } from './CopyButton';
1
+ export { CopyButton } from './CopyButton.js';
2
+ export type { CopyButtonProps } from './CopyButton.js';
@@ -0,0 +1 @@
1
+ export { CopyButton } from './CopyButton.js';
@@ -1,2 +1,2 @@
1
- export { CopyButton } from './components';
2
- export type { CopyButtonProps } from './components';
1
+ export { CopyButton } from './components/index.js';
2
+ export type { CopyButtonProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { CopyButton } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './DosFigure.css';
3
2
  export interface DosFigurePin {
4
3
  /** Horizontal position as a percentage (0–100). */
5
4
  x: number;
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useId } from 'react';
4
+ import { cn } from '../../../utils/cn.js';
5
+ /**
6
+ * DosFigure — demoscene-style placeholder for media.
7
+ *
8
+ * Sierra / LucasArts / demoscene title cards painted the screen with a
9
+ * limited palette, dithering, and annotated frames. DosFigure recreates
10
+ * that aesthetic: amber chrome, scanline sweep, optional pins, and a
11
+ * resolution tag. Use as a lead-in for blog articles or as a placeholder
12
+ * where a photograph would otherwise go.
13
+ *
14
+ * Not intended as a replacement for semantic imagery — pass `aria-label`
15
+ * (or a `<figcaption>` via `caption`) so the figure is meaningful to AT.
16
+ */
17
+ export const DosFigure = forwardRef(({ title, resolution, subject, caption, pins = [], animated = true, 'aria-label': ariaLabel, className, }, ref) => {
18
+ const captionId = useId();
19
+ const describedById = caption ? captionId : undefined;
20
+ return (_jsxs("figure", { ref: ref, className: cn('eidotter-dos-figure', animated && 'eidotter-dos-figure--animated', className), role: "img", "aria-label": ariaLabel, "aria-describedby": describedById, children: [title && (_jsx("div", { className: "eidotter-dos-figure__title", "aria-hidden": "true", children: _jsx("span", { children: title }) })), _jsxs("div", { className: "eidotter-dos-figure__frame", children: [_jsx("div", { className: "eidotter-dos-figure__subject", children: subject }), pins.length > 0 && (_jsx("ul", { className: "eidotter-dos-figure__pins", role: "list", children: pins.map((pin, idx) => {
21
+ const x = Number.isFinite(pin.x) ? Math.max(0, Math.min(100, pin.x)) : 0;
22
+ const y = Number.isFinite(pin.y) ? Math.max(0, Math.min(100, pin.y)) : 0;
23
+ return (_jsxs("li", { className: "eidotter-dos-figure__pin", style: { left: `${x}%`, top: `${y}%` }, children: [_jsx("span", { className: "eidotter-dos-figure__pin-dot", "aria-hidden": "true" }), _jsx("span", { className: "eidotter-dos-figure__pin-label", children: pin.label })] }, `${x}-${y}-${idx}`));
24
+ }) })), _jsx("span", { className: "eidotter-dos-figure__scanline", "aria-hidden": "true" }), resolution && (_jsx("span", { className: "eidotter-dos-figure__resolution", "aria-hidden": "true", children: resolution }))] }), caption && (_jsx("figcaption", { id: captionId, className: "eidotter-dos-figure__caption", children: caption }))] }));
25
+ });
26
+ DosFigure.displayName = 'DosFigure';
@@ -1,2 +1,2 @@
1
- export { DosFigure } from './DosFigure';
2
- export type { DosFigureProps, DosFigurePin } from './DosFigure';
1
+ export { DosFigure } from './DosFigure.js';
2
+ export type { DosFigureProps, DosFigurePin } from './DosFigure.js';
@@ -0,0 +1 @@
1
+ export { DosFigure } from './DosFigure.js';