@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,70 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type LabelsProp } from "../lib/labels.js";
|
|
3
|
+
import { type FontCategory, type GoogleFont } from "./catalog.js";
|
|
4
|
+
export declare const fontPickerLabels: {
|
|
5
|
+
placeholder: string;
|
|
6
|
+
search: string;
|
|
7
|
+
searchPlaceholder: string;
|
|
8
|
+
categories: string;
|
|
9
|
+
all: string;
|
|
10
|
+
list: string;
|
|
11
|
+
empty: string;
|
|
12
|
+
results: string;
|
|
13
|
+
variable: string;
|
|
14
|
+
italic: string;
|
|
15
|
+
weights: string;
|
|
16
|
+
};
|
|
17
|
+
export type FontPickerLabels = typeof fontPickerLabels;
|
|
18
|
+
export interface FontPickerListProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
|
|
19
|
+
/** Selected family name. */
|
|
20
|
+
value?: string | null;
|
|
21
|
+
defaultValue?: string | null;
|
|
22
|
+
onValueChange?: (family: string, font: GoogleFont) => void;
|
|
23
|
+
/** Families to offer. Default: the 59-family catalog. */
|
|
24
|
+
fonts?: GoogleFont[];
|
|
25
|
+
/** Only these categories (e.g. `["mono"]` for a code font field). */
|
|
26
|
+
categories?: FontCategory[];
|
|
27
|
+
/** Sample line under each family. */
|
|
28
|
+
previewText?: string;
|
|
29
|
+
/** Load glyph-subset previews from Google Fonts. Default `true`. Turn off when fonts are self-hosted. */
|
|
30
|
+
loadPreviews?: boolean;
|
|
31
|
+
/** Show the large specimen of the active option. Default `true`. */
|
|
32
|
+
specimen?: boolean;
|
|
33
|
+
/** Focus the search field on mount. */
|
|
34
|
+
autoFocus?: boolean;
|
|
35
|
+
/** Max height of the list (CSS length). Default `"18rem"`. */
|
|
36
|
+
listHeight?: string;
|
|
37
|
+
labels?: LabelsProp<FontPickerLabels>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Searchable, categorised list of font families with live previews. ARIA combobox + listbox:
|
|
41
|
+
* focus stays in the search field; ↑/↓, PageUp/PageDown, Home/End (with Ctrl) move, Enter selects.
|
|
42
|
+
* Use it inline (settings pages) or through `FontPicker` (popover).
|
|
43
|
+
*/
|
|
44
|
+
export declare const FontPickerList: React.ForwardRefExoticComponent<FontPickerListProps & React.RefAttributes<HTMLDivElement>>;
|
|
45
|
+
export interface FontPickerProps extends Omit<FontPickerListProps, "autoFocus" | "className" | "onChange" | "id"> {
|
|
46
|
+
open?: boolean;
|
|
47
|
+
defaultOpen?: boolean;
|
|
48
|
+
onOpenChange?: (open: boolean) => void;
|
|
49
|
+
size?: "sm" | "md" | "lg";
|
|
50
|
+
placeholder?: string;
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
/** Show the category under the family name in the trigger. Default `true`. */
|
|
53
|
+
showCategory?: boolean;
|
|
54
|
+
align?: "start" | "center" | "end";
|
|
55
|
+
id?: string;
|
|
56
|
+
name?: string;
|
|
57
|
+
required?: boolean;
|
|
58
|
+
"aria-label"?: string;
|
|
59
|
+
"aria-labelledby"?: string;
|
|
60
|
+
"aria-describedby"?: string;
|
|
61
|
+
"aria-invalid"?: boolean | "true" | "false";
|
|
62
|
+
className?: string;
|
|
63
|
+
/** Class for the popover panel. */
|
|
64
|
+
contentClassName?: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A select-like trigger that opens the searchable font list in a popover. Closes on selection.
|
|
68
|
+
* Inside a `Field` it picks up the id, description and invalid state.
|
|
69
|
+
*/
|
|
70
|
+
export declare const FontPicker: React.ForwardRefExoticComponent<FontPickerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,225 @@
|
|
|
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 { Check, ChevronsUpDown, Search } from "lucide-react";
|
|
5
|
+
import { Popover as PopoverPrimitive } from "radix-ui";
|
|
6
|
+
import { cn } from "../lib/cn.js";
|
|
7
|
+
import { controlVariants } from "../lib/variants.js";
|
|
8
|
+
import { useControllableState } from "../lib/use-controllable-state.js";
|
|
9
|
+
import { useFieldControl, FieldContextReset } from "../lib/field-context.js";
|
|
10
|
+
import { usePortalContainer } from "../lib/theme-scope.js";
|
|
11
|
+
import { Layer } from "../lib/layer.js";
|
|
12
|
+
import { useLabels } from "../lib/labels.js";
|
|
13
|
+
import { useLocale } from "../lib/locale.js";
|
|
14
|
+
import { highlightParts, matchText } from "../lib/text.js";
|
|
15
|
+
import { fontCategories, fontGroupOf, fontGroups, fontStack, getFont, googleFonts, isVariableFont } from "./catalog.js";
|
|
16
|
+
import { FONT_PREVIEW_TEXT, loadFontPreviews } from "./loader.js";
|
|
17
|
+
export const fontPickerLabels = {
|
|
18
|
+
placeholder: "Choose a font",
|
|
19
|
+
search: "Search fonts",
|
|
20
|
+
searchPlaceholder: "Search by name, style or use",
|
|
21
|
+
categories: "Category",
|
|
22
|
+
all: "All",
|
|
23
|
+
list: "Fonts",
|
|
24
|
+
empty: "No fonts match “{query}”.",
|
|
25
|
+
results: "{count, plural, one {# family} other {# families}}",
|
|
26
|
+
variable: "Variable",
|
|
27
|
+
italic: "Italic",
|
|
28
|
+
weights: "{count, plural, one {# weight} other {# weights}}",
|
|
29
|
+
};
|
|
30
|
+
/* ------------------------------------------------------------------ */
|
|
31
|
+
/* Preview font visibility */
|
|
32
|
+
/* ------------------------------------------------------------------ */
|
|
33
|
+
/** Applies a family's face only once its row has scrolled into view, so only visible previews download. */
|
|
34
|
+
function useSeen(root) {
|
|
35
|
+
const [seen, setSeen] = React.useState(() => new Set());
|
|
36
|
+
const observer = React.useRef(null);
|
|
37
|
+
const pending = React.useRef(new Map());
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
if (typeof IntersectionObserver === "undefined")
|
|
40
|
+
return;
|
|
41
|
+
const io = new IntersectionObserver((entries) => {
|
|
42
|
+
const add = [];
|
|
43
|
+
for (const e of entries) {
|
|
44
|
+
if (!e.isIntersecting)
|
|
45
|
+
continue;
|
|
46
|
+
const id = pending.current.get(e.target);
|
|
47
|
+
if (id)
|
|
48
|
+
add.push(id);
|
|
49
|
+
io.unobserve(e.target);
|
|
50
|
+
}
|
|
51
|
+
if (add.length)
|
|
52
|
+
setSeen((s) => new Set([...s, ...add]));
|
|
53
|
+
}, { root: root.current, rootMargin: "120px 0px" });
|
|
54
|
+
observer.current = io;
|
|
55
|
+
for (const el of pending.current.keys())
|
|
56
|
+
io.observe(el);
|
|
57
|
+
return () => io.disconnect();
|
|
58
|
+
}, [root]);
|
|
59
|
+
const observe = React.useCallback((id) => (el) => {
|
|
60
|
+
if (!el)
|
|
61
|
+
return;
|
|
62
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
63
|
+
setSeen((s) => (s.has(id) ? s : new Set(s).add(id)));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
pending.current.set(el, id);
|
|
67
|
+
observer.current?.observe(el);
|
|
68
|
+
}, []);
|
|
69
|
+
return { seen, observe };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Searchable, categorised list of font families with live previews. ARIA combobox + listbox:
|
|
73
|
+
* focus stays in the search field; ↑/↓, PageUp/PageDown, Home/End (with Ctrl) move, Enter selects.
|
|
74
|
+
* Use it inline (settings pages) or through `FontPicker` (popover).
|
|
75
|
+
*/
|
|
76
|
+
export const FontPickerList = React.forwardRef(function FontPickerList({ value: valueProp, defaultValue, onValueChange, fonts = googleFonts, categories, previewText = FONT_PREVIEW_TEXT, loadPreviews = true, specimen = true, autoFocus, listHeight = "18rem", labels, className, ...props }, ref) {
|
|
77
|
+
const t = useLabels("fontPicker", fontPickerLabels, labels);
|
|
78
|
+
const { locale } = useLocale();
|
|
79
|
+
const uid = React.useId();
|
|
80
|
+
const [value, setValue] = useControllableState({ value: valueProp, defaultValue: defaultValue ?? null, name: "FontPickerList" });
|
|
81
|
+
const [query, setQuery] = React.useState("");
|
|
82
|
+
const pool = React.useMemo(() => (categories?.length ? fonts.filter((f) => categories.includes(f.category)) : fonts), [fonts, categories]);
|
|
83
|
+
const cats = React.useMemo(() => fontCategories.filter((c) => pool.some((f) => f.category === c.id)), [pool]);
|
|
84
|
+
const [cat, setCat] = React.useState("all");
|
|
85
|
+
const rows = React.useMemo(() => {
|
|
86
|
+
const out = [];
|
|
87
|
+
for (const g of fontGroups) {
|
|
88
|
+
for (const f of pool) {
|
|
89
|
+
if (fontGroupOf(f).id !== g.id)
|
|
90
|
+
continue;
|
|
91
|
+
if (cat !== "all" && f.category !== cat)
|
|
92
|
+
continue;
|
|
93
|
+
if (query && !matchText(`${f.family} ${g.label} ${f.use}`, query, locale))
|
|
94
|
+
continue;
|
|
95
|
+
out.push({ font: f, group: g.id });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (query) {
|
|
99
|
+
// Name matches first, keep group order otherwise.
|
|
100
|
+
const byName = (r) => (matchText(r.font.family, query, locale) ? 0 : 1);
|
|
101
|
+
out.sort((a, b) => byName(a) - byName(b));
|
|
102
|
+
}
|
|
103
|
+
return out;
|
|
104
|
+
}, [pool, cat, query, locale]);
|
|
105
|
+
const [active, setActive] = React.useState(null);
|
|
106
|
+
const activeIndex = Math.max(0, rows.findIndex((r) => r.font.family === active));
|
|
107
|
+
const activeRow = rows.length ? rows[activeIndex] : undefined;
|
|
108
|
+
// Keep the active option on the selection when the list changes.
|
|
109
|
+
React.useEffect(() => {
|
|
110
|
+
if (rows.length === 0)
|
|
111
|
+
return setActive(null);
|
|
112
|
+
if (active && rows.some((r) => r.font.family === active))
|
|
113
|
+
return;
|
|
114
|
+
setActive(rows.find((r) => r.font.family === value)?.font.family ?? rows[0].font.family);
|
|
115
|
+
}, [rows, value, active]);
|
|
116
|
+
const listRef = React.useRef(null);
|
|
117
|
+
const { seen, observe } = useSeen(listRef);
|
|
118
|
+
React.useEffect(() => {
|
|
119
|
+
if (loadPreviews)
|
|
120
|
+
void loadFontPreviews(pool.map((f) => f.family), { extraText: previewText });
|
|
121
|
+
}, [loadPreviews, pool, previewText]);
|
|
122
|
+
const optionId = (f) => `${uid}-opt-${f.id}`;
|
|
123
|
+
React.useEffect(() => {
|
|
124
|
+
if (!activeRow)
|
|
125
|
+
return;
|
|
126
|
+
const el = listRef.current?.querySelector(`[id="${optionId(activeRow.font)}"]`);
|
|
127
|
+
el?.scrollIntoView?.({ block: "nearest" });
|
|
128
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
129
|
+
}, [activeRow?.font.id]);
|
|
130
|
+
const select = (f) => {
|
|
131
|
+
setValue(f.family);
|
|
132
|
+
onValueChange?.(f.family, f);
|
|
133
|
+
};
|
|
134
|
+
const move = (to) => {
|
|
135
|
+
if (!rows.length)
|
|
136
|
+
return;
|
|
137
|
+
const i = Math.min(rows.length - 1, Math.max(0, to));
|
|
138
|
+
setActive(rows[i].font.family);
|
|
139
|
+
};
|
|
140
|
+
const onKeyDown = (e) => {
|
|
141
|
+
switch (e.key) {
|
|
142
|
+
case "ArrowDown":
|
|
143
|
+
e.preventDefault();
|
|
144
|
+
move(activeIndex + 1);
|
|
145
|
+
break;
|
|
146
|
+
case "ArrowUp":
|
|
147
|
+
e.preventDefault();
|
|
148
|
+
move(activeIndex - 1);
|
|
149
|
+
break;
|
|
150
|
+
case "PageDown":
|
|
151
|
+
e.preventDefault();
|
|
152
|
+
move(activeIndex + 8);
|
|
153
|
+
break;
|
|
154
|
+
case "PageUp":
|
|
155
|
+
e.preventDefault();
|
|
156
|
+
move(activeIndex - 8);
|
|
157
|
+
break;
|
|
158
|
+
case "Home":
|
|
159
|
+
if (e.ctrlKey || e.metaKey) {
|
|
160
|
+
e.preventDefault();
|
|
161
|
+
move(0);
|
|
162
|
+
}
|
|
163
|
+
break;
|
|
164
|
+
case "End":
|
|
165
|
+
if (e.ctrlKey || e.metaKey) {
|
|
166
|
+
e.preventDefault();
|
|
167
|
+
move(rows.length - 1);
|
|
168
|
+
}
|
|
169
|
+
break;
|
|
170
|
+
case "Enter":
|
|
171
|
+
if (activeRow) {
|
|
172
|
+
e.preventDefault();
|
|
173
|
+
select(activeRow.font);
|
|
174
|
+
}
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
const face = (f) => (seen.has(f.id) || !loadPreviews ? { fontFamily: fontStack(f.family) } : undefined);
|
|
179
|
+
const listId = `${uid}-list`;
|
|
180
|
+
const sections = React.useMemo(() => {
|
|
181
|
+
const m = new Map();
|
|
182
|
+
for (const r of rows)
|
|
183
|
+
m.set(r.group, [...(m.get(r.group) ?? []), r]);
|
|
184
|
+
return [...m.entries()];
|
|
185
|
+
}, [rows]);
|
|
186
|
+
const renderOption = (r) => {
|
|
187
|
+
const g = fontGroups.find((x) => x.id === r.group);
|
|
188
|
+
const selected = r.font.family === value;
|
|
189
|
+
const isActive = r.font.family === activeRow?.font.family;
|
|
190
|
+
return (_jsxs("div", { ref: observe(r.font.id), id: optionId(r.font), role: "option", "aria-selected": selected, "data-active": isActive || undefined, onPointerMove: () => !isActive && setActive(r.font.family), onMouseDown: (e) => e.preventDefault(), onClick: () => select(r.font), className: "relative grid cursor-default grid-cols-[minmax(0,1fr)_auto] items-baseline gap-x-3 rounded-ui-sm px-2.5 py-1.5 data-active:bg-hover", children: [_jsx("span", { className: "truncate text-[15.5px] leading-snug text-fg", style: face(r.font), children: query
|
|
191
|
+
? highlightParts(r.font.family, query, locale).map((p, i) => (p.match ? _jsx("mark", { className: "rounded-[2px] bg-accent-soft text-fg", children: p.text }, i) : _jsx(React.Fragment, { children: p.text }, i)))
|
|
192
|
+
: r.font.family }), _jsxs("span", { className: "flex items-center gap-1.5 text-[11px] text-fg-subtle", children: [query ? _jsx("span", { children: g.label }) : null, isVariableFont(r.font) ? _jsx("span", { className: "font-mono uppercase tracking-wide", children: "var" }) : _jsxs("span", { className: "tabular-nums", children: [r.font.weights.length, "w"] }), _jsx(Check, { "aria-hidden": true, className: cn("size-3.5 text-accent-ink", !selected && "invisible") })] }), _jsx("span", { "aria-hidden": true, className: "col-span-2 truncate text-[12.5px] leading-snug text-fg-muted", style: face(r.font), children: previewText })] }, r.font.id));
|
|
193
|
+
};
|
|
194
|
+
return (_jsxs("div", { ref: ref, "data-slot": "font-picker-list", className: cn("grid min-w-0 gap-2.5", className), ...props, children: [_jsxs("div", { className: cn(controlVariants({ size: "md" }), "ps-2.5"), children: [_jsx(Search, { "aria-hidden": true, className: "text-fg-subtle" }), _jsx("input", { role: "combobox", "aria-label": t("search"), "aria-expanded": true, "aria-controls": listId, "aria-autocomplete": "list", "aria-activedescendant": activeRow ? optionId(activeRow.font) : undefined, autoFocus: autoFocus, autoComplete: "off", spellCheck: false, value: query, placeholder: t("searchPlaceholder"), onChange: (e) => setQuery(e.target.value), onKeyDown: onKeyDown, className: "h-full min-w-0 flex-1 bg-transparent text-fg outline-none placeholder:text-fg-subtle" }), _jsx("span", { "aria-live": "polite", className: "shrink-0 text-[11.5px] tabular-nums text-fg-subtle", children: t("results", { count: rows.length }) })] }), cats.length > 1 ? (_jsx("div", { role: "group", "aria-label": t("categories"), className: "-mx-0.5 flex flex-wrap gap-1 px-0.5", children: [{ id: "all", label: t("all") }, ...cats].map((c) => (_jsx("button", { type: "button", "aria-pressed": cat === c.id, onClick: () => setCat(c.id), className: cn("h-6 rounded-full border px-2.5 text-[11.5px] font-medium transition-colors focus-ring", cat === c.id ? "border-transparent bg-fg text-scene" : "border-line text-fg-muted hover:border-field-border-hover hover:text-fg"), children: c.label }, c.id))) })) : null, _jsx("div", { ref: listRef, id: listId, role: "listbox", "aria-label": t("list"), tabIndex: -1, style: { maxHeight: listHeight }, className: "-mx-1 overflow-y-auto overscroll-contain px-1", children: rows.length === 0 ? (_jsx("p", { className: "px-2 py-8 text-center text-[13px] text-fg-muted", children: t("empty", { query }) })) : query ? (rows.map((r) => renderOption(r))) : (sections.map(([gid, items]) => {
|
|
195
|
+
const g = fontGroups.find((x) => x.id === gid);
|
|
196
|
+
const hid = `${uid}-grp-${gid}`;
|
|
197
|
+
return (_jsxs("div", { role: "group", "aria-labelledby": hid, className: "pb-1", children: [_jsx("div", { id: hid, className: "px-2.5 pb-1 pt-2.5 font-mono text-[10.5px] uppercase tracking-[0.08em] text-fg-subtle", children: g.label }), items.map((r) => renderOption(r))] }, gid));
|
|
198
|
+
})) }), specimen && activeRow ? (_jsxs("div", { "aria-hidden": true, className: "relative -mx-(--popover-p,0px) -mb-(--popover-p,0px) overflow-hidden border-t border-line bg-surface-2 px-(--popover-p,0.75rem) py-3", children: [_jsx("div", { className: "truncate text-[28px] leading-[1.1] text-fg", style: { fontFamily: fontStack(activeRow.font.family) }, children: "A\u011Fa\u00E7 i\u015F\u00E7ili\u011Fi" }), _jsxs("div", { className: "mt-1.5 flex items-baseline justify-between gap-3 text-[11.5px]", children: [_jsx("span", { className: "min-w-0 truncate text-fg-muted", children: activeRow.font.use }), _jsxs("span", { className: "shrink-0 font-mono text-[10.5px] uppercase tracking-[0.06em] text-fg-subtle", children: [isVariableFont(activeRow.font) ? t("variable") : t("weights", { count: activeRow.font.weights.length }), activeRow.font.italics ? ` · ${t("italic")}` : ""] })] })] })) : null] }));
|
|
199
|
+
});
|
|
200
|
+
/**
|
|
201
|
+
* A select-like trigger that opens the searchable font list in a popover. Closes on selection.
|
|
202
|
+
* Inside a `Field` it picks up the id, description and invalid state.
|
|
203
|
+
*/
|
|
204
|
+
export const FontPicker = React.forwardRef(function FontPicker(rawProps, ref) {
|
|
205
|
+
const props = useFieldControl(rawProps);
|
|
206
|
+
const { open: openProp, defaultOpen, onOpenChange, size = "md", placeholder, disabled, showCategory = true, align = "start", id, name, required, className, contentClassName, value: valueProp, defaultValue, onValueChange, labels, loadPreviews = true, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, "aria-invalid": ariaInvalid, ...listProps } = props;
|
|
207
|
+
delete listProps.readOnly;
|
|
208
|
+
const t = useLabels("fontPicker", fontPickerLabels, labels);
|
|
209
|
+
const [open, setOpen] = useControllableState({ value: openProp, defaultValue: defaultOpen ?? false, onChange: onOpenChange, name: "FontPicker" });
|
|
210
|
+
const [value, setValue] = useControllableState({ value: valueProp, defaultValue: defaultValue ?? null, name: "FontPicker" });
|
|
211
|
+
const font = value ? getFont(value) : undefined;
|
|
212
|
+
const container = usePortalContainer();
|
|
213
|
+
React.useEffect(() => {
|
|
214
|
+
if (loadPreviews && value)
|
|
215
|
+
void loadFontPreviews([value]);
|
|
216
|
+
}, [loadPreviews, value]);
|
|
217
|
+
return (_jsxs(PopoverPrimitive.Root, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverPrimitive.Trigger, { asChild: true, disabled: disabled, children: _jsxs("button", { ref: ref, type: "button", id: id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, "aria-invalid": ariaInvalid, "aria-haspopup": "dialog", "data-slot": "font-picker-trigger", className: cn(controlVariants({ size }), "justify-between text-start", className), children: [_jsx("span", { className: "flex min-w-0 items-baseline gap-2", children: value ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "truncate text-[1.05em]", style: font ? { fontFamily: fontStack(font.family) } : undefined, children: value }), showCategory && font ? _jsx("span", { className: "truncate text-[11.5px] text-fg-subtle", children: fontGroupOf(font).label }) : null] })) : (_jsx("span", { className: "truncate text-fg-subtle", children: placeholder ?? t("placeholder") })) }), _jsx(ChevronsUpDown, { "aria-hidden": true, className: "shrink-0 text-fg-subtle" })] }) }), name ? _jsx("input", { type: "hidden", name: name, value: value ?? "", required: required }) : null, _jsx(PopoverPrimitive.Portal, { container: container, children: _jsx(Layer, { asChild: true, children: _jsx(PopoverPrimitive.Content, { align: align, sideOffset: 6, collisionPadding: 12, "aria-label": t("list"), onOpenAutoFocus: (e) => {
|
|
218
|
+
e.preventDefault();
|
|
219
|
+
e.currentTarget?.querySelector("input[role=combobox]")?.focus();
|
|
220
|
+
}, className: cn("surface-popover ui-pop z-(--z-popover) w-[24rem] max-w-[calc(100vw-1.5rem)] overflow-hidden rounded-ui-lg p-(--popover-p) outline-none [--popover-p:0.625rem]", contentClassName), children: _jsx(FieldContextReset, { children: _jsx(FontPickerList, { ...listProps, labels: labels, loadPreviews: loadPreviews, value: value, onValueChange: (fam, f) => {
|
|
221
|
+
setValue(fam);
|
|
222
|
+
onValueChange?.(fam, f);
|
|
223
|
+
setOpen(false);
|
|
224
|
+
} }) }) }) }) })] }));
|
|
225
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { googleFonts, fontGroups, fontCategories, getFont, fontGroupOf, fontStack, isVariableFont, type GoogleFont, type FontAxis, type FontCategory, type FontStyle, type FontGroup, } from "./catalog.js";
|
|
2
|
+
export { googleFontsUrl, familySpec, nearestWeight, loadGoogleFonts, loadFontPreviews, preconnectGoogleFonts, fontPreviewCharacters, FONT_PREVIEW_TEXT, GOOGLE_FONTS_CSS, GOOGLE_FONTS_ORIGINS, type FontRequest, type FontDisplay, type GoogleFontsUrlOptions, type LoadGoogleFontsOptions, } from "./loader.js";
|
|
3
|
+
export { fontPairings, getFontPairing, createFontPairing, displayTokensFor, pairingFamilies, pairingUrl, pairingVars, applyFontPairing, clearFontPairing, serializeFontPairing, parseFontPairing, fontBootScript, FONT_PAIRING_VARS, type FontPairing, type FontDisplayTokens, type ApplyFontPairingOptions, type StoredFontPairing, } from "./pairings.js";
|
|
4
|
+
export { FontProvider, useFontPairing, type FontProviderProps, type FontPairingContextValue } from "./provider.js";
|
|
5
|
+
export { FontPicker, FontPickerList, fontPickerLabels, type FontPickerProps, type FontPickerListProps, type FontPickerLabels } from "./font-picker.js";
|
|
6
|
+
export { FontPairingPicker, fontPairingPickerLabels, type FontPairingPickerProps, type FontPairingPickerLabels } from "./pairing-picker.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Public API of @vamos-ui/react/fonts — Google Fonts catalog, pairings, loader, pickers.
|
|
2
|
+
export { googleFonts, fontGroups, fontCategories, getFont, fontGroupOf, fontStack, isVariableFont, } from "./catalog.js";
|
|
3
|
+
export { googleFontsUrl, familySpec, nearestWeight, loadGoogleFonts, loadFontPreviews, preconnectGoogleFonts, fontPreviewCharacters, FONT_PREVIEW_TEXT, GOOGLE_FONTS_CSS, GOOGLE_FONTS_ORIGINS, } from "./loader.js";
|
|
4
|
+
export { fontPairings, getFontPairing, createFontPairing, displayTokensFor, pairingFamilies, pairingUrl, pairingVars, applyFontPairing, clearFontPairing, serializeFontPairing, parseFontPairing, fontBootScript, FONT_PAIRING_VARS, } from "./pairings.js";
|
|
5
|
+
export { FontProvider, useFontPairing } from "./provider.js";
|
|
6
|
+
export { FontPicker, FontPickerList, fontPickerLabels } from "./font-picker.js";
|
|
7
|
+
export { FontPairingPicker, fontPairingPickerLabels } from "./pairing-picker.js";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type GoogleFont } from "./catalog.js";
|
|
2
|
+
export declare const GOOGLE_FONTS_CSS = "https://fonts.googleapis.com/css2";
|
|
3
|
+
export declare const GOOGLE_FONTS_ORIGINS: readonly ["https://fonts.googleapis.com", "https://fonts.gstatic.com"];
|
|
4
|
+
/** A family to request, optionally narrowed. */
|
|
5
|
+
export interface FontRequest {
|
|
6
|
+
family: string;
|
|
7
|
+
/** Only these weights (default: the whole range / every static weight). */
|
|
8
|
+
weights?: number[];
|
|
9
|
+
/** Request italics when the family has them. Default `true`. */
|
|
10
|
+
italics?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export type FontDisplay = "auto" | "block" | "swap" | "fallback" | "optional";
|
|
13
|
+
export interface GoogleFontsUrlOptions {
|
|
14
|
+
/** `font-display` for every face. Default `"swap"`. */
|
|
15
|
+
display?: FontDisplay;
|
|
16
|
+
/** Only the glyphs in this string (tiny files — for previews and logos). */
|
|
17
|
+
text?: string;
|
|
18
|
+
/** Request the optical-size axis when a variable family has one. Default `true`. */
|
|
19
|
+
opticalSize?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** The `family=` value of one request, e.g. `Fraunces:ital,opsz,wght@0,9..144,100..900;1,9..144,100..900`. */
|
|
22
|
+
export declare function familySpec(request: string | FontRequest, options?: Pick<GoogleFontsUrlOptions, "opticalSize">): string;
|
|
23
|
+
/** Closest available weight to `target`. */
|
|
24
|
+
export declare function nearestWeight(font: GoogleFont, target?: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* Google Fonts CSS2 URL for one or more families. Duplicates are dropped.
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* googleFontsUrl(["Onest", "Instrument Serif"]);
|
|
30
|
+
* // https://fonts.googleapis.com/css2?family=Onest:wght@100..900&family=Instrument+Serif:ital@0;1&display=swap
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function googleFontsUrl(families: Array<string | FontRequest>, options?: GoogleFontsUrlOptions): string;
|
|
34
|
+
export interface LoadGoogleFontsOptions extends GoogleFontsUrlOptions {
|
|
35
|
+
/** Document to inject into (iframes, tests). Default: the global `document`. */
|
|
36
|
+
document?: Document;
|
|
37
|
+
/**
|
|
38
|
+
* Add `blocking="render"` to the link so supporting browsers wait for the CSS
|
|
39
|
+
* (not the font files) before first paint. Use only in a boot script. Default `false`.
|
|
40
|
+
*/
|
|
41
|
+
renderBlocking?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** Adds `<link rel="preconnect">` for both Google Fonts origins, once per document. */
|
|
44
|
+
export declare function preconnectGoogleFonts(doc?: Document | undefined): void;
|
|
45
|
+
/**
|
|
46
|
+
* Loads Google Fonts families by injecting a single `<link rel="stylesheet">` (plus preconnect).
|
|
47
|
+
* Families already requested by an earlier call — with the same options — are skipped, so calling
|
|
48
|
+
* it on every render is cheap. Resolves when the stylesheet has loaded (or failed); a no-op on the server.
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* await loadGoogleFonts(["Fraunces", "Figtree"], { display: "swap" });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare function loadGoogleFonts(families: Array<string | FontRequest>, options?: LoadGoogleFontsOptions): Promise<void>;
|
|
55
|
+
/** The sample line pickers show under each family. */
|
|
56
|
+
export declare const FONT_PREVIEW_TEXT = "Hamburgefonstiv \u2014 A\u011Fa\u00E7 i\u015F\u00E7ili\u011Fi";
|
|
57
|
+
/** Every glyph a preview may need: the sample line, digits and all catalog family names. Stable, so loads dedupe. */
|
|
58
|
+
export declare function fontPreviewCharacters(extra?: string): string;
|
|
59
|
+
/**
|
|
60
|
+
* Loads tiny glyph-subset files — one weight per family, only the characters of the preview line and
|
|
61
|
+
* the catalog family names — so a picker can show every family in its own face without full downloads.
|
|
62
|
+
* Pass `{ family, weights: [700] }` to preview a heavier weight.
|
|
63
|
+
*/
|
|
64
|
+
export declare function loadFontPreviews(families: Array<string | FontRequest>, options?: Omit<LoadGoogleFontsOptions, "text" | "opticalSize"> & {
|
|
65
|
+
extraText?: string;
|
|
66
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// Google Fonts CSS2 URL builder and a deduped, SSR-safe <link> loader.
|
|
2
|
+
import { getFont, googleFonts } from "./catalog.js";
|
|
3
|
+
export const GOOGLE_FONTS_CSS = "https://fonts.googleapis.com/css2";
|
|
4
|
+
export const GOOGLE_FONTS_ORIGINS = ["https://fonts.googleapis.com", "https://fonts.gstatic.com"];
|
|
5
|
+
const norm = (r) => (typeof r === "string" ? { family: r } : r);
|
|
6
|
+
/** The `family=` value of one request, e.g. `Fraunces:ital,opsz,wght@0,9..144,100..900;1,9..144,100..900`. */
|
|
7
|
+
export function familySpec(request, options = {}) {
|
|
8
|
+
const r = norm(request);
|
|
9
|
+
const font = getFont(r.family);
|
|
10
|
+
const name = (font?.family ?? r.family).trim().replace(/\s+/g, "+");
|
|
11
|
+
if (!font) {
|
|
12
|
+
// Not in the catalog: pass weights through as given.
|
|
13
|
+
return r.weights?.length ? `${name}:wght@${[...r.weights].sort((a, b) => a - b).join(";")}` : name;
|
|
14
|
+
}
|
|
15
|
+
const ital = font.italics && r.italics !== false;
|
|
16
|
+
const wghtAxis = font.axes.find((a) => a.tag === "wght");
|
|
17
|
+
const opszAxis = options.opticalSize === false || r.weights ? undefined : font.axes.find((a) => a.tag === "opsz");
|
|
18
|
+
let weights;
|
|
19
|
+
if (r.weights?.length) {
|
|
20
|
+
const ok = r.weights.filter((w) => (wghtAxis ? w >= wghtAxis.min && w <= wghtAxis.max : font.weights.includes(w)));
|
|
21
|
+
weights = [...new Set(ok.length ? ok : [nearestWeight(font, 400)])].sort((a, b) => a - b).map(String);
|
|
22
|
+
}
|
|
23
|
+
else if (wghtAxis) {
|
|
24
|
+
weights = [`${wghtAxis.min}..${wghtAxis.max}`];
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
weights = font.weights.map(String);
|
|
28
|
+
}
|
|
29
|
+
const single = weights.length === 1 && weights[0] === "400" && !opszAxis;
|
|
30
|
+
if (single && !ital)
|
|
31
|
+
return name;
|
|
32
|
+
if (single && ital)
|
|
33
|
+
return `${name}:ital@0;1`;
|
|
34
|
+
const tags = [ital && "ital", opszAxis && "opsz", "wght"].filter(Boolean).join(",");
|
|
35
|
+
const tuples = [];
|
|
36
|
+
for (const i of ital ? [0, 1] : [null]) {
|
|
37
|
+
for (const w of weights) {
|
|
38
|
+
const parts = [];
|
|
39
|
+
if (i !== null)
|
|
40
|
+
parts.push(String(i));
|
|
41
|
+
if (opszAxis)
|
|
42
|
+
parts.push(`${opszAxis.min}..${opszAxis.max}`);
|
|
43
|
+
parts.push(w);
|
|
44
|
+
tuples.push(parts.join(","));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return `${name}:${tags}@${tuples.join(";")}`;
|
|
48
|
+
}
|
|
49
|
+
/** Closest available weight to `target`. */
|
|
50
|
+
export function nearestWeight(font, target = 400) {
|
|
51
|
+
return font.weights.reduce((best, w) => (Math.abs(w - target) < Math.abs(best - target) ? w : best), font.weights[0] ?? 400);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Google Fonts CSS2 URL for one or more families. Duplicates are dropped.
|
|
55
|
+
*
|
|
56
|
+
* ```ts
|
|
57
|
+
* googleFontsUrl(["Onest", "Instrument Serif"]);
|
|
58
|
+
* // https://fonts.googleapis.com/css2?family=Onest:wght@100..900&family=Instrument+Serif:ital@0;1&display=swap
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export function googleFontsUrl(families, options = {}) {
|
|
62
|
+
const seen = new Set();
|
|
63
|
+
const specs = [];
|
|
64
|
+
for (const f of families) {
|
|
65
|
+
const spec = familySpec(f, options);
|
|
66
|
+
if (seen.has(spec))
|
|
67
|
+
continue;
|
|
68
|
+
seen.add(spec);
|
|
69
|
+
specs.push(`family=${spec}`);
|
|
70
|
+
}
|
|
71
|
+
let url = `${GOOGLE_FONTS_CSS}?${specs.join("&")}&display=${options.display ?? "swap"}`;
|
|
72
|
+
if (options.text)
|
|
73
|
+
url += `&text=${encodeURIComponent(uniqueChars(options.text))}`;
|
|
74
|
+
return url;
|
|
75
|
+
}
|
|
76
|
+
function uniqueChars(s) {
|
|
77
|
+
return [...new Set(Array.from(s))].sort().join("");
|
|
78
|
+
}
|
|
79
|
+
const LINK_ATTR = "data-vamos-fonts";
|
|
80
|
+
/** Adds `<link rel="preconnect">` for both Google Fonts origins, once per document. */
|
|
81
|
+
export function preconnectGoogleFonts(doc = typeof document === "undefined" ? undefined : document) {
|
|
82
|
+
if (!doc)
|
|
83
|
+
return;
|
|
84
|
+
for (const origin of GOOGLE_FONTS_ORIGINS) {
|
|
85
|
+
if (doc.head.querySelector(`link[rel="preconnect"][href="${origin}"]`))
|
|
86
|
+
continue;
|
|
87
|
+
const l = doc.createElement("link");
|
|
88
|
+
l.rel = "preconnect";
|
|
89
|
+
l.href = origin;
|
|
90
|
+
if (origin.includes("gstatic"))
|
|
91
|
+
l.crossOrigin = "anonymous";
|
|
92
|
+
doc.head.appendChild(l);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Loads Google Fonts families by injecting a single `<link rel="stylesheet">` (plus preconnect).
|
|
97
|
+
* Families already requested by an earlier call — with the same options — are skipped, so calling
|
|
98
|
+
* it on every render is cheap. Resolves when the stylesheet has loaded (or failed); a no-op on the server.
|
|
99
|
+
*
|
|
100
|
+
* ```ts
|
|
101
|
+
* await loadGoogleFonts(["Fraunces", "Figtree"], { display: "swap" });
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export function loadGoogleFonts(families, options = {}) {
|
|
105
|
+
const doc = options.document ?? (typeof document === "undefined" ? undefined : document);
|
|
106
|
+
if (!doc || families.length === 0)
|
|
107
|
+
return Promise.resolve();
|
|
108
|
+
const variant = `${options.display ?? "swap"}|${options.text ? uniqueChars(options.text) : ""}|${options.opticalSize === false ? 0 : 1}`;
|
|
109
|
+
const loaded = new Set(Array.from(doc.head.querySelectorAll(`link[${LINK_ATTR}]`)).flatMap((l) => l.getAttribute("data-variant") === variant ? (l.getAttribute(LINK_ATTR) ?? "").split("|") : []));
|
|
110
|
+
const fresh = [];
|
|
111
|
+
const keys = [];
|
|
112
|
+
for (const f of families) {
|
|
113
|
+
const key = familySpec(f, options);
|
|
114
|
+
if (loaded.has(key) || keys.includes(key))
|
|
115
|
+
continue;
|
|
116
|
+
keys.push(key);
|
|
117
|
+
fresh.push(f);
|
|
118
|
+
}
|
|
119
|
+
if (fresh.length === 0)
|
|
120
|
+
return Promise.resolve();
|
|
121
|
+
preconnectGoogleFonts(doc);
|
|
122
|
+
const link = doc.createElement("link");
|
|
123
|
+
link.rel = "stylesheet";
|
|
124
|
+
link.href = googleFontsUrl(fresh, options);
|
|
125
|
+
link.setAttribute(LINK_ATTR, keys.join("|"));
|
|
126
|
+
link.setAttribute("data-variant", variant);
|
|
127
|
+
if (options.renderBlocking)
|
|
128
|
+
link.setAttribute("blocking", "render");
|
|
129
|
+
const done = new Promise((resolve) => {
|
|
130
|
+
link.addEventListener("load", () => resolve(), { once: true });
|
|
131
|
+
link.addEventListener("error", () => resolve(), { once: true });
|
|
132
|
+
});
|
|
133
|
+
doc.head.appendChild(link);
|
|
134
|
+
return done;
|
|
135
|
+
}
|
|
136
|
+
/** The sample line pickers show under each family. */
|
|
137
|
+
export const FONT_PREVIEW_TEXT = "Hamburgefonstiv — Ağaç işçiliği";
|
|
138
|
+
let previewChars;
|
|
139
|
+
/** Every glyph a preview may need: the sample line, digits and all catalog family names. Stable, so loads dedupe. */
|
|
140
|
+
export function fontPreviewCharacters(extra = "") {
|
|
141
|
+
previewChars ??= uniqueChars(FONT_PREVIEW_TEXT + "AaGg0123456789 " + googleFonts.map((f) => f.family).join(""));
|
|
142
|
+
return extra ? uniqueChars(previewChars + extra) : previewChars;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Loads tiny glyph-subset files — one weight per family, only the characters of the preview line and
|
|
146
|
+
* the catalog family names — so a picker can show every family in its own face without full downloads.
|
|
147
|
+
* Pass `{ family, weights: [700] }` to preview a heavier weight.
|
|
148
|
+
*/
|
|
149
|
+
export function loadFontPreviews(families, options = {}) {
|
|
150
|
+
const { extraText, ...rest } = options;
|
|
151
|
+
const reqs = [];
|
|
152
|
+
for (const r of families.map(norm)) {
|
|
153
|
+
const f = getFont(r.family);
|
|
154
|
+
if (!f)
|
|
155
|
+
continue;
|
|
156
|
+
reqs.push({ family: f.family, weights: r.weights?.length ? r.weights : [nearestWeight(f, 400)], italics: r.italics ?? false });
|
|
157
|
+
}
|
|
158
|
+
if (reqs.length === 0)
|
|
159
|
+
return Promise.resolve();
|
|
160
|
+
return loadGoogleFonts(reqs, { ...rest, text: fontPreviewCharacters(extraText), opticalSize: false });
|
|
161
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type LabelsProp } from "../lib/labels.js";
|
|
3
|
+
import { type FontPairing } from "./pairings.js";
|
|
4
|
+
export declare const fontPairingPickerLabels: {
|
|
5
|
+
label: string;
|
|
6
|
+
headings: string;
|
|
7
|
+
body: string;
|
|
8
|
+
code: string;
|
|
9
|
+
};
|
|
10
|
+
export type FontPairingPickerLabels = typeof fontPairingPickerLabels;
|
|
11
|
+
export interface FontPairingPickerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue" | "dir"> {
|
|
12
|
+
/** Selected pairing id. */
|
|
13
|
+
value?: string | null;
|
|
14
|
+
defaultValue?: string | null;
|
|
15
|
+
onValueChange?: (id: string, pairing: FontPairing) => void;
|
|
16
|
+
/** Pairings to offer. Default: the 16 built-ins. */
|
|
17
|
+
pairings?: FontPairing[];
|
|
18
|
+
/** `"grid"` cards (settings pages) or a compact `"list"` (popovers). Default `"grid"`. */
|
|
19
|
+
layout?: "grid" | "list";
|
|
20
|
+
/** Show the one-line description. Default: `true` for grid, `false` for list. */
|
|
21
|
+
showDescription?: boolean;
|
|
22
|
+
/** Load preview glyphs from Google Fonts. Default `true`. */
|
|
23
|
+
loadPreviews?: boolean;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
labels?: LabelsProp<FontPairingPickerLabels>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Pick one of the curated pairings. A WAI-ARIA radio group with a roving tab stop:
|
|
29
|
+
* arrow keys move and select, Home/End jump to the ends.
|
|
30
|
+
*/
|
|
31
|
+
export declare const FontPairingPicker: React.ForwardRefExoticComponent<FontPairingPickerProps & React.RefAttributes<HTMLDivElement>>;
|