@refraction-ui/astro 0.4.0 → 0.4.4

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 (469) hide show
  1. package/dist/accordion/index.ts +1 -0
  2. package/dist/ai/ai-manager.ts +121 -0
  3. package/dist/ai/index.ts +23 -0
  4. package/dist/ai/mock-providers.ts +68 -0
  5. package/dist/ai/sanitizer.ts +174 -0
  6. package/dist/ai/tts-manager.ts +80 -0
  7. package/dist/ai/types.ts +72 -0
  8. package/dist/animated-text/animated-text.styles.ts +28 -0
  9. package/dist/animated-text/animated-text.ts +83 -0
  10. package/dist/animated-text/index.ts +15 -0
  11. package/dist/app-shell/app-shell.ts +252 -0
  12. package/dist/app-shell/auth-shell.ts +84 -0
  13. package/dist/app-shell/index.ts +22 -0
  14. package/dist/app-shell/page-shell.ts +125 -0
  15. package/dist/astro-accordion/Button.astro +55 -0
  16. package/dist/astro-accordion/index.ts +1 -0
  17. package/dist/astro-ai/AIScript.astro +69 -0
  18. package/dist/astro-ai/TTSScript.astro +60 -0
  19. package/dist/astro-ai/index.ts +16 -0
  20. package/dist/astro-animated-text/AnimatedText.astro +81 -0
  21. package/dist/astro-animated-text/TypewriterText.astro +90 -0
  22. package/dist/astro-animated-text/index.ts +1 -0
  23. package/dist/astro-app-shell/AppShell.astro +195 -0
  24. package/dist/astro-app-shell/AppShellContent.astro +29 -0
  25. package/dist/astro-app-shell/AppShellHeader.astro +54 -0
  26. package/dist/astro-app-shell/AppShellMain.astro +18 -0
  27. package/dist/astro-app-shell/AppShellMobileNav.astro +27 -0
  28. package/dist/astro-app-shell/AppShellOverlay.astro +21 -0
  29. package/dist/astro-app-shell/AppShellSidebar.astro +26 -0
  30. package/dist/astro-app-shell/AuthShell.astro +31 -0
  31. package/dist/astro-app-shell/AuthShellCard.astro +24 -0
  32. package/dist/astro-app-shell/PageShell.astro +36 -0
  33. package/dist/astro-app-shell/PageShellFooter.astro +30 -0
  34. package/dist/astro-app-shell/PageShellNav.astro +33 -0
  35. package/dist/astro-app-shell/PageShellSection.astro +32 -0
  36. package/dist/astro-app-shell/index.ts +21 -0
  37. package/dist/astro-auth/AuthGuard.astro +133 -0
  38. package/dist/astro-auth/index.ts +5 -0
  39. package/dist/astro-avatar/Avatar.astro +22 -0
  40. package/dist/astro-avatar/AvatarFallback.astro +18 -0
  41. package/dist/astro-avatar/AvatarImage.astro +48 -0
  42. package/dist/astro-avatar/index.ts +1 -0
  43. package/dist/astro-avatar-group/AvatarGroup.astro +42 -0
  44. package/dist/astro-avatar-group/index.ts +1 -0
  45. package/dist/astro-badge/Badge.astro +27 -0
  46. package/dist/astro-badge/index.ts +1 -0
  47. package/dist/astro-bottom-nav/BottomNav.astro +40 -0
  48. package/dist/astro-bottom-nav/index.ts +1 -0
  49. package/dist/astro-breadcrumbs/Breadcrumbs.astro +56 -0
  50. package/dist/astro-breadcrumbs/index.ts +1 -0
  51. package/dist/astro-button/Button.astro +55 -0
  52. package/dist/astro-button/index.ts +1 -0
  53. package/dist/astro-calendar/Calendar.astro +259 -0
  54. package/dist/astro-calendar/index.ts +1 -0
  55. package/dist/astro-callout/Callout.astro +3 -0
  56. package/dist/astro-callout/index.ts +1 -0
  57. package/dist/astro-card/Card.astro +20 -0
  58. package/dist/astro-card/CardContent.astro +13 -0
  59. package/dist/astro-card/CardDescription.astro +13 -0
  60. package/dist/astro-card/CardFooter.astro +13 -0
  61. package/dist/astro-card/CardHeader.astro +13 -0
  62. package/dist/astro-card/CardTitle.astro +15 -0
  63. package/dist/astro-card/index.ts +1 -0
  64. package/dist/astro-card-grid/CardGrid.astro +17 -0
  65. package/dist/astro-card-grid/index.ts +1 -0
  66. package/dist/astro-carousel/Button.astro +55 -0
  67. package/dist/astro-carousel/index.ts +1 -0
  68. package/dist/astro-charts/Bars.astro +53 -0
  69. package/dist/astro-charts/Chart.astro +31 -0
  70. package/dist/astro-charts/Circles.astro +48 -0
  71. package/dist/astro-charts/Gradient.astro +34 -0
  72. package/dist/astro-charts/Histogram.astro +107 -0
  73. package/dist/astro-charts/Line.astro +55 -0
  74. package/dist/astro-charts/PieChart.astro +63 -0
  75. package/dist/astro-charts/ScatterPlot.astro +95 -0
  76. package/dist/astro-charts/XAxis.astro +46 -0
  77. package/dist/astro-charts/YAxis.astro +44 -0
  78. package/dist/astro-charts/index.ts +26 -0
  79. package/dist/astro-checkbox/Checkbox.astro +129 -0
  80. package/dist/astro-checkbox/index.ts +1 -0
  81. package/dist/astro-code-block/CodeBlock.astro +3 -0
  82. package/dist/astro-code-block/index.ts +1 -0
  83. package/dist/astro-code-editor/CodeEditor.astro +123 -0
  84. package/dist/astro-code-editor/index.ts +1 -0
  85. package/dist/astro-collapsible/Collapsible.astro +58 -0
  86. package/dist/astro-collapsible/CollapsibleContent.astro +21 -0
  87. package/dist/astro-collapsible/CollapsibleTrigger.astro +17 -0
  88. package/dist/astro-collapsible/index.ts +1 -0
  89. package/dist/astro-command/Command.astro +170 -0
  90. package/dist/astro-command/CommandEmpty.astro +17 -0
  91. package/dist/astro-command/CommandGroup.astro +25 -0
  92. package/dist/astro-command/CommandInput.astro +21 -0
  93. package/dist/astro-command/CommandItem.astro +26 -0
  94. package/dist/astro-command/CommandList.astro +17 -0
  95. package/dist/astro-command/CommandSeparator.astro +14 -0
  96. package/dist/astro-command/index.ts +1 -0
  97. package/dist/astro-command-input/CommandInput.astro +6 -0
  98. package/dist/astro-command-input/index.ts +1 -0
  99. package/dist/astro-content-protection/ContentProtection.astro +104 -0
  100. package/dist/astro-content-protection/index.ts +1 -0
  101. package/dist/astro-data-table/DataTable.astro +263 -0
  102. package/dist/astro-data-table/index.ts +1 -0
  103. package/dist/astro-date-picker/DatePicker.astro +398 -0
  104. package/dist/astro-date-picker/index.ts +1 -0
  105. package/dist/astro-device-frame/DeviceFrame.astro +44 -0
  106. package/dist/astro-device-frame/index.ts +1 -0
  107. package/dist/astro-dialog/Dialog.astro +138 -0
  108. package/dist/astro-dialog/DialogClose.astro +16 -0
  109. package/dist/astro-dialog/DialogContent.astro +24 -0
  110. package/dist/astro-dialog/DialogDescription.astro +15 -0
  111. package/dist/astro-dialog/DialogFooter.astro +14 -0
  112. package/dist/astro-dialog/DialogHeader.astro +14 -0
  113. package/dist/astro-dialog/DialogOverlay.astro +17 -0
  114. package/dist/astro-dialog/DialogTitle.astro +15 -0
  115. package/dist/astro-dialog/DialogTrigger.astro +18 -0
  116. package/dist/astro-dialog/index.ts +1 -0
  117. package/dist/astro-diff-viewer/DiffViewer.astro +371 -0
  118. package/dist/astro-diff-viewer/index.ts +1 -0
  119. package/dist/astro-dropdown-menu/DropdownMenu.astro +138 -0
  120. package/dist/astro-dropdown-menu/DropdownMenuContent.astro +20 -0
  121. package/dist/astro-dropdown-menu/DropdownMenuItem.astro +21 -0
  122. package/dist/astro-dropdown-menu/DropdownMenuLabel.astro +14 -0
  123. package/dist/astro-dropdown-menu/DropdownMenuSeparator.astro +14 -0
  124. package/dist/astro-dropdown-menu/DropdownMenuTrigger.astro +18 -0
  125. package/dist/astro-dropdown-menu/index.ts +1 -0
  126. package/dist/astro-emoji-picker/EmojiPicker.astro +255 -0
  127. package/dist/astro-emoji-picker/index.ts +1 -0
  128. package/dist/astro-feedback-dialog/FeedbackDialog.astro +152 -0
  129. package/dist/astro-feedback-dialog/index.ts +1 -0
  130. package/dist/astro-file-tree/astro-file-tree.astro +4 -0
  131. package/dist/astro-file-tree/index.ts +1 -0
  132. package/dist/astro-file-upload/FileUpload.astro +306 -0
  133. package/dist/astro-file-upload/index.ts +1 -0
  134. package/dist/astro-footer/Footer.astro +61 -0
  135. package/dist/astro-footer/index.ts +1 -0
  136. package/dist/astro-icon-system/astro-icon-system.astro +4 -0
  137. package/dist/astro-icon-system/index.ts +1 -0
  138. package/dist/astro-inline-editor/InlineEditor.astro +169 -0
  139. package/dist/astro-inline-editor/index.ts +1 -0
  140. package/dist/astro-input/Input.astro +49 -0
  141. package/dist/astro-input/index.ts +1 -0
  142. package/dist/astro-input-group/InputGroup.astro +29 -0
  143. package/dist/astro-input-group/InputGroupAddon.astro +14 -0
  144. package/dist/astro-input-group/InputGroupButton.astro +19 -0
  145. package/dist/astro-input-group/InputGroupText.astro +11 -0
  146. package/dist/astro-input-group/index.ts +1 -0
  147. package/dist/astro-install-prompt/InstallPrompt.astro +115 -0
  148. package/dist/astro-install-prompt/index.ts +1 -0
  149. package/dist/astro-keyboard-shortcut/KeyboardShortcut.astro +83 -0
  150. package/dist/astro-keyboard-shortcut/ShortcutBadge.astro +41 -0
  151. package/dist/astro-keyboard-shortcut/index.ts +1 -0
  152. package/dist/astro-language-selector/LanguageSelector.astro +247 -0
  153. package/dist/astro-language-selector/index.ts +1 -0
  154. package/dist/astro-link-card/LinkCard.astro +17 -0
  155. package/dist/astro-link-card/index.ts +1 -0
  156. package/dist/astro-markdown-renderer/MarkdownRenderer.astro +62 -0
  157. package/dist/astro-markdown-renderer/index.ts +1 -0
  158. package/dist/astro-mobile-nav/MobileNav.astro +84 -0
  159. package/dist/astro-mobile-nav/MobileNavContent.astro +29 -0
  160. package/dist/astro-mobile-nav/MobileNavLink.astro +16 -0
  161. package/dist/astro-mobile-nav/MobileNavTrigger.astro +57 -0
  162. package/dist/astro-mobile-nav/index.ts +1 -0
  163. package/dist/astro-navbar/Navbar.astro +49 -0
  164. package/dist/astro-navbar/index.ts +1 -0
  165. package/dist/astro-otp-input/OtpInput.astro +253 -0
  166. package/dist/astro-otp-input/index.ts +1 -0
  167. package/dist/astro-pagination/Pagination.astro +3 -0
  168. package/dist/astro-pagination/index.ts +1 -0
  169. package/dist/astro-payment/Payment.astro +19 -0
  170. package/dist/astro-payment/index.ts +1 -0
  171. package/dist/astro-popover/Popover.astro +87 -0
  172. package/dist/astro-popover/PopoverClose.astro +16 -0
  173. package/dist/astro-popover/PopoverContent.astro +23 -0
  174. package/dist/astro-popover/PopoverTrigger.astro +18 -0
  175. package/dist/astro-popover/index.ts +1 -0
  176. package/dist/astro-presence-indicator/PresenceIndicator.astro +26 -0
  177. package/dist/astro-presence-indicator/index.ts +1 -0
  178. package/dist/astro-progress-display/BadgeDisplay.astro +33 -0
  179. package/dist/astro-progress-display/ProgressBar.astro +27 -0
  180. package/dist/astro-progress-display/StatsGrid.astro +32 -0
  181. package/dist/astro-progress-display/index.ts +1 -0
  182. package/dist/astro-radio/RadioGroup.astro +111 -0
  183. package/dist/astro-radio/RadioItem.astro +36 -0
  184. package/dist/astro-radio/index.ts +1 -0
  185. package/dist/astro-reaction-bar/ReactionBar.astro +117 -0
  186. package/dist/astro-reaction-bar/index.ts +1 -0
  187. package/dist/astro-resizable-layout/ResizableDivider.astro +27 -0
  188. package/dist/astro-resizable-layout/ResizableLayout.astro +162 -0
  189. package/dist/astro-resizable-layout/ResizablePane.astro +28 -0
  190. package/dist/astro-resizable-layout/index.ts +11 -0
  191. package/dist/astro-rich-editor/RichEditor.astro +260 -0
  192. package/dist/astro-rich-editor/index.ts +25 -0
  193. package/dist/astro-search-bar/SearchBar.astro +140 -0
  194. package/dist/astro-search-bar/SearchResultItem.astro +16 -0
  195. package/dist/astro-search-bar/SearchResults.astro +17 -0
  196. package/dist/astro-search-bar/index.ts +1 -0
  197. package/dist/astro-select/Select.astro +165 -0
  198. package/dist/astro-select/SelectContent.astro +19 -0
  199. package/dist/astro-select/SelectItem.astro +42 -0
  200. package/dist/astro-select/SelectTrigger.astro +36 -0
  201. package/dist/astro-select/index.ts +1 -0
  202. package/dist/astro-sidebar/Sidebar.astro +64 -0
  203. package/dist/astro-sidebar/index.ts +1 -0
  204. package/dist/astro-skeleton/Skeleton.astro +39 -0
  205. package/dist/astro-skeleton/SkeletonText.astro +22 -0
  206. package/dist/astro-skeleton/index.ts +1 -0
  207. package/dist/astro-skip-to-content/SkipToContent.astro +3 -0
  208. package/dist/astro-skip-to-content/index.ts +1 -0
  209. package/dist/astro-slide-viewer/SlideViewer.astro +231 -0
  210. package/dist/astro-slide-viewer/index.ts +1 -0
  211. package/dist/astro-slider/index.ts +1 -0
  212. package/dist/astro-status-indicator/StatusIndicator.astro +31 -0
  213. package/dist/astro-status-indicator/index.ts +1 -0
  214. package/dist/astro-steps/Steps.astro +3 -0
  215. package/dist/astro-steps/index.ts +1 -0
  216. package/dist/astro-switch/Switch.astro +89 -0
  217. package/dist/astro-switch/index.ts +1 -0
  218. package/dist/astro-table-of-contents/TableOfContents.astro +53 -0
  219. package/dist/astro-table-of-contents/index.ts +1 -0
  220. package/dist/astro-tabs/Tabs.astro +96 -0
  221. package/dist/astro-tabs/TabsContent.astro +20 -0
  222. package/dist/astro-tabs/TabsList.astro +16 -0
  223. package/dist/astro-tabs/TabsTrigger.astro +24 -0
  224. package/dist/astro-tabs/index.ts +1 -0
  225. package/dist/astro-textarea/Textarea.astro +51 -0
  226. package/dist/astro-textarea/index.ts +1 -0
  227. package/dist/astro-theme/ThemeScript.astro +13 -0
  228. package/dist/astro-theme/ThemeToggle.astro +279 -0
  229. package/dist/astro-theme/index.ts +1 -0
  230. package/dist/astro-thread-view/ThreadView.astro +159 -0
  231. package/dist/astro-thread-view/index.ts +1 -0
  232. package/dist/astro-toast/Toast.astro +49 -0
  233. package/dist/astro-toast/Toaster.astro +142 -0
  234. package/dist/astro-toast/index.ts +1 -0
  235. package/dist/astro-tooltip/Tooltip.astro +95 -0
  236. package/dist/astro-tooltip/TooltipContent.astro +22 -0
  237. package/dist/astro-tooltip/TooltipTrigger.astro +16 -0
  238. package/dist/astro-tooltip/index.ts +1 -0
  239. package/dist/astro-version-selector/VersionSelector.astro +174 -0
  240. package/dist/astro-version-selector/index.ts +1 -0
  241. package/dist/astro-video-player/VideoPlayer.astro +153 -0
  242. package/dist/astro-video-player/index.ts +1 -0
  243. package/dist/auth/adapters/mock.ts +74 -0
  244. package/dist/auth/auth-machine.ts +120 -0
  245. package/dist/auth/index.ts +22 -0
  246. package/dist/auth/rbac.ts +44 -0
  247. package/dist/auth/types.ts +44 -0
  248. package/dist/avatar/avatar.styles.ts +47 -0
  249. package/dist/avatar/avatar.ts +73 -0
  250. package/dist/avatar/index.ts +15 -0
  251. package/dist/avatar-group/avatar-group.styles.ts +63 -0
  252. package/dist/avatar-group/avatar-group.ts +106 -0
  253. package/dist/avatar-group/index.ts +18 -0
  254. package/dist/badge/badge.styles.ts +24 -0
  255. package/dist/badge/badge.ts +48 -0
  256. package/dist/badge/index.ts +10 -0
  257. package/dist/bottom-nav/bottom-nav.styles.ts +18 -0
  258. package/dist/bottom-nav/bottom-nav.ts +33 -0
  259. package/dist/bottom-nav/index.ts +2 -0
  260. package/dist/breadcrumbs/breadcrumbs.styles.ts +20 -0
  261. package/dist/breadcrumbs/breadcrumbs.ts +72 -0
  262. package/dist/breadcrumbs/index.ts +8 -0
  263. package/dist/button/button.styles.ts +38 -0
  264. package/dist/button/button.ts +64 -0
  265. package/dist/button/index.ts +10 -0
  266. package/dist/calendar/calendar.styles.ts +21 -0
  267. package/dist/calendar/calendar.ts +202 -0
  268. package/dist/calendar/index.ts +9 -0
  269. package/dist/callout/callout.ts +1 -0
  270. package/dist/callout/index.ts +1 -0
  271. package/dist/card/card.styles.ts +55 -0
  272. package/dist/card/card.ts +45 -0
  273. package/dist/card/index.ts +20 -0
  274. package/dist/card-grid/card-grid.ts +9 -0
  275. package/dist/card-grid/index.ts +1 -0
  276. package/dist/carousel/index.ts +1 -0
  277. package/dist/charts/axis.ts +50 -0
  278. package/dist/charts/chart.ts +73 -0
  279. package/dist/charts/colorblind.ts +100 -0
  280. package/dist/charts/data.ts +72 -0
  281. package/dist/charts/geometry.ts +54 -0
  282. package/dist/charts/index.ts +61 -0
  283. package/dist/charts/scales.ts +151 -0
  284. package/dist/checkbox/checkbox.styles.ts +33 -0
  285. package/dist/checkbox/checkbox.ts +73 -0
  286. package/dist/checkbox/index.ts +10 -0
  287. package/dist/code-block/code-block.ts +1 -0
  288. package/dist/code-block/index.ts +1 -0
  289. package/dist/code-editor/code-editor.styles.ts +32 -0
  290. package/dist/code-editor/code-editor.ts +140 -0
  291. package/dist/code-editor/index.ts +9 -0
  292. package/dist/collapsible/collapsible.styles.ts +14 -0
  293. package/dist/collapsible/collapsible.ts +93 -0
  294. package/dist/collapsible/index.ts +7 -0
  295. package/dist/command/command.styles.ts +27 -0
  296. package/dist/command/command.ts +179 -0
  297. package/dist/command/index.ts +14 -0
  298. package/dist/command-input/command-input.ts +176 -0
  299. package/dist/command-input/index.ts +1 -0
  300. package/dist/content-protection/content-protection.styles.ts +9 -0
  301. package/dist/content-protection/content-protection.ts +68 -0
  302. package/dist/content-protection/index.ts +8 -0
  303. package/dist/data-table/data-table.styles.ts +55 -0
  304. package/dist/data-table/data-table.ts +183 -0
  305. package/dist/data-table/index.ts +15 -0
  306. package/dist/date-picker/date-picker.styles.ts +31 -0
  307. package/dist/date-picker/date-picker.ts +333 -0
  308. package/dist/date-picker/index.ts +18 -0
  309. package/dist/device-frame/device-frame.styles.ts +21 -0
  310. package/dist/device-frame/device-frame.ts +112 -0
  311. package/dist/device-frame/index.ts +10 -0
  312. package/dist/dialog/dialog.styles.ts +8 -0
  313. package/dist/dialog/dialog.ts +133 -0
  314. package/dist/dialog/index.ts +8 -0
  315. package/dist/diff-viewer/diff-viewer.styles.ts +124 -0
  316. package/dist/diff-viewer/diff-viewer.ts +255 -0
  317. package/dist/diff-viewer/index.ts +20 -0
  318. package/dist/dropdown-menu/dropdown-menu.styles.ts +9 -0
  319. package/dist/dropdown-menu/dropdown-menu.ts +139 -0
  320. package/dist/dropdown-menu/index.ts +9 -0
  321. package/dist/emoji-picker/emoji-data.ts +282 -0
  322. package/dist/emoji-picker/emoji-picker.styles.ts +32 -0
  323. package/dist/emoji-picker/emoji-picker.ts +165 -0
  324. package/dist/emoji-picker/index.ts +25 -0
  325. package/dist/feedback-dialog/feedback-dialog.styles.ts +15 -0
  326. package/dist/feedback-dialog/feedback-dialog.ts +147 -0
  327. package/dist/feedback-dialog/index.ts +11 -0
  328. package/dist/file-upload/file-upload.styles.ts +30 -0
  329. package/dist/file-upload/file-upload.ts +260 -0
  330. package/dist/file-upload/index.ts +19 -0
  331. package/dist/footer/footer.styles.ts +5 -0
  332. package/dist/footer/footer.ts +32 -0
  333. package/dist/footer/index.ts +9 -0
  334. package/dist/index.ts +77 -0
  335. package/dist/inline-editor/index.ts +13 -0
  336. package/dist/inline-editor/inline-editor.styles.ts +42 -0
  337. package/dist/inline-editor/inline-editor.ts +96 -0
  338. package/dist/input/index.ts +9 -0
  339. package/dist/input/input.styles.ts +15 -0
  340. package/dist/input/input.ts +84 -0
  341. package/dist/input-group/index.ts +13 -0
  342. package/dist/input-group/input-group.styles.ts +50 -0
  343. package/dist/input-group/input-group.ts +44 -0
  344. package/dist/install-prompt/index.ts +9 -0
  345. package/dist/install-prompt/install-prompt.styles.ts +5 -0
  346. package/dist/install-prompt/install-prompt.ts +68 -0
  347. package/dist/keyboard-shortcut/index.ts +12 -0
  348. package/dist/keyboard-shortcut/keyboard-shortcut.styles.ts +8 -0
  349. package/dist/keyboard-shortcut/keyboard-shortcut.ts +153 -0
  350. package/dist/language-selector/index.ts +8 -0
  351. package/dist/language-selector/language-selector.styles.ts +28 -0
  352. package/dist/language-selector/language-selector.ts +149 -0
  353. package/dist/link-card/index.ts +1 -0
  354. package/dist/link-card/link-card.ts +9 -0
  355. package/dist/markdown-renderer/index.ts +8 -0
  356. package/dist/markdown-renderer/markdown-renderer.styles.ts +31 -0
  357. package/dist/markdown-renderer/markdown-renderer.ts +251 -0
  358. package/dist/mobile-nav/index.ts +14 -0
  359. package/dist/mobile-nav/mobile-nav.styles.ts +39 -0
  360. package/dist/mobile-nav/mobile-nav.ts +74 -0
  361. package/dist/navbar/index.ts +9 -0
  362. package/dist/navbar/navbar.styles.ts +29 -0
  363. package/dist/navbar/navbar.ts +39 -0
  364. package/dist/otp-input/index.ts +13 -0
  365. package/dist/otp-input/otp-input.styles.ts +51 -0
  366. package/dist/otp-input/otp-input.ts +198 -0
  367. package/dist/pagination/index.ts +1 -0
  368. package/dist/payment/index.ts +1 -0
  369. package/dist/payment/payment.ts +16 -0
  370. package/dist/popover/index.ts +7 -0
  371. package/dist/popover/popover.styles.ts +16 -0
  372. package/dist/popover/popover.ts +89 -0
  373. package/dist/presence-indicator/index.ts +14 -0
  374. package/dist/presence-indicator/presence-indicator.styles.ts +29 -0
  375. package/dist/presence-indicator/presence-indicator.ts +63 -0
  376. package/dist/progress-display/index.ts +15 -0
  377. package/dist/progress-display/progress-display.styles.ts +72 -0
  378. package/dist/progress-display/progress-display.ts +60 -0
  379. package/dist/radio/index.ts +8 -0
  380. package/dist/radio/radio.styles.ts +34 -0
  381. package/dist/radio/radio.ts +70 -0
  382. package/dist/reaction-bar/index.ts +14 -0
  383. package/dist/reaction-bar/reaction-bar.styles.ts +23 -0
  384. package/dist/reaction-bar/reaction-bar.ts +87 -0
  385. package/dist/resizable-layout/index.ts +12 -0
  386. package/dist/resizable-layout/resizable-layout.styles.ts +50 -0
  387. package/dist/resizable-layout/resizable-layout.ts +139 -0
  388. package/dist/rich-editor/editor.ts +342 -0
  389. package/dist/rich-editor/emoji.ts +175 -0
  390. package/dist/rich-editor/history.ts +79 -0
  391. package/dist/rich-editor/index.ts +106 -0
  392. package/dist/rich-editor/markdown-shortcuts.ts +248 -0
  393. package/dist/rich-editor/mentions.ts +162 -0
  394. package/dist/rich-editor/model.ts +206 -0
  395. package/dist/rich-editor/operations.ts +772 -0
  396. package/dist/rich-editor/selection.ts +157 -0
  397. package/dist/rich-editor/serialization.ts +711 -0
  398. package/dist/rich-editor/slash-commands.ts +212 -0
  399. package/dist/search-bar/index.ts +7 -0
  400. package/dist/search-bar/search-bar.styles.ts +29 -0
  401. package/dist/search-bar/search-bar.ts +130 -0
  402. package/dist/select/index.ts +13 -0
  403. package/dist/select/select.styles.ts +52 -0
  404. package/dist/select/select.ts +152 -0
  405. package/dist/shared/a11y.ts +33 -0
  406. package/dist/shared/aria.ts +30 -0
  407. package/dist/shared/cn.ts +35 -0
  408. package/dist/shared/cva.ts +79 -0
  409. package/dist/shared/engine-adapter.ts +10 -0
  410. package/dist/shared/focus-trap.ts +123 -0
  411. package/dist/shared/index.ts +60 -0
  412. package/dist/shared/keyboard.ts +36 -0
  413. package/dist/shared/live-region.ts +90 -0
  414. package/dist/shared/motion.ts +15 -0
  415. package/dist/shared/skip-link.ts +35 -0
  416. package/dist/shared/state-machine.ts +57 -0
  417. package/dist/shared/tokens.ts +16 -0
  418. package/dist/shared/types.ts +45 -0
  419. package/dist/shared/variants.ts +17 -0
  420. package/dist/sidebar/index.ts +9 -0
  421. package/dist/sidebar/sidebar.styles.ts +27 -0
  422. package/dist/sidebar/sidebar.ts +59 -0
  423. package/dist/skeleton/index.ts +8 -0
  424. package/dist/skeleton/skeleton.styles.ts +16 -0
  425. package/dist/skeleton/skeleton.ts +39 -0
  426. package/dist/skip-to-content/index.ts +1 -0
  427. package/dist/skip-to-content/skip-to-content.ts +1 -0
  428. package/dist/slide-viewer/index.ts +16 -0
  429. package/dist/slide-viewer/slide-viewer.styles.ts +57 -0
  430. package/dist/slide-viewer/slide-viewer.ts +152 -0
  431. package/dist/slider/index.ts +1 -0
  432. package/dist/slider/slider.ts +2 -0
  433. package/dist/status-indicator/index.ts +15 -0
  434. package/dist/status-indicator/status-indicator.styles.ts +41 -0
  435. package/dist/status-indicator/status-indicator.ts +66 -0
  436. package/dist/steps/index.ts +1 -0
  437. package/dist/steps/steps.ts +1 -0
  438. package/dist/switch/index.ts +7 -0
  439. package/dist/switch/switch.styles.ts +55 -0
  440. package/dist/switch/switch.ts +63 -0
  441. package/dist/table-of-contents/index.ts +1 -0
  442. package/dist/table-of-contents/table-of-contents.ts +37 -0
  443. package/dist/tabs/index.ts +8 -0
  444. package/dist/tabs/tabs.styles.ts +9 -0
  445. package/dist/tabs/tabs.ts +133 -0
  446. package/dist/textarea/index.ts +7 -0
  447. package/dist/textarea/textarea.styles.ts +15 -0
  448. package/dist/textarea/textarea.ts +59 -0
  449. package/dist/theme/dom-adapters.ts +60 -0
  450. package/dist/theme/index.ts +18 -0
  451. package/dist/theme/theme-machine.ts +130 -0
  452. package/dist/theme/theme-script.ts +18 -0
  453. package/dist/thread-view/index.ts +26 -0
  454. package/dist/thread-view/thread-view.styles.ts +35 -0
  455. package/dist/thread-view/thread-view.ts +176 -0
  456. package/dist/toast/index.ts +13 -0
  457. package/dist/toast/toast.styles.ts +19 -0
  458. package/dist/toast/toast.ts +203 -0
  459. package/dist/tooltip/index.ts +7 -0
  460. package/dist/tooltip/tooltip.styles.ts +16 -0
  461. package/dist/tooltip/tooltip.ts +109 -0
  462. package/dist/version-selector/index.ts +12 -0
  463. package/dist/version-selector/version-selector.styles.ts +41 -0
  464. package/dist/version-selector/version-selector.ts +136 -0
  465. package/dist/video-player/index.ts +12 -0
  466. package/dist/video-player/video-player.styles.ts +42 -0
  467. package/dist/video-player/video-player.ts +100 -0
  468. package/package.json +20 -19
  469. package/src/index.ts +0 -94
