@vamos-ui/react 0.0.0-stage → 0.3.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 +101 -0
- package/dist/blocks/site/_kit-1.js +137 -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 +113 -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 +52 -0
- package/dist/blocks/site/feature-grid.d.ts +46 -0
- package/dist/blocks/site/feature-grid.js +50 -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 +48 -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 +73 -0
- package/dist/blocks/site/logo-strip.d.ts +44 -0
- package/dist/blocks/site/logo-strip.js +27 -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 +56 -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 +83 -0
- package/dist/blocks/site/process.d.ts +36 -0
- package/dist/blocks/site/process.js +42 -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 +108 -0
- package/dist/blocks/site/site-shell.js +254 -0
- package/dist/blocks/site/stats-band.d.ts +42 -0
- package/dist/blocks/site/stats-band.js +45 -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 +66 -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 +12 -0
- package/dist/business/index.js +22 -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/business/signer-status.d.ts +53 -0
- package/dist/business/signer-status.js +76 -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 +46 -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/_qr-core.d.ts +26 -0
- package/dist/components/_qr-core.js +376 -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/backup-codes.d.ts +42 -0
- package/dist/components/backup-codes.js +67 -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 +281 -0
- package/dist/components/command.js +498 -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/pin-map.d.ts +58 -0
- package/dist/components/pin-map.js +167 -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/qr-code.d.ts +36 -0
- package/dist/components/qr-code.js +27 -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/sla-timer.d.ts +75 -0
- package/dist/components/sla-timer.js +142 -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/tour.d.ts +60 -0
- package/dist/components/tour.js +139 -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 +91 -0
- package/dist/index.js +92 -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 +23 -0
- package/dist/lib/public.js +34 -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 +140 -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/motion/core.d.ts +32 -0
- package/dist/motion/core.js +77 -0
- package/dist/motion/count-up.d.ts +29 -0
- package/dist/motion/count-up.js +92 -0
- package/dist/motion/index.d.ts +11 -0
- package/dist/motion/index.js +13 -0
- package/dist/motion/motion-scope.d.ts +17 -0
- package/dist/motion/motion-scope.js +16 -0
- package/dist/motion/page-transition.d.ts +33 -0
- package/dist/motion/page-transition.js +61 -0
- package/dist/motion/parallax.d.ts +37 -0
- package/dist/motion/parallax.js +90 -0
- package/dist/motion/pointer.d.ts +38 -0
- package/dist/motion/pointer.js +117 -0
- package/dist/motion/reveal.d.ts +72 -0
- package/dist/motion/reveal.js +133 -0
- package/dist/motion/scroll-shrink.d.ts +18 -0
- package/dist/motion/scroll-shrink.js +47 -0
- package/dist/motion/skeleton-swap.d.ts +17 -0
- package/dist/motion/skeleton-swap.js +43 -0
- package/dist/motion/text-reveal.d.ts +30 -0
- package/dist/motion/text-reveal.js +29 -0
- package/dist/motion/ticker.d.ts +35 -0
- package/dist/motion/ticker.js +16 -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 +105 -0
- package/dist/sortable/sortable-tree.js +462 -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/motion.css +389 -0
- package/dist/styles/navigation.css +293 -0
- package/dist/styles/overlays.css +244 -0
- package/dist/styles.css +743 -0
- package/package.json +160 -4
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/** A point: x, y in pad pixels and pressure 0–1. */
|
|
3
|
+
export type SignaturePoint = [x: number, y: number, pressure: number];
|
|
4
|
+
export interface SignatureValue {
|
|
5
|
+
kind: "drawn" | "typed";
|
|
6
|
+
/** Standalone SVG document; ink is always solid dark so it prints on paper. */
|
|
7
|
+
svg: string;
|
|
8
|
+
/** PNG data URL (with `exportPng`). */
|
|
9
|
+
png?: string;
|
|
10
|
+
/** The typed name (typed signatures). */
|
|
11
|
+
text?: string;
|
|
12
|
+
/** Raw strokes of a drawn signature (keeps undo working after reload). */
|
|
13
|
+
strokes?: SignaturePoint[][];
|
|
14
|
+
/** Size of the pad the strokes were drawn on. */
|
|
15
|
+
width?: number;
|
|
16
|
+
height?: number;
|
|
17
|
+
/** ISO instant. */
|
|
18
|
+
signedAt: string;
|
|
19
|
+
}
|
|
20
|
+
/** Exported ink colour: the same in light and dark themes, so stored signatures print correctly. */
|
|
21
|
+
export declare const SIGNATURE_INK = "#14170f";
|
|
22
|
+
/** SVG path data for a perfect-freehand outline. */
|
|
23
|
+
export declare function outlineToPath(outline: number[][]): string;
|
|
24
|
+
/** SVG path for one stroke (a dot when it is a single tap). */
|
|
25
|
+
export declare function strokeToPath(points: SignaturePoint[], simulatePressure?: boolean): string;
|
|
26
|
+
/** Standalone SVG of drawn strokes. */
|
|
27
|
+
export declare function strokesToSvg(strokes: SignaturePoint[][], width: number, height: number): string;
|
|
28
|
+
/** Standalone SVG of a typed name. */
|
|
29
|
+
export declare function textToSvg(text: string, width: number, height: number): string;
|
|
30
|
+
/** PNG data URL of drawn strokes (transparent background). */
|
|
31
|
+
export declare function strokesToPng(strokes: SignaturePoint[][], width: number, height: number): string | undefined;
|
|
32
|
+
/** SVG data URL, for `<img src>` (safe: images never run scripts). */
|
|
33
|
+
export declare const svgDataUrl: (svg: string) => string;
|
|
34
|
+
declare const signatureLabels: {
|
|
35
|
+
draw: string;
|
|
36
|
+
type: string;
|
|
37
|
+
clear: string;
|
|
38
|
+
undo: string;
|
|
39
|
+
placeholder: string;
|
|
40
|
+
typePlaceholder: string;
|
|
41
|
+
typeLabel: string;
|
|
42
|
+
pad: string;
|
|
43
|
+
drawn: string;
|
|
44
|
+
preview: string;
|
|
45
|
+
signed: string;
|
|
46
|
+
signature: string;
|
|
47
|
+
empty: string;
|
|
48
|
+
cleared: string;
|
|
49
|
+
};
|
|
50
|
+
export type SignaturePadLabels = typeof signatureLabels;
|
|
51
|
+
export interface SignaturePadProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "defaultValue" | "onChange"> {
|
|
52
|
+
value?: SignatureValue | null;
|
|
53
|
+
defaultValue?: SignatureValue | null;
|
|
54
|
+
onValueChange?: (value: SignatureValue | null) => void;
|
|
55
|
+
/** Available modes. Default both — Type is the keyboard-accessible path, keep it unless another one exists. */
|
|
56
|
+
modes?: ("draw" | "type")[];
|
|
57
|
+
/** Pad height in px. Default 176. */
|
|
58
|
+
height?: number;
|
|
59
|
+
/** On-screen ink. Exported ink is always solid dark. Default `"fg"`. */
|
|
60
|
+
penColor?: "fg" | "accent";
|
|
61
|
+
/** Include a PNG data URL in the value (and in the hidden input instead of SVG). */
|
|
62
|
+
exportPng?: boolean;
|
|
63
|
+
/** Hidden input name; carries the SVG (or the PNG data URL with `exportPng`). */
|
|
64
|
+
name?: string;
|
|
65
|
+
disabled?: boolean;
|
|
66
|
+
/** Shows the stored signature as an image with its timestamp. */
|
|
67
|
+
readOnly?: boolean;
|
|
68
|
+
invalid?: boolean;
|
|
69
|
+
required?: boolean;
|
|
70
|
+
labels?: Partial<SignaturePadLabels>;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Captures a handwritten (pointer: mouse, pen with pressure, touch) or typed signature. Strokes
|
|
74
|
+
* are smoothed with `perfect-freehand` and exported as SVG (and PNG on request); the ink you
|
|
75
|
+
* export is always dark, so stored signatures print correctly in any theme.
|
|
76
|
+
*
|
|
77
|
+
* A drawn or typed image is not a qualified electronic signature (eIDAS, Turkey's Law 5070) —
|
|
78
|
+
* the legal wording around it is the app's responsibility.
|
|
79
|
+
*
|
|
80
|
+
* ```tsx
|
|
81
|
+
* <Field label="Customer signature" required><SignaturePad name="signature" exportPng /></Field>
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export declare const SignaturePad: React.ForwardRefExoticComponent<SignaturePadProps & React.RefAttributes<HTMLDivElement>>;
|
|
85
|
+
export {};
|
|
@@ -0,0 +1,283 @@
|
|
|
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 { getStroke } from "perfect-freehand";
|
|
5
|
+
import { Eraser, PenLine, Type, Undo2 } from "lucide-react";
|
|
6
|
+
import { cn } from "../lib/cn.js";
|
|
7
|
+
import { mergeIds } from "../lib/compose-refs.js";
|
|
8
|
+
import { useFieldContext } from "../lib/field-context.js";
|
|
9
|
+
import { useLabels } from "../lib/labels.js";
|
|
10
|
+
import { useFormat } from "../lib/locale.js";
|
|
11
|
+
import { useControllableState, useLatest } from "../lib/use-controllable-state.js";
|
|
12
|
+
import { useContainerWidth } from "../lib/use-container-width.js";
|
|
13
|
+
import { Button } from "./button.js";
|
|
14
|
+
import { Input } from "./input.js";
|
|
15
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./tabs.js";
|
|
16
|
+
/** Exported ink colour: the same in light and dark themes, so stored signatures print correctly. */
|
|
17
|
+
export const SIGNATURE_INK = "#14170f";
|
|
18
|
+
/** Font stack for typed signatures (override `--font-signature` to load a handwriting font). */
|
|
19
|
+
const TYPED_FONT = "var(--font-signature)";
|
|
20
|
+
const TYPED_FONT_EXPORT = '"Segoe Script", "Snell Roundhand", "Brush Script MT", "Apple Chancery", cursive';
|
|
21
|
+
const STROKE_OPTIONS = { size: 3.4, thinning: 0.62, smoothing: 0.55, streamline: 0.45, start: { taper: 6 }, end: { taper: 10 } };
|
|
22
|
+
/** SVG path data for a perfect-freehand outline. */
|
|
23
|
+
export function outlineToPath(outline) {
|
|
24
|
+
if (outline.length < 2)
|
|
25
|
+
return "";
|
|
26
|
+
const r = (n) => Math.round(n * 100) / 100;
|
|
27
|
+
let d = `M${r(outline[0][0])} ${r(outline[0][1])}Q`;
|
|
28
|
+
for (let i = 0; i < outline.length; i++) {
|
|
29
|
+
const [x0, y0] = outline[i];
|
|
30
|
+
const [x1, y1] = outline[(i + 1) % outline.length];
|
|
31
|
+
d += `${r(x0)} ${r(y0)} ${r((x0 + x1) / 2)} ${r((y0 + y1) / 2)} `;
|
|
32
|
+
}
|
|
33
|
+
return `${d.trim()}Z`;
|
|
34
|
+
}
|
|
35
|
+
/** SVG path for one stroke (a dot when it is a single tap). */
|
|
36
|
+
export function strokeToPath(points, simulatePressure = true) {
|
|
37
|
+
return outlineToPath(getStroke(points, { ...STROKE_OPTIONS, simulatePressure }));
|
|
38
|
+
}
|
|
39
|
+
const escapeXml = (s) => s.replace(/[<>&"']/g, (c) => ({ "<": "<", ">": ">", "&": "&", '"': """, "'": "'" })[c]);
|
|
40
|
+
/** Standalone SVG of drawn strokes. */
|
|
41
|
+
export function strokesToSvg(strokes, width, height) {
|
|
42
|
+
const paths = strokes.map((s) => `<path d="${strokeToPath(s)}"/>`).join("");
|
|
43
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${Math.round(width)} ${Math.round(height)}" width="${Math.round(width)}" height="${Math.round(height)}" fill="${SIGNATURE_INK}">${paths}</svg>`;
|
|
44
|
+
}
|
|
45
|
+
function typedFontSize(height) {
|
|
46
|
+
return Math.round(Math.min(56, height * 0.32));
|
|
47
|
+
}
|
|
48
|
+
/** Standalone SVG of a typed name. */
|
|
49
|
+
export function textToSvg(text, width, height) {
|
|
50
|
+
const size = typedFontSize(height);
|
|
51
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${Math.round(width)} ${Math.round(height)}" width="${Math.round(width)}" height="${Math.round(height)}"><text x="24" y="${Math.round(height * 0.68)}" font-family='${TYPED_FONT_EXPORT}' font-size="${size}" font-style="italic" fill="${SIGNATURE_INK}">${escapeXml(text)}</text></svg>`;
|
|
52
|
+
}
|
|
53
|
+
function toPng(width, height, draw) {
|
|
54
|
+
try {
|
|
55
|
+
if (typeof document === "undefined")
|
|
56
|
+
return undefined;
|
|
57
|
+
const scale = 2;
|
|
58
|
+
const canvas = document.createElement("canvas");
|
|
59
|
+
canvas.width = Math.round(width * scale);
|
|
60
|
+
canvas.height = Math.round(height * scale);
|
|
61
|
+
const ctx = canvas.getContext("2d");
|
|
62
|
+
if (!ctx)
|
|
63
|
+
return undefined;
|
|
64
|
+
ctx.scale(scale, scale);
|
|
65
|
+
ctx.fillStyle = SIGNATURE_INK;
|
|
66
|
+
draw(ctx);
|
|
67
|
+
return canvas.toDataURL("image/png");
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** PNG data URL of drawn strokes (transparent background). */
|
|
74
|
+
export function strokesToPng(strokes, width, height) {
|
|
75
|
+
if (typeof Path2D === "undefined")
|
|
76
|
+
return undefined;
|
|
77
|
+
return toPng(width, height, (ctx) => strokes.forEach((s) => ctx.fill(new Path2D(strokeToPath(s)))));
|
|
78
|
+
}
|
|
79
|
+
/** SVG data URL, for `<img src>` (safe: images never run scripts). */
|
|
80
|
+
export const svgDataUrl = (svg) => `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
81
|
+
/* ------------------------------------------------------------------ */
|
|
82
|
+
/* SignaturePad */
|
|
83
|
+
/* ------------------------------------------------------------------ */
|
|
84
|
+
const signatureLabels = {
|
|
85
|
+
draw: "Draw",
|
|
86
|
+
type: "Type",
|
|
87
|
+
clear: "Clear",
|
|
88
|
+
undo: "Undo",
|
|
89
|
+
placeholder: "Sign here",
|
|
90
|
+
typePlaceholder: "Type your full name",
|
|
91
|
+
typeLabel: "Full name",
|
|
92
|
+
pad: "Signature pad. Drawing needs a mouse, pen or finger; use Type to sign with the keyboard.",
|
|
93
|
+
drawn: "Signature drawn, {count, plural, one {# stroke} other {# strokes}}",
|
|
94
|
+
preview: "Signature preview",
|
|
95
|
+
signed: "Signed {date}",
|
|
96
|
+
signature: "Signature",
|
|
97
|
+
empty: "Not signed",
|
|
98
|
+
cleared: "Signature cleared",
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Captures a handwritten (pointer: mouse, pen with pressure, touch) or typed signature. Strokes
|
|
102
|
+
* are smoothed with `perfect-freehand` and exported as SVG (and PNG on request); the ink you
|
|
103
|
+
* export is always dark, so stored signatures print correctly in any theme.
|
|
104
|
+
*
|
|
105
|
+
* A drawn or typed image is not a qualified electronic signature (eIDAS, Turkey's Law 5070) —
|
|
106
|
+
* the legal wording around it is the app's responsibility.
|
|
107
|
+
*
|
|
108
|
+
* ```tsx
|
|
109
|
+
* <Field label="Customer signature" required><SignaturePad name="signature" exportPng /></Field>
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export const SignaturePad = React.forwardRef(function SignaturePad(props, ref) {
|
|
113
|
+
const { value, defaultValue, onValueChange, modes = ["draw", "type"], height = 176, penColor = "fg", exportPng = false, name, disabled: disabledProp, readOnly: readOnlyProp, invalid: invalidProp, required: requiredProp, labels, className, id, "aria-describedby": describedBy, ...rest } = props;
|
|
114
|
+
const field = useFieldContext();
|
|
115
|
+
const disabled = disabledProp ?? field?.disabled ?? false;
|
|
116
|
+
const readOnly = readOnlyProp ?? field?.readOnly ?? false;
|
|
117
|
+
const invalid = invalidProp ?? field?.invalid ?? false;
|
|
118
|
+
const required = requiredProp ?? field?.required ?? false;
|
|
119
|
+
const submitName = name ?? field?.name;
|
|
120
|
+
const t = useLabels("signature", signatureLabels, labels);
|
|
121
|
+
const f = useFormat();
|
|
122
|
+
const autoId = React.useId();
|
|
123
|
+
const rootId = id ?? field?.id ?? `sig${autoId.replace(/:/g, "")}`;
|
|
124
|
+
const [sig, setSig] = useControllableState({ value, defaultValue: defaultValue ?? null, onChange: onValueChange, name: "SignaturePad" });
|
|
125
|
+
const [mode, setMode] = React.useState(sig?.kind === "typed" && modes.includes("type") ? "type" : modes[0] ?? "draw");
|
|
126
|
+
const [strokes, setStrokes] = React.useState(() => (sig?.kind === "drawn" ? sig.strokes ?? [] : []));
|
|
127
|
+
const [current, setCurrent] = React.useState(null);
|
|
128
|
+
const [typed, setTyped] = React.useState(sig?.kind === "typed" ? sig.text ?? "" : "");
|
|
129
|
+
const [announce, setAnnounce] = React.useState("");
|
|
130
|
+
const { ref: measureRef, width: measured } = useContainerWidth();
|
|
131
|
+
const width = measured ?? 480;
|
|
132
|
+
const padSize = React.useRef(sig?.width && sig.height ? { w: sig.width, h: sig.height } : null);
|
|
133
|
+
const drawing = React.useRef(null);
|
|
134
|
+
const currentRef = React.useRef(null);
|
|
135
|
+
const latest = useLatest({ strokes, typed, width, height, exportPng });
|
|
136
|
+
// Controlled reset (e.g. parent clears the value).
|
|
137
|
+
React.useEffect(() => {
|
|
138
|
+
if (value === undefined)
|
|
139
|
+
return;
|
|
140
|
+
if (value === null) {
|
|
141
|
+
setStrokes([]);
|
|
142
|
+
setTyped("");
|
|
143
|
+
padSize.current = null;
|
|
144
|
+
}
|
|
145
|
+
else if (value.kind === "drawn" && value.strokes && value.strokes !== latest.current.strokes) {
|
|
146
|
+
setStrokes(value.strokes);
|
|
147
|
+
if (value.width && value.height)
|
|
148
|
+
padSize.current = { w: value.width, h: value.height };
|
|
149
|
+
}
|
|
150
|
+
else if (value.kind === "typed" && value.text !== undefined && value.text !== latest.current.typed)
|
|
151
|
+
setTyped(value.text);
|
|
152
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
153
|
+
}, [value]);
|
|
154
|
+
const emitDrawn = (next) => {
|
|
155
|
+
if (!next.length) {
|
|
156
|
+
setSig(null);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const size = padSize.current ?? { w: latest.current.width, h: latest.current.height };
|
|
160
|
+
setSig({
|
|
161
|
+
kind: "drawn",
|
|
162
|
+
svg: strokesToSvg(next, size.w, size.h),
|
|
163
|
+
png: latest.current.exportPng ? strokesToPng(next, size.w, size.h) : undefined,
|
|
164
|
+
strokes: next,
|
|
165
|
+
width: size.w,
|
|
166
|
+
height: size.h,
|
|
167
|
+
signedAt: new Date().toISOString(),
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
const emitTyped = (text) => {
|
|
171
|
+
const name = text.trim();
|
|
172
|
+
if (!name) {
|
|
173
|
+
setSig(null);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const { width: w, height: h, exportPng: png } = latest.current;
|
|
177
|
+
setSig({
|
|
178
|
+
kind: "typed",
|
|
179
|
+
text: name,
|
|
180
|
+
svg: textToSvg(name, w, h),
|
|
181
|
+
png: png
|
|
182
|
+
? toPng(w, h, (ctx) => {
|
|
183
|
+
ctx.font = `italic ${typedFontSize(h)}px ${TYPED_FONT_EXPORT}`;
|
|
184
|
+
ctx.fillText(name, 24, h * 0.68);
|
|
185
|
+
})
|
|
186
|
+
: undefined,
|
|
187
|
+
width: w,
|
|
188
|
+
height: h,
|
|
189
|
+
signedAt: new Date().toISOString(),
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
const inert = disabled || readOnly;
|
|
193
|
+
const point = (e, rect) => {
|
|
194
|
+
const size = padSize.current;
|
|
195
|
+
const sx = size ? size.w / rect.width : 1;
|
|
196
|
+
const sy = size ? size.h / rect.height : 1;
|
|
197
|
+
return [(e.clientX - rect.left) * sx, (e.clientY - rect.top) * sy, e.pointerType === "pen" ? e.pressure || 0.5 : 0.5];
|
|
198
|
+
};
|
|
199
|
+
const onPointerDown = (e) => {
|
|
200
|
+
if (inert || (e.pointerType === "mouse" && e.button !== 0))
|
|
201
|
+
return;
|
|
202
|
+
e.preventDefault();
|
|
203
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
204
|
+
if (!padSize.current)
|
|
205
|
+
padSize.current = { w: rect.width || width, h: rect.height || height };
|
|
206
|
+
try {
|
|
207
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
/* ignore */
|
|
211
|
+
}
|
|
212
|
+
drawing.current = { id: e.pointerId, pen: e.pointerType === "pen", rect };
|
|
213
|
+
currentRef.current = [point(e, rect)];
|
|
214
|
+
setCurrent(currentRef.current);
|
|
215
|
+
};
|
|
216
|
+
const onPointerMove = (e) => {
|
|
217
|
+
const d = drawing.current;
|
|
218
|
+
if (!d || d.id !== e.pointerId)
|
|
219
|
+
return;
|
|
220
|
+
const events = typeof e.nativeEvent.getCoalescedEvents === "function" ? e.nativeEvent.getCoalescedEvents() : [];
|
|
221
|
+
const pts = (events.length ? events : [e.nativeEvent]).map((ev) => point(ev, d.rect));
|
|
222
|
+
if (!currentRef.current)
|
|
223
|
+
return;
|
|
224
|
+
currentRef.current = [...currentRef.current, ...pts];
|
|
225
|
+
setCurrent(currentRef.current);
|
|
226
|
+
};
|
|
227
|
+
const finish = (e) => {
|
|
228
|
+
const d = drawing.current;
|
|
229
|
+
if (!d || d.id !== e.pointerId)
|
|
230
|
+
return;
|
|
231
|
+
drawing.current = null;
|
|
232
|
+
const c = currentRef.current;
|
|
233
|
+
currentRef.current = null;
|
|
234
|
+
setCurrent(null);
|
|
235
|
+
if (!c?.length)
|
|
236
|
+
return;
|
|
237
|
+
const next = [...latest.current.strokes, c];
|
|
238
|
+
setStrokes(next);
|
|
239
|
+
emitDrawn(next);
|
|
240
|
+
setAnnounce(t("drawn", { count: next.length }));
|
|
241
|
+
};
|
|
242
|
+
const undo = () => {
|
|
243
|
+
if (mode === "type") {
|
|
244
|
+
setTyped("");
|
|
245
|
+
emitTyped("");
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const next = strokes.slice(0, -1);
|
|
249
|
+
setStrokes(next);
|
|
250
|
+
if (!next.length)
|
|
251
|
+
padSize.current = null;
|
|
252
|
+
emitDrawn(next);
|
|
253
|
+
setAnnounce(next.length ? t("drawn", { count: next.length }) : t("cleared"));
|
|
254
|
+
};
|
|
255
|
+
const clear = () => {
|
|
256
|
+
setStrokes([]);
|
|
257
|
+
setTyped("");
|
|
258
|
+
padSize.current = null;
|
|
259
|
+
setSig(null);
|
|
260
|
+
setAnnounce(t("cleared"));
|
|
261
|
+
};
|
|
262
|
+
const ink = penColor === "accent" ? "text-accent-ink" : "text-fg";
|
|
263
|
+
const viewW = padSize.current?.w ?? width;
|
|
264
|
+
const viewH = padSize.current?.h ?? height;
|
|
265
|
+
const hasDrawing = strokes.length > 0 || !!current;
|
|
266
|
+
const empty = mode === "draw" ? !hasDrawing : !typed.trim();
|
|
267
|
+
const hidden = submitName ? _jsx("input", { type: "hidden", name: submitName, value: sig ? (exportPng && sig.png ? sig.png : sig.svg) : "", disabled: disabled }) : null;
|
|
268
|
+
const groupLabel = field?.labelId ? { "aria-labelledby": field.labelId } : { "aria-label": t("signature") };
|
|
269
|
+
const surface = cn("ui-signature relative w-full overflow-hidden rounded-ui border bg-field select-none touch-none", invalid ? "border-danger" : "border-field-border", disabled && "opacity-50");
|
|
270
|
+
const baseline = (_jsx("span", { "aria-hidden": true, className: "pointer-events-none absolute inset-x-6 bottom-[26%] flex items-end gap-2 border-b border-dashed border-line pb-1", children: _jsx("span", { className: "font-display text-lg leading-none text-fg-subtle", children: "\u00D7" }) }));
|
|
271
|
+
/* ---------------- read-only ---------------- */
|
|
272
|
+
if (readOnly) {
|
|
273
|
+
return (_jsxs("div", { ref: ref, ...rest, id: rootId, role: "group", ...groupLabel, "aria-describedby": mergeIds(field?.describedBy, describedBy), "data-slot": "signature-pad", "data-readonly": "", className: cn("grid min-w-0 gap-1.5", className), children: [_jsxs("div", { className: cn(surface, "border-dashed bg-transparent"), style: { height }, children: [sig ? _jsx("img", { src: svgDataUrl(sig.svg), alt: sig.kind === "typed" && sig.text ? `${t("signature")}: ${sig.text}` : t("signature"), className: "ui-signature-ink absolute inset-0 size-full object-contain object-left p-3" }) : _jsx("span", { className: "absolute inset-0 flex items-center justify-center text-sm text-fg-subtle", children: t("empty") }), baseline] }), sig ? _jsx("p", { className: "text-xs text-fg-subtle tabular", children: t("signed", { date: f.dateTime(sig.signedAt) }) }) : null, hidden] }));
|
|
274
|
+
}
|
|
275
|
+
/* ---------------- editable ---------------- */
|
|
276
|
+
const drawPad = (_jsxs("div", { ref: measureRef, className: surface, style: { height }, "data-empty": !hasDrawing ? "" : undefined, children: [baseline, !hasDrawing ? (_jsx("span", { "aria-hidden": true, className: "pointer-events-none absolute bottom-[calc(26%+0.5rem)] start-12 text-sm text-fg-subtle", children: t("placeholder") })) : null, _jsxs("svg", { role: "img", "aria-label": t("pad"), viewBox: `0 0 ${viewW} ${viewH}`, preserveAspectRatio: "xMinYMid meet", className: cn("absolute inset-0 size-full", ink, inert ? "cursor-not-allowed" : "cursor-crosshair"), fill: "currentColor", onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: finish, onPointerCancel: finish, "data-slot": "signature-pad-canvas", children: [strokes.map((s, i) => (_jsx("path", { d: strokeToPath(s) }, i))), current ? _jsx("path", { d: strokeToPath(current, !drawing.current?.pen) }) : null] })] }));
|
|
277
|
+
const typePad = (_jsxs("div", { className: "grid gap-2.5", children: [_jsxs("div", { className: surface, style: { height }, children: [baseline, _jsx("span", { "aria-hidden": true, className: cn("pointer-events-none absolute start-6 bottom-[calc(26%+0.25rem)] max-w-[calc(100%-3rem)] truncate italic leading-none", ink, !typed.trim() && "text-fg-subtle opacity-60"), style: { fontFamily: TYPED_FONT, fontSize: typedFontSize(height) }, children: typed.trim() || t("placeholder") })] }), _jsx(Input, { "aria-label": t("typeLabel"), placeholder: t("typePlaceholder"), value: typed, disabled: disabled, autoComplete: "name", "aria-invalid": invalid || undefined, onChange: (e) => {
|
|
278
|
+
setTyped(e.currentTarget.value);
|
|
279
|
+
emitTyped(e.currentTarget.value);
|
|
280
|
+
} })] }));
|
|
281
|
+
const toolbar = (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { size: "xs", variant: "ghost", onClick: undo, disabled: inert || empty, "aria-label": t("undo"), title: t("undo"), className: "px-1.5", children: _jsx(Undo2, { "aria-hidden": true, className: "rtl:-scale-x-100" }) }), _jsxs(Button, { size: "xs", variant: "ghost", onClick: clear, disabled: inert || (empty && !sig), children: [_jsx(Eraser, { "aria-hidden": true }), " ", t("clear")] })] }));
|
|
282
|
+
return (_jsxs("div", { ref: ref, ...rest, id: rootId, role: "group", ...groupLabel, "aria-describedby": mergeIds(field?.describedBy, describedBy), "aria-invalid": invalid || undefined, "data-required": required ? "" : undefined, "aria-disabled": disabled || undefined, "data-slot": "signature-pad", "data-mode": mode, "data-signed": sig ? "" : undefined, className: cn("grid min-w-0 gap-2", className), children: [modes.length > 1 ? (_jsxs(Tabs, { value: mode, onValueChange: (m) => setMode(m), className: "gap-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs(TabsList, { variant: "segmented", size: "sm", overflow: "none", children: [modes.includes("draw") ? (_jsx(TabsTrigger, { value: "draw", icon: _jsx(PenLine, {}), disabled: disabled, children: t("draw") })) : null, modes.includes("type") ? (_jsx(TabsTrigger, { value: "type", icon: _jsx(Type, {}), disabled: disabled, children: t("type") })) : null] }), toolbar] }), _jsx(TabsContent, { value: "draw", className: "focus-visible:outline-none", tabIndex: -1, children: drawPad }), _jsx(TabsContent, { value: "type", className: "focus-visible:outline-none", tabIndex: -1, children: typePad })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex justify-end", children: toolbar }), mode === "draw" ? drawPad : typePad] })), _jsx("span", { className: "sr-only", "aria-live": "polite", children: announce }), hidden] }));
|
|
283
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type VariantProps } from "class-variance-authority";
|
|
3
|
+
export declare const skeletonVariants: (props?: ({
|
|
4
|
+
shape?: "text" | "circle" | "rect" | null | undefined;
|
|
5
|
+
shimmer?: boolean | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
export interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof skeletonVariants> {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A placeholder block while content loads. Size it with classes (`h-4 w-32`).
|
|
11
|
+
* Skeletons are hidden from assistive tech; wrap a loading region in `SkeletonGroup` so it is
|
|
12
|
+
* announced once (`aria-busy` + one hidden "Loading…").
|
|
13
|
+
*
|
|
14
|
+
* The shimmer runs in the reading direction (RTL-aware) and stops under `prefers-reduced-motion`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const Skeleton: React.ForwardRefExoticComponent<SkeletonProps & React.RefAttributes<HTMLDivElement>>;
|
|
17
|
+
export interface SkeletonTextProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
18
|
+
/** Default 3. */
|
|
19
|
+
lines?: number;
|
|
20
|
+
/** Width of the last line. Default `"62%"`. */
|
|
21
|
+
lastLineWidth?: string;
|
|
22
|
+
shimmer?: boolean;
|
|
23
|
+
/** Classes for every line (e.g. `h-3`). */
|
|
24
|
+
lineClassName?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Paragraph placeholder: full-width lines with a shorter last line. */
|
|
27
|
+
export declare const SkeletonText: React.ForwardRefExoticComponent<SkeletonTextProps & React.RefAttributes<HTMLDivElement>>;
|
|
28
|
+
declare const AVATAR: {
|
|
29
|
+
readonly xs: "size-5";
|
|
30
|
+
readonly sm: "size-6";
|
|
31
|
+
readonly md: "size-8";
|
|
32
|
+
readonly lg: "size-10";
|
|
33
|
+
readonly xl: "size-14";
|
|
34
|
+
};
|
|
35
|
+
/** Round placeholder matching the Avatar sizes (20/24/32/40/56). */
|
|
36
|
+
export declare function SkeletonAvatar({ size, shape, className, ...props }: Omit<SkeletonProps, "shape"> & {
|
|
37
|
+
size?: keyof typeof AVATAR;
|
|
38
|
+
shape?: "circle" | "square";
|
|
39
|
+
}): React.JSX.Element;
|
|
40
|
+
export interface SkeletonRowProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
41
|
+
/** Default 4. */
|
|
42
|
+
columns?: number;
|
|
43
|
+
/** Leading avatar + two lines in the first column. */
|
|
44
|
+
avatar?: boolean;
|
|
45
|
+
shimmer?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/** A table/list row placeholder; height follows `--row-h`, padding `--cell-px`. */
|
|
48
|
+
export declare const SkeletonRow: React.ForwardRefExoticComponent<SkeletonRowProps & React.RefAttributes<HTMLDivElement>>;
|
|
49
|
+
export interface SkeletonGroupProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
50
|
+
/** Announced once for the whole region. Default from the dictionary (`skeleton.loading`). */
|
|
51
|
+
label?: string;
|
|
52
|
+
/** While `false`, children render normally and the region is no longer busy. Default `true`. */
|
|
53
|
+
loading?: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Wraps a loading region: sets `aria-busy` and announces one hidden status text instead of
|
|
57
|
+
* reading every skeleton.
|
|
58
|
+
*
|
|
59
|
+
* ```tsx
|
|
60
|
+
* <SkeletonGroup loading={isLoading}>{isLoading ? <SkeletonText /> : <Article />}</SkeletonGroup>
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare const SkeletonGroup: React.ForwardRefExoticComponent<SkeletonGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import { cn } from "../lib/cn.js";
|
|
5
|
+
import { LocalizedText } from "../lib/islands.js";
|
|
6
|
+
export const skeletonVariants = cva("block bg-skeleton", {
|
|
7
|
+
variants: {
|
|
8
|
+
shape: {
|
|
9
|
+
rect: "rounded-ui-sm",
|
|
10
|
+
/** One line of text: height follows the font size. */
|
|
11
|
+
text: "h-[0.8em] rounded-full",
|
|
12
|
+
circle: "aspect-square rounded-full",
|
|
13
|
+
},
|
|
14
|
+
shimmer: { true: "ui-shimmer", false: "" },
|
|
15
|
+
},
|
|
16
|
+
defaultVariants: { shape: "rect", shimmer: true },
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* A placeholder block while content loads. Size it with classes (`h-4 w-32`).
|
|
20
|
+
* Skeletons are hidden from assistive tech; wrap a loading region in `SkeletonGroup` so it is
|
|
21
|
+
* announced once (`aria-busy` + one hidden "Loading…").
|
|
22
|
+
*
|
|
23
|
+
* The shimmer runs in the reading direction (RTL-aware) and stops under `prefers-reduced-motion`.
|
|
24
|
+
*/
|
|
25
|
+
export const Skeleton = React.forwardRef(function Skeleton({ className, shape, shimmer, ...props }, ref) {
|
|
26
|
+
return _jsx("div", { ref: ref, "aria-hidden": true, "data-slot": "skeleton", className: cn(skeletonVariants({ shape, shimmer }), className), ...props });
|
|
27
|
+
});
|
|
28
|
+
/** Paragraph placeholder: full-width lines with a shorter last line. */
|
|
29
|
+
export const SkeletonText = React.forwardRef(function SkeletonText({ lines = 3, lastLineWidth = "62%", shimmer, lineClassName, className, ...props }, ref) {
|
|
30
|
+
return (_jsx("div", { ref: ref, "aria-hidden": true, "data-slot": "skeleton-text", className: cn("grid gap-2.5 text-sm", className), ...props, children: Array.from({ length: lines }, (_, i) => (_jsx(Skeleton, { shape: "text", shimmer: shimmer, className: lineClassName, style: i === lines - 1 && lines > 1 ? { width: lastLineWidth } : undefined }, i))) }));
|
|
31
|
+
});
|
|
32
|
+
const AVATAR = { xs: "size-5", sm: "size-6", md: "size-8", lg: "size-10", xl: "size-14" };
|
|
33
|
+
/** Round placeholder matching the Avatar sizes (20/24/32/40/56). */
|
|
34
|
+
export function SkeletonAvatar({ size = "md", shape = "circle", className, ...props }) {
|
|
35
|
+
return _jsx(Skeleton, { shape: shape === "circle" ? "circle" : "rect", className: cn(AVATAR[size], className), ...props });
|
|
36
|
+
}
|
|
37
|
+
const COLUMN_WIDTHS = ["72%", "48%", "60%", "36%", "54%", "40%"];
|
|
38
|
+
/** A table/list row placeholder; height follows `--row-h`, padding `--cell-px`. */
|
|
39
|
+
export const SkeletonRow = React.forwardRef(function SkeletonRow({ columns = 4, avatar, shimmer, className, ...props }, ref) {
|
|
40
|
+
return (_jsx("div", { ref: ref, "aria-hidden": true, "data-slot": "skeleton-row", className: cn("grid h-(--row-h) items-center gap-4 border-b border-line px-(--cell-px) text-sm last:border-b-0", className), style: { gridTemplateColumns: `minmax(0,2fr) repeat(${Math.max(columns - 1, 0)}, minmax(0,1fr))` }, ...props, children: Array.from({ length: columns }, (_, i) => i === 0 && avatar ? (_jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [_jsx(SkeletonAvatar, { size: "md", shimmer: shimmer }), _jsxs("div", { className: "grid min-w-0 flex-1 gap-1.5", children: [_jsx(Skeleton, { shape: "text", shimmer: shimmer, style: { width: "70%" } }), _jsx(Skeleton, { shape: "text", shimmer: shimmer, className: "h-[0.65em]", style: { width: "45%" } })] })] }, i)) : (_jsx(Skeleton, { shape: "text", shimmer: shimmer, style: { width: COLUMN_WIDTHS[i % COLUMN_WIDTHS.length] } }, i))) }));
|
|
41
|
+
});
|
|
42
|
+
const skeletonLabels = { loading: "Loading…" };
|
|
43
|
+
/**
|
|
44
|
+
* Wraps a loading region: sets `aria-busy` and announces one hidden status text instead of
|
|
45
|
+
* reading every skeleton.
|
|
46
|
+
*
|
|
47
|
+
* ```tsx
|
|
48
|
+
* <SkeletonGroup loading={isLoading}>{isLoading ? <SkeletonText /> : <Article />}</SkeletonGroup>
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export const SkeletonGroup = React.forwardRef(function SkeletonGroup({ label, loading = true, children, ...props }, ref) {
|
|
52
|
+
return (_jsxs("div", { ref: ref, "data-slot": "skeleton-group", "aria-busy": loading || undefined, ...props, children: [loading ? (_jsx("span", { role: "status", className: "sr-only", children: label ?? _jsx(LocalizedText, { namespace: "skeleton", id: "loading", defaults: skeletonLabels }) })) : null, children] }));
|
|
53
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type SlaState = "on-track" | "at-risk" | "breached" | "met" | "missed" | "paused";
|
|
3
|
+
export declare const slaTimerLabels: {
|
|
4
|
+
dueIn: string;
|
|
5
|
+
overdue: string;
|
|
6
|
+
met: string;
|
|
7
|
+
missed: string;
|
|
8
|
+
paused: string;
|
|
9
|
+
pausedOverdue: string;
|
|
10
|
+
stateOnTrack: string;
|
|
11
|
+
stateAtRisk: string;
|
|
12
|
+
stateBreached: string;
|
|
13
|
+
stateMet: string;
|
|
14
|
+
stateMissed: string;
|
|
15
|
+
statePaused: string;
|
|
16
|
+
};
|
|
17
|
+
export type SlaTimerLabels = typeof slaTimerLabels;
|
|
18
|
+
type DateLike = string | number | Date;
|
|
19
|
+
export interface SlaModel {
|
|
20
|
+
state: SlaState;
|
|
21
|
+
/** Milliseconds left (negative when overdue); frozen for met/missed/paused. */
|
|
22
|
+
remaining: number;
|
|
23
|
+
/** Share of the window used, 0…1+ (needs `start`). */
|
|
24
|
+
used: number | null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Pure SLA state: `on-track`, `at-risk` (less than `warnAt` of the window or `warnMinutes`
|
|
28
|
+
* left), `breached`, and the final `met` / `missed` once `completedAt` is set.
|
|
29
|
+
*/
|
|
30
|
+
export declare function slaState({ due, start, completedAt, pausedAt, now, warnAt, warnMinutes }: {
|
|
31
|
+
due: DateLike;
|
|
32
|
+
start?: DateLike;
|
|
33
|
+
completedAt?: DateLike | null;
|
|
34
|
+
pausedAt?: DateLike | null;
|
|
35
|
+
now: number;
|
|
36
|
+
warnAt?: number;
|
|
37
|
+
warnMinutes?: number;
|
|
38
|
+
}): SlaModel;
|
|
39
|
+
export interface SlaTimerProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
40
|
+
/** Deadline (ISO string, epoch ms or Date). */
|
|
41
|
+
due: DateLike;
|
|
42
|
+
/** When the clock started — enables the proportional warning and the bar. */
|
|
43
|
+
start?: DateLike;
|
|
44
|
+
/** Target reached (first reply sent, ticket solved) → `met` or `missed`, frozen. */
|
|
45
|
+
completedAt?: DateLike | null;
|
|
46
|
+
/** Clock stopped (waiting on customer) → `paused`, frozen. */
|
|
47
|
+
pausedAt?: DateLike | null;
|
|
48
|
+
/** Fixed "now" (epoch ms) for static screens, tests and screenshots. Omit to tick live. */
|
|
49
|
+
now?: number;
|
|
50
|
+
/** Warn when less than this share of the window is left (needs `start`). Default `0.25`. */
|
|
51
|
+
warnAt?: number;
|
|
52
|
+
/** Warn when fewer minutes than this are left (overrides `warnAt`). */
|
|
53
|
+
warnMinutes?: number;
|
|
54
|
+
/** `"badge"` (default), `"inline"`, or `"bar"` (label row + progress line). */
|
|
55
|
+
variant?: "badge" | "inline" | "bar";
|
|
56
|
+
/** What the SLA measures, prefixed to the accessible text: "First response". */
|
|
57
|
+
label?: string;
|
|
58
|
+
/** Show seconds under an hour left. Default `true`. */
|
|
59
|
+
seconds?: boolean;
|
|
60
|
+
/** Hide the icon (badge / inline). */
|
|
61
|
+
hideIcon?: boolean;
|
|
62
|
+
labels?: Partial<SlaTimerLabels>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Countdown to a service-level deadline — first response, resolution, delivery window.
|
|
66
|
+
* Colour follows the state (on track → at risk → breached), and it freezes as met/missed
|
|
67
|
+
* once `completedAt` is set. `role="timer"` with a full sentence for screen readers.
|
|
68
|
+
*
|
|
69
|
+
* ```tsx
|
|
70
|
+
* <SlaTimer label="First response" start={ticket.createdAt} due={ticket.firstResponseDue} />
|
|
71
|
+
* <SlaTimer variant="bar" label="Resolution" start={t.createdAt} due={t.resolveDue} completedAt={t.solvedAt} />
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare const SlaTimer: React.ForwardRefExoticComponent<SlaTimerProps & React.RefAttributes<HTMLSpanElement>>;
|
|
75
|
+
export {};
|