@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/add.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
import { bakeForStyle } from '../registry/style-bake.js';
|
|
2
3
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
-
import { dirname, join, basename, relative as relPath } from 'node:path';
|
|
4
|
+
import { dirname, join, basename, posix, relative as relPath } from 'node:path';
|
|
4
5
|
import prompts from 'prompts';
|
|
5
6
|
import { execSync } from 'node:child_process';
|
|
6
7
|
import { getConfig } from '../utils/get-config.js';
|
|
7
8
|
import { logger } from '../utils/logger.js';
|
|
8
9
|
import { resolveTree, collectNpmDeps } from '../registry/resolver.js';
|
|
9
|
-
import {
|
|
10
|
+
import { withIconLibrary } from '../registry/icons.js';
|
|
11
|
+
import { DEFAULT_REGISTRY_URL, getRegistryIndex, getRegistryItem } from '../registry/fetcher.js';
|
|
10
12
|
import { isCustomElementSource } from '../registry/local.js';
|
|
11
13
|
import { stripExample } from '../registry/example.js';
|
|
12
14
|
import { ensureTheme } from '../utils/theme.js';
|
|
@@ -36,7 +38,8 @@ export const add = new Command()
|
|
|
36
38
|
process.exit(1);
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
// The icon library is the one components.json names, not always Lucide.
|
|
42
|
+
const tree = await withIconLibrary(await resolveTree(components, opts.registry), config.iconLibrary, opts.registry);
|
|
40
43
|
logger.info(`Installing ${logger.bold(components.join(', '))}…`);
|
|
41
44
|
|
|
42
45
|
// Self-heal missing theme tokens (#983): the helpers render against CSS
|
|
@@ -53,10 +56,42 @@ export const add = new Command()
|
|
|
53
56
|
}
|
|
54
57
|
}
|
|
55
58
|
|
|
59
|
+
const written = [];
|
|
60
|
+
// Block files another block already wrote (two families sharing a
|
|
61
|
+
// target, sidebar-07 then dashboard-01), collected for one summary.
|
|
62
|
+
/** @type {{ file: string, item: string, by: string[] }[]} */
|
|
63
|
+
const conflicts = [];
|
|
64
|
+
/** @type {{ blocks?: any[] }} */
|
|
65
|
+
const blockCache = {};
|
|
56
66
|
for (const item of tree) {
|
|
57
67
|
for (const file of item.files || []) {
|
|
58
|
-
await writeRegistryFile(cwd, config, item, file, opts);
|
|
68
|
+
const out = await writeRegistryFile(cwd, config, item, file, { ...opts, conflicts, blockCache });
|
|
69
|
+
if (out) written.push(out);
|
|
59
70
|
}
|
|
71
|
+
// A block or a component that needs tokens an existing app may lack
|
|
72
|
+
// (sidebar's --sidebar-*, chart's --chart-*) carries them as cssVars,
|
|
73
|
+
// and the missing ones are added to the app's stylesheet (D18).
|
|
74
|
+
if (item.cssVars && tw.css) {
|
|
75
|
+
const added = mergeCssVars(cwd, tw.css, item.cssVars);
|
|
76
|
+
if (added > 0) logger.success(`Added ${added} theme token${added === 1 ? '' : 's'} for ${item.name} to ${tw.css}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (written.length) {
|
|
80
|
+
logger.info('Files written:');
|
|
81
|
+
for (const f of written) logger.info(` ${f}`);
|
|
82
|
+
}
|
|
83
|
+
if (conflicts.length) {
|
|
84
|
+
const names = [...new Set(conflicts.map((c) => c.item))];
|
|
85
|
+
const others = [...new Set(conflicts.flatMap((c) => c.by))];
|
|
86
|
+
logger.warn(
|
|
87
|
+
`${conflicts.length} file${conflicts.length === 1 ? '' : 's'} of ${names.join(', ')} ` +
|
|
88
|
+
`${conflicts.length === 1 ? 'was' : 'were'} kept from ${others.join(', ')}, so the app mixes the blocks:`,
|
|
89
|
+
);
|
|
90
|
+
for (const c of conflicts) logger.warn(` ${c.file} (from ${c.by.join(', ')})`);
|
|
91
|
+
logger.warn(
|
|
92
|
+
`Run ${logger.cyan(`npx @webjsdev/ui add ${names.join(' ')} --overwrite`)} to replace them with ${names.join(', ')}'s version ` +
|
|
93
|
+
'(it also replaces every kit component and helper the install writes, so commit your edits first).',
|
|
94
|
+
);
|
|
60
95
|
}
|
|
61
96
|
|
|
62
97
|
if (opts.deps !== false) {
|
|
@@ -64,8 +99,13 @@ export const add = new Command()
|
|
|
64
99
|
// @webjsdev/core is always a runtime dep
|
|
65
100
|
if (!dependencies.includes('@webjsdev/core')) dependencies.push('@webjsdev/core');
|
|
66
101
|
|
|
67
|
-
|
|
68
|
-
|
|
102
|
+
// Install only what the app does not already declare. Most components need
|
|
103
|
+
// nothing beyond @webjsdev/core, which every WebJs app has, and re-installing
|
|
104
|
+
// it ran a full install and rewrote the app's version range on every add.
|
|
105
|
+
const missing = undeclaredDeps(cwd, dependencies);
|
|
106
|
+
const missingDev = undeclaredDeps(cwd, devDependencies);
|
|
107
|
+
if (missing.length) await installDeps(cwd, missing, false);
|
|
108
|
+
if (missingDev.length) await installDeps(cwd, missingDev, true);
|
|
69
109
|
}
|
|
70
110
|
|
|
71
111
|
logger.success('Done.');
|
|
@@ -82,7 +122,31 @@ async function writeRegistryFile(cwd, config, item, file, opts) {
|
|
|
82
122
|
// replace edited source on every `add`. Only an explicit `--overwrite` may.
|
|
83
123
|
if (existsSync(target) && !opts.overwrite && helperTarget(config, item, file)) {
|
|
84
124
|
logger.info(`${relative(cwd, target)} already exists: keeping it.`);
|
|
85
|
-
return;
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// A block's files are app code the user owns (a page, a module), so `--yes`
|
|
129
|
+
// does not license replacing one: only `--overwrite` does (D18). Keeping it
|
|
130
|
+
// silently is wrong when ANOTHER block wrote it (two block families share
|
|
131
|
+
// targets such as components/app-sidebar.ts), since the app then mixes the
|
|
132
|
+
// two, so the existing file is compared against what this block and every
|
|
133
|
+
// other block would write there, and a match with another block is a
|
|
134
|
+
// warning that names it.
|
|
135
|
+
if (existsSync(target) && !opts.overwrite && isBlock(item, file)) {
|
|
136
|
+
const rel = relative(cwd, target);
|
|
137
|
+
const local = readFileSync(target, 'utf8');
|
|
138
|
+
if (local === transformForProject(file.content || '', target, config, item, { file, cwd })) {
|
|
139
|
+
logger.info(`${rel} is already ${item.name}'s version: keeping it.`);
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
const by = await otherBlockWriters(cwd, config, item, target, local, opts);
|
|
143
|
+
if (by.length) {
|
|
144
|
+
logger.warn(`${rel} was written by ${by.join(', ')}, not ${item.name}: keeping it (pass --overwrite to replace it).`);
|
|
145
|
+
opts.conflicts?.push({ file: rel, item: item.name, by });
|
|
146
|
+
} else {
|
|
147
|
+
logger.info(`${rel} already exists and differs from ${item.name}'s version: keeping it (pass --overwrite to replace it).`);
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
86
150
|
}
|
|
87
151
|
|
|
88
152
|
if (existsSync(target) && !opts.overwrite && !opts.yes) {
|
|
@@ -94,20 +158,67 @@ async function writeRegistryFile(cwd, config, item, file, opts) {
|
|
|
94
158
|
});
|
|
95
159
|
if (!r.overwrite) {
|
|
96
160
|
logger.info(`Skipped ${basename(target)}`);
|
|
97
|
-
return;
|
|
161
|
+
return null;
|
|
98
162
|
}
|
|
99
163
|
}
|
|
100
164
|
|
|
101
|
-
const content = transformForProject(file.content || '', target, config, item);
|
|
165
|
+
const content = transformForProject(file.content || '', target, config, item, { file, cwd });
|
|
102
166
|
writeFileSync(target, content, 'utf8');
|
|
103
167
|
logger.success(`Wrote ${relative(cwd, target)}`);
|
|
168
|
+
return relative(cwd, target);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* The OTHER blocks whose file at `target` is exactly `local`, by name: what
|
|
173
|
+
* `add` would have written for each of them there (the same transform, so a
|
|
174
|
+
* baked, import-rewritten file still matches). The registry's blocks are
|
|
175
|
+
* loaded once per `add` run, and only when a block file already exists.
|
|
176
|
+
*
|
|
177
|
+
* @param {string} cwd
|
|
178
|
+
* @param {any} config
|
|
179
|
+
* @param {{ name: string }} item the block being installed
|
|
180
|
+
* @param {string} target absolute path of the existing file
|
|
181
|
+
* @param {string} local its content
|
|
182
|
+
* @param {{ registry?: string, blockCache?: { blocks?: any[] } }} opts
|
|
183
|
+
* @returns {Promise<string[]>}
|
|
184
|
+
*/
|
|
185
|
+
async function otherBlockWriters(cwd, config, item, target, local, opts) {
|
|
186
|
+
const cache = opts.blockCache ?? {};
|
|
187
|
+
if (!cache.blocks) {
|
|
188
|
+
cache.blocks = [];
|
|
189
|
+
try {
|
|
190
|
+
const index = await getRegistryIndex(opts.registry);
|
|
191
|
+
for (const entry of index.filter((i) => i.type === 'registry:block')) {
|
|
192
|
+
cache.blocks.push(await getRegistryItem(entry.name, opts.registry));
|
|
193
|
+
}
|
|
194
|
+
} catch {
|
|
195
|
+
// An index that cannot be read only costs the warning its block name.
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const by = [];
|
|
199
|
+
for (const other of cache.blocks) {
|
|
200
|
+
if (other.name === item.name) continue;
|
|
201
|
+
const match = (other.files || []).some((f) =>
|
|
202
|
+
resolveTarget(cwd, config, other, f) === target &&
|
|
203
|
+
transformForProject(f.content || '', target, config, other, { file: f, cwd }) === local);
|
|
204
|
+
if (match) by.push(other.name);
|
|
205
|
+
}
|
|
206
|
+
return by;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function isBlock(item, file) {
|
|
210
|
+
return item?.type === 'registry:block' || file?.type === 'registry:block';
|
|
104
211
|
}
|
|
105
212
|
|
|
106
213
|
/**
|
|
107
214
|
* The single transform that turns a registry file's raw content into what
|
|
108
215
|
* lands in the user's project. `add` writes this; `diff` compares against it,
|
|
109
|
-
* so the two cannot disagree (#983).
|
|
216
|
+
* so the two cannot disagree (#983). Three steps:
|
|
110
217
|
*
|
|
218
|
+
* 0. Bake the style (#1666): a registry file in base form carries semantic
|
|
219
|
+
* `cn-*` names, which are replaced by the Tailwind classes of the style
|
|
220
|
+
* `components.json` names (`new-york` when it names none), so the file an
|
|
221
|
+
* app owns is plain Tailwind. A file with no `cn-*` name is untouched.
|
|
111
222
|
* 1. Retarget the registry-relative `../lib/utils.ts` / `../lib/dom.ts` imports
|
|
112
223
|
* to the project's resolved helper paths (see {@link rewriteUtilsImport}).
|
|
113
224
|
* 2. For a Tier-1 helper component (a `registry:ui` file that is NOT a custom
|
|
@@ -118,12 +229,15 @@ async function writeRegistryFile(cwd, config, item, file, opts) {
|
|
|
118
229
|
*
|
|
119
230
|
* @param {string} content raw registry file content
|
|
120
231
|
* @param {string} target absolute path where the file will be written
|
|
121
|
-
* @param {{ resolvedPaths: { utils: string } }} config parsed components.json
|
|
232
|
+
* @param {{ resolvedPaths: { utils: string }, style?: string }} config parsed components.json
|
|
122
233
|
* @param {{ name: string, type?: string }} [item] the registry item
|
|
123
234
|
* @returns {string}
|
|
124
235
|
*/
|
|
125
|
-
export function transformForProject(content, target, config, item) {
|
|
126
|
-
let out =
|
|
236
|
+
export function transformForProject(content, target, config, item, where = {}) {
|
|
237
|
+
let out = bakeForStyle(content, config?.style);
|
|
238
|
+
out = where.file?.path && where.cwd
|
|
239
|
+
? rewriteRegistryImports(out, where.file.path, target, config, where.cwd, item)
|
|
240
|
+
: rewriteUtilsImport(out, target, config);
|
|
127
241
|
if (item && item.type === 'registry:ui' && !isCustomElementSource(content)) {
|
|
128
242
|
out = stripExample(out, item.name);
|
|
129
243
|
}
|
|
@@ -160,6 +274,100 @@ export function rewriteUtilsImport(content, target, config) {
|
|
|
160
274
|
return out;
|
|
161
275
|
}
|
|
162
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Rewrite every registry-relative import in a file to the path that resolves
|
|
279
|
+
* from where the file lands in the app (D18). Each relative specifier is
|
|
280
|
+
* resolved against the file's own registry path, then mapped to where THAT
|
|
281
|
+
* registry file lands:
|
|
282
|
+
*
|
|
283
|
+
* - another file of the same item (a block's page importing its own
|
|
284
|
+
* component) lands at its own target;
|
|
285
|
+
* - `lib/utils.ts` and `lib/dom.ts` land at the utils alias and beside it,
|
|
286
|
+
* as {@link rewriteUtilsImport} has always done (and `lib/icons.ts` beside
|
|
287
|
+
* them too);
|
|
288
|
+
* - a component (`components/<name>.ts`) lands in the ui alias directory.
|
|
289
|
+
*
|
|
290
|
+
* Anything else is left as written. This is the general form of the two
|
|
291
|
+
* fixed literals {@link rewriteUtilsImport} rewrites, which a block, whose
|
|
292
|
+
* files sit at other depths and import components and each other, needs.
|
|
293
|
+
*
|
|
294
|
+
* @param {string} content
|
|
295
|
+
* @param {string} fromPath the file's path inside the registry
|
|
296
|
+
* @param {string} target absolute path where the file is written
|
|
297
|
+
* @param {object} config parsed components.json
|
|
298
|
+
* @param {string} cwd the project root
|
|
299
|
+
* @param {{ files?: { path: string }[] }} [item] the item the file belongs to
|
|
300
|
+
*/
|
|
301
|
+
export function rewriteRegistryImports(content, fromPath, target, config, cwd, item) {
|
|
302
|
+
const utilsAbs = config?.resolvedPaths?.utils;
|
|
303
|
+
const uiDir = config?.resolvedPaths?.ui ?? join(cwd, (config?.aliases?.ui || 'components/ui').replace(/^@\//, ''));
|
|
304
|
+
const own = new Map((item?.files || []).map((f) => [posix.normalize(f.path), f]));
|
|
305
|
+
const destOf = (regPath) => {
|
|
306
|
+
if (own.has(regPath) && regPath !== posix.normalize(fromPath)) return resolveTarget(cwd, config, item, own.get(regPath));
|
|
307
|
+
if (utilsAbs && regPath === 'lib/utils.ts') return utilsAbs;
|
|
308
|
+
if (utilsAbs && (regPath === 'lib/dom.ts' || regPath === 'lib/icons.ts')) return join(dirname(utilsAbs), posix.basename(regPath));
|
|
309
|
+
if (regPath.startsWith('components/') && !regPath.slice('components/'.length).includes('/')) return join(uiDir, posix.basename(regPath));
|
|
310
|
+
return null;
|
|
311
|
+
};
|
|
312
|
+
return content.replace(/((?:from|import)\s*\(?\s*)(['"])(\.{1,2}\/[^'"]+)\2/g, (whole, lead, q, spec) => {
|
|
313
|
+
const regPath = posix.normalize(posix.join(posix.dirname(fromPath), spec));
|
|
314
|
+
const dest = destOf(regPath);
|
|
315
|
+
if (!dest) return whole;
|
|
316
|
+
let rel = relPath(dirname(target), dest).split(/[\\/]/).join('/');
|
|
317
|
+
if (!rel.startsWith('.')) rel = './' + rel;
|
|
318
|
+
return `${lead}${q}${rel}${q}`;
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Add the CSS variables an item carries to the app's stylesheet, leaving
|
|
324
|
+
* every one the app already defines as it is. `light` goes in the `:root`
|
|
325
|
+
* block, `dark` in `.dark`, and `theme` in `@theme inline`, which is where
|
|
326
|
+
* the kit's theme puts each. A missing block is appended. Returns how many
|
|
327
|
+
* variables were added.
|
|
328
|
+
*
|
|
329
|
+
* @param {string} cwd
|
|
330
|
+
* @param {string} cssPath the app's stylesheet, relative to cwd
|
|
331
|
+
* @param {{ theme?: Record<string, string>, light?: Record<string, string>, dark?: Record<string, string> }} cssVars
|
|
332
|
+
*/
|
|
333
|
+
export function mergeCssVars(cwd, cssPath, cssVars) {
|
|
334
|
+
const file = join(cwd, cssPath);
|
|
335
|
+
let css = existsSync(file) ? readFileSync(file, 'utf8') : '';
|
|
336
|
+
let added = 0;
|
|
337
|
+
const groups = [
|
|
338
|
+
['@theme inline', cssVars.theme],
|
|
339
|
+
[':root', cssVars.light],
|
|
340
|
+
['.dark', cssVars.dark],
|
|
341
|
+
];
|
|
342
|
+
for (const [selector, vars] of groups) {
|
|
343
|
+
const entries = Object.entries(vars || {});
|
|
344
|
+
if (!entries.length) continue;
|
|
345
|
+
// A token counts as present only inside ITS block: a light value in
|
|
346
|
+
// :root says nothing about the dark one .dark still needs.
|
|
347
|
+
const open = css.indexOf(`${selector} {`);
|
|
348
|
+
const body = open >= 0 ? css.slice(open, css.indexOf('}', open)) : '';
|
|
349
|
+
const missing = entries.filter(([name]) => !new RegExp(`--${escapeRe(name)}\\s*:`).test(body));
|
|
350
|
+
if (!missing.length) continue;
|
|
351
|
+
const lines = missing.map(([name, value]) => ` --${name}: ${value};`).join('\n');
|
|
352
|
+
if (open >= 0) {
|
|
353
|
+
const close = css.indexOf('}', open);
|
|
354
|
+
css = `${css.slice(0, close).replace(/\s*$/, '')}\n${lines}\n${css.slice(close)}`;
|
|
355
|
+
} else {
|
|
356
|
+
css = `${css.replace(/\s*$/, '')}\n\n${selector} {\n${lines}\n}\n`;
|
|
357
|
+
}
|
|
358
|
+
added += missing.length;
|
|
359
|
+
}
|
|
360
|
+
if (added) {
|
|
361
|
+
ensureDir(dirname(file));
|
|
362
|
+
writeFileSync(file, css, 'utf8');
|
|
363
|
+
}
|
|
364
|
+
return added;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function escapeRe(s) {
|
|
368
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
369
|
+
}
|
|
370
|
+
|
|
163
371
|
/**
|
|
164
372
|
* Replace a single registry-relative import specifier with the relative path
|
|
165
373
|
* from `target`'s directory to `destAbs`. No-op when `spec` is absent.
|
|
@@ -178,7 +386,19 @@ function replaceImportSpecifier(content, spec, destAbs, target) {
|
|
|
178
386
|
.replaceAll(`"${spec}"`, `"${rel}"`);
|
|
179
387
|
}
|
|
180
388
|
|
|
181
|
-
|
|
389
|
+
/**
|
|
390
|
+
* The absolute path a registry file is written to: the helper alias for the
|
|
391
|
+
* shared helpers, else the file's own `target`, else a folder picked by the
|
|
392
|
+
* file's type. `diff` reads the same answer, so it compares the file `add`
|
|
393
|
+
* would have written.
|
|
394
|
+
*
|
|
395
|
+
* @param {string} cwd
|
|
396
|
+
* @param {any} config parsed components.json
|
|
397
|
+
* @param {any} item the registry item
|
|
398
|
+
* @param {{ path: string, type?: string, target?: string }} file
|
|
399
|
+
* @returns {string}
|
|
400
|
+
*/
|
|
401
|
+
export function resolveTarget(cwd, config, item, file) {
|
|
182
402
|
// The two shared helpers are pinned to `lib/utils.ts` / `lib/dom.ts` by the
|
|
183
403
|
// registry manifest, but where they actually BELONG is wherever the project's
|
|
184
404
|
// `utils` alias points, because that is the path `rewriteUtilsImport` writes
|
|
@@ -205,6 +425,11 @@ function resolveTarget(cwd, config, item, file) {
|
|
|
205
425
|
return join(cwd, (aliases.lib || 'lib').replace(/^@\//, ''), fileName);
|
|
206
426
|
case 'registry:hook':
|
|
207
427
|
return join(cwd, 'hooks', fileName);
|
|
428
|
+
case 'registry:block':
|
|
429
|
+
// Every shipped block file names its target (a registry test enforces
|
|
430
|
+
// it). A custom registry's block that does not keeps its path, so two
|
|
431
|
+
// files called page.ts cannot land on one another.
|
|
432
|
+
return join(cwd, file.path);
|
|
208
433
|
default:
|
|
209
434
|
return join(cwd, fileName);
|
|
210
435
|
}
|
|
@@ -236,6 +461,10 @@ function helperTarget(config, item, file) {
|
|
|
236
461
|
const name = basename(file.path || '');
|
|
237
462
|
if (item.name === 'lib-utils' && name === 'utils.ts') return utilsAbs;
|
|
238
463
|
if (item.name === 'lib-dom' && name === 'dom.ts') return join(dirname(utilsAbs), 'dom.ts');
|
|
464
|
+
// Every icon library (lib-icons, lib-icons-tabler, ...) is the SAME file in
|
|
465
|
+
// an app, the utils file's sibling `icons.ts`, which is where a block's
|
|
466
|
+
// `../lib/icons.ts` import is rewritten to (#1666).
|
|
467
|
+
if (/^lib-icons(-|$)/.test(item.name) && /^icons(-[a-z]+)?\.ts$/.test(name)) return join(dirname(utilsAbs), 'icons.ts');
|
|
239
468
|
return null;
|
|
240
469
|
}
|
|
241
470
|
|
|
@@ -247,6 +476,29 @@ function ensureDir(d) {
|
|
|
247
476
|
if (!existsSync(d)) mkdirSync(d, { recursive: true });
|
|
248
477
|
}
|
|
249
478
|
|
|
479
|
+
/**
|
|
480
|
+
* The dependency specs (`name` or `name@range`) that the app's package.json does
|
|
481
|
+
* not already declare in any dependency field. A missing or unreadable
|
|
482
|
+
* package.json declares nothing, so every spec is returned.
|
|
483
|
+
* @param {string} cwd
|
|
484
|
+
* @param {string[]} specs
|
|
485
|
+
* @returns {string[]}
|
|
486
|
+
*/
|
|
487
|
+
export function undeclaredDeps(cwd, specs) {
|
|
488
|
+
let pkg = {};
|
|
489
|
+
try { pkg = JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8')); } catch {}
|
|
490
|
+
const declared = new Set();
|
|
491
|
+
for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
|
|
492
|
+
for (const name of Object.keys(pkg?.[field] || {})) declared.add(name);
|
|
493
|
+
}
|
|
494
|
+
// A scoped name starts with @, so the version separator is the LAST @ past it.
|
|
495
|
+
const nameOf = (spec) => {
|
|
496
|
+
const at = spec.lastIndexOf('@');
|
|
497
|
+
return at > 0 ? spec.slice(0, at) : spec;
|
|
498
|
+
};
|
|
499
|
+
return specs.filter((spec) => !declared.has(nameOf(spec)));
|
|
500
|
+
}
|
|
501
|
+
|
|
250
502
|
async function installDeps(cwd, deps, dev) {
|
|
251
503
|
const manager = detectAddCommand(cwd);
|
|
252
504
|
const flag = dev ? '-D' : '';
|
package/src/commands/diff.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
-
import { join, basename } from 'node:path';
|
|
4
3
|
import { getConfig } from '../utils/get-config.js';
|
|
5
4
|
import { fetchRegistryItem, fetchRegistryIndex, DEFAULT_REGISTRY_URL } from '../registry/fetcher.js';
|
|
6
|
-
import { transformForProject } from './add.js';
|
|
5
|
+
import { transformForProject, resolveTarget } from './add.js';
|
|
7
6
|
import { logger } from '../utils/logger.js';
|
|
8
7
|
|
|
9
8
|
export const diff = new Command()
|
|
10
9
|
.name('diff')
|
|
11
|
-
.description('Show differences between local components and the registry')
|
|
12
|
-
.argument('[name]', 'component to diff (omit to show all out-of-date)')
|
|
10
|
+
.description('Show differences between local components or blocks and the registry')
|
|
11
|
+
.argument('[name]', 'component or block to diff (omit to show all out-of-date)')
|
|
13
12
|
.option('-c, --cwd <cwd>', 'the working directory', process.cwd())
|
|
14
13
|
.option('--registry <url>', 'registry base URL', DEFAULT_REGISTRY_URL)
|
|
15
14
|
.action(async (name, opts) => {
|
|
@@ -22,35 +21,50 @@ export const diff = new Command()
|
|
|
22
21
|
// diff compares local files against the LIVE upstream, so it stays on the
|
|
23
22
|
// network path (NOT local-first): local-first would compare the package
|
|
24
23
|
// against itself. Resolve the names to compare, then fetch each item's full
|
|
25
|
-
// content (the index is metadata-only).
|
|
24
|
+
// content (the index is metadata-only). Installed blocks are compared too
|
|
25
|
+
// (D18).
|
|
26
26
|
let names;
|
|
27
27
|
if (name) {
|
|
28
28
|
names = [name];
|
|
29
29
|
} else {
|
|
30
30
|
const index = await fetchRegistryIndex(opts.registry);
|
|
31
|
-
names = index.filter((i) => i.type === 'registry:ui').map((i) => i.name);
|
|
31
|
+
names = index.filter((i) => i.type === 'registry:ui' || i.type === 'registry:block').map((i) => i.name);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
// Grouped by the file on disk, not by item: several blocks can write the
|
|
35
|
+
// same target (every login block writes app/login/page.ts), so a file is
|
|
36
|
+
// up to date when it matches ANY item that writes it, and is reported
|
|
37
|
+
// once otherwise.
|
|
38
|
+
/** @type {Map<string, { items: string[], expected: string[] }>} */
|
|
39
|
+
const byTarget = new Map();
|
|
37
40
|
for (const n of names) {
|
|
38
41
|
const item = await fetchRegistryItem(n, opts.registry);
|
|
39
42
|
for (const file of item.files || []) {
|
|
40
|
-
|
|
43
|
+
// The path `add` writes, so the two cannot disagree (#983).
|
|
44
|
+
const target = resolveTarget(opts.cwd, config, item, file);
|
|
41
45
|
if (!existsSync(target)) continue;
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
46
|
+
// Compare against what `add` WOULD write (bake, import rewrite and
|
|
47
|
+
// example strip), not the raw registry content: otherwise a pristine
|
|
48
|
+
// install reports every import-rewritten file as differing (#983).
|
|
49
|
+
const expected = transformForProject(file.content || '', target, config, item, { file, cwd: opts.cwd });
|
|
50
|
+
const entry = byTarget.get(target) ?? { items: [], expected: [] };
|
|
51
|
+
entry.items.push(item.name);
|
|
52
|
+
entry.expected.push(expected);
|
|
53
|
+
byTarget.set(target, entry);
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
let changed = 0;
|
|
58
|
+
for (const [target, { items, expected }] of byTarget) {
|
|
59
|
+
const local = readFileSync(target, 'utf8');
|
|
60
|
+
if (expected.includes(local)) continue;
|
|
61
|
+
const rel = target.startsWith(opts.cwd) ? target.slice(opts.cwd.length + 1) : target;
|
|
62
|
+
logger.info(items.length === 1
|
|
63
|
+
? `${logger.bold(items[0])}: ${rel} differs from registry`
|
|
64
|
+
: `${rel} differs from every item that writes it (${items.join(', ')})`);
|
|
65
|
+
changed++;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (changed === 0) logger.success('All local components and blocks match the registry.');
|
|
55
69
|
else logger.info(`\n${changed} file${changed === 1 ? '' : 's'} differ. Re-add with ${logger.cyan('npx @webjsdev/ui add <name> -o')} to overwrite.`);
|
|
56
70
|
});
|
package/src/commands/info.js
CHANGED
|
@@ -3,6 +3,8 @@ import { existsSync } from 'node:fs';
|
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { getConfig } from '../utils/get-config.js';
|
|
5
5
|
import { DEFAULT_REGISTRY_URL } from '../registry/fetcher.js';
|
|
6
|
+
import { loadRegistryIndex } from '../registry/local.js';
|
|
7
|
+
import { itemKind } from '../registry/extract.js';
|
|
6
8
|
import { logger } from '../utils/logger.js';
|
|
7
9
|
|
|
8
10
|
export const info = new Command()
|
|
@@ -15,6 +17,11 @@ export const info = new Command()
|
|
|
15
17
|
|
|
16
18
|
logger.info(`${logger.bold('cwd')} ${cwd}`);
|
|
17
19
|
logger.info(`${logger.bold('Registry')} ${DEFAULT_REGISTRY_URL}`);
|
|
20
|
+
// What the installed kit ships (the packaged registry `add` reads), with
|
|
21
|
+
// the blocks and charts counted beside the components (D18).
|
|
22
|
+
const kinds = loadRegistryIndex().map(itemKind);
|
|
23
|
+
const count = (k) => kinds.filter((x) => x === k).length;
|
|
24
|
+
logger.info(`${logger.bold('Kit')} ${count('ui')} components, ${count('block')} blocks, ${count('chart')} charts`);
|
|
18
25
|
logger.info(`${logger.bold('Config')} ${config ? 'components.json ✔' : 'components.json ✖ (run `npx @webjsdev/ui init`)'}`);
|
|
19
26
|
if (config) {
|
|
20
27
|
logger.info(`${logger.bold('Base color')} ${config.tailwind.baseColor}`);
|