@@ -0,0 +1,263 @@
1
+ ---
2
+ import {
3
+ createDataTable,
4
+ tableVariants,
5
+ headerVariants,
6
+ cellVariants,
7
+ rowVariants,
8
+ type ColumnDef,
9
+ type SortDirection,
10
+ } from '../data-table/index.ts'
11
+ import { cn } from '../shared/index.ts'
12
+
13
+ interface Props extends astroHTML.JSX.HTMLAttributes {
14
+ columns: ColumnDef[]
15
+ data: Record<string, unknown>[]
16
+ sortBy?: string
17
+ sortDir?: SortDirection
18
+ emptyMessage?: string
19
+ }
20
+
21
+ const {
22
+ columns,
23
+ data,
24
+ sortBy,
25
+ sortDir = 'asc',
26
+ emptyMessage = 'No data available',
27
+ class: className,
28
+ ...props
29
+ } = Astro.props
30
+
31
+ const api = createDataTable({ columns, data, sortBy, sortDir })
32
+ const sortedData = api.state.sortedData
33
+ const hasFilterable = columns.some((c: ColumnDef) => c.filterable)
34
+ ---
35
+
36
+ <div class="relative w-full overflow-auto" data-rfr-data-table data-rfr-data-table-columns={JSON.stringify(columns)} data-rfr-data-table-data={JSON.stringify(data)} {...props}>
37
+ <table class={cn(tableVariants(), className)} role="table">
38
+ <thead>
39
+ <tr role="row">
40
+ {columns.map((col: ColumnDef) => {
41
+ const hProps = api.getHeaderProps(col)
42
+ return (
43
+ <th
44
+ class={headerVariants({ sortable: col.sortable ? 'true' : 'false' })}
45
+ role={hProps.role as string}
46
+ aria-sort={hProps['aria-sort'] as any}
47
+ data-rfr-data-table-header={col.id}
48
+ data-sortable={col.sortable ? 'true' : undefined}
49
+ >
50
+ {col.header}
51
+ {col.sortable && sortBy === col.id && (
52
+ <span aria-hidden="true">{sortDir === 'asc' ? ' \u2191' : ' \u2193'}</span>
53
+ )}
54
+ </th>
55
+ )
56
+ })}
57
+ </tr>
58
+ {hasFilterable && (
59
+ <tr role="row" data-filter-row="true">
60
+ {columns.map((col: ColumnDef) => (
61
+ <th>
62
+ {col.filterable ? (
63
+ <input
64
+ type="text"
65
+ aria-label={`Filter ${col.header}`}
66
+ placeholder="Filter..."
67
+ data-rfr-data-table-filter={col.id}
68
+ class="w-full px-2 py-1 text-sm border rounded"
69
+ />
70
+ ) : null}
71
+ </th>
72
+ ))}
73
+ </tr>
74
+ )}
75
+ </thead>
76
+ <tbody data-rfr-data-table-body>
77
+ {sortedData.length === 0 ? (
78
+ <tr role="row">
79
+ <td
80
+ colspan={columns.length}
81
+ class="text-center p-4 text-muted-foreground"
82
+ role="cell"
83
+ >
84
+ {emptyMessage}
85
+ </td>
86
+ </tr>
87
+ ) : (
88
+ sortedData.map((row: Record<string, unknown>, rowIndex: number) => (
89
+ <tr
90
+ role="row"
91
+ class={rowVariants()}
92
+ data-row-index={rowIndex}
93
+ >
94
+ {columns.map((col: ColumnDef) => (
95
+ <td
96
+ role="cell"
97
+ class={cellVariants()}
98
+ data-column={col.id}
99
+ >
100
+ {String(col.accessor(row) ?? '')}
101
+ </td>
102
+ ))}
103
+ </tr>
104
+ ))
105
+ )}
106
+ </tbody>
107
+ </table>
108
+ </div>
109
+
110
+ <script>
111
+ function initDataTables() {
112
+ document.querySelectorAll<HTMLElement>('[data-rfr-data-table]').forEach((root) => {
113
+ if (root.hasAttribute('data-rfr-data-table-init')) return
114
+ root.setAttribute('data-rfr-data-table-init', '')
115
+
116
+ let columns: Array<{ id: string; header: string; sortable?: boolean; filterable?: boolean }>
117
+ let data: Array<Record<string, unknown>>
118
+
119
+ try {
120
+ columns = JSON.parse(root.getAttribute('data-rfr-data-table-columns') || '[]')
121
+ data = JSON.parse(root.getAttribute('data-rfr-data-table-data') || '[]')
122
+ } catch {
123
+ return
124
+ }
125
+
126
+ let sortBy: string | null = null
127
+ let sortDir: 'asc' | 'desc' = 'asc'
128
+ const filters: Record<string, string> = {}
129
+
130
+ const tbody = root.querySelector<HTMLElement>('[data-rfr-data-table-body]')
131
+ if (!tbody) return
132
+
133
+ // Build accessor functions from column IDs
134
+ function getCellValue(row: Record<string, unknown>, colId: string): unknown {
135
+ return row[colId]
136
+ }
137
+
138
+ function getFilteredSortedData(): Array<Record<string, unknown>> {
139
+ let result = [...data]
140
+
141
+ // Apply filters
142
+ for (const [colId, filterValue] of Object.entries(filters)) {
143
+ if (!filterValue) continue
144
+ const lowerFilter = filterValue.toLowerCase()
145
+ result = result.filter((row) => {
146
+ const cellValue = getCellValue(row, colId)
147
+ return String(cellValue ?? '').toLowerCase().includes(lowerFilter)
148
+ })
149
+ }
150
+
151
+ // Apply sort
152
+ if (sortBy) {
153
+ const sBy = sortBy
154
+ result.sort((a, b) => {
155
+ const aStr = String(getCellValue(a, sBy) ?? '')
156
+ const bStr = String(getCellValue(b, sBy) ?? '')
157
+ const cmp = aStr.localeCompare(bStr, undefined, { numeric: true })
158
+ return sortDir === 'asc' ? cmp : -cmp
159
+ })
160
+ }
161
+
162
+ return result
163
+ }
164
+
165
+ function renderRows() {
166
+ const sorted = getFilteredSortedData()
167
+ tbody!.innerHTML = ''
168
+
169
+ if (sorted.length === 0) {
170
+ const tr = document.createElement('tr')
171
+ tr.setAttribute('role', 'row')
172
+ const td = document.createElement('td')
173
+ td.setAttribute('colspan', String(columns.length))
174
+ td.setAttribute('role', 'cell')
175
+ td.className = 'text-center p-4 text-muted-foreground'
176
+ td.textContent = root.querySelector('td[role="cell"]')?.textContent || 'No data available'
177
+ tr.appendChild(td)
178
+ tbody!.appendChild(tr)
179
+ return
180
+ }
181
+
182
+ for (let i = 0; i < sorted.length; i++) {
183
+ const row = sorted[i]
184
+ const tr = document.createElement('tr')
185
+ tr.setAttribute('role', 'row')
186
+ tr.setAttribute('data-row-index', String(i))
187
+ // Apply row hover styles
188
+ tr.className = 'border-b transition-colors hover:bg-muted/50'
189
+
190
+ for (const col of columns) {
191
+ const td = document.createElement('td')
192
+ td.setAttribute('role', 'cell')
193
+ td.setAttribute('data-column', col.id)
194
+ td.className = 'p-2 align-middle border-b'
195
+ td.textContent = String(getCellValue(row, col.id) ?? '')
196
+ tr.appendChild(td)
197
+ }
198
+
199
+ tbody!.appendChild(tr)
200
+ }
201
+
202
+ root.dispatchEvent(
203
+ new CustomEvent('rfr-data-table-change', {
204
+ detail: { sortBy, sortDir, filters: { ...filters } },
205
+ bubbles: true,
206
+ }),
207
+ )
208
+ }
209
+
210
+ // Sort click handlers
211
+ const headers = root.querySelectorAll<HTMLElement>('[data-rfr-data-table-header]')
212
+ headers.forEach((th) => {
213
+ const colId = th.getAttribute('data-rfr-data-table-header')!
214
+ const isSortable = th.getAttribute('data-sortable') === 'true'
215
+ if (!isSortable) return
216
+
217
+ th.addEventListener('click', () => {
218
+ if (sortBy === colId) {
219
+ sortDir = sortDir === 'asc' ? 'desc' : 'asc'
220
+ } else {
221
+ sortBy = colId
222
+ sortDir = 'asc'
223
+ }
224
+
225
+ // Update sort indicators on all headers
226
+ headers.forEach((h) => {
227
+ const hColId = h.getAttribute('data-rfr-data-table-header')
228
+ const indicator = h.querySelector('span[aria-hidden]')
229
+ if (hColId === sortBy) {
230
+ h.setAttribute('aria-sort', sortDir === 'asc' ? 'ascending' : 'descending')
231
+ if (indicator) {
232
+ indicator.textContent = sortDir === 'asc' ? ' \u2191' : ' \u2193'
233
+ } else {
234
+ const span = document.createElement('span')
235
+ span.setAttribute('aria-hidden', 'true')
236
+ span.textContent = sortDir === 'asc' ? ' \u2191' : ' \u2193'
237
+ h.appendChild(span)
238
+ }
239
+ } else {
240
+ h.setAttribute('aria-sort', 'none')
241
+ if (indicator) indicator.remove()
242
+ }
243
+ })
244
+
245
+ renderRows()
246
+ })
247
+ })
248
+
249
+ // Filter input handlers
250
+ const filterInputs = root.querySelectorAll<HTMLInputElement>('[data-rfr-data-table-filter]')
251
+ filterInputs.forEach((input) => {
252
+ const colId = input.getAttribute('data-rfr-data-table-filter')!
253
+ input.addEventListener('input', () => {
254
+ filters[colId] = input.value
255
+ renderRows()
256
+ })
257
+ })
258
+ })
259
+ }
260
+
261
+ initDataTables()
262
+ document.addEventListener('astro:after-swap', initDataTables)
263
+ </script>
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,398 @@
1
+ ---
2
+ import {
3
+ createDatePicker,
4
+ formatDate,
5
+ datePickerTriggerStyles,
6
+ datePickerDropdownStyles,
7
+ datePickerDayVariants,
8
+ datePickerTimeStyles,
9
+ datePickerTimeInputStyles,
10
+ type CalendarDay,
11
+ } from '../date-picker/index.ts'
12
+ import { cn } from '../shared/index.ts'
13
+
14
+ interface Props extends astroHTML.JSX.HTMLAttributes {
15
+ /** Selected date value (ISO string) */
16
+ value?: string
17
+ /** Minimum selectable date (ISO string) */
18
+ minDate?: string
19
+ /** Maximum selectable date (ISO string) */
20
+ maxDate?: string
21
+ /** Show time selection inputs */
22
+ showTime?: boolean
23
+ /** Date format string */
24
+ format?: string
25
+ /** Placeholder text */
26
+ placeholder?: string
27
+ /** Whether the picker is disabled */
28
+ disabled?: boolean
29
+ }
30
+
31
+ const {
32
+ value,
33
+ minDate,
34
+ maxDate,
35
+ showTime = false,
36
+ format,
37
+ placeholder = 'Select date...',
38
+ disabled = false,
39
+ class: className,
40
+ ...props
41
+ } = Astro.props
42
+
43
+ const parsedValue = value ? new Date(value) : undefined
44
+ const parsedMin = minDate ? new Date(minDate) : undefined
45
+ const parsedMax = maxDate ? new Date(maxDate) : undefined
46
+
47
+ const api = createDatePicker({
48
+ value: parsedValue,
49
+ minDate: parsedMin,
50
+ maxDate: parsedMax,
51
+ showTime,
52
+ format,
53
+ placeholder,
54
+ })
55
+
56
+ const displayValue = api.formatDisplay()
57
+ const DAY_HEADERS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
58
+ const currentMonth = api.state.currentMonth
59
+ const monthLabel = currentMonth.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })
60
+
61
+ function getDayState(day: CalendarDay): 'default' | 'selected' | 'today' | 'disabled' | 'outside' {
62
+ if (day.isDisabled) return 'disabled'
63
+ if (day.isSelected) return 'selected'
64
+ if (day.isToday) return 'today'
65
+ if (!day.isCurrentMonth) return 'outside'
66
+ return 'default'
67
+ }
68
+ ---
69
+
70
+ <div
71
+ data-rfr-datepicker
72
+ data-rfr-datepicker-value={value || ''}
73
+ data-rfr-datepicker-min={minDate || ''}
74
+ data-rfr-datepicker-max={maxDate || ''}
75
+ data-rfr-datepicker-show-time={showTime}
76
+ data-rfr-datepicker-format={format || (showTime ? 'YYYY-MM-DD HH:mm' : 'YYYY-MM-DD')}
77
+ data-rfr-datepicker-placeholder={placeholder}
78
+ data-rfr-datepicker-year={currentMonth.getFullYear()}
79
+ data-rfr-datepicker-month={currentMonth.getMonth()}
80
+ data-state="closed"
81
+ class={cn('relative inline-block', className)}
82
+ {...props}
83
+ >
84
+ <!-- Trigger button -->
85
+ <button
86
+ type="button"
87
+ data-rfr-datepicker-trigger
88
+ class={cn(datePickerTriggerStyles, disabled && 'opacity-50 cursor-not-allowed')}
89
+ aria-expanded="false"
90
+ aria-haspopup="dialog"
91
+ disabled={disabled}
92
+ >{displayValue}</button>
93
+
94
+ <!-- Dropdown (initially hidden) -->
95
+ <div
96
+ data-rfr-datepicker-dropdown
97
+ class={datePickerDropdownStyles}
98
+ role="dialog"
99
+ aria-modal="true"
100
+ hidden
101
+ >
102
+ <!-- Month navigation -->
103
+ <div class="flex items-center justify-between mb-3">
104
+ <button
105
+ type="button"
106
+ data-rfr-datepicker-prev
107
+ class="p-1 hover:bg-accent rounded cursor-pointer"
108
+ aria-label="Previous month"
109
+ >&lsaquo;</button>
110
+ <span data-rfr-datepicker-label class="text-sm font-medium">{monthLabel}</span>
111
+ <button
112
+ type="button"
113
+ data-rfr-datepicker-next
114
+ class="p-1 hover:bg-accent rounded cursor-pointer"
115
+ aria-label="Next month"
116
+ >&rsaquo;</button>
117
+ </div>
118
+
119
+ <!-- Calendar grid -->
120
+ <div class="grid grid-cols-7 gap-0 text-center" role="grid">
121
+ {DAY_HEADERS.map((d) => (
122
+ <div class="text-xs text-muted-foreground py-1 font-medium">{d}</div>
123
+ ))}
124
+ <div data-rfr-datepicker-grid class="contents">
125
+ {api.days.map((day) => {
126
+ const state = getDayState(day)
127
+ return (
128
+ <button
129
+ type="button"
130
+ class={datePickerDayVariants({ state })}
131
+ disabled={day.isDisabled}
132
+ data-rfr-datepicker-day
133
+ data-date={day.date.toISOString()}
134
+ aria-selected={day.isSelected}
135
+ aria-disabled={day.isDisabled}
136
+ >{day.date.getDate()}</button>
137
+ )
138
+ })}
139
+ </div>
140
+ </div>
141
+
142
+ <!-- Time inputs (optional) -->
143
+ {showTime && (
144
+ <div class={datePickerTimeStyles} data-rfr-datepicker-time>
145
+ <span class="text-sm text-muted-foreground">Time:</span>
146
+ <input
147
+ type="number"
148
+ min="0"
149
+ max="23"
150
+ value={parsedValue ? parsedValue.getHours() : 0}
151
+ class={datePickerTimeInputStyles}
152
+ aria-label="Hours"
153
+ data-rfr-datepicker-hours
154
+ />
155
+ <span class="text-muted-foreground">:</span>
156
+ <input
157
+ type="number"
158
+ min="0"
159
+ max="59"
160
+ value={parsedValue ? parsedValue.getMinutes() : 0}
161
+ class={datePickerTimeInputStyles}
162
+ aria-label="Minutes"
163
+ data-rfr-datepicker-minutes
164
+ />
165
+ </div>
166
+ )}
167
+ </div>
168
+ </div>
169
+
170
+ <script>
171
+ const MONTH_NAMES = [
172
+ 'January', 'February', 'March', 'April', 'May', 'June',
173
+ 'July', 'August', 'September', 'October', 'November', 'December',
174
+ ]
175
+ const DAY_VARIANT_DEFAULT = 'inline-flex h-8 w-8 items-center justify-center rounded-md text-sm cursor-pointer hover:bg-accent hover:text-accent-foreground'
176
+ const DAY_VARIANT_SELECTED = 'inline-flex h-8 w-8 items-center justify-center rounded-md text-sm cursor-pointer hover:bg-accent hover:text-accent-foreground bg-primary text-primary-foreground hover:bg-primary/90'
177
+ const DAY_VARIANT_TODAY = 'inline-flex h-8 w-8 items-center justify-center rounded-md text-sm cursor-pointer hover:bg-accent hover:text-accent-foreground border border-accent-foreground'
178
+ const DAY_VARIANT_DISABLED = 'inline-flex h-8 w-8 items-center justify-center rounded-md text-sm cursor-pointer hover:bg-accent hover:text-accent-foreground text-muted-foreground opacity-50 pointer-events-none'
179
+ const DAY_VARIANT_OUTSIDE = 'inline-flex h-8 w-8 items-center justify-center rounded-md text-sm cursor-pointer hover:bg-accent hover:text-accent-foreground text-muted-foreground opacity-30'
180
+
181
+ function isSameDay(a: Date, b: Date): boolean {
182
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate()
183
+ }
184
+
185
+ function padZero(n: number): string {
186
+ return n < 10 ? `0${n}` : `${n}`
187
+ }
188
+
189
+ function formatDateStr(date: Date | null, fmt: string, showTime: boolean): string {
190
+ if (!date) return ''
191
+ let result = fmt
192
+ .replace('YYYY', String(date.getFullYear()))
193
+ .replace('MM', padZero(date.getMonth() + 1))
194
+ .replace('DD', padZero(date.getDate()))
195
+ if (showTime) {
196
+ result = result.replace('HH', padZero(date.getHours())).replace('mm', padZero(date.getMinutes()))
197
+ }
198
+ return result
199
+ }
200
+
201
+ function isDateDisabled(date: Date, minStr: string, maxStr: string): boolean {
202
+ if (minStr) {
203
+ const min = new Date(minStr)
204
+ const startOfMin = new Date(min.getFullYear(), min.getMonth(), min.getDate())
205
+ if (date < startOfMin) return true
206
+ }
207
+ if (maxStr) {
208
+ const max = new Date(maxStr)
209
+ const endOfMax = new Date(max.getFullYear(), max.getMonth(), max.getDate(), 23, 59, 59, 999)
210
+ if (date > endOfMax) return true
211
+ }
212
+ return false
213
+ }
214
+
215
+ function renderDatePickerGrid(root: HTMLElement) {
216
+ const year = parseInt(root.getAttribute('data-rfr-datepicker-year') || '0', 10)
217
+ const month = parseInt(root.getAttribute('data-rfr-datepicker-month') || '0', 10)
218
+ const valueStr = root.getAttribute('data-rfr-datepicker-value') || ''
219
+ const minStr = root.getAttribute('data-rfr-datepicker-min') || ''
220
+ const maxStr = root.getAttribute('data-rfr-datepicker-max') || ''
221
+ const selectedDate = valueStr ? new Date(valueStr) : null
222
+ const today = new Date()
223
+
224
+ const label = root.querySelector<HTMLElement>('[data-rfr-datepicker-label]')
225
+ if (label) label.textContent = `${MONTH_NAMES[month]} ${year}`
226
+
227
+ const grid = root.querySelector<HTMLElement>('[data-rfr-datepicker-grid]')
228
+ if (!grid) return
229
+
230
+ grid.innerHTML = ''
231
+ const first = new Date(year, month, 1)
232
+ const startDow = first.getDay()
233
+ const gridStart = new Date(year, month, 1 - startDow)
234
+
235
+ for (let i = 0; i < 42; i++) {
236
+ const date = new Date(gridStart.getFullYear(), gridStart.getMonth(), gridStart.getDate() + i)
237
+ const isToday = isSameDay(date, today)
238
+ const isSelected = selectedDate ? isSameDay(date, selectedDate) : false
239
+ const isCurrentMonth = date.getMonth() === month
240
+ const isDisabled = isDateDisabled(date, minStr, maxStr)
241
+
242
+ let variant = DAY_VARIANT_DEFAULT
243
+ if (isDisabled) variant = DAY_VARIANT_DISABLED
244
+ else if (isSelected) variant = DAY_VARIANT_SELECTED
245
+ else if (isToday) variant = DAY_VARIANT_TODAY
246
+ else if (!isCurrentMonth) variant = DAY_VARIANT_OUTSIDE
247
+
248
+ const btn = document.createElement('button')
249
+ btn.type = 'button'
250
+ btn.className = variant
251
+ btn.disabled = isDisabled
252
+ btn.setAttribute('data-rfr-datepicker-day', '')
253
+ btn.setAttribute('data-date', date.toISOString())
254
+ btn.setAttribute('aria-selected', String(isSelected))
255
+ btn.setAttribute('aria-disabled', String(isDisabled))
256
+ btn.textContent = String(date.getDate())
257
+ grid.appendChild(btn)
258
+ }
259
+ }
260
+
261
+ function initDatePickers() {
262
+ document.querySelectorAll<HTMLElement>('[data-rfr-datepicker]').forEach((root) => {
263
+ if (root.hasAttribute('data-rfr-datepicker-init')) return
264
+ root.setAttribute('data-rfr-datepicker-init', '')
265
+
266
+ const trigger = root.querySelector<HTMLButtonElement>('[data-rfr-datepicker-trigger]')
267
+ const dropdown = root.querySelector<HTMLElement>('[data-rfr-datepicker-dropdown]')
268
+ const showTime = root.getAttribute('data-rfr-datepicker-show-time') === 'true'
269
+ const fmt = root.getAttribute('data-rfr-datepicker-format') || 'YYYY-MM-DD'
270
+ const placeholder = root.getAttribute('data-rfr-datepicker-placeholder') || 'Select date...'
271
+
272
+ let isOpen = false
273
+
274
+ function setOpen(open: boolean) {
275
+ isOpen = open
276
+ root.setAttribute('data-state', open ? 'open' : 'closed')
277
+ trigger?.setAttribute('aria-expanded', String(open))
278
+ if (dropdown) {
279
+ if (open) {
280
+ dropdown.removeAttribute('hidden')
281
+ renderDatePickerGrid(root)
282
+ } else {
283
+ dropdown.setAttribute('hidden', '')
284
+ }
285
+ }
286
+ }
287
+
288
+ function updateTriggerLabel() {
289
+ const valueStr = root.getAttribute('data-rfr-datepicker-value') || ''
290
+ const date = valueStr ? new Date(valueStr) : null
291
+ if (trigger) {
292
+ trigger.textContent = date ? formatDateStr(date, fmt, showTime) : placeholder
293
+ }
294
+ }
295
+
296
+ // Toggle dropdown
297
+ trigger?.addEventListener('click', () => {
298
+ if (trigger.disabled) return
299
+ setOpen(!isOpen)
300
+ })
301
+
302
+ // Prev month
303
+ root.querySelector('[data-rfr-datepicker-prev]')?.addEventListener('click', () => {
304
+ const year = parseInt(root.getAttribute('data-rfr-datepicker-year') || '0', 10)
305
+ const month = parseInt(root.getAttribute('data-rfr-datepicker-month') || '0', 10)
306
+ const prev = new Date(year, month - 1, 1)
307
+ root.setAttribute('data-rfr-datepicker-year', String(prev.getFullYear()))
308
+ root.setAttribute('data-rfr-datepicker-month', String(prev.getMonth()))
309
+ renderDatePickerGrid(root)
310
+ })
311
+
312
+ // Next month
313
+ root.querySelector('[data-rfr-datepicker-next]')?.addEventListener('click', () => {
314
+ const year = parseInt(root.getAttribute('data-rfr-datepicker-year') || '0', 10)
315
+ const month = parseInt(root.getAttribute('data-rfr-datepicker-month') || '0', 10)
316
+ const next = new Date(year, month + 1, 1)
317
+ root.setAttribute('data-rfr-datepicker-year', String(next.getFullYear()))
318
+ root.setAttribute('data-rfr-datepicker-month', String(next.getMonth()))
319
+ renderDatePickerGrid(root)
320
+ })
321
+
322
+ // Day click (delegated on grid's parent)
323
+ const gridParent = root.querySelector('[role="grid"]')
324
+ gridParent?.addEventListener('click', (e) => {
325
+ const btn = (e.target as HTMLElement).closest<HTMLButtonElement>('[data-rfr-datepicker-day]')
326
+ if (!btn || btn.disabled) return
327
+ const dateStr = btn.getAttribute('data-date')
328
+ if (!dateStr) return
329
+
330
+ const selectedDate = new Date(dateStr)
331
+ // Preserve existing time if showTime
332
+ if (showTime) {
333
+ const hoursInput = root.querySelector<HTMLInputElement>('[data-rfr-datepicker-hours]')
334
+ const minutesInput = root.querySelector<HTMLInputElement>('[data-rfr-datepicker-minutes]')
335
+ if (hoursInput) selectedDate.setHours(parseInt(hoursInput.value, 10) || 0)
336
+ if (minutesInput) selectedDate.setMinutes(parseInt(minutesInput.value, 10) || 0)
337
+ }
338
+
339
+ root.setAttribute('data-rfr-datepicker-value', selectedDate.toISOString())
340
+ updateTriggerLabel()
341
+ renderDatePickerGrid(root)
342
+
343
+ if (!showTime) {
344
+ setOpen(false)
345
+ }
346
+
347
+ root.dispatchEvent(new CustomEvent('rfr-date-change', {
348
+ detail: { date: selectedDate, iso: selectedDate.toISOString() },
349
+ bubbles: true,
350
+ }))
351
+ })
352
+
353
+ // Time input changes
354
+ const hoursInput = root.querySelector<HTMLInputElement>('[data-rfr-datepicker-hours]')
355
+ const minutesInput = root.querySelector<HTMLInputElement>('[data-rfr-datepicker-minutes]')
356
+
357
+ function handleTimeChange() {
358
+ const valueStr = root.getAttribute('data-rfr-datepicker-value') || ''
359
+ const date = valueStr ? new Date(valueStr) : new Date()
360
+ if (hoursInput) {
361
+ const h = parseInt(hoursInput.value, 10)
362
+ if (!isNaN(h) && h >= 0 && h <= 23) date.setHours(h)
363
+ }
364
+ if (minutesInput) {
365
+ const m = parseInt(minutesInput.value, 10)
366
+ if (!isNaN(m) && m >= 0 && m <= 59) date.setMinutes(m)
367
+ }
368
+ root.setAttribute('data-rfr-datepicker-value', date.toISOString())
369
+ updateTriggerLabel()
370
+ root.dispatchEvent(new CustomEvent('rfr-date-change', {
371
+ detail: { date, iso: date.toISOString() },
372
+ bubbles: true,
373
+ }))
374
+ }
375
+
376
+ hoursInput?.addEventListener('change', handleTimeChange)
377
+ minutesInput?.addEventListener('change', handleTimeChange)
378
+
379
+ // Close on outside click
380
+ document.addEventListener('mousedown', (e) => {
381
+ if (isOpen && !root.contains(e.target as Node)) {
382
+ setOpen(false)
383
+ }
384
+ })
385
+
386
+ // Close on Escape
387
+ document.addEventListener('keydown', (e) => {
388
+ if (isOpen && e.key === 'Escape') {
389
+ e.preventDefault()
390
+ setOpen(false)
391
+ }
392
+ })
393
+ })
394
+ }
395
+
396
+ initDatePickers()
397
+ document.addEventListener('astro:after-swap', initDatePickers)
398
+ </script>
@@ -0,0 +1 @@
1
+ export {}