@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,48 @@
|
|
|
1
|
+
import type { AccessibilityProps } from '../shared/index.ts'
|
|
2
|
+
|
|
3
|
+
export type BadgeVariant = 'default' | 'primary' | 'secondary' | 'destructive' | 'outline' | 'success' | 'warning'
|
|
4
|
+
export type BadgeSize = 'sm' | 'md'
|
|
5
|
+
|
|
6
|
+
export interface BadgeProps {
|
|
7
|
+
variant?: BadgeVariant
|
|
8
|
+
size?: BadgeSize
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface BadgeAPI {
|
|
12
|
+
/** ARIA attributes to spread on the element */
|
|
13
|
+
ariaProps: Partial<AccessibilityProps>
|
|
14
|
+
/** Data attributes for CSS styling hooks */
|
|
15
|
+
dataAttributes: Record<string, string>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const statusVariants: BadgeVariant[] = ['success', 'warning', 'destructive']
|
|
19
|
+
|
|
20
|
+
/** Icon name for status badge variants — non-color indicator for colorblind safety */
|
|
21
|
+
const BADGE_ICONS: Partial<Record<BadgeVariant, string>> = {
|
|
22
|
+
success: 'check',
|
|
23
|
+
warning: 'alert',
|
|
24
|
+
destructive: 'x',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Get the icon name for a badge variant (undefined for non-status variants) */
|
|
28
|
+
export function getBadgeIcon(variant: BadgeVariant): string | undefined {
|
|
29
|
+
return BADGE_ICONS[variant]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function createBadge(props: BadgeProps = {}): BadgeAPI {
|
|
33
|
+
const { variant = 'default' } = props
|
|
34
|
+
|
|
35
|
+
const ariaProps: Partial<AccessibilityProps> = {}
|
|
36
|
+
|
|
37
|
+
if (statusVariants.includes(variant)) {
|
|
38
|
+
ariaProps.role = 'status'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const dataAttributes: Record<string, string> = {}
|
|
42
|
+
dataAttributes['data-variant'] = variant
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
ariaProps,
|
|
46
|
+
dataAttributes,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { cva } from '../shared/index.ts'
|
|
2
|
+
|
|
3
|
+
export const bottomNavVariants = cva({
|
|
4
|
+
base: 'fixed bottom-0 left-0 right-0 z-40 border-t bg-background md:hidden',
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
export const bottomNavTabVariants = cva({
|
|
8
|
+
base: 'flex flex-1 flex-col items-center justify-center gap-1 py-2 text-xs transition-colors',
|
|
9
|
+
variants: {
|
|
10
|
+
active: {
|
|
11
|
+
true: 'text-foreground',
|
|
12
|
+
false: 'text-muted-foreground',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
active: 'false',
|
|
17
|
+
},
|
|
18
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface NavTab {
|
|
2
|
+
label: string
|
|
3
|
+
href: string
|
|
4
|
+
icon?: string
|
|
5
|
+
activeIcon?: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface BottomNavProps {
|
|
9
|
+
tabs?: NavTab[]
|
|
10
|
+
currentPath?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface BottomNavAPI {
|
|
14
|
+
ariaProps: Record<string, string>
|
|
15
|
+
isActive: (href: string) => boolean
|
|
16
|
+
tabAriaProps: (href: string) => Record<string, string>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function createBottomNav(props: BottomNavProps = {}): BottomNavAPI {
|
|
20
|
+
const { currentPath = '/' } = props
|
|
21
|
+
|
|
22
|
+
function isActive(href: string): boolean {
|
|
23
|
+
if (href === '/') return currentPath === '/'
|
|
24
|
+
return currentPath.startsWith(href)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
ariaProps: { role: 'navigation', 'aria-label': 'Main navigation' },
|
|
29
|
+
isActive,
|
|
30
|
+
tabAriaProps: (href: string): Record<string, string> =>
|
|
31
|
+
isActive(href) ? { 'aria-current': 'page' } : {},
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { cva } from '../shared/index.ts'
|
|
2
|
+
|
|
3
|
+
export const breadcrumbsVariants = cva({
|
|
4
|
+
base: 'flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground',
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
export const breadcrumbItemVariants = cva({
|
|
8
|
+
base: 'transition-colors',
|
|
9
|
+
variants: {
|
|
10
|
+
active: {
|
|
11
|
+
true: 'font-medium text-foreground',
|
|
12
|
+
false: 'hover:text-foreground',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
active: 'false',
|
|
17
|
+
},
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
export const breadcrumbSeparatorStyles = 'text-muted-foreground/50 select-none'
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export interface BreadcrumbItem {
|
|
2
|
+
label: string
|
|
3
|
+
href?: string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface BreadcrumbsProps {
|
|
7
|
+
/** Current pathname to auto-generate from */
|
|
8
|
+
pathname?: string
|
|
9
|
+
/** Manual items (overrides pathname) */
|
|
10
|
+
items?: BreadcrumbItem[]
|
|
11
|
+
/** Custom label map for pathname segments */
|
|
12
|
+
labels?: Record<string, string>
|
|
13
|
+
/** Separator character */
|
|
14
|
+
separator?: string
|
|
15
|
+
/** Max items to show before truncating */
|
|
16
|
+
maxItems?: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface BreadcrumbsAPI {
|
|
20
|
+
items: BreadcrumbItem[]
|
|
21
|
+
ariaProps: Record<string, string>
|
|
22
|
+
separator: string
|
|
23
|
+
isLast: (index: number) => boolean
|
|
24
|
+
itemAriaProps: (index: number) => Record<string, string>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function kebabToTitle(segment: string): string {
|
|
28
|
+
return segment
|
|
29
|
+
.split('-')
|
|
30
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
31
|
+
.join(' ')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function pathToItems(
|
|
35
|
+
pathname: string,
|
|
36
|
+
labels: Record<string, string> = {},
|
|
37
|
+
): BreadcrumbItem[] {
|
|
38
|
+
const segments = pathname.split('/').filter(Boolean)
|
|
39
|
+
const items: BreadcrumbItem[] = [{ label: 'Home', href: '/' }]
|
|
40
|
+
|
|
41
|
+
let currentPath = ''
|
|
42
|
+
for (const segment of segments) {
|
|
43
|
+
currentPath += `/${segment}`
|
|
44
|
+
items.push({
|
|
45
|
+
label: labels[segment] ?? labels[currentPath] ?? kebabToTitle(segment),
|
|
46
|
+
href: currentPath,
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return items
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function createBreadcrumbs(props: BreadcrumbsProps = {}): BreadcrumbsAPI {
|
|
54
|
+
const { pathname, items: manualItems, labels = {}, separator = '/', maxItems } = props
|
|
55
|
+
|
|
56
|
+
let items = manualItems ?? (pathname ? pathToItems(pathname, labels) : [])
|
|
57
|
+
|
|
58
|
+
if (maxItems && items.length > maxItems) {
|
|
59
|
+
const first = items[0]
|
|
60
|
+
const last = items.slice(-(maxItems - 1))
|
|
61
|
+
items = [first, { label: '...' }, ...last]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
items,
|
|
66
|
+
ariaProps: { 'aria-label': 'Breadcrumb' },
|
|
67
|
+
separator,
|
|
68
|
+
isLast: (index: number) => index === items.length - 1,
|
|
69
|
+
itemAriaProps: (index: number): Record<string, string> =>
|
|
70
|
+
index === items.length - 1 ? { 'aria-current': 'page' } : {},
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { cva } from '../shared/index.ts'
|
|
2
|
+
import type { TokenContract } from '../shared/index.ts'
|
|
3
|
+
|
|
4
|
+
export const buttonTokens: TokenContract = {
|
|
5
|
+
name: 'button',
|
|
6
|
+
tokens: {
|
|
7
|
+
bg: { variable: '--rfr-button-bg', fallback: 'hsl(var(--primary))' },
|
|
8
|
+
fg: { variable: '--rfr-button-fg', fallback: 'hsl(var(--primary-foreground))' },
|
|
9
|
+
border: { variable: '--rfr-button-border', fallback: 'hsl(var(--border))' },
|
|
10
|
+
radius: { variable: '--rfr-button-radius', fallback: 'var(--radius)' },
|
|
11
|
+
ring: { variable: '--rfr-button-ring', fallback: 'hsl(var(--ring))' },
|
|
12
|
+
},
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const buttonVariants = cva({
|
|
16
|
+
base: 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md 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 [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
|
17
|
+
variants: {
|
|
18
|
+
variant: {
|
|
19
|
+
default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',
|
|
20
|
+
destructive: 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
|
|
21
|
+
outline: 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
|
|
22
|
+
secondary: 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
|
|
23
|
+
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
|
24
|
+
link: 'text-primary underline-offset-4 hover:underline',
|
|
25
|
+
},
|
|
26
|
+
size: {
|
|
27
|
+
xs: 'h-7 rounded px-2 text-xs',
|
|
28
|
+
sm: 'h-8 rounded-md px-3 text-xs',
|
|
29
|
+
default: 'h-9 px-4 py-2',
|
|
30
|
+
lg: 'h-10 rounded-md px-8',
|
|
31
|
+
icon: 'h-9 w-9',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
variant: 'default',
|
|
36
|
+
size: 'default',
|
|
37
|
+
},
|
|
38
|
+
})
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { AccessibilityProps, KeyboardHandlerMap } from '../shared/index.ts'
|
|
2
|
+
import { Keys } from '../shared/index.ts'
|
|
3
|
+
|
|
4
|
+
export type ButtonVariant = 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'
|
|
5
|
+
export type ButtonSize = 'xs' | 'sm' | 'default' | 'lg' | 'icon'
|
|
6
|
+
|
|
7
|
+
export interface ButtonProps {
|
|
8
|
+
variant?: ButtonVariant
|
|
9
|
+
size?: ButtonSize
|
|
10
|
+
disabled?: boolean
|
|
11
|
+
loading?: boolean
|
|
12
|
+
asChild?: boolean
|
|
13
|
+
type?: 'button' | 'submit' | 'reset'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ButtonAPI {
|
|
17
|
+
/** ARIA attributes to spread on the element */
|
|
18
|
+
ariaProps: Partial<AccessibilityProps>
|
|
19
|
+
/** Keyboard handlers to attach */
|
|
20
|
+
keyboardHandlers: KeyboardHandlerMap
|
|
21
|
+
/** Whether interaction should be blocked */
|
|
22
|
+
isInteractive: boolean
|
|
23
|
+
/** Data attributes for CSS styling hooks */
|
|
24
|
+
dataAttributes: Record<string, string>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function createButton(props: ButtonProps = {}): ButtonAPI {
|
|
28
|
+
const { disabled = false, loading = false } = props
|
|
29
|
+
const isInteractive = !disabled && !loading
|
|
30
|
+
|
|
31
|
+
const ariaProps: Partial<AccessibilityProps> = {}
|
|
32
|
+
if (disabled) {
|
|
33
|
+
ariaProps['aria-disabled'] = true
|
|
34
|
+
}
|
|
35
|
+
if (loading) {
|
|
36
|
+
ariaProps['aria-disabled'] = true
|
|
37
|
+
ariaProps['aria-label'] = ariaProps['aria-label'] ?? undefined
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const dataAttributes: Record<string, string> = {}
|
|
41
|
+
if (loading) {
|
|
42
|
+
dataAttributes['data-loading'] = ''
|
|
43
|
+
}
|
|
44
|
+
if (disabled) {
|
|
45
|
+
dataAttributes['data-disabled'] = ''
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const keyboardHandlers: KeyboardHandlerMap = {}
|
|
49
|
+
if (!isInteractive) {
|
|
50
|
+
keyboardHandlers[Keys.Enter] = (e) => e.preventDefault()
|
|
51
|
+
keyboardHandlers[Keys.Space] = (e) => e.preventDefault()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
ariaProps,
|
|
56
|
+
keyboardHandlers,
|
|
57
|
+
isInteractive,
|
|
58
|
+
dataAttributes,
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getButtonType(props: ButtonProps): string {
|
|
63
|
+
return props.type ?? 'button'
|
|
64
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { cva } from '../shared/index.ts'
|
|
2
|
+
|
|
3
|
+
export const calendarVariants = cva({
|
|
4
|
+
base: 'p-3 rounded-md border bg-background',
|
|
5
|
+
})
|
|
6
|
+
|
|
7
|
+
export const dayVariants = cva({
|
|
8
|
+
base: 'inline-flex items-center justify-center rounded-md text-sm h-9 w-9',
|
|
9
|
+
variants: {
|
|
10
|
+
state: {
|
|
11
|
+
default: 'hover:bg-accent hover:text-accent-foreground',
|
|
12
|
+
selected: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
13
|
+
today: 'bg-accent text-accent-foreground',
|
|
14
|
+
disabled: 'text-muted-foreground opacity-50 cursor-not-allowed',
|
|
15
|
+
outside: 'text-muted-foreground opacity-50',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
state: 'default',
|
|
20
|
+
},
|
|
21
|
+
})
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import type { AccessibilityProps } from '../shared/index.ts'
|
|
2
|
+
import { generateId } from '../shared/index.ts'
|
|
3
|
+
|
|
4
|
+
export interface CalendarProps {
|
|
5
|
+
/** Selected date (controlled) */
|
|
6
|
+
value?: Date
|
|
7
|
+
/** Default selected date (uncontrolled) */
|
|
8
|
+
defaultValue?: Date
|
|
9
|
+
/** Callback when a date is selected */
|
|
10
|
+
onSelect?: (date: Date) => void
|
|
11
|
+
/** Displayed month (controlled) */
|
|
12
|
+
month?: Date
|
|
13
|
+
/** Callback when the displayed month changes */
|
|
14
|
+
onMonthChange?: (month: Date) => void
|
|
15
|
+
/** Minimum selectable date */
|
|
16
|
+
minDate?: Date
|
|
17
|
+
/** Maximum selectable date */
|
|
18
|
+
maxDate?: Date
|
|
19
|
+
/** Specific dates to disable */
|
|
20
|
+
disabledDates?: Date[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface CalendarDay {
|
|
24
|
+
/** The date this cell represents */
|
|
25
|
+
date: Date
|
|
26
|
+
/** Whether the date is today */
|
|
27
|
+
isToday: boolean
|
|
28
|
+
/** Whether the date is currently selected */
|
|
29
|
+
isSelected: boolean
|
|
30
|
+
/** Whether the date belongs to the currently displayed month */
|
|
31
|
+
isCurrentMonth: boolean
|
|
32
|
+
/** Whether the date is disabled */
|
|
33
|
+
isDisabled: boolean
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface CalendarState {
|
|
37
|
+
/** The currently displayed month */
|
|
38
|
+
currentMonth: Date
|
|
39
|
+
/** The currently selected date, if any */
|
|
40
|
+
selectedDate: Date | undefined
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface CalendarAPI {
|
|
44
|
+
/** Current calendar state */
|
|
45
|
+
state: CalendarState
|
|
46
|
+
/** Array of day objects for the current month grid (always 42: 6 weeks x 7 days) */
|
|
47
|
+
days: CalendarDay[]
|
|
48
|
+
/** Navigate to the previous month */
|
|
49
|
+
prevMonth(): void
|
|
50
|
+
/** Navigate to the next month */
|
|
51
|
+
nextMonth(): void
|
|
52
|
+
/** Select a date */
|
|
53
|
+
select(date: Date): void
|
|
54
|
+
/** ARIA attributes for the calendar grid */
|
|
55
|
+
ariaProps: Partial<AccessibilityProps> & Record<string, unknown>
|
|
56
|
+
/** Get ARIA attributes for a specific day cell */
|
|
57
|
+
getDayAriaProps(day: CalendarDay): Partial<AccessibilityProps> & Record<string, unknown>
|
|
58
|
+
/** Generated IDs */
|
|
59
|
+
ids: {
|
|
60
|
+
grid: string
|
|
61
|
+
label: string
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Check if two dates represent the same calendar day */
|
|
66
|
+
function isSameDay(a: Date, b: Date): boolean {
|
|
67
|
+
return (
|
|
68
|
+
a.getFullYear() === b.getFullYear() &&
|
|
69
|
+
a.getMonth() === b.getMonth() &&
|
|
70
|
+
a.getDate() === b.getDate()
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Get the first day of a month */
|
|
75
|
+
function startOfMonth(date: Date): Date {
|
|
76
|
+
return new Date(date.getFullYear(), date.getMonth(), 1)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Get day names */
|
|
80
|
+
const DAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
|
|
81
|
+
|
|
82
|
+
export function createCalendar(props: CalendarProps = {}): CalendarAPI {
|
|
83
|
+
const {
|
|
84
|
+
value: controlledValue,
|
|
85
|
+
defaultValue,
|
|
86
|
+
onSelect,
|
|
87
|
+
month: controlledMonth,
|
|
88
|
+
onMonthChange,
|
|
89
|
+
minDate,
|
|
90
|
+
maxDate,
|
|
91
|
+
disabledDates = [],
|
|
92
|
+
} = props
|
|
93
|
+
|
|
94
|
+
const today = new Date()
|
|
95
|
+
|
|
96
|
+
// Determine selected date
|
|
97
|
+
const selectedDate = controlledValue ?? defaultValue
|
|
98
|
+
|
|
99
|
+
// Determine current displayed month
|
|
100
|
+
const currentMonth = controlledMonth
|
|
101
|
+
? startOfMonth(controlledMonth)
|
|
102
|
+
: selectedDate
|
|
103
|
+
? startOfMonth(selectedDate)
|
|
104
|
+
: startOfMonth(today)
|
|
105
|
+
|
|
106
|
+
const gridId = generateId('rfr-calendar')
|
|
107
|
+
const labelId = generateId('rfr-calendar-label')
|
|
108
|
+
|
|
109
|
+
function isDateDisabled(date: Date): boolean {
|
|
110
|
+
if (minDate && date < startOfDay(minDate)) return true
|
|
111
|
+
if (maxDate && date > endOfDay(maxDate)) return true
|
|
112
|
+
return disabledDates.some((d) => isSameDay(d, date))
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function startOfDay(date: Date): Date {
|
|
116
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate())
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function endOfDay(date: Date): Date {
|
|
120
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Build the 42-cell grid for the current month view */
|
|
124
|
+
function buildDays(): CalendarDay[] {
|
|
125
|
+
const year = currentMonth.getFullYear()
|
|
126
|
+
const month = currentMonth.getMonth()
|
|
127
|
+
|
|
128
|
+
// First day of the month
|
|
129
|
+
const first = new Date(year, month, 1)
|
|
130
|
+
// Day of week the month starts on (0 = Sunday)
|
|
131
|
+
const startDow = first.getDay()
|
|
132
|
+
|
|
133
|
+
// Start from the Sunday before (or on) the first
|
|
134
|
+
const gridStart = new Date(year, month, 1 - startDow)
|
|
135
|
+
|
|
136
|
+
const days: CalendarDay[] = []
|
|
137
|
+
for (let i = 0; i < 42; i++) {
|
|
138
|
+
const date = new Date(
|
|
139
|
+
gridStart.getFullYear(),
|
|
140
|
+
gridStart.getMonth(),
|
|
141
|
+
gridStart.getDate() + i,
|
|
142
|
+
)
|
|
143
|
+
days.push({
|
|
144
|
+
date,
|
|
145
|
+
isToday: isSameDay(date, today),
|
|
146
|
+
isSelected: selectedDate ? isSameDay(date, selectedDate) : false,
|
|
147
|
+
isCurrentMonth: date.getMonth() === month,
|
|
148
|
+
isDisabled: isDateDisabled(date),
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
return days
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function prevMonth(): void {
|
|
155
|
+
const prev = new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1)
|
|
156
|
+
onMonthChange?.(prev)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function nextMonth(): void {
|
|
160
|
+
const next = new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1)
|
|
161
|
+
onMonthChange?.(next)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function select(date: Date): void {
|
|
165
|
+
if (!isDateDisabled(date)) {
|
|
166
|
+
onSelect?.(date)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const ariaProps: Partial<AccessibilityProps> & Record<string, unknown> = {
|
|
171
|
+
role: 'grid',
|
|
172
|
+
'aria-labelledby': labelId,
|
|
173
|
+
id: gridId,
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function getDayAriaProps(day: CalendarDay): Partial<AccessibilityProps> & Record<string, unknown> {
|
|
177
|
+
return {
|
|
178
|
+
role: 'gridcell',
|
|
179
|
+
'aria-selected': day.isSelected,
|
|
180
|
+
'aria-disabled': day.isDisabled,
|
|
181
|
+
'aria-current': day.isToday ? ('date' as const) : undefined,
|
|
182
|
+
'aria-label': `${DAY_NAMES[day.date.getDay()]}, ${day.date.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })}`,
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
state: {
|
|
188
|
+
currentMonth,
|
|
189
|
+
selectedDate,
|
|
190
|
+
},
|
|
191
|
+
days: buildDays(),
|
|
192
|
+
prevMonth,
|
|
193
|
+
nextMonth,
|
|
194
|
+
select,
|
|
195
|
+
ariaProps,
|
|
196
|
+
getDayAriaProps,
|
|
197
|
+
ids: {
|
|
198
|
+
grid: gridId,
|
|
199
|
+
label: labelId,
|
|
200
|
+
},
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const callout = {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './callout';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { cva } from '../shared/index.ts'
|
|
2
|
+
import type { TokenContract } from '../shared/index.ts'
|
|
3
|
+
|
|
4
|
+
export const cardTokens: TokenContract = {
|
|
5
|
+
name: 'card',
|
|
6
|
+
tokens: {
|
|
7
|
+
bg: { variable: '--rfr-card-bg', fallback: 'hsl(var(--card))' },
|
|
8
|
+
fg: { variable: '--rfr-card-fg', fallback: 'hsl(var(--card-foreground))' },
|
|
9
|
+
border: { variable: '--rfr-card-border', fallback: 'hsl(var(--border))' },
|
|
10
|
+
},
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const cardVariants = cva({
|
|
14
|
+
base: 'rounded-lg border bg-card text-card-foreground shadow',
|
|
15
|
+
variants: {
|
|
16
|
+
padding: {
|
|
17
|
+
none: '',
|
|
18
|
+
default: 'p-6',
|
|
19
|
+
compact: 'p-4',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
padding: 'none',
|
|
24
|
+
},
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export const cardHeaderVariants = cva({
|
|
28
|
+
base: 'flex flex-col space-y-1.5 p-6',
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
export const cardTitleVariants = cva({
|
|
32
|
+
base: 'font-semibold leading-none tracking-tight',
|
|
33
|
+
variants: {
|
|
34
|
+
size: {
|
|
35
|
+
sm: 'text-lg',
|
|
36
|
+
default: 'text-2xl',
|
|
37
|
+
lg: 'text-3xl',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
defaultVariants: {
|
|
41
|
+
size: 'default',
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
export const cardDescriptionVariants = cva({
|
|
46
|
+
base: 'text-sm text-muted-foreground',
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
export const cardContentVariants = cva({
|
|
50
|
+
base: 'p-6 pt-0',
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
export const cardFooterVariants = cva({
|
|
54
|
+
base: 'flex items-center p-6 pt-0',
|
|
55
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { AccessibilityProps } from '../shared/index.ts'
|
|
2
|
+
|
|
3
|
+
export interface CardProps {
|
|
4
|
+
/** Optional accessible role override */
|
|
5
|
+
role?: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface CardAPI {
|
|
9
|
+
/** ARIA attributes to spread on the element */
|
|
10
|
+
ariaProps: Partial<AccessibilityProps>
|
|
11
|
+
/** Data attributes for CSS styling hooks */
|
|
12
|
+
dataAttributes: Record<string, string>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function createCard(props: CardProps = {}): CardAPI {
|
|
16
|
+
const ariaProps: Partial<AccessibilityProps> = {}
|
|
17
|
+
if (props.role) {
|
|
18
|
+
ariaProps.role = props.role
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
ariaProps,
|
|
23
|
+
dataAttributes: { 'data-slot': 'card' },
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function createCardHeader(): { dataAttributes: Record<string, string> } {
|
|
28
|
+
return { dataAttributes: { 'data-slot': 'card-header' } }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createCardTitle(): { dataAttributes: Record<string, string> } {
|
|
32
|
+
return { dataAttributes: { 'data-slot': 'card-title' } }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function createCardDescription(): { dataAttributes: Record<string, string> } {
|
|
36
|
+
return { dataAttributes: { 'data-slot': 'card-description' } }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function createCardContent(): { dataAttributes: Record<string, string> } {
|
|
40
|
+
return { dataAttributes: { 'data-slot': 'card-content' } }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function createCardFooter(): { dataAttributes: Record<string, string> } {
|
|
44
|
+
return { dataAttributes: { 'data-slot': 'card-footer' } }
|
|
45
|
+
}
|