@refraction-ui/astro 0.4.0 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accordion/index.ts +1 -0
- package/dist/ai/ai-manager.ts +121 -0
- package/dist/ai/index.ts +23 -0
- package/dist/ai/mock-providers.ts +68 -0
- package/dist/ai/sanitizer.ts +174 -0
- package/dist/ai/tts-manager.ts +80 -0
- package/dist/ai/types.ts +72 -0
- package/dist/animated-text/animated-text.styles.ts +28 -0
- package/dist/animated-text/animated-text.ts +83 -0
- package/dist/animated-text/index.ts +15 -0
- package/dist/app-shell/app-shell.ts +252 -0
- package/dist/app-shell/auth-shell.ts +84 -0
- package/dist/app-shell/index.ts +22 -0
- package/dist/app-shell/page-shell.ts +125 -0
- package/dist/astro-accordion/Button.astro +55 -0
- package/dist/astro-accordion/index.ts +1 -0
- package/dist/astro-ai/AIScript.astro +69 -0
- package/dist/astro-ai/TTSScript.astro +60 -0
- package/dist/astro-ai/index.ts +16 -0
- package/dist/astro-animated-text/AnimatedText.astro +81 -0
- package/dist/astro-animated-text/TypewriterText.astro +90 -0
- package/dist/astro-animated-text/index.ts +1 -0
- package/dist/astro-app-shell/AppShell.astro +195 -0
- package/dist/astro-app-shell/AppShellContent.astro +29 -0
- package/dist/astro-app-shell/AppShellHeader.astro +54 -0
- package/dist/astro-app-shell/AppShellMain.astro +18 -0
- package/dist/astro-app-shell/AppShellMobileNav.astro +27 -0
- package/dist/astro-app-shell/AppShellOverlay.astro +21 -0
- package/dist/astro-app-shell/AppShellSidebar.astro +26 -0
- package/dist/astro-app-shell/AuthShell.astro +31 -0
- package/dist/astro-app-shell/AuthShellCard.astro +24 -0
- package/dist/astro-app-shell/PageShell.astro +36 -0
- package/dist/astro-app-shell/PageShellFooter.astro +30 -0
- package/dist/astro-app-shell/PageShellNav.astro +33 -0
- package/dist/astro-app-shell/PageShellSection.astro +32 -0
- package/dist/astro-app-shell/index.ts +21 -0
- package/dist/astro-auth/AuthGuard.astro +133 -0
- package/dist/astro-auth/index.ts +5 -0
- package/dist/astro-avatar/Avatar.astro +22 -0
- package/dist/astro-avatar/AvatarFallback.astro +18 -0
- package/dist/astro-avatar/AvatarImage.astro +48 -0
- package/dist/astro-avatar/index.ts +1 -0
- package/dist/astro-avatar-group/AvatarGroup.astro +42 -0
- package/dist/astro-avatar-group/index.ts +1 -0
- package/dist/astro-badge/Badge.astro +27 -0
- package/dist/astro-badge/index.ts +1 -0
- package/dist/astro-bottom-nav/BottomNav.astro +40 -0
- package/dist/astro-bottom-nav/index.ts +1 -0
- package/dist/astro-breadcrumbs/Breadcrumbs.astro +56 -0
- package/dist/astro-breadcrumbs/index.ts +1 -0
- package/dist/astro-button/Button.astro +55 -0
- package/dist/astro-button/index.ts +1 -0
- package/dist/astro-calendar/Calendar.astro +259 -0
- package/dist/astro-calendar/index.ts +1 -0
- package/dist/astro-callout/Callout.astro +3 -0
- package/dist/astro-callout/index.ts +1 -0
- package/dist/astro-card/Card.astro +20 -0
- package/dist/astro-card/CardContent.astro +13 -0
- package/dist/astro-card/CardDescription.astro +13 -0
- package/dist/astro-card/CardFooter.astro +13 -0
- package/dist/astro-card/CardHeader.astro +13 -0
- package/dist/astro-card/CardTitle.astro +15 -0
- package/dist/astro-card/index.ts +1 -0
- package/dist/astro-card-grid/CardGrid.astro +17 -0
- package/dist/astro-card-grid/index.ts +1 -0
- package/dist/astro-carousel/Button.astro +55 -0
- package/dist/astro-carousel/index.ts +1 -0
- package/dist/astro-charts/Bars.astro +53 -0
- package/dist/astro-charts/Chart.astro +31 -0
- package/dist/astro-charts/Circles.astro +48 -0
- package/dist/astro-charts/Gradient.astro +34 -0
- package/dist/astro-charts/Histogram.astro +107 -0
- package/dist/astro-charts/Line.astro +55 -0
- package/dist/astro-charts/PieChart.astro +63 -0
- package/dist/astro-charts/ScatterPlot.astro +95 -0
- package/dist/astro-charts/XAxis.astro +46 -0
- package/dist/astro-charts/YAxis.astro +44 -0
- package/dist/astro-charts/index.ts +26 -0
- package/dist/astro-checkbox/Checkbox.astro +129 -0
- package/dist/astro-checkbox/index.ts +1 -0
- package/dist/astro-code-block/CodeBlock.astro +3 -0
- package/dist/astro-code-block/index.ts +1 -0
- package/dist/astro-code-editor/CodeEditor.astro +123 -0
- package/dist/astro-code-editor/index.ts +1 -0
- package/dist/astro-collapsible/Collapsible.astro +58 -0
- package/dist/astro-collapsible/CollapsibleContent.astro +21 -0
- package/dist/astro-collapsible/CollapsibleTrigger.astro +17 -0
- package/dist/astro-collapsible/index.ts +1 -0
- package/dist/astro-command/Command.astro +170 -0
- package/dist/astro-command/CommandEmpty.astro +17 -0
- package/dist/astro-command/CommandGroup.astro +25 -0
- package/dist/astro-command/CommandInput.astro +21 -0
- package/dist/astro-command/CommandItem.astro +26 -0
- package/dist/astro-command/CommandList.astro +17 -0
- package/dist/astro-command/CommandSeparator.astro +14 -0
- package/dist/astro-command/index.ts +1 -0
- package/dist/astro-command-input/CommandInput.astro +6 -0
- package/dist/astro-command-input/index.ts +1 -0
- package/dist/astro-content-protection/ContentProtection.astro +104 -0
- package/dist/astro-content-protection/index.ts +1 -0
- package/dist/astro-data-table/DataTable.astro +263 -0
- package/dist/astro-data-table/index.ts +1 -0
- package/dist/astro-date-picker/DatePicker.astro +398 -0
- package/dist/astro-date-picker/index.ts +1 -0
- package/dist/astro-device-frame/DeviceFrame.astro +44 -0
- package/dist/astro-device-frame/index.ts +1 -0
- package/dist/astro-dialog/Dialog.astro +138 -0
- package/dist/astro-dialog/DialogClose.astro +16 -0
- package/dist/astro-dialog/DialogContent.astro +24 -0
- package/dist/astro-dialog/DialogDescription.astro +15 -0
- package/dist/astro-dialog/DialogFooter.astro +14 -0
- package/dist/astro-dialog/DialogHeader.astro +14 -0
- package/dist/astro-dialog/DialogOverlay.astro +17 -0
- package/dist/astro-dialog/DialogTitle.astro +15 -0
- package/dist/astro-dialog/DialogTrigger.astro +18 -0
- package/dist/astro-dialog/index.ts +1 -0
- package/dist/astro-diff-viewer/DiffViewer.astro +371 -0
- package/dist/astro-diff-viewer/index.ts +1 -0
- package/dist/astro-dropdown-menu/DropdownMenu.astro +138 -0
- package/dist/astro-dropdown-menu/DropdownMenuContent.astro +20 -0
- package/dist/astro-dropdown-menu/DropdownMenuItem.astro +21 -0
- package/dist/astro-dropdown-menu/DropdownMenuLabel.astro +14 -0
- package/dist/astro-dropdown-menu/DropdownMenuSeparator.astro +14 -0
- package/dist/astro-dropdown-menu/DropdownMenuTrigger.astro +18 -0
- package/dist/astro-dropdown-menu/index.ts +1 -0
- package/dist/astro-emoji-picker/EmojiPicker.astro +255 -0
- package/dist/astro-emoji-picker/index.ts +1 -0
- package/dist/astro-feedback-dialog/FeedbackDialog.astro +152 -0
- package/dist/astro-feedback-dialog/index.ts +1 -0
- package/dist/astro-file-tree/astro-file-tree.astro +4 -0
- package/dist/astro-file-tree/index.ts +1 -0
- package/dist/astro-file-upload/FileUpload.astro +306 -0
- package/dist/astro-file-upload/index.ts +1 -0
- package/dist/astro-footer/Footer.astro +61 -0
- package/dist/astro-footer/index.ts +1 -0
- package/dist/astro-icon-system/astro-icon-system.astro +4 -0
- package/dist/astro-icon-system/index.ts +1 -0
- package/dist/astro-inline-editor/InlineEditor.astro +169 -0
- package/dist/astro-inline-editor/index.ts +1 -0
- package/dist/astro-input/Input.astro +49 -0
- package/dist/astro-input/index.ts +1 -0
- package/dist/astro-input-group/InputGroup.astro +29 -0
- package/dist/astro-input-group/InputGroupAddon.astro +14 -0
- package/dist/astro-input-group/InputGroupButton.astro +19 -0
- package/dist/astro-input-group/InputGroupText.astro +11 -0
- package/dist/astro-input-group/index.ts +1 -0
- package/dist/astro-install-prompt/InstallPrompt.astro +115 -0
- package/dist/astro-install-prompt/index.ts +1 -0
- package/dist/astro-keyboard-shortcut/KeyboardShortcut.astro +83 -0
- package/dist/astro-keyboard-shortcut/ShortcutBadge.astro +41 -0
- package/dist/astro-keyboard-shortcut/index.ts +1 -0
- package/dist/astro-language-selector/LanguageSelector.astro +247 -0
- package/dist/astro-language-selector/index.ts +1 -0
- package/dist/astro-link-card/LinkCard.astro +17 -0
- package/dist/astro-link-card/index.ts +1 -0
- package/dist/astro-markdown-renderer/MarkdownRenderer.astro +62 -0
- package/dist/astro-markdown-renderer/index.ts +1 -0
- package/dist/astro-mobile-nav/MobileNav.astro +84 -0
- package/dist/astro-mobile-nav/MobileNavContent.astro +29 -0
- package/dist/astro-mobile-nav/MobileNavLink.astro +16 -0
- package/dist/astro-mobile-nav/MobileNavTrigger.astro +57 -0
- package/dist/astro-mobile-nav/index.ts +1 -0
- package/dist/astro-navbar/Navbar.astro +49 -0
- package/dist/astro-navbar/index.ts +1 -0
- package/dist/astro-otp-input/OtpInput.astro +253 -0
- package/dist/astro-otp-input/index.ts +1 -0
- package/dist/astro-pagination/Pagination.astro +3 -0
- package/dist/astro-pagination/index.ts +1 -0
- package/dist/astro-payment/Payment.astro +19 -0
- package/dist/astro-payment/index.ts +1 -0
- package/dist/astro-popover/Popover.astro +87 -0
- package/dist/astro-popover/PopoverClose.astro +16 -0
- package/dist/astro-popover/PopoverContent.astro +23 -0
- package/dist/astro-popover/PopoverTrigger.astro +18 -0
- package/dist/astro-popover/index.ts +1 -0
- package/dist/astro-presence-indicator/PresenceIndicator.astro +26 -0
- package/dist/astro-presence-indicator/index.ts +1 -0
- package/dist/astro-progress-display/BadgeDisplay.astro +33 -0
- package/dist/astro-progress-display/ProgressBar.astro +27 -0
- package/dist/astro-progress-display/StatsGrid.astro +32 -0
- package/dist/astro-progress-display/index.ts +1 -0
- package/dist/astro-radio/RadioGroup.astro +111 -0
- package/dist/astro-radio/RadioItem.astro +36 -0
- package/dist/astro-radio/index.ts +1 -0
- package/dist/astro-reaction-bar/ReactionBar.astro +117 -0
- package/dist/astro-reaction-bar/index.ts +1 -0
- package/dist/astro-resizable-layout/ResizableDivider.astro +27 -0
- package/dist/astro-resizable-layout/ResizableLayout.astro +162 -0
- package/dist/astro-resizable-layout/ResizablePane.astro +28 -0
- package/dist/astro-resizable-layout/index.ts +11 -0
- package/dist/astro-rich-editor/RichEditor.astro +260 -0
- package/dist/astro-rich-editor/index.ts +25 -0
- package/dist/astro-search-bar/SearchBar.astro +140 -0
- package/dist/astro-search-bar/SearchResultItem.astro +16 -0
- package/dist/astro-search-bar/SearchResults.astro +17 -0
- package/dist/astro-search-bar/index.ts +1 -0
- package/dist/astro-select/Select.astro +165 -0
- package/dist/astro-select/SelectContent.astro +19 -0
- package/dist/astro-select/SelectItem.astro +42 -0
- package/dist/astro-select/SelectTrigger.astro +36 -0
- package/dist/astro-select/index.ts +1 -0
- package/dist/astro-sidebar/Sidebar.astro +64 -0
- package/dist/astro-sidebar/index.ts +1 -0
- package/dist/astro-skeleton/Skeleton.astro +39 -0
- package/dist/astro-skeleton/SkeletonText.astro +22 -0
- package/dist/astro-skeleton/index.ts +1 -0
- package/dist/astro-skip-to-content/SkipToContent.astro +3 -0
- package/dist/astro-skip-to-content/index.ts +1 -0
- package/dist/astro-slide-viewer/SlideViewer.astro +231 -0
- package/dist/astro-slide-viewer/index.ts +1 -0
- package/dist/astro-slider/index.ts +1 -0
- package/dist/astro-status-indicator/StatusIndicator.astro +31 -0
- package/dist/astro-status-indicator/index.ts +1 -0
- package/dist/astro-steps/Steps.astro +3 -0
- package/dist/astro-steps/index.ts +1 -0
- package/dist/astro-switch/Switch.astro +89 -0
- package/dist/astro-switch/index.ts +1 -0
- package/dist/astro-table-of-contents/TableOfContents.astro +53 -0
- package/dist/astro-table-of-contents/index.ts +1 -0
- package/dist/astro-tabs/Tabs.astro +96 -0
- package/dist/astro-tabs/TabsContent.astro +20 -0
- package/dist/astro-tabs/TabsList.astro +16 -0
- package/dist/astro-tabs/TabsTrigger.astro +24 -0
- package/dist/astro-tabs/index.ts +1 -0
- package/dist/astro-textarea/Textarea.astro +51 -0
- package/dist/astro-textarea/index.ts +1 -0
- package/dist/astro-theme/ThemeScript.astro +13 -0
- package/dist/astro-theme/ThemeToggle.astro +279 -0
- package/dist/astro-theme/index.ts +1 -0
- package/dist/astro-thread-view/ThreadView.astro +159 -0
- package/dist/astro-thread-view/index.ts +1 -0
- package/dist/astro-toast/Toast.astro +49 -0
- package/dist/astro-toast/Toaster.astro +142 -0
- package/dist/astro-toast/index.ts +1 -0
- package/dist/astro-tooltip/Tooltip.astro +95 -0
- package/dist/astro-tooltip/TooltipContent.astro +22 -0
- package/dist/astro-tooltip/TooltipTrigger.astro +16 -0
- package/dist/astro-tooltip/index.ts +1 -0
- package/dist/astro-version-selector/VersionSelector.astro +174 -0
- package/dist/astro-version-selector/index.ts +1 -0
- package/dist/astro-video-player/VideoPlayer.astro +153 -0
- package/dist/astro-video-player/index.ts +1 -0
- package/dist/auth/adapters/mock.ts +74 -0
- package/dist/auth/auth-machine.ts +120 -0
- package/dist/auth/index.ts +22 -0
- package/dist/auth/rbac.ts +44 -0
- package/dist/auth/types.ts +44 -0
- package/dist/avatar/avatar.styles.ts +47 -0
- package/dist/avatar/avatar.ts +73 -0
- package/dist/avatar/index.ts +15 -0
- package/dist/avatar-group/avatar-group.styles.ts +63 -0
- package/dist/avatar-group/avatar-group.ts +106 -0
- package/dist/avatar-group/index.ts +18 -0
- package/dist/badge/badge.styles.ts +24 -0
- package/dist/badge/badge.ts +48 -0
- package/dist/badge/index.ts +10 -0
- package/dist/bottom-nav/bottom-nav.styles.ts +18 -0
- package/dist/bottom-nav/bottom-nav.ts +33 -0
- package/dist/bottom-nav/index.ts +2 -0
- package/dist/breadcrumbs/breadcrumbs.styles.ts +20 -0
- package/dist/breadcrumbs/breadcrumbs.ts +72 -0
- package/dist/breadcrumbs/index.ts +8 -0
- package/dist/button/button.styles.ts +38 -0
- package/dist/button/button.ts +64 -0
- package/dist/button/index.ts +10 -0
- package/dist/calendar/calendar.styles.ts +21 -0
- package/dist/calendar/calendar.ts +202 -0
- package/dist/calendar/index.ts +9 -0
- package/dist/callout/callout.ts +1 -0
- package/dist/callout/index.ts +1 -0
- package/dist/card/card.styles.ts +55 -0
- package/dist/card/card.ts +45 -0
- package/dist/card/index.ts +20 -0
- package/dist/card-grid/card-grid.ts +9 -0
- package/dist/card-grid/index.ts +1 -0
- package/dist/carousel/index.ts +1 -0
- package/dist/charts/axis.ts +50 -0
- package/dist/charts/chart.ts +73 -0
- package/dist/charts/colorblind.ts +100 -0
- package/dist/charts/data.ts +72 -0
- package/dist/charts/geometry.ts +54 -0
- package/dist/charts/index.ts +61 -0
- package/dist/charts/scales.ts +151 -0
- package/dist/checkbox/checkbox.styles.ts +33 -0
- package/dist/checkbox/checkbox.ts +73 -0
- package/dist/checkbox/index.ts +10 -0
- package/dist/code-block/code-block.ts +1 -0
- package/dist/code-block/index.ts +1 -0
- package/dist/code-editor/code-editor.styles.ts +32 -0
- package/dist/code-editor/code-editor.ts +140 -0
- package/dist/code-editor/index.ts +9 -0
- package/dist/collapsible/collapsible.styles.ts +14 -0
- package/dist/collapsible/collapsible.ts +93 -0
- package/dist/collapsible/index.ts +7 -0
- package/dist/command/command.styles.ts +27 -0
- package/dist/command/command.ts +179 -0
- package/dist/command/index.ts +14 -0
- package/dist/command-input/command-input.ts +176 -0
- package/dist/command-input/index.ts +1 -0
- package/dist/content-protection/content-protection.styles.ts +9 -0
- package/dist/content-protection/content-protection.ts +68 -0
- package/dist/content-protection/index.ts +8 -0
- package/dist/data-table/data-table.styles.ts +55 -0
- package/dist/data-table/data-table.ts +183 -0
- package/dist/data-table/index.ts +15 -0
- package/dist/date-picker/date-picker.styles.ts +31 -0
- package/dist/date-picker/date-picker.ts +333 -0
- package/dist/date-picker/index.ts +18 -0
- package/dist/device-frame/device-frame.styles.ts +21 -0
- package/dist/device-frame/device-frame.ts +112 -0
- package/dist/device-frame/index.ts +10 -0
- package/dist/dialog/dialog.styles.ts +8 -0
- package/dist/dialog/dialog.ts +133 -0
- package/dist/dialog/index.ts +8 -0
- package/dist/diff-viewer/diff-viewer.styles.ts +124 -0
- package/dist/diff-viewer/diff-viewer.ts +255 -0
- package/dist/diff-viewer/index.ts +20 -0
- package/dist/dropdown-menu/dropdown-menu.styles.ts +9 -0
- package/dist/dropdown-menu/dropdown-menu.ts +139 -0
- package/dist/dropdown-menu/index.ts +9 -0
- package/dist/emoji-picker/emoji-data.ts +282 -0
- package/dist/emoji-picker/emoji-picker.styles.ts +32 -0
- package/dist/emoji-picker/emoji-picker.ts +165 -0
- package/dist/emoji-picker/index.ts +25 -0
- package/dist/feedback-dialog/feedback-dialog.styles.ts +15 -0
- package/dist/feedback-dialog/feedback-dialog.ts +147 -0
- package/dist/feedback-dialog/index.ts +11 -0
- package/dist/file-upload/file-upload.styles.ts +30 -0
- package/dist/file-upload/file-upload.ts +260 -0
- package/dist/file-upload/index.ts +19 -0
- package/dist/footer/footer.styles.ts +5 -0
- package/dist/footer/footer.ts +32 -0
- package/dist/footer/index.ts +9 -0
- package/dist/index.ts +77 -0
- package/dist/inline-editor/index.ts +13 -0
- package/dist/inline-editor/inline-editor.styles.ts +42 -0
- package/dist/inline-editor/inline-editor.ts +96 -0
- package/dist/input/index.ts +9 -0
- package/dist/input/input.styles.ts +15 -0
- package/dist/input/input.ts +84 -0
- package/dist/input-group/index.ts +13 -0
- package/dist/input-group/input-group.styles.ts +50 -0
- package/dist/input-group/input-group.ts +44 -0
- package/dist/install-prompt/index.ts +9 -0
- package/dist/install-prompt/install-prompt.styles.ts +5 -0
- package/dist/install-prompt/install-prompt.ts +68 -0
- package/dist/keyboard-shortcut/index.ts +12 -0
- package/dist/keyboard-shortcut/keyboard-shortcut.styles.ts +8 -0
- package/dist/keyboard-shortcut/keyboard-shortcut.ts +153 -0
- package/dist/language-selector/index.ts +8 -0
- package/dist/language-selector/language-selector.styles.ts +28 -0
- package/dist/language-selector/language-selector.ts +149 -0
- package/dist/link-card/index.ts +1 -0
- package/dist/link-card/link-card.ts +9 -0
- package/dist/markdown-renderer/index.ts +8 -0
- package/dist/markdown-renderer/markdown-renderer.styles.ts +31 -0
- package/dist/markdown-renderer/markdown-renderer.ts +251 -0
- package/dist/mobile-nav/index.ts +14 -0
- package/dist/mobile-nav/mobile-nav.styles.ts +39 -0
- package/dist/mobile-nav/mobile-nav.ts +74 -0
- package/dist/navbar/index.ts +9 -0
- package/dist/navbar/navbar.styles.ts +29 -0
- package/dist/navbar/navbar.ts +39 -0
- package/dist/otp-input/index.ts +13 -0
- package/dist/otp-input/otp-input.styles.ts +51 -0
- package/dist/otp-input/otp-input.ts +198 -0
- package/dist/pagination/index.ts +1 -0
- package/dist/payment/index.ts +1 -0
- package/dist/payment/payment.ts +16 -0
- package/dist/popover/index.ts +7 -0
- package/dist/popover/popover.styles.ts +16 -0
- package/dist/popover/popover.ts +89 -0
- package/dist/presence-indicator/index.ts +14 -0
- package/dist/presence-indicator/presence-indicator.styles.ts +29 -0
- package/dist/presence-indicator/presence-indicator.ts +63 -0
- package/dist/progress-display/index.ts +15 -0
- package/dist/progress-display/progress-display.styles.ts +72 -0
- package/dist/progress-display/progress-display.ts +60 -0
- package/dist/radio/index.ts +8 -0
- package/dist/radio/radio.styles.ts +34 -0
- package/dist/radio/radio.ts +70 -0
- package/dist/reaction-bar/index.ts +14 -0
- package/dist/reaction-bar/reaction-bar.styles.ts +23 -0
- package/dist/reaction-bar/reaction-bar.ts +87 -0
- package/dist/resizable-layout/index.ts +12 -0
- package/dist/resizable-layout/resizable-layout.styles.ts +50 -0
- package/dist/resizable-layout/resizable-layout.ts +139 -0
- package/dist/rich-editor/editor.ts +342 -0
- package/dist/rich-editor/emoji.ts +175 -0
- package/dist/rich-editor/history.ts +79 -0
- package/dist/rich-editor/index.ts +106 -0
- package/dist/rich-editor/markdown-shortcuts.ts +248 -0
- package/dist/rich-editor/mentions.ts +162 -0
- package/dist/rich-editor/model.ts +206 -0
- package/dist/rich-editor/operations.ts +772 -0
- package/dist/rich-editor/selection.ts +157 -0
- package/dist/rich-editor/serialization.ts +711 -0
- package/dist/rich-editor/slash-commands.ts +212 -0
- package/dist/search-bar/index.ts +7 -0
- package/dist/search-bar/search-bar.styles.ts +29 -0
- package/dist/search-bar/search-bar.ts +130 -0
- package/dist/select/index.ts +13 -0
- package/dist/select/select.styles.ts +52 -0
- package/dist/select/select.ts +152 -0
- package/dist/shared/a11y.ts +33 -0
- package/dist/shared/aria.ts +30 -0
- package/dist/shared/cn.ts +35 -0
- package/dist/shared/cva.ts +79 -0
- package/dist/shared/engine-adapter.ts +10 -0
- package/dist/shared/focus-trap.ts +123 -0
- package/dist/shared/index.ts +60 -0
- package/dist/shared/keyboard.ts +36 -0
- package/dist/shared/live-region.ts +90 -0
- package/dist/shared/motion.ts +15 -0
- package/dist/shared/skip-link.ts +35 -0
- package/dist/shared/state-machine.ts +57 -0
- package/dist/shared/tokens.ts +16 -0
- package/dist/shared/types.ts +45 -0
- package/dist/shared/variants.ts +17 -0
- package/dist/sidebar/index.ts +9 -0
- package/dist/sidebar/sidebar.styles.ts +27 -0
- package/dist/sidebar/sidebar.ts +59 -0
- package/dist/skeleton/index.ts +8 -0
- package/dist/skeleton/skeleton.styles.ts +16 -0
- package/dist/skeleton/skeleton.ts +39 -0
- package/dist/skip-to-content/index.ts +1 -0
- package/dist/skip-to-content/skip-to-content.ts +1 -0
- package/dist/slide-viewer/index.ts +16 -0
- package/dist/slide-viewer/slide-viewer.styles.ts +57 -0
- package/dist/slide-viewer/slide-viewer.ts +152 -0
- package/dist/slider/index.ts +1 -0
- package/dist/slider/slider.ts +2 -0
- package/dist/status-indicator/index.ts +15 -0
- package/dist/status-indicator/status-indicator.styles.ts +41 -0
- package/dist/status-indicator/status-indicator.ts +66 -0
- package/dist/steps/index.ts +1 -0
- package/dist/steps/steps.ts +1 -0
- package/dist/switch/index.ts +7 -0
- package/dist/switch/switch.styles.ts +55 -0
- package/dist/switch/switch.ts +63 -0
- package/dist/table-of-contents/index.ts +1 -0
- package/dist/table-of-contents/table-of-contents.ts +37 -0
- package/dist/tabs/index.ts +8 -0
- package/dist/tabs/tabs.styles.ts +9 -0
- package/dist/tabs/tabs.ts +133 -0
- package/dist/textarea/index.ts +7 -0
- package/dist/textarea/textarea.styles.ts +15 -0
- package/dist/textarea/textarea.ts +59 -0
- package/dist/theme/dom-adapters.ts +60 -0
- package/dist/theme/index.ts +18 -0
- package/dist/theme/theme-machine.ts +130 -0
- package/dist/theme/theme-script.ts +18 -0
- package/dist/thread-view/index.ts +26 -0
- package/dist/thread-view/thread-view.styles.ts +35 -0
- package/dist/thread-view/thread-view.ts +176 -0
- package/dist/toast/index.ts +13 -0
- package/dist/toast/toast.styles.ts +19 -0
- package/dist/toast/toast.ts +203 -0
- package/dist/tooltip/index.ts +7 -0
- package/dist/tooltip/tooltip.styles.ts +16 -0
- package/dist/tooltip/tooltip.ts +109 -0
- package/dist/version-selector/index.ts +12 -0
- package/dist/version-selector/version-selector.styles.ts +41 -0
- package/dist/version-selector/version-selector.ts +136 -0
- package/dist/video-player/index.ts +12 -0
- package/dist/video-player/video-player.styles.ts +42 -0
- package/dist/video-player/video-player.ts +100 -0
- package/package.json +20 -19
- package/src/index.ts +0 -94
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight class-variance-authority alternative — zero dependencies.
|
|
3
|
+
* Creates variant-driven class name functions for components.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
interface VariantConfig {
|
|
7
|
+
[variant: string]: Record<string, string>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface CVAConfig<V extends VariantConfig> {
|
|
11
|
+
base?: string
|
|
12
|
+
variants?: V
|
|
13
|
+
defaultVariants?: {
|
|
14
|
+
[K in keyof V]?: keyof V[K]
|
|
15
|
+
}
|
|
16
|
+
compoundVariants?: Array<
|
|
17
|
+
{
|
|
18
|
+
[K in keyof V]?: keyof V[K]
|
|
19
|
+
} & { class: string }
|
|
20
|
+
>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type VariantProps<V extends VariantConfig> = {
|
|
24
|
+
[K in keyof V]?: keyof V[K]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function cva<V extends VariantConfig>(config: CVAConfig<V>) {
|
|
28
|
+
return (props?: VariantProps<V> & { className?: string }): string => {
|
|
29
|
+
const classes: string[] = []
|
|
30
|
+
|
|
31
|
+
if (config.base) {
|
|
32
|
+
classes.push(config.base)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (config.variants) {
|
|
36
|
+
for (const [variantKey, variantOptions] of Object.entries(config.variants)) {
|
|
37
|
+
const selectedValue =
|
|
38
|
+
(props as Record<string, unknown> | undefined)?.[variantKey] ??
|
|
39
|
+
config.defaultVariants?.[variantKey]
|
|
40
|
+
|
|
41
|
+
if (selectedValue != null) {
|
|
42
|
+
const variantClass = (variantOptions as Record<string, string>)[
|
|
43
|
+
selectedValue as string
|
|
44
|
+
]
|
|
45
|
+
if (variantClass) {
|
|
46
|
+
classes.push(variantClass)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (config.compoundVariants) {
|
|
53
|
+
for (const compound of config.compoundVariants) {
|
|
54
|
+
const { class: compoundClass, ...conditions } = compound
|
|
55
|
+
let matches = true
|
|
56
|
+
|
|
57
|
+
for (const [key, value] of Object.entries(conditions)) {
|
|
58
|
+
const propValue =
|
|
59
|
+
(props as Record<string, unknown>)?.[key] ??
|
|
60
|
+
config.defaultVariants?.[key]
|
|
61
|
+
if (propValue !== value) {
|
|
62
|
+
matches = false
|
|
63
|
+
break
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (matches) {
|
|
68
|
+
classes.push(compoundClass as string)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (props?.className) {
|
|
74
|
+
classes.push(props.className)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return classes.filter(Boolean).join(' ')
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface EngineAdapter<
|
|
2
|
+
TState = Record<string, unknown>,
|
|
3
|
+
TMethods = Record<string, unknown>,
|
|
4
|
+
TReturnProps = Record<string, unknown>
|
|
5
|
+
> {
|
|
6
|
+
name: string;
|
|
7
|
+
state: TState;
|
|
8
|
+
methods: TMethods;
|
|
9
|
+
getProps: (elementName: string, props?: Record<string, unknown>) => TReturnProps;
|
|
10
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Focus trap utilities — keeps keyboard focus within a container.
|
|
3
|
+
* Used by Dialog, DropdownMenu, and other overlay components.
|
|
4
|
+
* Pure TypeScript, no DOM dependency (accepts element via parameter).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Selector for all natively focusable elements */
|
|
8
|
+
export const FOCUSABLE_SELECTOR =
|
|
9
|
+
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
10
|
+
|
|
11
|
+
/** Get all focusable elements within a container */
|
|
12
|
+
export function getFocusableElements(container: Element): Element[] {
|
|
13
|
+
return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Configuration for creating a focus trap */
|
|
17
|
+
export interface FocusTrapConfig {
|
|
18
|
+
/** The container element */
|
|
19
|
+
container: Element
|
|
20
|
+
/** Called to get the initial focus target */
|
|
21
|
+
initialFocus?: () => Element | null
|
|
22
|
+
/** Called when Escape is pressed */
|
|
23
|
+
onEscape?: () => void
|
|
24
|
+
/** Whether to return focus to trigger on deactivate */
|
|
25
|
+
returnFocusOnDeactivate?: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** A focus trap instance */
|
|
29
|
+
export interface FocusTrap {
|
|
30
|
+
activate(): void
|
|
31
|
+
deactivate(): void
|
|
32
|
+
isActive(): boolean
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Create a focus trap that keeps Tab/Shift+Tab within a container */
|
|
36
|
+
export function createFocusTrap(config: FocusTrapConfig): FocusTrap {
|
|
37
|
+
let active = false
|
|
38
|
+
let previouslyFocused: Element | null = null
|
|
39
|
+
|
|
40
|
+
function handleKeyDown(event: KeyboardEvent): void {
|
|
41
|
+
if (event.key === 'Escape' && config.onEscape) {
|
|
42
|
+
event.preventDefault()
|
|
43
|
+
config.onEscape()
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (event.key !== 'Tab') return
|
|
48
|
+
|
|
49
|
+
const focusable = getFocusableElements(config.container)
|
|
50
|
+
if (focusable.length === 0) return
|
|
51
|
+
|
|
52
|
+
const first = focusable[0] as HTMLElement
|
|
53
|
+
const last = focusable[focusable.length - 1] as HTMLElement
|
|
54
|
+
|
|
55
|
+
if (event.shiftKey) {
|
|
56
|
+
// Shift+Tab: if on first element, wrap to last
|
|
57
|
+
if (document.activeElement === first) {
|
|
58
|
+
event.preventDefault()
|
|
59
|
+
last.focus()
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
// Tab: if on last element, wrap to first
|
|
63
|
+
if (document.activeElement === last) {
|
|
64
|
+
event.preventDefault()
|
|
65
|
+
first.focus()
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
activate() {
|
|
72
|
+
if (active) return
|
|
73
|
+
active = true
|
|
74
|
+
|
|
75
|
+
// Remember the currently focused element so we can restore it later
|
|
76
|
+
if (typeof document !== 'undefined') {
|
|
77
|
+
previouslyFocused = document.activeElement
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Set initial focus
|
|
81
|
+
if (config.initialFocus) {
|
|
82
|
+
const target = config.initialFocus()
|
|
83
|
+
if (target && 'focus' in target) {
|
|
84
|
+
(target as HTMLElement).focus()
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
const focusable = getFocusableElements(config.container)
|
|
88
|
+
if (focusable.length > 0) {
|
|
89
|
+
(focusable[0] as HTMLElement).focus()
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Attach keydown listener to the container
|
|
94
|
+
config.container.addEventListener(
|
|
95
|
+
'keydown',
|
|
96
|
+
handleKeyDown as EventListener,
|
|
97
|
+
)
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
deactivate() {
|
|
101
|
+
if (!active) return
|
|
102
|
+
active = false
|
|
103
|
+
|
|
104
|
+
config.container.removeEventListener(
|
|
105
|
+
'keydown',
|
|
106
|
+
handleKeyDown as EventListener,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
// Restore focus to the previously focused element
|
|
110
|
+
if (
|
|
111
|
+
config.returnFocusOnDeactivate !== false &&
|
|
112
|
+
previouslyFocused &&
|
|
113
|
+
'focus' in previouslyFocused
|
|
114
|
+
) {
|
|
115
|
+
(previouslyFocused as HTMLElement).focus()
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
isActive() {
|
|
120
|
+
return active
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Types
|
|
2
|
+
export type {
|
|
3
|
+
BaseProps,
|
|
4
|
+
AccessibilityProps,
|
|
5
|
+
ThemeProps,
|
|
6
|
+
CompositionProps,
|
|
7
|
+
} from './types.js'
|
|
8
|
+
|
|
9
|
+
export type {
|
|
10
|
+
Size,
|
|
11
|
+
Variant,
|
|
12
|
+
Orientation,
|
|
13
|
+
Side,
|
|
14
|
+
Align,
|
|
15
|
+
DataState,
|
|
16
|
+
} from './variants.js'
|
|
17
|
+
|
|
18
|
+
export type {
|
|
19
|
+
TokenContract,
|
|
20
|
+
TokenDefinition,
|
|
21
|
+
} from './tokens.js'
|
|
22
|
+
|
|
23
|
+
export type {
|
|
24
|
+
KeyboardKey,
|
|
25
|
+
KeyboardHandlerMap,
|
|
26
|
+
} from './keyboard.js'
|
|
27
|
+
|
|
28
|
+
export type {
|
|
29
|
+
MachineConfig,
|
|
30
|
+
Machine,
|
|
31
|
+
} from './state-machine.js'
|
|
32
|
+
|
|
33
|
+
export type {
|
|
34
|
+
FocusTrapConfig,
|
|
35
|
+
FocusTrap,
|
|
36
|
+
} from './focus-trap.js'
|
|
37
|
+
|
|
38
|
+
export type {
|
|
39
|
+
LiveRegionConfig,
|
|
40
|
+
LiveRegion,
|
|
41
|
+
} from './live-region.js'
|
|
42
|
+
|
|
43
|
+
export type {
|
|
44
|
+
EngineAdapter,
|
|
45
|
+
} from './engine-adapter.js'
|
|
46
|
+
|
|
47
|
+
export type {
|
|
48
|
+
SkipLinkProps,
|
|
49
|
+
} from './skip-link.js'
|
|
50
|
+
|
|
51
|
+
// Functions
|
|
52
|
+
export { mergeAriaProps, generateId, resetIdCounter } from './aria.js'
|
|
53
|
+
export { Keys, createKeyboardHandler } from './keyboard.js'
|
|
54
|
+
export { createMachine } from './state-machine.js'
|
|
55
|
+
export { cn } from './cn.js'
|
|
56
|
+
export { cva } from './cva.js'
|
|
57
|
+
export { FOCUSABLE_SELECTOR, getFocusableElements, createFocusTrap } from './focus-trap.js'
|
|
58
|
+
export { createLiveRegion } from './live-region.js'
|
|
59
|
+
export { prefersReducedMotion, getAnimationDuration } from './motion.js'
|
|
60
|
+
export { createSkipLink } from './skip-link.js'
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Standard keyboard key constants */
|
|
2
|
+
export const Keys = {
|
|
3
|
+
Enter: 'Enter',
|
|
4
|
+
Space: ' ',
|
|
5
|
+
Escape: 'Escape',
|
|
6
|
+
Tab: 'Tab',
|
|
7
|
+
ArrowUp: 'ArrowUp',
|
|
8
|
+
ArrowDown: 'ArrowDown',
|
|
9
|
+
ArrowLeft: 'ArrowLeft',
|
|
10
|
+
ArrowRight: 'ArrowRight',
|
|
11
|
+
Home: 'Home',
|
|
12
|
+
End: 'End',
|
|
13
|
+
PageUp: 'PageUp',
|
|
14
|
+
PageDown: 'PageDown',
|
|
15
|
+
Backspace: 'Backspace',
|
|
16
|
+
Delete: 'Delete',
|
|
17
|
+
} as const
|
|
18
|
+
|
|
19
|
+
export type KeyboardKey = (typeof Keys)[keyof typeof Keys]
|
|
20
|
+
|
|
21
|
+
/** Map of key → handler function */
|
|
22
|
+
export type KeyboardHandlerMap = Partial<
|
|
23
|
+
Record<string, (event: KeyboardEvent) => void>
|
|
24
|
+
>
|
|
25
|
+
|
|
26
|
+
/** Create a keyboard event handler from a handler map */
|
|
27
|
+
export function createKeyboardHandler(
|
|
28
|
+
handlers: KeyboardHandlerMap,
|
|
29
|
+
): (event: KeyboardEvent) => void {
|
|
30
|
+
return (event: KeyboardEvent) => {
|
|
31
|
+
const handler = handlers[event.key]
|
|
32
|
+
if (handler) {
|
|
33
|
+
handler(event)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screen reader announcement utility.
|
|
3
|
+
* Creates and manages an aria-live region for dynamic content updates.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface LiveRegionConfig {
|
|
7
|
+
/** 'polite' (default) or 'assertive' */
|
|
8
|
+
politeness?: 'polite' | 'assertive'
|
|
9
|
+
/** Clear the announcement after this many ms. Default: 5000 */
|
|
10
|
+
clearAfterMs?: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface LiveRegion {
|
|
14
|
+
announce(message: string): void
|
|
15
|
+
clear(): void
|
|
16
|
+
destroy(): void
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Create a live region that announces messages to screen readers */
|
|
20
|
+
export function createLiveRegion(config: LiveRegionConfig = {}): LiveRegion {
|
|
21
|
+
const { politeness = 'polite', clearAfterMs = 5000 } = config
|
|
22
|
+
let element: HTMLElement | null = null
|
|
23
|
+
let clearTimeout: ReturnType<typeof setTimeout> | null = null
|
|
24
|
+
|
|
25
|
+
function getElement(): HTMLElement {
|
|
26
|
+
if (!element && typeof document !== 'undefined') {
|
|
27
|
+
element = document.createElement('div')
|
|
28
|
+
element.setAttribute('role', 'status')
|
|
29
|
+
element.setAttribute('aria-live', politeness)
|
|
30
|
+
element.setAttribute('aria-atomic', 'true')
|
|
31
|
+
// Visually hidden but accessible to screen readers
|
|
32
|
+
Object.assign(element.style, {
|
|
33
|
+
position: 'absolute',
|
|
34
|
+
width: '1px',
|
|
35
|
+
height: '1px',
|
|
36
|
+
padding: '0',
|
|
37
|
+
margin: '-1px',
|
|
38
|
+
overflow: 'hidden',
|
|
39
|
+
clip: 'rect(0, 0, 0, 0)',
|
|
40
|
+
whiteSpace: 'nowrap',
|
|
41
|
+
border: '0',
|
|
42
|
+
})
|
|
43
|
+
document.body.appendChild(element)
|
|
44
|
+
}
|
|
45
|
+
return element!
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
announce(message: string): void {
|
|
50
|
+
const el = getElement()
|
|
51
|
+
if (!el) return
|
|
52
|
+
|
|
53
|
+
// Clear any pending timeout
|
|
54
|
+
if (clearTimeout !== null) {
|
|
55
|
+
globalThis.clearTimeout(clearTimeout)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Set text content — screen readers will detect the change via aria-live
|
|
59
|
+
el.textContent = message
|
|
60
|
+
|
|
61
|
+
if (clearAfterMs > 0) {
|
|
62
|
+
clearTimeout = globalThis.setTimeout(() => {
|
|
63
|
+
el.textContent = ''
|
|
64
|
+
clearTimeout = null
|
|
65
|
+
}, clearAfterMs)
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
clear(): void {
|
|
70
|
+
if (clearTimeout !== null) {
|
|
71
|
+
globalThis.clearTimeout(clearTimeout)
|
|
72
|
+
clearTimeout = null
|
|
73
|
+
}
|
|
74
|
+
if (element) {
|
|
75
|
+
element.textContent = ''
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
destroy(): void {
|
|
80
|
+
if (clearTimeout !== null) {
|
|
81
|
+
globalThis.clearTimeout(clearTimeout)
|
|
82
|
+
clearTimeout = null
|
|
83
|
+
}
|
|
84
|
+
if (element && element.parentNode) {
|
|
85
|
+
element.parentNode.removeChild(element)
|
|
86
|
+
element = null
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reduced motion utilities.
|
|
3
|
+
* Respects user preferences for reduced motion.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** Check if user prefers reduced motion */
|
|
7
|
+
export function prefersReducedMotion(): boolean {
|
|
8
|
+
if (typeof window === 'undefined') return false
|
|
9
|
+
return window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Get animation duration — returns '0ms' if reduced motion preferred */
|
|
13
|
+
export function getAnimationDuration(normalDuration: string): string {
|
|
14
|
+
return prefersReducedMotion() ? '0ms' : normalDuration
|
|
15
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skip-to-content link utility.
|
|
3
|
+
* Provides a keyboard-accessible link that is visually hidden until focused.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** Props for a skip-to-content link */
|
|
7
|
+
export interface SkipLinkProps {
|
|
8
|
+
/** ID of the target element. Default: 'main-content' */
|
|
9
|
+
targetId?: string
|
|
10
|
+
/** Label text for the link. Default: 'Skip to main content' */
|
|
11
|
+
label?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Create props for a skip-to-content link */
|
|
15
|
+
export function createSkipLink(props: SkipLinkProps = {}): {
|
|
16
|
+
ariaProps: Record<string, string>
|
|
17
|
+
href: string
|
|
18
|
+
label: string
|
|
19
|
+
/** CSS classes — visually hidden until focused */
|
|
20
|
+
className: string
|
|
21
|
+
} {
|
|
22
|
+
const targetId = props.targetId ?? 'main-content'
|
|
23
|
+
const label = props.label ?? 'Skip to main content'
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
ariaProps: {
|
|
27
|
+
role: 'link',
|
|
28
|
+
'aria-label': label,
|
|
29
|
+
},
|
|
30
|
+
href: `#${targetId}`,
|
|
31
|
+
label,
|
|
32
|
+
className:
|
|
33
|
+
'sr-only focus:not-sr-only focus:absolute focus:z-50 focus:p-4 focus:bg-white focus:text-black focus:underline',
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal state machine — zero dependencies, < 1KB.
|
|
3
|
+
* Inspired by XState concepts but dramatically simpler.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface MachineConfig<TState extends string, TEvent extends string> {
|
|
7
|
+
initial: TState
|
|
8
|
+
states: Record<TState, {
|
|
9
|
+
on?: Partial<Record<TEvent, TState>>
|
|
10
|
+
}>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface Machine<TState extends string, TEvent extends string> {
|
|
14
|
+
/** Current state */
|
|
15
|
+
state: TState
|
|
16
|
+
/** Send an event to transition */
|
|
17
|
+
send(event: TEvent): void
|
|
18
|
+
/** Subscribe to state changes. Returns unsubscribe function. */
|
|
19
|
+
subscribe(fn: (state: TState) => void): () => void
|
|
20
|
+
/** Check if machine is in a given state */
|
|
21
|
+
matches(state: TState): boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function createMachine<TState extends string, TEvent extends string>(
|
|
25
|
+
config: MachineConfig<TState, TEvent>,
|
|
26
|
+
): Machine<TState, TEvent> {
|
|
27
|
+
let current = config.initial
|
|
28
|
+
const listeners = new Set<(state: TState) => void>()
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
get state() {
|
|
32
|
+
return current
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
send(event: TEvent) {
|
|
36
|
+
const stateConfig = config.states[current]
|
|
37
|
+
const next = stateConfig?.on?.[event]
|
|
38
|
+
if (next && next !== current) {
|
|
39
|
+
current = next
|
|
40
|
+
for (const fn of listeners) {
|
|
41
|
+
fn(current)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
subscribe(fn: (state: TState) => void) {
|
|
47
|
+
listeners.add(fn)
|
|
48
|
+
return () => {
|
|
49
|
+
listeners.delete(fn)
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
matches(state: TState) {
|
|
54
|
+
return current === state
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Defines the CSS custom properties a component reads */
|
|
2
|
+
export interface TokenContract {
|
|
3
|
+
/** Component name */
|
|
4
|
+
name: string
|
|
5
|
+
/** Map of token name → CSS custom property info */
|
|
6
|
+
tokens: Record<string, TokenDefinition>
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface TokenDefinition {
|
|
10
|
+
/** CSS custom property name (e.g., '--rfr-button-bg') */
|
|
11
|
+
variable: string
|
|
12
|
+
/** Fallback value when the variable is not set */
|
|
13
|
+
fallback: string
|
|
14
|
+
/** Description of what this token controls */
|
|
15
|
+
description?: string
|
|
16
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-agnostic base prop types for all refraction-ui components.
|
|
3
|
+
* These are headless core types — no React, Angular, or Astro imports.
|
|
4
|
+
* Framework wrappers extend these with framework-specific types.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Base props shared by all components */
|
|
8
|
+
export interface BaseProps {
|
|
9
|
+
id?: string
|
|
10
|
+
className?: string
|
|
11
|
+
style?: Record<string, string | number>
|
|
12
|
+
[dataAttr: `data-${string}`]: string | undefined
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Accessibility props */
|
|
16
|
+
export interface AccessibilityProps {
|
|
17
|
+
role?: string
|
|
18
|
+
tabIndex?: number
|
|
19
|
+
'aria-label'?: string
|
|
20
|
+
'aria-labelledby'?: string
|
|
21
|
+
'aria-describedby'?: string
|
|
22
|
+
'aria-controls'?: string
|
|
23
|
+
'aria-expanded'?: boolean
|
|
24
|
+
'aria-selected'?: boolean
|
|
25
|
+
'aria-hidden'?: boolean
|
|
26
|
+
'aria-disabled'?: boolean
|
|
27
|
+
'aria-pressed'?: boolean | 'mixed'
|
|
28
|
+
'aria-checked'?: boolean | 'mixed'
|
|
29
|
+
'aria-current'?: boolean | 'page' | 'step' | 'location' | 'date' | 'time'
|
|
30
|
+
'aria-live'?: 'off' | 'assertive' | 'polite'
|
|
31
|
+
'aria-atomic'?: boolean
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Theme customization props (framework-agnostic) */
|
|
35
|
+
export interface ThemeProps {
|
|
36
|
+
variant?: string
|
|
37
|
+
size?: string
|
|
38
|
+
colorScheme?: string
|
|
39
|
+
disabled?: boolean
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Composition props (framework-agnostic) */
|
|
43
|
+
export interface CompositionProps {
|
|
44
|
+
asChild?: boolean
|
|
45
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Standard size scale */
|
|
2
|
+
export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
|
3
|
+
|
|
4
|
+
/** Standard component variants */
|
|
5
|
+
export type Variant = 'default' | 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost' | 'link'
|
|
6
|
+
|
|
7
|
+
/** Layout orientation */
|
|
8
|
+
export type Orientation = 'horizontal' | 'vertical'
|
|
9
|
+
|
|
10
|
+
/** Positioning side */
|
|
11
|
+
export type Side = 'top' | 'right' | 'bottom' | 'left'
|
|
12
|
+
|
|
13
|
+
/** Alignment */
|
|
14
|
+
export type Align = 'start' | 'center' | 'end'
|
|
15
|
+
|
|
16
|
+
/** Data state attribute values */
|
|
17
|
+
export type DataState = 'open' | 'closed' | 'active' | 'inactive'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { cva } from '../shared/index.ts'
|
|
2
|
+
|
|
3
|
+
export const sidebarVariants = cva({
|
|
4
|
+
base: 'hidden md:flex flex-col border-r bg-background',
|
|
5
|
+
variants: {
|
|
6
|
+
collapsed: {
|
|
7
|
+
true: 'w-16',
|
|
8
|
+
false: 'w-64',
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
defaultVariants: {
|
|
12
|
+
collapsed: 'false',
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export const sidebarItemVariants = cva({
|
|
17
|
+
base: 'flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors',
|
|
18
|
+
variants: {
|
|
19
|
+
active: {
|
|
20
|
+
true: 'bg-accent text-accent-foreground',
|
|
21
|
+
false: 'text-muted-foreground hover:bg-muted hover:text-foreground',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: {
|
|
25
|
+
active: 'false',
|
|
26
|
+
},
|
|
27
|
+
})
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export interface SidebarItem {
|
|
2
|
+
label: string
|
|
3
|
+
href: string
|
|
4
|
+
icon?: string
|
|
5
|
+
/** Roles required to see this item */
|
|
6
|
+
roles?: string[]
|
|
7
|
+
/** Nested items */
|
|
8
|
+
children?: SidebarItem[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface SidebarSection {
|
|
12
|
+
title?: string
|
|
13
|
+
items: SidebarItem[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface SidebarProps {
|
|
17
|
+
sections?: SidebarSection[]
|
|
18
|
+
currentPath?: string
|
|
19
|
+
collapsed?: boolean
|
|
20
|
+
userRoles?: string[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface SidebarAPI {
|
|
24
|
+
ariaProps: Record<string, string>
|
|
25
|
+
isActive: (href: string) => boolean
|
|
26
|
+
isVisible: (item: SidebarItem) => boolean
|
|
27
|
+
itemAriaProps: (href: string) => Record<string, string>
|
|
28
|
+
visibleSections: SidebarSection[]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createSidebar(props: SidebarProps = {}): SidebarAPI {
|
|
32
|
+
const { sections = [], currentPath = '/', userRoles = [] } = props
|
|
33
|
+
|
|
34
|
+
function isActive(href: string): boolean {
|
|
35
|
+
if (href === '/') return currentPath === '/'
|
|
36
|
+
return currentPath.startsWith(href)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function isVisible(item: SidebarItem): boolean {
|
|
40
|
+
if (!item.roles || item.roles.length === 0) return true
|
|
41
|
+
return item.roles.some((role) => userRoles.includes(role))
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const visibleSections = sections
|
|
45
|
+
.map((section) => ({
|
|
46
|
+
...section,
|
|
47
|
+
items: section.items.filter(isVisible),
|
|
48
|
+
}))
|
|
49
|
+
.filter((section) => section.items.length > 0)
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
ariaProps: { role: 'navigation', 'aria-label': 'Sidebar' },
|
|
53
|
+
isActive,
|
|
54
|
+
isVisible,
|
|
55
|
+
itemAriaProps: (href: string): Record<string, string> =>
|
|
56
|
+
isActive(href) ? { 'aria-current': 'page' } : {},
|
|
57
|
+
visibleSections,
|
|
58
|
+
}
|
|
59
|
+
}
|