@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
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Empty: the empty state for a list, table, search result, or any region with
|
|
3
|
+
* nothing to show yet. Tier-1 class helpers; compose with `<div>` (or a heading
|
|
4
|
+
* and paragraph) for each subpart.
|
|
5
|
+
*
|
|
6
|
+
* shadcn parity:
|
|
7
|
+
* Empty → emptyClass()
|
|
8
|
+
* EmptyHeader → emptyHeaderClass()
|
|
9
|
+
* EmptyMedia (variant: default | icon) → emptyMediaClass({ variant })
|
|
10
|
+
* EmptyTitle → emptyTitleClass()
|
|
11
|
+
* EmptyDescription → emptyDescriptionClass()
|
|
12
|
+
* EmptyContent → emptyContentClass()
|
|
13
|
+
*
|
|
14
|
+
* The root carries `border-dashed` but no border width, exactly as shadcn
|
|
15
|
+
* does, so it renders borderless by default. Add `border` beside it for the
|
|
16
|
+
* dashed outline: `class=${cn(emptyClass(), 'border')}`.
|
|
17
|
+
*
|
|
18
|
+
* Design tokens used: --muted, --foreground, --muted-foreground, --primary,
|
|
19
|
+
* --border.
|
|
20
|
+
*
|
|
21
|
+
* A11y (required for accessible output):
|
|
22
|
+
* Use a REAL HEADING for `emptyTitleClass()`, at the level the surrounding
|
|
23
|
+
* document wants (`<h2>` under the page `<h1>`, `<h3>` inside a section). The
|
|
24
|
+
* empty state usually replaces the list a heading already introduces, so the
|
|
25
|
+
* title is often a level below it.
|
|
26
|
+
* The media is decorative: put `aria-hidden="true"` on the icon or
|
|
27
|
+
* illustration, since the title already says what is missing.
|
|
28
|
+
* The action in `emptyContentClass()` is a real `<a href>` (navigates, e.g.
|
|
29
|
+
* to the create page) or a real `<button>` (acts in place). A create action
|
|
30
|
+
* that is a form submit keeps working without JavaScript.
|
|
31
|
+
* When the empty state appears in response to a user action (a search or a
|
|
32
|
+
* filter that matched nothing), put `role="status"` on the root so the change
|
|
33
|
+
* is announced; a page that simply loads empty needs no role.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```html
|
|
37
|
+
* <div class=${cn(emptyClass(), 'border')}>
|
|
38
|
+
* <div class=${emptyHeaderClass()}>
|
|
39
|
+
* <div class=${emptyMediaClass({ variant: 'icon' })}>
|
|
40
|
+
* <svg aria-hidden="true" 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"><path d="M22 12h-6l-2 3h-4l-2-3H2"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg>
|
|
41
|
+
* </div>
|
|
42
|
+
* <h3 class=${emptyTitleClass()}>No projects yet</h3>
|
|
43
|
+
* <p class=${emptyDescriptionClass()}>Create your first project to get started.</p>
|
|
44
|
+
* </div>
|
|
45
|
+
* <div class=${emptyContentClass()}>
|
|
46
|
+
* <a class=${buttonClass()} href="/projects/new">Create project</a>
|
|
47
|
+
* </div>
|
|
48
|
+
* </div>
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
const MEDIA_BASE =
|
|
53
|
+
'cn-empty-media flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0';
|
|
54
|
+
|
|
55
|
+
const MEDIA_VARIANTS = {
|
|
56
|
+
default: 'cn-empty-media-default',
|
|
57
|
+
icon: 'cn-empty-media-icon',
|
|
58
|
+
} as const;
|
|
59
|
+
|
|
60
|
+
export type EmptyMediaVariant = keyof typeof MEDIA_VARIANTS;
|
|
61
|
+
|
|
62
|
+
/** Empty root: centred column with generous padding. Add `border` for the dashed outline. */
|
|
63
|
+
export const emptyClass = (): string =>
|
|
64
|
+
'cn-empty flex w-full min-w-0 flex-1 flex-col items-center justify-center text-center text-balance';
|
|
65
|
+
|
|
66
|
+
/** Empty header: groups the media, title, and description. */
|
|
67
|
+
export const emptyHeaderClass = (): string =>
|
|
68
|
+
'cn-empty-header flex max-w-sm flex-col items-center';
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Empty media: the icon or illustration above the title. `icon` puts the icon
|
|
72
|
+
* on a muted tile; `default` leaves it bare (for an avatar or an illustration).
|
|
73
|
+
* Set `data-variant="<variant>"` on the same element for shadcn parity.
|
|
74
|
+
*/
|
|
75
|
+
export function emptyMediaClass(opts: { variant?: EmptyMediaVariant } = {}): string {
|
|
76
|
+
return MEDIA_BASE + ' ' + MEDIA_VARIANTS[opts.variant ?? 'default'];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Empty title: what is missing, in a few words. */
|
|
80
|
+
export const emptyTitleClass = (): string => 'cn-empty-title';
|
|
81
|
+
|
|
82
|
+
/** Empty description: the muted line under the title, saying what to do next. */
|
|
83
|
+
export const emptyDescriptionClass = (): string =>
|
|
84
|
+
'cn-empty-description text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary';
|
|
85
|
+
|
|
86
|
+
/** Empty content: the row for the action button(s) or a small form. */
|
|
87
|
+
export const emptyContentClass = (): string =>
|
|
88
|
+
'cn-empty-content flex w-full max-w-sm min-w-0 flex-col items-center text-balance';
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field: the layout system for a form, a label, a control, its helper text,
|
|
3
|
+
* and its error message, plus the fieldset, legend, and group that hold many
|
|
4
|
+
* fields. Tier-1 class helpers; compose with the native elements (`<fieldset>`,
|
|
5
|
+
* `<legend>`, `<label>`, `<p>`) and the kit's control helpers
|
|
6
|
+
* (`inputClass()`, `textareaClass()`, `checkboxClass()`, and the rest).
|
|
7
|
+
*
|
|
8
|
+
* shadcn parity:
|
|
9
|
+
* FieldSet → fieldSetClass()
|
|
10
|
+
* FieldLegend (variant: legend | label) → fieldLegendClass({ variant })
|
|
11
|
+
* FieldGroup → fieldGroupClass()
|
|
12
|
+
* Field (orientation: vertical | horizontal | responsive) → fieldClass({ orientation })
|
|
13
|
+
* FieldContent → fieldContentClass()
|
|
14
|
+
* FieldLabel → fieldLabelClass()
|
|
15
|
+
* FieldTitle → fieldTitleClass()
|
|
16
|
+
* FieldDescription → fieldDescriptionClass()
|
|
17
|
+
* FieldError → fieldErrorClass()
|
|
18
|
+
* FieldSeparator → fieldSeparatorClass() + fieldSeparatorContentClass()
|
|
19
|
+
*
|
|
20
|
+
* Set the shadcn data attributes on the same elements, because the sibling and
|
|
21
|
+
* group rules key on them: `data-slot="field"` + `data-orientation` on the
|
|
22
|
+
* field, `data-slot="field-label"` on the label, `data-slot="field-content"`
|
|
23
|
+
* on the content wrapper, `data-variant` on the legend, and
|
|
24
|
+
* `data-slot="field-group"` on the group (the `responsive` orientation reads
|
|
25
|
+
* the group's container width).
|
|
26
|
+
*
|
|
27
|
+
* Invalid state: put `data-invalid="true"` on the field, which turns the
|
|
28
|
+
* field's text destructive (`data-[invalid=true]:text-destructive`), and
|
|
29
|
+
* `aria-invalid="true"` on the control, which the control helpers style.
|
|
30
|
+
* Disabled state: `data-disabled="true"` on the field fades its label.
|
|
31
|
+
*
|
|
32
|
+
* Not the same as the `fieldClass()` / `fieldLabelClass()` in the `cn()`
|
|
33
|
+
* helper module (`lib/utils/cn.ts`), which are the older single-field rhythm
|
|
34
|
+
* helpers (`grid gap-2`). Both keep working. Import each from its own module,
|
|
35
|
+
* and alias one (`import { fieldClass as fieldStackClass } from ...`) if a file
|
|
36
|
+
* needs both.
|
|
37
|
+
*
|
|
38
|
+
* Design tokens used: --destructive, --muted-foreground, --primary,
|
|
39
|
+
* --background, --border.
|
|
40
|
+
*
|
|
41
|
+
* A11y (required for accessible output):
|
|
42
|
+
* Every control has a real `<label for>` (`fieldLabelClass()`), never a
|
|
43
|
+
* placeholder alone. A field carries `role="group"` (as shadcn's does) only
|
|
44
|
+
* when it holds more than one control; a single-control field needs no role.
|
|
45
|
+
* Wire the helper and error text to the control with `aria-describedby`,
|
|
46
|
+
* listing the description id and, when invalid, the error id
|
|
47
|
+
* (`aria-describedby="email-desc email-error"`). Point it only at ids that
|
|
48
|
+
* EXIST on the page, so render the error element only when there is an error.
|
|
49
|
+
* On a server validation error, re-render the form with the typed values
|
|
50
|
+
* kept (`value=${values.email}`), `data-invalid="true"` on the field,
|
|
51
|
+
* `aria-invalid="true"` on the control, and the message in
|
|
52
|
+
* `fieldErrorClass()` with `role="alert"`, so the user fixes the one field
|
|
53
|
+
* instead of retyping the form. Move focus to the first invalid control.
|
|
54
|
+
* Group related controls (a radio set, a checkbox list) in a `<fieldset>`
|
|
55
|
+
* with a `<legend>` (`fieldSetClass()` / `fieldLegendClass()`), which names
|
|
56
|
+
* the group. A `fieldTitleClass()` element is NOT a label: use it for the
|
|
57
|
+
* title inside a choice card whose `<label>` wraps the whole card.
|
|
58
|
+
* A decorative separator gets `role="none"`; its text (`or`) stays readable.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```html
|
|
62
|
+
* <form method="post" class="w-full max-w-md">
|
|
63
|
+
* <fieldset class=${fieldSetClass()}>
|
|
64
|
+
* <legend class=${fieldLegendClass()} data-variant="legend">Profile</legend>
|
|
65
|
+
* <p class=${fieldDescriptionClass()}>This is how others see you.</p>
|
|
66
|
+
* <div class=${fieldGroupClass()} data-slot="field-group">
|
|
67
|
+
* <div class=${fieldClass()} data-slot="field" data-orientation="vertical">
|
|
68
|
+
* <label class=${fieldLabelClass()} data-slot="field-label" for="name">Name</label>
|
|
69
|
+
* <input class=${inputClass()} id="name" name="name" value="Ada" aria-describedby="name-desc">
|
|
70
|
+
* <p class=${fieldDescriptionClass()} id="name-desc">Shown on your public page.</p>
|
|
71
|
+
* </div>
|
|
72
|
+
* <div class=${fieldClass()} data-slot="field" data-orientation="vertical" data-invalid="true">
|
|
73
|
+
* <label class=${fieldLabelClass()} data-slot="field-label" for="email">Email</label>
|
|
74
|
+
* <input class=${inputClass()} id="email" name="email" type="email" value="ada@" aria-invalid="true" aria-describedby="email-error">
|
|
75
|
+
* <div class=${fieldErrorClass()} id="email-error" role="alert">Enter a valid email address.</div>
|
|
76
|
+
* </div>
|
|
77
|
+
* <div class=${fieldSeparatorClass()} role="none"><span class=${fieldSeparatorContentClass()}>Notifications</span></div>
|
|
78
|
+
* <div class=${fieldClass({ orientation: 'horizontal' })} data-slot="field" data-orientation="horizontal">
|
|
79
|
+
* <input class=${checkboxClass()} data-slot="checkbox" type="checkbox" id="digest" name="digest">
|
|
80
|
+
* <label class=${fieldLabelClass()} data-slot="field-label" for="digest">Send me a weekly digest</label>
|
|
81
|
+
* </div>
|
|
82
|
+
* </div>
|
|
83
|
+
* </fieldset>
|
|
84
|
+
* </form>
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
export type FieldLegendVariant = 'legend' | 'label';
|
|
89
|
+
export type FieldOrientation = 'vertical' | 'horizontal' | 'responsive';
|
|
90
|
+
|
|
91
|
+
const LEGEND_VARIANTS = {
|
|
92
|
+
legend: 'cn-field-legend-variant-legend',
|
|
93
|
+
label: 'cn-field-legend-variant-label',
|
|
94
|
+
} as const;
|
|
95
|
+
|
|
96
|
+
// shadcn's `*:w-full` widens a field's control because the control is the
|
|
97
|
+
// field's child. A `<ui-select>` host is `display: contents` and its trigger
|
|
98
|
+
// (or, before it upgrades, the native select) sits two levels down, so the
|
|
99
|
+
// same width reaches through the host to it.
|
|
100
|
+
const ORIENTATIONS = {
|
|
101
|
+
vertical: 'cn-field-orientation-vertical flex-col *:w-full [&>.sr-only]:w-auto [&>ui-select_:is(select,[data-slot=select-trigger])]:w-full',
|
|
102
|
+
horizontal: 'cn-field-orientation-horizontal flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',
|
|
103
|
+
responsive: 'cn-field-orientation-responsive flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px [&>ui-select_:is(select,[data-slot=select-trigger])]:w-full @md/field-group:[&>ui-select_:is(select,[data-slot=select-trigger])]:w-auto',
|
|
104
|
+
} as const;
|
|
105
|
+
|
|
106
|
+
/** Field set: a native `<fieldset>` holding a legend and a group of fields. */
|
|
107
|
+
export const fieldSetClass = (): string =>
|
|
108
|
+
'cn-field-set flex flex-col';
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Field legend: the `<legend>` naming a field set. `legend` is section-sized,
|
|
112
|
+
* `label` matches a field label (for a radio or checkbox set). Set
|
|
113
|
+
* `data-variant="<variant>"` on the same element so a following description
|
|
114
|
+
* tightens its spacing.
|
|
115
|
+
*/
|
|
116
|
+
export function fieldLegendClass(opts: { variant?: FieldLegendVariant } = {}): string {
|
|
117
|
+
return 'cn-field-legend ' + LEGEND_VARIANTS[opts.variant ?? 'legend'];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Field group: stacks fields, and is the container `responsive` fields measure. */
|
|
121
|
+
export const fieldGroupClass = (): string =>
|
|
122
|
+
'cn-field-group group/field-group @container/field-group flex w-full flex-col';
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Field: one label + control + text unit. `vertical` stacks them, `horizontal`
|
|
126
|
+
* puts the control beside the label (checkbox, switch), and `responsive` stacks
|
|
127
|
+
* on a narrow group and goes side by side from the group's `md` width.
|
|
128
|
+
*/
|
|
129
|
+
export function fieldClass(opts: { orientation?: FieldOrientation } = {}): string {
|
|
130
|
+
return (
|
|
131
|
+
'cn-field group/field flex w-full ' +
|
|
132
|
+
ORIENTATIONS[opts.orientation ?? 'vertical']
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Field content: wraps a label and description beside a horizontal control. */
|
|
137
|
+
export const fieldContentClass = (): string =>
|
|
138
|
+
'cn-field-content group/field-content flex flex-1 flex-col leading-snug';
|
|
139
|
+
|
|
140
|
+
/** Field label: the `<label for>` of the control. Fades when the field is data-disabled. */
|
|
141
|
+
export const fieldLabelClass = (): string =>
|
|
142
|
+
'cn-label cn-field-label group/field-label peer/field-label flex w-fit items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col';
|
|
143
|
+
|
|
144
|
+
/** Field title: label-styled text that is not a `<label>` (a choice card's heading). */
|
|
145
|
+
export const fieldTitleClass = (): string =>
|
|
146
|
+
'cn-field-title flex w-fit items-center';
|
|
147
|
+
|
|
148
|
+
/** Field description: the muted helper text under (or beside) the control. */
|
|
149
|
+
export const fieldDescriptionClass = (): string =>
|
|
150
|
+
'cn-field-description leading-normal font-normal group-has-data-horizontal/field:text-balance last:mt-0 nth-last-2:-mt-1 [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary';
|
|
151
|
+
|
|
152
|
+
/** Field error: the inline validation message. Give it an id the control's aria-describedby lists. */
|
|
153
|
+
export const fieldErrorClass = (): string => 'cn-field-error font-normal';
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Field separator: a horizontal rule between fields, drawn by the element's own
|
|
157
|
+
* `::before`, with optional centred text in a `fieldSeparatorContentClass()`
|
|
158
|
+
* span.
|
|
159
|
+
*/
|
|
160
|
+
export const fieldSeparatorClass = (): string =>
|
|
161
|
+
'cn-field-separator relative before:absolute before:inset-x-0 before:top-1/2 before:h-px before:bg-border';
|
|
162
|
+
|
|
163
|
+
/** Field separator content: the text on the separator line (`or`, a section name). */
|
|
164
|
+
export const fieldSeparatorContentClass = (): string =>
|
|
165
|
+
'cn-field-separator-content relative mx-auto block w-fit bg-background';
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Floating placement: positions a panel beside the element that opened it.
|
|
3
|
+
* Tier-2 support module. The kit's overlays that measure their own placement
|
|
4
|
+
* (tooltip, hover card, the dropdown, context and menubar menus, select,
|
|
5
|
+
* combobox) import `positionFloating` from here, and so does a hand-built
|
|
6
|
+
* popover that wants measured placement.
|
|
7
|
+
*
|
|
8
|
+
* It is its own module because it reads the window and the elements' boxes,
|
|
9
|
+
* which is browser code. Kept beside the popover's class helpers, it would make
|
|
10
|
+
* every page importing `popoverContentClass` ship to the browser whole, the
|
|
11
|
+
* same reason `cn()` and the DOM helpers are separate modules.
|
|
12
|
+
*/
|
|
13
|
+
import type { PopoverSide, PopoverAlign } from './popover.ts';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Places `content` beside `trigger`, flipping to the opposite side when it
|
|
17
|
+
* does not fit, and keeps it 8px inside the viewport.
|
|
18
|
+
*
|
|
19
|
+
* `radix` names the component the way Radix does (`dropdown-menu`,
|
|
20
|
+
* `tooltip`), and makes this set the variables Radix's positioner sets on the
|
|
21
|
+
* panel, which shadcn's classes read: `--radix-<name>-trigger-width` /
|
|
22
|
+
* `-height`, `--radix-<name>-content-available-width` / `-height` and
|
|
23
|
+
* `--radix-<name>-content-transform-origin`. Without them a class such as
|
|
24
|
+
* `w-(--radix-dropdown-menu-trigger-width)` resolves to nothing, and a fixed
|
|
25
|
+
* panel with no width stretches across the viewport.
|
|
26
|
+
*/
|
|
27
|
+
export function positionFloating(
|
|
28
|
+
trigger: HTMLElement,
|
|
29
|
+
content: HTMLElement,
|
|
30
|
+
opts: {
|
|
31
|
+
side?: PopoverSide;
|
|
32
|
+
align?: PopoverAlign;
|
|
33
|
+
sideOffset?: number;
|
|
34
|
+
alignOffset?: number;
|
|
35
|
+
radix?: string;
|
|
36
|
+
} = {},
|
|
37
|
+
): void {
|
|
38
|
+
const side = opts.side ?? 'bottom';
|
|
39
|
+
const align = opts.align ?? 'center';
|
|
40
|
+
const sideOffset = opts.sideOffset ?? 4;
|
|
41
|
+
const alignOffset = opts.alignOffset ?? 0;
|
|
42
|
+
const tr = trigger.getBoundingClientRect();
|
|
43
|
+
const vars = opts.radix ? `--radix-${opts.radix}` : '';
|
|
44
|
+
// The trigger's size first: a panel sized from it can only be measured
|
|
45
|
+
// once it is set.
|
|
46
|
+
if (vars) {
|
|
47
|
+
content.style.setProperty(`${vars}-trigger-width`, `${tr.width}px`);
|
|
48
|
+
content.style.setProperty(`${vars}-trigger-height`, `${tr.height}px`);
|
|
49
|
+
}
|
|
50
|
+
const cr = content.getBoundingClientRect();
|
|
51
|
+
const vw = window.innerWidth;
|
|
52
|
+
const vh = window.innerHeight;
|
|
53
|
+
|
|
54
|
+
let top = 0;
|
|
55
|
+
let left = 0;
|
|
56
|
+
let actualSide = side;
|
|
57
|
+
|
|
58
|
+
const fitsBottom = tr.bottom + sideOffset + cr.height <= vh;
|
|
59
|
+
const fitsTop = tr.top - sideOffset - cr.height >= 0;
|
|
60
|
+
const fitsRight = tr.right + sideOffset + cr.width <= vw;
|
|
61
|
+
const fitsLeft = tr.left - sideOffset - cr.width >= 0;
|
|
62
|
+
|
|
63
|
+
if (side === 'bottom' && !fitsBottom && fitsTop) actualSide = 'top';
|
|
64
|
+
else if (side === 'top' && !fitsTop && fitsBottom) actualSide = 'bottom';
|
|
65
|
+
else if (side === 'right' && !fitsRight && fitsLeft) actualSide = 'left';
|
|
66
|
+
else if (side === 'left' && !fitsLeft && fitsRight) actualSide = 'right';
|
|
67
|
+
|
|
68
|
+
if (actualSide === 'bottom') top = tr.bottom + sideOffset;
|
|
69
|
+
else if (actualSide === 'top') top = tr.top - sideOffset - cr.height;
|
|
70
|
+
else if (actualSide === 'right' || actualSide === 'left') {
|
|
71
|
+
if (align === 'start') top = tr.top;
|
|
72
|
+
else if (align === 'end') top = tr.bottom - cr.height;
|
|
73
|
+
else top = tr.top + (tr.height - cr.height) / 2;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (actualSide === 'right') left = tr.right + sideOffset;
|
|
77
|
+
else if (actualSide === 'left') left = tr.left - sideOffset - cr.width;
|
|
78
|
+
else {
|
|
79
|
+
if (align === 'start') left = tr.left;
|
|
80
|
+
else if (align === 'end') left = tr.right - cr.width;
|
|
81
|
+
else left = tr.left + (tr.width - cr.width) / 2;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// alignOffset shifts the popover along the align axis. For align='start',
|
|
85
|
+
// positive shifts AWAY from the start edge; align='end' reverses; center
|
|
86
|
+
// is a no-op. Axis is perpendicular to the chosen side.
|
|
87
|
+
if (align !== 'center' && alignOffset !== 0) {
|
|
88
|
+
const dir = align === 'start' ? 1 : -1;
|
|
89
|
+
if (actualSide === 'top' || actualSide === 'bottom') {
|
|
90
|
+
left += dir * alignOffset;
|
|
91
|
+
} else {
|
|
92
|
+
top += dir * alignOffset;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
left = Math.max(8, Math.min(left, vw - cr.width - 8));
|
|
97
|
+
top = Math.max(8, Math.min(top, vh - cr.height - 8));
|
|
98
|
+
|
|
99
|
+
content.style.top = `${top}px`;
|
|
100
|
+
content.style.left = `${left}px`;
|
|
101
|
+
if (vars) {
|
|
102
|
+
// What Radix's size and transform-origin middleware report, with no
|
|
103
|
+
// collision padding and no arrow.
|
|
104
|
+
const availableHeight =
|
|
105
|
+
actualSide === 'bottom' ? vh - tr.bottom - sideOffset
|
|
106
|
+
: actualSide === 'top' ? tr.top - sideOffset
|
|
107
|
+
: vh;
|
|
108
|
+
const availableWidth =
|
|
109
|
+
actualSide === 'right' ? vw - tr.right - sideOffset
|
|
110
|
+
: actualSide === 'left' ? tr.left - sideOffset
|
|
111
|
+
: vw;
|
|
112
|
+
const along = align === 'start' ? '0%' : align === 'end' ? '100%' : '50%';
|
|
113
|
+
const origin =
|
|
114
|
+
actualSide === 'bottom' ? `${along} 0px`
|
|
115
|
+
: actualSide === 'top' ? `${along} 100%`
|
|
116
|
+
: actualSide === 'right' ? `0px ${along}`
|
|
117
|
+
: `100% ${along}`;
|
|
118
|
+
content.style.setProperty(`${vars}-content-available-height`, `${Math.max(0, availableHeight)}px`);
|
|
119
|
+
content.style.setProperty(`${vars}-content-available-width`, `${Math.max(0, availableWidth)}px`);
|
|
120
|
+
content.style.setProperty(`${vars}-content-transform-origin`, origin);
|
|
121
|
+
}
|
|
122
|
+
content.setAttribute('data-side', actualSide);
|
|
123
|
+
content.setAttribute('data-align', align);
|
|
124
|
+
}
|
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
* `side-offset`: number, default 4. Pixels between trigger and content.
|
|
22
22
|
* `align-offset`: number, default 0. Pixels of cross-axis shift.
|
|
23
23
|
*
|
|
24
|
-
* Events:
|
|
25
|
-
*
|
|
24
|
+
* Events:
|
|
25
|
+
* `ui-open-change` on <ui-hover-card>: `{ detail: { open } }` on every open
|
|
26
|
+
* and close, shadcn's `onOpenChange`. The `open` attribute is reflected too.
|
|
26
27
|
*
|
|
27
28
|
* Programmatic API on <ui-hover-card>: `.show()` · `.hide()`.
|
|
28
29
|
*
|
|
@@ -70,16 +71,18 @@
|
|
|
70
71
|
* ```
|
|
71
72
|
*/
|
|
72
73
|
import { WebComponent, html, prop } from '@webjsdev/core';
|
|
73
|
-
import { ensureId } from '../lib/utils.ts';
|
|
74
|
+
import { cn, ensureId, takeAuthoredClass } from '../lib/utils.ts';
|
|
74
75
|
import { onBeforeCache } from '../lib/dom.ts';
|
|
75
|
-
import { positionFloating
|
|
76
|
+
import { positionFloating } from './floating.ts';
|
|
77
|
+
import type { PopoverSide, PopoverAlign } from './popover.ts';
|
|
76
78
|
|
|
77
79
|
// `fixed m-0` opts out of the UA `[popover]` auto-centering margin so
|
|
78
80
|
// JS-computed top/left from positionFloating lands correctly. shadcn's
|
|
79
|
-
// visual layer sits on top.
|
|
80
|
-
//
|
|
81
|
+
// visual layer sits on top. `not-open:hidden` hides a closed panel, which
|
|
82
|
+
// the UA `[popover]:not(:popover-open)` rule cannot do once any author
|
|
83
|
+
// `display` applies (see popoverContentClass).
|
|
81
84
|
export const hoverCardContentClass = (): string =>
|
|
82
|
-
'
|
|
85
|
+
'cn-hover-card-content z-50 origin-(--radix-hover-card-content-transform-origin) outline-hidden not-open:hidden';
|
|
83
86
|
|
|
84
87
|
// --------------------------------------------------------------------------
|
|
85
88
|
// <ui-hover-card>
|
|
@@ -314,6 +317,7 @@ export class UiHoverCard extends WebComponent({
|
|
|
314
317
|
// engines with no Popover API: Escape has to work regardless of that.
|
|
315
318
|
if (this.open) this._bindEscape();
|
|
316
319
|
else this._unbindEscape();
|
|
320
|
+
this.dispatchEvent(new CustomEvent('ui-open-change', { detail: { open: this.open }, bubbles: true }));
|
|
317
321
|
// Wait one microtask for <ui-hover-card-content>'s inner [popover]
|
|
318
322
|
// element to commit; we drive its showPopover() / hidePopover() and
|
|
319
323
|
// refresh the trigger's aria-expanded.
|
|
@@ -352,6 +356,7 @@ export class UiHoverCard extends WebComponent({
|
|
|
352
356
|
align: (contentHost.getAttribute('align') ?? 'center') as PopoverAlign,
|
|
353
357
|
sideOffset: Number(contentHost.getAttribute('side-offset') ?? 4),
|
|
354
358
|
alignOffset: Number(contentHost.getAttribute('align-offset') ?? 0),
|
|
359
|
+
radix: this.localName.slice(3),
|
|
355
360
|
});
|
|
356
361
|
}
|
|
357
362
|
}
|
|
@@ -419,12 +424,18 @@ UiHoverCardTrigger.register('ui-hover-card-trigger');
|
|
|
419
424
|
// --------------------------------------------------------------------------
|
|
420
425
|
|
|
421
426
|
export class UiHoverCardContent extends WebComponent {
|
|
427
|
+
_authored: string | null = null;
|
|
428
|
+
|
|
429
|
+
// shadcn's className on HoverCardContent lands on the card panel (a `w-80`,
|
|
430
|
+
// say), so the class written on this host moves there, read once at first
|
|
431
|
+
// render.
|
|
422
432
|
render() {
|
|
433
|
+
this._authored = takeAuthoredClass(this, null);
|
|
423
434
|
return html`<div
|
|
424
435
|
data-slot="hover-card-content"
|
|
425
436
|
role="dialog"
|
|
426
437
|
popover="manual"
|
|
427
|
-
class=${hoverCardContentClass()}
|
|
438
|
+
class=${cn(hoverCardContentClass(), this._authored)}
|
|
428
439
|
@mouseenter=${this._onEnter}
|
|
429
440
|
@mouseleave=${this._onLeave}
|
|
430
441
|
@focusin=${this._onEnter}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input group: an input or textarea with addons inside its border (an icon, a
|
|
3
|
+
* prefix such as "https://", a button, a counter), sharing one focus ring.
|
|
4
|
+
* Tier-1 class helper; compose with a real `<input>` or `<textarea>`.
|
|
5
|
+
*
|
|
6
|
+
* shadcn parity:
|
|
7
|
+
* InputGroup → inputGroupClass()
|
|
8
|
+
* InputGroupAddon (align: inline-start | inline-end | block-start | block-end)
|
|
9
|
+
* → inputGroupAddonClass({ align }), alias inputGroupAddonVariants,
|
|
10
|
+
* plus the same `data-align` on the addon (the styles pad the
|
|
11
|
+
* control beside it by it)
|
|
12
|
+
* InputGroupButton (size) → inputGroupButtonClass({ size }) with buttonClass({ variant })
|
|
13
|
+
* InputGroupText → inputGroupTextClass()
|
|
14
|
+
* InputGroupInput / InputGroupTextarea
|
|
15
|
+
* → inputGroupInputClass() / inputGroupTextareaClass()
|
|
16
|
+
*
|
|
17
|
+
* The group draws the border and the focus ring, so the control inside drops
|
|
18
|
+
* its own. Clicking an addon focuses the control through a `<label for>`, with
|
|
19
|
+
* no script: make the addon a `<label>` pointing at the control's id.
|
|
20
|
+
*
|
|
21
|
+
* A11y (required for accessible output): the control still needs its own
|
|
22
|
+
* accessible name, from a visible `<label for>` outside the group or an
|
|
23
|
+
* `aria-label` on the control; an addon's text is not its name. A decorative
|
|
24
|
+
* icon addon takes `aria-hidden="true"`. An addon button is a real
|
|
25
|
+
* `<button type="button">` with its own name.
|
|
26
|
+
*
|
|
27
|
+
* Design tokens used: --input, --ring, --muted-foreground, --destructive.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```html
|
|
31
|
+
* <div class=${inputGroupClass()} data-slot="input-group" role="group">
|
|
32
|
+
* <label class=${inputGroupAddonClass()} data-slot="input-group-addon" data-align="inline-start" for="site">https://</label>
|
|
33
|
+
* <input class=${inputGroupInputClass()} data-slot="input-group-control" id="site" name="site" aria-label="Website">
|
|
34
|
+
* </div>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
import { cn } from '../lib/utils.ts';
|
|
38
|
+
import { inputClass } from './input.ts';
|
|
39
|
+
import { textareaClass } from './textarea.ts';
|
|
40
|
+
import { buttonClass, type ButtonVariant } from './button.ts';
|
|
41
|
+
|
|
42
|
+
/** Set `data-slot="input-group"` on the element. */
|
|
43
|
+
export function inputGroupClass(): string {
|
|
44
|
+
return 'group/input-group cn-input-group relative flex w-full min-w-0 items-center outline-none has-[>textarea]:h-auto';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const INPUT_GROUP_ADDON_BASE =
|
|
48
|
+
'cn-input-group-addon flex cursor-text items-center justify-center select-none';
|
|
49
|
+
|
|
50
|
+
const INPUT_GROUP_ADDON_ALIGNS = {
|
|
51
|
+
'inline-start': 'cn-input-group-addon-align-inline-start order-first',
|
|
52
|
+
'inline-end': 'cn-input-group-addon-align-inline-end order-last',
|
|
53
|
+
'block-start': 'cn-input-group-addon-align-block-start order-first w-full justify-start',
|
|
54
|
+
'block-end': 'cn-input-group-addon-align-block-end order-last w-full justify-start',
|
|
55
|
+
} as const;
|
|
56
|
+
|
|
57
|
+
/** The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match. */
|
|
58
|
+
export function inputGroupAddonClass(opts: { align?: keyof typeof INPUT_GROUP_ADDON_ALIGNS } = {}): string {
|
|
59
|
+
return cn(INPUT_GROUP_ADDON_BASE, INPUT_GROUP_ADDON_ALIGNS[opts.align ?? 'inline-start']);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* shadcn's name for {@link inputGroupAddonClass}, so shadcn code ports verbatim. Like cva,
|
|
64
|
+
* it merges a `className` into the result.
|
|
65
|
+
*/
|
|
66
|
+
export function inputGroupAddonVariants(opts: { align?: keyof typeof INPUT_GROUP_ADDON_ALIGNS } & { className?: string } = {}): string {
|
|
67
|
+
return cn(inputGroupAddonClass(opts), opts.className);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const INPUT_GROUP_BUTTON_BASE =
|
|
71
|
+
'cn-input-group-button flex items-center shadow-none';
|
|
72
|
+
|
|
73
|
+
const INPUT_GROUP_BUTTON_SIZES = {
|
|
74
|
+
xs: 'cn-input-group-button-size-xs',
|
|
75
|
+
sm: 'cn-input-group-button-size-sm',
|
|
76
|
+
'icon-xs': 'cn-input-group-button-size-icon-xs',
|
|
77
|
+
'icon-sm': 'cn-input-group-button-size-icon-sm',
|
|
78
|
+
} as const;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match.
|
|
82
|
+
*
|
|
83
|
+
* shadcn's InputGroupButton IS its Button (`variant` defaulting to ghost)
|
|
84
|
+
* with these classes on top, so the button's own classes come first and the
|
|
85
|
+
* group's size wins a conflict.
|
|
86
|
+
*/
|
|
87
|
+
export function inputGroupButtonClass(opts: { size?: keyof typeof INPUT_GROUP_BUTTON_SIZES; variant?: ButtonVariant } = {}): string {
|
|
88
|
+
return cn(buttonClass({ variant: opts.variant ?? 'ghost' }), INPUT_GROUP_BUTTON_BASE, INPUT_GROUP_BUTTON_SIZES[opts.size ?? 'xs']);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* shadcn's name for {@link inputGroupButtonClass}, so shadcn code ports verbatim. Like cva,
|
|
93
|
+
* it merges a `className` into the result.
|
|
94
|
+
*/
|
|
95
|
+
export function inputGroupButtonVariants(opts: { size?: keyof typeof INPUT_GROUP_BUTTON_SIZES; variant?: ButtonVariant } & { className?: string } = {}): string {
|
|
96
|
+
return cn(inputGroupButtonClass(opts), opts.className);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** A part with no `data-slot` of its own. */
|
|
100
|
+
export function inputGroupTextClass(): string {
|
|
101
|
+
return 'cn-input-group-text flex items-center [&_svg]:pointer-events-none';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Set `data-slot="input-group-control"` on the element. shadcn's
|
|
106
|
+
* InputGroupInput is its Input with these classes on top, so the input's own
|
|
107
|
+
* base (its `outline-none` and focus treatment included) comes first and the
|
|
108
|
+
* group's resets win a conflict. Without it a focused control shows the
|
|
109
|
+
* browser's own outline inside the group's ring.
|
|
110
|
+
*/
|
|
111
|
+
export function inputGroupInputClass(): string {
|
|
112
|
+
return cn(inputClass(), 'cn-input-group-input flex-1');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Set `data-slot="input-group-control"` on the element. The Textarea's classes, then the group's, as shadcn composes it. */
|
|
116
|
+
export function inputGroupTextareaClass(): string {
|
|
117
|
+
return cn(textareaClass(), 'cn-input-group-textarea flex-1 resize-none');
|
|
118
|
+
}
|