@vamos-ui/react 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +27 -2
- package/dist/blocks/block-heading.d.ts +29 -0
- package/dist/blocks/block-heading.js +39 -0
- package/dist/blocks/block-image.d.ts +52 -0
- package/dist/blocks/block-image.js +48 -0
- package/dist/blocks/block-link.d.ts +30 -0
- package/dist/blocks/block-link.js +36 -0
- package/dist/blocks/create-blocks.d.ts +54 -0
- package/dist/blocks/create-blocks.js +52 -0
- package/dist/blocks/index.d.ts +55 -0
- package/dist/blocks/index.js +59 -0
- package/dist/blocks/json-ld.d.ts +18 -0
- package/dist/blocks/json-ld.js +44 -0
- package/dist/blocks/labels.d.ts +20 -0
- package/dist/blocks/labels.js +43 -0
- package/dist/blocks/rich-text.d.ts +36 -0
- package/dist/blocks/rich-text.js +106 -0
- package/dist/blocks/schema/define-block.d.ts +151 -0
- package/dist/blocks/schema/define-block.js +120 -0
- package/dist/blocks/schema/emphasis.d.ts +17 -0
- package/dist/blocks/schema/emphasis.js +69 -0
- package/dist/blocks/schema/fields.d.ts +497 -0
- package/dist/blocks/schema/fields.js +240 -0
- package/dist/blocks/schema/icons.d.ts +2 -0
- package/dist/blocks/schema/icons.js +26 -0
- package/dist/blocks/schema/index.d.ts +18 -0
- package/dist/blocks/schema/index.js +21 -0
- package/dist/blocks/schema/lint-types.d.ts +16 -0
- package/dist/blocks/schema/lint-types.js +2 -0
- package/dist/blocks/schema/lint.d.ts +32 -0
- package/dist/blocks/schema/lint.js +164 -0
- package/dist/blocks/schema/localize.d.ts +20 -0
- package/dist/blocks/schema/localize.js +29 -0
- package/dist/blocks/schema/localized.d.ts +25 -0
- package/dist/blocks/schema/localized.js +53 -0
- package/dist/blocks/schema/migrate.d.ts +24 -0
- package/dist/blocks/schema/migrate.js +75 -0
- package/dist/blocks/schema/nodes.d.ts +196 -0
- package/dist/blocks/schema/nodes.js +78 -0
- package/dist/blocks/schema/rich-doc-schema.d.ts +32 -0
- package/dist/blocks/schema/rich-doc-schema.js +66 -0
- package/dist/blocks/schema/rich-doc.d.ts +90 -0
- package/dist/blocks/schema/rich-doc.js +62 -0
- package/dist/blocks/schema/safety.d.ts +20 -0
- package/dist/blocks/schema/safety.js +49 -0
- package/dist/blocks/schema/types.d.ts +172 -0
- package/dist/blocks/schema/types.js +3 -0
- package/dist/blocks/schema/validate.d.ts +17 -0
- package/dist/blocks/schema/validate.js +32 -0
- package/dist/blocks/schema/walk.d.ts +22 -0
- package/dist/blocks/schema/walk.js +60 -0
- package/dist/blocks/section-header.d.ts +38 -0
- package/dist/blocks/section-header.js +22 -0
- package/dist/blocks/section.d.ts +59 -0
- package/dist/blocks/section.js +66 -0
- package/dist/blocks/site/_kit-1.d.ts +100 -0
- package/dist/blocks/site/_kit-1.js +135 -0
- package/dist/blocks/site/_site-icon-1.d.ts +6 -0
- package/dist/blocks/site/_site-icon-1.js +15 -0
- package/dist/blocks/site/announcement-bar.d.ts +42 -0
- package/dist/blocks/site/announcement-bar.js +38 -0
- package/dist/blocks/site/announcement-dismiss.d.ts +18 -0
- package/dist/blocks/site/announcement-dismiss.js +28 -0
- package/dist/blocks/site/article-layout.d.ts +65 -0
- package/dist/blocks/site/article-layout.js +88 -0
- package/dist/blocks/site/blog-list.d.ts +79 -0
- package/dist/blocks/site/blog-list.js +78 -0
- package/dist/blocks/site/comparison-table.d.ts +54 -0
- package/dist/blocks/site/comparison-table.js +38 -0
- package/dist/blocks/site/consent-banner.d.ts +52 -0
- package/dist/blocks/site/consent-banner.js +33 -0
- package/dist/blocks/site/contact-dock.d.ts +52 -0
- package/dist/blocks/site/contact-dock.js +55 -0
- package/dist/blocks/site/contact-form.d.ts +60 -0
- package/dist/blocks/site/contact-form.js +45 -0
- package/dist/blocks/site/cta-booking.d.ts +43 -0
- package/dist/blocks/site/cta-booking.js +69 -0
- package/dist/blocks/site/cta.d.ts +74 -0
- package/dist/blocks/site/cta.js +112 -0
- package/dist/blocks/site/embed-facade.d.ts +20 -0
- package/dist/blocks/site/embed-facade.js +21 -0
- package/dist/blocks/site/faq.d.ts +48 -0
- package/dist/blocks/site/faq.js +51 -0
- package/dist/blocks/site/feature-grid.d.ts +46 -0
- package/dist/blocks/site/feature-grid.js +49 -0
- package/dist/blocks/site/feature-tabs.d.ts +22 -0
- package/dist/blocks/site/feature-tabs.js +11 -0
- package/dist/blocks/site/footer.d.ts +68 -0
- package/dist/blocks/site/footer.js +61 -0
- package/dist/blocks/site/gallery-section.d.ts +42 -0
- package/dist/blocks/site/gallery-section.js +47 -0
- package/dist/blocks/site/hero-video.d.ts +15 -0
- package/dist/blocks/site/hero-video.js +31 -0
- package/dist/blocks/site/hero.d.ts +64 -0
- package/dist/blocks/site/hero.js +67 -0
- package/dist/blocks/site/logo-strip.d.ts +42 -0
- package/dist/blocks/site/logo-strip.js +26 -0
- package/dist/blocks/site/map-hours.d.ts +83 -0
- package/dist/blocks/site/map-hours.js +125 -0
- package/dist/blocks/site/media-text.d.ts +45 -0
- package/dist/blocks/site/media-text.js +55 -0
- package/dist/blocks/site/menu-list.d.ts +74 -0
- package/dist/blocks/site/menu-list.js +84 -0
- package/dist/blocks/site/navbar-submenu.d.ts +18 -0
- package/dist/blocks/site/navbar-submenu.js +51 -0
- package/dist/blocks/site/navbar.d.ts +67 -0
- package/dist/blocks/site/navbar.js +64 -0
- package/dist/blocks/site/not-found.d.ts +40 -0
- package/dist/blocks/site/not-found.js +38 -0
- package/dist/blocks/site/page-intro.d.ts +46 -0
- package/dist/blocks/site/page-intro.js +44 -0
- package/dist/blocks/site/pricing-table.d.ts +67 -0
- package/dist/blocks/site/pricing-table.js +82 -0
- package/dist/blocks/site/process.d.ts +36 -0
- package/dist/blocks/site/process.js +41 -0
- package/dist/blocks/site/registry-1.d.ts +720 -0
- package/dist/blocks/site/registry-1.js +783 -0
- package/dist/blocks/site/registry-2.d.ts +914 -0
- package/dist/blocks/site/registry-2.js +563 -0
- package/dist/blocks/site/rich-text-section.d.ts +34 -0
- package/dist/blocks/site/rich-text-section.js +32 -0
- package/dist/blocks/site/shared/brand-icons.d.ts +21 -0
- package/dist/blocks/site/shared/brand-icons.js +56 -0
- package/dist/blocks/site/shared/consent-gate.d.ts +41 -0
- package/dist/blocks/site/shared/consent-gate.js +43 -0
- package/dist/blocks/site/shared/consent-island.d.ts +38 -0
- package/dist/blocks/site/shared/consent-island.js +63 -0
- package/dist/blocks/site/shared/consent.d.ts +49 -0
- package/dist/blocks/site/shared/consent.js +130 -0
- package/dist/blocks/site/shared/contact-form-island.d.ts +41 -0
- package/dist/blocks/site/shared/contact-form-island.js +100 -0
- package/dist/blocks/site/shared/copy-link.d.ts +10 -0
- package/dist/blocks/site/shared/copy-link.js +25 -0
- package/dist/blocks/site/shared/dock-avoid.d.ts +15 -0
- package/dist/blocks/site/shared/dock-avoid.js +107 -0
- package/dist/blocks/site/shared/dock-hours.d.ts +13 -0
- package/dist/blocks/site/shared/dock-hours.js +25 -0
- package/dist/blocks/site/shared/gallery-lightbox.d.ts +12 -0
- package/dist/blocks/site/shared/gallery-lightbox.js +10 -0
- package/dist/blocks/site/shared/island-keys.d.ts +10 -0
- package/dist/blocks/site/shared/island-keys.js +44 -0
- package/dist/blocks/site/shared/kit-2.d.ts +55 -0
- package/dist/blocks/site/shared/kit-2.js +84 -0
- package/dist/blocks/site/shared/labels-2.d.ts +209 -0
- package/dist/blocks/site/shared/labels-2.js +427 -0
- package/dist/blocks/site/shared/open-now.d.ts +22 -0
- package/dist/blocks/site/shared/open-now.js +27 -0
- package/dist/blocks/site/shared/opening-hours.d.ts +117 -0
- package/dist/blocks/site/shared/opening-hours.js +245 -0
- package/dist/blocks/site/shared/site-accent.d.ts +48 -0
- package/dist/blocks/site/shared/site-accent.js +249 -0
- package/dist/blocks/site/shared/site-form.d.ts +79 -0
- package/dist/blocks/site/shared/site-form.js +111 -0
- package/dist/blocks/site/shared/site-routing.d.ts +54 -0
- package/dist/blocks/site/shared/site-routing.js +86 -0
- package/dist/blocks/site/shared/testimonials-carousel.d.ts +17 -0
- package/dist/blocks/site/shared/testimonials-carousel.js +64 -0
- package/dist/blocks/site/site-shell.d.ts +97 -0
- package/dist/blocks/site/site-shell.js +227 -0
- package/dist/blocks/site/stats-band.d.ts +40 -0
- package/dist/blocks/site/stats-band.js +41 -0
- package/dist/blocks/site/team.d.ts +44 -0
- package/dist/blocks/site/team.js +48 -0
- package/dist/blocks/site/testimonials.d.ts +68 -0
- package/dist/blocks/site/testimonials.js +65 -0
- package/dist/blocks/types.d.ts +63 -0
- package/dist/blocks/types.js +2 -0
- package/dist/business/approval-flow.d.ts +152 -0
- package/dist/business/approval-flow.js +221 -0
- package/dist/business/export-core.d.ts +55 -0
- package/dist/business/export-core.js +101 -0
- package/dist/business/export.d.ts +148 -0
- package/dist/business/export.js +264 -0
- package/dist/business/import-core.d.ts +104 -0
- package/dist/business/import-core.js +281 -0
- package/dist/business/import-wizard.d.ts +186 -0
- package/dist/business/import-wizard.js +401 -0
- package/dist/business/index.d.ts +11 -0
- package/dist/business/index.js +20 -0
- package/dist/business/line-items-core.d.ts +129 -0
- package/dist/business/line-items-core.js +183 -0
- package/dist/business/line-items.d.ts +119 -0
- package/dist/business/line-items.js +299 -0
- package/dist/business/multi-step-form.d.ts +131 -0
- package/dist/business/multi-step-form.js +337 -0
- package/dist/business/permission-core.d.ts +59 -0
- package/dist/business/permission-core.js +99 -0
- package/dist/business/permission-matrix.d.ts +158 -0
- package/dist/business/permission-matrix.js +341 -0
- package/dist/business/setup-checklist.d.ts +80 -0
- package/dist/business/setup-checklist.js +92 -0
- package/dist/charts/area-chart.d.ts +35 -0
- package/dist/charts/area-chart.js +33 -0
- package/dist/charts/bar-chart.d.ts +27 -0
- package/dist/charts/bar-chart.js +42 -0
- package/dist/charts/bar-list.d.ts +47 -0
- package/dist/charts/bar-list.js +60 -0
- package/dist/charts/chart-shell.d.ts +173 -0
- package/dist/charts/chart-shell.js +205 -0
- package/dist/charts/chart.d.ts +73 -0
- package/dist/charts/chart.js +106 -0
- package/dist/charts/combo-chart.d.ts +29 -0
- package/dist/charts/combo-chart.js +47 -0
- package/dist/charts/donut-chart.d.ts +33 -0
- package/dist/charts/donut-chart.js +113 -0
- package/dist/charts/funnel.d.ts +51 -0
- package/dist/charts/funnel.js +69 -0
- package/dist/charts/gauge.d.ts +62 -0
- package/dist/charts/gauge.js +104 -0
- package/dist/charts/heatmap.d.ts +81 -0
- package/dist/charts/heatmap.js +338 -0
- package/dist/charts/index.d.ts +12 -0
- package/dist/charts/index.js +14 -0
- package/dist/charts/line-chart.d.ts +21 -0
- package/dist/charts/line-chart.js +36 -0
- package/dist/charts/test-utils.d.ts +2 -0
- package/dist/charts/test-utils.js +38 -0
- package/dist/charts/utils.d.ts +130 -0
- package/dist/charts/utils.js +262 -0
- package/dist/components/accordion.d.ts +47 -0
- package/dist/components/accordion.js +70 -0
- package/dist/components/activity-timeline.d.ts +149 -0
- package/dist/components/activity-timeline.js +122 -0
- package/dist/components/address-field.d.ts +116 -0
- package/dist/components/address-field.js +219 -0
- package/dist/components/alert-dialog.d.ts +99 -0
- package/dist/components/alert-dialog.js +192 -0
- package/dist/components/alert.d.ts +42 -0
- package/dist/components/alert.js +82 -0
- package/dist/components/app-shell.d.ts +159 -0
- package/dist/components/app-shell.js +289 -0
- package/dist/components/attachment-list.d.ts +96 -0
- package/dist/components/attachment-list.js +196 -0
- package/dist/components/audit-log.d.ts +150 -0
- package/dist/components/audit-log.js +205 -0
- package/dist/components/avatar.d.ts +87 -0
- package/dist/components/avatar.js +126 -0
- package/dist/components/badge.d.ts +41 -0
- package/dist/components/badge.js +68 -0
- package/dist/components/breadcrumb.d.ts +78 -0
- package/dist/components/breadcrumb.js +106 -0
- package/dist/components/button-group.d.ts +52 -0
- package/dist/components/button-group.js +77 -0
- package/dist/components/button.d.ts +58 -0
- package/dist/components/button.js +107 -0
- package/dist/components/calendar.d.ts +240 -0
- package/dist/components/calendar.js +483 -0
- package/dist/components/card.d.ts +66 -0
- package/dist/components/card.js +76 -0
- package/dist/components/carousel.d.ts +170 -0
- package/dist/components/carousel.js +348 -0
- package/dist/components/checkbox.d.ts +78 -0
- package/dist/components/checkbox.js +138 -0
- package/dist/components/color-picker.d.ts +112 -0
- package/dist/components/color-picker.js +235 -0
- package/dist/components/combobox.d.ts +136 -0
- package/dist/components/combobox.js +294 -0
- package/dist/components/command.d.ts +275 -0
- package/dist/components/command.js +493 -0
- package/dist/components/comment-thread.d.ts +252 -0
- package/dist/components/comment-thread.js +449 -0
- package/dist/components/context-menu.d.ts +77 -0
- package/dist/components/context-menu.js +82 -0
- package/dist/components/currency-input.d.ts +43 -0
- package/dist/components/currency-input.js +85 -0
- package/dist/components/date-picker.d.ts +141 -0
- package/dist/components/date-picker.js +241 -0
- package/dist/components/date-range-picker.d.ts +91 -0
- package/dist/components/date-range-picker.js +251 -0
- package/dist/components/description-list.d.ts +92 -0
- package/dist/components/description-list.js +42 -0
- package/dist/components/dialog.d.ts +139 -0
- package/dist/components/dialog.js +185 -0
- package/dist/components/dropdown-menu.d.ts +100 -0
- package/dist/components/dropdown-menu.js +102 -0
- package/dist/components/editor-layout.d.ts +166 -0
- package/dist/components/editor-layout.js +237 -0
- package/dist/components/empty-state.d.ts +49 -0
- package/dist/components/empty-state.js +68 -0
- package/dist/components/entity-card.d.ts +83 -0
- package/dist/components/entity-card.js +92 -0
- package/dist/components/file-upload.d.ts +256 -0
- package/dist/components/file-upload.js +490 -0
- package/dist/components/formatted-input.d.ts +177 -0
- package/dist/components/formatted-input.js +399 -0
- package/dist/components/hierarchy-chart.d.ts +190 -0
- package/dist/components/hierarchy-chart.js +890 -0
- package/dist/components/hover-card.d.ts +21 -0
- package/dist/components/hover-card.js +32 -0
- package/dist/components/iban-input.d.ts +38 -0
- package/dist/components/iban-input.js +112 -0
- package/dist/components/id-input.d.ts +65 -0
- package/dist/components/id-input.js +130 -0
- package/dist/components/image.d.ts +130 -0
- package/dist/components/image.js +168 -0
- package/dist/components/input-otp.d.ts +62 -0
- package/dist/components/input-otp.js +73 -0
- package/dist/components/input.d.ts +141 -0
- package/dist/components/input.js +187 -0
- package/dist/components/item.d.ts +96 -0
- package/dist/components/item.js +113 -0
- package/dist/components/kbd.d.ts +64 -0
- package/dist/components/kbd.js +119 -0
- package/dist/components/list-layout.d.ts +144 -0
- package/dist/components/list-layout.js +210 -0
- package/dist/components/native-select.d.ts +33 -0
- package/dist/components/native-select.js +48 -0
- package/dist/components/navigation-menu.d.ts +127 -0
- package/dist/components/navigation-menu.js +129 -0
- package/dist/components/notification-center.d.ts +164 -0
- package/dist/components/notification-center.js +399 -0
- package/dist/components/page-header.d.ts +60 -0
- package/dist/components/page-header.js +60 -0
- package/dist/components/pagination.d.ts +121 -0
- package/dist/components/pagination.js +174 -0
- package/dist/components/phone-input.d.ts +49 -0
- package/dist/components/phone-input.js +266 -0
- package/dist/components/popover.d.ts +38 -0
- package/dist/components/popover.js +69 -0
- package/dist/components/progress.d.ts +79 -0
- package/dist/components/progress.js +97 -0
- package/dist/components/radio-group.d.ts +43 -0
- package/dist/components/radio-group.js +81 -0
- package/dist/components/record-detail-layout.d.ts +167 -0
- package/dist/components/record-detail-layout.js +233 -0
- package/dist/components/record-picker.d.ts +199 -0
- package/dist/components/record-picker.js +650 -0
- package/dist/components/resizable.d.ts +50 -0
- package/dist/components/resizable.js +88 -0
- package/dist/components/scroll-area.d.ts +40 -0
- package/dist/components/scroll-area.js +56 -0
- package/dist/components/select.d.ts +126 -0
- package/dist/components/select.js +137 -0
- package/dist/components/separator.d.ts +31 -0
- package/dist/components/separator.js +41 -0
- package/dist/components/settings-layout.d.ts +134 -0
- package/dist/components/settings-layout.js +180 -0
- package/dist/components/sheet.d.ts +103 -0
- package/dist/components/sheet.js +165 -0
- package/dist/components/sidebar.d.ts +171 -0
- package/dist/components/sidebar.js +421 -0
- package/dist/components/signature-pad.d.ts +85 -0
- package/dist/components/signature-pad.js +283 -0
- package/dist/components/skeleton.d.ts +64 -0
- package/dist/components/skeleton.js +53 -0
- package/dist/components/slider.d.ts +57 -0
- package/dist/components/slider.js +133 -0
- package/dist/components/slug-input.d.ts +69 -0
- package/dist/components/slug-input.js +201 -0
- package/dist/components/sparkline.d.ts +54 -0
- package/dist/components/sparkline.js +122 -0
- package/dist/components/spinner.d.ts +34 -0
- package/dist/components/spinner.js +34 -0
- package/dist/components/stat.d.ts +135 -0
- package/dist/components/stat.js +130 -0
- package/dist/components/status-picker.d.ts +107 -0
- package/dist/components/status-picker.js +175 -0
- package/dist/components/stepper.d.ts +86 -0
- package/dist/components/stepper.js +103 -0
- package/dist/components/switch.d.ts +34 -0
- package/dist/components/switch.js +70 -0
- package/dist/components/table.d.ts +101 -0
- package/dist/components/table.js +72 -0
- package/dist/components/tabs.d.ts +103 -0
- package/dist/components/tabs.js +173 -0
- package/dist/components/tag-input.d.ts +77 -0
- package/dist/components/tag-input.js +305 -0
- package/dist/components/task-list.d.ts +89 -0
- package/dist/components/task-list.js +238 -0
- package/dist/components/time-picker.d.ts +119 -0
- package/dist/components/time-picker.js +399 -0
- package/dist/components/toast.d.ts +87 -0
- package/dist/components/toast.js +142 -0
- package/dist/components/toggle.d.ts +77 -0
- package/dist/components/toggle.js +109 -0
- package/dist/components/tooltip.d.ts +69 -0
- package/dist/components/tooltip.js +105 -0
- package/dist/components/top-bar.d.ts +87 -0
- package/dist/components/top-bar.js +99 -0
- package/dist/components/tree-select.d.ts +89 -0
- package/dist/components/tree-select.js +243 -0
- package/dist/components/tree-view.d.ts +109 -0
- package/dist/components/tree-view.js +170 -0
- package/dist/components/typography.d.ts +107 -0
- package/dist/components/typography.js +128 -0
- package/dist/components/user-picker.d.ts +89 -0
- package/dist/components/user-picker.js +162 -0
- package/dist/components/version-history.d.ts +191 -0
- package/dist/components/version-history.js +431 -0
- package/dist/data-table/csv.d.ts +27 -0
- package/dist/data-table/csv.js +68 -0
- package/dist/data-table/data-table.d.ts +423 -0
- package/dist/data-table/data-table.js +1259 -0
- package/dist/data-table/filter-bar.d.ts +146 -0
- package/dist/data-table/filter-bar.js +569 -0
- package/dist/data-table/filter-fns.d.ts +65 -0
- package/dist/data-table/filter-fns.js +382 -0
- package/dist/data-table/index.d.ts +8 -0
- package/dist/data-table/index.js +9 -0
- package/dist/data-table/saved-views.d.ts +100 -0
- package/dist/data-table/saved-views.js +251 -0
- package/dist/data-table/types.d.ts +168 -0
- package/dist/data-table/types.js +87 -0
- package/dist/data-table/url-state.d.ts +94 -0
- package/dist/data-table/url-state.js +303 -0
- package/dist/data-table/view-state.d.ts +16 -0
- package/dist/data-table/view-state.js +81 -0
- package/dist/editor/_test-setup.d.ts +1 -0
- package/dist/editor/_test-setup.js +33 -0
- package/dist/editor/block-editor.d.ts +137 -0
- package/dist/editor/block-editor.js +280 -0
- package/dist/editor/commands.d.ts +31 -0
- package/dist/editor/commands.js +150 -0
- package/dist/editor/context.d.ts +108 -0
- package/dist/editor/context.js +30 -0
- package/dist/editor/convert.d.ts +66 -0
- package/dist/editor/convert.js +567 -0
- package/dist/editor/drag-handle.d.ts +10 -0
- package/dist/editor/drag-handle.js +69 -0
- package/dist/editor/extensions.d.ts +34 -0
- package/dist/editor/extensions.js +239 -0
- package/dist/editor/index.d.ts +14 -0
- package/dist/editor/index.js +17 -0
- package/dist/editor/inserter.d.ts +12 -0
- package/dist/editor/inserter.js +88 -0
- package/dist/editor/inspector.d.ts +17 -0
- package/dist/editor/inspector.js +65 -0
- package/dist/editor/items.d.ts +62 -0
- package/dist/editor/items.js +195 -0
- package/dist/editor/labels.d.ts +119 -0
- package/dist/editor/labels.js +130 -0
- package/dist/editor/markdown.d.ts +14 -0
- package/dist/editor/markdown.js +209 -0
- package/dist/editor/menus.d.ts +20 -0
- package/dist/editor/menus.js +236 -0
- package/dist/editor/nodes.d.ts +14 -0
- package/dist/editor/nodes.js +201 -0
- package/dist/editor/outline.d.ts +11 -0
- package/dist/editor/outline.js +52 -0
- package/dist/editor/schema-form.d.ts +64 -0
- package/dist/editor/schema-form.js +290 -0
- package/dist/editor/slash-menu.d.ts +15 -0
- package/dist/editor/slash-menu.js +119 -0
- package/dist/fonts/catalog.d.ts +53 -0
- package/dist/fonts/catalog.js +121 -0
- package/dist/fonts/font-picker.d.ts +70 -0
- package/dist/fonts/font-picker.js +225 -0
- package/dist/fonts/index.d.ts +6 -0
- package/dist/fonts/index.js +7 -0
- package/dist/fonts/loader.d.ts +66 -0
- package/dist/fonts/loader.js +161 -0
- package/dist/fonts/pairing-picker.d.ts +31 -0
- package/dist/fonts/pairing-picker.js +81 -0
- package/dist/fonts/pairings.d.ts +84 -0
- package/dist/fonts/pairings.js +149 -0
- package/dist/fonts/provider.d.ts +34 -0
- package/dist/fonts/provider.js +51 -0
- package/dist/form/index.d.ts +1 -0
- package/dist/form/index.js +1 -0
- package/dist/format/core.d.ts +149 -0
- package/dist/format/core.js +357 -0
- package/dist/format/index.d.ts +4 -0
- package/dist/format/index.js +5 -0
- package/dist/format/use-format.d.ts +1 -0
- package/dist/format/use-format.js +3 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +87 -0
- package/dist/lib/cn.d.ts +3 -0
- package/dist/lib/cn.js +16 -0
- package/dist/lib/color.d.ts +64 -0
- package/dist/lib/color.js +177 -0
- package/dist/lib/compose-refs.d.ts +24 -0
- package/dist/lib/compose-refs.js +45 -0
- package/dist/lib/data-islands.d.ts +194 -0
- package/dist/lib/data-islands.js +368 -0
- package/dist/lib/date.d.ts +129 -0
- package/dist/lib/date.js +386 -0
- package/dist/lib/field-context.d.ts +64 -0
- package/dist/lib/field-context.js +62 -0
- package/dist/lib/floating-arrow.d.ts +18 -0
- package/dist/lib/floating-arrow.js +15 -0
- package/dist/lib/islands.d.ts +38 -0
- package/dist/lib/islands.js +40 -0
- package/dist/lib/labels.d.ts +51 -0
- package/dist/lib/labels.js +56 -0
- package/dist/lib/layer.d.ts +36 -0
- package/dist/lib/layer.js +42 -0
- package/dist/lib/locale.d.ts +85 -0
- package/dist/lib/locale.js +105 -0
- package/dist/lib/menu.d.ts +58 -0
- package/dist/lib/menu.js +99 -0
- package/dist/lib/message-format.d.ts +20 -0
- package/dist/lib/message-format.js +116 -0
- package/dist/lib/nav.d.ts +132 -0
- package/dist/lib/nav.js +178 -0
- package/dist/lib/provider.d.ts +100 -0
- package/dist/lib/provider.js +105 -0
- package/dist/lib/public.d.ts +22 -0
- package/dist/lib/public.js +33 -0
- package/dist/lib/sr-name.d.ts +18 -0
- package/dist/lib/sr-name.js +17 -0
- package/dist/lib/text.d.ts +100 -0
- package/dist/lib/text.js +233 -0
- package/dist/lib/theme-scope.d.ts +58 -0
- package/dist/lib/theme-scope.js +59 -0
- package/dist/lib/use-async-list.d.ts +60 -0
- package/dist/lib/use-async-list.js +119 -0
- package/dist/lib/use-container-width.d.ts +19 -0
- package/dist/lib/use-container-width.js +39 -0
- package/dist/lib/use-controllable-state.d.ts +33 -0
- package/dist/lib/use-controllable-state.js +56 -0
- package/dist/lib/use-edge-fade.d.ts +13 -0
- package/dist/lib/use-edge-fade.js +43 -0
- package/dist/lib/use-formatted-input.d.ts +69 -0
- package/dist/lib/use-formatted-input.js +152 -0
- package/dist/lib/use-hotkeys.d.ts +80 -0
- package/dist/lib/use-hotkeys.js +221 -0
- package/dist/lib/use-hover-intent.d.ts +44 -0
- package/dist/lib/use-hover-intent.js +119 -0
- package/dist/lib/use-media-query.d.ts +21 -0
- package/dist/lib/use-media-query.js +28 -0
- package/dist/lib/use-reduced-motion.d.ts +8 -0
- package/dist/lib/use-reduced-motion.js +13 -0
- package/dist/lib/use-tree.d.ts +153 -0
- package/dist/lib/use-tree.js +534 -0
- package/dist/lib/value-format.d.ts +25 -0
- package/dist/lib/value-format.js +56 -0
- package/dist/lib/variants.d.ts +131 -0
- package/dist/lib/variants.js +109 -0
- package/dist/locale-data/core/date.d.ts +24 -0
- package/dist/locale-data/core/date.js +68 -0
- package/dist/locale-data/core/decimal.d.ts +19 -0
- package/dist/locale-data/core/decimal.js +79 -0
- package/dist/locale-data/core/holidays.d.ts +30 -0
- package/dist/locale-data/core/holidays.js +79 -0
- package/dist/locale-data/core/iban.d.ts +29 -0
- package/dist/locale-data/core/iban.js +74 -0
- package/dist/locale-data/core/index.d.ts +7 -0
- package/dist/locale-data/core/index.js +6 -0
- package/dist/locale-data/core/types.d.ts +173 -0
- package/dist/locale-data/core/types.js +6 -0
- package/dist/locale-data/core/week-info.d.ts +23 -0
- package/dist/locale-data/core/week-info.js +85 -0
- package/dist/locale-data/core/working-days.d.ts +27 -0
- package/dist/locale-data/core/working-days.js +133 -0
- package/dist/locale-data/index.d.ts +2 -0
- package/dist/locale-data/index.js +4 -0
- package/dist/locale-data/tr/address-tr.json +1 -0
- package/dist/locale-data/tr/address.d.ts +23 -0
- package/dist/locale-data/tr/address.js +52 -0
- package/dist/locale-data/tr/holidays.d.ts +31 -0
- package/dist/locale-data/tr/holidays.js +81 -0
- package/dist/locale-data/tr/iban.d.ts +21 -0
- package/dist/locale-data/tr/iban.js +45 -0
- package/dist/locale-data/tr/id.d.ts +36 -0
- package/dist/locale-data/tr/id.js +120 -0
- package/dist/locale-data/tr/index.d.ts +12 -0
- package/dist/locale-data/tr/index.js +33 -0
- package/dist/locale-data/tr/kdv.d.ts +91 -0
- package/dist/locale-data/tr/kdv.js +222 -0
- package/dist/locales/en.d.ts +2102 -0
- package/dist/locales/en.js +2088 -0
- package/dist/locales/tr.d.ts +2086 -0
- package/dist/locales/tr.js +2087 -0
- package/dist/media/focal-point.d.ts +42 -0
- package/dist/media/focal-point.js +96 -0
- package/dist/media/gallery-layout.d.ts +19 -0
- package/dist/media/gallery-layout.js +61 -0
- package/dist/media/gallery.d.ts +64 -0
- package/dist/media/gallery.js +138 -0
- package/dist/media/image-cropper.d.ts +86 -0
- package/dist/media/image-cropper.js +170 -0
- package/dist/media/image-field.d.ts +115 -0
- package/dist/media/image-field.js +212 -0
- package/dist/media/index.d.ts +19 -0
- package/dist/media/index.js +23 -0
- package/dist/media/lightbox.d.ts +82 -0
- package/dist/media/lightbox.js +171 -0
- package/dist/media/link-preview.d.ts +97 -0
- package/dist/media/link-preview.js +177 -0
- package/dist/media/media-library.d.ts +244 -0
- package/dist/media/media-library.js +776 -0
- package/dist/media/media-picker.d.ts +96 -0
- package/dist/media/media-picker.js +209 -0
- package/dist/media/media-provider.d.ts +23 -0
- package/dist/media/media-provider.js +44 -0
- package/dist/media/media-utils.d.ts +39 -0
- package/dist/media/media-utils.js +145 -0
- package/dist/media/memory-adapter.d.ts +22 -0
- package/dist/media/memory-adapter.js +162 -0
- package/dist/media/rest-adapter.d.ts +90 -0
- package/dist/media/rest-adapter.js +208 -0
- package/dist/media/serp.d.ts +62 -0
- package/dist/media/serp.js +108 -0
- package/dist/media/test-fixtures.d.ts +3 -0
- package/dist/media/test-fixtures.js +37 -0
- package/dist/media/types.d.ts +183 -0
- package/dist/media/types.js +3 -0
- package/dist/media/use-pan-zoom.d.ts +51 -0
- package/dist/media/use-pan-zoom.js +156 -0
- package/dist/media/use-upload-queue.d.ts +64 -0
- package/dist/media/use-upload-queue.js +115 -0
- package/dist/media/video-player.d.ts +135 -0
- package/dist/media/video-player.js +319 -0
- package/dist/next/index.d.ts +42 -0
- package/dist/next/index.js +36 -0
- package/dist/render/block-renderer.d.ts +56 -0
- package/dist/render/block-renderer.js +137 -0
- package/dist/render/index.d.ts +6 -0
- package/dist/render/index.js +7 -0
- package/dist/render/prepare.d.ts +61 -0
- package/dist/render/prepare.js +119 -0
- package/dist/scheduler/core/duration.d.ts +83 -0
- package/dist/scheduler/core/duration.js +174 -0
- package/dist/scheduler/core/gantt.d.ts +63 -0
- package/dist/scheduler/core/gantt.js +226 -0
- package/dist/scheduler/core/index.d.ts +6 -0
- package/dist/scheduler/core/index.js +7 -0
- package/dist/scheduler/core/layout.d.ts +97 -0
- package/dist/scheduler/core/layout.js +249 -0
- package/dist/scheduler/core/time-scale.d.ts +89 -0
- package/dist/scheduler/core/time-scale.js +173 -0
- package/dist/scheduler/gantt.d.ts +125 -0
- package/dist/scheduler/gantt.js +532 -0
- package/dist/scheduler/index.d.ts +6 -0
- package/dist/scheduler/index.js +7 -0
- package/dist/scheduler/resource-calendar.d.ts +218 -0
- package/dist/scheduler/resource-calendar.js +661 -0
- package/dist/scheduler/scheduler.d.ts +168 -0
- package/dist/scheduler/scheduler.js +768 -0
- package/dist/scheduler/shared.d.ts +63 -0
- package/dist/scheduler/shared.js +145 -0
- package/dist/scheduler/time-tracker.d.ts +138 -0
- package/dist/scheduler/time-tracker.js +403 -0
- package/dist/sortable/core.d.ts +67 -0
- package/dist/sortable/core.js +167 -0
- package/dist/sortable/index.d.ts +8 -0
- package/dist/sortable/index.js +10 -0
- package/dist/sortable/kanban-core.d.ts +70 -0
- package/dist/sortable/kanban-core.js +67 -0
- package/dist/sortable/kanban.d.ts +147 -0
- package/dist/sortable/kanban.js +472 -0
- package/dist/sortable/sortable-list.d.ts +71 -0
- package/dist/sortable/sortable-list.js +76 -0
- package/dist/sortable/sortable-tree.d.ts +101 -0
- package/dist/sortable/sortable-tree.js +450 -0
- package/dist/sortable/sortable.d.ts +188 -0
- package/dist/sortable/sortable.js +485 -0
- package/dist/sortable/use-pointer-drag.d.ts +75 -0
- package/dist/sortable/use-pointer-drag.js +173 -0
- package/dist/sortable/use-time-scale.d.ts +11 -0
- package/dist/sortable/use-time-scale.js +19 -0
- package/dist/styles/base.css +51 -0
- package/dist/styles/blocks.css +949 -0
- package/dist/styles/calendar.css +642 -0
- package/dist/styles/charts.css +264 -0
- package/dist/styles/data.css +474 -0
- package/dist/styles/editors.css +1022 -0
- package/dist/styles/forms.css +406 -0
- package/dist/styles/media.css +515 -0
- package/dist/styles/navigation.css +293 -0
- package/dist/styles/overlays.css +244 -0
- package/dist/styles.css +742 -0
- package/package.json +156 -4
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Menu, Phone, X } from "lucide-react";
|
|
3
|
+
import { parsePhoneNumberFromString } from "libphonenumber-js/min";
|
|
4
|
+
import { cn } from "../../lib/cn.js";
|
|
5
|
+
import { baseLanguage } from "../../lib/text.js";
|
|
6
|
+
import { BlockImage } from "../block-image.js";
|
|
7
|
+
import { BlockLink } from "../block-link.js";
|
|
8
|
+
import { SkipLink } from "../section.js";
|
|
9
|
+
import { NavbarSubmenu } from "./navbar-submenu.js";
|
|
10
|
+
import { CtaList, useBlockIds, siteText } from "./_kit-1.js";
|
|
11
|
+
/** National format in the number's own locale, international elsewhere ("0216 000 00 00" for tr). */
|
|
12
|
+
export function formatSitePhone(e164, locale = "en-US") {
|
|
13
|
+
const p = parsePhoneNumberFromString(e164);
|
|
14
|
+
if (!p)
|
|
15
|
+
return e164;
|
|
16
|
+
const sameCountry = baseLanguage(locale) === "tr" ? p.country === "TR" : locale.toUpperCase().endsWith(`-${p.country ?? "?"}`);
|
|
17
|
+
return (sameCountry ? p.formatNational() : p.formatInternational()).replace(/[()]/g, "");
|
|
18
|
+
}
|
|
19
|
+
const isCurrent = (href, path) => !!path && (path === href || (href !== "/" && path.replace(/\/$/, "") === href.replace(/\/$/, "")));
|
|
20
|
+
const inGroup = (item, path) => !!path && (isCurrent(item.href, path) || !!item.children?.some((c) => isCurrent(c.href, path) || (c.href !== "/" && path.startsWith(`${c.href}/`))));
|
|
21
|
+
/**
|
|
22
|
+
* Site top navigation in four characters. Server component: the mobile menu is a native
|
|
23
|
+
* `popover` (0 JS), submenus a tiny disclosure island, the scrolled background a CSS scroll
|
|
24
|
+
* timeline.
|
|
25
|
+
*
|
|
26
|
+
* ```tsx
|
|
27
|
+
* <Navbar wordmark="Kıyı" items={[{ label: "Menu", href: "/menu" }]} actions={[{ link: { href: "/book", label: "Book a table" }, style: "primary" }]} sticky />
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function Navbar({ variant = "bar", logo, logoDark, wordmark, homeHref = "/", items = [], actions, phone, locales, sticky, overlay, currentPath, panelMeta, skipLink = true, id, anchor, className, labels, locale, components, editMode, }) {
|
|
31
|
+
const t = siteText(labels, locale);
|
|
32
|
+
const { base } = useBlockIds(id, "nav");
|
|
33
|
+
const panelId = `${base}-menu`;
|
|
34
|
+
const lang = baseLanguage(locale);
|
|
35
|
+
const phoneText = phone ? formatSitePhone(phone, locale) : undefined;
|
|
36
|
+
const linkProps = { components, labels, locale };
|
|
37
|
+
const brand = (_jsxs(BlockLink, { href: homeHref, ...linkProps, className: "vb-nav-brand flex shrink-0 items-center gap-3 rounded-[2px] focus-ring", children: [logo ? (_jsxs(_Fragment, { children: [_jsx(BlockImage, { ...logo, decorative: !!wordmark || logo.decorative, alt: wordmark ? undefined : logo.alt, priority: true, className: cn("vb-nav-logo", logoDark && "vb-logo-light"), components: components }), logoDark ? _jsx(BlockImage, { ...logoDark, decorative: true, priority: true, className: "vb-nav-logo vb-logo-dark", components: components }) : null] })) : null, wordmark || !logo ? (_jsx("span", { className: cn("vb-nav-wordmark font-display text-fg", variant === "split" ? "text-[1.625rem]" : "text-[1.375rem]"), "data-field": editMode ? "props.wordmark" : undefined, children: wordmark })) : null] }));
|
|
38
|
+
const renderLink = (item, key, className) => (_jsx(BlockLink, { href: item.href, newTab: item.newTab, ...linkProps, "aria-current": isCurrent(item.href, currentPath) ? "page" : undefined, className: cn("vb-nav-link", className), children: item.label }, key));
|
|
39
|
+
const desktopItem = (item, i) => item.children?.length ? (_jsx("li", { children: _jsx(NavbarSubmenu, { label: item.label, active: inGroup(item, currentPath), wide: item.children.some((c) => c.description), children: _jsx("ul", { className: cn("grid gap-0.5", item.children.some((c) => c.description) && "grid-cols-2"), children: item.children.map((c, j) => (_jsx("li", { children: _jsxs(BlockLink, { href: c.href, newTab: c.newTab, ...linkProps, "aria-current": isCurrent(c.href, currentPath) ? "page" : undefined, className: "vb-nav-sublink flex flex-col gap-0.5 rounded-ui-sm px-3 py-2.5 text-sm text-fg transition-colors hover:bg-hover focus-ring", children: [_jsx("span", { className: "font-medium", children: c.label }), c.description ? _jsx("span", { className: "text-small leading-snug text-fg-muted", children: c.description }) : null] }) }, j))) }) }) }, i)) : (_jsx("li", { children: renderLink(item, i) }, i));
|
|
40
|
+
const linkList = (list, offset = 0, className) => (_jsx("ul", { className: cn("vb-nav-links hidden items-center @4xl:flex", variant === "rail" ? "gap-1" : "gap-7", className), children: list.map((it, i) => desktopItem(it, i + offset)) }));
|
|
41
|
+
const phoneLink = phone ? (_jsxs("a", { href: `tel:${phone}`, "aria-label": t("callUs", { phone: phoneText }), "data-track": "call", className: "vb-nav-phone hidden items-center gap-2 rounded-[2px] font-mono text-small tabular text-fg-muted transition-colors hover:text-fg focus-ring @6xl:inline-flex", children: [_jsx(Phone, { "aria-hidden": true, strokeWidth: 1.5, className: "size-3.5" }), phoneText] })) : null;
|
|
42
|
+
const localeSwitch = locales?.length ? (_jsx("ul", { "aria-label": t("languages"), className: "hidden items-center gap-1 font-mono text-eyebrow uppercase tracking-[0.08em] @4xl:flex", children: locales.map((l, i) => {
|
|
43
|
+
const current = l.current ?? baseLanguage(l.code) === lang;
|
|
44
|
+
return (_jsxs("li", { className: "flex items-center gap-1", children: [i > 0 ? _jsx("span", { "aria-hidden": true, className: "text-fg-subtle", children: "/" }) : null, _jsx("a", { href: l.href, hrefLang: l.code, lang: l.code, "aria-current": current ? "true" : undefined, className: cn("rounded-[2px] px-0.5 transition-colors focus-ring", current ? "text-fg" : "text-fg-muted hover:text-fg"), children: l.code })] }, l.code));
|
|
45
|
+
}) })) : null;
|
|
46
|
+
const trigger = (always) => (_jsx("button", { type: "button", popoverTarget: panelId, "aria-haspopup": "dialog", "aria-controls": panelId, className: cn("vb-nav-trigger inline-flex h-10 items-center gap-2 rounded-ui px-2 text-sm font-medium text-fg transition-colors hover:bg-hover focus-ring", !always && "@4xl:hidden"), children: always ? (_jsx("span", { className: "font-mono text-eyebrow uppercase tracking-[0.08em]", children: t("openMenu") })) : (_jsxs(_Fragment, { children: [_jsx(Menu, { "aria-hidden": true, strokeWidth: 1.5, className: "size-5" }), _jsx("span", { className: "sr-only", children: t("openMenu") })] })) }));
|
|
47
|
+
const primaryAction = actions?.length ? _jsx(CtaList, { actions: actions, ...linkProps, size: "md", max: variant === "bar" || variant === "minimal" ? 1 : 2, className: "hidden flex-nowrap gap-x-2 @2xl:flex" }) : null;
|
|
48
|
+
let row;
|
|
49
|
+
if (variant === "split") {
|
|
50
|
+
const half = Math.ceil(items.length / 2);
|
|
51
|
+
row = (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex min-w-0 items-center", children: [trigger(false), linkList(items.slice(0, half))] }), _jsx("div", { className: "flex justify-center", children: brand }), _jsxs("div", { className: "flex min-w-0 items-center justify-end gap-7", children: [linkList(items.slice(half), half), localeSwitch, actions?.length ? _jsx(CtaList, { actions: actions.slice(0, 1), ...linkProps, forceStyle: "link", arrow: false, className: "hidden @2xl:flex" }) : null] })] }));
|
|
52
|
+
}
|
|
53
|
+
else if (variant === "minimal") {
|
|
54
|
+
row = (_jsxs(_Fragment, { children: [brand, _jsxs("div", { className: "ms-auto flex items-center gap-3", children: [localeSwitch, primaryAction, trigger(true)] })] }));
|
|
55
|
+
}
|
|
56
|
+
else if (variant === "rail") {
|
|
57
|
+
row = (_jsxs(_Fragment, { children: [brand, _jsx("div", { className: "flex flex-1 justify-center", children: items.length ? _jsx("div", { className: "vb-nav-rail hidden rounded-full p-1 @4xl:block", children: linkList(items) }) : null }), _jsxs("div", { className: "flex items-center gap-2", children: [localeSwitch, actions?.length ? (_jsx(CtaList, { actions: actions.map((a) => (a.style === "primary" ? a : { ...a, style: "secondary" })), ...linkProps, size: "md", className: "hidden flex-nowrap gap-x-1.5 @2xl:flex [&>a:not(.vb-action-primary)]:border-transparent [&>a:not(.vb-action-primary)]:bg-transparent [&>a:not(.vb-action-primary)]:shadow-none" })) : null, trigger(false)] })] }));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
row = (_jsxs(_Fragment, { children: [brand, linkList(items, 0, "ms-4"), _jsxs("div", { className: "ms-auto flex items-center gap-5", children: [phoneLink, localeSwitch, primaryAction, trigger(false)] })] }));
|
|
61
|
+
}
|
|
62
|
+
const panelLinkSize = variant === "minimal" ? "font-display text-display-l" : "font-display text-display-m";
|
|
63
|
+
return (_jsxs("header", { id: anchor, "data-variant": variant, "data-sticky": sticky ? "" : undefined, "data-overlay": overlay ? "" : undefined, "data-block-id": editMode ? id : undefined, className: cn("vb-navbar", overlay && "dark", className), children: [skipLink ? _jsx(SkipLink, { labels: labels, locale: locale }) : null, _jsx("nav", { "aria-label": t("mainNavigation"), className: cn("vb-container vb-navbar-row items-center", variant === "split" ? "grid grid-cols-[1fr_auto_1fr] gap-6" : "flex gap-6"), children: row }), _jsx("div", { id: panelId, popover: "auto", role: "dialog", "aria-label": t("menuDialog"), className: "vb-nav-panel", children: _jsxs("div", { className: "vb-container flex min-h-full flex-col", children: [_jsxs("div", { className: "vb-navbar-row flex items-center justify-between gap-6", children: [brand, _jsxs("button", { type: "button", popoverTarget: panelId, popoverTargetAction: "hide", className: "inline-flex h-10 items-center gap-2 rounded-ui px-2 text-fg transition-colors hover:bg-hover focus-ring", children: [_jsx("span", { className: variant === "minimal" ? "font-mono text-eyebrow uppercase tracking-[0.08em]" : "sr-only", children: t("closeMenu") }), _jsx(X, { "aria-hidden": true, strokeWidth: 1.5, className: "size-5" })] })] }), _jsx("ul", { className: "flex flex-col py-[clamp(1.5rem,6vh,4rem)]", children: items.map((it, i) => (_jsxs("li", { className: "border-b border-line", children: [renderLink(it, i, cn("vb-nav-panel-link block py-3 text-fg", panelLinkSize)), it.children?.length ? (_jsx("ul", { className: "flex flex-wrap gap-x-6 gap-y-2 pb-4", children: it.children.map((c, j) => (_jsx("li", { children: renderLink(c, j, "text-small text-fg-muted hover:text-fg") }, j))) })) : null] }, i))) }), _jsxs("div", { className: "mt-auto flex flex-col gap-8 pb-[max(2rem,env(safe-area-inset-bottom))]", children: [actions?.length ? _jsx(CtaList, { actions: actions, ...linkProps, size: "lg" }) : null, phone || panelMeta?.length || locales?.length ? (_jsxs("dl", { className: "grid gap-x-8 gap-y-4 border-t border-line pt-6 text-small sm:grid-cols-3", children: [phone ? (_jsxs("div", { children: [_jsx("dt", { className: "font-mono text-eyebrow uppercase tracking-[0.08em] text-fg-muted", children: t("phoneLabel") }), _jsx("dd", { className: "mt-1", children: _jsx("a", { href: `tel:${phone}`, "data-track": "call", className: "tabular text-fg underline decoration-line underline-offset-4 focus-ring", children: phoneText }) })] })) : null, panelMeta?.map((m, i) => (_jsxs("div", { children: [_jsx("dt", { className: "font-mono text-eyebrow uppercase tracking-[0.08em] text-fg-muted", children: m.label }), _jsx("dd", { className: "mt-1 text-fg", children: m.value })] }, i))), locales?.length ? (_jsxs("div", { children: [_jsx("dt", { className: "font-mono text-eyebrow uppercase tracking-[0.08em] text-fg-muted", children: t("languages") }), _jsx("dd", { className: "mt-1 flex gap-3", children: locales.map((l) => (_jsx("a", { href: l.href, hrefLang: l.code, lang: l.code, "aria-current": (l.current ?? baseLanguage(l.code) === lang) ? "true" : undefined, className: "font-mono uppercase text-fg-muted aria-[current]:text-fg focus-ring", children: l.code }, l.code))) })] })) : null] })) : null] })] }) })] }));
|
|
64
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { BlockBaseProps } from "../types.js";
|
|
3
|
+
import { type Site2BlockLabels } from "./shared/labels-2.js";
|
|
4
|
+
import { type SiteLink2 } from "./shared/kit-2.js";
|
|
5
|
+
export type NotFoundVariant = "plain" | "links";
|
|
6
|
+
export type NotFoundKind = "404" | "500" | "maintenance";
|
|
7
|
+
export interface NotFoundProps extends Omit<BlockBaseProps, "variant" | "labels"> {
|
|
8
|
+
/** plain: small mono code, a sentence title and one "Back to home" link. links: plus popular pages, a search field and a phone line. */
|
|
9
|
+
variant?: NotFoundVariant;
|
|
10
|
+
/** Default `"404"`. */
|
|
11
|
+
kind?: NotFoundKind;
|
|
12
|
+
/** Default per kind ("This page moved, or never existed."). One `*emphasis*`. */
|
|
13
|
+
title?: React.ReactNode;
|
|
14
|
+
text?: React.ReactNode;
|
|
15
|
+
/** Up to 6 popular pages (`links`). */
|
|
16
|
+
links?: SiteLink2[];
|
|
17
|
+
/** Default `"/"`. */
|
|
18
|
+
homeHref?: string;
|
|
19
|
+
/** Plain GET search form (`action="/search"`, `param="q"`). */
|
|
20
|
+
search?: {
|
|
21
|
+
action: string;
|
|
22
|
+
param?: string;
|
|
23
|
+
};
|
|
24
|
+
/** E.164 phone for "Still stuck? Call …". */
|
|
25
|
+
phone?: string;
|
|
26
|
+
/** `error.tsx`: Next.js's `reset()` — renders a "Try again" button (client usage only). */
|
|
27
|
+
reset?: () => void;
|
|
28
|
+
labels?: Site2BlockLabels;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Branded, useful not-found / error / maintenance page for `not-found.tsx` and `error.tsx`. No
|
|
32
|
+
* giant numerals: a small mono code, a sentence title (`h1`), the way back. Works as a server
|
|
33
|
+
* component, and inside `error.tsx` (client) with `reset`.
|
|
34
|
+
*
|
|
35
|
+
* ```tsx
|
|
36
|
+
* // app/not-found.tsx
|
|
37
|
+
* export default function NotFoundPage() { return <NotFound variant="links" links={popular} search={{ action: "/search" }} />; }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function NotFound({ variant, kind, title, text, links, homeHref, search, phone, reset, id, anchor, theme, headingLevel, className, labels, locale, components, editMode, }: NotFoundProps): React.JSX.Element;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ArrowRight, RotateCcw, Search } from "lucide-react";
|
|
3
|
+
import { cn2 as cn } from "./shared/kit-2.js";
|
|
4
|
+
import { buttonVariants } from "../../components/button.js";
|
|
5
|
+
import { Section, Container } from "../section.js";
|
|
6
|
+
import { BlockHeading } from "../block-heading.js";
|
|
7
|
+
import { BlockLink } from "../block-link.js";
|
|
8
|
+
import { site2Text } from "./shared/labels-2.js";
|
|
9
|
+
import { fieldAttr, prettyPhone, telHref, useBlockIds2 } from "./shared/kit-2.js";
|
|
10
|
+
const KIND = {
|
|
11
|
+
"404": { code: "notFoundCode", title: "notFoundTitle", text: "notFoundText" },
|
|
12
|
+
"500": { code: "serverErrorCode", title: "serverErrorTitle", text: "serverErrorText" },
|
|
13
|
+
maintenance: { code: "maintenanceCode", title: "maintenanceTitle", text: "maintenanceText" },
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Branded, useful not-found / error / maintenance page for `not-found.tsx` and `error.tsx`. No
|
|
17
|
+
* giant numerals: a small mono code, a sentence title (`h1`), the way back. Works as a server
|
|
18
|
+
* component, and inside `error.tsx` (client) with `reset`.
|
|
19
|
+
*
|
|
20
|
+
* ```tsx
|
|
21
|
+
* // app/not-found.tsx
|
|
22
|
+
* export default function NotFoundPage() { return <NotFound variant="links" links={popular} search={{ action: "/search" }} />; }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function NotFound({ variant = "plain", kind = "404", title, text, links = [], homeHref = "/", search, phone, reset, id, anchor, theme, headingLevel = 1, className, labels, locale = "en-US", components, editMode, }) {
|
|
26
|
+
const t = site2Text(labels, locale);
|
|
27
|
+
const { base, headingId } = useBlockIds2(id, "not-found");
|
|
28
|
+
const k = KIND[kind];
|
|
29
|
+
const showLinks = variant === "links";
|
|
30
|
+
return (_jsx(Section, { theme: theme, anchor: anchor, headingId: headingId, blockId: id, blockType: "not-found", editMode: editMode, className: cn("vb-not-found", className), "data-kind": kind, "data-variant": variant, children: _jsxs(Container, { className: "grid gap-x-(--gutter) gap-y-14 @4xl:grid-cols-12", children: [_jsxs("div", { className: "flex flex-col gap-6 @4xl:col-span-8", children: [_jsxs("p", { className: "flex items-center gap-3 font-mono text-eyebrow uppercase tracking-[0.08em] text-fg-muted", children: [_jsx("span", { className: "tabular text-fg", children: t(k.code) }), _jsx("span", { "aria-hidden": true, className: "h-px w-8 bg-current opacity-40" })] }), _jsx(BlockHeading, { id: headingId, level: headingLevel, size: "display-l", text: title ?? t(k.title), editMode: editMode, field: "props.title", labels: labels, locale: locale, className: "max-w-[20ch]" }), _jsx("p", { className: "max-w-[52ch] text-lead text-fg-muted text-pretty", ...fieldAttr(editMode, "text"), children: text ?? t(k.text) }), _jsxs("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-3 pt-2", children: [reset ? (_jsxs("button", { type: "button", onClick: reset, className: cn(buttonVariants({ variant: "primary", size: "lg" }), "vb-action-primary"), children: [_jsx(RotateCcw, { "aria-hidden": true, strokeWidth: 1.75 }), t("tryAgain")] })) : null, _jsxs(BlockLink, { href: homeHref, appearance: reset ? "link" : kind === "maintenance" && phone ? "secondary" : "primary", components: components, labels: labels, locale: locale, children: [t("backHome"), reset ? _jsx(ArrowRight, { "aria-hidden": true, strokeWidth: 1.5, className: "size-[1em] rtl:-scale-x-100" }) : null] }), kind === "maintenance" && phone ? (_jsx("a", { href: telHref(phone), className: cn(buttonVariants({ variant: "primary", size: "lg" }), "vb-action-primary tabular"), "data-track": "call", children: prettyPhone(phone) })) : null] })] }), showLinks ? (_jsxs("div", { className: "flex flex-col gap-10 border-t border-line pt-8 @4xl:col-span-12", children: [search ? (_jsxs("form", { role: "search", action: search.action, method: "get", className: "flex max-w-xl flex-col gap-2", children: [_jsx("label", { htmlFor: `${base}-q`, className: "font-mono text-eyebrow uppercase tracking-[0.08em] text-fg-muted", children: t("searchSite") }), _jsxs("div", { className: "flex gap-2", children: [_jsxs("span", { className: "relative flex-1", children: [_jsx(Search, { "aria-hidden": true, strokeWidth: 1.5, className: "pointer-events-none absolute start-3 top-1/2 size-4 -translate-y-1/2 text-fg-muted" }), _jsx("input", { id: `${base}-q`, type: "search", name: search.param ?? "q", placeholder: t("searchPlaceholder"), className: "h-12 w-full rounded-ui border border-field-border bg-field ps-9 pe-3 text-body text-fg placeholder:text-fg-subtle transition-colors hover:border-field-border-hover focus-ring" })] }), _jsx("button", { type: "submit", className: buttonVariants({ variant: "secondary", size: "lg" }), children: t("search") })] })] })) : null, links.length ? (_jsxs("nav", { "aria-labelledby": `${base}-pop`, className: "flex flex-col gap-4", children: [_jsx("p", { id: `${base}-pop`, className: "font-mono text-eyebrow uppercase tracking-[0.08em] text-fg-muted", children: t("popularPages") }), _jsx("ul", { className: "grid gap-x-(--gutter) @2xl:grid-cols-2", children: links.slice(0, 6).map((l, i) => (_jsx("li", { className: "border-t border-line", children: _jsxs(BlockLink, { href: l.href, newTab: l.newTab, components: components, labels: labels, locale: locale, className: "group/nf flex items-center justify-between gap-4 py-4 text-body text-fg transition-colors hover:text-accent-ink focus-ring rounded-[2px]", children: [_jsx("span", { children: l.label }), _jsx(ArrowRight, { "aria-hidden": true, strokeWidth: 1.5, className: "size-4 text-fg-subtle transition-colors group-hover/nf:text-current rtl:-scale-x-100" })] }) }, i))) })] })) : null, phone && kind !== "maintenance" ? (_jsx("p", { className: "text-small text-fg-muted", children: t("stillStuck", { phone: "\u0000" })
|
|
31
|
+
.split("\u0000")
|
|
32
|
+
.flatMap((part, i) => i === 0
|
|
33
|
+
? [part]
|
|
34
|
+
: [
|
|
35
|
+
_jsx("a", { href: telHref(phone), className: "font-medium tabular text-fg underline decoration-line underline-offset-[0.25em] hover:decoration-current focus-ring rounded-[2px]", "data-track": "call", children: prettyPhone(phone) }, "p"),
|
|
36
|
+
part,
|
|
37
|
+
]) })) : null] })) : null] }) }));
|
|
38
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { BlockBaseProps } from "../types.js";
|
|
3
|
+
import { type SiteBlockLabels, type SiteImage, type SiteMeta } from "./_kit-1.js";
|
|
4
|
+
export type PageIntroVariant = "simple" | "with-media" | "ruled";
|
|
5
|
+
export interface PageIntroCrumb {
|
|
6
|
+
label: React.ReactNode;
|
|
7
|
+
/** Omit on the current page (the last crumb). */
|
|
8
|
+
href?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface PageIntroProps extends Omit<BlockBaseProps, "variant" | "labels"> {
|
|
11
|
+
/**
|
|
12
|
+
* simple: small breadcrumb, display-l title, lead beside it on wide containers.
|
|
13
|
+
* with-media: title + lead, then a 21:9 image bleeding past the container.
|
|
14
|
+
* ruled: title at the start, 2–3 meta rows behind a vertical rule at the end, hairline below.
|
|
15
|
+
*/
|
|
16
|
+
variant?: PageIntroVariant;
|
|
17
|
+
/** Ancestors first; the last crumb is the current page (`aria-current="page"`). */
|
|
18
|
+
breadcrumb?: PageIntroCrumb[];
|
|
19
|
+
eyebrow?: React.ReactNode;
|
|
20
|
+
/** The page `h1` (inner pages). One `*emphasis*`. */
|
|
21
|
+
title: React.ReactNode;
|
|
22
|
+
lead?: React.ReactNode;
|
|
23
|
+
media?: SiteImage;
|
|
24
|
+
/** ruled: facts on the end side ("Service area" · "Asian side"), up to 3. */
|
|
25
|
+
meta?: SiteMeta[];
|
|
26
|
+
labels?: SiteBlockLabels;
|
|
27
|
+
/**
|
|
28
|
+
* Explicit id for the `h1` (e.g. to move focus back to it after an in-page route change).
|
|
29
|
+
* Default: `<id>-title`, or an auto id.
|
|
30
|
+
*/
|
|
31
|
+
headingId?: string;
|
|
32
|
+
}
|
|
33
|
+
/** `BreadcrumbList` JSON-LD for the crumbs (absolute URLs need `origin`). */
|
|
34
|
+
export declare function breadcrumbJsonLd(crumbs: {
|
|
35
|
+
label: string;
|
|
36
|
+
href?: string;
|
|
37
|
+
}[], origin?: string): Record<string, unknown> | null;
|
|
38
|
+
/**
|
|
39
|
+
* The `h1` + breadcrumb of an inner page (About, Services, Contact) — lighter than a hero.
|
|
40
|
+
* Server component.
|
|
41
|
+
*
|
|
42
|
+
* ```tsx
|
|
43
|
+
* <PageIntro breadcrumb={[{ label: "Home", href: "/" }, { label: "Treatments" }]} title="Treatments, *by the hour*" />
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function PageIntro({ variant, breadcrumb, eyebrow, title, lead, media, meta, id, theme, anchor, className, headingLevel, labels, locale, components, editMode, headingId: headingIdProp }: PageIntroProps): React.JSX.Element;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../lib/cn.js";
|
|
3
|
+
import { Container, Section } from "../section.js";
|
|
4
|
+
import { BlockHeading } from "../block-heading.js";
|
|
5
|
+
import { BlockImage } from "../block-image.js";
|
|
6
|
+
import { BlockLink } from "../block-link.js";
|
|
7
|
+
import { field, siteText, useBlockIds } from "./_kit-1.js";
|
|
8
|
+
/** `BreadcrumbList` JSON-LD for the crumbs (absolute URLs need `origin`). */
|
|
9
|
+
export function breadcrumbJsonLd(crumbs, origin = "") {
|
|
10
|
+
if (!crumbs.length)
|
|
11
|
+
return null;
|
|
12
|
+
return {
|
|
13
|
+
"@type": "BreadcrumbList",
|
|
14
|
+
itemListElement: crumbs.map((c, i) => ({ "@type": "ListItem", position: i + 1, name: c.label, ...(c.href ? { item: `${origin}${c.href}` } : null) })),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The `h1` + breadcrumb of an inner page (About, Services, Contact) — lighter than a hero.
|
|
19
|
+
* Server component.
|
|
20
|
+
*
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <PageIntro breadcrumb={[{ label: "Home", href: "/" }, { label: "Treatments" }]} title="Treatments, *by the hour*" />
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function PageIntro({ variant = "simple", breadcrumb, eyebrow, title, lead, media, meta, id, theme, anchor, className, headingLevel = 1, labels, locale, components, editMode, headingId: headingIdProp }) {
|
|
26
|
+
const t = siteText(labels, locale);
|
|
27
|
+
const { base, headingId: autoHeadingId } = useBlockIds(id, "intro");
|
|
28
|
+
const headingId = headingIdProp ?? autoHeadingId;
|
|
29
|
+
const linkProps = { components, labels, locale };
|
|
30
|
+
const crumbs = breadcrumb?.length ? (_jsx("nav", { "aria-label": t("breadcrumb"), ...field(editMode, "breadcrumb"), children: _jsx("ol", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 font-mono text-eyebrow uppercase tracking-[0.08em] text-fg-subtle", children: breadcrumb.map((c, i) => {
|
|
31
|
+
const last = i === breadcrumb.length - 1;
|
|
32
|
+
return (_jsxs("li", { className: "flex items-center gap-2", children: [i > 0 ? (_jsx("span", { "aria-hidden": true, className: "text-fg-subtle/70 rtl:-scale-x-100", children: "/" })) : null, c.href && !last ? (_jsx(BlockLink, { href: c.href, ...linkProps, className: "rounded-[2px] transition-colors hover:text-fg focus-ring", children: c.label })) : (_jsx("span", { "aria-current": last ? "page" : undefined, className: last ? "text-fg-muted" : undefined, children: c.label }))] }, i));
|
|
33
|
+
}) }) })) : eyebrow ? (_jsx("p", { className: "font-mono text-eyebrow uppercase tracking-[0.08em] text-fg-muted", ...field(editMode, "eyebrow"), children: eyebrow })) : null;
|
|
34
|
+
const heading = _jsx(BlockHeading, { id: headingId, level: headingLevel, size: "display-l", text: title, editMode: editMode, field: "props.title", labels: labels, locale: locale, className: "max-w-[20ch]" });
|
|
35
|
+
const leadEl = lead ? (_jsx("p", { className: "vb-lead max-w-[52ch] text-lead text-fg-muted", ...field(editMode, "lead"), children: lead })) : null;
|
|
36
|
+
let content;
|
|
37
|
+
if (variant === "ruled") {
|
|
38
|
+
content = (_jsx(Container, { children: _jsxs("div", { className: "grid gap-x-(--gutter) gap-y-10 border-b border-line pb-[calc(var(--section-y)*0.4)] @4xl:grid-cols-12 @4xl:items-end", children: [_jsxs("div", { className: "flex flex-col gap-6 @4xl:col-span-7", children: [crumbs, heading, leadEl] }), meta?.length ? (_jsx("dl", { className: "flex flex-col gap-4 border-s border-line ps-6 @4xl:col-span-4 @4xl:col-start-9", ...field(editMode, "meta"), children: meta.slice(0, 3).map((m, i) => (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("dt", { className: "font-mono text-eyebrow uppercase tracking-[0.08em] text-fg-subtle", children: m.label }), _jsx("dd", { className: "text-body text-fg", children: m.value })] }, i))) })) : null] }) }));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
content = (_jsxs(_Fragment, { children: [_jsxs(Container, { className: "flex flex-col gap-6", children: [crumbs, _jsxs("div", { className: "grid gap-x-(--gutter) gap-y-6 @4xl:grid-cols-12 @4xl:items-end", children: [_jsx("div", { className: "@4xl:col-span-7", children: heading }), leadEl ? _jsx("div", { className: "@4xl:col-span-5 @4xl:pb-[0.4em]", children: leadEl }) : null] })] }), variant === "with-media" && media ? (_jsx(Container, { size: "wide", className: "mt-[calc(var(--section-y)*0.5)] px-0! @6xl:px-(--gutter)!", children: _jsx(BlockImage, { ...media, aspect: "21:9", priority: true, sizes: "min(100vw, 90rem)", className: "@6xl:rounded-ui", components: components, labels: labels, editMode: editMode, field: "props.media" }) })) : null] }));
|
|
42
|
+
}
|
|
43
|
+
return (_jsx(Section, { theme: theme, anchor: anchor, headingId: headingId, blockId: base, blockType: "page-intro", editMode: editMode, className: cn("vb-page-intro", className), "data-variant": variant, children: content }));
|
|
44
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { BlockBaseProps } from "../types.js";
|
|
3
|
+
import type { CtaStyle, MoneyValue } from "../schema/types.js";
|
|
4
|
+
import type { RichDoc } from "../schema/rich-doc.js";
|
|
5
|
+
import { type Site2BlockLabels } from "./shared/labels-2.js";
|
|
6
|
+
import { type SiteLink2 } from "./shared/kit-2.js";
|
|
7
|
+
export type PricingVariant = "columns" | "rows" | "single";
|
|
8
|
+
export type PricingBilling = "monthly" | "yearly" | "both" | "once";
|
|
9
|
+
export interface PricingFeature {
|
|
10
|
+
text: React.ReactNode;
|
|
11
|
+
/** Default true. Excluded features read "Not included" (muted, a dash — never a cross). */
|
|
12
|
+
included?: boolean;
|
|
13
|
+
/** Small text under the feature ("up to 5 GB"). */
|
|
14
|
+
note?: React.ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export interface PricingPlan {
|
|
17
|
+
name: React.ReactNode;
|
|
18
|
+
description?: React.ReactNode;
|
|
19
|
+
price?: {
|
|
20
|
+
monthly?: MoneyValue;
|
|
21
|
+
yearly?: MoneyValue;
|
|
22
|
+
once?: MoneyValue; /** "from $4,500". */
|
|
23
|
+
from?: boolean;
|
|
24
|
+
};
|
|
25
|
+
/** Shown instead of a price ("Get a quote", "Custom"). */
|
|
26
|
+
custom?: React.ReactNode;
|
|
27
|
+
features?: PricingFeature[];
|
|
28
|
+
cta?: {
|
|
29
|
+
link: SiteLink2;
|
|
30
|
+
style?: CtaStyle;
|
|
31
|
+
};
|
|
32
|
+
/** Highlight label ("Most chosen"). Adds a 2px accent rule — no glow, no scale. */
|
|
33
|
+
highlight?: React.ReactNode;
|
|
34
|
+
}
|
|
35
|
+
export interface PricingTableProps extends Omit<BlockBaseProps, "variant" | "labels"> {
|
|
36
|
+
/**
|
|
37
|
+
* columns: 2–4 plans separated by hairline rules, no cards. rows: agency packages as quote-like
|
|
38
|
+
* rows. single: one package — big price beside a two-column inclusion list.
|
|
39
|
+
*/
|
|
40
|
+
variant?: PricingVariant;
|
|
41
|
+
eyebrow?: React.ReactNode;
|
|
42
|
+
title?: React.ReactNode;
|
|
43
|
+
lead?: React.ReactNode;
|
|
44
|
+
/** Which prices exist. `both` adds a monthly/yearly switch (radios + `:has()`, 0 JS). Default `"monthly"`. */
|
|
45
|
+
billing?: PricingBilling;
|
|
46
|
+
/** Selected period when `billing="both"`. Default `"monthly"`. */
|
|
47
|
+
defaultPeriod?: "monthly" | "yearly";
|
|
48
|
+
/** Next to "Yearly": "2 months free" (text, never a strikethrough). */
|
|
49
|
+
yearlySaving?: React.ReactNode;
|
|
50
|
+
plans: PricingPlan[];
|
|
51
|
+
/** Required by D6-8: "VAT included", "Prices exclude 20% VAT". */
|
|
52
|
+
taxNote?: React.ReactNode;
|
|
53
|
+
/** Terms under the table (cancellation, payment). */
|
|
54
|
+
footnote?: React.ReactNode | RichDoc;
|
|
55
|
+
labels?: Site2BlockLabels;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Plan pricing for SaaS subscriptions, agency packages and retainers. Money through `Intl` per
|
|
59
|
+
* locale and currency, a period suffix, a mandatory tax note. Server component; the
|
|
60
|
+
* monthly/yearly switch is plain radios (works without JS).
|
|
61
|
+
*
|
|
62
|
+
* ```tsx
|
|
63
|
+
* <PricingTable billing="both" yearlySaving="2 months free" taxNote="Prices exclude VAT."
|
|
64
|
+
* plans={[{ name: "Studio", price: { monthly: { amount: "49", currency: "USD" }, yearly: { amount: "490", currency: "USD" } }, … }]} />
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function PricingTable({ variant, eyebrow, title, lead, billing, defaultPeriod, yearlySaving, plans, taxNote, footnote, id, anchor, theme, headingLevel, className, labels, locale, components, editMode, }: PricingTableProps): React.JSX.Element;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Check, Minus } from "lucide-react";
|
|
4
|
+
import { cn2 as cn } from "./shared/kit-2.js";
|
|
5
|
+
import { Section, Container } from "../section.js";
|
|
6
|
+
import { SectionHeader } from "../section-header.js";
|
|
7
|
+
import { BlockLink } from "../block-link.js";
|
|
8
|
+
import { RichText } from "../rich-text.js";
|
|
9
|
+
import { site2Text } from "./shared/labels-2.js";
|
|
10
|
+
import { fieldAttr, formatMoney, formatMoneyLong, useBlockIds2 } from "./shared/kit-2.js";
|
|
11
|
+
/**
|
|
12
|
+
* Plan pricing for SaaS subscriptions, agency packages and retainers. Money through `Intl` per
|
|
13
|
+
* locale and currency, a period suffix, a mandatory tax note. Server component; the
|
|
14
|
+
* monthly/yearly switch is plain radios (works without JS).
|
|
15
|
+
*
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <PricingTable billing="both" yearlySaving="2 months free" taxNote="Prices exclude VAT."
|
|
18
|
+
* plans={[{ name: "Studio", price: { monthly: { amount: "49", currency: "USD" }, yearly: { amount: "490", currency: "USD" } }, … }]} />
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function PricingTable({ variant = "columns", eyebrow, title, lead, billing = "monthly", defaultPeriod = "monthly", yearlySaving, plans, taxNote, footnote, id, anchor, theme, headingLevel = 2, className, labels, locale = "en-US", components, editMode, }) {
|
|
22
|
+
const t = site2Text(labels, locale);
|
|
23
|
+
const { base, headingId } = useBlockIds2(id, "pricing");
|
|
24
|
+
const single = variant === "single" || plans.length === 1;
|
|
25
|
+
const ctx = { t, locale, billing, components, labels, editMode };
|
|
26
|
+
// One primary per block: the highlighted plan, else the first plan asking for it.
|
|
27
|
+
const primaryIndex = Math.max(0, plans.findIndex((p) => p.highlight) >= 0 ? plans.findIndex((p) => p.highlight) : plans.findIndex((p) => p.cta?.style === "primary"));
|
|
28
|
+
return (_jsx(Section, { theme: theme, anchor: anchor, headingId: title ? headingId : undefined, blockId: id, blockType: "pricing", editMode: editMode, className: cn("vb-pricing", className), "data-billing": billing, "data-variant": single ? "single" : variant, children: _jsxs(Container, { className: "flex flex-col gap-12 @4xl:gap-16", children: [title || eyebrow || lead || billing === "both" ? (_jsxs("div", { className: "flex flex-col gap-8 @4xl:flex-row @4xl:items-end @4xl:justify-between", children: [_jsx(SectionHeader, { eyebrow: eyebrow, title: title, lead: lead, headingId: headingId, headingLevel: headingLevel, editMode: editMode, labels: labels, locale: locale }), billing === "both" ? _jsx(BillingToggle, { name: `${base}-period`, defaultPeriod: defaultPeriod, saving: yearlySaving, t: t }) : null] })) : null, single ? (_jsx(SinglePlan, { plan: plans[0], ctx: ctx })) : variant === "rows" ? (_jsx("ol", { className: "flex flex-col border-b border-line", children: plans.map((plan, i) => (_jsx(PlanRow, { plan: plan, index: i, ctx: ctx, primary: i === primaryIndex }, i))) })) : (_jsx("ul", { className: "vb-plan-grid grid", "data-cols": Math.min(plans.length, 4), children: plans.map((plan, i) => (_jsx(PlanColumn, { plan: plan, index: i, ctx: ctx, primary: i === primaryIndex }, i))) })), taxNote || footnote ? (_jsxs("div", { className: "flex flex-col gap-2 border-t border-line pt-5 text-small text-fg-muted @2xl:flex-row @2xl:items-start @2xl:justify-between @2xl:gap-10", children: [taxNote ? (_jsx("p", { className: "shrink-0 font-mono text-eyebrow uppercase tracking-[0.08em]", ...fieldAttr(editMode, "taxNote"), children: taxNote })) : null, footnote ? (_jsx("div", { className: "max-w-(--measure) @2xl:text-end", ...fieldAttr(editMode, "footnote"), children: isRichDoc(footnote) ? _jsx(RichText, { doc: footnote, size: "sm", components: components, labels: labels, locale: locale }) : footnote })) : null] })) : null] }) }));
|
|
29
|
+
}
|
|
30
|
+
const isRichDoc = (v) => !!v && typeof v === "object" && v.type === "doc" && Array.isArray(v.content);
|
|
31
|
+
function BillingToggle({ name, defaultPeriod, saving, t }) {
|
|
32
|
+
return (_jsxs("fieldset", { className: "vb-period flex shrink-0 flex-col gap-2", children: [_jsx("legend", { className: "sr-only", children: t("billingPeriod") }), _jsx("div", { className: "inline-flex w-fit rounded-ui border border-line p-1", children: ["monthly", "yearly"].map((p) => (_jsxs("label", { className: "vb-period-option group relative inline-flex h-10 cursor-pointer items-center gap-2 rounded-ui-sm px-4 text-sm font-medium text-fg-muted transition-colors hover:text-fg has-checked:text-scene has-checked:hover:text-scene", children: [_jsx("input", { type: "radio", name: name, value: p, defaultChecked: p === defaultPeriod, className: "vb-period-input peer sr-only" }), _jsx("span", { children: t(p) }), p === "yearly" && saving ? _jsx("span", { className: "font-mono text-eyebrow uppercase tracking-[0.06em] text-accent-ink group-has-checked:text-[color-mix(in_oklch,var(--scene)_80%,var(--accent))]", children: saving }) : null] }, p))) })] }));
|
|
33
|
+
}
|
|
34
|
+
function PriceBlock({ plan, ctx, size = "m" }) {
|
|
35
|
+
const { t, locale, billing } = ctx;
|
|
36
|
+
const numberClass = cn("font-display tabular tracking-[-0.02em] text-fg", size === "l" ? "text-display-l" : "text-display-m");
|
|
37
|
+
if (!plan.price || (!plan.price.monthly && !plan.price.yearly && !plan.price.once)) {
|
|
38
|
+
return plan.custom ? (_jsx("p", { className: numberClass, "data-price": "custom", children: plan.custom })) : null;
|
|
39
|
+
}
|
|
40
|
+
const one = (money, suffix, period) => Number(money.amount) === 0 ? (
|
|
41
|
+
// A zero price reads as "Free", without a period suffix.
|
|
42
|
+
_jsx("p", { "data-period": billing === "both" ? period : undefined, "data-price": "free", className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: _jsx("span", { className: numberClass, children: t("priceFree") }) }, period ?? "once")) : (_jsxs("p", { "data-period": billing === "both" ? period : undefined, className: "flex flex-wrap items-baseline gap-x-2 gap-y-1", children: [plan.price.from ? _jsx("span", { className: "text-small text-fg-muted", children: t("priceFrom") }) : null, _jsx("span", { className: numberClass, "aria-hidden": true, children: formatMoney(money, locale) }), _jsxs("span", { className: "sr-only", children: [plan.price.from ? `${t("priceFrom")} ` : "", formatMoneyLong(money, locale), " ", suffix] }), _jsx("span", { "aria-hidden": true, className: "text-small text-fg-muted", children: suffix })] }, period ?? "once"));
|
|
43
|
+
const p = plan.price;
|
|
44
|
+
if (billing === "once" || (!p.monthly && !p.yearly))
|
|
45
|
+
return p.once ? one(p.once, t("oneOff")) : null;
|
|
46
|
+
if (billing === "yearly")
|
|
47
|
+
return p.yearly ? one(p.yearly, t("perYear"), "yearly") : p.monthly ? one(p.monthly, t("perMonth"), "monthly") : null;
|
|
48
|
+
if (billing === "monthly")
|
|
49
|
+
return p.monthly ? one(p.monthly, t("perMonth"), "monthly") : p.yearly ? one(p.yearly, t("perYear"), "yearly") : null;
|
|
50
|
+
return (_jsxs(_Fragment, { children: [p.monthly ? one(p.monthly, t("perMonth"), "monthly") : null, p.yearly ? one(p.yearly, t("perYear"), "yearly") : null] }));
|
|
51
|
+
}
|
|
52
|
+
function FeatureList({ features, ctx, columns }) {
|
|
53
|
+
if (!features.length)
|
|
54
|
+
return null;
|
|
55
|
+
return (_jsx("ul", { className: cn("flex flex-col gap-3 text-small", columns && "@2xl:grid @2xl:grid-cols-2 @2xl:gap-x-8"), children: features.map((f, i) => {
|
|
56
|
+
const included = f.included !== false;
|
|
57
|
+
return (_jsxs("li", { className: cn("flex gap-3", !included && "text-fg-subtle"), children: [included ? _jsx(Check, { "aria-hidden": true, strokeWidth: 1.5, className: "mt-0.5 size-4 shrink-0 text-fg-muted" }) : _jsx(Minus, { "aria-hidden": true, strokeWidth: 1.5, className: "mt-0.5 size-4 shrink-0" }), _jsxs("span", { className: "flex flex-col gap-0.5", children: [_jsxs("span", { className: included ? "text-fg" : undefined, children: [!included ? _jsxs("span", { className: "sr-only", children: [ctx.t("notIncluded"), ": "] }) : null, f.text] }), f.note ? _jsx("span", { className: "text-xs text-fg-muted", children: f.note }) : null] })] }, i));
|
|
58
|
+
}) }));
|
|
59
|
+
}
|
|
60
|
+
function PlanCta({ plan, ctx, primary, index, block }) {
|
|
61
|
+
if (!plan.cta)
|
|
62
|
+
return null;
|
|
63
|
+
let style = plan.cta.style ?? "secondary";
|
|
64
|
+
if (style === "primary" && !primary)
|
|
65
|
+
style = "secondary";
|
|
66
|
+
if (primary && style !== "link")
|
|
67
|
+
style = "primary";
|
|
68
|
+
return (_jsx(BlockLink, { href: plan.cta.link.href, newTab: plan.cta.link.newTab, appearance: style, size: "lg", components: ctx.components, labels: ctx.labels, locale: ctx.locale, editMode: ctx.editMode, field: `props.plans.${index}.cta`, "data-track": `pricing:${index}`, className: cn(block && style !== "link" && "w-full"), children: plan.cta.link.label }));
|
|
69
|
+
}
|
|
70
|
+
function PlanColumn({ plan, index, ctx, primary }) {
|
|
71
|
+
return (_jsxs("li", { "data-highlight": plan.highlight ? "" : undefined, className: "vb-plan relative flex flex-col gap-7", children: [plan.highlight ? _jsx("span", { "aria-hidden": true, className: "vb-plan-rule absolute -top-px end-0 h-0.5 bg-accent" }) : null, _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [_jsx("h3", { className: "text-h3 font-semibold tracking-[-0.012em] text-fg", ...fieldAttr(ctx.editMode, `plans.${index}.name`), children: plan.name }), plan.highlight ? _jsx("span", { className: "rounded-full bg-accent-soft px-2.5 py-0.5 font-mono text-eyebrow uppercase tracking-[0.06em] text-accent-ink", children: plan.highlight }) : null] }), plan.description ? _jsx("p", { className: "max-w-[34ch] text-small text-fg-muted text-pretty", children: plan.description }) : null] }), _jsx(PriceBlock, { plan: plan, ctx: ctx }), _jsx(PlanCta, { plan: plan, ctx: ctx, primary: primary, index: index, block: true }), plan.features?.length ? (_jsx("div", { className: "border-t border-line pt-6", children: _jsx(FeatureList, { features: plan.features, ctx: ctx }) })) : null] }));
|
|
72
|
+
}
|
|
73
|
+
function PlanRow({ plan, index, ctx, primary }) {
|
|
74
|
+
const included = (plan.features ?? []).filter((f) => f.included !== false);
|
|
75
|
+
return (_jsxs("li", { "data-highlight": plan.highlight ? "" : undefined, className: cn("relative grid gap-x-(--gutter) gap-y-5 border-t border-line py-8 @4xl:grid-cols-12 @4xl:items-start", plan.highlight && "before:absolute before:-top-px before:start-0 before:h-0.5 before:w-16 before:bg-accent"), children: [_jsxs("div", { className: "flex flex-col gap-2 @4xl:col-span-4", children: [_jsxs("div", { className: "flex flex-wrap items-baseline gap-3", children: [_jsx("span", { "aria-hidden": true, className: "font-mono text-eyebrow tabular text-fg-subtle", children: String(index + 1).padStart(2, "0") }), _jsx("h3", { className: "text-h3 font-semibold tracking-[-0.012em] text-fg", children: plan.name }), plan.highlight ? _jsx("span", { className: "font-mono text-eyebrow uppercase tracking-[0.06em] text-accent-ink", children: plan.highlight }) : null] }), plan.description ? _jsx("p", { className: "text-small text-fg-muted text-pretty", children: plan.description }) : null] }), _jsx("p", { className: "text-small text-fg-muted text-pretty @4xl:col-span-5", children: included.map((f, i) => (_jsxs(React.Fragment, { children: [i > 0 ? ", " : null, _jsx("span", { className: "text-fg", children: f.text })] }, i))) }), _jsxs("div", { className: "flex flex-col items-start gap-4 @4xl:col-span-3 @4xl:items-end @4xl:text-end", children: [_jsx(PriceBlock, { plan: plan, ctx: ctx }), _jsx(PlanCta, { plan: plan, ctx: ctx, primary: primary, index: index })] })] }));
|
|
76
|
+
}
|
|
77
|
+
function SinglePlan({ plan, ctx }) {
|
|
78
|
+
const features = plan.features ?? [];
|
|
79
|
+
const included = features.filter((f) => f.included !== false);
|
|
80
|
+
const excluded = features.filter((f) => f.included === false);
|
|
81
|
+
return (_jsxs("div", { className: "surface grid gap-x-(--gutter) gap-y-10 rounded-ui-lg p-6 @2xl:p-10 @4xl:grid-cols-12", children: [_jsxs("div", { className: "flex flex-col gap-6 @4xl:col-span-5", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [_jsx("h3", { className: "text-h3 font-semibold tracking-[-0.012em] text-fg", children: plan.name }), plan.highlight ? _jsx("span", { className: "rounded-full bg-accent-soft px-2.5 py-0.5 font-mono text-eyebrow uppercase tracking-[0.06em] text-accent-ink", children: plan.highlight }) : null] }), plan.description ? _jsx("p", { className: "text-small text-fg-muted text-pretty", children: plan.description }) : null] }), _jsx(PriceBlock, { plan: plan, ctx: ctx, size: "l" }), _jsx(PlanCta, { plan: plan, ctx: ctx, primary: true, index: 0 })] }), _jsxs("div", { className: "flex flex-col gap-6 @4xl:col-span-7 @4xl:border-s @4xl:border-line @4xl:ps-(--gutter)", children: [_jsx("p", { className: "font-mono text-eyebrow uppercase tracking-[0.08em] text-fg-muted", children: ctx.t("included") }), _jsx(FeatureList, { features: included, ctx: ctx, columns: true }), excluded.length ? (_jsxs("p", { className: "border-t border-line pt-4 text-small text-fg-muted", children: [_jsxs("span", { className: "font-medium text-fg", children: [ctx.t("notIncluded"), ": "] }), excluded.map((f, i) => (_jsxs(React.Fragment, { children: [i > 0 ? ", " : null, f.text] }, i)))] })) : null] })] }));
|
|
82
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { BlockBaseProps } from "../types.js";
|
|
3
|
+
import { type SiteBlockLabels, type SiteCta, type SiteImage } from "./_kit-1.js";
|
|
4
|
+
export type StepsVariant = "vertical" | "horizontal" | "split";
|
|
5
|
+
export interface StepsItem {
|
|
6
|
+
title: React.ReactNode;
|
|
7
|
+
/** A string renders as a paragraph; any other node (a code panel, a list) renders in a plain `div`. */
|
|
8
|
+
text?: React.ReactNode;
|
|
9
|
+
/** "1–2 weeks", "45 min". */
|
|
10
|
+
duration?: React.ReactNode;
|
|
11
|
+
media?: SiteImage;
|
|
12
|
+
}
|
|
13
|
+
export interface StepsProps extends Omit<BlockBaseProps, "variant" | "labels"> {
|
|
14
|
+
/**
|
|
15
|
+
* vertical: a thin rule along the start edge with mono numbers on it, a duration tag per step.
|
|
16
|
+
* horizontal: a timeline on wide containers (numbers above the line, text below); vertical when narrow.
|
|
17
|
+
* split: sticky title on the start side (4 cols), big hairline-separated numbered steps on the end side.
|
|
18
|
+
*/
|
|
19
|
+
variant?: StepsVariant;
|
|
20
|
+
eyebrow?: React.ReactNode;
|
|
21
|
+
title?: React.ReactNode;
|
|
22
|
+
lead?: React.ReactNode;
|
|
23
|
+
steps: StepsItem[];
|
|
24
|
+
/** Under the steps (≤ 2). */
|
|
25
|
+
actions?: SiteCta[];
|
|
26
|
+
labels?: SiteBlockLabels;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* "How we work" — discovery → design → launch; a first spa visit; SaaS setup. An ordered list
|
|
30
|
+
* (the order is announced; the numbers are visual). Server component.
|
|
31
|
+
*
|
|
32
|
+
* ```tsx
|
|
33
|
+
* <Steps title="How a project *runs*" steps={[{ title: "Discovery", text: "…", duration: "1 week" }]} />
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function Steps({ variant, eyebrow, title, lead, steps, actions, id, theme, anchor, className, headingLevel, labels, locale, components, editMode }: StepsProps): React.JSX.Element;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../lib/cn.js";
|
|
3
|
+
import { Container, Section } from "../section.js";
|
|
4
|
+
import { SectionHeader } from "../section-header.js";
|
|
5
|
+
import { BlockImage } from "../block-image.js";
|
|
6
|
+
import { CtaList, indexLabel, useBlockIds } from "./_kit-1.js";
|
|
7
|
+
/**
|
|
8
|
+
* "How we work" — discovery → design → launch; a first spa visit; SaaS setup. An ordered list
|
|
9
|
+
* (the order is announced; the numbers are visual). Server component.
|
|
10
|
+
*
|
|
11
|
+
* ```tsx
|
|
12
|
+
* <Steps title="How a project *runs*" steps={[{ title: "Discovery", text: "…", duration: "1 week" }]} />
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export function Steps({ variant = "vertical", eyebrow, title, lead, steps, actions, id, theme, anchor, className, headingLevel = 2, labels, locale, components, editMode }) {
|
|
16
|
+
const { base, headingId } = useBlockIds(id, "steps");
|
|
17
|
+
const StepTag = `h${Math.min(headingLevel + 1, 6)}`;
|
|
18
|
+
const f = (i, k) => (editMode ? { "data-field": `props.steps.${i}.${k}` } : undefined);
|
|
19
|
+
const stepTitle = (s, i, cls) => (_jsx(StepTag, { className: cn("text-h3 font-semibold tracking-[-0.012em] text-fg text-balance", cls), ...f(i, "title"), children: s.title }));
|
|
20
|
+
const stepText = (s, i) => {
|
|
21
|
+
if (!s.text)
|
|
22
|
+
return null;
|
|
23
|
+
const Tag = typeof s.text === "string" || typeof s.text === "number" ? "p" : "div";
|
|
24
|
+
return (_jsx(Tag, { className: cn("text-body text-fg-muted text-pretty", Tag === "p" ? "max-w-[52ch]" : "flex min-w-0 flex-col gap-3"), ...f(i, "text"), children: s.text }));
|
|
25
|
+
};
|
|
26
|
+
const duration = (s, i) => s.duration ? (_jsx("span", { className: "inline-flex w-fit items-center rounded-full border border-line px-2.5 py-0.5 font-mono text-[0.6875rem] tabular tracking-[0.04em] text-fg-muted", ...f(i, "duration"), children: s.duration })) : null;
|
|
27
|
+
const media = (s) => (s.media ? _jsx(BlockImage, { ...s.media, aspect: "3:2", sizes: "(min-width: 56rem) 30vw, 100vw", className: "mt-2 max-w-md rounded-ui", components: components, labels: labels }) : null);
|
|
28
|
+
const header = title || eyebrow || lead ? _jsx(SectionHeader, { eyebrow: eyebrow, title: title, lead: lead, align: variant === "horizontal" && lead ? "split" : "start", headingLevel: headingLevel, headingId: headingId, editMode: editMode, labels: labels, locale: locale }) : null;
|
|
29
|
+
const actionsEl = actions?.length ? _jsx(CtaList, { actions: actions, components: components, labels: labels, locale: locale, editMode: editMode }) : null;
|
|
30
|
+
let content;
|
|
31
|
+
if (variant === "split") {
|
|
32
|
+
content = (_jsxs(Container, { className: "grid gap-x-(--gutter) gap-y-10 @4xl:grid-cols-12", children: [_jsx("div", { className: "@4xl:col-span-4", children: _jsxs("div", { className: "flex flex-col gap-8 @4xl:sticky @4xl:top-[calc(var(--vb-nav-h,4.5rem)+2rem)]", children: [header, actionsEl] }) }), _jsx("ol", { className: "flex flex-col @4xl:col-span-7 @4xl:col-start-6", children: steps.map((s, i) => (_jsxs("li", { className: "grid grid-cols-[auto_1fr] gap-x-[clamp(1.25rem,4cqi,3rem)] gap-y-3 border-t border-line py-8 last:border-b", children: [_jsx("span", { "aria-hidden": true, className: "row-span-4 font-display text-display-m leading-none tabular text-fg-subtle", children: indexLabel(i) }), stepTitle(s, i, "pt-1"), stepText(s, i), duration(s, i), media(s)] }, i))) })] }));
|
|
33
|
+
}
|
|
34
|
+
else if (variant === "horizontal") {
|
|
35
|
+
content = (_jsxs(Container, { className: "flex flex-col gap-[calc(var(--section-y)*0.4)]", children: [header, _jsx("ol", { className: "vb-steps-h grid gap-y-0 @4xl:gap-x-(--gutter)", style: { "--vb-steps": steps.length }, children: steps.map((s, i) => (_jsxs("li", { className: "vb-step relative flex flex-col gap-3 ps-10 pb-10 @4xl:ps-0 @4xl:pb-0", children: [_jsx("span", { "aria-hidden": true, className: "vb-step-num font-mono text-eyebrow tabular text-fg-muted", children: indexLabel(i) }), _jsx("span", { "aria-hidden": true, className: cn("vb-step-dot", i === 0 && "vb-step-dot-first") }), _jsxs("div", { className: "flex flex-col gap-3 @4xl:pt-6", children: [stepTitle(s, i), stepText(s, i), duration(s, i), media(s)] })] }, i))) }), actionsEl] }));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
content = (_jsxs(Container, { className: "grid gap-x-(--gutter) gap-y-12 @4xl:grid-cols-12", children: [_jsxs("div", { className: "flex flex-col gap-8 @4xl:col-span-5", children: [header, actionsEl] }), _jsx("ol", { className: "vb-steps-v flex flex-col @4xl:col-span-6 @4xl:col-start-7", children: steps.map((s, i) => (_jsxs("li", { className: "vb-step relative flex flex-col gap-3 ps-12 pb-10 last:pb-0", children: [_jsx("span", { "aria-hidden": true, className: cn("vb-step-badge absolute start-0 top-0 inline-flex size-8 items-center justify-center rounded-full border border-line bg-scene font-mono text-[0.6875rem] tabular text-fg-muted", i === 0 && "vb-step-badge-first"), children: indexLabel(i) }), _jsxs("div", { className: "flex flex-wrap items-baseline justify-between gap-x-4 gap-y-2 pt-1", children: [stepTitle(s, i), duration(s, i)] }), stepText(s, i), media(s)] }, i))) })] }));
|
|
39
|
+
}
|
|
40
|
+
return (_jsx(Section, { theme: theme, anchor: anchor, headingId: title ? headingId : undefined, blockId: base, blockType: "steps", editMode: editMode, className: cn("vb-steps", className), "data-variant": variant, children: _jsx("div", { className: "vb-reveal", children: content }) }));
|
|
41
|
+
}
|