@refraction-ui/astro 0.4.2 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/dist/accordion/index.ts +1 -0
  2. package/dist/ai/ai-manager.ts +121 -0
  3. package/dist/ai/index.ts +23 -0
  4. package/dist/ai/mock-providers.ts +68 -0
  5. package/dist/ai/sanitizer.ts +174 -0
  6. package/dist/ai/tts-manager.ts +80 -0
  7. package/dist/ai/types.ts +72 -0
  8. package/dist/animated-text/animated-text.styles.ts +28 -0
  9. package/dist/animated-text/animated-text.ts +83 -0
  10. package/dist/animated-text/index.ts +15 -0
  11. package/dist/app-shell/app-shell.ts +252 -0
  12. package/dist/app-shell/auth-shell.ts +84 -0
  13. package/dist/app-shell/index.ts +22 -0
  14. package/dist/app-shell/page-shell.ts +125 -0
  15. package/dist/astro-accordion/Button.astro +1 -1
  16. package/dist/astro-ai/index.ts +1 -1
  17. package/dist/astro-animated-text/AnimatedText.astro +1 -1
  18. package/dist/astro-animated-text/TypewriterText.astro +1 -1
  19. package/dist/astro-app-shell/AppShell.astro +1 -1
  20. package/dist/astro-app-shell/AuthShell.astro +1 -1
  21. package/dist/astro-app-shell/AuthShellCard.astro +1 -1
  22. package/dist/astro-app-shell/PageShell.astro +1 -1
  23. package/dist/astro-app-shell/PageShellSection.astro +1 -1
  24. package/dist/astro-app-shell/index.ts +1 -1
  25. package/dist/astro-auth/index.ts +2 -2
  26. package/dist/astro-avatar/Avatar.astro +1 -1
  27. package/dist/astro-avatar/AvatarFallback.astro +1 -1
  28. package/dist/astro-avatar/AvatarImage.astro +1 -1
  29. package/dist/astro-avatar-group/AvatarGroup.astro +1 -1
  30. package/dist/astro-badge/Badge.astro +1 -1
  31. package/dist/astro-bottom-nav/BottomNav.astro +1 -1
  32. package/dist/astro-breadcrumbs/Breadcrumbs.astro +1 -1
  33. package/dist/astro-button/Button.astro +1 -1
  34. package/dist/astro-calendar/Calendar.astro +1 -1
  35. package/dist/astro-card/Card.astro +1 -1
  36. package/dist/astro-card/CardContent.astro +1 -1
  37. package/dist/astro-card/CardDescription.astro +1 -1
  38. package/dist/astro-card/CardFooter.astro +1 -1
  39. package/dist/astro-card/CardHeader.astro +1 -1
  40. package/dist/astro-card/CardTitle.astro +1 -1
  41. package/dist/astro-card-grid/CardGrid.astro +1 -1
  42. package/dist/astro-carousel/Button.astro +1 -1
  43. package/dist/astro-charts/Bars.astro +1 -1
  44. package/dist/astro-charts/Chart.astro +1 -1
  45. package/dist/astro-charts/Circles.astro +1 -1
  46. package/dist/astro-charts/Histogram.astro +1 -1
  47. package/dist/astro-charts/Line.astro +1 -1
  48. package/dist/astro-charts/PieChart.astro +1 -1
  49. package/dist/astro-charts/ScatterPlot.astro +1 -1
  50. package/dist/astro-charts/index.ts +1 -1
  51. package/dist/astro-checkbox/Checkbox.astro +1 -1
  52. package/dist/astro-code-editor/CodeEditor.astro +1 -1
  53. package/dist/astro-collapsible/Collapsible.astro +1 -1
  54. package/dist/astro-collapsible/CollapsibleContent.astro +1 -1
  55. package/dist/astro-command/Command.astro +1 -1
  56. package/dist/astro-command/CommandGroup.astro +1 -1
  57. package/dist/astro-command/CommandInput.astro +1 -1
  58. package/dist/astro-command/CommandItem.astro +1 -1
  59. package/dist/astro-command-input/CommandInput.astro +1 -1
  60. package/dist/astro-content-protection/ContentProtection.astro +1 -1
  61. package/dist/astro-data-table/DataTable.astro +1 -1
  62. package/dist/astro-date-picker/DatePicker.astro +1 -1
  63. package/dist/astro-device-frame/DeviceFrame.astro +1 -1
  64. package/dist/astro-dialog/DialogContent.astro +1 -1
  65. package/dist/astro-dialog/DialogOverlay.astro +1 -1
  66. package/dist/astro-diff-viewer/DiffViewer.astro +1 -1
  67. package/dist/astro-dropdown-menu/DropdownMenuContent.astro +1 -1
  68. package/dist/astro-dropdown-menu/DropdownMenuItem.astro +1 -1
  69. package/dist/astro-emoji-picker/EmojiPicker.astro +1 -1
  70. package/dist/astro-feedback-dialog/FeedbackDialog.astro +1 -1
  71. package/dist/astro-file-upload/FileUpload.astro +1 -1
  72. package/dist/astro-footer/Footer.astro +1 -1
  73. package/dist/astro-inline-editor/InlineEditor.astro +1 -1
  74. package/dist/astro-input/Input.astro +1 -1
  75. package/dist/astro-input-group/InputGroup.astro +1 -1
  76. package/dist/astro-input-group/InputGroupAddon.astro +1 -1
  77. package/dist/astro-input-group/InputGroupButton.astro +1 -1
  78. package/dist/astro-install-prompt/InstallPrompt.astro +1 -1
  79. package/dist/astro-keyboard-shortcut/ShortcutBadge.astro +1 -1
  80. package/dist/astro-language-selector/LanguageSelector.astro +1 -1
  81. package/dist/astro-link-card/LinkCard.astro +1 -1
  82. package/dist/astro-markdown-renderer/MarkdownRenderer.astro +1 -1
  83. package/dist/astro-mobile-nav/MobileNav.astro +1 -1
  84. package/dist/astro-mobile-nav/MobileNavLink.astro +1 -1
  85. package/dist/astro-mobile-nav/MobileNavTrigger.astro +1 -1
  86. package/dist/astro-navbar/Navbar.astro +1 -1
  87. package/dist/astro-otp-input/OtpInput.astro +1 -1
  88. package/dist/astro-payment/Payment.astro +1 -1
  89. package/dist/astro-popover/PopoverContent.astro +1 -1
  90. package/dist/astro-presence-indicator/PresenceIndicator.astro +1 -1
  91. package/dist/astro-progress-display/BadgeDisplay.astro +1 -1
  92. package/dist/astro-progress-display/ProgressBar.astro +1 -1
  93. package/dist/astro-progress-display/StatsGrid.astro +1 -1
  94. package/dist/astro-radio/RadioGroup.astro +1 -1
  95. package/dist/astro-radio/RadioItem.astro +1 -1
  96. package/dist/astro-reaction-bar/ReactionBar.astro +1 -1
  97. package/dist/astro-resizable-layout/ResizableDivider.astro +1 -1
  98. package/dist/astro-resizable-layout/ResizableLayout.astro +1 -1
  99. package/dist/astro-resizable-layout/ResizablePane.astro +1 -1
  100. package/dist/astro-resizable-layout/index.ts +1 -1
  101. package/dist/astro-rich-editor/index.ts +2 -2
  102. package/dist/astro-search-bar/SearchBar.astro +1 -1
  103. package/dist/astro-search-bar/SearchResults.astro +1 -1
  104. package/dist/astro-select/Select.astro +1 -1
  105. package/dist/astro-select/SelectContent.astro +1 -1
  106. package/dist/astro-select/SelectItem.astro +1 -1
  107. package/dist/astro-select/SelectTrigger.astro +1 -1
  108. package/dist/astro-sidebar/Sidebar.astro +1 -1
  109. package/dist/astro-skeleton/Skeleton.astro +1 -1
  110. package/dist/astro-slide-viewer/SlideViewer.astro +1 -1
  111. package/dist/astro-status-indicator/StatusIndicator.astro +1 -1
  112. package/dist/astro-switch/Switch.astro +1 -1
  113. package/dist/astro-table-of-contents/TableOfContents.astro +1 -1
  114. package/dist/astro-tabs/Tabs.astro +1 -1
  115. package/dist/astro-tabs/TabsList.astro +1 -1
  116. package/dist/astro-tabs/TabsTrigger.astro +1 -1
  117. package/dist/astro-textarea/Textarea.astro +1 -1
  118. package/dist/astro-theme/ThemeScript.astro +1 -1
  119. package/dist/astro-thread-view/ThreadView.astro +1 -1
  120. package/dist/astro-toast/Toast.astro +1 -1
  121. package/dist/astro-tooltip/TooltipContent.astro +1 -1
  122. package/dist/astro-version-selector/VersionSelector.astro +1 -1
  123. package/dist/astro-video-player/VideoPlayer.astro +1 -1
  124. package/dist/auth/adapters/mock.ts +74 -0
  125. package/dist/auth/auth-machine.ts +120 -0
  126. package/dist/auth/index.ts +22 -0
  127. package/dist/auth/rbac.ts +44 -0
  128. package/dist/auth/types.ts +44 -0
  129. package/dist/avatar/avatar.styles.ts +47 -0
  130. package/dist/avatar/avatar.ts +73 -0
  131. package/dist/avatar/index.ts +15 -0
  132. package/dist/avatar-group/avatar-group.styles.ts +63 -0
  133. package/dist/avatar-group/avatar-group.ts +106 -0
  134. package/dist/avatar-group/index.ts +18 -0
  135. package/dist/badge/badge.styles.ts +24 -0
  136. package/dist/badge/badge.ts +48 -0
  137. package/dist/badge/index.ts +10 -0
  138. package/dist/bottom-nav/bottom-nav.styles.ts +18 -0
  139. package/dist/bottom-nav/bottom-nav.ts +33 -0
  140. package/dist/bottom-nav/index.ts +2 -0
  141. package/dist/breadcrumbs/breadcrumbs.styles.ts +20 -0
  142. package/dist/breadcrumbs/breadcrumbs.ts +72 -0
  143. package/dist/breadcrumbs/index.ts +8 -0
  144. package/dist/button/button.styles.ts +38 -0
  145. package/dist/button/button.ts +64 -0
  146. package/dist/button/index.ts +10 -0
  147. package/dist/calendar/calendar.styles.ts +21 -0
  148. package/dist/calendar/calendar.ts +202 -0
  149. package/dist/calendar/index.ts +9 -0
  150. package/dist/callout/callout.ts +1 -0
  151. package/dist/callout/index.ts +1 -0
  152. package/dist/card/card.styles.ts +55 -0
  153. package/dist/card/card.ts +45 -0
  154. package/dist/card/index.ts +20 -0
  155. package/dist/card-grid/card-grid.ts +9 -0
  156. package/dist/card-grid/index.ts +1 -0
  157. package/dist/carousel/index.ts +1 -0
  158. package/dist/charts/axis.ts +50 -0
  159. package/dist/charts/chart.ts +73 -0
  160. package/dist/charts/colorblind.ts +100 -0
  161. package/dist/charts/data.ts +72 -0
  162. package/dist/charts/geometry.ts +54 -0
  163. package/dist/charts/index.ts +61 -0
  164. package/dist/charts/scales.ts +151 -0
  165. package/dist/checkbox/checkbox.styles.ts +33 -0
  166. package/dist/checkbox/checkbox.ts +73 -0
  167. package/dist/checkbox/index.ts +10 -0
  168. package/dist/code-block/code-block.ts +1 -0
  169. package/dist/code-block/index.ts +1 -0
  170. package/dist/code-editor/code-editor.styles.ts +32 -0
  171. package/dist/code-editor/code-editor.ts +140 -0
  172. package/dist/code-editor/index.ts +9 -0
  173. package/dist/collapsible/collapsible.styles.ts +14 -0
  174. package/dist/collapsible/collapsible.ts +93 -0
  175. package/dist/collapsible/index.ts +7 -0
  176. package/dist/command/command.styles.ts +27 -0
  177. package/dist/command/command.ts +179 -0
  178. package/dist/command/index.ts +14 -0
  179. package/dist/command-input/command-input.ts +176 -0
  180. package/dist/command-input/index.ts +1 -0
  181. package/dist/content-protection/content-protection.styles.ts +9 -0
  182. package/dist/content-protection/content-protection.ts +68 -0
  183. package/dist/content-protection/index.ts +8 -0
  184. package/dist/data-table/data-table.styles.ts +55 -0
  185. package/dist/data-table/data-table.ts +183 -0
  186. package/dist/data-table/index.ts +15 -0
  187. package/dist/date-picker/date-picker.styles.ts +31 -0
  188. package/dist/date-picker/date-picker.ts +333 -0
  189. package/dist/date-picker/index.ts +18 -0
  190. package/dist/device-frame/device-frame.styles.ts +21 -0
  191. package/dist/device-frame/device-frame.ts +112 -0
  192. package/dist/device-frame/index.ts +10 -0
  193. package/dist/dialog/dialog.styles.ts +8 -0
  194. package/dist/dialog/dialog.ts +133 -0
  195. package/dist/dialog/index.ts +8 -0
  196. package/dist/diff-viewer/diff-viewer.styles.ts +124 -0
  197. package/dist/diff-viewer/diff-viewer.ts +255 -0
  198. package/dist/diff-viewer/index.ts +20 -0
  199. package/dist/dropdown-menu/dropdown-menu.styles.ts +9 -0
  200. package/dist/dropdown-menu/dropdown-menu.ts +139 -0
  201. package/dist/dropdown-menu/index.ts +9 -0
  202. package/dist/emoji-picker/emoji-data.ts +282 -0
  203. package/dist/emoji-picker/emoji-picker.styles.ts +32 -0
  204. package/dist/emoji-picker/emoji-picker.ts +165 -0
  205. package/dist/emoji-picker/index.ts +25 -0
  206. package/dist/feedback-dialog/feedback-dialog.styles.ts +15 -0
  207. package/dist/feedback-dialog/feedback-dialog.ts +147 -0
  208. package/dist/feedback-dialog/index.ts +11 -0
  209. package/dist/file-upload/file-upload.styles.ts +30 -0
  210. package/dist/file-upload/file-upload.ts +260 -0
  211. package/dist/file-upload/index.ts +19 -0
  212. package/dist/footer/footer.styles.ts +5 -0
  213. package/dist/footer/footer.ts +32 -0
  214. package/dist/footer/index.ts +9 -0
  215. package/dist/index.ts +1 -1
  216. package/dist/inline-editor/index.ts +13 -0
  217. package/dist/inline-editor/inline-editor.styles.ts +42 -0
  218. package/dist/inline-editor/inline-editor.ts +96 -0
  219. package/dist/input/index.ts +9 -0
  220. package/dist/input/input.styles.ts +15 -0
  221. package/dist/input/input.ts +84 -0
  222. package/dist/input-group/index.ts +13 -0
  223. package/dist/input-group/input-group.styles.ts +50 -0
  224. package/dist/input-group/input-group.ts +44 -0
  225. package/dist/install-prompt/index.ts +9 -0
  226. package/dist/install-prompt/install-prompt.styles.ts +5 -0
  227. package/dist/install-prompt/install-prompt.ts +68 -0
  228. package/dist/keyboard-shortcut/index.ts +12 -0
  229. package/dist/keyboard-shortcut/keyboard-shortcut.styles.ts +8 -0
  230. package/dist/keyboard-shortcut/keyboard-shortcut.ts +153 -0
  231. package/dist/language-selector/index.ts +8 -0
  232. package/dist/language-selector/language-selector.styles.ts +28 -0
  233. package/dist/language-selector/language-selector.ts +149 -0
  234. package/dist/link-card/index.ts +1 -0
  235. package/dist/link-card/link-card.ts +9 -0
  236. package/dist/markdown-renderer/index.ts +8 -0
  237. package/dist/markdown-renderer/markdown-renderer.styles.ts +31 -0
  238. package/dist/markdown-renderer/markdown-renderer.ts +251 -0
  239. package/dist/mobile-nav/index.ts +14 -0
  240. package/dist/mobile-nav/mobile-nav.styles.ts +39 -0
  241. package/dist/mobile-nav/mobile-nav.ts +74 -0
  242. package/dist/navbar/index.ts +9 -0
  243. package/dist/navbar/navbar.styles.ts +29 -0
  244. package/dist/navbar/navbar.ts +39 -0
  245. package/dist/otp-input/index.ts +13 -0
  246. package/dist/otp-input/otp-input.styles.ts +51 -0
  247. package/dist/otp-input/otp-input.ts +198 -0
  248. package/dist/pagination/index.ts +1 -0
  249. package/dist/payment/index.ts +1 -0
  250. package/dist/payment/payment.ts +16 -0
  251. package/dist/popover/index.ts +7 -0
  252. package/dist/popover/popover.styles.ts +16 -0
  253. package/dist/popover/popover.ts +89 -0
  254. package/dist/presence-indicator/index.ts +14 -0
  255. package/dist/presence-indicator/presence-indicator.styles.ts +29 -0
  256. package/dist/presence-indicator/presence-indicator.ts +63 -0
  257. package/dist/progress-display/index.ts +15 -0
  258. package/dist/progress-display/progress-display.styles.ts +72 -0
  259. package/dist/progress-display/progress-display.ts +60 -0
  260. package/dist/radio/index.ts +8 -0
  261. package/dist/radio/radio.styles.ts +34 -0
  262. package/dist/radio/radio.ts +70 -0
  263. package/dist/reaction-bar/index.ts +14 -0
  264. package/dist/reaction-bar/reaction-bar.styles.ts +23 -0
  265. package/dist/reaction-bar/reaction-bar.ts +87 -0
  266. package/dist/resizable-layout/index.ts +12 -0
  267. package/dist/resizable-layout/resizable-layout.styles.ts +50 -0
  268. package/dist/resizable-layout/resizable-layout.ts +139 -0
  269. package/dist/rich-editor/editor.ts +342 -0
  270. package/dist/rich-editor/emoji.ts +175 -0
  271. package/dist/rich-editor/history.ts +79 -0
  272. package/dist/rich-editor/index.ts +106 -0
  273. package/dist/rich-editor/markdown-shortcuts.ts +248 -0
  274. package/dist/rich-editor/mentions.ts +162 -0
  275. package/dist/rich-editor/model.ts +206 -0
  276. package/dist/rich-editor/operations.ts +772 -0
  277. package/dist/rich-editor/selection.ts +157 -0
  278. package/dist/rich-editor/serialization.ts +711 -0
  279. package/dist/rich-editor/slash-commands.ts +212 -0
  280. package/dist/search-bar/index.ts +7 -0
  281. package/dist/search-bar/search-bar.styles.ts +29 -0
  282. package/dist/search-bar/search-bar.ts +130 -0
  283. package/dist/select/index.ts +13 -0
  284. package/dist/select/select.styles.ts +52 -0
  285. package/dist/select/select.ts +152 -0
  286. package/dist/sidebar/index.ts +9 -0
  287. package/dist/sidebar/sidebar.styles.ts +27 -0
  288. package/dist/sidebar/sidebar.ts +59 -0
  289. package/dist/skeleton/index.ts +8 -0
  290. package/dist/skeleton/skeleton.styles.ts +16 -0
  291. package/dist/skeleton/skeleton.ts +39 -0
  292. package/dist/skip-to-content/index.ts +1 -0
  293. package/dist/skip-to-content/skip-to-content.ts +1 -0
  294. package/dist/slide-viewer/index.ts +16 -0
  295. package/dist/slide-viewer/slide-viewer.styles.ts +57 -0
  296. package/dist/slide-viewer/slide-viewer.ts +152 -0
  297. package/dist/slider/index.ts +1 -0
  298. package/dist/slider/slider.ts +2 -0
  299. package/dist/status-indicator/index.ts +15 -0
  300. package/dist/status-indicator/status-indicator.styles.ts +41 -0
  301. package/dist/status-indicator/status-indicator.ts +66 -0
  302. package/dist/steps/index.ts +1 -0
  303. package/dist/steps/steps.ts +1 -0
  304. package/dist/switch/index.ts +7 -0
  305. package/dist/switch/switch.styles.ts +55 -0
  306. package/dist/switch/switch.ts +63 -0
  307. package/dist/table-of-contents/index.ts +1 -0
  308. package/dist/table-of-contents/table-of-contents.ts +37 -0
  309. package/dist/tabs/index.ts +8 -0
  310. package/dist/tabs/tabs.styles.ts +9 -0
  311. package/dist/tabs/tabs.ts +133 -0
  312. package/dist/textarea/index.ts +7 -0
  313. package/dist/textarea/textarea.styles.ts +15 -0
  314. package/dist/textarea/textarea.ts +59 -0
  315. package/dist/theme/dom-adapters.ts +60 -0
  316. package/dist/theme/index.ts +18 -0
  317. package/dist/theme/theme-machine.ts +130 -0
  318. package/dist/theme/theme-script.ts +18 -0
  319. package/dist/thread-view/index.ts +26 -0
  320. package/dist/thread-view/thread-view.styles.ts +35 -0
  321. package/dist/thread-view/thread-view.ts +176 -0
  322. package/dist/toast/index.ts +13 -0
  323. package/dist/toast/toast.styles.ts +19 -0
  324. package/dist/toast/toast.ts +203 -0
  325. package/dist/tooltip/index.ts +7 -0
  326. package/dist/tooltip/tooltip.styles.ts +16 -0
  327. package/dist/tooltip/tooltip.ts +109 -0
  328. package/dist/version-selector/index.ts +12 -0
  329. package/dist/version-selector/version-selector.styles.ts +41 -0
  330. package/dist/version-selector/version-selector.ts +136 -0
  331. package/dist/video-player/index.ts +12 -0
  332. package/dist/video-player/video-player.styles.ts +42 -0
  333. package/dist/video-player/video-player.ts +100 -0
  334. package/package.json +1 -1
