@refraction-ui/astro 0.4.2 → 0.4.5

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 (334) 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 +1 -1
  16. package/dist/astro-ai/index.ts +1 -1
  17. package/dist/astro-animated-text/AnimatedText.astro +1 -1
  18. package/dist/astro-animated-text/TypewriterText.astro +1 -1
  19. package/dist/astro-app-shell/AppShell.astro +1 -1
  20. package/dist/astro-app-shell/AuthShell.astro +1 -1
  21. package/dist/astro-app-shell/AuthShellCard.astro +1 -1
  22. package/dist/astro-app-shell/PageShell.astro +1 -1
  23. package/dist/astro-app-shell/PageShellSection.astro +1 -1
  24. package/dist/astro-app-shell/index.ts +1 -1
  25. package/dist/astro-auth/index.ts +2 -2
  26. package/dist/astro-avatar/Avatar.astro +1 -1
  27. package/dist/astro-avatar/AvatarFallback.astro +1 -1
  28. package/dist/astro-avatar/AvatarImage.astro +1 -1
  29. package/dist/astro-avatar-group/AvatarGroup.astro +1 -1
  30. package/dist/astro-badge/Badge.astro +1 -1
  31. package/dist/astro-bottom-nav/BottomNav.astro +1 -1
  32. package/dist/astro-breadcrumbs/Breadcrumbs.astro +1 -1
  33. package/dist/astro-button/Button.astro +1 -1
  34. package/dist/astro-calendar/Calendar.astro +1 -1
  35. package/dist/astro-card/Card.astro +1 -1
  36. package/dist/astro-card/CardContent.astro +1 -1
  37. package/dist/astro-card/CardDescription.astro +1 -1
  38. package/dist/astro-card/CardFooter.astro +1 -1
  39. package/dist/astro-card/CardHeader.astro +1 -1
  40. package/dist/astro-card/CardTitle.astro +1 -1
  41. package/dist/astro-card-grid/CardGrid.astro +1 -1
  42. package/dist/astro-carousel/Button.astro +1 -1
  43. package/dist/astro-charts/Bars.astro +1 -1
  44. package/dist/astro-charts/Chart.astro +1 -1
  45. package/dist/astro-charts/Circles.astro +1 -1
  46. package/dist/astro-charts/Histogram.astro +1 -1
  47. package/dist/astro-charts/Line.astro +1 -1
  48. package/dist/astro-charts/PieChart.astro +1 -1
  49. package/dist/astro-charts/ScatterPlot.astro +1 -1
  50. package/dist/astro-charts/index.ts +1 -1
  51. package/dist/astro-checkbox/Checkbox.astro +1 -1
  52. package/dist/astro-code-editor/CodeEditor.astro +1 -1
  53. package/dist/astro-collapsible/Collapsible.astro +1 -1
  54. package/dist/astro-collapsible/CollapsibleContent.astro +1 -1
  55. package/dist/astro-command/Command.astro +1 -1
  56. package/dist/astro-command/CommandGroup.astro +1 -1
  57. package/dist/astro-command/CommandInput.astro +1 -1
  58. package/dist/astro-command/CommandItem.astro +1 -1
  59. package/dist/astro-command-input/CommandInput.astro +1 -1
  60. package/dist/astro-content-protection/ContentProtection.astro +1 -1
  61. package/dist/astro-data-table/DataTable.astro +1 -1
  62. package/dist/astro-date-picker/DatePicker.astro +1 -1
  63. package/dist/astro-device-frame/DeviceFrame.astro +1 -1
  64. package/dist/astro-dialog/DialogContent.astro +1 -1
  65. package/dist/astro-dialog/DialogOverlay.astro +1 -1
  66. package/dist/astro-diff-viewer/DiffViewer.astro +1 -1
  67. package/dist/astro-dropdown-menu/DropdownMenuContent.astro +1 -1
  68. package/dist/astro-dropdown-menu/DropdownMenuItem.astro +1 -1
  69. package/dist/astro-emoji-picker/EmojiPicker.astro +1 -1
  70. package/dist/astro-feedback-dialog/FeedbackDialog.astro +1 -1
  71. package/dist/astro-file-upload/FileUpload.astro +1 -1
  72. package/dist/astro-footer/Footer.astro +1 -1
  73. package/dist/astro-inline-editor/InlineEditor.astro +1 -1
  74. package/dist/astro-input/Input.astro +1 -1
  75. package/dist/astro-input-group/InputGroup.astro +1 -1
  76. package/dist/astro-input-group/InputGroupAddon.astro +1 -1
  77. package/dist/astro-input-group/InputGroupButton.astro +1 -1
  78. package/dist/astro-install-prompt/InstallPrompt.astro +1 -1
  79. package/dist/astro-keyboard-shortcut/ShortcutBadge.astro +1 -1
  80. package/dist/astro-language-selector/LanguageSelector.astro +1 -1
  81. package/dist/astro-link-card/LinkCard.astro +1 -1
  82. package/dist/astro-markdown-renderer/MarkdownRenderer.astro +1 -1
  83. package/dist/astro-mobile-nav/MobileNav.astro +1 -1
  84. package/dist/astro-mobile-nav/MobileNavLink.astro +1 -1
  85. package/dist/astro-mobile-nav/MobileNavTrigger.astro +1 -1
  86. package/dist/astro-navbar/Navbar.astro +1 -1
  87. package/dist/astro-otp-input/OtpInput.astro +1 -1
  88. package/dist/astro-payment/Payment.astro +1 -1
  89. package/dist/astro-popover/PopoverContent.astro +1 -1
  90. package/dist/astro-presence-indicator/PresenceIndicator.astro +1 -1
  91. package/dist/astro-progress-display/BadgeDisplay.astro +1 -1
  92. package/dist/astro-progress-display/ProgressBar.astro +1 -1
  93. package/dist/astro-progress-display/StatsGrid.astro +1 -1
  94. package/dist/astro-radio/RadioGroup.astro +1 -1
  95. package/dist/astro-radio/RadioItem.astro +1 -1
  96. package/dist/astro-reaction-bar/ReactionBar.astro +1 -1
  97. package/dist/astro-resizable-layout/ResizableDivider.astro +1 -1
  98. package/dist/astro-resizable-layout/ResizableLayout.astro +1 -1
  99. package/dist/astro-resizable-layout/ResizablePane.astro +1 -1
  100. package/dist/astro-resizable-layout/index.ts +1 -1
  101. package/dist/astro-rich-editor/index.ts +2 -2
  102. package/dist/astro-search-bar/SearchBar.astro +1 -1
  103. package/dist/astro-search-bar/SearchResults.astro +1 -1
  104. package/dist/astro-select/Select.astro +1 -1
  105. package/dist/astro-select/SelectContent.astro +1 -1
  106. package/dist/astro-select/SelectItem.astro +1 -1
  107. package/dist/astro-select/SelectTrigger.astro +1 -1
  108. package/dist/astro-sidebar/Sidebar.astro +1 -1
  109. package/dist/astro-skeleton/Skeleton.astro +1 -1
  110. package/dist/astro-slide-viewer/SlideViewer.astro +1 -1
  111. package/dist/astro-status-indicator/StatusIndicator.astro +1 -1
  112. package/dist/astro-switch/Switch.astro +1 -1
  113. package/dist/astro-table-of-contents/TableOfContents.astro +1 -1
  114. package/dist/astro-tabs/Tabs.astro +1 -1
  115. package/dist/astro-tabs/TabsList.astro +1 -1
  116. package/dist/astro-tabs/TabsTrigger.astro +1 -1
  117. package/dist/astro-textarea/Textarea.astro +1 -1
  118. package/dist/astro-theme/ThemeScript.astro +1 -1
  119. package/dist/astro-thread-view/ThreadView.astro +1 -1
  120. package/dist/astro-toast/Toast.astro +1 -1
  121. package/dist/astro-tooltip/TooltipContent.astro +1 -1
  122. package/dist/astro-version-selector/VersionSelector.astro +1 -1
  123. package/dist/astro-video-player/VideoPlayer.astro +1 -1
  124. package/dist/auth/adapters/mock.ts +74 -0
  125. package/dist/auth/auth-machine.ts +120 -0
  126. package/dist/auth/index.ts +22 -0
  127. package/dist/auth/rbac.ts +44 -0
  128. package/dist/auth/types.ts +44 -0
  129. package/dist/avatar/avatar.styles.ts +47 -0
  130. package/dist/avatar/avatar.ts +73 -0
  131. package/dist/avatar/index.ts +15 -0
  132. package/dist/avatar-group/avatar-group.styles.ts +63 -0
  133. package/dist/avatar-group/avatar-group.ts +106 -0
  134. package/dist/avatar-group/index.ts +18 -0
  135. package/dist/badge/badge.styles.ts +24 -0
  136. package/dist/badge/badge.ts +48 -0
  137. package/dist/badge/index.ts +10 -0
  138. package/dist/bottom-nav/bottom-nav.styles.ts +18 -0
  139. package/dist/bottom-nav/bottom-nav.ts +33 -0
  140. package/dist/bottom-nav/index.ts +2 -0
  141. package/dist/breadcrumbs/breadcrumbs.styles.ts +20 -0
  142. package/dist/breadcrumbs/breadcrumbs.ts +72 -0
  143. package/dist/breadcrumbs/index.ts +8 -0
  144. package/dist/button/button.styles.ts +38 -0
  145. package/dist/button/button.ts +64 -0
  146. package/dist/button/index.ts +10 -0
  147. package/dist/calendar/calendar.styles.ts +21 -0
  148. package/dist/calendar/calendar.ts +202 -0
  149. package/dist/calendar/index.ts +9 -0
  150. package/dist/callout/callout.ts +1 -0
  151. package/dist/callout/index.ts +1 -0
  152. package/dist/card/card.styles.ts +55 -0
  153. package/dist/card/card.ts +45 -0
  154. package/dist/card/index.ts +20 -0
  155. package/dist/card-grid/card-grid.ts +9 -0
  156. package/dist/card-grid/index.ts +1 -0
  157. package/dist/carousel/index.ts +1 -0
  158. package/dist/charts/axis.ts +50 -0
  159. package/dist/charts/chart.ts +73 -0
  160. package/dist/charts/colorblind.ts +100 -0
  161. package/dist/charts/data.ts +72 -0
  162. package/dist/charts/geometry.ts +54 -0
  163. package/dist/charts/index.ts +61 -0
  164. package/dist/charts/scales.ts +151 -0
  165. package/dist/checkbox/checkbox.styles.ts +33 -0
  166. package/dist/checkbox/checkbox.ts +73 -0
  167. package/dist/checkbox/index.ts +10 -0
  168. package/dist/code-block/code-block.ts +1 -0
  169. package/dist/code-block/index.ts +1 -0
  170. package/dist/code-editor/code-editor.styles.ts +32 -0
  171. package/dist/code-editor/code-editor.ts +140 -0
  172. package/dist/code-editor/index.ts +9 -0
  173. package/dist/collapsible/collapsible.styles.ts +14 -0
  174. package/dist/collapsible/collapsible.ts +93 -0
  175. package/dist/collapsible/index.ts +7 -0
  176. package/dist/command/command.styles.ts +27 -0
  177. package/dist/command/command.ts +179 -0
  178. package/dist/command/index.ts +14 -0
  179. package/dist/command-input/command-input.ts +176 -0
  180. package/dist/command-input/index.ts +1 -0
  181. package/dist/content-protection/content-protection.styles.ts +9 -0
  182. package/dist/content-protection/content-protection.ts +68 -0
  183. package/dist/content-protection/index.ts +8 -0
  184. package/dist/data-table/data-table.styles.ts +55 -0
  185. package/dist/data-table/data-table.ts +183 -0
  186. package/dist/data-table/index.ts +15 -0
  187. package/dist/date-picker/date-picker.styles.ts +31 -0
  188. package/dist/date-picker/date-picker.ts +333 -0
  189. package/dist/date-picker/index.ts +18 -0
  190. package/dist/device-frame/device-frame.styles.ts +21 -0
  191. package/dist/device-frame/device-frame.ts +112 -0
  192. package/dist/device-frame/index.ts +10 -0
  193. package/dist/dialog/dialog.styles.ts +8 -0
  194. package/dist/dialog/dialog.ts +133 -0
  195. package/dist/dialog/index.ts +8 -0
  196. package/dist/diff-viewer/diff-viewer.styles.ts +124 -0
  197. package/dist/diff-viewer/diff-viewer.ts +255 -0
  198. package/dist/diff-viewer/index.ts +20 -0
  199. package/dist/dropdown-menu/dropdown-menu.styles.ts +9 -0
  200. package/dist/dropdown-menu/dropdown-menu.ts +139 -0
  201. package/dist/dropdown-menu/index.ts +9 -0
  202. package/dist/emoji-picker/emoji-data.ts +282 -0
  203. package/dist/emoji-picker/emoji-picker.styles.ts +32 -0
  204. package/dist/emoji-picker/emoji-picker.ts +165 -0
  205. package/dist/emoji-picker/index.ts +25 -0
  206. package/dist/feedback-dialog/feedback-dialog.styles.ts +15 -0
  207. package/dist/feedback-dialog/feedback-dialog.ts +147 -0
  208. package/dist/feedback-dialog/index.ts +11 -0
  209. package/dist/file-upload/file-upload.styles.ts +30 -0
  210. package/dist/file-upload/file-upload.ts +260 -0
  211. package/dist/file-upload/index.ts +19 -0
  212. package/dist/footer/footer.styles.ts +5 -0
  213. package/dist/footer/footer.ts +32 -0
  214. package/dist/footer/index.ts +9 -0
  215. package/dist/index.ts +1 -1
  216. package/dist/inline-editor/index.ts +13 -0
  217. package/dist/inline-editor/inline-editor.styles.ts +42 -0
  218. package/dist/inline-editor/inline-editor.ts +96 -0
  219. package/dist/input/index.ts +9 -0
  220. package/dist/input/input.styles.ts +15 -0
  221. package/dist/input/input.ts +84 -0
  222. package/dist/input-group/index.ts +13 -0
  223. package/dist/input-group/input-group.styles.ts +50 -0
  224. package/dist/input-group/input-group.ts +44 -0
  225. package/dist/install-prompt/index.ts +9 -0
  226. package/dist/install-prompt/install-prompt.styles.ts +5 -0
  227. package/dist/install-prompt/install-prompt.ts +68 -0
  228. package/dist/keyboard-shortcut/index.ts +12 -0
  229. package/dist/keyboard-shortcut/keyboard-shortcut.styles.ts +8 -0
  230. package/dist/keyboard-shortcut/keyboard-shortcut.ts +153 -0
  231. package/dist/language-selector/index.ts +8 -0
  232. package/dist/language-selector/language-selector.styles.ts +28 -0
  233. package/dist/language-selector/language-selector.ts +149 -0
  234. package/dist/link-card/index.ts +1 -0
  235. package/dist/link-card/link-card.ts +9 -0
  236. package/dist/markdown-renderer/index.ts +8 -0
  237. package/dist/markdown-renderer/markdown-renderer.styles.ts +31 -0
  238. package/dist/markdown-renderer/markdown-renderer.ts +251 -0
  239. package/dist/mobile-nav/index.ts +14 -0
  240. package/dist/mobile-nav/mobile-nav.styles.ts +39 -0
  241. package/dist/mobile-nav/mobile-nav.ts +74 -0
  242. package/dist/navbar/index.ts +9 -0
  243. package/dist/navbar/navbar.styles.ts +29 -0
  244. package/dist/navbar/navbar.ts +39 -0
  245. package/dist/otp-input/index.ts +13 -0
  246. package/dist/otp-input/otp-input.styles.ts +51 -0
  247. package/dist/otp-input/otp-input.ts +198 -0
  248. package/dist/pagination/index.ts +1 -0
  249. package/dist/payment/index.ts +1 -0
  250. package/dist/payment/payment.ts +16 -0
  251. package/dist/popover/index.ts +7 -0
  252. package/dist/popover/popover.styles.ts +16 -0
  253. package/dist/popover/popover.ts +89 -0
  254. package/dist/presence-indicator/index.ts +14 -0
  255. package/dist/presence-indicator/presence-indicator.styles.ts +29 -0
  256. package/dist/presence-indicator/presence-indicator.ts +63 -0
  257. package/dist/progress-display/index.ts +15 -0
  258. package/dist/progress-display/progress-display.styles.ts +72 -0
  259. package/dist/progress-display/progress-display.ts +60 -0
  260. package/dist/radio/index.ts +8 -0
  261. package/dist/radio/radio.styles.ts +34 -0
  262. package/dist/radio/radio.ts +70 -0
  263. package/dist/reaction-bar/index.ts +14 -0
  264. package/dist/reaction-bar/reaction-bar.styles.ts +23 -0
  265. package/dist/reaction-bar/reaction-bar.ts +87 -0
  266. package/dist/resizable-layout/index.ts +12 -0
  267. package/dist/resizable-layout/resizable-layout.styles.ts +50 -0
  268. package/dist/resizable-layout/resizable-layout.ts +139 -0
  269. package/dist/rich-editor/editor.ts +342 -0
  270. package/dist/rich-editor/emoji.ts +175 -0
  271. package/dist/rich-editor/history.ts +79 -0
  272. package/dist/rich-editor/index.ts +106 -0
  273. package/dist/rich-editor/markdown-shortcuts.ts +248 -0
  274. package/dist/rich-editor/mentions.ts +162 -0
  275. package/dist/rich-editor/model.ts +206 -0
  276. package/dist/rich-editor/operations.ts +772 -0
  277. package/dist/rich-editor/selection.ts +157 -0
  278. package/dist/rich-editor/serialization.ts +711 -0
  279. package/dist/rich-editor/slash-commands.ts +212 -0
  280. package/dist/search-bar/index.ts +7 -0
  281. package/dist/search-bar/search-bar.styles.ts +29 -0
  282. package/dist/search-bar/search-bar.ts +130 -0
  283. package/dist/select/index.ts +13 -0
  284. package/dist/select/select.styles.ts +52 -0
  285. package/dist/select/select.ts +152 -0
  286. package/dist/sidebar/index.ts +9 -0
  287. package/dist/sidebar/sidebar.styles.ts +27 -0
  288. package/dist/sidebar/sidebar.ts +59 -0
  289. package/dist/skeleton/index.ts +8 -0
  290. package/dist/skeleton/skeleton.styles.ts +16 -0
  291. package/dist/skeleton/skeleton.ts +39 -0
  292. package/dist/skip-to-content/index.ts +1 -0
  293. package/dist/skip-to-content/skip-to-content.ts +1 -0
  294. package/dist/slide-viewer/index.ts +16 -0
  295. package/dist/slide-viewer/slide-viewer.styles.ts +57 -0
  296. package/dist/slide-viewer/slide-viewer.ts +152 -0
  297. package/dist/slider/index.ts +1 -0
  298. package/dist/slider/slider.ts +2 -0
  299. package/dist/status-indicator/index.ts +15 -0
  300. package/dist/status-indicator/status-indicator.styles.ts +41 -0
  301. package/dist/status-indicator/status-indicator.ts +66 -0
  302. package/dist/steps/index.ts +1 -0
  303. package/dist/steps/steps.ts +1 -0
  304. package/dist/switch/index.ts +7 -0
  305. package/dist/switch/switch.styles.ts +55 -0
  306. package/dist/switch/switch.ts +63 -0
  307. package/dist/table-of-contents/index.ts +1 -0
  308. package/dist/table-of-contents/table-of-contents.ts +37 -0
  309. package/dist/tabs/index.ts +8 -0
  310. package/dist/tabs/tabs.styles.ts +9 -0
  311. package/dist/tabs/tabs.ts +133 -0
  312. package/dist/textarea/index.ts +7 -0
  313. package/dist/textarea/textarea.styles.ts +15 -0
  314. package/dist/textarea/textarea.ts +59 -0
  315. package/dist/theme/dom-adapters.ts +60 -0
  316. package/dist/theme/index.ts +18 -0
  317. package/dist/theme/theme-machine.ts +130 -0
  318. package/dist/theme/theme-script.ts +18 -0
  319. package/dist/thread-view/index.ts +26 -0
  320. package/dist/thread-view/thread-view.styles.ts +35 -0
  321. package/dist/thread-view/thread-view.ts +176 -0
  322. package/dist/toast/index.ts +13 -0
  323. package/dist/toast/toast.styles.ts +19 -0
  324. package/dist/toast/toast.ts +203 -0
  325. package/dist/tooltip/index.ts +7 -0
  326. package/dist/tooltip/tooltip.styles.ts +16 -0
  327. package/dist/tooltip/tooltip.ts +109 -0
  328. package/dist/version-selector/index.ts +12 -0
  329. package/dist/version-selector/version-selector.styles.ts +41 -0
  330. package/dist/version-selector/version-selector.ts +136 -0
  331. package/dist/video-player/index.ts +12 -0
  332. package/dist/video-player/video-player.styles.ts +42 -0
  333. package/dist/video-player/video-player.ts +100 -0
  334. package/package.json +1 -1
