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
@@ -1,2 +1,2 @@
1
- export { DosFigure } from './components';
2
- export type { DosFigureProps, DosFigurePin } from './components';
1
+ export { DosFigure } from './components/index.js';
2
+ export type { DosFigureProps, DosFigurePin } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { DosFigure } from './components/index.js';
@@ -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 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 empty / zero-state — a centred title, optional description, and an
11
+ * optional action slot. Pure presentational.
12
+ *
13
+ * Ported from Steuerdash (DMNC-859); tones and the description route through
14
+ * `text-dos-*` semantic roles (not raw `cga-*`) so it re-themes and the
15
+ * description stays AA-safe (`text-muted` → lightGray under amber-mono).
16
+ */
17
+ export const EmptyState = ({ title, description, tone = 'default', action, className, }) => (_jsxs("div", { className: cn('eidotter-empty-state', 'flex flex-col gap-2 py-6 text-center', className), role: "status", children: [_jsx("p", { className: cn('font-dos text-dos-text-sm', toneClasses[tone]), children: title }), description && (_jsx("p", { className: "font-dos text-dos-text-xs text-dos-text-muted", children: description })), action && _jsx("div", { className: "mt-2", children: action })] }));
18
+ EmptyState.displayName = 'EmptyState';
@@ -1,2 +1,2 @@
1
- export { EmptyState } from './EmptyState';
2
- export type { EmptyStateProps } from './EmptyState';
1
+ export { EmptyState } from './EmptyState.js';
2
+ export type { EmptyStateProps } from './EmptyState.js';
@@ -0,0 +1 @@
1
+ export { EmptyState } from './EmptyState.js';
@@ -1,2 +1,2 @@
1
- export { EmptyState } from './components';
2
- export type { EmptyStateProps } from './components';
1
+ export { EmptyState } from './components/index.js';
2
+ export type { EmptyStateProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { EmptyState } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './FilterBar.css';
3
2
  export interface FilterBarItem {
4
3
  /** Unique identifier for the filter */
5
4
  id: string;
@@ -0,0 +1,120 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useCallback, useRef } from 'react';
4
+ import { Button as AriaButton } from 'react-aria-components';
5
+ import { cn } from '../../../utils/cn.js';
6
+ /**
7
+ * DOS-styled FilterBar component for multi-select or single-select content filtering
8
+ *
9
+ * Features:
10
+ * - Multi-select (default) or single-select mode
11
+ * - Optional count badges on each filter item
12
+ * - Optional "All" toggle that selects/deselects everything
13
+ * - Full keyboard navigation (Arrow keys, Space, Enter, Home, End)
14
+ * - Controlled and uncontrolled modes
15
+ * - DOS-authentic styling with CGA colors
16
+ * - WCAG 2.1 AA compliant
17
+ * - prefers-reduced-motion support
18
+ * - prefers-contrast: high support
19
+ */
20
+ const sizeClasses = {
21
+ sm: 'eidotter-filter-bar--sm',
22
+ md: 'eidotter-filter-bar--md',
23
+ lg: 'eidotter-filter-bar--lg',
24
+ small: 'eidotter-filter-bar--sm',
25
+ medium: 'eidotter-filter-bar--md',
26
+ large: 'eidotter-filter-bar--lg',
27
+ };
28
+ /**
29
+ * DOS-styled FilterBar for multi-select or single-select content filtering.
30
+ * Pure presentational — uses CSS transitions for phosphor effects.
31
+ */
32
+ export const FilterBar = ({ items, activeIds, defaultActiveIds = [], mode = 'multi', showAll = false, allLabel = 'All', size = 'md', onChange, className, ...props }) => {
33
+ const [internalActiveIds, setInternalActiveIds] = useState(defaultActiveIds);
34
+ const toolbarRef = useRef(null);
35
+ const isControlled = activeIds !== undefined;
36
+ const currentActiveIds = isControlled ? activeIds : internalActiveIds;
37
+ // All non-disabled item IDs
38
+ const enabledItemIds = items.filter(item => !item.disabled).map(item => item.id);
39
+ // Whether "All" is logically active (no specific filters selected)
40
+ const isAllActive = currentActiveIds.length === 0;
41
+ const updateSelection = useCallback((newIds) => {
42
+ if (!isControlled) {
43
+ setInternalActiveIds(newIds);
44
+ }
45
+ onChange?.(newIds);
46
+ }, [isControlled, onChange]);
47
+ const handleItemToggle = useCallback((itemId) => {
48
+ if (mode === 'single') {
49
+ // In single mode, toggle the item or deselect it
50
+ const newIds = currentActiveIds.includes(itemId) ? [] : [itemId];
51
+ updateSelection(newIds);
52
+ }
53
+ else {
54
+ // In multi mode, toggle the item on/off
55
+ const newIds = currentActiveIds.includes(itemId)
56
+ ? currentActiveIds.filter(id => id !== itemId)
57
+ : [...currentActiveIds, itemId];
58
+ updateSelection(newIds);
59
+ }
60
+ }, [mode, currentActiveIds, updateSelection]);
61
+ const handleAllToggle = useCallback(() => {
62
+ // Selecting "All" clears all individual selections
63
+ updateSelection([]);
64
+ }, [updateSelection]);
65
+ // Build the list of all focusable button refs: [All?, ...items]
66
+ const getButtons = useCallback(() => {
67
+ if (!toolbarRef.current)
68
+ return [];
69
+ return Array.from(toolbarRef.current.querySelectorAll('button:not([disabled])'));
70
+ }, []);
71
+ const handleKeyDown = useCallback((event) => {
72
+ const buttons = getButtons();
73
+ const currentIndex = buttons.indexOf(event.target);
74
+ if (currentIndex === -1)
75
+ return;
76
+ let newIndex = null;
77
+ switch (event.key) {
78
+ case 'ArrowLeft':
79
+ case 'ArrowUp':
80
+ event.preventDefault();
81
+ newIndex = currentIndex > 0 ? currentIndex - 1 : buttons.length - 1;
82
+ break;
83
+ case 'ArrowRight':
84
+ case 'ArrowDown':
85
+ event.preventDefault();
86
+ newIndex = currentIndex < buttons.length - 1 ? currentIndex + 1 : 0;
87
+ break;
88
+ case 'Home':
89
+ event.preventDefault();
90
+ newIndex = 0;
91
+ break;
92
+ case 'End':
93
+ event.preventDefault();
94
+ newIndex = buttons.length - 1;
95
+ break;
96
+ }
97
+ if (newIndex !== null) {
98
+ buttons[newIndex].focus();
99
+ }
100
+ }, [getButtons]);
101
+ // Determine the currently focused index for roving tabindex
102
+ // The first active item gets tabIndex 0, or the All button, or the first enabled item
103
+ const getFocusableId = () => {
104
+ if (showAll && isAllActive)
105
+ return '__all__';
106
+ if (currentActiveIds.length > 0)
107
+ return currentActiveIds[0];
108
+ if (showAll)
109
+ return '__all__';
110
+ return enabledItemIds[0] || null;
111
+ };
112
+ const focusableId = getFocusableId();
113
+ return (_jsxs("div", { ref: toolbarRef, className: cn('inline-flex flex-wrap items-center gap-1 p-1 font-dos max-w-full', 'bg-dos-bg-secondary border border-dos-border-default rounded-dos-sm', 'eidotter-filter-bar', sizeClasses[size] || sizeClasses.md, className), role: "toolbar", onKeyDown: handleKeyDown, ...props, children: [showAll && (_jsx(AriaButton, { className: cn('eidotter-filter-bar__item', 'eidotter-filter-bar__item--all', isAllActive && 'eidotter-filter-bar__item--active'), "aria-pressed": isAllActive, excludeFromTabOrder: focusableId !== '__all__', onPress: handleAllToggle, children: _jsx("span", { className: "eidotter-filter-bar__label", children: allLabel }) })), items.map((item) => {
114
+ const isActive = currentActiveIds.includes(item.id);
115
+ const style = isActive && item.color
116
+ ? { '--filter-bar-item-color': `var(${item.color})` }
117
+ : undefined;
118
+ return (_jsxs(AriaButton, { className: cn('eidotter-filter-bar__item', isActive && 'eidotter-filter-bar__item--active', item.disabled && 'eidotter-filter-bar__item--disabled'), "aria-pressed": isActive, excludeFromTabOrder: focusableId !== item.id, isDisabled: item.disabled, onPress: () => handleItemToggle(item.id), style: style, children: [_jsx("span", { className: "eidotter-filter-bar__label", children: item.label }), item.count !== undefined && (_jsx("span", { className: "eidotter-filter-bar__count", "aria-label": `${item.count} items`, children: item.count }))] }, item.id));
119
+ })] }));
120
+ };
@@ -1,2 +1,2 @@
1
- export { FilterBar } from './FilterBar';
2
- export type { FilterBarProps, FilterBarItem } from './FilterBar';
1
+ export { FilterBar } from './FilterBar.js';
2
+ export type { FilterBarProps, FilterBarItem } from './FilterBar.js';
@@ -0,0 +1 @@
1
+ export { FilterBar } from './FilterBar.js';
@@ -1,2 +1,2 @@
1
- export { FilterBar } from './components';
2
- export type { FilterBarProps, FilterBarItem } from './components';
1
+ export { FilterBar } from './components/index.js';
2
+ export type { FilterBarProps, FilterBarItem } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { FilterBar } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './Footer.css';
3
2
  export interface FooterLink {
4
3
  /** Display text for the link */
5
4
  label: string;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { cn } from '../../../utils/cn.js';
4
+ /** Default legal links for German compliance (DDG § 5 / GDPR) */
5
+ export const defaultLegalLinks = [
6
+ { label: 'Impressum', href: '/impressum' },
7
+ { label: 'Datenschutz', href: '/datenschutz' },
8
+ ];
9
+ /**
10
+ * DOS-themed footer with copyright and configurable legal/nav links.
11
+ * Pure presentational — uses middle-dot separators for terminal aesthetic.
12
+ */
13
+ export const Footer = ({ copyright, links, linkComponent, children, className, ...props }) => {
14
+ const resolvedLinks = links ?? defaultLegalLinks;
15
+ const LinkTag = linkComponent ?? 'a';
16
+ const linkClassName = 'eidotter-footer__link text-dos-text-brand no-underline';
17
+ return (_jsxs("footer", { className: cn('font-dos text-sm py-4 px-2 text-center', 'eidotter-footer', className), ...props, children: [_jsx("div", { className: "h-px bg-dos-border-default mb-4", role: "separator" }), children && _jsx("div", { className: "mb-3", children: children }), resolvedLinks.length > 0 && (_jsx("nav", { className: "flex justify-center items-center flex-wrap gap-2 mb-2", "aria-label": "Footer links", children: resolvedLinks.map((link, index) => (_jsxs(React.Fragment, { children: [index > 0 && _jsx("span", { className: "text-dos-text-muted select-none eidotter-footer__dot", "aria-hidden": "true", children: "\u00B7" }), link.external ? (_jsx("a", { className: linkClassName, href: link.href, target: "_blank", rel: "noopener noreferrer", children: link.label })) : (_jsx(LinkTag, { className: linkClassName, href: link.href, children: link.label }))] }, link.href))) })), copyright && (_jsxs("p", { className: "text-dos-text-muted m-0", children: ["\u00A9 ", copyright] }))] }));
18
+ };
@@ -1,2 +1,2 @@
1
- export { Footer, defaultLegalLinks } from './Footer';
2
- export type { FooterProps, FooterLink } from './Footer';
1
+ export { Footer, defaultLegalLinks } from './Footer.js';
2
+ export type { FooterProps, FooterLink } from './Footer.js';
@@ -0,0 +1 @@
1
+ export { Footer, defaultLegalLinks } from './Footer.js';
@@ -1,2 +1,2 @@
1
- export { Footer, defaultLegalLinks } from './components';
2
- export type { FooterProps, FooterLink } from './components';
1
+ export { Footer, defaultLegalLinks } from './components/index.js';
2
+ export type { FooterProps, FooterLink } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { Footer, defaultLegalLinks } from './components/index.js';
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
- import type { NavItem, NavProps } from '../../Nav';
3
- import './Header.css';
2
+ import type { NavItem, NavProps } from '../../Nav/index.js';
4
3
  export interface HeaderProps extends React.HTMLAttributes<HTMLElement> {
5
4
  /** Site brand name displayed in the header */
6
5
  brandName?: string;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { cn } from '../../../utils/cn.js';
4
+ import { DesktopNav, MobileNav } from '../../Nav/index.js';
5
+ const variantClasses = {
6
+ retro: 'eidotter-header--retro',
7
+ modern: 'eidotter-header--modern',
8
+ };
9
+ export const Header = forwardRef(({ brandName, brandHref = '/', items, activeHref, variant = 'retro', sticky = true, linkComponent, children, className, ...rest }, ref) => {
10
+ const LinkTag = linkComponent ?? 'a';
11
+ return (_jsxs("header", { ref: ref, className: cn('flex items-center justify-between px-4 py-3 font-dos', 'eidotter-header', variantClasses[variant], sticky && 'sticky top-0 z-50 bg-dos-bg-primary', className), ...rest, children: [_jsx(LinkTag, { href: brandHref, className: cn('no-underline text-base font-bold tracking-wide', 'eidotter-header__branding'), children: children || brandName }), _jsx(DesktopNav, { items: items, activeHref: activeHref, variant: variant, linkComponent: linkComponent }), _jsx(MobileNav, { items: items, activeHref: activeHref, variant: variant, linkComponent: linkComponent })] }));
12
+ });
13
+ Header.displayName = 'Header';
@@ -1,2 +1,2 @@
1
- export { Header } from './Header';
2
- export type { HeaderProps } from './Header';
1
+ export { Header } from './Header.js';
2
+ export type { HeaderProps } from './Header.js';
@@ -0,0 +1 @@
1
+ export { Header } from './Header.js';
@@ -1,2 +1,2 @@
1
- export { Header } from './components';
2
- export type { HeaderProps } from './components';
1
+ export { Header } from './components/index.js';
2
+ export type { HeaderProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { Header } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React, { FC } from 'react';
2
- import './Icon.css';
3
2
  type PixelIcon = FC<React.SVGProps<SVGSVGElement>>;
4
3
  declare const ICON_MAP: {
5
4
  Info: (props: React.SVGProps<SVGSVGElement>) => JSX.Element;
@@ -0,0 +1,78 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { InfoBox } from 'pixelarticons/react/InfoBox';
4
+ import { WarningDiamond } from 'pixelarticons/react/WarningDiamond';
5
+ import { SquareAlert } from 'pixelarticons/react/SquareAlert';
6
+ import { Check } from 'pixelarticons/react/Check';
7
+ import { ChevronUp } from 'pixelarticons/react/ChevronUp';
8
+ import { ChevronDown } from 'pixelarticons/react/ChevronDown';
9
+ import { WindowFrame } from 'pixelarticons/react/WindowFrame';
10
+ import { Minus } from 'pixelarticons/react/Minus';
11
+ import { Expand } from 'pixelarticons/react/Expand';
12
+ import { Plus } from 'pixelarticons/react/Plus';
13
+ import { cn } from '../../../utils/cn.js';
14
+ /**
15
+ * Custom pixel-art X mark — pixelarticons v2 has no standalone close/X glyph.
16
+ * Matches pixelarticons' style: 24×24 viewBox, fill-based single path,
17
+ * currentColor inheritance, 2×2 unit "pixels" on the grid.
18
+ */
19
+ const PixelX = (props) => (_jsx("svg", { viewBox: "0 0 24 24", width: "24", height: "24", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg", ...props, children: _jsx("path", { d: "M5 5h2v2H5zM7 7h2v2H7zM9 9h2v2H9zM11 11h2v2h-2zM13 13h2v2h-2zM15 15h2v2h-2zM17 17h2v2h-2zM17 5h2v2h-2zM15 7h2v2h-2zM13 9h2v2h-2zM9 13h2v2H9zM7 15h2v2H7zM5 17h2v2H5z" }) }));
20
+ // 12 public icon names mapping to 11 unique pixelarticons components.
21
+ // Done and Check both map to the Check component intentionally — consumers
22
+ // can use either semantic name for a checkmark glyph.
23
+ //
24
+ // Non-obvious mappings:
25
+ // - 'Close' → custom PixelX component: pixelarticons v2 has no standalone
26
+ // X/close glyph, so we draw a pixel-art X mark matching their style
27
+ // (24×24 viewBox, fill-based single path, 2×2 unit pixels).
28
+ // - 'Cancel' → pixelarticons Minus: this name carries Terminal-window semantics
29
+ // (cancel/minimize control), rendered as a minus glyph matching DOS window
30
+ // chrome. A future release may rename this to 'Minimize' for clarity.
31
+ // - 'App' → pixelarticons WindowFrame: used for the Terminal window icon.
32
+ const ICON_MAP = {
33
+ 'Info': InfoBox,
34
+ 'Warning': WarningDiamond,
35
+ 'Error': SquareAlert,
36
+ 'Done': Check,
37
+ 'Check': Check,
38
+ 'Close': PixelX, // custom pixel-art X mark (pixelarticons has no X glyph)
39
+ 'Chevron Up': ChevronUp,
40
+ 'Chevron Down': ChevronDown,
41
+ 'App': WindowFrame,
42
+ 'Cancel': Minus, // window minimize control, not abort
43
+ 'Fullscreen': Expand,
44
+ 'Add': Plus,
45
+ };
46
+ const SIZE_MAP = { L: 56, S: 24 };
47
+ /**
48
+ * Icon component backed by pixelarticons (MIT licensed).
49
+ * Renders inline SVG with proper viewBox scaling at any size.
50
+ * The DOS pixel aesthetic matches eidotter's design language.
51
+ */
52
+ export const Icon = ({ name, size = 'L', className = '', onClick, color, role, 'aria-label': ariaLabel, }) => {
53
+ // Runtime defense against JS consumers or dynamically-cast names.
54
+ // TypeScript users are already constrained to IconName by IconProps.
55
+ const IconComponent = ICON_MAP[name];
56
+ if (!IconComponent)
57
+ return null;
58
+ const pixelSize = SIZE_MAP[size];
59
+ // Default to role="img" so the aria-label is allowed (ARIA 1.2 prohibits
60
+ // aria-label on the implicit `generic` role of <span>). When the consumer
61
+ // marks the icon as an interactive control via role="button", that takes
62
+ // precedence and the consumer is responsible for handling activation.
63
+ const resolvedRole = role ?? 'img';
64
+ const isButton = role === 'button';
65
+ // When the icon is itself the interactive control (role="button"), make it
66
+ // keyboard-operable: focusable + Enter/Space activation, matching native
67
+ // button behavior. Without this the shipped :focus-visible style can never
68
+ // fire because the span isn't in the tab order.
69
+ const handleKeyDown = isButton
70
+ ? (event) => {
71
+ if (event.key === 'Enter' || event.key === ' ') {
72
+ event.preventDefault();
73
+ onClick?.();
74
+ }
75
+ }
76
+ : undefined;
77
+ return (_jsx("span", { className: cn('icon', isButton && 'icon--button', className), onClick: onClick, onKeyDown: handleKeyDown, role: resolvedRole, tabIndex: isButton ? 0 : undefined, "aria-label": ariaLabel || `${name} icon`, style: color ? { color } : undefined, children: _jsx(IconComponent, { width: pixelSize, height: pixelSize, className: "icon__svg" }) }));
78
+ };
@@ -1,2 +1,2 @@
1
- export { Icon } from './Icon';
2
- export type { IconProps, IconName, IconSize } from './Icon';
1
+ export { Icon } from './Icon.js';
2
+ export type { IconProps, IconName, IconSize } from './Icon.js';
@@ -0,0 +1 @@
1
+ export { Icon } from './Icon.js';
@@ -1 +1 @@
1
- export * from './components';
1
+ export * from './components/index.js';
@@ -0,0 +1 @@
1
+ export * from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './InlineExpand.css';
3
2
  export interface InlineExpandSource {
4
3
  /** Link text displayed as accessible label */
5
4
  title: string;
@@ -0,0 +1,50 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useId, useRef } from 'react';
4
+ import { Button as AriaButton } from 'react-aria-components';
5
+ import { cn } from '../../../utils/cn.js';
6
+ import { isSafeUrl } from '../../../utils/isSafeUrl.js';
7
+ /**
8
+ * Inline disclosure widget that reveals content when trigger text is clicked.
9
+ *
10
+ * Unlike Section/Accordion (block-level, bordered sections), InlineExpand is
11
+ * designed for inline use within paragraphs and prose content.
12
+ *
13
+ * Features:
14
+ * - Controlled and uncontrolled modes
15
+ * - Native <button> trigger for full keyboard/screen reader support
16
+ * - Optional citation sources with favicons
17
+ * - DOS-authentic styling with phosphor glow and CGA tokens
18
+ * - WCAG 2.1 AA compliant
19
+ *
20
+ * Content stays in the DOM when collapsed (with visibility: hidden) to enable
21
+ * smooth CSS transition exit animations. This differs from Section which
22
+ * unmounts content on collapse via conditional rendering.
23
+ */
24
+ export const InlineExpand = ({ children, content, defaultExpanded = false, expanded, onToggle, sources = [], className, ...props }) => {
25
+ const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
26
+ const [failedFavicons, setFailedFavicons] = useState(new Set());
27
+ const hasBeenExpanded = useRef(defaultExpanded);
28
+ const contentId = useId();
29
+ const triggerRef = useRef(null);
30
+ const isControlled = expanded !== undefined;
31
+ const isExpanded = isControlled ? expanded : internalExpanded;
32
+ if (isExpanded) {
33
+ hasBeenExpanded.current = true;
34
+ }
35
+ const handleToggle = () => {
36
+ const next = !isExpanded;
37
+ if (!isControlled) {
38
+ setInternalExpanded(next);
39
+ }
40
+ onToggle?.(next);
41
+ };
42
+ const handleKeyDown = (event) => {
43
+ if (event.key === 'Escape' && isExpanded) {
44
+ event.stopPropagation();
45
+ handleToggle();
46
+ triggerRef.current?.focus();
47
+ }
48
+ };
49
+ return (_jsxs("span", { className: cn('eidotter-inline-expand', isExpanded && 'eidotter-inline-expand--expanded', className), onKeyDown: handleKeyDown, ...props, children: [_jsxs(AriaButton, { ref: triggerRef, className: "eidotter-inline-expand__trigger", "aria-expanded": isExpanded, "aria-controls": contentId, onPress: handleToggle, children: [children, _jsx("span", { className: "eidotter-inline-expand__indicator", "aria-hidden": "true", children: isExpanded ? '[-]' : '[+]' })] }), _jsx("span", { id: contentId, className: "eidotter-inline-expand__content", role: "region", inert: !isExpanded, children: _jsxs("span", { className: "eidotter-inline-expand__content-clip", children: [_jsx("span", { className: "eidotter-inline-expand__inner", children: content }), sources.length > 0 && (_jsx("span", { className: "eidotter-inline-expand__sources", role: "list", children: sources.map((source) => (_jsx("span", { className: "eidotter-inline-expand__source-item", role: "listitem", children: _jsxs("a", { href: isSafeUrl(source.url) ? source.url : undefined, className: "eidotter-inline-expand__source-link", target: "_blank", rel: "noopener noreferrer", "aria-label": `${source.title} (opens external website)`, children: [hasBeenExpanded.current && source.favicon && isSafeUrl(source.favicon) && !failedFavicons.has(source.url) ? (_jsx("img", { className: "eidotter-inline-expand__source-favicon", src: source.favicon, alt: "", width: 16, height: 16, decoding: "async", onError: () => setFailedFavicons(prev => new Set(prev).add(source.url)) })) : (_jsx("span", { className: "eidotter-inline-expand__source-icon", "aria-hidden": "true", children: "[\u2192]" })), _jsx("span", { className: "eidotter-inline-expand__source-title", children: source.title })] }) }, source.url))) }))] }) })] }));
50
+ };
@@ -1,2 +1,2 @@
1
- export { InlineExpand } from './InlineExpand';
2
- export type { InlineExpandProps, InlineExpandSource } from './InlineExpand';
1
+ export { InlineExpand } from './InlineExpand.js';
2
+ export type { InlineExpandProps, InlineExpandSource } from './InlineExpand.js';
@@ -0,0 +1 @@
1
+ export { InlineExpand } from './InlineExpand.js';
@@ -1,2 +1,2 @@
1
- export { InlineExpand } from './components';
2
- export type { InlineExpandProps, InlineExpandSource } from './components';
1
+ export { InlineExpand } from './components/index.js';
2
+ export type { InlineExpandProps, InlineExpandSource } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { InlineExpand } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './InlineLink.css';
3
2
  export interface InlineLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'children'> {
4
3
  /** Link text. */
5
4
  children: React.ReactNode;
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { cn } from '../../../utils/cn.js';
4
+ // Relative paths, hash/query fragments, and standard nav schemes are allowed.
5
+ // Everything else (javascript:, data:, vbscript:, unknown schemes) collapses
6
+ // to a safe "#" sentinel.
7
+ function sanitizeHref(href) {
8
+ const trimmed = href.trim();
9
+ if (trimmed === '')
10
+ return trimmed;
11
+ if (/^[#?/]/.test(trimmed))
12
+ return trimmed;
13
+ const schemeMatch = /^([a-z][a-z0-9+\-.]*):/i.exec(trimmed);
14
+ if (!schemeMatch)
15
+ return trimmed;
16
+ const scheme = schemeMatch[1].toLowerCase();
17
+ const allowed = ['http', 'https', 'mailto', 'tel', 'ftp', 'sms'];
18
+ return allowed.includes(scheme) ? trimmed : '#';
19
+ }
20
+ // Union-merge caller rel tokens with the required safety tokens so
21
+ // consumer-supplied `rel="external"` still gets `noopener noreferrer` when the
22
+ // link opens in a new tab.
23
+ function mergeRel(callerRel, required) {
24
+ if (required.length === 0)
25
+ return callerRel;
26
+ const tokens = new Set((callerRel ?? '').split(/\s+/).map(t => t.trim().toLowerCase()).filter(Boolean));
27
+ for (const token of required)
28
+ tokens.add(token.toLowerCase());
29
+ return Array.from(tokens).join(' ');
30
+ }
31
+ /**
32
+ * In-flow navigational anchor. Distinct from `<InlineExpand>` — this is a
33
+ * destination, not a disclosure.
34
+ *
35
+ * Rest: dotted amber underline, trailing `▸`.
36
+ * Hover: phosphor inversion — amber background, dark foreground.
37
+ * Visited: dimmed amber (`text.tertiary` role; amber-dim under the default theme).
38
+ * External: opens in a new tab safely, trailing glyph becomes `↗`.
39
+ *
40
+ * Consumer-passed `target="_blank"` is treated as implicit-external for
41
+ * `rel` safety — a `rel` is auto-applied if none is provided, preventing
42
+ * tabnabbing even when the caller doesn't explicitly set `external`.
43
+ */
44
+ export const InlineLink = forwardRef(({ children, href, showGlyph = true, external = false, className, target, rel, ...props }, ref) => {
45
+ const safeHref = sanitizeHref(href);
46
+ const resolvedTarget = target ?? (external ? '_blank' : undefined);
47
+ // Apply safe rel when the link opens in a new tab for ANY reason —
48
+ // explicit `external` or consumer-supplied `target="_blank"`. Merge with
49
+ // caller rel so `rel="author"` + target=_blank still guards against
50
+ // tabnabbing.
51
+ const opensInNewTab = resolvedTarget === '_blank';
52
+ const resolvedRel = opensInNewTab
53
+ ? mergeRel(rel, ['noopener', 'noreferrer'])
54
+ : rel;
55
+ // `external` drives the glyph, but only when the link actually opens in a
56
+ // new tab — `external={true} target="_self"` is an inconsistency we resolve
57
+ // by falling back to the in-flow glyph.
58
+ const glyph = external && opensInNewTab ? '↗' : '▸';
59
+ return (_jsxs("a", { ref: ref, href: safeHref, target: resolvedTarget, rel: resolvedRel, className: cn('eidotter-ilink', external && 'eidotter-ilink--external', className), ...props, children: [_jsx("span", { className: "eidotter-ilink__label", children: children }), showGlyph && (_jsx("span", { className: "eidotter-ilink__glyph", "aria-hidden": "true", children: glyph }))] }));
60
+ });
61
+ InlineLink.displayName = 'InlineLink';
@@ -1,2 +1,2 @@
1
- export { InlineLink } from './InlineLink';
2
- export type { InlineLinkProps } from './InlineLink';
1
+ export { InlineLink } from './InlineLink.js';
2
+ export type { InlineLinkProps } from './InlineLink.js';
@@ -0,0 +1 @@
1
+ export { InlineLink } from './InlineLink.js';
@@ -1,2 +1,2 @@
1
- export { InlineLink } from './components';
2
- export type { InlineLinkProps } from './components';
1
+ export { InlineLink } from './components/index.js';
2
+ export type { InlineLinkProps } from './components/index.js';
@@ -0,0 +1 @@
1
+ export { InlineLink } from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './Input.css';
3
2
  export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
4
3
  /** Visual variant for validation states */
5
4
  variant?: 'default' | 'error';
@@ -0,0 +1,18 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { TextField as AriaTextField, Input as AriaInput, Label as AriaLabel, Text as AriaText, } from 'react-aria-components';
5
+ import { cn } from '../../../utils/cn.js';
6
+ const variantClasses = {
7
+ default: 'eidotter-input--default',
8
+ error: 'eidotter-input--error',
9
+ };
10
+ /**
11
+ * DOS-styled Input with React Aria TextField.
12
+ * Provides automatic label association, description, and error message support.
13
+ */
14
+ export const Input = forwardRef(({ variant = 'default', label, description, errorMessage, disabled, className, onChange, isRequired, ...props }, ref) => {
15
+ const isInvalid = variant === 'error';
16
+ return (_jsxs(AriaTextField, { isDisabled: disabled, isInvalid: isInvalid, isRequired: isRequired, className: cn('eidotter-text-field', 'flex flex-col gap-1', className), children: [label && (_jsx(AriaLabel, { className: "text-dos-text-brand font-dos text-xs uppercase tracking-wider", children: label })), _jsx(AriaInput, { ref: ref, className: cn('w-full bg-transparent text-dos-text-brand font-dos text-base p-2', 'border-2 border-dos-border-default outline-none box-border', 'eidotter-input', variantClasses[variant] || variantClasses.default, disabled && 'eidotter-input--disabled'), onChange: onChange, ...props }), description && !isInvalid && (_jsx(AriaText, { slot: "description", className: "text-dos-text-muted font-dos text-xs", children: description })), errorMessage && isInvalid && (_jsx(AriaText, { slot: "errorMessage", className: "text-dos-text-error font-dos text-xs", children: errorMessage }))] }));
17
+ });
18
+ Input.displayName = 'Input';
@@ -1,2 +1,2 @@
1
- export { Input } from './Input';
2
- export type { InputProps } from './Input';
1
+ export { Input } from './Input.js';
2
+ export type { InputProps } from './Input.js';
@@ -0,0 +1 @@
1
+ export { Input } from './Input.js';
@@ -1 +1 @@
1
- export * from './components';
1
+ export * from './components/index.js';
@@ -0,0 +1 @@
1
+ export * from './components/index.js';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import './LabeledProgress.css';
3
2
  export interface LabeledProgressProps {
4
3
  /** Optional leading label rendered before the bar. */
5
4
  label?: React.ReactNode;