@@ -0,0 +1,8 @@
1
+ export {
2
+ createSkeleton,
3
+ type SkeletonShape,
4
+ type SkeletonProps,
5
+ type SkeletonAPI,
6
+ } from './skeleton.js'
7
+
8
+ export { skeletonVariants } from './skeleton.styles.js'
@@ -0,0 +1,16 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const skeletonVariants = cva({
4
+ base: 'animate-pulse bg-muted',
5
+ variants: {
6
+ shape: {
7
+ text: 'h-4 w-full rounded',
8
+ circular: 'rounded-full',
9
+ rectangular: 'rounded-none',
10
+ rounded: 'rounded-md',
11
+ },
12
+ },
13
+ defaultVariants: {
14
+ shape: 'text',
15
+ },
16
+ })
@@ -0,0 +1,39 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+
3
+ export type SkeletonShape = 'text' | 'circular' | 'rectangular' | 'rounded'
4
+
5
+ export interface SkeletonProps {
6
+ shape?: SkeletonShape
7
+ width?: string | number
8
+ height?: string | number
9
+ /** Number of lines to render for the text shape variant */
10
+ lines?: number
11
+ /** Whether to animate the skeleton pulse. Defaults to true */
12
+ animate?: boolean
13
+ }
14
+
15
+ export interface SkeletonAPI {
16
+ /** ARIA attributes to spread on the element */
17
+ ariaProps: Partial<AccessibilityProps>
18
+ /** Data attributes for CSS styling hooks */
19
+ dataAttributes: Record<string, string>
20
+ }
21
+
22
+ export function createSkeleton(props: SkeletonProps = {}): SkeletonAPI {
23
+ const { shape = 'text', animate = true } = props
24
+
25
+ const ariaProps: Partial<AccessibilityProps> = {
26
+ 'aria-hidden': true,
27
+ role: 'presentation',
28
+ }
29
+
30
+ const dataAttributes: Record<string, string> = {
31
+ 'data-shape': shape,
32
+ 'data-animate': String(animate),
33
+ }
34
+
35
+ return {
36
+ ariaProps,
37
+ dataAttributes,
38
+ }
39
+ }
@@ -0,0 +1 @@
1
+ export * from './skip-to-content';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ export {
2
+ createSlideViewer,
3
+ type SlideViewerProps,
4
+ type SlideViewerAPI,
5
+ type SlideViewerState,
6
+ type SlideData,
7
+ type SlideType,
8
+ type BookmarkType,
9
+ } from './slide-viewer.js'
10
+
11
+ export {
12
+ slideViewerVariants,
13
+ progressBarVariants,
14
+ slideTypeBadgeVariants,
15
+ slideViewerTokens,
16
+ } from './slide-viewer.styles.js'
@@ -0,0 +1,57 @@
1
+ import { cva } from '../shared/index.ts'
2
+ import type { TokenContract } from '../shared/index.ts'
3
+
4
+ export const slideViewerTokens: TokenContract = {
5
+ name: 'slide-viewer',
6
+ tokens: {
7
+ bg: { variable: '--rfr-slide-bg', fallback: 'hsl(var(--background))' },
8
+ fg: { variable: '--rfr-slide-fg', fallback: 'hsl(var(--foreground))' },
9
+ progressBg: { variable: '--rfr-slide-progress-bg', fallback: 'hsl(var(--primary))' },
10
+ progressTrack: { variable: '--rfr-slide-progress-track', fallback: 'hsl(var(--muted))' },
11
+ badgeBg: { variable: '--rfr-slide-badge-bg', fallback: 'hsl(var(--secondary))' },
12
+ },
13
+ }
14
+
15
+ export const slideViewerVariants = cva({
16
+ base: 'flex flex-col h-full w-full relative overflow-hidden',
17
+ variants: {
18
+ size: {
19
+ compact: 'max-w-2xl',
20
+ default: 'max-w-4xl',
21
+ full: 'max-w-none',
22
+ },
23
+ },
24
+ defaultVariants: {
25
+ size: 'default',
26
+ },
27
+ })
28
+
29
+ export const progressBarVariants = cva({
30
+ base: 'h-1 w-full bg-muted rounded-full overflow-hidden',
31
+ variants: {
32
+ position: {
33
+ top: 'rounded-none',
34
+ bottom: 'rounded-none',
35
+ inline: 'rounded-full',
36
+ },
37
+ },
38
+ defaultVariants: {
39
+ position: 'top',
40
+ },
41
+ })
42
+
43
+ export const slideTypeBadgeVariants = cva({
44
+ base: 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium',
45
+ variants: {
46
+ type: {
47
+ lesson: 'bg-blue-100 text-blue-800',
48
+ quiz: 'bg-purple-100 text-purple-800',
49
+ exercise: 'bg-green-100 text-green-800',
50
+ intro: 'bg-gray-100 text-gray-800',
51
+ summary: 'bg-orange-100 text-orange-800',
52
+ },
53
+ },
54
+ defaultVariants: {
55
+ type: 'lesson',
56
+ },
57
+ })
@@ -0,0 +1,152 @@
1
+ import type { AccessibilityProps, KeyboardHandlerMap } from '../shared/index.ts'
2
+ import { Keys } from '../shared/index.ts'
3
+
4
+ export type SlideType = 'lesson' | 'quiz' | 'exercise' | 'intro' | 'summary'
5
+
6
+ export type BookmarkType = 'important' | 'difficult' | 'to-revise'
7
+
8
+ export interface SlideData {
9
+ id: string
10
+ type: SlideType
11
+ content: string
12
+ }
13
+
14
+ export interface SlideViewerProps {
15
+ slides: SlideData[]
16
+ initialSlide?: number
17
+ onSlideChange?: (index: number) => void
18
+ onComplete?: () => void
19
+ }
20
+
21
+ export interface SlideViewerState {
22
+ currentSlide: number
23
+ totalSlides: number
24
+ bookmarks: Map<number, BookmarkType>
25
+ }
26
+
27
+ export interface SlideViewerAPI {
28
+ /** Current viewer state */
29
+ state: SlideViewerState
30
+ /** Navigate to the next slide */
31
+ next: () => void
32
+ /** Navigate to the previous slide */
33
+ prev: () => void
34
+ /** Navigate to a specific slide index */
35
+ goTo: (index: number) => void
36
+ /** Toggle a bookmark on the current slide */
37
+ toggleBookmark: (type: BookmarkType) => void
38
+ /** Get all bookmarks as an array of entries */
39
+ getBookmarks: () => Array<{ slide: number; type: BookmarkType }>
40
+ /** Current progress as a number between 0 and 1 */
41
+ progress: number
42
+ /** Keyboard handlers for slide navigation */
43
+ keyboardHandlers: KeyboardHandlerMap
44
+ /** ARIA props for the current slide */
45
+ getSlideAriaProps: () => Partial<AccessibilityProps> & { 'aria-roledescription'?: string }
46
+ }
47
+
48
+ /**
49
+ * Create a headless slide viewer.
50
+ *
51
+ * Manages slide navigation state, bookmarks, progress tracking,
52
+ * and keyboard navigation. Framework wrappers handle rendering.
53
+ */
54
+ export function createSlideViewer(props: SlideViewerProps): SlideViewerAPI {
55
+ const { slides, initialSlide = 0, onSlideChange, onComplete } = props
56
+
57
+ const totalSlides = slides.length
58
+ const bookmarks = new Map<number, BookmarkType>()
59
+
60
+ const state: SlideViewerState = {
61
+ currentSlide: Math.max(0, Math.min(initialSlide, totalSlides - 1)),
62
+ totalSlides,
63
+ bookmarks,
64
+ }
65
+
66
+ function updateProgress(): number {
67
+ if (totalSlides <= 1) return 1
68
+ return state.currentSlide / (totalSlides - 1)
69
+ }
70
+
71
+ function next() {
72
+ if (state.currentSlide < totalSlides - 1) {
73
+ state.currentSlide++
74
+ api.progress = updateProgress()
75
+ onSlideChange?.(state.currentSlide)
76
+ } else {
77
+ // Already on the last slide — trigger complete
78
+ onComplete?.()
79
+ }
80
+ }
81
+
82
+ function prev() {
83
+ if (state.currentSlide > 0) {
84
+ state.currentSlide--
85
+ api.progress = updateProgress()
86
+ onSlideChange?.(state.currentSlide)
87
+ }
88
+ }
89
+
90
+ function goTo(index: number) {
91
+ if (index >= 0 && index < totalSlides) {
92
+ state.currentSlide = index
93
+ api.progress = updateProgress()
94
+ onSlideChange?.(state.currentSlide)
95
+ }
96
+ }
97
+
98
+ function toggleBookmark(type: BookmarkType) {
99
+ const current = state.currentSlide
100
+ if (bookmarks.has(current) && bookmarks.get(current) === type) {
101
+ bookmarks.delete(current)
102
+ } else {
103
+ bookmarks.set(current, type)
104
+ }
105
+ }
106
+
107
+ function getBookmarks(): Array<{ slide: number; type: BookmarkType }> {
108
+ const result: Array<{ slide: number; type: BookmarkType }> = []
109
+ for (const [slide, type] of bookmarks.entries()) {
110
+ result.push({ slide, type })
111
+ }
112
+ return result.sort((a, b) => a.slide - b.slide)
113
+ }
114
+
115
+ const keyboardHandlers: KeyboardHandlerMap = {
116
+ [Keys.ArrowRight]: (e) => {
117
+ e.preventDefault()
118
+ next()
119
+ },
120
+ [Keys.ArrowLeft]: (e) => {
121
+ e.preventDefault()
122
+ prev()
123
+ },
124
+ [Keys.Escape]: (e) => {
125
+ e.preventDefault()
126
+ },
127
+ }
128
+
129
+ function getSlideAriaProps(): Partial<AccessibilityProps> & { 'aria-roledescription'?: string } {
130
+ const slide = slides[state.currentSlide]
131
+ return {
132
+ role: 'region',
133
+ 'aria-roledescription': 'slide',
134
+ 'aria-label': `Slide ${state.currentSlide + 1} of ${totalSlides}: ${slide?.type ?? 'unknown'} slide`,
135
+ 'aria-live': 'polite',
136
+ }
137
+ }
138
+
139
+ const api: SlideViewerAPI = {
140
+ state,
141
+ next,
142
+ prev,
143
+ goTo,
144
+ toggleBookmark,
145
+ getBookmarks,
146
+ progress: updateProgress(),
147
+ keyboardHandlers,
148
+ getSlideAriaProps,
149
+ }
150
+
151
+ return api
152
+ }
@@ -0,0 +1 @@
1
+ export * from './slider.js'
@@ -0,0 +1,2 @@
1
+ // Core slider logic
2
+ export interface SliderProps {}
@@ -0,0 +1,15 @@
1
+ export {
2
+ createStatusIndicator,
3
+ STATUS_COLORS,
4
+ STATUS_LABELS,
5
+ type StatusProps,
6
+ type StatusAPI,
7
+ type StatusType,
8
+ } from './status-indicator.js'
9
+
10
+ export {
11
+ statusContainerStyles,
12
+ statusDotVariants,
13
+ statusPulseVariants,
14
+ statusLabelStyles,
15
+ } from './status-indicator.styles.js'
@@ -0,0 +1,41 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const statusContainerStyles =
4
+ 'inline-flex items-center gap-1.5'
5
+
6
+ export const statusDotVariants = cva({
7
+ base: 'inline-block h-2 w-2 rounded-full',
8
+ variants: {
9
+ type: {
10
+ success: 'bg-green-500',
11
+ error: 'bg-red-500',
12
+ warning: 'bg-yellow-500',
13
+ info: 'bg-blue-500',
14
+ pending: 'bg-orange-500',
15
+ neutral: 'bg-gray-400',
16
+ },
17
+ },
18
+ defaultVariants: {
19
+ type: 'neutral',
20
+ },
21
+ })
22
+
23
+ export const statusPulseVariants = cva({
24
+ base: 'animate-pulse inline-block h-2 w-2 rounded-full',
25
+ variants: {
26
+ type: {
27
+ success: 'bg-green-500',
28
+ error: 'bg-red-500',
29
+ warning: 'bg-yellow-500',
30
+ info: 'bg-blue-500',
31
+ pending: 'bg-orange-500',
32
+ neutral: 'bg-gray-400',
33
+ },
34
+ },
35
+ defaultVariants: {
36
+ type: 'pending',
37
+ },
38
+ })
39
+
40
+ export const statusLabelStyles =
41
+ 'text-sm text-muted-foreground'
@@ -0,0 +1,66 @@
1
+ import type { AccessibilityProps } from '../shared/index.ts'
2
+
3
+ export type StatusType = 'success' | 'error' | 'warning' | 'info' | 'pending' | 'neutral'
4
+
5
+ export interface StatusProps {
6
+ /** The status type */
7
+ type: StatusType
8
+ /** Label to display alongside the status dot */
9
+ label?: string
10
+ /** Whether to show a pulse animation (primarily for 'pending' status) */
11
+ pulse?: boolean
12
+ }
13
+
14
+ export interface StatusAPI {
15
+ /** ARIA attributes for the status indicator */
16
+ ariaProps: Partial<AccessibilityProps> & Record<string, unknown>
17
+ /** The status type */
18
+ type: StatusType
19
+ /** The display label */
20
+ label: string
21
+ /** Whether to show pulse animation */
22
+ pulse: boolean
23
+ /** CSS color class name for the dot */
24
+ color: string
25
+ }
26
+
27
+ const STATUS_COLORS: Record<StatusType, string> = {
28
+ success: 'green',
29
+ error: 'red',
30
+ warning: 'yellow',
31
+ info: 'blue',
32
+ pending: 'orange',
33
+ neutral: 'gray',
34
+ }
35
+
36
+ const STATUS_LABELS: Record<StatusType, string> = {
37
+ success: 'Success',
38
+ error: 'Error',
39
+ warning: 'Warning',
40
+ info: 'Info',
41
+ pending: 'Pending',
42
+ neutral: 'Neutral',
43
+ }
44
+
45
+ export { STATUS_COLORS, STATUS_LABELS }
46
+
47
+ export function createStatusIndicator(props: StatusProps): StatusAPI {
48
+ const { type, label: labelOverride, pulse: pulseOverride } = props
49
+
50
+ const color = STATUS_COLORS[type]
51
+ const label = labelOverride ?? STATUS_LABELS[type]
52
+ const pulse = pulseOverride ?? (type === 'pending')
53
+
54
+ const ariaProps: Partial<AccessibilityProps> & Record<string, unknown> = {
55
+ role: 'status',
56
+ 'aria-label': label,
57
+ }
58
+
59
+ return {
60
+ ariaProps,
61
+ type,
62
+ label,
63
+ pulse,
64
+ color,
65
+ }
66
+ }
@@ -0,0 +1 @@
1
+ export * from './steps';
@@ -0,0 +1 @@
1
+ export const steps = {};
@@ -0,0 +1,7 @@
1
+ export {
2
+ createSwitch,
3
+ type SwitchProps,
4
+ type SwitchAPI,
5
+ } from './switch.js'
6
+
7
+ export { switchVariants, switchThumbVariants, switchTokens } from './switch.styles.js'
@@ -0,0 +1,55 @@
1
+ import { cva } from '../shared/index.ts'
2
+ import type { TokenContract } from '../shared/index.ts'
3
+
4
+ export const switchTokens: TokenContract = {
5
+ name: 'switch',
6
+ tokens: {
7
+ bg: { variable: '--rfr-switch-bg', fallback: 'hsl(var(--input))' },
8
+ 'bg-checked': { variable: '--rfr-switch-bg-checked', fallback: 'hsl(var(--primary))' },
9
+ thumb: { variable: '--rfr-switch-thumb', fallback: 'hsl(var(--background))' },
10
+ ring: { variable: '--rfr-switch-ring', fallback: 'hsl(var(--ring))' },
11
+ },
12
+ }
13
+
14
+ export const switchVariants = cva({
15
+ base: 'peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50',
16
+ variants: {
17
+ checked: {
18
+ true: 'bg-primary',
19
+ false: 'bg-input',
20
+ },
21
+ size: {
22
+ sm: 'h-4 w-7',
23
+ default: 'h-5 w-9',
24
+ lg: 'h-6 w-11',
25
+ },
26
+ },
27
+ defaultVariants: {
28
+ checked: 'false',
29
+ size: 'default',
30
+ },
31
+ })
32
+
33
+ export const switchThumbVariants = cva({
34
+ base: 'pointer-events-none block rounded-full bg-background shadow-lg ring-0 transition-transform',
35
+ variants: {
36
+ checked: {
37
+ true: '',
38
+ false: 'translate-x-0',
39
+ },
40
+ size: {
41
+ sm: 'h-3 w-3',
42
+ default: 'h-4 w-4',
43
+ lg: 'h-5 w-5',
44
+ },
45
+ },
46
+ defaultVariants: {
47
+ checked: 'false',
48
+ size: 'default',
49
+ },
50
+ compoundVariants: [
51
+ { checked: 'true', size: 'sm', class: 'translate-x-3' },
52
+ { checked: 'true', size: 'default', class: 'translate-x-4' },
53
+ { checked: 'true', size: 'lg', class: 'translate-x-5' },
54
+ ],
55
+ })
@@ -0,0 +1,63 @@
1
+ import type { AccessibilityProps, KeyboardHandlerMap } from '../shared/index.ts'
2
+ import { Keys } from '../shared/index.ts'
3
+
4
+ export interface SwitchProps {
5
+ checked?: boolean
6
+ disabled?: boolean
7
+ required?: boolean
8
+ name?: string
9
+ value?: string
10
+ }
11
+
12
+ export interface SwitchAPI {
13
+ /** ARIA attributes to spread on the element */
14
+ ariaProps: Partial<AccessibilityProps>
15
+ /** Keyboard handlers to attach */
16
+ keyboardHandlers: KeyboardHandlerMap
17
+ /** Whether interaction should be blocked */
18
+ isInteractive: boolean
19
+ /** Data attributes for CSS styling hooks */
20
+ dataAttributes: Record<string, string>
21
+ /** Current state */
22
+ state: {
23
+ checked: boolean
24
+ disabled: boolean
25
+ }
26
+ }
27
+
28
+ export function createSwitch(props: SwitchProps = {}): SwitchAPI {
29
+ const { checked = false, disabled = false } = props
30
+ const isInteractive = !disabled
31
+
32
+ const ariaProps: Partial<AccessibilityProps> = {
33
+ role: 'switch',
34
+ 'aria-checked': checked,
35
+ }
36
+
37
+ if (disabled) {
38
+ ariaProps['aria-disabled'] = true
39
+ }
40
+
41
+ const dataAttributes: Record<string, string> = {}
42
+ if (checked) {
43
+ dataAttributes['data-state'] = 'checked'
44
+ } else {
45
+ dataAttributes['data-state'] = 'unchecked'
46
+ }
47
+ if (disabled) {
48
+ dataAttributes['data-disabled'] = ''
49
+ }
50
+
51
+ const keyboardHandlers: KeyboardHandlerMap = {}
52
+ if (!isInteractive) {
53
+ keyboardHandlers[Keys.Space] = (e) => e.preventDefault()
54
+ }
55
+
56
+ return {
57
+ ariaProps,
58
+ keyboardHandlers,
59
+ isInteractive,
60
+ dataAttributes,
61
+ state: { checked, disabled },
62
+ }
63
+ }
@@ -0,0 +1 @@
1
+ export * from './table-of-contents'
@@ -0,0 +1,37 @@
1
+ export interface TocItem {
2
+ id: string;
3
+ text: string;
4
+ level: number;
5
+ }
6
+
7
+ export function parseHeadings(container: HTMLElement, selectors = 'h2, h3, h4'): TocItem[] {
8
+ const headings = Array.from(container.querySelectorAll(selectors));
9
+ return headings.map(h => ({
10
+ id: h.id || h.textContent?.toLowerCase().replace(/\s+/g, '-') || '',
11
+ text: h.textContent || '',
12
+ level: parseInt(h.tagName.charAt(1), 10)
13
+ })).filter(h => h.id !== ''); // Ensure headings have IDs
14
+ }
15
+
16
+ export function observeHeadings(
17
+ headingIds: string[],
18
+ callback: (activeId: string) => void,
19
+ options?: IntersectionObserverInit
20
+ ): () => void {
21
+ const observer = new IntersectionObserver((entries) => {
22
+ // Find the first intersecting entry
23
+ for (const entry of entries) {
24
+ if (entry.isIntersecting) {
25
+ callback(entry.target.id);
26
+ break; // Or handle multiple, but usually we just care about one
27
+ }
28
+ }
29
+ }, { rootMargin: '0px 0px -80% 0px', ...options });
30
+
31
+ headingIds.forEach(id => {
32
+ const el = document.getElementById(id);
33
+ if (el) observer.observe(el);
34
+ });
35
+
36
+ return () => observer.disconnect();
37
+ }
@@ -0,0 +1,8 @@
1
+ export {
2
+ createTabs,
3
+ type TabsProps,
4
+ type TabsAPI,
5
+ type TabsState,
6
+ } from './tabs.js'
7
+
8
+ export { tabsListVariants, tabsTriggerVariants } from './tabs.styles.js'
@@ -0,0 +1,9 @@
1
+ import { cva } from '../shared/index.ts'
2
+
3
+ export const tabsListVariants = cva({
4
+ base: 'inline-flex max-w-full overflow-x-auto items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',
5
+ })
6
+
7
+ export const tabsTriggerVariants = cva({
8
+ base: 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow',
9
+ })