@@ -0,0 +1,51 @@
1
+ import { cva } from '../shared/index.ts'
2
+ import type { TokenContract } from '../shared/index.ts'
3
+
4
+ export const otpInputTokens: TokenContract = {
5
+ name: 'otp-input',
6
+ tokens: {
7
+ bg: { variable: '--rfr-otp-bg', fallback: 'hsl(var(--background))' },
8
+ fg: { variable: '--rfr-otp-fg', fallback: 'hsl(var(--foreground))' },
9
+ border: { variable: '--rfr-otp-border', fallback: 'hsl(var(--border))' },
10
+ 'border-filled': { variable: '--rfr-otp-border-filled', fallback: 'hsl(var(--primary))' },
11
+ ring: { variable: '--rfr-otp-ring', fallback: 'hsl(var(--ring))' },
12
+ },
13
+ }
14
+
15
+ export const otpInputContainerVariants = cva({
16
+ base: 'flex items-center gap-2',
17
+ variants: {
18
+ size: {
19
+ sm: 'gap-1.5',
20
+ default: 'gap-2',
21
+ lg: 'gap-3',
22
+ },
23
+ },
24
+ defaultVariants: {
25
+ size: 'default',
26
+ },
27
+ })
28
+
29
+ export const otpInputSlotVariants = cva({
30
+ base: 'relative flex items-center justify-center rounded-md border border-input bg-background text-center font-mono shadow-sm transition-all',
31
+ variants: {
32
+ size: {
33
+ sm: 'h-8 w-8 text-sm',
34
+ default: 'h-10 w-10 text-base',
35
+ lg: 'h-12 w-12 text-lg',
36
+ },
37
+ focused: {
38
+ true: 'ring-2 ring-ring ring-offset-background',
39
+ false: '',
40
+ },
41
+ filled: {
42
+ true: 'border-primary',
43
+ false: '',
44
+ },
45
+ },
46
+ defaultVariants: {
47
+ size: 'default',
48
+ focused: 'false',
49
+ filled: 'false',
50
+ },
51
+ })
@@ -0,0 +1,198 @@
1
+ import type { AccessibilityProps, KeyboardHandlerMap } from '../shared/index.ts'
2
+ import { Keys } from '../shared/index.ts'
3
+
4
+ export type OtpInputType = 'number' | 'text'
5
+
6
+ export interface OtpInputProps {
7
+ length?: number
8
+ value?: string
9
+ autoFocus?: boolean
10
+ type?: OtpInputType
11
+ disabled?: boolean
12
+ }
13
+
14
+ export interface OtpSlotProps {
15
+ ariaProps: Partial<AccessibilityProps>
16
+ dataAttributes: Record<string, string>
17
+ inputProps: {
18
+ maxLength: number
19
+ inputMode: string
20
+ pattern?: string
21
+ autoComplete: string
22
+ disabled: boolean
23
+ }
24
+ }
25
+
26
+ export interface OtpInputAPI {
27
+ /** Current state */
28
+ state: {
29
+ values: string[]
30
+ focusedIndex: number
31
+ length: number
32
+ disabled: boolean
33
+ }
34
+ /** Set the value at a specific index */
35
+ setValue: (index: number, char: string) => string[]
36
+ /** Get the combined OTP string */
37
+ getValue: () => string
38
+ /** Move focus in a direction, returns new index */
39
+ moveFocus: (direction: 'left' | 'right') => number
40
+ /** Get aria/input props for a specific slot */
41
+ getSlotProps: (index: number) => OtpSlotProps
42
+ /** Keyboard handlers factory for a specific slot */
43
+ getKeyboardHandlers: (
44
+ index: number,
45
+ callbacks?: {
46
+ onMoveFocus?: (index: number) => void
47
+ onSetValue?: (index: number, values: string[]) => void
48
+ },
49
+ ) => KeyboardHandlerMap
50
+ /** Parse a paste string into values array */
51
+ parsePaste: (text: string) => string[]
52
+ /** Root container ARIA props */
53
+ rootAriaProps: Partial<AccessibilityProps>
54
+ /** Whether interaction should be blocked */
55
+ isInteractive: boolean
56
+ }
57
+
58
+ export function createOtpInput(props: OtpInputProps = {}): OtpInputAPI {
59
+ const {
60
+ length = 6,
61
+ value = '',
62
+ autoFocus = false,
63
+ type = 'number',
64
+ disabled = false,
65
+ } = props
66
+
67
+ const isInteractive = !disabled
68
+
69
+ // Initialize values from the provided value string
70
+ const values: string[] = Array.from({ length }, (_, i) => value.charAt(i) || '')
71
+ let focusedIndex = autoFocus ? 0 : -1
72
+
73
+ const rootAriaProps: Partial<AccessibilityProps> = {
74
+ role: 'group',
75
+ 'aria-label': 'One-time password input',
76
+ }
77
+
78
+ function setValue(index: number, char: string): string[] {
79
+ if (index < 0 || index >= length) return [...values]
80
+ const filtered = type === 'number' ? char.replace(/[^0-9]/g, '') : char
81
+ const newValues = [...values]
82
+ newValues[index] = filtered.charAt(0) || ''
83
+ // Update internal state
84
+ for (let i = 0; i < length; i++) {
85
+ values[i] = newValues[i]
86
+ }
87
+ return newValues
88
+ }
89
+
90
+ function getValue(): string {
91
+ return values.join('')
92
+ }
93
+
94
+ function moveFocus(direction: 'left' | 'right'): number {
95
+ if (direction === 'left') {
96
+ focusedIndex = Math.max(0, focusedIndex - 1)
97
+ } else {
98
+ focusedIndex = Math.min(length - 1, focusedIndex + 1)
99
+ }
100
+ return focusedIndex
101
+ }
102
+
103
+ function getSlotProps(index: number): OtpSlotProps {
104
+ const isFocused = index === focusedIndex
105
+ const isFilled = values[index] !== ''
106
+
107
+ const ariaProps: Partial<AccessibilityProps> = {
108
+ 'aria-label': `Digit ${index + 1} of ${length}`,
109
+ }
110
+
111
+ const dataAttributes: Record<string, string> = {
112
+ 'data-slot': 'otp-slot',
113
+ }
114
+ if (isFocused) {
115
+ dataAttributes['data-focused'] = ''
116
+ }
117
+ if (isFilled) {
118
+ dataAttributes['data-filled'] = ''
119
+ }
120
+
121
+ const inputProps = {
122
+ maxLength: 1,
123
+ inputMode: type === 'number' ? 'numeric' : 'text',
124
+ pattern: type === 'number' ? '[0-9]*' : undefined,
125
+ autoComplete: index === 0 ? 'one-time-code' : 'off',
126
+ disabled,
127
+ }
128
+
129
+ return { ariaProps, dataAttributes, inputProps }
130
+ }
131
+
132
+ function getKeyboardHandlers(
133
+ index: number,
134
+ callbacks?: {
135
+ onMoveFocus?: (index: number) => void
136
+ onSetValue?: (index: number, values: string[]) => void
137
+ },
138
+ ): KeyboardHandlerMap {
139
+ if (!isInteractive) {
140
+ return {
141
+ [Keys.Backspace]: (e) => e.preventDefault(),
142
+ [Keys.ArrowLeft]: (e) => e.preventDefault(),
143
+ [Keys.ArrowRight]: (e) => e.preventDefault(),
144
+ }
145
+ }
146
+
147
+ return {
148
+ [Keys.Backspace]: (e) => {
149
+ e.preventDefault()
150
+ if (values[index]) {
151
+ const newValues = setValue(index, '')
152
+ callbacks?.onSetValue?.(index, newValues)
153
+ } else if (index > 0) {
154
+ focusedIndex = index - 1
155
+ const newValues = setValue(index - 1, '')
156
+ callbacks?.onSetValue?.(index - 1, newValues)
157
+ callbacks?.onMoveFocus?.(focusedIndex)
158
+ }
159
+ },
160
+ [Keys.ArrowLeft]: (e) => {
161
+ e.preventDefault()
162
+ if (index > 0) {
163
+ focusedIndex = index - 1
164
+ callbacks?.onMoveFocus?.(focusedIndex)
165
+ }
166
+ },
167
+ [Keys.ArrowRight]: (e) => {
168
+ e.preventDefault()
169
+ if (index < length - 1) {
170
+ focusedIndex = index + 1
171
+ callbacks?.onMoveFocus?.(focusedIndex)
172
+ }
173
+ },
174
+ }
175
+ }
176
+
177
+ function parsePaste(text: string): string[] {
178
+ const chars = type === 'number' ? text.replace(/[^0-9]/g, '') : text
179
+ return Array.from({ length }, (_, i) => chars.charAt(i) || '')
180
+ }
181
+
182
+ return {
183
+ state: {
184
+ values,
185
+ focusedIndex,
186
+ length,
187
+ disabled,
188
+ },
189
+ setValue,
190
+ getValue,
191
+ moveFocus,
192
+ getSlotProps,
193
+ getKeyboardHandlers,
194
+ parsePaste,
195
+ rootAriaProps,
196
+ isInteractive,
197
+ }
198
+ }
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1 @@
1
+ export * from './payment.js';
@@ -0,0 +1,16 @@
1
+ export interface PaymentProps {
2
+ disabled?: boolean;
3
+ }
4
+
5
+ export interface PaymentAPI {
6
+ props: PaymentProps;
7
+ }
8
+
9
+ export function createPayment(props: PaymentProps = {}): PaymentAPI {
10
+ return {
11
+ props: {
12
+ ...props,
13
+ 'data-slot': 'payment',
14
+ } as PaymentProps & Record<string, unknown>,
15
+ };
16
+ }
@@ -0,0 +1,7 @@
1
+ export {
2
+ createPopover,
3
+ type PopoverProps,
4
+ type PopoverAPI,
5
+ } from './popover.js'
6
+
7
+ export { popoverContentVariants } from './popover.styles.js'
@@ -0,0 +1,16 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const popoverContentVariants = cva({
4
+ base: 'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none',
5
+ variants: {
6
+ side: {
7
+ top: 'animate-slide-down-fade',
8
+ right: 'animate-slide-left-fade',
9
+ bottom: 'animate-slide-up-fade',
10
+ left: 'animate-slide-right-fade',
11
+ },
12
+ },
13
+ defaultVariants: {
14
+ side: 'bottom',
15
+ },
16
+ })
@@ -0,0 +1,89 @@
1
+ import type { AccessibilityProps, Side, KeyboardHandlerMap } from '../shared/index.ts'
2
+ import { generateId, Keys, createKeyboardHandler } from '../shared/index.ts'
3
+
4
+ export interface PopoverProps {
5
+ open?: boolean
6
+ defaultOpen?: boolean
7
+ onOpenChange?: (open: boolean) => void
8
+ placement?: Side
9
+ }
10
+
11
+ export interface PopoverAPI {
12
+ /** Current open state */
13
+ state: { open: boolean }
14
+ /** Props to spread on the trigger element */
15
+ triggerProps: Partial<AccessibilityProps> & {
16
+ 'aria-expanded': boolean
17
+ 'aria-controls': string
18
+ 'aria-haspopup': 'dialog'
19
+ }
20
+ /** Props to spread on the content element */
21
+ contentProps: {
22
+ role: 'dialog'
23
+ id: string
24
+ }
25
+ /** Resolved placement */
26
+ placement: Side
27
+ /** Open the popover */
28
+ open: () => void
29
+ /** Close the popover */
30
+ close: () => void
31
+ /** Toggle the popover */
32
+ toggle: () => void
33
+ /** Keyboard handler map (Escape to close) */
34
+ keyboardHandlers: KeyboardHandlerMap
35
+ /** Pre-built keyboard event handler */
36
+ handleKeyDown: (event: KeyboardEvent) => void
37
+ }
38
+
39
+ export function createPopover(props: PopoverProps = {}): PopoverAPI {
40
+ const {
41
+ open: controlledOpen,
42
+ defaultOpen = false,
43
+ onOpenChange,
44
+ placement = 'bottom',
45
+ } = props
46
+
47
+ const contentId = generateId('rfr-popover')
48
+
49
+ let isOpen = controlledOpen ?? defaultOpen
50
+
51
+ const state = { open: isOpen }
52
+
53
+ function setOpen(value: boolean) {
54
+ isOpen = value
55
+ state.open = value
56
+ onOpenChange?.(value)
57
+ }
58
+
59
+ const triggerProps = {
60
+ 'aria-expanded': isOpen,
61
+ 'aria-controls': contentId,
62
+ 'aria-haspopup': 'dialog' as const,
63
+ }
64
+
65
+ const contentProps = {
66
+ role: 'dialog' as const,
67
+ id: contentId,
68
+ }
69
+
70
+ const keyboardHandlers: KeyboardHandlerMap = {
71
+ [Keys.Escape]: () => {
72
+ setOpen(false)
73
+ },
74
+ }
75
+
76
+ const handleKeyDown = createKeyboardHandler(keyboardHandlers)
77
+
78
+ return {
79
+ state,
80
+ triggerProps,
81
+ contentProps,
82
+ placement,
83
+ open: () => setOpen(true),
84
+ close: () => setOpen(false),
85
+ toggle: () => setOpen(!isOpen),
86
+ keyboardHandlers,
87
+ handleKeyDown,
88
+ }
89
+ }
@@ -0,0 +1,14 @@
1
+ export {
2
+ createPresence,
3
+ STATUS_COLORS,
4
+ STATUS_LABELS,
5
+ type PresenceProps,
6
+ type PresenceAPI,
7
+ type PresenceStatus,
8
+ } from './presence-indicator.js'
9
+
10
+ export {
11
+ presenceDotVariants,
12
+ presenceContainerStyles,
13
+ presenceLabelStyles,
14
+ } from './presence-indicator.styles.js'
@@ -0,0 +1,29 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const presenceDotVariants = cva({
4
+ base: 'inline-block rounded-full',
5
+ variants: {
6
+ status: {
7
+ online: 'bg-green-500',
8
+ offline: 'bg-gray-400',
9
+ away: 'bg-yellow-500',
10
+ busy: 'bg-red-500',
11
+ dnd: 'bg-red-500',
12
+ },
13
+ size: {
14
+ sm: 'h-2 w-2',
15
+ md: 'h-2.5 w-2.5',
16
+ lg: 'h-3 w-3',
17
+ },
18
+ },
19
+ defaultVariants: {
20
+ status: 'offline',
21
+ size: 'md',
22
+ },
23
+ })
24
+
25
+ export const presenceContainerStyles =
26
+ 'inline-flex items-center gap-1.5'
27
+
28
+ export const presenceLabelStyles =
29
+ 'text-sm text-muted-foreground'
@@ -0,0 +1,63 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+
3
+ export type PresenceStatus = 'online' | 'offline' | 'away' | 'busy' | 'dnd'
4
+
5
+ export interface PresenceProps {
6
+ /** The presence status to display */
7
+ status: PresenceStatus
8
+ /** Show a text label alongside the indicator */
9
+ showLabel?: boolean
10
+ /** Custom label override */
11
+ label?: string
12
+ }
13
+
14
+ export interface PresenceAPI {
15
+ /** ARIA attributes for the indicator */
16
+ ariaProps: Partial<AccessibilityProps> & Record<string, unknown>
17
+ /** CSS color for the status dot */
18
+ color: string
19
+ /** Human-readable label for the status */
20
+ label: string
21
+ /** Whether to show the label text */
22
+ showLabel: boolean
23
+ /** The current status */
24
+ status: PresenceStatus
25
+ }
26
+
27
+ const STATUS_COLORS: Record<PresenceStatus, string> = {
28
+ online: 'green',
29
+ offline: 'gray',
30
+ away: 'yellow',
31
+ busy: 'red',
32
+ dnd: 'red',
33
+ }
34
+
35
+ const STATUS_LABELS: Record<PresenceStatus, string> = {
36
+ online: 'Online',
37
+ offline: 'Offline',
38
+ away: 'Away',
39
+ busy: 'Busy',
40
+ dnd: 'Do Not Disturb',
41
+ }
42
+
43
+ export { STATUS_COLORS, STATUS_LABELS }
44
+
45
+ export function createPresence(props: PresenceProps): PresenceAPI {
46
+ const { status, showLabel: showLabelProp = false, label: labelOverride } = props
47
+
48
+ const color = STATUS_COLORS[status]
49
+ const label = labelOverride ?? STATUS_LABELS[status]
50
+
51
+ const ariaProps: Partial<AccessibilityProps> & Record<string, unknown> = {
52
+ role: 'status',
53
+ 'aria-label': label,
54
+ }
55
+
56
+ return {
57
+ ariaProps,
58
+ color,
59
+ label,
60
+ showLabel: showLabelProp,
61
+ status,
62
+ }
63
+ }
@@ -0,0 +1,15 @@
1
+ export {
2
+ createProgressDisplay,
3
+ type StatCardData,
4
+ type BadgeData,
5
+ type ProgressDisplayProps,
6
+ type ProgressDisplayAPI,
7
+ } from './progress-display.js'
8
+
9
+ export {
10
+ statsGridVariants,
11
+ statCardVariants,
12
+ badgeGridVariants,
13
+ badgeItemVariants,
14
+ progressBarVariants,
15
+ } from './progress-display.styles.js'
@@ -0,0 +1,72 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const statsGridVariants = cva({
4
+ base: 'grid gap-4',
5
+ variants: {
6
+ columns: {
7
+ '2': 'grid-cols-2',
8
+ '3': 'grid-cols-3',
9
+ '4': 'grid-cols-4',
10
+ },
11
+ },
12
+ defaultVariants: {
13
+ columns: '3',
14
+ },
15
+ })
16
+
17
+ export const statCardVariants = cva({
18
+ base: 'rounded-lg border p-4 text-center shadow-sm',
19
+ variants: {
20
+ color: {
21
+ default: 'bg-card text-card-foreground',
22
+ primary: 'bg-primary/10 text-primary border-primary/20',
23
+ success: 'bg-green-500/10 text-green-700 border-green-500/20',
24
+ warning: 'bg-yellow-500/10 text-yellow-700 border-yellow-500/20',
25
+ destructive: 'bg-destructive/10 text-destructive border-destructive/20',
26
+ },
27
+ },
28
+ defaultVariants: {
29
+ color: 'default',
30
+ },
31
+ })
32
+
33
+ export const badgeGridVariants = cva({
34
+ base: 'grid gap-4',
35
+ variants: {
36
+ columns: {
37
+ '3': 'grid-cols-3',
38
+ '4': 'grid-cols-4',
39
+ '5': 'grid-cols-5',
40
+ },
41
+ },
42
+ defaultVariants: {
43
+ columns: '4',
44
+ },
45
+ })
46
+
47
+ export const badgeItemVariants = cva({
48
+ base: 'flex flex-col items-center gap-2 rounded-lg border p-4 text-center transition-opacity',
49
+ variants: {
50
+ state: {
51
+ unlocked: 'opacity-100 bg-card',
52
+ locked: 'opacity-50 bg-muted grayscale',
53
+ },
54
+ },
55
+ defaultVariants: {
56
+ state: 'locked',
57
+ },
58
+ })
59
+
60
+ export const progressBarVariants = cva({
61
+ base: 'h-2 w-full overflow-hidden rounded-full bg-secondary',
62
+ variants: {
63
+ size: {
64
+ sm: 'h-1',
65
+ md: 'h-2',
66
+ lg: 'h-3',
67
+ },
68
+ },
69
+ defaultVariants: {
70
+ size: 'md',
71
+ },
72
+ })
@@ -0,0 +1,60 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+
3
+ export interface StatCardData {
4
+ label: string
5
+ value: number
6
+ icon?: string
7
+ color?: string
8
+ }
9
+
10
+ export interface BadgeData {
11
+ name: string
12
+ description: string
13
+ icon: string
14
+ unlockedAt?: string
15
+ isUnlocked: boolean
16
+ }
17
+
18
+ export interface ProgressDisplayProps {
19
+ stats: StatCardData[]
20
+ badges: BadgeData[]
21
+ level?: number
22
+ accuracy?: number
23
+ }
24
+
25
+ export interface ProgressDisplayAPI {
26
+ /** The computed stats array */
27
+ stats: StatCardData[]
28
+ /** The badges array */
29
+ badges: BadgeData[]
30
+ /** ARIA props for the stats region */
31
+ ariaProps: Partial<AccessibilityProps>
32
+ /** Get ARIA props for a specific badge */
33
+ getBadgeAriaProps: (badge: BadgeData) => Partial<AccessibilityProps>
34
+ }
35
+
36
+ export function createProgressDisplay(props: ProgressDisplayProps): ProgressDisplayAPI {
37
+ const { stats, badges } = props
38
+
39
+ const ariaProps: Partial<AccessibilityProps> = {
40
+ role: 'region',
41
+ 'aria-label': 'Progress statistics',
42
+ }
43
+
44
+ function getBadgeAriaProps(badge: BadgeData): Partial<AccessibilityProps> {
45
+ const label = badge.isUnlocked
46
+ ? `${badge.name}: ${badge.description}`
47
+ : `${badge.name}: ${badge.description} (locked)`
48
+
49
+ return {
50
+ 'aria-label': label,
51
+ }
52
+ }
53
+
54
+ return {
55
+ stats,
56
+ badges,
57
+ ariaProps,
58
+ getBadgeAriaProps,
59
+ }
60
+ }
@@ -0,0 +1,8 @@
1
+ export {
2
+ createRadioGroup,
3
+ type RadioOption,
4
+ type RadioGroupProps,
5
+ type RadioGroupAPI,
6
+ } from './radio.js'
7
+
8
+ export { radioGroupVariants, radioItemVariants, radioCircleVariants } from './radio.styles.js'
@@ -0,0 +1,34 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const radioGroupVariants = cva({
4
+ base: 'flex gap-3',
5
+ variants: {
6
+ orientation: {
7
+ vertical: 'flex-col',
8
+ horizontal: 'flex-row',
9
+ },
10
+ },
11
+ defaultVariants: { orientation: 'vertical' },
12
+ })
13
+
14
+ export const radioItemVariants = cva({
15
+ base: 'flex items-center gap-2 cursor-pointer',
16
+ variants: {
17
+ disabled: {
18
+ true: 'opacity-50 cursor-not-allowed',
19
+ false: '',
20
+ },
21
+ },
22
+ defaultVariants: { disabled: 'false' },
23
+ })
24
+
25
+ export const radioCircleVariants = cva({
26
+ base: 'h-4 w-4 rounded-full border border-primary transition-colors',
27
+ variants: {
28
+ checked: {
29
+ true: 'border-primary bg-primary',
30
+ false: 'border-input',
31
+ },
32
+ },
33
+ defaultVariants: { checked: 'false' },
34
+ })