@webjsdev/ui 0.3.16 → 0.4.0
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/README.md +71 -10
- package/THIRD_PARTY_NOTICES.md +349 -0
- package/package.json +4 -2
- package/packages/registry/blocks/_shared/placeholder.svg +1 -0
- package/packages/registry/blocks/charts/chart-area-axes.ts +72 -0
- package/packages/registry/blocks/charts/chart-area-default.ts +64 -0
- package/packages/registry/blocks/charts/chart-area-gradient.ts +82 -0
- package/packages/registry/blocks/charts/chart-area-icons.ts +77 -0
- package/packages/registry/blocks/charts/chart-area-interactive.ts +204 -0
- package/packages/registry/blocks/charts/chart-area-legend.ts +72 -0
- package/packages/registry/blocks/charts/chart-area-linear.ts +64 -0
- package/packages/registry/blocks/charts/chart-area-stacked-expand.ts +77 -0
- package/packages/registry/blocks/charts/chart-area-stacked.ts +71 -0
- package/packages/registry/blocks/charts/chart-area-step.ts +68 -0
- package/packages/registry/blocks/charts/chart-bar-active.ts +93 -0
- package/packages/registry/blocks/charts/chart-bar-default.ts +60 -0
- package/packages/registry/blocks/charts/chart-bar-horizontal.ts +62 -0
- package/packages/registry/blocks/charts/chart-bar-interactive.ts +185 -0
- package/packages/registry/blocks/charts/chart-bar-label-custom.ts +78 -0
- package/packages/registry/blocks/charts/chart-bar-label.ts +66 -0
- package/packages/registry/blocks/charts/chart-bar-mixed.ts +87 -0
- package/packages/registry/blocks/charts/chart-bar-multiple.ts +67 -0
- package/packages/registry/blocks/charts/chart-bar-negative.ts +61 -0
- package/packages/registry/blocks/charts/chart-bar-stacked.ts +68 -0
- package/packages/registry/blocks/charts/chart-line-default.ts +61 -0
- package/packages/registry/blocks/charts/chart-line-dots-colors.ts +86 -0
- package/packages/registry/blocks/charts/chart-line-dots-custom.ts +75 -0
- package/packages/registry/blocks/charts/chart-line-dots.ts +65 -0
- package/packages/registry/blocks/charts/chart-line-interactive.ts +185 -0
- package/packages/registry/blocks/charts/chart-line-label-custom.ts +94 -0
- package/packages/registry/blocks/charts/chart-line-label.ts +73 -0
- package/packages/registry/blocks/charts/chart-line-linear.ts +61 -0
- package/packages/registry/blocks/charts/chart-line-multiple.ts +71 -0
- package/packages/registry/blocks/charts/chart-line-step.ts +61 -0
- package/packages/registry/blocks/charts/chart-pie-donut-active.ts +86 -0
- package/packages/registry/blocks/charts/chart-pie-donut-text.ts +89 -0
- package/packages/registry/blocks/charts/chart-pie-donut.ts +77 -0
- package/packages/registry/blocks/charts/chart-pie-interactive.ts +120 -0
- package/packages/registry/blocks/charts/chart-pie-label-custom.ts +82 -0
- package/packages/registry/blocks/charts/chart-pie-label-list.ts +86 -0
- package/packages/registry/blocks/charts/chart-pie-label.ts +77 -0
- package/packages/registry/blocks/charts/chart-pie-legend.ts +79 -0
- package/packages/registry/blocks/charts/chart-pie-separator-none.ts +77 -0
- package/packages/registry/blocks/charts/chart-pie-simple.ts +77 -0
- package/packages/registry/blocks/charts/chart-pie-stacked.ts +99 -0
- package/packages/registry/blocks/charts/chart-radar-default.ts +61 -0
- package/packages/registry/blocks/charts/chart-radar-dots.ts +61 -0
- package/packages/registry/blocks/charts/chart-radar-grid-circle-fill.ts +61 -0
- package/packages/registry/blocks/charts/chart-radar-grid-circle-no-lines.ts +61 -0
- package/packages/registry/blocks/charts/chart-radar-grid-circle.ts +61 -0
- package/packages/registry/blocks/charts/chart-radar-grid-custom.ts +61 -0
- package/packages/registry/blocks/charts/chart-radar-grid-fill.ts +61 -0
- package/packages/registry/blocks/charts/chart-radar-grid-none.ts +60 -0
- package/packages/registry/blocks/charts/chart-radar-icons.ts +76 -0
- package/packages/registry/blocks/charts/chart-radar-label-custom.ts +77 -0
- package/packages/registry/blocks/charts/chart-radar-legend.ts +70 -0
- package/packages/registry/blocks/charts/chart-radar-lines-only.ts +68 -0
- package/packages/registry/blocks/charts/chart-radar-multiple.ts +68 -0
- package/packages/registry/blocks/charts/chart-radar-radius.ts +68 -0
- package/packages/registry/blocks/charts/chart-radial-grid.ts +80 -0
- package/packages/registry/blocks/charts/chart-radial-label.ts +85 -0
- package/packages/registry/blocks/charts/chart-radial-shape.ts +81 -0
- package/packages/registry/blocks/charts/chart-radial-simple.ts +79 -0
- package/packages/registry/blocks/charts/chart-radial-stacked.ts +69 -0
- package/packages/registry/blocks/charts/chart-radial-text.ts +82 -0
- package/packages/registry/blocks/charts/chart-tooltip-advanced.ts +84 -0
- package/packages/registry/blocks/charts/chart-tooltip-default.ts +62 -0
- package/packages/registry/blocks/charts/chart-tooltip-formatter.ts +75 -0
- package/packages/registry/blocks/charts/chart-tooltip-icons.ts +68 -0
- package/packages/registry/blocks/charts/chart-tooltip-indicator-line.ts +62 -0
- package/packages/registry/blocks/charts/chart-tooltip-indicator-none.ts +62 -0
- package/packages/registry/blocks/charts/chart-tooltip-label-custom.ts +65 -0
- package/packages/registry/blocks/charts/chart-tooltip-label-formatter.ts +66 -0
- package/packages/registry/blocks/charts/chart-tooltip-label-none.ts +62 -0
- package/packages/registry/blocks/dashboard-01/components/app-sidebar.ts +108 -0
- package/packages/registry/blocks/dashboard-01/components/chart-area-interactive.ts +276 -0
- package/packages/registry/blocks/dashboard-01/components/dashboard-data.ts +89 -0
- package/packages/registry/blocks/dashboard-01/components/data-table.ts +637 -0
- package/packages/registry/blocks/dashboard-01/components/nav-documents.ts +65 -0
- package/packages/registry/blocks/dashboard-01/components/nav-main.ts +61 -0
- package/packages/registry/blocks/dashboard-01/components/nav-secondary.ts +40 -0
- package/packages/registry/blocks/dashboard-01/components/nav-user.ts +66 -0
- package/packages/registry/blocks/dashboard-01/components/section-cards.ts +59 -0
- package/packages/registry/blocks/dashboard-01/components/site-header.ts +52 -0
- package/packages/registry/blocks/dashboard-01/page.ts +39 -0
- package/packages/registry/blocks/login-01/components/login-form.ts +70 -0
- package/packages/registry/blocks/login-01/page.ts +19 -0
- package/packages/registry/blocks/login-02/components/login-form.ts +68 -0
- package/packages/registry/blocks/login-02/page.ts +36 -0
- package/packages/registry/blocks/login-03/components/login-form.ts +89 -0
- package/packages/registry/blocks/login-03/page.ts +28 -0
- package/packages/registry/blocks/login-04/components/login-form.ts +91 -0
- package/packages/registry/blocks/login-04/page.ts +20 -0
- package/packages/registry/blocks/login-05/components/login-form.ts +75 -0
- package/packages/registry/blocks/login-05/page.ts +19 -0
- package/packages/registry/blocks/preview/cards/activate-agent-dialog.ts +77 -0
- package/packages/registry/blocks/preview/cards/analytics-card.ts +64 -0
- package/packages/registry/blocks/preview/cards/anomaly-alert.ts +35 -0
- package/packages/registry/blocks/preview/cards/bar-chart-card.ts +91 -0
- package/packages/registry/blocks/preview/cards/book-appointment.ts +51 -0
- package/packages/registry/blocks/preview/cards/codespaces-card.ts +172 -0
- package/packages/registry/blocks/preview/cards/contributions-activity.ts +63 -0
- package/packages/registry/blocks/preview/cards/contributors.ts +51 -0
- package/packages/registry/blocks/preview/cards/environment-variables.ts +47 -0
- package/packages/registry/blocks/preview/cards/feedback-form.ts +61 -0
- package/packages/registry/blocks/preview/cards/file-upload.ts +51 -0
- package/packages/registry/blocks/preview/cards/github-profile.ts +66 -0
- package/packages/registry/blocks/preview/cards/icon-preview-grid.ts +47 -0
- package/packages/registry/blocks/preview/cards/invite-team.ts +78 -0
- package/packages/registry/blocks/preview/cards/invoice.ts +91 -0
- package/packages/registry/blocks/preview/cards/live-waveform.ts +330 -0
- package/packages/registry/blocks/preview/cards/no-team-members.ts +61 -0
- package/packages/registry/blocks/preview/cards/not-found.ts +46 -0
- package/packages/registry/blocks/preview/cards/observability-card.ts +44 -0
- package/packages/registry/blocks/preview/cards/pie-chart-card.ts +84 -0
- package/packages/registry/blocks/preview/cards/report-bug.ts +71 -0
- package/packages/registry/blocks/preview/cards/shipping-address.ts +79 -0
- package/packages/registry/blocks/preview/cards/shortcuts.ts +57 -0
- package/packages/registry/blocks/preview/cards/skeleton-loading.ts +37 -0
- package/packages/registry/blocks/preview/cards/sleep-report.ts +85 -0
- package/packages/registry/blocks/preview/cards/style-overview.ts +64 -0
- package/packages/registry/blocks/preview/cards/typography-specimen.ts +107 -0
- package/packages/registry/blocks/preview/cards/ui-elements.ts +164 -0
- package/packages/registry/blocks/preview/cards/usage-card.ts +63 -0
- package/packages/registry/blocks/preview/cards/visitors.ts +71 -0
- package/packages/registry/blocks/preview/cards/weekly-fitness-summary.ts +54 -0
- package/packages/registry/blocks/preview/page.ts +103 -0
- package/packages/registry/blocks/preview-02/cards/account-access.ts +70 -0
- package/packages/registry/blocks/preview-02/cards/card-overview.ts +75 -0
- package/packages/registry/blocks/preview-02/cards/claimable-balance.ts +54 -0
- package/packages/registry/blocks/preview-02/cards/contribution-history.ts +80 -0
- package/packages/registry/blocks/preview-02/cards/cover-art.ts +41 -0
- package/packages/registry/blocks/preview-02/cards/dividend-income.ts +76 -0
- package/packages/registry/blocks/preview-02/cards/empty-connect-bank.ts +38 -0
- package/packages/registry/blocks/preview-02/cards/empty-distribute-track.ts +38 -0
- package/packages/registry/blocks/preview-02/cards/empty-explore-catalog.ts +39 -0
- package/packages/registry/blocks/preview-02/cards/faq.ts +79 -0
- package/packages/registry/blocks/preview-02/cards/front-door.ts +40 -0
- package/packages/registry/blocks/preview-02/cards/index-investing.ts +31 -0
- package/packages/registry/blocks/preview-02/cards/kitchen-island.ts +90 -0
- package/packages/registry/blocks/preview-02/cards/loading-card.ts +34 -0
- package/packages/registry/blocks/preview-02/cards/new-milestone.ts +53 -0
- package/packages/registry/blocks/preview-02/cards/notification-settings.ts +126 -0
- package/packages/registry/blocks/preview-02/cards/payments.ts +88 -0
- package/packages/registry/blocks/preview-02/cards/payout-threshold.ts +92 -0
- package/packages/registry/blocks/preview-02/cards/power-usage.ts +84 -0
- package/packages/registry/blocks/preview-02/cards/preferences.ts +89 -0
- package/packages/registry/blocks/preview-02/cards/qr-connect.ts +54 -0
- package/packages/registry/blocks/preview-02/cards/receiving-method.ts +89 -0
- package/packages/registry/blocks/preview-02/cards/recent-transactions.ts +101 -0
- package/packages/registry/blocks/preview-02/cards/release-catalog.ts +73 -0
- package/packages/registry/blocks/preview-02/cards/roller-shades.ts +110 -0
- package/packages/registry/blocks/preview-02/cards/savings-progress.ts +68 -0
- package/packages/registry/blocks/preview-02/cards/savings-targets.ts +132 -0
- package/packages/registry/blocks/preview-02/cards/sidebar-nav.ts +88 -0
- package/packages/registry/blocks/preview-02/cards/social-links.ts +57 -0
- package/packages/registry/blocks/preview-02/cards/stock-performance.ts +106 -0
- package/packages/registry/blocks/preview-02/cards/syncing-state.ts +37 -0
- package/packages/registry/blocks/preview-02/cards/transfer-funds.ts +111 -0
- package/packages/registry/blocks/preview-02/cards/upcoming-payments.ts +69 -0
- package/packages/registry/blocks/preview-02/page.ts +111 -0
- package/packages/registry/blocks/preview-03/cards/files-chat.ts +75 -0
- package/packages/registry/blocks/preview-03/cards/group-chat.ts +114 -0
- package/packages/registry/blocks/preview-03/cards/reasoning-chat.ts +88 -0
- package/packages/registry/blocks/preview-03/cards/simple-chat.ts +53 -0
- package/packages/registry/blocks/preview-03/components/chat-card.ts +126 -0
- package/packages/registry/blocks/preview-03/components/chat-player.ts +174 -0
- package/packages/registry/blocks/preview-03/components/part-file.ts +77 -0
- package/packages/registry/blocks/preview-03/components/part-reasoning.ts +25 -0
- package/packages/registry/blocks/preview-03/components/part-source.ts +48 -0
- package/packages/registry/blocks/preview-03/components/part-text.ts +69 -0
- package/packages/registry/blocks/preview-03/components/part-tool.ts +71 -0
- package/packages/registry/blocks/preview-03/components/prompt-input.ts +86 -0
- package/packages/registry/blocks/preview-03/page.ts +39 -0
- package/packages/registry/blocks/sidebar-01/components/app-sidebar.ts +113 -0
- package/packages/registry/blocks/sidebar-01/components/search-form.ts +33 -0
- package/packages/registry/blocks/sidebar-01/components/version-switcher.ts +50 -0
- package/packages/registry/blocks/sidebar-01/page.ts +58 -0
- package/packages/registry/blocks/sidebar-02/components/app-sidebar.ts +131 -0
- package/packages/registry/blocks/sidebar-02/components/search-form.ts +33 -0
- package/packages/registry/blocks/sidebar-02/components/version-switcher.ts +50 -0
- package/packages/registry/blocks/sidebar-02/page.ts +53 -0
- package/packages/registry/blocks/sidebar-03/components/app-sidebar.ts +134 -0
- package/packages/registry/blocks/sidebar-03/page.ts +60 -0
- package/packages/registry/blocks/sidebar-04/components/app-sidebar.ts +136 -0
- package/packages/registry/blocks/sidebar-04/page.ts +58 -0
- package/packages/registry/blocks/sidebar-05/components/app-sidebar.ts +147 -0
- package/packages/registry/blocks/sidebar-05/components/search-form.ts +33 -0
- package/packages/registry/blocks/sidebar-05/page.ts +58 -0
- package/packages/registry/blocks/sidebar-06/components/app-sidebar.ts +105 -0
- package/packages/registry/blocks/sidebar-06/components/nav-main.ts +56 -0
- package/packages/registry/blocks/sidebar-06/components/sidebar-opt-in-form.ts +44 -0
- package/packages/registry/blocks/sidebar-06/page.ts +57 -0
- package/packages/registry/blocks/sidebar-07/components/app-sidebar.ts +108 -0
- package/packages/registry/blocks/sidebar-07/components/nav-main.ts +61 -0
- package/packages/registry/blocks/sidebar-07/components/nav-projects.ts +65 -0
- package/packages/registry/blocks/sidebar-07/components/nav-user.ts +70 -0
- package/packages/registry/blocks/sidebar-07/components/team-switcher.ts +66 -0
- package/packages/registry/blocks/sidebar-07/page.ts +59 -0
- package/packages/registry/blocks/sidebar-08/components/app-sidebar.ts +122 -0
- package/packages/registry/blocks/sidebar-08/components/nav-main.ts +68 -0
- package/packages/registry/blocks/sidebar-08/components/nav-projects.ts +65 -0
- package/packages/registry/blocks/sidebar-08/components/nav-secondary.ts +40 -0
- package/packages/registry/blocks/sidebar-08/components/nav-user.ts +70 -0
- package/packages/registry/blocks/sidebar-08/page.ts +59 -0
- package/packages/registry/blocks/sidebar-09/components/app-sidebar.ts +213 -0
- package/packages/registry/blocks/sidebar-09/components/nav-user.ts +70 -0
- package/packages/registry/blocks/sidebar-09/page.ts +52 -0
- package/packages/registry/blocks/sidebar-10/components/app-sidebar.ts +125 -0
- package/packages/registry/blocks/sidebar-10/components/nav-actions.ts +84 -0
- package/packages/registry/blocks/sidebar-10/components/nav-favorites.ts +66 -0
- package/packages/registry/blocks/sidebar-10/components/nav-main.ts +37 -0
- package/packages/registry/blocks/sidebar-10/components/nav-secondary.ts +43 -0
- package/packages/registry/blocks/sidebar-10/components/nav-workspaces.ts +78 -0
- package/packages/registry/blocks/sidebar-10/components/team-switcher.ts +63 -0
- package/packages/registry/blocks/sidebar-10/page.ts +46 -0
- package/packages/registry/blocks/sidebar-11/components/app-sidebar.ts +114 -0
- package/packages/registry/blocks/sidebar-11/page.ts +63 -0
- package/packages/registry/blocks/sidebar-12/components/app-sidebar.ts +63 -0
- package/packages/registry/blocks/sidebar-12/components/calendars.ts +53 -0
- package/packages/registry/blocks/sidebar-12/components/date-picker.ts +26 -0
- package/packages/registry/blocks/sidebar-12/components/nav-user.ts +70 -0
- package/packages/registry/blocks/sidebar-12/page.ts +43 -0
- package/packages/registry/blocks/sidebar-13/components/settings-dialog.ts +114 -0
- package/packages/registry/blocks/sidebar-13/page.ts +21 -0
- package/packages/registry/blocks/sidebar-14/components/app-sidebar.ts +120 -0
- package/packages/registry/blocks/sidebar-14/page.ts +55 -0
- package/packages/registry/blocks/sidebar-15/components/calendars.ts +53 -0
- package/packages/registry/blocks/sidebar-15/components/date-picker.ts +26 -0
- package/packages/registry/blocks/sidebar-15/components/nav-favorites.ts +66 -0
- package/packages/registry/blocks/sidebar-15/components/nav-main.ts +35 -0
- package/packages/registry/blocks/sidebar-15/components/nav-secondary.ts +43 -0
- package/packages/registry/blocks/sidebar-15/components/nav-user.ts +70 -0
- package/packages/registry/blocks/sidebar-15/components/nav-workspaces.ts +75 -0
- package/packages/registry/blocks/sidebar-15/components/sidebar-left.ts +126 -0
- package/packages/registry/blocks/sidebar-15/components/sidebar-right.ts +62 -0
- package/packages/registry/blocks/sidebar-15/components/team-switcher.ts +63 -0
- package/packages/registry/blocks/sidebar-15/page.ts +47 -0
- package/packages/registry/blocks/sidebar-16/components/app-sidebar.ts +124 -0
- package/packages/registry/blocks/sidebar-16/components/nav-main.ts +67 -0
- package/packages/registry/blocks/sidebar-16/components/nav-projects.ts +65 -0
- package/packages/registry/blocks/sidebar-16/components/nav-secondary.ts +40 -0
- package/packages/registry/blocks/sidebar-16/components/nav-user.ts +70 -0
- package/packages/registry/blocks/sidebar-16/components/search-form.ts +27 -0
- package/packages/registry/blocks/sidebar-16/components/site-header.ts +42 -0
- package/packages/registry/blocks/sidebar-16/page.ts +38 -0
- package/packages/registry/blocks/signup-01/components/signup-form.ts +78 -0
- package/packages/registry/blocks/signup-01/page.ts +19 -0
- package/packages/registry/blocks/signup-02/components/signup-form.ts +78 -0
- package/packages/registry/blocks/signup-02/page.ts +36 -0
- package/packages/registry/blocks/signup-03/components/signup-form.ts +79 -0
- package/packages/registry/blocks/signup-03/page.ts +28 -0
- package/packages/registry/blocks/signup-04/components/signup-form.ts +100 -0
- package/packages/registry/blocks/signup-04/page.ts +20 -0
- package/packages/registry/blocks/signup-05/components/signup-form.ts +75 -0
- package/packages/registry/blocks/signup-05/page.ts +20 -0
- package/packages/registry/components/accordion.ts +20 -7
- package/packages/registry/components/alert-dialog.ts +58 -13
- package/packages/registry/components/alert.ts +11 -6
- package/packages/registry/components/attachment.ts +119 -0
- package/packages/registry/components/avatar.ts +17 -8
- package/packages/registry/components/badge.ts +16 -9
- package/packages/registry/components/breadcrumb.ts +6 -6
- package/packages/registry/components/bubble.ts +95 -0
- package/packages/registry/components/button-group.ts +73 -0
- package/packages/registry/components/button.ts +35 -25
- package/packages/registry/components/calendar.ts +566 -0
- package/packages/registry/components/card.ts +8 -8
- package/packages/registry/components/carousel.ts +352 -0
- package/packages/registry/components/chart-element.ts +547 -0
- package/packages/registry/components/chart-geometry.ts +457 -0
- package/packages/registry/components/chart.ts +932 -0
- package/packages/registry/components/checkbox.ts +22 -84
- package/packages/registry/components/code-block.ts +191 -0
- package/packages/registry/components/collapsible.ts +5 -2
- package/packages/registry/components/combobox.ts +802 -0
- package/packages/registry/components/command.ts +618 -0
- package/packages/registry/components/context-menu.ts +302 -0
- package/packages/registry/components/dialog.ts +156 -45
- package/packages/registry/components/direction.ts +43 -0
- package/packages/registry/components/drawer.ts +226 -0
- package/packages/registry/components/dropdown-menu.ts +262 -83
- package/packages/registry/components/empty.ts +88 -0
- package/packages/registry/components/field.ts +165 -0
- package/packages/registry/components/floating.ts +124 -0
- package/packages/registry/components/hover-card.ts +19 -8
- package/packages/registry/components/input-group.ts +118 -0
- package/packages/registry/components/input-otp.ts +365 -0
- package/packages/registry/components/input.ts +3 -3
- package/packages/registry/components/item.ts +134 -0
- package/packages/registry/components/kbd.ts +2 -2
- package/packages/registry/components/label.ts +1 -1
- package/packages/registry/components/marker.ts +63 -0
- package/packages/registry/components/menubar.ts +388 -0
- package/packages/registry/components/message-scroller.ts +470 -0
- package/packages/registry/components/message.ts +69 -0
- package/packages/registry/components/native-select.ts +5 -5
- package/packages/registry/components/navigation-menu.ts +564 -0
- package/packages/registry/components/pagination.ts +5 -5
- package/packages/registry/components/popover.ts +30 -84
- package/packages/registry/components/progress.ts +7 -3
- package/packages/registry/components/questionnaire.ts +840 -0
- package/packages/registry/components/radio-group.ts +18 -73
- package/packages/registry/components/resizable.ts +330 -0
- package/packages/registry/components/scroll-area.ts +46 -0
- package/packages/registry/components/select.ts +650 -0
- package/packages/registry/components/separator.ts +1 -1
- package/packages/registry/components/sheet.ts +128 -0
- package/packages/registry/components/sidebar.ts +457 -0
- package/packages/registry/components/skeleton.ts +1 -1
- package/packages/registry/components/slider.ts +333 -0
- package/packages/registry/components/sonner.ts +74 -7
- package/packages/registry/components/spinner.ts +66 -0
- package/packages/registry/components/switch.ts +117 -9
- package/packages/registry/components/table.ts +11 -9
- package/packages/registry/components/tabs.ts +76 -25
- package/packages/registry/components/textarea.ts +1 -1
- package/packages/registry/components/toggle-group.ts +30 -11
- package/packages/registry/components/toggle.ts +20 -13
- package/packages/registry/components/tooltip.ts +68 -7
- package/packages/registry/components/trace.ts +75 -0
- package/packages/registry/lib/icons-hugeicons.ts +955 -0
- package/packages/registry/lib/icons-phosphor.ts +955 -0
- package/packages/registry/lib/icons-remixicon.ts +955 -0
- package/packages/registry/lib/icons-tabler.ts +955 -0
- package/packages/registry/lib/icons.ts +768 -0
- package/packages/registry/lib/utils.ts +49 -4
- package/packages/registry/registry.json +4092 -60
- package/packages/registry/styles/shadcn-tailwind.css +654 -0
- package/packages/registry/styles/style-luma.css +1987 -0
- package/packages/registry/styles/style-lyra.css +1965 -0
- package/packages/registry/styles/style-maia.css +1987 -0
- package/packages/registry/styles/style-mira.css +1992 -0
- package/packages/registry/styles/style-new-york.css +1597 -0
- package/packages/registry/styles/style-nova.css +1990 -0
- package/packages/registry/styles/style-rhea.css +1987 -0
- package/packages/registry/styles/style-sera.css +1977 -0
- package/packages/registry/styles/style-vega.css +1990 -0
- package/packages/registry/styles/supplement.json +54 -0
- package/packages/registry/styles/tw-animate.css +6 -0
- package/packages/registry/themes/base-colors.js +8 -2
- package/packages/registry/themes/fonts.js +120 -0
- package/packages/registry/themes/index.css +2 -0
- package/packages/registry/themes/items.js +61 -0
- package/packages/registry/themes/preset.js +302 -0
- package/packages/registry/themes/themes.js +1193 -0
- package/src/commands/add.js +236 -12
- package/src/commands/diff.js +34 -20
- package/src/commands/info.js +7 -0
- package/src/commands/init.js +125 -8
- package/src/commands/list.js +43 -11
- package/src/commands/view.js +33 -5
- package/src/registry/extract.js +192 -2
- package/src/registry/icons.js +31 -0
- package/src/registry/local.js +15 -1
- package/src/registry/schema.js +13 -0
- package/src/registry/style-bake.js +506 -0
- package/src/utils/theme.js +110 -21
|
@@ -12,11 +12,10 @@
|
|
|
12
12
|
* Design tokens used: --input, --primary, --ring, --destructive.
|
|
13
13
|
*
|
|
14
14
|
* A11y (required for accessible output):
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* WCAG 1.4.1 problem (state by colour only). Every example here carries it.
|
|
15
|
+
* The dot is drawn by the class itself, so a selected radio never differs
|
|
16
|
+
* from an unselected one by colour alone (WCAG 1.4.1), with or without
|
|
17
|
+
* JavaScript. Keep `data-slot="radio"` on the input, as every example here
|
|
18
|
+
* does, since the styles' field rules select on it.
|
|
20
19
|
* NAME THE GROUP. A bare `<div role="radiogroup">` has no accessible name, so
|
|
21
20
|
* a screen reader announces "radio group" with no idea what is being chosen.
|
|
22
21
|
* Point `aria-labelledby` at the visible group label, as below, or use a
|
|
@@ -48,68 +47,17 @@
|
|
|
48
47
|
*/
|
|
49
48
|
import { cn } from '../lib/utils.ts';
|
|
50
49
|
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
// Hardcoding a single dark-coloured dot (the original implementation)
|
|
61
|
-
// painted invisibly on the near-black dark-mode surface, making the
|
|
62
|
-
// :checked state indistinguishable from unchecked. Same pattern the
|
|
63
|
-
// checkbox fix uses (CHECKMARK_LIGHT / CHECKMARK_DARK): `currentColor`
|
|
64
|
-
// in a data:url SVG used as background-image does not inherit from the
|
|
65
|
-
// host element, so we ship two SVGs and toggle them via a theme
|
|
66
|
-
// selector.
|
|
67
|
-
const DOT_LIGHT =
|
|
68
|
-
"url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><circle cx='10' cy='10' r='5' fill='oklch(0.205 0 0)'/></svg>\")";
|
|
69
|
-
const DOT_DARK =
|
|
70
|
-
"url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><circle cx='10' cy='10' r='5' fill='oklch(0.985 0 0)'/></svg>\")";
|
|
71
|
-
|
|
50
|
+
// The dot is a radial gradient in `currentColor`, the radio's own text colour,
|
|
51
|
+
// which the style chooses. shadcn's styles fill a checked radio with the
|
|
52
|
+
// primary colour and set `data-checked:text-primary-foreground`, so the dot is
|
|
53
|
+
// the light one on the fill; the default style keeps a transparent ring and
|
|
54
|
+
// sets `checked:text-primary`, so the dot is the primary one. A fixed colour
|
|
55
|
+
// (the SVG this replaced, one per theme) could only match one of the two, and
|
|
56
|
+
// disappeared into the fill under every shadcn style. Half the box across,
|
|
57
|
+
// as shadcn's indicator is. It rides the class itself, so a checked radio
|
|
58
|
+
// paints in the first paint and with JavaScript off.
|
|
72
59
|
const RADIO_CLASS =
|
|
73
|
-
'
|
|
74
|
-
|
|
75
|
-
// Three sibling rule blocks for theme selection: mirrors the
|
|
76
|
-
// checkbox.ts pattern in this same registry:
|
|
77
|
-
// - prefers-color-scheme: dark (OS preference, gated by
|
|
78
|
-
// :not([data-theme='light']):not(.light) so an explicit-light
|
|
79
|
-
// toggle still wins over the OS)
|
|
80
|
-
// - :root[data-theme='dark'] (explicit data-attribute toggle)
|
|
81
|
-
// - :root.dark (explicit class toggle, shadcn convention)
|
|
82
|
-
const STYLES = `
|
|
83
|
-
input[type="radio"][data-slot="radio"]:checked {
|
|
84
|
-
background-image: ${DOT_LIGHT};
|
|
85
|
-
background-size: 100%;
|
|
86
|
-
}
|
|
87
|
-
@media (prefers-color-scheme: dark) {
|
|
88
|
-
:root:not([data-theme='light']):not(.light) input[type="radio"][data-slot="radio"]:checked {
|
|
89
|
-
background-image: ${DOT_DARK};
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
:root[data-theme='dark'] input[type="radio"][data-slot="radio"]:checked,
|
|
93
|
-
:root.dark input[type="radio"][data-slot="radio"]:checked {
|
|
94
|
-
background-image: ${DOT_DARK};
|
|
95
|
-
}
|
|
96
|
-
`;
|
|
97
|
-
|
|
98
|
-
let installed = false;
|
|
99
|
-
export function installRadioStyles(): void {
|
|
100
|
-
if (installed || typeof document === 'undefined') return;
|
|
101
|
-
if (document.getElementById('ui-radio-styles')) {
|
|
102
|
-
installed = true;
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
const style = document.createElement('style');
|
|
106
|
-
style.id = 'ui-radio-styles';
|
|
107
|
-
style.textContent = STYLES;
|
|
108
|
-
document.head.appendChild(style);
|
|
109
|
-
installed = true;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (typeof document !== 'undefined') installRadioStyles();
|
|
60
|
+
'cn-radio-group-item group/radio-group-item peer aspect-square shrink-0 appearance-none border outline-none disabled:cursor-not-allowed disabled:opacity-50 checked:bg-[image:radial-gradient(circle_closest-side,currentColor_50%,transparent_calc(50%+0.5px))]';
|
|
113
61
|
|
|
114
62
|
/** Tailwind classes for a `<div role="radiogroup">` container. */
|
|
115
63
|
export type RadioGroupOrientation = 'vertical' | 'horizontal';
|
|
@@ -127,16 +75,13 @@ export function radioGroupClass(opts: { orientation?: RadioGroupOrientation } =
|
|
|
127
75
|
const orientation = opts.orientation ?? 'vertical';
|
|
128
76
|
return orientation === 'horizontal'
|
|
129
77
|
? 'flex flex-wrap gap-x-6 gap-y-3'
|
|
130
|
-
: '
|
|
78
|
+
: 'cn-radio-group';
|
|
131
79
|
}
|
|
132
80
|
|
|
133
81
|
/**
|
|
134
|
-
* Tailwind classes for a styled `<input type="radio">`.
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* keys the indicator dot on that attribute, and this class deliberately carries
|
|
138
|
-
* no checked background fill, so the class alone leaves a selected radio
|
|
139
|
-
* differing from an unselected one by border colour and nothing else.
|
|
82
|
+
* Tailwind classes for a styled `<input type="radio">`. The class draws the
|
|
83
|
+
* checked dot itself, so a selected radio paints with JavaScript off. Keep
|
|
84
|
+
* `data-slot="radio"` on the input as shadcn does.
|
|
140
85
|
*/
|
|
141
86
|
export function radioClass(): string {
|
|
142
87
|
return cn(RADIO_CLASS);
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resizable: panels in a row or a column with draggable handles between
|
|
3
|
+
* them. Tier-2. shadcn's is react-resizable-panels; this is the same layout
|
|
4
|
+
* on flex shares and Pointer Events, with no dependency. The server renders
|
|
5
|
+
* the default sizes, so the layout is in the first paint; resizing needs
|
|
6
|
+
* JavaScript.
|
|
7
|
+
*
|
|
8
|
+
* shadcn parity:
|
|
9
|
+
* ResizablePanelGroup orientation
|
|
10
|
+
* → <ui-resizable-panel-group orientation="horizontal" | "vertical">
|
|
11
|
+
* ResizablePanel (defaultSize, minSize, maxSize)
|
|
12
|
+
* → <ui-resizable-panel default-size min-size max-size> (percentages)
|
|
13
|
+
* ResizableHandle withHandle
|
|
14
|
+
* → <ui-resizable-handle with-handle>
|
|
15
|
+
* onLayout → `ui-layout-change` ({ detail: { sizes } }), percentages in order
|
|
16
|
+
*
|
|
17
|
+
* A panel with no `default-size` shares what the sized panels leave (give
|
|
18
|
+
* every panel a size for an exact server-rendered first paint). A drag
|
|
19
|
+
* or a key moves the boundary between the two panels around a handle, each
|
|
20
|
+
* kept within its `min-size` and `max-size`.
|
|
21
|
+
*
|
|
22
|
+
* Keyboard (the WAI-ARIA window splitter): a handle is a focusable
|
|
23
|
+
* separator; the arrows across the group (Left / Right in a row, Up / Down in
|
|
24
|
+
* a column; Left / Right swap under `dir="rtl"`) move it 10 points, Home and
|
|
25
|
+
* End move it as far as the panel before it allows.
|
|
26
|
+
*
|
|
27
|
+
* A11y (handled by the element): each handle is a `role="separator"` with
|
|
28
|
+
* `aria-orientation`, `aria-controls` naming the panel before it, and that
|
|
29
|
+
* panel's size as `aria-valuenow` within its `aria-valuemin` / `aria-valuemax`.
|
|
30
|
+
* Give the panels' content its own headings or labels, since a separator says
|
|
31
|
+
* only how big the panel is.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```html
|
|
35
|
+
* <ui-resizable-panel-group orientation="horizontal" class="max-w-md rounded-lg border">
|
|
36
|
+
* <ui-resizable-panel default-size="50"><div class="flex h-[200px] items-center justify-center p-6">One</div></ui-resizable-panel>
|
|
37
|
+
* <ui-resizable-handle with-handle></ui-resizable-handle>
|
|
38
|
+
* <ui-resizable-panel default-size="50" min-size="20"><div class="flex h-full items-center justify-center p-6">Two</div></ui-resizable-panel>
|
|
39
|
+
* </ui-resizable-panel-group>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
import { WebComponent, html, prop } from '@webjsdev/core';
|
|
43
|
+
import { cn, takeAuthoredClass } from '../lib/utils.ts';
|
|
44
|
+
|
|
45
|
+
/** The group's classes (the element applies them). */
|
|
46
|
+
export const resizablePanelGroupClass = (): string =>
|
|
47
|
+
'cn-resizable-panel-group flex h-full w-full aria-[orientation=vertical]:flex-col';
|
|
48
|
+
/** A handle's classes (the element puts them on the handle itself). */
|
|
49
|
+
export const resizableHandleClass = (): string =>
|
|
50
|
+
'cn-resizable-handle relative flex w-px items-center justify-center bg-border ring-offset-background after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-hidden aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90';
|
|
51
|
+
/** A handle's grip. */
|
|
52
|
+
export const resizableHandleIconClass = (): string => 'cn-resizable-handle-icon z-10 flex shrink-0';
|
|
53
|
+
|
|
54
|
+
const GROUP = 'ui-resizable-panel-group';
|
|
55
|
+
const STEP = 10;
|
|
56
|
+
let uid = 0;
|
|
57
|
+
|
|
58
|
+
function groupOf(el: Element): UiResizablePanelGroup | null {
|
|
59
|
+
return (typeof el.closest === 'function' ? el.closest(GROUP) : null) as UiResizablePanelGroup | null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function num(v: string | null | undefined, fallback: number): number {
|
|
63
|
+
const n = Number(v);
|
|
64
|
+
return v !== null && v !== undefined && v !== '' && Number.isFinite(n) ? n : fallback;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// --------------------------------------------------------------------------
|
|
68
|
+
// <ui-resizable-panel-group>
|
|
69
|
+
// --------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
export class UiResizablePanelGroup extends WebComponent({
|
|
72
|
+
orientation: prop<'horizontal' | 'vertical'>(String, { reflect: true }),
|
|
73
|
+
}) {
|
|
74
|
+
// The current sizes, in percent, panel by panel; empty until first laid out.
|
|
75
|
+
sizes: number[] = [];
|
|
76
|
+
_authored: string | null = null;
|
|
77
|
+
|
|
78
|
+
constructor() {
|
|
79
|
+
super();
|
|
80
|
+
this.orientation = 'horizontal';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// shadcn's className on ResizablePanelGroup lands on the group box, which
|
|
84
|
+
// is the flex item of whatever holds it (a `max-w-sm` on the group, the
|
|
85
|
+
// `h-full` that lets a nested group fill its panel). So the class written
|
|
86
|
+
// on this host moves to the box it renders, read once at first render, and
|
|
87
|
+
// the host becomes `display: contents`, leaving the box to size itself
|
|
88
|
+
// against the host's parent as shadcn's does. The host's box is turned off
|
|
89
|
+
// through its style rather than a class: the server serves the class the
|
|
90
|
+
// tag was written with, but it does serve a style the element adds, so the
|
|
91
|
+
// first paint already has one box, not two.
|
|
92
|
+
render() {
|
|
93
|
+
this._authored = takeAuthoredClass(this, null);
|
|
94
|
+
if (!this.getAttribute?.('style')) this.setAttribute?.('style', 'display: contents');
|
|
95
|
+
return html`<div
|
|
96
|
+
data-slot="resizable-panel-group"
|
|
97
|
+
data-panel-group-direction=${this.orientation}
|
|
98
|
+
aria-orientation=${this.orientation}
|
|
99
|
+
class=${cn(resizablePanelGroupClass(), this._authored)}
|
|
100
|
+
><slot></slot></div>`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The panels in this group, in order. */
|
|
104
|
+
panels(): UiResizablePanel[] {
|
|
105
|
+
if (typeof this.querySelectorAll !== 'function') return [];
|
|
106
|
+
return Array.from(this.querySelectorAll<UiResizablePanel>('ui-resizable-panel')).filter((p) => groupOf(p) === this);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** The handles in this group, in order. */
|
|
110
|
+
handles(): UiResizableHandle[] {
|
|
111
|
+
if (typeof this.querySelectorAll !== 'function') return [];
|
|
112
|
+
return Array.from(this.querySelectorAll<UiResizableHandle>('ui-resizable-handle')).filter((h) => groupOf(h) === this);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** The default layout: sized panels keep their size, the rest share what is left. */
|
|
116
|
+
initialSizes(panels = this.panels()): number[] {
|
|
117
|
+
const given = panels.map((p) => num(p.getAttribute?.('default-size'), NaN));
|
|
118
|
+
const used = given.filter((n) => !Number.isNaN(n)).reduce((a, b) => a + b, 0);
|
|
119
|
+
const free = given.filter((n) => Number.isNaN(n)).length;
|
|
120
|
+
const share = free ? Math.max(0, 100 - used) / free : 0;
|
|
121
|
+
return given.map((n) => (Number.isNaN(n) ? share : n));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** The size a panel is drawn at: its live size once laid out, else its default. */
|
|
125
|
+
sizeOf(panel: UiResizablePanel): number {
|
|
126
|
+
const panels = this.panels();
|
|
127
|
+
const i = panels.indexOf(panel);
|
|
128
|
+
// The server cannot list the panels, so there a panel draws at its own
|
|
129
|
+
// default size: give every panel one for an exact first paint.
|
|
130
|
+
if (i < 0) return num(panel.getAttribute?.('default-size'), 50);
|
|
131
|
+
return (this.sizes.length === panels.length ? this.sizes : this.initialSizes(panels))[i];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Move the boundary after panel `i` by `delta` points, keeping both panels
|
|
136
|
+
* within their limits. Returns whether anything moved.
|
|
137
|
+
*/
|
|
138
|
+
resize(i: number, delta: number): boolean {
|
|
139
|
+
const panels = this.panels();
|
|
140
|
+
if (i < 0 || i >= panels.length - 1) return false;
|
|
141
|
+
if (this.sizes.length !== panels.length) this.sizes = this.initialSizes(panels);
|
|
142
|
+
const a = panels[i];
|
|
143
|
+
const b = panels[i + 1];
|
|
144
|
+
const sa = this.sizes[i];
|
|
145
|
+
const sb = this.sizes[i + 1];
|
|
146
|
+
// The move lies between the most either panel can give and take.
|
|
147
|
+
const lo = Math.max(a.min - sa, sb - b.max);
|
|
148
|
+
const hi = Math.min(a.max - sa, sb - b.min);
|
|
149
|
+
const d = Math.min(Math.max(delta, lo), hi);
|
|
150
|
+
if (!Number.isFinite(d) || Math.abs(d) < 1e-9) return false;
|
|
151
|
+
const next = [...this.sizes];
|
|
152
|
+
next[i] = Number((sa + d).toFixed(4));
|
|
153
|
+
next[i + 1] = Number((sb - d).toFixed(4));
|
|
154
|
+
this.sizes = next;
|
|
155
|
+
this._apply();
|
|
156
|
+
this.dispatchEvent(new CustomEvent('ui-layout-change', { bubbles: true, detail: { sizes: [...next] } }));
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Redraw every panel and handle at the current sizes.
|
|
161
|
+
_apply(): void {
|
|
162
|
+
for (const p of this.panels()) p.requestUpdate?.();
|
|
163
|
+
for (const h of this.handles()) h.requestUpdate?.();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
_rtl(): boolean {
|
|
167
|
+
return typeof getComputedStyle === 'function' && getComputedStyle(this).direction === 'rtl';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** The group's length along its axis, in pixels. */
|
|
171
|
+
extent(): number {
|
|
172
|
+
const box = this.querySelector?.<HTMLElement>('[data-slot="resizable-panel-group"]');
|
|
173
|
+
const r = box?.getBoundingClientRect();
|
|
174
|
+
if (!r) return 0;
|
|
175
|
+
return this.orientation === 'vertical' ? r.height : r.width;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
UiResizablePanelGroup.register('ui-resizable-panel-group');
|
|
179
|
+
|
|
180
|
+
// --------------------------------------------------------------------------
|
|
181
|
+
// <ui-resizable-panel>
|
|
182
|
+
// --------------------------------------------------------------------------
|
|
183
|
+
|
|
184
|
+
export class UiResizablePanel extends WebComponent {
|
|
185
|
+
_id = '';
|
|
186
|
+
|
|
187
|
+
connectedCallback(): void {
|
|
188
|
+
super.connectedCallback?.();
|
|
189
|
+
this._id ||= `ui-resizable-panel-${++uid}`;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
get min(): number {
|
|
193
|
+
return num(this.getAttribute?.('min-size'), 0);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
get max(): number {
|
|
197
|
+
return num(this.getAttribute?.('max-size'), 100);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// A panel is the flex child itself, so it carries its own share.
|
|
201
|
+
render() {
|
|
202
|
+
const size = groupOf(this)?.sizeOf(this) ?? 100;
|
|
203
|
+
if (typeof this.setAttribute === 'function') {
|
|
204
|
+
if (this._id) this.setAttribute('id', this._id);
|
|
205
|
+
this.setAttribute('data-slot', 'resizable-panel');
|
|
206
|
+
this.setAttribute('data-panel-size', String(Number(size.toFixed(1))));
|
|
207
|
+
this.setAttribute('style', `flex: ${size} 1 0px; overflow: hidden;`);
|
|
208
|
+
}
|
|
209
|
+
return html`<slot></slot>`;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
UiResizablePanel.register('ui-resizable-panel');
|
|
213
|
+
|
|
214
|
+
// --------------------------------------------------------------------------
|
|
215
|
+
// <ui-resizable-handle>
|
|
216
|
+
// --------------------------------------------------------------------------
|
|
217
|
+
|
|
218
|
+
export class UiResizableHandle extends WebComponent({
|
|
219
|
+
withHandle: prop(Boolean, { attribute: 'with-handle' }),
|
|
220
|
+
}) {
|
|
221
|
+
_authored: string | null = null;
|
|
222
|
+
_drag: { at: number; extent: number } | null = null;
|
|
223
|
+
|
|
224
|
+
constructor() {
|
|
225
|
+
super();
|
|
226
|
+
this.withHandle = false;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
connectedCallback(): void {
|
|
230
|
+
super.connectedCallback?.();
|
|
231
|
+
this.addEventListener('keydown', this._onKeyDown);
|
|
232
|
+
this.addEventListener('pointerdown', this._onPointerDown);
|
|
233
|
+
this.addEventListener('pointermove', this._onPointerMove);
|
|
234
|
+
this.addEventListener('pointerup', this._onPointerUp);
|
|
235
|
+
this.addEventListener('pointercancel', this._onPointerUp);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
disconnectedCallback(): void {
|
|
239
|
+
this.removeEventListener('keydown', this._onKeyDown);
|
|
240
|
+
this.removeEventListener('pointerdown', this._onPointerDown);
|
|
241
|
+
this.removeEventListener('pointermove', this._onPointerMove);
|
|
242
|
+
this.removeEventListener('pointerup', this._onPointerUp);
|
|
243
|
+
this.removeEventListener('pointercancel', this._onPointerUp);
|
|
244
|
+
super.disconnectedCallback?.();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// The panel before this handle, whose size the handle reports.
|
|
248
|
+
_index(): number {
|
|
249
|
+
const group = groupOf(this);
|
|
250
|
+
if (!group) return -1;
|
|
251
|
+
const panels = group.panels();
|
|
252
|
+
let before = -1;
|
|
253
|
+
for (let i = 0; i < panels.length; i++) {
|
|
254
|
+
if (panels[i].compareDocumentPosition?.(this) & 4) before = i;
|
|
255
|
+
}
|
|
256
|
+
return before;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// The handle is the separator itself: a flex child that takes focus.
|
|
260
|
+
render() {
|
|
261
|
+
this._authored = takeAuthoredClass(this);
|
|
262
|
+
const group = groupOf(this);
|
|
263
|
+
const vertical = group?.orientation === 'vertical';
|
|
264
|
+
const i = typeof this.compareDocumentPosition === 'function' ? this._index() : -1;
|
|
265
|
+
const panel = i >= 0 ? group?.panels()[i] : null;
|
|
266
|
+
if (typeof this.setAttribute === 'function') {
|
|
267
|
+
this.setAttribute('class', cn(resizableHandleClass(), this._authored));
|
|
268
|
+
this.setAttribute('data-slot', 'resizable-handle');
|
|
269
|
+
this.setAttribute('role', 'separator');
|
|
270
|
+
this.setAttribute('tabindex', '0');
|
|
271
|
+
// A row of panels has upright separators, and a column flat ones.
|
|
272
|
+
this.setAttribute('aria-orientation', vertical ? 'horizontal' : 'vertical');
|
|
273
|
+
if (panel && group) {
|
|
274
|
+
this.setAttribute('aria-controls', panel.id);
|
|
275
|
+
this.setAttribute('aria-valuenow', String(Math.round(group.sizeOf(panel))));
|
|
276
|
+
this.setAttribute('aria-valuemin', String(panel.min));
|
|
277
|
+
this.setAttribute('aria-valuemax', String(panel.max));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return this.withHandle
|
|
281
|
+
? html`<div class=${resizableHandleIconClass()}><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="size-2.5"><circle cx="9" cy="12" r="1"></circle><circle cx="9" cy="5" r="1"></circle><circle cx="9" cy="19" r="1"></circle><circle cx="15" cy="12" r="1"></circle><circle cx="15" cy="5" r="1"></circle><circle cx="15" cy="19" r="1"></circle></svg></div>`
|
|
282
|
+
: html``;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
_onKeyDown = (e: KeyboardEvent): void => {
|
|
286
|
+
const group = groupOf(this);
|
|
287
|
+
if (!group) return;
|
|
288
|
+
const i = this._index();
|
|
289
|
+
const vertical = group.orientation === 'vertical';
|
|
290
|
+
const flip = !vertical && group._rtl() ? -1 : 1;
|
|
291
|
+
let delta: number | null = null;
|
|
292
|
+
if (!vertical && e.key === 'ArrowLeft') delta = -STEP * flip;
|
|
293
|
+
else if (!vertical && e.key === 'ArrowRight') delta = STEP * flip;
|
|
294
|
+
else if (vertical && e.key === 'ArrowUp') delta = -STEP;
|
|
295
|
+
else if (vertical && e.key === 'ArrowDown') delta = STEP;
|
|
296
|
+
else if (e.key === 'Home') delta = -100;
|
|
297
|
+
else if (e.key === 'End') delta = 100;
|
|
298
|
+
if (delta === null) return;
|
|
299
|
+
e.preventDefault();
|
|
300
|
+
group.resize(i, delta);
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
_onPointerDown = (e: PointerEvent): void => {
|
|
304
|
+
const group = groupOf(this);
|
|
305
|
+
if (!group || e.button !== 0) return;
|
|
306
|
+
e.preventDefault();
|
|
307
|
+
this.focus();
|
|
308
|
+
const vertical = group.orientation === 'vertical';
|
|
309
|
+
this._drag = { at: vertical ? e.clientY : e.clientX, extent: group.extent() };
|
|
310
|
+
try { this.setPointerCapture(e.pointerId); } catch { /* a pointer the engine does not track */ }
|
|
311
|
+
this.setAttribute('data-resize-handle-state', 'drag');
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
_onPointerMove = (e: PointerEvent): void => {
|
|
315
|
+
const group = groupOf(this);
|
|
316
|
+
if (!this._drag || !group || !this._drag.extent) return;
|
|
317
|
+
const vertical = group.orientation === 'vertical';
|
|
318
|
+
const now = vertical ? e.clientY : e.clientX;
|
|
319
|
+
const px = (now - this._drag.at) * (!vertical && group._rtl() ? -1 : 1);
|
|
320
|
+
if (group.resize(this._index(), (px / this._drag.extent) * 100)) this._drag.at = now;
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
_onPointerUp = (e: PointerEvent): void => {
|
|
324
|
+
if (!this._drag) return;
|
|
325
|
+
this._drag = null;
|
|
326
|
+
try { this.releasePointerCapture(e.pointerId); } catch { /* already released */ }
|
|
327
|
+
this.removeAttribute('data-resize-handle-state');
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
UiResizableHandle.register('ui-resizable-handle');
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scroll area: a region that scrolls inside a fixed size, with a thin,
|
|
3
|
+
* theme-coloured scrollbar. Tier-1 class helper on native overflow; no
|
|
4
|
+
* script, no custom scrollbar element.
|
|
5
|
+
*
|
|
6
|
+
* shadcn parity:
|
|
7
|
+
* ScrollArea (+ its viewport) → scrollAreaClass({ orientation })
|
|
8
|
+
* ScrollBar → the native scrollbar, styled through
|
|
9
|
+
* scrollbar-width and scrollbar-color
|
|
10
|
+
*
|
|
11
|
+
* shadcn draws its own scrollbar with Radix. The platform's scrollbar is
|
|
12
|
+
* styled instead here, which keeps native scrolling, momentum, keyboard
|
|
13
|
+
* scrolling and the browser's own overlay behaviour intact. Give the element
|
|
14
|
+
* a size (`h-72`, `max-h-96`, `w-96`) so it has something to scroll inside.
|
|
15
|
+
*
|
|
16
|
+
* A11y (required for accessible output): a region that scrolls must be
|
|
17
|
+
* reachable by keyboard, so give it `tabindex="0"`, and because a focusable
|
|
18
|
+
* region needs a name, add `role="region"` with an `aria-label` that says what
|
|
19
|
+
* scrolls ("Release notes"). The focus ring is part of the class.
|
|
20
|
+
*
|
|
21
|
+
* Design tokens used: --border, --ring.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```html
|
|
25
|
+
* <div class=${cn(scrollAreaClass(), 'h-72 w-48 rounded-md border')} tabindex="0" role="region" aria-label="Tags">
|
|
26
|
+
* <ul class="p-4">${tags.map((t) => html`<li>${t}</li>`)}</ul>
|
|
27
|
+
* </div>
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import { cn } from '../lib/utils.ts';
|
|
31
|
+
|
|
32
|
+
const BASE =
|
|
33
|
+
'cn-scroll-area relative rounded-[inherit] [scrollbar-width:thin] [scrollbar-color:var(--color-border)_transparent] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50';
|
|
34
|
+
|
|
35
|
+
const ORIENTATIONS = {
|
|
36
|
+
vertical: 'overflow-y-auto overflow-x-hidden',
|
|
37
|
+
horizontal: 'overflow-x-auto overflow-y-hidden',
|
|
38
|
+
both: 'overflow-auto',
|
|
39
|
+
} as const;
|
|
40
|
+
|
|
41
|
+
export type ScrollAreaOrientation = keyof typeof ORIENTATIONS;
|
|
42
|
+
|
|
43
|
+
/** The scrolling region. `orientation` picks the axis (default vertical). */
|
|
44
|
+
export function scrollAreaClass(opts: { orientation?: ScrollAreaOrientation } = {}): string {
|
|
45
|
+
return cn(BASE, ORIENTATIONS[opts.orientation ?? 'vertical']);
|
|
46
|
+
}
|