themelia-react-ui 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +281 -1
- package/README.md +10 -5
- package/dist/{accordion-BRTcsp8J.js → accordion-CQXVcd7Q.js} +13 -13
- package/dist/accordion-CQXVcd7Q.js.map +1 -0
- package/dist/action-menu-BTpyPWJ2.js +264 -0
- package/dist/action-menu-BTpyPWJ2.js.map +1 -0
- package/dist/{affordance-geometry.generated-CL84ZN9A.js → affordance-geometry.generated-CCIXb2A1.js} +7 -2
- package/dist/affordance-geometry.generated-CCIXb2A1.js.map +1 -0
- package/dist/{ai-artifact-DLVdK0Py.js → ai-artifact-2PQ2fItc.js} +171 -176
- package/dist/ai-artifact-2PQ2fItc.js.map +1 -0
- package/dist/{app-shell-C_fKpljx.js → app-shell-BE_j8-AT.js} +4 -4
- package/dist/{app-shell-C_fKpljx.js.map → app-shell-BE_j8-AT.js.map} +1 -1
- package/dist/{attachment-DbjUWsP0.js → attachment-q69dlt5Y.js} +9 -9
- package/dist/{attachment-DbjUWsP0.js.map → attachment-q69dlt5Y.js.map} +1 -1
- package/dist/{auth-CAQcasMV.js → auth-M3vGMgDR.js} +42 -42
- package/dist/{auth-CAQcasMV.js.map → auth-M3vGMgDR.js.map} +1 -1
- package/dist/{avatar-Bu2HhitA.js → avatar-djdaaQ_s.js} +14 -12
- package/dist/avatar-djdaaQ_s.js.map +1 -0
- package/dist/{badge-CzId1Wlm.js → badge-0tATj-tW.js} +9 -9
- package/dist/badge-0tATj-tW.js.map +1 -0
- 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/buttons.js +2 -2
- package/dist/base/cards.js +2 -2
- package/dist/base/carousel.js +11 -11
- package/dist/base/carousel.js.map +1 -1
- package/dist/base/cascader.js +244 -222
- package/dist/base/cascader.js.map +1 -1
- 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 +1 -1
- 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 +2 -2
- package/dist/base/inline-edit.js +81 -76
- package/dist/base/inline-edit.js.map +1 -1
- package/dist/base/item.js +1 -1
- package/dist/base/media-gallery.js +1 -1
- package/dist/base/navigation.js +6 -6
- package/dist/base/popover-menu.js +1 -1
- package/dist/base/popover.js +1 -1
- package/dist/base/qr-code.js +7 -4
- package/dist/base/qr-code.js.map +1 -1
- package/dist/base/repeaters.js +42 -42
- package/dist/base/repeaters.js.map +1 -1
- package/dist/base/sheet.js +1 -1
- package/dist/base/sidebar.js +1 -1
- package/dist/base/signature-pad.js +9 -9
- package/dist/base/signature-pad.js.map +1 -1
- package/dist/base/skeleton.js +1 -1
- package/dist/base/spinner.js +1 -1
- 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 +4 -4
- 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/blocks/admin.js +229 -220
- package/dist/blocks/admin.js.map +1 -1
- package/dist/blocks/ai.js +147 -180
- package/dist/blocks/ai.js.map +1 -1
- package/dist/blocks/analytics/usage-card.js +1 -1
- package/dist/blocks/analytics.js +530 -523
- 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 +1390 -1516
- package/dist/blocks/commerce.js.map +1 -1
- package/dist/blocks/data-display.js +1 -1
- package/dist/blocks/onboarding.js +5 -5
- package/dist/blocks/planning.js +82 -91
- package/dist/blocks/planning.js.map +1 -1
- package/dist/blocks/timelines.js +1 -1
- package/dist/{breadcrumbs-BuYz5SDU.js → breadcrumbs-BG_FfMK4.js} +5 -5
- package/dist/{breadcrumbs-BuYz5SDU.js.map → breadcrumbs-BG_FfMK4.js.map} +1 -1
- package/dist/{button-BZDasD04.js → button-BS3KDg00.js} +185 -162
- package/dist/button-BS3KDg00.js.map +1 -0
- package/dist/{button-BZyfTvwm.js → button-R9CCoH7A.js} +2 -2
- package/dist/{button-BZyfTvwm.js.map → button-R9CCoH7A.js.map} +1 -1
- package/dist/{buttons-D_6KJvEE.js → buttons-DS0ZIwJ_.js} +11 -11
- package/dist/buttons-DS0ZIwJ_.js.map +1 -0
- package/dist/{cards-qGSErLw_.js → cards-QoJ4syG9.js} +7 -7
- package/dist/{cards-qGSErLw_.js.map → cards-QoJ4syG9.js.map} +1 -1
- package/dist/{chart-Bsc5BICK.js → chart-DwYRKKc-.js} +17 -15
- package/dist/chart-DwYRKKc-.js.map +1 -0
- package/dist/checkbox-B7ygNTYp.js +35 -0
- package/dist/checkbox-B7ygNTYp.js.map +1 -0
- package/dist/choice-inputs-DrJ17tpL.js +752 -0
- package/dist/choice-inputs-DrJ17tpL.js.map +1 -0
- package/dist/{code-block-DzHKRybS.js → code-block-CD0B7M93.js} +19 -19
- package/dist/{code-block-DzHKRybS.js.map → code-block-CD0B7M93.js.map} +1 -1
- package/dist/{collapsible-ClvC7Bj3.js → collapsible-oMUGM4tr.js} +3 -3
- package/dist/{collapsible-ClvC7Bj3.js.map → collapsible-oMUGM4tr.js.map} +1 -1
- package/dist/{collection-content-D6S8cv_n.js → collection-content-Ys-OZOkY.js} +3 -3
- package/dist/{collection-content-D6S8cv_n.js.map → collection-content-Ys-OZOkY.js.map} +1 -1
- package/dist/{combobox-BFnbJJp3.js → combobox-6dvVny2q.js} +96 -97
- package/dist/combobox-6dvVny2q.js.map +1 -0
- package/dist/{combobox-hozNwUcc.js → combobox-CB7039j7.js} +326 -308
- package/dist/combobox-CB7039j7.js.map +1 -0
- package/dist/{command-BnmSchli.js → command-kPMPjIxJ.js} +34 -30
- package/dist/command-kPMPjIxJ.js.map +1 -0
- package/dist/{comments-u5L0OGip.js → comments-You0Bzbr.js} +349 -348
- package/dist/comments-You0Bzbr.js.map +1 -0
- package/dist/components/base/accordion/accordion-variants.d.ts +3 -3
- package/dist/components/base/action-menu/action-menu.d.ts +7 -2
- package/dist/components/base/avatar/stacked-avatars.d.ts +5 -4
- package/dist/components/base/badge/badge.d.ts +1 -1
- package/dist/components/base/badge/badge.recipes.d.ts +4 -4
- package/dist/components/base/buttons/base-button.d.ts +7 -0
- package/dist/components/base/buttons/button-group.recipes.d.ts +2 -2
- package/dist/components/base/buttons/button.variants.d.ts +1 -0
- package/dist/components/base/buttons/loader-button.d.ts +3 -1
- package/dist/components/base/buttons/text-button.d.ts +2 -2
- package/dist/components/base/carousel/carousel.d.ts +3 -1
- package/dist/components/base/chart/chart.d.ts +7 -7
- package/dist/components/base/choice-inputs/checkbox.d.ts +6 -7
- package/dist/components/base/choice-inputs/choice-types.d.ts +10 -1
- package/dist/components/base/choice-inputs/pill-radio-group.d.ts +9 -0
- package/dist/components/base/choice-inputs/select-popup.d.ts +9 -1
- package/dist/components/base/choice-inputs/switch-card.d.ts +1 -1
- package/dist/components/base/date-pickers/date-picker-field.d.ts +23 -0
- package/dist/components/base/date-pickers/datepicker.types.d.ts +13 -3
- package/dist/components/base/display/alert-dialog.d.ts +8 -2
- package/dist/components/base/display/content-block.d.ts +4 -2
- package/dist/components/base/display/date-block.d.ts +1 -1
- package/dist/components/base/display/dialog.d.ts +12 -5
- package/dist/components/base/display/surface-title.d.ts +6 -1
- package/dist/components/base/feedback/alert.d.ts +1 -1
- package/dist/components/base/feedback/state-display.d.ts +5 -4
- package/dist/components/base/forms/form-sizing.d.ts +32 -0
- package/dist/components/base/forms/workflow.d.ts +2 -0
- package/dist/components/base/forms-numeric/coordinates-input.d.ts +3 -0
- package/dist/components/base/forms-numeric/rounding-mode-select.d.ts +4 -1
- package/dist/components/base/navigation/dropdown-menu.d.ts +2 -2
- package/dist/components/base/navigation/language-switcher.d.ts +4 -1
- package/dist/components/base/navigation/overflow-tab-bar.d.ts +7 -0
- package/dist/components/base/navigation/page-header/page-header.d.ts +4 -1
- package/dist/components/base/qr-code/qr-code.d.ts +2 -0
- package/dist/components/base/sheet/index.d.ts +29 -1
- package/dist/components/base/sheet/sheet.d.ts +14 -5
- package/dist/components/base/spinner/spinner.d.ts +3 -2
- package/dist/components/base/structure/structure.types.d.ts +1 -1
- package/dist/components/base/text-inputs/input-group.d.ts +2 -2
- package/dist/components/base/upload/upload.recipes.d.ts +11 -0
- package/dist/components/base/value-inputs/date-time-input.d.ts +4 -2
- package/dist/components/base/value-inputs/tags-input.d.ts +2 -0
- package/dist/components/blocks/admin/api-key-list/api-key-list.types.d.ts +1 -1
- package/dist/components/blocks/analytics/format-metric-value.d.ts +11 -1
- package/dist/components/blocks/analytics/index.d.ts +1 -1
- package/dist/components/blocks/analytics/use-metric-format-options.d.ts +3 -0
- package/dist/components/blocks/commerce/address-card/address-card.d.ts +1 -1
- package/dist/components/blocks/commerce/address-card/types.d.ts +3 -1
- package/dist/components/blocks/commerce/booking-calendar-event-card/booking-calendar-event-card.d.ts +4 -0
- package/dist/components/blocks/commerce/booking-calendar-event-card/booking-calendar-event-card.types.d.ts +2 -2
- package/dist/components/blocks/commerce/discount-stack/types.d.ts +1 -1
- package/dist/components/blocks/commerce/inventory-section/types.d.ts +4 -1
- package/dist/components/blocks/commerce/loyalty-points/types.d.ts +1 -1
- package/dist/components/blocks/commerce/order-status/types.d.ts +4 -0
- package/dist/components/blocks/commerce/payment-method/payment-method.d.ts +1 -1
- package/dist/components/blocks/commerce/payment-method/types.d.ts +3 -1
- package/dist/components/blocks/commerce/seo-listing/seo-listing-card.d.ts +1 -1
- package/dist/components/blocks/commerce/seo-listing/types.d.ts +3 -1
- package/dist/components/blocks/commerce/vendor-profile/types.d.ts +4 -1
- package/dist/components/blocks/data-display/dense-info-card/dense-info.strings.d.ts +4 -1
- package/dist/components/blocks/data-display/inline-stat/inline-stat.d.ts +4 -1
- package/dist/components/features/global-search/partials/global-search-idle-state.d.ts +1 -1
- package/dist/components/features/overlays/alert-dialog.d.ts +1 -1
- package/dist/components/features/overlays/drawer.d.ts +1 -1
- package/dist/components/features/overlays/hooks/use-overlay-actions.d.ts +2 -2
- package/dist/components/features/overlays/hooks/use-overlay-visibility.d.ts +11 -4
- package/dist/components/features/overlays/overlay-tone-icon.d.ts +37 -0
- package/dist/components/features/overlays/overlays.types.d.ts +42 -19
- package/dist/components/features/products/components/product-variants-manager.d.ts +1 -1
- package/dist/components/features/products/partials/index.d.ts +1 -1
- package/dist/components/features/products/partials/product-metric-tile.d.ts +6 -0
- package/dist/components/features/products/partials/product-tone.d.ts +11 -1
- package/dist/components/features/products/products.types.d.ts +2 -1
- package/dist/components/features/table/partials/cell-renderers.d.ts +1 -1
- package/dist/components/layout/page/index.d.ts +1 -1
- package/dist/components/layout/page/page.types.d.ts +53 -3
- package/dist/components/layout/page/partials/page-header-commands.d.ts +13 -0
- package/dist/components/layout/page/partials/page-header.d.ts +1 -1
- package/dist/components/primitives/date.d.ts +16 -3
- package/dist/components/primitives/dimensions.d.ts +6 -0
- package/dist/components/primitives/duration.d.ts +6 -0
- package/dist/components/primitives/file-size.d.ts +6 -0
- package/dist/components/primitives/index.d.ts +1 -1
- package/dist/components/primitives/initials.d.ts +11 -2
- package/dist/components/primitives/link.d.ts +7 -0
- package/dist/components/primitives/money.d.ts +29 -7
- package/dist/components/primitives/number.d.ts +17 -0
- package/dist/components/primitives/value-typography.d.ts +54 -0
- package/dist/components/primitives/value.d.ts +31 -6
- package/dist/components/typography/heading.d.ts +9 -1
- package/dist/components/typography/label.d.ts +3 -0
- package/dist/components/typography/running-text.d.ts +12 -0
- package/dist/components/typography/text-link.d.ts +23 -1
- package/dist/components/typography/text.d.ts +12 -0
- package/dist/components/typography/text.styles.d.ts +35 -13
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/checkbox.d.ts +5 -0
- package/dist/components/ui/overlay.recipes.d.ts +15 -2
- package/dist/components/ui/select.d.ts +3 -1
- package/dist/components/ui/switch.d.ts +5 -0
- package/dist/{containers-DqB-bSYE.js → containers-D_L4mTVb.js} +3 -3
- package/dist/{containers-DqB-bSYE.js.map → containers-D_L4mTVb.js.map} +1 -1
- package/dist/{copyable-BTSByfmq.js → copyable-DDjTeW_j.js} +4 -4
- package/dist/{copyable-BTSByfmq.js.map → copyable-DDjTeW_j.js.map} +1 -1
- package/dist/{data-display-Bihs9Ven.js → data-display-3xWQUnMA.js} +471 -478
- package/dist/data-display-3xWQUnMA.js.map +1 -0
- package/dist/date-picker-DrDFj8Lo.js +1527 -0
- package/dist/date-picker-DrDFj8Lo.js.map +1 -0
- package/dist/date-pickers-CnFCb0n2.js +174 -0
- package/dist/date-pickers-CnFCb0n2.js.map +1 -0
- package/dist/date-uf3z37Nm.js +144 -0
- package/dist/date-uf3z37Nm.js.map +1 -0
- package/dist/{display-CS6Hbk18.js → display-DrdvPwF0.js} +25 -25
- package/dist/display-DrdvPwF0.js.map +1 -0
- package/dist/{dropdown-menu-D-boNgGO.js → dropdown-menu-CURh59jb.js} +22 -15
- package/dist/dropdown-menu-CURh59jb.js.map +1 -0
- package/dist/features/activities.js +38 -35
- package/dist/features/activities.js.map +1 -1
- package/dist/features/ai-chat.js +36 -35
- package/dist/features/ai-chat.js.map +1 -1
- package/dist/features/async-preview.js +8 -8
- package/dist/features/combobox.js +1 -1
- package/dist/features/comments.js +1 -1
- package/dist/features/data-view.js +10 -10
- package/dist/features/email-composer.js +325 -326
- package/dist/features/email-composer.js.map +1 -1
- package/dist/features/event-calendar.js +190 -200
- package/dist/features/event-calendar.js.map +1 -1
- package/dist/features/filters.js +1 -1
- package/dist/features/global-search.js +77 -77
- package/dist/features/global-search.js.map +1 -1
- package/dist/features/kanban.js +4 -4
- package/dist/features/map.js +8 -8
- package/dist/features/media-library.js +499 -502
- 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 +1216 -1248
- package/dist/features/products.js.map +1 -1
- package/dist/features/questionnaire.js +46 -44
- package/dist/features/questionnaire.js.map +1 -1
- package/dist/features/resource-assignment.js +96 -88
- package/dist/features/resource-assignment.js.map +1 -1
- package/dist/features/resource.js +11 -11
- package/dist/features/rich-text-editor.js +2 -2
- package/dist/features/schema-form.js +188 -184
- package/dist/features/schema-form.js.map +1 -1
- package/dist/features/suggestions.js +3 -3
- package/dist/features/sync.js +7 -7
- package/dist/features/sync.js.map +1 -1
- package/dist/features/table.js +1 -1
- package/dist/features/theme-tweaker.js +469 -470
- package/dist/features/theme-tweaker.js.map +1 -1
- package/dist/{feedback-CJkUAapr.js → feedback-C7nR0UtT.js} +9 -10
- package/dist/feedback-C7nR0UtT.js.map +1 -0
- package/dist/field-affordance-recipes-CkOCdE2y.js +46 -0
- package/dist/field-affordance-recipes-CkOCdE2y.js.map +1 -0
- package/dist/{field-state-recipes-DQQpiLWC.js → field-state-recipes-C-MFBX_8.js} +3 -3
- package/dist/field-state-recipes-C-MFBX_8.js.map +1 -0
- package/dist/{filters-D6FF8L6s.js → filters-Da-gNPsE.js} +467 -467
- package/dist/filters-Da-gNPsE.js.map +1 -0
- package/dist/{form-field-CZwrkP7m.js → form-field-VZRULhUK.js} +7 -7
- package/dist/{form-field-CZwrkP7m.js.map → form-field-VZRULhUK.js.map} +1 -1
- package/dist/form-sizing-uWP4lzVh.js +126 -0
- package/dist/form-sizing-uWP4lzVh.js.map +1 -0
- package/dist/{forms-B5NCbkSC.js → forms-DDeEnXSY.js} +11 -11
- package/dist/forms-DDeEnXSY.js.map +1 -0
- package/dist/forms-numeric-D3CO60IF.js +905 -0
- package/dist/forms-numeric-D3CO60IF.js.map +1 -0
- package/dist/{header-kxruN3RM.js → header-2ycNqGOR.js} +43 -42
- package/dist/header-2ycNqGOR.js.map +1 -0
- package/dist/{hooks-BrlnCwQd.js → hooks-DQ5SPwZw.js} +2 -2
- package/dist/{hooks-BrlnCwQd.js.map → hooks-DQ5SPwZw.js.map} +1 -1
- package/dist/{icon-badge-Btc6pQrp.js → icon-badge-DKlaKXoo.js} +3 -3
- package/dist/{icon-badge-Btc6pQrp.js.map → icon-badge-DKlaKXoo.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/{input-vxcaNCYC.js → input-BoLm9Hks.js} +3 -3
- package/dist/{input-vxcaNCYC.js.map → input-BoLm9Hks.js.map} +1 -1
- package/dist/input-DhQdBnV3.js +255 -0
- package/dist/{input-SX9V0AL3.js.map → input-DhQdBnV3.js.map} +1 -1
- package/dist/item-xzh8Df65.js +264 -0
- package/dist/item-xzh8Df65.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 +1 -1
- package/dist/layout/settings.js +1 -1
- package/dist/layout/sidebar.js +2 -2
- package/dist/layout/workspace.js +1 -1
- package/dist/layout.js +10 -10
- package/dist/lib/affordance-geometry.generated.d.ts +6 -1
- package/dist/lib/field-affordance-recipes.d.ts +35 -0
- package/dist/lib/field-state-recipes.d.ts +4 -2
- package/dist/lib/format.d.ts +9 -0
- package/dist/lib/money-format.d.ts +30 -0
- package/dist/lib/overlay-anatomy-recipes.d.ts +1 -1
- package/dist/lib/surface-recipes.d.ts +8 -6
- package/dist/lib/token-merge.generated.d.ts +11 -11
- package/dist/lib/track-recipes.d.ts +1 -1
- package/dist/lib/ui-provider/provider.d.ts +7 -2
- package/dist/lib/ui-provider/store.d.ts +6 -2
- package/dist/lib/ui-provider/types.d.ts +5 -2
- package/dist/lib/utils.js +1 -1
- package/dist/{media-gallery-DLp3HAz0.js → media-gallery-DQUQ0m3O.js} +8 -8
- package/dist/media-gallery-DQUQ0m3O.js.map +1 -0
- package/dist/{mentions-Cl0Kt_Pd.js → mentions-DwnO1hh4.js} +34 -35
- package/dist/{mentions-Cl0Kt_Pd.js.map → mentions-DwnO1hh4.js.map} +1 -1
- package/dist/{message-SZUNB1eX.js → message-YfFmbXNP.js} +5 -5
- package/dist/{message-SZUNB1eX.js.map → message-YfFmbXNP.js.map} +1 -1
- package/dist/{navigation-DyytsLRB.js → navigation-Cbp5V8gG.js} +33 -34
- package/dist/navigation-Cbp5V8gG.js.map +1 -0
- package/dist/{navigation-DnQSNMT0.js → navigation-Cs1npsPm.js} +111 -87
- package/dist/navigation-Cs1npsPm.js.map +1 -0
- package/dist/{navigation-row-recipes-DQEXQcqY.js → navigation-row-recipes-DlU-4QYO.js} +2 -2
- package/dist/{navigation-row-recipes-DQEXQcqY.js.map → navigation-row-recipes-DlU-4QYO.js.map} +1 -1
- package/dist/number-CKRBYmZK.js +352 -0
- package/dist/number-CKRBYmZK.js.map +1 -0
- package/dist/overlay.recipes-CNO2S9V6.js +34 -0
- package/dist/overlay.recipes-CNO2S9V6.js.map +1 -0
- package/dist/overlays-DhZO7N-I.js +994 -0
- package/dist/overlays-DhZO7N-I.js.map +1 -0
- package/dist/page-C6R_8jFt.js +325 -0
- package/dist/page-C6R_8jFt.js.map +1 -0
- package/dist/{page-header-D8nERkn5.js → page-header-hUTzcRZX.js} +9 -9
- package/dist/page-header-hUTzcRZX.js.map +1 -0
- package/dist/{pagination-NLGqRirf.js → pagination-Cm0jqa3I.js} +8 -8
- package/dist/{pagination-NLGqRirf.js.map → pagination-Cm0jqa3I.js.map} +1 -1
- package/dist/{popover-CghIYdQf.js → popover-Dcv_9jxr.js} +6 -6
- package/dist/{popover-CghIYdQf.js.map → popover-Dcv_9jxr.js.map} +1 -1
- package/dist/{popover-menu-B4PoWhRl.js → popover-menu-DnRFKnHP.js} +6 -6
- package/dist/{popover-menu-B4PoWhRl.js.map → popover-menu-DnRFKnHP.js.map} +1 -1
- package/dist/{popover.recipes-QlD4JenO.js → popover.recipes-wmbvL8Ah.js} +2 -2
- package/dist/{popover.recipes-QlD4JenO.js.map → popover.recipes-wmbvL8Ah.js.map} +1 -1
- package/dist/primitives-BHrwQXFC.js +379 -0
- package/dist/primitives-BHrwQXFC.js.map +1 -0
- package/dist/primitives.js +5 -5
- package/dist/{progress-BroqrAyV.js → progress-Br9WTFya.js} +7 -7
- package/dist/progress-Br9WTFya.js.map +1 -0
- package/dist/{receipt-BuJynLgf.js → receipt-CV89q1fs.js} +6 -6
- package/dist/{receipt-BuJynLgf.js.map → receipt-CV89q1fs.js.map} +1 -1
- package/dist/{rich-text-editor-BKyG7rWz.js → rich-text-editor-CF8QYt5p.js} +6 -6
- package/dist/{rich-text-editor-BKyG7rWz.js.map → rich-text-editor-CF8QYt5p.js.map} +1 -1
- package/dist/{rich-text-editor.recipes-B72Nfuze.js → rich-text-editor.recipes-CnrbmTS1.js} +4 -4
- package/dist/{rich-text-editor.recipes-B72Nfuze.js.map → rich-text-editor.recipes-CnrbmTS1.js.map} +1 -1
- package/dist/{rich-text-DlxDOtf4.js → rich-text-j-FGAeZW.js} +4 -4
- package/dist/{rich-text-DlxDOtf4.js.map → rich-text-j-FGAeZW.js.map} +1 -1
- package/dist/{scroll-area-D-pIhEKl.js → scroll-area-DRdr16Pt.js} +3 -3
- package/dist/scroll-area-DRdr16Pt.js.map +1 -0
- package/dist/{separator-BhtFyo4x.js → separator-BMEvwnSX.js} +2 -2
- package/dist/{separator-BhtFyo4x.js.map → separator-BMEvwnSX.js.map} +1 -1
- package/dist/{separator-BNIgG3au.js → separator-Do5GWDYi.js} +4 -4
- package/dist/separator-Do5GWDYi.js.map +1 -0
- package/dist/services/actions/action-adapters.d.ts +4 -0
- package/dist/services/actions.js +8 -3
- package/dist/services/actions.js.map +1 -1
- package/dist/{settings-DOTOzeZ2.js → settings-DHk0L2MF.js} +17 -17
- package/dist/settings-DHk0L2MF.js.map +1 -0
- package/dist/sheet-DRFNY1_D.js +207 -0
- package/dist/sheet-DRFNY1_D.js.map +1 -0
- package/dist/sidebar-Cb8WzOvE.js +511 -0
- package/dist/sidebar-Cb8WzOvE.js.map +1 -0
- package/dist/{sidebar-CyR4XKwR.js → sidebar-Crc9M9JV.js} +18 -18
- package/dist/sidebar-Crc9M9JV.js.map +1 -0
- package/dist/{skeleton-3F0uhYn3.js → skeleton-DVMXr15h.js} +4 -4
- package/dist/{skeleton-3F0uhYn3.js.map → skeleton-DVMXr15h.js.map} +1 -1
- package/dist/{smart-card-DjGVV2xr.js → smart-card-Bek-TwUp.js} +222 -207
- package/dist/smart-card-Bek-TwUp.js.map +1 -0
- package/dist/{spinner-Cpf7oRkF.js → spinner-CmTAbEp0.js} +8 -6
- package/dist/spinner-CmTAbEp0.js.map +1 -0
- package/dist/{structure-CRdqVawd.js → structure-hzCW-XsV.js} +3 -3
- package/dist/{structure-CRdqVawd.js.map → structure-hzCW-XsV.js.map} +1 -1
- package/dist/{structure.recipes-Bqhf9oIh.js → structure.recipes-EPz60cU8.js} +37 -19
- package/dist/structure.recipes-EPz60cU8.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/surface-recipes-DOdoBXGm.js +28 -0
- package/dist/surface-recipes-DOdoBXGm.js.map +1 -0
- package/dist/table-D6zKeYQX.js +162 -0
- package/dist/table-D6zKeYQX.js.map +1 -0
- package/dist/{table-CcRDZiLP.js → table-Dn4XSrSB.js} +348 -348
- package/dist/table-Dn4XSrSB.js.map +1 -0
- package/dist/{tabs-BNgu7g0u.js → tabs-Dk8E_knt.js} +14 -13
- package/dist/tabs-Dk8E_knt.js.map +1 -0
- package/dist/{text-inputs-DsR56TR-.js → text-inputs-BFpku0Qd.js} +150 -149
- package/dist/text-inputs-BFpku0Qd.js.map +1 -0
- package/dist/{text.styles-Q4sGAIgA.js → text.styles-g4He6UIW.js} +17 -14
- package/dist/text.styles-g4He6UIW.js.map +1 -0
- package/dist/theme.css +16 -12
- package/dist/themes/green.css +24 -0
- package/dist/{timelines-D1pkt3se.js → timelines-CxuAFIc2.js} +25 -38
- package/dist/timelines-CxuAFIc2.js.map +1 -0
- package/dist/track-recipes-CDcKmndW.js +10 -0
- package/dist/track-recipes-CDcKmndW.js.map +1 -0
- package/dist/{tree-BtmYyMZV.js → tree-BotPlyiD.js} +13 -13
- package/dist/{tree-BtmYyMZV.js.map → tree-BotPlyiD.js.map} +1 -1
- package/dist/typography/rich-text.js +1 -1
- package/dist/typography-CAr3dQhX.js +116 -0
- package/dist/typography-CAr3dQhX.js.map +1 -0
- package/dist/typography.js +2 -2
- package/dist/{ui-provider-DRPn3qNl.js → ui-provider-D2_TeLqw.js} +20 -21
- package/dist/ui-provider-D2_TeLqw.js.map +1 -0
- package/dist/ui-provider.js +1 -1
- package/dist/{upload-CDbYw1WN.js → upload-B0WHW7ak.js} +221 -220
- package/dist/upload-B0WHW7ak.js.map +1 -0
- package/dist/{upload-queue-CNd_hH_a.js → upload-queue-BHZ_wBfd.js} +59 -62
- package/dist/upload-queue-BHZ_wBfd.js.map +1 -0
- package/dist/{usage-card-VyJLUwRr.js → usage-card-U0YBLTNT.js} +42 -43
- package/dist/{usage-card-VyJLUwRr.js.map → usage-card-U0YBLTNT.js.map} +1 -1
- package/dist/{utils-BvH9PSmq.js → utils-Cospvlj1.js} +221 -51
- package/dist/utils-Cospvlj1.js.map +1 -0
- package/dist/value-inputs-CjfzGMsN.js +854 -0
- package/dist/value-inputs-CjfzGMsN.js.map +1 -0
- package/dist/value-typography-Deb3yQZg.js +116 -0
- package/dist/value-typography-Deb3yQZg.js.map +1 -0
- package/dist/{workspace-CcR8r-Nt.js → workspace-YoFjXi6i.js} +44 -45
- package/dist/workspace-YoFjXi6i.js.map +1 -0
- package/docs/consumer-skill/SKILL.md +51 -38
- package/docs/consumer-skill/examples/app-layout.tsx +2 -4
- package/docs/consumer-skill/examples/detail.tsx +3 -4
- package/docs/consumer-skill/examples/edit.tsx +1 -1
- package/docs/consumer-skill/examples/layout-blocks.tsx +20 -0
- package/docs/consumer-skill/examples/manifest.json +28 -6
- package/docs/consumer-skill/examples/scoped-directory.tsx +2 -2
- package/docs/consumer-skill/references/composition.md +89 -17
- package/docs/consumer-skill/references/discovery.md +4 -0
- package/docs/consumer-skill/references/installation.md +22 -0
- package/docs/consumer-skill/references/integration.md +32 -1
- package/docs/consumer-skill/references/public-api.json +111 -70
- package/docs/consumer-skill/references/review.md +20 -4
- package/docs/consumer-skill/references/theming.md +7 -1
- package/docs/consumer-skill/references/tokens.json +5 -2
- package/docs/consumer-skill/references/workflows.md +4 -2
- package/docs/consumer-skill/scripts/composition-policy.mjs +93 -2
- package/docs/consumer-skill/scripts/discovery.mjs +11 -3
- package/docs/consumer-skill/scripts/pin-button-defaults.mjs +95 -0
- package/package.json +5 -3
- package/dist/accordion-BRTcsp8J.js.map +0 -1
- package/dist/action-menu-Drxw_vJk.js +0 -265
- package/dist/action-menu-Drxw_vJk.js.map +0 -1
- package/dist/affordance-geometry.generated-CL84ZN9A.js.map +0 -1
- package/dist/ai-artifact-DLVdK0Py.js.map +0 -1
- package/dist/avatar-Bu2HhitA.js.map +0 -1
- package/dist/badge-CzId1Wlm.js.map +0 -1
- package/dist/button-BZDasD04.js.map +0 -1
- package/dist/buttons-D_6KJvEE.js.map +0 -1
- package/dist/chart-Bsc5BICK.js.map +0 -1
- package/dist/checkbox-BQNDjUCh.js +0 -34
- package/dist/checkbox-BQNDjUCh.js.map +0 -1
- package/dist/choice-inputs-Mk3iWbhr.js +0 -725
- package/dist/choice-inputs-Mk3iWbhr.js.map +0 -1
- package/dist/combobox-BFnbJJp3.js.map +0 -1
- package/dist/combobox-hozNwUcc.js.map +0 -1
- package/dist/command-BnmSchli.js.map +0 -1
- package/dist/comments-u5L0OGip.js.map +0 -1
- package/dist/data-display-Bihs9Ven.js.map +0 -1
- package/dist/date-DOKhJPu7.js +0 -140
- package/dist/date-DOKhJPu7.js.map +0 -1
- package/dist/date-picker-DzP5HQq7.js +0 -1541
- package/dist/date-picker-DzP5HQq7.js.map +0 -1
- package/dist/date-pickers-BpgGz7S-.js +0 -196
- package/dist/date-pickers-BpgGz7S-.js.map +0 -1
- package/dist/display-CS6Hbk18.js.map +0 -1
- package/dist/dropdown-menu-D-boNgGO.js.map +0 -1
- package/dist/feedback-CJkUAapr.js.map +0 -1
- package/dist/field-affordance-recipes-uKY4MsZ_.js +0 -25
- package/dist/field-affordance-recipes-uKY4MsZ_.js.map +0 -1
- package/dist/field-state-recipes-DQQpiLWC.js.map +0 -1
- package/dist/filters-D6FF8L6s.js.map +0 -1
- package/dist/form-sizing-QP8aIRaW.js +0 -103
- package/dist/form-sizing-QP8aIRaW.js.map +0 -1
- package/dist/format-iamDSqs2.js +0 -110
- package/dist/format-iamDSqs2.js.map +0 -1
- package/dist/forms-B5NCbkSC.js.map +0 -1
- package/dist/forms-numeric-Crrm80Lm.js +0 -867
- package/dist/forms-numeric-Crrm80Lm.js.map +0 -1
- package/dist/header-kxruN3RM.js.map +0 -1
- package/dist/input-SX9V0AL3.js +0 -255
- package/dist/item-DE4YnuJx.js +0 -258
- package/dist/item-DE4YnuJx.js.map +0 -1
- package/dist/media-gallery-DLp3HAz0.js.map +0 -1
- package/dist/navigation-DnQSNMT0.js.map +0 -1
- package/dist/navigation-DyytsLRB.js.map +0 -1
- package/dist/number-DasMFWEG.js +0 -269
- package/dist/number-DasMFWEG.js.map +0 -1
- package/dist/overlay.recipes-BxW5FIfK.js +0 -6
- package/dist/overlay.recipes-BxW5FIfK.js.map +0 -1
- package/dist/overlays-DUbs1KEi.js +0 -1011
- package/dist/overlays-DUbs1KEi.js.map +0 -1
- package/dist/page-hGmT4nWK.js +0 -213
- package/dist/page-hGmT4nWK.js.map +0 -1
- package/dist/page-header-D8nERkn5.js.map +0 -1
- package/dist/primitives-C7ff0QaI.js +0 -337
- package/dist/primitives-C7ff0QaI.js.map +0 -1
- package/dist/progress-BroqrAyV.js.map +0 -1
- package/dist/scroll-area-D-pIhEKl.js.map +0 -1
- package/dist/separator-BNIgG3au.js.map +0 -1
- package/dist/settings-DOTOzeZ2.js.map +0 -1
- package/dist/sheet-BFhrNehm.js +0 -205
- package/dist/sheet-BFhrNehm.js.map +0 -1
- package/dist/sidebar-CyR4XKwR.js.map +0 -1
- package/dist/sidebar-SvGJ0Zwi.js +0 -506
- package/dist/sidebar-SvGJ0Zwi.js.map +0 -1
- package/dist/smart-card-DjGVV2xr.js.map +0 -1
- package/dist/spinner-Cpf7oRkF.js.map +0 -1
- package/dist/structure.recipes-Bqhf9oIh.js.map +0 -1
- package/dist/surface-recipes-Dd__PD-w.js +0 -28
- package/dist/surface-recipes-Dd__PD-w.js.map +0 -1
- package/dist/table-CLtJTxoR.js +0 -147
- package/dist/table-CLtJTxoR.js.map +0 -1
- package/dist/table-CcRDZiLP.js.map +0 -1
- package/dist/tabs-BNgu7g0u.js.map +0 -1
- package/dist/text-inputs-DsR56TR-.js.map +0 -1
- package/dist/text.styles-Q4sGAIgA.js.map +0 -1
- package/dist/timelines-D1pkt3se.js.map +0 -1
- package/dist/track-recipes-LLPNVwFg.js +0 -10
- package/dist/track-recipes-LLPNVwFg.js.map +0 -1
- package/dist/typography-BxQgiZyw.js +0 -96
- package/dist/typography-BxQgiZyw.js.map +0 -1
- package/dist/ui-provider-DRPn3qNl.js.map +0 -1
- package/dist/upload-CDbYw1WN.js.map +0 -1
- package/dist/upload-queue-CNd_hH_a.js.map +0 -1
- package/dist/utils-BvH9PSmq.js.map +0 -1
- package/dist/value-inputs-D0KCrfVC.js +0 -840
- package/dist/value-inputs-D0KCrfVC.js.map +0 -1
- package/dist/workspace-CcR8r-Nt.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"timelines-D1pkt3se.js","names":["Text","Stack","SecondaryValue","MonoValue","Percent","Badge","ContentBlock","DOT_PX","ICON_PX","STATUS_TONE","Timeline","cn","className","items","tone","item","Icon","isLast","i","dotSize","statusStyles","Check","Loader2","Circle","StepsCard","steps","titleColor","step","HorizontalDot","status","stepNumber","StepsHorizontal","title","description","idx","lineColor","footerText","defaultChangelogTimelineStrings","KIND_TO_STATUS","KIND_TO_BADGE","KIND_ICON","Plus","Minus","Wrench","GitCommit","ChangelogTimeline","stringsProp","strings","useStrings","labelByKind","entries","entry","defaultMilestonesTimelineStrings","STATUS_TO_TIMELINE","STATUS_ICON","Clock","X","STATUS_BADGE","MilestonesTimeline","labelByStatus","milestones","m"],"sources":["../src/components/blocks/timelines/shared/timeline.tsx","../src/components/blocks/timelines/steps-card/steps-card.tsx","../src/components/blocks/timelines/changelog/types.ts","../src/components/blocks/timelines/changelog/changelog-timeline.tsx","../src/components/blocks/timelines/milestones/types.ts","../src/components/blocks/timelines/milestones/milestones-timeline.tsx"],"sourcesContent":["/**\n * Timeline — shared base primitive for the blocks timeline family.\n *\n * Renders a vertical, dot-and-line list of events. Each item supports an\n * icon (Lucide component), a status that maps to dot tone, a title row, an\n * optional description block, an optional timestamp, and free-form content\n * via `children`. Use this primitive directly for new timeline variants\n * instead of reinventing the dot/line geometry — see `ChangeLogTimeline`,\n * `MilestonesTimeline`, and the existing OrderTimeline / PaymentTimeline /\n * ActivityStream consumers for examples.\n */\nimport type { LucideIcon } from 'lucide-react';\nimport type { ReactNode } from 'react';\n\nimport { SecondaryValue } from '../../../primitives';\nimport { Text } from '../../../typography';\nimport { Stack } from '../../../base/structure';\nimport type { ComponentScale } from '../../../../lib/component-vocabulary';\nimport { cn } from '../../../../lib/utils';\n\nexport type TimelineStatus =\n\t| 'completed'\n\t| 'current'\n\t| 'pending'\n\t| 'success'\n\t| 'warning'\n\t| 'error'\n\t| 'neutral';\n\nexport type TimelineDotSize = ComponentScale;\n\nexport interface TimelineItem {\n\t/** Stable identity for this entry. */\n\tid: string;\n\t/** Surface title. */\n\ttitle: ReactNode;\n\t/** Supporting copy shown under the label. */\n\tdescription?: ReactNode;\n\t/** Formatted time for the entry. */\n\ttimestamp?: ReactNode;\n\t/** Leading glyph. */\n\ticon?: LucideIcon;\n\tstatus?: TimelineStatus;\n\tchildren?: ReactNode;\n}\n\nexport interface TimelineProps {\n\titems: TimelineItem[];\n\tdotSize?: TimelineDotSize;\n\t/** Merged onto the outermost node. */\n\tclassName?: string;\n}\n\nconst DOT_PX: Record<TimelineDotSize, string> = {\n\tsm: 'size-2.5',\n\tmd: 'size-icon-md',\n\tlg: 'size-icon-lg',\n};\n\nconst ICON_PX: Record<TimelineDotSize, string> = {\n\tsm: 'size-2',\n\tmd: 'size-2.5',\n\tlg: 'size-icon-sm',\n};\n\nconst STATUS_TONE: Record<TimelineStatus, { bg: string; text: string; ring: string; line: string }> = {\n\tcompleted: { bg: 'bg-success', text: 'text-success-foreground', ring: 'ring-success/20', line: 'bg-success/40' },\n\tcurrent: { bg: 'bg-primary', text: 'text-primary-foreground', ring: 'ring-primary/30', line: 'bg-primary/40' },\n\tpending: { bg: 'bg-muted', text: 'text-muted-foreground', ring: 'ring-border', line: 'bg-border' },\n\tsuccess: { bg: 'bg-success', text: 'text-success-foreground', ring: 'ring-success/20', line: 'bg-success/40' },\n\twarning: { bg: 'bg-warning', text: 'text-warning-foreground', ring: 'ring-warning/30', line: 'bg-warning/40' },\n\terror: { bg: 'bg-destructive', text: 'text-destructive-foreground', ring: 'ring-destructive/30', line: 'bg-destructive/40' },\n\tneutral: { bg: 'bg-card', text: 'text-foreground', ring: 'ring-border', line: 'bg-border' },\n};\n\nexport function Timeline({ items, dotSize = 'md', className }: TimelineProps) {\n\treturn (\n\t\t<ol className={cn('timeline--component', 'relative m-0 p-0 list-none space-y-space-xl', className)}>\n\t\t\t{items.map((item, i) => {\n\t\t\t\tconst status = item.status ?? 'neutral';\n\t\t\t\tconst tone = STATUS_TONE[status];\n\t\t\t\tconst Icon = item.icon;\n\t\t\t\tconst isLast = i === items.length - 1;\n\n\t\t\t\treturn (\n\t\t\t\t\t<li key={item.id} className=\"relative flex gap-space-lg\">\n\t\t\t\t\t\t{/* Connector line — fills available space below dot until last */}\n\t\t\t\t\t\t{!isLast && (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t'absolute left-[7px] top-4 bottom-[-1rem] w-px',\n\t\t\t\t\t\t\t\t\ttone.line,\n\t\t\t\t\t\t\t\t\tdotSize === 'lg' && 'left-[10px]',\n\t\t\t\t\t\t\t\t\tdotSize === 'sm' && 'left-[5px]',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t<div className=\"relative z-[1] mt-0.5 flex shrink-0 items-start\">\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t'inline-flex items-center justify-center rounded-full ring-2',\n\t\t\t\t\t\t\t\t\ttone.bg,\n\t\t\t\t\t\t\t\t\ttone.text,\n\t\t\t\t\t\t\t\t\ttone.ring,\n\t\t\t\t\t\t\t\t\tDOT_PX[dotSize],\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{!!Icon && <Icon className={ICON_PX[dotSize]} />}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div className=\"min-w-0 flex-1 pb-space-md\">\n\t\t\t\t\t\t\t<Stack gap=\"dense\">\n\t\t\t\t\t\t\t<div className=\"flex items-baseline justify-between gap-space-md\">\n\t\t\t\t\t\t\t\t<Text weight=\"medium\" className=\"leading-tight\">\n\t\t\t\t\t\t\t\t\t{item.title}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t{!!item.timestamp && (\n\t\t\t\t\t\t\t\t\t<SecondaryValue size=\"xs\" className=\"shrink-0 tabular-nums\">\n\t\t\t\t\t\t\t\t\t\t{item.timestamp}\n\t\t\t\t\t\t\t\t\t</SecondaryValue>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{!!item.description && (\n\t\t\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\">\n\t\t\t\t\t\t\t\t\t{item.description}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t{!!item.children && <div className=\"mt-space-md\">{item.children}</div>}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t);\n\t\t\t})}\n\t\t</ol>\n\t);\n}\n\nTimeline.displayName = 'Timeline';\n","import { Stack } from '../../../base/structure';\nimport { Text } from '../../../typography/text';\nimport { Badge } from '../../../base/badge';\nimport { ContentBlock } from '../../../base/display';\nimport { cn } from '../../../../lib/utils';\nimport { Check, Circle, Loader2 } from 'lucide-react';\nimport { Timeline, type TimelineItem } from '../shared';\nimport { type StepStatus, type StepsCardProps, type StepsHorizontalProps } from './types';\n\nconst statusStyles: Record<StepStatus, {\n\tdot: string;\n\tline: string;\n\ttitle: string;\n\tIcon: typeof Check;\n}> = {\n\tcompleted: {\n\t\tdot: 'bg-success text-success-foreground',\n\t\tline: 'bg-success',\n\t\ttitle: 'text-foreground',\n\t\tIcon: Check,\n\t},\n\tcurrent: {\n\t\tdot: 'bg-primary text-primary-foreground ring-4 ring-primary/20',\n\t\tline: 'bg-border',\n\t\ttitle: 'text-foreground',\n\t\tIcon: Loader2,\n\t},\n\tupcoming: {\n\t\tdot: 'bg-muted text-muted-foreground',\n\t\tline: 'bg-border',\n\t\ttitle: 'text-muted-foreground',\n\t\tIcon: Circle,\n\t},\n};\n\n/* ─── Vertical StepsCard (original) ────────────────────────────────────────── */\n\nexport function StepsCard({ title, description, steps, footerText, className }: StepsCardProps) {\n\tconst items: TimelineItem[] = steps.map((step) => {\n\t\tconst { Icon, title: titleColor } = statusStyles[step.status];\n\t\treturn {\n\t\t\tid: step.id,\n\t\t\ttitle: (\n\t\t\t\t<span className=\"inline-flex flex-wrap items-center gap-space-sm\">\n\t\t\t\t\t<Text tag=\"span\" size=\"inherit\" weight=\"semibold\" className={titleColor}>\n\t\t\t\t\t\t{step.title}\n\t\t\t\t\t</Text>\n\t\t\t\t\t{step.badge ? (\n\t\t\t\t\t\t<Badge tone={step.badgeTone ?? 'secondary'}>{step.badge}</Badge>\n\t\t\t\t\t) : null}\n\t\t\t\t</span>\n\t\t\t),\n\t\t\tdescription: step.description,\n\t\t\ttimestamp: step.timestamp,\n\t\t\ticon: Icon,\n\t\t\tstatus: step.status === 'upcoming' ? 'pending' : step.status,\n\t\t\tchildren: step.content,\n\t\t};\n\t});\n\n\treturn (\n\t\t<ContentBlock\n\t\t\tdata-component=\"steps-card\"\n\t\t\tdata-slot=\"steps-card\"\n\t\t\ttitle={title}\n\t\t\tdescription={description}\n\t\t\tfooterText={footerText}\n\t\t\tclassName={cn('steps-card--component', className)}\n\t\t>\n\t\t\t<Timeline items={items} dotSize=\"lg\" />\n\t\t</ContentBlock>\n\t);\n}\n\nStepsCard.displayName = 'StepsCard';\n\n/*──────────────────────────────────────────────────────────────────────────────\n * STEPS HORIZONTAL — Horizontal step bar with connecting lines\n *────────────────────────────────────────────────────────────────────────────*/\n\nfunction HorizontalDot({ status, stepNumber }: { status: StepStatus; stepNumber: number }) {\n\tif (status === 'completed') {\n\t\treturn (\n\t\t\t<div className=\"relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-radius bg-success text-success-foreground\">\n\t\t\t\t<Check className=\"h-4 w-4\" />\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (status === 'current') {\n\t\treturn (\n\t\t\t<div className=\"relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-radius bg-primary text-primary-foreground\">\n\t\t\t\t<Text weight=\"bold\" className=\"text-primary-foreground\">\n\t\t\t\t\t{stepNumber}\n\t\t\t\t</Text>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-radius border-2 border-muted text-muted-foreground\">\n\t\t\t<Text weight=\"medium\" className=\"text-muted-foreground\">\n\t\t\t\t{stepNumber}\n\t\t\t</Text>\n\t\t</div>\n\t);\n}\n\nexport function StepsHorizontal({ title, description, steps, footerText, className }: StepsHorizontalProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-component=\"steps-horizontal\"\n\t\t\tdata-slot=\"steps-horizontal\"\n\t\t\tclassName={cn('steps-horizontal--component @container/steps-horizontal grid min-w-0 gap-space-md', className)}\n\t\t>\n\t\t\t{!!(title || description) && (\n\t\t\t\t<div className=\"steps-horizontal--header grid min-w-0 gap-normal\">\n\t\t\t\t\t{!!title && <Text weight=\"semibold\">{title}</Text>}\n\t\t\t\t\t{!!description && <Text type=\"secondary\">{description}</Text>}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<div className=\"space-y-space-lg @xl/steps-horizontal:hidden\">\n\t\t\t\t{steps.map((step, idx) => {\n\t\t\t\t\tconst isLast = idx === steps.length - 1;\n\t\t\t\t\tconst lineColor = step.status === 'completed' ? 'bg-success' : 'bg-border';\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div key={step.id} className=\"flex gap-space-lg\">\n\t\t\t\t\t\t\t<div className=\"flex flex-col items-center\">\n\t\t\t\t\t\t\t\t<HorizontalDot status={step.status} stepNumber={idx + 1} />\n\t\t\t\t\t\t\t\t{!isLast && <div className={cn('mt-1 w-0.5 flex-1 min-h-5', lineColor)} />}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<Stack gap=\"dense\" className={cn('min-w-0 flex-1 pb-space-md', isLast && 'pb-0')}>\n\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\tweight=\"semibold\"\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t'leading-snug',\n\t\t\t\t\t\t\t\t\t\tstep.status === 'upcoming' ? 'text-muted-foreground' : 'text-foreground',\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{step.title}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t{!!step.description && (\n\t\t\t\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\" className=\"line-clamp-2\">\n\t\t\t\t\t\t\t\t\t\t{step.description}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\n\t\t\t{/* Horizontal scroll wrapper — when total step width exceeds the\n\t\t\t\tcard, this lets users scroll instead of clipping labels. */}\n\t\t\t<div className=\"hidden overflow-x-auto @xl/steps-horizontal:block\">\n\t\t\t\t<div className=\"flex min-w-fit items-start\">\n\t\t\t\t\t{steps.map((step, idx) => {\n\t\t\t\t\t\tconst isLast = idx === steps.length - 1;\n\t\t\t\t\t\tconst lineColor = step.status === 'completed' ? 'bg-success' : 'bg-border';\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div key={step.id} className=\"flex min-w-28 flex-1 items-start\">\n\t\t\t\t\t\t\t\t<div className=\"flex w-full flex-col items-center\">\n\t\t\t\t\t\t\t\t\t<div className=\"flex w-full items-center\">\n\t\t\t\t\t\t\t\t\t\t{idx > 0 && (\n\t\t\t\t\t\t\t\t\t\t\t<div className={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t'h-0.5 flex-1',\n\t\t\t\t\t\t\t\t\t\t\t\tsteps[idx - 1].status === 'completed' ? 'bg-success' : 'bg-border',\n\t\t\t\t\t\t\t\t\t\t\t)} />\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t{idx === 0 && <div className=\"flex-1\" />}\n\n\t\t\t\t\t\t\t\t\t\t<HorizontalDot status={step.status} stepNumber={idx + 1} />\n\n\t\t\t\t\t\t\t\t\t\t{!isLast && (\n\t\t\t\t\t\t\t\t\t\t\t<div className={cn('h-0.5 flex-1', lineColor)} />\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t{!!isLast && <div className=\"flex-1\" />}\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t{/* Labels below dot — clamped to 2 lines so long step\n\t\t\t\t\t\t\t\t\t\tnames break gracefully instead of pushing the\n\t\t\t\t\t\t\t\t\t\trow taller. */}\n\t\t\t\t\t\t\t\t\t<Stack gap=\"dense\" className=\"mt-space-md flex w-full flex-col items-center px-space-xs text-center\">\n\t\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\t\tweight=\"semibold\"\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t'leading-snug line-clamp-2',\n\t\t\t\t\t\t\t\t\t\t\t\tstep.status === 'upcoming' ? 'text-muted-foreground' : 'text-foreground',\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{step.title}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t{!!step.description && (\n\t\t\t\t\t\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\" className=\"leading-snug line-clamp-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t{step.description}\n\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{!!footerText && <Text size=\"xs\" type=\"secondary\">{footerText}</Text>}\n\t\t</div>\n\t);\n}\n\nStepsHorizontal.displayName = 'StepsHorizontal';\n","import type { ReactNode } from 'react';\nimport type { StringsProp } from '../../../../lib/strings';\n\nexport type ChangelogEntryKind = 'added' | 'removed' | 'modified' | 'fixed';\n\nexport interface ChangelogEntry {\n\t/** Stable identity for this entry. */\n\tid: string;\n\tkind: ChangelogEntryKind;\n\t/** Surface title. */\n\ttitle: ReactNode;\n\t/** Supporting copy shown under the label. */\n\tdescription?: ReactNode;\n\tversion?: string;\n\t/** Formatted time for the entry. */\n\ttimestamp?: string;\n\t/** Who produced the entry. */\n\tauthor?: string;\n}\n\nexport interface ChangelogTimelineStrings {\n\t/** Surface title. */\n\ttitle: string;\n\tadded: string;\n\tremoved: string;\n\tmodified: string;\n\tfixed: string;\n}\n\nexport const defaultChangelogTimelineStrings: ChangelogTimelineStrings = {\n\ttitle: 'Changelog',\n\tadded: 'Added',\n\tremoved: 'Removed',\n\tmodified: 'Modified',\n\tfixed: 'Fixed',\n};\n\nexport interface ChangelogTimelineProps {\n\tentries: ChangelogEntry[];\n\t/** Merged onto the outermost node. */\n\tclassName?: string;\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<ChangelogTimelineStrings>;\n}\n","/**\n * ChangelogTimeline — code/release changelog rendered through the shared\n * `Timeline` primitive. Each entry maps a semantic kind (added / removed /\n * modified / fixed) to a colour-coded chip (green / red / amber / blue) plus\n * an optional version label and timestamp. Strings overridable for i18n.\n */\nimport { GitCommit, Minus, Plus, Wrench } from 'lucide-react';\nimport { Badge } from '../../../base/badge';\nimport { MonoValue } from '../../../primitives';\nimport { Text } from '../../../typography';\nimport { Stack } from '../../../base/structure';\nimport { useStrings } from '../../../../lib/strings';\n\nimport {\n\tTimeline,\n\ttype TimelineItem,\n\ttype TimelineStatus,\n} from '../shared';\nimport {\n\tdefaultChangelogTimelineStrings,\n\ttype ChangelogEntry,\n\ttype ChangelogEntryKind,\n\ttype ChangelogTimelineProps,\n} from './types';\n\nimport { cn } from '../../../../lib/utils';\nconst KIND_TO_STATUS: Record<ChangelogEntryKind, TimelineStatus> = {\n\tadded: 'success',\n\tremoved: 'error',\n\tmodified: 'warning',\n\tfixed: 'current',\n};\n\nconst KIND_TO_BADGE: Record<\n\tChangelogEntryKind,\n\t'success' | 'destructive' | 'warning' | 'info'\n> = {\n\tadded: 'success',\n\tremoved: 'destructive',\n\tmodified: 'warning',\n\tfixed: 'info',\n};\n\nconst KIND_ICON = {\n\tadded: Plus,\n\tremoved: Minus,\n\tmodified: Wrench,\n\tfixed: GitCommit,\n} as const;\n\nexport function ChangelogTimeline({\n\tentries,\n\tclassName,\n\tstrings: stringsProp,\n}: ChangelogTimelineProps) {\n\tconst strings = useStrings(defaultChangelogTimelineStrings, stringsProp);\n\tconst labelByKind: Record<ChangelogEntryKind, string> = {\n\t\tadded: strings.added,\n\t\tremoved: strings.removed,\n\t\tmodified: strings.modified,\n\t\tfixed: strings.fixed,\n\t};\n\n\tconst items: TimelineItem[] = entries.map((entry: ChangelogEntry) => ({\n\t\tid: entry.id,\n\t\ttitle: (\n\t\t\t<span className=\"inline-flex flex-wrap items-center gap-space-sm\">\n\t\t\t\t<Badge tone={KIND_TO_BADGE[entry.kind]}>\n\t\t\t\t\t{labelByKind[entry.kind]}\n\t\t\t\t</Badge>\n\t\t\t\t<Text tag=\"span\" size=\"inherit\" weight=\"medium\" lineHeight=\"tight\">\n\t\t\t\t\t{entry.title}\n\t\t\t\t</Text>\n\t\t\t\t{!!entry.version && (\n\t\t\t\t\t<MonoValue size=\"xs\" className=\"text-muted-foreground\">\n\t\t\t\t\t\t{entry.version}\n\t\t\t\t\t</MonoValue>\n\t\t\t\t)}\n\t\t\t</span>\n\t\t),\n\t\tdescription: entry.author ? (\n\t\t\t<Stack render={<span />} direction=\"horizontal\" gap=\"md\" className=\"inline-flex\">\n\t\t\t\t{entry.description}\n\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"discrete\">\n\t\t\t\t\t— {entry.author}\n\t\t\t\t</Text>\n\t\t\t</Stack>\n\t\t) : (\n\t\t\tentry.description\n\t\t),\n\t\ttimestamp: entry.timestamp,\n\t\ticon: KIND_ICON[entry.kind],\n\t\tstatus: KIND_TO_STATUS[entry.kind],\n\t}));\n\n\treturn (\n\t\t<div\n\t\t\tdata-component=\"changelog-timeline\"\n\t\t\tdata-slot=\"changelog-timeline\"\n\t\t\tclassName={cn('changelog-timeline--component', className)}\n\t\t>\n\t\t\t<Timeline items={items} dotSize=\"md\" />\n\t\t</div>\n\t);\n}\n\nChangelogTimeline.displayName = 'ChangelogTimeline';\n","import type { ReactNode } from 'react';\nimport type { StringsProp } from '../../../../lib/strings';\n\nexport type MilestoneStatus = 'completed' | 'in_progress' | 'upcoming' | 'blocked';\n\nexport interface MilestoneItem {\n\t/** Stable identity for this entry. */\n\tid: string;\n\t/** Surface title. */\n\ttitle: ReactNode;\n\t/** Supporting copy shown under the label. */\n\tdescription?: ReactNode;\n\tdueDate?: string;\n\tstatus: MilestoneStatus;\n\t/** 0–100; only used when status is `in_progress`. */\n\tprogress?: number;\n}\n\nexport interface MilestonesTimelineStrings {\n\t/** Surface title. */\n\ttitle: string;\n\tcompleted: string;\n\tin_progress: string;\n\tupcoming: string;\n\tblocked: string;\n\tdueOn: string;\n}\n\nexport const defaultMilestonesTimelineStrings: MilestonesTimelineStrings = {\n\ttitle: 'Milestones',\n\tcompleted: 'Completed',\n\tin_progress: 'In progress',\n\tupcoming: 'Upcoming',\n\tblocked: 'Blocked',\n\tdueOn: 'Due',\n};\n\nexport interface MilestonesTimelineProps {\n\tmilestones: MilestoneItem[];\n\t/** Merged onto the outermost node. */\n\tclassName?: string;\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<MilestonesTimelineStrings>;\n}\n","/**\n * MilestonesTimeline — project / goal milestones rendered through the\n * shared `Timeline` primitive. Each milestone has a status (completed /\n * in-progress / upcoming / blocked) that drives the dot tone, and an\n * optional `progress` percent that renders an inline progress bar when the\n * milestone is in flight. Strings overridable for i18n.\n */\nimport { Check, Circle, Clock, X } from 'lucide-react';\nimport { Badge } from '../../../base/badge';\nimport { Percent } from '../../../primitives';\nimport { Text } from '../../../typography';\nimport { useStrings } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\n\nimport {\n\tTimeline,\n\ttype TimelineItem,\n\ttype TimelineStatus,\n} from '../shared';\nimport {\n\tdefaultMilestonesTimelineStrings,\n\ttype MilestoneItem,\n\ttype MilestoneStatus,\n\ttype MilestonesTimelineProps,\n} from './types';\n\nconst STATUS_TO_TIMELINE: Record<MilestoneStatus, TimelineStatus> = {\n\tcompleted: 'completed',\n\tin_progress: 'current',\n\tupcoming: 'pending',\n\tblocked: 'error',\n};\n\nconst STATUS_ICON = {\n\tcompleted: Check,\n\tin_progress: Clock,\n\tupcoming: Circle,\n\tblocked: X,\n} as const;\n\nconst STATUS_BADGE: Record<MilestoneStatus, 'success' | 'primary' | 'secondary' | 'destructive'> = {\n\tcompleted: 'success',\n\tin_progress: 'primary',\n\tupcoming: 'secondary',\n\tblocked: 'destructive',\n};\n\nexport function MilestonesTimeline({\n\tmilestones,\n\tclassName,\n\tstrings: stringsProp,\n}: MilestonesTimelineProps) {\n\tconst strings = useStrings(defaultMilestonesTimelineStrings, stringsProp);\n\tconst labelByStatus: Record<MilestoneStatus, string> = {\n\t\tcompleted: strings.completed,\n\t\tin_progress: strings.in_progress,\n\t\tupcoming: strings.upcoming,\n\t\tblocked: strings.blocked,\n\t};\n\n\tconst items: TimelineItem[] = milestones.map((m: MilestoneItem) => ({\n\t\tid: m.id,\n\t\ttitle: (\n\t\t\t<span className=\"inline-flex flex-wrap items-center gap-space-sm\">\n\t\t\t\t<Text tag=\"span\" size=\"inherit\" weight=\"medium\" lineHeight=\"tight\">\n\t\t\t\t\t{m.title}\n\t\t\t\t</Text>\n\t\t\t\t<Badge tone={STATUS_BADGE[m.status]}>\n\t\t\t\t\t{labelByStatus[m.status]}\n\t\t\t\t</Badge>\n\t\t\t</span>\n\t\t),\n\t\tdescription: m.description,\n\t\ttimestamp: m.dueDate ? `${strings.dueOn} ${m.dueDate}` : undefined,\n\t\ticon: STATUS_ICON[m.status],\n\t\tstatus: STATUS_TO_TIMELINE[m.status],\n\t\tchildren:\n\t\t\tm.status === 'in_progress' && typeof m.progress === 'number' ? (\n\t\t\t\t<div className=\"space-y-space-xs\">\n\t\t\t\t\t<div className=\"h-1.5 w-full overflow-hidden rounded-full bg-muted\">\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn('h-full rounded-full bg-primary transition-[width] duration-300')}\n\t\t\t\t\t\t\tstyle={{ width: `${Math.max(0, Math.min(100, m.progress))}%` }}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t<Percent value={Math.round(m.progress)} scaled size=\"xs\" type=\"secondary\" align=\"left\" />\n\t\t\t\t</div>\n\t\t\t) : undefined,\n\t}));\n\n\treturn (\n\t\t<div\n\t\t\tdata-component=\"milestones-timeline\"\n\t\t\tdata-slot=\"milestones-timeline\"\n\t\t\tclassName={cn('milestones-timeline--component', className)}\n\t\t>\n\t\t\t<Timeline items={items} dotSize=\"md\" />\n\t\t</div>\n\t);\n}\n\nMilestonesTimeline.displayName = 'MilestonesTimeline';\n"],"mappings":"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"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
//#region src/lib/track-recipes.ts
|
|
2
|
-
var e = {
|
|
3
|
-
sm: "h-[calc(var(--spacing-space-xs)+2px)]",
|
|
4
|
-
md: "h-[calc(var(--spacing-space-sm)+2px)]",
|
|
5
|
-
lg: "h-[calc(var(--spacing-space-md)+2px)]"
|
|
6
|
-
}, t = "data-[orientation=horizontal]:h-[calc(var(--spacing-space-sm)+2px)] data-[orientation=vertical]:w-[calc(var(--spacing-space-sm)+2px)]";
|
|
7
|
-
//#endregion
|
|
8
|
-
export { e as n, t };
|
|
9
|
-
|
|
10
|
-
//# sourceMappingURL=track-recipes-LLPNVwFg.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"track-recipes-LLPNVwFg.js","names":["trackHeightClasses","sliderTrackThickness"],"sources":["../src/lib/track-recipes.ts"],"sourcesContent":["import type { ComponentScale } from './component-vocabulary';\n\n/** Shared progress/slider track thickness, derived from spacing; no public knobs. */\nexport const trackHeightClasses: Record<ComponentScale, string> = {\n sm: 'h-[calc(var(--spacing-space-xs)+2px)]',\n md: 'h-[calc(var(--spacing-space-sm)+2px)]',\n lg: 'h-[calc(var(--spacing-space-md)+2px)]',\n};\nexport const sliderTrackThickness = 'data-[orientation=horizontal]:h-[calc(var(--spacing-space-sm)+2px)] data-[orientation=vertical]:w-[calc(var(--spacing-space-sm)+2px)]';\n"],"mappings":";AAGA,IAAaA,IAAqD;CACjE,IAAI;CACJ,IAAI;CACJ,IAAI;AACL,GACaC,IAAuB"}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { _ as e, p as t, s as n } from "./ui-provider-DRPn3qNl.js";
|
|
3
|
-
import { t as r } from "./utils-BvH9PSmq.js";
|
|
4
|
-
import { o as i, r as a, t as o } from "./text.styles-Q4sGAIgA.js";
|
|
5
|
-
import { forwardRef as s } from "react";
|
|
6
|
-
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
7
|
-
//#region src/components/typography/text.tsx
|
|
8
|
-
var u = s(function({ content: e, children: n, type: a = "main", size: o, weight: s, align: l, lineHeight: u, numeric: d, invert: f = !1, tag: p = "p", className: m, ...h }, g) {
|
|
9
|
-
let { defaultTextSize: _ } = t(), v = n ?? e;
|
|
10
|
-
return v == null || v === "" ? null : /* @__PURE__ */ c(p, {
|
|
11
|
-
"data-typography": "text",
|
|
12
|
-
...h,
|
|
13
|
-
ref: g,
|
|
14
|
-
className: r("text--component", i({
|
|
15
|
-
type: f ? "inverse" : a,
|
|
16
|
-
size: o ?? _,
|
|
17
|
-
weight: s,
|
|
18
|
-
align: l,
|
|
19
|
-
lineHeight: u,
|
|
20
|
-
numeric: d
|
|
21
|
-
}), m),
|
|
22
|
-
children: v
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
//#endregion
|
|
26
|
-
//#region src/components/typography/heading.tsx
|
|
27
|
-
function d({ tag: e = "h3", size: t = "base", subHeading: n, subHeadingClassName: i, subHeadingSize: s, containerClassName: d, align: f = "left", divider: p = !1, className: m, children: h, ref: g, ..._ }) {
|
|
28
|
-
return /* @__PURE__ */ l("div", {
|
|
29
|
-
className: r("heading--component flex min-w-0 flex-col gap-dense", a[f], d),
|
|
30
|
-
children: [h != null && /* @__PURE__ */ c(e, {
|
|
31
|
-
..._,
|
|
32
|
-
ref: g,
|
|
33
|
-
"data-typography": "heading",
|
|
34
|
-
className: r("heading--title m-0 font-heading", o[t], "font-semibold leading-snug text-foreground text-balance", a[f], p && "border-b border-border pb-space-md", m),
|
|
35
|
-
children: h
|
|
36
|
-
}), n != null && /* @__PURE__ */ c(u, {
|
|
37
|
-
type: "secondary",
|
|
38
|
-
size: s,
|
|
39
|
-
align: f,
|
|
40
|
-
className: i,
|
|
41
|
-
children: n
|
|
42
|
-
})]
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
//#endregion
|
|
46
|
-
//#region src/components/typography/display-label.tsx
|
|
47
|
-
function f({ tag: e = "span", tone: t = "default", className: n, ...i }) {
|
|
48
|
-
return /* @__PURE__ */ c(u, {
|
|
49
|
-
...i,
|
|
50
|
-
tag: e,
|
|
51
|
-
size: "sm",
|
|
52
|
-
type: "main",
|
|
53
|
-
weight: "medium",
|
|
54
|
-
lineHeight: "tight",
|
|
55
|
-
"data-typography": "display-label",
|
|
56
|
-
className: r("display-label--component", t === "inverse" && "text-inverse-muted", n)
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
//#endregion
|
|
60
|
-
//#region src/components/typography/label.tsx
|
|
61
|
-
var p = {
|
|
62
|
-
sm: "text-xs",
|
|
63
|
-
md: "text-sm",
|
|
64
|
-
lg: "text-base"
|
|
65
|
-
};
|
|
66
|
-
function m({ content: t, children: i, size: a, className: o, ref: s, ...l }) {
|
|
67
|
-
let { defaultScale: u } = n();
|
|
68
|
-
return /* @__PURE__ */ c("label", {
|
|
69
|
-
...l,
|
|
70
|
-
ref: s,
|
|
71
|
-
"data-typography": "label",
|
|
72
|
-
className: r("label--component font-sans font-medium leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-50", p[e(a, u)], o),
|
|
73
|
-
children: i ?? t
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
//#endregion
|
|
77
|
-
//#region src/components/typography/text-link.tsx
|
|
78
|
-
function h({ type: e = "main", size: n, weight: a, align: o, lineHeight: s, underline: l = !0, className: u, ref: d, ...f }) {
|
|
79
|
-
let { defaultTextSize: p } = t();
|
|
80
|
-
return /* @__PURE__ */ c("a", {
|
|
81
|
-
...f,
|
|
82
|
-
ref: d,
|
|
83
|
-
"data-typography": "link",
|
|
84
|
-
className: r("text-link--component rounded-radius outline-none focus-visible:ring-2 focus-visible:ring-ring", i({
|
|
85
|
-
type: e,
|
|
86
|
-
size: n ?? p,
|
|
87
|
-
weight: a,
|
|
88
|
-
align: o,
|
|
89
|
-
lineHeight: s
|
|
90
|
-
}), l ? "underline underline-offset-4 decoration-current hover:decoration-transparent" : "no-underline", u)
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
//#endregion
|
|
94
|
-
export { u as a, d as i, m as n, f as r, h as t };
|
|
95
|
-
|
|
96
|
-
//# sourceMappingURL=typography-BxQgiZyw.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"typography-BxQgiZyw.js","names":["resolveComponentScale","useTypographyConfig","useDensityConfig","cn","textVariants","textAlignments","headingSizes","Text","forwardRef","Tag","props","value","children","content","invert","type","size","defaultTextSize","className","Heading","align","containerClassName","divider","subHeading","subHeadingSize","subHeadingClassName","DisplayLabel","tone","sizes","Label","defaultScale","TextLink","underline"],"sources":["../src/components/typography/text.tsx","../src/components/typography/heading.tsx","../src/components/typography/display-label.tsx","../src/components/typography/label.tsx","../src/components/typography/text-link.tsx"],"sourcesContent":["import { forwardRef, type ComponentPropsWithoutRef, type ReactNode } from 'react';\nimport { useTypographyConfig, type TextSize } from '../../lib/ui-provider';\nimport { cn } from '../../lib/utils';\nimport { textVariants, type textTypes, type textWeights, type textAlignments, type textLineHeights } from './text.styles';\n\nexport interface TextProps extends Omit<ComponentPropsWithoutRef<'p'>, 'children'> {\n /** Plain text fallback; children take precedence, including zero and empty strings. */\n content?: string;\n children?: ReactNode;\n type?: keyof typeof textTypes;\n size?: TextSize;\n weight?: keyof typeof textWeights;\n align?: keyof typeof textAlignments;\n lineHeight?: keyof typeof textLineHeights;\n invert?: boolean;\n numeric?: boolean;\n tag?: 'div' | 'p' | 'span';\n}\n\nexport const Text = forwardRef<HTMLElement, TextProps>(function Text({\n content, children, type = 'main', size, weight, align, lineHeight,\n numeric, invert = false, tag: Tag = 'p', className, ...props\n}, ref) {\n const {defaultTextSize} = useTypographyConfig();\n const value = children ?? content;\n if (value === undefined || value === null || value === '') return null;\n return <Tag data-typography=\"text\" {...props} ref={ref as never} className={cn('text--component', textVariants({type: invert ? 'inverse' : type, size: size ?? defaultTextSize, weight, align, lineHeight, numeric}), className)}>{value}</Tag>;\n});\n","import type { HTMLAttributes, ReactNode, Ref } from 'react';\nimport type { TextSize } from '../../lib/ui-provider';\nimport { cn } from '../../lib/utils';\nimport { headingSizes, textAlignments } from './text.styles';\nimport { Text } from './text';\n\nexport type HeadingTag = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\nexport type HeadingSize = keyof typeof headingSizes;\nexport interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {\n ref?: Ref<HTMLHeadingElement>;\n tag?: HeadingTag;\n /** Visual emphasis; semantic tag and the default admin size remain independent. */\n size?: HeadingSize;\n subHeading?: ReactNode;\n subHeadingClassName?: string;\n subHeadingSize?: TextSize;\n containerClassName?: string;\n align?: keyof typeof textAlignments;\n divider?: boolean;\n}\n\n/** Semantic heading levels share Themelia's restrained admin heading scale. */\nexport function Heading({tag: Tag = 'h3', size = 'base', subHeading, subHeadingClassName, subHeadingSize, containerClassName, align = 'left', divider = false, className, children, ref, ...props}: HeadingProps) {\n return <div className={cn('heading--component flex min-w-0 flex-col gap-dense', textAlignments[align], containerClassName)}>\n {children != null && <Tag {...props} ref={ref} data-typography=\"heading\" className={cn('heading--title m-0 font-heading', headingSizes[size], 'font-semibold leading-snug text-foreground text-balance', textAlignments[align], divider && 'border-b border-border pb-space-md', className)}>{children}</Tag>}\n {subHeading != null && <Text type=\"secondary\" size={subHeadingSize} align={align} className={subHeadingClassName}>{subHeading}</Text>}\n </div>;\n}\n","import { Text, type TextProps } from './text';\nimport { cn } from '../../lib/utils';\n\nexport interface DisplayLabelProps extends Omit<TextProps, 'size' | 'type' | 'weight' | 'lineHeight'> {tone?: 'default' | 'inverse'}\nexport function DisplayLabel({tag = 'span', tone = 'default', className, ...props}: DisplayLabelProps) {\n return <Text {...props} tag={tag} size=\"sm\" type=\"main\" weight=\"medium\" lineHeight=\"tight\" data-typography=\"display-label\" className={cn('display-label--component', tone === 'inverse' && 'text-inverse-muted', className)} />;\n}\n","import type { LabelHTMLAttributes, ReactNode, Ref } from 'react';\nimport type { ComponentScale } from '../../lib/component-vocabulary';\nimport { useDensityConfig } from '../../lib/ui-provider';\nimport { resolveComponentScale } from '../../lib/ui-provider/scale';\nimport { cn } from '../../lib/utils';\n\nexport interface LabelProps extends Omit<LabelHTMLAttributes<HTMLLabelElement>, 'content'> {content?: ReactNode; size?: ComponentScale; ref?: Ref<HTMLLabelElement>}\nconst sizes = {sm: 'text-xs', md: 'text-sm', lg: 'text-base'} as const;\nexport function Label({content, children, size, className, ref, ...props}: LabelProps) {\n const {defaultScale} = useDensityConfig();\n return <label {...props} ref={ref} data-typography=\"label\" className={cn('label--component font-sans font-medium leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-50', sizes[resolveComponentScale(size, defaultScale)], className)}>{children ?? content}</label>;\n}\n","import type { AnchorHTMLAttributes, Ref } from 'react';\nimport { useTypographyConfig } from '../../lib/ui-provider';\nimport { cn } from '../../lib/utils';\nimport { textVariants } from './text.styles';\nimport type { TextProps } from './text';\n\nexport interface TextLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'type'>, Pick<TextProps, 'type' | 'size' | 'weight' | 'align' | 'lineHeight'> {underline?: boolean; ref?: Ref<HTMLAnchorElement>}\nexport function TextLink({type = 'main', size, weight, align, lineHeight, underline = true, className, ref, ...props}: TextLinkProps) {\n const {defaultTextSize} = useTypographyConfig();\n return <a {...props} ref={ref} data-typography=\"link\" className={cn('text-link--component rounded-radius outline-none focus-visible:ring-2 focus-visible:ring-ring', textVariants({type, size: size ?? defaultTextSize, weight, align, lineHeight}), underline ? 'underline underline-offset-4 decoration-current hover:decoration-transparent' : 'no-underline', className)} />;\n}\n"],"mappings":";;;;;;;AAmBA,IAAaO,IAAOC,EAAmC,SAAc,EACnE,YAAS,aAAU,UAAO,QAAQ,SAAM,WAAQ,UAAO,eACvD,YAAS,YAAS,IAAO,KAAKC,IAAM,KAAK,cAAW,GAAGC,KACtD,GAAK;CACN,IAAM,EAAC,uBAAmBT,EAAoB,GACxCU,IAAQC,KAAYC;CAE1B,OADIF,KAAiC,QAAQA,MAAU,KAAW,OAC3D,kBAACF,GAAD;EAAK,mBAAgB;EAAO,GAAIC;EAAY;EAAc,WAAWP,EAAG,mBAAmBC,EAAa;GAAC,MAAMU,IAAS,YAAYC;GAAM,MAAMC,KAAQC;GAAiB;GAAQ;GAAO;GAAY;EAAO,CAAC,GAAGC,CAAS;EAAI,UAAAP;CAAW,CAAA;AAChP,CAAC;;;ACLD,SAAgBQ,EAAQ,EAAC,KAAKV,IAAM,MAAM,UAAO,QAAQ,eAAY,wBAAqB,mBAAgB,uBAAoB,WAAQ,QAAQ,aAAU,IAAO,cAAW,aAAU,QAAK,GAAGC,KAAsB;CAChN,OAAO,kBAAC,OAAD;EAAK,WAAWP,EAAG,sDAAsDE,EAAee,IAAQC,CAAkB;EAAlH,UAAA,CACJT,KAAY,QAAQ,kBAACH,GAAD;GAAK,GAAIC;GAAY;GAAK,mBAAgB;GAAU,WAAWP,EAAG,mCAAmCG,EAAaU,IAAO,2DAA2DX,EAAee,IAAQE,KAAW,sCAAsCJ,CAAS;GAAI;EAAc,CAAA,GAC3SK,KAAc,QAAQ,kBAAChB,GAAD;GAAM,MAAK;GAAY,MAAMiB;GAAuB;GAAO,WAAWC;GAAsB,UAAAF;EAAiB,CAAA,CACjI;;AACP;;;ACvBA,SAAgBG,EAAa,EAAC,SAAM,QAAQ,UAAO,WAAW,cAAW,GAAGhB,KAA2B;CACrG,OAAO,kBAACH,GAAD;EAAM,GAAIG;EAAY;EAAK,MAAK;EAAK,MAAK;EAAO,QAAO;EAAS,YAAW;EAAQ,mBAAgB;EAAgB,WAAWP,EAAG,4BAA4BwB,MAAS,aAAa,sBAAsBT,CAAS;CAAI,CAAA;AAChO;;;ACCA,IAAMU,IAAQ;CAAC,IAAI;CAAW,IAAI;CAAW,IAAI;AAAW;AAC5D,SAAgBC,EAAM,EAAC,YAAS,aAAU,SAAM,cAAW,QAAK,GAAGnB,KAAoB;CACrF,IAAM,EAAC,oBAAgBR,EAAiB;CACxC,OAAO,kBAAC,SAAD;EAAO,GAAIQ;EAAY;EAAK,mBAAgB;EAAQ,WAAWP,EAAG,iIAAiIyB,EAAM5B,EAAsBgB,GAAMc,CAAY,IAAIZ,CAAS;EAAI,UAAAN,KAAYC;CAAe,CAAA;AACtS;;;ACJA,SAAgBkB,EAAS,EAAC,UAAO,QAAQ,SAAM,WAAQ,UAAO,eAAY,eAAY,IAAM,cAAW,QAAK,GAAGrB,KAAuB;CACpI,IAAM,EAAC,uBAAmBT,EAAoB;CAC9C,OAAO,kBAAC,KAAD;EAAG,GAAIS;EAAY;EAAK,mBAAgB;EAAO,WAAWP,EAAG,iGAAiGC,EAAa;GAAC;GAAM,MAAMY,KAAQC;GAAiB;GAAQ;GAAO;EAAU,CAAC,GAAGe,IAAY,iFAAiF,gBAAgBd,CAAS;CAAI,CAAA;AACjX"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui-provider-DRPn3qNl.js","names":["DEFAULT_UI_CONFIG","isComponentScale","COMPONENT_SCALES","value","resolveComponentScale","propScale","providerScale","fallback","resolveUIConfig","config","createUIStore","createStore","UIStoreContext","createContext","fallbackUIStore","useUIStore","contextualStore","useContext","useStore","selector","UIProvider","parentStore","storeRef","useRef","useEffect","useDensityConfig","s","useFormattingConfig","useMoneyConfig","useDatesConfig","useCommentsConfig","useTypographyConfig","useItemConfig","useButtonConfig","useBadgeConfig","useCardConfig","useToastConfig","useSpinnerConfig","DirectionProvider"],"sources":["../src/lib/ui-provider/defaults.ts","../src/lib/ui-provider/scale.ts","../src/lib/ui-provider/store.ts","../src/lib/ui-provider/provider.tsx","../src/lib/ui-provider/hooks.ts"],"sourcesContent":["/**\n * Hardcoded library-wide defaults.\n *\n * These are the values the store ships with — every component reading via\n * `useFooConfig()` gets these even when no `<UIProvider>` is mounted.\n *\n * Each `<UIProvider>` creates an isolated mount-once store synchronously, so\n * these defaults work for browser rendering, SSR, and multiple React roots.\n * Components outside a provider read the no-provider fallback store.\n */\nimport type { ResolvedUIConfig } from './types';\n\nexport const DEFAULT_UI_CONFIG: ResolvedUIConfig = {\n\tdensity: {\n\t\tdefaultScale: 'md',\n\t},\n\tformatting: {\n\t\tlocale: 'en-US',\n\t},\n\tmoney: {\n\t\tdefaultCurrency: 'USD',\n\t\tdualPricingEnabled: false,\n\t\tdisplayMode: 'default_only',\n\t\tdualPricingDisplay: 'lines',\n\t\tformatMode: 'with_code',\n\t},\n\tdates: {\n\t\tweekStartsOn: 1,\n\t\tformat: 'dd MMM yyyy',\n\t},\n\tcomments: {\n\t\tcomposerPosition: 'top',\n\t},\n\ttypography: {\n\t\tdefaultTextSize: 'sm',\n\t},\n\titem: {\n\t\tdefaultVariant: 'default',\n\t},\n\tbutton: {\n\t\tdefaultTone: 'primary',\n\t\tdefaultButtonStyle: 'solid',\n\t},\n\tbadge: {\n\t\tdefaultTone: 'primary',\n\t},\n\tcard: {\n\t\tdefaultSurface: 'framed',\n\t\tdefaultHeaderDivider: false,\n\t\tdefaultFooterDivider: false,\n\t},\n\ttoast: {\n\t\tduration: 5000,\n\t\tposition: 'bottom-center',\n\t\ttheme: 'dark',\n\t\tcloseButton: true,\n\t\trichColors: false,\n\t\tvisibleToasts: 4,\n\t},\n\tspinner: {\n\t\tdefaultVariant: 'default',\n\t},\n};\n","import {\n\tCOMPONENT_SCALES,\n\ttype ComponentScale,\n} from '../component-vocabulary';\n\n/** Runtime guard for serialized or otherwise untyped component scale values. */\nexport function isComponentScale(value: unknown): value is ComponentScale {\n\treturn COMPONENT_SCALES.includes(value as ComponentScale);\n}\n\n/** Resolve direct, provider, and local scale defaults in precedence order. */\nexport function resolveComponentScale(\n\tpropScale: ComponentScale | undefined,\n\tproviderScale: ComponentScale | undefined,\n\tfallback: ComponentScale = 'md',\n): ComponentScale {\n\tif (isComponentScale(propScale)) return propScale;\n\tif (isComponentScale(providerScale)) return providerScale;\n\treturn isComponentScale(fallback) ? fallback : 'md';\n}\n","/**\n * Store plumbing for `<UIProvider>`.\n *\n * Each provider owns a vanilla Zustand store. This keeps independent React\n * roots and concurrent SSR requests isolated while retaining slice-scoped\n * subscriptions. A fallback store keeps components functional when no\n * provider is mounted and preserves the historical test bootstrap helpers.\n */\nimport { createContext, useContext } from 'react';\nimport { useStore } from 'zustand';\nimport { createStore, type StoreApi } from 'zustand/vanilla';\n\nimport { DEFAULT_UI_CONFIG } from './defaults';\nimport { resolveComponentScale } from './scale';\nimport type { ResolvedUIConfig, UIConfig } from './types';\n\nexport type UIStore = StoreApi<ResolvedUIConfig>;\n\nexport function resolveUIConfig(config: UIConfig = {}): ResolvedUIConfig {\n\treturn {\n\t\tdensity: {\n\t\t\tdefaultScale: resolveComponentScale(\n\t\t\t\tconfig.density?.defaultScale,\n\t\t\t\tDEFAULT_UI_CONFIG.density.defaultScale,\n\t\t\t),\n\t\t},\n\t\tformatting: { ...DEFAULT_UI_CONFIG.formatting, ...config.formatting },\n\t\tmoney: { ...DEFAULT_UI_CONFIG.money, ...config.money },\n\t\tdates: { ...DEFAULT_UI_CONFIG.dates, ...config.dates },\n\t\tcomments: { ...DEFAULT_UI_CONFIG.comments, ...config.comments },\n\t\ttypography: { ...DEFAULT_UI_CONFIG.typography, ...config.typography },\n\t\titem: { ...DEFAULT_UI_CONFIG.item, ...config.item },\n\t\tbutton: { ...DEFAULT_UI_CONFIG.button, ...config.button },\n\t\tbadge: { ...DEFAULT_UI_CONFIG.badge, ...config.badge },\n\t\tcard: { ...DEFAULT_UI_CONFIG.card, ...config.card },\n\t\ttoast: { ...DEFAULT_UI_CONFIG.toast, ...config.toast },\n\t\tspinner: { ...DEFAULT_UI_CONFIG.spinner, ...config.spinner },\n\t};\n}\n\nexport function createUIStore(config: UIConfig = {}): UIStore {\n\treturn createStore<ResolvedUIConfig>(() => resolveUIConfig(config));\n}\n\nexport const UIStoreContext = createContext<UIStore | null>(null);\n\nconst fallbackUIStore = createUIStore();\n\nexport function useUIStore<T>(selector: (state: ResolvedUIConfig) => T): T {\n\tconst contextualStore = useContext(UIStoreContext);\n\treturn useStore(contextualStore ?? fallbackUIStore, selector);\n}\n\n/** Test-only helper for components rendered without a provider. */\nexport function applyUIConfig(config: UIConfig): void {\n\tfallbackUIStore.setState((state) => {\n\t\tconst next = { ...state };\n\t\tconst nextSlices = next as unknown as Record<keyof UIConfig, object>;\n\t\tconst currentSlices = state as unknown as Record<keyof UIConfig, object>;\n\n\t\tfor (const key of Object.keys(config) as Array<keyof UIConfig>) {\n\t\t\tconst override = config[key];\n\t\t\tif (!override) continue;\n\t\t\tnextSlices[key] = { ...currentSlices[key], ...override };\n\t\t}\n\n\t\treturn next;\n\t});\n}\n\n/** Test-only reset for the no-provider fallback store. */\nexport function resetUIConfig(): void {\n\tfallbackUIStore.setState(resolveUIConfig(), true);\n}\n","/**\n * `<UIProvider>` — an isolated, mount-once display-default boundary.\n *\n * The store is created synchronously on the first render, so server output,\n * hydration, and the first browser render all observe the same configuration.\n * Independent roots and SSR requests never share mutable provider state.\n */\nimport { useContext, useEffect, useRef, type ReactNode } from 'react';\n\nimport { createUIStore, UIStoreContext, type UIStore } from './store';\nimport type { UIConfig } from './types';\n\nexport interface UIProviderProps {\n\t/** Partial display-default tree merged over `DEFAULT_UI_CONFIG`. */\n\tconfig?: UIConfig;\n\tchildren: ReactNode;\n}\n\nexport function UIProvider({ config, children }: UIProviderProps) {\n\tconst parentStore = useContext(UIStoreContext);\n\tconst storeRef = useRef<UIStore | null>(null);\n\tconst initialConfigRef = useRef<UIConfig | undefined>(config);\n\tif (parentStore) {\n\t\tthrow new Error(\n\t\t\t'[UIProvider] Nested providers are not supported. Mount one UIProvider ' +\n\t\t\t\t'per React root; use direct component props or CSS ThemeScope boundaries ' +\n\t\t\t\t'for local overrides.',\n\t\t);\n\t}\n\n\tif (storeRef.current === null) {\n\t\tstoreRef.current = createUIStore(config);\n\t}\n\n\tuseEffect(() => {\n\t\tif (import.meta.env?.DEV && initialConfigRef.current !== config) {\n\t\t\tconsole.warn(\n\t\t\t\t'[UIProvider] `config` is mount-once. Subsequent prop identity ' +\n\t\t\t\t\t'changes are ignored; use direct component props for per-mount state.',\n\t\t\t);\n\t\t}\n\t}, [config]);\n\n\treturn (\n\t\t<UIStoreContext.Provider value={storeRef.current}>\n\t\t\t{children}\n\t\t</UIStoreContext.Provider>\n\t);\n}\n","/**\n * Slice selector hooks.\n *\n * Each hook reads exactly one slice from the store. Components that only\n * care about `money` will not re-render when `dates` changes, etc.\n *\n * Every selector returns a guaranteed-populated slice (the store is\n * initialized with `DEFAULT_UI_CONFIG`), so component code can write:\n *\n * const { defaultCurrency } = useMoneyConfig();\n * const currency = props.currency ?? defaultCurrency;\n *\n * — no need to chain optional-access through the slice.\n */\nimport { useUIStore } from './store';\nimport type {\n\tButtonConfigSlice,\n\tBadgeConfigSlice,\n\tCardConfigSlice,\n\tCommentsDefaultsConfig,\n\tDatesConfig,\n\tDensityConfigSlice,\n\tFormattingConfigSlice,\n\tItemConfigSlice,\n\tMoneyConfig,\n\tSpinnerConfigSlice,\n\tToastConfig,\n\tTypographyConfigSlice,\n} from './types';\n\nexport const useDensityConfig = (): DensityConfigSlice =>\n\tuseUIStore((s) => s.density);\n\nexport const useFormattingConfig = (): FormattingConfigSlice =>\n\tuseUIStore((s) => s.formatting);\n\nexport const useMoneyConfig = (): MoneyConfig =>\n\tuseUIStore((s) => s.money);\n\nexport const useDatesConfig = (): DatesConfig =>\n\tuseUIStore((s) => s.dates);\n\nexport const useCommentsConfig = (): CommentsDefaultsConfig =>\n\tuseUIStore((s) => s.comments);\n\nexport const useTypographyConfig = (): TypographyConfigSlice =>\n\tuseUIStore((s) => s.typography);\n\nexport const useItemConfig = (): ItemConfigSlice =>\n\tuseUIStore((s) => s.item);\n\nexport const useButtonConfig = (): ButtonConfigSlice =>\n\tuseUIStore((s) => s.button);\n\nexport const useBadgeConfig = (): BadgeConfigSlice =>\n\tuseUIStore((s) => s.badge);\n\nexport const useCardConfig = (): CardConfigSlice =>\n\tuseUIStore((s) => s.card);\n\nexport const useToastConfig = (): ToastConfig =>\n\tuseUIStore((s) => s.toast);\n\nexport const useSpinnerConfig = (): SpinnerConfigSlice =>\n\tuseUIStore((s) => s.spinner);\n"],"mappings":";;;;;;;;AAYA,IAAaA,IAAsC;CAClD,SAAS,EACR,cAAc,KACf;CACA,YAAY,EACX,QAAQ,QACT;CACA,OAAO;EACN,iBAAiB;EACjB,oBAAoB;EACpB,aAAa;EACb,oBAAoB;EACpB,YAAY;CACb;CACA,OAAO;EACN,cAAc;EACd,QAAQ;CACT;CACA,UAAU,EACT,kBAAkB,MACnB;CACA,YAAY,EACX,iBAAiB,KAClB;CACA,MAAM,EACL,gBAAgB,UACjB;CACA,QAAQ;EACP,aAAa;EACb,oBAAoB;CACrB;CACA,OAAO,EACN,aAAa,UACd;CACA,MAAM;EACL,gBAAgB;EAChB,sBAAsB;EACtB,sBAAsB;CACvB;CACA,OAAO;EACN,UAAU;EACV,UAAU;EACV,OAAO;EACP,aAAa;EACb,YAAY;EACZ,eAAe;CAChB;CACA,SAAS,EACR,gBAAgB,UACjB;AACD;;;ACxDA,SAAgBC,EAAiB,GAAyC;CACzE,OAAOC,EAAiB,SAASC,CAAuB;AACzD;AAGA,SAAgBC,EACf,GACA,GACA,IAA2B,MACV;CAGjB,OAFIH,EAAiBI,CAAS,IAAUA,IACpCJ,EAAiBK,CAAa,IAAUA,IACrCL,EAAiBM,CAAQ,IAAIA,IAAW;AAChD;;;ACDA,SAAgBC,EAAgB,IAAmB,CAAC,GAAqB;CACxE,OAAO;EACN,SAAS,EACR,cAAcJ,EACbK,EAAO,SAAS,cAChBT,EAAkB,QAAQ,YAC3B,EACD;EACA,YAAY;GAAE,GAAGA,EAAkB;GAAY,GAAGS,EAAO;EAAW;EACpE,OAAO;GAAE,GAAGT,EAAkB;GAAO,GAAGS,EAAO;EAAM;EACrD,OAAO;GAAE,GAAGT,EAAkB;GAAO,GAAGS,EAAO;EAAM;EACrD,UAAU;GAAE,GAAGT,EAAkB;GAAU,GAAGS,EAAO;EAAS;EAC9D,YAAY;GAAE,GAAGT,EAAkB;GAAY,GAAGS,EAAO;EAAW;EACpE,MAAM;GAAE,GAAGT,EAAkB;GAAM,GAAGS,EAAO;EAAK;EAClD,QAAQ;GAAE,GAAGT,EAAkB;GAAQ,GAAGS,EAAO;EAAO;EACxD,OAAO;GAAE,GAAGT,EAAkB;GAAO,GAAGS,EAAO;EAAM;EACrD,MAAM;GAAE,GAAGT,EAAkB;GAAM,GAAGS,EAAO;EAAK;EAClD,OAAO;GAAE,GAAGT,EAAkB;GAAO,GAAGS,EAAO;EAAM;EACrD,SAAS;GAAE,GAAGT,EAAkB;GAAS,GAAGS,EAAO;EAAQ;CAC5D;AACD;AAEA,SAAgBC,EAAc,IAAmB,CAAC,GAAY;CAC7D,OAAOC,QAAoCH,EAAgBC,CAAM,CAAC;AACnE;AAEA,IAAaG,IAAiBC,EAA8B,IAAI,GAE1DC,IAAkBJ,EAAc;AAEtC,SAAgBK,EAAc,GAA6C;CAC1E,IAAMC,IAAkBC,EAAWL,CAAc;CACjD,OAAOM,EAASF,KAAmBF,GAAiBK,CAAQ;AAC7D;;;ACjCA,SAAgBC,EAAW,EAAE,WAAQ,eAA6B;CACjE,IAAMC,IAAcJ,EAAWL,CAAc,GACvCU,IAAWC,EAAuB,IAAI;CAE5C,IADyBA,EAA6Bd,CAAM,GACxDY,GACH,MAAU,MACT,oKAGD;CAgBD,OAbIC,EAAS,YAAY,SACxB,EAAS,UAAUZ,EAAcD,CAAM,IAGxCe,QAAgB,CAOhB,GAAG,CAACf,CAAM,CAAC,GAGV,kBAACG,EAAe,UAAhB;EAAyB,OAAOU,EAAS;EACvC;CACuB,CAAA;AAE3B;;;AClBA,IAAaG,UACZV,GAAY,MAAMW,EAAE,OAAO,GAEfC,UACZZ,GAAY,MAAMW,EAAE,UAAU,GAElBE,UACZb,GAAY,MAAMW,EAAE,KAAK,GAEbG,UACZd,GAAY,MAAMW,EAAE,KAAK,GAEbI,UACZf,GAAY,MAAMW,EAAE,QAAQ,GAEhBK,UACZhB,GAAY,MAAMW,EAAE,UAAU,GAElBM,UACZjB,GAAY,MAAMW,EAAE,IAAI,GAEZO,UACZlB,GAAY,MAAMW,EAAE,MAAM,GAEdQ,UACZnB,GAAY,MAAMW,EAAE,KAAK,GAEbS,UACZpB,GAAY,MAAMW,EAAE,IAAI,GAEZU,UACZrB,GAAY,MAAMW,EAAE,KAAK,GAEbW,UACZtB,GAAY,MAAMW,EAAE,OAAO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upload-CDbYw1WN.js","names":["React","resolveComponentScale","useFormattingConfig","useDensityConfig","cn","Button","AlertDescription","Alert","AlertTitle","formatFileSize","FileSize","fieldAffordanceRecipes","ItemGroup","useFileDropTarget","Dropzone","FilePickerInput","AttachmentFileIcon","AttachmentTitle","AttachmentDescription","AttachmentActions","AttachmentMedia","AttachmentContent","Attachment","React$1","React","defaultFileUploadStrings","fileName","accept","minimum","maximum","fileFingerprint","file","fileMatchesAccept","fileType","part","rule","validateOneFile","options","strings","minSizeBytes","formatSize","maxSizeBytes","validateFile","result","validateFileSelection","nextFiles","append","current","fingerprints","accepted","rejections","incoming","validationRejection","fingerprint","maxFiles","hasOwnValue","props","normalizeMaximum","value","fileKey","index","assignInputRef","node","forwardedRef","SelectedFileRow","replaceLabel","removeLabel","showReplace","UploadIcon","onReplace","Text","Trash2Icon","onRemove","FileUploadImpl","sizeProp","stringsProp","_value","_defaultValue","_onValueChange","_selectionMode","_maxFiles","ariaDescribedBy","nativeAriaInvalid","nativeInputProps","useStrings","size","defaultScale","controlled","uncontrolledFiles","setUncontrolledFiles","useState","setRejections","inputRef","useRef","rootRef","continueFocus","pickerWasFocused","generatedId","useId","files","useMemo","target","multipleProps","multiple","errorId","describedBy","hasInvalidState","invalid","commitFiles","useCallback","nextFile","bytes","locale","handleFiles","disabled","onRejectedFiles","clearNativeInput","handleRemove","fileIndex","openPicker","inputProps","picker","className","dropTargetProps","isDragging","TriangleAlert","rejection","FileUpload","forwardRef","FILE_SIZE_UNITS","defaultFormatSize","unitIndex","idCounter","generateId","getExtension","getFingerprint","createMeta","extension","rules","allowed","toErrorMap","useFiles","setFilesState","filesRef","processFiles","incomingFiles","previousFiles","replace","meta","nextRejections","id","MAX_FILE_SIZE_MB","ASPECT_RATIO_CLASSES","defaultImageUploadStrings","count","getImageUploadRejectionMessage","code","details","ImageUploadImpl","inputId","allowedExtensions","parsed","item","subtype","ext","setFiles","removeAll","selected","selectOrChangeButtonLabel","filePreviewUrl","setFilePreviewUrl","acceptedExtensionsLabel","url","previewUrl","initialPreviewUrl","hasPreview","previewAlt","aspectClass","aspectRatio","imgFitClass","fit","computedMaxWidth","maxWidth","wrapperStyle","layout","inlinePreviewStyle","acceptedFile","onValueChange","handleInput","event","triggerFileDialog","remove","ImageIcon","Trash2","ImageUpload","defaultAvatarUploadStrings","getAvatarUploadRejectionMessage","SIZE_PX","AvatarUploadImpl","sizes","s","list","initials","Camera","X","AvatarUpload"],"sources":["../src/components/base/upload/file-upload.strings.ts","../src/components/base/upload/file-upload.validation.ts","../src/components/base/upload/file-upload.tsx","../src/hooks/use-files.ts","../src/components/base/upload/image-upload.tsx","../src/components/base/upload/avatar-upload.tsx"],"sourcesContent":["export interface FileUploadStrings {\n\tinstruction: string;\n\thelper: string;\n\tbrowse: string;\n\treplace: string;\n\tremove: string;\n\tdragOver: string;\n\terrorsHeading: string;\n\treplaceFileAria: (fileName: string) => string;\n\tremoveFileAria: (fileName: string) => string;\n\tinvalidType: (fileName: string, accept: string) => string;\n\tfileTooSmall: (fileName: string, minimum: string) => string;\n\tfileTooLarge: (fileName: string, maximum: string) => string;\n\ttooManyFiles: (fileName: string, maximum: number) => string;\n\tduplicateFile: (fileName: string) => string;\n\tcustomValidationFailed: (fileName: string) => string;\n}\n\nexport const defaultFileUploadStrings: FileUploadStrings = {\n\tinstruction: 'Drag files here or click to browse',\n\thelper: '',\n\tbrowse: 'Browse files',\n\treplace: 'Replace file',\n\tremove: 'Remove file',\n\tdragOver: 'Release to select',\n\terrorsHeading: 'Some files could not be selected',\n\treplaceFileAria: (fileName) => `Replace ${fileName}`,\n\tremoveFileAria: (fileName) => `Remove ${fileName}`,\n\tinvalidType: (fileName, accept) => `${fileName} is not an accepted file type (${accept}).`,\n\tfileTooSmall: (fileName, minimum) => `${fileName} is smaller than the minimum size of ${minimum}.`,\n\tfileTooLarge: (fileName, maximum) => `${fileName} is larger than the maximum size of ${maximum}.`,\n\ttooManyFiles: (fileName, maximum) => `${fileName} exceeds the limit of ${maximum} files.`,\n\tduplicateFile: (fileName) => `${fileName} has already been selected.`,\n\tcustomValidationFailed: (fileName) => `${fileName} did not pass validation.`,\n};\n\n","import type {\n\tFileUploadRejection,\n\tFileUploadValidator,\n} from './file-upload.types';\nimport type { FileUploadStrings } from './file-upload.strings';\n\ninterface ValidateFileSelectionOptions {\n\tincoming: File[];\n\tcurrent: File[];\n\taccept?: string;\n\tminSizeBytes?: number;\n\tmaxSizeBytes?: number;\n\tmaxFiles: number;\n\tappend: boolean;\n\tvalidateFile?: FileUploadValidator;\n\tformatSize: (bytes: number) => string;\n\tstrings: FileUploadStrings;\n}\n\nexport interface FileSelectionResult {\n\taccepted: File[];\n\tnextFiles: File[];\n\trejections: FileUploadRejection[];\n}\n\nfunction fileFingerprint(file: File) {\n\treturn `${file.name}\\u0000${file.size}\\u0000${file.type}\\u0000${file.lastModified}`;\n}\n\nfunction fileMatchesAccept(file: File, accept?: string) {\n\tif (!accept?.trim()) return true;\n\n\tconst fileName = file.name.toLowerCase();\n\tconst fileType = file.type.toLowerCase();\n\treturn accept\n\t\t.split(',')\n\t\t.map((part) => part.trim().toLowerCase())\n\t\t.filter(Boolean)\n\t\t.some((rule) => {\n\t\t\tif (rule.startsWith('.')) return fileName.endsWith(rule);\n\t\t\tif (rule.endsWith('/*')) return fileType.startsWith(rule.slice(0, -1));\n\t\t\treturn fileType === rule;\n\t\t});\n}\n\nfunction validateOneFile(\n\tfile: File,\n\toptions: Pick<\n\t\tValidateFileSelectionOptions,\n\t\t'accept' | 'minSizeBytes' | 'maxSizeBytes' | 'validateFile' | 'formatSize' | 'strings'\n\t>,\n): FileUploadRejection | undefined {\n\tconst { accept, minSizeBytes, maxSizeBytes, validateFile, formatSize, strings } = options;\n\n\tif (!fileMatchesAccept(file, accept)) {\n\t\treturn {\n\t\t\tfile,\n\t\t\tcode: 'invalid-type',\n\t\t\tmessage: strings.invalidType(file.name, accept ?? ''),\n\t\t};\n\t}\n\tif (minSizeBytes !== undefined && file.size < minSizeBytes) {\n\t\treturn {\n\t\t\tfile,\n\t\t\tcode: 'too-small',\n\t\t\tmessage: strings.fileTooSmall(file.name, formatSize(minSizeBytes)),\n\t\t};\n\t}\n\tif (maxSizeBytes !== undefined && file.size > maxSizeBytes) {\n\t\treturn {\n\t\t\tfile,\n\t\t\tcode: 'too-large',\n\t\t\tmessage: strings.fileTooLarge(file.name, formatSize(maxSizeBytes)),\n\t\t};\n\t}\n\tif (validateFile) {\n\t\tlet result: boolean | string;\n\t\ttry {\n\t\t\tresult = validateFile(file);\n\t\t} catch {\n\t\t\tresult = false;\n\t\t}\n\t\tif (result !== true) {\n\t\t\treturn {\n\t\t\t\tfile,\n\t\t\t\tcode: 'custom',\n\t\t\t\tmessage: typeof result === 'string'\n\t\t\t\t\t? result\n\t\t\t\t\t: strings.customValidationFailed(file.name),\n\t\t\t};\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nexport function validateFileSelection({\n\tincoming,\n\tcurrent,\n\taccept,\n\tminSizeBytes,\n\tmaxSizeBytes,\n\tmaxFiles,\n\tappend,\n\tvalidateFile,\n\tformatSize,\n\tstrings,\n}: ValidateFileSelectionOptions): FileSelectionResult {\n\tconst nextFiles = append ? [...current] : [];\n\tconst fingerprints = new Set(nextFiles.map(fileFingerprint));\n\tconst accepted: File[] = [];\n\tconst rejections: FileUploadRejection[] = [];\n\n\tfor (const file of incoming) {\n\t\tconst validationRejection = validateOneFile(file, {\n\t\t\taccept,\n\t\t\tminSizeBytes,\n\t\t\tmaxSizeBytes,\n\t\t\tvalidateFile,\n\t\t\tformatSize,\n\t\t\tstrings,\n\t\t});\n\t\tif (validationRejection) {\n\t\t\trejections.push(validationRejection);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst fingerprint = fileFingerprint(file);\n\t\tif (fingerprints.has(fingerprint)) {\n\t\t\trejections.push({\n\t\t\t\tfile,\n\t\t\t\tcode: 'duplicate',\n\t\t\t\tmessage: strings.duplicateFile(file.name),\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tif (nextFiles.length >= maxFiles) {\n\t\t\trejections.push({\n\t\t\t\tfile,\n\t\t\t\tcode: 'too-many',\n\t\t\t\tmessage: strings.tooManyFiles(file.name, maxFiles),\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\taccepted.push(file);\n\t\tnextFiles.push(file);\n\t\tfingerprints.add(fingerprint);\n\t}\n\n\treturn { accepted, nextFiles, rejections };\n}\n","/**\n * FileUpload — controlled or uncontrolled local-file selection with validation.\n * The component never transfers files; consumers own upload/network behavior.\n */\nimport {\n\tforwardRef,\n\tuseCallback,\n\tuseLayoutEffect,\n\tuseId,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n\ttype ForwardedRef,\n\ttype MutableRefObject,\n} from 'react';\nimport {\n\tTrash2Icon,\n\tTriangleAlert,\n\tUploadIcon,\n} from 'lucide-react';\n\nimport { Button } from '../buttons';\nimport { Alert, AlertDescription, AlertTitle } from '../feedback';\nimport {\n\tItemGroup,\n} from '../item';\nimport { Attachment, AttachmentMedia, AttachmentContent, AttachmentTitle, AttachmentDescription, AttachmentActions, AttachmentFileIcon } from '../attachment';\nimport { FileSize, formatFileSize } from '../../primitives';\nimport { Text } from '../../typography';\nimport { useStrings } from '../../../lib/strings';\nimport { useFormattingConfig, useDensityConfig, type ComponentScale } from '../../../lib/ui-provider';\nimport { resolveComponentScale } from '../../../lib/ui-provider/scale';\nimport { cn } from '../../../lib/utils';\n\nimport { Dropzone } from './dropzone';\nimport {\n\tFilePickerInput,\n\ttype FilePickerNativeInputProps,\n} from './file-picker-input';\nimport {\n\tdefaultFileUploadStrings,\n\ttype FileUploadStrings,\n} from './file-upload.strings';\nimport type {\n\tFileUploadRejection,\n\tMultipleFileUploadProps,\n\tSingleFileUploadProps,\n} from './file-upload.types';\nimport { validateFileSelection } from './file-upload.validation';\nimport { useFileDropTarget } from './use-file-drop-target';\n\n/** Public discriminated single/multiple contract, declared here for docgen discoverability. */\nexport type FileUploadProps = SingleFileUploadProps | MultipleFileUploadProps;\n\nfunction hasOwnValue(props: FileUploadProps) {\n\treturn Object.prototype.hasOwnProperty.call(props, 'value');\n}\n\nfunction normalizeMaximum(value: number | undefined) {\n\tif (value === undefined) return Number.MAX_SAFE_INTEGER;\n\tif (!Number.isFinite(value)) return Number.MAX_SAFE_INTEGER;\n\treturn Math.max(1, Math.floor(value));\n}\n\nfunction fileKey(file: File, index: number) {\n\treturn `${file.name}-${file.size}-${file.type}-${file.lastModified}-${index}`;\n}\n\nfunction assignInputRef(\n\tnode: HTMLInputElement | null,\n\tlocalRef: MutableRefObject<HTMLInputElement | null>,\n\tforwardedRef: ForwardedRef<HTMLInputElement>,\n) {\n\tlocalRef.current = node;\n\tif (typeof forwardedRef === 'function') forwardedRef(node);\n\telse if (forwardedRef) forwardedRef.current = node;\n}\n\ninterface SelectedFileRowProps {\n\tfile: File;\n\tindex: number;\n\tdisabled: boolean;\n\tsize: ComponentScale;\n\tlocale?: string;\n\tstrings: FileUploadStrings;\n\tshowReplace: boolean;\n\tonReplace: () => void;\n\tonRemove: (index: number) => void;\n}\n\nfunction SelectedFileRow({\n\tfile,\n\tindex,\n\tdisabled,\n\tsize,\n\tlocale,\n\tstrings,\n\tshowReplace,\n\tonReplace,\n\tonRemove,\n}: SelectedFileRowProps) {\n\tconst replaceLabel = strings.replaceFileAria(file.name);\n\tconst removeLabel = strings.removeFileAria(file.name);\n\n\treturn (\n\t\t<Attachment\n\t\t\tvariant=\"outline\"\n\t\t\tsize={size}\n\t\t\tclassName=\"file-upload--file flex-nowrap bg-card text-card-foreground\"\n\t\t>\n\t\t\t<AttachmentMedia variant=\"icon\" className=\"file-upload--file-media self-center group-has-data-[slot=item-description]/item:self-center\">\n\t\t\t\t<AttachmentFileIcon name={file.name} />\n\t\t\t</AttachmentMedia>\n\t\t\t<AttachmentContent className=\"file-upload--file-content min-w-0\">\n\t\t\t\t<AttachmentTitle className=\"file-upload--file-name truncate\" title={file.name}>\n\t\t\t\t\t{file.name}\n\t\t\t\t</AttachmentTitle>\n\t\t\t\t<AttachmentDescription className=\"file-upload--file-size\" clamp={1}>\n\t\t\t\t\t<FileSize\n\t\t\t\t\t\tvalue={file.size}\n\t\t\t\t\t\tlocale={locale}\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\talign=\"left\"\n\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t/>\n\t\t\t\t</AttachmentDescription>\n\t\t\t</AttachmentContent>\n\t\t\t<AttachmentActions className=\"file-upload--actions gap-space-xs\">\n\t\t\t\t{showReplace && (\n\t\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=\"sm\" iconOnly\n\t\t\t\t\t\ticon={UploadIcon}\n\t\t\t\t\t\taria-label={replaceLabel}\n\t\t\t\t\t\ttitle={replaceLabel}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tonClick={onReplace}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Text tag=\"span\" size=\"inherit\" className=\"sr-only\">\n\t\t\t\t\t\t\t{strings.replace}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t\t<Button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\ttone=\"destructive\"\n\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\tsize=\"sm\" iconOnly\n\t\t\t\t\ticon={Trash2Icon}\n\t\t\t\t\taria-label={removeLabel}\n\t\t\t\t\ttitle={removeLabel}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonClick={() => onRemove(index)}\n\t\t\t\t>\n\t\t\t\t\t<Text tag=\"span\" size=\"inherit\" className=\"sr-only\">\n\t\t\t\t\t\t{strings.remove}\n\t\t\t\t\t</Text>\n\t\t\t\t</Button>\n\t\t\t</AttachmentActions>\n\t\t</Attachment>\n\t);\n}\n\nfunction FileUploadImpl(\n\tprops: FileUploadProps,\n\tforwardedRef: ForwardedRef<HTMLInputElement>,\n) {\n\tconst {\n\t\taccept,\n\t\tdisabled = false,\n\t\tinvalid = false,\n\t\tsize: sizeProp,\n\t\tminSizeBytes,\n\t\tmaxSizeBytes,\n\t\tvalidateFile,\n\t\tonRejectedFiles,\n\t\tclassName,\n\t\tstrings: stringsProp,\n\t\tmultiple = false,\n\t\tvalue: _value,\n\t\tdefaultValue: _defaultValue,\n\t\tonValueChange: _onValueChange,\n\t\tselectionMode: _selectionMode,\n\t\tmaxFiles: _maxFiles,\n\t\t'aria-describedby': ariaDescribedBy,\n\t\t'aria-invalid': nativeAriaInvalid,\n\t\t...nativeInputProps\n\t} = props;\n\tconst strings = useStrings(defaultFileUploadStrings, stringsProp);\n\tconst { defaultScale } = useDensityConfig();\n\tconst { locale } = useFormattingConfig();\n\tconst size = resolveComponentScale(sizeProp, defaultScale);\n\tconst controlled = hasOwnValue(props);\n\tconst [uncontrolledFiles, setUncontrolledFiles] = useState<File[]>(() => {\n\t\tif (props.multiple) return [...(props.defaultValue ?? [])];\n\t\treturn props.defaultValue ? [props.defaultValue] : [];\n\t});\n\tconst [rejections, setRejections] = useState<FileUploadRejection[]>([]);\n\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\tconst rootRef = useRef<HTMLDivElement | null>(null);\n\tconst continueFocus = useRef(false);\n\tconst pickerWasFocused = useRef(false);\n\tconst generatedId = useId();\n\n\tconst files = useMemo(() => {\n\t\tif (!controlled) return uncontrolledFiles;\n\t\tif (props.multiple) return props.value ?? [];\n\t\treturn props.value ? [props.value] : [];\n\t}, [controlled, props.multiple, props.value, uncontrolledFiles]);\n\tuseLayoutEffect(() => {\n\t\tif (!continueFocus.current) return;\n\t\tconst target = rootRef.current?.querySelector<HTMLElement>('.file-upload--actions button, .file-upload--dropzone input[type=file], .file-upload--dropzone button');\n\t\tif (target) {\n\t\t\ttarget.focus();\n\t\t\tcontinueFocus.current = false;\n\t\t}\n\t}, [files]);\n\tconst multipleProps = props.multiple ? props as MultipleFileUploadProps : undefined;\n\tconst maxFiles = multiple ? normalizeMaximum(multipleProps?.maxFiles) : 1;\n\tconst append = multiple && (multipleProps?.selectionMode ?? 'append') === 'append';\n\tconst errorId = `${nativeInputProps.id ?? `file-upload-${generatedId}`}-errors`;\n\tconst describedBy = [ariaDescribedBy, rejections.length > 0 ? errorId : undefined]\n\t\t.filter(Boolean)\n\t\t.join(' ') || undefined;\n\tconst hasInvalidState = invalid || rejections.length > 0;\n\n\tconst commitFiles = useCallback((nextFiles: File[]) => {\n\t\tif (!controlled) setUncontrolledFiles(nextFiles);\n\t\tif (props.multiple) {\n\t\t\tprops.onValueChange?.(nextFiles);\n\t\t} else {\n\t\t\tconst nextFile = nextFiles[0];\n\t\t\tprops.onValueChange?.(nextFile);\n\t\t}\n\t}, [controlled, props]);\n\n\tconst formatSize = useCallback((bytes: number) => (\n\t\tformatFileSize(bytes, { locale }) ?? `${bytes} B`\n\t), [locale]);\n\n\tconst handleFiles = useCallback((incoming: File[]) => {\n\t\tif (disabled || incoming.length === 0) return false;\n\t\tconst result = validateFileSelection({\n\t\t\tincoming,\n\t\t\tcurrent: files,\n\t\t\taccept,\n\t\t\tminSizeBytes,\n\t\t\tmaxSizeBytes,\n\t\t\tmaxFiles,\n\t\t\tappend,\n\t\t\tvalidateFile,\n\t\t\tformatSize,\n\t\t\tstrings,\n\t\t});\n\n\t\tsetRejections(result.rejections);\n\t\tif (result.rejections.length > 0) onRejectedFiles?.(result.rejections);\n\t\tif (result.accepted.length === 0) return false;\n\t\tcontinueFocus.current = !multiple && (pickerWasFocused.current || Boolean(rootRef.current?.contains(document.activeElement)));\n\t\tpickerWasFocused.current = false;\n\t\tcommitFiles(result.nextFiles);\n\t\treturn result.rejections.length === 0;\n\t}, [\n\t\taccept,\n\t\tappend,\n\t\tcommitFiles,\n\t\tdisabled,\n\t\tmultiple,\n\t\tfiles,\n\t\tformatSize,\n\t\tmaxFiles,\n\t\tmaxSizeBytes,\n\t\tminSizeBytes,\n\t\tonRejectedFiles,\n\t\tstrings,\n\t\tvalidateFile,\n\t]);\n\n\tconst clearNativeInput = useCallback(() => {\n\t\tif (inputRef.current) inputRef.current.value = '';\n\t}, []);\n\n\tconst handleRemove = useCallback((index: number) => {\n\t\tif (disabled) return;\n\t\tsetRejections([]);\n\t\tclearNativeInput();\n\t\tcontinueFocus.current = Boolean(rootRef.current?.contains(document.activeElement));\n\t\tcommitFiles(files.filter((_, fileIndex) => fileIndex !== index));\n\t}, [clearNativeInput, commitFiles, disabled, files]);\n\n\tconst openPicker = useCallback(() => {\n\t\tif (!disabled) {\n\t\t\tpickerWasFocused.current = Boolean(rootRef.current?.contains(document.activeElement));\n\t\t\tinputRef.current?.click();\n\t\t}\n\t}, [disabled]);\n\n\tconst { isDragging, dropTargetProps } = useFileDropTarget({\n\t\tdisabled,\n\t\tonFiles: handleFiles,\n\t});\n\n\tconst inputProps: FilePickerNativeInputProps = {\n\t\t...(nativeInputProps as FilePickerNativeInputProps),\n\t\taccept,\n\t\tmultiple,\n\t\tdisabled,\n\t\t'aria-describedby': describedBy,\n\t\t'aria-invalid': hasInvalidState ? true : nativeAriaInvalid,\n\t};\n\n\tconst picker = (\n\t\t<Dropzone\n\t\t\tref={(node) => assignInputRef(node, inputRef, forwardedRef)}\n\t\t\tonDrop={handleFiles}\n\t\t\taccept={accept}\n\t\t\tmultiple={multiple}\n\t\t\tdisabled={disabled}\n\t\t\tinvalid={hasInvalidState}\n\t\t\tsize={size}\n\t\t\tclassName=\"file-upload--dropzone\"\n\t\t\tinputProps={inputProps}\n\t\t\tstrings={{\n\t\t\t\tinstruction: strings.instruction,\n\t\t\t\thelper: strings.helper,\n\t\t\t\tdragOver: strings.dragOver,\n\t\t\t}}\n\t\t>\n\t\t\t<Button\n\t\t\t\ttype=\"button\"\n\t\t\t\ttone=\"secondary\"\n\t\t\t\tbuttonStyle=\"outline\"\n\t\t\t\tsize={size}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonClick={openPicker}\n\t\t\t>\n\t\t\t\t{strings.browse}\n\t\t\t</Button>\n\t\t</Dropzone>\n\t);\n\n\treturn (\n\t\t<div\n\t\t\tref={rootRef}\n\t\t\tdata-disabled={disabled || undefined}\n\t\t\tdata-invalid={hasInvalidState || undefined}\n\t\t\tclassName={cn('file-upload--component grid gap-space-md', className)}\n\t\t>\n\t\t\t{(multiple || files.length === 0) && picker}\n\n\t\t\t{!multiple && files[0] && (\n\t\t\t\t<div\n\t\t\t\t\t{...dropTargetProps}\n\t\t\t\t\tdata-dragging={isDragging || undefined}\n\t\t\t\t\tdata-invalid={hasInvalidState || undefined}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'file-upload--selected rounded-radius transition-shadow',\n\t\t\t\t\t\thasInvalidState && '[&_.file-upload--file]:border-destructive',\n\t\t\t\t\t\t!disabled && isDragging && (\n\t\t\t\t\t\t\thasInvalidState\n\t\t\t\t\t\t\t\t? 'ring-2 ring-destructive/50 ring-offset-2'\n\t\t\t\t\t\t\t\t: 'ring-2 ring-primary/50 ring-offset-2'\n\t\t\t\t\t\t),\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<FilePickerInput\n\t\t\t\t\t\t{...inputProps}\n\t\t\t\t\t\tref={(node) => assignInputRef(node, inputRef, forwardedRef)}\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\tclassName=\"file-upload--input\"\n\t\t\t\t\t\tonFiles={handleFiles}\n\t\t\t\t\t/>\n\t\t\t\t\t<SelectedFileRow\n\t\t\t\t\t\tfile={files[0]}\n\t\t\t\t\t\tindex={0}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tsize={size}\n\t\t\t\t\t\tlocale={locale}\n\t\t\t\t\t\tstrings={strings}\n\t\t\t\t\t\tshowReplace\n\t\t\t\t\t\tonReplace={openPicker}\n\t\t\t\t\t\tonRemove={handleRemove}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{multiple && files.length > 0 && (\n\t\t\t\t<ItemGroup className=\"file-upload--files\">\n\t\t\t\t\t{files.map((file, index) => (\n\t\t\t\t\t\t<SelectedFileRow\n\t\t\t\t\t\t\tkey={fileKey(file, index)}\n\t\t\t\t\t\t\tfile={file}\n\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\tsize={size}\n\t\t\t\t\t\t\tlocale={locale}\n\t\t\t\t\t\t\tstrings={strings}\n\t\t\t\t\t\t\tshowReplace={false}\n\t\t\t\t\t\t\tonReplace={openPicker}\n\t\t\t\t\t\t\tonRemove={handleRemove}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</ItemGroup>\n\t\t\t)}\n\n\t\t\t{rejections.length > 0 && (\n\t\t\t\t<Alert\n\t\t\t\t\tid={errorId}\n\t\t\t\t\ttone=\"destructive\"\n\t\t\t\t\taria-live=\"polite\"\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'file-upload--errors',\n\t\t\t\t\t\tsize === 'sm' && 'p-surface-xs',\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<TriangleAlert aria-hidden=\"true\" />\n\t\t\t\t\t<AlertTitle>{strings.errorsHeading}</AlertTitle>\n\t\t\t\t\t<AlertDescription>\n\t\t\t\t\t\t<ul className=\"m-0 p-0 list-none grid gap-space-2xs\">\n\t\t\t\t\t\t\t{rejections.map((rejection, index) => (\n\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\tkey={`${rejection.code}-${fileKey(rejection.file, index)}`}\n\t\t\t\t\t\t\t\t\tclassName=\"file-upload--error\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"error\">\n\t\t\t\t\t\t\t\t\t\t{rejection.message}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</AlertDescription>\n\t\t\t\t</Alert>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n/** Selects and validates local File values without performing network uploads. */\nexport const FileUpload = forwardRef<HTMLInputElement, FileUploadProps>(FileUploadImpl);\nFileUpload.displayName = 'FileUpload';\n\nexport { defaultFileUploadStrings };\nexport type { FileUploadStrings };\nexport type {\n\tFileUploadRejection,\n\tFileUploadRejectionCode,\n\tFileUploadCommonProps,\n\tFileUploadSelectionMode,\n\tFileUploadValidator,\n\tMultipleFileUploadProps,\n\tSingleFileUploadProps,\n} from './file-upload.types';\n","import { useCallback, useRef, useState } from 'react';\n\nexport type FileRejectionCode =\n\t| 'invalid-type'\n\t| 'too-small'\n\t| 'too-large'\n\t| 'too-many'\n\t| 'duplicate'\n\t| 'custom';\n\nexport interface FileRejectionDetails {\n\textension?: string;\n\tminimumBytes?: number;\n\tmaximumBytes?: number;\n\tmaximumFiles?: number;\n\t/** Consumer-provided custom copy. The hook never manufactures a message. */\n\tcustomMessage?: string;\n}\n\nexport interface FileRejection {\n\tfile: File;\n\tcode: FileRejectionCode;\n\tdetails: FileRejectionDetails;\n}\n\nexport interface FileValidationRules {\n\tmaxSize?: number;\n\tminSize?: number;\n\tallowedExtensions?: string[];\n\tmaxFiles?: number;\n\tcustomValidator?: (file: File) => boolean | string;\n}\n\nexport interface FileMeta {\n\tid: string;\n\tfile: File;\n\tname: string;\n\tsize: number;\n\tformattedSize: string;\n\ttype: string;\n\textension: string;\n\tlastModified: number;\n}\n\nexport interface FileProcessingResult {\n\taccepted: FileMeta[];\n\tfiles: FileMeta[];\n\trejections: FileRejection[];\n}\n\nexport interface UseFilesReturn {\n\tfiles: FileMeta[];\n\taddFiles: (incoming: FileList | File[]) => FileProcessingResult;\n\tsetFiles: (incoming: FileList | File[]) => FileProcessingResult;\n\tremove: (id: string) => void;\n\tremoveAll: () => void;\n\tformatSize: (bytes: number) => string;\n\t/** Compatibility lookup keyed by file name. Values are typed details, never copy. */\n\tvalidationErrors: Record<string, FileRejection>;\n\trejections: FileRejection[];\n}\n\nconst FILE_SIZE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const;\n\nfunction defaultFormatSize(bytes: number): string {\n\tif (!Number.isFinite(bytes) || bytes <= 0) return '0 B';\n\tconst unitIndex = Math.min(\n\t\tMath.floor(Math.log(bytes) / Math.log(1024)),\n\t\tFILE_SIZE_UNITS.length - 1,\n\t);\n\tconst value = bytes / 1024 ** unitIndex;\n\tconst formattedValue = unitIndex === 0\n\t\t? value.toFixed(0)\n\t\t: Number(value.toFixed(1)).toString();\n\treturn `${formattedValue} ${FILE_SIZE_UNITS[unitIndex]}`;\n}\n\nlet idCounter = 0;\nfunction generateId(): string {\n\tconst timestamp = Date.now().toString(36);\n\tconst count = (idCounter++).toString(36);\n\treturn `${timestamp}-${count}`;\n}\n\nfunction getExtension(file: File) {\n\treturn file.name.split('.').pop()?.toLowerCase() ?? '';\n}\n\nfunction getFingerprint(file: File) {\n\treturn `${file.name}\\u0000${file.size}\\u0000${file.type}\\u0000${file.lastModified}`;\n}\n\nfunction createMeta(file: File): FileMeta {\n\treturn {\n\t\tid: generateId(),\n\t\tfile,\n\t\tname: file.name,\n\t\tsize: file.size,\n\t\tformattedSize: defaultFormatSize(file.size),\n\t\ttype: file.type,\n\t\textension: getExtension(file),\n\t\tlastModified: file.lastModified,\n\t};\n}\n\nfunction validateFile(\n\tfile: File,\n\trules?: FileValidationRules,\n): FileRejection | undefined {\n\tconst extension = getExtension(file);\n\tif (rules?.minSize !== undefined && file.size < rules.minSize) {\n\t\treturn {\n\t\t\tfile,\n\t\t\tcode: 'too-small',\n\t\t\tdetails: { minimumBytes: rules.minSize },\n\t\t};\n\t}\n\tif (rules?.maxSize !== undefined && file.size > rules.maxSize) {\n\t\treturn {\n\t\t\tfile,\n\t\t\tcode: 'too-large',\n\t\t\tdetails: { maximumBytes: rules.maxSize },\n\t\t};\n\t}\n\tif (\n\t\trules?.allowedExtensions &&\n\t\t!rules.allowedExtensions.some((allowed) => allowed.toLowerCase().replace(/^\\./, '') === extension)\n\t) {\n\t\treturn {\n\t\t\tfile,\n\t\t\tcode: 'invalid-type',\n\t\t\tdetails: { extension },\n\t\t};\n\t}\n\tif (rules?.customValidator) {\n\t\tlet result: boolean | string;\n\t\ttry {\n\t\t\tresult = rules.customValidator(file);\n\t\t} catch {\n\t\t\tresult = false;\n\t\t}\n\t\tif (result !== true) {\n\t\t\treturn {\n\t\t\t\tfile,\n\t\t\t\tcode: 'custom',\n\t\t\t\tdetails: {\n\t\t\t\t\tcustomMessage: typeof result === 'string' && result.length > 0\n\t\t\t\t\t\t? result\n\t\t\t\t\t\t: undefined,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction toErrorMap(rejections: FileRejection[]) {\n\treturn Object.fromEntries(rejections.map((rejection) => [rejection.file.name, rejection]));\n}\n\nexport function useFiles(rules?: FileValidationRules): UseFilesReturn {\n\tconst [files, setFilesState] = useState<FileMeta[]>([]);\n\tconst filesRef = useRef<FileMeta[]>([]);\n\tconst [rejections, setRejections] = useState<FileRejection[]>([]);\n\n\tconst formatSize = useCallback(defaultFormatSize, []);\n\n\tconst processFiles = useCallback((incoming: FileList | File[], replace: boolean) => {\n\t\tconst incomingFiles = Array.isArray(incoming) ? incoming : Array.from(incoming);\n\t\tconst previousFiles = filesRef.current;\n\t\tlet nextFiles = replace ? [] : [...previousFiles];\n\t\tconst fingerprints = new Set(nextFiles.map((meta) => getFingerprint(meta.file)));\n\t\tconst accepted: FileMeta[] = [];\n\t\tconst nextRejections: FileRejection[] = [];\n\n\t\tfor (const file of incomingFiles) {\n\t\t\tconst fingerprint = getFingerprint(file);\n\t\t\tif (fingerprints.has(fingerprint)) {\n\t\t\t\tnextRejections.push({ file, code: 'duplicate', details: {} });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst rejection = validateFile(file, rules);\n\t\t\tif (rejection) {\n\t\t\t\tnextRejections.push(rejection);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (rules?.maxFiles !== undefined && nextFiles.length >= rules.maxFiles) {\n\t\t\t\tnextRejections.push({\n\t\t\t\t\tfile,\n\t\t\t\t\tcode: 'too-many',\n\t\t\t\t\tdetails: { maximumFiles: rules.maxFiles },\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst meta = createMeta(file);\n\t\t\taccepted.push(meta);\n\t\t\tnextFiles.push(meta);\n\t\t\tfingerprints.add(fingerprint);\n\t\t}\n\t\tif (replace && accepted.length === 0 && nextRejections.length > 0) {\n\t\t\tnextFiles = previousFiles;\n\t\t}\n\n\t\tfilesRef.current = nextFiles;\n\t\tsetFilesState(nextFiles);\n\t\tsetRejections(nextRejections);\n\t\treturn { accepted, files: nextFiles, rejections: nextRejections };\n\t}, [rules]);\n\n\tconst addFiles = useCallback(\n\t\t(incoming: FileList | File[]) => processFiles(incoming, false),\n\t\t[processFiles],\n\t);\n\tconst setFiles = useCallback(\n\t\t(incoming: FileList | File[]) => processFiles(incoming, true),\n\t\t[processFiles],\n\t);\n\tconst remove = useCallback((id: string) => {\n\t\tconst nextFiles = filesRef.current.filter((file) => file.id !== id);\n\t\tfilesRef.current = nextFiles;\n\t\tsetFilesState(nextFiles);\n\t}, []);\n\tconst removeAll = useCallback(() => {\n\t\tfilesRef.current = [];\n\t\tsetFilesState([]);\n\t\tsetRejections([]);\n\t}, []);\n\n\treturn {\n\t\tfiles,\n\t\taddFiles,\n\t\tsetFiles,\n\t\tremove,\n\t\tremoveAll,\n\t\tformatSize,\n\t\tvalidationErrors: toErrorMap(rejections),\n\t\trejections,\n\t};\n}\n","/**\n * ImageUpload — preview-first image picker. Drops in a file → renders an img\n * preview with a configurable aspect ratio and fit mode. Layout can be\n * stacked (preview on top, controls below) or inline (preview alongside\n * controls). Reflects controlled `value` and reports change via `onValueChange`.\n * Strings overridable for i18n.\n */\nimport { ImageIcon, Trash2 } from 'lucide-react';\nimport React, { useEffect, useId, useMemo, useRef, useState, useCallback } from 'react';\nimport { Button } from '../buttons';\nimport { Text } from '../../typography';\nimport { useFiles, type FileRejection } from '../../../hooks/use-files';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\nimport { useFileDropTarget } from './use-file-drop-target';\n\nconst MAX_FILE_SIZE_MB = 2;\n\ntype ImageUploadAspectRatio = 'square' | 'standard' | 'widescreen' | 'portrait';\ntype ImageUploadLayout = 'stacked' | 'inline';\ntype ImageUploadFit = 'cover' | 'contain';\n\nconst ASPECT_RATIO_CLASSES: Record<ImageUploadAspectRatio, string> = {\n\t\tsquare: 'aspect-square',\n\t\tstandard: 'aspect-[4/3]',\n\t\twidescreen: 'aspect-[16/9]',\n\t\tportrait: 'aspect-[9/16]',\n};\n\nexport interface ImageUploadStrings {\n\t\tselect: string;\n\t\tchange: string;\n\t\tremove: string;\n\t\tnoSelection: string;\n\t\tkeepCurrent: string;\n\t/** Accessible description for an existing preview without a selected file name. */\n\tpreviewAlt?: string;\n\t\t/** Template for the supports-text. `{ext}` is the comma-separated allowed\n\t\t * extensions; `{size}` is the max-size MB number. */\n\t\tsupportsTemplate: string;\n\tinvalidType: (fileName: string, extension: string) => string;\n\ttooSmall: (fileName: string, minimum: string) => string;\n\ttooLarge: (fileName: string, maximum: string) => string;\n\ttooMany: (fileName: string, maximum: number) => string;\n\tduplicate: (fileName: string) => string;\n\tcustomValidationFailed: (fileName: string) => string;\n\t\t/** Summary line when `multiple` is set and more than one file is selected.\n\t\t * Receives the count of files beyond the displayed one — e.g. `count=3`\n\t\t * for \"+ 3 more files\". Override to swap the English plural-`s` rule\n\t\t * (`'+ ' + count + ' more file' + (count === 1 ? '' : 's')`) for the\n\t\t * consumer locale. */\n\t\tmoreFiles: (count: number) => string;\n}\n\nexport const defaultImageUploadStrings: ImageUploadStrings = {\n\t\tselect: 'Select image',\n\t\tchange: 'Change image',\n\t\tremove: 'Remove',\n\t\tnoSelection: 'No file selected yet.',\n\t\tkeepCurrent: 'Current image stays until you upload a new one.',\n\tpreviewAlt: 'Selected image',\n\t\tsupportsTemplate: 'Supports {ext} files up to {size} MB.',\n\tinvalidType: (fileName, extension) => `${fileName} uses an unsupported .${extension || 'unknown'} file type.`,\n\ttooSmall: (fileName, minimum) => `${fileName} is smaller than ${minimum}.`,\n\ttooLarge: (fileName, maximum) => `${fileName} is larger than ${maximum}.`,\n\ttooMany: (fileName, maximum) => `${fileName} exceeds the limit of ${maximum} images.`,\n\tduplicate: (fileName) => `${fileName} is already selected.`,\n\tcustomValidationFailed: (fileName) => `${fileName} did not pass validation.`,\n\t\tmoreFiles: (count) => `+ ${count} more file${count === 1 ? '' : 's'}`,\n};\n\nfunction getImageUploadRejectionMessage(\n\trejection: FileRejection,\n\tstrings: ImageUploadStrings,\n\tformatSize: (bytes: number) => string,\n) {\n\tconst { file, code, details } = rejection;\n\tswitch (code) {\n\t\tcase 'invalid-type':\n\t\t\treturn strings.invalidType(file.name, details.extension ?? '');\n\t\tcase 'too-small':\n\t\t\treturn strings.tooSmall(file.name, formatSize(details.minimumBytes ?? 0));\n\t\tcase 'too-large':\n\t\t\treturn strings.tooLarge(file.name, formatSize(details.maximumBytes ?? 0));\n\t\tcase 'too-many':\n\t\t\treturn strings.tooMany(file.name, details.maximumFiles ?? 1);\n\t\tcase 'duplicate':\n\t\t\treturn strings.duplicate(file.name);\n\t\tcase 'custom':\n\t\t\treturn details.customMessage ?? strings.customValidationFailed(file.name);\n\t}\n}\n\nexport interface ImageUploadProps {\n\t\t/** Accepted MIME types or extensions, as the native `accept` attribute. */\n\t\taccept?: string;\n\t\t/** Allows more than one file to be chosen. */\n\t\tmultiple?: boolean;\n\t\t/** Selected files. Controlled. */\n\t\tvalue?: File;\n\t\tonValueChange?: (file?: File) => void;\n\t\t/** Disables the control and blocks drops. */\n\t\tdisabled?: boolean;\n\t\t/** Image shown before anything is chosen — an existing upload. */\n\t\tinitialPreviewUrl?: string;\n\t\t/** Aspect ratio the preview is cropped to. */\n\t\taspectRatio?: ImageUploadAspectRatio;\n\t\t/** How the preview fills its frame — cover or contain. */\n\t\tfit?: ImageUploadFit;\n\t\t/** Caps the preview's width. */\n\t\tmaxWidth?: number | string;\n\t\t/** Arrangement of the preview and drop target. */\n\t\tlayout?: ImageUploadLayout;\n\t\t/** Applies the invalid styling. */\n\t\tinvalid?: boolean;\n\t\t/** Override default strings (button labels, helper text, supports template). */\n\t\tstrings?: StringsProp<ImageUploadStrings>;\n}\n\nfunction ImageUploadImpl(\n\t\t{\n\t\taccept = '.png,.jpg,.jpeg,.gif,.svg',\n\t\tmultiple = false,\n\t\tvalue,\n\t\tonValueChange,\n\t\tdisabled,\n\t\tinitialPreviewUrl,\n\t\taspectRatio = 'square',\n\t\tfit = 'cover',\n\t\tmaxWidth,\n\t\tlayout = 'stacked',\n\t\tinvalid,\n\t\tstrings: stringsProp,\n}: ImageUploadProps,\n\t\tforwardedRef: React.ForwardedRef<HTMLInputElement>,\n) {\n\t\tconst strings = useStrings(defaultImageUploadStrings, stringsProp);\n\t\tconst inputId = useId();\n\t\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\n\t\tconst allowedExtensions = useMemo(() => {\n\t\t\t\tif (!accept) {\n\t\t\t\t\t\treturn ['png', 'jpg', 'jpeg', 'gif', 'svg'];\n\t\t\t\t}\n\n\t\t\t\tconst parsed = accept\n\t\t\t\t\t\t.split(',')\n\t\t\t\t\t\t.map((item) => item.trim())\n\t\t\t\t\t\t.map((item) => {\n\t\t\t\t\t\t\t\tif (!item) return null;\n\t\t\t\t\t\t\t\tif (item.startsWith('.')) {\n\t\t\t\t\t\t\t\t\t\treturn item.slice(1).toLowerCase();\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (item.includes('/')) {\n\t\t\t\t\t\t\t\t\t\tconst subtype = item.split('/')[1] ?? '';\n\t\t\t\t\t\t\t\t\t\tif (subtype === '*' || subtype.length === 0) {\n\t\t\t\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\treturn subtype.replace(/\\+.*/, '').toLowerCase();\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn item.toLowerCase();\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.filter((ext): ext is string => Boolean(ext));\n\n\t\t\t\tif (parsed.length === 0) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\treturn Array.from(new Set(parsed));\n\t\t}, [accept]);\n\n\t\tconst fileRules = useMemo(\n\t\t\t\t() => ({\n\t\t\t\t\t\tmaxFiles: multiple ? undefined : 1,\n\t\t\tmaxSize: MAX_FILE_SIZE_MB * 1024 * 1024,\n\t\t\t\t\t\tallowedExtensions,\n\t\t\t\t}),\n\t\t\t\t[multiple, allowedExtensions]\n\t\t);\n\n\t\tconst { files, setFiles, remove, removeAll, formatSize, rejections } = useFiles(fileRules);\n\n\t\t// Reflect controlled value into local preview if provided\n\t\tuseEffect(() => {\n\t\t\t\tif (value) {\n\t\t\t\t\t\tsetFiles([value]);\n\t\t\t\t} else {\n\t\t\t\t\t\tremoveAll();\n\t\t\t\t\t\tif (inputRef.current) {\n\t\t\t\t\t\t\t\tinputRef.current.value = '';\n\t\t\t\t\t\t}\n\t\t\t\t}\n\t\t}, [value, setFiles, removeAll]);\n\n\t\tconst selected = files[0];\n\tconst selectOrChangeButtonLabel = selected ? strings.change : strings.select;\n\t\tconst [filePreviewUrl, setFilePreviewUrl] = useState<string | undefined>(undefined);\n\n\t\tconst acceptedExtensionsLabel = useMemo(() => {\n\t\t\t\tif (!allowedExtensions || allowedExtensions.length === 0) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\treturn allowedExtensions.map((ext) => ext.toUpperCase()).join(', ');\n\t\t}, [allowedExtensions]);\n\n\t\tuseEffect(() => {\n\t\t\t\tconst file = selected?.file ?? value;\n\t\t\t\tif (!file) {\n\t\t\t\t\t\tsetFilePreviewUrl(undefined);\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst url = URL.createObjectURL(file);\n\t\t\t\tsetFilePreviewUrl(url);\n\t\t\t\treturn () => URL.revokeObjectURL(url);\n\t\t}, [selected, value]);\n\n\t\tconst previewUrl = filePreviewUrl ?? initialPreviewUrl;\n\t\tconst hasPreview = Boolean(previewUrl);\n\tconst previewAlt = selected?.name ?? strings.previewAlt ?? defaultImageUploadStrings.previewAlt;\n\t\tconst aspectClass = ASPECT_RATIO_CLASSES[aspectRatio] ?? ASPECT_RATIO_CLASSES.square;\n\t\tconst imgFitClass = fit === 'contain' ? 'object-contain p-space-sm' : 'object-cover';\n\t\t// Default max-width caps the preview at a sensible thumbnail size — without\n\t\t// this, an `aspect-square` preview inside a wide form column becomes a\n\t\t// huge square (`w-full` × 1:1 ratio = container width tall). Consumers\n\t\t// can override via the `maxWidth` prop.\n\t\tconst computedMaxWidth = maxWidth ? (typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth) : '240px';\n\t\tconst wrapperStyle = layout === 'inline' ? undefined : { maxWidth: computedMaxWidth };\n\t\tconst inlinePreviewStyle =\n\t\t\t\tlayout === 'inline'\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tmaxWidth: maxWidth ? computedMaxWidth : '185px',\n\t\t\t\t\t\t\t\t\twidth: '100%',\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined;\n\n\t\tconst handleFiles = useCallback((incoming: File[]) => {\n\t\t\tif (disabled || incoming.length === 0) return;\n\t\t\tconst result = setFiles(incoming);\n\t\t\tconst acceptedFile = result.accepted[0]?.file;\n\t\t\tif (acceptedFile) onValueChange?.(acceptedFile);\n\t\t}, [disabled, setFiles, onValueChange]);\n\t\tconst handleInput = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\thandleFiles(Array.from(event.target.files ?? []));\n\t\t}, [handleFiles]);\n\t\tconst { isDragging, dropTargetProps } = useFileDropTarget({ disabled, onFiles: handleFiles });\n\n\t\tconst triggerFileDialog = useCallback(() => {\n\t\t\t\tif (disabled) return;\n\t\t\t\tinputRef.current?.click();\n\t\t}, [disabled]);\n\n\t\tconst handleRemove = useCallback(() => {\n\t\t\t\tif (selected) {\n\t\t\t\t\t\tremove(selected.id);\n\t\t\t\t}\n\t\t\t\tonValueChange?.(undefined);\n\t\t\t\tif (inputRef.current) {\n\t\t\t\t\t\tinputRef.current.value = '';\n\t\t\t\t}\n\t\t}, [selected, remove, onValueChange]);\n\n\t\treturn (\n\t\t\t\t<div className={cn('image-upload--component', 'grid gap-space-md')} style={wrapperStyle}>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tref={(node) => { inputRef.current = node; if (typeof forwardedRef === \"function\") forwardedRef(node); else if (forwardedRef) forwardedRef.current = node; }}\n\t\t\t\t\t\t\t\tid={inputId}\n\t\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\t\tclassName=\"sr-only\"\n\t\t\t\t\t\t\t\taria-label={selectOrChangeButtonLabel}\n\t\t\t\t\t\t\t\taccept={accept}\n\t\t\t\t\t\t\t\tmultiple={multiple}\n\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\tonChange={handleInput}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<div className={cn(layout === 'inline' ? 'flex flex-wrap items-start gap-space-xl' : 'grid gap-space-md')}>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t{...dropTargetProps}\n\t\t\t\t\t\t\t\t\t\tdata-dragging={isDragging || undefined}\n\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t'relative overflow-hidden rounded-radius border transition-colors',\n\t\t\t\t\t\t\t\t\t\t\t\tlayout === 'inline' ? 'flex-shrink-0 w-full' : 'w-full',\n\t\t\t\t\t\t\t\t\t\t\t\taspectClass,\n\t\t\t\t\t\t\t\t\t\t\t\t!disabled && isDragging && 'ring-2 ring-ring',\n\t\t\t\t\t\t\t\t\t\t\t\thasPreview\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? 'border-border bg-muted/20'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'border-dashed bg-background text-muted-foreground ',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tinvalid ? 'border-destructive' : 'border-border'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\tstyle={inlinePreviewStyle}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{hasPreview && previewUrl ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsrc={previewUrl}\n\t\t\t\t\t\t\t\t\t\t\t\talt={previewAlt}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={cn('absolute inset-0 box-border h-full w-full', imgFitClass)}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"absolute inset-0 flex items-center justify-center\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<ImageIcon aria-hidden className=\"size-icon-lg\" />\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t<div className={cn('grid gap-space-sm', layout === 'inline' && 'flex-1 min-w-0 basis-40')}>\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex flex-wrap items-center gap-space-md\">\n\t <Button\n\t type=\"button\"\n\t tone=\"secondary\"\n\t buttonStyle=\"outline\"\n\t onClick={triggerFileDialog}\n\t disabled={disabled}\n\t >\n\t {selectOrChangeButtonLabel}\n\t </Button>\n\t\t\t\t\t\t\t\t\t\t\t\t{!selected && !!hasPreview && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\">{strings.keepCurrent}</Text>\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t\t{!!acceptedExtensionsLabel && (\n\t\t\t\t\t\t\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{strings.supportsTemplate\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.replace('{ext}', acceptedExtensionsLabel)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.replace('{size}', String(MAX_FILE_SIZE_MB))}\n\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t\t{!!selected && (\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"grid gap-space-2xs\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Text weight=\"medium\" title={selected.name} className=\"truncate\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{selected.name}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{selected.formattedSize}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{!!multiple && files.length > 1 && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{strings.moreFiles(files.length - 1)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttone=\"destructive\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ticon={Trash2}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={handleRemove}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{strings.remove}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t\t{!selected && !hasPreview && (\n\t\t\t\t\t\t\t\t\t\t\t\t<Text size=\"xs\" type=\"secondary\">{strings.noSelection}</Text>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* Validation errors */}\n\t\t\t\t\t\t{rejections.length > 0 && (\n\t\t\t\t\t\t\t\t<div className=\"image-upload--errors grid gap-space-2xs\" role=\"alert\" aria-live=\"polite\">\n\t\t\t\t\t\t\t\t\t\t{rejections.map((rejection, index) => (\n\t\t\t\t\t\t\t\t\t\t\t\t<Text key={`${rejection.file.name}-${rejection.code}-${index}`} size=\"xs\" type=\"error\">\n\t\t\t\t\t\t\t{getImageUploadRejectionMessage(rejection, strings, formatSize)}\n\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t);\n}\n\nconst ImageUpload = React.forwardRef<HTMLInputElement, ImageUploadProps>(ImageUploadImpl);\nImageUpload.displayName = 'ImageUpload';\n\nexport { ImageUpload };\n","import * as React from 'react';\n/**\n * AvatarUpload — round avatar picker. Click or drag a file onto the circle to\n * upload; an X button (visible on hover) clears the selection. Honours\n * controlled `value` (a `File`), and reflects an existing `initialPreviewUrl`\n * when no file is staged. Use for profile photos / org logos where the\n * preview is small and the only meaningful interaction is replace + clear.\n *\n * Pair with a separate \"remove from server\" handler if your data model\n * needs to delete a previously persisted image (this component only manages\n * the local staged file).\n *\n * Strings overridable for i18n.\n */\nimport { useCallback, useEffect, useId, useMemo, useRef, useState} from 'react';\nimport type { ChangeEvent, ForwardedRef} from 'react';\nimport { Camera, X } from 'lucide-react';\nimport { Text } from '../../typography';\nimport { useFiles, type FileRejection } from '../../../hooks/use-files';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { useDensityConfig, type ComponentScale } from '../../../lib/ui-provider';\nimport { resolveComponentScale } from '../../../lib/ui-provider/scale';\nimport { cn } from '../../../lib/utils';\nimport { fieldAffordanceRecipes } from '../../../lib/field-affordance-recipes';\nimport { useFileDropTarget } from './use-file-drop-target';\n\nexport type AvatarUploadSize = ComponentScale;\n\nexport interface AvatarUploadStrings {\n\tchange: string;\n\tremove: string;\n\thint: string;\n\tdragOver: string;\n\tinvalidType: (fileName: string, extension: string) => string;\n\ttooSmall: (fileName: string, minimum: string) => string;\n\ttooLarge: (fileName: string, maximum: string) => string;\n\ttooMany: (fileName: string, maximum: number) => string;\n\tduplicate: (fileName: string) => string;\n\tcustomValidationFailed: (fileName: string) => string;\n}\n\nexport const defaultAvatarUploadStrings: AvatarUploadStrings = {\n\tchange: 'Change photo',\n\tremove: 'Remove photo',\n\thint: 'Click or drop an image',\n\tdragOver: 'Drop image to upload',\n\tinvalidType: (fileName, extension) => `${fileName} uses an unsupported .${extension || 'unknown'} file type.`,\n\ttooSmall: (fileName, minimum) => `${fileName} is smaller than ${minimum}.`,\n\ttooLarge: (fileName, maximum) => `${fileName} is larger than ${maximum}.`,\n\ttooMany: (fileName, maximum) => `${fileName} exceeds the limit of ${maximum} images.`,\n\tduplicate: (fileName) => `${fileName} is already selected.`,\n\tcustomValidationFailed: (fileName) => `${fileName} did not pass validation.`,\n};\n\nfunction getAvatarUploadRejectionMessage(\n\trejection: FileRejection,\n\tstrings: AvatarUploadStrings,\n\tformatSize: (bytes: number) => string,\n) {\n\tconst { file, code, details } = rejection;\n\tswitch (code) {\n\t\tcase 'invalid-type':\n\t\t\treturn strings.invalidType(file.name, details.extension ?? '');\n\t\tcase 'too-small':\n\t\t\treturn strings.tooSmall(file.name, formatSize(details.minimumBytes ?? 0));\n\t\tcase 'too-large':\n\t\t\treturn strings.tooLarge(file.name, formatSize(details.maximumBytes ?? 0));\n\t\tcase 'too-many':\n\t\t\treturn strings.tooMany(file.name, details.maximumFiles ?? 1);\n\t\tcase 'duplicate':\n\t\t\treturn strings.duplicate(file.name);\n\t\tcase 'custom':\n\t\t\treturn details.customMessage ?? strings.customValidationFailed(file.name);\n\t}\n}\n\nexport interface AvatarUploadProps {\n\t/** Selected file. Controlled. */\n\tvalue?: File;\n\tonValueChange?: (file?: File) => void;\n\t/** Image shown before anything is chosen — an existing avatar. */\n\tinitialPreviewUrl?: string;\n\t/** Accepted MIME types or extensions. */\n\taccept?: string;\n\t/** Disables the control and blocks drops. */\n\tdisabled?: boolean;\n\t/** Applies the invalid styling. */\n\tinvalid?: boolean;\n\t/** Diameter preset for the avatar. */\n\tsize?: AvatarUploadSize;\n\tclassName?: string;\n\t/** Overrides the upload and remove copy. */\n\tstrings?: StringsProp<AvatarUploadStrings>;\n\t/** Initials shown when no preview is available. */\n\tinitials?: string;\n}\n\nconst SIZE_PX: Record<AvatarUploadSize, { box: string; icon: string; remove: string }> = {\n\tsm: { box: 'size-upload-avatar-small', icon: 'size-icon', remove: 'size-control-clear' },\n\tmd: { box: 'size-upload-avatar', icon: 'size-icon-lg', remove: 'size-action' },\n\tlg: { box: 'size-upload-avatar-large', icon: 'size-icon-lg', remove: 'size-action-lg' },\n};\n\nfunction AvatarUploadImpl(\n\t{\n\tvalue,\n\tonValueChange,\n\tinitialPreviewUrl,\n\taccept = '.png,.jpg,.jpeg,.gif,.webp',\n\tdisabled = false,\n\tinvalid = false,\n\tsize: sizeProp,\n\tclassName,\n\tstrings: stringsProp,\n\tinitials,\n}: AvatarUploadProps,\n\tforwardedRef: ForwardedRef<HTMLInputElement>,\n) {\n\tconst { defaultScale } = useDensityConfig();\n\tconst size = resolveComponentScale(sizeProp, defaultScale);\n\tconst strings = useStrings(defaultAvatarUploadStrings, stringsProp);\n\tconst inputId = useId();\n\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\tconst sizes = SIZE_PX[size];\n\n\tconst { files, setFiles, removeAll, formatSize, rejections } = useFiles({\n\t\tmaxFiles: 1,\n\t\tallowedExtensions: useMemo(\n\t\t\t() =>\n\t\t\t\taccept\n\t\t\t\t\t.split(',')\n\t\t\t\t\t.map((s) => s.trim().replace(/^\\./, '').toLowerCase())\n\t\t\t\t\t.filter(Boolean),\n\t\t\t[accept],\n\t\t),\n\t});\n\n\tuseEffect(() => {\n\t\tif (value) setFiles([value]);\n\t\telse removeAll();\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [value]);\n\n\tconst selected = files[0];\n\tconst [filePreviewUrl, setFilePreviewUrl] = useState<string | undefined>(undefined);\n\n\tuseEffect(() => {\n\t\tconst file = selected?.file ?? value;\n\t\tif (!file) {\n\t\t\tsetFilePreviewUrl(undefined);\n\t\t\treturn;\n\t\t}\n\t\tconst url = URL.createObjectURL(file);\n\t\tsetFilePreviewUrl(url);\n\t\treturn () => URL.revokeObjectURL(url);\n\t}, [selected, value]);\n\n\tconst previewUrl = filePreviewUrl ?? initialPreviewUrl;\n\tconst hasPreview = Boolean(previewUrl);\n\n\tconst handleInput = useCallback(\n\t\t(e: ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst list = e.target.files;\n\t\t\tif (!list || list.length === 0) return;\n\t\t\tconst result = setFiles(list);\n\t\t\tconst acceptedFile = result.accepted[0]?.file;\n\t\t\tif (acceptedFile) onValueChange?.(acceptedFile);\n\t\t\tif (inputRef.current) inputRef.current.value = '';\n\t\t},\n\t\t[onValueChange, setFiles],\n\t);\n\n\tconst handleRemove = useCallback(() => {\n\t\tremoveAll();\n\t\tonValueChange?.(undefined);\n\t\tif (inputRef.current) inputRef.current.value = '';\n\t}, [onValueChange, removeAll]);\n\n\tconst handleFiles = useCallback((incoming: File[]) => {\n\t\tconst result = setFiles(incoming);\n\t\tconst acceptedFile = result.accepted[0]?.file;\n\t\tif (acceptedFile) onValueChange?.(acceptedFile);\n\t}, [onValueChange, setFiles]);\n\tconst { isDragging, dropTargetProps } = useFileDropTarget({ disabled, onFiles: handleFiles });\n\n\treturn (\n\t\t<div className={cn('avatar-upload--component', 'inline-flex flex-col items-center gap-space-md', className)}>\n\t\t\t<div\n\t\t\t\t{...dropTargetProps}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'group relative flex shrink-0 items-center justify-center rounded-full',\n\t\t\t\t\t'border border-dashed transition-colors duration-150 outline-none',\n\t\t\t\t\t'focus-within:ring-2 focus-within:ring-ring',\n\t\t\t\t\thasPreview\n\t\t\t\t\t\t? 'border-border/60 bg-muted/20'\n\t\t\t\t\t\t: cn(\n\t\t\t\t\t\t\t\t'bg-muted/30 hover:border-primary hover:bg-primary/5',\n\t\t\t\t\t\t\t\tinvalid ? 'border-destructive' : 'border-muted-foreground/40',\n\t\t\t\t\t\t\t),\n\t\t\t\t\tdisabled && 'cursor-not-allowed opacity-50',\n\t\t\t\t\t!disabled && isDragging && 'border-primary bg-primary/10',\n\t\t\t\t\tsizes.box,\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<input\n\t\t\t\t\tid={inputId}\n\t\t\t\t\tref={(node) => { inputRef.current = node; if (typeof forwardedRef === \"function\") forwardedRef(node); else if (forwardedRef) forwardedRef.current = node; }}\n\t\t\t\t\ttype=\"file\"\n\t\t\t\t\tclassName=\"absolute inset-0 z-10 size-full cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n\t\t\t\t\taria-label={strings.change}\n\t\t\t\t\taria-invalid={invalid || undefined}\n\t\t\t\t\taccept={accept}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonChange={handleInput}\n\t\t\t\t/>\n\n\t\t\t\t{/* Only the visual preview is circularly clipped; removal and focus\n\t\t\t\t remain outside that clip as space and density scale independently. */}\n\t\t\t\t<div className=\"pointer-events-none absolute inset-0 flex items-center justify-center overflow-hidden rounded-full\">\n\t\t\t\t\t{hasPreview && previewUrl ? (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tsrc={previewUrl}\n\t\t\t\t\t\t\talt={strings.change}\n\t\t\t\t\t\t\tclassName=\"absolute inset-0 size-full object-cover\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : initials ? (\n\t\t\t\t\t\t<Text size={size === 'sm' ? 'sm' : size === 'lg' ? 'lg' : 'base'} weight=\"bold\" className=\"leading-none\">\n\t\t\t\t\t\t\t{initials}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Camera className={cn(sizes.icon, 'text-muted-foreground')} aria-hidden=\"true\" />\n\t\t\t\t\t)}\n\n\t\t\t\t\t{/* Hover overlay */}\n\t\t\t\t\t{!disabled && hasPreview && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"absolute inset-0 hidden items-center justify-center bg-foreground/50 text-background backdrop-blur-[1px] group-hover:flex\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Camera className={sizes.icon} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t{/* Remove pill */}\n\t\t\t\t{!disabled && hasPreview && (\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\taria-label={strings.remove}\n\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\thandleRemove();\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\tfieldAffordanceRecipes.target,\n\t\t\t\t\t\t\tfieldAffordanceRecipes.focus,\n\t\t\t\t\t\t\t'absolute right-0.5 top-0.5 z-20 bg-card text-foreground shadow ring-1 ring-border',\n\t\t\t\t\t\t\t'opacity-100 transition-opacity sm:opacity-0 sm:group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100',\n\t\t\t\t\t\t\tsizes.remove,\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<X className={fieldAffordanceRecipes.icon} />\n\t\t\t\t\t</button>\n\t\t\t\t)}\n\n\t\t\t\t{!disabled && !hasPreview && isDragging && (\n\t\t\t\t\t<Text size=\"xs\" weight=\"medium\" className=\"absolute inset-x-0 bottom-1.5 text-center text-primary-accent\">\n\t\t\t\t\t\t{strings.dragOver}\n\t\t\t\t\t</Text>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{!hasPreview && (\n\t\t\t\t<Text size=\"xs\" type=\"secondary\">\n\t\t\t\t\t{strings.hint}\n\t\t\t\t</Text>\n\t\t\t)}\n\t\t\t{rejections.length > 0 && (\n\t\t\t\t<div className=\"avatar-upload--errors grid gap-space-2xs\" role=\"alert\" aria-live=\"polite\">\n\t\t\t\t\t{rejections.map((rejection, index) => (\n\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\tkey={`${rejection.file.name}-${rejection.code}-${index}`}\n\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\ttype=\"error\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{getAvatarUploadRejectionMessage(rejection, strings, formatSize)}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nconst AvatarUpload = React.forwardRef<HTMLInputElement, AvatarUploadProps>(AvatarUploadImpl);\nAvatarUpload.displayName = 'AvatarUpload';\n\nexport { AvatarUpload };\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upload-queue-CNd_hH_a.js","names":["_Fragment","resolveComponentScale","useDensityConfig","cn","Text","Button","Stack","SecondaryValue","FileSize","Badge","useFileDropTarget","AttachmentFileIcon","AttachmentTitle","AttachmentDescription","AttachmentActions","AttachmentMedia","AttachmentContent","AttachmentProgress","Attachment","Fragment$1","FilePickerInput","forwardRef","props","handleClick","event","onClick","handleChange","files","onFiles","className","defaultDropzoneStrings","SIZE_CHROME","assignInputRef","forwardedRef","node","DropzoneImpl","sizeProp","stringsProp","strings","useStrings","generatedId","useId","inputId","inputProps","onDrop","chrome","defaultScale","dropTargetProps","disabled","invalid","isDragging","icon","UploadCloud","children","Dropzone","defaultUploadProgressListStrings","STATUS_TONE","Clock","Check","AlertCircle","X","UploadProgressList","statusLabel","items","tone","item","Icon","pct","showProgress","onPreview","Eye","onDownload","Download","onCancel","onRetry","RefreshCw","onRemove","defaultUploadTrayStrings","countStatus","completed","failed","uploading","queued","UploadTray","handleDrop","useCallback","onAddFiles","hasItems","dropzone","onClearAll","listStrings"],"sources":["../src/components/base/upload/file-picker-input.tsx","../src/components/base/upload/dropzone.tsx","../src/components/base/upload-queue/upload-progress-list.tsx","../src/components/base/upload-queue/upload-tray.tsx"],"sourcesContent":["import {\n\tforwardRef,\n\ttype ChangeEvent,\n\ttype InputHTMLAttributes,\n\ttype MouseEvent,\n} from 'react';\n\nimport { cn } from '../../../lib/utils';\n\ntype DataAttributes = {\n\t[key: `data-${string}`]: string | number | boolean | undefined;\n};\n\nexport type FilePickerNativeInputProps = Omit<\n\tInputHTMLAttributes<HTMLInputElement>,\n\t'type' | 'value' | 'defaultValue' | 'onChange' | 'children'\n> & DataAttributes;\n\nexport type FilePickerInputProps = FilePickerNativeInputProps & {\n\t/** Return `false` when the native FileList must be cleared (for example, after rejection). */\n\tonFiles: (files: File[]) => boolean | void;\n};\n\n/** Shared native-input plumbing for FileUpload and Dropzone. Not a public export. */\nexport const FilePickerInput = forwardRef<HTMLInputElement, FilePickerInputProps>(\n\tfunction FilePickerInput(\n\t\t{ className, onFiles, onClick, ...props },\n\t\tref,\n\t) {\n\t\tconst handleClick = (event: MouseEvent<HTMLInputElement>) => {\n\t\t\tevent.stopPropagation();\n\t\t\tonClick?.(event);\n\t\t\tif (!event.defaultPrevented) {\n\t\t\t\t// Clearing before the picker opens makes choosing the same file again\n\t\t\t\t// observable without retaining an opaque native FileList as state.\n\t\t\t\tevent.currentTarget.value = '';\n\t\t\t}\n\t\t};\n\n\t\tconst handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst files = event.currentTarget.files;\n\t\t\tif (files?.length && onFiles(Array.from(files)) === false) {\n\t\t\t\tevent.currentTarget.value = '';\n\t\t\t}\n\t\t};\n\n\t\treturn (\n\t\t\t<input\n\t\t\t\t{...props}\n\t\t\t\tref={ref}\n\t\t\t\ttype=\"file\"\n\t\t\t\tdata-slot=\"file-picker-input\"\n\t\t\t\tclassName={cn('file-picker-input--component sr-only', className)}\n\t\t\t\tonClick={handleClick}\n\t\t\t\tonChange={handleChange}\n\t\t\t/>\n\t\t);\n\t},\n);\n\nFilePickerInput.displayName = 'FilePickerInput';\n","/**\n * Dropzone — accessible drag-and-drop chrome with a native file-input fallback.\n * It owns no validation or file state; consumers receive local `File` values.\n */\nimport { forwardRef, useId, type ForwardedRef, type ReactNode } from 'react';\nimport { UploadCloud } from 'lucide-react';\n\nimport { Text } from '../../typography';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { useDensityConfig, type ComponentScale } from '../../../lib/ui-provider';\nimport { resolveComponentScale } from '../../../lib/ui-provider/scale';\nimport { cn } from '../../../lib/utils';\n\nimport {\n\tFilePickerInput,\n\ttype FilePickerNativeInputProps,\n} from './file-picker-input';\nimport { useFileDropTarget } from './use-file-drop-target';\n\nexport type DropzoneSize = ComponentScale;\n\nexport interface DropzoneStrings {\n\tinstruction: string;\n\thelper: string;\n\tdragOver: string;\n}\n\nexport const defaultDropzoneStrings: DropzoneStrings = {\n\tinstruction: 'Drag files here or click to browse',\n\thelper: '',\n\tdragOver: 'Release to select',\n};\n\nexport type DropzoneInputProps = Omit<\n\tFilePickerNativeInputProps,\n\t'accept' | 'disabled' | 'multiple'\n>;\n\nexport interface DropzoneProps {\n\tonDrop: (files: File[]) => void;\n\t/** Accepted MIME types or extensions. */\n\taccept?: string;\n\t/** Allows more than one file to be dropped. */\n\tmultiple?: boolean;\n\t/** Disables the control and blocks drops. */\n\tdisabled?: boolean;\n\t/** Applies the invalid styling. */\n\tinvalid?: boolean;\n\t/** Height preset for the drop target. */\n\tsize?: DropzoneSize;\n\t/** Glyph shown inside the drop target. */\n\ticon?: ReactNode;\n\tclassName?: string;\n\t/** Native form, ARIA, data, and event attributes forwarded to the file input. */\n\tinputProps?: DropzoneInputProps;\n\t/** Optional action rendered outside the input label, so nested controls remain valid. */\n\tchildren?: ReactNode;\n\t/** Overrides the prompt and constraint copy. */\n\tstrings?: StringsProp<DropzoneStrings>;\n}\n\nconst SIZE_CHROME: Record<\n\tDropzoneSize,\n\t{ padding: string; minHeight: string; iconBox: string; iconSize: string }\n> = {\n\tsm: {\n\t\tpadding: 'p-surface-xs',\n\t\tminHeight: 'min-h-24',\n\t\ticonBox: 'size-avatar-lg',\n\t\ticonSize: 'size-icon',\n\t},\n\tmd: {\n\t\tpadding: 'p-surface',\n\t\tminHeight: 'min-h-32',\n\t\ticonBox: 'size-avatar-lg',\n\t\ticonSize: 'size-icon-lg',\n\t},\n\tlg: {\n\t\tpadding: 'p-surface-lg',\n\t\tminHeight: 'min-h-40',\n\t\ticonBox: 'size-upload-avatar-small',\n\t\ticonSize: 'size-icon-lg',\n\t},\n};\n\nfunction assignInputRef(\n\tnode: HTMLInputElement | null,\n\tforwardedRef: ForwardedRef<HTMLInputElement>,\n) {\n\tif (typeof forwardedRef === 'function') forwardedRef(node);\n\telse if (forwardedRef) forwardedRef.current = node;\n}\n\nfunction DropzoneImpl(\n\t{\n\t\tonDrop,\n\t\taccept,\n\t\tmultiple = false,\n\t\tdisabled = false,\n\t\tinvalid = false,\n\t\tsize: sizeProp,\n\t\ticon,\n\t\tclassName,\n\t\tinputProps,\n\t\tchildren,\n\t\tstrings: stringsProp,\n\t}: DropzoneProps,\n\tforwardedRef: ForwardedRef<HTMLInputElement>,\n) {\n\tconst { defaultScale } = useDensityConfig();\n\tconst strings = useStrings(defaultDropzoneStrings, stringsProp);\n\tconst generatedId = useId();\n\tconst inputId = inputProps?.id ?? `dropzone-${generatedId}`;\n\tconst { isDragging, dropTargetProps } = useFileDropTarget({\n\t\tdisabled,\n\t\tonFiles: onDrop,\n\t});\n\tconst resolvedSize = resolveComponentScale(sizeProp, defaultScale);\n\tconst chrome = SIZE_CHROME[resolvedSize];\n\n\treturn (\n\t\t<div\n\t\t\t{...dropTargetProps}\n\t\t\tdata-disabled={disabled || undefined}\n\t\t\tdata-invalid={invalid || undefined}\n\t\t\tdata-dragging={isDragging || undefined}\n\t\t\tclassName={cn(\n\t\t\t\t'dropzone--component relative flex flex-col items-center justify-center gap-space-md rounded-radius border border-dashed text-center transition-colors duration-150',\n\t\t\t\t'has-[[data-slot=file-picker-input]:focus-visible]:ring-2 has-[[data-slot=file-picker-input]:focus-visible]:ring-ring has-[[data-slot=file-picker-input]:focus-visible]:ring-offset-2',\n\t\t\t\tchrome.minHeight,\n\t\t\t\tchrome.padding,\n\t\t\t\tinvalid ? 'border-destructive' : 'border-muted-foreground/40',\n\t\t\t\tinvalid\n\t\t\t\t\t? !disabled && 'hover:bg-destructive/5'\n\t\t\t\t\t: !disabled && 'hover:border-primary hover:bg-primary/5',\n\t\t\t\tdisabled && 'cursor-not-allowed opacity-50',\n\t\t\t\t!disabled && isDragging && (\n\t\t\t\t\tinvalid\n\t\t\t\t\t\t? 'border-destructive bg-destructive/5'\n\t\t\t\t\t\t: 'border-primary bg-primary/10'\n\t\t\t\t),\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<FilePickerInput\n\t\t\t\t{...inputProps}\n\t\t\t\tref={(node) => assignInputRef(node, forwardedRef)}\n\t\t\t\tid={inputId}\n\t\t\t\taccept={accept}\n\t\t\t\tmultiple={multiple}\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-invalid={invalid || undefined}\n\t\t\t\tclassName={cn('dropzone--input', inputProps?.className)}\n\t\t\t\tonFiles={onDrop}\n\t\t\t/>\n\n\t\t\t<label\n\t\t\t\thtmlFor={disabled ? undefined : inputId}\n\t\t\t\taria-disabled={disabled || undefined}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'dropzone--trigger flex w-full flex-1 cursor-pointer flex-col items-center justify-center gap-space-md',\n\t\t\t\t\tdisabled && 'cursor-not-allowed',\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'dropzone--icon inline-flex items-center justify-center rounded-full bg-primary/10 text-primary-accent',\n\t\t\t\t\t\tchrome.iconBox,\n\t\t\t\t\t)}\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t>\n\t\t\t\t\t{icon ?? <UploadCloud className={chrome.iconSize} />}\n\t\t\t\t</span>\n\n\t\t\t\t<span className=\"dropzone--copy grid gap-normal text-center [&_p]:text-center\">\n\t\t\t\t\t<Text\n\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\t\t\tweight=\"medium\"\n\t\t\t\t\t\tclassName=\"dropzone--instruction\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{isDragging ? strings.dragOver : strings.instruction}\n\t\t\t\t\t</Text>\n\t\t\t\t\t{!!strings.helper && (\n\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t\tclassName=\"dropzone--helper\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{strings.helper}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t)}\n\t\t\t\t</span>\n\t\t\t</label>\n\n\t\t\t{!!children && <div className=\"dropzone--action\">{children}</div>}\n\t\t</div>\n\t);\n}\n\nconst Dropzone = forwardRef<HTMLInputElement, DropzoneProps>(DropzoneImpl);\nDropzone.displayName = 'Dropzone';\n\nexport { Dropzone };\n","/**\n * UploadProgressList — render-only list of in-flight uploads. Each row shows\n * a status icon (queued / uploading / done / error / cancelled), filename,\n * size, a progress bar driven by `progress` (0–100), and an action button\n * that maps to the row's status (cancel while uploading, retry on error,\n * remove when done). Pair with FileUpload / MediaGallery / Dropzone — those\n * components emit raw `File` instances; this one displays the upload UI\n * once the consumer has wired them to its API.\n *\n * Strings overridable for i18n.\n */\nimport { AlertCircle, Check, Clock, RefreshCw, UploadCloud, X, Eye, Download } from 'lucide-react';\nimport { Button } from '../buttons';\nimport { Stack } from '../structure';\nimport { SecondaryValue } from '../../primitives';\nimport { Attachment, AttachmentMedia, AttachmentContent, AttachmentTitle, AttachmentDescription, AttachmentActions, AttachmentProgress, AttachmentFileIcon, type AttachmentKind } from '../attachment';\nimport { FileSize } from '../../primitives';\nimport { Text } from '../../typography';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nexport type UploadStatus = 'queued' | 'uploading' | 'done' | 'error' | 'cancelled';\n\nexport interface UploadItem {\n\t/** Stable identity for this entry. */\n\tid: string;\n\t/** Displayed file name. */\n\tname: string;\n\t/** Pre-formatted size string (e.g. \"2.4 MB\"). */\n\tsize?: string;\n\t/** Numeric file size used when the formatted size is absent. */\n\tbytes?: number;\n\tkind?: AttachmentKind;\n\t/** Upload progress 0–100. Omit for an indeterminate transfer. Ignored when status is `done`/`error`/`cancelled`. */\n\tprogress?: number;\n\tstatus: UploadStatus;\n\t/** Error message rendered under the row when status is `error`. */\n\terror?: string;\n\t/**\n\t * Optional thumbnail URL, shown in place of the status icon.\n\t * The status remains visible beside the file name.\n\t */\n\tpreview?: string;\n}\n\nexport interface UploadProgressListStrings {\n\tqueued: string;\n\tuploading: string;\n\tdone: string;\n\terror: string;\n\tcancelled: string;\n\tcancel: string;\n\tretry: string;\n\tremove: string;\n\tpreview?: string;\n\tdownload?: string;\n}\n\nexport const defaultUploadProgressListStrings: UploadProgressListStrings = {\n\tqueued: 'Queued',\n\tuploading: 'Uploading',\n\tdone: 'Uploaded',\n\terror: 'Failed',\n\tcancelled: 'Cancelled',\n\tcancel: 'Cancel',\n\tretry: 'Retry',\n\tremove: 'Remove',\n\tpreview: 'Preview',\n\tdownload: 'Download',\n};\n\nexport interface UploadProgressListProps {\n\t/** Entries to render, in order. */\n\titems: UploadItem[];\n\t/** File preview action; consumers own the effect. */\n\tonPreview?: (id: string) => void;\n\t/** Download action for completed files. Receives the stable item identity. */\n\tonDownload?: (id: string) => void;\n\tonCancel?: (id: string) => void;\n\tonRetry?: (id: string) => void;\n\tonRemove?: (id: string) => void;\n\tclassName?: string;\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<UploadProgressListStrings>;\n}\n\nconst STATUS_TONE: Record<UploadStatus, { icon: typeof Check; fg: string }> = {\n\tqueued: { icon: Clock, fg: 'text-muted-foreground' },\n\tuploading: { icon: UploadCloud, fg: 'text-primary-accent' },\n\tdone: { icon: Check, fg: 'text-success' },\n\terror: { icon: AlertCircle, fg: 'text-destructive' },\n\tcancelled: { icon: X, fg: 'text-muted-foreground' },\n};\n\nexport function UploadProgressList({\n\titems,\n\tonPreview,\n\tonDownload,\n\tonCancel,\n\tonRetry,\n\tonRemove,\n\tclassName,\n\tstrings: stringsProp,\n}: UploadProgressListProps) {\n\tconst strings = useStrings(defaultUploadProgressListStrings, stringsProp);\n\tconst statusLabel: Record<UploadStatus, string> = {\n\t\tqueued: strings.queued,\n\t\tuploading: strings.uploading,\n\t\tdone: strings.done,\n\t\terror: strings.error,\n\t\tcancelled: strings.cancelled,\n\t};\n\n\tif (items.length === 0) return null;\n\n\treturn (\n\t\t<Stack render={<ul />} gap=\"sm\" className={cn('upload-progress-list--component m-0 p-0 list-none', className)}>\n\t\t\t{items.map((item) => {\n\t\t\t\tconst tone = STATUS_TONE[item.status];\n\t\t\t\tconst Icon = tone.icon;\n\t\t\t\tconst pct = item.progress === undefined ? null : Number.isFinite(item.progress) ? Math.max(0, Math.min(100, item.progress ?? 0)) : 0;\n\t\t\t\tconst showProgress = item.status === 'uploading' || item.status === 'queued';\n\t\t\t\treturn (\n\t\t\t\t\t<Attachment key={item.id} render={<li />} variant=\"outline\" className=\"upload-progress-list--item flex-nowrap bg-card text-card-foreground\">\n\t\t\t\t\t\t<AttachmentMedia variant={item.preview ? 'image' : 'icon'} className={cn('upload-progress-list--media self-center group-has-data-[slot=item-description]/item:self-center', tone.fg)}>\n\t\t\t\t\t\t\t{item.preview ? <img src={item.preview} alt=\"\" /> : item.status === 'done' ? <AttachmentFileIcon name={item.name} kind={item.kind} /> : <Icon aria-hidden=\"true\" className={cn('size-icon', item.status === 'uploading' && 'animate-pulse motion-reduce:animate-none')} />}\n\t\t\t\t\t\t</AttachmentMedia>\n\t\t\t\t\t\t<AttachmentContent className=\"min-w-0 gap-space-xs\">\n\t\t\t\t\t\t\t<Stack direction=\"horizontal\" align=\"baseline\" justify=\"between\" gap=\"md\" wrap>\n\t\t\t\t\t\t\t\t<AttachmentTitle className=\"min-w-0 max-w-full\" title={item.name}><Text tag=\"span\" weight=\"medium\" className=\"truncate\">{item.name}</Text></AttachmentTitle>\n\t\t\t\t\t\t\t\t<SecondaryValue size=\"xs\" className=\"shrink-0 tabular-nums\">{item.size ?? (item.bytes !== undefined ? <FileSize value={item.bytes} size=\"xs\" type=\"secondary\" /> : null)}</SecondaryValue>\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t\t<AttachmentDescription clamp=\"none\"><Text tag=\"span\" size=\"xs\" lineHeight=\"tight\" type={item.status === 'error' ? 'error' : 'secondary'} role={item.status === 'error' ? 'alert' : undefined}>{`${statusLabel[item.status]}${item.status === 'error' && item.error ? ` — ${item.error}` : ''}`}</Text></AttachmentDescription>\n\t\t\t\t\t\t\t{showProgress && <AttachmentProgress value={item.status === 'queued' && pct === null ? 0 : pct} aria-label={item.name} size=\"sm\" tone={item.status === 'queued' ? 'neutral' : 'primary'} className=\"upload-progress-list--progress\" />}\n\t\t\t\t\t\t</AttachmentContent>\n\t\t\t\t\t\t<AttachmentActions className=\"shrink-0\">\n {!!onPreview && <Button type=\"button\" tone=\"secondary\" buttonStyle=\"ghost\" size=\"sm\" iconOnly aria-label={`${strings.preview ?? 'Preview'} ${item.name}`} onClick={() => onPreview(item.id)}><Eye aria-hidden=\"true\" className=\"size-icon-md\" /></Button>}\n {!!onDownload && item.status === 'done' && <Button type=\"button\" tone=\"secondary\" buttonStyle=\"ghost\" size=\"sm\" iconOnly aria-label={`${strings.download ?? 'Download'} ${item.name}`} onClick={() => onDownload(item.id)}><Download aria-hidden=\"true\" className=\"size-icon-md\" /></Button>}\n\n\t\t\t\t\t\t\t\t{(item.status === 'uploading' || item.status === 'queued') && !!onCancel && (\n\t\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=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\ticonOnly\n\t\t\t\t\t\t\t\t\t\taria-label={`${strings.cancel} ${item.name}`}\n\t\t\t\t\t\t\t\t\t\tonClick={() => onCancel(item.id)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<X className=\"size-icon-md\" />\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{item.status === 'error' && !!onRetry && (\n\t\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=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\ticonOnly\n\t\t\t\t\t\t\t\t\t\taria-label={`${strings.retry} ${item.name}`}\n\t\t\t\t\t\t\t\t\t\tonClick={() => onRetry(item.id)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<RefreshCw className=\"size-icon-md\" />\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{(item.status === 'done' || item.status === 'error' || item.status === 'cancelled' || (item.status === 'queued' && !onCancel)) && !!onRemove && (\n\t\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=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\ticonOnly\n\t\t\t\t\t\t\t\t\t\taria-label={`${strings.remove} ${item.name}`}\n\t\t\t\t\t\t\t\t\t\tonClick={() => onRemove(item.id)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<X className=\"size-icon-md\" />\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</AttachmentActions>\n\t\t\t\t\t</Attachment>\n\t\t\t\t);\n\t\t\t})}\n\t\t</Stack>\n\t);\n}\n\nUploadProgressList.displayName = 'UploadProgressList';\n","/**\n * UploadTray — the canonical \"drag-and-drop area + per-file progress\n * rows + summary toolbar\" surface. Composes:\n *\n * - `Dropzone` — drag/drop chrome + click-to-browse\n * - `UploadProgressList` — per-file row with status icon + progress\n * bar + cancel/retry/remove actions\n * - `Badge` — status counters in the toolbar\n * - `Button` — \"Clear all\" action\n *\n * Framework-agnostic. Every action is callback-driven — the library\n * doesn't perform the upload; it surfaces the UX. The consumer wires\n * the actual transfer (XHR, fetch, S3 multipart, …) and feeds back\n * `progress` / `status` updates by mutating the `items` array.\n *\n * Pair with `useFiles` (the existing client-side validation hook) at\n * the call site if you want pre-flight size/type rejection.\n */\nimport { forwardRef, useCallback } from 'react';\n\nimport { Badge } from '../badge';\nimport { Button } from '../buttons';\nimport { Stack } from '../structure';\nimport { Text } from '../../typography';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\n\nimport { Dropzone, type DropzoneProps } from '../upload/dropzone';\nimport { UploadProgressList, type UploadItem, type UploadProgressListStrings } from './upload-progress-list';\n\nexport interface UploadTrayStrings {\n\theading: string;\n\tcompletedLabel: string;\n\tfailedLabel: string;\n\tuploadingLabel: string;\n\tqueuedLabel: string;\n\tclearAll: string;\n}\n\nexport const defaultUploadTrayStrings: UploadTrayStrings = {\n\theading: 'Upload progress',\n\tcompletedLabel: 'Completed',\n\tfailedLabel: 'Failed',\n\tuploadingLabel: 'Uploading',\n\tqueuedLabel: 'Queued',\n\tclearAll: 'Clear all',\n};\n\nexport interface UploadTrayProps {\n\t/** Files currently in the tray (queued / uploading / done / error / cancelled). */\n\titems: UploadItem[];\n\t/**\n\t * Fires when the user drops or browses files. The library does NOT\n\t * write to the items array — the consumer turns these into queued\n\t * `UploadItem`s, kicks off the actual transfer, and updates progress.\n\t */\n\tonAddFiles: (files: File[]) => void;\n\t/** Preview callback forwarded with the item identity. */\n\tonPreview?: (id: string) => void;\n\t/** Download callback for completed files, forwarded with the item identity. */\n\tonDownload?: (id: string) => void;\n\t/** Per-row cancel handler (passed through to UploadProgressList). */\n\tonCancel?: (id: string) => void;\n\t/** Per-row retry handler. */\n\tonRetry?: (id: string) => void;\n\t/** Per-row remove handler. */\n\tonRemove?: (id: string) => void;\n\t/**\n\t * Clears the entire tray. When omitted, the \"Clear all\" button is\n\t * hidden — useful for surfaces where in-flight uploads can't be\n\t * cancelled in bulk.\n\t */\n\tonClearAll?: () => void;\n\t/** Forwarded to the inner `<Dropzone>`. Only the meaningful subset. */\n\tdropzone?: Pick<DropzoneProps, 'accept' | 'multiple' | 'size' | 'disabled' | 'invalid' | 'strings'>;\n\tclassName?: string;\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<UploadTrayStrings>;\n\t/** Strings forwarded to the inner `<UploadProgressList>`. */\n\tlistStrings?: StringsProp<UploadProgressListStrings>;\n}\n\nfunction countStatus(items: UploadItem[]) {\n\tlet completed = 0;\n\tlet failed = 0;\n\tlet uploading = 0;\n\tlet queued = 0;\n\tfor (const item of items) {\n\t\tif (item.status === 'done') completed += 1;\n\t\telse if (item.status === 'error') failed += 1;\n\t\telse if (item.status === 'uploading') uploading += 1;\n\t\telse if (item.status === 'queued') queued += 1;\n\t}\n\treturn { completed, failed, uploading, queued };\n}\n\nexport const UploadTray = forwardRef<HTMLDivElement, UploadTrayProps>(function UploadTray(\n\t{\n\t\titems,\n\t\tonAddFiles,\n\t\tonPreview,\n\t\tonDownload,\n\t\tonCancel,\n\t\tonRetry,\n\t\tonRemove,\n\t\tonClearAll,\n\t\tdropzone,\n\t\tclassName,\n\t\tstrings: stringsProp,\n\t\tlistStrings,\n\t},\n\tref,\n) {\n\tconst strings = useStrings(defaultUploadTrayStrings, stringsProp);\n\tconst { completed, failed, uploading, queued } = countStatus(items);\n\n\tconst handleDrop = useCallback(\n\t\t(files: File[]) => {\n\t\t\tif (files.length > 0) onAddFiles(files);\n\t\t},\n\t\t[onAddFiles],\n\t);\n\n\tconst hasItems = items.length > 0;\n\n\treturn (\n\t\t<Stack ref={ref} gap=\"md\" className={cn('upload-tray--component', className)}>\n\t\t\t<Dropzone\n\t\t\t\tonDrop={handleDrop}\n\t\t\t\taccept={dropzone?.accept}\n\t\t\t\tmultiple={dropzone?.multiple}\n\t\t\t\tsize={dropzone?.size}\n\t\t\t\tdisabled={dropzone?.disabled}\n\t\t\t\tinvalid={dropzone?.invalid}\n\t\t\t\tstrings={dropzone?.strings}\n\t\t\t/>\n\n\t\t\t{!!hasItems && (\n\t\t\t\t<>\n\t\t\t\t\t<Stack direction=\"horizontal\" wrap align=\"center\" justify=\"between\" gap=\"md\">\n\t\t\t\t\t\t<Stack direction=\"horizontal\" wrap align=\"center\" gap=\"md\">\n\t\t\t\t\t\t\t<Text tag=\"span\" weight=\"semibold\">\n\t\t\t\t\t\t\t\t{strings.heading}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t{completed > 0 && (\n\t\t\t\t\t\t\t\t<Badge tone=\"success\">\n\t\t\t\t\t\t\t\t\t{strings.completedLabel}: {completed}\n\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{failed > 0 && (\n\t\t\t\t\t\t\t\t<Badge tone=\"destructive\">\n\t\t\t\t\t\t\t\t\t{strings.failedLabel}: {failed}\n\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{uploading > 0 && (\n\t\t\t\t\t\t\t\t<Badge tone=\"info\">\n\t\t\t\t\t\t\t\t\t{strings.uploadingLabel}: {uploading}\n\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{queued > 0 && (\n\t\t\t\t\t\t\t\t<Badge tone=\"secondary\">\n\t\t\t\t\t\t\t\t\t{strings.queuedLabel}: {queued}\n\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t{!!onClearAll && (\n\t\t\t\t\t\t\t<Button type=\"button\" tone=\"secondary\" buttonStyle=\"ghost\" onClick={onClearAll}>\n\t\t\t\t\t\t\t\t{strings.clearAll}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Stack>\n\n\t\t\t\t\t<UploadProgressList\n\t\t\t\t\t\titems={items}\n\t\t\t\t\t\tonPreview={onPreview}\n\t\t\t\t\t\tonDownload={onDownload}\n\t\t\t\t\t\tonCancel={onCancel}\n\t\t\t\t\t\tonRetry={onRetry}\n\t\t\t\t\t\tonRemove={onRemove}\n\t\t\t\t\t\tstrings={listStrings}\n\t\t\t\t\t/>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</Stack>\n\t);\n});\n\nUploadTray.displayName = 'UploadTray';\n"],"mappings":"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"}
|