themelia-react-ui 1.0.0 → 1.0.2
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 +190 -1
- package/README.md +92 -13
- package/dist/{accordion-BRWh3BM1.js → accordion-BRTcsp8J.js} +8 -8
- package/dist/accordion-BRTcsp8J.js.map +1 -0
- package/dist/{action-menu-Cx3SdfbN.js → action-menu-Drxw_vJk.js} +36 -36
- package/dist/action-menu-Drxw_vJk.js.map +1 -0
- package/dist/affordance-geometry.generated-CL84ZN9A.js +63 -0
- package/dist/affordance-geometry.generated-CL84ZN9A.js.map +1 -0
- package/dist/{ai-artifact-DkOArd3-.js → ai-artifact-DLVdK0Py.js} +151 -155
- package/dist/ai-artifact-DLVdK0Py.js.map +1 -0
- package/dist/{app-shell-BH_bGcE2.js → app-shell-C_fKpljx.js} +11 -10
- package/dist/app-shell-C_fKpljx.js.map +1 -0
- package/dist/{attachment-DsLgNHXt.js → attachment-DbjUWsP0.js} +12 -12
- package/dist/{attachment-DsLgNHXt.js.map → attachment-DbjUWsP0.js.map} +1 -1
- package/dist/auth-CAQcasMV.js +723 -0
- package/dist/auth-CAQcasMV.js.map +1 -0
- package/dist/{avatar-CsnWaYmt.js → avatar-Bu2HhitA.js} +76 -71
- package/dist/avatar-Bu2HhitA.js.map +1 -0
- package/dist/{badge-BZXZT9wd.js → badge-CzId1Wlm.js} +4 -4
- package/dist/{badge-BZXZT9wd.js.map → badge-CzId1Wlm.js.map} +1 -1
- package/dist/base/accordion.js +1 -1
- package/dist/base/action-menu.js +1 -1
- package/dist/base/attachment.js +1 -1
- package/dist/base/avatar.js +1 -1
- package/dist/base/badge.js +1 -1
- package/dist/base/buttons.js +3 -2
- package/dist/base/cards.js +3 -3
- package/dist/base/carousel.js +25 -27
- package/dist/base/carousel.js.map +1 -1
- package/dist/base/cascader.js +150 -148
- package/dist/base/cascader.js.map +1 -1
- package/dist/base/chart.js +1 -1
- package/dist/base/choice-inputs.js +3 -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 +3 -3
- package/dist/base/display.js +7 -7
- package/dist/base/feedback.js +4 -3
- package/dist/base/forms-numeric.js +1 -1
- package/dist/base/forms.js +2 -2
- package/dist/base/inline-edit.js +233 -0
- package/dist/base/inline-edit.js.map +1 -0
- 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 +1 -1
- package/dist/base/repeaters.js +33 -33
- 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 +83 -81
- 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 +6 -6
- 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 +134 -134
- package/dist/blocks/admin.js.map +1 -1
- package/dist/blocks/ai.js +120 -117
- package/dist/blocks/ai.js.map +1 -1
- package/dist/blocks/analytics/usage-card.js +3 -0
- package/dist/blocks/analytics.js +530 -491
- package/dist/blocks/analytics.js.map +1 -1
- package/dist/blocks/collaboration.js +2 -2
- package/dist/blocks/commerce/receipt.js +1 -1
- package/dist/blocks/commerce.js +395 -383
- package/dist/blocks/commerce.js.map +1 -1
- package/dist/blocks/data-display.js +1 -1
- package/dist/blocks/onboarding.js +6 -6
- package/dist/blocks/onboarding.js.map +1 -1
- package/dist/blocks/planning.js +311 -0
- package/dist/blocks/planning.js.map +1 -0
- package/dist/blocks/timelines.js +1 -1
- package/dist/{breadcrumbs-DdQ_I5ra.js → breadcrumbs-BuYz5SDU.js} +9 -8
- package/dist/breadcrumbs-BuYz5SDU.js.map +1 -0
- package/dist/button-BZDasD04.js +651 -0
- package/dist/button-BZDasD04.js.map +1 -0
- package/dist/{button-BS6l5JUw.js → button-BZyfTvwm.js} +3 -3
- package/dist/button-BZyfTvwm.js.map +1 -0
- package/dist/buttons-D_6KJvEE.js +99 -0
- package/dist/buttons-D_6KJvEE.js.map +1 -0
- package/dist/{cards-BMB0laLG.js → cards-qGSErLw_.js} +12 -12
- package/dist/{cards-BMB0laLG.js.map → cards-qGSErLw_.js.map} +1 -1
- package/dist/chart-Bsc5BICK.js +150 -0
- package/dist/chart-Bsc5BICK.js.map +1 -0
- package/dist/checkbox-BQNDjUCh.js +34 -0
- package/dist/checkbox-BQNDjUCh.js.map +1 -0
- package/dist/choice-inputs-Mk3iWbhr.js +725 -0
- package/dist/choice-inputs-Mk3iWbhr.js.map +1 -0
- package/dist/{code-block-DIlqzoiD.js → code-block-DzHKRybS.js} +23 -23
- package/dist/code-block-DzHKRybS.js.map +1 -0
- package/dist/{collapsible-DsnktFNv.js → collapsible-ClvC7Bj3.js} +3 -3
- package/dist/{collapsible-DsnktFNv.js.map → collapsible-ClvC7Bj3.js.map} +1 -1
- package/dist/{collection-content-C4fthJV_.js → collection-content-D6S8cv_n.js} +3 -3
- package/dist/{collection-content-C4fthJV_.js.map → collection-content-D6S8cv_n.js.map} +1 -1
- package/dist/{combobox-HDftpzxt.js → combobox-BFnbJJp3.js} +18 -18
- package/dist/combobox-BFnbJJp3.js.map +1 -0
- package/dist/{combobox-CHD750do.js → combobox-hozNwUcc.js} +313 -316
- package/dist/combobox-hozNwUcc.js.map +1 -0
- package/dist/{command-D0kWBZfd.js → command-BnmSchli.js} +9 -9
- package/dist/command-BnmSchli.js.map +1 -0
- package/dist/comments-u5L0OGip.js +1156 -0
- package/dist/comments-u5L0OGip.js.map +1 -0
- package/dist/components/base/buttons/button-group.recipes.d.ts +1 -1
- package/dist/components/base/buttons/button.recipes.d.ts +10 -19
- package/dist/components/base/buttons/use-pending-button-focus.d.ts +3 -0
- package/dist/components/base/cards/card.recipes.d.ts +13 -5
- package/dist/components/base/cards/partials/card-primitives.d.ts +9 -4
- package/dist/components/base/cards/smart-card.types.d.ts +3 -1
- package/dist/components/base/date-pickers/date-picker.recipes.d.ts +5 -18
- package/dist/components/base/date-pickers/datepicker.types.d.ts +3 -0
- package/dist/components/base/forms/form-field.d.ts +1 -0
- package/dist/components/base/forms/form-sizing.d.ts +3 -3
- package/dist/components/base/inline-edit/index.d.ts +2 -0
- package/dist/components/base/inline-edit/inline-edit.d.ts +81 -0
- package/dist/components/base/inline-edit/inline-edit.recipes.d.ts +6 -0
- package/dist/components/base/navigation/tabs.d.ts +3 -5
- package/dist/components/base/popover/popover.recipes.d.ts +3 -3
- package/dist/components/base/structure/structure.recipes.d.ts +6 -0
- package/dist/components/base/table/index.d.ts +1 -1
- package/dist/components/base/text-inputs/clear-native-field.d.ts +2 -0
- package/dist/components/base/text-inputs/input-trailing-action.d.ts +3 -0
- package/dist/components/blocks/analytics/index.d.ts +1 -0
- package/dist/components/blocks/analytics/types.d.ts +1 -1
- package/dist/components/blocks/analytics/usage-card/index.d.ts +3 -0
- package/dist/components/blocks/analytics/usage-card/types.d.ts +52 -0
- package/dist/components/blocks/analytics/usage-card/usage-card.d.ts +6 -0
- package/dist/components/blocks/analytics/usage-card/usage-card.data.d.ts +19 -0
- package/dist/components/blocks/analytics/usage-card/usage-card.strings.d.ts +22 -0
- package/dist/components/blocks/collaboration/message/message.recipes.d.ts +12 -0
- package/dist/components/blocks/data-display/empty-state/partials/illustrations/document-stack.d.ts +1 -4
- package/dist/components/blocks/data-display/empty-state/partials/illustrations/inbox-clean.d.ts +1 -4
- package/dist/components/blocks/data-display/empty-state/partials/illustrations/index.d.ts +3 -3
- package/dist/components/blocks/data-display/empty-state/partials/illustrations/stacked-cards.d.ts +1 -6
- package/dist/components/blocks/planning/index.d.ts +3 -0
- package/dist/components/blocks/planning/task-card.d.ts +3 -0
- package/dist/components/blocks/planning/task-card.strings.d.ts +15 -0
- package/dist/components/blocks/planning/task-card.types.d.ts +66 -0
- package/dist/components/features/combobox/components/error-message.d.ts +1 -1
- package/dist/components/features/comments/hooks/use-attachment-upload.d.ts +5 -0
- package/dist/components/features/filters/facets/search-facet.d.ts +0 -12
- package/dist/components/features/filters/facets/tags-facet.d.ts +1 -1
- package/dist/components/features/media-library/media-library.d.ts +1 -1
- package/dist/components/features/media-library/media-library.types.d.ts +9 -1
- package/dist/components/features/media-library/partials/media-library-partials.d.ts +1 -1
- package/dist/components/features/overlays/hooks/use-pending-overlay-focus.d.ts +2 -0
- package/dist/components/features/overlays/overlays.types.d.ts +5 -4
- package/dist/components/features/rich-text-editor/rich-text-editor.recipes.d.ts +2 -1
- package/dist/components/features/table/data-table.d.ts +1 -1
- package/dist/components/features/table/table.types.d.ts +1 -1
- package/dist/components/features/theme-tweaker/theme-provider-settings.d.ts +3 -1
- package/dist/components/layout/auth/auth.types.d.ts +1 -0
- package/dist/components/layout/page/page.d.ts +0 -1
- package/dist/components/layout/page/page.types.d.ts +9 -3
- package/dist/components/layout/sidebar/sidebar.context.d.ts +1 -1
- package/dist/components/layout/sidebar/sidebar.types.d.ts +4 -0
- package/dist/components/layout/workspace/workspace.types.d.ts +3 -0
- package/dist/components/typography/heading.d.ts +5 -2
- package/dist/components/typography/index.d.ts +1 -1
- package/dist/components/typography/text.styles.d.ts +10 -0
- package/dist/components/ui/popover.d.ts +1 -1
- package/dist/components/ui/sidebar.d.ts +1 -1
- package/dist/components/ui/table.d.ts +2 -1
- package/dist/container.recipes-D9t8MHR3.js +27 -0
- package/dist/container.recipes-D9t8MHR3.js.map +1 -0
- package/dist/{containers-CPNyNo1_.js → containers-DqB-bSYE.js} +34 -56
- package/dist/containers-DqB-bSYE.js.map +1 -0
- package/dist/control-group-recipes-DBXmfh2E.js +21 -0
- package/dist/control-group-recipes-DBXmfh2E.js.map +1 -0
- package/dist/{copyable-B7SBXJMr.js → copyable-BTSByfmq.js} +6 -6
- package/dist/{copyable-B7SBXJMr.js.map → copyable-BTSByfmq.js.map} +1 -1
- package/dist/{data-display-b3d1TfL4.js → data-display-Bihs9Ven.js} +542 -329
- package/dist/data-display-Bihs9Ven.js.map +1 -0
- package/dist/{date-BFNMnrS5.js → date-DOKhJPu7.js} +4 -4
- package/dist/{date-BFNMnrS5.js.map → date-DOKhJPu7.js.map} +1 -1
- package/dist/{date-picker-DI6kPNof.js → date-picker-DzP5HQq7.js} +492 -472
- package/dist/date-picker-DzP5HQq7.js.map +1 -0
- package/dist/date-pickers-BpgGz7S-.js +196 -0
- package/dist/date-pickers-BpgGz7S-.js.map +1 -0
- package/dist/{display-ByI5tkqy.js → display-CS6Hbk18.js} +8 -8
- package/dist/{display-ByI5tkqy.js.map → display-CS6Hbk18.js.map} +1 -1
- package/dist/{dropdown-menu-BlnyHr-9.js → dropdown-menu-D-boNgGO.js} +7 -7
- package/dist/{dropdown-menu-BlnyHr-9.js.map → dropdown-menu-D-boNgGO.js.map} +1 -1
- package/dist/features/activities.js +152 -141
- package/dist/features/activities.js.map +1 -1
- package/dist/features/ai-chat.js +182 -179
- package/dist/features/ai-chat.js.map +1 -1
- package/dist/features/async-preview.js +9 -9
- package/dist/features/async-preview.js.map +1 -1
- package/dist/features/combobox.js +1 -1
- package/dist/features/comments.js +1 -1
- package/dist/features/data-view.js +25 -23
- package/dist/features/data-view.js.map +1 -1
- package/dist/features/email-composer/engine.js +1 -1
- package/dist/features/email-composer.js +103 -104
- package/dist/features/email-composer.js.map +1 -1
- package/dist/features/event-calendar.js +375 -373
- package/dist/features/event-calendar.js.map +1 -1
- package/dist/features/filters.js +1 -1
- package/dist/features/global-search.js +222 -224
- package/dist/features/global-search.js.map +1 -1
- package/dist/features/kanban.js +29 -29
- package/dist/features/kanban.js.map +1 -1
- package/dist/features/map.js +59 -58
- package/dist/features/map.js.map +1 -1
- package/dist/features/media-library.js +856 -855
- 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 +1210 -1209
- package/dist/features/products.js.map +1 -1
- package/dist/features/questionnaire.js +133 -132
- package/dist/features/questionnaire.js.map +1 -1
- package/dist/features/resource-assignment.js +29 -31
- package/dist/features/resource-assignment.js.map +1 -1
- package/dist/features/resource.js +13 -13
- package/dist/features/resource.js.map +1 -1
- package/dist/features/rich-text-editor.js +2 -2
- package/dist/features/schema-form.js +82 -82
- package/dist/features/schema-form.js.map +1 -1
- package/dist/features/suggestions.js +3 -3
- package/dist/features/sync.js +4 -4
- package/dist/features/sync.js.map +1 -1
- package/dist/features/table.js +1 -1
- package/dist/features/theme-tweaker.js +456 -450
- package/dist/features/theme-tweaker.js.map +1 -1
- package/dist/feedback-CJkUAapr.js +233 -0
- package/dist/feedback-CJkUAapr.js.map +1 -0
- package/dist/field-affordance-recipes-uKY4MsZ_.js +25 -0
- package/dist/field-affordance-recipes-uKY4MsZ_.js.map +1 -0
- package/dist/{field-state-recipes-CBTRt9Bt.js → field-state-recipes-DQQpiLWC.js} +3 -3
- package/dist/field-state-recipes-DQQpiLWC.js.map +1 -0
- package/dist/{filters-qtrcv1hf.js → filters-D6FF8L6s.js} +715 -720
- package/dist/filters-D6FF8L6s.js.map +1 -0
- package/dist/{form-field-C6W-y2hR.js → form-field-CZwrkP7m.js} +17 -9
- package/dist/form-field-CZwrkP7m.js.map +1 -0
- package/dist/{form-sizing-39NohSqn.js → form-sizing-QP8aIRaW.js} +10 -6
- package/dist/form-sizing-QP8aIRaW.js.map +1 -0
- package/dist/{forms-BF-HSbff.js → forms-B5NCbkSC.js} +35 -35
- package/dist/{forms-BF-HSbff.js.map → forms-B5NCbkSC.js.map} +1 -1
- package/dist/forms-numeric-Crrm80Lm.js +867 -0
- package/dist/forms-numeric-Crrm80Lm.js.map +1 -0
- package/dist/{header-B8ex54cY.js → header-kxruN3RM.js} +53 -49
- package/dist/header-kxruN3RM.js.map +1 -0
- package/dist/{hooks-D6UBVzf2.js → hooks-BrlnCwQd.js} +2 -2
- package/dist/{hooks-D6UBVzf2.js.map → hooks-BrlnCwQd.js.map} +1 -1
- package/dist/{http-CLTVJc5I.js → http-CdEIHyQf.js} +2 -2
- package/dist/http-CdEIHyQf.js.map +1 -0
- package/dist/{icon-badge-Dv0RYQwj.js → icon-badge-Btc6pQrp.js} +4 -4
- package/dist/{icon-badge-Dv0RYQwj.js.map → icon-badge-Btc6pQrp.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/input-SX9V0AL3.js +255 -0
- package/dist/input-SX9V0AL3.js.map +1 -0
- package/dist/input-vxcaNCYC.js +20 -0
- package/dist/input-vxcaNCYC.js.map +1 -0
- package/dist/{item-pJ0GsOiJ.js → item-DE4YnuJx.js} +18 -17
- package/dist/item-DE4YnuJx.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 +44 -4
- package/dist/lib/control-group-recipes.d.ts +22 -0
- package/dist/lib/field-affordance-recipes.d.ts +35 -2
- package/dist/lib/field-state-recipes.d.ts +2 -2
- package/dist/lib/navigation-row-recipes.d.ts +3 -2
- package/dist/lib/overlay-anatomy-recipes.d.ts +1 -1
- package/dist/lib/surface-recipes.d.ts +5 -2
- package/dist/lib/token-merge.generated.d.ts +144 -2
- package/dist/lib/ui-provider/types.d.ts +4 -2
- package/dist/lib/use-prefers-reduced-motion.d.ts +2 -0
- package/dist/lib/utils.js +1 -1
- package/dist/{media-gallery-Ca4YmvBi.js → media-gallery-DLp3HAz0.js} +75 -74
- package/dist/media-gallery-DLp3HAz0.js.map +1 -0
- package/dist/{mentions-CRio8mTm.js → mentions-Cl0Kt_Pd.js} +52 -50
- package/dist/{mentions-CRio8mTm.js.map → mentions-Cl0Kt_Pd.js.map} +1 -1
- package/dist/message-SZUNB1eX.js +127 -0
- package/dist/message-SZUNB1eX.js.map +1 -0
- package/dist/{navigation-BTrEb5u4.js → navigation-DnQSNMT0.js} +64 -55
- package/dist/navigation-DnQSNMT0.js.map +1 -0
- package/dist/{navigation-DqEITuD2.js → navigation-DyytsLRB.js} +37 -37
- package/dist/navigation-DyytsLRB.js.map +1 -0
- package/dist/{navigation-row-recipes-BFpvGPGE.js → navigation-row-recipes-DQEXQcqY.js} +3 -3
- package/dist/navigation-row-recipes-DQEXQcqY.js.map +1 -0
- package/dist/{number-BNT_BIzJ.js → number-DasMFWEG.js} +4 -4
- package/dist/{number-BNT_BIzJ.js.map → number-DasMFWEG.js.map} +1 -1
- package/dist/overlays-DUbs1KEi.js +1011 -0
- package/dist/overlays-DUbs1KEi.js.map +1 -0
- package/dist/{page-BMBGjJY8.js → page-hGmT4nWK.js} +75 -64
- package/dist/page-hGmT4nWK.js.map +1 -0
- package/dist/{page-header-BH41wCyY.js → page-header-D8nERkn5.js} +9 -9
- package/dist/page-header-D8nERkn5.js.map +1 -0
- package/dist/{pagination-C29vvt3I.js → pagination-NLGqRirf.js} +20 -20
- package/dist/pagination-NLGqRirf.js.map +1 -0
- package/dist/{popover-TInGXsjg.js → popover-CghIYdQf.js} +23 -22
- package/dist/popover-CghIYdQf.js.map +1 -0
- package/dist/{popover-menu-BzqXqE72.js → popover-menu-B4PoWhRl.js} +6 -6
- package/dist/{popover-menu-BzqXqE72.js.map → popover-menu-B4PoWhRl.js.map} +1 -1
- package/dist/{popover.recipes-zgBhMlUu.js → popover.recipes-QlD4JenO.js} +5 -5
- package/dist/popover.recipes-QlD4JenO.js.map +1 -0
- package/dist/{primitives-DKPOGVpj.js → primitives-C7ff0QaI.js} +120 -113
- package/dist/primitives-C7ff0QaI.js.map +1 -0
- package/dist/primitives.js +3 -3
- package/dist/progress-BroqrAyV.js +169 -0
- package/dist/progress-BroqrAyV.js.map +1 -0
- package/dist/{receipt-DYWTQGEc.js → receipt-BuJynLgf.js} +8 -8
- package/dist/{receipt-DYWTQGEc.js.map → receipt-BuJynLgf.js.map} +1 -1
- package/dist/{rich-text-B7sBAdDG.js → rich-text-DlxDOtf4.js} +4 -4
- package/dist/{rich-text-B7sBAdDG.js.map → rich-text-DlxDOtf4.js.map} +1 -1
- package/dist/rich-text-editor-BKyG7rWz.js +574 -0
- package/dist/rich-text-editor-BKyG7rWz.js.map +1 -0
- package/dist/{rich-text-editor.recipes-DxvOE0Lp.js → rich-text-editor.recipes-B72Nfuze.js} +35 -26
- package/dist/rich-text-editor.recipes-B72Nfuze.js.map +1 -0
- package/dist/{scroll-area-BheMQ270.js → scroll-area-D-pIhEKl.js} +3 -3
- package/dist/scroll-area-D-pIhEKl.js.map +1 -0
- package/dist/{separator-Gk_WXH-l.js → separator-BNIgG3au.js} +3 -3
- package/dist/{separator-Gk_WXH-l.js.map → separator-BNIgG3au.js.map} +1 -1
- package/dist/{separator-DO0EbCEm.js → separator-BhtFyo4x.js} +2 -2
- package/dist/{separator-DO0EbCEm.js.map → separator-BhtFyo4x.js.map} +1 -1
- package/dist/services/actions.js +1 -1
- package/dist/{settings-D9f_wdIC.js → settings-DOTOzeZ2.js} +10 -9
- package/dist/{settings-D9f_wdIC.js.map → settings-DOTOzeZ2.js.map} +1 -1
- package/dist/{sheet-vOUloJ4O.js → sheet-BFhrNehm.js} +11 -11
- package/dist/sheet-BFhrNehm.js.map +1 -0
- package/dist/{sidebar-CNBKFDRW.js → sidebar-CyR4XKwR.js} +219 -200
- package/dist/sidebar-CyR4XKwR.js.map +1 -0
- package/dist/{sidebar-C3UKkbC5.js → sidebar-SvGJ0Zwi.js} +63 -58
- package/dist/sidebar-SvGJ0Zwi.js.map +1 -0
- package/dist/{skeleton-BvRhK8y-.js → skeleton-3F0uhYn3.js} +4 -4
- package/dist/{skeleton-BvRhK8y-.js.map → skeleton-3F0uhYn3.js.map} +1 -1
- package/dist/{smart-card-B5FcKODh.js → smart-card-DjGVV2xr.js} +206 -199
- package/dist/smart-card-DjGVV2xr.js.map +1 -0
- package/dist/{spinner-JtlFJ7Nc.js → spinner-Cpf7oRkF.js} +5 -5
- package/dist/{spinner-JtlFJ7Nc.js.map → spinner-Cpf7oRkF.js.map} +1 -1
- package/dist/{structure-BvW4vG4H.js → structure-CRdqVawd.js} +14 -14
- package/dist/{structure-BvW4vG4H.js.map → structure-CRdqVawd.js.map} +1 -1
- package/dist/{structure.recipes-DjqnBpwz.js → structure.recipes-Bqhf9oIh.js} +2 -2
- package/dist/structure.recipes-Bqhf9oIh.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/{surface-recipes-CQfRr-VL.js → surface-recipes-Dd__PD-w.js} +4 -3
- package/dist/surface-recipes-Dd__PD-w.js.map +1 -0
- package/dist/{table-DnlAJ-xR.js → table-CLtJTxoR.js} +17 -16
- package/dist/table-CLtJTxoR.js.map +1 -0
- package/dist/table-CcRDZiLP.js +1444 -0
- package/dist/table-CcRDZiLP.js.map +1 -0
- package/dist/tabs-BNgu7g0u.js +188 -0
- package/dist/tabs-BNgu7g0u.js.map +1 -0
- package/dist/text-inputs-DsR56TR-.js +330 -0
- package/dist/text-inputs-DsR56TR-.js.map +1 -0
- package/dist/{text.styles-BwB7vAF2.js → text.styles-Q4sGAIgA.js} +18 -10
- package/dist/text.styles-Q4sGAIgA.js.map +1 -0
- package/dist/theme.css +77 -115
- package/dist/{timelines-CnZ2S_Gr.js → timelines-D1pkt3se.js} +84 -78
- package/dist/timelines-D1pkt3se.js.map +1 -0
- package/dist/{tree-COD9BGdU.js → tree-BtmYyMZV.js} +8 -8
- package/dist/{tree-COD9BGdU.js.map → tree-BtmYyMZV.js.map} +1 -1
- package/dist/typography/rich-text.js +1 -1
- package/dist/typography-BxQgiZyw.js +96 -0
- package/dist/typography-BxQgiZyw.js.map +1 -0
- package/dist/typography.js +1 -1
- package/dist/{ui-provider-CftIB6TY.js → ui-provider-DRPn3qNl.js} +3 -2
- package/dist/ui-provider-DRPn3qNl.js.map +1 -0
- package/dist/ui-provider.js +1 -1
- package/dist/{upload-DIzw1dx1.js → upload-CDbYw1WN.js} +326 -323
- package/dist/upload-CDbYw1WN.js.map +1 -0
- package/dist/{upload-queue-xRJ3qDmd.js → upload-queue-CNd_hH_a.js} +25 -25
- package/dist/upload-queue-CNd_hH_a.js.map +1 -0
- package/dist/usage-card-VyJLUwRr.js +457 -0
- package/dist/usage-card-VyJLUwRr.js.map +1 -0
- package/dist/utils-BvH9PSmq.js +4275 -0
- package/dist/utils-BvH9PSmq.js.map +1 -0
- package/dist/value-inputs-D0KCrfVC.js +840 -0
- package/dist/value-inputs-D0KCrfVC.js.map +1 -0
- package/dist/{workspace-Cbqz4FzN.js → workspace-CcR8r-Nt.js} +115 -122
- package/dist/workspace-CcR8r-Nt.js.map +1 -0
- package/docs/consumer-skill/SKILL.md +112 -18
- package/docs/consumer-skill/examples/analytics.tsx +34 -0
- package/docs/consumer-skill/examples/app-layout.tsx +42 -12
- package/docs/consumer-skill/examples/detail.tsx +24 -9
- package/docs/consumer-skill/examples/manifest.json +27 -1
- package/docs/consumer-skill/examples/planning-usage-edit.tsx +29 -0
- package/docs/consumer-skill/examples/scoped-directory.tsx +77 -0
- package/docs/consumer-skill/examples/website.tsx +56 -0
- package/docs/consumer-skill/references/analytics.md +70 -0
- package/docs/consumer-skill/references/composition.md +219 -2
- package/docs/consumer-skill/references/design-contract.md +37 -10
- package/docs/consumer-skill/references/discovery.md +93 -5
- package/docs/consumer-skill/references/installation.md +20 -3
- package/docs/consumer-skill/references/integration.md +26 -0
- package/docs/consumer-skill/references/public-api.json +2416 -388
- package/docs/consumer-skill/references/review.md +126 -0
- package/docs/consumer-skill/references/theming.md +52 -7
- package/docs/consumer-skill/references/tokens.json +177 -9
- package/docs/consumer-skill/references/workflows.md +129 -1
- package/docs/consumer-skill/scripts/check-composition.mjs +31 -0
- package/docs/consumer-skill/scripts/composition-policy.mjs +317 -0
- package/docs/consumer-skill/scripts/discovery.mjs +65 -8
- package/docs/consumer-skill/scripts/surface-policy.mjs +66 -0
- package/package.json +30 -6
- package/dist/accordion-BRWh3BM1.js.map +0 -1
- package/dist/action-menu-Cx3SdfbN.js.map +0 -1
- package/dist/affordance-geometry.generated-DXl-Zb3Z.js +0 -23
- package/dist/affordance-geometry.generated-DXl-Zb3Z.js.map +0 -1
- package/dist/ai-artifact-DkOArd3-.js.map +0 -1
- package/dist/app-shell-BH_bGcE2.js.map +0 -1
- package/dist/auth-BDB1V_2q.js +0 -704
- package/dist/auth-BDB1V_2q.js.map +0 -1
- package/dist/avatar-CsnWaYmt.js.map +0 -1
- package/dist/breadcrumbs-DdQ_I5ra.js.map +0 -1
- package/dist/button-BS6l5JUw.js.map +0 -1
- package/dist/buttons-Co6GavvM.js +0 -674
- package/dist/buttons-Co6GavvM.js.map +0 -1
- package/dist/chart-DVfcwQu6.js +0 -149
- package/dist/chart-DVfcwQu6.js.map +0 -1
- package/dist/choice-inputs-CavA-SGV.js +0 -644
- package/dist/choice-inputs-CavA-SGV.js.map +0 -1
- package/dist/code-block-DIlqzoiD.js.map +0 -1
- package/dist/combobox-CHD750do.js.map +0 -1
- package/dist/combobox-HDftpzxt.js.map +0 -1
- package/dist/command-D0kWBZfd.js.map +0 -1
- package/dist/comments-CvYeglMS.js +0 -1132
- package/dist/comments-CvYeglMS.js.map +0 -1
- package/dist/containers-CPNyNo1_.js.map +0 -1
- package/dist/data-display-b3d1TfL4.js.map +0 -1
- package/dist/date-picker-DI6kPNof.js.map +0 -1
- package/dist/date-pickers-ByP6Cv2z.js +0 -224
- package/dist/date-pickers-ByP6Cv2z.js.map +0 -1
- package/dist/feedback-a9j9J-9A.js +0 -391
- package/dist/feedback-a9j9J-9A.js.map +0 -1
- package/dist/field-affordance-recipes-CHdUtn2Z.js +0 -17
- package/dist/field-affordance-recipes-CHdUtn2Z.js.map +0 -1
- package/dist/field-state-recipes-CBTRt9Bt.js.map +0 -1
- package/dist/filters-qtrcv1hf.js.map +0 -1
- package/dist/form-field-C6W-y2hR.js.map +0 -1
- package/dist/form-sizing-39NohSqn.js.map +0 -1
- package/dist/forms-numeric-Y15Bg5Nr.js +0 -867
- package/dist/forms-numeric-Y15Bg5Nr.js.map +0 -1
- package/dist/header-B8ex54cY.js.map +0 -1
- package/dist/http-CLTVJc5I.js.map +0 -1
- package/dist/input-DMorJiTI.js +0 -202
- package/dist/input-DMorJiTI.js.map +0 -1
- package/dist/input-ci9fIgFH.js +0 -20
- package/dist/input-ci9fIgFH.js.map +0 -1
- package/dist/item-pJ0GsOiJ.js.map +0 -1
- package/dist/media-gallery-Ca4YmvBi.js.map +0 -1
- package/dist/message-B5-6LeYl.js +0 -108
- package/dist/message-B5-6LeYl.js.map +0 -1
- package/dist/navigation-BTrEb5u4.js.map +0 -1
- package/dist/navigation-DqEITuD2.js.map +0 -1
- package/dist/navigation-row-recipes-BFpvGPGE.js.map +0 -1
- package/dist/overlays-DBqV0J_V.js +0 -982
- package/dist/overlays-DBqV0J_V.js.map +0 -1
- package/dist/page-BMBGjJY8.js.map +0 -1
- package/dist/page-header-BH41wCyY.js.map +0 -1
- package/dist/pagination-C29vvt3I.js.map +0 -1
- package/dist/popover-TInGXsjg.js.map +0 -1
- package/dist/popover.recipes-zgBhMlUu.js.map +0 -1
- package/dist/primitives-DKPOGVpj.js.map +0 -1
- package/dist/rich-text-editor-BZSJchAF.js +0 -575
- package/dist/rich-text-editor-BZSJchAF.js.map +0 -1
- package/dist/rich-text-editor.recipes-DxvOE0Lp.js.map +0 -1
- package/dist/scroll-area-BheMQ270.js.map +0 -1
- package/dist/select-B2mb-qN2.js +0 -108
- package/dist/select-B2mb-qN2.js.map +0 -1
- package/dist/sheet-vOUloJ4O.js.map +0 -1
- package/dist/sidebar-C3UKkbC5.js.map +0 -1
- package/dist/sidebar-CNBKFDRW.js.map +0 -1
- package/dist/smart-card-B5FcKODh.js.map +0 -1
- package/dist/structure.recipes-DjqnBpwz.js.map +0 -1
- package/dist/surface-recipes-CQfRr-VL.js.map +0 -1
- package/dist/table-DnlAJ-xR.js.map +0 -1
- package/dist/table-ghtAQ-JJ.js +0 -1424
- package/dist/table-ghtAQ-JJ.js.map +0 -1
- package/dist/tabs-DY09eoZg.js +0 -187
- package/dist/tabs-DY09eoZg.js.map +0 -1
- package/dist/text-inputs-BhOcedTo.js +0 -331
- package/dist/text-inputs-BhOcedTo.js.map +0 -1
- package/dist/text.styles-BwB7vAF2.js.map +0 -1
- package/dist/timelines-CnZ2S_Gr.js.map +0 -1
- package/dist/typography-Cv8MT-82.js +0 -96
- package/dist/typography-Cv8MT-82.js.map +0 -1
- package/dist/ui-provider-CftIB6TY.js.map +0 -1
- package/dist/upload-DIzw1dx1.js.map +0 -1
- package/dist/upload-queue-xRJ3qDmd.js.map +0 -1
- package/dist/utils-C2EKeIw3.js +0 -72
- package/dist/utils-C2EKeIw3.js.map +0 -1
- package/dist/value-inputs-Co1fu-xv.js +0 -824
- package/dist/value-inputs-Co1fu-xv.js.map +0 -1
- package/dist/workspace-Cbqz4FzN.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
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,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { _ as e, s as t } from "./ui-provider-
|
|
2
|
+
import { _ as e, s as t } from "./ui-provider-DRPn3qNl.js";
|
|
3
3
|
import { useStrings as n } from "./lib/strings.js";
|
|
4
|
-
import { t as r } from "./utils-
|
|
5
|
-
import {
|
|
6
|
-
import { a } from "./
|
|
7
|
-
import { t as o } from "./structure-
|
|
8
|
-
import { g as s, i as c } from "./primitives-
|
|
9
|
-
import { t as l } from "./badge-
|
|
4
|
+
import { t as r } from "./utils-BvH9PSmq.js";
|
|
5
|
+
import { a as i } from "./typography-BxQgiZyw.js";
|
|
6
|
+
import { t as a } from "./button-BZDasD04.js";
|
|
7
|
+
import { t as o } from "./structure-CRdqVawd.js";
|
|
8
|
+
import { g as s, i as c } from "./primitives-C7ff0QaI.js";
|
|
9
|
+
import { t as l } from "./badge-CzId1Wlm.js";
|
|
10
10
|
import { t as u } from "./use-file-drop-target-BX7GnhoQ.js";
|
|
11
|
-
import { a as d, c as f, i as p, n as m, o as h, r as g, s as _, t as v } from "./attachment-
|
|
11
|
+
import { a as d, c as f, i as p, n as m, o as h, r as g, s as _, t as v } from "./attachment-DbjUWsP0.js";
|
|
12
12
|
import { forwardRef as y, useCallback as b, useId as x } from "react";
|
|
13
13
|
import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
14
14
|
import { AlertCircle as T, Check as E, Clock as D, Download as O, Eye as k, RefreshCw as A, UploadCloud as j, X as M } from "lucide-react";
|
|
@@ -60,17 +60,17 @@ var P = {
|
|
|
60
60
|
function I(e, t) {
|
|
61
61
|
typeof t == "function" ? t(e) : t && (t.current = e);
|
|
62
62
|
}
|
|
63
|
-
function L({ onDrop:
|
|
63
|
+
function L({ onDrop: a, accept: o, multiple: s = !1, disabled: c = !1, invalid: l = !1, size: d, icon: f, className: p, inputProps: m, children: h, strings: g }, _) {
|
|
64
64
|
let { defaultScale: v } = t(), y = n(P, g), b = x(), S = m?.id ?? `dropzone-${b}`, { isDragging: T, dropTargetProps: E } = u({
|
|
65
65
|
disabled: c,
|
|
66
|
-
onFiles:
|
|
66
|
+
onFiles: a
|
|
67
67
|
}), D = F[e(d, v)];
|
|
68
68
|
return /* @__PURE__ */ w("div", {
|
|
69
69
|
...E,
|
|
70
70
|
"data-disabled": c || void 0,
|
|
71
71
|
"data-invalid": l || void 0,
|
|
72
72
|
"data-dragging": T || void 0,
|
|
73
|
-
className: r("dropzone--component relative flex flex-col items-center justify-center gap-space-md rounded-radius
|
|
73
|
+
className: r("dropzone--component relative flex flex-col items-center justify-center gap-space-md rounded-radius border border-dashed text-center transition-colors duration-150", "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", D.minHeight, D.padding, l ? "border-destructive" : "border-muted-foreground/40", l ? !c && "hover:bg-destructive/5" : !c && "hover:border-primary hover:bg-primary/5", c && "cursor-not-allowed opacity-50", !c && T && (l ? "border-destructive bg-destructive/5" : "border-primary bg-primary/10"), p),
|
|
74
74
|
children: [
|
|
75
75
|
/* @__PURE__ */ C(N, {
|
|
76
76
|
...m,
|
|
@@ -81,7 +81,7 @@ function L({ onDrop: i, accept: o, multiple: s = !1, disabled: c = !1, invalid:
|
|
|
81
81
|
disabled: c,
|
|
82
82
|
"aria-invalid": l || void 0,
|
|
83
83
|
className: r("dropzone--input", m?.className),
|
|
84
|
-
onFiles:
|
|
84
|
+
onFiles: a
|
|
85
85
|
}),
|
|
86
86
|
/* @__PURE__ */ w("label", {
|
|
87
87
|
htmlFor: c ? void 0 : S,
|
|
@@ -93,12 +93,12 @@ function L({ onDrop: i, accept: o, multiple: s = !1, disabled: c = !1, invalid:
|
|
|
93
93
|
children: f ?? /* @__PURE__ */ C(j, { className: D.iconSize })
|
|
94
94
|
}), /* @__PURE__ */ w("span", {
|
|
95
95
|
className: "dropzone--copy grid gap-normal text-center [&_p]:text-center",
|
|
96
|
-
children: [/* @__PURE__ */ C(
|
|
96
|
+
children: [/* @__PURE__ */ C(i, {
|
|
97
97
|
tag: "span",
|
|
98
98
|
weight: "medium",
|
|
99
99
|
className: "dropzone--instruction",
|
|
100
100
|
children: T ? y.dragOver : y.instruction
|
|
101
|
-
}), !!y.helper && /* @__PURE__ */ C(
|
|
101
|
+
}), !!y.helper && /* @__PURE__ */ C(i, {
|
|
102
102
|
tag: "span",
|
|
103
103
|
size: "xs",
|
|
104
104
|
type: "secondary",
|
|
@@ -162,7 +162,7 @@ function V({ items: e, onPreview: t, onDownload: l, onCancel: u, onRetry: y, onR
|
|
|
162
162
|
return e.length === 0 ? null : /* @__PURE__ */ C(o, {
|
|
163
163
|
render: /* @__PURE__ */ C("ul", {}),
|
|
164
164
|
gap: "sm",
|
|
165
|
-
className: r("upload-progress-list--component", x),
|
|
165
|
+
className: r("upload-progress-list--component m-0 p-0 list-none", x),
|
|
166
166
|
children: e.map((e) => {
|
|
167
167
|
let n = B[e.status], x = n.icon, S = e.progress === void 0 ? null : Number.isFinite(e.progress) ? Math.max(0, Math.min(100, e.progress ?? 0)) : 0, D = e.status === "uploading" || e.status === "queued";
|
|
168
168
|
return /* @__PURE__ */ w(v, {
|
|
@@ -196,7 +196,7 @@ function V({ items: e, onPreview: t, onDownload: l, onCancel: u, onRetry: y, onR
|
|
|
196
196
|
children: [/* @__PURE__ */ C(f, {
|
|
197
197
|
className: "min-w-0 max-w-full",
|
|
198
198
|
title: e.name,
|
|
199
|
-
children: /* @__PURE__ */ C(
|
|
199
|
+
children: /* @__PURE__ */ C(i, {
|
|
200
200
|
tag: "span",
|
|
201
201
|
weight: "medium",
|
|
202
202
|
className: "truncate",
|
|
@@ -214,7 +214,7 @@ function V({ items: e, onPreview: t, onDownload: l, onCancel: u, onRetry: y, onR
|
|
|
214
214
|
}),
|
|
215
215
|
/* @__PURE__ */ C(p, {
|
|
216
216
|
clamp: "none",
|
|
217
|
-
children: /* @__PURE__ */ C(
|
|
217
|
+
children: /* @__PURE__ */ C(i, {
|
|
218
218
|
tag: "span",
|
|
219
219
|
size: "xs",
|
|
220
220
|
lineHeight: "tight",
|
|
@@ -235,7 +235,7 @@ function V({ items: e, onPreview: t, onDownload: l, onCancel: u, onRetry: y, onR
|
|
|
235
235
|
/* @__PURE__ */ w(m, {
|
|
236
236
|
className: "shrink-0",
|
|
237
237
|
children: [
|
|
238
|
-
!!t && /* @__PURE__ */ C(
|
|
238
|
+
!!t && /* @__PURE__ */ C(a, {
|
|
239
239
|
type: "button",
|
|
240
240
|
tone: "secondary",
|
|
241
241
|
buttonStyle: "ghost",
|
|
@@ -248,7 +248,7 @@ function V({ items: e, onPreview: t, onDownload: l, onCancel: u, onRetry: y, onR
|
|
|
248
248
|
className: "size-icon-md"
|
|
249
249
|
})
|
|
250
250
|
}),
|
|
251
|
-
!!l && e.status === "done" && /* @__PURE__ */ C(
|
|
251
|
+
!!l && e.status === "done" && /* @__PURE__ */ C(a, {
|
|
252
252
|
type: "button",
|
|
253
253
|
tone: "secondary",
|
|
254
254
|
buttonStyle: "ghost",
|
|
@@ -261,7 +261,7 @@ function V({ items: e, onPreview: t, onDownload: l, onCancel: u, onRetry: y, onR
|
|
|
261
261
|
className: "size-icon-md"
|
|
262
262
|
})
|
|
263
263
|
}),
|
|
264
|
-
(e.status === "uploading" || e.status === "queued") && !!u && /* @__PURE__ */ C(
|
|
264
|
+
(e.status === "uploading" || e.status === "queued") && !!u && /* @__PURE__ */ C(a, {
|
|
265
265
|
type: "button",
|
|
266
266
|
tone: "secondary",
|
|
267
267
|
buttonStyle: "ghost",
|
|
@@ -271,7 +271,7 @@ function V({ items: e, onPreview: t, onDownload: l, onCancel: u, onRetry: y, onR
|
|
|
271
271
|
onClick: () => u(e.id),
|
|
272
272
|
children: /* @__PURE__ */ C(M, { className: "size-icon-md" })
|
|
273
273
|
}),
|
|
274
|
-
e.status === "error" && !!y && /* @__PURE__ */ C(
|
|
274
|
+
e.status === "error" && !!y && /* @__PURE__ */ C(a, {
|
|
275
275
|
type: "button",
|
|
276
276
|
tone: "secondary",
|
|
277
277
|
buttonStyle: "ghost",
|
|
@@ -281,7 +281,7 @@ function V({ items: e, onPreview: t, onDownload: l, onCancel: u, onRetry: y, onR
|
|
|
281
281
|
onClick: () => y(e.id),
|
|
282
282
|
children: /* @__PURE__ */ C(A, { className: "size-icon-md" })
|
|
283
283
|
}),
|
|
284
|
-
(e.status === "done" || e.status === "error" || e.status === "cancelled" || e.status === "queued" && !u) && !!b && /* @__PURE__ */ C(
|
|
284
|
+
(e.status === "done" || e.status === "error" || e.status === "cancelled" || e.status === "queued" && !u) && !!b && /* @__PURE__ */ C(a, {
|
|
285
285
|
type: "button",
|
|
286
286
|
tone: "secondary",
|
|
287
287
|
buttonStyle: "ghost",
|
|
@@ -347,7 +347,7 @@ var W = y(function({ items: e, onAddFiles: t, onPreview: s, onDownload: c, onCan
|
|
|
347
347
|
align: "center",
|
|
348
348
|
gap: "md",
|
|
349
349
|
children: [
|
|
350
|
-
/* @__PURE__ */ C(
|
|
350
|
+
/* @__PURE__ */ C(i, {
|
|
351
351
|
tag: "span",
|
|
352
352
|
weight: "semibold",
|
|
353
353
|
children: y.heading
|
|
@@ -385,7 +385,7 @@ var W = y(function({ items: e, onAddFiles: t, onPreview: s, onDownload: c, onCan
|
|
|
385
385
|
]
|
|
386
386
|
})
|
|
387
387
|
]
|
|
388
|
-
}), !!p && /* @__PURE__ */ C(
|
|
388
|
+
}), !!p && /* @__PURE__ */ C(a, {
|
|
389
389
|
type: "button",
|
|
390
390
|
tone: "secondary",
|
|
391
391
|
buttonStyle: "ghost",
|
|
@@ -407,4 +407,4 @@ W.displayName = "UploadTray";
|
|
|
407
407
|
//#endregion
|
|
408
408
|
export { R as a, z as i, H as n, P as o, V as r, N as s, W as t };
|
|
409
409
|
|
|
410
|
-
//# sourceMappingURL=upload-queue-
|
|
410
|
+
//# sourceMappingURL=upload-queue-CNd_hH_a.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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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"}
|