@webjsdev/ui 0.3.17 → 0.5.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 +67 -8
- 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 +644 -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 +8 -8
- package/packages/registry/components/field.ts +20 -18
- 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 +7 -4
- 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/dom.ts +3 -4
- 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 +52 -8
- package/packages/registry/registry.json +4056 -72
- 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 +266 -14
- package/src/commands/diff.js +34 -20
- package/src/commands/info.js +7 -0
- package/src/commands/init.js +127 -10
- package/src/commands/list.js +43 -11
- package/src/commands/view.js +33 -5
- package/src/lint/rules/no-restyle.js +1 -1
- package/src/registry/extract.js +194 -5
- 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,564 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation menu: a site's top navigation, where some entries are links and
|
|
3
|
+
* some open a panel of links. Tier-2. It is a set of disclosures inside a
|
|
4
|
+
* `<nav>`, as in Radix, NOT an ARIA menu: the panels hold ordinary links, Tab
|
|
5
|
+
* walks into an open panel, and screen readers read it as navigation.
|
|
6
|
+
*
|
|
7
|
+
* shadcn parity:
|
|
8
|
+
* NavigationMenu → <ui-navigation-menu viewport delay-duration skip-delay-duration>
|
|
9
|
+
* NavigationMenuList → <ui-navigation-menu-list>
|
|
10
|
+
* NavigationMenuItem → <ui-navigation-menu-item value>
|
|
11
|
+
* NavigationMenuTrigger → <ui-navigation-menu-trigger>Getting started</ui-navigation-menu-trigger>
|
|
12
|
+
* NavigationMenuContent → <ui-navigation-menu-content>
|
|
13
|
+
* NavigationMenuLink → <ui-navigation-menu-link href active> (renders the <a>),
|
|
14
|
+
* or navigationMenuLinkClass() on your own <a data-slot="navigation-menu-link">
|
|
15
|
+
* NavigationMenuIndicator → <ui-navigation-menu-indicator>
|
|
16
|
+
* NavigationMenuViewport → rendered by the root unless viewport="false"
|
|
17
|
+
* navigationMenuTriggerStyle → the same helper as navigationMenuTriggerClass, for a
|
|
18
|
+
* link that sits in the bar beside the triggers
|
|
19
|
+
*
|
|
20
|
+
* The viewport: by default the open panel shows in one frame under the whole
|
|
21
|
+
* list, which the root renders and sizes to the panel through the
|
|
22
|
+
* `--radix-navigation-menu-viewport-width` / `-height` variables shadcn's
|
|
23
|
+
* classes read. Radix moves the panel into that frame; this element keeps it
|
|
24
|
+
* where it is and places it over the frame, so a slotted panel never changes
|
|
25
|
+
* parents. The frame keeps its size between panels rather than animating it.
|
|
26
|
+
* With `viewport="false"` each panel opens under its own trigger instead.
|
|
27
|
+
*
|
|
28
|
+
* Opening: pointing at a trigger opens its panel after `delay-duration`
|
|
29
|
+
* (200ms), at once while another panel is open or within
|
|
30
|
+
* `skip-delay-duration` (300ms) of one closing. Leaving the trigger and the
|
|
31
|
+
* panel closes it after a short grace. A click toggles it. Escape, a click
|
|
32
|
+
* outside, focus leaving the nav, and following a link in the panel close it.
|
|
33
|
+
*
|
|
34
|
+
* Keyboard: Tab walks the bar and into an open panel. ArrowLeft / ArrowRight
|
|
35
|
+
* (and Home / End) move between the bar's triggers and links, ArrowDown on a
|
|
36
|
+
* trigger opens its panel on the first link, ArrowDown / ArrowUp move within
|
|
37
|
+
* a panel, and Escape returns to the trigger.
|
|
38
|
+
*
|
|
39
|
+
* A11y (handled by the element, plus your part): the root is a `<nav>` named
|
|
40
|
+
* "Main" unless you name it (`aria-label` on `<ui-navigation-menu>`), the list
|
|
41
|
+
* and items are a real `<ul>` / `<li>`, each trigger is a button with
|
|
42
|
+
* `aria-expanded` and `aria-controls`, each panel is named by its trigger, and
|
|
43
|
+
* `<ui-navigation-menu-link active>` marks the current page with
|
|
44
|
+
* `aria-current="page"`. Your part: link text that reads well out of context,
|
|
45
|
+
* and the `active` flag on the link for the page being shown.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```html
|
|
49
|
+
* <ui-navigation-menu>
|
|
50
|
+
* <ui-navigation-menu-list>
|
|
51
|
+
* <ui-navigation-menu-item>
|
|
52
|
+
* <ui-navigation-menu-trigger>Components</ui-navigation-menu-trigger>
|
|
53
|
+
* <ui-navigation-menu-content>
|
|
54
|
+
* <ul class="grid w-[400px] gap-2">
|
|
55
|
+
* <li><ui-navigation-menu-link href="/ui/dialog">Dialog</ui-navigation-menu-link></li>
|
|
56
|
+
* <li><ui-navigation-menu-link href="/ui/tabs">Tabs</ui-navigation-menu-link></li>
|
|
57
|
+
* </ul>
|
|
58
|
+
* </ui-navigation-menu-content>
|
|
59
|
+
* </ui-navigation-menu-item>
|
|
60
|
+
* <ui-navigation-menu-item>
|
|
61
|
+
* <ui-navigation-menu-link href="/docs" active>Docs</ui-navigation-menu-link>
|
|
62
|
+
* </ui-navigation-menu-item>
|
|
63
|
+
* </ui-navigation-menu-list>
|
|
64
|
+
* </ui-navigation-menu>
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
import { WebComponent, html, prop, signal, nothing } from '@webjsdev/core';
|
|
68
|
+
import { ensureId } from '../lib/utils.ts';
|
|
69
|
+
|
|
70
|
+
/** The root's classes (the element applies them). */
|
|
71
|
+
export const navigationMenuClass = (): string =>
|
|
72
|
+
'cn-navigation-menu group/navigation-menu relative flex max-w-max flex-1 items-center justify-center';
|
|
73
|
+
/** The list's classes (the element applies them). */
|
|
74
|
+
export const navigationMenuListClass = (): string =>
|
|
75
|
+
'cn-navigation-menu-list group flex flex-1 list-none items-center justify-center';
|
|
76
|
+
/** An item's classes (the element applies them). Positioned only without a viewport. */
|
|
77
|
+
export const navigationMenuItemClass = (): string =>
|
|
78
|
+
'cn-navigation-menu-item group-data-[viewport=false]/navigation-menu:relative';
|
|
79
|
+
/** A trigger's classes. Also right for a link that sits in the bar beside the triggers. */
|
|
80
|
+
export const navigationMenuTriggerClass = (): string =>
|
|
81
|
+
'cn-navigation-menu-trigger group/navigation-menu-trigger inline-flex h-9 w-max items-center justify-center outline-none disabled:pointer-events-none';
|
|
82
|
+
/** shadcn's name for {@link navigationMenuTriggerClass}. */
|
|
83
|
+
export function navigationMenuTriggerStyle(opts: { className?: string } = {}): string {
|
|
84
|
+
return opts.className ? `${navigationMenuTriggerClass()} ${opts.className}` : navigationMenuTriggerClass();
|
|
85
|
+
}
|
|
86
|
+
/** The trigger's chevron. */
|
|
87
|
+
export const navigationMenuTriggerIconClass = (): string =>
|
|
88
|
+
'cn-navigation-menu-trigger-icon';
|
|
89
|
+
/** A panel's classes (the element applies them). */
|
|
90
|
+
export const navigationMenuContentClass = (): string =>
|
|
91
|
+
'cn-navigation-menu-content absolute top-full start-0 z-[51] mt-1.5 w-auto **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none group-data-[viewport=false]/navigation-menu:overflow-hidden';
|
|
92
|
+
/** The viewport frame's wrapper (the root renders it). */
|
|
93
|
+
export const navigationMenuViewportWrapperClass = (): string =>
|
|
94
|
+
'cn-navigation-menu-viewport-wrapper absolute top-full start-0 isolate z-50 flex justify-center';
|
|
95
|
+
/** The viewport frame (the root renders it). */
|
|
96
|
+
export const navigationMenuViewportClass = (): string =>
|
|
97
|
+
'cn-navigation-menu-viewport origin-top-center relative mt-1.5 h-(--radix-navigation-menu-viewport-height) w-full overflow-hidden md:w-(--radix-navigation-menu-viewport-width)';
|
|
98
|
+
/** A link's classes, for an `<a data-slot="navigation-menu-link">` of your own. */
|
|
99
|
+
export const navigationMenuLinkClass = (): string =>
|
|
100
|
+
'cn-navigation-menu-link';
|
|
101
|
+
/** The indicator under the open trigger. */
|
|
102
|
+
export const navigationMenuIndicatorClass = (): string =>
|
|
103
|
+
'cn-navigation-menu-indicator absolute top-full z-1 flex h-1.5 items-end justify-center overflow-hidden';
|
|
104
|
+
/** The indicator's arrow. */
|
|
105
|
+
export const navigationMenuIndicatorArrowClass = (): string =>
|
|
106
|
+
'cn-navigation-menu-indicator-arrow relative top-[60%] h-2 w-2 rotate-45';
|
|
107
|
+
|
|
108
|
+
const ROOT = 'ui-navigation-menu';
|
|
109
|
+
const CLOSE_GRACE_MS = 150;
|
|
110
|
+
|
|
111
|
+
// A late part asks for the current state after its first render. Measure on
|
|
112
|
+
// the following microtask, once the newly opened panel has rendered too.
|
|
113
|
+
function announce(el: Element): void {
|
|
114
|
+
queueMicrotask(() => {
|
|
115
|
+
(el.closest(`${ROOT}-item`) as UiNavigationMenuItem | null)?._sync?.();
|
|
116
|
+
queueMicrotask(() => (el.closest(ROOT) as UiNavigationMenu | null)?._layout?.());
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// --------------------------------------------------------------------------
|
|
121
|
+
// <ui-navigation-menu>
|
|
122
|
+
// --------------------------------------------------------------------------
|
|
123
|
+
|
|
124
|
+
export class UiNavigationMenu extends WebComponent({
|
|
125
|
+
// The open item's value, '' when none is open.
|
|
126
|
+
value: prop(String, { reflect: true }),
|
|
127
|
+
// "false" opens each panel under its own trigger instead of in the frame.
|
|
128
|
+
viewport: String,
|
|
129
|
+
delayDuration: prop(Number, { attribute: 'delay-duration' }),
|
|
130
|
+
skipDelayDuration: prop(Number, { attribute: 'skip-delay-duration' }),
|
|
131
|
+
}) {
|
|
132
|
+
_openTimer = 0;
|
|
133
|
+
_closeTimer = 0;
|
|
134
|
+
_skipDelayUntil = 0;
|
|
135
|
+
// The order of the last two open items, for the panel's slide direction.
|
|
136
|
+
_previous = '';
|
|
137
|
+
|
|
138
|
+
constructor() {
|
|
139
|
+
super();
|
|
140
|
+
this.value = '';
|
|
141
|
+
this.viewport = 'true';
|
|
142
|
+
this.delayDuration = 200;
|
|
143
|
+
this.skipDelayDuration = 300;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
get _hasViewport(): boolean {
|
|
147
|
+
return this.viewport !== 'false';
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
render() {
|
|
151
|
+
const open = !!this.value;
|
|
152
|
+
return html`<nav
|
|
153
|
+
data-slot="navigation-menu"
|
|
154
|
+
data-viewport=${this._hasViewport ? 'true' : 'false'}
|
|
155
|
+
data-orientation="horizontal"
|
|
156
|
+
aria-label=${this.getAttribute?.('aria-label') || 'Main'}
|
|
157
|
+
class=${navigationMenuClass()}
|
|
158
|
+
@keydown=${this._onKeyDown}
|
|
159
|
+
@focusout=${this._onFocusOut}
|
|
160
|
+
><slot></slot>${this._hasViewport
|
|
161
|
+
? html`<div class=${navigationMenuViewportWrapperClass()}><div
|
|
162
|
+
data-slot="navigation-menu-viewport"
|
|
163
|
+
data-state=${open ? 'open' : 'closed'}
|
|
164
|
+
?hidden=${!open}
|
|
165
|
+
class=${navigationMenuViewportClass()}
|
|
166
|
+
></div></div>`
|
|
167
|
+
: ''}</nav>`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** The items in this menu, in order. */
|
|
171
|
+
items(): UiNavigationMenuItem[] {
|
|
172
|
+
return Array.from(this.querySelectorAll<UiNavigationMenuItem>(`${ROOT}-item`)).filter(
|
|
173
|
+
(i) => i.closest(ROOT) === this,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Open the item whose value is `value`, or close every panel with ''. */
|
|
178
|
+
setValue(value: string): void {
|
|
179
|
+
clearTimeout(this._openTimer);
|
|
180
|
+
clearTimeout(this._closeTimer);
|
|
181
|
+
if (value === this.value) return;
|
|
182
|
+
if (!value && this.value) this._skipDelayUntil = Date.now() + this.skipDelayDuration;
|
|
183
|
+
this._previous = this.value;
|
|
184
|
+
this.value = value;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Pointer intent. A touch "hover" is a tap, which the click handles.
|
|
188
|
+
_pointerOpen(item: UiNavigationMenuItem): void {
|
|
189
|
+
clearTimeout(this._closeTimer);
|
|
190
|
+
clearTimeout(this._openTimer);
|
|
191
|
+
if (this.value === item.itemValue) return;
|
|
192
|
+
const now = !!this.value || Date.now() < this._skipDelayUntil;
|
|
193
|
+
if (now) this.setValue(item.itemValue);
|
|
194
|
+
else this._openTimer = window.setTimeout(() => this.setValue(item.itemValue), this.delayDuration);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
_pointerLeave(): void {
|
|
198
|
+
clearTimeout(this._openTimer);
|
|
199
|
+
clearTimeout(this._closeTimer);
|
|
200
|
+
if (!this.value) return;
|
|
201
|
+
this._closeTimer = window.setTimeout(() => this.setValue(''), CLOSE_GRACE_MS);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
_cancelClose(): void {
|
|
205
|
+
clearTimeout(this._closeTimer);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
updated(changedProperties: Map<string, unknown>): void {
|
|
209
|
+
super.updated?.(changedProperties);
|
|
210
|
+
if (!changedProperties.has('value')) return;
|
|
211
|
+
this.items().forEach((item) => item._sync());
|
|
212
|
+
queueMicrotask(() => this._layout());
|
|
213
|
+
if (this.value) document.addEventListener('pointerdown', this._onDocPointerDown, true);
|
|
214
|
+
else document.removeEventListener('pointerdown', this._onDocPointerDown, true);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
disconnectedCallback(): void {
|
|
218
|
+
clearTimeout(this._openTimer);
|
|
219
|
+
clearTimeout(this._closeTimer);
|
|
220
|
+
document.removeEventListener('pointerdown', this._onDocPointerDown, true);
|
|
221
|
+
window.removeEventListener('resize', this._onResize);
|
|
222
|
+
super.disconnectedCallback?.();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
connectedCallback(): void {
|
|
226
|
+
super.connectedCallback?.();
|
|
227
|
+
window.addEventListener('resize', this._onResize);
|
|
228
|
+
// Items are slotted after the first render, so their ARIA is wired once
|
|
229
|
+
// they are in place.
|
|
230
|
+
if (typeof requestAnimationFrame === 'function') {
|
|
231
|
+
requestAnimationFrame(() => this.items().forEach((item) => item._sync()));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
_onResize = (): void => this._layout();
|
|
236
|
+
|
|
237
|
+
// Size the frame to the open panel and put the indicator under its trigger.
|
|
238
|
+
_layout(): void {
|
|
239
|
+
const item = this.items().find((i) => i.itemValue === this.value) ?? null;
|
|
240
|
+
const panel = item?._panel() ?? null;
|
|
241
|
+
const frame = this.querySelector<HTMLElement>('[data-slot="navigation-menu-viewport"]');
|
|
242
|
+
if (frame && panel) {
|
|
243
|
+
frame.style.setProperty('--radix-navigation-menu-viewport-width', `${panel.offsetWidth}px`);
|
|
244
|
+
frame.style.setProperty('--radix-navigation-menu-viewport-height', `${panel.offsetHeight}px`);
|
|
245
|
+
}
|
|
246
|
+
this.querySelectorAll<UiNavigationMenuIndicator>(`${ROOT}-indicator`).forEach((ind) =>
|
|
247
|
+
ind._place(item?._button() ?? null),
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
_onDocPointerDown = (e: Event): void => {
|
|
252
|
+
if (e.composedPath().includes(this)) return;
|
|
253
|
+
this.setValue('');
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
_onFocusOut = (e: FocusEvent): void => {
|
|
257
|
+
const next = e.relatedTarget as Node | null;
|
|
258
|
+
if (next && this.contains(next)) return;
|
|
259
|
+
// Focus left the nav (or went nowhere a click put it); a pointer close is
|
|
260
|
+
// handled by the pointerdown listener, so only a keyboard exit closes here.
|
|
261
|
+
if (next) this.setValue('');
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
// The bar's own focusables, in order: triggers and the links that sit in
|
|
265
|
+
// the list, never the links inside a panel.
|
|
266
|
+
_barFocusables(): HTMLElement[] {
|
|
267
|
+
return Array.from(
|
|
268
|
+
this.querySelectorAll<HTMLElement>(
|
|
269
|
+
'[data-slot="navigation-menu-trigger"], a[data-slot="navigation-menu-link"]',
|
|
270
|
+
),
|
|
271
|
+
).filter((el) => el.closest(ROOT) === this && !el.closest('[data-slot="navigation-menu-content"]'));
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
_onKeyDown = (e: KeyboardEvent): void => {
|
|
275
|
+
const target = e.target as HTMLElement;
|
|
276
|
+
const panel = target.closest<HTMLElement>('[data-slot="navigation-menu-content"]');
|
|
277
|
+
if (e.key === 'Escape' && this.value) {
|
|
278
|
+
e.preventDefault();
|
|
279
|
+
const item = this.items().find((i) => i.itemValue === this.value);
|
|
280
|
+
item?._button()?.focus();
|
|
281
|
+
this.setValue('');
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (panel) {
|
|
285
|
+
if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return;
|
|
286
|
+
const links = Array.from(panel.querySelectorAll<HTMLElement>('a[href], button:not([disabled])'));
|
|
287
|
+
const i = links.indexOf(target.closest('a[href], button') as HTMLElement);
|
|
288
|
+
if (i < 0 || !links.length) return;
|
|
289
|
+
e.preventDefault();
|
|
290
|
+
links[(i + (e.key === 'ArrowDown' ? 1 : -1) + links.length) % links.length].focus();
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const bar = this._barFocusables();
|
|
294
|
+
const i = bar.indexOf(target);
|
|
295
|
+
if (i < 0) return;
|
|
296
|
+
const go = (j: number) => {
|
|
297
|
+
e.preventDefault();
|
|
298
|
+
bar[(j + bar.length) % bar.length].focus();
|
|
299
|
+
};
|
|
300
|
+
if (e.key === 'ArrowRight') go(i + 1);
|
|
301
|
+
else if (e.key === 'ArrowLeft') go(i - 1);
|
|
302
|
+
else if (e.key === 'Home') go(0);
|
|
303
|
+
else if (e.key === 'End') go(bar.length - 1);
|
|
304
|
+
else if (e.key === 'ArrowDown' && target.matches('[data-slot="navigation-menu-trigger"]')) {
|
|
305
|
+
const item = target.closest(`${ROOT}-item`) as UiNavigationMenuItem | null;
|
|
306
|
+
if (!item) return;
|
|
307
|
+
e.preventDefault();
|
|
308
|
+
this.setValue(item.itemValue);
|
|
309
|
+
// The panel is shown on the next render.
|
|
310
|
+
requestAnimationFrame(() => item._panel()?.querySelector<HTMLElement>('a[href], button')?.focus());
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
UiNavigationMenu.register('ui-navigation-menu');
|
|
315
|
+
|
|
316
|
+
// --------------------------------------------------------------------------
|
|
317
|
+
// <ui-navigation-menu-list>
|
|
318
|
+
// --------------------------------------------------------------------------
|
|
319
|
+
|
|
320
|
+
export class UiNavigationMenuList extends WebComponent {
|
|
321
|
+
render() {
|
|
322
|
+
return html`<ul
|
|
323
|
+
data-slot="navigation-menu-list"
|
|
324
|
+
data-orientation="horizontal"
|
|
325
|
+
class=${navigationMenuListClass()}
|
|
326
|
+
><slot></slot></ul>`;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
UiNavigationMenuList.register('ui-navigation-menu-list');
|
|
330
|
+
|
|
331
|
+
// --------------------------------------------------------------------------
|
|
332
|
+
// <ui-navigation-menu-item>
|
|
333
|
+
// --------------------------------------------------------------------------
|
|
334
|
+
|
|
335
|
+
export class UiNavigationMenuItem extends WebComponent({
|
|
336
|
+
value: String,
|
|
337
|
+
}) {
|
|
338
|
+
constructor() {
|
|
339
|
+
super();
|
|
340
|
+
this.value = '';
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
render() {
|
|
344
|
+
return html`<li data-slot="navigation-menu-item" class=${navigationMenuItemClass()}><slot></slot></li>`;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
_root(): UiNavigationMenu | null {
|
|
348
|
+
return this.closest(ROOT) as UiNavigationMenu | null;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/** The value that opens this item: its `value`, else its position. */
|
|
352
|
+
get itemValue(): string {
|
|
353
|
+
if (this.value) return this.value;
|
|
354
|
+
const i = this._root()?.items().indexOf(this) ?? -1;
|
|
355
|
+
return `item-${i + 1}`;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
get isOpen(): boolean {
|
|
359
|
+
return !!this._root()?.value && this._root()?.value === this.itemValue;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
_button(): HTMLElement | null {
|
|
363
|
+
return this.querySelector<HTMLElement>('[data-slot="navigation-menu-trigger"]');
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
_panel(): HTMLElement | null {
|
|
367
|
+
return this.querySelector<HTMLElement>('[data-slot="navigation-menu-content"]');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Push open state into the trigger and panel, and link them both ways.
|
|
371
|
+
_sync(): void {
|
|
372
|
+
const root = this._root();
|
|
373
|
+
this.querySelectorAll<UiNavigationMenuTrigger | UiNavigationMenuContent>(
|
|
374
|
+
`${ROOT}-trigger, ${ROOT}-content`,
|
|
375
|
+
).forEach((part) => { part.open?.set(this.isOpen); });
|
|
376
|
+
const button = this._button();
|
|
377
|
+
const panel = this._panel();
|
|
378
|
+
if (button && panel) {
|
|
379
|
+
button.setAttribute('aria-controls', ensureId(panel, 'ui-navigation-menu-content'));
|
|
380
|
+
panel.setAttribute('aria-labelledby', ensureId(button, 'ui-navigation-menu-trigger'));
|
|
381
|
+
}
|
|
382
|
+
if (panel && root && this.isOpen) {
|
|
383
|
+
const order = root.items().map((i) => i.itemValue);
|
|
384
|
+
const from = order.indexOf(root._previous);
|
|
385
|
+
const to = order.indexOf(this.itemValue);
|
|
386
|
+
if (from < 0) panel.removeAttribute('data-motion');
|
|
387
|
+
else panel.setAttribute('data-motion', to > from ? 'from-end' : 'from-start');
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
UiNavigationMenuItem.register('ui-navigation-menu-item');
|
|
392
|
+
|
|
393
|
+
// --------------------------------------------------------------------------
|
|
394
|
+
// <ui-navigation-menu-trigger>
|
|
395
|
+
// --------------------------------------------------------------------------
|
|
396
|
+
|
|
397
|
+
export class UiNavigationMenuTrigger extends WebComponent {
|
|
398
|
+
readonly open = signal(false);
|
|
399
|
+
// After a click closes the panel, the pointer still on the trigger must not
|
|
400
|
+
// reopen it until it leaves.
|
|
401
|
+
_clickClosed = false;
|
|
402
|
+
|
|
403
|
+
constructor() {
|
|
404
|
+
super();
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
connectedCallback(): void {
|
|
408
|
+
super.connectedCallback?.();
|
|
409
|
+
announce(this);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
render() {
|
|
413
|
+
return html`<button
|
|
414
|
+
type="button"
|
|
415
|
+
data-slot="navigation-menu-trigger"
|
|
416
|
+
data-state=${this.open.get() ? 'open' : 'closed'}
|
|
417
|
+
aria-expanded=${this.open.get() ? 'true' : 'false'}
|
|
418
|
+
class=${navigationMenuTriggerClass()}
|
|
419
|
+
@click=${this._onClick}
|
|
420
|
+
@pointerenter=${this._onPointerEnter}
|
|
421
|
+
@pointerleave=${this._onPointerLeave}
|
|
422
|
+
><slot></slot> <svg
|
|
423
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
424
|
+
viewBox="0 0 24 24"
|
|
425
|
+
fill="none"
|
|
426
|
+
stroke="currentColor"
|
|
427
|
+
stroke-width="2"
|
|
428
|
+
stroke-linecap="round"
|
|
429
|
+
stroke-linejoin="round"
|
|
430
|
+
aria-hidden="true"
|
|
431
|
+
class=${navigationMenuTriggerIconClass()}
|
|
432
|
+
><path d="m6 9 6 6 6-6"></path></svg></button>`;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
_item(): UiNavigationMenuItem | null {
|
|
436
|
+
return this.closest(`${ROOT}-item`) as UiNavigationMenuItem | null;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
_onClick = (): void => {
|
|
440
|
+
const item = this._item();
|
|
441
|
+
const root = item?._root();
|
|
442
|
+
if (!item || !root) return;
|
|
443
|
+
if (item.isOpen) {
|
|
444
|
+
this._clickClosed = true;
|
|
445
|
+
root.setValue('');
|
|
446
|
+
} else {
|
|
447
|
+
root.setValue(item.itemValue);
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
_onPointerEnter = (e: PointerEvent): void => {
|
|
452
|
+
if (e.pointerType === 'touch' || this._clickClosed) return;
|
|
453
|
+
const item = this._item();
|
|
454
|
+
if (item) item._root()?._pointerOpen(item);
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
_onPointerLeave = (e: PointerEvent): void => {
|
|
458
|
+
this._clickClosed = false;
|
|
459
|
+
if (e.pointerType === 'touch') return;
|
|
460
|
+
this._item()?._root()?._pointerLeave();
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
UiNavigationMenuTrigger.register('ui-navigation-menu-trigger');
|
|
464
|
+
|
|
465
|
+
// --------------------------------------------------------------------------
|
|
466
|
+
// <ui-navigation-menu-content>
|
|
467
|
+
// --------------------------------------------------------------------------
|
|
468
|
+
|
|
469
|
+
export class UiNavigationMenuContent extends WebComponent {
|
|
470
|
+
readonly open = signal(false);
|
|
471
|
+
constructor() {
|
|
472
|
+
super();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
connectedCallback(): void {
|
|
476
|
+
super.connectedCallback?.();
|
|
477
|
+
announce(this);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
render() {
|
|
481
|
+
return html`<div
|
|
482
|
+
data-slot="navigation-menu-content"
|
|
483
|
+
data-state=${this.open.get() ? 'open' : 'closed'}
|
|
484
|
+
?hidden=${!this.open.get()}
|
|
485
|
+
class=${navigationMenuContentClass()}
|
|
486
|
+
@pointerenter=${this._onPointerEnter}
|
|
487
|
+
@pointerleave=${this._onPointerLeave}
|
|
488
|
+
@click=${this._onClick}
|
|
489
|
+
><slot></slot></div>`;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
_root(): UiNavigationMenu | null {
|
|
493
|
+
return this.closest(ROOT) as UiNavigationMenu | null;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
_onPointerEnter = (e: PointerEvent): void => {
|
|
497
|
+
if (e.pointerType !== 'touch') this._root()?._cancelClose();
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
_onPointerLeave = (e: PointerEvent): void => {
|
|
501
|
+
if (e.pointerType !== 'touch') this._root()?._pointerLeave();
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
// Following a link in the panel closes it, as Radix does on select.
|
|
505
|
+
_onClick = (e: Event): void => {
|
|
506
|
+
if ((e.target as Element).closest('a[href]')) this._root()?.setValue('');
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
UiNavigationMenuContent.register('ui-navigation-menu-content');
|
|
510
|
+
|
|
511
|
+
// --------------------------------------------------------------------------
|
|
512
|
+
// <ui-navigation-menu-link>
|
|
513
|
+
// --------------------------------------------------------------------------
|
|
514
|
+
|
|
515
|
+
export class UiNavigationMenuLink extends WebComponent({
|
|
516
|
+
href: String,
|
|
517
|
+
active: Boolean,
|
|
518
|
+
}) {
|
|
519
|
+
constructor() {
|
|
520
|
+
super();
|
|
521
|
+
this.href = '';
|
|
522
|
+
this.active = false;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
render() {
|
|
526
|
+
return html`<a
|
|
527
|
+
data-slot="navigation-menu-link"
|
|
528
|
+
href=${this.href || nothing}
|
|
529
|
+
data-active=${this.active ? 'true' : nothing}
|
|
530
|
+
aria-current=${this.active ? 'page' : nothing}
|
|
531
|
+
class=${navigationMenuLinkClass()}
|
|
532
|
+
><slot></slot></a>`;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
UiNavigationMenuLink.register('ui-navigation-menu-link');
|
|
536
|
+
|
|
537
|
+
// --------------------------------------------------------------------------
|
|
538
|
+
// <ui-navigation-menu-indicator>
|
|
539
|
+
// --------------------------------------------------------------------------
|
|
540
|
+
|
|
541
|
+
export class UiNavigationMenuIndicator extends WebComponent {
|
|
542
|
+
render() {
|
|
543
|
+
return html`<div
|
|
544
|
+
data-slot="navigation-menu-indicator"
|
|
545
|
+
data-state="hidden"
|
|
546
|
+
aria-hidden="true"
|
|
547
|
+
class=${navigationMenuIndicatorClass()}
|
|
548
|
+
><div class=${navigationMenuIndicatorArrowClass()}></div></div>`;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// Sit under the open trigger, or hide.
|
|
552
|
+
_place(button: HTMLElement | null): void {
|
|
553
|
+
const el = this.querySelector<HTMLElement>('[data-slot="navigation-menu-indicator"]');
|
|
554
|
+
const nav = this.closest(ROOT)?.querySelector<HTMLElement>('[data-slot="navigation-menu"]');
|
|
555
|
+
if (!el) return;
|
|
556
|
+
el.setAttribute('data-state', button ? 'visible' : 'hidden');
|
|
557
|
+
if (!button || !nav) return;
|
|
558
|
+
const b = button.getBoundingClientRect();
|
|
559
|
+
const n = nav.getBoundingClientRect();
|
|
560
|
+
el.style.left = `${b.left - n.left}px`;
|
|
561
|
+
el.style.width = `${b.width}px`;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
UiNavigationMenuIndicator.register('ui-navigation-menu-indicator');
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
import { cn } from '../lib/utils.ts';
|
|
38
38
|
import { buttonClass, type ButtonSize } from './button.ts';
|
|
39
39
|
|
|
40
|
-
export const paginationClass = (): string => 'mx-auto flex w-full justify-center';
|
|
40
|
+
export const paginationClass = (): string => 'cn-pagination mx-auto flex w-full justify-center';
|
|
41
41
|
|
|
42
|
-
export const paginationContentClass = (): string => '
|
|
42
|
+
export const paginationContentClass = (): string => 'cn-pagination-content flex items-center';
|
|
43
43
|
|
|
44
44
|
export function paginationLinkClass(opts: { isActive?: boolean; size?: ButtonSize } = {}): string {
|
|
45
45
|
return cn(buttonClass({ variant: opts.isActive ? 'outline' : 'ghost', size: opts.size ?? 'icon' }));
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export const paginationPreviousClass = (): string =>
|
|
49
|
-
cn(buttonClass({ variant: 'ghost', size: 'default' }), 'gap-1 px-2.5 sm:
|
|
49
|
+
cn(buttonClass({ variant: 'ghost', size: 'default' }), 'gap-1 px-2.5 sm:ps-2.5');
|
|
50
50
|
|
|
51
51
|
export const paginationNextClass = (): string =>
|
|
52
|
-
cn(buttonClass({ variant: 'ghost', size: 'default' }), 'gap-1 px-2.5 sm:
|
|
52
|
+
cn(buttonClass({ variant: 'ghost', size: 'default' }), 'gap-1 px-2.5 sm:pe-2.5');
|
|
53
53
|
|
|
54
|
-
export const paginationEllipsisClass = (): string => 'flex
|
|
54
|
+
export const paginationEllipsisClass = (): string => 'cn-pagination-ellipsis flex items-center justify-center';
|