@refraction-ui/astro 0.4.2 → 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 (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,70 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+
3
+ export interface RadioOption {
4
+ value: string
5
+ label: string
6
+ disabled?: boolean
7
+ }
8
+
9
+ export interface RadioGroupProps {
10
+ value?: string
11
+ defaultValue?: string
12
+ onValueChange?: (value: string) => void
13
+ name?: string
14
+ disabled?: boolean
15
+ orientation?: 'horizontal' | 'vertical'
16
+ }
17
+
18
+ export interface RadioGroupAPI {
19
+ state: { selectedValue: string | undefined }
20
+ groupProps: Partial<AccessibilityProps> & Record<string, unknown>
21
+ getItemProps(value: string, disabled?: boolean): Partial<AccessibilityProps> & Record<string, unknown>
22
+ select(value: string): void
23
+ keyboardHandlers: Record<string, (e: KeyboardEvent) => void>
24
+ }
25
+
26
+ export function createRadioGroup(props: RadioGroupProps = {}): RadioGroupAPI {
27
+ const { value: controlled, defaultValue, onValueChange, name, disabled = false, orientation = 'vertical' } = props
28
+ let selected = controlled ?? defaultValue
29
+
30
+ function select(value: string) {
31
+ if (disabled) return
32
+ selected = value
33
+ onValueChange?.(value)
34
+ }
35
+
36
+ const groupProps = {
37
+ role: 'radiogroup' as const,
38
+ 'aria-orientation': orientation,
39
+ ...(disabled ? { 'aria-disabled': true } : {}),
40
+ }
41
+
42
+ function getItemProps(value: string, itemDisabled?: boolean) {
43
+ const isSelected = selected === value
44
+ const isDisabled = disabled || itemDisabled
45
+ return {
46
+ role: 'radio' as const,
47
+ 'aria-checked': isSelected,
48
+ 'aria-disabled': isDisabled || undefined,
49
+ tabIndex: isSelected ? 0 : -1,
50
+ 'data-state': isSelected ? 'checked' : 'unchecked',
51
+ ...(isDisabled ? { 'data-disabled': '' } : {}),
52
+ ...(name ? { name } : {}),
53
+ }
54
+ }
55
+
56
+ const keyboardHandlers: Record<string, (e: KeyboardEvent) => void> = {
57
+ ArrowDown(e) { e.preventDefault() },
58
+ ArrowUp(e) { e.preventDefault() },
59
+ ArrowRight(e) { e.preventDefault() },
60
+ ArrowLeft(e) { e.preventDefault() },
61
+ }
62
+
63
+ return {
64
+ state: { get selectedValue() { return selected } },
65
+ groupProps,
66
+ getItemProps,
67
+ select,
68
+ keyboardHandlers,
69
+ }
70
+ }
@@ -0,0 +1,14 @@
1
+ export {
2
+ createReactionBar,
3
+ type Reaction,
4
+ type ReactionBarProps,
5
+ type ReactionBarAPI,
6
+ } from './reaction-bar.js'
7
+
8
+ export {
9
+ reactionBarStyles,
10
+ reactionPillVariants,
11
+ reactionAddButtonStyles,
12
+ reactionEmojiStyles,
13
+ reactionCountStyles,
14
+ } from './reaction-bar.styles.js'
@@ -0,0 +1,23 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const reactionBarStyles =
4
+ 'flex flex-wrap items-center gap-1'
5
+
6
+ export const reactionPillVariants = cva({
7
+ base: 'inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs cursor-pointer transition-colors hover:bg-accent',
8
+ variants: {
9
+ state: {
10
+ active: 'border-primary bg-primary/10 text-primary',
11
+ inactive: 'border-border bg-background text-foreground',
12
+ },
13
+ },
14
+ defaultVariants: {
15
+ state: 'inactive',
16
+ },
17
+ })
18
+
19
+ export const reactionAddButtonStyles =
20
+ 'inline-flex items-center justify-center h-6 w-6 rounded-full border border-dashed border-muted-foreground/30 text-muted-foreground hover:border-muted-foreground hover:text-foreground cursor-pointer transition-colors text-xs'
21
+
22
+ export const reactionEmojiStyles = 'text-sm'
23
+ export const reactionCountStyles = 'text-xs font-medium tabular-nums'
@@ -0,0 +1,87 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+ import { generateId } from '../shared/index.ts'
3
+
4
+ export interface Reaction {
5
+ /** The emoji character */
6
+ emoji: string
7
+ /** Number of users who reacted with this emoji */
8
+ count: number
9
+ /** Whether the current user has reacted */
10
+ userReacted: boolean
11
+ }
12
+
13
+ export interface ReactionBarProps {
14
+ /** Current reactions */
15
+ reactions: Reaction[]
16
+ /** Callback when a reaction is toggled */
17
+ onToggle?: (emoji: string) => void
18
+ /** Callback when a new reaction is added */
19
+ onAdd?: (emoji: string) => void
20
+ }
21
+
22
+ export interface ReactionBarAPI {
23
+ /** Current reactions */
24
+ reactions: Reaction[]
25
+ /** Toggle a reaction */
26
+ toggle(emoji: string): void
27
+ /** Add a new reaction */
28
+ add(emoji: string): void
29
+ /** ARIA props for the reaction bar container */
30
+ ariaProps: Partial<AccessibilityProps> & Record<string, unknown>
31
+ /** Get ARIA props for an individual reaction pill */
32
+ getReactionAriaProps(reaction: Reaction): Record<string, unknown>
33
+ /** ARIA props for the "add reaction" button */
34
+ addButtonAriaProps: Record<string, unknown>
35
+ /** Generated IDs */
36
+ ids: {
37
+ container: string
38
+ label: string
39
+ }
40
+ }
41
+
42
+ export function createReactionBar(props: ReactionBarProps): ReactionBarAPI {
43
+ const { reactions, onToggle, onAdd } = props
44
+
45
+ const containerId = generateId('rfr-reactions')
46
+ const labelId = generateId('rfr-reactions-label')
47
+
48
+ function toggle(emoji: string): void {
49
+ onToggle?.(emoji)
50
+ }
51
+
52
+ function add(emoji: string): void {
53
+ onAdd?.(emoji)
54
+ }
55
+
56
+ const ariaProps: Partial<AccessibilityProps> & Record<string, unknown> = {
57
+ role: 'group',
58
+ 'aria-label': 'Reactions',
59
+ id: containerId,
60
+ }
61
+
62
+ function getReactionAriaProps(reaction: Reaction): Record<string, unknown> {
63
+ return {
64
+ role: 'button',
65
+ 'aria-pressed': reaction.userReacted,
66
+ 'aria-label': `${reaction.emoji} ${reaction.count} reaction${reaction.count === 1 ? '' : 's'}${reaction.userReacted ? ', you reacted' : ''}`,
67
+ }
68
+ }
69
+
70
+ const addButtonAriaProps: Record<string, unknown> = {
71
+ role: 'button',
72
+ 'aria-label': 'Add reaction',
73
+ }
74
+
75
+ return {
76
+ reactions,
77
+ toggle,
78
+ add,
79
+ ariaProps,
80
+ getReactionAriaProps,
81
+ addButtonAriaProps,
82
+ ids: {
83
+ container: containerId,
84
+ label: labelId,
85
+ },
86
+ }
87
+ }
@@ -0,0 +1,12 @@
1
+ export {
2
+ createResizableLayout,
3
+ type ResizableLayoutProps,
4
+ type ResizableLayoutAPI,
5
+ } from './resizable-layout.js'
6
+
7
+ export {
8
+ resizableLayoutVariants,
9
+ resizableDividerVariants,
10
+ resizablePaneVariants,
11
+ resizableLayoutTokens,
12
+ } from './resizable-layout.styles.js'
@@ -0,0 +1,50 @@
1
+ import { cva } from '../shared/index.ts'
2
+ import type { TokenContract } from '../shared/index.ts'
3
+
4
+ export const resizableLayoutTokens: TokenContract = {
5
+ name: 'resizable-layout',
6
+ tokens: {
7
+ dividerColor: { variable: '--rfr-resizable-divider-color', fallback: 'hsl(var(--border))' },
8
+ dividerHover: { variable: '--rfr-resizable-divider-hover', fallback: 'hsl(var(--primary))' },
9
+ dividerSize: { variable: '--rfr-resizable-divider-size', fallback: '4px' },
10
+ },
11
+ }
12
+
13
+ export const resizableLayoutVariants = cva({
14
+ base: 'flex h-full w-full',
15
+ variants: {
16
+ orientation: {
17
+ horizontal: 'flex-row',
18
+ vertical: 'flex-col',
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ orientation: 'horizontal',
23
+ },
24
+ })
25
+
26
+ export const resizableDividerVariants = cva({
27
+ base: 'relative flex items-center justify-center bg-border transition-colors hover:bg-primary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 active:bg-primary/70',
28
+ variants: {
29
+ orientation: {
30
+ horizontal: 'w-1 cursor-col-resize',
31
+ vertical: 'h-1 cursor-row-resize',
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ orientation: 'horizontal',
36
+ },
37
+ })
38
+
39
+ export const resizablePaneVariants = cva({
40
+ base: 'overflow-auto',
41
+ variants: {
42
+ orientation: {
43
+ horizontal: 'h-full',
44
+ vertical: 'w-full',
45
+ },
46
+ },
47
+ defaultVariants: {
48
+ orientation: 'horizontal',
49
+ },
50
+ })
@@ -0,0 +1,139 @@
1
+ import type { Orientation } from '../shared/index.ts'
2
+
3
+ export interface ResizableLayoutProps {
4
+ orientation?: Orientation
5
+ /** Initial sizes as percentages (must sum to 100) */
6
+ defaultSizes?: number[]
7
+ /** Minimum size for each pane (percentage) */
8
+ minSizes?: number[]
9
+ /** Maximum size for each pane (percentage) */
10
+ maxSizes?: number[]
11
+ /** localStorage key for persisting sizes */
12
+ persistKey?: string
13
+ }
14
+
15
+ export interface ResizableLayoutAPI {
16
+ /** Current pane sizes as percentages */
17
+ sizes: number[]
18
+ /** Begin a resize operation at divider index */
19
+ startResize: (index: number) => void
20
+ /** Apply a delta (percentage) during resize */
21
+ onResize: (delta: number) => void
22
+ /** End the current resize operation */
23
+ endResize: () => void
24
+ /** Generate CSS custom properties for pane sizes */
25
+ getCSSVariables: () => Record<string, string>
26
+ /** Current orientation */
27
+ orientation: Orientation
28
+ }
29
+
30
+ /**
31
+ * Clamp a value between min and max.
32
+ */
33
+ function clamp(value: number, min: number, max: number): number {
34
+ return Math.min(Math.max(value, min), max)
35
+ }
36
+
37
+ export function createResizableLayout(props: ResizableLayoutProps = {}): ResizableLayoutAPI {
38
+ const {
39
+ orientation = 'horizontal',
40
+ defaultSizes = [50, 50],
41
+ minSizes = [],
42
+ maxSizes = [],
43
+ persistKey,
44
+ } = props
45
+
46
+ const sizes = loadSizes(persistKey) ?? [...defaultSizes]
47
+ let resizingIndex: number | null = null
48
+ let sizesBeforeResize: number[] = []
49
+
50
+ function loadSizes(key?: string): number[] | null {
51
+ if (!key) return null
52
+ try {
53
+ if (typeof globalThis.localStorage !== 'undefined') {
54
+ const stored = globalThis.localStorage.getItem(key)
55
+ if (stored) {
56
+ const parsed = JSON.parse(stored) as number[]
57
+ if (Array.isArray(parsed) && parsed.length === defaultSizes.length) {
58
+ return parsed
59
+ }
60
+ }
61
+ }
62
+ } catch {
63
+ // localStorage not available or invalid data
64
+ }
65
+ return null
66
+ }
67
+
68
+ function saveSizes(key: string, values: number[]): void {
69
+ try {
70
+ if (typeof globalThis.localStorage !== 'undefined') {
71
+ globalThis.localStorage.setItem(key, JSON.stringify(values))
72
+ }
73
+ } catch {
74
+ // localStorage not available
75
+ }
76
+ }
77
+
78
+ function getMinSize(index: number): number {
79
+ return minSizes[index] ?? 0
80
+ }
81
+
82
+ function getMaxSize(index: number): number {
83
+ return maxSizes[index] ?? 100
84
+ }
85
+
86
+ function startResize(index: number): void {
87
+ resizingIndex = index
88
+ sizesBeforeResize = [...sizes]
89
+ }
90
+
91
+ function onResize(delta: number): void {
92
+ if (resizingIndex === null) return
93
+
94
+ const i = resizingIndex
95
+ const j = i + 1
96
+ if (j >= sizes.length) return
97
+
98
+ const totalAvailable = sizesBeforeResize[i] + sizesBeforeResize[j]
99
+
100
+ // Compute new size for pane i
101
+ let newSizeI = sizesBeforeResize[i] + delta
102
+ newSizeI = clamp(newSizeI, getMinSize(i), getMaxSize(i))
103
+
104
+ // Compute new size for pane j from remaining
105
+ let newSizeJ = totalAvailable - newSizeI
106
+ newSizeJ = clamp(newSizeJ, getMinSize(j), getMaxSize(j))
107
+
108
+ // Re-adjust pane i if pane j was constrained
109
+ newSizeI = totalAvailable - newSizeJ
110
+
111
+ sizes[i] = newSizeI
112
+ sizes[j] = newSizeJ
113
+ }
114
+
115
+ function endResize(): void {
116
+ resizingIndex = null
117
+ sizesBeforeResize = []
118
+ if (persistKey) {
119
+ saveSizes(persistKey, sizes)
120
+ }
121
+ }
122
+
123
+ function getCSSVariables(): Record<string, string> {
124
+ const vars: Record<string, string> = {}
125
+ for (let i = 0; i < sizes.length; i++) {
126
+ vars[`--rfr-pane-${i}-size`] = `${sizes[i]}%`
127
+ }
128
+ return vars
129
+ }
130
+
131
+ return {
132
+ sizes,
133
+ startResize,
134
+ onResize,
135
+ endResize,
136
+ getCSSVariables,
137
+ orientation,
138
+ }
139
+ }