@px-ui/ui 1.0.3 → 1.0.4
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/dist/{avatar-B2FY4pgk.js → avatar-B1kOPk5C.js} +4 -4
- package/dist/{avatar-B2FY4pgk.js.map → avatar-B1kOPk5C.js.map} +1 -1
- package/dist/{avatar-CtZEW1Kd.d.ts → avatar-CZr6NzW8.d.ts} +6 -6
- package/dist/{avatar-CtZEW1Kd.d.ts.map → avatar-CZr6NzW8.d.ts.map} +1 -1
- package/dist/{button-peTbHgr6.d.ts → button-BWB2PWYv.d.ts} +7 -7
- package/dist/{button-peTbHgr6.d.ts.map → button-BWB2PWYv.d.ts.map} +1 -1
- package/dist/{button-B3SNyz-U.js → button-hBUFMmsZ.js} +2 -2
- package/dist/{button-B3SNyz-U.js.map → button-hBUFMmsZ.js.map} +1 -1
- package/dist/{combobox-CBerynHz.js → combobox-C-dF33ce.js} +9 -9
- package/dist/{combobox-CBerynHz.js.map → combobox-C-dF33ce.js.map} +1 -1
- package/dist/{combobox-BGJkF5tM.d.ts → combobox-z8wdqIlf.d.ts} +18 -18
- package/dist/combobox-z8wdqIlf.d.ts.map +1 -0
- package/dist/components/accordion.d.ts +5 -5
- package/dist/components/accordion.d.ts.map +1 -1
- package/dist/components/accordion.js +1 -1
- package/dist/components/alert-dialog.d.ts +14 -14
- package/dist/components/alert-dialog.d.ts.map +1 -1
- package/dist/components/alert-dialog.js +3 -3
- package/dist/components/alert.d.ts +7 -7
- package/dist/components/alert.d.ts.map +1 -1
- package/dist/components/alert.js +2 -2
- package/dist/components/aspect-ratio.js +1 -1
- package/dist/components/avatar-group.d.ts +4 -4
- package/dist/components/avatar-group.js +5 -5
- package/dist/components/avatar.d.ts +1 -1
- package/dist/components/avatar.js +3 -3
- package/dist/components/badge.d.ts +3 -3
- package/dist/components/badge.js +1 -1
- package/dist/components/breadcrumb.d.ts +7 -7
- package/dist/components/breadcrumb.d.ts.map +1 -1
- package/dist/components/breadcrumb.js +2 -2
- package/dist/components/button-group.d.ts +6 -6
- package/dist/components/button-group.d.ts.map +1 -1
- package/dist/components/button-group.js +2 -2
- package/dist/components/button.d.ts +1 -1
- package/dist/components/button.js +2 -2
- package/dist/components/calendar.d.ts +4 -4
- package/dist/components/calendar.js +3 -3
- package/dist/components/card.d.ts +8 -8
- package/dist/components/card.d.ts.map +1 -1
- package/dist/components/card.js +2 -2
- package/dist/components/carousel.d.ts +7 -7
- package/dist/components/carousel.js +3 -3
- package/dist/components/chart.d.ts +5 -5
- package/dist/components/chart.d.ts.map +1 -1
- package/dist/components/chart.js +2 -2
- package/dist/components/checkbox.d.ts +2 -2
- package/dist/components/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/collapsible.d.ts +4 -4
- package/dist/components/collapsible.d.ts.map +1 -1
- package/dist/components/collapsible.js +1 -1
- package/dist/components/combobox.d.ts +1 -1
- package/dist/components/combobox.js +11 -11
- package/dist/components/command.d.ts +11 -11
- package/dist/components/command.d.ts.map +1 -1
- package/dist/components/command.js +7 -7
- package/dist/components/context-menu.d.ts +16 -16
- package/dist/components/context-menu.d.ts.map +1 -1
- package/dist/components/context-menu.js +2 -2
- package/dist/components/currency-select-field.d.ts +3 -3
- package/dist/components/currency-select-field.d.ts.map +1 -1
- package/dist/components/currency-select-field.js +12 -12
- package/dist/components/dialog.d.ts +11 -11
- package/dist/components/dialog.js +3 -3
- package/dist/components/direction.js +1 -1
- package/dist/components/drawer.d.ts +11 -11
- package/dist/components/drawer.js +2 -2
- package/dist/components/dropdown-menu.d.ts +1 -1
- package/dist/components/dropdown-menu.js +2 -2
- package/dist/components/empty.d.ts +9 -9
- package/dist/components/empty.d.ts.map +1 -1
- package/dist/components/empty.js +1 -1
- package/dist/components/field.d.ts +15 -15
- package/dist/components/field.d.ts.map +1 -1
- package/dist/components/field.js +4 -4
- package/dist/components/file-upload-field.d.ts +2 -2
- package/dist/components/file-upload-field.js +6 -6
- package/dist/components/file-upload.d.ts +2 -2
- package/dist/components/file-upload.js +4 -4
- package/dist/components/hover-card.d.ts +4 -4
- package/dist/components/hover-card.js +1 -1
- package/dist/components/input-group.d.ts +12 -12
- package/dist/components/input-group.js +5 -5
- package/dist/components/input-otp.d.ts +5 -5
- package/dist/components/input-otp.js +2 -2
- package/dist/components/input.d.ts +1 -1
- package/dist/components/input.js +2 -2
- package/dist/components/item.d.ts +15 -15
- package/dist/components/item.d.ts.map +1 -1
- package/dist/components/item.js +3 -3
- package/dist/components/kbd.d.ts +3 -3
- package/dist/components/kbd.d.ts.map +1 -1
- package/dist/components/kbd.js +1 -1
- package/dist/components/label.d.ts +1 -1
- package/dist/components/label.js +2 -2
- package/dist/components/menubar.d.ts +18 -18
- package/dist/components/menubar.d.ts.map +1 -1
- package/dist/components/menubar.js +3 -3
- package/dist/components/native-select.d.ts +4 -4
- package/dist/components/native-select.d.ts.map +1 -1
- package/dist/components/native-select.js +2 -2
- package/dist/components/navigation-menu.d.ts +11 -11
- package/dist/components/navigation-menu.d.ts.map +1 -1
- package/dist/components/navigation-menu.js +1 -1
- package/dist/components/pagination.d.ts +9 -9
- package/dist/components/pagination.js +3 -3
- package/dist/components/phone-input.d.ts +2 -2
- package/dist/components/phone-input.d.ts.map +1 -1
- package/dist/components/phone-input.js +4 -4
- package/dist/components/phone-input.js.map +1 -1
- package/dist/components/popover.d.ts +7 -7
- package/dist/components/popover.js +2 -2
- package/dist/components/progress.d.ts +6 -6
- package/dist/components/progress.js +1 -1
- package/dist/components/radio-group.d.ts +3 -3
- package/dist/components/radio-group.js +1 -1
- package/dist/components/resizable.d.ts +4 -4
- package/dist/components/resizable.js +1 -1
- package/dist/components/scroll-area.d.ts +3 -3
- package/dist/components/scroll-area.js +2 -2
- package/dist/components/select.d.ts +10 -10
- package/dist/components/select.js +2 -2
- package/dist/components/separator.d.ts +1 -1
- package/dist/components/separator.js +2 -2
- package/dist/components/sheet.d.ts +9 -9
- package/dist/components/sheet.js +3 -3
- package/dist/components/sidebar.d.ts +25 -25
- package/dist/components/sidebar.js +9 -9
- package/dist/components/skeleton.d.ts +2 -2
- package/dist/components/skeleton.js +2 -2
- package/dist/components/slider.d.ts +2 -2
- package/dist/components/slider.js +1 -1
- package/dist/components/spinner.d.ts +2 -2
- package/dist/components/spinner.js +2 -2
- package/dist/components/switch.d.ts +2 -2
- package/dist/components/switch.js +1 -1
- package/dist/components/table.d.ts +9 -9
- package/dist/components/table.js +2 -2
- package/dist/components/tabs.d.ts +7 -7
- package/dist/components/tabs.js +1 -1
- package/dist/components/textarea.d.ts +2 -2
- package/dist/components/textarea.js +2 -2
- package/dist/components/toast.d.ts +1 -1
- package/dist/components/toast.js +2 -2
- package/dist/components/toggle-group.d.ts +4 -4
- package/dist/components/toggle-group.js +3 -3
- package/dist/components/toggle.d.ts +1 -1
- package/dist/components/toggle.js +2 -2
- package/dist/components/tooltip.js +2 -2
- package/dist/{dialog-6oTB2jEH.js → dialog-DrdXva1a.js} +4 -4
- package/dist/{dialog-6oTB2jEH.js.map → dialog-DrdXva1a.js.map} +1 -1
- package/dist/{dropdown-menu-z9weMtW6.d.ts → dropdown-menu-BNmyNq9W.d.ts} +17 -17
- package/dist/{dropdown-menu-z9weMtW6.d.ts.map → dropdown-menu-BNmyNq9W.d.ts.map} +1 -1
- package/dist/{dropdown-menu-CN7gHXiF.js → dropdown-menu-CcumvwhM.js} +3 -3
- package/dist/{dropdown-menu-CN7gHXiF.js.map → dropdown-menu-CcumvwhM.js.map} +1 -1
- package/dist/{file-upload-CPaU1bTN.js → file-upload-DeCIv13t.js} +5 -5
- package/dist/{file-upload-CPaU1bTN.js.map → file-upload-DeCIv13t.js.map} +1 -1
- package/dist/{file-upload-CHIguMmH.d.ts → file-upload-Dzih3NuX.d.ts} +12 -12
- package/dist/{file-upload-CHIguMmH.d.ts.map → file-upload-Dzih3NuX.d.ts.map} +1 -1
- package/dist/hooks/use-async-options.js +1 -1
- package/dist/hooks/use-debounce.js +1 -1
- package/dist/hooks/use-file-upload.js +1 -1
- package/dist/hooks/use-infinite-scroll.js +2 -2
- package/dist/hooks/use-intersection-observer.js +1 -1
- package/dist/hooks/use-mobile.js +1 -1
- package/dist/{input-ByI__4Tb.js → input-8jqdnUZl.js} +3 -3
- package/dist/{input-ByI__4Tb.js.map → input-8jqdnUZl.js.map} +1 -1
- package/dist/{input-BY_HLiBI.d.ts → input-CKTvQqOU.d.ts} +3 -3
- package/dist/input-CKTvQqOU.d.ts.map +1 -0
- package/dist/{input-group-Dw3LpMMS.js → input-group-DqEkmpXW.js} +6 -6
- package/dist/{input-group-Dw3LpMMS.js.map → input-group-DqEkmpXW.js.map} +1 -1
- package/dist/{label-DJ-ONU1d.js → label-AaH9ZYCZ.js} +3 -3
- package/dist/{label-DJ-ONU1d.js.map → label-AaH9ZYCZ.js.map} +1 -1
- package/dist/label-DMeHPQml.d.ts +11 -0
- package/dist/label-DMeHPQml.d.ts.map +1 -0
- package/dist/lib/utils.js +1 -1
- package/dist/{popover-z4aFoVCA.js → popover-C9D43EuT.js} +3 -3
- package/dist/{popover-z4aFoVCA.js.map → popover-C9D43EuT.js.map} +1 -1
- package/dist/providers/px-ui-provider.d.ts +3 -3
- package/dist/providers/px-ui-provider.js +8 -5
- package/dist/providers/px-ui-provider.js.map +1 -1
- package/dist/{separator-Cay2tYJi.js → separator-BS3ilczC.js} +2 -2
- package/dist/{separator-Cay2tYJi.js.map → separator-BS3ilczC.js.map} +1 -1
- package/dist/{separator-7n2clBT1.d.ts → separator-CuuVnw-z.d.ts} +3 -3
- package/dist/{separator-7n2clBT1.d.ts.map → separator-CuuVnw-z.d.ts.map} +1 -1
- package/dist/{sheet-BLGcp2vY.js → sheet-CLjNDrfL.js} +4 -4
- package/dist/{sheet-BLGcp2vY.js.map → sheet-CLjNDrfL.js.map} +1 -1
- package/dist/{skeleton-Cpayevuv.js → skeleton-BcIxI5Wq.js} +2 -2
- package/dist/{skeleton-Cpayevuv.js.map → skeleton-BcIxI5Wq.js.map} +1 -1
- package/dist/{spinner-EaERkwNt.js → spinner-Bo0sUZEg.js} +2 -2
- package/dist/{spinner-EaERkwNt.js.map → spinner-Bo0sUZEg.js.map} +1 -1
- package/dist/{textarea-CD4lb4bT.js → textarea-Cq0o323P.js} +3 -3
- package/dist/{textarea-CD4lb4bT.js.map → textarea-Cq0o323P.js.map} +1 -1
- package/dist/{toast-C3bNvyqf.d.ts → toast-BBU6Q5ZU.d.ts} +4 -4
- package/dist/{toast-C3bNvyqf.d.ts.map → toast-BBU6Q5ZU.d.ts.map} +1 -1
- package/dist/{toast-BIAksZXy.js → toast-COWAQbIk.js} +3 -3
- package/dist/{toast-BIAksZXy.js.map → toast-COWAQbIk.js.map} +1 -1
- package/dist/{toggle-E0JXUyzs.d.ts → toggle-CsHqUVUY.d.ts} +3 -3
- package/dist/{toggle-E0JXUyzs.d.ts.map → toggle-CsHqUVUY.d.ts.map} +1 -1
- package/dist/{toggle-Cwsbk1jY.js → toggle-DhJ_qwgw.js} +2 -2
- package/dist/{toggle-Cwsbk1jY.js.map → toggle-DhJ_qwgw.js.map} +1 -1
- package/dist/{tooltip-CIwyqk_3.js → tooltip-DkPxCJIL.js} +2 -2
- package/dist/{tooltip-CIwyqk_3.js.map → tooltip-DkPxCJIL.js.map} +1 -1
- package/dist/{use-async-options-MznolA0k.js → use-async-options-wZ9LJ2BJ.js} +1 -1
- package/dist/{use-async-options-MznolA0k.js.map → use-async-options-wZ9LJ2BJ.js.map} +1 -1
- package/dist/{use-debounce-CwnVqtDF.js → use-debounce-_qaEZqtt.js} +1 -1
- package/dist/{use-debounce-CwnVqtDF.js.map → use-debounce-_qaEZqtt.js.map} +1 -1
- package/dist/{use-file-upload-CiAqUFFh.js → use-file-upload-Dxrej28u.js} +1 -1
- package/dist/{use-file-upload-CiAqUFFh.js.map → use-file-upload-Dxrej28u.js.map} +1 -1
- package/dist/{use-infinite-scroll-DHi7CKyt.js → use-infinite-scroll-CpbhGGT5.js} +2 -2
- package/dist/{use-infinite-scroll-DHi7CKyt.js.map → use-infinite-scroll-CpbhGGT5.js.map} +1 -1
- package/dist/{use-intersection-observer-h5ZpX18y.js → use-intersection-observer-CZfnep4z.js} +1 -1
- package/dist/{use-intersection-observer-h5ZpX18y.js.map → use-intersection-observer-CZfnep4z.js.map} +1 -1
- package/dist/{use-mobile-CFSCadSm.js → use-mobile-l5ebOdQl.js} +1 -1
- package/dist/{use-mobile-CFSCadSm.js.map → use-mobile-l5ebOdQl.js.map} +1 -1
- package/dist/{utils-8o789qxH.js → utils-mWJR2N24.js} +1 -1
- package/dist/{utils-8o789qxH.js.map → utils-mWJR2N24.js.map} +1 -1
- package/package.json +1 -1
- package/dist/combobox-BGJkF5tM.d.ts.map +0 -1
- package/dist/input-BY_HLiBI.d.ts.map +0 -1
- package/dist/label-C3yvmi-S.d.ts +0 -11
- package/dist/label-C3yvmi-S.d.ts.map +0 -1
- /package/dist/{direction-CB0IW0WZ.js → direction-BKSh6e6q.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet-
|
|
1
|
+
{"version":3,"file":"sheet-CLjNDrfL.js","names":["SheetPrimitive"],"sources":["../src/components/sheet.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Dialog as SheetPrimitive } from \"@base-ui/react/dialog\"\n\nimport { cn } from \"@px-ui/ui/lib/utils\"\nimport { Button } from \"@px-ui/ui/components/button\"\nimport { XIcon } from \"lucide-react\"\n\nfunction Sheet({ ...props }: SheetPrimitive.Root.Props) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />\n}\n\nfunction SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({ ...props }: SheetPrimitive.Close.Props) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {\n return (\n <SheetPrimitive.Backdrop\n data-slot=\"sheet-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n showCloseButton = true,\n ...props\n}: SheetPrimitive.Popup.Props & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n showCloseButton?: boolean\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Popup\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n \"fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-e data-[side=left]:data-ending-style:translate-x-[-2.5rem] rtl:data-[side=left]:data-ending-style:-translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] rtl:data-[side=left]:data-starting-style:-translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-s data-[side=right]:data-ending-style:translate-x-[2.5rem] rtl:data-[side=right]:data-ending-style:-translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] rtl:data-[side=right]:data-starting-style:-translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:ppx-sm:max-w-sm data-[side=right]:ppx-sm:max-w-sm\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n render={\n <Button\n variant=\"ghost\"\n className=\"absolute top-4 end-4\"\n size=\"icon-sm\"\n />\n }\n >\n <XIcon\n />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n )}\n </SheetPrimitive.Popup>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"font-heading font-medium text-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: SheetPrimitive.Description.Props) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n"],"mappings":";;;;;;;;AASA,SAAS,MAAM,EAAE,GAAG,SAAoC;AACtD,QAAO,oBAACA,OAAe;EAAK,aAAU;EAAQ,GAAI;GAAS;;AAG7D,SAAS,aAAa,EAAE,GAAG,SAAuC;AAChE,QAAO,oBAACA,OAAe;EAAQ,aAAU;EAAgB,GAAI;GAAS;;AAGxE,SAAS,WAAW,EAAE,GAAG,SAAqC;AAC5D,QAAO,oBAACA,OAAe;EAAM,aAAU;EAAc,GAAI;GAAS;;AAGpE,SAAS,YAAY,EAAE,GAAG,SAAsC;AAC9D,QAAO,oBAACA,OAAe;EAAO,aAAU;EAAe,GAAI;GAAS;;AAGtE,SAAS,aAAa,EAAE,WAAW,GAAG,SAAwC;AAC5E,QACE,oBAACA,OAAe;EACd,aAAU;EACV,WAAW,GACT,sKACA,UACD;EACD,GAAI;GACJ;;AAIN,SAAS,aAAa,EACpB,WACA,UACA,OAAO,SACP,kBAAkB,MAClB,GAAG,SAIF;AACD,QACE,qBAAC,0BACC,oBAAC,iBAAe,EAChB,qBAACA,OAAe;EACd,aAAU;EACV,aAAW;EACX,WAAW,GACT,i6CACA,UACD;EACD,GAAI;aAEH,UACA,mBACC,qBAACA,OAAe;GACd,aAAU;GACV,QACE,oBAAC;IACC,SAAQ;IACR,WAAU;IACV,MAAK;KACL;cAGJ,oBAAC,UACC,EACF,oBAAC;IAAK,WAAU;cAAU;KAAY;IACjB;GAEJ,IACX;;AAIlB,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;AACzE,QACE,oBAAC;EACC,aAAU;EACV,WAAW,GAAG,6BAA6B,UAAU;EACrD,GAAI;GACJ;;AAIN,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;AACzE,QACE,oBAAC;EACC,aAAU;EACV,WAAW,GAAG,mCAAmC,UAAU;EAC3D,GAAI;GACJ;;AAIN,SAAS,WAAW,EAAE,WAAW,GAAG,SAAqC;AACvE,QACE,oBAACA,OAAe;EACd,aAAU;EACV,WAAW,GAAG,4CAA4C,UAAU;EACpE,GAAI;GACJ;;AAIN,SAAS,iBAAiB,EACxB,WACA,GAAG,SACgC;AACnC,QACE,oBAACA,OAAe;EACd,aAAU;EACV,WAAW,GAAG,iCAAiC,UAAU;EACzD,GAAI;GACJ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as cn } from "./utils-
|
|
1
|
+
import { t as cn } from "./utils-mWJR2N24.js";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/skeleton.tsx
|
|
@@ -12,4 +12,4 @@ function Skeleton({ className, ...props }) {
|
|
|
12
12
|
|
|
13
13
|
//#endregion
|
|
14
14
|
export { Skeleton as t };
|
|
15
|
-
//# sourceMappingURL=skeleton-
|
|
15
|
+
//# sourceMappingURL=skeleton-BcIxI5Wq.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skeleton-
|
|
1
|
+
{"version":3,"file":"skeleton-BcIxI5Wq.js","names":[],"sources":["../src/components/skeleton.tsx"],"sourcesContent":["import { cn } from \"@px-ui/ui/lib/utils\"\n\nfunction Skeleton({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"skeleton\"\n className={cn(\"animate-pulse rounded-md bg-muted\", className)}\n {...props}\n />\n )\n}\n\nexport { Skeleton }\n"],"mappings":";;;;AAEA,SAAS,SAAS,EAAE,WAAW,GAAG,SAAsC;AACtE,QACE,oBAAC;EACC,aAAU;EACV,WAAW,GAAG,qCAAqC,UAAU;EAC7D,GAAI;GACJ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as cn } from "./utils-
|
|
1
|
+
import { t as cn } from "./utils-mWJR2N24.js";
|
|
2
2
|
import { Loader2Icon } from "lucide-react";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
|
|
@@ -14,4 +14,4 @@ function Spinner({ className, ...props }) {
|
|
|
14
14
|
|
|
15
15
|
//#endregion
|
|
16
16
|
export { Spinner as t };
|
|
17
|
-
//# sourceMappingURL=spinner-
|
|
17
|
+
//# sourceMappingURL=spinner-Bo0sUZEg.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spinner-
|
|
1
|
+
{"version":3,"file":"spinner-Bo0sUZEg.js","names":[],"sources":["../src/components/spinner.tsx"],"sourcesContent":["import { cn } from \"@px-ui/ui/lib/utils\";\nimport { Loader2Icon } from \"lucide-react\";\n\nfunction Spinner({\n className,\n ...props\n}: React.ComponentProps<typeof Loader2Icon>) {\n return (\n <Loader2Icon\n role=\"status\"\n aria-label=\"Loading\"\n className={cn(\"size-4 animate-spin\", className)}\n {...props}\n />\n );\n}\n\nexport { Spinner };\n"],"mappings":";;;;;AAGA,SAAS,QAAQ,EACf,WACA,GAAG,SACwC;AAC3C,QACE,oBAAC;EACC,MAAK;EACL,cAAW;EACX,WAAW,GAAG,uBAAuB,UAAU;EAC/C,GAAI;GACJ"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as cn } from "./utils-
|
|
2
|
-
import "react";
|
|
1
|
+
import { t as cn } from "./utils-mWJR2N24.js";
|
|
3
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import "react";
|
|
4
4
|
|
|
5
5
|
//#region src/components/textarea.tsx
|
|
6
6
|
function Textarea({ className, ...props }) {
|
|
@@ -13,4 +13,4 @@ function Textarea({ className, ...props }) {
|
|
|
13
13
|
|
|
14
14
|
//#endregion
|
|
15
15
|
export { Textarea as t };
|
|
16
|
-
//# sourceMappingURL=textarea-
|
|
16
|
+
//# sourceMappingURL=textarea-Cq0o323P.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea-
|
|
1
|
+
{"version":3,"file":"textarea-Cq0o323P.js","names":[],"sources":["../src/components/textarea.tsx"],"sourcesContent":["import * as React from \"react\"\n\nimport { cn } from \"@px-ui/ui/lib/utils\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n \"flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-2.5 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 ppx-md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Textarea }\n"],"mappings":";;;;;AAIA,SAAS,SAAS,EAAE,WAAW,GAAG,SAA2C;AAC3E,QACE,oBAAC;EACC,aAAU;EACV,WAAW,GACT,qgBACA,UACD;EACD,GAAI;GACJ"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import * as react_jsx_runtime285 from "react/jsx-runtime";
|
|
1
2
|
import * as React$1 from "react";
|
|
2
|
-
import * as react_jsx_runtime260 from "react/jsx-runtime";
|
|
3
3
|
import * as _base_ui_react0 from "@base-ui/react";
|
|
4
4
|
import { Toast, ToastManagerAddOptions, ToastManagerPromiseOptions, ToastManagerUpdateOptions } from "@base-ui/react/toast";
|
|
5
5
|
|
|
@@ -20,7 +20,7 @@ type ToasterProps = Omit<Toast.Provider.Props, "toastManager" | "children"> & {
|
|
|
20
20
|
declare function Toaster({
|
|
21
21
|
position,
|
|
22
22
|
...props
|
|
23
|
-
}: ToasterProps):
|
|
23
|
+
}: ToasterProps): react_jsx_runtime285.JSX.Element;
|
|
24
24
|
type ToastOptions = Omit<ToastManagerAddOptions<any>, "title" | "type">;
|
|
25
25
|
/**
|
|
26
26
|
* Dispatch a toast from anywhere. Backed by a global Base UI toast manager, so
|
|
@@ -68,7 +68,7 @@ declare const anchoredToast: ((title: React$1.ReactNode, options: AnchoredToastO
|
|
|
68
68
|
* Host for anchored toasts. Mount it once near the app root; dispatch with the
|
|
69
69
|
* exported `anchoredToast` helper.
|
|
70
70
|
*/
|
|
71
|
-
declare function AnchoredToaster(props: Omit<Toast.Provider.Props, "toastManager" | "children">):
|
|
71
|
+
declare function AnchoredToaster(props: Omit<Toast.Provider.Props, "toastManager" | "children">): react_jsx_runtime285.JSX.Element;
|
|
72
72
|
//#endregion
|
|
73
73
|
export { ToasterPosition as a, anchoredToastManager as c, Toaster as i, toast as l, AnchoredToaster as n, ToasterProps as o, ToastOptions as r, anchoredToast as s, AnchoredToastOptions as t, toastManager as u };
|
|
74
|
-
//# sourceMappingURL=toast-
|
|
74
|
+
//# sourceMappingURL=toast-BBU6Q5ZU.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast-
|
|
1
|
+
{"version":3,"file":"toast-BBU6Q5ZU.d.ts","names":[],"sources":["../src/components/toast.tsx"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as cn } from "./utils-
|
|
2
|
-
import "react";
|
|
1
|
+
import { t as cn } from "./utils-mWJR2N24.js";
|
|
3
2
|
import { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon, XIcon } from "lucide-react";
|
|
4
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import "react";
|
|
5
5
|
import { Toast } from "@base-ui/react/toast";
|
|
6
6
|
|
|
7
7
|
//#region src/components/toast.tsx
|
|
@@ -208,4 +208,4 @@ function AnchoredToastList() {
|
|
|
208
208
|
|
|
209
209
|
//#endregion
|
|
210
210
|
export { toast as a, anchoredToastManager as i, Toaster as n, toastManager as o, anchoredToast as r, AnchoredToaster as t };
|
|
211
|
-
//# sourceMappingURL=toast-
|
|
211
|
+
//# sourceMappingURL=toast-COWAQbIk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast-BIAksZXy.js","names":["VIEWPORT_POSITION: Record<ToasterPosition, string>","toast"],"sources":["../src/components/toast.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Toast } from \"@base-ui/react/toast\"\nimport type {\n ToastManagerAddOptions,\n ToastManagerPromiseOptions,\n ToastManagerUpdateOptions,\n} from \"@base-ui/react/toast\"\nimport {\n CircleCheckIcon,\n InfoIcon,\n Loader2Icon,\n OctagonXIcon,\n TriangleAlertIcon,\n XIcon,\n} from \"lucide-react\"\n\nimport { cn } from \"@px-ui/ui/lib/utils\"\n\n// A global manager so toasts can be dispatched from anywhere — including outside\n// the React tree — while still rendering inside the mounted `<Toaster />`.\nconst toastManager = Toast.createToastManager()\n\ntype ToasterPosition =\n | \"top-left\"\n | \"top-center\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\"\n\nconst VIEWPORT_POSITION: Record<ToasterPosition, string> = {\n \"top-left\": \"top-4 left-4 ppx-sm:top-8 ppx-sm:left-8\",\n \"top-center\": \"top-4 left-1/2 -translate-x-1/2 rtl:translate-x-1/2 ppx-sm:top-8\",\n \"top-right\": \"top-4 right-4 ppx-sm:top-8 ppx-sm:right-8\",\n \"bottom-left\": \"bottom-4 left-4 ppx-sm:bottom-8 ppx-sm:left-8\",\n \"bottom-center\":\n \"bottom-4 left-1/2 -translate-x-1/2 rtl:translate-x-1/2 ppx-sm:bottom-8\",\n \"bottom-right\": \"bottom-4 right-4 ppx-sm:bottom-8 ppx-sm:right-8\",\n}\n\ntype ToasterProps = Omit<Toast.Provider.Props, \"toastManager\" | \"children\"> & {\n /**\n * Where toasts are anchored on the screen.\n * @default \"bottom-right\"\n */\n position?: ToasterPosition\n}\n\n/**\n * Host component for toasts. Mount it once near the root of your app. Toasts are\n * dispatched with the exported `toast` helper.\n */\nfunction Toaster({ position = \"bottom-right\", ...props }: ToasterProps) {\n return (\n <Toast.Provider toastManager={toastManager} {...props}>\n <Toast.Portal>\n <Toast.Viewport\n data-slot=\"toaster\"\n className={cn(\n \"fixed z-[100] mx-auto flex w-[calc(100vw-2rem)] outline-none ppx-sm:w-90\",\n VIEWPORT_POSITION[position]\n )}\n >\n <ToastList position={position} />\n </Toast.Viewport>\n </Toast.Portal>\n </Toast.Provider>\n )\n}\n\nfunction ToastList({ position }: { position: ToasterPosition }) {\n const { toasts } = Toast.useToastManager()\n const side = position.startsWith(\"top\") ? \"top\" : \"bottom\"\n const swipeDirection = [\n side === \"top\" ? \"up\" : \"down\",\n position.includes(\"left\")\n ? \"left\"\n : position.includes(\"right\")\n ? \"right\"\n : null,\n ].filter(Boolean) as (\"up\" | \"down\" | \"left\" | \"right\")[]\n\n return toasts.map((toast) => (\n <Toast.Root\n key={toast.id}\n toast={toast}\n data-side={side}\n swipeDirection={swipeDirection}\n className={cn(\n // Stacking + swipe driver variables exposed by Base UI.\n \"[--gap:0.75rem] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))] [--height:var(--toast-frontmost-height,var(--toast-height))] [--dir:1] data-[side=top]:[--dir:-1]\",\n \"[--offset-y:calc(var(--toast-swipe-movement-y)+var(--dir)*(var(--toast-offset-y)*-1-var(--toast-index)*var(--gap)))]\",\n // Layout + appearance.\n \"absolute right-0 left-auto z-[calc(1000-var(--toast-index))] mr-0 w-full origin-bottom rounded-lg border bg-popover text-popover-foreground shadow-lg ring-1 ring-foreground/10 select-none\",\n toastTint(toast.type),\n \"bottom-0 data-[side=top]:top-0 data-[side=top]:bottom-auto data-[side=top]:origin-top\",\n \"h-[var(--height)] data-expanded:h-[var(--toast-height)]\",\n // Hover bridge so the stack stays expanded between toasts.\n \"after:absolute after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-[''] after:top-full data-[side=top]:after:top-auto data-[side=top]:after:bottom-full\",\n // Collapsed (stacked) transform.\n \"[transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)+var(--dir)*(var(--toast-index)*var(--peek)*-1-var(--shrink)*var(--height))))_scale(var(--scale))]\",\n // Expanded transform.\n \"data-expanded:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]\",\n // Enter / exit.\n \"data-starting-style:[transform:translateY(calc(var(--dir)*150%))]\",\n \"data-ending-style:opacity-0 data-limited:opacity-0\",\n \"[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(calc(var(--dir)*150%))]\",\n // Swipe-to-dismiss exits.\n \"data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))] data-expanded:data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]\",\n \"data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))] data-expanded:data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n \"data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))] data-expanded:data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]\",\n \"data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))] data-expanded:data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]\",\n \"[transition:transform_0.5s_cubic-bezier(0.22,1,0.36,1),opacity_0.5s,height_0.15s]\"\n )}\n >\n {/*\n Each control (icon, action, close) is wrapped in an `h-[1lh]` box so it\n centers on the *first* line of text. With `items-start`, that means a\n single-line toast centers in the card (equal padding) while a wrapped /\n multi-line toast keeps the icon and close aligned to the title's first\n line instead of floating in the vertical middle. `text-sm leading-tight`\n sets the line-height that `1lh` resolves against, matching the title.\n */}\n <Toast.Content className=\"flex h-full items-start gap-3 overflow-hidden p-4 text-sm leading-tight transition-opacity duration-[250ms] ease-[cubic-bezier(0.22,1,0.36,1)] data-behind:opacity-0 data-expanded:opacity-100\">\n <ToastIcon type={toast.type} />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n {toast.title ? (\n <Toast.Title className=\"text-sm leading-tight font-medium\" />\n ) : null}\n {toast.description ? (\n <Toast.Description className=\"text-sm text-muted-foreground\" />\n ) : null}\n </div>\n {toast.actionProps ? (\n <div className=\"flex h-[1lh] shrink-0 items-center\">\n <Toast.Action className=\"inline-flex h-8 shrink-0 items-center justify-center gap-1.5 rounded-md border bg-transparent px-3 text-xs font-medium whitespace-nowrap transition-colors hover:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50\" />\n </div>\n ) : null}\n <div className=\"-me-1 flex h-[1lh] shrink-0 items-center\">\n <Toast.Close\n aria-label=\"Dismiss\"\n className=\"inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none\"\n >\n <XIcon className=\"size-4\" />\n </Toast.Close>\n </div>\n </Toast.Content>\n </Toast.Root>\n ))\n}\n\nconst TOAST_ICONS = {\n success: { Icon: CircleCheckIcon, color: \"text-success\" },\n info: { Icon: InfoIcon, color: \"text-info\" },\n warning: { Icon: TriangleAlertIcon, color: \"text-warning\" },\n error: { Icon: OctagonXIcon, color: \"text-destructive\" },\n loading: { Icon: Loader2Icon, color: \"text-muted-foreground\" },\n} as const\n\nfunction ToastIcon({ type }: { type?: string }) {\n const entry = type\n ? TOAST_ICONS[type as keyof typeof TOAST_ICONS]\n : undefined\n if (!entry) return null\n const { Icon, color } = entry\n // `h-[1lh]` sizes the icon box to one line of text, so the icon centers on the\n // first line whether the toast is a single line or wraps to several.\n return (\n <span\n className={cn(\"flex h-[1lh] shrink-0 items-center justify-center\", color)}\n >\n <Icon className={cn(\"size-4\", type === \"loading\" && \"animate-spin\")} />\n </span>\n )\n}\n\n// Per-type tinted card — a 10% mix of the status color into the popover surface,\n// reproducing px-ui's classic soft-tinted toast look. Shared by both toasters.\nfunction toastTint(type?: string) {\n switch (type) {\n case \"success\":\n return \"bg-[color-mix(in_srgb,var(--success)_10%,var(--popover))]\"\n case \"info\":\n return \"bg-[color-mix(in_srgb,var(--info)_10%,var(--popover))]\"\n case \"warning\":\n return \"bg-[color-mix(in_srgb,var(--warning)_10%,var(--popover))]\"\n case \"error\":\n return \"bg-[color-mix(in_srgb,var(--destructive)_10%,var(--popover))]\"\n default:\n return undefined\n }\n}\n\ntype ToastOptions = Omit<ToastManagerAddOptions<any>, \"title\" | \"type\">\n\nfunction makeToast(type?: string) {\n return (title: React.ReactNode, options?: ToastOptions) =>\n toastManager.add({ title, ...(type ? { type } : {}), ...options })\n}\n\n/**\n * Dispatch a toast from anywhere. Backed by a global Base UI toast manager, so\n * it works even outside the React tree.\n *\n * @example\n * toast(\"Event has been created\")\n * toast.success(\"Saved\", { description: \"Your changes are live.\" })\n */\nconst toast = Object.assign(makeToast(), {\n success: makeToast(\"success\"),\n info: makeToast(\"info\"),\n warning: makeToast(\"warning\"),\n error: makeToast(\"error\"),\n message: makeToast(),\n loading: (title: React.ReactNode, options?: ToastOptions) =>\n toastManager.add({ title, type: \"loading\", timeout: 0, ...options }),\n promise: <Value,>(\n promise: Promise<Value> | (() => Promise<Value>),\n options: ToastManagerPromiseOptions<Value, any>\n ) =>\n toastManager.promise(\n typeof promise === \"function\" ? promise() : promise,\n options\n ),\n update: (id: string, options: ToastManagerUpdateOptions<any>) =>\n toastManager.update(id, options),\n dismiss: (id?: string) => toastManager.close(id),\n})\n\n// A separate manager + host for anchored toasts: small popovers positioned next\n// to a trigger element (e.g. a \"Copied\" confirmation beside a button) rather\n// than stacked in a screen corner.\nconst anchoredToastManager = Toast.createToastManager()\n\ntype AnchoredToastOptions = ToastOptions & {\n /** Element to position the toast against, e.g. `event.currentTarget`. */\n anchor: Element | null\n}\n\nfunction makeAnchoredToast(type?: string) {\n return (title: React.ReactNode, options: AnchoredToastOptions) => {\n const { anchor, ...rest } = options\n // The anchor element rides along in `data`; `AnchoredToaster` reads it back\n // out and hands it to `Toast.Positioner`.\n return anchoredToastManager.add({\n title,\n ...(type ? { type } : {}),\n ...rest,\n data: { ...rest.data, anchor },\n })\n }\n}\n\n/**\n * Dispatch a toast anchored to an element instead of a screen corner. Render\n * `<AnchoredToaster />` once, then pass the trigger element as `anchor`.\n *\n * @example\n * <Button\n * onClick={(e) => anchoredToast.success(\"Copied\", { anchor: e.currentTarget })}\n * >\n * Copy\n * </Button>\n */\nconst anchoredToast = Object.assign(makeAnchoredToast(), {\n success: makeAnchoredToast(\"success\"),\n info: makeAnchoredToast(\"info\"),\n warning: makeAnchoredToast(\"warning\"),\n error: makeAnchoredToast(\"error\"),\n dismiss: (id?: string) => anchoredToastManager.close(id),\n})\n\n/**\n * Host for anchored toasts. Mount it once near the app root; dispatch with the\n * exported `anchoredToast` helper.\n */\nfunction AnchoredToaster(\n props: Omit<Toast.Provider.Props, \"toastManager\" | \"children\">\n) {\n return (\n <Toast.Provider toastManager={anchoredToastManager} {...props}>\n <Toast.Portal>\n <Toast.Viewport data-slot=\"anchored-toaster\" className=\"outline-none\">\n <AnchoredToastList />\n </Toast.Viewport>\n </Toast.Portal>\n </Toast.Provider>\n )\n}\n\nfunction AnchoredToastList() {\n const { toasts } = Toast.useToastManager()\n\n return toasts.map((toast) => {\n const anchor = (toast.data as { anchor?: Element | null } | undefined)\n ?.anchor\n if (!anchor) return null\n\n return (\n <Toast.Positioner\n key={toast.id}\n toast={toast}\n anchor={anchor}\n sideOffset={6}\n className=\"z-[100] max-w-[min(20rem,var(--available-width))]\"\n >\n <Toast.Root\n toast={toast}\n className={cn(\n \"rounded-lg border bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10\",\n \"scale-100 transition-[transform,opacity] data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0\",\n toastTint(toast.type)\n )}\n >\n <Toast.Content className=\"flex items-start gap-2.5 px-3 py-2 text-sm leading-tight\">\n <ToastIcon type={toast.type} />\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <Toast.Title className=\"text-sm leading-tight font-medium\" />\n {toast.description ? (\n <Toast.Description className=\"text-sm text-muted-foreground\" />\n ) : null}\n </div>\n </Toast.Content>\n </Toast.Root>\n </Toast.Positioner>\n )\n })\n}\n\nexport {\n Toaster,\n toast,\n toastManager,\n AnchoredToaster,\n anchoredToast,\n anchoredToastManager,\n}\nexport type {\n ToasterProps,\n ToasterPosition,\n ToastOptions,\n AnchoredToastOptions,\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toast-COWAQbIk.js","names":["VIEWPORT_POSITION: Record<ToasterPosition, string>","toast"],"sources":["../src/components/toast.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Toast } from \"@base-ui/react/toast\"\nimport type {\n ToastManagerAddOptions,\n ToastManagerPromiseOptions,\n ToastManagerUpdateOptions,\n} from \"@base-ui/react/toast\"\nimport {\n CircleCheckIcon,\n InfoIcon,\n Loader2Icon,\n OctagonXIcon,\n TriangleAlertIcon,\n XIcon,\n} from \"lucide-react\"\n\nimport { cn } from \"@px-ui/ui/lib/utils\"\n\n// A global manager so toasts can be dispatched from anywhere — including outside\n// the React tree — while still rendering inside the mounted `<Toaster />`.\nconst toastManager = Toast.createToastManager()\n\ntype ToasterPosition =\n | \"top-left\"\n | \"top-center\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\"\n\nconst VIEWPORT_POSITION: Record<ToasterPosition, string> = {\n \"top-left\": \"top-4 left-4 ppx-sm:top-8 ppx-sm:left-8\",\n \"top-center\": \"top-4 left-1/2 -translate-x-1/2 rtl:translate-x-1/2 ppx-sm:top-8\",\n \"top-right\": \"top-4 right-4 ppx-sm:top-8 ppx-sm:right-8\",\n \"bottom-left\": \"bottom-4 left-4 ppx-sm:bottom-8 ppx-sm:left-8\",\n \"bottom-center\":\n \"bottom-4 left-1/2 -translate-x-1/2 rtl:translate-x-1/2 ppx-sm:bottom-8\",\n \"bottom-right\": \"bottom-4 right-4 ppx-sm:bottom-8 ppx-sm:right-8\",\n}\n\ntype ToasterProps = Omit<Toast.Provider.Props, \"toastManager\" | \"children\"> & {\n /**\n * Where toasts are anchored on the screen.\n * @default \"bottom-right\"\n */\n position?: ToasterPosition\n}\n\n/**\n * Host component for toasts. Mount it once near the root of your app. Toasts are\n * dispatched with the exported `toast` helper.\n */\nfunction Toaster({ position = \"bottom-right\", ...props }: ToasterProps) {\n return (\n <Toast.Provider toastManager={toastManager} {...props}>\n <Toast.Portal>\n <Toast.Viewport\n data-slot=\"toaster\"\n className={cn(\n \"fixed z-[100] mx-auto flex w-[calc(100vw-2rem)] outline-none ppx-sm:w-90\",\n VIEWPORT_POSITION[position]\n )}\n >\n <ToastList position={position} />\n </Toast.Viewport>\n </Toast.Portal>\n </Toast.Provider>\n )\n}\n\nfunction ToastList({ position }: { position: ToasterPosition }) {\n const { toasts } = Toast.useToastManager()\n const side = position.startsWith(\"top\") ? \"top\" : \"bottom\"\n const swipeDirection = [\n side === \"top\" ? \"up\" : \"down\",\n position.includes(\"left\")\n ? \"left\"\n : position.includes(\"right\")\n ? \"right\"\n : null,\n ].filter(Boolean) as (\"up\" | \"down\" | \"left\" | \"right\")[]\n\n return toasts.map((toast) => (\n <Toast.Root\n key={toast.id}\n toast={toast}\n data-side={side}\n swipeDirection={swipeDirection}\n className={cn(\n // Stacking + swipe driver variables exposed by Base UI.\n \"[--gap:0.75rem] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))] [--height:var(--toast-frontmost-height,var(--toast-height))] [--dir:1] data-[side=top]:[--dir:-1]\",\n \"[--offset-y:calc(var(--toast-swipe-movement-y)+var(--dir)*(var(--toast-offset-y)*-1-var(--toast-index)*var(--gap)))]\",\n // Layout + appearance.\n \"absolute right-0 left-auto z-[calc(1000-var(--toast-index))] mr-0 w-full origin-bottom rounded-lg border bg-popover text-popover-foreground shadow-lg ring-1 ring-foreground/10 select-none\",\n toastTint(toast.type),\n \"bottom-0 data-[side=top]:top-0 data-[side=top]:bottom-auto data-[side=top]:origin-top\",\n \"h-[var(--height)] data-expanded:h-[var(--toast-height)]\",\n // Hover bridge so the stack stays expanded between toasts.\n \"after:absolute after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-[''] after:top-full data-[side=top]:after:top-auto data-[side=top]:after:bottom-full\",\n // Collapsed (stacked) transform.\n \"[transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)+var(--dir)*(var(--toast-index)*var(--peek)*-1-var(--shrink)*var(--height))))_scale(var(--scale))]\",\n // Expanded transform.\n \"data-expanded:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]\",\n // Enter / exit.\n \"data-starting-style:[transform:translateY(calc(var(--dir)*150%))]\",\n \"data-ending-style:opacity-0 data-limited:opacity-0\",\n \"[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(calc(var(--dir)*150%))]\",\n // Swipe-to-dismiss exits.\n \"data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))] data-expanded:data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]\",\n \"data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))] data-expanded:data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n \"data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))] data-expanded:data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]\",\n \"data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))] data-expanded:data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]\",\n \"[transition:transform_0.5s_cubic-bezier(0.22,1,0.36,1),opacity_0.5s,height_0.15s]\"\n )}\n >\n {/*\n Each control (icon, action, close) is wrapped in an `h-[1lh]` box so it\n centers on the *first* line of text. With `items-start`, that means a\n single-line toast centers in the card (equal padding) while a wrapped /\n multi-line toast keeps the icon and close aligned to the title's first\n line instead of floating in the vertical middle. `text-sm leading-tight`\n sets the line-height that `1lh` resolves against, matching the title.\n */}\n <Toast.Content className=\"flex h-full items-start gap-3 overflow-hidden p-4 text-sm leading-tight transition-opacity duration-[250ms] ease-[cubic-bezier(0.22,1,0.36,1)] data-behind:opacity-0 data-expanded:opacity-100\">\n <ToastIcon type={toast.type} />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n {toast.title ? (\n <Toast.Title className=\"text-sm leading-tight font-medium\" />\n ) : null}\n {toast.description ? (\n <Toast.Description className=\"text-sm text-muted-foreground\" />\n ) : null}\n </div>\n {toast.actionProps ? (\n <div className=\"flex h-[1lh] shrink-0 items-center\">\n <Toast.Action className=\"inline-flex h-8 shrink-0 items-center justify-center gap-1.5 rounded-md border bg-transparent px-3 text-xs font-medium whitespace-nowrap transition-colors hover:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50\" />\n </div>\n ) : null}\n <div className=\"-me-1 flex h-[1lh] shrink-0 items-center\">\n <Toast.Close\n aria-label=\"Dismiss\"\n className=\"inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none\"\n >\n <XIcon className=\"size-4\" />\n </Toast.Close>\n </div>\n </Toast.Content>\n </Toast.Root>\n ))\n}\n\nconst TOAST_ICONS = {\n success: { Icon: CircleCheckIcon, color: \"text-success\" },\n info: { Icon: InfoIcon, color: \"text-info\" },\n warning: { Icon: TriangleAlertIcon, color: \"text-warning\" },\n error: { Icon: OctagonXIcon, color: \"text-destructive\" },\n loading: { Icon: Loader2Icon, color: \"text-muted-foreground\" },\n} as const\n\nfunction ToastIcon({ type }: { type?: string }) {\n const entry = type\n ? TOAST_ICONS[type as keyof typeof TOAST_ICONS]\n : undefined\n if (!entry) return null\n const { Icon, color } = entry\n // `h-[1lh]` sizes the icon box to one line of text, so the icon centers on the\n // first line whether the toast is a single line or wraps to several.\n return (\n <span\n className={cn(\"flex h-[1lh] shrink-0 items-center justify-center\", color)}\n >\n <Icon className={cn(\"size-4\", type === \"loading\" && \"animate-spin\")} />\n </span>\n )\n}\n\n// Per-type tinted card — a 10% mix of the status color into the popover surface,\n// reproducing px-ui's classic soft-tinted toast look. Shared by both toasters.\nfunction toastTint(type?: string) {\n switch (type) {\n case \"success\":\n return \"bg-[color-mix(in_srgb,var(--success)_10%,var(--popover))]\"\n case \"info\":\n return \"bg-[color-mix(in_srgb,var(--info)_10%,var(--popover))]\"\n case \"warning\":\n return \"bg-[color-mix(in_srgb,var(--warning)_10%,var(--popover))]\"\n case \"error\":\n return \"bg-[color-mix(in_srgb,var(--destructive)_10%,var(--popover))]\"\n default:\n return undefined\n }\n}\n\ntype ToastOptions = Omit<ToastManagerAddOptions<any>, \"title\" | \"type\">\n\nfunction makeToast(type?: string) {\n return (title: React.ReactNode, options?: ToastOptions) =>\n toastManager.add({ title, ...(type ? { type } : {}), ...options })\n}\n\n/**\n * Dispatch a toast from anywhere. Backed by a global Base UI toast manager, so\n * it works even outside the React tree.\n *\n * @example\n * toast(\"Event has been created\")\n * toast.success(\"Saved\", { description: \"Your changes are live.\" })\n */\nconst toast = Object.assign(makeToast(), {\n success: makeToast(\"success\"),\n info: makeToast(\"info\"),\n warning: makeToast(\"warning\"),\n error: makeToast(\"error\"),\n message: makeToast(),\n loading: (title: React.ReactNode, options?: ToastOptions) =>\n toastManager.add({ title, type: \"loading\", timeout: 0, ...options }),\n promise: <Value,>(\n promise: Promise<Value> | (() => Promise<Value>),\n options: ToastManagerPromiseOptions<Value, any>\n ) =>\n toastManager.promise(\n typeof promise === \"function\" ? promise() : promise,\n options\n ),\n update: (id: string, options: ToastManagerUpdateOptions<any>) =>\n toastManager.update(id, options),\n dismiss: (id?: string) => toastManager.close(id),\n})\n\n// A separate manager + host for anchored toasts: small popovers positioned next\n// to a trigger element (e.g. a \"Copied\" confirmation beside a button) rather\n// than stacked in a screen corner.\nconst anchoredToastManager = Toast.createToastManager()\n\ntype AnchoredToastOptions = ToastOptions & {\n /** Element to position the toast against, e.g. `event.currentTarget`. */\n anchor: Element | null\n}\n\nfunction makeAnchoredToast(type?: string) {\n return (title: React.ReactNode, options: AnchoredToastOptions) => {\n const { anchor, ...rest } = options\n // The anchor element rides along in `data`; `AnchoredToaster` reads it back\n // out and hands it to `Toast.Positioner`.\n return anchoredToastManager.add({\n title,\n ...(type ? { type } : {}),\n ...rest,\n data: { ...rest.data, anchor },\n })\n }\n}\n\n/**\n * Dispatch a toast anchored to an element instead of a screen corner. Render\n * `<AnchoredToaster />` once, then pass the trigger element as `anchor`.\n *\n * @example\n * <Button\n * onClick={(e) => anchoredToast.success(\"Copied\", { anchor: e.currentTarget })}\n * >\n * Copy\n * </Button>\n */\nconst anchoredToast = Object.assign(makeAnchoredToast(), {\n success: makeAnchoredToast(\"success\"),\n info: makeAnchoredToast(\"info\"),\n warning: makeAnchoredToast(\"warning\"),\n error: makeAnchoredToast(\"error\"),\n dismiss: (id?: string) => anchoredToastManager.close(id),\n})\n\n/**\n * Host for anchored toasts. Mount it once near the app root; dispatch with the\n * exported `anchoredToast` helper.\n */\nfunction AnchoredToaster(\n props: Omit<Toast.Provider.Props, \"toastManager\" | \"children\">\n) {\n return (\n <Toast.Provider toastManager={anchoredToastManager} {...props}>\n <Toast.Portal>\n <Toast.Viewport data-slot=\"anchored-toaster\" className=\"outline-none\">\n <AnchoredToastList />\n </Toast.Viewport>\n </Toast.Portal>\n </Toast.Provider>\n )\n}\n\nfunction AnchoredToastList() {\n const { toasts } = Toast.useToastManager()\n\n return toasts.map((toast) => {\n const anchor = (toast.data as { anchor?: Element | null } | undefined)\n ?.anchor\n if (!anchor) return null\n\n return (\n <Toast.Positioner\n key={toast.id}\n toast={toast}\n anchor={anchor}\n sideOffset={6}\n className=\"z-[100] max-w-[min(20rem,var(--available-width))]\"\n >\n <Toast.Root\n toast={toast}\n className={cn(\n \"rounded-lg border bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10\",\n \"scale-100 transition-[transform,opacity] data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0\",\n toastTint(toast.type)\n )}\n >\n <Toast.Content className=\"flex items-start gap-2.5 px-3 py-2 text-sm leading-tight\">\n <ToastIcon type={toast.type} />\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <Toast.Title className=\"text-sm leading-tight font-medium\" />\n {toast.description ? (\n <Toast.Description className=\"text-sm text-muted-foreground\" />\n ) : null}\n </div>\n </Toast.Content>\n </Toast.Root>\n </Toast.Positioner>\n )\n })\n}\n\nexport {\n Toaster,\n toast,\n toastManager,\n AnchoredToaster,\n anchoredToast,\n anchoredToastManager,\n}\nexport type {\n ToasterProps,\n ToasterPosition,\n ToastOptions,\n AnchoredToastOptions,\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime254 from "react/jsx-runtime";
|
|
2
2
|
import { VariantProps } from "class-variance-authority";
|
|
3
3
|
import { Toggle } from "@base-ui/react/toggle";
|
|
4
4
|
import * as class_variance_authority_types11 from "class-variance-authority/types";
|
|
@@ -13,7 +13,7 @@ declare function Toggle$1({
|
|
|
13
13
|
variant,
|
|
14
14
|
size,
|
|
15
15
|
...props
|
|
16
|
-
}: Toggle.Props & VariantProps<typeof toggleVariants>):
|
|
16
|
+
}: Toggle.Props & VariantProps<typeof toggleVariants>): react_jsx_runtime254.JSX.Element;
|
|
17
17
|
//#endregion
|
|
18
18
|
export { toggleVariants as n, Toggle$1 as t };
|
|
19
|
-
//# sourceMappingURL=toggle-
|
|
19
|
+
//# sourceMappingURL=toggle-CsHqUVUY.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-
|
|
1
|
+
{"version":3,"file":"toggle-CsHqUVUY.d.ts","names":[],"sources":["../src/components/toggle.tsx"],"sourcesContent":[],"mappings":";;;;;;cAOM;;;IAoBL,gCAAA,CAAA;AAxBiE,iBA0BzD,QAAA,CAFR;EAAA,SAAA;EAAA,OAAA;EAAA,IAAA;EAAA,GAAA;AAAA,CAAA,EAOE,MAAA,CAAgB,KAPlB,GAO0B,YAP1B,CAAA,OAO8C,cAP9C,CAAA,CAAA,EAO6D,oBAAA,CAAA,GAAA,CAAA,OAP7D"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as cn } from "./utils-
|
|
1
|
+
import { t as cn } from "./utils-mWJR2N24.js";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
4
|
import { Toggle } from "@base-ui/react/toggle";
|
|
@@ -35,4 +35,4 @@ function Toggle$1({ className, variant = "default", size = "default", ...props }
|
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
37
|
export { toggleVariants as n, Toggle$1 as t };
|
|
38
|
-
//# sourceMappingURL=toggle-
|
|
38
|
+
//# sourceMappingURL=toggle-DhJ_qwgw.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-
|
|
1
|
+
{"version":3,"file":"toggle-DhJ_qwgw.js","names":["Toggle","TogglePrimitive"],"sources":["../src/components/toggle.tsx"],"sourcesContent":["\"use client\";\n\nimport { Toggle as TogglePrimitive } from \"@base-ui/react/toggle\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@px-ui/ui/lib/utils\";\n\nconst toggleVariants = cva(\n \"group/toggle inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n outline: \"border border-input bg-transparent shadow-xs hover:bg-muted\",\n },\n size: {\n default:\n \"h-9 min-w-9 px-2.5 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2\",\n sm: \"h-8 min-w-8 px-2.5 has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5\",\n lg: \"h-10 min-w-10 px-2.5 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Toggle({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {\n return (\n <TogglePrimitive\n data-slot=\"toggle\"\n className={cn(toggleVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Toggle, toggleVariants };\n"],"mappings":";;;;;;AAOA,MAAM,iBAAiB,IACrB,6gBACA;CACE,UAAU;EACR,SAAS;GACP,SAAS;GACT,SAAS;GACV;EACD,MAAM;GACJ,SACE;GACF,IAAI;GACJ,IAAI;GACL;EACF;CACD,iBAAiB;EACf,SAAS;EACT,MAAM;EACP;CACF,CACF;AAED,SAASA,SAAO,EACd,WACA,UAAU,WACV,OAAO,WACP,GAAG,SAC2D;AAC9D,QACE,oBAACC;EACC,aAAU;EACV,WAAW,GAAG,eAAe;GAAE;GAAS;GAAM;GAAW,CAAC,CAAC;EAC3D,GAAI;GACJ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as cn } from "./utils-
|
|
1
|
+
import { t as cn } from "./utils-mWJR2N24.js";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Tooltip } from "@base-ui/react/tooltip";
|
|
4
4
|
|
|
@@ -40,4 +40,4 @@ function TooltipContent({ className, side = "top", sideOffset = 4, align = "cent
|
|
|
40
40
|
|
|
41
41
|
//#endregion
|
|
42
42
|
export { TooltipTrigger as i, TooltipContent as n, TooltipProvider as r, Tooltip$1 as t };
|
|
43
|
-
//# sourceMappingURL=tooltip-
|
|
43
|
+
//# sourceMappingURL=tooltip-DkPxCJIL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip-
|
|
1
|
+
{"version":3,"file":"tooltip-DkPxCJIL.js","names":["TooltipPrimitive","Tooltip"],"sources":["../src/components/tooltip.tsx"],"sourcesContent":["import { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\"\n\nimport { cn } from \"@px-ui/ui/lib/utils\"\n\nfunction TooltipProvider({\n delay = 0,\n ...props\n}: TooltipPrimitive.Provider.Props) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delay={delay}\n {...props}\n />\n )\n}\n\nfunction Tooltip({ ...props }: TooltipPrimitive.Root.Props) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n}\n\nfunction TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n className,\n side = \"top\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 0,\n children,\n ...props\n}: TooltipPrimitive.Popup.Props &\n Pick<\n TooltipPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-50\"\n >\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n className={cn(\n \"z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-start-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-start-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-end-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5\" />\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"],"mappings":";;;;;AAIA,SAAS,gBAAgB,EACvB,QAAQ,GACR,GAAG,SAC+B;AAClC,QACE,oBAACA,QAAiB;EAChB,aAAU;EACH;EACP,GAAI;GACJ;;AAIN,SAASC,UAAQ,EAAE,GAAG,SAAsC;AAC1D,QAAO,oBAACD,QAAiB;EAAK,aAAU;EAAU,GAAI;GAAS;;AAGjE,SAAS,eAAe,EAAE,GAAG,SAAyC;AACpE,QAAO,oBAACA,QAAiB;EAAQ,aAAU;EAAkB,GAAI;GAAS;;AAG5E,SAAS,eAAe,EACtB,WACA,OAAO,OACP,aAAa,GACb,QAAQ,UACR,cAAc,GACd,UACA,GAAG,SAKA;AACH,QACE,oBAACA,QAAiB,oBAChB,oBAACA,QAAiB;EACT;EACM;EACP;EACM;EACZ,WAAU;YAEV,qBAACA,QAAiB;GAChB,aAAU;GACV,WAAW,GACT,kwBACA,UACD;GACD,GAAI;cAEH,UACD,oBAACA,QAAiB,SAAM,WAAU,4hBAA4hB;IACviB;GACG,GACN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-async-options-
|
|
1
|
+
{"version":3,"file":"use-async-options-wZ9LJ2BJ.js","names":["EMPTY_ITEMS: readonly unknown[]"],"sources":["../src/hooks/use-async-options.ts"],"sourcesContent":["import { useCallback, useMemo, useRef } from \"react\";\nimport { useInfiniteQuery, type QueryKey } from \"@tanstack/react-query\";\n\nconst EMPTY_ITEMS: readonly unknown[] = Object.freeze([]);\n\ntype LoadOptionsData<TData> = {\n options: TData[];\n hasMore: boolean;\n};\n\ntype LoadOptionsReturn<TData> = {\n data: LoadOptionsData<TData>;\n error: any;\n};\n\ntype LoadOptionsFn<TData> = (params: {\n search: string;\n page: number;\n signal: AbortSignal;\n}) => Promise<LoadOptionsReturn<TData>>;\n\nexport function useAsyncOptions<TData = any>(\n params: {\n cacheKey: QueryKey;\n loader: LoadOptionsFn<TData>;\n },\n {\n isOpen,\n inputValue,\n }: {\n isOpen: boolean;\n inputValue: string;\n },\n) {\n const isFetchedAfterMount = useRef(false);\n\n const query = useInfiniteQuery({\n queryKey: [...params.cacheKey, inputValue],\n queryFn: async ({ pageParam, signal }) => {\n const { error, data } = await params.loader({\n search: inputValue,\n page: pageParam,\n signal,\n });\n\n if (error) {\n throw new Error(error);\n }\n\n return data;\n },\n enabled: isOpen,\n initialPageParam: 1,\n staleTime: () => (isFetchedAfterMount.current ? Infinity : 0),\n getNextPageParam: (lastPage, allPages) =>\n lastPage.hasMore ? allPages.length + 1 : undefined,\n retry: false,\n });\n\n if (query.isFetchedAfterMount && !isFetchedAfterMount.current) {\n isFetchedAfterMount.current = true;\n }\n\n const items = useMemo(\n () =>\n (query.data?.pages.flatMap((page) => page.options) ??\n EMPTY_ITEMS) as TData[],\n [query.data?.pages],\n );\n\n const handleLoadMore = useCallback(() => {\n query.fetchNextPage();\n }, [query.fetchNextPage]);\n\n return {\n items,\n isLoading: query.isLoading,\n isLoadingMore: query.isFetchingNextPage,\n hasMore: query.hasNextPage,\n isError: query.isError,\n onLoadMore: handleLoadMore,\n _query: query,\n };\n}\n\nexport type LoadOptionsConfig<TData> = {\n cacheKey: QueryKey;\n loader: LoadOptionsFn<TData>;\n};\n\nexport function defineLoadOptions<TData = any>(\n loadOptions: LoadOptionsConfig<TData>,\n) {\n return loadOptions;\n}\n\nexport type InferOption<T> =\n T extends LoadOptionsConfig<infer TData> ? TData : never;\nexport type InferOptions<T> =\n T extends LoadOptionsConfig<infer TData> ? TData[] : never;\n"],"mappings":";;;;AAGA,MAAMA,cAAkC,OAAO,OAAO,EAAE,CAAC;AAkBzD,SAAgB,gBACd,QAIA,EACE,QACA,cAKF;CACA,MAAM,sBAAsB,OAAO,MAAM;CAEzC,MAAM,QAAQ,iBAAiB;EAC7B,UAAU,CAAC,GAAG,OAAO,UAAU,WAAW;EAC1C,SAAS,OAAO,EAAE,WAAW,aAAa;GACxC,MAAM,EAAE,OAAO,SAAS,MAAM,OAAO,OAAO;IAC1C,QAAQ;IACR,MAAM;IACN;IACD,CAAC;AAEF,OAAI,MACF,OAAM,IAAI,MAAM,MAAM;AAGxB,UAAO;;EAET,SAAS;EACT,kBAAkB;EAClB,iBAAkB,oBAAoB,UAAU,WAAW;EAC3D,mBAAmB,UAAU,aAC3B,SAAS,UAAU,SAAS,SAAS,IAAI;EAC3C,OAAO;EACR,CAAC;AAEF,KAAI,MAAM,uBAAuB,CAAC,oBAAoB,QACpD,qBAAoB,UAAU;CAGhC,MAAM,QAAQ,cAET,MAAM,MAAM,MAAM,SAAS,SAAS,KAAK,QAAQ,IAChD,aACJ,CAAC,MAAM,MAAM,MAAM,CACpB;CAED,MAAM,iBAAiB,kBAAkB;AACvC,QAAM,eAAe;IACpB,CAAC,MAAM,cAAc,CAAC;AAEzB,QAAO;EACL;EACA,WAAW,MAAM;EACjB,eAAe,MAAM;EACrB,SAAS,MAAM;EACf,SAAS,MAAM;EACf,YAAY;EACZ,QAAQ;EACT;;AAQH,SAAgB,kBACd,aACA;AACA,QAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-debounce-
|
|
1
|
+
{"version":3,"file":"use-debounce-_qaEZqtt.js","names":[],"sources":["../src/hooks/use-debounce.ts"],"sourcesContent":["import { useEffect, useEffectEvent, useRef } from \"react\";\n\nexport default function useDebounce<T>(\n callback: () => void,\n delay: number,\n deps: React.DependencyList,\n) {\n const timeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n const cb = useEffectEvent(callback);\n\n useEffect(() => {\n if (timeout.current) {\n clearTimeout(timeout.current);\n }\n\n timeout.current = setTimeout(() => {\n cb();\n timeout.current = null;\n }, delay);\n\n return () => {\n if (timeout.current) {\n clearTimeout(timeout.current);\n timeout.current = null;\n }\n };\n }, [...deps, delay]);\n}\n"],"mappings":";;;AAEA,SAAwB,YACtB,UACA,OACA,MACA;CACA,MAAM,UAAU,OAA6C,KAAK;CAClE,MAAM,KAAK,eAAe,SAAS;AAEnC,iBAAgB;AACd,MAAI,QAAQ,QACV,cAAa,QAAQ,QAAQ;AAG/B,UAAQ,UAAU,iBAAiB;AACjC,OAAI;AACJ,WAAQ,UAAU;KACjB,MAAM;AAET,eAAa;AACX,OAAI,QAAQ,SAAS;AACnB,iBAAa,QAAQ,QAAQ;AAC7B,YAAQ,UAAU;;;IAGrB,CAAC,GAAG,MAAM,MAAM,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-file-upload-CiAqUFFh.js","names":["uploadedFile: FileUploadItem","failedFile: FileUploadItem","results: FileUploadItem[]","newErrors: string[]","validFiles: FileUploadItem[]","initializedFiles: FileUploadItem[]"],"sources":["../src/hooks/use-file-upload.ts"],"sourcesContent":["import {\n type ChangeEvent,\n type DragEvent,\n type InputHTMLAttributes,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type FileMetadata = {\n name: string;\n size: number;\n type: string;\n url: string;\n id: string;\n};\n\nexport type UploadStatus = \"idle\" | \"uploading\" | \"complete\" | \"error\";\n\nexport type FileUploadItem = {\n file: File | FileMetadata;\n id: string;\n preview?: string;\n progress: number;\n status: UploadStatus;\n error?: string;\n uploadedUrl?: string;\n};\n\nexport type PresignedUrlResponse = {\n /** The S3 bucket URL to POST to */\n url: string;\n /** The full accessible path after upload (may include signed query params) */\n full_path: string;\n /** The S3 object key (e.g., \"uuid/filename.pdf\") */\n key?: string;\n /** Access control level */\n acl?: string;\n /** Expected response status from S3 */\n success_action_status?: string;\n /** Content-Type for the upload */\n \"Content-Type\"?: string;\n /** Base64-encoded policy document */\n policy?: string;\n /** AWS credential string */\n \"x-amz-credential\"?: string;\n /** AWS signing algorithm */\n \"x-amz-algorithm\"?: string;\n /** AWS request date */\n \"x-amz-date\"?: string;\n /** AWS request signature */\n \"x-amz-signature\"?: string;\n /** Additional fields */\n [key: string]: unknown;\n};\n\nexport type UploadConfig = {\n /**\n * Function to get a presigned URL for uploading\n */\n getPresignedUrl: (params: {\n filename: string;\n contentType: string;\n size: number;\n signal?: AbortSignal;\n }) => Promise<{\n result?: PresignedUrlResponse | null;\n error?: unknown;\n }>;\n\n /**\n * Function to upload the file to the storage\n */\n uploadFile: (\n url: string,\n file: File,\n presignedData: PresignedUrlResponse,\n onProgress?: (progress: number) => void,\n signal?: AbortSignal,\n ) => Promise<{\n result?: { url: string; [key: string]: unknown };\n error?: unknown;\n }>;\n\n /**\n * Whether to auto-upload files when they are added\n * @default true\n */\n autoUpload?: boolean;\n\n /**\n * Called when a single file upload completes\n */\n onUploadComplete?: (file: FileUploadItem) => void;\n\n /**\n * Called when a single file upload fails\n */\n onUploadError?: (file: FileUploadItem, error: unknown) => void;\n\n /**\n * Called when all files finish uploading\n */\n onAllUploadsComplete?: (files: FileUploadItem[]) => void;\n};\n\nexport type UseFileUploadOptions = {\n maxFiles?: number;\n maxSize?: number;\n minSize?: number;\n accept?: string;\n multiple?: boolean;\n initialFiles?: FileMetadata[];\n onFilesChange?: (files: FileUploadItem[]) => void;\n onFileAdd?: (addedFile: FileUploadItem) => void;\n onFileRemove?: (removedFile: FileUploadItem) => void;\n upload?: UploadConfig;\n};\n\nexport type UseFileUploadReturn = {\n // State\n files: FileUploadItem[];\n isDragging: boolean;\n isUploading: boolean;\n errors: string[];\n\n // Core Actions\n addFiles: (files: FileList | File[]) => void;\n removeFile: (id: string) => void;\n clearFiles: () => void;\n clearErrors: () => void;\n\n // Form integration\n reset: (newFiles?: FileMetadata[]) => void;\n setFiles: (\n files: FileUploadItem[] | ((prev: FileUploadItem[]) => FileUploadItem[]),\n ) => void;\n instanceKey: number;\n\n // Upload Actions\n uploadFiles: (files?: FileUploadItem[]) => Promise<FileUploadItem[]>;\n retryUpload: (id: string) => Promise<void>;\n cancelUpload: (id: string) => void;\n\n // Drag/Drop + Input\n handleDragEnter: (e: DragEvent<HTMLElement>) => void;\n handleDragLeave: (e: DragEvent<HTMLElement>) => void;\n handleDragOver: (e: DragEvent<HTMLElement>) => void;\n handleDrop: (e: DragEvent<HTMLElement>) => void;\n handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void;\n openFileDialog: () => void;\n getInputProps: (\n props?: InputHTMLAttributes<HTMLInputElement>,\n ) => InputHTMLAttributes<HTMLInputElement> & {\n // biome-ignore lint/suspicious/noExplicitAny: intentional for cross-React ref compatibility\n ref: any;\n };\n};\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n if (bytes === 0) return \"0 Bytes\";\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return Number.parseFloat((bytes / k ** i).toFixed(dm)) + sizes[i];\n};\n\n/**\n * Extract error message from various error formats, including S3 XML errors\n */\nfunction extractErrorMessage(error: unknown): string {\n if (typeof error === \"string\") {\n return error;\n }\n\n if (error instanceof Error) {\n // Check if it's an S3 XML error in the message\n const xmlMatch = error.message.match(/<Message>(.*?)<\\/Message>/);\n if (xmlMatch) {\n return xmlMatch[1];\n }\n return error.message;\n }\n\n // Handle objects with message property\n if (error && typeof error === \"object\") {\n // Check for responseText with XML\n if (\"responseText\" in error && typeof error.responseText === \"string\") {\n const xmlMatch = error.responseText.match(/<Message>(.*?)<\\/Message>/);\n if (xmlMatch) {\n return xmlMatch[1];\n }\n }\n\n // Check for body with XML\n if (\"body\" in error && typeof error.body === \"string\") {\n const xmlMatch = error.body.match(/<Message>(.*?)<\\/Message>/);\n if (xmlMatch) {\n return xmlMatch[1];\n }\n }\n\n // Standard message property\n if (\"message\" in error && typeof error.message === \"string\") {\n return error.message;\n }\n\n // Check for error property\n if (\"error\" in error) {\n return extractErrorMessage(error.error);\n }\n }\n\n return \"Upload failed\";\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport const useFileUpload = (\n options: UseFileUploadOptions = {},\n): UseFileUploadReturn => {\n const { upload, ...baseOptions } = options;\n const autoUpload = upload?.autoUpload ?? true;\n\n const [files, setFilesState] = useState<FileUploadItem[]>(\n (baseOptions.initialFiles ?? []).map((file) => ({\n file,\n id: file.id,\n preview: file.url,\n progress: 100,\n status: \"complete\" as const,\n uploadedUrl: file.url,\n })),\n );\n const [isUploading, setIsUploading] = useState(false);\n const [isDragging, setIsDragging] = useState(false);\n const [errors, setErrors] = useState<string[]>([]);\n const [instanceKey, setInstanceKey] = useState(0);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const abortControllersRef = useRef<Map<string, AbortController>>(new Map());\n\n // Helper to cancel all ongoing uploads\n const cancelAllUploads = useCallback(() => {\n for (const controller of abortControllersRef.current.values()) {\n controller.abort();\n }\n abortControllersRef.current.clear();\n }, []);\n\n const {\n maxFiles = Number.POSITIVE_INFINITY,\n maxSize = Number.POSITIVE_INFINITY,\n minSize = 4 * 1024,\n accept = \"*\",\n multiple = false,\n onFilesChange,\n onFileAdd,\n onFileRemove,\n } = baseOptions;\n\n const validateFile = useCallback(\n (file: File): string | null => {\n if (file.size > maxSize) {\n return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`;\n }\n\n if (file.size < minSize) {\n return `File \"${file.name}\" is below the minimum size of ${formatBytes(minSize)}.`;\n }\n\n if (accept !== \"*\") {\n const acceptedTypes = accept.split(\",\").map((type) => type.trim());\n const fileType = file.type || \"\";\n const fileExtension = `.${file.name.split(\".\").pop()}`;\n\n const isAccepted = acceptedTypes.some((type) => {\n if (type.startsWith(\".\")) {\n return fileExtension.toLowerCase() === type.toLowerCase();\n }\n if (type.endsWith(\"/*\")) {\n const baseType = type.split(\"/\")[0];\n return fileType.startsWith(`${baseType}/`);\n }\n return fileType === type;\n });\n\n if (!isAccepted) {\n return `File \"${file.name}\" is not an accepted file type.`;\n }\n }\n\n return null;\n },\n [accept, maxSize, minSize],\n );\n\n const createPreview = useCallback((file: File): string | undefined => {\n if (file.type.startsWith(\"image/\")) {\n return URL.createObjectURL(file);\n }\n return undefined;\n }, []);\n\n const generateUniqueId = useCallback((file: File): string => {\n return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n }, []);\n\n const uploadSingleFile = useCallback(\n async (fileWithStatus: FileUploadItem): Promise<FileUploadItem> => {\n if (!upload) {\n return {\n ...fileWithStatus,\n status: \"error\",\n error: \"No upload config provided\",\n };\n }\n\n const file = fileWithStatus.file as File;\n if (!(file instanceof File)) {\n // Already uploaded file (FileMetadata)\n return { ...fileWithStatus, status: \"complete\", progress: 100 };\n }\n\n const abortController = new AbortController();\n abortControllersRef.current.set(fileWithStatus.id, abortController);\n\n try {\n // Update status to uploading\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === fileWithStatus.id\n ? { ...f, status: \"uploading\" as const, progress: 0 }\n : f,\n ),\n );\n\n // Step 1: Get presigned URL\n const { result: presignedResult, error: presignedError } =\n await upload.getPresignedUrl({\n filename: file.name,\n contentType: file.type,\n size: file.size,\n signal: abortController.signal,\n });\n\n if (presignedError || !presignedResult) {\n throw presignedError || new Error(\"Failed to get presigned URL\");\n }\n\n // Update progress after getting presigned URL\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === fileWithStatus.id ? { ...f, progress: 10 } : f,\n ),\n );\n\n // Step 2: Upload file\n const { result: uploadResult, error: uploadError } =\n await upload.uploadFile(\n presignedResult.url,\n file,\n presignedResult,\n (progress) => {\n // Scale progress from 10-99 (leave room for final 100%)\n const scaledProgress = Math.min(10 + progress * 0.89, 99);\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === fileWithStatus.id\n ? { ...f, progress: Math.round(scaledProgress) }\n : f,\n ),\n );\n },\n abortController.signal,\n );\n\n if (uploadError) {\n throw uploadError;\n }\n\n if (!uploadResult?.url) {\n throw new Error(\"Upload failed, no URL was returned\");\n }\n\n // Ensure progress hits 100% before changing status\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === fileWithStatus.id ? { ...f, progress: 100 } : f,\n ),\n );\n\n // Small delay to show 100% before marking complete\n await new Promise((resolve) => setTimeout(resolve, 150));\n\n const uploadedFile: FileUploadItem = {\n ...fileWithStatus,\n status: \"complete\",\n progress: 100,\n uploadedUrl: uploadResult.url,\n };\n\n setFilesState((prev) =>\n prev.map((f) => (f.id === fileWithStatus.id ? uploadedFile : f)),\n );\n\n upload.onUploadComplete?.(uploadedFile);\n\n return uploadedFile;\n } catch (error) {\n // Check if the upload was cancelled via AbortController\n const isAborted =\n error instanceof Error &&\n (error.name === \"AbortError\" || abortController.signal.aborted);\n\n if (isAborted) {\n // Upload was cancelled - return idle state\n const cancelledFile: FileUploadItem = {\n ...fileWithStatus,\n status: \"idle\",\n progress: 0,\n };\n return cancelledFile;\n }\n\n const errorMessage = extractErrorMessage(error);\n const failedFile: FileUploadItem = {\n ...fileWithStatus,\n status: \"error\",\n error: errorMessage,\n };\n\n setFilesState((prev) =>\n prev.map((f) => (f.id === fileWithStatus.id ? failedFile : f)),\n );\n\n upload.onUploadError?.(failedFile, error);\n\n return failedFile;\n } finally {\n abortControllersRef.current.delete(fileWithStatus.id);\n }\n },\n [upload],\n );\n\n const uploadFiles = useCallback(\n async (filesToUpload?: FileUploadItem[]): Promise<FileUploadItem[]> => {\n const targetFiles =\n filesToUpload ?? files.filter((f) => f.status === \"idle\");\n\n if (targetFiles.length === 0) return [];\n\n setIsUploading(true);\n const results: FileUploadItem[] = [];\n\n for (const file of targetFiles) {\n const result = await uploadSingleFile(file);\n results.push(result);\n }\n\n setIsUploading(false);\n upload?.onAllUploadsComplete?.(results);\n\n return results;\n },\n [files, uploadSingleFile, upload],\n );\n\n const addFiles = useCallback(\n (newFiles: FileList | File[]) => {\n if (!newFiles || newFiles.length === 0) return;\n\n const newFilesArray = Array.from(newFiles);\n const newErrors: string[] = [];\n\n // Clear existing errors\n setErrors([]);\n\n // In single file mode, clear existing files first\n if (!multiple) {\n setFilesState((prev) => {\n for (const file of prev) {\n if (file.preview && file.file instanceof File) {\n URL.revokeObjectURL(file.preview);\n }\n }\n return [];\n });\n }\n\n // Check if adding these files would exceed maxFiles\n if (\n multiple &&\n maxFiles !== Number.POSITIVE_INFINITY &&\n files.length + newFilesArray.length > maxFiles\n ) {\n newErrors.push(`You can only upload a maximum of ${maxFiles} files.`);\n setErrors(newErrors);\n return;\n }\n\n const validFiles: FileUploadItem[] = [];\n\n for (const file of newFilesArray) {\n // Check for duplicates in multiple mode\n if (multiple) {\n const isDuplicate = files.some(\n (existingFile) =>\n existingFile.file.name === file.name &&\n existingFile.file.size === file.size,\n );\n if (isDuplicate) continue;\n }\n\n const error = validateFile(file);\n if (error) {\n newErrors.push(error);\n continue;\n }\n\n validFiles.push({\n file,\n id: generateUniqueId(file),\n preview: createPreview(file),\n progress: 0,\n status: \"idle\",\n });\n }\n\n if (validFiles.length > 0) {\n // Call onFileAdd callback for each file\n if (onFileAdd) {\n for (const file of validFiles) {\n onFileAdd(file);\n }\n }\n\n setFilesState((prev) => {\n const updatedFiles = !multiple ? validFiles : [...prev, ...validFiles];\n onFilesChange?.(updatedFiles);\n return updatedFiles;\n });\n\n // Auto-upload if configured\n if (autoUpload && upload) {\n // Use setTimeout to ensure state is updated before uploading\n setTimeout(() => {\n uploadFiles(validFiles);\n }, 0);\n }\n }\n\n if (newErrors.length > 0) {\n setErrors(newErrors);\n }\n\n // Reset input value\n if (inputRef.current) {\n inputRef.current.value = \"\";\n }\n },\n [\n files,\n maxFiles,\n multiple,\n validateFile,\n createPreview,\n generateUniqueId,\n onFilesChange,\n onFileAdd,\n autoUpload,\n upload,\n uploadFiles,\n ],\n );\n\n const removeFile = useCallback(\n (id: string) => {\n // Cancel any ongoing upload\n const controller = abortControllersRef.current.get(id);\n if (controller) {\n controller.abort();\n abortControllersRef.current.delete(id);\n }\n\n setFilesState((prev) => {\n const fileToRemove = prev.find((file) => file.id === id);\n if (fileToRemove) {\n // Call onFileRemove callback before removing\n onFileRemove?.(fileToRemove);\n\n if (fileToRemove.preview && fileToRemove.file instanceof File) {\n URL.revokeObjectURL(fileToRemove.preview);\n }\n }\n\n const newFiles = prev.filter((file) => file.id !== id);\n onFilesChange?.(newFiles);\n return newFiles;\n });\n },\n [onFilesChange, onFileRemove],\n );\n\n const clearFiles = useCallback(() => {\n cancelAllUploads();\n\n setFilesState((prev) => {\n for (const file of prev) {\n // Call onFileRemove for each file\n onFileRemove?.(file);\n\n if (file.preview && file.file instanceof File) {\n URL.revokeObjectURL(file.preview);\n }\n }\n return [];\n });\n\n if (inputRef.current) {\n inputRef.current.value = \"\";\n }\n\n setErrors([]);\n onFilesChange?.([]);\n }, [cancelAllUploads, onFilesChange, onFileRemove]);\n\n const clearErrors = useCallback(() => {\n setErrors([]);\n }, []);\n\n const reset = useCallback(\n (newFiles?: FileMetadata[]) => {\n cancelAllUploads();\n\n // Revoke all previews\n for (const file of files) {\n if (file.preview && file.file instanceof File) {\n URL.revokeObjectURL(file.preview);\n }\n }\n\n // Reset input\n if (inputRef.current) {\n inputRef.current.value = \"\";\n }\n\n // Clear errors\n setErrors([]);\n\n // Set new files or clear\n const initializedFiles: FileUploadItem[] = (newFiles ?? []).map(\n (file) => ({\n file,\n id: file.id,\n preview: file.url,\n progress: 100,\n status: \"complete\" as const,\n uploadedUrl: file.url,\n }),\n );\n\n setFilesState(initializedFiles);\n onFilesChange?.(initializedFiles);\n\n // Increment instance key to force remount\n setInstanceKey((prev) => prev + 1);\n },\n [cancelAllUploads, files, onFilesChange],\n );\n\n const setFiles = useCallback(\n (\n newFiles:\n | FileUploadItem[]\n | ((prev: FileUploadItem[]) => FileUploadItem[]),\n ) => {\n setFilesState((prev) => {\n const nextFiles =\n typeof newFiles === \"function\" ? newFiles(prev) : newFiles;\n onFilesChange?.(nextFiles);\n return nextFiles;\n });\n },\n [onFilesChange],\n );\n\n const retryUpload = useCallback(\n async (id: string) => {\n const file = files.find((f) => f.id === id);\n if (file && file.status === \"error\") {\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === id\n ? { ...f, status: \"idle\" as const, error: undefined }\n : f,\n ),\n );\n await uploadSingleFile({ ...file, status: \"idle\", error: undefined });\n }\n },\n [files, uploadSingleFile],\n );\n\n const cancelUpload = useCallback((id: string) => {\n const controller = abortControllersRef.current.get(id);\n if (controller) {\n controller.abort();\n abortControllersRef.current.delete(id);\n }\n\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === id ? { ...f, status: \"idle\" as const, progress: 0 } : f,\n ),\n );\n }, []);\n\n const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(true);\n }, []);\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n if (e.currentTarget.contains(e.relatedTarget as Node)) return;\n setIsDragging(false);\n }, []);\n\n const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n\n if (inputRef.current?.disabled) return;\n\n if (e.dataTransfer.files?.length > 0) {\n if (!multiple) {\n addFiles([e.dataTransfer.files[0]]);\n } else {\n addFiles(e.dataTransfer.files);\n }\n }\n },\n [addFiles, multiple],\n );\n\n const handleFileChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n if (e.target.files?.length) {\n addFiles(e.target.files);\n }\n },\n [addFiles],\n );\n\n const openFileDialog = useCallback(() => {\n inputRef.current?.click();\n }, []);\n\n const getInputProps = useCallback(\n (props: InputHTMLAttributes<HTMLInputElement> = {}) => ({\n ...props,\n accept: props.accept || accept,\n multiple: props.multiple !== undefined ? props.multiple : multiple,\n onChange: handleFileChange,\n // biome-ignore lint/suspicious/noExplicitAny: intentional\n ref: inputRef as any,\n type: \"file\" as const,\n }),\n [accept, multiple, handleFileChange],\n );\n\n return {\n // State\n files,\n isDragging,\n isUploading,\n errors,\n\n // Core Actions\n addFiles,\n removeFile,\n clearFiles,\n clearErrors,\n\n // Form integration\n reset,\n setFiles,\n instanceKey,\n\n // Upload Actions\n uploadFiles,\n retryUpload,\n cancelUpload,\n\n // Drag/Drop + Input\n handleDragEnter,\n handleDragLeave,\n handleDragOver,\n handleDrop,\n handleFileChange,\n openFileDialog,\n getInputProps,\n };\n};\n\n// Legacy type exports for backwards compatibility\nexport type FileWithPreview = FileUploadItem;\nexport type FileWithUploadStatus = FileUploadItem;\nexport type FileUploadOptions = UseFileUploadOptions;\nexport type FileUploadWithUploaderOptions = UseFileUploadOptions;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-file-upload-Dxrej28u.js","names":["uploadedFile: FileUploadItem","failedFile: FileUploadItem","results: FileUploadItem[]","newErrors: string[]","validFiles: FileUploadItem[]","initializedFiles: FileUploadItem[]"],"sources":["../src/hooks/use-file-upload.ts"],"sourcesContent":["import {\n type ChangeEvent,\n type DragEvent,\n type InputHTMLAttributes,\n useCallback,\n useRef,\n useState,\n} from \"react\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type FileMetadata = {\n name: string;\n size: number;\n type: string;\n url: string;\n id: string;\n};\n\nexport type UploadStatus = \"idle\" | \"uploading\" | \"complete\" | \"error\";\n\nexport type FileUploadItem = {\n file: File | FileMetadata;\n id: string;\n preview?: string;\n progress: number;\n status: UploadStatus;\n error?: string;\n uploadedUrl?: string;\n};\n\nexport type PresignedUrlResponse = {\n /** The S3 bucket URL to POST to */\n url: string;\n /** The full accessible path after upload (may include signed query params) */\n full_path: string;\n /** The S3 object key (e.g., \"uuid/filename.pdf\") */\n key?: string;\n /** Access control level */\n acl?: string;\n /** Expected response status from S3 */\n success_action_status?: string;\n /** Content-Type for the upload */\n \"Content-Type\"?: string;\n /** Base64-encoded policy document */\n policy?: string;\n /** AWS credential string */\n \"x-amz-credential\"?: string;\n /** AWS signing algorithm */\n \"x-amz-algorithm\"?: string;\n /** AWS request date */\n \"x-amz-date\"?: string;\n /** AWS request signature */\n \"x-amz-signature\"?: string;\n /** Additional fields */\n [key: string]: unknown;\n};\n\nexport type UploadConfig = {\n /**\n * Function to get a presigned URL for uploading\n */\n getPresignedUrl: (params: {\n filename: string;\n contentType: string;\n size: number;\n signal?: AbortSignal;\n }) => Promise<{\n result?: PresignedUrlResponse | null;\n error?: unknown;\n }>;\n\n /**\n * Function to upload the file to the storage\n */\n uploadFile: (\n url: string,\n file: File,\n presignedData: PresignedUrlResponse,\n onProgress?: (progress: number) => void,\n signal?: AbortSignal,\n ) => Promise<{\n result?: { url: string; [key: string]: unknown };\n error?: unknown;\n }>;\n\n /**\n * Whether to auto-upload files when they are added\n * @default true\n */\n autoUpload?: boolean;\n\n /**\n * Called when a single file upload completes\n */\n onUploadComplete?: (file: FileUploadItem) => void;\n\n /**\n * Called when a single file upload fails\n */\n onUploadError?: (file: FileUploadItem, error: unknown) => void;\n\n /**\n * Called when all files finish uploading\n */\n onAllUploadsComplete?: (files: FileUploadItem[]) => void;\n};\n\nexport type UseFileUploadOptions = {\n maxFiles?: number;\n maxSize?: number;\n minSize?: number;\n accept?: string;\n multiple?: boolean;\n initialFiles?: FileMetadata[];\n onFilesChange?: (files: FileUploadItem[]) => void;\n onFileAdd?: (addedFile: FileUploadItem) => void;\n onFileRemove?: (removedFile: FileUploadItem) => void;\n upload?: UploadConfig;\n};\n\nexport type UseFileUploadReturn = {\n // State\n files: FileUploadItem[];\n isDragging: boolean;\n isUploading: boolean;\n errors: string[];\n\n // Core Actions\n addFiles: (files: FileList | File[]) => void;\n removeFile: (id: string) => void;\n clearFiles: () => void;\n clearErrors: () => void;\n\n // Form integration\n reset: (newFiles?: FileMetadata[]) => void;\n setFiles: (\n files: FileUploadItem[] | ((prev: FileUploadItem[]) => FileUploadItem[]),\n ) => void;\n instanceKey: number;\n\n // Upload Actions\n uploadFiles: (files?: FileUploadItem[]) => Promise<FileUploadItem[]>;\n retryUpload: (id: string) => Promise<void>;\n cancelUpload: (id: string) => void;\n\n // Drag/Drop + Input\n handleDragEnter: (e: DragEvent<HTMLElement>) => void;\n handleDragLeave: (e: DragEvent<HTMLElement>) => void;\n handleDragOver: (e: DragEvent<HTMLElement>) => void;\n handleDrop: (e: DragEvent<HTMLElement>) => void;\n handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void;\n openFileDialog: () => void;\n getInputProps: (\n props?: InputHTMLAttributes<HTMLInputElement>,\n ) => InputHTMLAttributes<HTMLInputElement> & {\n // biome-ignore lint/suspicious/noExplicitAny: intentional for cross-React ref compatibility\n ref: any;\n };\n};\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n if (bytes === 0) return \"0 Bytes\";\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return Number.parseFloat((bytes / k ** i).toFixed(dm)) + sizes[i];\n};\n\n/**\n * Extract error message from various error formats, including S3 XML errors\n */\nfunction extractErrorMessage(error: unknown): string {\n if (typeof error === \"string\") {\n return error;\n }\n\n if (error instanceof Error) {\n // Check if it's an S3 XML error in the message\n const xmlMatch = error.message.match(/<Message>(.*?)<\\/Message>/);\n if (xmlMatch) {\n return xmlMatch[1];\n }\n return error.message;\n }\n\n // Handle objects with message property\n if (error && typeof error === \"object\") {\n // Check for responseText with XML\n if (\"responseText\" in error && typeof error.responseText === \"string\") {\n const xmlMatch = error.responseText.match(/<Message>(.*?)<\\/Message>/);\n if (xmlMatch) {\n return xmlMatch[1];\n }\n }\n\n // Check for body with XML\n if (\"body\" in error && typeof error.body === \"string\") {\n const xmlMatch = error.body.match(/<Message>(.*?)<\\/Message>/);\n if (xmlMatch) {\n return xmlMatch[1];\n }\n }\n\n // Standard message property\n if (\"message\" in error && typeof error.message === \"string\") {\n return error.message;\n }\n\n // Check for error property\n if (\"error\" in error) {\n return extractErrorMessage(error.error);\n }\n }\n\n return \"Upload failed\";\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport const useFileUpload = (\n options: UseFileUploadOptions = {},\n): UseFileUploadReturn => {\n const { upload, ...baseOptions } = options;\n const autoUpload = upload?.autoUpload ?? true;\n\n const [files, setFilesState] = useState<FileUploadItem[]>(\n (baseOptions.initialFiles ?? []).map((file) => ({\n file,\n id: file.id,\n preview: file.url,\n progress: 100,\n status: \"complete\" as const,\n uploadedUrl: file.url,\n })),\n );\n const [isUploading, setIsUploading] = useState(false);\n const [isDragging, setIsDragging] = useState(false);\n const [errors, setErrors] = useState<string[]>([]);\n const [instanceKey, setInstanceKey] = useState(0);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const abortControllersRef = useRef<Map<string, AbortController>>(new Map());\n\n // Helper to cancel all ongoing uploads\n const cancelAllUploads = useCallback(() => {\n for (const controller of abortControllersRef.current.values()) {\n controller.abort();\n }\n abortControllersRef.current.clear();\n }, []);\n\n const {\n maxFiles = Number.POSITIVE_INFINITY,\n maxSize = Number.POSITIVE_INFINITY,\n minSize = 4 * 1024,\n accept = \"*\",\n multiple = false,\n onFilesChange,\n onFileAdd,\n onFileRemove,\n } = baseOptions;\n\n const validateFile = useCallback(\n (file: File): string | null => {\n if (file.size > maxSize) {\n return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`;\n }\n\n if (file.size < minSize) {\n return `File \"${file.name}\" is below the minimum size of ${formatBytes(minSize)}.`;\n }\n\n if (accept !== \"*\") {\n const acceptedTypes = accept.split(\",\").map((type) => type.trim());\n const fileType = file.type || \"\";\n const fileExtension = `.${file.name.split(\".\").pop()}`;\n\n const isAccepted = acceptedTypes.some((type) => {\n if (type.startsWith(\".\")) {\n return fileExtension.toLowerCase() === type.toLowerCase();\n }\n if (type.endsWith(\"/*\")) {\n const baseType = type.split(\"/\")[0];\n return fileType.startsWith(`${baseType}/`);\n }\n return fileType === type;\n });\n\n if (!isAccepted) {\n return `File \"${file.name}\" is not an accepted file type.`;\n }\n }\n\n return null;\n },\n [accept, maxSize, minSize],\n );\n\n const createPreview = useCallback((file: File): string | undefined => {\n if (file.type.startsWith(\"image/\")) {\n return URL.createObjectURL(file);\n }\n return undefined;\n }, []);\n\n const generateUniqueId = useCallback((file: File): string => {\n return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n }, []);\n\n const uploadSingleFile = useCallback(\n async (fileWithStatus: FileUploadItem): Promise<FileUploadItem> => {\n if (!upload) {\n return {\n ...fileWithStatus,\n status: \"error\",\n error: \"No upload config provided\",\n };\n }\n\n const file = fileWithStatus.file as File;\n if (!(file instanceof File)) {\n // Already uploaded file (FileMetadata)\n return { ...fileWithStatus, status: \"complete\", progress: 100 };\n }\n\n const abortController = new AbortController();\n abortControllersRef.current.set(fileWithStatus.id, abortController);\n\n try {\n // Update status to uploading\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === fileWithStatus.id\n ? { ...f, status: \"uploading\" as const, progress: 0 }\n : f,\n ),\n );\n\n // Step 1: Get presigned URL\n const { result: presignedResult, error: presignedError } =\n await upload.getPresignedUrl({\n filename: file.name,\n contentType: file.type,\n size: file.size,\n signal: abortController.signal,\n });\n\n if (presignedError || !presignedResult) {\n throw presignedError || new Error(\"Failed to get presigned URL\");\n }\n\n // Update progress after getting presigned URL\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === fileWithStatus.id ? { ...f, progress: 10 } : f,\n ),\n );\n\n // Step 2: Upload file\n const { result: uploadResult, error: uploadError } =\n await upload.uploadFile(\n presignedResult.url,\n file,\n presignedResult,\n (progress) => {\n // Scale progress from 10-99 (leave room for final 100%)\n const scaledProgress = Math.min(10 + progress * 0.89, 99);\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === fileWithStatus.id\n ? { ...f, progress: Math.round(scaledProgress) }\n : f,\n ),\n );\n },\n abortController.signal,\n );\n\n if (uploadError) {\n throw uploadError;\n }\n\n if (!uploadResult?.url) {\n throw new Error(\"Upload failed, no URL was returned\");\n }\n\n // Ensure progress hits 100% before changing status\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === fileWithStatus.id ? { ...f, progress: 100 } : f,\n ),\n );\n\n // Small delay to show 100% before marking complete\n await new Promise((resolve) => setTimeout(resolve, 150));\n\n const uploadedFile: FileUploadItem = {\n ...fileWithStatus,\n status: \"complete\",\n progress: 100,\n uploadedUrl: uploadResult.url,\n };\n\n setFilesState((prev) =>\n prev.map((f) => (f.id === fileWithStatus.id ? uploadedFile : f)),\n );\n\n upload.onUploadComplete?.(uploadedFile);\n\n return uploadedFile;\n } catch (error) {\n // Check if the upload was cancelled via AbortController\n const isAborted =\n error instanceof Error &&\n (error.name === \"AbortError\" || abortController.signal.aborted);\n\n if (isAborted) {\n // Upload was cancelled - return idle state\n const cancelledFile: FileUploadItem = {\n ...fileWithStatus,\n status: \"idle\",\n progress: 0,\n };\n return cancelledFile;\n }\n\n const errorMessage = extractErrorMessage(error);\n const failedFile: FileUploadItem = {\n ...fileWithStatus,\n status: \"error\",\n error: errorMessage,\n };\n\n setFilesState((prev) =>\n prev.map((f) => (f.id === fileWithStatus.id ? failedFile : f)),\n );\n\n upload.onUploadError?.(failedFile, error);\n\n return failedFile;\n } finally {\n abortControllersRef.current.delete(fileWithStatus.id);\n }\n },\n [upload],\n );\n\n const uploadFiles = useCallback(\n async (filesToUpload?: FileUploadItem[]): Promise<FileUploadItem[]> => {\n const targetFiles =\n filesToUpload ?? files.filter((f) => f.status === \"idle\");\n\n if (targetFiles.length === 0) return [];\n\n setIsUploading(true);\n const results: FileUploadItem[] = [];\n\n for (const file of targetFiles) {\n const result = await uploadSingleFile(file);\n results.push(result);\n }\n\n setIsUploading(false);\n upload?.onAllUploadsComplete?.(results);\n\n return results;\n },\n [files, uploadSingleFile, upload],\n );\n\n const addFiles = useCallback(\n (newFiles: FileList | File[]) => {\n if (!newFiles || newFiles.length === 0) return;\n\n const newFilesArray = Array.from(newFiles);\n const newErrors: string[] = [];\n\n // Clear existing errors\n setErrors([]);\n\n // In single file mode, clear existing files first\n if (!multiple) {\n setFilesState((prev) => {\n for (const file of prev) {\n if (file.preview && file.file instanceof File) {\n URL.revokeObjectURL(file.preview);\n }\n }\n return [];\n });\n }\n\n // Check if adding these files would exceed maxFiles\n if (\n multiple &&\n maxFiles !== Number.POSITIVE_INFINITY &&\n files.length + newFilesArray.length > maxFiles\n ) {\n newErrors.push(`You can only upload a maximum of ${maxFiles} files.`);\n setErrors(newErrors);\n return;\n }\n\n const validFiles: FileUploadItem[] = [];\n\n for (const file of newFilesArray) {\n // Check for duplicates in multiple mode\n if (multiple) {\n const isDuplicate = files.some(\n (existingFile) =>\n existingFile.file.name === file.name &&\n existingFile.file.size === file.size,\n );\n if (isDuplicate) continue;\n }\n\n const error = validateFile(file);\n if (error) {\n newErrors.push(error);\n continue;\n }\n\n validFiles.push({\n file,\n id: generateUniqueId(file),\n preview: createPreview(file),\n progress: 0,\n status: \"idle\",\n });\n }\n\n if (validFiles.length > 0) {\n // Call onFileAdd callback for each file\n if (onFileAdd) {\n for (const file of validFiles) {\n onFileAdd(file);\n }\n }\n\n setFilesState((prev) => {\n const updatedFiles = !multiple ? validFiles : [...prev, ...validFiles];\n onFilesChange?.(updatedFiles);\n return updatedFiles;\n });\n\n // Auto-upload if configured\n if (autoUpload && upload) {\n // Use setTimeout to ensure state is updated before uploading\n setTimeout(() => {\n uploadFiles(validFiles);\n }, 0);\n }\n }\n\n if (newErrors.length > 0) {\n setErrors(newErrors);\n }\n\n // Reset input value\n if (inputRef.current) {\n inputRef.current.value = \"\";\n }\n },\n [\n files,\n maxFiles,\n multiple,\n validateFile,\n createPreview,\n generateUniqueId,\n onFilesChange,\n onFileAdd,\n autoUpload,\n upload,\n uploadFiles,\n ],\n );\n\n const removeFile = useCallback(\n (id: string) => {\n // Cancel any ongoing upload\n const controller = abortControllersRef.current.get(id);\n if (controller) {\n controller.abort();\n abortControllersRef.current.delete(id);\n }\n\n setFilesState((prev) => {\n const fileToRemove = prev.find((file) => file.id === id);\n if (fileToRemove) {\n // Call onFileRemove callback before removing\n onFileRemove?.(fileToRemove);\n\n if (fileToRemove.preview && fileToRemove.file instanceof File) {\n URL.revokeObjectURL(fileToRemove.preview);\n }\n }\n\n const newFiles = prev.filter((file) => file.id !== id);\n onFilesChange?.(newFiles);\n return newFiles;\n });\n },\n [onFilesChange, onFileRemove],\n );\n\n const clearFiles = useCallback(() => {\n cancelAllUploads();\n\n setFilesState((prev) => {\n for (const file of prev) {\n // Call onFileRemove for each file\n onFileRemove?.(file);\n\n if (file.preview && file.file instanceof File) {\n URL.revokeObjectURL(file.preview);\n }\n }\n return [];\n });\n\n if (inputRef.current) {\n inputRef.current.value = \"\";\n }\n\n setErrors([]);\n onFilesChange?.([]);\n }, [cancelAllUploads, onFilesChange, onFileRemove]);\n\n const clearErrors = useCallback(() => {\n setErrors([]);\n }, []);\n\n const reset = useCallback(\n (newFiles?: FileMetadata[]) => {\n cancelAllUploads();\n\n // Revoke all previews\n for (const file of files) {\n if (file.preview && file.file instanceof File) {\n URL.revokeObjectURL(file.preview);\n }\n }\n\n // Reset input\n if (inputRef.current) {\n inputRef.current.value = \"\";\n }\n\n // Clear errors\n setErrors([]);\n\n // Set new files or clear\n const initializedFiles: FileUploadItem[] = (newFiles ?? []).map(\n (file) => ({\n file,\n id: file.id,\n preview: file.url,\n progress: 100,\n status: \"complete\" as const,\n uploadedUrl: file.url,\n }),\n );\n\n setFilesState(initializedFiles);\n onFilesChange?.(initializedFiles);\n\n // Increment instance key to force remount\n setInstanceKey((prev) => prev + 1);\n },\n [cancelAllUploads, files, onFilesChange],\n );\n\n const setFiles = useCallback(\n (\n newFiles:\n | FileUploadItem[]\n | ((prev: FileUploadItem[]) => FileUploadItem[]),\n ) => {\n setFilesState((prev) => {\n const nextFiles =\n typeof newFiles === \"function\" ? newFiles(prev) : newFiles;\n onFilesChange?.(nextFiles);\n return nextFiles;\n });\n },\n [onFilesChange],\n );\n\n const retryUpload = useCallback(\n async (id: string) => {\n const file = files.find((f) => f.id === id);\n if (file && file.status === \"error\") {\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === id\n ? { ...f, status: \"idle\" as const, error: undefined }\n : f,\n ),\n );\n await uploadSingleFile({ ...file, status: \"idle\", error: undefined });\n }\n },\n [files, uploadSingleFile],\n );\n\n const cancelUpload = useCallback((id: string) => {\n const controller = abortControllersRef.current.get(id);\n if (controller) {\n controller.abort();\n abortControllersRef.current.delete(id);\n }\n\n setFilesState((prev) =>\n prev.map((f) =>\n f.id === id ? { ...f, status: \"idle\" as const, progress: 0 } : f,\n ),\n );\n }, []);\n\n const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(true);\n }, []);\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n if (e.currentTarget.contains(e.relatedTarget as Node)) return;\n setIsDragging(false);\n }, []);\n\n const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n }, []);\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n\n if (inputRef.current?.disabled) return;\n\n if (e.dataTransfer.files?.length > 0) {\n if (!multiple) {\n addFiles([e.dataTransfer.files[0]]);\n } else {\n addFiles(e.dataTransfer.files);\n }\n }\n },\n [addFiles, multiple],\n );\n\n const handleFileChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n if (e.target.files?.length) {\n addFiles(e.target.files);\n }\n },\n [addFiles],\n );\n\n const openFileDialog = useCallback(() => {\n inputRef.current?.click();\n }, []);\n\n const getInputProps = useCallback(\n (props: InputHTMLAttributes<HTMLInputElement> = {}) => ({\n ...props,\n accept: props.accept || accept,\n multiple: props.multiple !== undefined ? props.multiple : multiple,\n onChange: handleFileChange,\n // biome-ignore lint/suspicious/noExplicitAny: intentional\n ref: inputRef as any,\n type: \"file\" as const,\n }),\n [accept, multiple, handleFileChange],\n );\n\n return {\n // State\n files,\n isDragging,\n isUploading,\n errors,\n\n // Core Actions\n addFiles,\n removeFile,\n clearFiles,\n clearErrors,\n\n // Form integration\n reset,\n setFiles,\n instanceKey,\n\n // Upload Actions\n uploadFiles,\n retryUpload,\n cancelUpload,\n\n // Drag/Drop + Input\n handleDragEnter,\n handleDragLeave,\n handleDragOver,\n handleDrop,\n handleFileChange,\n openFileDialog,\n getInputProps,\n };\n};\n\n// Legacy type exports for backwards compatibility\nexport type FileWithPreview = FileUploadItem;\nexport type FileWithUploadStatus = FileUploadItem;\nexport type FileUploadOptions = UseFileUploadOptions;\nexport type FileUploadWithUploaderOptions = UseFileUploadOptions;\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as useIntersectionObserver } from "./use-intersection-observer-
|
|
1
|
+
import { t as useIntersectionObserver } from "./use-intersection-observer-CZfnep4z.js";
|
|
2
2
|
import { useEffect, useEffectEvent } from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/hooks/use-infinite-scroll.ts
|
|
@@ -35,4 +35,4 @@ var use_infinite_scroll_default = useInfiniteScroll;
|
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
37
|
export { use_infinite_scroll_default as t };
|
|
38
|
-
//# sourceMappingURL=use-infinite-scroll-
|
|
38
|
+
//# sourceMappingURL=use-infinite-scroll-CpbhGGT5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-infinite-scroll-
|
|
1
|
+
{"version":3,"file":"use-infinite-scroll-CpbhGGT5.js","names":[],"sources":["../src/hooks/use-infinite-scroll.ts"],"sourcesContent":["import { useEffect, useEffectEvent } from \"react\";\nimport {\n useIntersectionObserver,\n type UseIntersectionObserverOptions,\n} from \"./use-intersection-observer\";\n\nconst DEFAULT_DELAY_IN_MS = 100;\n\nexport type UseInfiniteScrollHookArgs = Pick<\n UseIntersectionObserverOptions,\n \"rootMargin\" | \"threshold\" | \"root\"\n> & {\n isLoadingMore: boolean;\n hasMore: boolean;\n onLoadMore: () => unknown;\n disabled?: boolean;\n};\n\nfunction useInfiniteScroll({\n isLoadingMore,\n hasMore,\n onLoadMore,\n rootMargin,\n root,\n disabled,\n threshold = 0,\n}: UseInfiniteScrollHookArgs) {\n const [ref, entry] = useIntersectionObserver({\n rootMargin,\n threshold,\n root,\n });\n const isVisible = Boolean(entry?.isIntersecting);\n\n const onLoadMoreEvent = useEffectEvent(() => {\n onLoadMore();\n });\n\n useEffect(() => {\n if (disabled) return;\n\n if (isVisible && hasMore && !isLoadingMore && !disabled) {\n const timer = setTimeout(() => {\n onLoadMoreEvent();\n }, DEFAULT_DELAY_IN_MS);\n\n return () => {\n clearTimeout(timer);\n };\n }\n }, [isVisible, isLoadingMore, hasMore, disabled]);\n\n return [ref] as const;\n}\n\nexport default useInfiniteScroll;\n"],"mappings":";;;;AAMA,MAAM,sBAAsB;AAY5B,SAAS,kBAAkB,EACzB,eACA,SACA,YACA,YACA,MACA,UACA,YAAY,KACgB;CAC5B,MAAM,CAAC,KAAK,SAAS,wBAAwB;EAC3C;EACA;EACA;EACD,CAAC;CACF,MAAM,YAAY,QAAQ,OAAO,eAAe;CAEhD,MAAM,kBAAkB,qBAAqB;AAC3C,cAAY;GACZ;AAEF,iBAAgB;AACd,MAAI,SAAU;AAEd,MAAI,aAAa,WAAW,CAAC,iBAAiB,CAAC,UAAU;GACvD,MAAM,QAAQ,iBAAiB;AAC7B,qBAAiB;MAChB,oBAAoB;AAEvB,gBAAa;AACX,iBAAa,MAAM;;;IAGtB;EAAC;EAAW;EAAe;EAAS;EAAS,CAAC;AAEjD,QAAO,CAAC,IAAI;;AAGd,kCAAe"}
|