@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,96 @@
1
+ export interface InlineEditorProps {
2
+ /** Current value */
3
+ value: string
4
+ /** Callback when saving */
5
+ onSave?: (value: string) => void
6
+ /** Callback when cancelling */
7
+ onCancel?: () => void
8
+ }
9
+
10
+ export interface ToolbarAction {
11
+ name: string
12
+ syntax: string
13
+ }
14
+
15
+ export interface InlineEditorState {
16
+ isEditing: boolean
17
+ value: string
18
+ preview: string
19
+ }
20
+
21
+ export interface InlineEditorAPI {
22
+ /** Current editor state */
23
+ state: InlineEditorState
24
+ /** Enter editing mode */
25
+ startEditing(): void
26
+ /** Cancel editing, revert to original value */
27
+ cancel(): void
28
+ /** Save the current value */
29
+ save(): void
30
+ /** Update the editing value */
31
+ updateValue(value: string): void
32
+ /** Insert syntax at cursor position */
33
+ insertAtCursor(syntax: string): void
34
+ /** Available toolbar actions */
35
+ toolbarActions: ToolbarAction[]
36
+ }
37
+
38
+ export function createInlineEditor(props: InlineEditorProps): InlineEditorAPI {
39
+ const { value: initialValue, onSave, onCancel } = props
40
+
41
+ let isEditing = false
42
+ let currentValue = initialValue
43
+
44
+ const toolbarActions: ToolbarAction[] = [
45
+ { name: 'bold', syntax: '**' },
46
+ { name: 'heading', syntax: '# ' },
47
+ { name: 'list', syntax: '- ' },
48
+ { name: 'link', syntax: '[text](url)' },
49
+ ]
50
+
51
+ function startEditing(): void {
52
+ isEditing = true
53
+ currentValue = initialValue
54
+ }
55
+
56
+ function cancel(): void {
57
+ isEditing = false
58
+ currentValue = initialValue
59
+ onCancel?.()
60
+ }
61
+
62
+ function save(): void {
63
+ isEditing = false
64
+ onSave?.(currentValue)
65
+ }
66
+
67
+ function updateValue(value: string): void {
68
+ currentValue = value
69
+ }
70
+
71
+ function insertAtCursor(syntax: string): void {
72
+ currentValue = currentValue + syntax
73
+ }
74
+
75
+ return {
76
+ get state(): InlineEditorState {
77
+ return {
78
+ get isEditing() {
79
+ return isEditing
80
+ },
81
+ get value() {
82
+ return currentValue
83
+ },
84
+ get preview() {
85
+ return currentValue
86
+ },
87
+ }
88
+ },
89
+ startEditing,
90
+ cancel,
91
+ save,
92
+ updateValue,
93
+ insertAtCursor,
94
+ toolbarActions,
95
+ }
96
+ }
@@ -0,0 +1,9 @@
1
+ export {
2
+ createInput,
3
+ getInputAriaProps,
4
+ type InputType,
5
+ type InputProps,
6
+ type InputAPI,
7
+ } from './input.js'
8
+
9
+ export { inputVariants } from './input.styles.js'
@@ -0,0 +1,15 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const inputVariants = cva({
4
+ base: 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
5
+ variants: {
6
+ size: {
7
+ sm: 'h-8 text-xs',
8
+ default: 'h-9',
9
+ lg: 'h-10 text-base',
10
+ },
11
+ },
12
+ defaultVariants: {
13
+ size: 'default',
14
+ },
15
+ })
@@ -0,0 +1,84 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+
3
+ export type InputType = 'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search'
4
+
5
+ export interface InputProps {
6
+ type?: InputType
7
+ disabled?: boolean
8
+ readOnly?: boolean
9
+ required?: boolean
10
+ placeholder?: string
11
+ 'aria-invalid'?: boolean
12
+ }
13
+
14
+ export interface InputAPI {
15
+ /** ARIA attributes to spread on the element */
16
+ ariaProps: Partial<AccessibilityProps> & { 'aria-invalid'?: boolean; 'aria-required'?: boolean }
17
+ /** Data attributes for CSS styling hooks */
18
+ dataAttributes: Record<string, string>
19
+ }
20
+
21
+ export function createInput(props: InputProps = {}): InputAPI {
22
+ const {
23
+ disabled = false,
24
+ readOnly = false,
25
+ required = false,
26
+ 'aria-invalid': ariaInvalid,
27
+ } = props
28
+
29
+ const ariaProps: InputAPI['ariaProps'] = {}
30
+
31
+ if (disabled) {
32
+ ariaProps['aria-disabled'] = true
33
+ }
34
+
35
+ if (ariaInvalid) {
36
+ ariaProps['aria-invalid'] = true
37
+ }
38
+
39
+ if (required) {
40
+ ariaProps['aria-required'] = true
41
+ }
42
+
43
+ const dataAttributes: Record<string, string> = {}
44
+
45
+ if (disabled) {
46
+ dataAttributes['data-disabled'] = ''
47
+ }
48
+
49
+ if (readOnly) {
50
+ dataAttributes['data-readonly'] = ''
51
+ }
52
+
53
+ if (ariaInvalid) {
54
+ dataAttributes['data-invalid'] = ''
55
+ }
56
+
57
+ return {
58
+ ariaProps,
59
+ dataAttributes,
60
+ }
61
+ }
62
+
63
+ export function getInputAriaProps(state: {
64
+ disabled?: boolean
65
+ readOnly?: boolean
66
+ required?: boolean
67
+ invalid?: boolean
68
+ }): Partial<AccessibilityProps> & { 'aria-invalid'?: boolean; 'aria-required'?: boolean } {
69
+ const ariaProps: Partial<AccessibilityProps> & { 'aria-invalid'?: boolean; 'aria-required'?: boolean } = {}
70
+
71
+ if (state.disabled) {
72
+ ariaProps['aria-disabled'] = true
73
+ }
74
+
75
+ if (state.invalid) {
76
+ ariaProps['aria-invalid'] = true
77
+ }
78
+
79
+ if (state.required) {
80
+ ariaProps['aria-required'] = true
81
+ }
82
+
83
+ return ariaProps
84
+ }
@@ -0,0 +1,13 @@
1
+ export {
2
+ createInputGroup,
3
+ type InputGroupProps,
4
+ type InputGroupAPI,
5
+ type InputGroupOrientation,
6
+ } from './input-group.js'
7
+
8
+ export {
9
+ inputGroupVariants,
10
+ inputGroupAddonVariants,
11
+ inputGroupButtonVariants,
12
+ inputGroupTokens,
13
+ } from './input-group.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 inputGroupTokens: TokenContract = {
5
+ name: 'input-group',
6
+ tokens: {
7
+ bg: { variable: '--rfr-input-group-bg', fallback: 'hsl(var(--background))' },
8
+ border: { variable: '--rfr-input-group-border', fallback: 'hsl(var(--border))' },
9
+ radius: { variable: '--rfr-input-group-radius', fallback: 'var(--radius)' },
10
+ },
11
+ }
12
+
13
+ export const inputGroupVariants = cva({
14
+ base: 'flex items-stretch [&>*:not(:first-child):not(:last-child)]:rounded-none',
15
+ variants: {
16
+ orientation: {
17
+ horizontal: 'flex-row [&>*:first-child]:rounded-r-none [&>*:last-child]:rounded-l-none',
18
+ vertical: 'flex-col [&>*:first-child]:rounded-b-none [&>*:last-child]:rounded-t-none',
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ orientation: 'horizontal',
23
+ },
24
+ })
25
+
26
+ export const inputGroupAddonVariants = cva({
27
+ base: 'flex items-center justify-center border bg-muted px-3 text-sm text-muted-foreground',
28
+ variants: {
29
+ orientation: {
30
+ horizontal: 'border-y border-x first:border-r-0 last:border-l-0',
31
+ vertical: 'border-x border-y first:border-b-0 last:border-t-0',
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ orientation: 'horizontal',
36
+ },
37
+ })
38
+
39
+ export const inputGroupButtonVariants = cva({
40
+ base: 'relative inline-flex items-center justify-center whitespace-nowrap text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
41
+ variants: {
42
+ orientation: {
43
+ horizontal: '',
44
+ vertical: '',
45
+ },
46
+ },
47
+ defaultVariants: {
48
+ orientation: 'horizontal',
49
+ },
50
+ })
@@ -0,0 +1,44 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+ import { generateId } from '../shared/index.ts'
3
+
4
+ export type InputGroupOrientation = 'horizontal' | 'vertical'
5
+
6
+ export interface InputGroupProps {
7
+ orientation?: InputGroupOrientation
8
+ id?: string
9
+ 'aria-label'?: string
10
+ 'aria-labelledby'?: string
11
+ }
12
+
13
+ export interface InputGroupAPI {
14
+ /** ARIA attributes to spread on the group container */
15
+ ariaProps: Partial<AccessibilityProps>
16
+ /** Data attributes for CSS styling hooks */
17
+ dataAttributes: Record<string, string>
18
+ }
19
+
20
+ export function createInputGroup(props: InputGroupProps = {}): InputGroupAPI {
21
+ const { orientation = 'horizontal' } = props
22
+ const id = props.id ?? generateId('rfr-input-group')
23
+
24
+ const ariaProps: Partial<AccessibilityProps> = {
25
+ role: 'group',
26
+ }
27
+
28
+ if (props['aria-label']) {
29
+ ariaProps['aria-label'] = props['aria-label']
30
+ }
31
+ if (props['aria-labelledby']) {
32
+ ariaProps['aria-labelledby'] = props['aria-labelledby']
33
+ }
34
+
35
+ const dataAttributes: Record<string, string> = {
36
+ 'data-orientation': orientation,
37
+ id,
38
+ }
39
+
40
+ return {
41
+ ariaProps,
42
+ dataAttributes,
43
+ }
44
+ }
@@ -0,0 +1,9 @@
1
+ export {
2
+ createInstallPrompt,
3
+ type StorageAdapter,
4
+ type InstallPromptProps,
5
+ type InstallPromptState,
6
+ type InstallPromptAPI,
7
+ } from './install-prompt.js'
8
+
9
+ export { installPromptVariants } from './install-prompt.styles.js'
@@ -0,0 +1,5 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const installPromptVariants = cva({
4
+ base: 'fixed bottom-0 left-0 right-0 z-50 flex items-center justify-between gap-4 border-t bg-background px-4 py-3 shadow-lg',
5
+ })
@@ -0,0 +1,68 @@
1
+ export interface StorageAdapter {
2
+ get(key: string): string | null
3
+ set(key: string, value: string): void
4
+ }
5
+
6
+ export interface InstallPromptProps {
7
+ /** Delay in ms before showing prompt. Default: 3000 */
8
+ delay?: number
9
+ /** Key used to persist dismissed state. Default: 'rfr-install-dismissed' */
10
+ storageKey?: string
11
+ }
12
+
13
+ export interface InstallPromptState {
14
+ canShow: boolean
15
+ isDismissed: boolean
16
+ }
17
+
18
+ export interface InstallPromptAPI {
19
+ state: InstallPromptState
20
+ /** Mark the prompt as showable (call after delay + event fire) */
21
+ show(): void
22
+ /** Dismiss and persist */
23
+ dismiss(): void
24
+ /** Trigger the browser install prompt */
25
+ install(promptEvent?: { prompt(): void }): void
26
+ /** ARIA attributes for the banner */
27
+ ariaProps: Record<string, string>
28
+ }
29
+
30
+ export function createInstallPrompt(
31
+ props: InstallPromptProps = {},
32
+ storage?: StorageAdapter,
33
+ ): InstallPromptAPI {
34
+ const { storageKey = 'rfr-install-dismissed' } = props
35
+
36
+ const dismissed = storage?.get(storageKey) === 'true'
37
+
38
+ const state: InstallPromptState = {
39
+ canShow: false,
40
+ isDismissed: dismissed,
41
+ }
42
+
43
+ return {
44
+ state,
45
+
46
+ show() {
47
+ if (!state.isDismissed) {
48
+ state.canShow = true
49
+ }
50
+ },
51
+
52
+ dismiss() {
53
+ state.canShow = false
54
+ state.isDismissed = true
55
+ storage?.set(storageKey, 'true')
56
+ },
57
+
58
+ install(promptEvent?: { prompt(): void }) {
59
+ promptEvent?.prompt()
60
+ state.canShow = false
61
+ },
62
+
63
+ ariaProps: {
64
+ role: 'banner',
65
+ 'aria-label': 'Install application',
66
+ },
67
+ }
68
+ }
@@ -0,0 +1,12 @@
1
+ export {
2
+ createKeyboardShortcut,
3
+ formatShortcut,
4
+ type ShortcutProps,
5
+ type KeyboardShortcutAPI,
6
+ } from './keyboard-shortcut.js'
7
+
8
+ export {
9
+ shortcutBadgeStyles,
10
+ shortcutKeyStyles,
11
+ shortcutSeparatorStyles,
12
+ } from './keyboard-shortcut.styles.js'
@@ -0,0 +1,8 @@
1
+ export const shortcutBadgeStyles =
2
+ 'inline-flex items-center gap-0.5 rounded border bg-muted px-1.5 py-0.5 text-xs font-mono text-muted-foreground'
3
+
4
+ export const shortcutKeyStyles =
5
+ 'inline-flex items-center justify-center min-w-[1.25rem] rounded bg-background px-1 py-0.5 text-xs font-mono border shadow-sm'
6
+
7
+ export const shortcutSeparatorStyles =
8
+ 'text-muted-foreground text-xs'
@@ -0,0 +1,153 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+
3
+ export interface ShortcutProps {
4
+ /** Key combination (e.g., ['Ctrl', 'K'] or ['Meta', 'Shift', 'P']) */
5
+ keys: string[]
6
+ /** Callback when the shortcut is triggered */
7
+ onTrigger: () => void
8
+ /** Whether the shortcut is enabled */
9
+ enabled?: boolean
10
+ /** Prevent default browser behavior */
11
+ preventDefault?: boolean
12
+ }
13
+
14
+ export interface KeyboardShortcutAPI {
15
+ /** Handle a keyboard event (returns true if it matched) */
16
+ handler(event: KeyboardEvent): boolean
17
+ /** Human-readable display of the shortcut */
18
+ display: string
19
+ /** Platform-aware display (uses command symbol on Mac) */
20
+ platformDisplay: string
21
+ /** Whether the shortcut is currently enabled */
22
+ enabled: boolean
23
+ /** The key combination */
24
+ keys: string[]
25
+ /** ARIA props for a visual shortcut badge */
26
+ badgeAriaProps: Record<string, unknown>
27
+ }
28
+
29
+ const MODIFIER_KEYS = new Set(['Ctrl', 'Control', 'Alt', 'Shift', 'Meta', 'Cmd', 'Command'])
30
+
31
+ const KEY_DISPLAY: Record<string, string> = {
32
+ 'Ctrl': 'Ctrl',
33
+ 'Control': 'Ctrl',
34
+ 'Alt': 'Alt',
35
+ 'Shift': 'Shift',
36
+ 'Meta': 'Meta',
37
+ 'Cmd': 'Cmd',
38
+ 'Command': 'Cmd',
39
+ 'Enter': '\u21B5',
40
+ 'Backspace': '\u232B',
41
+ 'Delete': 'Del',
42
+ 'Escape': 'Esc',
43
+ 'ArrowUp': '\u2191',
44
+ 'ArrowDown': '\u2193',
45
+ 'ArrowLeft': '\u2190',
46
+ 'ArrowRight': '\u2192',
47
+ 'Tab': 'Tab',
48
+ ' ': 'Space',
49
+ }
50
+
51
+ const MAC_KEY_DISPLAY: Record<string, string> = {
52
+ 'Ctrl': '\u2303',
53
+ 'Control': '\u2303',
54
+ 'Alt': '\u2325',
55
+ 'Shift': '\u21E7',
56
+ 'Meta': '\u2318',
57
+ 'Cmd': '\u2318',
58
+ 'Command': '\u2318',
59
+ 'Enter': '\u21B5',
60
+ 'Backspace': '\u232B',
61
+ 'Delete': '\u2326',
62
+ 'Escape': '\u238B',
63
+ 'ArrowUp': '\u2191',
64
+ 'ArrowDown': '\u2193',
65
+ 'ArrowLeft': '\u2190',
66
+ 'ArrowRight': '\u2192',
67
+ 'Tab': '\u21E5',
68
+ ' ': '\u2423',
69
+ }
70
+
71
+ function normalizeKey(key: string): string {
72
+ // Normalize modifier variants
73
+ if (key === 'Command' || key === 'Cmd') return 'Meta'
74
+ if (key === 'Control') return 'Ctrl'
75
+ return key
76
+ }
77
+
78
+ function isMac(): boolean {
79
+ if (typeof navigator !== 'undefined') {
80
+ return navigator.platform?.includes('Mac') || navigator.userAgent?.includes('Mac')
81
+ }
82
+ return false
83
+ }
84
+
85
+ export function formatShortcut(keys: string[], mac?: boolean): string {
86
+ const displayMap = mac ? MAC_KEY_DISPLAY : KEY_DISPLAY
87
+ return keys.map((key) => displayMap[key] ?? key.toUpperCase()).join(mac ? '' : '+')
88
+ }
89
+
90
+ export function createKeyboardShortcut(props: ShortcutProps): KeyboardShortcutAPI {
91
+ const {
92
+ keys,
93
+ onTrigger,
94
+ enabled: enabledProp = true,
95
+ preventDefault: preventDefaultProp = true,
96
+ } = props
97
+
98
+ const normalizedKeys = keys.map(normalizeKey)
99
+ const modifiers = normalizedKeys.filter((k) => MODIFIER_KEYS.has(k))
100
+ const regularKeys = normalizedKeys.filter((k) => !MODIFIER_KEYS.has(k))
101
+
102
+ function handler(event: KeyboardEvent): boolean {
103
+ if (!enabledProp) return false
104
+
105
+ // Check modifiers
106
+ const ctrlRequired = modifiers.includes('Ctrl')
107
+ const altRequired = modifiers.includes('Alt')
108
+ const shiftRequired = modifiers.includes('Shift')
109
+ const metaRequired = modifiers.includes('Meta')
110
+
111
+ if (ctrlRequired !== (event.ctrlKey || event.metaKey && !metaRequired)) {
112
+ // For Ctrl, also accept Meta on Mac
113
+ }
114
+
115
+ const ctrlMatch = ctrlRequired ? event.ctrlKey : !event.ctrlKey
116
+ const altMatch = altRequired ? event.altKey : !event.altKey
117
+ const shiftMatch = shiftRequired ? event.shiftKey : !event.shiftKey
118
+ const metaMatch = metaRequired ? event.metaKey : !event.metaKey
119
+
120
+ if (!ctrlMatch || !altMatch || !shiftMatch || !metaMatch) return false
121
+
122
+ // Check regular key
123
+ if (regularKeys.length > 0) {
124
+ const eventKey = event.key.length === 1 ? event.key.toUpperCase() : event.key
125
+ const targetKey = regularKeys[0].length === 1 ? regularKeys[0].toUpperCase() : regularKeys[0]
126
+ if (eventKey !== targetKey) return false
127
+ }
128
+
129
+ if (preventDefaultProp) {
130
+ event.preventDefault()
131
+ }
132
+ onTrigger()
133
+ return true
134
+ }
135
+
136
+ const mac = isMac()
137
+ const display = formatShortcut(keys, false)
138
+ const platformDisplay = formatShortcut(keys, mac)
139
+
140
+ const badgeAriaProps: Record<string, unknown> = {
141
+ 'aria-hidden': true,
142
+ role: 'presentation',
143
+ }
144
+
145
+ return {
146
+ handler,
147
+ display,
148
+ platformDisplay,
149
+ enabled: enabledProp,
150
+ keys,
151
+ badgeAriaProps,
152
+ }
153
+ }
@@ -0,0 +1,8 @@
1
+ export {
2
+ createLanguageSelector,
3
+ type LanguageSelectorProps,
4
+ type LanguageSelectorAPI,
5
+ type LanguageOption,
6
+ } from './language-selector.js'
7
+
8
+ export { selectorVariants, optionVariants } from './language-selector.styles.js'
@@ -0,0 +1,28 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const selectorVariants = cva({
4
+ base: 'relative inline-flex items-center justify-between rounded-md border bg-background text-foreground cursor-pointer',
5
+ variants: {
6
+ size: {
7
+ sm: 'h-8 text-sm px-2 min-w-[120px]',
8
+ md: 'h-10 text-base px-3 min-w-[160px]',
9
+ lg: 'h-12 text-lg px-4 min-w-[200px]',
10
+ },
11
+ },
12
+ defaultVariants: {
13
+ size: 'md',
14
+ },
15
+ })
16
+
17
+ export const optionVariants = cva({
18
+ base: 'flex items-center gap-2 px-3 py-2 cursor-pointer hover:bg-accent',
19
+ variants: {
20
+ selected: {
21
+ true: 'bg-accent/50 font-medium',
22
+ false: '',
23
+ },
24
+ },
25
+ defaultVariants: {
26
+ selected: 'false',
27
+ },
28
+ })