@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
package/src/commands/init.js
CHANGED
|
@@ -5,7 +5,16 @@ import prompts from 'prompts';
|
|
|
5
5
|
import { writeConfig, CONFIG_FILE } from '../utils/get-config.js';
|
|
6
6
|
import { logger } from '../utils/logger.js';
|
|
7
7
|
import { getRegistryItem, DEFAULT_REGISTRY_URL } from '../registry/fetcher.js';
|
|
8
|
-
import { ensureTheme } from '../utils/theme.js';
|
|
8
|
+
import { ensureTheme, presetThemeBlock } from '../utils/theme.js';
|
|
9
|
+
import { STYLE_NAMES } from '../registry/style-bake.js';
|
|
10
|
+
import {
|
|
11
|
+
ICON_LIBRARIES,
|
|
12
|
+
decodePreset,
|
|
13
|
+
getIconLibrary,
|
|
14
|
+
isPresetCode,
|
|
15
|
+
presetFontUrls,
|
|
16
|
+
resolvePresetConfig,
|
|
17
|
+
} from '../../packages/registry/themes/preset.js';
|
|
9
18
|
|
|
10
19
|
const BASE_COLORS = ['neutral', 'stone', 'zinc', 'mauve', 'olive', 'mist', 'taupe'];
|
|
11
20
|
|
|
@@ -50,11 +59,46 @@ export const init = new Command()
|
|
|
50
59
|
.option('-y, --yes', 'skip confirmation prompts', false)
|
|
51
60
|
.option('--base-color <color>', `base color (${BASE_COLORS.join('|')})`)
|
|
52
61
|
.option('--css <path>', 'path to the project Tailwind CSS file')
|
|
53
|
-
.option('-o, --overwrite', 'replace an existing alias map
|
|
62
|
+
.option('-o, --overwrite', 'replace an existing alias map, existing helper files and the theme block', false)
|
|
63
|
+
.option('--preset <code>', 'apply a design-system preset code from webjs.dev/ui/create (style, colors, font, radius, icons)')
|
|
64
|
+
.option('--style <name>', `component style (${STYLE_NAMES.join('|')})`)
|
|
65
|
+
.option('--icons <library>', `icon library (${ICON_LIBRARIES.map((l) => l.name).join('|')})`)
|
|
54
66
|
.option('--registry <url>', 'registry base URL', DEFAULT_REGISTRY_URL)
|
|
55
67
|
.action(async (opts) => {
|
|
56
68
|
const cwd = opts.cwd;
|
|
57
69
|
|
|
70
|
+
// A preset is the configurator's whole design system in one code (#1666).
|
|
71
|
+
// An explicit flag beside it wins over the field it names, so a code can
|
|
72
|
+
// be reused with one choice changed.
|
|
73
|
+
/** @type {import('../../packages/registry/themes/preset.js').PresetConfig | null} */
|
|
74
|
+
let preset = null;
|
|
75
|
+
if (opts.preset) {
|
|
76
|
+
const decoded = isPresetCode(opts.preset) ? decodePreset(opts.preset) : null;
|
|
77
|
+
if (!decoded) {
|
|
78
|
+
logger.error(`"${opts.preset}" is not a preset code. Copy one from ${logger.cyan('https://webjs.dev/ui/create')}.`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
const resolved = resolvePresetConfig({
|
|
82
|
+
...decoded,
|
|
83
|
+
...(opts.style ? { style: opts.style } : null),
|
|
84
|
+
...(opts.icons ? { iconLibrary: opts.icons } : null),
|
|
85
|
+
...(opts.baseColor ? { baseColor: opts.baseColor } : null),
|
|
86
|
+
});
|
|
87
|
+
if (resolved.error) {
|
|
88
|
+
logger.error(`Preset ${opts.preset}: ${resolved.error}.`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
preset = resolved.config;
|
|
92
|
+
}
|
|
93
|
+
if (opts.style && !STYLE_NAMES.includes(opts.style)) {
|
|
94
|
+
logger.error(`Unknown style "${opts.style}". Use one of: ${STYLE_NAMES.join(', ')}.`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
if (opts.icons && !getIconLibrary(opts.icons)) {
|
|
98
|
+
logger.error(`Unknown icon library "${opts.icons}". Use one of: ${ICON_LIBRARIES.map((l) => l.name).join(', ')}.`);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
|
|
58
102
|
// Re-running `init` on a project that already has one must not RELOCATE it.
|
|
59
103
|
// The alias map decides where cn() lives and what every already-added
|
|
60
104
|
// component imports, and `tailwind.css` decides which stylesheet the app
|
|
@@ -97,7 +141,7 @@ export const init = new Command()
|
|
|
97
141
|
|
|
98
142
|
/** @type {{ baseColor: string, css: string }} */
|
|
99
143
|
let answers = {
|
|
100
|
-
baseColor: opts.baseColor || initialBaseColor,
|
|
144
|
+
baseColor: (preset && preset.baseColor) || opts.baseColor || initialBaseColor,
|
|
101
145
|
css: opts.css || initialCss,
|
|
102
146
|
};
|
|
103
147
|
|
|
@@ -105,7 +149,7 @@ export const init = new Command()
|
|
|
105
149
|
const r = await prompts(
|
|
106
150
|
[
|
|
107
151
|
{
|
|
108
|
-
type: opts.baseColor ? null : 'select',
|
|
152
|
+
type: opts.baseColor || preset ? null : 'select',
|
|
109
153
|
name: 'baseColor',
|
|
110
154
|
message: 'Base color?',
|
|
111
155
|
choices: BASE_COLORS.map((c) => ({ title: c, value: c })),
|
|
@@ -127,9 +171,12 @@ export const init = new Command()
|
|
|
127
171
|
// unrecognised key through here would write a file that `getConfig` (and
|
|
128
172
|
// therefore `add` / `diff` / `info`) throws on. Preserving a project's
|
|
129
173
|
// settings means its VALUES, not arbitrary extra fields.
|
|
174
|
+
// A style or icon library the command names replaces the stored one,
|
|
175
|
+
// since naming it is the request; otherwise a re-run keeps what is there.
|
|
176
|
+
const iconLibrary = (preset && preset.iconLibrary) || opts.icons || (keep && existing.iconLibrary) || 'lucide';
|
|
130
177
|
const config = {
|
|
131
178
|
$schema: 'https://ui.webjs.dev/schema.json',
|
|
132
|
-
style: (keep && existing.style) || 'default',
|
|
179
|
+
style: (preset && preset.style) || opts.style || (keep && existing.style) || 'default',
|
|
133
180
|
tailwind: {
|
|
134
181
|
css: answers.css,
|
|
135
182
|
baseColor: answers.baseColor,
|
|
@@ -138,7 +185,7 @@ export const init = new Command()
|
|
|
138
185
|
: true,
|
|
139
186
|
},
|
|
140
187
|
aliases,
|
|
141
|
-
iconLibrary
|
|
188
|
+
iconLibrary,
|
|
142
189
|
};
|
|
143
190
|
|
|
144
191
|
writeConfig(cwd, config);
|
|
@@ -147,17 +194,49 @@ export const init = new Command()
|
|
|
147
194
|
// Pull lib/utils + the chosen theme from the registry and write them in.
|
|
148
195
|
await writeLibUtils(cwd, aliases.utils, opts.registry, opts.overwrite);
|
|
149
196
|
|
|
197
|
+
// The icon library is written only when the command names one, since it
|
|
198
|
+
// is a large file an app that draws no kit icons does not need.
|
|
199
|
+
if (preset || opts.icons) await writeIcons(cwd, aliases.utils, iconLibrary, opts.registry, opts.overwrite);
|
|
200
|
+
|
|
201
|
+
// A preset's tokens are its own palette over the kit's theme file.
|
|
202
|
+
let block;
|
|
203
|
+
if (preset) {
|
|
204
|
+
try {
|
|
205
|
+
const neutral = await getRegistryItem('theme-neutral', opts.registry);
|
|
206
|
+
block = presetThemeBlock(neutral.files[0].content || '', preset);
|
|
207
|
+
} catch (e) {
|
|
208
|
+
logger.error(`Could not build the theme for preset ${opts.preset}: ${e.message}`);
|
|
209
|
+
process.exit(1);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
150
213
|
// The theme tokens are what the class helpers render against. A silent
|
|
151
214
|
// failure here (the old behaviour) left an unstyled install with a clean
|
|
152
215
|
// exit code, the exact trap for an autonomous agent, so hard-fail (#983).
|
|
153
|
-
|
|
216
|
+
// A preset, or --overwrite, replaces an existing block in place (#1666).
|
|
217
|
+
const theme = await ensureTheme(cwd, answers.baseColor, answers.css, opts.registry, {
|
|
218
|
+
replace: Boolean(preset || opts.overwrite),
|
|
219
|
+
block,
|
|
220
|
+
});
|
|
154
221
|
if (theme.status === 'failed') {
|
|
155
222
|
logger.error(`Could not write theme tokens into ${answers.css}: ${theme.error}`);
|
|
156
223
|
logger.info('The class helpers render against these tokens, so this must succeed.');
|
|
157
224
|
process.exit(1);
|
|
158
225
|
}
|
|
159
226
|
if (theme.status === 'written') logger.success(`Wrote theme into ${answers.css}`);
|
|
160
|
-
else logger.
|
|
227
|
+
else if (theme.status === 'replaced') logger.success(`Replaced the theme in ${answers.css}`);
|
|
228
|
+
else if (theme.status === 'legacy') {
|
|
229
|
+
logger.warn(`The theme block in ${answers.css} predates the end marker, so it was left as it is.`);
|
|
230
|
+
logger.info(`To replace it, delete the block (from ${logger.cyan('/* @webjsdev/ui theme */')} to the end of its rules) and re-run init.`);
|
|
231
|
+
} else logger.info(`Theme already present in ${answers.css}: skipping.`);
|
|
232
|
+
|
|
233
|
+
if (preset) {
|
|
234
|
+
const urls = presetFontUrls(preset);
|
|
235
|
+
if (urls.length) {
|
|
236
|
+
logger.info('The preset names its fonts in the theme. Load the faces, either self-hosted under public/ or from:');
|
|
237
|
+
for (const url of urls) logger.info(` ${url}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
161
240
|
|
|
162
241
|
logger.break();
|
|
163
242
|
logger.success('Done.');
|
|
@@ -201,8 +280,8 @@ async function writeLibUtils(cwd, utilsAlias, registryUrl, overwrite) {
|
|
|
201
280
|
}
|
|
202
281
|
|
|
203
282
|
// The onBeforeCache() DOM helper lives in a SEPARATE module (#819) because
|
|
204
|
-
// it references `document`, so keeping it out of cn()'s file
|
|
205
|
-
//
|
|
283
|
+
// it references `document`, so keeping it out of cn()'s file keeps cn()
|
|
284
|
+
// free of browser globals for the pages and layouts that import it.
|
|
206
285
|
// Overlay components import it from `../lib/dom.ts`, so write it as a
|
|
207
286
|
// sibling of the utils file, which lands it at lib/utils/dom.ts next to
|
|
208
287
|
// cn.ts. `add` reads that same adjacency when it rewrites the import.
|
|
@@ -224,6 +303,44 @@ async function writeLibUtils(cwd, utilsAlias, registryUrl, overwrite) {
|
|
|
224
303
|
}
|
|
225
304
|
}
|
|
226
305
|
|
|
306
|
+
/**
|
|
307
|
+
* Write the chosen icon library as the utils file's sibling `icons.ts`, the
|
|
308
|
+
* path a block's icon import is rewritten to (#1666). Naming a library is a
|
|
309
|
+
* request to switch, so a file that is still one of the five libraries as
|
|
310
|
+
* shipped is replaced. A file the app has edited is kept unless `--overwrite`
|
|
311
|
+
* says otherwise, the same rule as the other helpers.
|
|
312
|
+
*/
|
|
313
|
+
async function writeIcons(cwd, utilsAlias, library, registryUrl, overwrite) {
|
|
314
|
+
const lib = getIconLibrary(library);
|
|
315
|
+
if (!lib) return;
|
|
316
|
+
const target = join(dirname(join(cwd, utilsAlias.replace(/^@\//, '') + '.ts')), 'icons.ts');
|
|
317
|
+
const rel = relative(cwd, target);
|
|
318
|
+
try {
|
|
319
|
+
const item = await getRegistryItem(lib.item, registryUrl);
|
|
320
|
+
const content = item.files && item.files[0] ? item.files[0].content || '' : '';
|
|
321
|
+
if (!content) throw new Error(`${lib.item} has no content`);
|
|
322
|
+
if (existsSync(target) && !overwrite) {
|
|
323
|
+
const current = readFileSync(target, 'utf8');
|
|
324
|
+
if (current === content) {
|
|
325
|
+
logger.info(`${rel} is already ${lib.title}: keeping it.`);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const pristine = await Promise.all(
|
|
329
|
+
ICON_LIBRARIES.map((l) => getRegistryItem(l.item, registryUrl).then((it) => it.files[0].content, () => null)),
|
|
330
|
+
);
|
|
331
|
+
if (!pristine.includes(current)) {
|
|
332
|
+
logger.warn(`${rel} has been edited, so it was kept. Re-run with --overwrite to replace it with ${lib.title}.`);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
ensureDir(dirname(target));
|
|
337
|
+
writeFileSync(target, content, 'utf8');
|
|
338
|
+
logger.success(`Wrote ${rel} (${lib.title})`);
|
|
339
|
+
} catch (e) {
|
|
340
|
+
logger.warn(`Could not fetch ${lib.item} from the registry (${e.message}).`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
227
344
|
function relative(cwd, p) {
|
|
228
345
|
return p.startsWith(cwd) ? p.slice(cwd.length + 1) : p;
|
|
229
346
|
}
|
package/src/commands/list.js
CHANGED
|
@@ -1,25 +1,57 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { getRegistryIndex, DEFAULT_REGISTRY_URL } from '../registry/fetcher.js';
|
|
3
|
+
import { uiBlocks, BLOCK_DEFINITION } from '../registry/extract.js';
|
|
3
4
|
import { logger } from '../utils/logger.js';
|
|
4
5
|
|
|
6
|
+
const TYPES = ['ui', 'block', 'chart', 'all'];
|
|
7
|
+
|
|
8
|
+
/** The three labelled groups `list` prints, in order. */
|
|
9
|
+
const GROUPS = [
|
|
10
|
+
['ui', 'Components'],
|
|
11
|
+
['block', `Blocks (${BLOCK_DEFINITION})`],
|
|
12
|
+
['chart', 'Charts'],
|
|
13
|
+
];
|
|
14
|
+
|
|
5
15
|
export const list = new Command()
|
|
6
16
|
.name('list')
|
|
7
17
|
.alias('search')
|
|
8
|
-
.description('List components
|
|
9
|
-
.argument('[filter]', 'filter by substring')
|
|
18
|
+
.description('List the components, blocks and charts in the registry')
|
|
19
|
+
.argument('[filter]', 'filter by substring of the name')
|
|
20
|
+
.option('--type <type>', `ui, block, chart or all (${TYPES.join(' | ')})`, 'all')
|
|
21
|
+
.option('--category <name>', 'only blocks and charts in this category (e.g. login, sidebar, area)')
|
|
22
|
+
.option('--json', 'print one compact JSON array of { name, type, categories, description }')
|
|
10
23
|
.option('--registry <url>', 'registry base URL', DEFAULT_REGISTRY_URL)
|
|
11
24
|
.action(async (filter, opts) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
if (!TYPES.includes(opts.type)) {
|
|
26
|
+
logger.error(`Unknown --type "${opts.type}". Use one of: ${TYPES.join(', ')}.`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const index = await getRegistryIndex(opts.registry);
|
|
30
|
+
const items = uiBlocks({ type: opts.type, category: opts.category }, index)
|
|
31
|
+
.filter((i) => !filter || i.name.includes(filter));
|
|
32
|
+
|
|
33
|
+
// The JSON form is the whole of stdout, so nothing else is printed.
|
|
34
|
+
if (opts.json) {
|
|
35
|
+
console.log(JSON.stringify(items));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (!items.length) {
|
|
16
39
|
logger.info('No matches.');
|
|
17
40
|
return;
|
|
18
41
|
}
|
|
19
|
-
for (const
|
|
20
|
-
const
|
|
21
|
-
|
|
42
|
+
for (const [type, label] of GROUPS) {
|
|
43
|
+
const group = items.filter((i) => i.type === type);
|
|
44
|
+
if (!group.length) continue;
|
|
45
|
+
logger.info(logger.bold(`${label}:`));
|
|
46
|
+
for (const i of group) {
|
|
47
|
+
const desc = i.description ? logger.dim(': ' + i.description) : '';
|
|
48
|
+
logger.info(` ${logger.cyan(i.name)}${desc}`);
|
|
49
|
+
}
|
|
50
|
+
logger.info('');
|
|
22
51
|
}
|
|
23
|
-
|
|
24
|
-
|
|
52
|
+
const count = (type, word) => {
|
|
53
|
+
const n = items.filter((i) => i.type === type).length;
|
|
54
|
+
return n ? `${n} ${word}${n === 1 ? '' : 's'}` : null;
|
|
55
|
+
};
|
|
56
|
+
logger.info([count('ui', 'component'), count('block', 'block'), count('chart', 'chart')].filter(Boolean).join(', ') + '.');
|
|
25
57
|
});
|
package/src/commands/view.js
CHANGED
|
@@ -1,34 +1,62 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { getRegistryItem, DEFAULT_REGISTRY_URL, isDefaultRegistry } from '../registry/fetcher.js';
|
|
3
|
-
import { uiComponent, renderComponentText } from '../registry/extract.js';
|
|
3
|
+
import { uiComponent, renderComponentText, itemKind, projectBlock, renderBlockText } from '../registry/extract.js';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
|
+
import { getConfig } from '../utils/get-config.js';
|
|
6
|
+
import { bakeForStyle } from '../registry/style-bake.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The style to bake with: `--style`, else the project's components.json, else
|
|
10
|
+
* the default. Outside a project (no components.json) there is no config to
|
|
11
|
+
* read, which is not an error for `view`.
|
|
12
|
+
*/
|
|
13
|
+
function styleFor(opts) {
|
|
14
|
+
if (opts.style) return opts.style;
|
|
15
|
+
try { return getConfig(process.cwd())?.style; } catch { return undefined; }
|
|
16
|
+
}
|
|
5
17
|
|
|
6
18
|
export const view = new Command()
|
|
7
19
|
.name('view')
|
|
8
20
|
.description("Print a registry item's source (and the paste-ready example) to stdout")
|
|
9
|
-
.argument('<name>', 'component name')
|
|
21
|
+
.argument('<name>', 'component, block or chart name')
|
|
10
22
|
.option('--registry <url>', 'registry base URL', DEFAULT_REGISTRY_URL)
|
|
11
23
|
.option('--source', 'print only the raw source, not the projected view')
|
|
24
|
+
.option('--style <name>', 'the style to bake the source with (default: components.json, else new-york)')
|
|
25
|
+
.option('--json', 'a block or chart: print the projection as one JSON document')
|
|
26
|
+
.option('--files-only', 'a block or chart: print the file list and stop before the sources')
|
|
12
27
|
.action(async (name, opts) => {
|
|
28
|
+
const style = styleFor(opts);
|
|
29
|
+
|
|
30
|
+
// A block or chart (D18) prints what it is, how to install it and where
|
|
31
|
+
// its files land, then the sources, all from the projector the MCP `ui`
|
|
32
|
+
// tool shares. Resolved first, since a block has no component projection.
|
|
33
|
+
const item = await getRegistryItem(name, opts.registry);
|
|
34
|
+
const kind = itemKind(item);
|
|
35
|
+
if (kind === 'block' || kind === 'chart') {
|
|
36
|
+
const block = projectBlock(item, { style, source: !opts.filesOnly });
|
|
37
|
+
console.log(opts.json ? JSON.stringify(block, null, 2) : renderBlockText(block));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
13
40
|
// For a local registry:ui component, lead with the projected view (helper
|
|
14
41
|
// signatures + the paste-ready @example + deps). This is the human /
|
|
15
42
|
// offline path to the example that `add` strips from the copied file, and
|
|
16
43
|
// it shares ONE projector with the MCP `ui` tool (`registry/extract.js`).
|
|
17
44
|
// The projection reads the LOCAL packaged registry, so it only applies to
|
|
18
45
|
// the default registry (a custom --registry gets the raw fetched source).
|
|
19
|
-
const projected = opts.source || !isDefaultRegistry(opts.registry) ? null : uiComponent(name);
|
|
46
|
+
const projected = opts.source || !isDefaultRegistry(opts.registry) ? null : uiComponent(name, { style });
|
|
20
47
|
if (projected) {
|
|
21
48
|
console.log(renderComponentText(projected));
|
|
22
49
|
console.log('');
|
|
23
50
|
logger.info(logger.dim('# --- full source ---'));
|
|
24
51
|
}
|
|
25
52
|
|
|
26
|
-
const item = await getRegistryItem(name, opts.registry);
|
|
27
53
|
logger.info(logger.dim(`# ${item.name}: ${item.type}`));
|
|
28
54
|
if (item.description) logger.info(logger.dim(`# ${item.description}`));
|
|
29
55
|
for (const f of item.files || []) {
|
|
30
56
|
logger.info('');
|
|
31
57
|
logger.info(logger.dim(`# ${f.path}`));
|
|
32
|
-
|
|
58
|
+
// Baked, so the printed source is the plain Tailwind `add` would write
|
|
59
|
+
// (#1666). A custom registry's file with no cn-* name passes unchanged.
|
|
60
|
+
console.log(bakeForStyle(f.content || '', style));
|
|
33
61
|
}
|
|
34
62
|
});
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* invented: a helper matching neither authored shape yields no value list.
|
|
12
12
|
*
|
|
13
13
|
* `allow` takes category names and class-group ids. The documented starting
|
|
14
|
-
* configuration is `["layout", "rounded"]`, which is what lets the
|
|
14
|
+
* configuration is `["layout", "rounded"]`, which is what lets the kit's
|
|
15
15
|
* sanctioned one-off (`cn(buttonClass({ size: 'none' }), 'w-9 h-9
|
|
16
16
|
* rounded-full')`) pass: `w-9 h-9` is layout, and `rounded-full` is the plain
|
|
17
17
|
* radius group granted by name without opening the whole `shape` category.
|
package/src/registry/extract.js
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import { loadRegistryItem, loadRegistryIndex, isCustomElementSource } from './local.js';
|
|
22
|
+
import { bakeForStyle } from './style-bake.js';
|
|
22
23
|
import { extractExample } from './example.js';
|
|
23
24
|
|
|
24
25
|
/**
|
|
@@ -243,17 +244,23 @@ export function extractDocHeader(src) {
|
|
|
243
244
|
* Project one registry component into the agent-facing shape. Returns null when
|
|
244
245
|
* the name is not a `registry:ui` component.
|
|
245
246
|
*
|
|
247
|
+
* The source is BAKED first (#1666): the registry is in base form, and what an
|
|
248
|
+
* agent copies from this projection must be the plain Tailwind an app gets,
|
|
249
|
+
* never a `cn-*` name. `style` is the app's `components.json` style, and an
|
|
250
|
+
* absent one means `new-york`, the kit's default look.
|
|
251
|
+
*
|
|
246
252
|
* @param {string} name
|
|
253
|
+
* @param {{ style?: string }} [opts]
|
|
247
254
|
* @returns {{
|
|
248
255
|
* name: string, tier: 1|2, type: string,
|
|
249
256
|
* description: string, helpers: string[], example: string,
|
|
250
257
|
* dependencies: string[], registryDependencies: string[],
|
|
251
258
|
* } | null}
|
|
252
259
|
*/
|
|
253
|
-
export function uiComponent(name) {
|
|
260
|
+
export function uiComponent(name, opts = {}) {
|
|
254
261
|
const item = loadRegistryItem(name);
|
|
255
262
|
if (!item || item.type !== 'registry:ui') return null;
|
|
256
|
-
const src = (item.files || []).map((f) => f.content || '').join('\n');
|
|
263
|
+
const src = (item.files || []).map((f) => bakeForStyle(f.content || '', opts.style)).join('\n');
|
|
257
264
|
const tier = isCustomElementSource(src) ? 2 : 1;
|
|
258
265
|
return {
|
|
259
266
|
name: item.name,
|
|
@@ -267,11 +274,25 @@ export function uiComponent(name) {
|
|
|
267
274
|
};
|
|
268
275
|
}
|
|
269
276
|
|
|
277
|
+
/**
|
|
278
|
+
* A component's files baked for a style, as `webjs ui view` prints them and
|
|
279
|
+
* `add` writes them (paths are the registry's). The /ui docs' Manual tab
|
|
280
|
+
* shows these, so the page and the CLI cannot disagree about the source.
|
|
281
|
+
*
|
|
282
|
+
* @param {string} name
|
|
283
|
+
* @param {{ style?: string }} [opts]
|
|
284
|
+
* @returns {Array<{ path: string, content: string }> | null}
|
|
285
|
+
*/
|
|
286
|
+
export function uiComponentFiles(name, opts = {}) {
|
|
287
|
+
const item = loadRegistryItem(name);
|
|
288
|
+
if (!item) return null;
|
|
289
|
+
return (item.files || []).map((f) => ({ path: f.path, content: bakeForStyle(f.content || '', opts.style) }));
|
|
290
|
+
}
|
|
291
|
+
|
|
270
292
|
/**
|
|
271
293
|
* The kit inventory: one compact entry per `registry:ui` component (name, tier,
|
|
272
|
-
* helper signatures, npm deps). The no-args payload for the MCP `ui` tool
|
|
273
|
-
*
|
|
274
|
-
* instead of expanding Tailwind by hand.
|
|
294
|
+
* helper signatures, npm deps). The no-args payload for the MCP `ui` tool, so
|
|
295
|
+
* an agent reaches for a helper instead of expanding Tailwind by hand.
|
|
275
296
|
*
|
|
276
297
|
* @returns {Array<{ name: string, tier: 1|2, helpers: string[], dependencies: string[] }>}
|
|
277
298
|
*/
|
|
@@ -290,6 +311,174 @@ export function uiInventory() {
|
|
|
290
311
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
291
312
|
}
|
|
292
313
|
|
|
314
|
+
/* -------------------- blocks and charts (#1666, D18) -------------------- */
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* What a block is, in the one phrasing every agent-facing surface uses. A
|
|
318
|
+
* block and a chart are both `registry:block` items on the wire (shadcn
|
|
319
|
+
* parity), told apart by a chart's `chart` category.
|
|
320
|
+
*/
|
|
321
|
+
export const BLOCK_DEFINITION = 'a ready-made view you install and then edit';
|
|
322
|
+
|
|
323
|
+
/** The category that marks a `registry:block` as a chart. */
|
|
324
|
+
export const CHART_CATEGORY = 'chart';
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* The agent-facing kind of a registry item: `ui` for a component, `chart` for
|
|
328
|
+
* a block carrying the `chart` category, `block` for any other block, and
|
|
329
|
+
* null for everything else (a lib, a theme).
|
|
330
|
+
*
|
|
331
|
+
* @param {{ type?: string, categories?: string[] }} item
|
|
332
|
+
* @returns {'ui' | 'block' | 'chart' | null}
|
|
333
|
+
*/
|
|
334
|
+
export function itemKind(item) {
|
|
335
|
+
if (!item) return null;
|
|
336
|
+
if (item.type === 'registry:ui') return 'ui';
|
|
337
|
+
if (item.type !== 'registry:block') return null;
|
|
338
|
+
return (item.categories || []).includes(CHART_CATEGORY) ? 'chart' : 'block';
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* The category a block is grouped under in a compact listing: its LAST, most
|
|
343
|
+
* specific category (`login` for `['authentication', 'login']`, `area` for
|
|
344
|
+
* `['chart', 'area']`), so each name appears once. A block with none is
|
|
345
|
+
* grouped under `other`. Filtering by category still matches every one.
|
|
346
|
+
*
|
|
347
|
+
* @param {{ categories?: string[] }} item
|
|
348
|
+
* @returns {string}
|
|
349
|
+
*/
|
|
350
|
+
export function primaryCategory(item) {
|
|
351
|
+
const cats = (item.categories || []).filter((c) => c !== CHART_CATEGORY);
|
|
352
|
+
return cats.length ? cats[cats.length - 1] : 'other';
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* One compact entry per block or chart (and per component when `type` asks
|
|
357
|
+
* for them): `{ name, type, categories, description }`, sorted by name. The
|
|
358
|
+
* shape `webjsui list --json` prints and the MCP `ui` tool's filtered
|
|
359
|
+
* listing returns.
|
|
360
|
+
*
|
|
361
|
+
* @param {{ type?: 'ui' | 'block' | 'chart' | 'all', category?: string }} [opts]
|
|
362
|
+
* `type` defaults to `block` plus `chart`; `all` adds the components.
|
|
363
|
+
* @param {any[]} [index] the registry index, the packaged one by default
|
|
364
|
+
* @returns {Array<{ name: string, type: 'ui' | 'block' | 'chart', categories: string[], description: string }>}
|
|
365
|
+
*/
|
|
366
|
+
export function uiBlocks(opts = {}, index = loadRegistryIndex()) {
|
|
367
|
+
const want = opts.type || 'blocks';
|
|
368
|
+
const keep = (/** @type {string|null} */ kind) =>
|
|
369
|
+
kind !== null && (
|
|
370
|
+
want === 'all' ? true
|
|
371
|
+
: want === 'blocks' ? kind === 'block' || kind === 'chart'
|
|
372
|
+
: kind === want
|
|
373
|
+
);
|
|
374
|
+
return index
|
|
375
|
+
.map((i) => ({ i, kind: itemKind(i) }))
|
|
376
|
+
.filter(({ i, kind }) => keep(kind) && (!opts.category || (i.categories || []).includes(opts.category)))
|
|
377
|
+
.map(({ i, kind }) => ({
|
|
378
|
+
name: i.name,
|
|
379
|
+
type: /** @type {'ui' | 'block' | 'chart'} */ (kind),
|
|
380
|
+
categories: i.categories || [],
|
|
381
|
+
description: i.description || '',
|
|
382
|
+
}))
|
|
383
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* The blocks and charts as NAME LISTS grouped by {@link primaryCategory}, with
|
|
388
|
+
* no descriptions: `{ blocks: { login: [...] }, charts: { area: [...] } }`.
|
|
389
|
+
* The no-argument MCP `ui` payload carries this, so it stays cheap however
|
|
390
|
+
* many blocks the kit ships.
|
|
391
|
+
*
|
|
392
|
+
* @param {any[]} [index]
|
|
393
|
+
* @returns {{ blocks: Record<string, string[]>, charts: Record<string, string[]> }}
|
|
394
|
+
*/
|
|
395
|
+
export function uiBlockIndex(index = loadRegistryIndex()) {
|
|
396
|
+
/** @type {{ blocks: Record<string, string[]>, charts: Record<string, string[]> }} */
|
|
397
|
+
const out = { blocks: {}, charts: {} };
|
|
398
|
+
for (const b of uiBlocks({}, index)) {
|
|
399
|
+
const group = b.type === 'chart' ? out.charts : out.blocks;
|
|
400
|
+
(group[primaryCategory(b)] ??= []).push(b.name);
|
|
401
|
+
}
|
|
402
|
+
return out;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/** The command that installs a registry item, as every printed hint spells it (invariant 8). */
|
|
406
|
+
export function installCommand(name) {
|
|
407
|
+
return `npx @webjsdev/ui add ${name}`;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Project one block (or chart) item into the agent-facing shape: what it is,
|
|
412
|
+
* how to install it, and the files it writes with their targets. Pure over
|
|
413
|
+
* the item, so `view` can project an item fetched from a custom registry.
|
|
414
|
+
* Returns null when the item is not a block.
|
|
415
|
+
*
|
|
416
|
+
* The sources are left out unless `source` is true, since the cheap path is
|
|
417
|
+
* to install the block and read the files on disk. When included they are
|
|
418
|
+
* BAKED (#1666), so no `cn-*` name reaches an agent, but their imports stay
|
|
419
|
+
* registry-relative: `add` is what rewrites them to the app's aliases.
|
|
420
|
+
*
|
|
421
|
+
* @param {any} item a registry item with its files
|
|
422
|
+
* @param {{ style?: string, source?: boolean }} [opts]
|
|
423
|
+
*/
|
|
424
|
+
export function projectBlock(item, opts = {}) {
|
|
425
|
+
const kind = itemKind(item);
|
|
426
|
+
if (kind !== 'block' && kind !== 'chart') return null;
|
|
427
|
+
return {
|
|
428
|
+
name: item.name,
|
|
429
|
+
type: kind,
|
|
430
|
+
title: item.title || item.name,
|
|
431
|
+
description: item.description || '',
|
|
432
|
+
categories: item.categories || [],
|
|
433
|
+
install: installCommand(item.name),
|
|
434
|
+
dependencies: item.dependencies || [],
|
|
435
|
+
registryDependencies: item.registryDependencies || [],
|
|
436
|
+
...(item.cssVars ? { cssVars: item.cssVars } : {}),
|
|
437
|
+
files: (item.files || []).map((f) => ({
|
|
438
|
+
path: f.path,
|
|
439
|
+
type: f.type,
|
|
440
|
+
target: f.target || f.path,
|
|
441
|
+
...(opts.source ? { content: bakeForStyle(f.content || '', opts.style) } : {}),
|
|
442
|
+
})),
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* {@link projectBlock} for a block in the packaged registry, by name. Null
|
|
448
|
+
* when the name is not a block.
|
|
449
|
+
*
|
|
450
|
+
* @param {string} name
|
|
451
|
+
* @param {{ style?: string, source?: boolean }} [opts]
|
|
452
|
+
*/
|
|
453
|
+
export function uiBlock(name, opts = {}) {
|
|
454
|
+
const item = loadRegistryItem(name);
|
|
455
|
+
return item ? projectBlock(item, opts) : null;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Render a block projection as human-readable text for `webjsui view`: the
|
|
460
|
+
* description, categories, dependencies, the install command and the file
|
|
461
|
+
* list with targets. The sources, when the projection carries them, follow.
|
|
462
|
+
*
|
|
463
|
+
* @param {ReturnType<typeof projectBlock>} b
|
|
464
|
+
* @returns {string}
|
|
465
|
+
*/
|
|
466
|
+
export function renderBlockText(b) {
|
|
467
|
+
if (!b) return '';
|
|
468
|
+
const lines = [`# ${b.name} (${b.type})`];
|
|
469
|
+
if (b.description) lines.push('', b.description);
|
|
470
|
+
if (b.categories.length) lines.push('', `categories: ${b.categories.join(', ')}`);
|
|
471
|
+
if (b.registryDependencies.length) lines.push(`registry deps: ${b.registryDependencies.join(', ')}`);
|
|
472
|
+
if (b.dependencies.length) lines.push(`npm: ${b.dependencies.join(', ')}`);
|
|
473
|
+
lines.push('', `Install: ${b.install}`, '', 'Files:');
|
|
474
|
+
for (const f of b.files) lines.push(` ${f.target}`);
|
|
475
|
+
for (const f of b.files) {
|
|
476
|
+
if (f.content === undefined) continue;
|
|
477
|
+
lines.push('', `# --- ${f.target} ---`, f.content.replace(/\n$/, ''));
|
|
478
|
+
}
|
|
479
|
+
return lines.join('\n');
|
|
480
|
+
}
|
|
481
|
+
|
|
293
482
|
/**
|
|
294
483
|
* Render a component projection as human-readable text for `webjsui view`.
|
|
295
484
|
* Shares the SAME {@link uiComponent} data the MCP `ui` tool returns, so the
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The app's icon library in a resolved install tree (#1666).
|
|
3
|
+
*
|
|
4
|
+
* Registry items depend on `lib-icons` (the Lucide file). The other four
|
|
5
|
+
* libraries export the same function names and land at the same path, so an
|
|
6
|
+
* app whose `components.json` names one of them gets that library's file in
|
|
7
|
+
* place of Lucide's, and a block's icons draw in the library the app chose.
|
|
8
|
+
*
|
|
9
|
+
* @module registry/icons
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { getRegistryItem } from './fetcher.js';
|
|
13
|
+
import { getIconLibrary } from '../../packages/registry/themes/preset.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Replace `lib-icons` in a resolved tree with the item for `iconLibrary`.
|
|
17
|
+
* A tree without `lib-icons`, Lucide, or an unknown library name is
|
|
18
|
+
* returned as it is.
|
|
19
|
+
*
|
|
20
|
+
* @param {any[]} tree the items `resolveTree` returned
|
|
21
|
+
* @param {string | undefined} iconLibrary `components.json` `iconLibrary`
|
|
22
|
+
* @param {string} [registryUrl]
|
|
23
|
+
* @returns {Promise<any[]>}
|
|
24
|
+
*/
|
|
25
|
+
export async function withIconLibrary(tree, iconLibrary, registryUrl) {
|
|
26
|
+
const lib = getIconLibrary(iconLibrary || 'lucide');
|
|
27
|
+
if (!lib || lib.item === 'lib-icons') return tree;
|
|
28
|
+
if (!tree.some((it) => it.name === 'lib-icons')) return tree;
|
|
29
|
+
const chosen = await getRegistryItem(lib.item, registryUrl);
|
|
30
|
+
return tree.map((it) => (it.name === 'lib-icons' ? chosen : it));
|
|
31
|
+
}
|