@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,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input OTP: a one-time code typed into a row of boxes. Tier-2. It ENHANCES
|
|
3
|
+
* one real `<input>` (D13): you author the input, so without JavaScript the
|
|
4
|
+
* page shows an ordinary text field that the form submits, autofills from an
|
|
5
|
+
* SMS (`autocomplete="one-time-code"`) and pastes into. With JavaScript the
|
|
6
|
+
* element lays that same input, transparent, over shadcn's slots and draws
|
|
7
|
+
* each character in its box, so typing, pasting, autofill and the mobile
|
|
8
|
+
* keyboard all still go to the real input.
|
|
9
|
+
*
|
|
10
|
+
* shadcn parity:
|
|
11
|
+
* InputOTP maxLength → <ui-input-otp> around <input maxlength="6" ...>
|
|
12
|
+
* pattern → the input's `pattern` (a keystroke that would
|
|
13
|
+
* make the value stop matching is refused)
|
|
14
|
+
* InputOTPGroup → <ui-input-otp-group>
|
|
15
|
+
* InputOTPSlot index → <ui-input-otp-slot index="0">
|
|
16
|
+
* InputOTPSeparator → <ui-input-otp-separator>
|
|
17
|
+
* onChange → `ui-value-change` ({ detail: { value } }); the input fires `input`
|
|
18
|
+
* onComplete → `ui-complete` ({ detail: { value } }) once every slot is filled
|
|
19
|
+
*
|
|
20
|
+
* A11y (handled by the element, plus your part): the real input is the only
|
|
21
|
+
* thing assistive technology meets, so it keeps its own name, value and
|
|
22
|
+
* focus. The slots, group and separator are drawn decoration, hidden from the
|
|
23
|
+
* accessibility tree. An `aria-invalid` on the input reaches the slots for
|
|
24
|
+
* the error styling. Your part: a `<label for>` (or `aria-label`) on the input,
|
|
25
|
+
* and `inputmode="numeric"` for a numeric code so phones show the number pad.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```html
|
|
29
|
+
* <label for="otp" class=${labelClass()}>One-time code</label>
|
|
30
|
+
* <ui-input-otp>
|
|
31
|
+
* <input id="otp" name="otp" class=${inputClass()} maxlength="6" pattern="[0-9]*"
|
|
32
|
+
* inputmode="numeric" autocomplete="one-time-code">
|
|
33
|
+
* <ui-input-otp-group>
|
|
34
|
+
* <ui-input-otp-slot index="0"></ui-input-otp-slot>
|
|
35
|
+
* <ui-input-otp-slot index="1"></ui-input-otp-slot>
|
|
36
|
+
* <ui-input-otp-slot index="2"></ui-input-otp-slot>
|
|
37
|
+
* </ui-input-otp-group>
|
|
38
|
+
* <ui-input-otp-separator></ui-input-otp-separator>
|
|
39
|
+
* <ui-input-otp-group>
|
|
40
|
+
* <ui-input-otp-slot index="3"></ui-input-otp-slot>
|
|
41
|
+
* <ui-input-otp-slot index="4"></ui-input-otp-slot>
|
|
42
|
+
* <ui-input-otp-slot index="5"></ui-input-otp-slot>
|
|
43
|
+
* </ui-input-otp-group>
|
|
44
|
+
* </ui-input-otp>
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
import { WebComponent, html, signal } from '@webjsdev/core';
|
|
48
|
+
import { takeAuthoredClass } from '../lib/utils.ts';
|
|
49
|
+
|
|
50
|
+
/** The row's classes (the element applies them). */
|
|
51
|
+
export const inputOtpClass = (): string =>
|
|
52
|
+
'cn-input-otp relative flex items-center has-disabled:opacity-50';
|
|
53
|
+
/** A group's classes (the element applies them). */
|
|
54
|
+
export const inputOtpGroupClass = (): string => 'cn-input-otp-group flex items-center';
|
|
55
|
+
/** A slot's classes (the element applies them, to the slot's own host). */
|
|
56
|
+
export const inputOtpSlotClass = (): string =>
|
|
57
|
+
'cn-input-otp-slot relative flex items-center justify-center data-[active=true]:z-10';
|
|
58
|
+
/** The fake caret's box. */
|
|
59
|
+
export const inputOtpCaretClass = (): string =>
|
|
60
|
+
'cn-input-otp-caret pointer-events-none absolute inset-0 flex items-center justify-center';
|
|
61
|
+
/** The fake caret's line. */
|
|
62
|
+
export const inputOtpCaretLineClass = (): string => 'cn-input-otp-caret-line';
|
|
63
|
+
/** The separator's classes (the element applies them). */
|
|
64
|
+
export const inputOtpSeparatorClass = (): string => 'cn-input-otp-separator flex items-center';
|
|
65
|
+
|
|
66
|
+
// The real input, laid transparent over the slots so it takes every click,
|
|
67
|
+
// keystroke, paste and autofill while the slots do the drawing.
|
|
68
|
+
const OVERLAY =
|
|
69
|
+
'position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;box-shadow:none;background:transparent;color:transparent;-webkit-text-fill-color:transparent;caret-color:transparent;font-size:1px;letter-spacing:-0.5em;z-index:20;';
|
|
70
|
+
|
|
71
|
+
const ROOT = 'ui-input-otp';
|
|
72
|
+
|
|
73
|
+
export class UiInputOtp extends WebComponent {
|
|
74
|
+
readonly #enhanced = signal(false);
|
|
75
|
+
_observer: MutationObserver | null = null;
|
|
76
|
+
_waiting: MutationObserver | null = null;
|
|
77
|
+
_form: HTMLFormElement | null = null;
|
|
78
|
+
_savedStyle: string | null = null;
|
|
79
|
+
_last = '';
|
|
80
|
+
_focused = false;
|
|
81
|
+
_disabled: boolean | null = null;
|
|
82
|
+
|
|
83
|
+
constructor() {
|
|
84
|
+
super();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** The real input this element enhances. */
|
|
88
|
+
get input(): HTMLInputElement | null {
|
|
89
|
+
// The server renders the element with no DOM queries available.
|
|
90
|
+
return typeof this.querySelector === 'function' ? this.querySelector('input') : null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** The code typed so far. */
|
|
94
|
+
get value(): string {
|
|
95
|
+
return this.input?.value ?? '';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** How many characters the code has: the input's maxlength, else the slots. */
|
|
99
|
+
get maxLength(): number {
|
|
100
|
+
const m = this.input?.maxLength ?? -1;
|
|
101
|
+
return m > 0 ? m : this._slots().length;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
connectedCallback(): void {
|
|
105
|
+
super.connectedCallback?.();
|
|
106
|
+
queueMicrotask(() => {
|
|
107
|
+
if (this._enhance() || this._waiting) return;
|
|
108
|
+
this._waiting = new MutationObserver(() => {
|
|
109
|
+
if (this._enhance()) { this._waiting?.disconnect(); this._waiting = null; }
|
|
110
|
+
});
|
|
111
|
+
this._waiting.observe(this, { childList: true, subtree: true });
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
disconnectedCallback(): void {
|
|
116
|
+
this._waiting?.disconnect();
|
|
117
|
+
this._observer?.disconnect();
|
|
118
|
+
const input = this.input;
|
|
119
|
+
if (input) {
|
|
120
|
+
input.removeEventListener('input', this._onInput);
|
|
121
|
+
input.removeEventListener('focus', this._onFocus);
|
|
122
|
+
input.removeEventListener('blur', this._onBlur);
|
|
123
|
+
input.removeEventListener('keyup', this._sync);
|
|
124
|
+
input.removeEventListener('click', this._sync);
|
|
125
|
+
input.removeEventListener('select', this._sync);
|
|
126
|
+
if (this._savedStyle !== null) input.setAttribute('style', this._savedStyle);
|
|
127
|
+
else input.removeAttribute('style');
|
|
128
|
+
}
|
|
129
|
+
document.removeEventListener('selectionchange', this._sync);
|
|
130
|
+
this._form?.removeEventListener('reset', this._onReset);
|
|
131
|
+
super.disconnectedCallback?.();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Take over from the plain input. True once it has (or already had). */
|
|
135
|
+
_enhance(): boolean {
|
|
136
|
+
if (this.#enhanced.get()) return true;
|
|
137
|
+
const input = this.input;
|
|
138
|
+
if (!input) return false;
|
|
139
|
+
this._savedStyle = input.getAttribute('style');
|
|
140
|
+
input.setAttribute('style', (this._savedStyle ?? '') + OVERLAY);
|
|
141
|
+
input.addEventListener('input', this._onInput);
|
|
142
|
+
input.addEventListener('focus', this._onFocus);
|
|
143
|
+
input.addEventListener('blur', this._onBlur);
|
|
144
|
+
input.addEventListener('keyup', this._sync);
|
|
145
|
+
input.addEventListener('click', this._sync);
|
|
146
|
+
input.addEventListener('select', this._sync);
|
|
147
|
+
this._form = input.form;
|
|
148
|
+
this._form?.addEventListener('reset', this._onReset);
|
|
149
|
+
this._observer = new MutationObserver(() => this._sync());
|
|
150
|
+
this._observer.observe(input, { attributes: true });
|
|
151
|
+
this._last = input.value;
|
|
152
|
+
this.#enhanced.set(true);
|
|
153
|
+
this._sync();
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// A part connected after the input (a client render appends children in
|
|
158
|
+
// order) asks to be drawn.
|
|
159
|
+
_partConnected(): void {
|
|
160
|
+
if (this.#enhanced.get()) queueMicrotask(() => this._sync());
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
render() {
|
|
164
|
+
const disabled = !!this.input?.disabled;
|
|
165
|
+
return html`<div data-slot="input-otp" ?data-disabled=${disabled} class=${inputOtpClass()}><slot></slot></div>`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
_slots(): UiInputOtpSlot[] {
|
|
169
|
+
return Array.from(this.querySelectorAll<UiInputOtpSlot>(`${ROOT}-slot`));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
_pattern(): RegExp | null {
|
|
173
|
+
const p = this.input?.getAttribute('pattern');
|
|
174
|
+
if (!p) return null;
|
|
175
|
+
// HTML compiles `pattern` with the v flag; an engine without it gets u.
|
|
176
|
+
for (const flags of ['v', 'u']) {
|
|
177
|
+
try { return new RegExp(`^(?:${p})$`, flags); } catch { /* next */ }
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Refuse an edit that breaks the pattern or the length, as input-otp does.
|
|
183
|
+
_onInput = (): void => {
|
|
184
|
+
const input = this.input;
|
|
185
|
+
if (!input) return;
|
|
186
|
+
const re = this._pattern();
|
|
187
|
+
const v = input.value;
|
|
188
|
+
if ((re && v && !re.test(v)) || v.length > this.maxLength) {
|
|
189
|
+
const at = Math.max(0, (input.selectionStart ?? this._last.length) - (v.length - this._last.length));
|
|
190
|
+
input.value = this._last;
|
|
191
|
+
input.setSelectionRange(at, at);
|
|
192
|
+
this._sync();
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (v !== this._last) {
|
|
196
|
+
this._last = v;
|
|
197
|
+
this.dispatchEvent(new CustomEvent('ui-value-change', { bubbles: true, detail: { value: v } }));
|
|
198
|
+
if (v.length === this.maxLength) {
|
|
199
|
+
this.dispatchEvent(new CustomEvent('ui-complete', { bubbles: true, detail: { value: v } }));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
this._sync();
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
_onFocus = (): void => {
|
|
206
|
+
this._focused = true;
|
|
207
|
+
document.addEventListener('selectionchange', this._sync);
|
|
208
|
+
// Typing continues the code, so the caret starts at its end.
|
|
209
|
+
const input = this.input;
|
|
210
|
+
if (input) {
|
|
211
|
+
queueMicrotask(() => {
|
|
212
|
+
const end = input.value.length;
|
|
213
|
+
input.setSelectionRange(end, end);
|
|
214
|
+
this._sync();
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
this._sync();
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
_onBlur = (): void => {
|
|
221
|
+
this._focused = false;
|
|
222
|
+
document.removeEventListener('selectionchange', this._sync);
|
|
223
|
+
this._sync();
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
_onReset = (): void => {
|
|
227
|
+
queueMicrotask(() => { this._last = this.input?.value ?? ''; this._sync(); });
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// Push the value, the caret and the state into every drawn part. It runs
|
|
231
|
+
// several times per keystroke (input, keyup, each selectionchange), so it
|
|
232
|
+
// hands a part new state only when something it draws changed: every
|
|
233
|
+
// attribute write re-checks the page's :has() rules, and a page carrying
|
|
234
|
+
// the kit's styles has hundreds of them, which made each keystroke wait on
|
|
235
|
+
// style recalculation.
|
|
236
|
+
_sync = (): void => {
|
|
237
|
+
const input = this.input;
|
|
238
|
+
if (!input || !this.#enhanced.get()) return;
|
|
239
|
+
const value = input.value;
|
|
240
|
+
const max = this.maxLength;
|
|
241
|
+
const start = Math.min(input.selectionStart ?? value.length, max - 1);
|
|
242
|
+
const end = input.selectionEnd ?? start;
|
|
243
|
+
const invalid = input.getAttribute('aria-invalid') === 'true';
|
|
244
|
+
this._slots().forEach((slot) => {
|
|
245
|
+
const i = Number(slot.index);
|
|
246
|
+
const char = value[i] ?? '';
|
|
247
|
+
const active = this._focused && (end > start ? i >= start && i < end : i === start);
|
|
248
|
+
const next = { shown: true, char, active, caret: active && !char, invalid };
|
|
249
|
+
// A slot not upgraded yet has no state signal; the next sync reaches it.
|
|
250
|
+
const s = slot.state?.get();
|
|
251
|
+
if (s && (s.shown !== next.shown || s.char !== next.char || s.active !== next.active || s.caret !== next.caret || s.invalid !== next.invalid)) {
|
|
252
|
+
slot.state?.set(next);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
this.querySelectorAll<UiInputOtpGroup | UiInputOtpSeparator>(`${ROOT}-group, ${ROOT}-separator`).forEach((part) => {
|
|
256
|
+
if (!part.shown?.get()) part.shown?.set(true);
|
|
257
|
+
});
|
|
258
|
+
const disabled = !!input.disabled;
|
|
259
|
+
if (disabled !== this._disabled) {
|
|
260
|
+
this._disabled = disabled;
|
|
261
|
+
this.requestUpdate();
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
UiInputOtp.register('ui-input-otp');
|
|
266
|
+
|
|
267
|
+
// --------------------------------------------------------------------------
|
|
268
|
+
// <ui-input-otp-group>
|
|
269
|
+
// --------------------------------------------------------------------------
|
|
270
|
+
|
|
271
|
+
export class UiInputOtpGroup extends WebComponent {
|
|
272
|
+
readonly shown = signal(false);
|
|
273
|
+
constructor() {
|
|
274
|
+
super();
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
connectedCallback(): void {
|
|
278
|
+
super.connectedCallback?.();
|
|
279
|
+
(this.closest(ROOT) as UiInputOtp | null)?._partConnected();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
render() {
|
|
283
|
+
return html`<div data-slot="input-otp-group" ?hidden=${!this.shown.get()} class=${inputOtpGroupClass()}><slot></slot></div>`;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
UiInputOtpGroup.register('ui-input-otp-group');
|
|
287
|
+
|
|
288
|
+
// --------------------------------------------------------------------------
|
|
289
|
+
// <ui-input-otp-slot>
|
|
290
|
+
// --------------------------------------------------------------------------
|
|
291
|
+
|
|
292
|
+
type SlotState = { shown: boolean; char: string; active: boolean; caret: boolean; invalid: boolean };
|
|
293
|
+
|
|
294
|
+
export class UiInputOtpSlot extends WebComponent({
|
|
295
|
+
index: Number,
|
|
296
|
+
}) {
|
|
297
|
+
readonly state = signal<SlotState>({ shown: false, char: '', active: false, caret: false, invalid: false });
|
|
298
|
+
_authored: string | null = null;
|
|
299
|
+
|
|
300
|
+
constructor() {
|
|
301
|
+
super();
|
|
302
|
+
this.index = 0;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
connectedCallback(): void {
|
|
306
|
+
// The author's own classes, read once: later the host carries ours too.
|
|
307
|
+
this._authored = takeAuthoredClass(this);
|
|
308
|
+
super.connectedCallback?.();
|
|
309
|
+
(this.closest(ROOT) as UiInputOtp | null)?._partConnected();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// shadcn's slot classes use first: / last: for the joined corners, which
|
|
313
|
+
// only work on the elements that are siblings in the group: the slot hosts
|
|
314
|
+
// themselves, not a box inside each. So the slot styles its own host.
|
|
315
|
+
// Each write is guarded: an attribute set to the value it already has still
|
|
316
|
+
// invalidates style, and the page re-checks its :has() rules for it.
|
|
317
|
+
updated(changedProperties: Map<string, unknown>): void {
|
|
318
|
+
super.updated?.(changedProperties);
|
|
319
|
+
const s = this.state.get();
|
|
320
|
+
const set = (name: string, value: string | null) => {
|
|
321
|
+
if (this.getAttribute(name) === value) return;
|
|
322
|
+
if (value === null) this.removeAttribute(name);
|
|
323
|
+
else this.setAttribute(name, value);
|
|
324
|
+
};
|
|
325
|
+
set('class', [inputOtpSlotClass(), this._authored].filter(Boolean).join(' '));
|
|
326
|
+
set('data-slot', 'input-otp-slot');
|
|
327
|
+
set('data-active', s.active ? 'true' : 'false');
|
|
328
|
+
set('aria-hidden', 'true');
|
|
329
|
+
set('aria-invalid', s.invalid ? 'true' : null);
|
|
330
|
+
if (this.hidden !== !s.shown) this.hidden = !s.shown;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// The caret is always in the slot and only its class changes. Inserting or
|
|
334
|
+
// removing an element makes the browser re-check every :has() rule on the
|
|
335
|
+
// page, which on a page carrying the kit's styles took longer than a frame
|
|
336
|
+
// on each keystroke; a class change on a leaf is nearly free.
|
|
337
|
+
render() {
|
|
338
|
+
const s = this.state.get();
|
|
339
|
+
return html`${s.char}<div class=${s.caret ? inputOtpCaretClass() : 'hidden'}><div class=${inputOtpCaretLineClass()}></div></div>`;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
UiInputOtpSlot.register('ui-input-otp-slot');
|
|
343
|
+
|
|
344
|
+
// --------------------------------------------------------------------------
|
|
345
|
+
// <ui-input-otp-separator>
|
|
346
|
+
// --------------------------------------------------------------------------
|
|
347
|
+
|
|
348
|
+
export class UiInputOtpSeparator extends WebComponent {
|
|
349
|
+
readonly shown = signal(false);
|
|
350
|
+
constructor() {
|
|
351
|
+
super();
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
connectedCallback(): void {
|
|
355
|
+
super.connectedCallback?.();
|
|
356
|
+
(this.closest(ROOT) as UiInputOtp | null)?._partConnected();
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
render() {
|
|
360
|
+
return html`<div data-slot="input-otp-separator" role="separator" aria-hidden="true" ?hidden=${!this.shown.get()} class=${inputOtpSeparatorClass()}><svg
|
|
361
|
+
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"
|
|
362
|
+
><path d="M5 12h14"></path></svg></div>`;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
UiInputOtpSeparator.register('ui-input-otp-separator');
|
|
@@ -56,13 +56,13 @@
|
|
|
56
56
|
import { cn } from '../lib/utils.ts';
|
|
57
57
|
|
|
58
58
|
const INPUT_BASE =
|
|
59
|
-
'
|
|
59
|
+
'cn-input w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50';
|
|
60
60
|
|
|
61
61
|
const INPUT_FOCUS =
|
|
62
|
-
'
|
|
62
|
+
'cn-input-focus';
|
|
63
63
|
|
|
64
64
|
const INPUT_INVALID =
|
|
65
|
-
'
|
|
65
|
+
'cn-input-invalid';
|
|
66
66
|
|
|
67
67
|
/** Compose Tailwind classes for a native `<input>`. */
|
|
68
68
|
export function inputClass(): string {
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Item: a flexible row for lists of things (a person, a file, a setting), with
|
|
3
|
+
* media, a title and description, and actions. Tier-1 class helper; compose
|
|
4
|
+
* with a plain element, or an `<a>` / `<button>` when the whole row acts.
|
|
5
|
+
*
|
|
6
|
+
* shadcn parity:
|
|
7
|
+
* ItemGroup / ItemSeparator → itemGroupClass() / itemSeparatorClass()
|
|
8
|
+
* Item (variant: default | outline | muted, size: default | sm | xs)
|
|
9
|
+
* → itemClass({ variant, size }), alias itemVariants
|
|
10
|
+
* ItemMedia (variant: default | icon | image)
|
|
11
|
+
* → itemMediaClass({ variant }), alias itemMediaVariants
|
|
12
|
+
* ItemContent / ItemTitle / ItemDescription / ItemActions / ItemHeader / ItemFooter
|
|
13
|
+
* → itemContentClass() ... itemFooterClass()
|
|
14
|
+
*
|
|
15
|
+
* Every part takes its `data-slot` (shown on each helper), which is what the
|
|
16
|
+
* styles use to lay the parts out relative to each other.
|
|
17
|
+
*
|
|
18
|
+
* A11y (required for accessible output): a group of items is a list, so render
|
|
19
|
+
* it as `<ul role="list">` with each item an `<li>`, or keep `role="list"` /
|
|
20
|
+
* `role="listitem"` on divs. A whole-row link is a real `<a>` holding the
|
|
21
|
+
* content, never a click handler on a div. Media that only decorates takes
|
|
22
|
+
* `alt=""` or `aria-hidden="true"`, and an icon-only action needs
|
|
23
|
+
* `aria-label`.
|
|
24
|
+
*
|
|
25
|
+
* Design tokens used: --border, --muted, --muted-foreground, --accent, --ring.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```html
|
|
29
|
+
* <div class=${itemClass({ variant: 'outline' })} data-slot="item" data-variant="outline">
|
|
30
|
+
* <div class=${itemContentClass()} data-slot="item-content">
|
|
31
|
+
* <div class=${itemTitleClass()} data-slot="item-title">Two-factor authentication</div>
|
|
32
|
+
* <p class=${itemDescriptionClass()} data-slot="item-description">Verify it is you with a code.</p>
|
|
33
|
+
* </div>
|
|
34
|
+
* <div class=${itemActionsClass()} data-slot="item-actions">
|
|
35
|
+
* <button class=${buttonClass({ variant: 'outline', size: 'sm' })} type="button">Enable</button>
|
|
36
|
+
* </div>
|
|
37
|
+
* </div>
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
import { cn } from '../lib/utils.ts';
|
|
41
|
+
|
|
42
|
+
/** Set `data-slot="item-group"` on the element. */
|
|
43
|
+
export function itemGroupClass(): string {
|
|
44
|
+
return 'cn-item-group group/item-group flex w-full flex-col';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Set `data-slot="item-separator"` on the element. shadcn's ItemSeparator is a
|
|
49
|
+
* horizontal Separator, so the line's own size and colour come with it, and
|
|
50
|
+
* the style adds its margin.
|
|
51
|
+
*/
|
|
52
|
+
export function itemSeparatorClass(): string {
|
|
53
|
+
return 'cn-item-separator h-px w-full shrink-0 bg-border';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const ITEM_BASE =
|
|
57
|
+
'cn-item group/item flex w-full flex-wrap items-center transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors';
|
|
58
|
+
|
|
59
|
+
const ITEM_VARIANTS = {
|
|
60
|
+
default: 'cn-item-variant-default',
|
|
61
|
+
outline: 'cn-item-variant-outline',
|
|
62
|
+
muted: 'cn-item-variant-muted',
|
|
63
|
+
} as const;
|
|
64
|
+
|
|
65
|
+
const ITEM_SIZES = {
|
|
66
|
+
default: 'cn-item-size-default',
|
|
67
|
+
sm: 'cn-item-size-sm',
|
|
68
|
+
xs: 'cn-item-size-xs',
|
|
69
|
+
} as const;
|
|
70
|
+
|
|
71
|
+
/** The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match. */
|
|
72
|
+
export function itemClass(opts: { variant?: keyof typeof ITEM_VARIANTS; size?: keyof typeof ITEM_SIZES } = {}): string {
|
|
73
|
+
return cn(ITEM_BASE, ITEM_VARIANTS[opts.variant ?? 'default'], ITEM_SIZES[opts.size ?? 'default']);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* shadcn's name for {@link itemClass}, so shadcn code ports verbatim. Like cva,
|
|
78
|
+
* it merges a `className` into the result.
|
|
79
|
+
*/
|
|
80
|
+
export function itemVariants(opts: { variant?: keyof typeof ITEM_VARIANTS; size?: keyof typeof ITEM_SIZES } & { className?: string } = {}): string {
|
|
81
|
+
return cn(itemClass(opts), opts.className);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const ITEM_MEDIA_BASE =
|
|
85
|
+
'cn-item-media flex shrink-0 items-center justify-center [&_svg]:pointer-events-none';
|
|
86
|
+
|
|
87
|
+
const ITEM_MEDIA_VARIANTS = {
|
|
88
|
+
default: 'cn-item-media-variant-default',
|
|
89
|
+
icon: 'cn-item-media-variant-icon',
|
|
90
|
+
image: 'cn-item-media-variant-image',
|
|
91
|
+
} as const;
|
|
92
|
+
|
|
93
|
+
/** The part, with its variant options. Set its `data-slot` and any `data-variant` / `data-size` to match. */
|
|
94
|
+
export function itemMediaClass(opts: { variant?: keyof typeof ITEM_MEDIA_VARIANTS } = {}): string {
|
|
95
|
+
return cn(ITEM_MEDIA_BASE, ITEM_MEDIA_VARIANTS[opts.variant ?? 'default']);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* shadcn's name for {@link itemMediaClass}, so shadcn code ports verbatim. Like cva,
|
|
100
|
+
* it merges a `className` into the result.
|
|
101
|
+
*/
|
|
102
|
+
export function itemMediaVariants(opts: { variant?: keyof typeof ITEM_MEDIA_VARIANTS } & { className?: string } = {}): string {
|
|
103
|
+
return cn(itemMediaClass(opts), opts.className);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Set `data-slot="item-content"` on the element. */
|
|
107
|
+
export function itemContentClass(): string {
|
|
108
|
+
return 'cn-item-content flex flex-1 flex-col [&+[data-slot=item-content]]:flex-none';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Set `data-slot="item-title"` on the element. */
|
|
112
|
+
export function itemTitleClass(): string {
|
|
113
|
+
return 'cn-item-title line-clamp-1 flex w-fit items-center';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Set `data-slot="item-description"` on the element. */
|
|
117
|
+
export function itemDescriptionClass(): string {
|
|
118
|
+
return 'cn-item-description line-clamp-2 font-normal [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Set `data-slot="item-actions"` on the element. */
|
|
122
|
+
export function itemActionsClass(): string {
|
|
123
|
+
return 'cn-item-actions flex items-center';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Set `data-slot="item-header"` on the element. */
|
|
127
|
+
export function itemHeaderClass(): string {
|
|
128
|
+
return 'cn-item-header flex basis-full items-center justify-between';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Set `data-slot="item-footer"` on the element. */
|
|
132
|
+
export function itemFooterClass(): string {
|
|
133
|
+
return 'cn-item-footer flex basis-full items-center justify-between';
|
|
134
|
+
}
|
|
@@ -55,6 +55,6 @@
|
|
|
55
55
|
*/
|
|
56
56
|
|
|
57
57
|
export const kbdClass = (): string =>
|
|
58
|
-
|
|
58
|
+
'cn-kbd pointer-events-none inline-flex items-center justify-center select-none';
|
|
59
59
|
|
|
60
|
-
export const kbdGroupClass = (): string => 'inline-flex items-center
|
|
60
|
+
export const kbdGroupClass = (): string => 'cn-kbd-group inline-flex items-center';
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
|
|
43
43
|
/** Compose Tailwind classes for a native `<label>`. */
|
|
44
44
|
export function labelClass(): string {
|
|
45
|
-
return 'flex items-center
|
|
45
|
+
return 'cn-label flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed';
|
|
46
46
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marker: a small inline note in a stream of content, such as "Today" between
|
|
3
|
+
* chat messages or "Edited" under a post, with an optional icon. Tier-1
|
|
4
|
+
* class helper; compose with a plain element.
|
|
5
|
+
*
|
|
6
|
+
* shadcn parity:
|
|
7
|
+
* Marker (variant: default | separator | border)
|
|
8
|
+
* → markerClass({ variant }), alias markerVariants
|
|
9
|
+
* MarkerIcon → markerIconClass()
|
|
10
|
+
* MarkerContent → markerContentClass()
|
|
11
|
+
*
|
|
12
|
+
* The `separator` variant draws a rule on both sides of the content, and
|
|
13
|
+
* `border` underlines the whole marker. Set `data-variant` to the variant you
|
|
14
|
+
* pass, which is what the content's centring keys on.
|
|
15
|
+
*
|
|
16
|
+
* A11y (required for accessible output): a marker is text, so it needs no
|
|
17
|
+
* role. When it announces a change in a live log (a date divider inside a
|
|
18
|
+
* chat), it is read in order with the messages around it, which is usually
|
|
19
|
+
* right. Hide a purely decorative icon with `aria-hidden="true"`.
|
|
20
|
+
*
|
|
21
|
+
* Design tokens used: --muted-foreground, --foreground, --border.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```html
|
|
25
|
+
* <div class=${markerClass({ variant: 'separator' })} data-variant="separator">
|
|
26
|
+
* <span class=${markerContentClass()}>Today</span>
|
|
27
|
+
* </div>
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import { cn } from '../lib/utils.ts';
|
|
31
|
+
|
|
32
|
+
const BASE = 'cn-marker group/marker relative flex w-full items-center';
|
|
33
|
+
|
|
34
|
+
const VARIANTS = {
|
|
35
|
+
default: 'cn-marker-variant-default',
|
|
36
|
+
separator: 'cn-marker-variant-separator',
|
|
37
|
+
border: 'cn-marker-variant-border',
|
|
38
|
+
} as const;
|
|
39
|
+
|
|
40
|
+
export type MarkerVariant = keyof typeof VARIANTS;
|
|
41
|
+
|
|
42
|
+
/** The marker row. Pair with `data-variant` set to the same variant. */
|
|
43
|
+
export function markerClass(opts: { variant?: MarkerVariant } = {}): string {
|
|
44
|
+
return cn(BASE, VARIANTS[opts.variant ?? 'default']);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* shadcn's name for {@link markerClass}, so shadcn code ports verbatim. Like
|
|
49
|
+
* cva, it merges a `className` into the result.
|
|
50
|
+
*/
|
|
51
|
+
export function markerVariants(opts: { variant?: MarkerVariant } & { className?: string } = {}): string {
|
|
52
|
+
return cn(markerClass(opts), opts.className);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** The leading icon. */
|
|
56
|
+
export function markerIconClass(): string {
|
|
57
|
+
return 'cn-marker-icon shrink-0';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** The marker's text. */
|
|
61
|
+
export function markerContentClass(): string {
|
|
62
|
+
return 'cn-marker-content min-w-0 wrap-break-word';
|
|
63
|
+
}
|