@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,337 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { ArrowLeft, ArrowRight, Check, CloudUpload, Pencil } from "lucide-react";
|
|
5
|
+
import { cn } from "../lib/cn.js";
|
|
6
|
+
import { useLabels } from "../lib/labels.js";
|
|
7
|
+
import { useLocale } from "../lib/locale.js";
|
|
8
|
+
import { useLatest } from "../lib/use-controllable-state.js";
|
|
9
|
+
import { focusFirstInvalid } from "../lib/field-context.js";
|
|
10
|
+
import { Button } from "../components/button.js";
|
|
11
|
+
import { Alert } from "../components/alert.js";
|
|
12
|
+
import { Stepper } from "../components/stepper.js";
|
|
13
|
+
export const multiStepFormLabels = {
|
|
14
|
+
back: "Back",
|
|
15
|
+
next: "Next",
|
|
16
|
+
submit: "Submit",
|
|
17
|
+
submitting: "Submitting…",
|
|
18
|
+
saveDraft: "Save draft",
|
|
19
|
+
savingDraft: "Saving…",
|
|
20
|
+
draftSaved: "Draft saved {time}",
|
|
21
|
+
draftFailed: "Draft not saved",
|
|
22
|
+
step: "Step {current} of {total}",
|
|
23
|
+
stepHeading: "Step {current} of {total}: {title}",
|
|
24
|
+
optional: "Optional",
|
|
25
|
+
fixErrors: "Check this step",
|
|
26
|
+
submitFailed: "Couldn't submit",
|
|
27
|
+
edit: "Edit {title}",
|
|
28
|
+
review: "Review",
|
|
29
|
+
leave: "You have unsaved changes. Leave anyway?",
|
|
30
|
+
};
|
|
31
|
+
const MultiStepFormContext = React.createContext(null);
|
|
32
|
+
function useCtx(part) {
|
|
33
|
+
const ctx = React.useContext(MultiStepFormContext);
|
|
34
|
+
if (!ctx)
|
|
35
|
+
throw new Error(`<${part}> must be used inside <MultiStepForm>.`);
|
|
36
|
+
return ctx;
|
|
37
|
+
}
|
|
38
|
+
/** State and navigation of the surrounding `MultiStepForm`. */
|
|
39
|
+
export function useMultiStepForm() {
|
|
40
|
+
const c = useCtx("useMultiStepForm");
|
|
41
|
+
return {
|
|
42
|
+
current: c.current.id,
|
|
43
|
+
index: c.index,
|
|
44
|
+
total: c.visible.length,
|
|
45
|
+
steps: c.visible,
|
|
46
|
+
next: c.next,
|
|
47
|
+
back: c.back,
|
|
48
|
+
goTo: c.goTo,
|
|
49
|
+
saveDraft: c.saveDraft,
|
|
50
|
+
isFirst: c.isFirst,
|
|
51
|
+
isLast: c.isLast,
|
|
52
|
+
status: c.status,
|
|
53
|
+
submitting: c.submitting,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function urlKey(syncUrl) {
|
|
57
|
+
if (!syncUrl)
|
|
58
|
+
return null;
|
|
59
|
+
return typeof syncUrl === "object" ? syncUrl.key : "step";
|
|
60
|
+
}
|
|
61
|
+
function MultiStepFormInner(props, ref) {
|
|
62
|
+
const { steps, value, defaultValue, onValueChange, context, linear = true, onComplete, onSaveDraft, autosave, presentation = "page", orientation = "horizontal", syncUrl, confirmLeave, labels, className, children, ...formProps } = props;
|
|
63
|
+
const t = useLabels("multiStepForm", multiStepFormLabels, labels);
|
|
64
|
+
const visible = React.useMemo(() => steps.filter((s) => !s.when || s.when(context)), [steps, context]);
|
|
65
|
+
const key = urlKey(syncUrl);
|
|
66
|
+
const [inner, setInner] = React.useState(() => defaultValue ?? steps[0]?.id ?? "");
|
|
67
|
+
// Resume from the URL after mount (keeps server and client markup identical).
|
|
68
|
+
React.useEffect(() => {
|
|
69
|
+
if (!key)
|
|
70
|
+
return;
|
|
71
|
+
const fromUrl = new URLSearchParams(window.location.search).get(key);
|
|
72
|
+
if (fromUrl && steps.some((s) => s.id === fromUrl)) {
|
|
73
|
+
if (value === undefined)
|
|
74
|
+
setInner(fromUrl);
|
|
75
|
+
onValueChange?.(fromUrl);
|
|
76
|
+
}
|
|
77
|
+
}, [key]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
78
|
+
const currentId = value ?? inner;
|
|
79
|
+
const index = Math.max(0, visible.findIndex((s) => s.id === currentId));
|
|
80
|
+
const current = visible[index] ?? visible[0];
|
|
81
|
+
const [completed, setCompleted] = React.useState(() => new Set());
|
|
82
|
+
const [errors, setErrors] = React.useState({});
|
|
83
|
+
const [validating, setValidating] = React.useState(false);
|
|
84
|
+
const [submitting, setSubmitting] = React.useState(false);
|
|
85
|
+
const [submitError, setSubmitError] = React.useState(null);
|
|
86
|
+
const [draft, setDraft] = React.useState({ state: "idle" });
|
|
87
|
+
const [done, setDone] = React.useState(false);
|
|
88
|
+
const headingRef = React.useRef(null);
|
|
89
|
+
const formRef = React.useRef(null);
|
|
90
|
+
const moved = React.useRef(false);
|
|
91
|
+
const setStep = React.useCallback((id) => {
|
|
92
|
+
moved.current = true;
|
|
93
|
+
if (value === undefined)
|
|
94
|
+
setInner(id);
|
|
95
|
+
onValueChange?.(id);
|
|
96
|
+
setSubmitError(null);
|
|
97
|
+
if (key && typeof window !== "undefined") {
|
|
98
|
+
const url = new URL(window.location.href);
|
|
99
|
+
url.searchParams.set(key, id);
|
|
100
|
+
window.history.replaceState(window.history.state, "", url);
|
|
101
|
+
}
|
|
102
|
+
}, [value, onValueChange, key]);
|
|
103
|
+
// Focus the step heading after a step change (announced as "Step 3 of 6: Contract").
|
|
104
|
+
React.useEffect(() => {
|
|
105
|
+
if (!moved.current)
|
|
106
|
+
return;
|
|
107
|
+
moved.current = false;
|
|
108
|
+
headingRef.current?.focus({ preventScroll: false });
|
|
109
|
+
}, [current?.id]);
|
|
110
|
+
const runValidate = async (step) => {
|
|
111
|
+
if (!step.validate)
|
|
112
|
+
return true;
|
|
113
|
+
setValidating(true);
|
|
114
|
+
try {
|
|
115
|
+
const r = await step.validate();
|
|
116
|
+
setErrors((e) => ({ ...e, [step.id]: r === true ? undefined : r }));
|
|
117
|
+
if (r !== true) {
|
|
118
|
+
requestAnimationFrame(() => {
|
|
119
|
+
const panel = formRef.current?.querySelector(`[data-step-panel="${step.id}"]`);
|
|
120
|
+
if (!focusFirstInvalid(panel))
|
|
121
|
+
panel?.querySelector("[data-msf-error]")?.focus();
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return r === true;
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
setValidating(false);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
const isLast = index === visible.length - 1;
|
|
131
|
+
const next = async () => {
|
|
132
|
+
if (submitting || validating)
|
|
133
|
+
return;
|
|
134
|
+
const ok = await runValidate(current);
|
|
135
|
+
if (!ok)
|
|
136
|
+
return;
|
|
137
|
+
setCompleted((s) => new Set(s).add(current.id));
|
|
138
|
+
if (!isLast) {
|
|
139
|
+
setStep(visible[index + 1].id);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
setSubmitting(true);
|
|
143
|
+
setSubmitError(null);
|
|
144
|
+
try {
|
|
145
|
+
await onComplete();
|
|
146
|
+
setDone(true);
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
setSubmitError(e instanceof Error ? e.message : String(e));
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
setSubmitting(false);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const back = () => {
|
|
156
|
+
if (index > 0 && !submitting)
|
|
157
|
+
setStep(visible[index - 1].id);
|
|
158
|
+
};
|
|
159
|
+
const canGoTo = (id) => {
|
|
160
|
+
if (submitting)
|
|
161
|
+
return false;
|
|
162
|
+
const target = visible.findIndex((s) => s.id === id);
|
|
163
|
+
if (target < 0)
|
|
164
|
+
return false;
|
|
165
|
+
if (!linear || target <= index)
|
|
166
|
+
return true;
|
|
167
|
+
// Linear: every step before the target must be complete.
|
|
168
|
+
return visible.slice(0, target).every((s) => completed.has(s.id) && !errors[s.id]);
|
|
169
|
+
};
|
|
170
|
+
const goTo = (id) => {
|
|
171
|
+
if (canGoTo(id))
|
|
172
|
+
setStep(id);
|
|
173
|
+
};
|
|
174
|
+
const saveRef = useLatest(onSaveDraft);
|
|
175
|
+
const saveDraft = React.useCallback(async () => {
|
|
176
|
+
if (!saveRef.current)
|
|
177
|
+
return;
|
|
178
|
+
setDraft((d) => ({ ...d, state: "saving" }));
|
|
179
|
+
try {
|
|
180
|
+
await saveRef.current();
|
|
181
|
+
setDraft({ state: "saved", at: Date.now() });
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
setDraft({ state: "error" });
|
|
185
|
+
}
|
|
186
|
+
}, [saveRef]);
|
|
187
|
+
React.useEffect(() => {
|
|
188
|
+
if (!autosave || !onSaveDraft || done)
|
|
189
|
+
return;
|
|
190
|
+
const id = setInterval(() => void saveDraft(), Math.max(2000, autosave.intervalMs));
|
|
191
|
+
return () => clearInterval(id);
|
|
192
|
+
}, [autosave?.intervalMs, onSaveDraft, saveDraft, done]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
193
|
+
React.useEffect(() => {
|
|
194
|
+
if (!confirmLeave || done)
|
|
195
|
+
return;
|
|
196
|
+
const onBeforeUnload = (e) => {
|
|
197
|
+
e.preventDefault();
|
|
198
|
+
e.returnValue = t("leave");
|
|
199
|
+
};
|
|
200
|
+
window.addEventListener("beforeunload", onBeforeUnload);
|
|
201
|
+
return () => window.removeEventListener("beforeunload", onBeforeUnload);
|
|
202
|
+
}, [confirmLeave, done, t]);
|
|
203
|
+
const status = {};
|
|
204
|
+
visible.forEach((s, i) => {
|
|
205
|
+
status[s.id] = errors[s.id] ? "error" : i === index ? "current" : completed.has(s.id) ? "complete" : "upcoming";
|
|
206
|
+
});
|
|
207
|
+
const ctx = {
|
|
208
|
+
steps: steps,
|
|
209
|
+
visible: visible,
|
|
210
|
+
current: current,
|
|
211
|
+
index,
|
|
212
|
+
status,
|
|
213
|
+
errors,
|
|
214
|
+
isFirst: index === 0,
|
|
215
|
+
isLast,
|
|
216
|
+
submitting,
|
|
217
|
+
validating,
|
|
218
|
+
submitError,
|
|
219
|
+
draft,
|
|
220
|
+
canSaveDraft: !!onSaveDraft,
|
|
221
|
+
linear,
|
|
222
|
+
presentation,
|
|
223
|
+
orientation,
|
|
224
|
+
next,
|
|
225
|
+
back,
|
|
226
|
+
goTo,
|
|
227
|
+
saveDraft,
|
|
228
|
+
canGoTo,
|
|
229
|
+
t,
|
|
230
|
+
headingRef,
|
|
231
|
+
};
|
|
232
|
+
return (_jsx(MultiStepFormContext.Provider, { value: ctx, children: _jsx("form", { ref: (node) => {
|
|
233
|
+
formRef.current = node;
|
|
234
|
+
if (typeof ref === "function")
|
|
235
|
+
ref(node);
|
|
236
|
+
else if (ref)
|
|
237
|
+
ref.current = node;
|
|
238
|
+
}, noValidate: true, "data-slot": "multi-step-form", "data-presentation": presentation, "data-orientation": orientation, "aria-busy": submitting || undefined, className: cn("vui-msf flex min-w-0 flex-col gap-6", orientation === "vertical" && "md:grid md:grid-cols-[14rem_minmax(0,1fr)] md:gap-x-10", className), onSubmit: (e) => {
|
|
239
|
+
e.preventDefault();
|
|
240
|
+
void next();
|
|
241
|
+
}, onKeyDown: (e) => {
|
|
242
|
+
// Enter in a single-line field moves to the next step instead of submitting everything.
|
|
243
|
+
const el = e.target;
|
|
244
|
+
if (e.key !== "Enter" || e.shiftKey || e.altKey || e.nativeEvent.isComposing)
|
|
245
|
+
return;
|
|
246
|
+
if (el.tagName === "INPUT" && !["checkbox", "radio", "button", "submit", "file"].includes(el.type)) {
|
|
247
|
+
e.preventDefault();
|
|
248
|
+
void next();
|
|
249
|
+
}
|
|
250
|
+
}, ...formProps, children: children }) }));
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* A long form split into steps: per-step validation, conditional steps, draft saving, a review
|
|
254
|
+
* step and URL resume. Form-library agnostic — each step exposes `validate()`.
|
|
255
|
+
*
|
|
256
|
+
* ```tsx
|
|
257
|
+
* <MultiStepForm steps={steps} onComplete={submit}>
|
|
258
|
+
* <MultiStepFormStepper />
|
|
259
|
+
* <MultiStepFormStep id="identity">…fields…</MultiStepFormStep>
|
|
260
|
+
* <MultiStepFormStep id="review"><MultiStepFormReview>…</MultiStepFormReview></MultiStepFormStep>
|
|
261
|
+
* <MultiStepFormFooter />
|
|
262
|
+
* </MultiStepForm>
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
export const MultiStepForm = React.forwardRef(MultiStepFormInner);
|
|
266
|
+
/** The progress display (kit `Stepper`), wired to the form: completed steps are clickable. */
|
|
267
|
+
export function MultiStepFormStepper({ variant = "numbered", className }) {
|
|
268
|
+
const c = useCtx("MultiStepFormStepper");
|
|
269
|
+
const items = c.visible.map((s) => ({
|
|
270
|
+
id: s.id,
|
|
271
|
+
title: s.title,
|
|
272
|
+
description: c.orientation === "vertical" ? s.description : undefined,
|
|
273
|
+
optional: s.optional,
|
|
274
|
+
status: c.status[s.id] === "error" ? "error" : undefined,
|
|
275
|
+
disabled: !c.canGoTo(s.id),
|
|
276
|
+
}));
|
|
277
|
+
return (_jsx(Stepper, { "data-slot": "multi-step-form-stepper", value: c.index, steps: items, orientation: c.orientation, variant: variant, loading: c.validating || c.submitting, navigable: (i) => i !== c.index && c.canGoTo(c.visible[i].id), onValueChange: (i) => c.goTo(c.visible[i].id), className: cn(c.orientation === "vertical" && "md:row-span-3 md:sticky md:top-4 md:self-start", className) }));
|
|
278
|
+
}
|
|
279
|
+
/** One step's content. Shows its heading ("Step 2 of 5" + title) and the error summary. */
|
|
280
|
+
export function MultiStepFormStep({ id, hideHeading, keepMounted = true, className, children, ...props }) {
|
|
281
|
+
const c = useCtx("MultiStepFormStep");
|
|
282
|
+
const step = c.visible.find((s) => s.id === id);
|
|
283
|
+
if (!step)
|
|
284
|
+
return null;
|
|
285
|
+
const active = c.current.id === id;
|
|
286
|
+
if (!active && !keepMounted)
|
|
287
|
+
return null;
|
|
288
|
+
const position = c.visible.indexOf(step) + 1;
|
|
289
|
+
const error = c.errors[id];
|
|
290
|
+
const headingId = `msf-${id}-heading`;
|
|
291
|
+
return (_jsx("section", { "data-slot": "multi-step-form-step", "data-step-panel": id, hidden: !active, "aria-labelledby": headingId, className: cn("min-w-0", active && "vui-msf-step-in", className), ...props, children: _jsxs("fieldset", { disabled: c.submitting, className: "m-0 min-w-0 border-0 p-0", children: [hideHeading ? (_jsx("h2", { id: headingId, className: "sr-only", tabIndex: -1, ref: active ? c.headingRef : undefined, children: c.t("stepHeading", { current: position, total: c.visible.length, title: step.title }) })) : (_jsxs("header", { className: "mb-5", children: [_jsxs("p", { className: "font-mono text-[11px] tracking-[0.06em] text-fg-subtle uppercase", "aria-hidden": true, children: [c.t("step", { current: position, total: c.visible.length }), step.optional ? ` · ${c.t("optional")}` : ""] }), _jsxs("h2", { id: headingId, tabIndex: -1, ref: active ? c.headingRef : undefined, className: "mt-1 text-[22px] font-semibold tracking-[-0.016em] text-fg outline-none", children: [_jsxs("span", { className: "sr-only", children: [c.t("step", { current: position, total: c.visible.length }), ":"] }), " ", step.title] }), step.description ? _jsx("p", { className: "mt-1 max-w-prose text-sm text-fg-muted", children: step.description }) : null] })), error ? (_jsx(Alert, { tone: "danger", title: c.t("fixErrors"), className: "mb-5", "data-msf-error": "", tabIndex: -1, live: "assertive", children: error })) : null, active && c.isLast && c.submitError ? (_jsx(Alert, { tone: "danger", title: c.t("submitFailed"), className: "mb-5", live: "assertive", children: c.submitError })) : null, children] }) }));
|
|
292
|
+
}
|
|
293
|
+
/** A summary of earlier steps with "Edit" links back to each one. */
|
|
294
|
+
export function MultiStepFormReview({ sections, className, ...props }) {
|
|
295
|
+
const c = useCtx("MultiStepFormReview");
|
|
296
|
+
return (_jsx("div", { "data-slot": "multi-step-form-review", className: cn("flex flex-col divide-y divide-line rounded-ui-lg border border-line", className), ...props, children: sections
|
|
297
|
+
.filter((s) => c.visible.some((v) => v.id === s.step))
|
|
298
|
+
.map((s) => {
|
|
299
|
+
const title = s.title ?? c.visible.find((v) => v.id === s.step)?.title ?? s.step;
|
|
300
|
+
return (_jsxs("section", { className: "px-4 py-3.5", "aria-label": title, children: [_jsxs("div", { className: "mb-2 flex items-center justify-between gap-3", children: [_jsx("h3", { className: "text-[13px] font-semibold text-fg", children: title }), _jsxs(Button, { size: "xs", variant: "ghost", onClick: () => c.goTo(s.step), "aria-label": c.t("edit", { title }), children: [_jsx(Pencil, {}), " ", _jsx("span", { "aria-hidden": true, children: c.t("edit", { title: "" }).trim() })] })] }), _jsx("dl", { className: "grid grid-cols-1 gap-x-6 gap-y-1.5 text-sm sm:grid-cols-[minmax(8rem,12rem)_1fr]", children: s.items.map((it) => (_jsxs("div", { className: "contents", children: [_jsx("dt", { className: "text-fg-muted", children: it.label }), _jsx("dd", { className: "min-w-0 text-fg [overflow-wrap:anywhere]", children: it.value || _jsx("span", { className: "text-fg-subtle", children: "\u2014" }) })] }, it.label))) })] }, s.step));
|
|
301
|
+
}) }));
|
|
302
|
+
}
|
|
303
|
+
/** Back · Save draft · Next / Submit. Sticky at the bottom in page presentation. */
|
|
304
|
+
export function MultiStepFormFooter({ submitLabel, start, className, ...props }) {
|
|
305
|
+
const c = useCtx("MultiStepFormFooter");
|
|
306
|
+
// The opaque backing only appears while the footer is actually stuck over scrolling content;
|
|
307
|
+
// at rest it sits flush on whatever surface holds the form.
|
|
308
|
+
const footerRef = React.useRef(null);
|
|
309
|
+
const [stuck, setStuck] = React.useState(false);
|
|
310
|
+
React.useEffect(() => {
|
|
311
|
+
const el = footerRef.current;
|
|
312
|
+
if (c.presentation !== "page" || !el || typeof IntersectionObserver === "undefined")
|
|
313
|
+
return;
|
|
314
|
+
const io = new IntersectionObserver(([e]) => setStuck(!!e && e.intersectionRatio < 1 && e.boundingClientRect.top > 0), {
|
|
315
|
+
rootMargin: "0px 0px -1px 0px",
|
|
316
|
+
threshold: [1],
|
|
317
|
+
});
|
|
318
|
+
io.observe(el);
|
|
319
|
+
return () => io.disconnect();
|
|
320
|
+
}, [c.presentation]);
|
|
321
|
+
const { format } = useLocale();
|
|
322
|
+
const [, tick] = React.useReducer((n) => n + 1, 0);
|
|
323
|
+
React.useEffect(() => {
|
|
324
|
+
if (c.draft.state !== "saved")
|
|
325
|
+
return;
|
|
326
|
+
const id = setInterval(tick, 30_000);
|
|
327
|
+
return () => clearInterval(id);
|
|
328
|
+
}, [c.draft.state]);
|
|
329
|
+
const draftText = c.draft.state === "saving"
|
|
330
|
+
? c.t("savingDraft")
|
|
331
|
+
: c.draft.state === "saved" && c.draft.at
|
|
332
|
+
? c.t("draftSaved", { time: format.relative(c.draft.at) })
|
|
333
|
+
: c.draft.state === "error"
|
|
334
|
+
? c.t("draftFailed")
|
|
335
|
+
: "";
|
|
336
|
+
return (_jsxs("div", { ref: footerRef, "data-slot": "multi-step-form-footer", "data-stuck": stuck ? "" : undefined, className: cn("vui-msf-footer flex flex-wrap items-center gap-2 border-t border-line pt-4", c.presentation === "page" && "sticky bottom-0 z-10 -mx-1 px-1 pb-1", c.orientation === "vertical" && "md:col-start-2", className), ...props, children: [start, !c.isFirst ? (_jsxs(Button, { variant: "ghost", onClick: c.back, disabled: c.submitting, children: [_jsx(ArrowLeft, { className: "rtl:rotate-180" }), " ", c.t("back")] })) : null, _jsx("span", { className: "flex-1" }), _jsx("span", { className: cn("text-xs text-fg-subtle", c.draft.state === "error" && "text-danger"), "aria-live": "polite", children: draftText }), c.canSaveDraft ? (_jsxs(Button, { variant: "secondary", onClick: () => void c.saveDraft(), loading: c.draft.state === "saving", disabled: c.submitting, children: [_jsx(CloudUpload, {}), " ", c.t("saveDraft")] })) : null, _jsx(Button, { type: "submit", variant: "primary", loading: c.submitting || c.validating, loadingText: c.submitting ? c.t("submitting") : undefined, children: c.isLast ? (_jsxs(_Fragment, { children: [_jsx(Check, {}), " ", submitLabel ?? c.t("submit")] })) : (_jsxs(_Fragment, { children: [c.t("next"), " ", _jsx(ArrowRight, { className: "rtl:rotate-180" })] })) })] }));
|
|
337
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission matrix maths — React-free. A value is `resource → action → Scope | boolean`;
|
|
3
|
+
* missing entries mean "not granted here" (and fall back to `inherited` when given).
|
|
4
|
+
*/
|
|
5
|
+
export type PermissionScope = "none" | "own" | "team" | "all";
|
|
6
|
+
export type PermissionLevel = PermissionScope | boolean;
|
|
7
|
+
export type PermissionValue = Record<string, Record<string, PermissionLevel | undefined>>;
|
|
8
|
+
export interface PermissionDependency {
|
|
9
|
+
/** "edit" … */
|
|
10
|
+
action: string;
|
|
11
|
+
/** … requires "view". */
|
|
12
|
+
requires: string;
|
|
13
|
+
}
|
|
14
|
+
export interface PermissionChange {
|
|
15
|
+
resource: string;
|
|
16
|
+
action: string;
|
|
17
|
+
from: PermissionLevel | undefined;
|
|
18
|
+
to: PermissionLevel | undefined;
|
|
19
|
+
}
|
|
20
|
+
export declare const SCOPE_ORDER: PermissionScope[];
|
|
21
|
+
/** 0 none · 1 own · 2 team · 3 all; booleans map to 0 / 3. */
|
|
22
|
+
export declare function scopeRank(v: PermissionLevel | undefined): number;
|
|
23
|
+
export declare function isGranted(v: PermissionLevel | undefined): boolean;
|
|
24
|
+
/** The value in effect: own entry, else the inherited one. */
|
|
25
|
+
export declare function effectiveLevel(value: PermissionValue, inherited: PermissionValue | undefined, resource: string, action: string): PermissionLevel | undefined;
|
|
26
|
+
/** Every changed cell between two values, in resource / action order of `b`, then `a`. */
|
|
27
|
+
export declare function diffPermissions(a: PermissionValue, b: PermissionValue): PermissionChange[];
|
|
28
|
+
declare function setLevel(v: PermissionValue, resource: string, action: string, level: PermissionLevel | undefined): PermissionValue;
|
|
29
|
+
/**
|
|
30
|
+
* Makes a value consistent with dependencies: a granted action raises what it requires to at
|
|
31
|
+
* least its scope ("edit: team" → "view: team"); a revoked requirement lowers its dependents.
|
|
32
|
+
* `changed` (the cell the user just set) decides the direction. Returns the new value and the
|
|
33
|
+
* cells that were adjusted.
|
|
34
|
+
*/
|
|
35
|
+
export declare function applyDependencies(value: PermissionValue, deps: PermissionDependency[], options?: {
|
|
36
|
+
changed?: {
|
|
37
|
+
resource: string;
|
|
38
|
+
action: string;
|
|
39
|
+
};
|
|
40
|
+
scoped?: (action: string) => boolean;
|
|
41
|
+
resources?: string[];
|
|
42
|
+
}): {
|
|
43
|
+
value: PermissionValue;
|
|
44
|
+
adjusted: {
|
|
45
|
+
resource: string;
|
|
46
|
+
action: string;
|
|
47
|
+
reason: PermissionDependency;
|
|
48
|
+
level: PermissionLevel;
|
|
49
|
+
}[];
|
|
50
|
+
};
|
|
51
|
+
/** Grants (or revokes) one action on many resources, or many actions on one resource. */
|
|
52
|
+
export declare function setMany(value: PermissionValue, cells: {
|
|
53
|
+
resource: string;
|
|
54
|
+
action: string;
|
|
55
|
+
}[], level: (cell: {
|
|
56
|
+
resource: string;
|
|
57
|
+
action: string;
|
|
58
|
+
}) => PermissionLevel | undefined): PermissionValue;
|
|
59
|
+
export { setLevel as setPermission };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission matrix maths — React-free. A value is `resource → action → Scope | boolean`;
|
|
3
|
+
* missing entries mean "not granted here" (and fall back to `inherited` when given).
|
|
4
|
+
*/
|
|
5
|
+
export const SCOPE_ORDER = ["none", "own", "team", "all"];
|
|
6
|
+
/** 0 none · 1 own · 2 team · 3 all; booleans map to 0 / 3. */
|
|
7
|
+
export function scopeRank(v) {
|
|
8
|
+
if (v === undefined || v === false || v === "none")
|
|
9
|
+
return 0;
|
|
10
|
+
if (v === true)
|
|
11
|
+
return 3;
|
|
12
|
+
return SCOPE_ORDER.indexOf(v);
|
|
13
|
+
}
|
|
14
|
+
export function isGranted(v) {
|
|
15
|
+
return scopeRank(v) > 0;
|
|
16
|
+
}
|
|
17
|
+
/** The value in effect: own entry, else the inherited one. */
|
|
18
|
+
export function effectiveLevel(value, inherited, resource, action) {
|
|
19
|
+
const own = value[resource]?.[action];
|
|
20
|
+
return own !== undefined ? own : inherited?.[resource]?.[action];
|
|
21
|
+
}
|
|
22
|
+
/** Every changed cell between two values, in resource / action order of `b`, then `a`. */
|
|
23
|
+
export function diffPermissions(a, b) {
|
|
24
|
+
const out = [];
|
|
25
|
+
const resources = [...new Set([...Object.keys(b), ...Object.keys(a)])];
|
|
26
|
+
for (const r of resources) {
|
|
27
|
+
const actions = [...new Set([...Object.keys(b[r] ?? {}), ...Object.keys(a[r] ?? {})])];
|
|
28
|
+
for (const act of actions) {
|
|
29
|
+
const from = a[r]?.[act];
|
|
30
|
+
const to = b[r]?.[act];
|
|
31
|
+
const norm = (v) => (v === undefined || v === false || v === "none" ? undefined : v);
|
|
32
|
+
if (norm(from) !== norm(to))
|
|
33
|
+
out.push({ resource: r, action: act, from, to });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
function setLevel(v, resource, action, level) {
|
|
39
|
+
const row = { ...(v[resource] ?? {}) };
|
|
40
|
+
if (level === undefined)
|
|
41
|
+
delete row[action];
|
|
42
|
+
else
|
|
43
|
+
row[action] = level;
|
|
44
|
+
return { ...v, [resource]: row };
|
|
45
|
+
}
|
|
46
|
+
/** Same kind of level (boolean or scope) at a given rank. */
|
|
47
|
+
function atRank(sample, rank, scoped) {
|
|
48
|
+
if (!scoped && (typeof sample === "boolean" || sample === undefined))
|
|
49
|
+
return rank > 0;
|
|
50
|
+
return SCOPE_ORDER[rank];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Makes a value consistent with dependencies: a granted action raises what it requires to at
|
|
54
|
+
* least its scope ("edit: team" → "view: team"); a revoked requirement lowers its dependents.
|
|
55
|
+
* `changed` (the cell the user just set) decides the direction. Returns the new value and the
|
|
56
|
+
* cells that were adjusted.
|
|
57
|
+
*/
|
|
58
|
+
export function applyDependencies(value, deps, options = {}) {
|
|
59
|
+
let v = value;
|
|
60
|
+
const adjusted = [];
|
|
61
|
+
const scoped = options.scoped ?? (() => false);
|
|
62
|
+
const resources = options.resources ?? Object.keys(value);
|
|
63
|
+
for (let pass = 0; pass < 4; pass++) {
|
|
64
|
+
let touched = false;
|
|
65
|
+
for (const r of resources) {
|
|
66
|
+
for (const d of deps) {
|
|
67
|
+
const dep = v[r]?.[d.action];
|
|
68
|
+
const req = v[r]?.[d.requires];
|
|
69
|
+
const depRank = scopeRank(dep);
|
|
70
|
+
const reqRank = scopeRank(req);
|
|
71
|
+
if (depRank <= reqRank)
|
|
72
|
+
continue;
|
|
73
|
+
const loweringRequirement = options.changed?.resource === r && options.changed.action === d.requires;
|
|
74
|
+
if (loweringRequirement) {
|
|
75
|
+
const level = atRank(dep, reqRank, scoped(d.action));
|
|
76
|
+
v = setLevel(v, r, d.action, reqRank === 0 ? undefined : level);
|
|
77
|
+
adjusted.push({ resource: r, action: d.action, reason: d, level });
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const level = atRank(req, depRank, scoped(d.requires));
|
|
81
|
+
v = setLevel(v, r, d.requires, level);
|
|
82
|
+
adjusted.push({ resource: r, action: d.requires, reason: d, level });
|
|
83
|
+
}
|
|
84
|
+
touched = true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!touched)
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
return { value: v, adjusted };
|
|
91
|
+
}
|
|
92
|
+
/** Grants (or revokes) one action on many resources, or many actions on one resource. */
|
|
93
|
+
export function setMany(value, cells, level) {
|
|
94
|
+
let v = value;
|
|
95
|
+
for (const c of cells)
|
|
96
|
+
v = setLevel(v, c.resource, c.action, level(c));
|
|
97
|
+
return v;
|
|
98
|
+
}
|
|
99
|
+
export { setLevel as setPermission };
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type LabelFn } from "../lib/labels.js";
|
|
3
|
+
import { type PermissionChange, type PermissionDependency, type PermissionLevel, type PermissionScope, type PermissionValue } from "./permission-core.js";
|
|
4
|
+
export declare const permissionMatrixLabels: {
|
|
5
|
+
label: string;
|
|
6
|
+
resource: string;
|
|
7
|
+
none: string;
|
|
8
|
+
own: string;
|
|
9
|
+
team: string;
|
|
10
|
+
all: string;
|
|
11
|
+
granted: string;
|
|
12
|
+
denied: string;
|
|
13
|
+
notApplicable: string;
|
|
14
|
+
cell: string;
|
|
15
|
+
inheritedFrom: string;
|
|
16
|
+
inheritedState: string;
|
|
17
|
+
override: string;
|
|
18
|
+
reset: string;
|
|
19
|
+
grantRow: string;
|
|
20
|
+
revokeRow: string;
|
|
21
|
+
grantColumn: string;
|
|
22
|
+
revokeColumn: string;
|
|
23
|
+
grantGroup: string;
|
|
24
|
+
revokeGroup: string;
|
|
25
|
+
collapse: string;
|
|
26
|
+
expand: string;
|
|
27
|
+
scopeMenu: string;
|
|
28
|
+
dependencyRaised: string;
|
|
29
|
+
dependencyLowered: string;
|
|
30
|
+
changes: string;
|
|
31
|
+
review: string;
|
|
32
|
+
discard: string;
|
|
33
|
+
save: string;
|
|
34
|
+
close: string;
|
|
35
|
+
reviewTitle: string;
|
|
36
|
+
reviewDescription: string;
|
|
37
|
+
change: string;
|
|
38
|
+
dangerous: string;
|
|
39
|
+
noChanges: string;
|
|
40
|
+
readOnly: string;
|
|
41
|
+
differs: string;
|
|
42
|
+
permission: string;
|
|
43
|
+
keyboard: string;
|
|
44
|
+
};
|
|
45
|
+
export type PermissionMatrixLabels = typeof permissionMatrixLabels;
|
|
46
|
+
export interface PermissionResource {
|
|
47
|
+
id: string;
|
|
48
|
+
label: string;
|
|
49
|
+
/** Rows with the same group are shown under a collapsible heading. */
|
|
50
|
+
group?: string;
|
|
51
|
+
description?: string;
|
|
52
|
+
/** Actions that apply to this resource. Default: all. */
|
|
53
|
+
actions?: string[];
|
|
54
|
+
}
|
|
55
|
+
export interface PermissionAction {
|
|
56
|
+
id: string;
|
|
57
|
+
label: string;
|
|
58
|
+
/** Scope cells (None / Own / Team / All) instead of a checkbox. */
|
|
59
|
+
scoped?: boolean;
|
|
60
|
+
/** Highlight grants ("Delete: All"). */
|
|
61
|
+
danger?: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface PermissionMatrixProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "defaultValue" | "onChange"> {
|
|
64
|
+
resources: PermissionResource[];
|
|
65
|
+
actions: PermissionAction[];
|
|
66
|
+
/** Scope names. Default None / Own / Team / All from the dictionary. */
|
|
67
|
+
scopes?: {
|
|
68
|
+
id: PermissionScope;
|
|
69
|
+
label: string;
|
|
70
|
+
}[];
|
|
71
|
+
value?: PermissionValue;
|
|
72
|
+
defaultValue?: PermissionValue;
|
|
73
|
+
onValueChange?: (value: PermissionValue) => void;
|
|
74
|
+
/** From the parent role: shown locked until overridden. */
|
|
75
|
+
inherited?: PermissionValue;
|
|
76
|
+
/** Parent role name ("Manager"). */
|
|
77
|
+
inheritedFrom?: string;
|
|
78
|
+
/** Saved value: changed cells get a dot and a save bar appears. */
|
|
79
|
+
baseline?: PermissionValue;
|
|
80
|
+
onSave?: (value: PermissionValue, changes: PermissionChange[]) => Promise<void> | void;
|
|
81
|
+
/** Role / plan being edited, for the review dialog ("Sales rep"). */
|
|
82
|
+
subject?: string;
|
|
83
|
+
readOnly?: boolean;
|
|
84
|
+
/** "edit" requires "view": kept consistent automatically. */
|
|
85
|
+
dependencies?: PermissionDependency[];
|
|
86
|
+
/** Called with a message when a dependency changed another cell (show a toast). */
|
|
87
|
+
onDependencyApplied?: (message: string) => void;
|
|
88
|
+
/** Max height of the scroll area (sticky headers). Default none. */
|
|
89
|
+
maxHeight?: string;
|
|
90
|
+
labels?: Partial<PermissionMatrixLabels>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Who may do what: resources × actions with checkbox or scope cells (None / Own / Team / All),
|
|
94
|
+
* inheritance from a parent role, row / column / group bulk toggles, dependencies ("Edit needs
|
|
95
|
+
* View"), sticky headers, and a review-before-save diff. A WAI-ARIA grid.
|
|
96
|
+
*
|
|
97
|
+
* ```tsx
|
|
98
|
+
* <PermissionMatrix resources={resources} actions={actions} value={value} onValueChange={setValue}
|
|
99
|
+
* inherited={manager} inheritedFrom="Manager" baseline={saved} onSave={save} dependencies={[{ action: "edit", requires: "view" }]} />
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export declare const PermissionMatrix: React.ForwardRefExoticComponent<PermissionMatrixProps & React.RefAttributes<HTMLDivElement>>;
|
|
103
|
+
export interface PermissionMatrixCellProps {
|
|
104
|
+
resource: PermissionResource;
|
|
105
|
+
action: PermissionAction;
|
|
106
|
+
applicable: boolean;
|
|
107
|
+
own: PermissionLevel | undefined;
|
|
108
|
+
inherited: PermissionLevel | undefined;
|
|
109
|
+
inheritedFrom: string;
|
|
110
|
+
changed: boolean;
|
|
111
|
+
readOnly?: boolean;
|
|
112
|
+
scopeNames?: Record<string, string>;
|
|
113
|
+
pos: string;
|
|
114
|
+
tabIndex: number;
|
|
115
|
+
onFocus: () => void;
|
|
116
|
+
onNav: (e: React.KeyboardEvent) => boolean;
|
|
117
|
+
onToggle: () => void;
|
|
118
|
+
onSet: (level: PermissionLevel | undefined) => void;
|
|
119
|
+
onReset: () => void;
|
|
120
|
+
t: LabelFn<PermissionMatrixLabels>;
|
|
121
|
+
}
|
|
122
|
+
/** One grid cell: a checkbox (boolean actions) or a scope menu (scoped actions). */
|
|
123
|
+
export declare function PermissionMatrixCell({ resource: r, action: a, applicable, own, inherited, inheritedFrom, changed, readOnly, scopeNames, pos, tabIndex, onFocus, onNav, onToggle, onSet, onReset, t, }: PermissionMatrixCellProps): React.JSX.Element;
|
|
124
|
+
export interface PermissionDiffProps extends React.HTMLAttributes<HTMLUListElement> {
|
|
125
|
+
changes: PermissionChange[];
|
|
126
|
+
resources: PermissionResource[];
|
|
127
|
+
actions: PermissionAction[];
|
|
128
|
+
scopes?: {
|
|
129
|
+
id: PermissionScope;
|
|
130
|
+
label: string;
|
|
131
|
+
}[];
|
|
132
|
+
labels?: Partial<PermissionMatrixLabels>;
|
|
133
|
+
}
|
|
134
|
+
/** The review list before saving: "Quotes · Delete: None → Team", sensitive grants flagged. */
|
|
135
|
+
export declare function PermissionDiff({ changes, resources, actions, scopes, labels, className, ...props }: PermissionDiffProps): React.JSX.Element;
|
|
136
|
+
export interface PermissionCompareProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
137
|
+
/** Roles or plans as columns. */
|
|
138
|
+
subjects: {
|
|
139
|
+
id: string;
|
|
140
|
+
label: string;
|
|
141
|
+
value: PermissionValue;
|
|
142
|
+
description?: string;
|
|
143
|
+
}[];
|
|
144
|
+
resources: PermissionResource[];
|
|
145
|
+
actions: PermissionAction[];
|
|
146
|
+
scopes?: {
|
|
147
|
+
id: PermissionScope;
|
|
148
|
+
label: string;
|
|
149
|
+
}[];
|
|
150
|
+
/** Only rows where subjects differ. */
|
|
151
|
+
onlyDifferences?: boolean;
|
|
152
|
+
/** Highlight rows where subjects differ. Default `true`. */
|
|
153
|
+
highlightDifferences?: boolean;
|
|
154
|
+
maxHeight?: string;
|
|
155
|
+
labels?: Partial<PermissionMatrixLabels>;
|
|
156
|
+
}
|
|
157
|
+
/** Subjects side by side: one row per permission, one column per role or plan. Read-only. */
|
|
158
|
+
export declare function PermissionCompare({ subjects, resources, actions, scopes, onlyDifferences, highlightDifferences, maxHeight, labels, className, ...props }: PermissionCompareProps): React.JSX.Element;
|