@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,74 @@
1
+ import type { AuthAdapter, User } from '../types.js'
2
+
3
+ /**
4
+ * Mock auth adapter for testing and development.
5
+ * No external dependencies. Stores state in memory.
6
+ */
7
+ export function createMockAdapter(initialUser?: User): AuthAdapter {
8
+ let currentUser: User | null = initialUser ?? null
9
+ const listeners = new Set<(user: User | null) => void>()
10
+
11
+ function notify() {
12
+ for (const fn of listeners) {
13
+ fn(currentUser)
14
+ }
15
+ }
16
+
17
+ return {
18
+ async signIn(email, _password) {
19
+ currentUser = {
20
+ uid: 'mock-' + email,
21
+ email,
22
+ displayName: email.split('@')[0],
23
+ photoURL: null,
24
+ roles: ['student'],
25
+ }
26
+ notify()
27
+ return currentUser
28
+ },
29
+
30
+ async signInWithOAuth(_provider) {
31
+ currentUser = {
32
+ uid: 'mock-oauth',
33
+ email: 'oauth@example.com',
34
+ displayName: 'OAuth User',
35
+ photoURL: null,
36
+ roles: ['student'],
37
+ }
38
+ notify()
39
+ return currentUser
40
+ },
41
+
42
+ async signUp(email, _password, displayName) {
43
+ currentUser = {
44
+ uid: 'mock-' + email,
45
+ email,
46
+ displayName,
47
+ photoURL: null,
48
+ roles: ['student'],
49
+ }
50
+ notify()
51
+ return currentUser
52
+ },
53
+
54
+ async signOut() {
55
+ currentUser = null
56
+ notify()
57
+ },
58
+
59
+ async resetPassword(_email) {
60
+ // no-op in mock
61
+ },
62
+
63
+ async getToken() {
64
+ return currentUser ? 'mock-token-' + currentUser.uid : null
65
+ },
66
+
67
+ onAuthStateChange(callback) {
68
+ listeners.add(callback)
69
+ // Fire immediately with current state
70
+ callback(currentUser)
71
+ return () => { listeners.delete(callback) }
72
+ },
73
+ }
74
+ }
@@ -0,0 +1,120 @@
1
+ import type { User, AuthState, AuthStatus, AuthConfig, AuthAdapter, OAuthProvider } from './types.js'
2
+
3
+ export interface AuthAPI {
4
+ getState(): AuthState
5
+ signIn(email: string, password: string): Promise<User>
6
+ signInWithOAuth(provider: OAuthProvider): Promise<User>
7
+ signUp(email: string, password: string, displayName: string): Promise<User>
8
+ signOut(): Promise<void>
9
+ resetPassword(email: string): Promise<void>
10
+ getToken(): Promise<string | null>
11
+ subscribe(fn: (state: AuthState) => void): () => void
12
+ destroy(): void
13
+ }
14
+
15
+ export function createAuth(
16
+ adapter: AuthAdapter,
17
+ config: Omit<AuthConfig, 'adapter'> = {},
18
+ ): AuthAPI {
19
+ const listeners = new Set<(state: AuthState) => void>()
20
+ let state: AuthState = { user: null, status: 'loading' }
21
+ let unsubAuth: (() => void) | null = null
22
+ let tokenRefreshTimer: ReturnType<typeof setInterval> | null = null
23
+
24
+ const { tokenRefreshInterval = 50, testMode = false, testUser } = config
25
+
26
+ function setState(newState: AuthState) {
27
+ state = newState
28
+ for (const fn of listeners) {
29
+ fn(state)
30
+ }
31
+ }
32
+
33
+ function setUser(user: User | null) {
34
+ setState({
35
+ user,
36
+ status: user ? 'authenticated' : 'unauthenticated',
37
+ })
38
+ }
39
+
40
+ // Start token refresh timer
41
+ function startTokenRefresh() {
42
+ if (tokenRefreshTimer) clearInterval(tokenRefreshTimer)
43
+ tokenRefreshTimer = setInterval(
44
+ () => { adapter.getToken().catch(() => {}) },
45
+ tokenRefreshInterval * 60 * 1000,
46
+ )
47
+ }
48
+
49
+ // Initialize
50
+ if (testMode && testUser) {
51
+ setUser(testUser)
52
+ } else {
53
+ unsubAuth = adapter.onAuthStateChange((user) => {
54
+ setUser(user)
55
+ if (user) {
56
+ startTokenRefresh()
57
+ } else if (tokenRefreshTimer) {
58
+ clearInterval(tokenRefreshTimer)
59
+ tokenRefreshTimer = null
60
+ }
61
+ })
62
+ }
63
+
64
+ return {
65
+ getState() {
66
+ return state
67
+ },
68
+
69
+ async signIn(email, password) {
70
+ const user = await adapter.signIn(email, password)
71
+ setUser(user)
72
+ startTokenRefresh()
73
+ return user
74
+ },
75
+
76
+ async signInWithOAuth(provider) {
77
+ const user = await adapter.signInWithOAuth(provider)
78
+ setUser(user)
79
+ startTokenRefresh()
80
+ return user
81
+ },
82
+
83
+ async signUp(email, password, displayName) {
84
+ const user = await adapter.signUp(email, password, displayName)
85
+ setUser(user)
86
+ startTokenRefresh()
87
+ return user
88
+ },
89
+
90
+ async signOut() {
91
+ await adapter.signOut()
92
+ if (tokenRefreshTimer) {
93
+ clearInterval(tokenRefreshTimer)
94
+ tokenRefreshTimer = null
95
+ }
96
+ setUser(null)
97
+ },
98
+
99
+ async resetPassword(email) {
100
+ await adapter.resetPassword(email)
101
+ },
102
+
103
+ async getToken() {
104
+ return adapter.getToken()
105
+ },
106
+
107
+ subscribe(fn) {
108
+ listeners.add(fn)
109
+ return () => { listeners.delete(fn) }
110
+ },
111
+
112
+ destroy() {
113
+ listeners.clear()
114
+ unsubAuth?.()
115
+ if (tokenRefreshTimer) {
116
+ clearInterval(tokenRefreshTimer)
117
+ }
118
+ },
119
+ }
120
+ }
@@ -0,0 +1,22 @@
1
+ export type {
2
+ User,
3
+ AuthState,
4
+ AuthStatus,
5
+ OAuthProvider,
6
+ AuthConfig,
7
+ AuthAdapter,
8
+ } from './types.js'
9
+
10
+ export { createAuth, type AuthAPI } from './auth-machine.js'
11
+
12
+ export {
13
+ hasRole,
14
+ hasAnyRole,
15
+ hasAllRoles,
16
+ canAccessAdmin,
17
+ canAccessReviewer,
18
+ getDefaultPortal,
19
+ getAssignableRoles,
20
+ } from './rbac.js'
21
+
22
+ export { createMockAdapter } from './adapters/mock.js'
@@ -0,0 +1,44 @@
1
+ import type { User } from './types.js'
2
+
3
+ /** Check if user has a specific role */
4
+ export function hasRole(user: User | null, role: string): boolean {
5
+ return user?.roles?.includes(role) ?? false
6
+ }
7
+
8
+ /** Check if user has any of the specified roles */
9
+ export function hasAnyRole(user: User | null, roles: string[]): boolean {
10
+ if (!user?.roles) return false
11
+ return roles.some((role) => user.roles.includes(role))
12
+ }
13
+
14
+ /** Check if user has all of the specified roles */
15
+ export function hasAllRoles(user: User | null, roles: string[]): boolean {
16
+ if (!user?.roles) return false
17
+ return roles.every((role) => user.roles.includes(role))
18
+ }
19
+
20
+ /** Convenience role checks */
21
+ export function canAccessAdmin(user: User | null): boolean {
22
+ return hasRole(user, 'admin')
23
+ }
24
+
25
+ export function canAccessReviewer(user: User | null): boolean {
26
+ return hasAnyRole(user, ['admin', 'reviewer'])
27
+ }
28
+
29
+ /** Get the default portal URL based on highest-privilege role */
30
+ export function getDefaultPortal(roles: string[]): string {
31
+ if (roles.includes('admin')) return '/admin'
32
+ if (roles.includes('reviewer')) return '/reviewer'
33
+ if (roles.includes('parent')) return '/parent'
34
+ if (roles.includes('student')) return '/student'
35
+ return '/'
36
+ }
37
+
38
+ /** Get roles that the given user can assign to others */
39
+ export function getAssignableRoles(user: User | null): string[] {
40
+ if (!user) return []
41
+ if (hasRole(user, 'admin')) return ['admin', 'reviewer', 'parent', 'student']
42
+ if (hasRole(user, 'reviewer')) return ['student']
43
+ return []
44
+ }
@@ -0,0 +1,44 @@
1
+ /** User object — framework-agnostic, provider-agnostic */
2
+ export interface User {
3
+ uid: string
4
+ email: string | null
5
+ displayName: string | null
6
+ photoURL: string | null
7
+ roles: string[]
8
+ }
9
+
10
+ /** Auth state */
11
+ export type AuthStatus = 'loading' | 'authenticated' | 'unauthenticated'
12
+
13
+ export interface AuthState {
14
+ user: User | null
15
+ status: AuthStatus
16
+ }
17
+
18
+ /** OAuth providers */
19
+ export type OAuthProvider = string
20
+
21
+ /**
22
+ * AuthAdapter — interface implemented by provider adapters (e.g. Firebase, Supabase, Auth0).
23
+ * Consumers must provide an implementation of this adapter to the AuthProvider.
24
+ */
25
+ export interface AuthAdapter {
26
+ signIn(email: string, password: string): Promise<User>
27
+ signInWithOAuth(provider: OAuthProvider): Promise<User>
28
+ signUp(email: string, password: string, displayName: string): Promise<User>
29
+ signOut(): Promise<void>
30
+ resetPassword(email: string): Promise<void>
31
+ getToken(): Promise<string | null>
32
+ onAuthStateChange(callback: (user: User | null) => void): () => void
33
+ }
34
+
35
+ export interface AuthConfig {
36
+ /** The adapter implementation for your specific auth provider (Supabase, Firebase, Auth0, Custom, etc.) */
37
+ adapter: AuthAdapter
38
+ /** Token refresh interval in minutes. Default: 50 */
39
+ tokenRefreshInterval?: number
40
+ /** Enable E2E test mode with mock user */
41
+ testMode?: boolean
42
+ /** Mock user for test mode */
43
+ testUser?: User
44
+ }
@@ -0,0 +1,47 @@
1
+ import { cva } from '../shared/index.ts'
2
+ import type { TokenContract } from '../shared/index.ts'
3
+
4
+ export const avatarTokens: TokenContract = {
5
+ name: 'avatar',
6
+ tokens: {
7
+ bg: { variable: '--rfr-avatar-bg', fallback: 'hsl(var(--muted))' },
8
+ fg: { variable: '--rfr-avatar-fg', fallback: 'hsl(var(--muted-foreground))' },
9
+ border: { variable: '--rfr-avatar-border', fallback: 'hsl(var(--border))' },
10
+ },
11
+ }
12
+
13
+ export const avatarVariants = cva({
14
+ base: 'relative flex shrink-0 overflow-hidden rounded-full',
15
+ variants: {
16
+ size: {
17
+ xs: 'h-6 w-6',
18
+ sm: 'h-8 w-8',
19
+ md: 'h-10 w-10',
20
+ lg: 'h-12 w-12',
21
+ xl: 'h-16 w-16',
22
+ },
23
+ },
24
+ defaultVariants: {
25
+ size: 'md',
26
+ },
27
+ })
28
+
29
+ export const avatarImageVariants = cva({
30
+ base: 'aspect-square h-full w-full object-cover',
31
+ })
32
+
33
+ export const avatarFallbackVariants = cva({
34
+ base: 'flex h-full w-full items-center justify-center rounded-full bg-muted text-muted-foreground',
35
+ variants: {
36
+ size: {
37
+ xs: 'text-xs',
38
+ sm: 'text-xs',
39
+ md: 'text-sm',
40
+ lg: 'text-base',
41
+ xl: 'text-lg',
42
+ },
43
+ },
44
+ defaultVariants: {
45
+ size: 'md',
46
+ },
47
+ })
@@ -0,0 +1,73 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+
3
+ export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
4
+
5
+ export type AvatarLoadingStatus = 'idle' | 'loading' | 'loaded' | 'error'
6
+
7
+ export interface AvatarProps {
8
+ src?: string
9
+ alt?: string
10
+ fallback?: string
11
+ size?: AvatarSize
12
+ }
13
+
14
+ export interface AvatarAPI {
15
+ /** ARIA attributes to spread on the root element */
16
+ ariaProps: Partial<AccessibilityProps>
17
+ /** Data attributes for CSS styling hooks */
18
+ dataAttributes: Record<string, string>
19
+ /** Image ARIA props */
20
+ imageProps: {
21
+ alt: string
22
+ role: string
23
+ }
24
+ /** Fallback text (initials) */
25
+ fallbackText: string
26
+ /** Current state */
27
+ state: {
28
+ size: AvatarSize
29
+ hasSrc: boolean
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Extract initials from a name or fallback string.
35
+ * Takes first letter of first two words, uppercased.
36
+ */
37
+ export function getInitials(name: string): string {
38
+ const parts = name.trim().split(/\s+/)
39
+ if (parts.length === 0 || parts[0] === '') return ''
40
+ if (parts.length === 1) return parts[0].charAt(0).toUpperCase()
41
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase()
42
+ }
43
+
44
+ export function createAvatar(props: AvatarProps = {}): AvatarAPI {
45
+ const { src, alt = '', fallback = '', size = 'md' } = props
46
+
47
+ const ariaProps: Partial<AccessibilityProps> = {
48
+ role: 'img',
49
+ }
50
+ if (alt) {
51
+ ariaProps['aria-label'] = alt
52
+ }
53
+
54
+ const fallbackText = fallback ? getInitials(fallback) : (alt ? getInitials(alt) : '')
55
+
56
+ const dataAttributes: Record<string, string> = {
57
+ 'data-slot': 'avatar',
58
+ }
59
+
60
+ return {
61
+ ariaProps,
62
+ dataAttributes,
63
+ imageProps: {
64
+ alt,
65
+ role: 'img',
66
+ },
67
+ fallbackText,
68
+ state: {
69
+ size,
70
+ hasSrc: !!src,
71
+ },
72
+ }
73
+ }
@@ -0,0 +1,15 @@
1
+ export {
2
+ createAvatar,
3
+ getInitials,
4
+ type AvatarProps,
5
+ type AvatarAPI,
6
+ type AvatarSize,
7
+ type AvatarLoadingStatus,
8
+ } from './avatar.js'
9
+
10
+ export {
11
+ avatarVariants,
12
+ avatarImageVariants,
13
+ avatarFallbackVariants,
14
+ avatarTokens,
15
+ } from './avatar.styles.js'
@@ -0,0 +1,63 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const avatarGroupStyles =
4
+ 'flex items-center -space-x-2'
5
+
6
+ export const avatarVariants = cva({
7
+ base: 'relative inline-flex items-center justify-center rounded-full border-2 border-background bg-muted text-muted-foreground font-medium overflow-hidden ring-2 ring-background',
8
+ variants: {
9
+ size: {
10
+ xs: 'h-6 w-6 text-[10px]',
11
+ sm: 'h-8 w-8 text-xs',
12
+ md: 'h-10 w-10 text-sm',
13
+ lg: 'h-12 w-12 text-base',
14
+ xl: 'h-16 w-16 text-xl',
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ size: 'md',
19
+ },
20
+ })
21
+
22
+ export const avatarOverflowBadgeVariants = cva({
23
+ base: 'relative inline-flex items-center justify-center rounded-full border-2 border-background bg-muted text-muted-foreground font-medium ring-2 ring-background',
24
+ variants: {
25
+ size: {
26
+ xs: 'h-6 w-6 text-[10px]',
27
+ sm: 'h-8 w-8 text-xs',
28
+ md: 'h-10 w-10 text-sm',
29
+ lg: 'h-12 w-12 text-base',
30
+ xl: 'h-16 w-16 text-xl',
31
+ },
32
+ },
33
+ defaultVariants: {
34
+ size: 'md',
35
+ },
36
+ })
37
+
38
+ export const avatarImageStyles =
39
+ 'h-full w-full object-cover'
40
+
41
+ export const avatarPresenceDotVariants = cva({
42
+ base: 'absolute bottom-0 right-0 rounded-full border-2 border-background',
43
+ variants: {
44
+ size: {
45
+ xs: 'h-2 w-2',
46
+ sm: 'h-2.5 w-2.5',
47
+ md: 'h-3 w-3',
48
+ lg: 'h-3.5 w-3.5',
49
+ xl: 'h-4 w-4',
50
+ },
51
+ status: {
52
+ online: 'bg-green-500',
53
+ offline: 'bg-gray-400',
54
+ away: 'bg-yellow-500',
55
+ busy: 'bg-red-500',
56
+ dnd: 'bg-red-500',
57
+ },
58
+ },
59
+ defaultVariants: {
60
+ size: 'md',
61
+ status: 'offline',
62
+ },
63
+ })
@@ -0,0 +1,106 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+ import { generateId } from '../shared/index.ts'
3
+
4
+ export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
5
+ export type PresenceStatus = 'online' | 'offline' | 'away' | 'busy' | 'dnd'
6
+
7
+ export interface AvatarUser {
8
+ /** Unique identifier */
9
+ id: string
10
+ /** Display name */
11
+ name: string
12
+ /** Avatar image URL */
13
+ src?: string
14
+ /** Online presence status */
15
+ status?: PresenceStatus
16
+ }
17
+
18
+ export interface AvatarGroupProps {
19
+ /** Array of users to display */
20
+ users: AvatarUser[]
21
+ /** Maximum number of visible avatars */
22
+ max?: number
23
+ /** Avatar size */
24
+ size?: AvatarSize
25
+ }
26
+
27
+ export interface AvatarGroupAPI {
28
+ /** Users that are visible (within max limit) */
29
+ visibleUsers: AvatarUser[]
30
+ /** Number of overflow users */
31
+ overflowCount: number
32
+ /** All overflow users (for tooltip/popup) */
33
+ overflowUsers: AvatarUser[]
34
+ /** ARIA props for the group container */
35
+ ariaProps: Partial<AccessibilityProps> & Record<string, unknown>
36
+ /** Get ARIA props for an individual avatar */
37
+ getAvatarAriaProps(user: AvatarUser): Record<string, unknown>
38
+ /** Get initials from a user's name */
39
+ getInitials(name: string): string
40
+ /** Get the overflow badge ARIA props */
41
+ overflowBadgeProps: Record<string, unknown>
42
+ /** Generated IDs */
43
+ ids: {
44
+ group: string
45
+ label: string
46
+ }
47
+ }
48
+
49
+ export const AVATAR_SIZES: Record<AvatarSize, { width: number; fontSize: number }> = {
50
+ xs: { width: 24, fontSize: 10 },
51
+ sm: { width: 32, fontSize: 12 },
52
+ md: { width: 40, fontSize: 14 },
53
+ lg: { width: 48, fontSize: 16 },
54
+ xl: { width: 64, fontSize: 20 },
55
+ }
56
+
57
+ export function getInitials(name: string): string {
58
+ const parts = name.trim().split(/\s+/)
59
+ if (parts.length === 0) return ''
60
+ if (parts.length === 1) return parts[0].charAt(0).toUpperCase()
61
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase()
62
+ }
63
+
64
+ export function createAvatarGroup(props: AvatarGroupProps): AvatarGroupAPI {
65
+ const { users, max, size = 'md' } = props
66
+
67
+ const visibleUsers = max && max > 0 ? users.slice(0, max) : users
68
+ const overflowUsers = max && max > 0 ? users.slice(max) : []
69
+ const overflowCount = overflowUsers.length
70
+
71
+ const groupId = generateId('rfr-avatar-group')
72
+ const labelId = generateId('rfr-avatar-group-label')
73
+
74
+ const ariaProps: Partial<AccessibilityProps> & Record<string, unknown> = {
75
+ role: 'group',
76
+ 'aria-label': `${users.length} users`,
77
+ id: groupId,
78
+ }
79
+
80
+ function getAvatarAriaProps(user: AvatarUser): Record<string, unknown> {
81
+ const label = user.status ? `${user.name} (${user.status})` : user.name
82
+ return {
83
+ role: 'img',
84
+ 'aria-label': label,
85
+ }
86
+ }
87
+
88
+ const overflowBadgeProps: Record<string, unknown> = {
89
+ role: 'button',
90
+ 'aria-label': `${overflowCount} more users`,
91
+ }
92
+
93
+ return {
94
+ visibleUsers,
95
+ overflowCount,
96
+ overflowUsers,
97
+ ariaProps,
98
+ getAvatarAriaProps,
99
+ getInitials,
100
+ overflowBadgeProps,
101
+ ids: {
102
+ group: groupId,
103
+ label: labelId,
104
+ },
105
+ }
106
+ }
@@ -0,0 +1,18 @@
1
+ export {
2
+ createAvatarGroup,
3
+ getInitials,
4
+ AVATAR_SIZES,
5
+ type AvatarGroupProps,
6
+ type AvatarGroupAPI,
7
+ type AvatarUser,
8
+ type AvatarSize,
9
+ type PresenceStatus,
10
+ } from './avatar-group.js'
11
+
12
+ export {
13
+ avatarGroupStyles,
14
+ avatarVariants,
15
+ avatarOverflowBadgeVariants,
16
+ avatarImageStyles,
17
+ avatarPresenceDotVariants,
18
+ } from './avatar-group.styles.js'
@@ -0,0 +1,24 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const badgeVariants = cva({
4
+ base: 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
5
+ variants: {
6
+ variant: {
7
+ default: 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80',
8
+ primary: 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80',
9
+ secondary: 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
10
+ destructive: 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80 font-semibold',
11
+ outline: 'text-foreground',
12
+ success: 'border-transparent bg-green-500 text-white shadow hover:bg-green-500/80 font-semibold',
13
+ warning: 'border-transparent bg-yellow-500 text-white shadow hover:bg-yellow-500/80 font-semibold',
14
+ },
15
+ size: {
16
+ sm: 'px-2 py-0 text-[10px]',
17
+ md: 'px-2.5 py-0.5 text-xs',
18
+ },
19
+ },
20
+ defaultVariants: {
21
+ variant: 'default',
22
+ size: 'md',
23
+ },
24
+ })