themelia-react-ui 2.0.3 → 2.0.5
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/CHANGELOG.md +185 -0
- package/README.md +168 -36
- package/dist/{accordion-Cjb6sx0G.js → accordion-B9MHG0cT.js} +11 -11
- package/dist/accordion-B9MHG0cT.js.map +1 -0
- package/dist/action-menu-Dr8K-ghE.js +284 -0
- package/dist/action-menu-Dr8K-ghE.js.map +1 -0
- package/dist/{affordance-geometry.generated-tF36bREk.js → affordance-geometry.generated-P-aVJisu.js} +42 -36
- package/dist/affordance-geometry.generated-P-aVJisu.js.map +1 -0
- package/dist/{ai-artifact-DvTwDVyL.js → ai-artifact-C58tQcBy.js} +387 -350
- package/dist/ai-artifact-C58tQcBy.js.map +1 -0
- package/dist/app-shell-B_IuNWOo.js +321 -0
- package/dist/app-shell-B_IuNWOo.js.map +1 -0
- package/dist/{attachment-BxDfL2mw.js → attachment-Dg_69lPS.js} +9 -9
- package/dist/{attachment-BxDfL2mw.js.map → attachment-Dg_69lPS.js.map} +1 -1
- package/dist/{auth-BGua8ouh.js → auth-DTkkshS8.js} +44 -47
- package/dist/auth-DTkkshS8.js.map +1 -0
- package/dist/{avatar-DAPlDvhJ.js → avatar-CeZaFmNH.js} +8 -8
- package/dist/avatar-CeZaFmNH.js.map +1 -0
- package/dist/{badge-HpFqoqSY.js → badge-xIiV_E7f.js} +5 -5
- package/dist/{badge-HpFqoqSY.js.map → badge-xIiV_E7f.js.map} +1 -1
- package/dist/base/accordion.js +1 -1
- package/dist/base/action-menu.js +1 -1
- package/dist/base/attachment.js +1 -1
- package/dist/base/avatar.js +1 -1
- package/dist/base/badge.js +1 -1
- package/dist/base/batch-action-bar.js +1 -1
- package/dist/base/buttons.js +1 -1
- package/dist/base/cards.js +2 -2
- package/dist/base/carousel.js +3 -3
- package/dist/base/cascader.js +2 -372
- package/dist/base/chart.js +1 -1
- package/dist/base/choice-inputs.js +2 -2
- package/dist/base/code-block.js +1 -1
- package/dist/base/combobox.js +2 -2
- package/dist/base/command.js +1 -1
- package/dist/base/copyable.js +1 -1
- package/dist/base/date-pickers.js +2 -2
- package/dist/base/display.js +6 -6
- package/dist/base/feedback.js +3 -3
- package/dist/base/forms-numeric.js +1 -1
- package/dist/base/forms.js +3 -3
- package/dist/base/inline-edit.js +10 -10
- package/dist/base/item.js +1 -1
- package/dist/base/media-gallery.js +1 -1
- package/dist/base/metadata-list.js +1 -1
- package/dist/base/navigation.js +7 -7
- package/dist/base/popover-menu.js +1 -1
- package/dist/base/popover.js +1 -1
- package/dist/base/qr-code.js +1 -1
- package/dist/base/repeaters.js +12 -12
- package/dist/base/repeaters.js.map +1 -1
- package/dist/base/sheet.js +1 -1
- package/dist/base/sidebar.js +2 -2
- package/dist/base/signature-pad.js +7 -7
- package/dist/base/signature-pad.js.map +1 -1
- package/dist/base/skeleton.js +1 -1
- package/dist/base/spinner.js +4 -4
- package/dist/base/structure.js +1 -1
- package/dist/base/table.js +1 -1
- package/dist/base/text-inputs.js +2 -2
- package/dist/base/toaster.js +36 -36
- package/dist/base/toaster.js.map +1 -1
- package/dist/base/tree.js +1 -1
- package/dist/base/upload-queue.js +1 -1
- package/dist/base/upload.js +3 -3
- package/dist/base/value-inputs.js +1 -1
- package/dist/{batch-action-bar-DnUJ21NQ.js → batch-action-bar-Cb8cuvyy.js} +6 -6
- package/dist/batch-action-bar-Cb8cuvyy.js.map +1 -0
- package/dist/blocks/admin.js +23 -23
- package/dist/blocks/admin.js.map +1 -1
- package/dist/blocks/ai.js +230 -216
- package/dist/blocks/ai.js.map +1 -1
- package/dist/blocks/analytics/usage-card.js +1 -1
- package/dist/blocks/analytics.js +326 -307
- package/dist/blocks/analytics.js.map +1 -1
- package/dist/blocks/collaboration.js +1 -1
- package/dist/blocks/commerce/receipt.js +1 -1
- package/dist/blocks/commerce.js +1247 -1169
- package/dist/blocks/commerce.js.map +1 -1
- package/dist/blocks/data-display.js +2 -2
- package/dist/blocks/onboarding.js +6 -6
- package/dist/blocks/onboarding.js.map +1 -1
- package/dist/blocks/planning.js +11 -11
- package/dist/blocks/timelines.js +1 -1
- package/dist/{breadcrumbs-C-oqs1sQ.js → breadcrumbs-J-K2kl4c.js} +6 -6
- package/dist/{breadcrumbs-C-oqs1sQ.js.map → breadcrumbs-J-K2kl4c.js.map} +1 -1
- package/dist/{button-DVzspB_G.js → button-S2Cubiiz.js} +3 -3
- package/dist/button-S2Cubiiz.js.map +1 -0
- package/dist/{buttons-DPZekJFu.js → buttons-BedGfygC.js} +16 -16
- package/dist/buttons-BedGfygC.js.map +1 -0
- package/dist/cards-rNX1M4Xn.js +69 -0
- package/dist/cards-rNX1M4Xn.js.map +1 -0
- package/dist/cascader-B1MiqkBq.js +439 -0
- package/dist/cascader-B1MiqkBq.js.map +1 -0
- package/dist/chart-Darg_0Kv.js +162 -0
- package/dist/chart-Darg_0Kv.js.map +1 -0
- package/dist/{checkbox-AWIhNhmo.js → checkbox-fflqmODR.js} +9 -5
- package/dist/checkbox-fflqmODR.js.map +1 -0
- package/dist/choice-inputs-zUgBZfE4.js +777 -0
- package/dist/choice-inputs-zUgBZfE4.js.map +1 -0
- package/dist/{code-block-DeneBJR_.js → code-block-BzmM9Eig.js} +9 -9
- package/dist/code-block-BzmM9Eig.js.map +1 -0
- package/dist/{collapsible-C-_l4hpy.js → collapsible-BkAI_XD4.js} +5 -5
- package/dist/{collapsible-C-_l4hpy.js.map → collapsible-BkAI_XD4.js.map} +1 -1
- package/dist/{collection-content-By56pLog.js → collection-content-gDh1v6O4.js} +3 -3
- package/dist/{collection-content-By56pLog.js.map → collection-content-gDh1v6O4.js.map} +1 -1
- package/dist/combobox-BEx0vJgF.js +362 -0
- package/dist/combobox-BEx0vJgF.js.map +1 -0
- package/dist/{combobox-Dxo2fAYQ.js → combobox-BwzoXFSG.js} +254 -247
- package/dist/combobox-BwzoXFSG.js.map +1 -0
- package/dist/{command-C25VMRII.js → command-CrlPIL6m.js} +12 -12
- package/dist/command-CrlPIL6m.js.map +1 -0
- package/dist/{comments-DD0DUPwJ.js → comments-Dmpp0YIc.js} +380 -379
- package/dist/comments-Dmpp0YIc.js.map +1 -0
- package/dist/components/base/action-menu/action-menu.d.ts +9 -1
- package/dist/components/base/buttons/button-group.recipes.d.ts +2 -2
- package/dist/components/base/cards/card.recipes.d.ts +16 -7
- package/dist/components/base/cards/partials/card-primitives.d.ts +9 -2
- package/dist/components/base/cards/partials/smart-card-header-row.d.ts +3 -1
- package/dist/components/base/cards/smart-card.types.d.ts +11 -7
- package/dist/components/base/cascader/cascader-panel.d.ts +76 -0
- package/dist/components/base/chart/chart.d.ts +6 -1
- package/dist/components/base/choice-inputs/checkbox.d.ts +7 -2
- package/dist/components/base/choice-inputs/choice-types.d.ts +1 -1
- package/dist/components/base/choice-inputs/switch-card.d.ts +7 -0
- package/dist/components/base/choice-inputs/toggle-field.d.ts +7 -0
- package/dist/components/base/combobox/index.d.ts +4 -2
- package/dist/components/base/date-pickers/datepicker.types.d.ts +7 -0
- package/dist/components/base/feedback/alert.d.ts +1 -1
- package/dist/components/base/forms/controlled-form-field.d.ts +6 -6
- package/dist/components/base/forms/form-field.d.ts +5 -3
- package/dist/components/base/forms/form-sizing.d.ts +7 -7
- package/dist/components/base/forms/index.d.ts +1 -0
- package/dist/components/base/forms/server-errors.d.ts +16 -0
- package/dist/components/base/forms/workflow.d.ts +11 -2
- package/dist/components/base/forms-numeric/coordinates-input.d.ts +4 -0
- package/dist/components/base/metadata-list/metadata-list.d.ts +3 -1
- package/dist/components/base/navigation/dropdown-menu.d.ts +1 -1
- package/dist/components/base/navigation/page-header/page-header-commands.d.ts +14 -7
- package/dist/components/base/navigation/page-header/page-header.d.ts +13 -4
- package/dist/components/base/popover/popover.d.ts +3 -3
- package/dist/components/base/popover/popover.recipes.d.ts +10 -6
- package/dist/components/base/sheet/sheet.d.ts +2 -0
- package/dist/components/base/sidebar/index.d.ts +1 -1
- package/dist/components/base/sidebar/sidebar.d.ts +27 -5
- package/dist/components/base/structure/composition.recipes.d.ts +17 -0
- package/dist/components/base/text-inputs/hooks/use-form-field-state.d.ts +7 -2
- package/dist/components/base/text-inputs/input.d.ts +4 -2
- package/dist/components/base/text-inputs/textarea.d.ts +4 -2
- package/dist/components/base/toaster/index.d.ts +1 -0
- package/dist/components/base/value-inputs/date-time-input.d.ts +2 -1
- package/dist/components/base/value-inputs/slider.d.ts +5 -1
- package/dist/components/base/value-inputs/tags-input.d.ts +5 -1
- package/dist/components/blocks/ai/ai-file-tree/types.d.ts +1 -1
- package/dist/components/blocks/ai/ai-tool-call/types.d.ts +3 -1
- package/dist/components/blocks/ai/ai.strings.d.ts +2 -0
- package/dist/components/blocks/analytics/metric-comparison/metric-comparison.d.ts +2 -0
- package/dist/components/blocks/analytics/usage-card/usage-card.strings.d.ts +2 -0
- package/dist/components/blocks/commerce/cart-summary/cart-summary.d.ts +1 -1
- package/dist/components/blocks/commerce/cart-summary/types.d.ts +3 -1
- package/dist/components/blocks/commerce/discount-stack/discount-stack.d.ts +1 -1
- package/dist/components/blocks/commerce/discount-stack/types.d.ts +3 -1
- package/dist/components/blocks/commerce/fulfillment-group/fulfillment-group.d.ts +1 -1
- package/dist/components/blocks/commerce/fulfillment-group/types.d.ts +11 -2
- package/dist/components/blocks/commerce/index.d.ts +7 -6
- package/dist/components/blocks/commerce/inventory-section/inventory-section.d.ts +1 -1
- package/dist/components/blocks/commerce/inventory-section/types.d.ts +7 -2
- package/dist/components/blocks/commerce/invoice-header/index.d.ts +2 -1
- package/dist/components/blocks/commerce/invoice-header/invoice-header.d.ts +1 -1
- package/dist/components/blocks/commerce/invoice-header/types.d.ts +20 -6
- package/dist/components/blocks/commerce/invoice-line-items/invoice-line-items.d.ts +1 -1
- package/dist/components/blocks/commerce/invoice-line-items/types.d.ts +24 -7
- package/dist/components/blocks/commerce/invoice-mini/index.d.ts +2 -1
- package/dist/components/blocks/commerce/invoice-mini/types.d.ts +7 -1
- package/dist/components/blocks/commerce/order-customer/order-customer.d.ts +1 -1
- package/dist/components/blocks/commerce/order-customer/types.d.ts +9 -1
- package/dist/components/blocks/commerce/refund-status/refund-status.d.ts +1 -1
- package/dist/components/blocks/commerce/refund-status/types.d.ts +3 -1
- package/dist/components/blocks/commerce/shipment-tracking/shipment-tracking.d.ts +1 -1
- package/dist/components/blocks/commerce/shipment-tracking/types.d.ts +3 -1
- package/dist/components/blocks/commerce/tax-breakdown/tax-breakdown.d.ts +1 -1
- package/dist/components/blocks/commerce/tax-breakdown/types.d.ts +3 -1
- package/dist/components/features/activities/activities.types.d.ts +8 -2
- package/dist/components/features/activities/partials/activity-marker.d.ts +7 -3
- package/dist/components/features/activities/partials/activity-row.d.ts +24 -0
- package/dist/components/features/event-calendar/colors.d.ts +2 -2
- package/dist/components/features/event-calendar/event-calendar.types.d.ts +4 -0
- package/dist/components/features/filters/facets/select-facet.d.ts +2 -1
- package/dist/components/features/filters/filters.strings.d.ts +4 -0
- package/dist/components/features/filters/filters.types.d.ts +3 -0
- package/dist/components/features/filters/partials/filter-editor-header.d.ts +16 -0
- package/dist/components/features/filters/partials/filter-popover-content.d.ts +1 -1
- package/dist/components/features/filters/partials/nested-filter-options.d.ts +21 -0
- package/dist/components/features/filters/partials/regular-filter-content.d.ts +2 -1
- package/dist/components/features/filters/utils/filter-utils.d.ts +21 -3
- package/dist/components/features/global-search/global-search.types.d.ts +2 -0
- package/dist/components/features/global-search/partials/global-search-input.d.ts +10 -0
- package/dist/components/features/global-search/partials/global-search-result-row.d.ts +7 -1
- package/dist/components/features/media-library/media-library.strings.d.ts +2 -0
- package/dist/components/features/media-library/media-library.types.d.ts +14 -4
- package/dist/components/features/media-library/partials/media-library-partials.d.ts +1 -1
- package/dist/components/features/products/components/product-options-matrix.d.ts +1 -1
- package/dist/components/features/products/components/product-variant-editor.d.ts +1 -1
- package/dist/components/features/products/components/product-variants-manager.d.ts +1 -1
- package/dist/components/features/products/products.strings.d.ts +9 -1
- package/dist/components/features/products/products.types.d.ts +43 -6
- package/dist/components/features/resource/resource.d.ts +5 -1
- package/dist/components/features/resource/resource.types.d.ts +12 -1
- package/dist/components/features/rich-text-editor/partials/image-uploads.d.ts +1 -1
- package/dist/components/features/rich-text-editor/rich-text-editor.recipes.d.ts +12 -2
- package/dist/components/features/table/partials/resource-cell.d.ts +22 -5
- package/dist/components/features/table/table.types.d.ts +1 -1
- package/dist/components/layout/app-shell/app-shell.types.d.ts +35 -6
- package/dist/components/layout/app-shell/index.d.ts +1 -1
- package/dist/components/layout/app-shell/shell-regions.d.ts +27 -0
- package/dist/components/layout/app-shell/sidebar-inset-layout.d.ts +1 -1
- package/dist/components/layout/app-shell/stacked-layout.d.ts +1 -1
- package/dist/components/layout/app-shell/topbar-sidebar-layout.d.ts +1 -1
- package/dist/components/layout/containers/two-column-layout.d.ts +2 -0
- package/dist/components/layout/header/header.recipes.d.ts +6 -0
- package/dist/components/layout/header/header.types.d.ts +6 -6
- package/dist/components/layout/navigation/section-nav/section-nav.d.ts +5 -0
- package/dist/components/layout/page/index.d.ts +2 -1
- package/dist/components/layout/page/page.d.ts +1 -0
- package/dist/components/layout/page/page.strings.d.ts +11 -0
- package/dist/components/layout/page/page.types.d.ts +69 -17
- package/dist/components/layout/page/partials/page-header.d.ts +1 -1
- package/dist/components/layout/settings/settings.d.ts +9 -2
- package/dist/components/layout/sidebar/app-sidebar.d.ts +1 -1
- package/dist/components/layout/sidebar/components/sidebar-grouped-navigation.d.ts +1 -1
- package/dist/components/layout/sidebar/components/sidebar-navigation.d.ts +1 -1
- package/dist/components/layout/sidebar/index.d.ts +2 -1
- package/dist/components/layout/sidebar/sidebar-navigation-rail.d.ts +36 -0
- package/dist/components/layout/sidebar/sidebar.context.d.ts +5 -7
- package/dist/components/layout/sidebar/sidebar.types.d.ts +48 -10
- package/dist/components/layout/sidebar/sidebar.utils.d.ts +9 -1
- package/dist/components/layout/workspace/workspace.types.d.ts +8 -1
- package/dist/components/typography/text.styles.d.ts +26 -1
- package/dist/components/ui/alert-dialog.d.ts +2 -2
- package/dist/components/ui/combobox.d.ts +1 -1
- package/dist/components/ui/dialog.d.ts +2 -2
- package/dist/components/ui/overlay-layer.d.ts +18 -0
- package/dist/components/ui/sheet.d.ts +5 -1
- package/dist/components/ui/sidebar-state.d.ts +82 -0
- package/dist/components/ui/sidebar.d.ts +5 -17
- package/dist/composition.recipes-COdiFhxB.js +19 -0
- package/dist/composition.recipes-COdiFhxB.js.map +1 -0
- package/dist/containers-CIxwbZt5.js +112 -0
- package/dist/containers-CIxwbZt5.js.map +1 -0
- package/dist/{control-group-recipes-DBXmfh2E.js → control-group-recipes-fMuFo0H7.js} +6 -6
- package/dist/control-group-recipes-fMuFo0H7.js.map +1 -0
- package/dist/{copyable-ClBuk_UK.js → copyable-DIznBqiT.js} +7 -7
- package/dist/{copyable-ClBuk_UK.js.map → copyable-DIznBqiT.js.map} +1 -1
- package/dist/{data-display-DT_khPl_.js → data-display-BdgCAw8T.js} +277 -285
- package/dist/data-display-BdgCAw8T.js.map +1 -0
- package/dist/{date-DCrsDTZc.js → date-Cq8ioE4o.js} +5 -5
- package/dist/{date-DCrsDTZc.js.map → date-Cq8ioE4o.js.map} +1 -1
- package/dist/{date-picker-B2K3ucWn.js → date-picker-RlIzKom_.js} +501 -480
- package/dist/date-picker-RlIzKom_.js.map +1 -0
- package/dist/date-pickers-DY-CpXS1.js +179 -0
- package/dist/date-pickers-DY-CpXS1.js.map +1 -0
- package/dist/{display-hAc1HjpI.js → display-KsZLw9Ov.js} +9 -9
- package/dist/{display-hAc1HjpI.js.map → display-KsZLw9Ov.js.map} +1 -1
- package/dist/dropdown-menu-CLs8Lihj.js +194 -0
- package/dist/dropdown-menu-CLs8Lihj.js.map +1 -0
- package/dist/features/activities.js +302 -253
- package/dist/features/activities.js.map +1 -1
- package/dist/features/ai-chat.js +15 -14
- package/dist/features/ai-chat.js.map +1 -1
- package/dist/features/appointment-calendar.js +222 -220
- package/dist/features/appointment-calendar.js.map +1 -1
- package/dist/features/async-preview.js +11 -10
- package/dist/features/async-preview.js.map +1 -1
- package/dist/features/combobox.js +1 -1
- package/dist/features/comments.js +1 -1
- package/dist/features/data-view.js +13 -13
- package/dist/features/data-view.js.map +1 -1
- package/dist/features/email-composer.js +249 -249
- package/dist/features/email-composer.js.map +1 -1
- package/dist/features/event-calendar.js +264 -269
- package/dist/features/event-calendar.js.map +1 -1
- package/dist/features/filters.js +1 -1
- package/dist/features/global-search.js +167 -138
- package/dist/features/global-search.js.map +1 -1
- package/dist/features/kanban.js +6 -7
- package/dist/features/kanban.js.map +1 -1
- package/dist/features/map.js +269 -260
- package/dist/features/map.js.map +1 -1
- package/dist/features/media-library.js +827 -777
- package/dist/features/media-library.js.map +1 -1
- package/dist/features/mentions.js +1 -1
- package/dist/features/overlays.js +1 -1
- package/dist/features/products.js +1246 -1169
- package/dist/features/products.js.map +1 -1
- package/dist/features/questionnaire.js +13 -13
- package/dist/features/questionnaire.js.map +1 -1
- package/dist/features/resource-assignment.js +8 -8
- package/dist/features/resource.js +127 -123
- package/dist/features/resource.js.map +1 -1
- package/dist/features/rich-text-editor.js +2 -2
- package/dist/features/schema-form.js +254 -253
- package/dist/features/schema-form.js.map +1 -1
- package/dist/features/suggestions.js +3 -3
- package/dist/features/sync.js +3 -3
- package/dist/features/table.js +1 -1
- package/dist/features/theme-tweaker.js +95 -96
- package/dist/features/theme-tweaker.js.map +1 -1
- package/dist/{feedback-BYIhtitP.js → feedback-Dm4izqFn.js} +81 -80
- package/dist/feedback-Dm4izqFn.js.map +1 -0
- package/dist/{field-affordance-recipes-DZhnIL_Y.js → field-affordance-recipes-DWcNcOjh.js} +4 -4
- package/dist/field-affordance-recipes-DWcNcOjh.js.map +1 -0
- package/dist/{filters-DJVAveHA.js → filters-DzgSJpMK.js} +693 -645
- package/dist/filters-DzgSJpMK.js.map +1 -0
- package/dist/{form-field-CwH9y77i.js → form-field-BriWAXyg.js} +14 -8
- package/dist/form-field-BriWAXyg.js.map +1 -0
- package/dist/{form-sizing-BdP_Mf5p.js → form-sizing-Bs2qFUeE.js} +4 -4
- package/dist/form-sizing-Bs2qFUeE.js.map +1 -0
- package/dist/forms-C0RGnJTe.js +216 -0
- package/dist/forms-C0RGnJTe.js.map +1 -0
- package/dist/{forms-numeric-B_jraJaQ.js → forms-numeric-DIhghX1Q.js} +295 -291
- package/dist/forms-numeric-DIhghX1Q.js.map +1 -0
- package/dist/{header-BSfIEWbI.js → header-DMMxG__r.js} +67 -63
- package/dist/header-DMMxG__r.js.map +1 -0
- package/dist/header.recipes-BigdJjw1.js +6 -0
- package/dist/header.recipes-BigdJjw1.js.map +1 -0
- package/dist/hooks/useFormErrors.d.ts +1 -1
- package/dist/{hooks-ClH9thn4.js → hooks-DB6CJ4MR.js} +26 -14
- package/dist/hooks-DB6CJ4MR.js.map +1 -0
- package/dist/{icon-badge-DYKIwvOV.js → icon-badge-DZF-YjQp.js} +4 -4
- package/dist/{icon-badge-DYKIwvOV.js.map → icon-badge-DZF-YjQp.js.map} +1 -1
- package/dist/index.js +4 -5
- package/dist/input-CvyDQlY7.js +289 -0
- package/dist/input-CvyDQlY7.js.map +1 -0
- package/dist/input-DMBwAZmr.js +21 -0
- package/dist/input-DMBwAZmr.js.map +1 -0
- package/dist/item-DjCcM18E.js +277 -0
- package/dist/item-DjCcM18E.js.map +1 -0
- package/dist/layout/app-shell.js +1 -1
- package/dist/layout/auth.js +1 -1
- package/dist/layout/containers.js +1 -1
- package/dist/layout/header.js +1 -1
- package/dist/layout/hooks.js +1 -1
- package/dist/layout/navigation.js +1 -1
- package/dist/layout/page.js +2 -2
- package/dist/layout/settings.js +1 -1
- package/dist/layout/sidebar.js +3 -3
- package/dist/layout/workspace.js +1 -1
- package/dist/layout.js +11 -11
- package/dist/lib/affordance-geometry.generated.d.ts +41 -35
- package/dist/lib/control-group-recipes.d.ts +5 -5
- package/dist/lib/field-affordance-recipes.d.ts +2 -2
- package/dist/lib/motion-recipes.d.ts +3 -0
- package/dist/lib/navigation-row-recipes.d.ts +7 -7
- package/dist/lib/overlay-anatomy-recipes.d.ts +3 -3
- package/dist/lib/portal-recipes.d.ts +3 -0
- package/dist/lib/token-merge.generated.d.ts +13 -10
- package/dist/lib/ui-provider/types.d.ts +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/map-demo-tile.svg +1 -1
- package/dist/{media-gallery-3zIVLMWH.js → media-gallery-C-vChPmE.js} +6 -6
- package/dist/{media-gallery-3zIVLMWH.js.map → media-gallery-C-vChPmE.js.map} +1 -1
- package/dist/{mentions-CGlEJ15c.js → mentions-0_4nWuI-.js} +10 -10
- package/dist/{mentions-CGlEJ15c.js.map → mentions-0_4nWuI-.js.map} +1 -1
- package/dist/{message-DZ_ruyUV.js → message-g8p7eVtN.js} +7 -7
- package/dist/message-g8p7eVtN.js.map +1 -0
- package/dist/metadata-list-C3MkU-Om.js +443 -0
- package/dist/metadata-list-C3MkU-Om.js.map +1 -0
- package/dist/{motion-recipes-ChBg4HBq.js → motion-recipes-DitYv6P2.js} +10 -2
- package/dist/motion-recipes-DitYv6P2.js.map +1 -0
- package/dist/navigation-C90-oQFq.js +255 -0
- package/dist/navigation-C90-oQFq.js.map +1 -0
- package/dist/{navigation-BzhHI3lo.js → navigation-DaRjthVk.js} +101 -82
- package/dist/navigation-DaRjthVk.js.map +1 -0
- package/dist/{navigation-row-recipes-BFLCk_Aq.js → navigation-row-recipes-BGVLvU_O.js} +9 -9
- package/dist/navigation-row-recipes-BGVLvU_O.js.map +1 -0
- package/dist/{number-DbV1Dija.js → number-CRU3kGuk.js} +5 -5
- package/dist/{number-DbV1Dija.js.map → number-CRU3kGuk.js.map} +1 -1
- package/dist/overflow-tab-bar-IVFVQFV6.js +172 -0
- package/dist/overflow-tab-bar-IVFVQFV6.js.map +1 -0
- package/dist/overlays-BSgCtM2v.js +1013 -0
- package/dist/overlays-BSgCtM2v.js.map +1 -0
- package/dist/page-DUUKDAjo.js +331 -0
- package/dist/page-DUUKDAjo.js.map +1 -0
- package/dist/page-header-commands-7P3sfE9u.js +193 -0
- package/dist/page-header-commands-7P3sfE9u.js.map +1 -0
- package/dist/{pagination-BL25hu2s.js → pagination-CgCjElfu.js} +7 -7
- package/dist/{pagination-BL25hu2s.js.map → pagination-CgCjElfu.js.map} +1 -1
- package/dist/popover-B85RenIl.js +201 -0
- package/dist/popover-B85RenIl.js.map +1 -0
- package/dist/{popover-menu-Cn9rUkdc.js → popover-menu-DlnQ2zlR.js} +7 -7
- package/dist/{popover-menu-Cn9rUkdc.js.map → popover-menu-DlnQ2zlR.js.map} +1 -1
- package/dist/{popover.recipes-D3j8R8Yp.js → popover.recipes-DdiEp0rd.js} +18 -11
- package/dist/popover.recipes-DdiEp0rd.js.map +1 -0
- package/dist/portal-recipes-BpsV_iRw.js +9 -0
- package/dist/portal-recipes-BpsV_iRw.js.map +1 -0
- package/dist/{primitives-BFK08r9M.js → primitives-ByWgGUgt.js} +6 -6
- package/dist/{primitives-BFK08r9M.js.map → primitives-ByWgGUgt.js.map} +1 -1
- package/dist/primitives.js +4 -4
- package/dist/{progress-B1VnCT0K.js → progress-BJhQP9WX.js} +9 -9
- package/dist/{progress-B1VnCT0K.js.map → progress-BJhQP9WX.js.map} +1 -1
- package/dist/{receipt-BVSOH3Xo.js → receipt-tOc7B3hw.js} +7 -7
- package/dist/receipt-tOc7B3hw.js.map +1 -0
- package/dist/{rich-text-GOUyKQ-s.js → rich-text-Dth5E882.js} +4 -4
- package/dist/{rich-text-GOUyKQ-s.js.map → rich-text-Dth5E882.js.map} +1 -1
- package/dist/{rich-text-editor-cRLC-eBK.js → rich-text-editor-C1fOjBTd.js} +429 -430
- package/dist/rich-text-editor-C1fOjBTd.js.map +1 -0
- package/dist/{rich-text-editor-toolbar-DfXg0-VC.js → rich-text-editor-toolbar-laT3tpBT.js} +33 -29
- package/dist/rich-text-editor-toolbar-laT3tpBT.js.map +1 -0
- package/dist/{scroll-area-DcI-M1UT.js → scroll-area-B0dB2cBi.js} +2 -2
- package/dist/{scroll-area-DcI-M1UT.js.map → scroll-area-B0dB2cBi.js.map} +1 -1
- package/dist/{separator-Bom7NsGO.js → separator-Bb17I4pu.js} +2 -2
- package/dist/{separator-Bom7NsGO.js.map → separator-Bb17I4pu.js.map} +1 -1
- package/dist/{separator-BDV-Y648.js → separator-Ct_WSWTJ.js} +3 -3
- package/dist/{separator-BDV-Y648.js.map → separator-Ct_WSWTJ.js.map} +1 -1
- package/dist/services/actions.js +1 -1
- package/dist/settings-Bar5wiSo.js +167 -0
- package/dist/settings-Bar5wiSo.js.map +1 -0
- package/dist/sheet-BGPERY55.js +250 -0
- package/dist/sheet-BGPERY55.js.map +1 -0
- package/dist/sidebar-D-JYMMbY.js +686 -0
- package/dist/sidebar-D-JYMMbY.js.map +1 -0
- package/dist/sidebar-f9gRWXIR.js +1001 -0
- package/dist/sidebar-f9gRWXIR.js.map +1 -0
- package/dist/skeleton-BapcJd9C.js +265 -0
- package/dist/skeleton-BapcJd9C.js.map +1 -0
- package/dist/smart-card-CW0hjetE.js +617 -0
- package/dist/smart-card-CW0hjetE.js.map +1 -0
- package/dist/{structure-BmisBK-3.js → structure-DuxKl954.js} +3 -3
- package/dist/{structure-BmisBK-3.js.map → structure-DuxKl954.js.map} +1 -1
- package/dist/{structure.recipes-EPz60cU8.js → structure.recipes-BB4-n58V.js} +2 -2
- package/dist/{structure.recipes-EPz60cU8.js.map → structure.recipes-BB4-n58V.js.map} +1 -1
- package/dist/style.css +1 -1
- package/dist/{table-DsfzoUia.js → table-B4TE7iOV.js} +3 -3
- package/dist/{table-DsfzoUia.js.map → table-B4TE7iOV.js.map} +1 -1
- package/dist/{table-BweFy_P9.js → table-CFOWY9pQ.js} +394 -388
- package/dist/table-CFOWY9pQ.js.map +1 -0
- package/dist/{tabs-CDocW5D1.js → tabs-e7ko9S2o.js} +11 -11
- package/dist/tabs-e7ko9S2o.js.map +1 -0
- package/dist/{text-inputs-f9Ia-aCi.js → text-inputs-B1culiSK.js} +107 -104
- package/dist/text-inputs-B1culiSK.js.map +1 -0
- package/dist/{text.styles-g4He6UIW.js → text.styles-B64My8RZ.js} +25 -10
- package/dist/text.styles-B64My8RZ.js.map +1 -0
- package/dist/theme.css +192 -149
- package/dist/{timelines-CwM_9IhD.js → timelines-D3Sl9ueq.js} +13 -12
- package/dist/timelines-D3Sl9ueq.js.map +1 -0
- package/dist/tooltip-8wz5S_Zr.js +113 -0
- package/dist/tooltip-8wz5S_Zr.js.map +1 -0
- package/dist/{tree-WnKQzwbq.js → tree-CzUJHnFs.js} +9 -9
- package/dist/{tree-WnKQzwbq.js.map → tree-CzUJHnFs.js.map} +1 -1
- package/dist/typography/rich-text.js +1 -1
- package/dist/typography-BQnine1k.js +117 -0
- package/dist/typography-BQnine1k.js.map +1 -0
- package/dist/typography.js +1 -1
- package/dist/ui-provider-C-74NVLc.js +178 -0
- package/dist/ui-provider-C-74NVLc.js.map +1 -0
- package/dist/ui-provider.js +2 -3
- package/dist/{upload-CXyxmQBP.js → upload-BOW6U2tI.js} +25 -24
- package/dist/upload-BOW6U2tI.js.map +1 -0
- package/dist/{upload-queue-Boscubn9.js → upload-queue-qUXn1ykN.js} +16 -14
- package/dist/upload-queue-qUXn1ykN.js.map +1 -0
- package/dist/{usage-card-BhO5eqkX.js → usage-card-BeSLY0i0.js} +145 -137
- package/dist/usage-card-BeSLY0i0.js.map +1 -0
- package/dist/{utils-BRhFDwuU.js → utils-B6kKb8jB.js} +303 -144
- package/dist/utils-B6kKb8jB.js.map +1 -0
- package/dist/value-inputs-skdVB2zh.js +980 -0
- package/dist/value-inputs-skdVB2zh.js.map +1 -0
- package/dist/{value-typography-BP8OG6h5.js → value-typography-uAmWUAL1.js} +2 -2
- package/dist/{value-typography-BP8OG6h5.js.map → value-typography-uAmWUAL1.js.map} +1 -1
- package/dist/workspace-DHeHv0qw.js +411 -0
- package/dist/workspace-DHeHv0qw.js.map +1 -0
- package/docs/consumer-skill/SKILL.md +15 -129
- package/docs/consumer-skill/agents/themelia-ui-designer.md +96 -0
- package/docs/consumer-skill/examples/app-layout.tsx +74 -13
- package/docs/consumer-skill/examples/authentication.tsx +77 -0
- package/docs/consumer-skill/examples/commerce-lines.tsx +271 -0
- package/docs/consumer-skill/examples/custom-composition.tsx +21 -0
- package/docs/consumer-skill/examples/detail.tsx +5 -4
- package/docs/consumer-skill/examples/edit.tsx +30 -38
- package/docs/consumer-skill/examples/editable-sections.tsx +38 -0
- package/docs/consumer-skill/examples/index-table.tsx +4 -4
- package/docs/consumer-skill/examples/manifest.json +88 -1
- package/docs/consumer-skill/examples/product-media.tsx +41 -0
- package/docs/consumer-skill/examples/product-parts.tsx +81 -0
- package/docs/consumer-skill/examples/rhf-bindings.tsx +86 -0
- package/docs/consumer-skill/examples/rhf-edit-page.tsx +141 -0
- package/docs/consumer-skill/examples/rhf-overlay-form.tsx +105 -0
- package/docs/consumer-skill/examples/rhf-transport.tsx +28 -0
- package/docs/consumer-skill/examples/token-domain-structure.tsx +68 -0
- package/docs/consumer-skill/references/agents-md.md +23 -11
- package/docs/consumer-skill/references/analytics.md +18 -1
- package/docs/consumer-skill/references/authentication.md +42 -0
- package/docs/consumer-skill/references/commerce-composition.md +97 -0
- package/docs/consumer-skill/references/component-contracts.json +325201 -0
- package/docs/consumer-skill/references/composition-mapping.md +106 -0
- package/docs/consumer-skill/references/composition.md +198 -46
- package/docs/consumer-skill/references/critique-rubric.md +98 -0
- package/docs/consumer-skill/references/custom-composition.md +261 -0
- package/docs/consumer-skill/references/data-reading.md +79 -0
- package/docs/consumer-skill/references/design-contract.md +43 -9
- package/docs/consumer-skill/references/discovery.md +109 -8
- package/docs/consumer-skill/references/domain-structures.md +124 -0
- package/docs/consumer-skill/references/installation.md +51 -36
- package/docs/consumer-skill/references/integration.md +41 -2
- package/docs/consumer-skill/references/product-composition.md +94 -0
- package/docs/consumer-skill/references/public-api.json +4390 -475
- package/docs/consumer-skill/references/review.md +47 -5
- package/docs/consumer-skill/references/rhf-workflows.md +93 -0
- package/docs/consumer-skill/references/screen-archetypes.md +34 -0
- package/docs/consumer-skill/references/screen-decisions.md +126 -0
- package/docs/consumer-skill/references/theming.md +25 -27
- package/docs/consumer-skill/references/tokens.json +20 -11
- package/docs/consumer-skill/references/view-craft.md +153 -0
- package/docs/consumer-skill/references/view-spec.md +73 -0
- package/docs/consumer-skill/references/workflows.md +9 -2
- package/docs/consumer-skill/scripts/composition-policy.mjs +39 -3
- package/docs/consumer-skill/scripts/composition-schema.d.mts +2 -0
- package/docs/consumer-skill/scripts/composition-schema.mjs +32 -0
- package/docs/consumer-skill/scripts/composition.mjs +254 -0
- package/docs/consumer-skill/scripts/discovery.mjs +96 -10
- package/docs/consumer-skill/scripts/inspect-component.mjs +11 -0
- package/docs/consumer-skill/scripts/inspect-tokens.mjs +11 -0
- package/docs/consumer-skill/scripts/inspection.mjs +193 -0
- package/docs/consumer-skill/scripts/map-composition.mjs +12 -0
- package/docs/consumer-skill/scripts/setup-skills.mjs +111 -0
- package/docs/consumer-skill/scripts/surface-policy.mjs +5 -5
- package/docs/consumer-skills/themelia-components/SKILL.md +31 -0
- package/docs/consumer-skills/themelia-composition/SKILL.md +34 -0
- package/docs/consumer-skills/themelia-design/SKILL.md +55 -0
- package/docs/consumer-skills/themelia-forms/SKILL.md +12 -0
- package/docs/consumer-skills/themelia-foundation/SKILL.md +15 -0
- package/docs/consumer-skills/themelia-tokenization/SKILL.md +42 -0
- package/package.json +4 -2
- package/templates/README.md +39 -0
- package/templates/admin-shell-template.tsx +382 -0
- package/templates/analytics-operations-template.tsx +376 -0
- package/templates/customers-template.tsx +509 -0
- package/templates/index.ts +29 -0
- package/templates/orders-template.tsx +1102 -0
- package/templates/products-template.tsx +834 -0
- package/templates/user-permissions-template.tsx +450 -0
- package/dist/accordion-Cjb6sx0G.js.map +0 -1
- package/dist/action-menu-CllU52Mm.js +0 -280
- package/dist/action-menu-CllU52Mm.js.map +0 -1
- package/dist/affordance-geometry.generated-tF36bREk.js.map +0 -1
- package/dist/ai-artifact-DvTwDVyL.js.map +0 -1
- package/dist/app-shell-C4FhvCqF.js +0 -236
- package/dist/app-shell-C4FhvCqF.js.map +0 -1
- package/dist/auth-BGua8ouh.js.map +0 -1
- package/dist/avatar-DAPlDvhJ.js.map +0 -1
- package/dist/base/cascader.js.map +0 -1
- package/dist/batch-action-bar-DnUJ21NQ.js.map +0 -1
- package/dist/button-DVzspB_G.js.map +0 -1
- package/dist/buttons-DPZekJFu.js.map +0 -1
- package/dist/cards-BaBZR-AU.js +0 -68
- package/dist/cards-BaBZR-AU.js.map +0 -1
- package/dist/chart-ZOYyK2xG.js +0 -155
- package/dist/chart-ZOYyK2xG.js.map +0 -1
- package/dist/checkbox-AWIhNhmo.js.map +0 -1
- package/dist/choice-inputs-CNHvARCJ.js +0 -770
- package/dist/choice-inputs-CNHvARCJ.js.map +0 -1
- package/dist/code-block-DeneBJR_.js.map +0 -1
- package/dist/combobox-DaHESuiL.js +0 -355
- package/dist/combobox-DaHESuiL.js.map +0 -1
- package/dist/combobox-Dxo2fAYQ.js.map +0 -1
- package/dist/command-C25VMRII.js.map +0 -1
- package/dist/comments-DD0DUPwJ.js.map +0 -1
- package/dist/containers-Mu1LMGV1.js +0 -103
- package/dist/containers-Mu1LMGV1.js.map +0 -1
- package/dist/control-group-recipes-DBXmfh2E.js.map +0 -1
- package/dist/data-display-DT_khPl_.js.map +0 -1
- package/dist/date-picker-B2K3ucWn.js.map +0 -1
- package/dist/date-pickers-Ds8gLaoP.js +0 -175
- package/dist/date-pickers-Ds8gLaoP.js.map +0 -1
- package/dist/dropdown-menu-Cl4X7L5S.js +0 -193
- package/dist/dropdown-menu-Cl4X7L5S.js.map +0 -1
- package/dist/feedback-BYIhtitP.js.map +0 -1
- package/dist/field-affordance-recipes-DZhnIL_Y.js.map +0 -1
- package/dist/filters-DJVAveHA.js.map +0 -1
- package/dist/form-field-CwH9y77i.js.map +0 -1
- package/dist/form-sizing-BdP_Mf5p.js.map +0 -1
- package/dist/forms-B9G_xwzi.js +0 -194
- package/dist/forms-B9G_xwzi.js.map +0 -1
- package/dist/forms-numeric-B_jraJaQ.js.map +0 -1
- package/dist/header-BSfIEWbI.js.map +0 -1
- package/dist/hooks-ClH9thn4.js.map +0 -1
- package/dist/input-CZw8iU99.js +0 -21
- package/dist/input-CZw8iU99.js.map +0 -1
- package/dist/input-DQdEd0YD.js +0 -263
- package/dist/input-DQdEd0YD.js.map +0 -1
- package/dist/item-K5_ghvze.js +0 -275
- package/dist/item-K5_ghvze.js.map +0 -1
- package/dist/message-DZ_ruyUV.js.map +0 -1
- package/dist/metadata-list-8N16ZMW_.js +0 -405
- package/dist/metadata-list-8N16ZMW_.js.map +0 -1
- package/dist/motion-recipes-ChBg4HBq.js.map +0 -1
- package/dist/navigation-Bnotn4AQ.js +0 -145
- package/dist/navigation-Bnotn4AQ.js.map +0 -1
- package/dist/navigation-BzhHI3lo.js.map +0 -1
- package/dist/navigation-row-recipes-BFLCk_Aq.js.map +0 -1
- package/dist/overflow-tab-bar-CWY7Nogn.js +0 -282
- package/dist/overflow-tab-bar-CWY7Nogn.js.map +0 -1
- package/dist/overlays-tMkF-VAN.js +0 -1003
- package/dist/overlays-tMkF-VAN.js.map +0 -1
- package/dist/page-CL9YeH_V.js +0 -224
- package/dist/page-CL9YeH_V.js.map +0 -1
- package/dist/page-header-commands-DOb6WsfD.js +0 -126
- package/dist/page-header-commands-DOb6WsfD.js.map +0 -1
- package/dist/popover-gnTOhbFM.js +0 -198
- package/dist/popover-gnTOhbFM.js.map +0 -1
- package/dist/popover.recipes-D3j8R8Yp.js.map +0 -1
- package/dist/receipt-BVSOH3Xo.js.map +0 -1
- package/dist/rich-text-editor-cRLC-eBK.js.map +0 -1
- package/dist/rich-text-editor-toolbar-DfXg0-VC.js.map +0 -1
- package/dist/settings-ybnjVwbd.js +0 -171
- package/dist/settings-ybnjVwbd.js.map +0 -1
- package/dist/sheet-ijlsjq-n.js +0 -213
- package/dist/sheet-ijlsjq-n.js.map +0 -1
- package/dist/sidebar-Db6gkh3U.js +0 -619
- package/dist/sidebar-Db6gkh3U.js.map +0 -1
- package/dist/sidebar-DkTO4VTO.js +0 -512
- package/dist/sidebar-DkTO4VTO.js.map +0 -1
- package/dist/skeleton-Byjnt7qr.js +0 -264
- package/dist/skeleton-Byjnt7qr.js.map +0 -1
- package/dist/smart-card-DiC5aac3.js +0 -604
- package/dist/smart-card-DiC5aac3.js.map +0 -1
- package/dist/table-BweFy_P9.js.map +0 -1
- package/dist/tabs-CDocW5D1.js.map +0 -1
- package/dist/text-inputs-f9Ia-aCi.js.map +0 -1
- package/dist/text.styles-g4He6UIW.js.map +0 -1
- package/dist/theme-scope-BJ6eE2xt.js +0 -50
- package/dist/theme-scope-BJ6eE2xt.js.map +0 -1
- package/dist/timelines-CwM_9IhD.js.map +0 -1
- package/dist/tooltip-yiRJUFjp.js +0 -111
- package/dist/tooltip-yiRJUFjp.js.map +0 -1
- package/dist/typography-UTnveOEy.js +0 -117
- package/dist/typography-UTnveOEy.js.map +0 -1
- package/dist/ui-provider-C_U0Xma4.js +0 -136
- package/dist/ui-provider-C_U0Xma4.js.map +0 -1
- package/dist/upload-CXyxmQBP.js.map +0 -1
- package/dist/upload-queue-Boscubn9.js.map +0 -1
- package/dist/usage-card-BhO5eqkX.js.map +0 -1
- package/dist/use-mobile-vaLKwgyf.js +0 -15
- package/dist/use-mobile-vaLKwgyf.js.map +0 -1
- package/dist/utils-BRhFDwuU.js.map +0 -1
- package/dist/value-inputs-TaX4OjNk.js +0 -963
- package/dist/value-inputs-TaX4OjNk.js.map +0 -1
- package/dist/workspace-B-OEm3Kf.js +0 -408
- package/dist/workspace-B-OEm3Kf.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repeaters.js","names":["useDensityConfig","cn","affordanceGeometry","Button","Text","Stack","interactionRecipes","Input","FormField","defaultRepeaterStrings","defaultRepeaterPrimitiveStrings","Row","sortableState","useSortable","item","disabled","sortable","isDragging","style","CSS","ref","dragAttributes","dragListeners","dragHandle","actionSize","strings","GripVertical","removeButton","hideRemove","removeVariant","onRemove","index","Trash2","X","rowVariant","renderRow","Repeater","stringsProp","useStrings","defaultScale","sensors","useSensors","useSensor","PointerSensor","KeyboardSensor","sortableKeyboardCoordinates","handleDragEnd","useCallback","event","over","active","fromIndex","items","toIndex","onMove","itemIds","useMemo","list","className","DndContext","closestCenter","SortableContext","verticalListSortingStrategy","hideAdd","onAdd","Plus","moveStringRepeaterItem","next","moved","stringArraysEqual","left","right","value","reconcileStringRepeaterIds","idsByValue","nextId","initialNextId","previousValues","existing","id","previousIds","nextValues","prefix","createStringRepeaterRowState","ids","values","stringRepeaterRowReducer","action","state","reconciled","useStringRepeaterRows","storedState","dispatch","useReducer","name","needsSync","syncAction","defaultStringRepeaterStrings","StringRepeater","useFormContext","useController","field","resolvedInvalid","invalid","fieldState","instanceId","useId","rowState","dispatchRows","commitValue","nextIds","updateValue","nextValue","addValue","removeValue","valueIndex","moveValue","context","renderField","defaultObjectRepeaterStrings","ObjectRepeater","fieldDefs","useFieldArray","createEmptyObject","acc","move","from","to","fields","append","remove","fieldPath","fieldDef","inputProps","register","Textarea","defaultKeyValueEditorStrings","generateId","KeyValueEditorRow","memo","keyValue","row","keyLabel","Label","keyPlaceholder","onKeyChange","valueLabel","valuePlaceholder","onValueChange","KeyValueEditor","forwardRef","isInternalChange","useRef","rows","setRows","useState","k","v","emit","obj","key","handleKeyChange","prev","newKey","handleValueChange","newValue","addRow","removeRow","i","result","moveRow","showHeader","gutter","gutterClasses","leftGutter","rightGutter","sortingProps","LocalizedStringField","fieldName","activeLocale","primaryLocale","secondaryLocale","type","LocalizedObjectField","localeKey","defaultLocalizedStringRepeaterStrings","LocalizedStringRepeater"],"sources":["../../src/components/base/repeaters/repeaters.strings.ts","../../src/components/base/repeaters/repeater.tsx","../../src/components/base/repeaters/string-repeater.utils.ts","../../src/components/base/repeaters/string-repeater.tsx","../../src/components/base/repeaters/object-repeater.tsx","../../src/components/base/repeaters/key-value-editor.tsx","../../src/components/base/repeaters/localized-string-field.tsx","../../src/components/base/repeaters/localized-object-field.tsx","../../src/components/base/repeaters/localized-string-repeater.tsx"],"sourcesContent":["/**\n * Shared default strings for repeater-style form fields\n * (`<StringRepeater>`, `<ObjectRepeater>`,\n * `<LocalizedStringRepeater>`, …).\n *\n * Each repeater has its own concrete `Strings` interface — the shared\n * defaults below cover the keys they all share. Per-field strings files\n * spread these defaults into their own constant so consumers can override\n * any subset uniformly.\n */\n\nexport interface RepeaterSharedStrings {\n\temptyState: string;\n\taddItem: string;\n\tremoveAriaLabel: string;\n}\n\nexport const defaultRepeaterStrings: RepeaterSharedStrings = {\n\temptyState: 'No items added yet.',\n\taddItem: 'Add item',\n\tremoveAriaLabel: 'Remove item',\n};\n","/**\n * Repeater — shared chrome for any list-style form field. Renders a list of\n * rows with optional drag handle and a per-row remove icon, plus an empty\n * state and a trailing \"+ add\" button. The row body is consumer-rendered via\n * `children` (or `renderRow`), so this primitive is the visual contract that\n * `StringRepeater`, `ObjectRepeater`, `LocalizedStringRepeater`, and\n * `KeyValueEditor` all share — without locking down what each row is editing.\n *\n * Sortable is opt-in (`sortable`); when enabled the rows are wired up\n * through `@dnd-kit/sortable` and the consumer can render the supplied\n * `dragHandleProps` on whichever element is the visual handle.\n *\n * The `<Repeater>` is intentionally headless on the value side — it does not\n * own the items array. Consumers (RHF callers via `useFieldArray`, manual\n * controlled state, etc.) pass `items`, `onAdd`, `onRemove`, and\n * (optionally) `onMove` callbacks. This keeps the primitive framework- and\n * state-shape-agnostic.\n */\nimport {\n\t\tDndContext,\n\t\tKeyboardSensor,\n\t\tPointerSensor,\n\t\tclosestCenter,\n\t\tuseSensor,\n\t\tuseSensors,\n\t\ttype DragEndEvent,\n} from '@dnd-kit/core';\nimport {\n\t\tSortableContext,\n\t\tsortableKeyboardCoordinates,\n\t\tuseSortable,\n\t\tverticalListSortingStrategy,\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { GripVertical, Plus, Trash2, X } from 'lucide-react';\nimport {\n\t\ttype CSSProperties,\n\t\ttype ReactNode,\n\t\tuseCallback,\n\t\tuseMemo,\n} from 'react';\n\nimport { Button, type ButtonSize } from '../buttons';\nimport { Stack } from '../structure';\nimport { Text } from '../../typography/text';\nimport { useDensityConfig } from '../../../lib/ui-provider';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nimport { defaultRepeaterStrings } from './repeaters.strings';\nimport { interactionRecipes } from '../../../lib/interaction-recipes';\n\nexport interface RepeaterStrings {\n\t\t/** Empty state copy — shown when `items` is empty. */\n\t\temptyState: string;\n\t\t/** Label of the trailing \"+\" button. */\n\t\taddButton: string;\n\t\t/** Per-row remove button aria-label. */\n\t\tremoveAriaLabel: string;\n\t\t/** Drag-handle aria-label (only relevant when `sortable`). */\n\t\tdragHandleAriaLabel: string;\n}\n\nexport const defaultRepeaterPrimitiveStrings: RepeaterStrings = {\n\t\temptyState: defaultRepeaterStrings.emptyState,\n\t\taddButton: defaultRepeaterStrings.addItem,\n\t\tremoveAriaLabel: defaultRepeaterStrings.removeAriaLabel,\n\t\tdragHandleAriaLabel: 'Drag to reorder',\n};\n\n/**\n * Visual density of a row. `inline` is the canonical compact admin row\n * (single input + remove icon). `card` wraps richer content in a\n * bordered surface — used by `ObjectRepeater` and any consumer with\n * multi-field rows that need their own delete affordance.\n */\nexport type RepeaterRowVariant = 'inline' | 'card';\n\nexport type RepeaterRemoveVariant = 'ghost' | 'icon-button';\n\nexport interface RepeaterItem {\n\t\t/** Stable id (RHF `field.id`, generated UUID, etc.) — used as React key\n\t\t * and as the drag handle id when sortable. */\n\t\tid: string;\n}\n\nexport interface RepeaterRowRenderContext {\n\t\t/** Index of the row in the items array. */\n\t\tindex: number;\n\t\t/** True while the row is being actively dragged. */\n\t\tisDragging: boolean;\n}\n\ninterface RepeaterBaseProps<T extends RepeaterItem> {\n\t\t/** Entries to render, in order. */\n\t\titems: ReadonlyArray<T>;\n\t\t/** Render the body of a single row. */\n\t\trenderRow: (item: T, ctx: RepeaterRowRenderContext) => ReactNode;\n\t\t/** Called when the consumer presses the \"+ add\" button. */\n\t\tonAdd: () => void;\n\t\t/** Called when the consumer presses a per-row remove button. */\n\t\tonRemove: (index: number) => void;\n\t\t/** Visual style of each row's outer chrome. Default `'inline'`. */\n\t\trowVariant?: RepeaterRowVariant;\n\t\t/** Remove button style. Default `'ghost'` (subtle X icon, hover →\n\t\t * destructive tint). `'icon-button'` mirrors `<Button icon={Trash2}>`\n\t\t * — used by card rows that need a more prominent affordance. */\n\t\tremoveVariant?: RepeaterRemoveVariant;\n\t\t/** Hide the per-row remove button. Default `false`. Useful when the\n\t\t * consumer renders its own remove inside the row body. */\n\t\thideRemove?: boolean;\n\t\t/** Disable add + remove + drag affordances. */\n\t\tdisabled?: boolean;\n\t\t/** Hide the trailing \"+ add\" button. Useful when the consumer composes\n\t\t * it elsewhere or has a maxItems cap. */\n\t\thideAdd?: boolean;\n\t\t/** Override default strings. */\n\t\tstrings?: StringsProp<RepeaterStrings>;\n\t\t/** Class applied to the outer wrapper. */\n\t\tclassName?: string;\n}\n\ntype RepeaterSortingProps =\n\t\t| {\n\t\t\t\t\t/** Enable drag-to-reorder. */\n\t\t\t\t\tsortable: true;\n\t\t\t\t\t/** Called when a row is dragged to a new position. */\n\t\t\t\t\tonMove: (fromIndex: number, toIndex: number) => void;\n\t\t\t}\n\t\t| {\n\t\t\t\t\t/** Disable drag-to-reorder. Default `false`. */\n\t\t\t\t\tsortable?: false;\n\t\t\t\t\t/** Optional callback retained for shared prop builders; ignored while sorting is disabled. */\n\t\t\t\t\tonMove?: (fromIndex: number, toIndex: number) => void;\n\t\t\t};\n\n/**\n * Extensible consumer shape for callers that derive their own repeater\n * props. The component itself accepts `RepeaterComponentProps`, whose\n * discriminated sorting contract requires `onMove` when `sortable` is true.\n */\nexport interface RepeaterProps<T extends RepeaterItem> extends RepeaterBaseProps<T> {\n\t\tsortable?: boolean;\n\t\tonMove?: (fromIndex: number, toIndex: number) => void;\n}\n\nexport type RepeaterComponentProps<T extends RepeaterItem> =\n\t\tOmit<RepeaterProps<T>, 'sortable' | 'onMove'> & RepeaterSortingProps;\n\ninterface RowProps<T extends RepeaterItem> {\n\t\titem: T;\n\t\tindex: number;\n\t\tsortable: boolean;\n\t\trowVariant: RepeaterRowVariant;\n\t\tremoveVariant: RepeaterRemoveVariant;\n\t\thideRemove: boolean;\n\t\t/** Disables the control. */\n\t\tdisabled: boolean;\n\t\t/** Overrides this surface's own copy. */\n\t\tstrings: RepeaterStrings;\n\t\tactionSize: ButtonSize;\n\t\tonRemove: (index: number) => void;\n\t\trenderRow: RepeaterProps<T>['renderRow'];\n}\n\nfunction Row<T extends RepeaterItem>({\n\t\titem,\n\t\tindex,\n\t\tsortable,\n\t\trowVariant,\n\t\tremoveVariant,\n\t\thideRemove,\n\t\tdisabled,\n\t\tstrings,\n\t\tactionSize,\n\t\tonRemove,\n\t\trenderRow,\n}: RowProps<T>) {\n\t\tconst sortableState = useSortable({ id: item.id, disabled: disabled || !sortable });\n\t\tconst isDragging = sortable ? sortableState.isDragging : false;\n\n\t\tconst style: CSSProperties | undefined = sortable\n\t\t\t\t? {\n\t\t\t\t\t\t\ttransform: CSS.Transform.toString(sortableState.transform),\n\t\t\t\t\t\t\ttransition: sortableState.transition,\n\t\t\t\t\t\t\topacity: isDragging ? 0.6 : 1,\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\n\t\tconst ref = sortable ? sortableState.setNodeRef : undefined;\n\t\tconst dragAttributes = sortable ? sortableState.attributes : {};\n\t\tconst dragListeners = sortable ? sortableState.listeners : undefined;\n\n\t\tconst dragHandle = sortable ? (\n\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\tsize={actionSize}\n\t\t\t\t\t\ticonOnly\n\t\t\t\t\t\taria-label={strings.dragHandleAriaLabel}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'repeater--drag-handle',\n\t\t\t\t'shrink-0',\n\t\t\t\t\t\t\t\t`text-muted-foreground ${interactionRecipes.rowHover}`,\n\t\t\t\t\t\t\t\t'cursor-grab active:cursor-grabbing',\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{...dragAttributes}\n\t\t\t\t\t\t{...dragListeners}\n\t\t\t\t>\n\t\t\t\t\t\t<GripVertical className=\"size-icon\" aria-hidden=\"true\" />\n\t\t\t\t</Button>\n\t\t) : null;\n\n\t\tconst removeButton = hideRemove ? null : removeVariant === 'icon-button' ? (\n\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"outline\"\n\t\t\t\t\t\tsize={actionSize}\n\t\t\t\t\t\ticonOnly\n\t\t\t\t\t\taria-label={strings.removeAriaLabel}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tonClick={() => onRemove(index)}\n\t\t\t\t\t\tclassName=\"repeater--remove shrink-0\"\n\t\t\t\t>\n\t\t\t\t\t\t<Trash2 className=\"size-icon\" aria-hidden=\"true\" />\n\t\t\t\t</Button>\n\t\t) : (\n\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\tsize={actionSize}\n\t\t\t\t\t\ticonOnly\n\t\t\t\t\t\taria-label={strings.removeAriaLabel}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tonClick={() => onRemove(index)}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'repeater--remove',\n\t\t\t\t'shrink-0',\n\t\t\t\t\t\t\t\t'text-muted-foreground hover:text-destructive',\n\t\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t\t<X className=\"size-icon\" aria-hidden=\"true\" />\n\t\t\t\t</Button>\n\t\t);\n\n\t\tif (rowVariant === 'card') {\n\t\t\t\treturn (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\t\t\tstyle={style}\n\t\t\t\t\t\t\t\tdata-repeater-item-id={item.id}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t'repeater--item',\n\t\t\t\t\t\t\t\t\t\t'relative rounded-radius border border-border bg-card text-card-foreground p-surface',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div className=\"flex items-start gap-space-md\">\n\t\t\t\t\t\t\t\t\t\t{dragHandle}\n\t\t\t\t\t\t\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t{renderRow(item, { index, isDragging })}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{removeButton}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t\t<div\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\tstyle={style}\n\t\t\t\t\t\tdata-repeater-item-id={item.id}\n\t\t\t\t\t\tclassName=\"repeater--item flex items-start gap-space-md\"\n\t\t\t\t>\n\t\t\t\t\t\t{dragHandle}\n\t\t\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t{renderRow(item, { index, isDragging })}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{removeButton}\n\t\t\t\t</div>\n\t\t);\n}\n\n/** Framework-neutral controlled list chrome with optional sortable rows. */\nexport function Repeater<T extends RepeaterItem>({\n\t\titems,\n\t\trenderRow,\n\t\tonAdd,\n\t\tonRemove,\n\t\tonMove,\n\t\tsortable = false,\n\t\trowVariant = 'inline',\n\t\tremoveVariant = 'ghost',\n\t\thideRemove = false,\n\t\thideAdd = false,\n\t\tdisabled = false,\n\t\tstrings: stringsProp,\n\t\tclassName,\n}: RepeaterComponentProps<T>) {\n\t\tconst strings = useStrings(defaultRepeaterPrimitiveStrings, stringsProp);\n\t\tconst { defaultScale } = useDensityConfig();\n\t\tconst actionSize: ButtonSize = defaultScale ?? 'md';\n\n\t\tconst sensors = useSensors(\n\t\t\t\tuseSensor(PointerSensor, { activationConstraint: { distance: 4 } }),\n\t\t\t\tuseSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),\n\t\t);\n\n\t\tconst handleDragEnd = useCallback(\n\t\t\t\t(event: DragEndEvent) => {\n\t\t\t\t\t\tconst { active, over } = event;\n\t\t\t\t\t\tif (!over || active.id === over.id) return;\n\t\t\t\t\t\tconst fromIndex = items.findIndex((item) => item.id === active.id);\n\t\t\t\t\t\tconst toIndex = items.findIndex((item) => item.id === over.id);\n\t\t\t\t\t\tif (fromIndex < 0 || toIndex < 0) return;\n\t\t\t\t\t\tonMove?.(fromIndex, toIndex);\n\t\t\t\t},\n\t\t\t\t[items, onMove],\n\t\t);\n\n\t\tconst itemIds = useMemo(() => items.map((item) => item.id), [items]);\n\n\t\tconst list = (\n\t\t<Stack gap=\"md\" className=\"repeater--list\">\n\t\t\t\t\t\t{items.map((item, index) => (\n\t\t\t\t\t\t\t\t<Row<T>\n\t\t\t\t\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t\t\t\t\titem={item}\n\t\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\t\tsortable={sortable}\n\t\t\t\t\t\t\t\t\t\trowVariant={rowVariant}\n\t\t\t\t\t\t\t\t\t\tremoveVariant={removeVariant}\n\t\t\t\t\t\t\t\t\t\thideRemove={hideRemove}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\tstrings={strings}\n\t\t\t\t\t\t\t\t\t\tactionSize={actionSize}\n\t\t\t\t\t\t\t\t\t\tonRemove={onRemove}\n\t\t\t\t\t\t\t\t\t\trenderRow={renderRow}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t</Stack>\n\t\t);\n\n\t\treturn (\n\t\t<Stack gap=\"lg\" className={cn('repeater--component', className)}>\n\t\t\t\t\t\t{items.length === 0 ? (\n\t\t\t\t<div className=\"repeater--empty rounded-radius border border-dashed border-border p-surface\">\n\t\t\t\t\t<Text type=\"secondary\">{strings.emptyState}</Text>\n\t\t\t\t</div>\n\t\t\t\t\t\t) : sortable ? (\n\t\t\t\t\t\t\t\t<DndContext\n\t\t\t\t\t\t\t\t\t\tsensors={sensors}\n\t\t\t\t\t\t\t\t\t\tcollisionDetection={closestCenter}\n\t\t\t\t\t\t\t\t\t\tonDragEnd={handleDragEnd}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<SortableContext items={itemIds} strategy={verticalListSortingStrategy}>\n\t\t\t\t\t\t\t\t\t\t\t\t{list}\n\t\t\t\t\t\t\t\t\t\t</SortableContext>\n\t\t\t\t\t\t\t\t</DndContext>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tlist\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{!hideAdd && (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\t\t\t\tbuttonStyle=\"outline\"\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\tonClick={onAdd}\n\t\t\t\t\t\t\t\t\t\tclassName=\"repeater--add self-start\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Plus className=\"size-icon\" />\n\t\t\t\t\t\t\t\t\t\t{strings.addButton}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t</Stack>\n\t\t);\n}\n\nRepeater.displayName = 'Repeater';\n","/** Reorders a scalar-array value without changing its item shape. */\nexport function moveStringRepeaterItem<T>(\n\titems: ReadonlyArray<T>,\n\tfromIndex: number,\n\ttoIndex: number,\n): T[] {\n\tconst next = [...items];\n\tconst [moved] = next.splice(fromIndex, 1);\n\tif (moved === undefined) return [...items];\n\tnext.splice(toIndex, 0, moved);\n\treturn next;\n}\n","/**\n * StringRepeater — React Hook Form adapter for a controlled `string[]`.\n *\n * React Hook Form's `useFieldArray` only supports arrays of objects. This\n * adapter therefore controls the whole scalar array with `useController` and\n * gives each visual row a stable opaque id for React and drag-and-drop. The\n * `renderField` seam lets textarea and localized variants reuse the same state\n * engine without duplicating flat-array behavior.\n */\nimport {\n\ttype ReactNode,\n\ttype RefCallback,\n\tuseId,\n\tuseReducer,\n} from 'react';\nimport { useController, useFormContext } from 'react-hook-form';\n\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nimport { Input } from '../text-inputs';\nimport { Repeater } from './repeater';\nimport { defaultRepeaterStrings } from './repeaters.strings';\nimport { moveStringRepeaterItem } from './string-repeater.utils';\n\nfunction stringArraysEqual(left: ReadonlyArray<string>, right: ReadonlyArray<string>): boolean {\n\treturn left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nfunction reconcileStringRepeaterIds(\n\tpreviousValues: ReadonlyArray<string>,\n\tpreviousIds: ReadonlyArray<string>,\n\tnextValues: ReadonlyArray<string>,\n\tprefix: string,\n\tinitialNextId: number,\n): { ids: string[]; nextId: number } {\n\tconst idsByValue = new Map<string, string[]>();\n\tlet nextId = initialNextId;\n\n\tpreviousValues.forEach((value, index) => {\n\t\tconst existing = idsByValue.get(value) ?? [];\n\t\tconst id = previousIds[index];\n\t\tif (id) existing.push(id);\n\t\tidsByValue.set(value, existing);\n\t});\n\n\treturn {\n\t\tids: nextValues.map((value) => idsByValue.get(value)?.shift() ?? `${prefix}-row-${nextId++}`),\n\t\tnextId,\n\t};\n}\n\ninterface StringRepeaterRowState {\n\tname: string;\n\tprefix: string;\n\tvalues: string[];\n\tids: string[];\n\tnextId: number;\n\tlastExternalValues: string[];\n\tpendingInternalValues: string[] | null;\n}\n\ntype StringRepeaterRowAction =\n\t| { type: 'sync'; name: string; values: string[] }\n\t| { type: 'commit'; values: string[]; ids: string[]; nextId?: number };\n\nfunction createStringRepeaterRowState(\n\tname: string,\n\tvalues: ReadonlyArray<string>,\n\tprefix: string,\n\tinitialNextId = 0,\n): StringRepeaterRowState {\n\tconst ids = values.map((_, index) => `${prefix}-row-${initialNextId + index}`);\n\treturn {\n\t\tname,\n\t\tprefix,\n\t\tvalues: [...values],\n\t\tids,\n\t\tnextId: initialNextId + ids.length,\n\t\tlastExternalValues: [...values],\n\t\tpendingInternalValues: null,\n\t};\n}\n\nfunction stringRepeaterRowReducer(\n\tstate: StringRepeaterRowState,\n\taction: StringRepeaterRowAction,\n): StringRepeaterRowState {\n\tif (action.type === 'commit') {\n\t\treturn {\n\t\t\t...state,\n\t\t\tvalues: action.values,\n\t\t\tids: action.ids,\n\t\t\tnextId: action.nextId ?? state.nextId,\n\t\t\tpendingInternalValues: action.values,\n\t\t};\n\t}\n\n\tif (action.name !== state.name) {\n\t\treturn createStringRepeaterRowState(\n\t\t\taction.name,\n\t\t\taction.values,\n\t\t\tstate.prefix,\n\t\t\tstate.nextId,\n\t\t);\n\t}\n\n\tif (\n\t\tstate.pendingInternalValues &&\n\t\tstringArraysEqual(action.values, state.pendingInternalValues)\n\t) {\n\t\treturn {\n\t\t\t...state,\n\t\t\tlastExternalValues: [...action.values],\n\t\t\tpendingInternalValues: null,\n\t\t};\n\t}\n\n\tconst reconciled = reconcileStringRepeaterIds(\n\t\tstate.values,\n\t\tstate.ids,\n\t\taction.values,\n\t\tstate.prefix,\n\t\tstate.nextId,\n\t);\n\n\treturn {\n\t\t...state,\n\t\tvalues: [...action.values],\n\t\tids: reconciled.ids,\n\t\tnextId: reconciled.nextId,\n\t\tlastExternalValues: [...action.values],\n\t\tpendingInternalValues: null,\n\t};\n}\n\nfunction useStringRepeaterRows(name: string, values: string[], prefix: string) {\n\tconst [storedState, dispatch] = useReducer(\n\t\tstringRepeaterRowReducer,\n\t\tundefined,\n\t\t() => createStringRepeaterRowState(name, values, prefix),\n\t);\n\n\tconst needsSync = storedState.name !== name ||\n\t\t!stringArraysEqual(values, storedState.lastExternalValues);\n\tconst syncAction: StringRepeaterRowAction = { type: 'sync', name, values };\n\tconst state = needsSync\n\t\t? stringRepeaterRowReducer(storedState, syncAction)\n\t\t: storedState;\n\n\tif (needsSync) dispatch(syncAction);\n\n\treturn { state, dispatch };\n}\n\nexport interface StringRepeaterStrings {\n\t/** Placeholder shown by the default input renderer. */\n\tplaceholder: string;\n\t/** Label for the add-row action. */\n\taddButton: string;\n\t/** Copy shown when the array is empty. */\n\temptyState: string;\n\t/** Accessible label for each remove action. */\n\tremoveAriaLabel: string;\n\t/** Accessible label for each drag handle. */\n\tdragHandleAriaLabel: string;\n}\n\nexport const defaultStringRepeaterStrings: StringRepeaterStrings = {\n\tplaceholder: 'Enter value',\n\taddButton: 'Add item',\n\tdragHandleAriaLabel: 'Drag to reorder',\n\t...defaultRepeaterStrings,\n};\n\nexport interface StringRepeaterFieldRenderContext {\n\t/** Stable opaque id for this visual row. */\n\tid: string;\n\t/** Current row position. */\n\tindex: number;\n\t/** Native-style field name for the row. */\n\tname: string;\n\t/** Current scalar value. */\n\tvalue: string;\n\t/** Whether the field should render invalid styling. */\n\tinvalid: boolean;\n\t/** Whether editing and row actions are disabled. */\n\tdisabled: boolean;\n\t/** Update only this scalar value. */\n\tonValueChange: (value: string) => void;\n\t/** Forward blur to React Hook Form. */\n\tonBlur: () => void;\n\t/** React Hook Form's array-level focus ref, provided on the first row only. */\n\tref?: RefCallback<HTMLInputElement | HTMLTextAreaElement>;\n}\n\nexport interface StringRepeaterProps {\n\t/** React Hook Form field path pointing to a `string[]`. */\n\tname: string;\n\t/** Force invalid styling in addition to React Hook Form field state. */\n\tinvalid?: boolean;\n\t/** Disable editing, addition, removal, and sorting. */\n\tdisabled?: boolean;\n\t/** Enable drag-to-reorder. Default `false`. */\n\tsortable?: boolean;\n\t/** Replace the default Input while retaining the canonical array engine. */\n\trenderField?: (context: StringRepeaterFieldRenderContext) => ReactNode;\n\t/** Override default strings. */\n\tstrings?: StringsProp<StringRepeaterStrings>;\n\t/** Class applied to the public repeater root. */\n\tclassName?: string;\n}\n\n/** React Hook Form adapter for a scalar `string[]` using the canonical Repeater chrome. */\nexport function StringRepeater({\n\tname,\n\tinvalid,\n\tdisabled = false,\n\tsortable = false,\n\trenderField,\n\tstrings: stringsProp,\n\tclassName,\n}: StringRepeaterProps) {\n\tconst strings = useStrings(defaultStringRepeaterStrings, stringsProp);\n\tconst { control } = useFormContext();\n\tconst { field, fieldState } = useController({ control, name });\n\tconst values = Array.isArray(field.value) ? field.value as string[] : [];\n\tconst resolvedInvalid = Boolean(invalid || fieldState.invalid);\n\n\tconst instanceId = useId().replace(/:/g, '');\n\tconst { state: rowState, dispatch: dispatchRows } = useStringRepeaterRows(\n\t\tname,\n\t\tvalues,\n\t\tinstanceId,\n\t);\n\n\tconst commitValue = (nextValues: string[], nextIds: string[], nextId?: number) => {\n\t\tdispatchRows({ type: 'commit', values: nextValues, ids: nextIds, nextId });\n\t\tfield.onChange(nextValues);\n\t};\n\n\tconst updateValue = (index: number, nextValue: string) => {\n\t\tconst next = [...rowState.values];\n\t\tnext[index] = nextValue;\n\t\tcommitValue(next, rowState.ids);\n\t};\n\n\tconst addValue = () => {\n\t\tconst id = `${instanceId}-row-${rowState.nextId}`;\n\t\tcommitValue(\n\t\t\t[...rowState.values, ''],\n\t\t\t[...rowState.ids, id],\n\t\t\trowState.nextId + 1,\n\t\t);\n\t};\n\n\tconst removeValue = (index: number) => {\n\t\tcommitValue(\n\t\t\trowState.values.filter((_, valueIndex) => valueIndex !== index),\n\t\t\trowState.ids.filter((_, valueIndex) => valueIndex !== index),\n\t\t);\n\t};\n\n\tconst moveValue = (fromIndex: number, toIndex: number) => {\n\t\tconst nextValues = moveStringRepeaterItem(rowState.values, fromIndex, toIndex);\n\t\tconst nextIds = moveStringRepeaterItem(rowState.ids, fromIndex, toIndex);\n\t\tcommitValue(nextValues, nextIds);\n\t};\n\n\tconst items = rowState.values.map((value, index) => ({\n\t\tid: rowState.ids[index]!,\n\t\tvalue,\n\t}));\n\n\tconst sortingProps = sortable\n\t\t? { sortable: true as const, onMove: moveValue }\n\t\t: { sortable: false as const };\n\n\treturn (\n\t\t<Repeater\n\t\t\t{...sortingProps}\n\t\t\tclassName={cn('string-repeater--component', className)}\n\t\t\titems={items}\n\t\t\tdisabled={disabled}\n\t\t\tonAdd={addValue}\n\t\t\tonRemove={removeValue}\n\t\t\tstrings={{\n\t\t\t\temptyState: strings.emptyState,\n\t\t\t\taddButton: strings.addButton,\n\t\t\t\tremoveAriaLabel: strings.removeAriaLabel,\n\t\t\t\tdragHandleAriaLabel: strings.dragHandleAriaLabel,\n\t\t\t}}\n\t\t\trenderRow={(item, { index }) => {\n\t\t\t\tconst context: StringRepeaterFieldRenderContext = {\n\t\t\t\t\tid: item.id,\n\t\t\t\t\tindex,\n\t\t\t\t\tname: `${name}.${index}`,\n\t\t\t\t\tvalue: item.value,\n\t\t\t\t\tinvalid: resolvedInvalid,\n\t\t\t\t\tdisabled,\n\t\t\t\t\tonValueChange: (nextValue) => updateValue(index, nextValue),\n\t\t\t\t\tonBlur: field.onBlur,\n\t\t\t\t\t// React Hook Form owns one ref for the scalar array field.\n\t\t\t\t\t// Forward it only to the first focus target instead of\n\t\t\t\t\t// repeatedly replacing it with every rendered row.\n\t\t\t\t\tref: index === 0 ? field.ref : undefined,\n\t\t\t\t};\n\n\t\t\t\tif (renderField) return renderField(context);\n\n\t\t\t\treturn (\n\t\t\t\t\t<Input\n\t\t\t\t\t\tref={context.ref}\n\t\t\t\t\t\tname={context.name}\n\t\t\t\t\t\tvalue={context.value}\n\t\t\t\t\t\tonChange={(event) => context.onValueChange(event.target.value)}\n\t\t\t\t\t\tonBlur={context.onBlur}\n\t\t\t\t\t\tplaceholder={strings.placeholder}\n\t\t\t\t\t\tinvalid={context.invalid}\n\t\t\t\t\t\tdisabled={context.disabled}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nStringRepeater.displayName = 'StringRepeater';\n","/**\n * ObjectRepeater — RHF-driven repeater for arrays of homogeneous objects.\n * Field definitions describe the shape of each row (label, type, placeholder,\n * required, hint); the repeater wires each cell through `useFieldArray` and\n * renders rows as bordered cards via the shared `<Repeater>` primitive.\n * Strings overridable for i18n.\n */\nimport { type ReactNode, useCallback } from 'react';\nimport {\n\tuseFieldArray,\n\tuseFormContext,\n\ttype UseFormRegisterReturn,\n} from 'react-hook-form';\n\nimport { FormField } from '../forms/form-field';\nimport { Stack } from '../structure';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nimport { Input } from '../text-inputs';\nimport { Repeater } from './repeater';\nimport { defaultRepeaterStrings } from './repeaters.strings';\nimport { Textarea } from '../text-inputs';\n\nexport interface ObjectRepeaterStrings {\n\taddButton: string;\n\temptyState: string;\n\tremoveAriaLabel: string;\n\tdragHandleAriaLabel: string;\n}\n\nexport const defaultObjectRepeaterStrings: ObjectRepeaterStrings = {\n\taddButton: 'Add item',\n\tdragHandleAriaLabel: 'Drag to reorder',\n\t...defaultRepeaterStrings,\n};\n\nexport interface ObjectFieldDef {\n\t/** Field name within the object */\n\tname: string;\n\n\t/** Label for the field */\n\tlabel: string;\n\n\t/** Input type */\n\ttype?: 'text' | 'textarea' | 'number';\n\n\t/** Placeholder text */\n\tplaceholder?: string;\n\n\t/** Whether the field is required */\n\trequired?: boolean;\n\n\t/** Hint text (shown right of label) */\n\thint?: string;\n}\n\nexport interface ObjectRepeaterFieldRenderContext {\n\t/** Current object row position. */\n\tindex: number;\n\t/** Fully-qualified React Hook Form field path. */\n\tname: string;\n\t/** Registration props for the current field. */\n\tinputProps: UseFormRegisterReturn;\n\t/** Whether invalid styling should be applied. */\n\tinvalid: boolean;\n\t/** Whether editing is disabled. */\n\tdisabled: boolean;\n}\n\nexport interface ObjectRepeaterProps {\n\t/** React Hook Form field path pointing to an object array. */\n\tname: string;\n\t/** Definitions for each editable property in a row. */\n\tfields: ObjectFieldDef[];\n\t/** Force invalid styling for every field. */\n\tinvalid?: boolean;\n\t/** Disable editing, addition, removal, and sorting. */\n\tdisabled?: boolean;\n\t/** Enable drag-to-reorder. Default `false`. */\n\tsortable?: boolean;\n\t/** Replace the default field rendering while retaining array behavior. */\n\trenderField?: (\n\t\tfield: ObjectFieldDef,\n\t\tcontext: ObjectRepeaterFieldRenderContext,\n\t) => ReactNode;\n\t/** Override default strings (button labels, empty state). */\n\tstrings?: StringsProp<ObjectRepeaterStrings>;\n\t/** Class applied to the public repeater root. */\n\tclassName?: string;\n}\n\n/** React Hook Form object-array adapter using the canonical Repeater chrome. */\nexport function ObjectRepeater({\n\tname,\n\tfields: fieldDefs,\n\tinvalid,\n\tdisabled = false,\n\tsortable = false,\n\trenderField,\n\tstrings: stringsProp,\n\tclassName,\n}: ObjectRepeaterProps) {\n\tconst strings = useStrings(defaultObjectRepeaterStrings, stringsProp);\n\tconst { control, register } = useFormContext();\n\tconst { fields, append, remove, move } = useFieldArray({\n\t\tcontrol,\n\t\tname,\n\t});\n\n\tconst createEmptyObject = useCallback(() => {\n\t\treturn fieldDefs.reduce(\n\t\t\t(acc, field) => {\n\t\t\t\tacc[field.name] = '';\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{} as Record<string, string>\n\t\t);\n\t}, [fieldDefs]);\n\n\tconst sortingProps = sortable\n\t\t? { sortable: true as const, onMove: (from: number, to: number) => move(from, to) }\n\t\t: { sortable: false as const };\n\n\treturn (\n\t\t<Repeater\n\t\t\t{...sortingProps}\n\t\t\tclassName={cn('object-repeater--component', className)}\n\t\t\titems={fields}\n\t\t\trowVariant=\"card\"\n\t\t\tremoveVariant=\"ghost\"\n\t\t\tdisabled={disabled}\n\t\t\tonAdd={() => append(createEmptyObject())}\n\t\t\tonRemove={(index) => remove(index)}\n\t\t\tstrings={{\n\t\t\t\temptyState: strings.emptyState,\n\t\t\t\taddButton: strings.addButton,\n\t\t\t\tremoveAriaLabel: strings.removeAriaLabel,\n\t\t\t\tdragHandleAriaLabel: strings.dragHandleAriaLabel,\n\t\t\t}}\n\t\t\trenderRow={(_field, { index }) => (\n\t\t\t\t<Stack gap=\"lg\" className=\"object-repeater--fields\">\n\t\t\t\t\t{fieldDefs.map((fieldDef) => {\n\t\t\t\t\t\tconst fieldPath = `${name}.${index}.${fieldDef.name}`;\n\t\t\t\t\t\tconst inputProps = register(fieldPath);\n\t\t\t\t\t\tconst context: ObjectRepeaterFieldRenderContext = {\n\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\tname: fieldPath,\n\t\t\t\t\t\t\tinputProps,\n\t\t\t\t\t\t\tinvalid: Boolean(invalid),\n\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (renderField) {\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<div key={fieldDef.name} className=\"object-repeater--field\">\n\t\t\t\t\t\t\t\t\t{renderField(fieldDef, context)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tkey={fieldDef.name}\n\t\t\t\t\t\t\t\tlabel={fieldDef.label}\n\t\t\t\t\t\t\t\trequired={fieldDef.required}\n\t\t\t\t\t\t\t\thint={fieldDef.hint}\n\t\t\t\t\t\t\t\thtmlFor={fieldPath}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{fieldDef.type === 'textarea' ? (\n\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\t{...inputProps}\n\t\t\t\t\t\t\t\t\t\tid={fieldPath}\n\t\t\t\t\t\t\t\t\t\tplaceholder={fieldDef.placeholder}\n\t\t\t\t\t\t\t\t\t\tminRows={3}\n\t\t\t\t\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t{...inputProps}\n\t\t\t\t\t\t\t\t\t\tid={fieldPath}\n\t\t\t\t\t\t\t\t\t\ttype={fieldDef.type || 'text'}\n\t\t\t\t\t\t\t\t\t\tplaceholder={fieldDef.placeholder}\n\t\t\t\t\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</FormField>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</Stack>\n\t\t\t)}\n\t\t/>\n\t);\n}\n\nObjectRepeater.displayName = 'ObjectRepeater';\n","/**\n * KeyValueEditor — dynamic editor for arbitrary key→value string pairs. Emits\n * a `Record<string, string>` to consumers; rows with empty keys are dropped\n * from the output. Use for metadata, environment vars, or feature flags.\n *\n * Built on the shared `<Repeater>` primitive so it visually matches the\n * `StringRepeater` / `ObjectRepeater` / `LocalizedStringRepeater` family —\n * same row chrome, same remove icon, same add-button styling, optional\n * drag-to-reorder.\n */\nimport { forwardRef, useState, useRef, useCallback, memo } from 'react';\n\nimport { Label } from '../../typography';\nimport { affordanceGeometry } from '../../../lib/affordance-geometry.generated';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { useDensityConfig } from '../../../lib/ui-provider';\nimport { cn } from '../../../lib/utils';\n\nimport { Input } from '../text-inputs';\nimport { Repeater } from './repeater';\n\nexport type KeyValuePair = { key: string; value: string };\n\nexport interface KeyValueEditorStrings {\n\tkeyLabel: string;\n\tvalueLabel: string;\n\tkeyPlaceholder: string;\n\tvaluePlaceholder: string;\n\taddButton: string;\n\tremoveRowAriaLabel: string;\n\temptyState: string;\n}\n\nexport const defaultKeyValueEditorStrings: KeyValueEditorStrings = {\n\tkeyLabel: 'Key',\n\tvalueLabel: 'Value',\n\tkeyPlaceholder: 'key',\n\tvaluePlaceholder: 'value',\n\taddButton: 'Add row',\n\tremoveRowAriaLabel: 'Remove row',\n\temptyState: 'No rows yet.',\n};\n\nexport interface KeyValueEditorProps {\n\t/** Current value. Controlled. */\n\tvalue?: Record<string, string>;\n\tonValueChange?: (val: Record<string, string>) => void;\n\t/** Applies the invalid styling. */\n\tinvalid?: boolean;\n\t/** Enable drag-to-reorder. Default `false`. */\n\tsortable?: boolean;\n\t/** Override default strings (labels, placeholders, button text). */\n\tstrings?: StringsProp<KeyValueEditorStrings>;\n}\n\ntype KeyValueRow = KeyValuePair & { id: string };\n\nconst generateId = (): string => {\n\tif (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n\t\treturn crypto.randomUUID();\n\t}\n\treturn Math.random().toString(36).slice(2, 10);\n};\n\ninterface KeyValueEditorRowProps {\n\trow: KeyValueRow;\n\tkeyPlaceholder: string;\n\tvaluePlaceholder: string;\n\tkeyLabel: string;\n\tvalueLabel: string;\n\t/** Applies the invalid styling. */\n\tinvalid?: boolean;\n\tonKeyChange: (id: string, value: string) => void;\n\tonValueChange: (id: string, value: string) => void;\n}\n\nconst KeyValueEditorRow = memo(function KeyValueEditorRow({\n\trow,\n\tkeyPlaceholder,\n\tvaluePlaceholder,\n\tkeyLabel,\n\tvalueLabel,\n\tinvalid,\n\tonKeyChange,\n\tonValueChange,\n}: KeyValueEditorRowProps) {\n\tconst { id, key: keyValue, value } = row;\n\n\treturn (\n\t\t<div className={cn('key-value-editor--row', 'grid grid-cols-1 @md/key-value-editor:grid-cols-2 gap-space-md')}>\n\t\t\t<div className=\"grid min-w-0 gap-space-sm\">\n\t\t\t\t{!!keyLabel && <Label htmlFor={`${id}-key`} className=\"text-inherit @md/key-value-editor:sr-only\">{keyLabel}</Label>}\n\t\t\t\t<Input id={`${id}-key`} aria-label={keyLabel || keyPlaceholder} value={keyValue ?? ''} placeholder={keyPlaceholder} onChange={(event) => onKeyChange(id, event.target.value)} invalid={invalid} />\n\t\t\t</div>\n\t\t\t<div className=\"grid min-w-0 gap-space-sm\">\n\t\t\t\t{!!valueLabel && <Label htmlFor={`${id}-value`} className=\"text-inherit @md/key-value-editor:sr-only\">{valueLabel}</Label>}\n\t\t\t\t<Input id={`${id}-value`} aria-label={valueLabel || valuePlaceholder} value={value ?? ''} placeholder={valuePlaceholder} onChange={(event) => onValueChange(id, event.target.value)} invalid={invalid} />\n\t\t\t</div>\n\t\t</div>\n\t);\n});\n\nexport const KeyValueEditor = forwardRef<HTMLDivElement, KeyValueEditorProps>(function KeyValueEditor({\n\tvalue,\n\tonValueChange,\n\tinvalid,\n\tsortable = false,\n\tstrings: stringsProp,\n}: KeyValueEditorProps, ref) {\n\tconst strings = useStrings(defaultKeyValueEditorStrings, stringsProp);\n\tconst { defaultScale } = useDensityConfig();\n\t// Track if we're making internal changes to avoid re-syncing\n\tconst isInternalChange = useRef(false);\n\n\t// Initialize rows from value prop\n\tconst [rows, setRows] = useState<KeyValueRow[]>(() => {\n\t\tif (value && Object.keys(value).length > 0) {\n\t\t\treturn Object.entries(value).map(([k, v]) => ({\n\t\t\t\tid: generateId(),\n\t\t\t\tkey: k,\n\t\t\t\tvalue: String(v ?? ''),\n\t\t\t}));\n\t\t}\n\t\treturn [{ id: generateId(), key: '', value: '' }];\n\t});\n\n\t// Emit changes to parent\n\tconst emit = useCallback(\n\t\t(next: KeyValueRow[]) => {\n\t\t\tconst obj: Record<string, string> = {};\n\t\t\tnext.forEach(({ key, value }) => {\n\t\t\t\tif (key.trim() !== '') obj[key] = value ?? '';\n\t\t\t});\n\t\t\tisInternalChange.current = true;\n\t\t\tonValueChange?.(obj);\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tisInternalChange.current = false;\n\t\t\t});\n\t\t},\n\t\t[onValueChange]\n\t);\n\n\tconst handleKeyChange = useCallback(\n\t\t(id: string, newKey: string) => {\n\t\t\tsetRows((prev) => {\n\t\t\t\tconst next = prev.map((row) => (row.id === id ? { ...row, key: newKey } : row));\n\t\t\t\temit(next);\n\t\t\t\treturn next;\n\t\t\t});\n\t\t},\n\t\t[emit]\n\t);\n\n\tconst handleValueChange = useCallback(\n\t\t(id: string, newValue: string) => {\n\t\t\tsetRows((prev) => {\n\t\t\t\tconst next = prev.map((row) => (row.id === id ? { ...row, value: newValue } : row));\n\t\t\t\temit(next);\n\t\t\t\treturn next;\n\t\t\t});\n\t\t},\n\t\t[emit]\n\t);\n\n\tconst addRow = useCallback(() => {\n\t\tsetRows((prev) => {\n\t\t\tconst next = [...prev, { id: generateId(), key: '', value: '' }];\n\t\t\temit(next);\n\t\t\treturn next;\n\t\t});\n\t}, [emit]);\n\n\tconst removeRow = useCallback(\n\t\t(index: number) => {\n\t\t\tsetRows((prev) => {\n\t\t\t\tconst next = prev.filter((_, i) => i !== index);\n\t\t\t\tconst result = next.length ? next : [{ id: generateId(), key: '', value: '' }];\n\t\t\t\temit(result);\n\t\t\t\treturn result;\n\t\t\t});\n\t\t},\n\t\t[emit]\n\t);\n\n\tconst moveRow = useCallback(\n\t\t(from: number, to: number) => {\n\t\t\tsetRows((prev) => {\n\t\t\t\tconst next = [...prev];\n\t\t\t\tconst [moved] = next.splice(from, 1);\n\t\t\t\tnext.splice(to, 0, moved);\n\t\t\t\temit(next);\n\t\t\t\treturn next;\n\t\t\t});\n\t\t},\n\t\t[emit]\n\t);\n\n\t// Render the column labels OUTSIDE the repeater so the per-row drag\n\t// handle + remove button stay aligned with the input baseline. Gutter\n\t// padding follows the shared action height and row gap at each density.\n\t// Written from the root tokens (not the derived --spacing-* aliases, which\n\t// resolve at :root) so a scoped density or spacing keeps the columns aligned;\n\t// logical sides follow the row's reading direction.\n\tconst showHeader = !!strings.keyLabel || !!strings.valueLabel;\n\tconst gutter = affordanceGeometry.actionGutter[defaultScale === 'sm' || defaultScale === 'lg' ? defaultScale : 'md'];\n\tconst gutterClasses = { left: gutter.start, right: gutter.end };\n\tconst leftGutter = sortable ? gutterClasses.left : '';\n\tconst rightGutter = gutterClasses.right;\n\tconst sortingProps = sortable\n\t\t? { sortable: true as const, onMove: moveRow }\n\t\t: { sortable: false as const };\n\n\treturn (\n\t\t<div ref={ref} className=\"key-value-editor--component @container/key-value-editor space-y-space-sm\">\n\t\t\t{showHeader && (\n\t\t\t\t<div data-action-gutter className={cn('hidden @md/key-value-editor:grid grid-cols-2 gap-space-md', leftGutter, rightGutter)}>\n\t\t\t\t\t<div>{!!strings.keyLabel && <Label className=\"flex items-center text-inherit\">{strings.keyLabel}</Label>}</div>\n\t\t\t\t\t<div>{!!strings.valueLabel && <Label className=\"flex items-center text-inherit\">{strings.valueLabel}</Label>}</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<Repeater\n\t\t\t\t{...sortingProps}\n\t\t\t\titems={rows}\n\t\t\t\tonAdd={addRow}\n\t\t\t\tonRemove={removeRow}\n\t\t\t\tstrings={{\n\t\t\t\t\temptyState: strings.emptyState,\n\t\t\t\t\taddButton: strings.addButton,\n\t\t\t\t\tremoveAriaLabel: strings.removeRowAriaLabel,\n\t\t\t\t}}\n\t\t\t\trenderRow={(row) => (\n\t\t\t\t\t<KeyValueEditorRow\n\t\t\t\t\t\trow={row}\n\t\t\t\t\t\tkeyPlaceholder={strings.keyPlaceholder}\n\t\t\t\t\t\tvaluePlaceholder={strings.valuePlaceholder}\n\t\t\t\t\t\tkeyLabel={strings.keyLabel}\n\t\t\t\t\t\tvalueLabel={strings.valueLabel}\n\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\tonKeyChange={handleKeyChange}\n\t\t\t\t\t\tonValueChange={handleValueChange}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t/>\n\t\t</div>\n\t);\n});\n\nKeyValueEditor.displayName = 'KeyValueEditor';\n","import { useFormContext } from 'react-hook-form';\n\nimport { Input } from '../text-inputs';\nimport { Textarea } from '../text-inputs';\n\nimport { cn } from '../../../lib/utils';\nexport interface LocalizedStringFieldProps {\n\t/** Field name (path in form values) - should point to object with locale keys (e.g., 'en' and 'bg') */\n\tname: string;\n\n\t/** Input type */\n\ttype?: 'text' | 'textarea' | 'number';\n\n\t/** Placeholder text */\n\tplaceholder?: string;\n\n\t/** Primary locale code (e.g., 'en') */\n\tprimaryLocale: string;\n\n\t/** Secondary locale code (e.g., 'bg') */\n\tsecondaryLocale: string;\n\n\t/** Current active locale ('primary' or 'secondary') */\n\tactiveLocale: 'primary' | 'secondary';\n\n\t/** Error state for styling (passed from FormField) */\n\tinvalid?: boolean;\n\n\t/** Additional class names */\n\tclassName?: string;\n}\n\n/**\n * LocalizedStringField - Input for bilingual string fields\n */\nexport function LocalizedStringField({\n\tname,\n\ttype = 'text',\n\tplaceholder,\n\tprimaryLocale,\n\tsecondaryLocale,\n\tactiveLocale,\n\tinvalid,\n\tclassName,\n}: LocalizedStringFieldProps) {\n\tconst { register } = useFormContext();\n\n\tconst localeKey = activeLocale === 'primary' ? primaryLocale : secondaryLocale;\n\tconst fieldName = `${name}.${localeKey}`;\n\n\tif (type === 'textarea') {\n\t\treturn (\n\t\t\t<Textarea\n\t\t\t\tkey={fieldName}\n\t\t\t\t{...register(fieldName)}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tminRows={3}\n\t\t\t\tinvalid={invalid}\n\t\t\t\tclassName={cn('localized-string-field--component', className)}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Input\n\t\t\tkey={fieldName}\n\t\t\t\t{...register(fieldName)}\n\t\t\ttype={type === 'number' ? 'number' : 'text'}\n\t\t\tplaceholder={placeholder}\n\t\t\tinvalid={invalid}\n\t\t\tclassName={cn('localized-string-field--component', className)}\n\t\t/>\n\t);\n}\n\nLocalizedStringField.displayName = 'LocalizedStringField';\n","import { useFormContext } from 'react-hook-form';\n\nimport { Stack } from '../structure';\nimport { FormField } from '../forms';\nimport { cn } from '../../../lib/utils';\nimport { Input } from '../text-inputs';\nimport { Textarea } from '../text-inputs';\n\nexport interface LocalizedObjectFieldDef {\n\t/** Field name within the object */\n\tname: string;\n\n\t/** Label for the field */\n\tlabel: string;\n\n\t/** Input type */\n\ttype?: 'text' | 'textarea' | 'number';\n\n\t/** Placeholder text */\n\tplaceholder?: string;\n\n\t/** Whether the field is required */\n\trequired?: boolean;\n}\n\nexport interface LocalizedObjectFieldProps {\n\t/** Field name (path in form values) - should point to object with locale keys */\n\tname: string;\n\n\t/** Field definitions for the object properties */\n\tfields: LocalizedObjectFieldDef[];\n\n\t/** Primary locale code (e.g., 'en') */\n\tprimaryLocale: string;\n\n\t/** Secondary locale code (e.g., 'bg') */\n\tsecondaryLocale: string;\n\n\t/** Current active locale ('primary' or 'secondary') */\n\tactiveLocale: 'primary' | 'secondary';\n\n\t/** Error state for styling (passed from FormField) */\n\tinvalid?: boolean;\n\n\t/** Additional class names */\n\tclassName?: string;\n}\n\n/**\n * LocalizedObjectField - Input for bilingual object fields\n */\nexport function LocalizedObjectField({\n\tname,\n\tfields,\n\tprimaryLocale,\n\tsecondaryLocale,\n\tactiveLocale,\n\tinvalid,\n\tclassName,\n}: LocalizedObjectFieldProps) {\n\tconst { register } = useFormContext();\n\n\tconst localeKey = activeLocale === 'primary' ? primaryLocale : secondaryLocale;\n\n\treturn (\n\t\t<div className={cn('localized-object-field--component w-full rounded-radius border border-border p-surface', className)}>\n\t\t<Stack gap=\"lg\">\n\t\t\t{fields.map((field) => {\n\t\t\t\tconst fieldName = `${name}.${localeKey}.${field.name}`;\n\n\t\t\t\treturn (\n\t\t\t\t\t<FormField key={fieldName} label={field.label} htmlFor={fieldName} required={field.required} className=\"w-full\">\n\t\t\t\t\t\t{field.type === 'textarea' ? (\n\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t{...register(fieldName)}\n\t\t\t\t\t\t\t\tid={fieldName}\n\t\t\t\t\t\t\t\tplaceholder={field.placeholder}\n\t\t\t\t\t\t\t\tminRows={3}\n\t\t\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t{...register(fieldName)}\n\t\t\t\t\t\t\t\tid={fieldName}\n\t\t\t\t\t\t\t\ttype={field.type === 'number' ? 'number' : 'text'}\n\t\t\t\t\t\t\t\tplaceholder={field.placeholder}\n\t\t\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</FormField>\n\t\t\t\t);\n\t\t\t})}\n\t\t</Stack>\n\t\t</div>\n\t);\n}\n\nLocalizedObjectField.displayName = 'LocalizedObjectField';\n","/**\n * LocalizedStringRepeater — locale-path adapter over `<StringRepeater>`.\n * The canonical scalar-array engine stays in StringRepeater; this component\n * selects the active locale path and swaps the default Input for Textarea.\n */\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nimport {\n\tStringRepeater,\n\ttype StringRepeaterFieldRenderContext,\n} from './string-repeater';\nimport { defaultRepeaterStrings } from './repeaters.strings';\nimport { Textarea } from '../text-inputs';\n\nexport interface LocalizedStringRepeaterStrings {\n\t/** Placeholder shown in every localized textarea. */\n\tplaceholder: string;\n\t/** Label for the add-row action. */\n\taddButton: string;\n\t/** Copy shown when the active locale array is empty. */\n\temptyState: string;\n\t/** Accessible label for each remove action. */\n\tremoveAriaLabel: string;\n\t/** Accessible label for each drag handle. */\n\tdragHandleAriaLabel: string;\n}\n\nexport const defaultLocalizedStringRepeaterStrings: LocalizedStringRepeaterStrings = {\n\tplaceholder: 'Enter value',\n\taddButton: defaultRepeaterStrings.addItem,\n\temptyState: defaultRepeaterStrings.emptyState,\n\tremoveAriaLabel: defaultRepeaterStrings.removeAriaLabel,\n\tdragHandleAriaLabel: 'Drag to reorder',\n};\n\nexport interface LocalizedStringRepeaterProps {\n\t/** Field path pointing to an object of locale-keyed `string[]` values. */\n\tname: string;\n\t/** Primary locale key, for example `en`. */\n\tprimaryLocale: string;\n\t/** Secondary locale key, for example `bg`. */\n\tsecondaryLocale: string;\n\t/** Selects which locale array is currently editable. */\n\tactiveLocale: 'primary' | 'secondary';\n\t/** Enable drag-to-reorder. Default `false`. */\n\tsortable?: boolean;\n\t/** Force invalid styling in addition to React Hook Form state. */\n\tinvalid?: boolean;\n\t/** Disable editing and all row actions. */\n\tdisabled?: boolean;\n\t/** Override default strings. */\n\tstrings?: StringsProp<LocalizedStringRepeaterStrings>;\n\t/** Class applied to the public repeater root. */\n\tclassName?: string;\n}\n\n/** Locale-path adapter over the canonical StringRepeater array engine. */\nexport function LocalizedStringRepeater({\n\tname,\n\tprimaryLocale,\n\tsecondaryLocale,\n\tactiveLocale,\n\tinvalid,\n\tdisabled = false,\n\tsortable = false,\n\tstrings: stringsProp,\n\tclassName,\n}: LocalizedStringRepeaterProps) {\n\tconst strings = useStrings(defaultLocalizedStringRepeaterStrings, stringsProp);\n\tconst localeKey = activeLocale === 'primary' ? primaryLocale : secondaryLocale;\n\tconst fieldName = `${name}.${localeKey}`;\n\n\tconst renderTextarea = (context: StringRepeaterFieldRenderContext) => (\n\t\t<Textarea\n\t\t\tref={context.ref}\n\t\t\tname={context.name}\n\t\t\tvalue={context.value}\n\t\t\tonChange={(event) => context.onValueChange(event.target.value)}\n\t\t\tonBlur={context.onBlur}\n\t\t\tplaceholder={strings.placeholder}\n\t\t\tminRows={2}\n\t\t\tinvalid={context.invalid}\n\t\t\tdisabled={context.disabled}\n\t\t/>\n\t);\n\n\treturn (\n\t\t<StringRepeater\n\t\t\tname={fieldName}\n\t\t\tsortable={sortable}\n\t\t\tinvalid={invalid}\n\t\t\tdisabled={disabled}\n\t\t\tclassName={cn('localized-string-repeater--component', className)}\n\t\t\tstrings={strings}\n\t\t\trenderField={renderTextarea}\n\t\t/>\n\t);\n}\n\nLocalizedStringRepeater.displayName = 'LocalizedStringRepeater';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"repeaters.js","names":["useDensityConfig","cn","affordanceGeometry","Button","Text","Stack","interactionRecipes","Input","FormField","defaultRepeaterStrings","defaultRepeaterPrimitiveStrings","Row","sortableState","useSortable","item","disabled","sortable","isDragging","style","CSS","ref","dragAttributes","dragListeners","dragHandle","actionSize","strings","GripVertical","removeButton","hideRemove","removeVariant","onRemove","index","Trash2","X","rowVariant","renderRow","Repeater","stringsProp","useStrings","defaultScale","sensors","useSensors","useSensor","PointerSensor","KeyboardSensor","sortableKeyboardCoordinates","handleDragEnd","useCallback","event","over","active","fromIndex","items","toIndex","onMove","itemIds","useMemo","list","className","DndContext","closestCenter","SortableContext","verticalListSortingStrategy","hideAdd","onAdd","Plus","moveStringRepeaterItem","next","moved","stringArraysEqual","left","right","value","reconcileStringRepeaterIds","idsByValue","nextId","initialNextId","previousValues","existing","id","previousIds","nextValues","prefix","createStringRepeaterRowState","ids","values","stringRepeaterRowReducer","action","state","reconciled","useStringRepeaterRows","storedState","dispatch","useReducer","name","needsSync","syncAction","defaultStringRepeaterStrings","StringRepeater","useFormContext","useController","field","resolvedInvalid","invalid","fieldState","instanceId","useId","rowState","dispatchRows","commitValue","nextIds","updateValue","nextValue","addValue","removeValue","valueIndex","moveValue","context","renderField","defaultObjectRepeaterStrings","ObjectRepeater","fieldDefs","useFieldArray","createEmptyObject","acc","move","from","to","fields","append","remove","fieldPath","fieldDef","inputProps","register","Textarea","defaultKeyValueEditorStrings","generateId","KeyValueEditorRow","memo","keyValue","row","keyLabel","Label","keyPlaceholder","onKeyChange","valueLabel","valuePlaceholder","onValueChange","KeyValueEditor","forwardRef","isInternalChange","useRef","rows","setRows","useState","k","v","emit","obj","key","handleKeyChange","prev","newKey","handleValueChange","newValue","addRow","removeRow","i","result","moveRow","showHeader","gutter","gutterClasses","leftGutter","rightGutter","sortingProps","LocalizedStringField","fieldName","activeLocale","primaryLocale","secondaryLocale","type","LocalizedObjectField","localeKey","defaultLocalizedStringRepeaterStrings","LocalizedStringRepeater"],"sources":["../../src/components/base/repeaters/repeaters.strings.ts","../../src/components/base/repeaters/repeater.tsx","../../src/components/base/repeaters/string-repeater.utils.ts","../../src/components/base/repeaters/string-repeater.tsx","../../src/components/base/repeaters/object-repeater.tsx","../../src/components/base/repeaters/key-value-editor.tsx","../../src/components/base/repeaters/localized-string-field.tsx","../../src/components/base/repeaters/localized-object-field.tsx","../../src/components/base/repeaters/localized-string-repeater.tsx"],"sourcesContent":["/**\n * Shared default strings for repeater-style form fields\n * (`<StringRepeater>`, `<ObjectRepeater>`,\n * `<LocalizedStringRepeater>`, …).\n *\n * Each repeater has its own concrete `Strings` interface — the shared\n * defaults below cover the keys they all share. Per-field strings files\n * spread these defaults into their own constant so consumers can override\n * any subset uniformly.\n */\n\nexport interface RepeaterSharedStrings {\n\temptyState: string;\n\taddItem: string;\n\tremoveAriaLabel: string;\n}\n\nexport const defaultRepeaterStrings: RepeaterSharedStrings = {\n\temptyState: 'No items added yet.',\n\taddItem: 'Add item',\n\tremoveAriaLabel: 'Remove item',\n};\n","/**\n * Repeater — shared chrome for any list-style form field. Renders a list of\n * rows with optional drag handle and a per-row remove icon, plus an empty\n * state and a trailing \"+ add\" button. The row body is consumer-rendered via\n * `children` (or `renderRow`), so this primitive is the visual contract that\n * `StringRepeater`, `ObjectRepeater`, `LocalizedStringRepeater`, and\n * `KeyValueEditor` all share — without locking down what each row is editing.\n *\n * Sortable is opt-in (`sortable`); when enabled the rows are wired up\n * through `@dnd-kit/sortable` and the consumer can render the supplied\n * `dragHandleProps` on whichever element is the visual handle.\n *\n * The `<Repeater>` is intentionally headless on the value side — it does not\n * own the items array. Consumers (RHF callers via `useFieldArray`, manual\n * controlled state, etc.) pass `items`, `onAdd`, `onRemove`, and\n * (optionally) `onMove` callbacks. This keeps the primitive framework- and\n * state-shape-agnostic.\n */\nimport {\n\t\tDndContext,\n\t\tKeyboardSensor,\n\t\tPointerSensor,\n\t\tclosestCenter,\n\t\tuseSensor,\n\t\tuseSensors,\n\t\ttype DragEndEvent,\n} from '@dnd-kit/core';\nimport {\n\t\tSortableContext,\n\t\tsortableKeyboardCoordinates,\n\t\tuseSortable,\n\t\tverticalListSortingStrategy,\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { GripVertical, Plus, Trash2, X } from 'lucide-react';\nimport {\n\t\ttype CSSProperties,\n\t\ttype ReactNode,\n\t\tuseCallback,\n\t\tuseMemo,\n} from 'react';\n\nimport { Button, type ButtonSize } from '../buttons';\nimport { Stack } from '../structure';\nimport { Text } from '../../typography/text';\nimport { useDensityConfig } from '../../../lib/ui-provider';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nimport { defaultRepeaterStrings } from './repeaters.strings';\nimport { interactionRecipes } from '../../../lib/interaction-recipes';\n\nexport interface RepeaterStrings {\n\t\t/** Empty state copy — shown when `items` is empty. */\n\t\temptyState: string;\n\t\t/** Label of the trailing \"+\" button. */\n\t\taddButton: string;\n\t\t/** Per-row remove button aria-label. */\n\t\tremoveAriaLabel: string;\n\t\t/** Drag-handle aria-label (only relevant when `sortable`). */\n\t\tdragHandleAriaLabel: string;\n}\n\nexport const defaultRepeaterPrimitiveStrings: RepeaterStrings = {\n\t\temptyState: defaultRepeaterStrings.emptyState,\n\t\taddButton: defaultRepeaterStrings.addItem,\n\t\tremoveAriaLabel: defaultRepeaterStrings.removeAriaLabel,\n\t\tdragHandleAriaLabel: 'Drag to reorder',\n};\n\n/**\n * Visual density of a row. `inline` is the canonical compact admin row\n * (single input + remove icon). `card` wraps richer content in a\n * bordered surface — used by `ObjectRepeater` and any consumer with\n * multi-field rows that need their own delete affordance.\n */\nexport type RepeaterRowVariant = 'inline' | 'card';\n\nexport type RepeaterRemoveVariant = 'ghost' | 'icon-button';\n\nexport interface RepeaterItem {\n\t\t/** Stable id (RHF `field.id`, generated UUID, etc.) — used as React key\n\t\t * and as the drag handle id when sortable. */\n\t\tid: string;\n}\n\nexport interface RepeaterRowRenderContext {\n\t\t/** Index of the row in the items array. */\n\t\tindex: number;\n\t\t/** True while the row is being actively dragged. */\n\t\tisDragging: boolean;\n}\n\ninterface RepeaterBaseProps<T extends RepeaterItem> {\n\t\t/** Entries to render, in order. */\n\t\titems: ReadonlyArray<T>;\n\t\t/** Render the body of a single row. */\n\t\trenderRow: (item: T, ctx: RepeaterRowRenderContext) => ReactNode;\n\t\t/** Called when the consumer presses the \"+ add\" button. */\n\t\tonAdd: () => void;\n\t\t/** Called when the consumer presses a per-row remove button. */\n\t\tonRemove: (index: number) => void;\n\t\t/** Visual style of each row's outer chrome. Default `'inline'`. */\n\t\trowVariant?: RepeaterRowVariant;\n\t\t/** Remove button style. Default `'ghost'` (subtle X icon, hover →\n\t\t * destructive tint). `'icon-button'` mirrors `<Button icon={Trash2}>`\n\t\t * — used by card rows that need a more prominent affordance. */\n\t\tremoveVariant?: RepeaterRemoveVariant;\n\t\t/** Hide the per-row remove button. Default `false`. Useful when the\n\t\t * consumer renders its own remove inside the row body. */\n\t\thideRemove?: boolean;\n\t\t/** Disable add + remove + drag affordances. */\n\t\tdisabled?: boolean;\n\t\t/** Hide the trailing \"+ add\" button. Useful when the consumer composes\n\t\t * it elsewhere or has a maxItems cap. */\n\t\thideAdd?: boolean;\n\t\t/** Override default strings. */\n\t\tstrings?: StringsProp<RepeaterStrings>;\n\t\t/** Class applied to the outer wrapper. */\n\t\tclassName?: string;\n}\n\ntype RepeaterSortingProps =\n\t\t| {\n\t\t\t\t\t/** Enable drag-to-reorder. */\n\t\t\t\t\tsortable: true;\n\t\t\t\t\t/** Called when a row is dragged to a new position. */\n\t\t\t\t\tonMove: (fromIndex: number, toIndex: number) => void;\n\t\t\t}\n\t\t| {\n\t\t\t\t\t/** Disable drag-to-reorder. Default `false`. */\n\t\t\t\t\tsortable?: false;\n\t\t\t\t\t/** Optional callback retained for shared prop builders; ignored while sorting is disabled. */\n\t\t\t\t\tonMove?: (fromIndex: number, toIndex: number) => void;\n\t\t\t};\n\n/**\n * Extensible consumer shape for callers that derive their own repeater\n * props. The component itself accepts `RepeaterComponentProps`, whose\n * discriminated sorting contract requires `onMove` when `sortable` is true.\n */\nexport interface RepeaterProps<T extends RepeaterItem> extends RepeaterBaseProps<T> {\n\t\tsortable?: boolean;\n\t\tonMove?: (fromIndex: number, toIndex: number) => void;\n}\n\nexport type RepeaterComponentProps<T extends RepeaterItem> =\n\t\tOmit<RepeaterProps<T>, 'sortable' | 'onMove'> & RepeaterSortingProps;\n\ninterface RowProps<T extends RepeaterItem> {\n\t\titem: T;\n\t\tindex: number;\n\t\tsortable: boolean;\n\t\trowVariant: RepeaterRowVariant;\n\t\tremoveVariant: RepeaterRemoveVariant;\n\t\thideRemove: boolean;\n\t\t/** Disables the control. */\n\t\tdisabled: boolean;\n\t\t/** Overrides this surface's own copy. */\n\t\tstrings: RepeaterStrings;\n\t\tactionSize: ButtonSize;\n\t\tonRemove: (index: number) => void;\n\t\trenderRow: RepeaterProps<T>['renderRow'];\n}\n\nfunction Row<T extends RepeaterItem>({\n\t\titem,\n\t\tindex,\n\t\tsortable,\n\t\trowVariant,\n\t\tremoveVariant,\n\t\thideRemove,\n\t\tdisabled,\n\t\tstrings,\n\t\tactionSize,\n\t\tonRemove,\n\t\trenderRow,\n}: RowProps<T>) {\n\t\tconst sortableState = useSortable({ id: item.id, disabled: disabled || !sortable });\n\t\tconst isDragging = sortable ? sortableState.isDragging : false;\n\n\t\tconst style: CSSProperties | undefined = sortable\n\t\t\t\t? {\n\t\t\t\t\t\t\ttransform: CSS.Transform.toString(sortableState.transform),\n\t\t\t\t\t\t\ttransition: sortableState.transition,\n\t\t\t\t\t\t\topacity: isDragging ? 0.6 : 1,\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\n\t\tconst ref = sortable ? sortableState.setNodeRef : undefined;\n\t\tconst dragAttributes = sortable ? sortableState.attributes : {};\n\t\tconst dragListeners = sortable ? sortableState.listeners : undefined;\n\n\t\tconst dragHandle = sortable ? (\n\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\tsize={actionSize}\n\t\t\t\t\t\ticonOnly\n\t\t\t\t\t\taria-label={strings.dragHandleAriaLabel}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'repeater--drag-handle',\n\t\t\t\t'shrink-0',\n\t\t\t\t\t\t\t\t`text-muted-foreground ${interactionRecipes.rowHover}`,\n\t\t\t\t\t\t\t\t'cursor-grab active:cursor-grabbing',\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{...dragAttributes}\n\t\t\t\t\t\t{...dragListeners}\n\t\t\t\t>\n\t\t\t\t\t\t<GripVertical className=\"size-icon\" aria-hidden=\"true\" />\n\t\t\t\t</Button>\n\t\t) : null;\n\n\t\tconst removeButton = hideRemove ? null : removeVariant === 'icon-button' ? (\n\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"outline\"\n\t\t\t\t\t\tsize={actionSize}\n\t\t\t\t\t\ticonOnly\n\t\t\t\t\t\taria-label={strings.removeAriaLabel}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tonClick={() => onRemove(index)}\n\t\t\t\t\t\tclassName=\"repeater--remove shrink-0\"\n\t\t\t\t>\n\t\t\t\t\t\t<Trash2 className=\"size-icon\" aria-hidden=\"true\" />\n\t\t\t\t</Button>\n\t\t) : (\n\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\tsize={actionSize}\n\t\t\t\t\t\ticonOnly\n\t\t\t\t\t\taria-label={strings.removeAriaLabel}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tonClick={() => onRemove(index)}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'repeater--remove',\n\t\t\t\t'shrink-0',\n\t\t\t\t\t\t\t\t'text-muted-foreground hover:text-destructive',\n\t\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t\t<X className=\"size-icon\" aria-hidden=\"true\" />\n\t\t\t\t</Button>\n\t\t);\n\n\t\tif (rowVariant === 'card') {\n\t\t\t\treturn (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\t\t\tstyle={style}\n\t\t\t\t\t\t\t\tdata-repeater-item-id={item.id}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t'repeater--item',\n\t\t\t\t\t\t\t\t\t\t'relative rounded-surface border border-border bg-card text-card-foreground p-surface',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div className=\"flex items-start gap-space-md\">\n\t\t\t\t\t\t\t\t\t\t{dragHandle}\n\t\t\t\t\t\t\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t{renderRow(item, { index, isDragging })}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t{removeButton}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t\t<div\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\tstyle={style}\n\t\t\t\t\t\tdata-repeater-item-id={item.id}\n\t\t\t\t\t\tclassName=\"repeater--item flex items-start gap-space-md\"\n\t\t\t\t>\n\t\t\t\t\t\t{dragHandle}\n\t\t\t\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t{renderRow(item, { index, isDragging })}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{removeButton}\n\t\t\t\t</div>\n\t\t);\n}\n\n/** Framework-neutral controlled list chrome with optional sortable rows. */\nexport function Repeater<T extends RepeaterItem>({\n\t\titems,\n\t\trenderRow,\n\t\tonAdd,\n\t\tonRemove,\n\t\tonMove,\n\t\tsortable = false,\n\t\trowVariant = 'inline',\n\t\tremoveVariant = 'ghost',\n\t\thideRemove = false,\n\t\thideAdd = false,\n\t\tdisabled = false,\n\t\tstrings: stringsProp,\n\t\tclassName,\n}: RepeaterComponentProps<T>) {\n\t\tconst strings = useStrings(defaultRepeaterPrimitiveStrings, stringsProp);\n\t\tconst { defaultScale } = useDensityConfig();\n\t\tconst actionSize: ButtonSize = defaultScale ?? 'md';\n\n\t\tconst sensors = useSensors(\n\t\t\t\tuseSensor(PointerSensor, { activationConstraint: { distance: 4 } }),\n\t\t\t\tuseSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),\n\t\t);\n\n\t\tconst handleDragEnd = useCallback(\n\t\t\t\t(event: DragEndEvent) => {\n\t\t\t\t\t\tconst { active, over } = event;\n\t\t\t\t\t\tif (!over || active.id === over.id) return;\n\t\t\t\t\t\tconst fromIndex = items.findIndex((item) => item.id === active.id);\n\t\t\t\t\t\tconst toIndex = items.findIndex((item) => item.id === over.id);\n\t\t\t\t\t\tif (fromIndex < 0 || toIndex < 0) return;\n\t\t\t\t\t\tonMove?.(fromIndex, toIndex);\n\t\t\t\t},\n\t\t\t\t[items, onMove],\n\t\t);\n\n\t\tconst itemIds = useMemo(() => items.map((item) => item.id), [items]);\n\n\t\tconst list = (\n\t\t<Stack gap=\"md\" className=\"repeater--list\">\n\t\t\t\t\t\t{items.map((item, index) => (\n\t\t\t\t\t\t\t\t<Row<T>\n\t\t\t\t\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t\t\t\t\titem={item}\n\t\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\t\tsortable={sortable}\n\t\t\t\t\t\t\t\t\t\trowVariant={rowVariant}\n\t\t\t\t\t\t\t\t\t\tremoveVariant={removeVariant}\n\t\t\t\t\t\t\t\t\t\thideRemove={hideRemove}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\tstrings={strings}\n\t\t\t\t\t\t\t\t\t\tactionSize={actionSize}\n\t\t\t\t\t\t\t\t\t\tonRemove={onRemove}\n\t\t\t\t\t\t\t\t\t\trenderRow={renderRow}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t</Stack>\n\t\t);\n\n\t\treturn (\n\t\t<Stack gap=\"lg\" className={cn('repeater--component', className)}>\n\t\t\t\t\t\t{items.length === 0 ? (\n\t\t\t\t<div className=\"repeater--empty rounded-surface border border-dashed border-border p-surface\">\n\t\t\t\t\t<Text type=\"secondary\">{strings.emptyState}</Text>\n\t\t\t\t</div>\n\t\t\t\t\t\t) : sortable ? (\n\t\t\t\t\t\t\t\t<DndContext\n\t\t\t\t\t\t\t\t\t\tsensors={sensors}\n\t\t\t\t\t\t\t\t\t\tcollisionDetection={closestCenter}\n\t\t\t\t\t\t\t\t\t\tonDragEnd={handleDragEnd}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<SortableContext items={itemIds} strategy={verticalListSortingStrategy}>\n\t\t\t\t\t\t\t\t\t\t\t\t{list}\n\t\t\t\t\t\t\t\t\t\t</SortableContext>\n\t\t\t\t\t\t\t\t</DndContext>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tlist\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{!hideAdd && (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\t\t\t\tbuttonStyle=\"outline\"\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t\tonClick={onAdd}\n\t\t\t\t\t\t\t\t\t\tclassName=\"repeater--add self-start\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Plus className=\"size-icon\" />\n\t\t\t\t\t\t\t\t\t\t{strings.addButton}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t</Stack>\n\t\t);\n}\n\nRepeater.displayName = 'Repeater';\n","/** Reorders a scalar-array value without changing its item shape. */\nexport function moveStringRepeaterItem<T>(\n\titems: ReadonlyArray<T>,\n\tfromIndex: number,\n\ttoIndex: number,\n): T[] {\n\tconst next = [...items];\n\tconst [moved] = next.splice(fromIndex, 1);\n\tif (moved === undefined) return [...items];\n\tnext.splice(toIndex, 0, moved);\n\treturn next;\n}\n","/**\n * StringRepeater — React Hook Form adapter for a controlled `string[]`.\n *\n * React Hook Form's `useFieldArray` only supports arrays of objects. This\n * adapter therefore controls the whole scalar array with `useController` and\n * gives each visual row a stable opaque id for React and drag-and-drop. The\n * `renderField` seam lets textarea and localized variants reuse the same state\n * engine without duplicating flat-array behavior.\n */\nimport {\n\ttype ReactNode,\n\ttype RefCallback,\n\tuseId,\n\tuseReducer,\n} from 'react';\nimport { useController, useFormContext } from 'react-hook-form';\n\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nimport { Input } from '../text-inputs';\nimport { Repeater } from './repeater';\nimport { defaultRepeaterStrings } from './repeaters.strings';\nimport { moveStringRepeaterItem } from './string-repeater.utils';\n\nfunction stringArraysEqual(left: ReadonlyArray<string>, right: ReadonlyArray<string>): boolean {\n\treturn left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nfunction reconcileStringRepeaterIds(\n\tpreviousValues: ReadonlyArray<string>,\n\tpreviousIds: ReadonlyArray<string>,\n\tnextValues: ReadonlyArray<string>,\n\tprefix: string,\n\tinitialNextId: number,\n): { ids: string[]; nextId: number } {\n\tconst idsByValue = new Map<string, string[]>();\n\tlet nextId = initialNextId;\n\n\tpreviousValues.forEach((value, index) => {\n\t\tconst existing = idsByValue.get(value) ?? [];\n\t\tconst id = previousIds[index];\n\t\tif (id) existing.push(id);\n\t\tidsByValue.set(value, existing);\n\t});\n\n\treturn {\n\t\tids: nextValues.map((value) => idsByValue.get(value)?.shift() ?? `${prefix}-row-${nextId++}`),\n\t\tnextId,\n\t};\n}\n\ninterface StringRepeaterRowState {\n\tname: string;\n\tprefix: string;\n\tvalues: string[];\n\tids: string[];\n\tnextId: number;\n\tlastExternalValues: string[];\n\tpendingInternalValues: string[] | null;\n}\n\ntype StringRepeaterRowAction =\n\t| { type: 'sync'; name: string; values: string[] }\n\t| { type: 'commit'; values: string[]; ids: string[]; nextId?: number };\n\nfunction createStringRepeaterRowState(\n\tname: string,\n\tvalues: ReadonlyArray<string>,\n\tprefix: string,\n\tinitialNextId = 0,\n): StringRepeaterRowState {\n\tconst ids = values.map((_, index) => `${prefix}-row-${initialNextId + index}`);\n\treturn {\n\t\tname,\n\t\tprefix,\n\t\tvalues: [...values],\n\t\tids,\n\t\tnextId: initialNextId + ids.length,\n\t\tlastExternalValues: [...values],\n\t\tpendingInternalValues: null,\n\t};\n}\n\nfunction stringRepeaterRowReducer(\n\tstate: StringRepeaterRowState,\n\taction: StringRepeaterRowAction,\n): StringRepeaterRowState {\n\tif (action.type === 'commit') {\n\t\treturn {\n\t\t\t...state,\n\t\t\tvalues: action.values,\n\t\t\tids: action.ids,\n\t\t\tnextId: action.nextId ?? state.nextId,\n\t\t\tpendingInternalValues: action.values,\n\t\t};\n\t}\n\n\tif (action.name !== state.name) {\n\t\treturn createStringRepeaterRowState(\n\t\t\taction.name,\n\t\t\taction.values,\n\t\t\tstate.prefix,\n\t\t\tstate.nextId,\n\t\t);\n\t}\n\n\tif (\n\t\tstate.pendingInternalValues &&\n\t\tstringArraysEqual(action.values, state.pendingInternalValues)\n\t) {\n\t\treturn {\n\t\t\t...state,\n\t\t\tlastExternalValues: [...action.values],\n\t\t\tpendingInternalValues: null,\n\t\t};\n\t}\n\n\tconst reconciled = reconcileStringRepeaterIds(\n\t\tstate.values,\n\t\tstate.ids,\n\t\taction.values,\n\t\tstate.prefix,\n\t\tstate.nextId,\n\t);\n\n\treturn {\n\t\t...state,\n\t\tvalues: [...action.values],\n\t\tids: reconciled.ids,\n\t\tnextId: reconciled.nextId,\n\t\tlastExternalValues: [...action.values],\n\t\tpendingInternalValues: null,\n\t};\n}\n\nfunction useStringRepeaterRows(name: string, values: string[], prefix: string) {\n\tconst [storedState, dispatch] = useReducer(\n\t\tstringRepeaterRowReducer,\n\t\tundefined,\n\t\t() => createStringRepeaterRowState(name, values, prefix),\n\t);\n\n\tconst needsSync = storedState.name !== name ||\n\t\t!stringArraysEqual(values, storedState.lastExternalValues);\n\tconst syncAction: StringRepeaterRowAction = { type: 'sync', name, values };\n\tconst state = needsSync\n\t\t? stringRepeaterRowReducer(storedState, syncAction)\n\t\t: storedState;\n\n\tif (needsSync) dispatch(syncAction);\n\n\treturn { state, dispatch };\n}\n\nexport interface StringRepeaterStrings {\n\t/** Placeholder shown by the default input renderer. */\n\tplaceholder: string;\n\t/** Label for the add-row action. */\n\taddButton: string;\n\t/** Copy shown when the array is empty. */\n\temptyState: string;\n\t/** Accessible label for each remove action. */\n\tremoveAriaLabel: string;\n\t/** Accessible label for each drag handle. */\n\tdragHandleAriaLabel: string;\n}\n\nexport const defaultStringRepeaterStrings: StringRepeaterStrings = {\n\tplaceholder: 'Enter value',\n\taddButton: 'Add item',\n\tdragHandleAriaLabel: 'Drag to reorder',\n\t...defaultRepeaterStrings,\n};\n\nexport interface StringRepeaterFieldRenderContext {\n\t/** Stable opaque id for this visual row. */\n\tid: string;\n\t/** Current row position. */\n\tindex: number;\n\t/** Native-style field name for the row. */\n\tname: string;\n\t/** Current scalar value. */\n\tvalue: string;\n\t/** Whether the field should render invalid styling. */\n\tinvalid: boolean;\n\t/** Whether editing and row actions are disabled. */\n\tdisabled: boolean;\n\t/** Update only this scalar value. */\n\tonValueChange: (value: string) => void;\n\t/** Forward blur to React Hook Form. */\n\tonBlur: () => void;\n\t/** React Hook Form's array-level focus ref, provided on the first row only. */\n\tref?: RefCallback<HTMLInputElement | HTMLTextAreaElement>;\n}\n\nexport interface StringRepeaterProps {\n\t/** React Hook Form field path pointing to a `string[]`. */\n\tname: string;\n\t/** Force invalid styling in addition to React Hook Form field state. */\n\tinvalid?: boolean;\n\t/** Disable editing, addition, removal, and sorting. */\n\tdisabled?: boolean;\n\t/** Enable drag-to-reorder. Default `false`. */\n\tsortable?: boolean;\n\t/** Replace the default Input while retaining the canonical array engine. */\n\trenderField?: (context: StringRepeaterFieldRenderContext) => ReactNode;\n\t/** Override default strings. */\n\tstrings?: StringsProp<StringRepeaterStrings>;\n\t/** Class applied to the public repeater root. */\n\tclassName?: string;\n}\n\n/** React Hook Form adapter for a scalar `string[]` using the canonical Repeater chrome. */\nexport function StringRepeater({\n\tname,\n\tinvalid,\n\tdisabled = false,\n\tsortable = false,\n\trenderField,\n\tstrings: stringsProp,\n\tclassName,\n}: StringRepeaterProps) {\n\tconst strings = useStrings(defaultStringRepeaterStrings, stringsProp);\n\tconst { control } = useFormContext();\n\tconst { field, fieldState } = useController({ control, name });\n\tconst values = Array.isArray(field.value) ? field.value as string[] : [];\n\tconst resolvedInvalid = Boolean(invalid || fieldState.invalid);\n\n\tconst instanceId = useId().replace(/:/g, '');\n\tconst { state: rowState, dispatch: dispatchRows } = useStringRepeaterRows(\n\t\tname,\n\t\tvalues,\n\t\tinstanceId,\n\t);\n\n\tconst commitValue = (nextValues: string[], nextIds: string[], nextId?: number) => {\n\t\tdispatchRows({ type: 'commit', values: nextValues, ids: nextIds, nextId });\n\t\tfield.onChange(nextValues);\n\t};\n\n\tconst updateValue = (index: number, nextValue: string) => {\n\t\tconst next = [...rowState.values];\n\t\tnext[index] = nextValue;\n\t\tcommitValue(next, rowState.ids);\n\t};\n\n\tconst addValue = () => {\n\t\tconst id = `${instanceId}-row-${rowState.nextId}`;\n\t\tcommitValue(\n\t\t\t[...rowState.values, ''],\n\t\t\t[...rowState.ids, id],\n\t\t\trowState.nextId + 1,\n\t\t);\n\t};\n\n\tconst removeValue = (index: number) => {\n\t\tcommitValue(\n\t\t\trowState.values.filter((_, valueIndex) => valueIndex !== index),\n\t\t\trowState.ids.filter((_, valueIndex) => valueIndex !== index),\n\t\t);\n\t};\n\n\tconst moveValue = (fromIndex: number, toIndex: number) => {\n\t\tconst nextValues = moveStringRepeaterItem(rowState.values, fromIndex, toIndex);\n\t\tconst nextIds = moveStringRepeaterItem(rowState.ids, fromIndex, toIndex);\n\t\tcommitValue(nextValues, nextIds);\n\t};\n\n\tconst items = rowState.values.map((value, index) => ({\n\t\tid: rowState.ids[index]!,\n\t\tvalue,\n\t}));\n\n\tconst sortingProps = sortable\n\t\t? { sortable: true as const, onMove: moveValue }\n\t\t: { sortable: false as const };\n\n\treturn (\n\t\t<Repeater\n\t\t\t{...sortingProps}\n\t\t\tclassName={cn('string-repeater--component', className)}\n\t\t\titems={items}\n\t\t\tdisabled={disabled}\n\t\t\tonAdd={addValue}\n\t\t\tonRemove={removeValue}\n\t\t\tstrings={{\n\t\t\t\temptyState: strings.emptyState,\n\t\t\t\taddButton: strings.addButton,\n\t\t\t\tremoveAriaLabel: strings.removeAriaLabel,\n\t\t\t\tdragHandleAriaLabel: strings.dragHandleAriaLabel,\n\t\t\t}}\n\t\t\trenderRow={(item, { index }) => {\n\t\t\t\tconst context: StringRepeaterFieldRenderContext = {\n\t\t\t\t\tid: item.id,\n\t\t\t\t\tindex,\n\t\t\t\t\tname: `${name}.${index}`,\n\t\t\t\t\tvalue: item.value,\n\t\t\t\t\tinvalid: resolvedInvalid,\n\t\t\t\t\tdisabled,\n\t\t\t\t\tonValueChange: (nextValue) => updateValue(index, nextValue),\n\t\t\t\t\tonBlur: field.onBlur,\n\t\t\t\t\t// React Hook Form owns one ref for the scalar array field.\n\t\t\t\t\t// Forward it only to the first focus target instead of\n\t\t\t\t\t// repeatedly replacing it with every rendered row.\n\t\t\t\t\tref: index === 0 ? field.ref : undefined,\n\t\t\t\t};\n\n\t\t\t\tif (renderField) return renderField(context);\n\n\t\t\t\treturn (\n\t\t\t\t\t<Input\n\t\t\t\t\t\tref={context.ref}\n\t\t\t\t\t\tname={context.name}\n\t\t\t\t\t\tvalue={context.value}\n\t\t\t\t\t\tonChange={(event) => context.onValueChange(event.target.value)}\n\t\t\t\t\t\tonBlur={context.onBlur}\n\t\t\t\t\t\tplaceholder={strings.placeholder}\n\t\t\t\t\t\tinvalid={context.invalid}\n\t\t\t\t\t\tdisabled={context.disabled}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nStringRepeater.displayName = 'StringRepeater';\n","/**\n * ObjectRepeater — RHF-driven repeater for arrays of homogeneous objects.\n * Field definitions describe the shape of each row (label, type, placeholder,\n * required, hint); the repeater wires each cell through `useFieldArray` and\n * renders rows as bordered cards via the shared `<Repeater>` primitive.\n * Strings overridable for i18n.\n */\nimport { type ReactNode, useCallback } from 'react';\nimport {\n\tuseFieldArray,\n\tuseFormContext,\n\ttype UseFormRegisterReturn,\n} from 'react-hook-form';\n\nimport { FormField } from '../forms/form-field';\nimport { Stack } from '../structure';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nimport { Input } from '../text-inputs';\nimport { Repeater } from './repeater';\nimport { defaultRepeaterStrings } from './repeaters.strings';\nimport { Textarea } from '../text-inputs';\n\nexport interface ObjectRepeaterStrings {\n\taddButton: string;\n\temptyState: string;\n\tremoveAriaLabel: string;\n\tdragHandleAriaLabel: string;\n}\n\nexport const defaultObjectRepeaterStrings: ObjectRepeaterStrings = {\n\taddButton: 'Add item',\n\tdragHandleAriaLabel: 'Drag to reorder',\n\t...defaultRepeaterStrings,\n};\n\nexport interface ObjectFieldDef {\n\t/** Field name within the object */\n\tname: string;\n\n\t/** Label for the field */\n\tlabel: string;\n\n\t/** Input type */\n\ttype?: 'text' | 'textarea' | 'number';\n\n\t/** Placeholder text */\n\tplaceholder?: string;\n\n\t/** Whether the field is required */\n\trequired?: boolean;\n\n\t/** Hint text (shown right of label) */\n\thint?: string;\n}\n\nexport interface ObjectRepeaterFieldRenderContext {\n\t/** Current object row position. */\n\tindex: number;\n\t/** Fully-qualified React Hook Form field path. */\n\tname: string;\n\t/** Registration props for the current field. */\n\tinputProps: UseFormRegisterReturn;\n\t/** Whether invalid styling should be applied. */\n\tinvalid: boolean;\n\t/** Whether editing is disabled. */\n\tdisabled: boolean;\n}\n\nexport interface ObjectRepeaterProps {\n\t/** React Hook Form field path pointing to an object array. */\n\tname: string;\n\t/** Definitions for each editable property in a row. */\n\tfields: ObjectFieldDef[];\n\t/** Force invalid styling for every field. */\n\tinvalid?: boolean;\n\t/** Disable editing, addition, removal, and sorting. */\n\tdisabled?: boolean;\n\t/** Enable drag-to-reorder. Default `false`. */\n\tsortable?: boolean;\n\t/** Replace the default field rendering while retaining array behavior. */\n\trenderField?: (\n\t\tfield: ObjectFieldDef,\n\t\tcontext: ObjectRepeaterFieldRenderContext,\n\t) => ReactNode;\n\t/** Override default strings (button labels, empty state). */\n\tstrings?: StringsProp<ObjectRepeaterStrings>;\n\t/** Class applied to the public repeater root. */\n\tclassName?: string;\n}\n\n/** React Hook Form object-array adapter using the canonical Repeater chrome. */\nexport function ObjectRepeater({\n\tname,\n\tfields: fieldDefs,\n\tinvalid,\n\tdisabled = false,\n\tsortable = false,\n\trenderField,\n\tstrings: stringsProp,\n\tclassName,\n}: ObjectRepeaterProps) {\n\tconst strings = useStrings(defaultObjectRepeaterStrings, stringsProp);\n\tconst { control, register } = useFormContext();\n\tconst { fields, append, remove, move } = useFieldArray({\n\t\tcontrol,\n\t\tname,\n\t});\n\n\tconst createEmptyObject = useCallback(() => {\n\t\treturn fieldDefs.reduce(\n\t\t\t(acc, field) => {\n\t\t\t\tacc[field.name] = '';\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{} as Record<string, string>\n\t\t);\n\t}, [fieldDefs]);\n\n\tconst sortingProps = sortable\n\t\t? { sortable: true as const, onMove: (from: number, to: number) => move(from, to) }\n\t\t: { sortable: false as const };\n\n\treturn (\n\t\t<Repeater\n\t\t\t{...sortingProps}\n\t\t\tclassName={cn('object-repeater--component', className)}\n\t\t\titems={fields}\n\t\t\trowVariant=\"card\"\n\t\t\tremoveVariant=\"ghost\"\n\t\t\tdisabled={disabled}\n\t\t\tonAdd={() => append(createEmptyObject())}\n\t\t\tonRemove={(index) => remove(index)}\n\t\t\tstrings={{\n\t\t\t\temptyState: strings.emptyState,\n\t\t\t\taddButton: strings.addButton,\n\t\t\t\tremoveAriaLabel: strings.removeAriaLabel,\n\t\t\t\tdragHandleAriaLabel: strings.dragHandleAriaLabel,\n\t\t\t}}\n\t\t\trenderRow={(_field, { index }) => (\n\t\t\t\t<Stack gap=\"lg\" className=\"object-repeater--fields\">\n\t\t\t\t\t{fieldDefs.map((fieldDef) => {\n\t\t\t\t\t\tconst fieldPath = `${name}.${index}.${fieldDef.name}`;\n\t\t\t\t\t\tconst inputProps = register(fieldPath);\n\t\t\t\t\t\tconst context: ObjectRepeaterFieldRenderContext = {\n\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\tname: fieldPath,\n\t\t\t\t\t\t\tinputProps,\n\t\t\t\t\t\t\tinvalid: Boolean(invalid),\n\t\t\t\t\t\t\tdisabled,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (renderField) {\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<div key={fieldDef.name} className=\"object-repeater--field\">\n\t\t\t\t\t\t\t\t\t{renderField(fieldDef, context)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tkey={fieldDef.name}\n\t\t\t\t\t\t\t\tlabel={fieldDef.label}\n\t\t\t\t\t\t\t\trequired={fieldDef.required}\n\t\t\t\t\t\t\t\thint={fieldDef.hint}\n\t\t\t\t\t\t\t\thtmlFor={fieldPath}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{fieldDef.type === 'textarea' ? (\n\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\t{...inputProps}\n\t\t\t\t\t\t\t\t\t\tid={fieldPath}\n\t\t\t\t\t\t\t\t\t\tplaceholder={fieldDef.placeholder}\n\t\t\t\t\t\t\t\t\t\tminRows={3}\n\t\t\t\t\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t{...inputProps}\n\t\t\t\t\t\t\t\t\t\tid={fieldPath}\n\t\t\t\t\t\t\t\t\t\ttype={fieldDef.type || 'text'}\n\t\t\t\t\t\t\t\t\t\tplaceholder={fieldDef.placeholder}\n\t\t\t\t\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</FormField>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</Stack>\n\t\t\t)}\n\t\t/>\n\t);\n}\n\nObjectRepeater.displayName = 'ObjectRepeater';\n","/**\n * KeyValueEditor — dynamic editor for arbitrary key→value string pairs. Emits\n * a `Record<string, string>` to consumers; rows with empty keys are dropped\n * from the output. Use for metadata, environment vars, or feature flags.\n *\n * Built on the shared `<Repeater>` primitive so it visually matches the\n * `StringRepeater` / `ObjectRepeater` / `LocalizedStringRepeater` family —\n * same row chrome, same remove icon, same add-button styling, optional\n * drag-to-reorder.\n */\nimport { forwardRef, useState, useRef, useCallback, memo } from 'react';\n\nimport { Label } from '../../typography';\nimport { affordanceGeometry } from '../../../lib/affordance-geometry.generated';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { useDensityConfig } from '../../../lib/ui-provider';\nimport { cn } from '../../../lib/utils';\n\nimport { Input } from '../text-inputs';\nimport { Repeater } from './repeater';\n\nexport type KeyValuePair = { key: string; value: string };\n\nexport interface KeyValueEditorStrings {\n\tkeyLabel: string;\n\tvalueLabel: string;\n\tkeyPlaceholder: string;\n\tvaluePlaceholder: string;\n\taddButton: string;\n\tremoveRowAriaLabel: string;\n\temptyState: string;\n}\n\nexport const defaultKeyValueEditorStrings: KeyValueEditorStrings = {\n\tkeyLabel: 'Key',\n\tvalueLabel: 'Value',\n\tkeyPlaceholder: 'key',\n\tvaluePlaceholder: 'value',\n\taddButton: 'Add row',\n\tremoveRowAriaLabel: 'Remove row',\n\temptyState: 'No rows yet.',\n};\n\nexport interface KeyValueEditorProps {\n\t/** Current value. Controlled. */\n\tvalue?: Record<string, string>;\n\tonValueChange?: (val: Record<string, string>) => void;\n\t/** Applies the invalid styling. */\n\tinvalid?: boolean;\n\t/** Enable drag-to-reorder. Default `false`. */\n\tsortable?: boolean;\n\t/** Override default strings (labels, placeholders, button text). */\n\tstrings?: StringsProp<KeyValueEditorStrings>;\n}\n\ntype KeyValueRow = KeyValuePair & { id: string };\n\nconst generateId = (): string => {\n\tif (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n\t\treturn crypto.randomUUID();\n\t}\n\treturn Math.random().toString(36).slice(2, 10);\n};\n\ninterface KeyValueEditorRowProps {\n\trow: KeyValueRow;\n\tkeyPlaceholder: string;\n\tvaluePlaceholder: string;\n\tkeyLabel: string;\n\tvalueLabel: string;\n\t/** Applies the invalid styling. */\n\tinvalid?: boolean;\n\tonKeyChange: (id: string, value: string) => void;\n\tonValueChange: (id: string, value: string) => void;\n}\n\nconst KeyValueEditorRow = memo(function KeyValueEditorRow({\n\trow,\n\tkeyPlaceholder,\n\tvaluePlaceholder,\n\tkeyLabel,\n\tvalueLabel,\n\tinvalid,\n\tonKeyChange,\n\tonValueChange,\n}: KeyValueEditorRowProps) {\n\tconst { id, key: keyValue, value } = row;\n\n\treturn (\n\t\t<div className={cn('key-value-editor--row', 'grid grid-cols-1 @md/key-value-editor:grid-cols-2 gap-space-md')}>\n\t\t\t<div className=\"grid min-w-0 gap-space-sm\">\n\t\t\t\t{!!keyLabel && <Label htmlFor={`${id}-key`} className=\"text-inherit @md/key-value-editor:sr-only\">{keyLabel}</Label>}\n\t\t\t\t<Input id={`${id}-key`} aria-label={keyLabel || keyPlaceholder} value={keyValue ?? ''} placeholder={keyPlaceholder} onChange={(event) => onKeyChange(id, event.target.value)} invalid={invalid} />\n\t\t\t</div>\n\t\t\t<div className=\"grid min-w-0 gap-space-sm\">\n\t\t\t\t{!!valueLabel && <Label htmlFor={`${id}-value`} className=\"text-inherit @md/key-value-editor:sr-only\">{valueLabel}</Label>}\n\t\t\t\t<Input id={`${id}-value`} aria-label={valueLabel || valuePlaceholder} value={value ?? ''} placeholder={valuePlaceholder} onChange={(event) => onValueChange(id, event.target.value)} invalid={invalid} />\n\t\t\t</div>\n\t\t</div>\n\t);\n});\n\nexport const KeyValueEditor = forwardRef<HTMLDivElement, KeyValueEditorProps>(function KeyValueEditor({\n\tvalue,\n\tonValueChange,\n\tinvalid,\n\tsortable = false,\n\tstrings: stringsProp,\n}: KeyValueEditorProps, ref) {\n\tconst strings = useStrings(defaultKeyValueEditorStrings, stringsProp);\n\tconst { defaultScale } = useDensityConfig();\n\t// Track if we're making internal changes to avoid re-syncing\n\tconst isInternalChange = useRef(false);\n\n\t// Initialize rows from value prop\n\tconst [rows, setRows] = useState<KeyValueRow[]>(() => {\n\t\tif (value && Object.keys(value).length > 0) {\n\t\t\treturn Object.entries(value).map(([k, v]) => ({\n\t\t\t\tid: generateId(),\n\t\t\t\tkey: k,\n\t\t\t\tvalue: String(v ?? ''),\n\t\t\t}));\n\t\t}\n\t\treturn [{ id: generateId(), key: '', value: '' }];\n\t});\n\n\t// Emit changes to parent\n\tconst emit = useCallback(\n\t\t(next: KeyValueRow[]) => {\n\t\t\tconst obj: Record<string, string> = {};\n\t\t\tnext.forEach(({ key, value }) => {\n\t\t\t\tif (key.trim() !== '') obj[key] = value ?? '';\n\t\t\t});\n\t\t\tisInternalChange.current = true;\n\t\t\tonValueChange?.(obj);\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tisInternalChange.current = false;\n\t\t\t});\n\t\t},\n\t\t[onValueChange]\n\t);\n\n\tconst handleKeyChange = useCallback(\n\t\t(id: string, newKey: string) => {\n\t\t\tsetRows((prev) => {\n\t\t\t\tconst next = prev.map((row) => (row.id === id ? { ...row, key: newKey } : row));\n\t\t\t\temit(next);\n\t\t\t\treturn next;\n\t\t\t});\n\t\t},\n\t\t[emit]\n\t);\n\n\tconst handleValueChange = useCallback(\n\t\t(id: string, newValue: string) => {\n\t\t\tsetRows((prev) => {\n\t\t\t\tconst next = prev.map((row) => (row.id === id ? { ...row, value: newValue } : row));\n\t\t\t\temit(next);\n\t\t\t\treturn next;\n\t\t\t});\n\t\t},\n\t\t[emit]\n\t);\n\n\tconst addRow = useCallback(() => {\n\t\tsetRows((prev) => {\n\t\t\tconst next = [...prev, { id: generateId(), key: '', value: '' }];\n\t\t\temit(next);\n\t\t\treturn next;\n\t\t});\n\t}, [emit]);\n\n\tconst removeRow = useCallback(\n\t\t(index: number) => {\n\t\t\tsetRows((prev) => {\n\t\t\t\tconst next = prev.filter((_, i) => i !== index);\n\t\t\t\tconst result = next.length ? next : [{ id: generateId(), key: '', value: '' }];\n\t\t\t\temit(result);\n\t\t\t\treturn result;\n\t\t\t});\n\t\t},\n\t\t[emit]\n\t);\n\n\tconst moveRow = useCallback(\n\t\t(from: number, to: number) => {\n\t\t\tsetRows((prev) => {\n\t\t\t\tconst next = [...prev];\n\t\t\t\tconst [moved] = next.splice(from, 1);\n\t\t\t\tnext.splice(to, 0, moved);\n\t\t\t\temit(next);\n\t\t\t\treturn next;\n\t\t\t});\n\t\t},\n\t\t[emit]\n\t);\n\n\t// Render the column labels OUTSIDE the repeater so the per-row drag\n\t// handle + remove button stay aligned with the input baseline. Gutter\n\t// padding follows the shared action height and row gap at each density.\n\t// Written from the root tokens (not the derived --spacing-* aliases, which\n\t// resolve at :root) so a scoped density or spacing keeps the columns aligned;\n\t// logical sides follow the row's reading direction.\n\tconst showHeader = !!strings.keyLabel || !!strings.valueLabel;\n\tconst gutter = affordanceGeometry.actionGutter[defaultScale === 'sm' || defaultScale === 'lg' ? defaultScale : 'md'];\n\tconst gutterClasses = { left: gutter.start, right: gutter.end };\n\tconst leftGutter = sortable ? gutterClasses.left : '';\n\tconst rightGutter = gutterClasses.right;\n\tconst sortingProps = sortable\n\t\t? { sortable: true as const, onMove: moveRow }\n\t\t: { sortable: false as const };\n\n\treturn (\n\t\t<div ref={ref} className=\"key-value-editor--component @container/key-value-editor space-y-space-sm\">\n\t\t\t{showHeader && (\n\t\t\t\t<div data-action-gutter className={cn('hidden @md/key-value-editor:grid grid-cols-2 gap-space-md', leftGutter, rightGutter)}>\n\t\t\t\t\t<div>{!!strings.keyLabel && <Label className=\"flex items-center text-inherit\">{strings.keyLabel}</Label>}</div>\n\t\t\t\t\t<div>{!!strings.valueLabel && <Label className=\"flex items-center text-inherit\">{strings.valueLabel}</Label>}</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<Repeater\n\t\t\t\t{...sortingProps}\n\t\t\t\titems={rows}\n\t\t\t\tonAdd={addRow}\n\t\t\t\tonRemove={removeRow}\n\t\t\t\tstrings={{\n\t\t\t\t\temptyState: strings.emptyState,\n\t\t\t\t\taddButton: strings.addButton,\n\t\t\t\t\tremoveAriaLabel: strings.removeRowAriaLabel,\n\t\t\t\t}}\n\t\t\t\trenderRow={(row) => (\n\t\t\t\t\t<KeyValueEditorRow\n\t\t\t\t\t\trow={row}\n\t\t\t\t\t\tkeyPlaceholder={strings.keyPlaceholder}\n\t\t\t\t\t\tvaluePlaceholder={strings.valuePlaceholder}\n\t\t\t\t\t\tkeyLabel={strings.keyLabel}\n\t\t\t\t\t\tvalueLabel={strings.valueLabel}\n\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\tonKeyChange={handleKeyChange}\n\t\t\t\t\t\tonValueChange={handleValueChange}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t/>\n\t\t</div>\n\t);\n});\n\nKeyValueEditor.displayName = 'KeyValueEditor';\n","import { useFormContext } from 'react-hook-form';\n\nimport { Input } from '../text-inputs';\nimport { Textarea } from '../text-inputs';\n\nimport { cn } from '../../../lib/utils';\nexport interface LocalizedStringFieldProps {\n\t/** Field name (path in form values) - should point to object with locale keys (e.g., 'en' and 'bg') */\n\tname: string;\n\n\t/** Input type */\n\ttype?: 'text' | 'textarea' | 'number';\n\n\t/** Placeholder text */\n\tplaceholder?: string;\n\n\t/** Primary locale code (e.g., 'en') */\n\tprimaryLocale: string;\n\n\t/** Secondary locale code (e.g., 'bg') */\n\tsecondaryLocale: string;\n\n\t/** Current active locale ('primary' or 'secondary') */\n\tactiveLocale: 'primary' | 'secondary';\n\n\t/** Error state for styling (passed from FormField) */\n\tinvalid?: boolean;\n\n\t/** Additional class names */\n\tclassName?: string;\n}\n\n/**\n * LocalizedStringField - Input for bilingual string fields\n */\nexport function LocalizedStringField({\n\tname,\n\ttype = 'text',\n\tplaceholder,\n\tprimaryLocale,\n\tsecondaryLocale,\n\tactiveLocale,\n\tinvalid,\n\tclassName,\n}: LocalizedStringFieldProps) {\n\tconst { register } = useFormContext();\n\n\tconst localeKey = activeLocale === 'primary' ? primaryLocale : secondaryLocale;\n\tconst fieldName = `${name}.${localeKey}`;\n\n\tif (type === 'textarea') {\n\t\treturn (\n\t\t\t<Textarea\n\t\t\t\tkey={fieldName}\n\t\t\t\t{...register(fieldName)}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tminRows={3}\n\t\t\t\tinvalid={invalid}\n\t\t\t\tclassName={cn('localized-string-field--component', className)}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Input\n\t\t\tkey={fieldName}\n\t\t\t\t{...register(fieldName)}\n\t\t\ttype={type === 'number' ? 'number' : 'text'}\n\t\t\tplaceholder={placeholder}\n\t\t\tinvalid={invalid}\n\t\t\tclassName={cn('localized-string-field--component', className)}\n\t\t/>\n\t);\n}\n\nLocalizedStringField.displayName = 'LocalizedStringField';\n","import { useFormContext } from 'react-hook-form';\n\nimport { Stack } from '../structure';\nimport { FormField } from '../forms';\nimport { cn } from '../../../lib/utils';\nimport { Input } from '../text-inputs';\nimport { Textarea } from '../text-inputs';\n\nexport interface LocalizedObjectFieldDef {\n\t/** Field name within the object */\n\tname: string;\n\n\t/** Label for the field */\n\tlabel: string;\n\n\t/** Input type */\n\ttype?: 'text' | 'textarea' | 'number';\n\n\t/** Placeholder text */\n\tplaceholder?: string;\n\n\t/** Whether the field is required */\n\trequired?: boolean;\n}\n\nexport interface LocalizedObjectFieldProps {\n\t/** Field name (path in form values) - should point to object with locale keys */\n\tname: string;\n\n\t/** Field definitions for the object properties */\n\tfields: LocalizedObjectFieldDef[];\n\n\t/** Primary locale code (e.g., 'en') */\n\tprimaryLocale: string;\n\n\t/** Secondary locale code (e.g., 'bg') */\n\tsecondaryLocale: string;\n\n\t/** Current active locale ('primary' or 'secondary') */\n\tactiveLocale: 'primary' | 'secondary';\n\n\t/** Error state for styling (passed from FormField) */\n\tinvalid?: boolean;\n\n\t/** Additional class names */\n\tclassName?: string;\n}\n\n/**\n * LocalizedObjectField - Input for bilingual object fields\n */\nexport function LocalizedObjectField({\n\tname,\n\tfields,\n\tprimaryLocale,\n\tsecondaryLocale,\n\tactiveLocale,\n\tinvalid,\n\tclassName,\n}: LocalizedObjectFieldProps) {\n\tconst { register } = useFormContext();\n\n\tconst localeKey = activeLocale === 'primary' ? primaryLocale : secondaryLocale;\n\n\treturn (\n\t\t<div className={cn('localized-object-field--component w-full rounded-surface border border-border p-surface', className)}>\n\t\t<Stack gap=\"lg\">\n\t\t\t{fields.map((field) => {\n\t\t\t\tconst fieldName = `${name}.${localeKey}.${field.name}`;\n\n\t\t\t\treturn (\n\t\t\t\t\t<FormField key={fieldName} label={field.label} htmlFor={fieldName} required={field.required} className=\"w-full\">\n\t\t\t\t\t\t{field.type === 'textarea' ? (\n\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t{...register(fieldName)}\n\t\t\t\t\t\t\t\tid={fieldName}\n\t\t\t\t\t\t\t\tplaceholder={field.placeholder}\n\t\t\t\t\t\t\t\tminRows={3}\n\t\t\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t{...register(fieldName)}\n\t\t\t\t\t\t\t\tid={fieldName}\n\t\t\t\t\t\t\t\ttype={field.type === 'number' ? 'number' : 'text'}\n\t\t\t\t\t\t\t\tplaceholder={field.placeholder}\n\t\t\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</FormField>\n\t\t\t\t);\n\t\t\t})}\n\t\t</Stack>\n\t\t</div>\n\t);\n}\n\nLocalizedObjectField.displayName = 'LocalizedObjectField';\n","/**\n * LocalizedStringRepeater — locale-path adapter over `<StringRepeater>`.\n * The canonical scalar-array engine stays in StringRepeater; this component\n * selects the active locale path and swaps the default Input for Textarea.\n */\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nimport {\n\tStringRepeater,\n\ttype StringRepeaterFieldRenderContext,\n} from './string-repeater';\nimport { defaultRepeaterStrings } from './repeaters.strings';\nimport { Textarea } from '../text-inputs';\n\nexport interface LocalizedStringRepeaterStrings {\n\t/** Placeholder shown in every localized textarea. */\n\tplaceholder: string;\n\t/** Label for the add-row action. */\n\taddButton: string;\n\t/** Copy shown when the active locale array is empty. */\n\temptyState: string;\n\t/** Accessible label for each remove action. */\n\tremoveAriaLabel: string;\n\t/** Accessible label for each drag handle. */\n\tdragHandleAriaLabel: string;\n}\n\nexport const defaultLocalizedStringRepeaterStrings: LocalizedStringRepeaterStrings = {\n\tplaceholder: 'Enter value',\n\taddButton: defaultRepeaterStrings.addItem,\n\temptyState: defaultRepeaterStrings.emptyState,\n\tremoveAriaLabel: defaultRepeaterStrings.removeAriaLabel,\n\tdragHandleAriaLabel: 'Drag to reorder',\n};\n\nexport interface LocalizedStringRepeaterProps {\n\t/** Field path pointing to an object of locale-keyed `string[]` values. */\n\tname: string;\n\t/** Primary locale key, for example `en`. */\n\tprimaryLocale: string;\n\t/** Secondary locale key, for example `bg`. */\n\tsecondaryLocale: string;\n\t/** Selects which locale array is currently editable. */\n\tactiveLocale: 'primary' | 'secondary';\n\t/** Enable drag-to-reorder. Default `false`. */\n\tsortable?: boolean;\n\t/** Force invalid styling in addition to React Hook Form state. */\n\tinvalid?: boolean;\n\t/** Disable editing and all row actions. */\n\tdisabled?: boolean;\n\t/** Override default strings. */\n\tstrings?: StringsProp<LocalizedStringRepeaterStrings>;\n\t/** Class applied to the public repeater root. */\n\tclassName?: string;\n}\n\n/** Locale-path adapter over the canonical StringRepeater array engine. */\nexport function LocalizedStringRepeater({\n\tname,\n\tprimaryLocale,\n\tsecondaryLocale,\n\tactiveLocale,\n\tinvalid,\n\tdisabled = false,\n\tsortable = false,\n\tstrings: stringsProp,\n\tclassName,\n}: LocalizedStringRepeaterProps) {\n\tconst strings = useStrings(defaultLocalizedStringRepeaterStrings, stringsProp);\n\tconst localeKey = activeLocale === 'primary' ? primaryLocale : secondaryLocale;\n\tconst fieldName = `${name}.${localeKey}`;\n\n\tconst renderTextarea = (context: StringRepeaterFieldRenderContext) => (\n\t\t<Textarea\n\t\t\tref={context.ref}\n\t\t\tname={context.name}\n\t\t\tvalue={context.value}\n\t\t\tonChange={(event) => context.onValueChange(event.target.value)}\n\t\t\tonBlur={context.onBlur}\n\t\t\tplaceholder={strings.placeholder}\n\t\t\tminRows={2}\n\t\t\tinvalid={context.invalid}\n\t\t\tdisabled={context.disabled}\n\t\t/>\n\t);\n\n\treturn (\n\t\t<StringRepeater\n\t\t\tname={fieldName}\n\t\t\tsortable={sortable}\n\t\t\tinvalid={invalid}\n\t\t\tdisabled={disabled}\n\t\t\tclassName={cn('localized-string-repeater--component', className)}\n\t\t\tstrings={strings}\n\t\t\trenderField={renderTextarea}\n\t\t/>\n\t);\n}\n\nLocalizedStringRepeater.displayName = 'LocalizedStringRepeater';\n"],"mappings":"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"}
|
package/dist/base/sheet.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c } from "../sheet-
|
|
2
|
+
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c } from "../sheet-BGPERY55.js";
|
|
3
3
|
export { c as Sheet, i as SheetBody, o as SheetClose, n as SheetContent, e as SheetDescription, a as SheetFooter, s as SheetHeader, t as SheetTitle, r as SheetTrigger };
|
package/dist/base/sidebar.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { C as e,
|
|
3
|
-
export {
|
|
2
|
+
import { C as e, O as t, S as n, T as r, _ as i, a, b as o, c as s, d as c, f as l, g as u, h as d, i as f, l as p, m, n as h, o as g, p as _, r as v, s as y, t as b, u as x, v as S, w as C, x as w, y as T } from "../sidebar-f9gRWXIR.js";
|
|
3
|
+
export { b as Sidebar, h as SidebarContent, v as SidebarFooter, f as SidebarGroup, a as SidebarGroupAction, g as SidebarGroupContent, y as SidebarGroupLabel, s as SidebarHeader, p as SidebarInput, x as SidebarInset, c as SidebarMenu, l as SidebarMenuAction, _ as SidebarMenuBadge, m as SidebarMenuButton, d as SidebarMenuItem, u as SidebarMenuSkeleton, i as SidebarMenuSub, S as SidebarMenuSubButton, T as SidebarMenuSubItem, o as SidebarProvider, w as SidebarRail, n as SidebarRegion, e as SidebarSeparator, C as SidebarTrigger, r as defaultSidebarStrings, t as useSidebar };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useStrings as e } from "../lib/strings.js";
|
|
3
|
-
import { t } from "../utils-
|
|
4
|
-
import { n } from "../buttons-
|
|
5
|
-
import { c as r } from "../typography-
|
|
6
|
-
import { t as i } from "../structure-
|
|
3
|
+
import { t } from "../utils-B6kKb8jB.js";
|
|
4
|
+
import { n } from "../buttons-BedGfygC.js";
|
|
5
|
+
import { c as r } from "../typography-BQnine1k.js";
|
|
6
|
+
import { t as i } from "../structure-DuxKl954.js";
|
|
7
7
|
import { t as a } from "../field-state-recipes-BVA2CWHo.js";
|
|
8
|
-
import { t as o } from "../input-
|
|
9
|
-
import { t as s } from "../form-field-
|
|
8
|
+
import { t as o } from "../input-CvyDQlY7.js";
|
|
9
|
+
import { t as s } from "../form-field-BriWAXyg.js";
|
|
10
10
|
import { forwardRef as c, useEffect as l, useId as u, useImperativeHandle as d, useLayoutEffect as ee, useMemo as te, useRef as f, useState as p } from "react";
|
|
11
11
|
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
12
12
|
//#region src/components/base/signature-pad/signature-pad.types.ts
|
|
@@ -208,7 +208,7 @@ var C = c(function(c, y) {
|
|
|
208
208
|
children: ge
|
|
209
209
|
}),
|
|
210
210
|
/* @__PURE__ */ h("div", {
|
|
211
|
-
className: t("signature-pad--area relative overflow-hidden rounded-
|
|
211
|
+
className: t("signature-pad--area relative overflow-hidden rounded-radius border border-input bg-background text-foreground transition-[color,box-shadow]", "has-[canvas:focus-visible]:border-ring has-[canvas:focus-visible]:ring-3 has-[canvas:focus-visible]:ring-ring/50", a.invalid, "aria-invalid:has-[canvas:focus-visible]:border-destructive aria-invalid:has-[canvas:focus-visible]:ring-destructive/30 dark:aria-invalid:has-[canvas:focus-visible]:ring-destructive/50", w && "cursor-not-allowed opacity-50"),
|
|
212
212
|
"aria-invalid": E || void 0,
|
|
213
213
|
children: [/* @__PURE__ */ m("canvas", {
|
|
214
214
|
ref: z,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature-pad.js","names":["Text","Stack","fieldStateRecipes","Input","FormField","defaultSignaturePadStrings","emptySignature","isSignatureEmpty","value","stroke","clamp","normalizeSignature","point","signatureFallbackFont","drawSignature","context","width","height","first","strokeWidth","i","a","b","maxWidth","fontSize","fontFamily","measured","escapeXml","text","character","signaturePadToSVG","signature","ink","index","SignaturePad","forwardRef","controlledValue","stringsProp","rootProps","props","controlled","internalValue","setInternalValue","useState","defaultValue","normalizedControlledValue","useMemo","valueRef","useRef","undoHistory","redoHistory","historyVersion","setHistoryVersion","live","drawing","setDrawing","canvasRef","fieldRef","typedRef","lastPublished","generatedId","useId","rootId","id","strings","useStrings","instructions","allowTypedSignature","locked","disabled","readOnly","inkWidth","paint","canvas","bounds","scale","style","cancelStroke","publish","normalized","next","history","onValueChange","version","undo","previous","redo","focus","useImperativeHandle","ref","snapshot","format","options","useEffect","redraw","resize","theme","ancestor","fonts","owner","active","resetTimer","reset","event","form","name","required","pointFrom","sample","finish","endpoint","last","empty","cn","className","invalid","samples","Button","SignaturePadPreview","pointIndex"],"sources":["../../src/components/base/signature-pad/signature-pad.types.ts","../../src/components/base/signature-pad/signature-pad.utils.ts","../../src/components/base/signature-pad/signature-pad.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef } from 'react';\nimport type { StringsProp } from '../../../lib/strings';\n\n/** Coordinates are fractions of the drawing area, so signatures survive resize. */\nexport interface SignaturePadPoint { x: number; y: number; pressure: number }\nexport interface SignaturePadStroke { points: readonly SignaturePadPoint[] }\nexport interface SignaturePadValue {\n\tstrokes: readonly SignaturePadStroke[];\n\t/** Accessible alternative to drawing; included in exports and native form data. */\n\ttypedName?: string;\n}\nexport type SignaturePadFormat = 'png' | 'svg' | 'json';\nexport interface SignaturePadExportOptions { width?: number; height?: number; scale?: number }\nexport interface SignaturePadHandle {\n\tfocus: () => void;\n\tclear: () => void;\n\tundo: () => void;\n\tredo: () => void;\n\t/** PNG is a data URL, SVG is markup, JSON is the structured value. */\n\tserialize: (format?: SignaturePadFormat, options?: SignaturePadExportOptions) => string;\n}\nexport interface SignaturePadStrings {\n\tlabel: string; instructions: string; drawingInstructions: string; placeholder: string; typedName: string;\n\tundo: string; redo: string; clear: string; empty: string; signed: string;\n}\nexport const defaultSignaturePadStrings: SignaturePadStrings = {\n\tlabel: 'Signature', instructions: 'Draw with a pointer or type your name below. Escape cancels a stroke; Control or Command Z undoes it.',\n\tdrawingInstructions: 'Draw with a pointer. Escape cancels a stroke; Control or Command Z undoes it.',\n\tplaceholder: 'Sign here', typedName: 'Or type your full name',\n\tundo: 'Undo', redo: 'Redo', clear: 'Clear signature', empty: 'Signature is empty', signed: 'Signature entered',\n};\nexport interface SignaturePadProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'defaultValue' | 'onChange'> {\n\t/** Controlled structured signature. */\n\tvalue?: SignaturePadValue;\n\t/** Initial structured signature for uncontrolled use. */\n\tdefaultValue?: SignaturePadValue;\n\tonValueChange?: (value: SignaturePadValue) => void;\n\tdisabled?: boolean;\n\treadOnly?: boolean;\n\tinvalid?: boolean;\n\t/** Native field serializes JSON; an empty signature fails required validation. */\n\tname?: string;\n\tform?: string;\n\trequired?: boolean;\n\t/**\n\t * Shows the keyboard-accessible typed signature alternative. The typed name is\n\t * drawn and exported in the pad's font family: the theme sans unless a font is\n\t * set on the pad through `className` or `style`. @default true\n\t */\n\tallowTypedSignature?: boolean;\n\t/** Ink diameter in CSS drawing pixels; pen pressure varies it. @default 2 */\n\tstrokeWidth?: number;\n\tstrings?: StringsProp<SignaturePadStrings>;\n}\nexport interface SignaturePadPreviewProps extends ComponentPropsWithoutRef<'svg'> {\n\tvalue: SignaturePadValue;\n\tstrokeWidth?: number;\n}\n","import type { SignaturePadValue } from './signature-pad.types';\n\nexport const emptySignature: SignaturePadValue = { strokes: [] };\nexport function isSignatureEmpty(value: SignaturePadValue): boolean {\n\treturn !value.typedName?.trim() && !value.strokes.some((stroke) => stroke.points.length > 0);\n}\nconst clamp = (value: number) => Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : 0;\nexport function normalizeSignature(value: SignaturePadValue): SignaturePadValue {\n\treturn {\n\t\tstrokes: value.strokes.filter((stroke) => stroke.points.length > 0).map((stroke) => ({\n\t\t\tpoints: stroke.points.map((point) => ({ x: clamp(point.x), y: clamp(point.y), pressure: clamp(point.pressure) })),\n\t\t})),\n\t\t...(value.typedName !== undefined ? { typedName: value.typedName } : {}),\n\t};\n}\n\n/**\n * A typed name is drawn in the field's own font family: the theme sans unless the\n * consumer sets a font on the pad. This fallback applies only outside the DOM.\n */\nexport const signatureFallbackFont = 'sans-serif';\n\n/** Drawing geometry, separate from structural UI spacing and theme tokens. */\nexport function drawSignature(context: CanvasRenderingContext2D, value: SignaturePadValue, width: number, height: number, strokeWidth: number, fontFamily = signatureFallbackFont) {\n\tcontext.clearRect(0, 0, width, height);\n\tcontext.lineCap = 'round';\n\tcontext.lineJoin = 'round';\n\tfor (const stroke of value.strokes) {\n\t\tconst first = stroke.points[0];\n\t\tif (!first) continue;\n\t\tif (stroke.points.length === 1) {\n\t\t\tcontext.beginPath();\n\t\t\tcontext.arc(first.x * width, first.y * height, strokeWidth * (0.5 + first.pressure) / 2, 0, Math.PI * 2);\n\t\t\tcontext.fill();\n\t\t}\n\t\tfor (let i = 1; i < stroke.points.length; i++) {\n\t\t\tconst a = stroke.points[i - 1]; const b = stroke.points[i];\n\t\t\tcontext.lineWidth = strokeWidth * (0.5 + (a.pressure + b.pressure) / 2);\n\t\t\tcontext.beginPath(); context.moveTo(a.x * width, a.y * height); context.lineTo(b.x * width, b.y * height); context.stroke();\n\t\t}\n\t}\n\tif (value.typedName) {\n\t\t// A long name steps the font down to fit before the canvas narrows its glyphs.\n\t\tconst maxWidth = width * 0.92;\n\t\tlet fontSize = Math.max(12, height / 5);\n\t\tcontext.font = `${fontSize}px ${fontFamily}`;\n\t\tconst measured = context.measureText?.(value.typedName).width ?? 0;\n\t\tif (measured > maxWidth) {\n\t\t\tfontSize = Math.max(12, fontSize * maxWidth / measured);\n\t\t\tcontext.font = `${fontSize}px ${fontFamily}`;\n\t\t}\n\t\tcontext.textBaseline = 'bottom';\n\t\tcontext.fillText(value.typedName, width * 0.04, height * 0.9, maxWidth);\n\t}\n}\n\nconst escapeXml = (text: string) => text.replace(/[&<>\"']/g, (character) => ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[character]!);\n/**\n * Semantic currentColor is preserved unless a resolved export ink is supplied. The\n * typed name uses `fontFamily`, which SignaturePad resolves from its rendered font.\n */\nexport function signaturePadToSVG(value: SignaturePadValue, width = 600, height = 200, strokeWidth = 2, ink = 'currentColor', fontFamily = signatureFallbackFont): string {\n\tconst signature = normalizeSignature(value);\n\tconst shapes = signature.strokes.map((stroke) => {\n\t\tconst first = stroke.points[0];\n\t\tif (stroke.points.length === 1) return `<circle cx=\"${first.x * width}\" cy=\"${first.y * height}\" r=\"${strokeWidth * (0.5 + first.pressure) / 2}\" fill=\"${escapeXml(ink)}\"/>`;\n\t\treturn stroke.points.slice(1).map((point, index) => {\n\t\t\tconst a = stroke.points[index];\n\t\t\treturn `<path d=\"M${a.x * width} ${a.y * height}L${point.x * width} ${point.y * height}\" fill=\"none\" stroke=\"${escapeXml(ink)}\" stroke-width=\"${strokeWidth * (0.5 + (a.pressure + point.pressure) / 2)}\" stroke-linecap=\"round\"/>`;\n\t\t}).join('');\n\t}).join('');\n\treturn `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\">${shapes}${signature.typedName ? `<text x=\"${width * 0.04}\" y=\"${height * 0.9}\" textLength=\"${Math.min(width * 0.92, signature.typedName.length * height * 0.1)}\" font-family=\"${escapeXml(fontFamily)}\" font-size=\"${Math.max(12, height / 5)}\" fill=\"${escapeXml(ink)}\">${escapeXml(signature.typedName)}</text>` : ''}</svg>`;\n}\n","import { forwardRef, useEffect, useLayoutEffect, useId, useImperativeHandle, useMemo, useRef, useState, type PointerEvent } from 'react';\nimport { Button } from '../buttons';\nimport { FormField } from '../forms/form-field';\nimport { Input } from '../text-inputs';\nimport { Stack } from '../structure';\nimport { Text } from '../../typography';\nimport { cn } from '../../../lib/utils';\nimport { useStrings } from '../../../lib/strings';\nimport { fieldStateRecipes } from '../../../lib/field-state-recipes';\nimport { defaultSignaturePadStrings, type SignaturePadHandle, type SignaturePadPoint, type SignaturePadProps, type SignaturePadPreviewProps, type SignaturePadValue } from './signature-pad.types';\nimport { drawSignature, emptySignature, isSignatureEmpty, normalizeSignature, signaturePadToSVG } from './signature-pad.utils';\n\nexport const SignaturePad = forwardRef<SignaturePadHandle, SignaturePadProps>(function SignaturePad(props, ref) {\n\tconst { value: controlledValue, defaultValue = emptySignature, onValueChange, disabled = false, readOnly = false, invalid,\n\t\tname, form, required, allowTypedSignature = true, strokeWidth = 2, strings: stringsProp, className, id, ...rootProps } = props;\n\tconst controlled = Object.prototype.hasOwnProperty.call(props, 'value');\n\tconst [internalValue, setInternalValue] = useState(() => normalizeSignature(defaultValue));\n\tconst normalizedControlledValue = useMemo(() => normalizeSignature(controlledValue ?? emptySignature), [controlledValue]);\n\tconst value = controlled ? normalizedControlledValue : internalValue;\n\tconst valueRef = useRef(value);\n\tuseLayoutEffect(() => { valueRef.current = value; }, [value]);\n\tconst undoHistory = useRef<SignaturePadValue[]>([]);\n\tconst redoHistory = useRef<SignaturePadValue[]>([]);\n\tconst [historyVersion, setHistoryVersion] = useState(0);\n\tconst live = useRef<{ pointerId: number; points: SignaturePadPoint[]; initial: SignaturePadValue } | null>(null);\n\tconst [drawing, setDrawing] = useState(false);\n\tconst canvasRef = useRef<HTMLCanvasElement>(null);\n\tconst fieldRef = useRef<HTMLInputElement>(null);\n\tconst typedRef = useRef<HTMLInputElement>(null);\n\tconst lastPublished = useRef<SignaturePadValue | null>(null);\n\tconst generatedId = useId();\n\tconst rootId = id ?? `signature-${generatedId}`;\n\tconst strings = useStrings(defaultSignaturePadStrings, stringsProp);\n\tconst instructions = allowTypedSignature ? strings.instructions : stringsProp?.instructions ?? strings.drawingInstructions;\n\tconst locked = disabled || readOnly;\n\tconst inkWidth = Number.isFinite(strokeWidth) ? Math.max(0.25, strokeWidth) : 2;\n\n\tconst paint = (signature: SignaturePadValue) => {\n\t\tconst canvas = canvasRef.current;\n\t\tif (!canvas) return;\n\t\tconst bounds = canvas.getBoundingClientRect();\n\t\tif (!bounds.width || !bounds.height) return;\n\t\tconst scale = window.devicePixelRatio || 1;\n\t\tif (canvas.width !== Math.round(bounds.width * scale)) canvas.width = Math.round(bounds.width * scale);\n\t\tif (canvas.height !== Math.round(bounds.height * scale)) canvas.height = Math.round(bounds.height * scale);\n\t\tconst context = canvas.getContext('2d');\n\t\tif (!context) return;\n\t\tcontext.setTransform(scale, 0, 0, scale, 0, 0);\n\t\tconst style = getComputedStyle(canvas);\n\t\tcontext.strokeStyle = context.fillStyle = style.color;\n\t\tdrawSignature(context, normalizeSignature(signature), bounds.width, bounds.height, inkWidth, style.fontFamily || undefined);\n\t};\n\tconst cancelStroke = () => {\n\t\tconst stroke = live.current;\n\t\tlive.current = null;\n\t\tsetDrawing(false);\n\t\tif (stroke && canvasRef.current?.hasPointerCapture?.(stroke.pointerId)) canvasRef.current.releasePointerCapture(stroke.pointerId);\n\t\tpaint(valueRef.current);\n\t};\n\tconst publish = (next: SignaturePadValue, history = true) => {\n\t\tif (locked) return;\n\t\tcancelStroke();\n\t\tconst normalized = normalizeSignature(next);\n\t\tif (history) { undoHistory.current.push(valueRef.current); redoHistory.current = []; }\n\t\tlastPublished.current = normalized;\n\t\tif (!controlled) { valueRef.current = normalized; setInternalValue(normalized); }\n\t\tonValueChange?.(normalized);\n\t\tsetHistoryVersion((version) => version + 1);\n\t};\n\tconst undo = () => {\n\t\tif (locked || !undoHistory.current.length) return;\n\t\tconst previous = undoHistory.current.pop()!;\n\t\tredoHistory.current.push(valueRef.current); publish(previous, false);\n\t};\n\tconst redo = () => {\n\t\tif (locked || !redoHistory.current.length) return;\n\t\tconst next = redoHistory.current.pop()!;\n\t\tundoHistory.current.push(valueRef.current); publish(next, false);\n\t};\n\tconst focus = () => (allowTypedSignature ? typedRef.current : canvasRef.current)?.focus();\n\tuseImperativeHandle(ref, () => ({ focus, undo, redo, clear: () => publish(emptySignature), serialize: (format = 'png', options = {}) => {\n\t\tconst snapshot = normalizeSignature(valueRef.current);\n\t\tif (format === 'json') return JSON.stringify(snapshot);\n\t\tconst bounds = canvasRef.current?.getBoundingClientRect();\n\t\tconst width = Number.isFinite(options.width) ? Math.max(1, options.width!) : bounds?.width || 600;\n\t\tconst height = Number.isFinite(options.height) ? Math.max(1, options.height!) : bounds?.height || 200;\n\t\tconst style = canvasRef.current ? getComputedStyle(canvasRef.current) : undefined;\n\t\tconst ink = style?.color || 'currentColor';\n\t\tconst fontFamily = style?.fontFamily || undefined;\n\t\tif (format === 'svg') return signaturePadToSVG(snapshot, width, height, inkWidth, ink, fontFamily);\n\t\tconst scale = Number.isFinite(options.scale) ? Math.max(0.1, Math.min(8, options.scale!)) : window.devicePixelRatio || 1;\n\t\tconst canvas = document.createElement('canvas'); canvas.width = Math.round(width * scale); canvas.height = Math.round(height * scale);\n\t\tconst context = canvas.getContext('2d');\n\t\tif (!context) throw new Error('Canvas export is unavailable in this environment. Use SVG or JSON.');\n\t\tcontext.scale(scale, scale); context.strokeStyle = context.fillStyle = ink;\n\t\tdrawSignature(context, snapshot, width, height, inkWidth, fontFamily);\n\t\treturn canvas.toDataURL('image/png');\n\t} }));\n\n\tuseEffect(() => {\n\t\t// External replacement invalidates history; an acknowledged controlled edit retains it.\n\t\tif (controlled && JSON.stringify(value) !== JSON.stringify(lastPublished.current)) { undoHistory.current = []; redoHistory.current = []; setHistoryVersion((version) => version + 1); }\n\t\tlastPublished.current = value;\n\t\tcancelStroke();\n\t}, [value, disabled, readOnly]);\n\tuseEffect(() => {\n\t\tconst canvas = canvasRef.current;\n\t\tif (!canvas) return;\n\t\tconst redraw = () => paint(live.current ? { ...live.current.initial, strokes: [...live.current.initial.strokes, { points: live.current.points }] } : valueRef.current);\n\t\tredraw();\n\t\tconst resize = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(redraw) : undefined;\n\t\tresize?.observe(canvas);\n\t\t// Theme scopes can change without resizing the drawing area.\n\t\tconst theme = new MutationObserver(redraw);\n\t\tfor (let ancestor: HTMLElement | null = canvas; ancestor; ancestor = ancestor.parentElement) theme.observe(ancestor, { attributes: true, attributeFilter: ['class', 'style', 'data-theme'] });\n\t\twindow.addEventListener('resize', redraw);\n\t\t// A typed name drawn before the theme font finished loading repaints in it.\n\t\tconst fonts = typeof document !== 'undefined' ? document.fonts : undefined;\n\t\tfonts?.addEventListener?.('loadingdone', redraw);\n\t\treturn () => { resize?.disconnect(); theme.disconnect(); window.removeEventListener('resize', redraw); fonts?.removeEventListener?.('loadingdone', redraw); };\n\t}, [inkWidth]);\n\tuseEffect(() => {\n\t\tconst owner = fieldRef.current?.form ?? typedRef.current?.form ?? canvasRef.current?.closest('form');\n\t\tlet active = true;\n\t\tlet resetTimer: ReturnType<typeof setTimeout> | undefined;\n\t\t// Trusted events can run microtasks between listeners. Wait for propagation and the native default action.\n\t\tconst reset = (event: Event) => {\n\t\t\tclearTimeout(resetTimer);\n\t\t\tresetTimer = setTimeout(() => { resetTimer = undefined; if (active && !event.defaultPrevented && !locked) { undoHistory.current = []; redoHistory.current = []; publish(defaultValue, false); } }, 0);\n\t\t};\n\t\towner?.addEventListener('reset', reset);\n\t\treturn () => { active = false; clearTimeout(resetTimer); owner?.removeEventListener('reset', reset); };\n\t}, [defaultValue, controlled, locked, onValueChange, form, name, required, allowTypedSignature]);\n\tconst pointFrom = (event: PointerEvent<HTMLCanvasElement>, sample: Pick<globalThis.PointerEvent, 'clientX' | 'clientY' | 'pressure'> = event): SignaturePadPoint => {\n\t\tconst bounds = event.currentTarget.getBoundingClientRect();\n\t\treturn { x: Math.max(0, Math.min(1, (sample.clientX - bounds.left) / (bounds.width || 1))), y: Math.max(0, Math.min(1, (sample.clientY - bounds.top) / (bounds.height || 1))), pressure: event.pointerType === 'pen' ? sample.pressure || 0.5 : 0.5 };\n\t};\n\tconst finish = (event: PointerEvent<HTMLCanvasElement>) => {\n\t\tconst stroke = live.current;\n\t\tif (!stroke || stroke.pointerId !== event.pointerId) return;\n\t\t// A lift can arrive beyond the last move; keep that endpoint without duplicating a resting tap.\n\t\tconst endpoint = pointFrom(event);\n\t\tconst last = stroke.points[stroke.points.length - 1];\n\t\tif (last.x !== endpoint.x || last.y !== endpoint.y) stroke.points.push(endpoint);\n\t\tlive.current = null;\n\t\tsetDrawing(false);\n\t\tif (valueRef.current === stroke.initial) publish({ ...stroke.initial, strokes: [...stroke.initial.strokes, { points: stroke.points }] });\n\t};\n\tconst empty = isSignatureEmpty(value);\n\treturn <Stack {...rootProps} id={rootId} role=\"group\" aria-label={rootProps['aria-label'] ?? strings.label} gap=\"sm\" className={cn('signature-pad--component min-w-0 font-sans', className)} data-history-version={historyVersion} data-disabled={disabled || undefined} data-readonly={readOnly || undefined}>\n\t\t<Text id={`${rootId}-instructions`} size=\"xs\" type=\"secondary\">{instructions}</Text>\n\t\t{/* The drawing area is the field frame: keyboard focus on the canvas draws the\n\t\t shared outer ring on the frame, like any other field, instead of an inset ring. */}\n\t\t<div className={cn('signature-pad--area relative overflow-hidden rounded-inner border border-input bg-background text-foreground transition-[color,box-shadow]', 'has-[canvas:focus-visible]:border-ring has-[canvas:focus-visible]:ring-3 has-[canvas:focus-visible]:ring-ring/50', fieldStateRecipes.invalid, 'aria-invalid:has-[canvas:focus-visible]:border-destructive aria-invalid:has-[canvas:focus-visible]:ring-destructive/30 dark:aria-invalid:has-[canvas:focus-visible]:ring-destructive/50', disabled && 'cursor-not-allowed opacity-50')} aria-invalid={invalid || undefined}>\n\t\t\t<canvas ref={canvasRef} className={cn('signature-pad--canvas block w-full aspect-[3/1] min-h-40 outline-none', !locked && 'touch-none cursor-crosshair')}\n\t\t\t\ttabIndex={disabled ? -1 : 0} role=\"img\" aria-label={strings.label} aria-describedby={`${rootId}-instructions ${rootId}-status`} aria-disabled={disabled || undefined} aria-invalid={invalid || undefined}\n\t\t\t\tonPointerDown={(event) => { if (locked || live.current || event.button !== 0) return; event.preventDefault(); event.currentTarget.focus(); event.currentTarget.setPointerCapture?.(event.pointerId); live.current = { pointerId: event.pointerId, points: [pointFrom(event)], initial: valueRef.current }; setDrawing(true); paint({ ...valueRef.current, strokes: [...valueRef.current.strokes, { points: live.current.points }] }); }}\n\t\t\t\tonPointerMove={(event) => {\n\t\t\t\t\tconst stroke = live.current;\n\t\t\t\t\tif (!stroke || stroke.pointerId !== event.pointerId) return;\n\t\t\t\t\tconst samples = event.nativeEvent.getCoalescedEvents?.().filter((sample) => sample.pointerId === stroke.pointerId) ?? [];\n\t\t\t\t\tfor (const sample of samples.length ? samples : [event.nativeEvent]) stroke.points.push(pointFrom(event, sample));\n\t\t\t\t\tpaint({ ...stroke.initial, strokes: [...stroke.initial.strokes, { points: stroke.points }] });\n\t\t\t\t}}\n\t\t\t\tonPointerUp={finish} onPointerCancel={(event) => { if (live.current?.pointerId === event.pointerId) cancelStroke(); }} onLostPointerCapture={(event) => { if (live.current?.pointerId === event.pointerId) cancelStroke(); }}\n\t\t\t\tonContextMenu={(event) => { if (live.current) event.preventDefault(); }}\n\t\t\t\tonKeyDown={(event) => { if (event.key === 'Escape') cancelStroke(); if (locked) return; if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'z') { event.preventDefault(); if (event.shiftKey) redo(); else undo(); } if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'y') { event.preventDefault(); redo(); } }}>\n\t\t\t\t{instructions}\n\t\t\t</canvas>\n\t\t\t{empty && !drawing && <div aria-hidden=\"true\" className=\"signature-pad--placeholder pointer-events-none absolute inset-0 flex items-center justify-center\"><Text type=\"secondary\">{strings.placeholder}</Text></div>}\n\t\t</div>\n\t\t{allowTypedSignature && <FormField label={strings.typedName} htmlFor={`${rootId}-typed`}><Input ref={typedRef} id={`${rootId}-typed`} value={value.typedName ?? ''} disabled={disabled} readOnly={readOnly} invalid={invalid} onChange={(event) => publish({ ...valueRef.current, typedName: event.target.value })} /></FormField>}\n\t\t<Stack direction=\"horizontal\" gap=\"xs\" wrap>\n\t\t\t<Button type=\"button\" buttonStyle=\"outline\" disabled={locked || !undoHistory.current.length} onClick={() => { undo(); focus(); }}>{strings.undo}</Button>\n\t\t\t<Button type=\"button\" buttonStyle=\"outline\" disabled={locked || !redoHistory.current.length} onClick={() => { redo(); focus(); }}>{strings.redo}</Button>\n\t\t\t<Button type=\"button\" buttonStyle=\"outline\" disabled={locked || empty} onClick={() => { publish(emptySignature); focus(); }}>{strings.clear}</Button>\n\t\t</Stack>\n\t\t<Text id={`${rootId}-status`} role=\"status\" size=\"xs\" type=\"secondary\">{empty ? strings.empty : strings.signed}</Text>\n\t\t{(name || required) && <input ref={fieldRef} className=\"sr-only\" type=\"text\" tabIndex={-1} aria-hidden=\"true\" name={name} form={form} disabled={disabled} readOnly={readOnly} required={required} value={empty ? '' : JSON.stringify(value)} onChange={() => {}} onFocus={focus} onInvalid={focus} />}\n\t</Stack>;\n});\n\n/** Server-renderable preview; normalized geometry follows the semantic foreground. */\nexport const SignaturePadPreview = forwardRef<SVGSVGElement, SignaturePadPreviewProps>(function SignaturePadPreview({ value, strokeWidth = 2, className, ...props }, ref) {\n\tconst normalized = normalizeSignature(value);\n\treturn <svg ref={ref} role=\"img\" viewBox=\"0 0 600 200\" aria-label=\"Signature\" {...props} className={cn('signature-pad-preview--component w-full h-auto font-sans text-foreground', className)}>\n\t\t{normalized.strokes.map((stroke, index) => stroke.points.length === 1 ? <circle key={index} cx={stroke.points[0].x * 600} cy={stroke.points[0].y * 200} r={strokeWidth * (0.5 + stroke.points[0].pressure) / 2} fill=\"currentColor\" /> : <g key={index}>{stroke.points.slice(1).map((point, pointIndex) => { const a = stroke.points[pointIndex]; return <path key={pointIndex} d={`M${a.x * 600} ${a.y * 200}L${point.x * 600} ${point.y * 200}`} fill=\"none\" stroke=\"currentColor\" strokeWidth={strokeWidth * (0.5 + (a.pressure + point.pressure) / 2)} strokeLinecap=\"round\" />; })}</g>)}\n\t\t{normalized.typedName && <text x=\"24\" y=\"180\" fill=\"currentColor\" fontSize=\"40\" textLength={Math.min(552, normalized.typedName.length * 20)}>{normalized.typedName}</text>}\n\t</svg>;\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"signature-pad.js","names":["Text","Stack","fieldStateRecipes","Input","FormField","defaultSignaturePadStrings","emptySignature","isSignatureEmpty","value","stroke","clamp","normalizeSignature","point","signatureFallbackFont","drawSignature","context","width","height","first","strokeWidth","i","a","b","maxWidth","fontSize","fontFamily","measured","escapeXml","text","character","signaturePadToSVG","signature","ink","index","SignaturePad","forwardRef","controlledValue","stringsProp","rootProps","props","controlled","internalValue","setInternalValue","useState","defaultValue","normalizedControlledValue","useMemo","valueRef","useRef","undoHistory","redoHistory","historyVersion","setHistoryVersion","live","drawing","setDrawing","canvasRef","fieldRef","typedRef","lastPublished","generatedId","useId","rootId","id","strings","useStrings","instructions","allowTypedSignature","locked","disabled","readOnly","inkWidth","paint","canvas","bounds","scale","style","cancelStroke","publish","normalized","next","history","onValueChange","version","undo","previous","redo","focus","useImperativeHandle","ref","snapshot","format","options","useEffect","redraw","resize","theme","ancestor","fonts","owner","active","resetTimer","reset","event","form","name","required","pointFrom","sample","finish","endpoint","last","empty","cn","className","invalid","samples","Button","SignaturePadPreview","pointIndex"],"sources":["../../src/components/base/signature-pad/signature-pad.types.ts","../../src/components/base/signature-pad/signature-pad.utils.ts","../../src/components/base/signature-pad/signature-pad.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef } from 'react';\nimport type { StringsProp } from '../../../lib/strings';\n\n/** Coordinates are fractions of the drawing area, so signatures survive resize. */\nexport interface SignaturePadPoint { x: number; y: number; pressure: number }\nexport interface SignaturePadStroke { points: readonly SignaturePadPoint[] }\nexport interface SignaturePadValue {\n\tstrokes: readonly SignaturePadStroke[];\n\t/** Accessible alternative to drawing; included in exports and native form data. */\n\ttypedName?: string;\n}\nexport type SignaturePadFormat = 'png' | 'svg' | 'json';\nexport interface SignaturePadExportOptions { width?: number; height?: number; scale?: number }\nexport interface SignaturePadHandle {\n\tfocus: () => void;\n\tclear: () => void;\n\tundo: () => void;\n\tredo: () => void;\n\t/** PNG is a data URL, SVG is markup, JSON is the structured value. */\n\tserialize: (format?: SignaturePadFormat, options?: SignaturePadExportOptions) => string;\n}\nexport interface SignaturePadStrings {\n\tlabel: string; instructions: string; drawingInstructions: string; placeholder: string; typedName: string;\n\tundo: string; redo: string; clear: string; empty: string; signed: string;\n}\nexport const defaultSignaturePadStrings: SignaturePadStrings = {\n\tlabel: 'Signature', instructions: 'Draw with a pointer or type your name below. Escape cancels a stroke; Control or Command Z undoes it.',\n\tdrawingInstructions: 'Draw with a pointer. Escape cancels a stroke; Control or Command Z undoes it.',\n\tplaceholder: 'Sign here', typedName: 'Or type your full name',\n\tundo: 'Undo', redo: 'Redo', clear: 'Clear signature', empty: 'Signature is empty', signed: 'Signature entered',\n};\nexport interface SignaturePadProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'defaultValue' | 'onChange'> {\n\t/** Controlled structured signature. */\n\tvalue?: SignaturePadValue;\n\t/** Initial structured signature for uncontrolled use. */\n\tdefaultValue?: SignaturePadValue;\n\tonValueChange?: (value: SignaturePadValue) => void;\n\tdisabled?: boolean;\n\treadOnly?: boolean;\n\tinvalid?: boolean;\n\t/** Native field serializes JSON; an empty signature fails required validation. */\n\tname?: string;\n\tform?: string;\n\trequired?: boolean;\n\t/**\n\t * Shows the keyboard-accessible typed signature alternative. The typed name is\n\t * drawn and exported in the pad's font family: the theme sans unless a font is\n\t * set on the pad through `className` or `style`. @default true\n\t */\n\tallowTypedSignature?: boolean;\n\t/** Ink diameter in CSS drawing pixels; pen pressure varies it. @default 2 */\n\tstrokeWidth?: number;\n\tstrings?: StringsProp<SignaturePadStrings>;\n}\nexport interface SignaturePadPreviewProps extends ComponentPropsWithoutRef<'svg'> {\n\tvalue: SignaturePadValue;\n\tstrokeWidth?: number;\n}\n","import type { SignaturePadValue } from './signature-pad.types';\n\nexport const emptySignature: SignaturePadValue = { strokes: [] };\nexport function isSignatureEmpty(value: SignaturePadValue): boolean {\n\treturn !value.typedName?.trim() && !value.strokes.some((stroke) => stroke.points.length > 0);\n}\nconst clamp = (value: number) => Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : 0;\nexport function normalizeSignature(value: SignaturePadValue): SignaturePadValue {\n\treturn {\n\t\tstrokes: value.strokes.filter((stroke) => stroke.points.length > 0).map((stroke) => ({\n\t\t\tpoints: stroke.points.map((point) => ({ x: clamp(point.x), y: clamp(point.y), pressure: clamp(point.pressure) })),\n\t\t})),\n\t\t...(value.typedName !== undefined ? { typedName: value.typedName } : {}),\n\t};\n}\n\n/**\n * A typed name is drawn in the field's own font family: the theme sans unless the\n * consumer sets a font on the pad. This fallback applies only outside the DOM.\n */\nexport const signatureFallbackFont = 'sans-serif';\n\n/** Drawing geometry, separate from structural UI spacing and theme tokens. */\nexport function drawSignature(context: CanvasRenderingContext2D, value: SignaturePadValue, width: number, height: number, strokeWidth: number, fontFamily = signatureFallbackFont) {\n\tcontext.clearRect(0, 0, width, height);\n\tcontext.lineCap = 'round';\n\tcontext.lineJoin = 'round';\n\tfor (const stroke of value.strokes) {\n\t\tconst first = stroke.points[0];\n\t\tif (!first) continue;\n\t\tif (stroke.points.length === 1) {\n\t\t\tcontext.beginPath();\n\t\t\tcontext.arc(first.x * width, first.y * height, strokeWidth * (0.5 + first.pressure) / 2, 0, Math.PI * 2);\n\t\t\tcontext.fill();\n\t\t}\n\t\tfor (let i = 1; i < stroke.points.length; i++) {\n\t\t\tconst a = stroke.points[i - 1]; const b = stroke.points[i];\n\t\t\tcontext.lineWidth = strokeWidth * (0.5 + (a.pressure + b.pressure) / 2);\n\t\t\tcontext.beginPath(); context.moveTo(a.x * width, a.y * height); context.lineTo(b.x * width, b.y * height); context.stroke();\n\t\t}\n\t}\n\tif (value.typedName) {\n\t\t// A long name steps the font down to fit before the canvas narrows its glyphs.\n\t\tconst maxWidth = width * 0.92;\n\t\tlet fontSize = Math.max(12, height / 5);\n\t\tcontext.font = `${fontSize}px ${fontFamily}`;\n\t\tconst measured = context.measureText?.(value.typedName).width ?? 0;\n\t\tif (measured > maxWidth) {\n\t\t\tfontSize = Math.max(12, fontSize * maxWidth / measured);\n\t\t\tcontext.font = `${fontSize}px ${fontFamily}`;\n\t\t}\n\t\tcontext.textBaseline = 'bottom';\n\t\tcontext.fillText(value.typedName, width * 0.04, height * 0.9, maxWidth);\n\t}\n}\n\nconst escapeXml = (text: string) => text.replace(/[&<>\"']/g, (character) => ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[character]!);\n/**\n * Semantic currentColor is preserved unless a resolved export ink is supplied. The\n * typed name uses `fontFamily`, which SignaturePad resolves from its rendered font.\n */\nexport function signaturePadToSVG(value: SignaturePadValue, width = 600, height = 200, strokeWidth = 2, ink = 'currentColor', fontFamily = signatureFallbackFont): string {\n\tconst signature = normalizeSignature(value);\n\tconst shapes = signature.strokes.map((stroke) => {\n\t\tconst first = stroke.points[0];\n\t\tif (stroke.points.length === 1) return `<circle cx=\"${first.x * width}\" cy=\"${first.y * height}\" r=\"${strokeWidth * (0.5 + first.pressure) / 2}\" fill=\"${escapeXml(ink)}\"/>`;\n\t\treturn stroke.points.slice(1).map((point, index) => {\n\t\t\tconst a = stroke.points[index];\n\t\t\treturn `<path d=\"M${a.x * width} ${a.y * height}L${point.x * width} ${point.y * height}\" fill=\"none\" stroke=\"${escapeXml(ink)}\" stroke-width=\"${strokeWidth * (0.5 + (a.pressure + point.pressure) / 2)}\" stroke-linecap=\"round\"/>`;\n\t\t}).join('');\n\t}).join('');\n\treturn `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\">${shapes}${signature.typedName ? `<text x=\"${width * 0.04}\" y=\"${height * 0.9}\" textLength=\"${Math.min(width * 0.92, signature.typedName.length * height * 0.1)}\" font-family=\"${escapeXml(fontFamily)}\" font-size=\"${Math.max(12, height / 5)}\" fill=\"${escapeXml(ink)}\">${escapeXml(signature.typedName)}</text>` : ''}</svg>`;\n}\n","import { forwardRef, useEffect, useLayoutEffect, useId, useImperativeHandle, useMemo, useRef, useState, type PointerEvent } from 'react';\nimport { Button } from '../buttons';\nimport { FormField } from '../forms/form-field';\nimport { Input } from '../text-inputs';\nimport { Stack } from '../structure';\nimport { Text } from '../../typography';\nimport { cn } from '../../../lib/utils';\nimport { useStrings } from '../../../lib/strings';\nimport { fieldStateRecipes } from '../../../lib/field-state-recipes';\nimport { defaultSignaturePadStrings, type SignaturePadHandle, type SignaturePadPoint, type SignaturePadProps, type SignaturePadPreviewProps, type SignaturePadValue } from './signature-pad.types';\nimport { drawSignature, emptySignature, isSignatureEmpty, normalizeSignature, signaturePadToSVG } from './signature-pad.utils';\n\nexport const SignaturePad = forwardRef<SignaturePadHandle, SignaturePadProps>(function SignaturePad(props, ref) {\n\tconst { value: controlledValue, defaultValue = emptySignature, onValueChange, disabled = false, readOnly = false, invalid,\n\t\tname, form, required, allowTypedSignature = true, strokeWidth = 2, strings: stringsProp, className, id, ...rootProps } = props;\n\tconst controlled = Object.prototype.hasOwnProperty.call(props, 'value');\n\tconst [internalValue, setInternalValue] = useState(() => normalizeSignature(defaultValue));\n\tconst normalizedControlledValue = useMemo(() => normalizeSignature(controlledValue ?? emptySignature), [controlledValue]);\n\tconst value = controlled ? normalizedControlledValue : internalValue;\n\tconst valueRef = useRef(value);\n\tuseLayoutEffect(() => { valueRef.current = value; }, [value]);\n\tconst undoHistory = useRef<SignaturePadValue[]>([]);\n\tconst redoHistory = useRef<SignaturePadValue[]>([]);\n\tconst [historyVersion, setHistoryVersion] = useState(0);\n\tconst live = useRef<{ pointerId: number; points: SignaturePadPoint[]; initial: SignaturePadValue } | null>(null);\n\tconst [drawing, setDrawing] = useState(false);\n\tconst canvasRef = useRef<HTMLCanvasElement>(null);\n\tconst fieldRef = useRef<HTMLInputElement>(null);\n\tconst typedRef = useRef<HTMLInputElement>(null);\n\tconst lastPublished = useRef<SignaturePadValue | null>(null);\n\tconst generatedId = useId();\n\tconst rootId = id ?? `signature-${generatedId}`;\n\tconst strings = useStrings(defaultSignaturePadStrings, stringsProp);\n\tconst instructions = allowTypedSignature ? strings.instructions : stringsProp?.instructions ?? strings.drawingInstructions;\n\tconst locked = disabled || readOnly;\n\tconst inkWidth = Number.isFinite(strokeWidth) ? Math.max(0.25, strokeWidth) : 2;\n\n\tconst paint = (signature: SignaturePadValue) => {\n\t\tconst canvas = canvasRef.current;\n\t\tif (!canvas) return;\n\t\tconst bounds = canvas.getBoundingClientRect();\n\t\tif (!bounds.width || !bounds.height) return;\n\t\tconst scale = window.devicePixelRatio || 1;\n\t\tif (canvas.width !== Math.round(bounds.width * scale)) canvas.width = Math.round(bounds.width * scale);\n\t\tif (canvas.height !== Math.round(bounds.height * scale)) canvas.height = Math.round(bounds.height * scale);\n\t\tconst context = canvas.getContext('2d');\n\t\tif (!context) return;\n\t\tcontext.setTransform(scale, 0, 0, scale, 0, 0);\n\t\tconst style = getComputedStyle(canvas);\n\t\tcontext.strokeStyle = context.fillStyle = style.color;\n\t\tdrawSignature(context, normalizeSignature(signature), bounds.width, bounds.height, inkWidth, style.fontFamily || undefined);\n\t};\n\tconst cancelStroke = () => {\n\t\tconst stroke = live.current;\n\t\tlive.current = null;\n\t\tsetDrawing(false);\n\t\tif (stroke && canvasRef.current?.hasPointerCapture?.(stroke.pointerId)) canvasRef.current.releasePointerCapture(stroke.pointerId);\n\t\tpaint(valueRef.current);\n\t};\n\tconst publish = (next: SignaturePadValue, history = true) => {\n\t\tif (locked) return;\n\t\tcancelStroke();\n\t\tconst normalized = normalizeSignature(next);\n\t\tif (history) { undoHistory.current.push(valueRef.current); redoHistory.current = []; }\n\t\tlastPublished.current = normalized;\n\t\tif (!controlled) { valueRef.current = normalized; setInternalValue(normalized); }\n\t\tonValueChange?.(normalized);\n\t\tsetHistoryVersion((version) => version + 1);\n\t};\n\tconst undo = () => {\n\t\tif (locked || !undoHistory.current.length) return;\n\t\tconst previous = undoHistory.current.pop()!;\n\t\tredoHistory.current.push(valueRef.current); publish(previous, false);\n\t};\n\tconst redo = () => {\n\t\tif (locked || !redoHistory.current.length) return;\n\t\tconst next = redoHistory.current.pop()!;\n\t\tundoHistory.current.push(valueRef.current); publish(next, false);\n\t};\n\tconst focus = () => (allowTypedSignature ? typedRef.current : canvasRef.current)?.focus();\n\tuseImperativeHandle(ref, () => ({ focus, undo, redo, clear: () => publish(emptySignature), serialize: (format = 'png', options = {}) => {\n\t\tconst snapshot = normalizeSignature(valueRef.current);\n\t\tif (format === 'json') return JSON.stringify(snapshot);\n\t\tconst bounds = canvasRef.current?.getBoundingClientRect();\n\t\tconst width = Number.isFinite(options.width) ? Math.max(1, options.width!) : bounds?.width || 600;\n\t\tconst height = Number.isFinite(options.height) ? Math.max(1, options.height!) : bounds?.height || 200;\n\t\tconst style = canvasRef.current ? getComputedStyle(canvasRef.current) : undefined;\n\t\tconst ink = style?.color || 'currentColor';\n\t\tconst fontFamily = style?.fontFamily || undefined;\n\t\tif (format === 'svg') return signaturePadToSVG(snapshot, width, height, inkWidth, ink, fontFamily);\n\t\tconst scale = Number.isFinite(options.scale) ? Math.max(0.1, Math.min(8, options.scale!)) : window.devicePixelRatio || 1;\n\t\tconst canvas = document.createElement('canvas'); canvas.width = Math.round(width * scale); canvas.height = Math.round(height * scale);\n\t\tconst context = canvas.getContext('2d');\n\t\tif (!context) throw new Error('Canvas export is unavailable in this environment. Use SVG or JSON.');\n\t\tcontext.scale(scale, scale); context.strokeStyle = context.fillStyle = ink;\n\t\tdrawSignature(context, snapshot, width, height, inkWidth, fontFamily);\n\t\treturn canvas.toDataURL('image/png');\n\t} }));\n\n\tuseEffect(() => {\n\t\t// External replacement invalidates history; an acknowledged controlled edit retains it.\n\t\tif (controlled && JSON.stringify(value) !== JSON.stringify(lastPublished.current)) { undoHistory.current = []; redoHistory.current = []; setHistoryVersion((version) => version + 1); }\n\t\tlastPublished.current = value;\n\t\tcancelStroke();\n\t}, [value, disabled, readOnly]);\n\tuseEffect(() => {\n\t\tconst canvas = canvasRef.current;\n\t\tif (!canvas) return;\n\t\tconst redraw = () => paint(live.current ? { ...live.current.initial, strokes: [...live.current.initial.strokes, { points: live.current.points }] } : valueRef.current);\n\t\tredraw();\n\t\tconst resize = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(redraw) : undefined;\n\t\tresize?.observe(canvas);\n\t\t// Theme scopes can change without resizing the drawing area.\n\t\tconst theme = new MutationObserver(redraw);\n\t\tfor (let ancestor: HTMLElement | null = canvas; ancestor; ancestor = ancestor.parentElement) theme.observe(ancestor, { attributes: true, attributeFilter: ['class', 'style', 'data-theme'] });\n\t\twindow.addEventListener('resize', redraw);\n\t\t// A typed name drawn before the theme font finished loading repaints in it.\n\t\tconst fonts = typeof document !== 'undefined' ? document.fonts : undefined;\n\t\tfonts?.addEventListener?.('loadingdone', redraw);\n\t\treturn () => { resize?.disconnect(); theme.disconnect(); window.removeEventListener('resize', redraw); fonts?.removeEventListener?.('loadingdone', redraw); };\n\t}, [inkWidth]);\n\tuseEffect(() => {\n\t\tconst owner = fieldRef.current?.form ?? typedRef.current?.form ?? canvasRef.current?.closest('form');\n\t\tlet active = true;\n\t\tlet resetTimer: ReturnType<typeof setTimeout> | undefined;\n\t\t// Trusted events can run microtasks between listeners. Wait for propagation and the native default action.\n\t\tconst reset = (event: Event) => {\n\t\t\tclearTimeout(resetTimer);\n\t\t\tresetTimer = setTimeout(() => { resetTimer = undefined; if (active && !event.defaultPrevented && !locked) { undoHistory.current = []; redoHistory.current = []; publish(defaultValue, false); } }, 0);\n\t\t};\n\t\towner?.addEventListener('reset', reset);\n\t\treturn () => { active = false; clearTimeout(resetTimer); owner?.removeEventListener('reset', reset); };\n\t}, [defaultValue, controlled, locked, onValueChange, form, name, required, allowTypedSignature]);\n\tconst pointFrom = (event: PointerEvent<HTMLCanvasElement>, sample: Pick<globalThis.PointerEvent, 'clientX' | 'clientY' | 'pressure'> = event): SignaturePadPoint => {\n\t\tconst bounds = event.currentTarget.getBoundingClientRect();\n\t\treturn { x: Math.max(0, Math.min(1, (sample.clientX - bounds.left) / (bounds.width || 1))), y: Math.max(0, Math.min(1, (sample.clientY - bounds.top) / (bounds.height || 1))), pressure: event.pointerType === 'pen' ? sample.pressure || 0.5 : 0.5 };\n\t};\n\tconst finish = (event: PointerEvent<HTMLCanvasElement>) => {\n\t\tconst stroke = live.current;\n\t\tif (!stroke || stroke.pointerId !== event.pointerId) return;\n\t\t// A lift can arrive beyond the last move; keep that endpoint without duplicating a resting tap.\n\t\tconst endpoint = pointFrom(event);\n\t\tconst last = stroke.points[stroke.points.length - 1];\n\t\tif (last.x !== endpoint.x || last.y !== endpoint.y) stroke.points.push(endpoint);\n\t\tlive.current = null;\n\t\tsetDrawing(false);\n\t\tif (valueRef.current === stroke.initial) publish({ ...stroke.initial, strokes: [...stroke.initial.strokes, { points: stroke.points }] });\n\t};\n\tconst empty = isSignatureEmpty(value);\n\treturn <Stack {...rootProps} id={rootId} role=\"group\" aria-label={rootProps['aria-label'] ?? strings.label} gap=\"sm\" className={cn('signature-pad--component min-w-0 font-sans', className)} data-history-version={historyVersion} data-disabled={disabled || undefined} data-readonly={readOnly || undefined}>\n\t\t<Text id={`${rootId}-instructions`} size=\"xs\" type=\"secondary\">{instructions}</Text>\n\t\t{/* The drawing area is the field frame: keyboard focus on the canvas draws the\n\t\t shared outer ring on the frame, like any other field, instead of an inset ring. */}\n\t\t<div className={cn('signature-pad--area relative overflow-hidden rounded-radius border border-input bg-background text-foreground transition-[color,box-shadow]', 'has-[canvas:focus-visible]:border-ring has-[canvas:focus-visible]:ring-3 has-[canvas:focus-visible]:ring-ring/50', fieldStateRecipes.invalid, 'aria-invalid:has-[canvas:focus-visible]:border-destructive aria-invalid:has-[canvas:focus-visible]:ring-destructive/30 dark:aria-invalid:has-[canvas:focus-visible]:ring-destructive/50', disabled && 'cursor-not-allowed opacity-50')} aria-invalid={invalid || undefined}>\n\t\t\t<canvas ref={canvasRef} className={cn('signature-pad--canvas block w-full aspect-[3/1] min-h-40 outline-none', !locked && 'touch-none cursor-crosshair')}\n\t\t\t\ttabIndex={disabled ? -1 : 0} role=\"img\" aria-label={strings.label} aria-describedby={`${rootId}-instructions ${rootId}-status`} aria-disabled={disabled || undefined} aria-invalid={invalid || undefined}\n\t\t\t\tonPointerDown={(event) => { if (locked || live.current || event.button !== 0) return; event.preventDefault(); event.currentTarget.focus(); event.currentTarget.setPointerCapture?.(event.pointerId); live.current = { pointerId: event.pointerId, points: [pointFrom(event)], initial: valueRef.current }; setDrawing(true); paint({ ...valueRef.current, strokes: [...valueRef.current.strokes, { points: live.current.points }] }); }}\n\t\t\t\tonPointerMove={(event) => {\n\t\t\t\t\tconst stroke = live.current;\n\t\t\t\t\tif (!stroke || stroke.pointerId !== event.pointerId) return;\n\t\t\t\t\tconst samples = event.nativeEvent.getCoalescedEvents?.().filter((sample) => sample.pointerId === stroke.pointerId) ?? [];\n\t\t\t\t\tfor (const sample of samples.length ? samples : [event.nativeEvent]) stroke.points.push(pointFrom(event, sample));\n\t\t\t\t\tpaint({ ...stroke.initial, strokes: [...stroke.initial.strokes, { points: stroke.points }] });\n\t\t\t\t}}\n\t\t\t\tonPointerUp={finish} onPointerCancel={(event) => { if (live.current?.pointerId === event.pointerId) cancelStroke(); }} onLostPointerCapture={(event) => { if (live.current?.pointerId === event.pointerId) cancelStroke(); }}\n\t\t\t\tonContextMenu={(event) => { if (live.current) event.preventDefault(); }}\n\t\t\t\tonKeyDown={(event) => { if (event.key === 'Escape') cancelStroke(); if (locked) return; if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'z') { event.preventDefault(); if (event.shiftKey) redo(); else undo(); } if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'y') { event.preventDefault(); redo(); } }}>\n\t\t\t\t{instructions}\n\t\t\t</canvas>\n\t\t\t{empty && !drawing && <div aria-hidden=\"true\" className=\"signature-pad--placeholder pointer-events-none absolute inset-0 flex items-center justify-center\"><Text type=\"secondary\">{strings.placeholder}</Text></div>}\n\t\t</div>\n\t\t{allowTypedSignature && <FormField label={strings.typedName} htmlFor={`${rootId}-typed`}><Input ref={typedRef} id={`${rootId}-typed`} value={value.typedName ?? ''} disabled={disabled} readOnly={readOnly} invalid={invalid} onChange={(event) => publish({ ...valueRef.current, typedName: event.target.value })} /></FormField>}\n\t\t<Stack direction=\"horizontal\" gap=\"xs\" wrap>\n\t\t\t<Button type=\"button\" buttonStyle=\"outline\" disabled={locked || !undoHistory.current.length} onClick={() => { undo(); focus(); }}>{strings.undo}</Button>\n\t\t\t<Button type=\"button\" buttonStyle=\"outline\" disabled={locked || !redoHistory.current.length} onClick={() => { redo(); focus(); }}>{strings.redo}</Button>\n\t\t\t<Button type=\"button\" buttonStyle=\"outline\" disabled={locked || empty} onClick={() => { publish(emptySignature); focus(); }}>{strings.clear}</Button>\n\t\t</Stack>\n\t\t<Text id={`${rootId}-status`} role=\"status\" size=\"xs\" type=\"secondary\">{empty ? strings.empty : strings.signed}</Text>\n\t\t{(name || required) && <input ref={fieldRef} className=\"sr-only\" type=\"text\" tabIndex={-1} aria-hidden=\"true\" name={name} form={form} disabled={disabled} readOnly={readOnly} required={required} value={empty ? '' : JSON.stringify(value)} onChange={() => {}} onFocus={focus} onInvalid={focus} />}\n\t</Stack>;\n});\n\n/** Server-renderable preview; normalized geometry follows the semantic foreground. */\nexport const SignaturePadPreview = forwardRef<SVGSVGElement, SignaturePadPreviewProps>(function SignaturePadPreview({ value, strokeWidth = 2, className, ...props }, ref) {\n\tconst normalized = normalizeSignature(value);\n\treturn <svg ref={ref} role=\"img\" viewBox=\"0 0 600 200\" aria-label=\"Signature\" {...props} className={cn('signature-pad-preview--component w-full h-auto font-sans text-foreground', className)}>\n\t\t{normalized.strokes.map((stroke, index) => stroke.points.length === 1 ? <circle key={index} cx={stroke.points[0].x * 600} cy={stroke.points[0].y * 200} r={strokeWidth * (0.5 + stroke.points[0].pressure) / 2} fill=\"currentColor\" /> : <g key={index}>{stroke.points.slice(1).map((point, pointIndex) => { const a = stroke.points[pointIndex]; return <path key={pointIndex} d={`M${a.x * 600} ${a.y * 200}L${point.x * 600} ${point.y * 200}`} fill=\"none\" stroke=\"currentColor\" strokeWidth={strokeWidth * (0.5 + (a.pressure + point.pressure) / 2)} strokeLinecap=\"round\" />; })}</g>)}\n\t\t{normalized.typedName && <text x=\"24\" y=\"180\" fill=\"currentColor\" fontSize=\"40\" textLength={Math.min(552, normalized.typedName.length * 20)}>{normalized.typedName}</text>}\n\t</svg>;\n});\n"],"mappings":";;;;;;;;;;;;AAyBA,IAAaK,IAAkD;CAC9D,OAAO;CAAa,cAAc;CAClC,qBAAqB;CACrB,aAAa;CAAa,WAAW;CACrC,MAAM;CAAQ,MAAM;CAAQ,OAAO;CAAmB,OAAO;CAAsB,QAAQ;AAC5F,GC5BaC,IAAoC,EAAE,SAAS,CAAC,EAAE;AAC/D,SAAgBC,EAAiB,GAAmC;CACnE,OAAO,CAACC,EAAM,WAAW,KAAK,KAAK,CAACA,EAAM,QAAQ,MAAM,MAAWC,EAAO,OAAO,SAAS,CAAC;AAC5F;AACA,IAAMC,KAAS,MAAkB,OAAO,SAASF,CAAK,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGA,CAAK,CAAC,IAAI;AAC5F,SAAgBG,EAAmB,GAA6C;CAC/E,OAAO;EACN,SAASH,EAAM,QAAQ,QAAQ,MAAWC,EAAO,OAAO,SAAS,CAAC,CAAC,CAAC,KAAK,OAAY,EACpF,QAAQA,EAAO,OAAO,KAAK,OAAW;GAAE,GAAGC,EAAME,EAAM,CAAC;GAAG,GAAGF,EAAME,EAAM,CAAC;GAAG,UAAUF,EAAME,EAAM,QAAQ;EAAE,EAAE,EACjH,EAAE;EACF,GAAIJ,EAAM,cAAc,KAAA,IAA6C,CAAC,IAAlC,EAAE,WAAWA,EAAM,UAAU;CAClE;AACD;AAMA,IAAaK,IAAwB;AAGrC,SAAgBC,GAAc,GAAmC,GAA0B,GAAe,GAAgB,GAAqB,IAAaD,GAAuB;CAGlL,AAFAE,EAAQ,UAAU,GAAG,GAAGC,GAAOC,CAAM,GACrC,EAAQ,UAAU,SAClB,EAAQ,WAAW;CACnB,KAAK,IAAMR,KAAUD,EAAM,SAAS;EACnC,IAAMU,IAAQT,EAAO,OAAO;EAC5B,IAAKS,GACL;GAAIT,EAAO,OAAO,WAAW,MAC5BM,EAAQ,UAAU,GAClBA,EAAQ,IAAIG,EAAM,IAAIF,GAAOE,EAAM,IAAID,GAAQE,KAAe,KAAMD,EAAM,YAAY,GAAG,GAAG,KAAK,KAAK,CAAC,GACvGH,EAAQ,KAAK;GAEd,KAAK,IAAIK,IAAI,GAAGA,IAAIX,EAAO,OAAO,QAAQ,KAAK;IAC9C,IAAMY,IAAIZ,EAAO,OAAOW,IAAI,IAAUE,IAAIb,EAAO,OAAOW;IAEmD,AAD3G,EAAQ,YAAYD,KAAe,MAAOE,EAAE,WAAWC,EAAE,YAAY,IACrEP,EAAQ,UAAU,GAAGA,EAAQ,OAAOM,EAAE,IAAIL,GAAOK,EAAE,IAAIJ,CAAM,GAAGF,EAAQ,OAAOO,EAAE,IAAIN,GAAOM,EAAE,IAAIL,CAAM,GAAGF,EAAQ,OAAO;GAC3H;EALA;CAMD;CACA,IAAIP,EAAM,WAAW;EAEpB,IAAMe,IAAWP,IAAQ,KACrBQ,IAAW,KAAK,IAAI,IAAIP,IAAS,CAAC;EACtC,EAAQ,OAAO,GAAGO,EAAS,KAAKC;EAChC,IAAMC,IAAWX,EAAQ,cAAcP,EAAM,SAAS,CAAC,CAAC,SAAS;EAMjE,AALIkB,IAAWH,MACd,IAAW,KAAK,IAAI,IAAIC,IAAWD,IAAWG,CAAQ,GACtD,EAAQ,OAAO,GAAGF,EAAS,KAAKC,MAEjC,EAAQ,eAAe,UACvBV,EAAQ,SAASP,EAAM,WAAWQ,IAAQ,KAAMC,IAAS,IAAKM,CAAQ;CACvE;AACD;AAEA,IAAMI,KAAa,MAAiBC,EAAK,QAAQ,aAAa,OAAe;CAAE,KAAK;CAAS,KAAK;CAAQ,KAAK;CAAQ,MAAK;CAAU,KAAK;AAAS,EAAA,CAAGC,EAAW;AAKlK,SAAgBC,GAAkB,GAA0B,IAAQ,KAAK,IAAS,KAAK,IAAc,GAAG,IAAM,gBAAgB,IAAajB,GAA+B;CACzK,IAAMkB,IAAYpB,EAAmBH,CAAK;CAS1C,OAAO,wDAAwDQ,EAAM,GAAGC,EAAO,WAAWD,EAAM,YAAYC,EAAO,IARpGc,EAAU,QAAQ,KAAK,MAAW;EAChD,IAAMb,IAAQT,EAAO,OAAO;EAE5B,OADIA,EAAO,OAAO,WAAW,IAAU,eAAeS,EAAM,IAAIF,EAAM,QAAQE,EAAM,IAAID,EAAO,OAAOE,KAAe,KAAMD,EAAM,YAAY,EAAE,UAAUS,EAAUK,CAAG,EAAE,OACjKvB,EAAO,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,GAAO,MAAU;GACnD,IAAMY,IAAIZ,EAAO,OAAOwB;GACxB,OAAO,aAAaZ,EAAE,IAAIL,EAAM,GAAGK,EAAE,IAAIJ,EAAO,GAAGL,EAAM,IAAII,EAAM,GAAGJ,EAAM,IAAIK,EAAO,wBAAwBU,EAAUK,CAAG,EAAE,kBAAkBb,KAAe,MAAOE,EAAE,WAAWT,EAAM,YAAY,GAAG;EACzM,CAAC,CAAC,CAAC,KAAK,EAAE;CACX,CAAC,CAAC,CAAC,KAAK,EAC+G,IAASmB,EAAU,YAAY,YAAYf,IAAQ,IAAK,OAAOC,IAAS,GAAI,gBAAgB,KAAK,IAAID,IAAQ,KAAMe,EAAU,UAAU,SAASd,IAAS,EAAG,EAAE,iBAAiBU,EAAUF,CAAU,EAAE,eAAe,KAAK,IAAI,IAAIR,IAAS,CAAC,EAAE,UAAUU,EAAUK,CAAG,EAAE,IAAIL,EAAUI,EAAU,SAAS,EAAE,WAAW,GAAG;AAC/a;;;AC5DA,IAAaG,IAAeC,EAAkD,SAAsB,GAAO,GAAK;CAC/G,IAAM,EAAE,OAAOC,GAAiB,kBAAe9B,GAAgB,kBAAe,cAAW,IAAO,cAAW,IAAO,YACjH,SAAM,SAAM,aAAU,yBAAsB,IAAM,iBAAc,GAAG,SAAS+B,IAAa,eAAW,QAAI,GAAGC,OAAcC,GACpHC,IAAa,OAAO,UAAU,eAAe,KAAKD,GAAO,OAAO,GAChE,CAACE,IAAeC,MAAoBC,QAAehC,EAAmBiC,CAAY,CAAC,GACnFC,KAA4BC,SAAcnC,EAAmByB,KAAmB9B,CAAc,GAAG,CAAC8B,CAAe,CAAC,GAClH5B,IAAQgC,IAAaK,KAA4BJ,IACjDM,IAAWC,EAAOxC,CAAK;CAC7B,SAAsB;EAAE,EAAS,UAAUA;CAAO,GAAG,CAACA,CAAK,CAAC;CAC5D,IAAMyC,IAAcD,EAA4B,CAAC,CAAC,GAC5CE,IAAcF,EAA4B,CAAC,CAAC,GAC5C,CAACG,IAAgBC,MAAqBT,EAAS,CAAC,GAChDU,IAAOL,EAA8F,IAAI,GACzG,CAACM,IAASC,KAAcZ,EAAS,EAAK,GACtCa,IAAYR,EAA0B,IAAI,GAC1CS,KAAWT,EAAyB,IAAI,GACxCU,IAAWV,EAAyB,IAAI,GACxCW,IAAgBX,EAAiC,IAAI,GACrDY,KAAcC,EAAM,GACpBC,IAASC,MAAM,aAAaH,MAC5BI,IAAUC,EAAW5D,GAA4BgC,EAAW,GAC5D6B,KAAeC,IAAsBH,EAAQ,eAAe3B,IAAa,gBAAgB2B,EAAQ,qBACjGI,IAASC,KAAYC,GACrBC,IAAW,OAAO,SAASpD,CAAW,IAAI,KAAK,IAAI,KAAMA,CAAW,IAAI,GAExEqD,KAAS,MAAiC;EAC/C,IAAMC,IAASjB,EAAU;EACzB,IAAI,CAACiB,GAAQ;EACb,IAAMC,IAASD,EAAO,sBAAsB;EAC5C,IAAI,CAACC,EAAO,SAAS,CAACA,EAAO,QAAQ;EACrC,IAAMC,IAAQ,OAAO,oBAAoB;EAEzC,AADIF,EAAO,UAAU,KAAK,MAAMC,EAAO,QAAQC,CAAK,MAAG,EAAO,QAAQ,KAAK,MAAMD,EAAO,QAAQC,CAAK,IACjGF,EAAO,WAAW,KAAK,MAAMC,EAAO,SAASC,CAAK,MAAG,EAAO,SAAS,KAAK,MAAMD,EAAO,SAASC,CAAK;EACzG,IAAM5D,IAAU0D,EAAO,WAAW,IAAI;EACtC,IAAI,CAAC1D,GAAS;EACd,EAAQ,aAAa4D,GAAO,GAAG,GAAGA,GAAO,GAAG,CAAC;EAC7C,IAAMC,IAAQ,iBAAiBH,CAAM;EAErC,AADA,EAAQ,cAAc,EAAQ,YAAYG,EAAM,OAChD9D,GAAcC,GAASJ,EAAmBoB,CAAS,GAAG2C,EAAO,OAAOA,EAAO,QAAQH,GAAUK,EAAM,cAAc,KAAA,CAAS;CAC3H,GACMC,UAAqB;EAC1B,IAAMpE,IAAS4C,EAAK;EAIpB,AAHA,EAAK,UAAU,MACfE,EAAW,EAAK,GACZ9C,KAAU+C,EAAU,SAAS,oBAAoB/C,EAAO,SAAS,KAAG+C,EAAU,QAAQ,sBAAsB/C,EAAO,SAAS,GAChI+D,EAAMzB,EAAS,OAAO;CACvB,GACM+B,KAAW,GAAyB,IAAU,OAAS;EAC5D,IAAIV,GAAQ;EACZ,EAAa;EACb,IAAMW,IAAapE,EAAmBqE,CAAI;EAK1C,AAJIC,MAAWhC,EAAY,QAAQ,KAAKF,EAAS,OAAO,GAAG,EAAY,UAAU,CAAC,IAClF,EAAc,UAAUgC,GACnBvC,MAAc,EAAS,UAAUuC,GAAYrC,GAAiBqC,CAAU,IAC7EG,IAAgBH,CAAU,GAC1B3B,IAAmB,MAAY+B,IAAU,CAAC;CAC3C,GACMC,UAAa;EAClB,IAAIhB,KAAU,CAACnB,EAAY,QAAQ,QAAQ;EAC3C,IAAMoC,IAAWpC,EAAY,QAAQ,IAAI;EACG,AAA5CC,EAAY,QAAQ,KAAKH,EAAS,OAAO,GAAG+B,EAAQO,GAAU,EAAK;CACpE,GACMC,UAAa;EAClB,IAAIlB,KAAU,CAAClB,EAAY,QAAQ,QAAQ;EAC3C,IAAM8B,IAAO9B,EAAY,QAAQ,IAAI;EACO,AAA5CD,EAAY,QAAQ,KAAKF,EAAS,OAAO,GAAG+B,EAAQE,GAAM,EAAK;CAChE,GACMO,WAAepB,IAAsBT,EAAS,UAAUF,EAAU,QAAA,EAAU,MAAM;CA0CxF,AAzCAgC,EAAoBC,UAAY;EAAE;EAAO;EAAM;EAAM,aAAaX,EAAQxE,CAAc;EAAG,YAAY,IAAS,OAAO,IAAU,CAAC,MAAM;GACvI,IAAMoF,IAAW/E,EAAmBoC,EAAS,OAAO;GACpD,IAAI4C,MAAW,QAAQ,OAAO,KAAK,UAAUD,CAAQ;GACrD,IAAMhB,IAASlB,EAAU,SAAS,sBAAsB,GAClDxC,IAAQ,OAAO,SAAS4E,EAAQ,KAAK,IAAI,KAAK,IAAI,GAAGA,EAAQ,KAAM,IAAIlB,GAAQ,SAAS,KACxFzD,IAAS,OAAO,SAAS2E,EAAQ,MAAM,IAAI,KAAK,IAAI,GAAGA,EAAQ,MAAO,IAAIlB,GAAQ,UAAU,KAC5FE,IAAQpB,EAAU,UAAU,iBAAiBA,EAAU,OAAO,IAAI,KAAA,GAClExB,IAAM4C,GAAO,SAAS,gBACtBnD,IAAamD,GAAO,cAAc,KAAA;GACxC,IAAIe,MAAW,OAAO,OAAO7D,GAAkB4D,GAAU1E,GAAOC,GAAQsD,GAAUvC,GAAKP,CAAU;GACjG,IAAMkD,IAAQ,OAAO,SAASiB,EAAQ,KAAK,IAAI,KAAK,IAAI,IAAK,KAAK,IAAI,GAAGA,EAAQ,KAAM,CAAC,IAAI,OAAO,oBAAoB,GACjHnB,IAAS,SAAS,cAAc,QAAQ;GAA6C,AAA1C,EAAO,QAAQ,KAAK,MAAMzD,IAAQ2D,CAAK,GAAG,EAAO,SAAS,KAAK,MAAM1D,IAAS0D,CAAK;GACpI,IAAM5D,IAAU0D,EAAO,WAAW,IAAI;GACtC,IAAI,CAAC1D,GAAS,MAAU,MAAM,oEAAoE;GAGlG,OAFAA,EAAQ,MAAM4D,GAAOA,CAAK,GAAG,EAAQ,cAAc,EAAQ,YAAY3C,GACvElB,GAAcC,GAAS2E,GAAU1E,GAAOC,GAAQsD,GAAU9C,CAAU,GAC7DgD,EAAO,UAAU,WAAW;EACpC;CAAE,EAAE,GAEJoB,QAAgB;EAIf,AAFIrD,KAAc,KAAK,UAAUhC,CAAK,MAAM,KAAK,UAAUmD,EAAc,OAAO,MAAK,EAAY,UAAU,CAAC,GAAG,EAAY,UAAU,CAAC,GAAGP,IAAmB,MAAY+B,IAAU,CAAC,IACnL,EAAc,UAAU3E,GACxBqE,EAAa;CACd,GAAG;EAACrE;EAAO6D;EAAUC;CAAQ,CAAC,GAC9BuB,QAAgB;EACf,IAAMpB,IAASjB,EAAU;EACzB,IAAI,CAACiB,GAAQ;EACb,IAAMqB,UAAetB,EAAMnB,EAAK,UAAU;GAAE,GAAGA,EAAK,QAAQ;GAAS,SAAS,CAAC,GAAGA,EAAK,QAAQ,QAAQ,SAAS,EAAE,QAAQA,EAAK,QAAQ,OAAO,CAAC;EAAE,IAAIN,EAAS,OAAO;EACrK,EAAO;EACP,IAAMgD,IAAS,OAAO,iBAAmB,MAAc,IAAI,eAAeD,CAAM,IAAI,KAAA;EACpF,GAAQ,QAAQrB,CAAM;EAEtB,IAAMuB,IAAQ,IAAI,iBAAiBF,CAAM;EACzC,KAAK,IAAIG,IAA+BxB,GAAQwB,GAAU,IAAWA,EAAS,eAAe,EAAM,QAAQA,GAAU;GAAE,YAAY;GAAM,iBAAiB;IAAC;IAAS;IAAS;GAAY;EAAE,CAAC;EAC5L,OAAO,iBAAiB,UAAUH,CAAM;EAExC,IAAMI,IAAQ,OAAO,WAAa,MAAc,SAAS,QAAQ,KAAA;EAEjE,OADAA,GAAO,mBAAmB,eAAeJ,CAAM,SAClC;GAA0F,AAAxFC,GAAQ,WAAW,GAAGC,EAAM,WAAW,GAAG,OAAO,oBAAoB,UAAUF,CAAM,GAAGI,GAAO,sBAAsB,eAAeJ,CAAM;EAAG;CAC7J,GAAG,CAACvB,CAAQ,CAAC,GACbsB,QAAgB;EACf,IAAMM,IAAQ1C,GAAS,SAAS,QAAQC,EAAS,SAAS,QAAQF,EAAU,SAAS,QAAQ,MAAM,GAC/F4C,IAAS,IACTC,GAEEC,KAAS,MAAiB;GAE/B,AADA,aAAaD,CAAU,GACvB,IAAa,iBAAiB;IAA0B,AAAxB,IAAa,KAAA,GAAeD,KAAU,CAACG,EAAM,oBAAoB,CAACnC,MAAU,EAAY,UAAU,CAAC,GAAG,EAAY,UAAU,CAAC,GAAGU,EAAQlC,GAAc,EAAK;GAAK,GAAG,CAAC;EACrM;EAEA,OADAuD,GAAO,iBAAiB,SAASG,CAAK,SACzB;GAA4C,AAA1C,IAAS,IAAO,aAAaD,CAAU,GAAGF,GAAO,oBAAoB,SAASG,CAAK;EAAG;CACtG,GAAG;EAAC1D;EAAcJ;EAAY4B;EAAQc;EAAesB;EAAMC;EAAMC;EAAUvC;CAAmB,CAAC;CAC/F,IAAMwC,KAAa,GAAwC,IAA4EJ,MAA6B;EACnK,IAAM7B,IAAS6B,EAAM,cAAc,sBAAsB;EACzD,OAAO;GAAE,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,IAAIK,EAAO,UAAUlC,EAAO,SAASA,EAAO,SAAS,EAAE,CAAC;GAAG,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,IAAIkC,EAAO,UAAUlC,EAAO,QAAQA,EAAO,UAAU,EAAE,CAAC;GAAG,UAAU6B,EAAM,gBAAgB,SAAQK,EAAO,YAAkB;EAAI;CACrP,GACMC,MAAU,MAA2C;EAC1D,IAAMpG,IAAS4C,EAAK;EACpB,IAAI,CAAC5C,KAAUA,EAAO,cAAc8F,EAAM,WAAW;EAErD,IAAMO,IAAWH,EAAUJ,CAAK,GAC1BQ,IAAOtG,EAAO,OAAOA,EAAO,OAAO,SAAS;EAIlD,CAHIsG,EAAK,MAAMD,EAAS,KAAKC,EAAK,MAAMD,EAAS,MAAGrG,EAAO,OAAO,KAAKqG,CAAQ,GAC/E,EAAK,UAAU,MACfvD,EAAW,EAAK,GACZR,EAAS,YAAYtC,EAAO,WAASqE,EAAQ;GAAE,GAAGrE,EAAO;GAAS,SAAS,CAAC,GAAGA,EAAO,QAAQ,SAAS,EAAE,QAAQA,EAAO,OAAO,CAAC;EAAE,CAAC;CACxI,GACMuG,IAAQzG,EAAiBC,CAAK;CACpC,OAAO,kBAACP,GAAD;EAAO,GAAIqC;EAAW,IAAIwB;EAAQ,MAAK;EAAQ,cAAYxB,GAAU,iBAAiB0B,EAAQ;EAAO,KAAI;EAAK,WAAWiD,EAAG,8CAA8CC,EAAS;EAAG,wBAAsB/D;EAAgB,iBAAekB,KAAY,KAAA;EAAW,iBAAeC,KAAY,KAAA;EAA7R,UAAA;GACN,kBAACtE,GAAD;IAAM,IAAI,GAAG8D,EAAO;IAAgB,MAAK;IAAK,MAAK;IAAa,UAAAI;GAAmB,CAAA;GAGnF,kBAAC,OAAD;IAAK,WAAW+C,EAAG,+IAA+I,oHAAoH/G,EAAkB,SAAS,2LAA2LmE,KAAY,+BAA+B;IAAG,gBAAc8C,KAAW,KAAA;IAAnjB,UAAA,CACC,kBAAC,UAAD;KAAQ,KAAK3D;KAAW,WAAWyD,EAAG,yEAAyE,CAAC7C,KAAU,6BAA6B;KACtJ,UAAUC,IAAW,KAAK;KAAG,MAAK;KAAM,cAAYL,EAAQ;KAAO,oBAAkB,GAAGF,EAAO,gBAAgBA,EAAO;KAAU,iBAAeO,KAAY,KAAA;KAAW,gBAAc8C,KAAW,KAAA;KAC/L,gBAAgB,MAAU;MAAE,AAAI/C,KAAUf,EAAK,WAAWkD,EAAM,WAAW,MAAWA,EAAM,eAAe,GAAGA,EAAM,cAAc,MAAM,GAAGA,EAAM,cAAc,oBAAoBA,EAAM,SAAS,GAAG,EAAK,UAAU;OAAE,WAAWA,EAAM;OAAW,QAAQ,CAACI,EAAUJ,CAAK,CAAC;OAAG,SAASxD,EAAS;MAAQ,GAAGQ,EAAW,EAAI,GAAGiB,EAAM;OAAE,GAAGzB,EAAS;OAAS,SAAS,CAAC,GAAGA,EAAS,QAAQ,SAAS,EAAE,QAAQM,EAAK,QAAQ,OAAO,CAAC;MAAE,CAAC;KAAG;KACta,gBAAgB,MAAU;MACzB,IAAM5C,IAAS4C,EAAK;MACpB,IAAI,CAAC5C,KAAUA,EAAO,cAAc8F,EAAM,WAAW;MACrD,IAAMa,IAAUb,EAAM,YAAY,qBAAqB,CAAC,CAAC,QAAQ,MAAWK,EAAO,cAAcnG,EAAO,SAAS,KAAK,CAAC;MACvH,KAAK,IAAMmG,KAAUQ,EAAQ,SAASA,IAAU,CAACb,EAAM,WAAW,GAAG,EAAO,OAAO,KAAKI,EAAUJ,GAAOK,CAAM,CAAC;MAChH,EAAM;OAAE,GAAGnG,EAAO;OAAS,SAAS,CAAC,GAAGA,EAAO,QAAQ,SAAS,EAAE,QAAQA,EAAO,OAAO,CAAC;MAAE,CAAC;KAC7F;KACA,aAAaoG;KAAQ,kBAAkB,MAAU;MAAE,AAAIxD,EAAK,SAAS,cAAckD,EAAM,aAAW1B,EAAa;KAAG;KAAG,uBAAuB,MAAU;MAAE,AAAIxB,EAAK,SAAS,cAAckD,EAAM,aAAW1B,EAAa;KAAG;KAC3N,gBAAgB,MAAU;MAAE,AAAIxB,EAAK,WAASkD,EAAM,eAAe;KAAG;KACtE,YAAY,MAAU;MAA8C,AAAxCA,EAAM,QAAQ,YAAU1B,EAAa,GAAO,QAAqB0B,EAAM,WAAWA,EAAM,YAAYA,EAAM,IAAI,YAAY,MAAM,QAAOA,EAAM,eAAe,GAAOA,EAAM,WAAUjB,EAAK,IAAQF,EAAK,KAAUmB,EAAM,WAAWA,EAAM,YAAYA,EAAM,IAAI,YAAY,MAAM,QAAOA,EAAM,eAAe,GAAGjB,EAAK;KAAK;KAClV,UAAApB;IACM,CAAA,GACP8C,KAAS,CAAC1D,MAAW,kBAAC,OAAD;KAAK,eAAY;KAAO,WAAU;KAAmG,UAAA,kBAACtD,GAAD;MAAM,MAAK;MAAa,UAAAgE,EAAQ;KAAkB,CAAA;IAAM,CAAA,CAC/M;;GACJG,KAAuB,kBAAC/D,GAAD;IAAW,OAAO4D,EAAQ;IAAW,SAAS,GAAGF,EAAO;IAAS,UAAA,kBAAC3D,GAAD;KAAO,KAAKuD;KAAU,IAAI,GAAGI,EAAO;KAAS,OAAOtD,EAAM,aAAa;KAAc;KAAoB;KAAmB;KAAS,WAAW,MAAUsE,EAAQ;MAAE,GAAG/B,EAAS;MAAS,WAAWwD,EAAM,OAAO;KAAM,CAAC;IAAI,CAAA;GAAY,CAAA;GACjU,kBAACtG,GAAD;IAAO,WAAU;IAAa,KAAI;IAAK,MAAA;IAAvC,UAAA;KACC,kBAACoH,GAAD;MAAQ,MAAK;MAAS,aAAY;MAAU,UAAUjD,KAAU,CAACnB,EAAY,QAAQ;MAAQ,eAAe;OAAU,AAARmC,EAAK,GAAGG,EAAM;MAAG;MAAI,UAAAvB,EAAQ;KAAa,CAAA;KACxJ,kBAACqD,GAAD;MAAQ,MAAK;MAAS,aAAY;MAAU,UAAUjD,KAAU,CAAClB,EAAY,QAAQ;MAAQ,eAAe;OAAU,AAARoC,EAAK,GAAGC,EAAM;MAAG;MAAI,UAAAvB,EAAQ;KAAa,CAAA;KACxJ,kBAACqD,GAAD;MAAQ,MAAK;MAAS,aAAY;MAAU,UAAUjD,KAAU4C;MAAO,eAAe;OAA2B,AAAzBlC,EAAQxE,CAAc,GAAGiF,EAAM;MAAG;MAAI,UAAAvB,EAAQ;KAAc,CAAA;IAC9I;;GACP,kBAAChE,GAAD;IAAM,IAAI,GAAG8D,EAAO;IAAU,MAAK;IAAS,MAAK;IAAK,MAAK;IAAa,UAAAkD,IAAQhD,EAAQ,QAAQA,EAAQ;GAAa,CAAA;IACnHyC,KAAQC,MAAa,kBAAC,SAAD;IAAO,KAAKjD;IAAU,WAAU;IAAU,MAAK;IAAO,UAAU;IAAI,eAAY;IAAa;IAAY;IAAgB;IAAoB;IAAoB;IAAU,OAAOuD,IAAQ,KAAK,KAAK,UAAUxG,CAAK;IAAG,gBAAgB,CAAC;IAAG,SAAS+E;IAAO,WAAWA;GAAQ,CAAA;EAC9R;;AACR,CAAC,GAGY+B,IAAsBnF,EAAoD,SAA6B,EAAE,UAAO,iBAAc,GAAG,cAAW,GAAGI,KAAS,GAAK;CACzK,IAAMwC,IAAapE,EAAmBH,CAAK;CAC3C,OAAO,kBAAC,OAAD;EAAU;EAAK,MAAK;EAAM,SAAQ;EAAc,cAAW;EAAY,GAAI+B;EAAO,WAAW0E,EAAG,4EAA4EC,CAAS;EAArL,UAAA,CACLnC,EAAW,QAAQ,KAAK,GAAQ,MAAUtE,EAAO,OAAO,WAAW,IAAI,kBAAC,UAAD;GAAoB,IAAIA,EAAO,OAAO,EAAE,CAAC,IAAI;GAAK,IAAIA,EAAO,OAAO,EAAE,CAAC,IAAI;GAAK,GAAGU,KAAe,KAAMV,EAAO,OAAO,EAAE,CAAC,YAAY;GAAG,MAAK;EAAgB,GAAhJwB,CAAgJ,IAAI,kBAAC,KAAD,EAAA,UAAgBxB,EAAO,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,GAAO,MAAe;GAAE,IAAMY,IAAIZ,EAAO,OAAO8G;GAAa,OAAO,kBAAC,QAAD;IAAuB,GAAG,IAAIlG,EAAE,IAAI,IAAI,GAAGA,EAAE,IAAI,IAAI,GAAGT,EAAM,IAAI,IAAI,GAAGA,EAAM,IAAI;IAAO,MAAK;IAAO,QAAO;IAAe,aAAaO,KAAe,MAAOE,EAAE,WAAWT,EAAM,YAAY;IAAI,eAAc;GAAS,GAA9M2G,CAA8M;EAAG,CAAC,EAAK,GAA1UtF,CAA0U,CAAC,GAC3jB8C,EAAW,aAAa,kBAAC,QAAD;GAAM,GAAE;GAAK,GAAE;GAAM,MAAK;GAAe,UAAS;GAAK,YAAY,KAAK,IAAI,KAAKA,EAAW,UAAU,SAAS,EAAE;GAAI,UAAAA,EAAW;EAAgB,CAAA,CACrK;;AACN,CAAC"}
|
package/dist/base/skeleton.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as e, i as t, n, r, t as i } from "../skeleton-
|
|
2
|
+
import { a as e, i as t, n, r, t as i } from "../skeleton-BapcJd9C.js";
|
|
3
3
|
export { i as ContentSkeleton, n as PageSkeleton, r as Skeleton, t as TableSkeleton, e as TwoColumnPageSkeleton };
|
package/dist/base/spinner.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { g as e } from "../ui-provider-C-74NVLc.js";
|
|
3
3
|
import { useStrings as t } from "../lib/strings.js";
|
|
4
|
-
import { t as n } from "../utils-
|
|
5
|
-
import { c as r } from "../typography-
|
|
6
|
-
import { t as i } from "../structure-
|
|
4
|
+
import { t as n } from "../utils-B6kKb8jB.js";
|
|
5
|
+
import { c as r } from "../typography-BQnine1k.js";
|
|
6
|
+
import { t as i } from "../structure-DuxKl954.js";
|
|
7
7
|
import { n as a } from "../track-recipes-CDcKmndW.js";
|
|
8
8
|
import { forwardRef as o } from "react";
|
|
9
9
|
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|