@useupup/preact 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +80 -0
- package/dist/AudioUploader-2WITC5YR-4WGBUCEB.js +298 -0
- package/dist/AudioUploader-2WITC5YR-4WGBUCEB.js.map +1 -0
- package/dist/AudioUploader-2WITC5YR-GCKVRJAT.cjs +298 -0
- package/dist/AudioUploader-2WITC5YR-GCKVRJAT.cjs.map +1 -0
- package/dist/BoxUploader-VE5LRJ7M-CWGNYYJV.js +170 -0
- package/dist/BoxUploader-VE5LRJ7M-CWGNYYJV.js.map +1 -0
- package/dist/BoxUploader-VE5LRJ7M-IE7LYW5P.cjs +170 -0
- package/dist/BoxUploader-VE5LRJ7M-IE7LYW5P.cjs.map +1 -0
- package/dist/CameraUploader-WF5A6UIS-3KBW647M.cjs +628 -0
- package/dist/CameraUploader-WF5A6UIS-3KBW647M.cjs.map +1 -0
- package/dist/CameraUploader-WF5A6UIS-DONVXSEZ.js +628 -0
- package/dist/CameraUploader-WF5A6UIS-DONVXSEZ.js.map +1 -0
- package/dist/DropboxUploader-VMUYG3OP-7FKTLIIL.cjs +172 -0
- package/dist/DropboxUploader-VMUYG3OP-7FKTLIIL.cjs.map +1 -0
- package/dist/DropboxUploader-VMUYG3OP-DBUPHIG7.js +172 -0
- package/dist/DropboxUploader-VMUYG3OP-DBUPHIG7.js.map +1 -0
- package/dist/GoogleDriveUploader-YA56X3QR-FMS6MTYU.js +175 -0
- package/dist/GoogleDriveUploader-YA56X3QR-FMS6MTYU.js.map +1 -0
- package/dist/GoogleDriveUploader-YA56X3QR-OR3CQLX2.cjs +175 -0
- package/dist/GoogleDriveUploader-YA56X3QR-OR3CQLX2.cjs.map +1 -0
- package/dist/ImageEditorInline-N2NSAODR-QWXPP3ON.js +184 -0
- package/dist/ImageEditorInline-N2NSAODR-QWXPP3ON.js.map +1 -0
- package/dist/ImageEditorInline-N2NSAODR-ZVAM6EOA.cjs +184 -0
- package/dist/ImageEditorInline-N2NSAODR-ZVAM6EOA.cjs.map +1 -0
- package/dist/ImageEditorModal-CWKMDVPY-PRD43JPH.cjs +236 -0
- package/dist/ImageEditorModal-CWKMDVPY-PRD43JPH.cjs.map +1 -0
- package/dist/ImageEditorModal-CWKMDVPY-ZRPTYHYN.js +236 -0
- package/dist/ImageEditorModal-CWKMDVPY-ZRPTYHYN.js.map +1 -0
- package/dist/OneDriveUploader-I25Y6AJP-FVXK6RGT.js +173 -0
- package/dist/OneDriveUploader-I25Y6AJP-FVXK6RGT.js.map +1 -0
- package/dist/OneDriveUploader-I25Y6AJP-GBOBEJQR.cjs +173 -0
- package/dist/OneDriveUploader-I25Y6AJP-GBOBEJQR.cjs.map +1 -0
- package/dist/ScreenCaptureUploader-WKDO4S75-3TT6GNEN.js +286 -0
- package/dist/ScreenCaptureUploader-WKDO4S75-3TT6GNEN.js.map +1 -0
- package/dist/ScreenCaptureUploader-WKDO4S75-G7ADH264.cjs +286 -0
- package/dist/ScreenCaptureUploader-WKDO4S75-G7ADH264.cjs.map +1 -0
- package/dist/chunk-2XFVSPFN.cjs +293 -0
- package/dist/chunk-2XFVSPFN.cjs.map +1 -0
- package/dist/chunk-7JLN2HMZ.cjs +4296 -0
- package/dist/chunk-7JLN2HMZ.cjs.map +1 -0
- package/dist/chunk-BVMKSTAE.js +4296 -0
- package/dist/chunk-BVMKSTAE.js.map +1 -0
- package/dist/chunk-C7QBCXAH.js +39 -0
- package/dist/chunk-C7QBCXAH.js.map +1 -0
- package/dist/chunk-CR6CXFRP.js +195 -0
- package/dist/chunk-CR6CXFRP.js.map +1 -0
- package/dist/chunk-ETIJATY7.cjs +39 -0
- package/dist/chunk-ETIJATY7.cjs.map +1 -0
- package/dist/chunk-FH3LYESR.js +411 -0
- package/dist/chunk-FH3LYESR.js.map +1 -0
- package/dist/chunk-GKMTOOTQ.cjs +411 -0
- package/dist/chunk-GKMTOOTQ.cjs.map +1 -0
- package/dist/chunk-KHH3WHWU.js +74 -0
- package/dist/chunk-KHH3WHWU.js.map +1 -0
- package/dist/chunk-V2O5HRJV.cjs +74 -0
- package/dist/chunk-V2O5HRJV.cjs.map +1 -0
- package/dist/chunk-WCI3AGJV.js +831 -0
- package/dist/chunk-WCI3AGJV.js.map +1 -0
- package/dist/chunk-YWJHE7U4.cjs +195 -0
- package/dist/chunk-YWJHE7U4.cjs.map +1 -0
- package/dist/chunk-ZGWETRKI.js +293 -0
- package/dist/chunk-ZGWETRKI.js.map +1 -0
- package/dist/chunk-ZKZJ5PPP.cjs +831 -0
- package/dist/chunk-ZKZJ5PPP.cjs.map +1 -0
- package/dist/filerobot-bridge-52YH7W2M.cjs +92 -0
- package/dist/filerobot-bridge-52YH7W2M.cjs.map +1 -0
- package/dist/filerobot-bridge-ED4XMHX4.js +92 -0
- package/dist/filerobot-bridge-ED4XMHX4.js.map +1 -0
- package/dist/filerobot-island.css +97 -0
- package/dist/filerobot-island.css.map +1 -0
- package/dist/filerobot-island.js +77951 -0
- package/dist/filerobot-island.js.map +1 -0
- package/dist/index.cjs +5600 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5600 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.d.ts +4 -0
- package/dist/tailwind-prefixed.css +2529 -0
- package/package.json +130 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../react/src/upup-uploader.tsx","../../react/src/components/DefaultLoaderIcon.tsx","../../react/src/components/UploaderPanel.tsx","../../react/src/assets/logos.ts","../../react/src/hooks/useUploaderPanel.ts","../../react/src/components/SourceSelector.tsx","../../react/src/components/Icons.tsx","../../react/src/hooks/useSourceSelector.ts","../../react/src/lib/constants.ts","../../react/src/components/UrlUploader.tsx","../../react/src/components/SourceView.tsx","../../react/src/components/FileList.tsx","../../react/src/components/FileItem.tsx","../../react/src/components/FilePreview.tsx","../../react/src/components/FilePreviewThumbnail.tsx","../../react/src/components/FileIcon.tsx","../../react/src/components/shared/ProgressBar.tsx","../../react/src/components/shared/FileSuccessCheck.tsx","../../react/src/components/shared/EditIcon.tsx","../../react/src/components/FilePreviewPortal.tsx","../../react/src/components/FileRow.tsx","../../react/src/components/FileHero.tsx","../../react/src/components/shared/UploaderHeader.tsx","../../react/src/lib/view-mode.ts","../../react/src/lib/use-tiles-per-row.ts","../../react/src/hooks/useUploaderController.ts","../../react/src/use-upup-upload.ts","../../react/src/prop-getters.ts","../../react/src/hooks/useSSEProcessing.ts","../../react/src/hooks/useUpload.ts","../../react/src/theme/UpupThemeProvider.tsx","../../react/src/use-is-client.ts","../../react/src/index.ts","../../../node_modules/.pnpm/@tanstack+virtual-core@3.17.8/node_modules/@tanstack/virtual-core/src/lazy-measurements.ts","../../../node_modules/.pnpm/@tanstack+virtual-core@3.17.8/node_modules/@tanstack/virtual-core/src/utils.ts","../../../node_modules/.pnpm/@tanstack+virtual-core@3.17.8/node_modules/@tanstack/virtual-core/src/index.ts","../../../node_modules/.pnpm/@tanstack+react-virtual@3.1_a6f1e828bd484cece18b8523c4ba467e/node_modules/@tanstack/react-virtual/src/index.tsx"],"sourcesContent":["'use client'\r\n\r\nimport React, { forwardRef, lazy, Suspense, useImperativeHandle } from 'react'\r\nimport { cn } from '@useupup/core/internal'\r\nimport type { UploadFile } from '@useupup/core'\r\nimport { UploaderProps } from './shared/types'\r\nimport Icon from './components/Icon'\r\nimport DefaultLoaderIcon from './components/DefaultLoaderIcon'\r\nimport UploaderPanel from './components/UploaderPanel'\r\nimport { UploaderContextProvider } from './context/UploaderContext'\r\nimport useUploaderController from './hooks/useUploaderController'\r\nimport useUpload from './hooks/useUpload'\r\nimport { UpupThemeProvider } from './theme'\r\n\r\nconst ImageEditorInline = lazy(() => import('./components/ImageEditorInline'))\r\nconst ImageEditorModal = lazy(() => import('./components/ImageEditorModal'))\r\n\r\nexport type UploaderRef = {\r\n useUpload(): {\r\n error?: string | undefined\r\n files: UploadFile[]\r\n loading: boolean\r\n progress: number\r\n upload(): Promise<UploadFile[] | undefined>\r\n resetState(): void\r\n uploadFiles(\r\n files: File[] | UploadFile[],\r\n ): Promise<UploadFile[] | undefined>\r\n setFiles(newFiles: File[]): void\r\n replaceFiles(files: File[] | UploadFile[]): void\r\n }\r\n}\r\n\r\nexport default forwardRef<UploaderRef, UploaderProps>(\r\n function UpupUploader(props, ref) {\r\n const providerValues = useUploaderController({\r\n ...props,\r\n icons: {\r\n ...props.icons,\r\n LoaderIcon: DefaultLoaderIcon,\r\n },\r\n })\r\n const uploadApi = useUpload({\r\n upload: providerValues.upload,\r\n files: providerValues.files,\r\n setFiles: providerValues.setFiles,\r\n uploadFiles: providerValues.uploadFiles,\r\n resetState: providerValues.resetState,\r\n replaceFiles: providerValues.replaceFiles,\r\n })\r\n\r\n useImperativeHandle(ref, () => ({\r\n useUpload: () => uploadApi,\r\n }))\r\n\r\n return (\r\n <UpupThemeProvider theme={props.theme}>\r\n <UploaderContextProvider value={providerValues}>\r\n <div\r\n className={`upup-scope upup-h-full upup-w-full ${providerValues.props.className ?? ''}`}\r\n style={providerValues.props.style}\r\n data-testid=\"upup-root\"\r\n data-upup-slot=\"root\"\r\n data-state={\r\n providerValues.upload.uploadStatus?.toLowerCase() ??\r\n 'idle'\r\n }\r\n lang={providerValues.lang}\r\n dir={providerValues.dir}\r\n >\r\n <div\r\n className={cn('upup-w-full', {\r\n 'upup-h-[480px] upup-max-w-[600px]':\r\n !providerValues.props.mini,\r\n 'upup-h-auto upup-max-w-[280px]':\r\n providerValues.props.mini,\r\n })}\r\n style={\r\n providerValues.props.mini\r\n ? { aspectRatio: '1 / 1' }\r\n : undefined\r\n }\r\n >\r\n <section\r\n data-testid=\"upup-container\"\r\n aria-labelledby=\"drop-instructions\"\r\n className={cn(\r\n `upup-panel-sheen upup-relative ${\r\n providerValues.theme.themeMode ===\r\n 'dark'\r\n ? 'upup-panel-sheen-dark upup-bg-gradient-to-b upup-from-[#141b2e] upup-to-[#0a0e1a] upup-ring-1 upup-ring-white/10 upup-shadow-[0_24px_70px_-24px_rgba(2,6,23,0.85)]'\r\n : 'upup-bg-gradient-to-b upup-from-white upup-to-[#dde6f0] upup-ring-1 upup-ring-slate-200'\r\n } upup-flex upup-h-full upup-w-full upup-select-none upup-flex-col upup-gap-3 upup-overflow-hidden upup-rounded-2xl upup-px-5 upup-py-4`,\r\n {\r\n [providerValues.theme.slotOverrides\r\n .containerFull ?? '']:\r\n providerValues.theme.slotOverrides\r\n .containerFull &&\r\n !providerValues.props.mini,\r\n\r\n [providerValues.theme.slotOverrides\r\n .containerMini ?? '']:\r\n providerValues.theme.slotOverrides\r\n .containerMini &&\r\n providerValues.props.mini,\r\n },\r\n )}\r\n >\r\n {providerValues.props.isProcessing && (\r\n <Icon\r\n name=\"loader\"\r\n className={cn(\r\n 'upup-absolute upup-right-5 upup-animate-spin upup-text-xs upup-leading-5 upup-text-[#0284c7] md:upup-text-xl',\r\n {\r\n 'upup-text-[#38bdf8] dark:upup-text-[#38bdf8]':\r\n providerValues.theme\r\n .themeMode === 'dark',\r\n },\r\n )}\r\n />\r\n )}\r\n <UploaderPanel />\r\n\r\n {/* Inline image editor — overlays the uploader content */}\r\n {providerValues.editingFile &&\r\n providerValues.props.imageEditor.display ===\r\n 'inline' && (\r\n <Suspense\r\n fallback={\r\n <div className=\"upup-absolute upup-inset-0 upup-z-[9999] upup-flex upup-items-center upup-justify-center upup-bg-white/80 dark:upup-bg-black/60\">\r\n <DefaultLoaderIcon />\r\n </div>\r\n }\r\n >\r\n <ImageEditorInline\r\n file={\r\n providerValues.editingFile\r\n }\r\n onClose={\r\n providerValues.closeImageEditor\r\n }\r\n onSave={\r\n providerValues.saveImageEdit\r\n }\r\n />\r\n </Suspense>\r\n )}\r\n\r\n {/* Branding renders INSIDE UploaderPanel now,\r\n so the idle dashed frame wraps it. */}\r\n </section>\r\n </div>\r\n </div>\r\n {providerValues.editingFile &&\r\n providerValues.props.imageEditor.display ===\r\n 'modal' && (\r\n <Suspense\r\n fallback={\r\n <div className=\"upup-scope upup-fixed upup-inset-0 upup-z-[2147483647] upup-flex upup-items-center upup-justify-center upup-bg-black/60\">\r\n <DefaultLoaderIcon />\r\n </div>\r\n }\r\n >\r\n <ImageEditorModal\r\n file={providerValues.editingFile}\r\n onClose={providerValues.closeImageEditor}\r\n onSave={providerValues.saveImageEdit}\r\n />\r\n </Suspense>\r\n )}\r\n </UploaderContextProvider>\r\n </UpupThemeProvider>\r\n )\r\n },\r\n)\r\n","import React from 'react'\r\nimport Icon from './Icon'\r\n\r\nexport default function DefaultLoaderIcon(): React.ReactElement | null {\r\n return (\r\n <Icon\r\n name=\"loader\"\r\n className=\"upup-animate-spin upup-text-3xl upup-text-[#6D6D6D]\"\r\n />\r\n )\r\n}\r\n","import React, { useEffect, useRef } from 'react'\r\nimport {\r\n useUploaderFiles,\r\n useUploaderI18n,\r\n useUploaderOptions,\r\n useUploaderRuntime,\r\n useUploaderSource,\r\n useUploaderTheme,\r\n useUploaderUploadControls,\r\n useUploaderView,\r\n} from '../context/UploaderContext'\r\nimport { devinoDark, devinoLight, logoDark, logoLight } from '../assets/logos'\r\nimport useUploaderPanel from '../hooks/useUploaderPanel'\r\nimport { cn } from '@useupup/core/internal'\r\nimport { UploadStatus, formatUiMessage } from '@useupup/core'\r\nimport SourceSelector from './SourceSelector'\r\nimport SourceView from './SourceView'\r\nimport FileList from './FileList'\r\nexport default function UploaderPanel(): React.ReactElement | null {\r\n const { files } = useUploaderFiles()\r\n const { activeSource } = useUploaderSource()\r\n const {\r\n sourceOverlayOpen,\r\n sourceOverlayClosing,\r\n dropRejected,\r\n closeSourceOverlay,\r\n } = useUploaderView()\r\n const { isOnline, motionMode } = useUploaderRuntime()\r\n const { translations: tr } = useUploaderI18n()\r\n const { isDark: dark } = useUploaderTheme()\r\n const { mini, showBranding } = useUploaderOptions()\r\n const {\r\n upload: { uploadStatus },\r\n } = useUploaderUploadControls()\r\n const {\r\n isDragging,\r\n absoluteIsDragging,\r\n absoluteHasBorder,\r\n handleDragOver,\r\n handleDragLeave,\r\n handleDrop,\r\n handlePaste,\r\n } = useUploaderPanel()\r\n\r\n // The dashed dropzone frame is the idle-view affordance: shown only when the\r\n // panel is an empty, at-rest dropzone (no active source, no add-more flow, no\r\n // files). It supersedes the old pulsing CSS border — the CSS border is kept\r\n // for the file-present states, so we suppress it whenever the frame is shown.\r\n const showDropzoneFrame =\r\n absoluteHasBorder && !activeSource && !sourceOverlayOpen && !files.size\r\n\r\n // The add-more overlay: once files exist, the source surface (selector, or a\r\n // chosen source's view) slides up over the still-mounted, dimmed file list.\r\n // With no files the same surface is the panel's primary content instead.\r\n // It stays mounted through the reverse close-slide (`sourceOverlayClosing`).\r\n const hasFiles = files.size > 0\r\n const sourceSurface = activeSource ? <SourceView /> : <SourceSelector />\r\n const showSourceOverlay =\r\n hasFiles &&\r\n (sourceOverlayOpen || sourceOverlayClosing || !!activeSource)\r\n\r\n // Focus management (minimal — no focus trap; the dimmed list is `inert`).\r\n // On open (or an inner view swap) pull focus into the overlay so keyboard/SR\r\n // users don't land on the inert list underneath, capturing the element that\r\n // triggered it. Skips the closing phase (open/activeSource both false there)\r\n // so the departing overlay never steals focus back.\r\n const overlayRef = useRef<HTMLDivElement>(null)\r\n const triggerRef = useRef<HTMLElement | null>(null)\r\n // Sheet swipe-to-dismiss state (refs — dragging must not re-render).\r\n const swipeStartYRef = useRef<number | null>(null)\r\n const swipedRef = useRef(false)\r\n useEffect(() => {\r\n if (!(sourceOverlayOpen || activeSource)) return\r\n const overlayEl = overlayRef.current\r\n if (!overlayEl) return\r\n if (\r\n !triggerRef.current &&\r\n document.activeElement instanceof HTMLElement\r\n )\r\n triggerRef.current = document.activeElement\r\n overlayEl.querySelector<HTMLElement>('button:not([disabled])')?.focus()\r\n }, [sourceOverlayOpen, activeSource])\r\n // When the overlay fully settles closed (past the reverse slide), restore\r\n // focus to the trigger if it's still in the document.\r\n useEffect(() => {\r\n if (sourceOverlayOpen || sourceOverlayClosing || activeSource) return\r\n const trigger = triggerRef.current\r\n if (!trigger) return\r\n triggerRef.current = null\r\n if (trigger.isConnected) trigger.focus()\r\n }, [sourceOverlayOpen, sourceOverlayClosing, activeSource])\r\n\r\n const dropEffectProps: React.AriaAttributes = {\r\n // aria-dropeffect is intentionally set for drag-and-drop\r\n // assistive-tech feedback; still honored by current screen readers.\r\n 'aria-dropeffect': isDragging ? 'copy' : 'none',\r\n }\r\n\r\n // Polite screen-reader announcement for upload-lifecycle transitions. It is a\r\n // pure projection of uploadStatus (no new event plumbing): when the status\r\n // flips, this text changes and assistive tech announces it via the live\r\n // region below. The panel itself is a non-interactive labelled region — the\r\n // click-to-browse affordance lives in the real buttons inside SourceSelector,\r\n // so no interactive element nests inside another (axe nested-interactive).\r\n const uploadAnnouncement =\r\n uploadStatus === UploadStatus.UPLOADING\r\n ? tr.announceUploadStarted\r\n : uploadStatus === UploadStatus.SUCCESSFUL\r\n ? tr.announceUploadComplete\r\n : uploadStatus === UploadStatus.FAILED\r\n ? tr.announceUploadFailed\r\n : ''\r\n\r\n return (\r\n <div\r\n data-testid=\"upup-dropzone\"\r\n data-upup-slot=\"uploader-panel\"\r\n data-motion={motionMode}\r\n role=\"region\"\r\n aria-label={tr.dropzoneLabel}\r\n {...dropEffectProps}\r\n className={cn(\r\n 'upup-relative upup-flex upup-flex-1 upup-flex-col upup-overflow-hidden upup-rounded-lg',\r\n {\r\n // Solid/dashed CSS border stays for the file-present states;\r\n // the idle dropzone uses the animated SVG frame instead.\r\n 'upup-border upup-border-[#0ea5e9]':\r\n absoluteHasBorder && !showDropzoneFrame,\r\n 'upup-border-[#38bdf8] dark:upup-border-[#38bdf8]':\r\n absoluteHasBorder && !showDropzoneFrame && dark,\r\n 'upup-border-dashed': !isDragging && !showDropzoneFrame,\r\n 'upup-bg-[#e0f2fe] upup-backdrop-blur-sm':\r\n absoluteIsDragging && !dark,\r\n 'upup-bg-[#0b2a3a] upup-backdrop-blur-sm dark:upup-bg-[#0b2a3a]':\r\n absoluteIsDragging && dark,\r\n },\r\n )}\r\n onDragOver={handleDragOver}\r\n onDragLeave={handleDragLeave}\r\n onDrop={handleDrop}\r\n onPaste={handlePaste}\r\n >\r\n <div role=\"status\" aria-live=\"polite\" className=\"upup-sr-only\">\r\n {uploadAnnouncement}\r\n </div>\r\n {/* Drop-rejection toast: a file was dropped onto a read-only drive\r\n picker (core DragDropController → transient-UI store). Auto-clears\r\n after the store's 3s window drives an unmount — no JS timer here. */}\r\n {dropRejected && (\r\n <div\r\n data-testid=\"upup-drop-rejected-toast\"\r\n data-upup-slot=\"drop-rejected-toast\"\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n className={cn(\r\n 'upup-animate-informer-in upup-absolute upup-inset-x-4 upup-top-4 upup-z-30 upup-flex upup-items-center upup-gap-2.5 upup-rounded-xl upup-px-3.5 upup-py-2.5 upup-text-[13px] upup-leading-snug upup-ring-1',\r\n dark\r\n ? 'upup-bg-rose-500/[0.14] upup-text-rose-200 upup-ring-rose-400/30'\r\n : 'upup-bg-rose-50 upup-text-rose-700 upup-ring-rose-300/60',\r\n )}\r\n >\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n width=\"16\"\r\n height=\"16\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.9\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden=\"true\"\r\n className=\"upup-flex-none\"\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\r\n <path d=\"M12 8v4\" />\r\n <path d=\"M12 16h.01\" />\r\n </svg>\r\n <span>\r\n {formatUiMessage(tr.dropRejected, {\r\n provider: dropRejected,\r\n })}\r\n </span>\r\n </div>\r\n )}\r\n {!isOnline && (\r\n <div\r\n className={cn(\r\n 'upup-absolute upup-inset-x-0 upup-top-0 upup-z-30 upup-px-3 upup-py-1.5 upup-text-center upup-text-xs upup-font-medium upup-text-white upup-bg-yellow-500',\r\n { 'upup-bg-yellow-600': dark },\r\n )}\r\n >\r\n No internet connection — uploads will resume when you\r\n reconnect.\r\n </div>\r\n )}\r\n {showDropzoneFrame && (\r\n <svg\r\n data-upup-slot=\"dropzone-frame\"\r\n aria-hidden=\"true\"\r\n // An <svg> is a replaced element: absolute insets position it\r\n // but do NOT stretch it (it keeps the 300x150 default), so the\r\n // frame needs its size stated explicitly alongside its inset.\r\n // Hugs the panel edge (4px) so the in-frame branding row has\r\n // breathing room above the bottom dashes.\r\n className=\"upup-pointer-events-none upup-absolute upup-inset-1 upup-h-[calc(100%-0.5rem)] upup-w-[calc(100%-0.5rem)]\"\r\n >\r\n <rect\r\n x=\"1\"\r\n y=\"1\"\r\n rx=\"14\"\r\n ry=\"14\"\r\n fill=\"none\"\r\n strokeWidth=\"1.5\"\r\n // 12px period (5 dash + 7 gap) — the fx-dash-march\r\n // keyframe shifts stroke-dashoffset by exactly -24 (two\r\n // periods), so the marching loop stays seamless.\r\n strokeDasharray=\"5 7\"\r\n stroke={\r\n dark\r\n ? absoluteIsDragging\r\n ? 'rgba(56,189,248,0.65)'\r\n : 'rgba(56,189,248,0.35)'\r\n : absoluteIsDragging\r\n ? 'rgba(2,132,199,0.7)'\r\n : 'rgba(2,132,199,0.4)'\r\n }\r\n // The dashes rest at idle and march only while a drag is\r\n // over the panel (interaction state, not a motion-pref\r\n // gate — the `[data-motion='off']` kill rule still stops\r\n // the march entirely when motion is off).\r\n className={cn(\r\n absoluteIsDragging && 'upup-animate-fx-dash-march',\r\n )}\r\n style={{\r\n width: 'calc(100% - 2px)',\r\n height: 'calc(100% - 2px)',\r\n }}\r\n />\r\n </svg>\r\n )}\r\n {/* Drag-over prompt: an explicit \"drop it here\" affordance (icon +\r\n text) so the drag state never reads as a mere glow. Pointer\r\n events pass through — the panel underneath owns the drop. */}\r\n {absoluteIsDragging && (\r\n <div\r\n data-testid=\"upup-drag-overlay\"\r\n data-upup-slot=\"drag-overlay\"\r\n aria-hidden=\"true\"\r\n className={cn(\r\n 'upup-animate-fx-view upup-pointer-events-none upup-absolute upup-inset-0 upup-z-10 upup-flex upup-flex-col upup-items-center upup-justify-center upup-gap-3',\r\n dark ? 'upup-bg-[#0b1220]/70' : 'upup-bg-white/70',\r\n )}\r\n >\r\n <span\r\n className={cn(\r\n 'upup-flex upup-h-16 upup-w-16 upup-items-center upup-justify-center upup-rounded-2xl',\r\n dark\r\n ? 'upup-bg-[#38bdf8]/15 upup-text-[#38bdf8]'\r\n : 'upup-bg-[#0284c7]/10 upup-text-[#0284c7]',\r\n )}\r\n >\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n width=\"30\"\r\n height=\"30\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.8\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden=\"true\"\r\n >\r\n <path d=\"M12 4v11\" />\r\n <path d=\"m7 10 5 5 5-5\" />\r\n <path d=\"M4 17v1a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-1\" />\r\n </svg>\r\n </span>\r\n <span\r\n className={cn(\r\n 'upup-text-[15px] upup-font-semibold',\r\n dark\r\n ? 'upup-text-[#e2e8f0]'\r\n : 'upup-text-[#0f172a]',\r\n )}\r\n >\r\n {tr.dropToUpload}\r\n </span>\r\n </div>\r\n )}\r\n {/* Content area (source surface / file list) flexes above the\r\n in-panel branding row so the dashed frame — inset-3 of this\r\n panel — wraps EVERYTHING including the brand, per the mock. */}\r\n <div className=\"upup-relative upup-flex upup-min-h-0 upup-flex-1 upup-flex-col\">\r\n {/* Idle primary: the source surface fills the panel when empty. */}\r\n {!hasFiles && sourceSurface}\r\n <FileList />\r\n </div>\r\n {/* Add-more DRAWER (states-tour-v2 sheet): the source surface slides\r\n up as a translucent bottom sheet over the dimmed, still-mounted\r\n file list — the files stay visible behind it so nothing feels\r\n lost. Swipe the grip down (or Escape / the grip click) to close. */}\r\n {showSourceOverlay && (\r\n <div\r\n ref={overlayRef}\r\n data-upup-slot=\"source-overlay\"\r\n // Modality applies only while the overlay is the live surface.\r\n // During the reverse close-slide it's departing (the list has\r\n // already un-dimmed/un-inerted), so drop the dialog role +\r\n // aria-modal and let pointer events fall through to the list —\r\n // otherwise AT/pointer briefly see two live surfaces.\r\n role={sourceOverlayClosing ? undefined : 'dialog'}\r\n aria-modal={sourceOverlayClosing ? undefined : 'true'}\r\n aria-label={tr.addingMoreFiles}\r\n onKeyDown={e => {\r\n if (e.key === 'Escape' && !sourceOverlayClosing)\r\n closeSourceOverlay()\r\n }}\r\n className={cn(\r\n 'upup-absolute upup-inset-x-3 upup-bottom-3 upup-top-11 upup-z-20 upup-flex upup-flex-col upup-overflow-hidden upup-rounded-2xl upup-ring-1 upup-ring-inset upup-backdrop-blur-md',\r\n sourceOverlayClosing\r\n ? 'upup-fx-overlay-close-slide upup-pointer-events-none'\r\n : 'upup-fx-overlay-slide',\r\n dark\r\n ? 'upup-bg-[#0b1220]/[0.85] upup-ring-white/[0.08] upup-shadow-[0_-18px_40px_-18px_rgba(0,0,0,0.65)]'\r\n : 'upup-bg-white/[0.85] upup-ring-black/[0.08] upup-shadow-[0_-18px_40px_-18px_rgba(15,23,42,0.25)]',\r\n )}\r\n >\r\n {/* Sheet grip: click closes; drag down past the threshold\r\n closes (pointer capture — no transitionend reliance). */}\r\n <button\r\n type=\"button\"\r\n data-testid=\"upup-sheet-grip\"\r\n data-upup-slot=\"sheet-grip\"\r\n aria-label={tr.overlayBack}\r\n onClick={() => {\r\n if (!swipedRef.current) closeSourceOverlay()\r\n swipedRef.current = false\r\n }}\r\n onPointerDown={e => {\r\n swipeStartYRef.current = e.clientY\r\n e.currentTarget.setPointerCapture(e.pointerId)\r\n }}\r\n onPointerMove={e => {\r\n const startY = swipeStartYRef.current\r\n const sheet = overlayRef.current\r\n if (startY === null || !sheet) return\r\n const dy = Math.max(0, e.clientY - startY)\r\n sheet.style.transition = 'none'\r\n sheet.style.transform = `translateY(${dy}px)`\r\n }}\r\n onPointerUp={e => {\r\n const startY = swipeStartYRef.current\r\n const sheet = overlayRef.current\r\n swipeStartYRef.current = null\r\n if (startY === null || !sheet) return\r\n const dy = Math.max(0, e.clientY - startY)\r\n sheet.style.transition = ''\r\n sheet.style.transform = ''\r\n if (dy > 72) {\r\n swipedRef.current = true\r\n closeSourceOverlay()\r\n }\r\n }}\r\n className=\"upup-absolute upup-left-1/2 upup-top-1.5 upup-z-10 upup-flex upup-h-6 upup-w-20 upup--translate-x-1/2 upup-cursor-grab upup-touch-none upup-items-center upup-justify-center upup-rounded-full\"\r\n >\r\n <span\r\n aria-hidden=\"true\"\r\n className={cn(\r\n 'upup-h-1 upup-w-10 upup-rounded-full',\r\n dark ? 'upup-bg-white/20' : 'upup-bg-black/20',\r\n )}\r\n />\r\n </button>\r\n {sourceSurface}\r\n </div>\r\n )}\r\n {/* Branding row INSIDE the panel (and the dashed frame). The\r\n add-more sheet slides over it, per the states-tour mock. Hidden\r\n while a source view is active — the drive browser / camera / url\r\n views own the full panel — and once files are selected: the\r\n file-list screen needs the vertical space (round-7 item 1). */}\r\n {!mini && showBranding && !activeSource && !hasFiles && (\r\n <div\r\n data-testid=\"upup-branding\"\r\n className=\"upup-flex upup-w-full upup-flex-none upup-flex-col upup-items-center upup-justify-between upup-gap-1 upup-px-6 upup-pb-5 upup-pt-1.5 md:upup-flex-row\"\r\n >\r\n <a\r\n href={'https://useupup.com/'}\r\n target={'_blank'}\r\n rel=\"noopener noreferrer\"\r\n className=\"upup-flex upup-items-center upup-gap-[5px]\"\r\n >\r\n {dark ? (\r\n <img\r\n src={logoDark}\r\n width={61}\r\n height={13}\r\n alt=\"logo-dark\"\r\n />\r\n ) : (\r\n <img\r\n src={logoLight}\r\n width={61}\r\n height={13}\r\n alt=\"logo-light\"\r\n />\r\n )}\r\n </a>\r\n <a\r\n href={'https://devino.ca/'}\r\n target={'_blank'}\r\n rel=\"noopener noreferrer\"\r\n className=\"upup-flex upup-flex-row upup-items-center upup-justify-end upup-gap-1\"\r\n >\r\n <span\r\n className={cn(\r\n 'upup-mr-0.5 upup-text-xs upup-leading-5 upup-text-[#6D6D6D] md:upup-text-sm',\r\n {\r\n 'upup-text-gray-300 dark:upup-text-gray-300':\r\n dark,\r\n },\r\n )}\r\n >\r\n {tr.builtBy}{' '}\r\n </span>\r\n {dark ? (\r\n <img\r\n src={devinoDark}\r\n width={61}\r\n height={13}\r\n alt=\"logo-dark\"\r\n />\r\n ) : (\r\n <img\r\n src={devinoLight}\r\n width={61}\r\n height={13}\r\n alt=\"logo-light\"\r\n />\r\n )}\r\n </a>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n","export const devinoDark =\r\n 'data:image/png;base64,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'\r\nexport const devinoLight =\r\n 'data:image/png;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP+w/w+fcfClL07rlQAAAA5lWElmTU0AKgAAAAgAAAAAAAAA0lOTAAAAAElFTkSuQmCC'\r\nexport const logoDark =\r\n 'data:image/png;base64,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'\r\nexport const logoLight =\r\n 'data:image/png;base64,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'\r\n","import {\r\n ClipboardEventHandler,\r\n DragEventHandler,\r\n useEffect,\r\n useRef,\r\n useSyncExternalStore,\r\n} from 'react'\r\nimport {\r\n DragDropController,\r\n type DragDropSnapshot,\r\n} from '@useupup/core/internal'\r\nimport {\r\n useUploaderFiles,\r\n useUploaderOptions,\r\n useUploaderRuntime,\r\n useUploaderView,\r\n} from '../context/UploaderContext'\r\n\r\nconst EMPTY_SNAPSHOT: DragDropSnapshot = {\r\n isDragging: false,\r\n absoluteIsDragging: false,\r\n absoluteHasBorder: true,\r\n}\r\nconst NOOP = () => {}\r\nconst NOOP_SUBSCRIBE = () => () => {}\r\nconst getEmptySnapshot = () => EMPTY_SNAPSHOT\r\n\r\nexport default function useUploaderPanel(): DragDropSnapshot & {\r\n handleDragOver: DragEventHandler<HTMLDivElement>\r\n handleDragLeave: DragEventHandler<HTMLDivElement>\r\n handleDrop: DragEventHandler<HTMLDivElement>\r\n handlePaste: ClipboardEventHandler<HTMLDivElement>\r\n} {\r\n const { core, orchestrator } = useUploaderRuntime()\r\n const { setFiles } = useUploaderFiles()\r\n const { flagDriveDropRejected } = useUploaderView()\r\n const options = useUploaderOptions()\r\n\r\n // Keep the latest values for the controller to read fresh (React re-reads each render).\r\n const latest = useRef({ setFiles, options, flagDriveDropRejected })\r\n latest.current = { setFiles, options, flagDriveDropRejected }\r\n\r\n // Construct lazily, only once core + orchestrator exist (both are null on the first render).\r\n const controllerRef = useRef<DragDropController | null>(null)\r\n if (!controllerRef.current && core && orchestrator) {\r\n controllerRef.current = new DragDropController({\r\n core,\r\n orchestrator,\r\n setFiles: files => {\r\n latest.current.setFiles(files)\r\n },\r\n // The file list derives from the orchestrator snapshot — derive the\r\n // border's file count from the same source so it stays in lockstep.\r\n filesSize: () => orchestrator.getSnapshot().files.size,\r\n options: () => latest.current.options,\r\n props: () => ({\r\n disableDragDrop: latest.current.options.disableDragDrop,\r\n isProcessing: latest.current.options.isProcessing,\r\n folderUploadAllowDrop:\r\n latest.current.options.folderUploadAllowDrop,\r\n }),\r\n onReadonlyDropRejected: source => {\r\n latest.current.flagDriveDropRejected(source)\r\n },\r\n })\r\n }\r\n const controller = controllerRef.current\r\n\r\n const snapshot = useSyncExternalStore(\r\n controller?.subscribe ?? NOOP_SUBSCRIBE,\r\n controller?.getSnapshot ?? getEmptySnapshot,\r\n getEmptySnapshot, // getServerSnapshot — required for SSR (renders the empty-state snapshot)\r\n )\r\n\r\n useEffect(() => {\r\n controller?.init()\r\n return () => controller?.destroy()\r\n }, [controller])\r\n\r\n // React synthetic events extend the native DOM events, so casting to DragEvent is safe.\r\n const handleDragOver: DragEventHandler<HTMLDivElement> = controller\r\n ? e => {\r\n controller.handleDragOver(e as unknown as DragEvent)\r\n }\r\n : NOOP\r\n const handleDragLeave: DragEventHandler<HTMLDivElement> = controller\r\n ? e => {\r\n controller.handleDragLeave(e as unknown as DragEvent)\r\n }\r\n : NOOP\r\n const handleDrop: DragEventHandler<HTMLDivElement> = controller\r\n ? e => {\r\n void controller.handleDrop(e as unknown as DragEvent)\r\n }\r\n : NOOP\r\n const handlePaste: ClipboardEventHandler<HTMLDivElement> = controller\r\n ? e => {\r\n controller.handlePaste(e as unknown as ClipboardEvent)\r\n }\r\n : NOOP\r\n\r\n return {\r\n isDragging: snapshot.isDragging,\r\n absoluteIsDragging: snapshot.absoluteIsDragging,\r\n absoluteHasBorder: snapshot.absoluteHasBorder,\r\n handleDragOver,\r\n handleDragLeave,\r\n handleDrop,\r\n handlePaste,\r\n }\r\n}\r\n","import React, { useCallback } from 'react'\r\nimport Icon from './Icon'\r\nimport { StackedFilesIcon, StorageIcon } from './Icons'\r\nimport { formatUiMessage as t, pluralUiMessage as plural } from '@useupup/core'\r\nimport { cn } from '@useupup/core/internal'\r\nimport {\r\n useUploaderFiles,\r\n useUploaderI18n,\r\n useUploaderOptions,\r\n useUploaderRuntime,\r\n useUploaderTheme,\r\n} from '../context/UploaderContext'\r\nimport useSourceSelector from '../hooks/useSourceSelector'\r\n\r\n// Regular chips fit at most 4 per row inside the max-w-[420px] grid, so up to 8\r\n// sources wrap into balanced rows; 9 would wrap 4/4/1. Past this count the chips\r\n// switch to the compact size, which fits 5 per row (5/4).\r\nconst COMPACT_SOURCE_THRESHOLD = 8\r\n\r\nexport default function SourceSelector(): React.ReactElement | null {\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- inputRef is required for direct webkitdirectory/directory DOM wiring; openFilePicker() cannot toggle those attributes\r\n const { core, inputRef, openFilePicker } = useUploaderRuntime()\r\n const { translations: tr } = useUploaderI18n()\r\n const { setFiles } = useUploaderFiles()\r\n const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme()\r\n const {\r\n mini,\r\n allowedFileTypes,\r\n multiple,\r\n limit,\r\n maxFileSize,\r\n folderPickerButtonVisible,\r\n } = useUploaderOptions()\r\n\r\n // Idle limits caption (data-upup-slot=\"limits-caption\"): iconified file-count\r\n // and per-file size limits, plus a leading text-only type-restriction segment\r\n // so no constraint the consumer configured is dropped. Each segment renders\r\n // only when its limit is actually set.\r\n let typeConstraint: string | null = null\r\n if (\r\n allowedFileTypes &&\r\n allowedFileTypes !== '*/*' &&\r\n allowedFileTypes !== '*'\r\n ) {\r\n const humanized = allowedFileTypes\r\n .split(',')\r\n .map(s => s.trim())\r\n .map(m => {\r\n if (m.startsWith('.')) return m\r\n const [type, sub] = m.split('/')\r\n if (!type || !sub) return m\r\n if (sub === '*')\r\n return type.charAt(0).toUpperCase() + type.slice(1) + 's'\r\n return sub.toUpperCase()\r\n })\r\n .join(', ')\r\n typeConstraint = humanized + ' only'\r\n }\r\n const showFilesLimit = limit > 1\r\n const showSizeLimit = !!(maxFileSize?.size && maxFileSize?.unit)\r\n const hasLimitsCaption = !!typeConstraint || showFilesLimit || showSizeLimit\r\n const { chosenSources, handleSourceClick, handleInputFileChange } =\r\n useSourceSelector()\r\n const compact = chosenSources.length > COMPACT_SOURCE_THRESHOLD\r\n\r\n const handleBrowseFilesClick = useCallback(() => {\r\n if (inputRef.current) {\r\n inputRef.current.removeAttribute('webkitdirectory')\r\n inputRef.current.removeAttribute('directory')\r\n }\r\n openFilePicker()\r\n core?.emit('browse-files', {})\r\n }, [core, inputRef, openFilePicker])\r\n\r\n const handleSelectFolderClick = useCallback(async () => {\r\n const fsWindow = window as Window & {\r\n showDirectoryPicker?: () => Promise<FileSystemDirectoryHandle>\r\n }\r\n if (fsWindow.showDirectoryPicker) {\r\n try {\r\n const directoryHandle = await fsWindow.showDirectoryPicker()\r\n const files: File[] = []\r\n\r\n type IterableDirHandle = {\r\n values(): AsyncIterableIterator<\r\n FileSystemHandle & {\r\n kind: string\r\n getFile: () => Promise<File>\r\n }\r\n >\r\n }\r\n async function getFiles(\r\n dirHandle: IterableDirHandle,\r\n path = '',\r\n ) {\r\n for await (const entry of dirHandle.values()) {\r\n const newPath = path\r\n ? `${path}/${entry.name}`\r\n : entry.name\r\n if (entry.kind === 'file') {\r\n const pickedFile = await entry.getFile()\r\n const file = new File(\r\n [await pickedFile.arrayBuffer()],\r\n pickedFile.name,\r\n {\r\n type: pickedFile.type,\r\n lastModified: pickedFile.lastModified,\r\n },\r\n )\r\n try {\r\n Object.defineProperty(\r\n file,\r\n 'webkitRelativePath',\r\n {\r\n value: newPath,\r\n configurable: true,\r\n writable: true,\r\n },\r\n )\r\n Object.defineProperty(file, 'relativePath', {\r\n value: newPath,\r\n configurable: true,\r\n writable: true,\r\n })\r\n } catch {\r\n // upup-catch: defineProperty can throw on frozen File in some engines; Object.assign is the fallback path\r\n Object.assign(file, { relativePath: newPath })\r\n }\r\n files.push(file)\r\n } else if (entry.kind === 'directory') {\r\n await getFiles(\r\n entry as unknown as IterableDirHandle,\r\n newPath,\r\n )\r\n }\r\n }\r\n }\r\n await getFiles(directoryHandle as unknown as IterableDirHandle)\r\n if (files.length > 0) {\r\n setFiles(files)\r\n core?.emit('folder-select', { count: files.length })\r\n if (inputRef.current) {\r\n inputRef.current.value = ''\r\n }\r\n }\r\n } catch (error) {\r\n const name = error instanceof DOMException ? error.name : ''\r\n if (name !== 'AbortError') {\r\n throw error\r\n }\r\n // User cancelled, do nothing.\r\n }\r\n } else {\r\n // Fallback to existing behavior\r\n if (inputRef.current) {\r\n inputRef.current.setAttribute('webkitdirectory', 'true')\r\n inputRef.current.setAttribute('directory', 'true')\r\n }\r\n openFilePicker()\r\n core?.emit('folder-select', { count: 0 })\r\n }\r\n }, [core, inputRef, openFilePicker, setFiles])\r\n\r\n return (\r\n <div\r\n data-testid=\"upup-source-selector\"\r\n data-upup-slot=\"source-selector\"\r\n // Centered in BOTH the idle panel and the add-more sheet — the sheet\r\n // supplies its own chrome (grip), so the selector no longer swaps in\r\n // a header bar (which also un-centered the capped-width chip grid).\r\n className=\"upup-animate-fx-view upup-relative upup-flex upup-h-full upup-flex-col upup-items-center upup-justify-center upup-gap-6 upup-rounded-lg upup-px-4 upup-py-6\"\r\n >\r\n {!mini && (\r\n <>\r\n <div\r\n className={cn(\r\n 'upup-flex upup-flex-wrap upup-items-center upup-justify-center upup-gap-x-1.5 upup-gap-y-1 upup-px-2 upup-text-center upup-text-base upup-font-medium md:upup-text-lg',\r\n {\r\n 'upup-text-[#242634]': !dark,\r\n 'upup-text-[#e2e8f0] dark:upup-text-[#e2e8f0]':\r\n dark,\r\n },\r\n )}\r\n >\r\n <span>{tr.dropFilesHere}</span>\r\n <button\r\n type=\"button\"\r\n data-testid=\"upup-browse-files\"\r\n className={cn(\r\n 'upup-cursor-pointer upup-rounded upup-font-semibold focus-visible:upup-outline-none focus-visible:upup-ring-2 focus-visible:upup-ring-[#38bdf8]',\r\n {\r\n 'upup-text-[#0284c7]': !dark,\r\n 'upup-text-[#38bdf8] dark:upup-text-[#38bdf8]':\r\n dark,\r\n },\r\n )}\r\n onClick={handleBrowseFilesClick}\r\n >\r\n {tr.browseFiles}\r\n </button>\r\n {folderPickerButtonVisible && (\r\n <>\r\n <span>{tr.or}</span>\r\n <button\r\n type=\"button\"\r\n className={cn(\r\n 'upup-cursor-pointer upup-rounded upup-font-semibold focus-visible:upup-outline-none focus-visible:upup-ring-2 focus-visible:upup-ring-[#38bdf8]',\r\n {\r\n 'upup-text-[#0284c7]': !dark,\r\n 'upup-text-[#38bdf8] dark:upup-text-[#38bdf8]':\r\n dark,\r\n },\r\n )}\r\n onClick={() => {\r\n void handleSelectFolderClick()\r\n }}\r\n >\r\n {tr.selectAFolder}\r\n </button>\r\n </>\r\n )}\r\n <span>{tr.orImportFrom}</span>\r\n </div>\r\n <div\r\n className={cn(\r\n compact\r\n ? 'upup-flex upup-max-w-[420px] upup-flex-wrap upup-items-start upup-justify-center upup-gap-x-3 upup-gap-y-4'\r\n : 'upup-flex upup-max-w-[420px] upup-flex-wrap upup-items-start upup-justify-center upup-gap-x-6 upup-gap-y-5',\r\n slotClasses.sourceButtonList,\r\n )}\r\n >\r\n {chosenSources.map(({ Icon: SourceIcon, id, name }) => (\r\n <button\r\n key={id}\r\n type=\"button\"\r\n data-testid={`upup-source-${id}`}\r\n className={cn(\r\n // hover:shadow-none cancels fx-hover-lift's\r\n // glow here: the chip button box is\r\n // transparent (icon + label), so the shadow\r\n // would halo empty space, not a card.\r\n compact\r\n ? 'upup-fx-hover-lift upup-fx-press upup-fx-icon-nudge upup-group upup-flex upup-w-[62px] upup-cursor-pointer upup-flex-col upup-items-center upup-gap-[7px] upup-rounded-[12px] focus-visible:upup-outline-none focus-visible:upup-ring-2 focus-visible:upup-ring-[#38bdf8] hover:upup-shadow-none'\r\n : 'upup-fx-hover-lift upup-fx-press upup-fx-icon-nudge upup-group upup-flex upup-w-[66px] upup-cursor-pointer upup-flex-col upup-items-center upup-gap-[9px] upup-rounded-[14px] focus-visible:upup-outline-none focus-visible:upup-ring-2 focus-visible:upup-ring-[#38bdf8] hover:upup-shadow-none',\r\n slotClasses.sourceButton,\r\n )}\r\n onClick={() => {\r\n handleSourceClick(id)\r\n }}\r\n >\r\n <span\r\n className={cn(\r\n compact\r\n ? 'upup-flex upup-h-[42px] upup-w-[42px] upup-items-center upup-justify-center upup-rounded-[12px] upup-ring-1 upup-transition-colors'\r\n : 'upup-flex upup-h-[52px] upup-w-[52px] upup-items-center upup-justify-center upup-rounded-[14px] upup-ring-1 upup-transition-colors',\r\n {\r\n 'upup-bg-white upup-ring-black/[0.07] group-hover:upup-bg-slate-50':\r\n !dark,\r\n 'upup-bg-white/[0.055] upup-ring-white/[0.06] group-hover:upup-bg-white/[0.09] dark:upup-bg-white/[0.055] dark:upup-ring-white/[0.06]':\r\n dark,\r\n },\r\n )}\r\n >\r\n <SourceIcon\r\n className={cn(\r\n // The registry glyphs carry ~30% internal\r\n // viewBox padding; the 32px (compact) /\r\n // 40px (regular) box keeps the visible\r\n // glyph reading confidently sized.\r\n compact\r\n ? 'upup-h-8 upup-w-8'\r\n : 'upup-h-10 upup-w-10',\r\n slotClasses.sourceButtonIcon,\r\n )}\r\n />\r\n </span>\r\n <span\r\n className={cn(\r\n 'upup-text-xs upup-leading-none',\r\n {\r\n 'upup-text-[#6D6D6D]': !dark,\r\n 'upup-text-[#94a3b8] dark:upup-text-[#94a3b8]':\r\n dark,\r\n },\r\n slotClasses.sourceButtonText,\r\n )}\r\n >\r\n {name}\r\n </span>\r\n </button>\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n <input\r\n type=\"file\"\r\n name=\"upup-files\"\r\n accept={allowedFileTypes}\r\n className=\"upup-hidden\"\r\n data-testid=\"upup-file-input\"\r\n aria-hidden=\"true\"\r\n tabIndex={-1}\r\n ref={inputRef}\r\n multiple={multiple}\r\n onChange={handleInputFileChange}\r\n />\r\n {mini ? (\r\n <button\r\n type=\"button\"\r\n onClick={handleBrowseFilesClick}\r\n className=\"upup-flex upup-cursor-pointer upup-flex-col upup-items-center upup-justify-center upup-gap-2 upup-rounded-lg upup-p-2\"\r\n >\r\n <Icon\r\n name=\"upload\"\r\n size={32}\r\n className={cn(\r\n 'upup-h-16 upup-w-16 md:upup-h-20 md:upup-w-20',\r\n {\r\n 'upup-text-[#0B0B0B]': !dark,\r\n 'upup-text-white dark:upup-text-white': dark,\r\n },\r\n )}\r\n />\r\n <p\r\n className={cn('px-6 upup-text-center upup-text-xs', {\r\n 'upup-text-[#6D6D6D] dark:upup-text-gray-400':\r\n !dark,\r\n 'upup-text-gray-400 dark:upup-text-gray-500': dark,\r\n })}\r\n >\r\n Drag or browse to upload\r\n </p>\r\n </button>\r\n ) : (\r\n hasLimitsCaption && (\r\n <div\r\n data-upup-slot=\"limits-caption\"\r\n className={cn(\r\n 'upup-flex upup-flex-wrap upup-items-center upup-justify-center upup-gap-x-2.5 upup-gap-y-1 upup-px-3 upup-text-center upup-text-xs',\r\n {\r\n 'upup-text-[#6D6D6D]': !dark,\r\n 'upup-text-[#94a3b8] dark:upup-text-[#94a3b8]':\r\n dark,\r\n },\r\n )}\r\n >\r\n {typeConstraint && <span>{typeConstraint}</span>}\r\n {typeConstraint &&\r\n (showFilesLimit || showSizeLimit) && (\r\n <span aria-hidden=\"true\">·</span>\r\n )}\r\n {showFilesLimit && (\r\n <span className=\"upup-inline-flex upup-items-center upup-gap-1.5\">\r\n <span\r\n aria-hidden=\"true\"\r\n className=\"upup-inline-flex\"\r\n >\r\n <StackedFilesIcon className=\"upup-h-4 upup-w-4\" />\r\n </span>\r\n {t(plural(tr, 'filesMax', limit), {\r\n count: limit,\r\n })}\r\n </span>\r\n )}\r\n {showFilesLimit && showSizeLimit && (\r\n <span aria-hidden=\"true\">·</span>\r\n )}\r\n {showSizeLimit && (\r\n <span className=\"upup-inline-flex upup-items-center upup-gap-1.5\">\r\n <span\r\n aria-hidden=\"true\"\r\n className=\"upup-inline-flex\"\r\n >\r\n <StorageIcon className=\"upup-h-4 upup-w-4\" />\r\n </span>\r\n {t(tr.sizeEach, {\r\n size: maxFileSize?.size ?? 0,\r\n unit: maxFileSize?.unit ?? '',\r\n })}\r\n </span>\r\n )}\r\n </div>\r\n )\r\n )}\r\n </div>\r\n )\r\n}\r\n","import type { ReactElement } from 'react'\r\nimport Icon from './Icon'\r\n\r\ntype SourceIconProps = { className?: string | undefined }\r\n\r\nexport const MyDeviceIcon = ({ className }: SourceIconProps): ReactElement => (\r\n <Icon name=\"my-device\" className={className} />\r\n)\r\nexport const BoxIcon = ({ className }: SourceIconProps): ReactElement => (\r\n <Icon name=\"box\" className={className} />\r\n)\r\nexport const DropboxIcon = ({ className }: SourceIconProps): ReactElement => (\r\n <Icon name=\"dropbox\" className={className} />\r\n)\r\nexport const GoogleDriveIcon = ({\r\n className,\r\n}: SourceIconProps): ReactElement => (\r\n <Icon name=\"google-drive\" className={className} />\r\n)\r\nexport const OneDriveIcon = ({ className }: SourceIconProps): ReactElement => (\r\n <Icon name=\"one-drive\" className={className} />\r\n)\r\nexport const LinkIcon = ({ className }: SourceIconProps): ReactElement => (\r\n <Icon name=\"link\" className={className} />\r\n)\r\nexport const CameraIcon = ({ className }: SourceIconProps): ReactElement => (\r\n <Icon name=\"camera\" className={className} />\r\n)\r\nexport const AudioIcon = ({ className }: SourceIconProps): ReactElement => (\r\n <Icon name=\"audio\" className={className} />\r\n)\r\nexport const ScreenCaptureIcon = ({\r\n className,\r\n}: SourceIconProps): ReactElement => (\r\n <Icon name=\"screen-capture\" className={className} />\r\n)\r\nexport const StackedFilesIcon = ({\r\n className,\r\n}: SourceIconProps): ReactElement => (\r\n <Icon name=\"stacked-files\" className={className} />\r\n)\r\nexport const StorageIcon = ({ className }: SourceIconProps): ReactElement => (\r\n <Icon name=\"storage\" className={className} />\r\n)\r\n","import { ChangeEventHandler, useCallback, useMemo } from 'react'\r\nimport { FileSource } from '@useupup/core'\r\nimport {\r\n useUploaderFiles,\r\n useUploaderI18n,\r\n useUploaderOptions,\r\n useUploaderRuntime,\r\n useUploaderSource,\r\n} from '../context/UploaderContext'\r\nimport { uploadSourceObject } from '../lib/constants'\r\n\r\ntype ChosenSource =\r\n (typeof uploadSourceObject)[keyof typeof uploadSourceObject] & {\r\n name: string\r\n }\r\n\r\nexport default function useSourceSelector(): {\r\n chosenSources: ChosenSource[]\r\n handleSourceClick: (sourceId: FileSource) => void\r\n handleInputFileChange: ChangeEventHandler<HTMLInputElement>\r\n} {\r\n const { core, openFilePicker } = useUploaderRuntime()\r\n const { setActiveSource } = useUploaderSource()\r\n const { setFiles } = useUploaderFiles()\r\n const { translations } = useUploaderI18n()\r\n const { sources, onIntegrationClick } = useUploaderOptions()\r\n\r\n const chosenSources = useMemo(\r\n () =>\r\n Object.values(uploadSourceObject)\r\n .filter(item => sources.includes(item.id))\r\n .map(item => ({\r\n ...item,\r\n name: translations[item.nameKey],\r\n })),\r\n [sources, translations],\r\n )\r\n\r\n const handleSourceClick = useCallback(\r\n (sourceId: FileSource) => {\r\n onIntegrationClick(sourceId)\r\n core?.emit('source-click', { sourceId })\r\n if (sourceId === FileSource.LOCAL) openFilePicker()\r\n else setActiveSource(sourceId)\r\n },\r\n [core, openFilePicker, onIntegrationClick, setActiveSource],\r\n )\r\n\r\n const handleInputFileChange: ChangeEventHandler<HTMLInputElement> =\r\n useCallback(\r\n e => {\r\n setFiles(Array.from(e.currentTarget.files || []))\r\n e.currentTarget.value = ''\r\n },\r\n [setFiles],\r\n )\r\n\r\n return {\r\n chosenSources,\r\n handleSourceClick,\r\n handleInputFileChange,\r\n }\r\n}\r\n","import type { Translations } from '@useupup/core'\r\nimport { FileSource } from '@useupup/core'\r\nimport { lazy } from 'react'\r\nimport {\r\n AudioIcon,\r\n BoxIcon,\r\n CameraIcon,\r\n DropboxIcon,\r\n GoogleDriveIcon,\r\n LinkIcon,\r\n MyDeviceIcon,\r\n OneDriveIcon,\r\n ScreenCaptureIcon,\r\n} from '../components/Icons'\r\nimport UrlUploader from '../components/UrlUploader'\r\n\r\nexport { sourceNameKeys } from '@useupup/core/internal'\r\n\r\nconst AudioUploader = lazy(() => import('../components/AudioUploader'))\r\nconst BoxUploader = lazy(() => import('../components/BoxUploader'))\r\nconst CameraUploader = lazy(() => import('../components/CameraUploader'))\r\nconst DropboxUploader = lazy(() => import('../components/DropboxUploader'))\r\nconst GoogleDriveUploader = lazy(\r\n () => import('../components/GoogleDriveUploader'),\r\n)\r\nconst OneDriveUploader = lazy(() => import('../components/OneDriveUploader'))\r\nconst ScreenCaptureUploader = lazy(\r\n () => import('../components/ScreenCaptureUploader'),\r\n)\r\n\r\nexport const uploadSourceObject = {\r\n [FileSource.LOCAL]: {\r\n id: FileSource.LOCAL,\r\n nameKey: 'myDevice' as keyof Translations,\r\n Icon: MyDeviceIcon,\r\n Component: undefined,\r\n },\r\n [FileSource.GOOGLE_DRIVE]: {\r\n id: FileSource.GOOGLE_DRIVE,\r\n nameKey: 'googleDrive' as keyof Translations,\r\n Icon: GoogleDriveIcon,\r\n Component: GoogleDriveUploader,\r\n },\r\n [FileSource.ONE_DRIVE]: {\r\n id: FileSource.ONE_DRIVE,\r\n nameKey: 'oneDrive' as keyof Translations,\r\n Icon: OneDriveIcon,\r\n Component: OneDriveUploader,\r\n },\r\n [FileSource.DROPBOX]: {\r\n id: FileSource.DROPBOX,\r\n nameKey: 'dropbox' as keyof Translations,\r\n Icon: DropboxIcon,\r\n Component: DropboxUploader,\r\n },\r\n [FileSource.BOX]: {\r\n id: FileSource.BOX,\r\n nameKey: 'box' as keyof Translations,\r\n Icon: BoxIcon,\r\n Component: BoxUploader,\r\n },\r\n [FileSource.URL]: {\r\n id: FileSource.URL,\r\n nameKey: 'link' as keyof Translations,\r\n Icon: LinkIcon,\r\n Component: UrlUploader,\r\n },\r\n [FileSource.CAMERA]: {\r\n id: FileSource.CAMERA,\r\n nameKey: 'camera' as keyof Translations,\r\n Icon: CameraIcon,\r\n Component: CameraUploader,\r\n },\r\n [FileSource.MICROPHONE]: {\r\n id: FileSource.MICROPHONE,\r\n nameKey: 'audio' as keyof Translations,\r\n Icon: AudioIcon,\r\n Component: AudioUploader,\r\n },\r\n [FileSource.SCREEN]: {\r\n id: FileSource.SCREEN,\r\n nameKey: 'screenCapture' as keyof Translations,\r\n Icon: ScreenCaptureIcon,\r\n Component: ScreenCaptureUploader,\r\n },\r\n}\r\n","import React, { useState } from 'react'\r\nimport {\r\n useUploaderFiles,\r\n useUploaderI18n,\r\n useUploaderOptions,\r\n useUploaderRuntime,\r\n useUploaderSource,\r\n useUploaderTheme,\r\n} from '../context/UploaderContext'\r\nimport useFetchFileByUrl from '../hooks/useFetchFileByUrl'\r\nimport { cn } from '@useupup/core/internal'\r\nimport SourceViewContainer from './shared/SourceViewContainer'\r\n\r\nexport default function UrlUploader(): React.ReactElement | null {\r\n const { core } = useUploaderRuntime()\r\n const { setFiles } = useUploaderFiles()\r\n const { setActiveSource } = useUploaderSource()\r\n const { translations: tr } = useUploaderI18n()\r\n const {\r\n icons: { LoaderIcon },\r\n } = useUploaderOptions()\r\n const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme()\r\n const [url, setUrl] = useState('')\r\n const { loading, fetchImage } = useFetchFileByUrl()\r\n\r\n const handleFormSubmit = async (\r\n e: React.SyntheticEvent<HTMLFormElement>,\r\n ) => {\r\n e.preventDefault()\r\n core?.emit('url-submit', { url })\r\n const file = await fetchImage(url)\r\n if (file) {\r\n Object.assign(file, {\r\n url,\r\n })\r\n setFiles([file])\r\n setUrl('')\r\n setActiveSource(undefined)\r\n }\r\n }\r\n\r\n return (\r\n <SourceViewContainer\r\n data-testid=\"upup-url-uploader\"\r\n data-upup-slot=\"url-uploader\"\r\n >\r\n <form\r\n onSubmit={e => {\r\n void handleFormSubmit(e)\r\n }}\r\n className=\"upup-flex upup-w-full upup-max-w-[380px] upup-flex-col upup-items-center upup-gap-3 upup-px-6\"\r\n >\r\n <span\r\n className={cn(\r\n 'upup-flex upup-h-12 upup-w-12 upup-items-center upup-justify-center upup-rounded-2xl',\r\n dark\r\n ? 'upup-bg-[#38bdf8]/15 upup-text-[#38bdf8]'\r\n : 'upup-bg-[#0284c7]/10 upup-text-[#0284c7]',\r\n )}\r\n aria-hidden=\"true\"\r\n >\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n width=\"22\"\r\n height=\"22\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <path d=\"M9.5 14.5l5-5\" />\r\n <path d=\"M11 6.5l1-1a3.6 3.6 0 0 1 5 5l-2 2\" />\r\n <path d=\"M13 17.5l-1 1a3.6 3.6 0 0 1-5-5l2-2\" />\r\n </svg>\r\n </span>\r\n <input\r\n type=\"url\"\r\n name=\"upup-url\"\r\n aria-label={tr.enterFileUrl}\r\n placeholder={tr.enterFileUrl}\r\n className={cn(\r\n 'upup-w-full upup-rounded-xl upup-px-3.5 upup-py-2.5 upup-text-sm upup-outline-none upup-ring-1 upup-transition-shadow focus:upup-ring-2 focus:upup-ring-[#38bdf8]',\r\n dark\r\n ? 'upup-bg-white/[0.06] upup-text-[#e2e8f0] upup-ring-white/[0.1] placeholder:upup-text-[#64748b]'\r\n : 'upup-bg-white upup-text-[#0f172a] upup-ring-black/[0.08] placeholder:upup-text-[#94a3b8]',\r\n slotClasses.urlInput,\r\n )}\r\n value={url}\r\n onChange={e => {\r\n setUrl(e.currentTarget.value)\r\n }}\r\n />\r\n <button\r\n className={cn(\r\n 'upup-fx-sheen-sweep upup-fx-press upup-w-full upup-rounded-xl upup-px-4 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white disabled:upup-cursor-not-allowed disabled:upup-opacity-50',\r\n dark\r\n ? 'upup-bg-[#38bdf8] dark:upup-bg-[#38bdf8]'\r\n : 'upup-bg-[#0ea5e9]',\r\n slotClasses.urlFetchButton,\r\n )}\r\n type=\"submit\"\r\n disabled={!url}\r\n >\r\n {loading ? <LoaderIcon /> : tr.fetch}\r\n </button>\r\n </form>\r\n </SourceViewContainer>\r\n )\r\n}\r\n","import React, { Suspense, useState } from 'react'\r\nimport {\r\n useUploaderI18n,\r\n useUploaderOptions,\r\n useUploaderRuntime,\r\n useUploaderSource,\r\n useUploaderTheme,\r\n} from '../context/UploaderContext'\r\nimport { SourceViewHeaderExtraContext } from '../context/SourceViewHeaderExtraContext'\r\nimport { uploadSourceObject } from '../lib/constants'\r\nimport { cn } from '@useupup/core/internal'\r\nimport DefaultLoaderIcon from './DefaultLoaderIcon'\r\n\r\nexport default function SourceView(): React.ReactElement | null {\r\n const { core } = useUploaderRuntime()\r\n const { activeSource, setActiveSource } = useUploaderSource()\r\n const { translations: tr } = useUploaderI18n()\r\n const { mini } = useUploaderOptions()\r\n const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme()\r\n // Portal host for a source view's header extras (drive avatar + log out);\r\n // lives left of Back. `empty:hidden` keeps the flex gap from showing when\r\n // no view portals anything in.\r\n const [headerExtraHost, setHeaderExtraHost] = useState<HTMLElement | null>(\r\n null,\r\n )\r\n const UploadComponent =\r\n activeSource && uploadSourceObject[activeSource].Component\r\n const Icon = activeSource && uploadSourceObject[activeSource].Icon\r\n\r\n if (!UploadComponent || mini || !activeSource || !Icon) return null\r\n\r\n return (\r\n <div\r\n className=\"upup-animate-fx-view upup-grid upup-h-full upup-w-full upup-grid-rows-[auto,1fr]\"\r\n data-upup-slot=\"source-view\"\r\n >\r\n {/* Transparent header on the panel gradient (no inner box): the\r\n provider icon + name fill the row; \"Back\" returns to sources. */}\r\n <div\r\n className={cn(\r\n 'upup-flex upup-items-center upup-justify-between upup-gap-2 upup-px-3 upup-py-2 upup-text-sm upup-font-medium',\r\n dark ? 'upup-text-[#FAFAFA]' : 'upup-text-[#0f172a]',\r\n slotClasses.sourceViewHeader,\r\n )}\r\n >\r\n <span className=\"upup-flex upup-items-center upup-gap-2\">\r\n <Icon />\r\n <span>{tr[uploadSourceObject[activeSource].nameKey]}</span>\r\n </span>\r\n <span className=\"upup-flex upup-items-center upup-gap-2.5\">\r\n <span\r\n ref={setHeaderExtraHost}\r\n data-upup-slot=\"source-view-header-extra\"\r\n className=\"upup-flex upup-items-center upup-gap-2.5 empty:upup-hidden\"\r\n />\r\n <button\r\n className={cn(\r\n 'upup-rounded-md upup-p-1 upup-text-[#0284c7] upup-transition-all upup-duration-300',\r\n {\r\n 'upup-text-[#38bdf8] dark:upup-text-[#38bdf8]':\r\n dark,\r\n },\r\n slotClasses.sourceViewCancelButton,\r\n )}\r\n onClick={() => {\r\n core?.emit('source-view-cancel', {\r\n sourceId: activeSource,\r\n })\r\n setActiveSource(undefined)\r\n }}\r\n type=\"button\"\r\n >\r\n {tr.overlayBack}\r\n </button>\r\n </span>\r\n </div>\r\n <SourceViewHeaderExtraContext.Provider value={headerExtraHost}>\r\n <Suspense\r\n fallback={\r\n <div className=\"upup-flex upup-h-full upup-items-center upup-justify-center\">\r\n <DefaultLoaderIcon />\r\n </div>\r\n }\r\n >\r\n <UploadComponent />\r\n </Suspense>\r\n </SourceViewHeaderExtraContext.Provider>\r\n </div>\r\n )\r\n}\r\n","import { useVirtualizer } from '@tanstack/react-virtual'\r\nimport React, { memo, useRef } from 'react'\r\nimport Icon from './Icon'\r\nimport { formatUiMessage as t, pluralUiMessage as plural } from '@useupup/core'\r\nimport { cn, isUploadActive } from '@useupup/core/internal'\r\nimport { UploadStatus } from '@useupup/core'\r\nimport {\r\n useUploaderFiles,\r\n useUploaderI18n,\r\n useUploaderOptions,\r\n useUploaderSource,\r\n useUploaderTheme,\r\n useUploaderUploadControls,\r\n useUploaderView,\r\n} from '../context/UploaderContext'\r\nimport FileItem from './FileItem'\r\nimport FileHero from './FileHero'\r\nimport UploaderHeader from './shared/UploaderHeader'\r\nimport ProgressBar from './shared/ProgressBar'\r\nimport FileSuccessCheck from './shared/FileSuccessCheck'\r\nimport { isListViewForced } from '../lib/view-mode'\r\nimport { useTilesPerRow } from '../lib/use-tiles-per-row'\r\n\r\nconst VIRTUAL_SCROLL_THRESHOLD = 20\r\nconst ESTIMATED_ITEM_HEIGHT = 76 // px — approximate FileItem row height\r\n\r\nfunction formatBytes(bytes: number): string {\r\n if (bytes === 0) return '0 B'\r\n const k = 1024\r\n const sizes = ['B', 'KB', 'MB', 'GB']\r\n const i = Math.floor(Math.log(bytes) / Math.log(k))\r\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i] ?? ''}`\r\n}\r\n\r\nfunction formatEta(seconds: number): string {\r\n if (seconds <= 0 || !isFinite(seconds)) return ''\r\n const m = Math.floor(seconds / 60)\r\n const s = seconds % 60\r\n if (m > 0) return `${m}m ${s}s left`\r\n return `${s}s left`\r\n}\r\n\r\nexport default memo(function FileList() {\r\n const { viewMode, sourceOverlayOpen, openSourceOverlay } = useUploaderView()\r\n const { activeSource } = useUploaderSource()\r\n const { files, leavingFileIds } = useUploaderFiles()\r\n const { translations: tr } = useUploaderI18n()\r\n const {\r\n upload: {\r\n startUpload,\r\n retryUpload,\r\n uploadStatus,\r\n uploadError,\r\n uploadErrorCode,\r\n totalProgress,\r\n uploadSpeed,\r\n uploadEta,\r\n uploadedBytes,\r\n totalBytes,\r\n },\r\n handleDone,\r\n handleCancel,\r\n handlePause,\r\n handleResume,\r\n } = useUploaderUploadControls()\r\n const {\r\n isProcessing,\r\n resumable,\r\n limit,\r\n quietCompletion,\r\n icons: { ContainerAddMoreIcon },\r\n } = useUploaderOptions()\r\n const {\r\n isDark: dark,\r\n slotOverrides: slotClasses,\r\n slots: themeSlots,\r\n } = useUploaderTheme()\r\n\r\n const scrollRef = useRef<HTMLDivElement>(null)\r\n\r\n // Render in CORE's insertion order (FileManager's Map preserves it, stable\r\n // across renders and unchanged by in-place updateFile). A file added after\r\n // others must appear LAST, never re-sorted into the middle alphabetically\r\n // (round-7 item 3). Folder uploads already add folder-by-folder, so grouping\r\n // survives without a sort.\r\n const orderedFiles = Array.from(files.values())\r\n\r\n const isSingle = orderedFiles.length === 1\r\n\r\n // Adaptive layout rule: the square-tile grid is only honored when every tile\r\n // fits in ONE row of the fixed-height panel. tilesPerRow is measured from the\r\n // scroll container (160px min tile + 16px gap); past it the row list is FORCED\r\n // and UploaderHeader hides the grid/list toggle.\r\n const tilesPerRow = useTilesPerRow(scrollRef)\r\n const forcedList = isListViewForced(orderedFiles.length, tilesPerRow)\r\n const effectiveViewMode = forcedList ? 'list' : viewMode\r\n\r\n // Virtual scrolling only for list mode with many files (never for the hero)\r\n const shouldVirtualize =\r\n orderedFiles.length >= VIRTUAL_SCROLL_THRESHOLD &&\r\n effectiveViewMode !== 'grid'\r\n\r\n const virtualizer = useVirtualizer({\r\n count: orderedFiles.length,\r\n getScrollElement: () => scrollRef.current,\r\n estimateSize: () => ESTIMATED_ITEM_HEIGHT,\r\n overscan: 5,\r\n enabled: shouldVirtualize,\r\n })\r\n\r\n const isUploading = isUploadActive(uploadStatus)\r\n // When the add-more source surface is up (overlay open, or a source chosen\r\n // while files exist), this list stays mounted but dimmed and inert behind it.\r\n const dimmed = sourceOverlayOpen || !!activeSource\r\n const heroFile = isSingle ? orderedFiles[0] : undefined\r\n const heroLeaving =\r\n heroFile !== undefined && leavingFileIds.has(heroFile.id)\r\n // Quiet completion (item 7): a successful run under `quietCompletion` shows\r\n // ONLY the checkmark overlay — Done/add-more/CTA are all suppressed and the\r\n // host takes over via the completion callbacks. Wins over 6a's continue flow.\r\n const quietDone =\r\n quietCompletion && uploadStatus === UploadStatus.SUCCESSFUL\r\n const canAddMore =\r\n limit > 1 &&\r\n files.size < limit &&\r\n !isUploading &&\r\n !isProcessing &&\r\n !quietDone\r\n\r\n return (\r\n <div\r\n data-testid=\"upup-file-list\"\r\n data-upup-slot=\"file-list\"\r\n // When the source overlay is up, the list is dimmed AND inert so\r\n // keyboard/screen-reader users can't reach the hidden remove/add-more\r\n // controls underneath (opacity+pointer-events alone don't block Tab/AT).\r\n inert={dimmed}\r\n className={cn(\r\n 'upup-relative upup-flex upup-h-full upup-flex-col upup-rounded-lg upup-shadow',\r\n {\r\n 'upup-hidden': !files.size,\r\n // Mock st2-listdim: the list stays clearly visible behind\r\n // the add-more sheet — dimmed and softly blurred, not gone.\r\n 'upup-opacity-50 upup-blur-[2px] upup-pointer-events-none':\r\n dimmed,\r\n },\r\n themeSlots?.fileList?.root,\r\n )}\r\n >\r\n {/* Visually-hidden live region: announces the current selection count\r\n to screen readers via the existing header.filesSelected i18n key. */}\r\n <div role=\"status\" aria-live=\"polite\" className=\"upup-sr-only\">\r\n {t(plural(tr, 'filesSelected', files.size), {\r\n count: files.size,\r\n })}\r\n </div>\r\n\r\n <UploaderHeader\r\n handleCancel={handleCancel}\r\n forcedList={forcedList}\r\n hideAddMore={quietDone}\r\n />\r\n\r\n {/* Quiet-completion overlay (item 7): checkmark only, no CTAs. The fx\r\n classes on FileSuccessCheck die under data-motion='off' (it then\r\n simply appears drawn), so this satisfies the static-state rule. */}\r\n {quietDone && (\r\n <div\r\n data-testid=\"upup-complete-check\"\r\n data-upup-slot=\"complete-check\"\r\n role=\"status\"\r\n className={cn(\r\n 'upup-absolute upup-inset-0 upup-z-20 upup-flex upup-flex-col upup-items-center upup-justify-center upup-gap-2 upup-rounded-lg upup-backdrop-blur-[1px]',\r\n dark ? 'upup-bg-[#04080f]/40' : 'upup-bg-white/50',\r\n )}\r\n >\r\n <FileSuccessCheck size={56} />\r\n <span\r\n className={cn(\r\n 'upup-text-sm upup-font-medium',\r\n dark\r\n ? 'upup-text-[#e2e8f0]'\r\n : 'upup-text-[#1e293b]',\r\n )}\r\n >\r\n {tr.announceUploadComplete}\r\n </span>\r\n </div>\r\n )}\r\n\r\n <div\r\n ref={scrollRef}\r\n className={cn(\r\n 'upup-preview-scroll upup-flex upup-flex-1 upup-flex-col upup-overflow-y-auto upup-p-3',\r\n dark ? 'upup-bg-transparent' : 'upup-bg-black/[0.075]',\r\n slotClasses.fileListContainer,\r\n )}\r\n >\r\n {heroFile ? (\r\n // Single-file HERO: one visual fills the content area.\r\n <div\r\n role=\"list\"\r\n className={cn(\r\n 'upup-animate-fx-enter upup-flex upup-min-h-0 upup-flex-1 upup-flex-col',\r\n heroLeaving &&\r\n 'upup-animate-fx-exit upup-overflow-hidden',\r\n )}\r\n >\r\n <FileHero file={heroFile} />\r\n </div>\r\n ) : shouldVirtualize ? (\r\n // Virtualized list: only renders visible FileItems\r\n <div\r\n role=\"list\"\r\n data-upup-slot=\"file-list-virtual\"\r\n style={{\r\n height: virtualizer.getTotalSize(),\r\n position: 'relative',\r\n }}\r\n className={cn(\r\n isProcessing &&\r\n 'upup-pointer-events-none upup-opacity-75',\r\n 'upup-font-[Arial,Helvetica,sans-serif]',\r\n )}\r\n >\r\n {virtualizer.getVirtualItems().map(virtualItem => {\r\n const file = orderedFiles[virtualItem.index]\r\n if (!file) return null\r\n return (\r\n <div\r\n key={virtualItem.key}\r\n data-index={virtualItem.index}\r\n ref={virtualizer.measureElement}\r\n style={{\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n transform: `translateY(${virtualItem.start}px)`,\r\n paddingBottom: 12,\r\n }}\r\n >\r\n <FileItem\r\n file={file}\r\n index={virtualItem.index}\r\n forcedList={forcedList}\r\n />\r\n </div>\r\n )\r\n })}\r\n </div>\r\n ) : (\r\n // Standard rendering for small lists and grid mode. Grid is a\r\n // single row of auto-fit tiles that STRETCH to fill the row\r\n // (minmax(160px,1fr) — no dead columns at 2/3 files). It is\r\n // only reached when the tiles fit one row (else forcedList\r\n // swaps to the list), so the grid can never wrap the fixed panel.\r\n <div\r\n role=\"list\"\r\n // Inline gridTemplateColumns (not a Tailwind arbitrary\r\n // class): the comma/paren value doesn't survive the JIT\r\n // scanner reliably, and this is the one place the tile\r\n // count must be data-driven. auto-fit + minmax(160px,1fr)\r\n // stretches tiles to fill the row with no dead columns.\r\n style={\r\n files.size > 1 && effectiveViewMode === 'grid'\r\n ? {\r\n gridTemplateColumns:\r\n 'repeat(auto-fit, minmax(160px, 1fr))',\r\n }\r\n : undefined\r\n }\r\n className={cn(\r\n isProcessing &&\r\n 'upup-pointer-events-none upup-opacity-75',\r\n 'upup-font-[Arial,Helvetica,sans-serif]',\r\n files.size > 1 && effectiveViewMode === 'grid'\r\n ? 'upup-grid upup-gap-4'\r\n : 'upup-flex upup-flex-col upup-gap-3',\r\n {\r\n [slotClasses.fileListContainerInnerMultiple ??\r\n '']:\r\n slotClasses.fileListContainerInnerMultiple &&\r\n files.size > 1,\r\n [slotClasses.fileListContainerInnerSingle ??\r\n '']:\r\n slotClasses.fileListContainerInnerSingle &&\r\n files.size === 1,\r\n },\r\n )}\r\n >\r\n {orderedFiles.map((file, index) => (\r\n <FileItem\r\n key={file.id}\r\n file={file}\r\n index={index}\r\n forcedList={forcedList}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Full-width dashed \"Add more\" row (spec §4 state 3): a second\r\n add-more affordance beneath the list/hero. Shares the\r\n upup-add-more testid with the header control; disambiguated by\r\n data-placement. Opens the add-more source overlay over this\r\n dimmed list (core transient-UI store). */}\r\n {canAddMore && (\r\n <button\r\n data-testid=\"upup-add-more\"\r\n data-placement=\"footer\"\r\n data-upup-slot=\"add-more\"\r\n className={cn(\r\n 'upup-fx-hover-lift upup-fx-press upup-mt-2.5 upup-flex upup-flex-none upup-items-center upup-justify-center upup-gap-2 upup-whitespace-nowrap upup-rounded-xl upup-border-[1.5px] upup-border-dashed upup-px-3 upup-py-2 upup-text-[13px] upup-font-medium',\r\n dark\r\n ? 'upup-border-white/[0.16] upup-text-[#94a3b8]'\r\n : 'upup-border-black/[0.16] upup-text-gray-500',\r\n slotClasses.containerAddMoreButton,\r\n )}\r\n onClick={() => {\r\n openSourceOverlay()\r\n }}\r\n disabled={isUploading || isProcessing}\r\n >\r\n <ContainerAddMoreIcon />\r\n {tr.addMore}\r\n </button>\r\n )}\r\n </div>\r\n <div\r\n className={cn(\r\n 'upup-shadow-top upup-flex upup-items-center upup-gap-3 upup-rounded-b-lg upup-bg-black/[0.025] upup-px-3 upup-py-2',\r\n {\r\n 'upup-bg-white/5 dark:upup-bg-white/5': dark,\r\n },\r\n slotClasses.fileListFooter,\r\n )}\r\n >\r\n {/* Primary CTA only in a pre-run/idle state. Once a run is\r\n active it becomes Cancel; when PAUSED it becomes Resume;\r\n SUCCESSFUL shows Done and FAILED shows Retry (below). */}\r\n {uploadStatus !== UploadStatus.SUCCESSFUL &&\r\n uploadStatus !== UploadStatus.FAILED &&\r\n uploadStatus !== UploadStatus.PAUSED &&\r\n !isUploading && (\r\n <button\r\n data-testid=\"upup-upload-btn\"\r\n className={cn(\r\n 'upup-fx-sheen-sweep upup-fx-press upup-disabled:animate-pulse upup-ml-auto upup-rounded-full upup-bg-[#0ea5e9] upup-px-4 upup-py-2 upup-text-sm upup-font-medium upup-text-white',\r\n {\r\n 'upup-bg-[#38bdf8] dark:upup-bg-[#38bdf8]':\r\n dark,\r\n },\r\n slotClasses.uploadButton,\r\n )}\r\n onClick={() => {\r\n void startUpload().catch(() => undefined)\r\n }}\r\n disabled={\r\n isUploadActive(uploadStatus) || isProcessing\r\n }\r\n >\r\n {t(plural(tr, 'uploadFiles', files.size), {\r\n count: files.size,\r\n })}\r\n </button>\r\n )}\r\n {uploadStatus === UploadStatus.FAILED && uploadError && (\r\n <p\r\n data-testid=\"upup-upload-error\"\r\n data-upup-slot=\"upload-error\"\r\n title={uploadErrorCode}\r\n className=\"upup-mr-auto upup-text-sm upup-text-red-600 dark:upup-text-red-400\"\r\n >\r\n {uploadErrorCode\r\n ? t(tr.uploadFailedWithCode, {\r\n code: uploadErrorCode,\r\n })\r\n : t(tr.uploadFailed, { message: uploadError })}\r\n </p>\r\n )}\r\n {uploadStatus === UploadStatus.FAILED && (\r\n <button\r\n data-testid=\"upup-retry-btn\"\r\n className={cn(\r\n 'upup-fx-press upup-disabled:animate-pulse upup-ml-auto upup-rounded-full upup-bg-red-600 upup-px-4 upup-py-2 upup-text-sm upup-font-medium upup-text-white',\r\n {\r\n 'upup-bg-red-500 dark:upup-bg-red-500': dark,\r\n },\r\n slotClasses.uploadButton,\r\n )}\r\n onClick={() => {\r\n void retryUpload().catch(() => undefined)\r\n }}\r\n >\r\n {resumable?.protocol === 'multipart'\r\n ? tr.resumeUpload\r\n : tr.retryUpload}\r\n </button>\r\n )}\r\n {uploadStatus === UploadStatus.SUCCESSFUL &&\r\n !quietCompletion && (\r\n <button\r\n className={cn(\r\n 'upup-fx-sheen-sweep upup-fx-press upup-disabled:animate-pulse upup-ml-auto upup-rounded-lg upup-bg-[#0ea5e9] upup-px-3 upup-py-2 upup-text-sm upup-font-medium upup-text-white',\r\n {\r\n 'upup-bg-[#38bdf8] dark:upup-bg-[#38bdf8]':\r\n dark,\r\n },\r\n slotClasses.uploadDoneButton,\r\n )}\r\n onClick={handleDone}\r\n >\r\n {tr.done}\r\n </button>\r\n )}\r\n <div className=\"upup-flex upup-flex-1 upup-flex-col upup-gap-1\">\r\n <div className=\"upup-flex upup-items-center upup-gap-2\">\r\n {/* Cancel an in-flight run: aborts the active request(s)\r\n but KEEPS the files (status → PAUSED) so the run can be\r\n resumed. A true discard is the header's \"remove all\".\r\n Works for every protocol; multipart/tus resume partial\r\n parts, others re-send the still-pending files. */}\r\n {uploadStatus === UploadStatus.UPLOADING && (\r\n <button\r\n data-testid=\"upup-upload-cancel\"\r\n className={cn(\r\n 'upup-fx-press upup-flex upup-h-7 upup-items-center upup-gap-1 upup-whitespace-nowrap upup-rounded-full upup-bg-red-100 upup-px-3 upup-text-xs upup-font-medium upup-text-red-700 upup-transition-colors hover:upup-bg-red-200',\r\n {\r\n 'upup-bg-red-500/20 upup-text-red-100 hover:upup-bg-red-500/30':\r\n dark,\r\n },\r\n )}\r\n onClick={handlePause}\r\n aria-label={tr.cancel}\r\n title={tr.cancel}\r\n >\r\n <Icon name=\"x\" size={14} />\r\n {tr.cancel}\r\n </button>\r\n )}\r\n {uploadStatus === UploadStatus.PAUSED && (\r\n <button\r\n data-testid=\"upup-upload-resume\"\r\n className={cn(\r\n 'upup-fx-press upup-flex upup-h-7 upup-items-center upup-gap-1 upup-whitespace-nowrap upup-rounded-full upup-bg-[#0ea5e9] upup-px-3 upup-text-xs upup-font-medium upup-text-white upup-transition-colors',\r\n {\r\n 'upup-bg-[#38bdf8] dark:upup-bg-[#38bdf8]':\r\n dark,\r\n },\r\n )}\r\n onClick={handleResume}\r\n aria-label={tr.resumeUpload}\r\n title={tr.resumeUpload}\r\n >\r\n <Icon name=\"player-play\" size={14} />\r\n {tr.resumeUpload}\r\n </button>\r\n )}\r\n <ProgressBar\r\n className=\"upup-flex-1\"\r\n progressBarClassName=\"upup-rounded\"\r\n progress={totalProgress}\r\n showValue\r\n />\r\n </div>\r\n {(isUploadActive(uploadStatus) ||\r\n uploadStatus === UploadStatus.PAUSED) &&\r\n totalBytes > 0 && (\r\n <div\r\n className={cn(\r\n 'upup-flex upup-items-center upup-justify-between upup-text-[11px] upup-text-gray-500',\r\n {\r\n 'upup-text-gray-400': dark,\r\n },\r\n )}\r\n >\r\n <span>\r\n {formatBytes(uploadedBytes)} of{' '}\r\n {formatBytes(totalBytes)}\r\n {uploadSpeed > 0 &&\r\n ` · ${formatBytes(uploadSpeed)}/s`}\r\n </span>\r\n {isUploadActive(uploadStatus) &&\r\n uploadEta > 0 && (\r\n <span>{formatEta(uploadEta)}</span>\r\n )}\r\n {uploadStatus === UploadStatus.PAUSED && (\r\n <span>{tr.paused}</span>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n})\r\n","import React, { MouseEventHandler, memo, useCallback, useState } from 'react'\r\nimport { cn } from '@useupup/core/internal'\r\nimport type { UploadFile } from '@useupup/core'\r\nimport {\r\n useUploaderFiles,\r\n useUploaderOptions,\r\n useUploaderRuntime,\r\n useUploaderTheme,\r\n useUploaderView,\r\n} from '../context/UploaderContext'\r\nimport FilePreview from './FilePreview'\r\nimport FilePreviewPortal from './FilePreviewPortal'\r\nimport FileRow from './FileRow'\r\n\r\ntype Props = {\r\n file: UploadFile\r\n /** Position in the sorted list — drives the entrance stagger. */\r\n index?: number\r\n /** True when the panel forces the row list (tiles don't fit one row). */\r\n forcedList?: boolean\r\n}\r\n\r\nexport default memo(function FileItem({\r\n file,\r\n index = 0,\r\n forcedList = false,\r\n}: Props) {\r\n const { core } = useUploaderRuntime()\r\n const { files, leavingFileIds } = useUploaderFiles()\r\n const { viewMode } = useUploaderView()\r\n const { onFileClick } = useUploaderOptions()\r\n const { slotOverrides: slotClasses } = useUploaderTheme()\r\n const [showPreviewPortal, setShowPreviewPortal] = useState(false)\r\n const [canPreview, setCanPreview] = useState(false)\r\n\r\n const leaving = leavingFileIds.has(file.id)\r\n\r\n const handleStopPropagation: MouseEventHandler<HTMLElement> = useCallback(\r\n e => {\r\n e.stopPropagation()\r\n },\r\n [],\r\n )\r\n const openPreviewPortal = useCallback(() => {\r\n setShowPreviewPortal(true)\r\n core?.emit('file-preview-open', {\r\n fileId: file.id,\r\n fileName: file.name,\r\n })\r\n }, [core, file.id, file.name])\r\n const closePreviewPortal = useCallback(() => {\r\n setShowPreviewPortal(false)\r\n core?.emit('file-preview-close', {\r\n fileId: file.id,\r\n fileName: file.name,\r\n })\r\n }, [core, file.id, file.name])\r\n\r\n return (\r\n <div\r\n data-testid=\"upup-file-item\"\r\n data-upup-slot=\"file-item\"\r\n role=\"listitem\"\r\n // Entrance/exit fx: `upup-animate-fx-enter` plays on mount (staggered\r\n // via animation-delay); a leaving id (deferred-removal window) swaps\r\n // in the collapse. The central CSS motion gate makes both inert under\r\n // data-motion='off' — render them unconditionally.\r\n className={cn(\r\n 'upup-animate-fx-enter',\r\n 'upup-relative upup-flex upup-flex-1 upup-flex-col upup-items-start upup-gap-1 upup-bg-transparent',\r\n leaving && 'upup-animate-fx-exit upup-overflow-hidden',\r\n {\r\n [slotClasses.fileItemMultiple ?? '']:\r\n slotClasses.fileItemMultiple && files.size > 1,\r\n [slotClasses.fileItemSingle ?? '']:\r\n slotClasses.fileItemSingle && files.size === 1,\r\n },\r\n )}\r\n // Cap the stagger: in the virtualized branch `index` is unbounded,\r\n // so a late row would otherwise wait index*40ms (index 30 = 1200ms).\r\n style={\r\n leaving\r\n ? undefined\r\n : { animationDelay: `${Math.min(index, 8) * 40}ms` }\r\n }\r\n >\r\n {viewMode === 'list' || forcedList ? (\r\n <FileRow file={file} index={index} />\r\n ) : (\r\n <>\r\n <FilePreview\r\n fileName={file.name}\r\n fileType={file.type ?? ''}\r\n fileId={file.id}\r\n fileUrl={file.url ?? ''}\r\n fileSize={file.size}\r\n index={index}\r\n canPreview={canPreview}\r\n setCanPreview={setCanPreview}\r\n onRequestPreview={openPreviewPortal}\r\n onClick={() => {\r\n onFileClick(file)\r\n }}\r\n />\r\n {/* Keep preview portal mounted without showing duplicate info */}\r\n {canPreview && showPreviewPortal && (\r\n <FilePreviewPortal\r\n onStopPropagation={handleStopPropagation}\r\n onClose={closePreviewPortal}\r\n fileType={file.type ?? ''}\r\n fileUrl={file.url ?? ''}\r\n fileName={file.name}\r\n fileSize={file.size}\r\n />\r\n )}\r\n </>\r\n )}\r\n </div>\r\n )\r\n})\r\n","import React, {\r\n Dispatch,\r\n HTMLAttributes,\r\n MouseEventHandler,\r\n SetStateAction,\r\n memo,\r\n useEffect,\r\n useMemo,\r\n} from 'react'\r\n\r\nimport { cn, isFileRemovalLocked } from '@useupup/core/internal'\r\nimport { UploadStatus } from '@useupup/core'\r\nimport {\r\n useUploaderEditor,\r\n useUploaderFiles,\r\n useUploaderI18n,\r\n useUploaderOptions,\r\n useUploaderTheme,\r\n useUploaderUploadControls,\r\n} from '../context/UploaderContext'\r\nimport {\r\n fileCanPreviewText,\r\n fileGetIsImage,\r\n fileGetIsPdf,\r\n fileGetIsText,\r\n formatFileSize,\r\n} from '../lib/file'\r\nimport FilePreviewThumbnail from './FilePreviewThumbnail'\r\nimport ProgressBar from './shared/ProgressBar'\r\nimport FileSuccessCheck from './shared/FileSuccessCheck'\r\nimport EditIcon from './shared/EditIcon'\r\n\r\ntype Props = {\r\n fileName: string\r\n fileType: string\r\n fileId: string\r\n fileUrl: string\r\n fileSize?: number | undefined\r\n canPreview: boolean\r\n setCanPreview: Dispatch<SetStateAction<boolean>>\r\n onRequestPreview?: (() => void) | undefined\r\n /** Position in the sorted list — drives the completion-check stagger. */\r\n index?: number\r\n} & HTMLAttributes<HTMLDivElement>\r\n\r\nexport default memo(function FilePreview(props: Props) {\r\n const {\r\n fileType,\r\n fileId,\r\n fileName,\r\n fileUrl,\r\n fileSize,\r\n canPreview,\r\n setCanPreview,\r\n onRequestPreview,\r\n onClick,\r\n index = 0,\r\n ...restProps\r\n } = props\r\n\r\n const { handleFileRemove, files } = useUploaderFiles()\r\n const { translations: tr } = useUploaderI18n()\r\n const { openImageEditor } = useUploaderEditor()\r\n const {\r\n upload: { filesProgressMap },\r\n } = useUploaderUploadControls()\r\n const {\r\n icons: { FileDeleteIcon },\r\n allowPreview,\r\n imageEditor,\r\n } = useUploaderOptions()\r\n const {\r\n isDark: isDarkTheme,\r\n slotOverrides: slotClasses,\r\n slots: themeSlots,\r\n } = useUploaderTheme()\r\n\r\n const isImage = useMemo(() => fileGetIsImage(fileType), [fileType])\r\n const isVideo = useMemo(() => fileType.startsWith('video/'), [fileType])\r\n const isPdf = useMemo(\r\n () => fileGetIsPdf(fileType, fileName),\r\n [fileType, fileName],\r\n )\r\n const isText = useMemo(\r\n () => fileGetIsText(fileType, fileName),\r\n [fileType, fileName],\r\n )\r\n\r\n // Only allow inline text preview for files within the safe size threshold\r\n const canPreviewText = useMemo(\r\n () => fileCanPreviewText(fileType, fileName, fileSize),\r\n [fileType, fileName, fileSize],\r\n )\r\n\r\n const progress = useMemo(() => {\r\n const fileProgress = filesProgressMap[fileId]\r\n const loaded = fileProgress?.loaded ?? NaN\r\n const total = fileProgress?.total ?? NaN\r\n const pct = Math.floor((loaded / total) * 100)\r\n // No progress entry ⇒ NaN; total === 0 ⇒ Infinity. Either would render\r\n // width:NaN%/aria-valuenow=NaN in ProgressBar while an upload is active.\r\n return Number.isFinite(pct) ? pct : 0\r\n }, [fileId, filesProgressMap])\r\n\r\n useEffect(() => {\r\n // Images and PDFs are always previewable; text only if below the safe size threshold.\r\n if ((isImage || isPdf || (isText && canPreviewText)) && !canPreview)\r\n setCanPreview(true)\r\n }, [isImage, isPdf, isText, canPreviewText, canPreview, setCanPreview])\r\n\r\n const fileStatus = files.get(fileId)?.status\r\n const isSuccessful = fileStatus === UploadStatus.SUCCESSFUL\r\n // Edit stays available pre- AND post-upload — only an in-flight file is busy\r\n // (round-8 item 1). Editing a completed image re-opens the editor; it does\r\n // not re-trigger the upload by itself (openImageEditor semantics).\r\n const isBusy =\r\n fileStatus === UploadStatus.UPLOADING ||\r\n fileStatus === UploadStatus.PROCESSING\r\n\r\n const onHandleFileRemove: MouseEventHandler<HTMLButtonElement> = e => {\r\n e.stopPropagation()\r\n handleFileRemove(fileId)\r\n }\r\n\r\n const onHandleEditImage: MouseEventHandler<HTMLButtonElement> = e => {\r\n e.stopPropagation()\r\n const file = files.get(fileId)\r\n if (file) openImageEditor(file)\r\n }\r\n\r\n return (\r\n <div\r\n // Fills its grid cell (auto-fit minmax(160px,1fr) in FileList), so the\r\n // tile stretches to share the row evenly — no dead columns at 2/3\r\n // files. The cell has a definite width, so the caption `truncate`\r\n // still works without an explicit pixel width here.\r\n className={cn(\r\n 'upup-block upup-w-full',\r\n themeSlots?.filePreview?.root,\r\n )}\r\n data-testid=\"upup-file-preview\"\r\n data-upup-slot=\"file-preview\"\r\n {...restProps}\r\n >\r\n <div\r\n className={cn(\r\n // Chrome-language tile (spec §3): translucent card + hairline\r\n // ring, sky accents. Image tiles paint the picture over it.\r\n // Fluid width, fixed height — fills the cell horizontally but\r\n // never balloons vertically in the widest (2-file) row.\r\n 'upup-fx-hover-lift upup-relative upup-h-[160px] upup-w-full upup-overflow-hidden upup-rounded-xl upup-ring-1',\r\n 'upup-bg-contain upup-bg-center upup-bg-no-repeat',\r\n isDarkTheme\r\n ? 'upup-bg-white/[0.055] upup-ring-white/[0.08]'\r\n : 'upup-bg-black/[0.04] upup-ring-black/[0.06]',\r\n {\r\n [slotClasses.fileThumbnailMultiple ?? '']:\r\n slotClasses.fileThumbnailMultiple && files.size > 1,\r\n [slotClasses.fileThumbnailSingle ?? '']:\r\n slotClasses.fileThumbnailSingle && files.size === 1,\r\n },\r\n themeSlots?.filePreview?.thumbnail,\r\n )}\r\n style={\r\n isImage ? { backgroundImage: `url(${fileUrl})` } : undefined\r\n }\r\n >\r\n {/* Whole-thumbnail click affordance: a real <button> that is a\r\n sibling of the edit/remove controls (never their ancestor), so\r\n no interactive element nests inside another (axe\r\n nested-interactive). It sits behind the action buttons\r\n (z-0 < z-10) and is transparent so the thumbnail shows through. */}\r\n <button\r\n type=\"button\"\r\n aria-label={fileName}\r\n className=\"upup-absolute upup-inset-0 upup-z-0 upup-cursor-pointer\"\r\n onClick={e =>\r\n onClick?.(\r\n e as unknown as React.MouseEvent<HTMLDivElement>,\r\n )\r\n }\r\n />\r\n {isVideo && (\r\n // First-frame video thumbnail — no controls chrome (the\r\n // native player pill read as broken CSS in a 145px tile).\r\n <video\r\n src={fileUrl}\r\n muted\r\n playsInline\r\n preload=\"metadata\"\r\n className=\"upup-pointer-events-none upup-absolute upup-inset-0 upup-h-full upup-w-full upup-object-cover\"\r\n />\r\n )}\r\n {!isImage && !isVideo && (\r\n <div className=\"upup-flex upup-h-full upup-items-center upup-justify-center upup-p-6\">\r\n <FilePreviewThumbnail\r\n canPreview={canPreview}\r\n setCanPreview={setCanPreview}\r\n fileType={fileType}\r\n fileName={fileName}\r\n fileUrl={fileUrl}\r\n fileSize={fileSize}\r\n allowPreview={allowPreview}\r\n slotClasses={slotClasses}\r\n labels={tr}\r\n />\r\n </div>\r\n )}\r\n\r\n {isImage && imageEditor.enabled && (\r\n <button\r\n className={cn(\r\n // Hero-chrome action button (matches FileHero's\r\n // remove): translucent dark square. Sits below the\r\n // trash normally; once the file is done (trash gone)\r\n // it slides up to the top slot.\r\n 'upup-fx-press upup-absolute upup-right-1.5 upup-z-10',\r\n isSuccessful ? 'upup-top-1.5' : 'upup-top-9',\r\n 'upup-flex upup-h-[30px] upup-w-[30px] upup-items-center upup-justify-center',\r\n 'upup-rounded-[8px] upup-bg-[#04080f]/40 upup-text-[#e2e8f0]',\r\n 'hover:upup-bg-[#04080f]/65',\r\n 'disabled:upup-cursor-not-allowed disabled:upup-opacity-50',\r\n )}\r\n onClick={onHandleEditImage}\r\n type=\"button\"\r\n disabled={isBusy}\r\n aria-label={tr.editImage}\r\n data-testid=\"upup-file-edit\"\r\n >\r\n <EditIcon className=\"upup-h-[18px] upup-w-[18px]\" />\r\n </button>\r\n )}\r\n\r\n {/* Delete disappears once the file has uploaded successfully —\r\n the completion check is then the only overlay affordance. */}\r\n {!isSuccessful && (\r\n <button\r\n className={cn(\r\n 'upup-fx-remove upup-fx-press upup-absolute upup-right-1.5 upup-top-1.5 upup-z-10',\r\n 'upup-flex upup-h-[30px] upup-w-[30px] upup-items-center upup-justify-center',\r\n 'upup-rounded-[8px] upup-bg-[#04080f]/40 upup-text-[#e2e8f0]',\r\n 'hover:upup-bg-[#04080f]/65',\r\n 'disabled:upup-cursor-not-allowed disabled:upup-opacity-50',\r\n slotClasses.fileDeleteButton,\r\n themeSlots?.filePreview?.deleteButton,\r\n )}\r\n onClick={onHandleFileRemove}\r\n type=\"button\"\r\n disabled={isFileRemovalLocked(\r\n progress,\r\n fileStatus ?? UploadStatus.IDLE,\r\n )}\r\n aria-label={tr.removeFile}\r\n data-testid=\"upup-file-remove\"\r\n >\r\n <FileDeleteIcon className=\"upup-h-5 upup-w-5\" />\r\n </button>\r\n )}\r\n\r\n {isSuccessful && (\r\n <FileSuccessCheck\r\n index={index}\r\n size={20}\r\n className=\"upup-absolute upup-left-1.5 upup-top-1.5 upup-z-10\"\r\n />\r\n )}\r\n\r\n <ProgressBar\r\n className=\"upup-absolute upup-bottom-0 upup-left-0 upup-right-0\"\r\n progressBarClassName=\"upup-rounded-t-none upup-rounded-b-md\"\r\n progress={progress}\r\n />\r\n </div>\r\n\r\n <div className=\"upup-mt-1 upup-px-0.5\">\r\n <div\r\n className={cn(\r\n 'upup-truncate upup-text-[13px] upup-font-normal upup-leading-tight upup-text-gray-900',\r\n { 'upup-text-white': isDarkTheme },\r\n themeSlots?.filePreview?.name,\r\n )}\r\n >\r\n {fileName}\r\n </div>\r\n <div\r\n className={cn(\r\n 'upup-mt-0.5 upup-text-[11px] upup-leading-tight upup-text-gray-500',\r\n { 'upup-text-gray-400': isDarkTheme },\r\n themeSlots?.filePreview?.size,\r\n )}\r\n >\r\n {formatFileSize(fileSize, tr)}\r\n </div>\r\n {allowPreview && canPreview && (\r\n <button\r\n type=\"button\"\r\n className={cn(\r\n 'upup-mt-1 upup-text-[11px] upup-font-normal upup-leading-tight upup-text-[#0284c7] upup-transition-all hover:upup-text-[#0284c7] hover:upup-underline',\r\n {\r\n 'upup-text-[#38bdf8] hover:upup-text-[#7dd3fc]':\r\n isDarkTheme,\r\n },\r\n themeSlots?.filePreview?.previewButton,\r\n )}\r\n onClick={onRequestPreview}\r\n >\r\n {tr.clickToPreview}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n})\r\n","import React, { Dispatch, SetStateAction, memo, useMemo } from 'react'\r\nimport { cn } from '@useupup/core/internal'\r\nimport type { Translations } from '@useupup/core'\r\nimport type { InternalFlatClassNames } from '@useupup/core/internal'\r\nimport {\r\n fileGetExtension,\r\n fileGetIsPdf,\r\n fileGetIsText,\r\n fileIs3D,\r\n} from '../lib/file'\r\nimport FileIcon from './FileIcon'\r\n\r\ntype Props = {\r\n canPreview: boolean\r\n setCanPreview: Dispatch<SetStateAction<boolean>>\r\n fileType: string\r\n fileName: string\r\n fileUrl: string\r\n fileSize?: number | undefined\r\n slotClasses: InternalFlatClassNames\r\n allowPreview: boolean\r\n labels: Translations\r\n}\r\n\r\nexport default memo(\r\n function FilePreviewThumbnail({\r\n canPreview,\r\n setCanPreview,\r\n fileUrl,\r\n fileName,\r\n fileType,\r\n fileSize: _fileSize,\r\n slotClasses,\r\n allowPreview,\r\n labels: tr,\r\n }: Props) {\r\n const extension = useMemo(\r\n () => fileGetExtension(fileType, fileName),\r\n [fileType, fileName],\r\n )\r\n\r\n const is3D = useMemo(() => {\r\n return fileIs3D(extension?.toLowerCase() || '')\r\n }, [extension])\r\n\r\n const isPdf = useMemo(\r\n () => fileGetIsPdf(fileType, fileName),\r\n [fileType, fileName],\r\n )\r\n\r\n // Text files render as a static doc icon (cross-framework parity — all\r\n // adapters show the doc icon, not the inline text). The full content stays\r\n // available via the \"click to preview\" portal, and this also avoids laying\r\n // out huge text files inline (which froze the main thread).\r\n const isText = useMemo(\r\n () => fileGetIsText(fileType, fileName),\r\n [fileType, fileName],\r\n )\r\n\r\n // PDFs, 3D files, and text → static icon (no inline embedding)\r\n if (isPdf || is3D || isText) {\r\n return (\r\n <div className=\"upup-flex upup-flex-col upup-items-center upup-gap-2\">\r\n <FileIcon\r\n extension={extension}\r\n className={slotClasses.fileIcon}\r\n />\r\n </div>\r\n )\r\n }\r\n\r\n return (\r\n <>\r\n {!canPreview && (\r\n <>\r\n <object\r\n data={fileUrl}\r\n width=\"0%\"\r\n height=\"0%\"\r\n name={fileName}\r\n type={fileType}\r\n onLoad={() => {\r\n setCanPreview(true)\r\n }}\r\n >\r\n <p>{tr.loading}</p>\r\n </object>\r\n <FileIcon extension={extension} />\r\n </>\r\n )}\r\n\r\n {canPreview && (\r\n <>\r\n <FileIcon\r\n extension={extension}\r\n className={cn(\r\n {\r\n 'md:upup-hidden': allowPreview,\r\n },\r\n slotClasses.fileIcon,\r\n )}\r\n />\r\n <div\r\n className={cn(\r\n `upup-relative upup-hidden upup-h-full upup-w-full ${\r\n allowPreview && 'md:upup-block'\r\n }`,\r\n )}\r\n >\r\n <object\r\n data={fileUrl}\r\n width=\"100%\"\r\n height=\"100%\"\r\n name={fileName}\r\n type={fileType}\r\n className=\"upup-absolute upup-h-full upup-w-full\"\r\n >\r\n <p>{tr.loading}</p>\r\n </object>\r\n </div>\r\n </>\r\n )}\r\n </>\r\n )\r\n },\r\n (prev, next) =>\r\n prev.canPreview === next.canPreview &&\r\n prev.fileType === next.fileType &&\r\n prev.fileUrl === next.fileUrl,\r\n)\r\n","import { memo, SVGAttributes } from 'react'\r\nimport { fileTypeIconName } from '@useupup/core'\r\nimport { cn } from '@useupup/core/internal'\r\nimport { useUploaderTheme } from '../context/UploaderContext'\r\nimport Icon from './Icon'\r\n\r\nexport default memo(function FileIcon({\r\n extension = '',\r\n className,\r\n}: { extension?: string } & SVGAttributes<SVGElement>) {\r\n const { isDark: dark } = useUploaderTheme()\r\n return (\r\n <span\r\n className=\"upup-inline-flex\"\r\n data-testid=\"upup-file-icon\"\r\n data-upup-slot=\"file-icon\"\r\n >\r\n <Icon\r\n name={fileTypeIconName(extension)}\r\n className={cn('upup-text-5xl upup-text-[#0284c7]', className, {\r\n 'upup-text-[#38bdf8] dark:upup-text-[#38bdf8]': dark,\r\n })}\r\n />\r\n </span>\r\n )\r\n})\r\n","import React, { forwardRef, HTMLAttributes } from 'react'\r\nimport {\r\n useUploaderI18n,\r\n useUploaderTheme,\r\n useUploaderUploadControls,\r\n} from '../../context/UploaderContext'\r\nimport { cn, isUploadActive } from '@useupup/core/internal'\r\n\r\ntype Props = {\r\n progress: number\r\n showValue?: boolean\r\n progressBarClassName?: string\r\n} & HTMLAttributes<HTMLDivElement>\r\n\r\nexport default forwardRef<HTMLDivElement, Props>(function ProgressBar(\r\n { progress, className, progressBarClassName, showValue = false, ...rest },\r\n ref,\r\n) {\r\n const {\r\n isDark: dark,\r\n slotOverrides: slotClasses,\r\n slots: themeSlots,\r\n } = useUploaderTheme()\r\n const { translations: tr } = useUploaderI18n()\r\n const {\r\n upload: { uploadStatus },\r\n } = useUploaderUploadControls()\r\n return (\r\n (!!progress || isUploadActive(uploadStatus)) && (\r\n <div\r\n data-testid=\"upup-progress-bar\"\r\n data-upup-slot=\"progress-bar\"\r\n ref={ref}\r\n role=\"progressbar\"\r\n aria-valuenow={progress}\r\n aria-valuemin={0}\r\n aria-valuemax={100}\r\n aria-label={tr.uploadProgress}\r\n className={cn(\r\n 'upup-flex upup-items-center upup-gap-2',\r\n className,\r\n slotClasses.progressBarContainer,\r\n themeSlots?.progressBar?.root,\r\n )}\r\n {...rest}\r\n >\r\n <div\r\n className={cn(\r\n 'upup-relative upup-h-[6px] upup-flex-1 upup-overflow-hidden upup-rounded-[4px]',\r\n dark ? 'upup-bg-white/[0.12]' : 'upup-bg-[#F5F5F5]',\r\n progressBarClassName,\r\n slotClasses.progressBar,\r\n themeSlots?.progressBar?.track,\r\n )}\r\n >\r\n <div\r\n style={{\r\n width: `${progress}%`,\r\n }}\r\n className={cn(\r\n // fx-essential keeps the width tween alive under\r\n // data-motion=\"off\"; fx-progress-fill carries the\r\n // transition. Sky accent replaces the legacy periwinkle.\r\n 'upup-fx-progress-fill upup-fx-essential upup-h-full',\r\n dark ? 'upup-bg-[#38bdf8]' : 'upup-bg-[#0ea5e9]',\r\n slotClasses.progressBarInner,\r\n themeSlots?.progressBar?.fill,\r\n )}\r\n />\r\n {isUploadActive(uploadStatus) && (\r\n <div\r\n aria-hidden=\"true\"\r\n className=\"upup-animate-fx-sheen upup-pointer-events-none upup-absolute upup-inset-y-0 upup-left-0 upup-w-2/5\"\r\n style={{\r\n background:\r\n 'linear-gradient(90deg, transparent, rgba(255,255,255,0.45), transparent)',\r\n }}\r\n />\r\n )}\r\n </div>\r\n {showValue && (\r\n <p\r\n className={cn(\r\n 'upup-text-xs upup-font-semibold',\r\n {\r\n 'upup-text-white': dark,\r\n },\r\n slotClasses.progressBarText,\r\n themeSlots?.progressBar?.text,\r\n )}\r\n >\r\n {progress}%\r\n </p>\r\n )}\r\n </div>\r\n )\r\n )\r\n})\r\n","import React from 'react'\r\nimport { cn } from '@useupup/core/internal'\r\n\r\ntype Props = {\r\n /** Position in the sorted list — drives the draw/pop stagger (capped at 8). */\r\n index?: number\r\n /** Host-supplied positioning classes (absolute placement on tiles/hero). */\r\n className?: string\r\n size?: number\r\n}\r\n\r\n/**\r\n * Completion checkmark (states-tour.html state E): a sky ring with a tick that\r\n * DRAWS in and a wrapper that POPS, shown when a file reaches\r\n * UploadStatus.SUCCESSFUL. Hosts (FilePreview tile, FileRow, FileHero) gate it\r\n * on status; the fx classes render UNCONDITIONALLY — the shared CSS\r\n * `data-motion=\"off\"` kill rule is the one gate, so under motion-off the mark\r\n * simply appears drawn (no draw/pop). aria-hidden: completion is already\r\n * conveyed textually by the file list's live region + the upload announcement.\r\n */\r\nexport default function FileSuccessCheck({\r\n index = 0,\r\n className,\r\n size = 22,\r\n}: Readonly<Props>): React.ReactElement {\r\n const delay = `${Math.min(index, 8) * 40}ms`\r\n return (\r\n <span\r\n data-upup-slot=\"file-success\"\r\n aria-hidden=\"true\"\r\n className={cn('upup-animate-fx-pop upup-inline-flex', className)}\r\n style={{ animationDelay: delay }}\r\n >\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n width={size}\r\n height={size}\r\n fill=\"none\"\r\n aria-hidden=\"true\"\r\n >\r\n <circle\r\n cx=\"12\"\r\n cy=\"12\"\r\n r=\"11\"\r\n stroke=\"#38bdf8\"\r\n strokeWidth=\"2\"\r\n />\r\n <path\r\n d=\"M7 12.5l3.2 3.2L17 8.8\"\r\n stroke=\"#38bdf8\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n pathLength={24}\r\n strokeDasharray={24}\r\n className=\"upup-animate-fx-draw\"\r\n style={{ animationDelay: delay }}\r\n />\r\n </svg>\r\n </span>\r\n )\r\n}\r\n","import React from 'react'\r\n\r\n/**\r\n * Pencil glyph for the image-edit affordance shared by the grid tile\r\n * (FilePreview), list row (FileRow), and single-file hero (FileHero). One copy\r\n * of the path so the three edit buttons stay byte-identical and the mandatory\r\n * bundle carries the markup once.\r\n */\r\nexport default function EditIcon({\r\n className,\r\n}: {\r\n className?: string\r\n}): React.JSX.Element {\r\n return (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 20 20\"\r\n fill=\"currentColor\"\r\n className={className}\r\n aria-hidden=\"true\"\r\n >\r\n <path d=\"M2.695 14.763l-1.262 3.154a.5.5 0 00.65.65l3.155-1.262a4 4 0 001.343-.885L17.5 5.5a2.121 2.121 0 00-3-3L3.58 13.42a4 4 0 00-.885 1.343z\" />\r\n </svg>\r\n )\r\n}\r\n","import React, {\r\n forwardRef,\r\n HTMLAttributes,\r\n memo,\r\n MouseEventHandler,\r\n useEffect,\r\n useMemo,\r\n useState,\r\n} from 'react'\r\nimport { createPortal } from 'react-dom'\r\nimport { formatUiMessage as t } from '@useupup/core'\r\nimport { cn } from '@useupup/core/internal'\r\nimport { useUploaderI18n, useUploaderTheme } from '../context/UploaderContext'\r\nimport {\r\n fileGetIsImage,\r\n fileGetIsPdf,\r\n fileGetIsText,\r\n PREVIEW_MAX_TEXT_SIZE,\r\n PREVIEW_TEXT_TRUNCATE_LENGTH,\r\n} from '../lib/file'\r\n\r\nexport default memo(\r\n forwardRef<\r\n HTMLDivElement,\r\n HTMLAttributes<HTMLDivElement> & {\r\n onStopPropagation: MouseEventHandler<HTMLDivElement>\r\n onClose: () => void\r\n fileUrl: string\r\n fileName: string\r\n fileType: string\r\n fileSize?: number\r\n }\r\n >(function FilePreviewPortal(\r\n {\r\n onStopPropagation,\r\n onClose,\r\n fileUrl,\r\n fileName,\r\n fileType,\r\n fileSize,\r\n ...restProps\r\n },\r\n ref,\r\n ) {\r\n const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme()\r\n const { translations: tr } = useUploaderI18n()\r\n const isImage = useMemo(() => fileGetIsImage(fileType), [fileType])\r\n const isPdf = useMemo(\r\n () => fileGetIsPdf(fileType, fileName),\r\n [fileType, fileName],\r\n )\r\n const isText = useMemo(\r\n () => fileGetIsText(fileType, fileName),\r\n [fileType, fileName],\r\n )\r\n\r\n const isOversizedText = useMemo(\r\n () =>\r\n isText &&\r\n fileSize !== undefined &&\r\n fileSize > PREVIEW_MAX_TEXT_SIZE,\r\n [isText, fileSize],\r\n )\r\n\r\n const [textContent, setTextContent] = useState<string>('')\r\n const [textLoading, setTextLoading] = useState(false)\r\n const [textError, setTextError] = useState<string>()\r\n\r\n const [isTruncated, setIsTruncated] = useState(false)\r\n\r\n useEffect(() => {\r\n const handleKeyDown = (event: KeyboardEvent) => {\r\n if (event.key === 'Escape') onClose()\r\n }\r\n window.addEventListener('keydown', handleKeyDown)\r\n return () => {\r\n window.removeEventListener('keydown', handleKeyDown)\r\n }\r\n }, [onClose])\r\n\r\n useEffect(() => {\r\n let cancelled = false\r\n const loadText = async () => {\r\n if (!isText) return\r\n try {\r\n setTextLoading(true)\r\n\r\n if (isOversizedText) {\r\n // For large text files, only read up to PREVIEW_TEXT_TRUNCATE_LENGTH\r\n // to avoid freezing the browser with massive DOM rendering\r\n const res = await fetch(fileUrl)\r\n const reader = res.body?.getReader()\r\n if (!reader) throw new Error('Cannot read file')\r\n\r\n const decoder = new TextDecoder()\r\n let result = ''\r\n let done = false\r\n\r\n while (\r\n !done &&\r\n result.length < PREVIEW_TEXT_TRUNCATE_LENGTH\r\n ) {\r\n const { value, done: streamDone } =\r\n await reader.read()\r\n done = streamDone\r\n if (value) {\r\n result += decoder.decode(value, {\r\n stream: !done,\r\n })\r\n }\r\n }\r\n void reader.cancel()\r\n\r\n if (!cancelled) {\r\n const wasTruncated =\r\n !done ||\r\n result.length > PREVIEW_TEXT_TRUNCATE_LENGTH\r\n if (wasTruncated) {\r\n result = result.slice(\r\n 0,\r\n PREVIEW_TEXT_TRUNCATE_LENGTH,\r\n )\r\n }\r\n setIsTruncated(wasTruncated)\r\n setTextContent(result)\r\n }\r\n } else {\r\n const res = await fetch(fileUrl)\r\n const txt = await res.text()\r\n if (!cancelled) setTextContent(txt)\r\n }\r\n } catch (e) {\r\n // upup-catch: text-preview fetch/decode failure is shown inline via setTextError, not a system fault\r\n if (!cancelled)\r\n setTextError((e as Error)?.message || 'Preview error')\r\n } finally {\r\n if (!cancelled) setTextLoading(false)\r\n }\r\n }\r\n void loadText()\r\n return () => {\r\n cancelled = true\r\n }\r\n }, [fileUrl, isText, isOversizedText])\r\n\r\n return createPortal(\r\n <div className=\"upup-scope\" data-upup-slot=\"file-preview-portal\">\r\n <div\r\n className=\"upup-fixed upup-inset-0 upup-z-[2147483647] upup-flex upup-items-center upup-justify-center upup-bg-black/40\"\r\n ref={ref}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-label={fileName}\r\n onClick={onClose}\r\n {...restProps}\r\n >\r\n <div className=\"upup-relative upup-h-[90vh] upup-w-[90vw] upup-p-4\">\r\n <div\r\n className={cn(\r\n 'upup-absolute upup-inset-0 upup-m-4 upup-bg-white',\r\n {\r\n 'upup-bg-[#232323] dark:upup-bg-[#232323]':\r\n dark,\r\n },\r\n slotClasses.filePreviewPortal,\r\n )}\r\n onClick={onStopPropagation}\r\n >\r\n <button\r\n type=\"button\"\r\n aria-label={tr.cancel}\r\n className=\"upup-absolute upup-right-3 upup-top-3 upup-z-10 upup-flex upup-size-8 upup-items-center upup-justify-center upup-rounded-full upup-bg-black/70 upup-text-sm upup-font-semibold upup-text-white upup-shadow-sm hover:upup-bg-black focus:upup-outline-none focus:upup-ring-2 focus:upup-ring-white\"\r\n onClick={onClose}\r\n >\r\n x\r\n </button>\r\n {isImage && (\r\n <img\r\n src={fileUrl}\r\n alt={fileName}\r\n className=\"upup-h-full upup-w-full upup-rounded upup-object-contain\"\r\n />\r\n )}\r\n {isPdf && (\r\n <embed\r\n src={fileUrl}\r\n type=\"application/pdf\"\r\n width=\"100%\"\r\n height=\"100%\"\r\n className=\"upup-rounded\"\r\n title={fileName}\r\n />\r\n )}\r\n {!isImage && !isPdf && (\r\n <>\r\n {isText && (\r\n <div className=\"upup-h-full upup-w-full upup-overflow-auto upup-p-4 upup-font-mono upup-text-xs\">\r\n {textLoading && <p>{tr.loading}</p>}\r\n {textError && (\r\n <p>\r\n {t(tr.previewError, {\r\n message: textError,\r\n })}\r\n </p>\r\n )}\r\n {!textLoading && !textError && (\r\n <>\r\n <pre className=\"upup-whitespace-pre-wrap\">\r\n {textContent}\r\n </pre>\r\n {isTruncated && (\r\n <div className=\"upup-mt-4 upup-rounded upup-border upup-border-yellow-500/30 upup-bg-yellow-500/10 upup-px-3 upup-py-2 upup-text-xs upup-text-yellow-400\">\r\n Content truncated -\r\n file is too large to\r\n preview in full.\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n )}\r\n {!isText && (\r\n <object\r\n data={fileUrl}\r\n width=\"100%\"\r\n height=\"100%\"\r\n name={fileName}\r\n type={fileType}\r\n >\r\n <p>{tr.loading}</p>\r\n </object>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>,\r\n document.body,\r\n )\r\n }),\r\n)\r\n","import React, { memo, useMemo } from 'react'\r\nimport { cn, isFileRemovalLocked } from '@useupup/core/internal'\r\nimport { UploadStatus, fileTypeIconName, type UploadFile } from '@useupup/core'\r\nimport {\r\n useUploaderEditor,\r\n useUploaderFiles,\r\n useUploaderI18n,\r\n useUploaderOptions,\r\n useUploaderTheme,\r\n useUploaderUploadControls,\r\n} from '../context/UploaderContext'\r\nimport { fileGetExtension, fileGetIsImage, formatFileSize } from '../lib/file'\r\nimport Icon from './Icon'\r\nimport ProgressBar from './shared/ProgressBar'\r\nimport FileSuccessCheck from './shared/FileSuccessCheck'\r\nimport EditIcon from './shared/EditIcon'\r\n\r\nconst ARCHIVE_EXTENSIONS = new Set([\r\n 'zip',\r\n 'rar',\r\n '7z',\r\n 'tar',\r\n 'gz',\r\n 'bz2',\r\n 'xz',\r\n])\r\n\r\n/**\r\n * Per-category thumbnail treatment for non-media rows so pdf / archive / audio /\r\n * generic no longer all read as the same blue doc: a distinct gradient tint plus\r\n * the type-specific glyph (audio uses the waveform icon; the rest use the\r\n * file-<ext> registry icon, falling back to the generic file glyph).\r\n */\r\nfunction nonMediaThumb(\r\n type: string,\r\n name: string,\r\n): {\r\n gradient: string\r\n icon: 'audio' | ReturnType<typeof fileTypeIconName>\r\n} {\r\n const ext = fileGetExtension(type, name)\r\n if (type.startsWith('audio/'))\r\n return {\r\n gradient: 'linear-gradient(135deg,#a855f7,#6366f1)',\r\n icon: 'audio',\r\n }\r\n if (ext === 'pdf' || type === 'application/pdf')\r\n return {\r\n gradient: 'linear-gradient(135deg,#f43f5e,#ec4899)',\r\n icon: 'file-pdf',\r\n }\r\n if (ARCHIVE_EXTENSIONS.has(ext) || type.includes('zip'))\r\n return {\r\n gradient: 'linear-gradient(135deg,#f59e0b,#f97316)',\r\n icon: fileTypeIconName(ext === 'zip' ? 'zip' : ext),\r\n }\r\n return {\r\n gradient: 'linear-gradient(135deg,#0ea5e9,#6366f1)',\r\n icon: fileTypeIconName(ext),\r\n }\r\n}\r\n\r\ntype Props = {\r\n file: UploadFile\r\n /** Position in the sorted list — drives the completion-check stagger. */\r\n index?: number\r\n}\r\n\r\n/**\r\n * Compact list-mode row (spec §4 state 3, states-tour-v2.html \"multiple files\").\r\n * A horizontal card: thumbnail · name/size · remove. The grid-mode tile\r\n * (FilePreview) keeps the richer affordances (edit, click-to-preview); the row\r\n * is the dense overview and matches the mockup exactly.\r\n */\r\nexport default memo(function FileRow({ file, index = 0 }: Props) {\r\n const { handleFileRemove } = useUploaderFiles()\r\n const { translations: tr } = useUploaderI18n()\r\n const {\r\n icons: { FileDeleteIcon },\r\n imageEditor,\r\n } = useUploaderOptions()\r\n const { openImageEditor } = useUploaderEditor()\r\n const { isDark: dark } = useUploaderTheme()\r\n const {\r\n upload: { filesProgressMap },\r\n } = useUploaderUploadControls()\r\n\r\n const type = file.type ?? ''\r\n const isImage = useMemo(() => fileGetIsImage(type), [type])\r\n const isVideo = useMemo(() => type.startsWith('video/'), [type])\r\n const isSuccessful = file.status === UploadStatus.SUCCESSFUL\r\n const isBusy =\r\n file.status === UploadStatus.UPLOADING ||\r\n file.status === UploadStatus.PROCESSING\r\n const thumb = useMemo(\r\n () => nonMediaThumb(type, file.name),\r\n [type, file.name],\r\n )\r\n const progress = useMemo(() => {\r\n const p = filesProgressMap[file.id]\r\n const loaded = p?.loaded ?? NaN\r\n const total = p?.total ?? NaN\r\n const pct = Math.floor((loaded / total) * 100)\r\n // No progress entry ⇒ NaN; total === 0 ⇒ Infinity. Either would render\r\n // width:NaN%/aria-valuenow=NaN in ProgressBar while an upload is active.\r\n return Number.isFinite(pct) ? pct : 0\r\n }, [file.id, filesProgressMap])\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'upup-fx-hover-lift upup-flex upup-w-full upup-items-center upup-gap-3 upup-rounded-xl upup-px-3 upup-py-2.5 upup-ring-1',\r\n dark\r\n ? 'upup-bg-white/[0.04] upup-ring-white/[0.07]'\r\n : 'upup-bg-black/[0.04] upup-ring-black/[0.06]',\r\n )}\r\n >\r\n <div\r\n className=\"upup-relative upup-flex upup-h-10 upup-w-10 upup-flex-none upup-items-center upup-justify-center upup-overflow-hidden upup-rounded-[9px] upup-bg-center upup-bg-cover upup-bg-no-repeat\"\r\n style={\r\n isImage\r\n ? { backgroundImage: `url(${file.url ?? ''})` }\r\n : isVideo\r\n ? undefined\r\n : { background: thumb.gradient }\r\n }\r\n >\r\n {/* Real first-frame video thumbnail (no controls chrome). Uses the\r\n local object URL, which persists through upload (updateFile keeps\r\n `url`), so the preview survives a completed run. */}\r\n {isVideo && (\r\n <video\r\n src={file.url ?? ''}\r\n muted\r\n playsInline\r\n preload=\"metadata\"\r\n className=\"upup-pointer-events-none upup-absolute upup-inset-0 upup-h-full upup-w-full upup-object-cover\"\r\n />\r\n )}\r\n {!isImage && !isVideo && (\r\n <Icon\r\n name={thumb.icon}\r\n size={20}\r\n className=\"upup-text-white\"\r\n />\r\n )}\r\n </div>\r\n\r\n <div className=\"upup-flex upup-min-w-0 upup-flex-1 upup-flex-col upup-gap-0.5\">\r\n <div\r\n className={cn(\r\n 'upup-truncate upup-text-[13px]',\r\n dark ? 'upup-text-[#e2e8f0]' : 'upup-text-gray-900',\r\n )}\r\n >\r\n {file.name}\r\n </div>\r\n <div\r\n className={cn(\r\n 'upup-text-[12px]',\r\n dark ? 'upup-text-[#94a3b8]' : 'upup-text-gray-500',\r\n )}\r\n >\r\n {formatFileSize(file.size, tr)}\r\n </div>\r\n {!!progress && (\r\n <ProgressBar\r\n className=\"upup-mt-1\"\r\n progressBarClassName=\"upup-rounded\"\r\n progress={progress}\r\n showValue\r\n />\r\n )}\r\n </div>\r\n\r\n {/* Edit affordance for images (list view) — enabled pre/post upload,\r\n disabled only while the file is in flight (round-8 item 1). */}\r\n {isImage && imageEditor.enabled && (\r\n <button\r\n className={cn(\r\n 'upup-fx-press upup-flex upup-h-8 upup-w-8 upup-flex-none upup-items-center upup-justify-center upup-rounded-lg',\r\n dark\r\n ? 'upup-text-[#64748b] hover:upup-bg-white/[0.06]'\r\n : 'upup-text-gray-500 hover:upup-bg-black/[0.06]',\r\n 'disabled:upup-cursor-not-allowed disabled:upup-opacity-50',\r\n )}\r\n onClick={e => {\r\n e.stopPropagation()\r\n openImageEditor(file)\r\n }}\r\n type=\"button\"\r\n disabled={isBusy}\r\n aria-label={tr.editImage}\r\n data-testid=\"upup-file-edit\"\r\n >\r\n <EditIcon className=\"upup-h-5 upup-w-5\" />\r\n </button>\r\n )}\r\n\r\n {isSuccessful && (\r\n <FileSuccessCheck\r\n index={index}\r\n size={22}\r\n className=\"upup-flex-none\"\r\n />\r\n )}\r\n\r\n {/* Once a file has uploaded successfully its delete control is gone —\r\n the completion check is the only trailing affordance. */}\r\n {!isSuccessful && (\r\n <button\r\n className={cn(\r\n 'upup-fx-remove upup-fx-press upup-flex upup-h-8 upup-w-8 upup-flex-none upup-items-center upup-justify-center upup-rounded-lg',\r\n dark\r\n ? 'upup-text-[#64748b] hover:upup-bg-white/[0.06]'\r\n : 'upup-text-gray-500 hover:upup-bg-black/[0.06]',\r\n 'disabled:upup-cursor-not-allowed disabled:upup-opacity-50',\r\n )}\r\n onClick={e => {\r\n e.stopPropagation()\r\n handleFileRemove(file.id)\r\n }}\r\n type=\"button\"\r\n disabled={isFileRemovalLocked(progress, file.status)}\r\n aria-label={tr.removeFile}\r\n data-testid=\"upup-file-remove\"\r\n >\r\n <FileDeleteIcon className=\"upup-h-5 upup-w-5\" />\r\n </button>\r\n )}\r\n </div>\r\n )\r\n})\r\n","import React, { memo, useMemo } from 'react'\r\nimport { cn, isFileRemovalLocked } from '@useupup/core/internal'\r\nimport { UploadStatus, type UploadFile } from '@useupup/core'\r\nimport {\r\n useUploaderEditor,\r\n useUploaderFiles,\r\n useUploaderI18n,\r\n useUploaderOptions,\r\n useUploaderTheme,\r\n useUploaderUploadControls,\r\n} from '../context/UploaderContext'\r\nimport { fileGetExtension, fileGetIsImage, formatFileSize } from '../lib/file'\r\nimport FileIcon from './FileIcon'\r\nimport ProgressBar from './shared/ProgressBar'\r\nimport FileSuccessCheck from './shared/FileSuccessCheck'\r\nimport EditIcon from './shared/EditIcon'\r\n\r\ntype Props = {\r\n file: UploadFile\r\n}\r\n\r\n/**\r\n * Single-file HERO preview (spec §4 state 3, states-tour-v2.html \"single file\").\r\n * One visual fills the fixed-height content area with a bottom scrim caption.\r\n * The panel is fixed-height by ruling, so the media MUST stay bounded with\r\n * `min-h-0 flex-1 object-contain` — the repo's #1 visual trap.\r\n */\r\nexport default memo(function FileHero({ file }: Props) {\r\n const { handleFileRemove } = useUploaderFiles()\r\n const { translations: tr } = useUploaderI18n()\r\n const {\r\n icons: { FileDeleteIcon },\r\n imageEditor,\r\n } = useUploaderOptions()\r\n const { openImageEditor } = useUploaderEditor()\r\n const { isDark: dark } = useUploaderTheme()\r\n const {\r\n upload: { filesProgressMap },\r\n } = useUploaderUploadControls()\r\n\r\n const isSuccessful = file.status === UploadStatus.SUCCESSFUL\r\n const isBusy =\r\n file.status === UploadStatus.UPLOADING ||\r\n file.status === UploadStatus.PROCESSING\r\n const isImage = useMemo(() => fileGetIsImage(file.type ?? ''), [file.type])\r\n const isVideo = useMemo(\r\n () => (file.type ?? '').startsWith('video/'),\r\n [file.type],\r\n )\r\n const extension = useMemo(\r\n () => fileGetExtension(file.type ?? '', file.name),\r\n [file.type, file.name],\r\n )\r\n const progress = useMemo(() => {\r\n const p = filesProgressMap[file.id]\r\n const loaded = p?.loaded ?? NaN\r\n const total = p?.total ?? NaN\r\n const pct = Math.floor((loaded / total) * 100)\r\n // No progress entry ⇒ NaN; total === 0 ⇒ Infinity. Either would render\r\n // width:NaN%/aria-valuenow=NaN in ProgressBar while an upload is active.\r\n return Number.isFinite(pct) ? pct : 0\r\n }, [file.id, filesProgressMap])\r\n\r\n return (\r\n <div\r\n data-testid=\"upup-file-hero\"\r\n data-upup-slot=\"file-hero\"\r\n role=\"listitem\"\r\n className={cn(\r\n 'upup-relative upup-flex upup-min-h-0 upup-flex-1 upup-flex-col upup-overflow-hidden upup-rounded-2xl upup-ring-1',\r\n dark\r\n ? 'upup-bg-white/[0.03] upup-ring-white/[0.08]'\r\n : 'upup-bg-black/[0.04] upup-ring-black/[0.06]',\r\n )}\r\n >\r\n {isImage ? (\r\n <img\r\n src={file.url ?? ''}\r\n alt={file.name}\r\n className=\"upup-min-h-0 upup-flex-1 upup-object-contain\"\r\n />\r\n ) : isVideo ? (\r\n // preload=\"metadata\" paints the first frame — a real thumbnail\r\n // without controls chrome. Muted + playsInline keep mobile\r\n // browsers from hijacking it into a player.\r\n <video\r\n src={file.url ?? ''}\r\n muted\r\n playsInline\r\n preload=\"metadata\"\r\n className=\"upup-pointer-events-none upup-min-h-0 upup-flex-1 upup-object-contain\"\r\n />\r\n ) : (\r\n <div className=\"upup-flex upup-min-h-0 upup-flex-1 upup-items-center upup-justify-center upup-bg-gradient-to-br upup-from-[#0ea5e9]/10 upup-to-[#7c3aed]/10\">\r\n <FileIcon extension={extension} />\r\n </div>\r\n )}\r\n\r\n {file.status === UploadStatus.SUCCESSFUL && (\r\n <FileSuccessCheck className=\"upup-absolute upup-left-3 upup-top-3 upup-z-10\" />\r\n )}\r\n\r\n {/* Delete is gone once the file has uploaded successfully — the\r\n completion check (top-left) is the only remaining overlay mark. */}\r\n {file.status !== UploadStatus.SUCCESSFUL && (\r\n <button\r\n className={cn(\r\n 'upup-fx-remove upup-fx-press upup-absolute upup-right-3 upup-top-3 upup-z-10',\r\n 'upup-flex upup-h-[34px] upup-w-[34px] upup-items-center upup-justify-center',\r\n 'upup-rounded-[9px] upup-bg-[#04080f]/40 upup-text-[#e2e8f0]',\r\n 'hover:upup-bg-[#04080f]/65',\r\n 'disabled:upup-cursor-not-allowed disabled:upup-opacity-50',\r\n )}\r\n onClick={e => {\r\n e.stopPropagation()\r\n handleFileRemove(file.id)\r\n }}\r\n type=\"button\"\r\n disabled={isFileRemovalLocked(progress, file.status)}\r\n aria-label={tr.removeFile}\r\n data-testid=\"upup-file-remove\"\r\n >\r\n <FileDeleteIcon className=\"upup-h-5 upup-w-5\" />\r\n </button>\r\n )}\r\n\r\n {/* Edit affordance for images (single-file hero) — pre/post upload;\r\n sits left of the trash, and slides to the trash's slot once the\r\n file is done and the trash is gone (round-8 item 1). */}\r\n {isImage && imageEditor.enabled && (\r\n <button\r\n className={cn(\r\n 'upup-fx-press upup-absolute upup-top-3 upup-z-10',\r\n isSuccessful ? 'upup-right-3' : 'upup-right-[54px]',\r\n 'upup-flex upup-h-[34px] upup-w-[34px] upup-items-center upup-justify-center',\r\n 'upup-rounded-[9px] upup-bg-[#04080f]/40 upup-text-[#e2e8f0]',\r\n 'hover:upup-bg-[#04080f]/65',\r\n 'disabled:upup-cursor-not-allowed disabled:upup-opacity-50',\r\n )}\r\n onClick={e => {\r\n e.stopPropagation()\r\n openImageEditor(file)\r\n }}\r\n type=\"button\"\r\n disabled={isBusy}\r\n aria-label={tr.editImage}\r\n data-testid=\"upup-file-edit\"\r\n >\r\n <EditIcon className=\"upup-h-5 upup-w-5\" />\r\n </button>\r\n )}\r\n\r\n {/* Caption scrim: theme-aware (a black scrim over a light hero read\r\n as a dark-mode leak). The progress bar lives INSIDE the scrim\r\n flow so it can never overlap the name/size lines. */}\r\n <div\r\n className={cn(\r\n 'upup-pointer-events-none upup-absolute upup-inset-x-0 upup-bottom-0 upup-bg-gradient-to-t upup-to-transparent upup-px-[18px] upup-pb-3.5 upup-pt-4',\r\n dark\r\n ? 'upup-from-[#04080f]/[0.86] upup-via-[#04080f]/50'\r\n : 'upup-from-white/[0.92] upup-via-white/60',\r\n )}\r\n >\r\n <div\r\n className={cn(\r\n 'upup-truncate upup-text-[13px] upup-font-semibold',\r\n dark ? 'upup-text-[#e2e8f0]' : 'upup-text-[#1e293b]',\r\n )}\r\n >\r\n {file.name}\r\n </div>\r\n <div\r\n className={cn(\r\n 'upup-mt-0.5 upup-text-[12px]',\r\n dark ? 'upup-text-[#94a3b8]' : 'upup-text-[#64748b]',\r\n )}\r\n >\r\n {formatFileSize(file.size, tr)}\r\n </div>\r\n <ProgressBar\r\n className={cn(\r\n 'upup-mt-2',\r\n dark ? 'upup-text-white' : 'upup-text-[#0f172a]',\r\n )}\r\n progressBarClassName=\"upup-rounded\"\r\n progress={progress}\r\n showValue\r\n />\r\n </div>\r\n </div>\r\n )\r\n})\r\n","import React from 'react'\r\nimport Icon from '../Icon'\r\nimport { formatUiMessage as t, pluralUiMessage as plural } from '@useupup/core'\r\nimport { cn, isUploadActive } from '@useupup/core/internal'\r\nimport {\r\n useUploaderFiles,\r\n useUploaderI18n,\r\n useUploaderOptions,\r\n useUploaderTheme,\r\n useUploaderUploadControls,\r\n useUploaderView,\r\n} from '../../context/UploaderContext'\r\ntype Props = {\r\n handleCancel(): void\r\n /** True when the panel forces the row list (tiles don't fit one row) —\r\n * the grid/list toggle is hidden in that state. */\r\n forcedList?: boolean\r\n /** True in quiet-completion mode after success — hides the add-more control\r\n * so the completed panel offers no further CTAs. */\r\n hideAddMore?: boolean\r\n}\r\n\r\nexport default function UploaderHeader({\r\n handleCancel,\r\n forcedList = false,\r\n hideAddMore = false,\r\n}: Readonly<Props>): React.ReactElement | null {\r\n const { files } = useUploaderFiles()\r\n const { viewMode, setViewMode, openSourceOverlay } = useUploaderView()\r\n const { translations: tr } = useUploaderI18n()\r\n const {\r\n mini,\r\n limit,\r\n isProcessing,\r\n icons: { ContainerAddMoreIcon },\r\n } = useUploaderOptions()\r\n const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme()\r\n const {\r\n upload: { uploadStatus },\r\n } = useUploaderUploadControls()\r\n const isUploading = isUploadActive(uploadStatus)\r\n const isLimitReached = limit === files.size\r\n\r\n if (mini) return null\r\n\r\n return (\r\n <div\r\n data-testid=\"upup-header\"\r\n data-upup-slot=\"header\"\r\n className={cn(\r\n 'upup-shadow-bottom upup-left-0 upup-right-0 upup-top-0 upup-z-10 upup-grid upup-grid-cols-4 upup-grid-rows-2 upup-items-center upup-justify-between upup-rounded-t-lg upup-bg-black/[0.025] upup-px-3 upup-py-2 md:upup-grid-rows-1',\r\n {\r\n 'upup-bg-white/5 dark:upup-bg-white/5': dark,\r\n },\r\n slotClasses.containerHeader,\r\n )}\r\n >\r\n <button\r\n className={cn(\r\n 'upup-max-md upup-col-start-1 upup-col-end-3 upup-row-start-2 upup-p-1 upup-text-left upup-text-sm upup-text-[#0284c7] md:upup-col-end-2 md:upup-row-start-1',\r\n {\r\n 'upup-text-[#38bdf8] dark:upup-text-[#38bdf8]': dark,\r\n },\r\n slotClasses.containerCancelButton,\r\n )}\r\n onClick={handleCancel}\r\n disabled={isUploading || isProcessing}\r\n >\r\n {tr.removeAllFiles}\r\n </button>\r\n <span\r\n className={cn(\r\n 'upup-col-span-4 upup-text-center upup-text-sm upup-text-[#6D6D6D] md:upup-col-span-2',\r\n {\r\n 'upup-text-gray-300 dark:upup-text-gray-300': dark,\r\n },\r\n )}\r\n >\r\n {t(plural(tr, 'filesSelected', files.size), {\r\n count: files.size,\r\n })}\r\n </span>\r\n <div className=\"upup-col-start-3 upup-col-end-5 upup-flex upup-items-center upup-justify-end upup-gap-2 md:upup-col-start-4\">\r\n {/* Two-segment grid|list control. Hidden once the row list is\r\n forced (tiles don't fit one row of the fixed panel). The\r\n active segment carries the sky highlight; both segments always\r\n show their icon so the choice is self-evident. */}\r\n {files.size > 1 && !forcedList && (\r\n <div\r\n role=\"group\"\r\n aria-label={tr.switchToGridView}\r\n data-upup-slot=\"view-toggle\"\r\n className={cn(\r\n 'upup-flex upup-items-center upup-gap-0.5 upup-rounded-lg upup-p-0.5',\r\n dark\r\n ? 'upup-bg-white/[0.06]'\r\n : 'upup-bg-black/[0.05]',\r\n )}\r\n >\r\n <button\r\n data-testid=\"upup-view-toggle-grid\"\r\n aria-label={tr.switchToGridView}\r\n aria-pressed={viewMode === 'grid'}\r\n title={tr.switchToGridView}\r\n className={cn(\r\n 'upup-flex upup-h-6 upup-items-center upup-justify-center upup-gap-1 upup-rounded-md upup-px-1.5 upup-transition-colors',\r\n viewMode === 'grid'\r\n ? 'upup-bg-[#0ea5e9] upup-text-white'\r\n : dark\r\n ? 'upup-text-gray-300 hover:upup-bg-white/10'\r\n : 'upup-text-gray-500 hover:upup-bg-black/10',\r\n )}\r\n onClick={() => {\r\n setViewMode('grid')\r\n }}\r\n >\r\n <Icon name=\"layout-grid\" size={15} />\r\n {/* Label only on the ACTIVE segment, and only at md+\r\n where the header has room (mini shows no header at\r\n all). Inactive segment stays icon-only. */}\r\n {viewMode === 'grid' && (\r\n <span className=\"upup-hidden upup-text-xs upup-font-medium upup-leading-none md:upup-inline\">\r\n {tr.viewGrid}\r\n </span>\r\n )}\r\n </button>\r\n <button\r\n data-testid=\"upup-view-toggle-list\"\r\n aria-label={tr.switchToListView}\r\n aria-pressed={viewMode === 'list'}\r\n title={tr.switchToListView}\r\n className={cn(\r\n 'upup-flex upup-h-6 upup-items-center upup-justify-center upup-gap-1 upup-rounded-md upup-px-1.5 upup-transition-colors',\r\n viewMode === 'list'\r\n ? 'upup-bg-[#0ea5e9] upup-text-white'\r\n : dark\r\n ? 'upup-text-gray-300 hover:upup-bg-white/10'\r\n : 'upup-text-gray-500 hover:upup-bg-black/10',\r\n )}\r\n onClick={() => {\r\n setViewMode('list')\r\n }}\r\n >\r\n <Icon name=\"layout-list\" size={15} />\r\n {viewMode === 'list' && (\r\n <span className=\"upup-hidden upup-text-xs upup-font-medium upup-leading-none md:upup-inline\">\r\n {tr.viewList}\r\n </span>\r\n )}\r\n </button>\r\n </div>\r\n )}\r\n {limit > 1 && !isLimitReached && !hideAddMore && (\r\n <button\r\n data-testid=\"upup-add-more\"\r\n data-placement=\"header\"\r\n data-upup-slot=\"add-more\"\r\n className={cn(\r\n 'upup-fx-hover-lift upup-fx-press upup-inline-flex upup-shrink-0 upup-items-center upup-gap-1 upup-whitespace-nowrap upup-rounded-md upup-border upup-border-dashed upup-border-[#38bdf8]/50 upup-px-2 upup-py-1 upup-text-sm upup-leading-none upup-text-[#0284c7]',\r\n {\r\n 'upup-text-[#38bdf8] dark:upup-text-[#38bdf8]':\r\n dark,\r\n },\r\n slotClasses.containerAddMoreButton,\r\n )}\r\n onClick={() => {\r\n openSourceOverlay()\r\n }}\r\n disabled={isUploading || isProcessing}\r\n >\r\n <ContainerAddMoreIcon /> {tr.addMore}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n}\r\n","/**\r\n * Grid-tile geometry. The grid lays tiles with\r\n * `repeat(auto-fit, minmax(FILE_TILE_MIN, 1fr))` and a FILE_TILE_GAP gap, so a\r\n * row fits floor((width + gap) / (min + gap)) tiles before it would wrap, and\r\n * the tiles STRETCH to fill the row (no dead columns). The force-list rule below\r\n * uses the SAME numbers so the grid never wraps: the moment one more tile would\r\n * spill to a second row, list mode is forced instead.\r\n */\r\nexport const FILE_TILE_MIN = 160\r\nexport const FILE_TILE_GAP = 16\r\n\r\n/**\r\n * How many auto-fit tiles fit across `containerWidth` in a single row. A\r\n * non-positive / non-finite (unmeasured) width yields 0, which\r\n * isListViewForced reads as \"not measured yet — don't force a switch\".\r\n */\r\nexport function computeTilesPerRow(containerWidth: number): number {\r\n if (!Number.isFinite(containerWidth) || containerWidth <= 0) return 0\r\n return Math.max(\r\n 1,\r\n Math.floor(\r\n (containerWidth + FILE_TILE_GAP) / (FILE_TILE_MIN + FILE_TILE_GAP),\r\n ),\r\n )\r\n}\r\n\r\n/**\r\n * The square-tile grid is only honored when every tile fits in ONE row of the\r\n * fixed-height panel; past that the row list is FORCED and UploaderHeader hides\r\n * the grid/list toggle. `tilesPerRow <= 0` means the container has not been\r\n * measured yet — treated as \"fits\" so the first paint never flashes to list.\r\n */\r\nexport function isListViewForced(\r\n fileCount: number,\r\n tilesPerRow: number,\r\n): boolean {\r\n if (tilesPerRow <= 0) return false\r\n return fileCount > tilesPerRow\r\n}\r\n","import { RefObject, useEffect, useState } from 'react'\r\nimport { computeTilesPerRow } from './view-mode'\r\n\r\n/**\r\n * Measure `ref`'s content-box width with a ResizeObserver and derive how many\r\n * 145px grid tiles fit one row (see view-mode.ts). Returns 0 until measured\r\n * (SSR / jsdom / pre-paint), which isListViewForced reads as \"unknown — don't\r\n * force list yet\". Isolated in its own module so tests can mock the measurement\r\n * seam without a real layout engine.\r\n */\r\nexport function useTilesPerRow(ref: RefObject<HTMLElement | null>): number {\r\n const [width, setWidth] = useState(0)\r\n useEffect(() => {\r\n const el = ref.current\r\n if (!el || typeof ResizeObserver === 'undefined') return\r\n const ro = new ResizeObserver(entries => {\r\n const next = entries[0]?.contentRect.width ?? 0\r\n setWidth(prev => (prev === next ? prev : next))\r\n })\r\n ro.observe(el)\r\n return () => {\r\n ro.disconnect()\r\n }\r\n }, [ref])\r\n return computeTilesPerRow(width)\r\n}\r\n","import {\r\n Dispatch,\r\n SetStateAction,\r\n createElement,\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useSyncExternalStore,\r\n} from 'react'\r\nimport {\r\n FileSource,\r\n UploadStatus,\r\n resolveTheme,\r\n flattenSlotsToClassNames,\r\n type UploadFile,\r\n type UiTranslations,\r\n} from '@useupup/core'\r\nimport {\r\n normalizeUploaderOptions,\r\n createUploaderController,\r\n type UploaderController,\r\n type UploaderControllerOptions,\r\n type OrchestratorState,\r\n type ThemeStoreState,\r\n type MotionMode,\r\n type TransientUiSnapshot,\r\n type CloudProvider,\r\n} from '@useupup/core/internal'\r\nimport Icon from '../components/Icon'\r\nimport { UploaderProps } from '../shared/types'\r\nimport { IUploaderContext } from '../context/UploaderContext'\r\nimport { useUpupUpload } from '../use-upup-upload'\r\nimport { useSSEProcessing } from './useSSEProcessing'\r\n\r\n/** Default loader icon — renders the registry 'loader' glyph via the shared Icon renderer\r\n * (which applies the stroke attrs, so the glyph is visible). Forwards size/class like the\r\n * former react-icons default did. */\r\nconst DefaultLoaderIconComponent = (props: {\r\n size?: number | undefined\r\n className?: string | undefined\r\n}) => createElement(Icon, { name: 'loader', ...props })\r\n\r\n/** Default 'add more' icon — renders the registry 'plus' glyph (was react-icons TbPlus). */\r\nconst DefaultPlusIconComponent = (props: {\r\n size?: number | undefined\r\n className?: string | undefined\r\n}) => createElement(Icon, { name: 'plus', ...props })\r\n\r\n/** Default camera-capture icon — renders the registry 'capture' glyph (was react-icons TbCapture). */\r\nconst DefaultCaptureIconComponent = (props: {\r\n size?: number | undefined\r\n className?: string | undefined\r\n}) => createElement(Icon, { name: 'capture', ...props })\r\n\r\n/** Default camera-rotate icon — renders the registry 'camera-rotate' glyph (was react-icons TbCameraRotate). */\r\nconst DefaultCameraRotateIconComponent = (props: {\r\n size?: number | undefined\r\n className?: string | undefined\r\n}) => createElement(Icon, { name: 'camera-rotate', ...props })\r\n\r\n/** Default delete icon (file + camera slots) — renders the registry 'trash' glyph (was react-icons TbTrash). */\r\nconst DefaultTrashIconComponent = (props: {\r\n size?: number | undefined\r\n className?: string | undefined\r\n}) => createElement(Icon, { name: 'trash', ...props })\r\n\r\nconst EMPTY_THEME_SLOTS = {}\r\nconst EMPTY_STYLE = {}\r\n\r\n/** Read-only drive provider → flattened i18n label key (the human provider name\r\n * for the drop-rejection toast). Typed `Record<CloudProvider, keyof\r\n * UiTranslations>` so the compiler enforces exhaustiveness against the same\r\n * drive-source union core's DragDropController gates on — a new provider fails\r\n * typecheck here until its label key is wired. */\r\nconst DRIVE_SOURCE_LABEL_KEY: Record<CloudProvider, keyof UiTranslations> = {\r\n googleDrive: 'googleDrive',\r\n oneDrive: 'oneDrive',\r\n dropbox: 'dropbox',\r\n box: 'box',\r\n}\r\n\r\n/** Stable server/pre-mount snapshot for the transient-UI store (matches the\r\n * core unit's initial shape: nothing leaving, no overlay, no rejection). */\r\nconst EMPTY_TRANSIENT_UI: TransientUiSnapshot = {\r\n leavingFileIds: new Set<string>(),\r\n sourceOverlayOpen: false,\r\n sourceOverlayClosing: false,\r\n dropRejected: null,\r\n}\r\n\r\n/** Stable server snapshot for SSR (useSyncExternalStore third arg). */\r\nconst SERVER_SNAPSHOT: OrchestratorState = {\r\n files: new Map(),\r\n uploadStatus: UploadStatus.IDLE,\r\n uploadError: '',\r\n totalProgress: 0,\r\n filesProgressMap: {},\r\n uploadSpeed: 0,\r\n uploadEta: 0,\r\n uploadedBytes: 0,\r\n totalBytes: 0,\r\n activeSource: undefined,\r\n editingFile: null,\r\n editorQueue: [],\r\n isAddingMore: false,\r\n viewMode: 'grid',\r\n isOnline: true,\r\n}\r\n\r\n/** Shape a resolved theme into the ThemeStoreState snapshot (mirrors ThemeStore.compute()).\r\n * Pure — used for the pre-mount / SSR fallback when `controller` (hence controller.theme) is not yet created. */\r\nfunction themeStateFromResolved(\r\n resolved: ThemeStoreState['resolved'],\r\n): ThemeStoreState {\r\n return {\r\n themeMode: resolved.mode,\r\n isDark: resolved.mode === 'dark',\r\n tokens: resolved.tokens,\r\n resolved,\r\n slotOverrides: flattenSlotsToClassNames(resolved.slots),\r\n slots: resolved.slots ?? {},\r\n }\r\n}\r\n\r\nexport default function useUploaderController(\r\n props: UploaderProps,\r\n): IUploaderContext {\r\n const {\r\n allowedFileTypes: acceptProp = '*',\r\n mini = false,\r\n animations = true,\r\n theme,\r\n maxFiles,\r\n isProcessing = false,\r\n allowPreview = true,\r\n folderUpload,\r\n showBranding = true,\r\n quietCompletion = false,\r\n disableDragDrop = false,\r\n className,\r\n style,\r\n maxFileSize: maxFileSizeProp,\r\n minFileSize: minFileSizeProp,\r\n maxTotalFileSize: maxTotalFileSizeProp,\r\n imageCompression = false,\r\n thumbnailGenerator = false,\r\n checksumVerification = false,\r\n webWorker,\r\n heicConversion = false,\r\n stripExifData = false,\r\n contentDeduplication = false,\r\n crashRecovery = false,\r\n // No destructure default: `undefined` must reach core so its default-on\r\n // network awareness applies; only an explicit `false` opts out.\r\n networkAware,\r\n sources,\r\n onError: errorHandler,\r\n onWarn: warningHandler,\r\n icons = {},\r\n i18n,\r\n onIntegrationClick = () => {},\r\n onFileClick = () => {},\r\n onFileRemoved,\r\n onStatusChange,\r\n onFilesDragOver = () => {},\r\n onFilesDragLeave = () => {},\r\n onFilesDrop = () => {},\r\n onFileTypeMismatch = () => {},\r\n onBeforeFileAdded,\r\n onRestrictionFailed,\r\n enablePaste = false,\r\n autoUpload = false,\r\n maxConcurrentUploads,\r\n imageEditor: imageEditorProp,\r\n onUploadStart = () => {},\r\n onFileUploadStart = () => {},\r\n onFileUploadProgress = () => {},\r\n onFilesUploadProgress = () => {},\r\n onFileUploadComplete = () => {},\r\n onFilesUploadComplete = () => {},\r\n onUploadComplete = () => {},\r\n onFilesSelected = () => {},\r\n onDoneClicked = () => {},\r\n onPrepareFiles,\r\n provider,\r\n mode: modeProp,\r\n uploadEndpoint,\r\n serverUrl,\r\n cloudDrives,\r\n metadata,\r\n cors,\r\n maxRetries,\r\n resumable,\r\n processingEndpoint,\r\n onFileProcessed,\r\n processingTimeout,\r\n } = props\r\n\r\n const onError = useCallback(\r\n (message: string) => {\r\n errorHandler?.(message)\r\n },\r\n [errorHandler],\r\n )\r\n const onWarn = useCallback(\r\n (message: string) => {\r\n warningHandler?.(message)\r\n },\r\n [warningHandler],\r\n )\r\n\r\n // ── Build factory-compatible options object ──────────────────\r\n // UploaderProps.allowedFileTypes is string | string[] | undefined;\r\n // UploaderControllerOptions.allowedFileTypes is string | undefined.\r\n // normalizeUploaderOptions handles both at runtime via a cast, so we cast here.\r\n const factoryOptions = useMemo<UploaderControllerOptions>(\r\n () => ({\r\n provider,\r\n mode: modeProp,\r\n sources: sources,\r\n uploadEndpoint,\r\n serverUrl,\r\n maxFiles,\r\n theme,\r\n folderUpload,\r\n cors,\r\n cloudDrives,\r\n imageCompression,\r\n thumbnailGenerator,\r\n checksumVerification,\r\n webWorker,\r\n heicConversion,\r\n stripExifData,\r\n contentDeduplication,\r\n autoUpload,\r\n maxConcurrentUploads,\r\n crashRecovery,\r\n networkAware,\r\n allowedFileTypes:\r\n typeof acceptProp === 'string'\r\n ? acceptProp\r\n : acceptProp.join(','),\r\n mini,\r\n animations,\r\n isProcessing,\r\n allowPreview,\r\n showBranding,\r\n quietCompletion,\r\n disableDragDrop,\r\n className,\r\n maxFileSize: maxFileSizeProp,\r\n minFileSize: minFileSizeProp,\r\n maxTotalFileSize: maxTotalFileSizeProp,\r\n imageEditor: imageEditorProp,\r\n metadata,\r\n maxRetries,\r\n resumable,\r\n i18n,\r\n onBeforeFileAdded,\r\n // Callbacks: set to current stable refs; updated live via controller.updateCallbacks() each render\r\n onError: errorHandler,\r\n onWarn: warningHandler,\r\n onUploadStart,\r\n onFileUploadStart,\r\n onFileUploadProgress,\r\n onFilesUploadProgress,\r\n onFileUploadComplete,\r\n onFilesUploadComplete,\r\n onUploadComplete,\r\n onFilesSelected,\r\n onDoneClicked,\r\n onPrepareFiles,\r\n onFileRemoved,\r\n onStatusChange,\r\n onFileTypeMismatch,\r\n onRestrictionFailed,\r\n }),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps -- every field is destructured from `props`; memoizing on props identity is equivalent to listing all ~50 and intentional (mirrors normalizeUploaderOptions below)\r\n [props],\r\n ) // props identity memoization — same as normalizeUploaderOptions below\r\n\r\n // ── Normalize options (pure; memoized on props identity) ─────\r\n const normalized = useMemo(\r\n () => normalizeUploaderOptions(factoryOptions),\r\n [factoryOptions],\r\n )\r\n const { resolved } = normalized\r\n\r\n // ── Core (via useUpupUpload; owns core lifecycle) ────────────\r\n const upload = useUpupUpload(normalized.coreOptions)\r\n const core = upload.core\r\n\r\n // ── SSE processing ──────────────────────────────────────────\r\n const { connectSSE } = useSSEProcessing({\r\n processingEndpoint,\r\n onFileProcessed,\r\n onError: err => {\r\n onError(err.message)\r\n },\r\n processingTimeout,\r\n })\r\n\r\n // Keep connectSSERef fresh every render (factory proxy reads via closure)\r\n const connectSSERef = useRef(connectSSE)\r\n connectSSERef.current = connectSSE\r\n\r\n // ── Uploader controller (created once, guarded ref) ──────────────\r\n const controllerRef = useRef<UploaderController | null>(null)\r\n if (!controllerRef.current && core) {\r\n controllerRef.current = createUploaderController(\r\n { core, options: factoryOptions, normalized },\r\n {\r\n connectSSE: file => {\r\n connectSSERef.current(file)\r\n },\r\n },\r\n )\r\n }\r\n const controller = controllerRef.current\r\n\r\n // Refresh proxied callbacks every render (replaces old callbackRefs.current overwrite).\r\n // Must call before any render-path reads from the proxy.\r\n if (controller) {\r\n controller.updateCallbacks({\r\n onError,\r\n onWarn,\r\n onUploadStart,\r\n onFileUploadStart,\r\n onFileUploadProgress,\r\n onFilesUploadProgress,\r\n onFileUploadComplete,\r\n onFilesUploadComplete,\r\n onUploadComplete,\r\n onFilesSelected,\r\n onDoneClicked,\r\n onPrepareFiles,\r\n onFileRemoved,\r\n onStatusChange,\r\n onFileTypeMismatch,\r\n onRestrictionFailed,\r\n autoUpload,\r\n })\r\n }\r\n\r\n // ── Subscribe to orchestrator state (React 18 useSyncExternalStore) ──\r\n const getServerSnapshot = useCallback(() => SERVER_SNAPSHOT, [])\r\n const state = useSyncExternalStore(\r\n controller?.orchestrator.subscribe ?? (() => () => {}),\r\n controller?.orchestrator.getSnapshot ?? (() => SERVER_SNAPSHOT),\r\n getServerSnapshot,\r\n )\r\n\r\n // ── Subscribe to theme state (ThemeStore → replaces useResolvedThemeMode) ──\r\n // ThemeStore.init() owns the same matchMedia('prefers-color-scheme: dark') subscription\r\n // as the old useResolvedThemeMode, so light/dark/system resolve identically.\r\n // ThemeStoreState fields (themeMode, isDark, tokens, resolved, slotOverrides, slots)\r\n // map 1:1 to ContextTheme — no field renaming needed.\r\n //\r\n // First-paint parity: on the very first render `controller` is null (core is created in\r\n // useUpupUpload's post-paint effect), so the store/server snapshot is used. It must\r\n // resolve the EXPLICIT mode synchronously to match the OLD synchronous resolveTheme:\r\n // - mode 'dark' → dark on first paint (no light→dark flash)\r\n // - mode 'light' → light\r\n // - mode 'system' → 'light' pre-mount (matches old useState('light') initial; the\r\n // matchMedia flip happens after mount via ThemeStore.init()).\r\n // Memoized on props.theme for referential stability (useSyncExternalStore requires the\r\n // server/getSnapshot fallback to be stable). Deterministic from props → SSR + hydration\r\n // compute the same value, so no hydration mismatch and the module-level light constant\r\n // is no longer needed.\r\n const themeFallback = useMemo<ThemeStoreState>(() => {\r\n const requested = theme?.mode\r\n const mode: 'light' | 'dark' = requested === 'dark' ? 'dark' : 'light'\r\n return themeStateFromResolved(\r\n resolveTheme({\r\n ...(theme ?? {}),\r\n mode,\r\n }) as ThemeStoreState['resolved'],\r\n )\r\n }, [theme])\r\n const getThemeServerSnapshot = useCallback(\r\n () => themeFallback,\r\n [themeFallback],\r\n )\r\n const themeState = useSyncExternalStore(\r\n controller?.theme.subscribe ?? (() => () => {}),\r\n controller?.theme.getSnapshot ?? (() => themeFallback),\r\n getThemeServerSnapshot,\r\n )\r\n\r\n // ── Subscribe to the motion gate (data-motion resolution) ──\r\n // The gate resolves `off` iff `animations={false}` OR the OS asks for\r\n // reduced motion; the panel writes the snapshot as `data-motion` and the\r\n // shared CSS gates every `upup-fx-*` rule on it. `on` is the SSR/pre-mount\r\n // fallback (matches the gate's own default before matchMedia is read).\r\n const getMotionServerSnapshot = useCallback((): MotionMode => 'on', [])\r\n const subscribeMotionGate = useCallback(\r\n (listener: () => void) =>\r\n controller ? controller.motionGate.subscribe(listener) : () => {},\r\n [controller],\r\n )\r\n const getMotionSnapshot = useCallback(\r\n (): MotionMode =>\r\n controller ? controller.motionGate.getSnapshot() : 'on',\r\n [controller],\r\n )\r\n const motionMode = useSyncExternalStore(\r\n subscribeMotionGate,\r\n getMotionSnapshot,\r\n getMotionServerSnapshot,\r\n )\r\n\r\n // ── Subscribe to the transient-UI store (deferred removal / overlay / toast) ──\r\n // Core owns the timing: `handleFileRemove` marks a file `leaving` for the\r\n // exit-animation window before the real removal fires. Components read\r\n // `leavingFileIds` to render `upup-fx-exit`; `sourceOverlayOpen`/`dropRejected`\r\n // feed later states (Tasks 7-8). The empty snapshot is the SSR/pre-mount value.\r\n const getTransientUiServerSnapshot = useCallback(\r\n () => EMPTY_TRANSIENT_UI,\r\n [],\r\n )\r\n const subscribeTransientUi = useCallback(\r\n (listener: () => void) =>\r\n controller ? controller.transientUi.subscribe(listener) : () => {},\r\n [controller],\r\n )\r\n const getTransientUiSnapshot = useCallback(\r\n () =>\r\n controller\r\n ? controller.transientUi.getSnapshot()\r\n : EMPTY_TRANSIENT_UI,\r\n [controller],\r\n )\r\n const transientUi = useSyncExternalStore(\r\n subscribeTransientUi,\r\n getTransientUiSnapshot,\r\n getTransientUiServerSnapshot,\r\n )\r\n\r\n // ── Single lifecycle effect (replaces 4 old effects) ─────────\r\n // init()/destroy() are idempotent + re-entrant; safe for React 18/19 StrictMode double-mount.\r\n //\r\n // The four old effects (orchestrator init/destroy, plugin registration, crash recovery,\r\n // status-change) now live INSIDE createUploaderController.init()/destroy(). Notably the\r\n // status-change callback is now DEDUPED there (it no longer fires an initial 'idle'),\r\n // and crash recovery is triggered once from init() — both factory-owned.\r\n //\r\n // StrictMode/plugin behavior: factory destroy() calls p.destroy() on each plugin,\r\n // which is IDENTICAL to the old React adapter's plugin-effect cleanup:\r\n // return () => { plugins.forEach(p => p.destroy()) }\r\n // So after StrictMode init→destroy→init on the same core, cloud plugins could be dead.\r\n // This is NOT a regression — the original React adapter had the same behavior.\r\n useEffect(() => {\r\n controller?.init()\r\n return () => {\r\n controller?.destroy()\r\n }\r\n }, [controller])\r\n\r\n // ── Re-resolve on theme-prop change (post-mount) ─────────────\r\n // The controller (hence its ThemeStore) is created once, so a `theme` prop\r\n // change after mount would otherwise never reach the live store. ThemeStore\r\n // short-circuits structurally-equal configs, so an inlined object literal\r\n // (e.g. theme={{ mode: 'dark' }}) per render costs nothing.\r\n useEffect(() => {\r\n controller?.theme.setThemeConfig(theme)\r\n }, [controller, theme])\r\n\r\n // ── Input ref (React-specific) ──────────────────────────────\r\n const inputRef = useRef<HTMLInputElement>(null)\r\n const openFilePicker = useCallback(() => {\r\n inputRef.current?.click()\r\n }, [])\r\n\r\n // ── Commands (delegate to factory commands) ──────────────────\r\n const handleSetSelectedFiles = useCallback(\r\n (newFiles: File[]) => {\r\n // Overlay close-on-add is owned by core's handleSetSelectedFiles\r\n // command (count-increase + no-active-source gate) so every framework\r\n // inherits it — do not re-add it here.\r\n void controller?.commands.handleSetSelectedFiles(newFiles)\r\n },\r\n [controller],\r\n )\r\n\r\n const handleFileRemove = useCallback(\r\n (fileId: string) => {\r\n controller?.commands.handleFileRemove(fileId)\r\n },\r\n [controller],\r\n )\r\n\r\n const uploadFiles = useCallback(\r\n async (newFiles: File[] | UploadFile[]) => {\r\n return controller?.commands.uploadFiles(newFiles)\r\n },\r\n [controller],\r\n )\r\n\r\n const replaceFiles = useCallback(\r\n (newFiles: File[] | UploadFile[]) => {\r\n controller?.commands.replaceFiles(newFiles)\r\n },\r\n [controller],\r\n )\r\n\r\n const startUpload = useCallback(async () => {\r\n return controller?.commands.startUpload()\r\n }, [controller])\r\n\r\n const retryUpload = useCallback(\r\n async (fileId?: string) => {\r\n return controller?.commands.retryUpload(fileId)\r\n },\r\n [controller],\r\n )\r\n\r\n const handleCancel = useCallback(() => {\r\n controller?.commands.handleCancel()\r\n }, [controller])\r\n\r\n const handlePause = useCallback(() => {\r\n controller?.commands.handlePause()\r\n }, [controller])\r\n\r\n const handleResume = useCallback(() => {\r\n controller?.commands.handleResume()\r\n }, [controller])\r\n\r\n const handleDone = useCallback(() => {\r\n controller?.commands.handleDone()\r\n }, [controller])\r\n\r\n const resetState = useCallback(() => {\r\n controller?.commands.resetState()\r\n }, [controller])\r\n\r\n const openImageEditor = useCallback(\r\n (file: UploadFile) => {\r\n controller?.commands.openImageEditor(file)\r\n },\r\n [controller],\r\n )\r\n\r\n const closeImageEditor = useCallback(() => {\r\n controller?.commands.closeImageEditor()\r\n }, [controller])\r\n\r\n const saveImageEdit = useCallback(\r\n (editedImageData: string, mimeType?: string) => {\r\n controller?.commands.saveImageEdit(editedImageData, mimeType)\r\n },\r\n [controller],\r\n )\r\n\r\n const replaceFile = useCallback(\r\n (fileId: string, newFile: UploadFile) => {\r\n controller?.commands.replaceFile(fileId, newFile)\r\n },\r\n [controller],\r\n )\r\n\r\n // ── Dispatch<SetStateAction> setters (preserve functional-update branch) ──\r\n const setActiveSource: Dispatch<SetStateAction<FileSource | undefined>> =\r\n useCallback(\r\n (value: SetStateAction<FileSource | undefined>) => {\r\n if (typeof value === 'function') {\r\n controller?.commands.setActiveSource(\r\n value(\r\n controller.orchestrator.getSnapshot().activeSource,\r\n ),\r\n )\r\n } else {\r\n controller?.commands.setActiveSource(value)\r\n }\r\n },\r\n [controller],\r\n )\r\n // Add-more source overlay commands (core transient-UI store; idempotent).\r\n const openSourceOverlay = useCallback(() => {\r\n controller?.transientUi.openSourceOverlay()\r\n }, [controller])\r\n const closeSourceOverlay = useCallback(() => {\r\n controller?.transientUi.closeSourceOverlay()\r\n }, [controller])\r\n // Drop-rejection: core's DragDropController decides WHICH source rejects; the\r\n // host resolves the human provider label and raises the toast (core store).\r\n const flagDriveDropRejected = useCallback(\r\n (source: FileSource) => {\r\n // core only calls this for drive sources; FileSource's drive values\r\n // are exactly the CloudProvider strings, but the enum type doesn't\r\n // structurally overlap the literal union — index by value.\r\n const key: keyof UiTranslations | undefined =\r\n DRIVE_SOURCE_LABEL_KEY[source as unknown as CloudProvider]\r\n const label = key ? resolved.translations[key] : source\r\n controller?.transientUi.flagDropRejected(label)\r\n },\r\n [controller, resolved.translations],\r\n )\r\n const setViewMode: Dispatch<SetStateAction<'grid' | 'list'>> = useCallback(\r\n (value: SetStateAction<'grid' | 'list'>) => {\r\n if (typeof value === 'function') {\r\n controller?.commands.setViewMode(\r\n value(\r\n controller.orchestrator.getSnapshot().viewMode ??\r\n 'grid',\r\n ),\r\n )\r\n } else {\r\n controller?.commands.setViewMode(value)\r\n }\r\n },\r\n [controller],\r\n )\r\n\r\n // ── Icons resolution (React-specific) ───────────────────────\r\n const resolvedIcons = useMemo(\r\n () => ({\r\n ContainerAddMoreIcon:\r\n icons.ContainerAddMoreIcon || DefaultPlusIconComponent,\r\n FileDeleteIcon: icons.FileDeleteIcon || DefaultTrashIconComponent,\r\n CameraCaptureIcon:\r\n icons.CameraCaptureIcon || DefaultCaptureIconComponent,\r\n CameraRotateIcon:\r\n icons.CameraRotateIcon || DefaultCameraRotateIconComponent,\r\n CameraDeleteIcon:\r\n icons.CameraDeleteIcon || DefaultTrashIconComponent,\r\n LoaderIcon: icons.LoaderIcon || DefaultLoaderIconComponent,\r\n }),\r\n [\r\n icons.CameraCaptureIcon,\r\n icons.CameraDeleteIcon,\r\n icons.CameraRotateIcon,\r\n icons.ContainerAddMoreIcon,\r\n icons.FileDeleteIcon,\r\n icons.LoaderIcon,\r\n ],\r\n )\r\n\r\n const resolvedStyle = style ?? EMPTY_STYLE\r\n\r\n // ── Assemble IUploaderContext ────────────────────────────────────\r\n // themeState fields match ContextTheme 1:1 (ThemeStoreState ≡ ContextTheme shape)\r\n return {\r\n core,\r\n orchestrator: controller?.orchestrator ?? null,\r\n mode: resolved.mode,\r\n serverUrl: resolved.serverUrl,\r\n inputRef,\r\n openFilePicker,\r\n activeSource: state.activeSource,\r\n setActiveSource,\r\n sourceOverlayOpen: transientUi.sourceOverlayOpen,\r\n sourceOverlayClosing: transientUi.sourceOverlayClosing,\r\n openSourceOverlay,\r\n closeSourceOverlay,\r\n dropRejected: transientUi.dropRejected,\r\n flagDriveDropRejected,\r\n viewMode: state.viewMode,\r\n setViewMode,\r\n isOnline: state.isOnline,\r\n motionMode,\r\n translations: resolved.translations,\r\n translator: resolved.translator,\r\n lang: resolved.lang,\r\n dir: resolved.dir,\r\n theme: {\r\n themeMode: themeState.themeMode,\r\n isDark: themeState.isDark,\r\n tokens: themeState.tokens,\r\n resolved: themeState.resolved,\r\n slotOverrides: themeState.slotOverrides,\r\n slots: themeState.slots ?? EMPTY_THEME_SLOTS,\r\n },\r\n files: state.files,\r\n leavingFileIds: transientUi.leavingFileIds,\r\n setFiles: handleSetSelectedFiles,\r\n uploadFiles,\r\n resetState,\r\n replaceFiles,\r\n handleDone,\r\n handleCancel,\r\n handlePause,\r\n handleResume,\r\n handleFileRemove,\r\n editingFile: state.editingFile,\r\n openImageEditor,\r\n closeImageEditor,\r\n saveImageEdit,\r\n replaceFile,\r\n cloudDrives: resolved.cloudDrives,\r\n upload: {\r\n totalProgress: state.totalProgress,\r\n filesProgressMap: state.filesProgressMap,\r\n startUpload,\r\n retryUpload,\r\n uploadStatus: state.uploadStatus,\r\n setUploadStatus: () => {},\r\n uploadError: state.uploadError,\r\n uploadErrorCode: state.uploadErrorCode,\r\n uploadSpeed: state.uploadSpeed,\r\n uploadEta: state.uploadEta,\r\n uploadedBytes: state.uploadedBytes,\r\n totalBytes: state.totalBytes,\r\n },\r\n props: {\r\n mini,\r\n maxRetries,\r\n resumable,\r\n onError,\r\n onIntegrationClick,\r\n onFileClick,\r\n onFilesDragOver,\r\n onFilesDragLeave,\r\n onFilesDrop,\r\n onWarn,\r\n enablePaste,\r\n sources: resolved.sources,\r\n allowedFileTypes: resolved.allowedFileTypes,\r\n maxFileSize: resolved.maxFileSize,\r\n limit: resolved.limit,\r\n isProcessing,\r\n allowPreview,\r\n folderUploadAllowDrop: resolved.folderUploadAllowDrop,\r\n folderPickerButtonVisible: resolved.folderPickerButtonVisible,\r\n showBranding,\r\n quietCompletion,\r\n disableDragDrop,\r\n className: className ?? '',\r\n style: resolvedStyle,\r\n multiple: resolved.multiple,\r\n icons: resolvedIcons,\r\n imageEditor: resolved.imageEditor,\r\n },\r\n }\r\n}\r\n","'use client'\r\n\r\nimport {\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n useSyncExternalStore,\r\n} from 'react'\r\nimport { UpupCore, type CoreOptions } from '@useupup/core'\r\nimport {\r\n DragDropController,\r\n UploaderOrchestrator,\r\n} from '@useupup/core/internal'\r\nimport type { CoreEvents } from '@useupup/core/internal'\r\nimport { UploadStatus, type UploadFile, type UpupError } from '@useupup/core'\r\nimport type { ExtensionMethods } from '@useupup/core'\r\nimport { createPropGetters } from './prop-getters'\r\n\r\nexport interface UseUpupUploadReturn {\r\n files: UploadFile[]\r\n status: UploadStatus\r\n progress: { totalFiles: number; completedFiles: number; percentage: number }\r\n error: UpupError | null\r\n\r\n addFiles(files: File[]): Promise<void>\r\n removeFile(id: string): void\r\n removeAll(): void\r\n setFiles(files: File[]): Promise<void>\r\n reorderFiles(fileIds: string[]): void\r\n\r\n upload(): Promise<UploadFile[]>\r\n pause(): void\r\n resume(): void\r\n cancel(): void\r\n retry(fileId?: string): Promise<UploadFile[]>\r\n\r\n // Mirrors UpupCore.on (F-723): bare names are the typed CoreEvents\r\n // catalog; namespaced '<provider>:<event>' names pass through untyped.\r\n on<K extends keyof CoreEvents>(\r\n event: K,\r\n handler: (payload: CoreEvents[K]) => void,\r\n ): () => void\r\n on(\r\n event: `${string}:${string}`,\r\n handler: (payload: unknown) => void,\r\n ): () => void\r\n ext: Record<string, ExtensionMethods>\r\n\r\n core: UpupCore\r\n\r\n getDropzoneProps: ReturnType<typeof createPropGetters>['getDropzoneProps']\r\n getRootProps: ReturnType<typeof createPropGetters>['getRootProps']\r\n getInputProps: ReturnType<typeof createPropGetters>['getInputProps']\r\n}\r\n\r\nexport interface UseUpupUploadOptions extends CoreOptions {\r\n onFileAdded?: ((files: UploadFile[]) => void) | undefined\r\n onFileRemoved?: ((file: UploadFile) => void) | undefined\r\n onUploadProgress?:\r\n | ((progress: {\r\n fileId: string\r\n loaded: number\r\n total: number\r\n }) => void)\r\n | undefined\r\n onUploadComplete?: ((files: UploadFile[]) => void) | undefined\r\n\r\n // ── F-606: drag/drop/paste gating, mirroring <UpupUploader>'s own props ──\r\n // (packages/core/src/types/uploader-props.ts's UploaderBaseProps) so the\r\n // headless path can honor the SAME rules the visual panel does. These are\r\n // UI-package concerns, deliberately NOT added to core's engine-level\r\n // CoreOptions (packages/core/src/options/types.ts) — @useupup/core stays\r\n // framework-agnostic with zero opinions on drag/drop UI gating.\r\n /** Enable clipboard paste uploads (Ctrl+V / Cmd+V). Default false. */\r\n enablePaste?: boolean | undefined\r\n /** Disable drag-and-drop (keep browse/click functional). Default false. */\r\n disableDragDrop?: boolean | undefined\r\n /** When true, drag/drop/paste are no-ops (e.g. while another action is mid-flight). */\r\n isProcessing?: boolean | undefined\r\n /** Folder upload configuration (drag-and-drop folder traversal). */\r\n folderUpload?: { allowDrop?: boolean | undefined } | undefined\r\n onWarn?: ((warningMessage: string) => void) | undefined\r\n}\r\n\r\nconst EMPTY_DRAG_SNAPSHOT = {\r\n isDragging: false,\r\n absoluteIsDragging: false,\r\n absoluteHasBorder: true,\r\n}\r\nconst NOOP_SUBSCRIBE = () => () => {}\r\nconst getEmptyDragSnapshot = () => EMPTY_DRAG_SNAPSHOT\r\n\r\nexport function useUpupUpload(\r\n options: UseUpupUploadOptions,\r\n): UseUpupUploadReturn {\r\n const coreRef = useRef<UpupCore | null>(null)\r\n const dragDropRef = useRef<DragDropController | null>(null)\r\n const [, forceUpdate] = useState(0)\r\n\r\n // Keep the latest options for the controller's getters to read fresh\r\n // (React re-reads each render — same freshness contract as useUploaderPanel.ts).\r\n const optionsRef = useRef(options)\r\n optionsRef.current = options\r\n\r\n // Callback refs — always hold latest callbacks, avoiding stale closures\r\n const onFileAddedRef = useRef(options.onFileAdded)\r\n const onFileRemovedRef = useRef(options.onFileRemoved)\r\n const onUploadProgressRef = useRef(options.onUploadProgress)\r\n const onUploadCompleteRef = useRef(options.onUploadComplete)\r\n\r\n // Sync refs every render (intentionally no deps)\r\n useEffect(() => {\r\n onFileAddedRef.current = options.onFileAdded\r\n onFileRemovedRef.current = options.onFileRemoved\r\n onUploadProgressRef.current = options.onUploadProgress\r\n onUploadCompleteRef.current = options.onUploadComplete\r\n })\r\n\r\n useEffect(() => {\r\n const core = new UpupCore(options)\r\n coreRef.current = core\r\n\r\n // Minimal headless orchestrator (F-606): DragDropController's only hard\r\n // dependency, built the same way createUploaderController builds the\r\n // panel's — the ctor is plain-state-only (no plugin/theme registration,\r\n // that lives in createUploaderController/.init(), neither called here),\r\n // so this stays a lean headless wrapper, not a second panel.\r\n const orchestrator = new UploaderOrchestrator(core, {})\r\n const dragDrop = new DragDropController({\r\n core,\r\n orchestrator,\r\n // Append (core.addFiles), NOT replace (core.setFiles) — preserves\r\n // the headless hook's existing drop/paste semantics; only the\r\n // GATING (enablePaste/isProcessing/folder-drop/filename/events)\r\n // was the bug, not the append-vs-replace choice.\r\n //\r\n // The .catch honors DragDropDeps.setFiles' void contract (#342):\r\n // the controller fires this drop/paste path without awaiting, and\r\n // core.addFiles rethrows restriction failures AFTER emitting\r\n // `restriction-failed`. Every other framework satisfies the same\r\n // contract via handleSetSelectedFiles, which try/catches; this\r\n // headless dep is the one that reached core.addFiles bare.\r\n setFiles: files => {\r\n core.addFiles(files).catch(() => {})\r\n },\r\n filesSize: () => orchestrator.getSnapshot().files.size,\r\n options: () => ({\r\n ...(optionsRef.current.enablePaste !== undefined\r\n ? { enablePaste: optionsRef.current.enablePaste }\r\n : {}),\r\n ...(optionsRef.current.onWarn !== undefined\r\n ? { onWarn: optionsRef.current.onWarn }\r\n : {}),\r\n }),\r\n props: () => ({\r\n disableDragDrop: optionsRef.current.disableDragDrop ?? false,\r\n isProcessing: optionsRef.current.isProcessing ?? false,\r\n folderUploadAllowDrop:\r\n optionsRef.current.folderUpload?.allowDrop ?? false,\r\n }),\r\n })\r\n dragDrop.init()\r\n dragDropRef.current = dragDrop\r\n\r\n coreRef.current = core\r\n forceUpdate(n => n + 1)\r\n\r\n // Subscribe to state changes to trigger re-renders\r\n const unsub = core.on('state-change', () => {\r\n forceUpdate(n => n + 1)\r\n })\r\n const unsubDragDrop = dragDrop.subscribe(() => {\r\n forceUpdate(n => n + 1)\r\n })\r\n\r\n // Wire convenience callbacks through refs for freshness\r\n const unsubCallbacks: Array<() => void> = [\r\n core.on('files-added', (...args: unknown[]) =>\r\n onFileAddedRef.current?.(...(args as [UploadFile[]])),\r\n ),\r\n core.on('file-removed', (...args: unknown[]) =>\r\n onFileRemovedRef.current?.(...(args as [UploadFile])),\r\n ),\r\n core.on('upload-progress', (...args: unknown[]) =>\r\n onUploadProgressRef.current?.(\r\n ...(args as [\r\n { fileId: string; loaded: number; total: number },\r\n ]),\r\n ),\r\n ),\r\n core.on('upload-all-complete', (...args: unknown[]) =>\r\n onUploadCompleteRef.current?.(...(args as [UploadFile[]])),\r\n ),\r\n ]\r\n\r\n return () => {\r\n unsub()\r\n unsubDragDrop()\r\n for (const u of unsubCallbacks) u()\r\n dragDrop.destroy()\r\n dragDropRef.current = null\r\n core.destroy()\r\n coreRef.current = null\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps -- mount-once: create/destroy the core exactly once per mount; options are synced by the separate effect below\r\n }, [])\r\n\r\n useEffect(() => {\r\n coreRef.current?.updateOptions(options)\r\n }, [options])\r\n\r\n const dragSnapshot = useSyncExternalStore(\r\n dragDropRef.current?.subscribe ?? NOOP_SUBSCRIBE,\r\n dragDropRef.current?.getSnapshot ?? getEmptyDragSnapshot,\r\n getEmptyDragSnapshot,\r\n )\r\n\r\n const fallbackCore = coreRef.current\r\n\r\n const propGetters = createPropGetters({\r\n addFiles: files =>\r\n coreRef.current?.addFiles(files) ?? Promise.resolve(),\r\n status: fallbackCore?.status ?? UploadStatus.IDLE,\r\n allowedFileTypes: options.allowedFileTypes,\r\n multiple: options.limit !== 1,\r\n isDragging: dragSnapshot.isDragging,\r\n dragDrop: dragDropRef.current ?? undefined,\r\n })\r\n\r\n const fallback = useMemo<UseUpupUploadReturn>(\r\n () => ({\r\n files: [],\r\n status: UploadStatus.IDLE,\r\n progress: { totalFiles: 0, completedFiles: 0, percentage: 0 },\r\n error: null,\r\n addFiles: async () => {},\r\n removeFile: () => {},\r\n removeAll: () => {},\r\n setFiles: async () => {},\r\n reorderFiles: () => {},\r\n upload: () => Promise.resolve([]),\r\n pause: () => {},\r\n resume: () => {},\r\n cancel: () => {},\r\n retry: () => Promise.resolve([]),\r\n on: () => () => {},\r\n ext: {},\r\n core: null as unknown as UpupCore,\r\n ...propGetters,\r\n }),\r\n [propGetters],\r\n )\r\n\r\n const core = coreRef.current\r\n const addFiles = useCallback(\r\n (files: File[]) =>\r\n coreRef.current?.addFiles(files) ?? Promise.resolve(),\r\n [],\r\n )\r\n const removeFile = useCallback(\r\n (id: string) => coreRef.current?.removeFile(id),\r\n [],\r\n )\r\n const removeAll = useCallback(() => coreRef.current?.removeAll(), [])\r\n const setFiles = useCallback(\r\n (files: File[]) =>\r\n coreRef.current?.setFiles(files) ?? Promise.resolve(),\r\n [],\r\n )\r\n const reorderFiles = useCallback(\r\n (fileIds: string[]) => coreRef.current?.reorderFiles(fileIds),\r\n [],\r\n )\r\n const upload = useCallback(\r\n () => coreRef.current?.upload() ?? Promise.resolve([]),\r\n [],\r\n )\r\n const pause = useCallback(() => coreRef.current?.pause(), [])\r\n const resume = useCallback(() => coreRef.current?.resume(), [])\r\n const cancel = useCallback(() => coreRef.current?.cancel(), [])\r\n const retry = useCallback(\r\n (fileId?: string) =>\r\n coreRef.current?.retry(fileId) ?? Promise.resolve([]),\r\n [],\r\n )\r\n const on = useCallback(\r\n (event: string, handler: (payload: never) => void) => {\r\n // Single untyped dispatch point — the overloads on\r\n // UseUpupUploadReturn['on'] are the consumer-facing contract.\r\n // Dynamic names route through the namespaced overload (same\r\n // runtime dispatch).\r\n return (\r\n coreRef.current?.on(\r\n event as `${string}:${string}`,\r\n handler as (p: unknown) => void,\r\n ) ?? (() => {})\r\n )\r\n },\r\n [],\r\n )\r\n\r\n if (!core) return fallback\r\n\r\n return {\r\n files: [...core.files.values()],\r\n status: core.status,\r\n progress: core.progress,\r\n error: core.error as UpupError | null,\r\n\r\n addFiles,\r\n removeFile,\r\n removeAll,\r\n setFiles,\r\n reorderFiles,\r\n\r\n upload,\r\n pause,\r\n resume,\r\n cancel,\r\n retry,\r\n\r\n on,\r\n ext: core.ext,\r\n\r\n core,\r\n\r\n ...propGetters,\r\n }\r\n}\r\n","import type React from 'react'\r\nimport type {\r\n ChangeEventHandler,\r\n HTMLAttributes,\r\n InputHTMLAttributes,\r\n} from 'react'\r\nimport type { DragDropController } from '@useupup/core/internal'\r\n\r\nexport interface PropGetterDeps {\r\n addFiles: (files: File[]) => Promise<void> | void\r\n status: string\r\n allowedFileTypes: string | undefined\r\n multiple: boolean\r\n isDragging: boolean\r\n /**\r\n * Drag/drop/paste gate (F-606). The SAME DragDropController every visual\r\n * panel's useUploaderPanel already runs — routing the headless path through\r\n * it (rather than a second, drifted inline implementation) is the one home\r\n * for enablePaste/isProcessing/folder-drop/filename-normalization/'paste'+\r\n * 'drop' core-event semantics. Optional only for back-compat with any\r\n * direct createPropGetters caller predating the controller wiring; the\r\n * shipped useUpupUpload hook always supplies one.\r\n */\r\n dragDrop?: DragDropController | undefined\r\n}\r\n\r\nfunction composeEventHandlers<E>(\r\n ...handlers: (((e: E) => void) | undefined)[]\r\n): (e: E) => void {\r\n return (event: E) => {\r\n for (const handler of handlers) {\r\n handler?.(event)\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Detach a fire-and-forget promise from the unhandled-rejection channel (#342).\r\n *\r\n * `core.addFiles()` emits `restriction-failed` and THEN rethrows — the rethrow\r\n * is deliberate, so a direct `await core.addFiles()` caller can narrow on the\r\n * error. But a DOM callback has nobody to rethrow to, so an ordinary restriction\r\n * failure (wrong type, too large, over the limit) used to surface a second time\r\n * as an unhandled rejection and pollute error reporting. Dropping it here loses\r\n * nothing: the event bus already carried the identical error before the throw.\r\n */\r\nfunction ignoreRejection(result: unknown): void {\r\n // Duck-typed rather than `instanceof Promise` — a dep may hand back a\r\n // thenable from another realm, which `instanceof` would silently miss.\r\n // `unknown` rather than `Promise<unknown> | void`, because the callers'\r\n // return types are void-unions that no narrower parameter type accepts.\r\n const thenable = result as { catch?: (cb: () => void) => unknown } | null\r\n if (typeof thenable?.catch === 'function') {\r\n thenable.catch(() => {})\r\n }\r\n}\r\n\r\n/**\r\n * All three getters share ONE override contract (#341):\r\n *\r\n * 1. `...overrides` is spread first — anything you pass survives by default.\r\n * 2. Getter-OWNED keys are applied after the spread and win. Only two kinds\r\n * qualify: values derived from live core state, and the handful without\r\n * which the element stops being an uploader element.\r\n * - `getRootProps` → `aria-busy`\r\n * - `getDropzoneProps` → `aria-dropeffect`\r\n * - `getInputProps` → `type`, `multiple`, `accept` (only when core\r\n * declares a filter), `style.display`\r\n * 3. Event handlers are COMPOSED, never replaced: the getter's own handler\r\n * runs first, then yours.\r\n * 4. `style` is MERGED, not replaced.\r\n * 5. Everything else the getters set — `role`, `aria-label`, `tabIndex`,\r\n * `aria-hidden` — is a DEFAULT you may override.\r\n *\r\n * Pinned by tests/prop-getters-override-contract.test.ts.\r\n */\r\nexport interface PropGetters {\r\n getDropzoneProps: (\r\n overrides?: HTMLAttributes<HTMLElement>,\r\n ) => HTMLAttributes<HTMLElement>\r\n getRootProps: (\r\n overrides?: HTMLAttributes<HTMLElement>,\r\n ) => HTMLAttributes<HTMLElement>\r\n getInputProps: (\r\n overrides?: InputHTMLAttributes<HTMLInputElement>,\r\n ) => InputHTMLAttributes<HTMLInputElement>\r\n}\r\n\r\nexport function createPropGetters(deps: PropGetterDeps): PropGetters {\r\n const {\r\n addFiles,\r\n status,\r\n allowedFileTypes,\r\n multiple,\r\n isDragging,\r\n dragDrop,\r\n } = deps\r\n\r\n function getDropzoneProps(\r\n overrides: HTMLAttributes<HTMLElement> = {},\r\n ): HTMLAttributes<HTMLElement> {\r\n // React synthetic events extend the native DOM events, so casting is\r\n // safe — byte-identical to useUploaderPanel.ts's handoff to the same\r\n // controller class.\r\n const onDragOver = (e: React.DragEvent<HTMLElement>): void => {\r\n dragDrop?.handleDragOver(e as unknown as DragEvent)\r\n }\r\n const onDragLeave = (e: React.DragEvent<HTMLElement>): void => {\r\n dragDrop?.handleDragLeave(e as unknown as DragEvent)\r\n }\r\n const onDrop = (e: React.DragEvent<HTMLElement>): void => {\r\n ignoreRejection(dragDrop?.handleDrop(e as unknown as DragEvent))\r\n }\r\n const onPaste = (e: React.ClipboardEvent<HTMLElement>): void => {\r\n dragDrop?.handlePaste(e as unknown as ClipboardEvent)\r\n }\r\n\r\n return {\r\n // Defaults first so a caller can replace the descriptive ones.\r\n role: 'region' as const,\r\n 'aria-label': 'Drop files here or click to browse',\r\n tabIndex: 0,\r\n ...overrides,\r\n // Owned: derived from live drag state.\r\n 'aria-dropeffect': isDragging ? 'copy' : 'none',\r\n // Owned: composed, so the delegation can never be replaced away.\r\n onDragOver: composeEventHandlers<React.DragEvent<HTMLElement>>(\r\n onDragOver,\r\n overrides.onDragOver,\r\n ),\r\n onDragLeave: composeEventHandlers<React.DragEvent<HTMLElement>>(\r\n onDragLeave,\r\n overrides.onDragLeave,\r\n ),\r\n onDrop: composeEventHandlers<React.DragEvent<HTMLElement>>(\r\n onDrop,\r\n overrides.onDrop,\r\n ),\r\n onPaste: composeEventHandlers<React.ClipboardEvent<HTMLElement>>(\r\n onPaste,\r\n overrides.onPaste,\r\n ),\r\n }\r\n }\r\n\r\n function getRootProps(\r\n overrides: HTMLAttributes<HTMLElement> = {},\r\n ): HTMLAttributes<HTMLElement> {\r\n const isUploading = status === 'uploading'\r\n return {\r\n role: 'application' as const,\r\n 'aria-label': 'File uploader',\r\n ...overrides,\r\n // Owned: derived from live upload status.\r\n 'aria-busy': isUploading,\r\n }\r\n }\r\n\r\n function getInputProps(\r\n overrides: InputHTMLAttributes<HTMLInputElement> = {},\r\n ): InputHTMLAttributes<HTMLInputElement> {\r\n const onChange: ChangeEventHandler<HTMLInputElement> = e => {\r\n const fileList = e.target.files\r\n if (fileList) {\r\n ignoreRejection(addFiles(Array.from(fileList)))\r\n }\r\n }\r\n return {\r\n tabIndex: -1,\r\n 'aria-hidden': true as const,\r\n ...overrides,\r\n // Owned: without type=file the element is not a file picker at all.\r\n type: 'file' as const,\r\n // Owned: mirrors the uploader's own `limit` / `allowedFileTypes`, so\r\n // the picker can't advertise a selection core would then reject.\r\n // `accept` is only claimed when core actually declares a filter —\r\n // writing `undefined` unconditionally would delete a caller's own\r\n // accept, which is the silent-drop bug this contract exists to end.\r\n multiple,\r\n ...(allowedFileTypes !== undefined\r\n ? { accept: allowedFileTypes }\r\n : {}),\r\n // Owned: composed, never replaced — an override that swapped this\r\n // out would leave a file input that adds no files.\r\n onChange: composeEventHandlers<React.ChangeEvent<HTMLInputElement>>(\r\n onChange,\r\n overrides.onChange,\r\n ),\r\n // Owned: `display` only. Every other style key a caller passes\r\n // survives, so positioning/sizing the visually-hidden input works.\r\n style: { ...overrides.style, display: 'none' as const },\r\n }\r\n }\r\n\r\n return { getDropzoneProps, getRootProps, getInputProps }\r\n}\r\n","import { useCallback, useEffect, useRef } from 'react'\r\nimport type { UploadFile } from '@useupup/core'\r\nimport { SSEProcessor } from '@useupup/core/internal'\r\n\r\ntype Options = {\r\n processingEndpoint?: string | undefined\r\n onFileProcessed?:\r\n ((file: UploadFile, data: Record<string, unknown>) => void) | undefined\r\n onError?: ((error: Error) => void) | undefined\r\n processingTimeout?: number | undefined\r\n}\r\n\r\n/**\r\n * Manages server-sent event connections opened after each file upload.\r\n * When `processingEndpoint` is set, calling `connectSSE(file)` opens an\r\n * EventSource at `${processingEndpoint}?key=${file.key}`. The first message\r\n * received is parsed as JSON and forwarded to `onFileProcessed`. The\r\n * connection is closed automatically on message, error, or timeout.\r\n */\r\nexport function useSSEProcessing({\r\n processingEndpoint,\r\n onFileProcessed,\r\n onError,\r\n processingTimeout = 60_000,\r\n}: Options): { connectSSE: (file: UploadFile) => void } {\r\n const processorRef = useRef(new SSEProcessor())\r\n\r\n useEffect(() => {\r\n const processor = processorRef.current\r\n return () => {\r\n processor.destroy()\r\n }\r\n }, [])\r\n\r\n const connectSSE = useCallback(\r\n (file: UploadFile) => {\r\n const key = file.key\r\n if (!processingEndpoint || !onFileProcessed || !key) return\r\n\r\n processorRef.current.subscribe(\r\n key,\r\n processingEndpoint,\r\n (data: Record<string, unknown>) => {\r\n onFileProcessed(file, data)\r\n },\r\n (error: Error) => onError?.(error),\r\n processingTimeout,\r\n )\r\n },\r\n [processingEndpoint, onFileProcessed, onError, processingTimeout],\r\n )\r\n\r\n return { connectSSE }\r\n}\r\n","import { IUploaderContext } from '../context/UploaderContext'\r\nimport type { UploadFile } from '@useupup/core'\r\nimport { isUploadActive } from '@useupup/core/internal'\r\n\r\nexport default function useUpload({\r\n upload,\r\n files,\r\n setFiles,\r\n replaceFiles,\r\n uploadFiles,\r\n resetState,\r\n}: Pick<\r\n IUploaderContext,\r\n | 'upload'\r\n | 'files'\r\n | 'setFiles'\r\n | 'replaceFiles'\r\n | 'resetState'\r\n | 'uploadFiles'\r\n>): {\r\n upload: IUploaderContext['upload']['startUpload']\r\n loading: boolean\r\n error: IUploaderContext['upload']['uploadError']\r\n progress: number\r\n files: UploadFile[]\r\n setFiles: IUploaderContext['setFiles']\r\n replaceFiles: IUploaderContext['replaceFiles']\r\n uploadFiles: IUploaderContext['uploadFiles']\r\n resetState: IUploaderContext['resetState']\r\n} {\r\n const { startUpload, uploadStatus, uploadError, totalProgress } =\r\n upload || {}\r\n\r\n return {\r\n upload: startUpload,\r\n loading: isUploadActive(uploadStatus),\r\n error: uploadError,\r\n progress: totalProgress,\r\n files: Array.from(files.values()).map(file => {\r\n return file\r\n }),\r\n setFiles,\r\n replaceFiles,\r\n uploadFiles,\r\n resetState,\r\n }\r\n}\r\n","'use client'\r\nimport React, { useEffect, useState } from 'react'\r\nimport { resolveTheme, tokensToVars } from '@useupup/core'\r\nimport type { UpupThemeConfig } from '@useupup/core'\r\n\r\ninterface UpupThemeProviderProps {\r\n theme?: UpupThemeConfig | undefined\r\n children: React.ReactNode\r\n}\r\n\r\nexport function UpupThemeProvider({\r\n theme,\r\n children,\r\n}: UpupThemeProviderProps): React.ReactElement | null {\r\n const resolved = resolveTheme(theme)\r\n const cssVars = tokensToVars(resolved.tokens)\r\n\r\n // SSR-safe: when `mode === 'system'`, start with 'light' on both server and\r\n // client-first-render (identical HTML → no hydration mismatch), then read the\r\n // real `prefers-color-scheme` after mount and stay subscribed to changes.\r\n const [resolvedMode, setResolvedMode] = useState<'light' | 'dark'>(\r\n resolved.mode === 'system' ? 'light' : resolved.mode,\r\n )\r\n\r\n useEffect(() => {\r\n if (resolved.mode !== 'system') {\r\n setResolvedMode(resolved.mode)\r\n return\r\n }\r\n if (\r\n typeof window === 'undefined' ||\r\n typeof window.matchMedia !== 'function'\r\n ) {\r\n return\r\n }\r\n const mq = window.matchMedia('(prefers-color-scheme: dark)')\r\n const apply = () => {\r\n setResolvedMode(mq.matches ? 'dark' : 'light')\r\n }\r\n apply()\r\n mq.addEventListener?.('change', apply)\r\n return () => {\r\n mq.removeEventListener?.('change', apply)\r\n }\r\n }, [resolved.mode])\r\n\r\n return (\r\n <div\r\n data-theme={resolvedMode}\r\n style={{\r\n display: 'block',\r\n width: '100%',\r\n height: '100%',\r\n ...cssVars,\r\n }}\r\n >\r\n {children}\r\n </div>\r\n )\r\n}\r\n","'use client'\r\n\r\nimport { useState, useEffect } from 'react'\r\n\r\nexport function useIsClient(): boolean {\r\n const [isClient, setIsClient] = useState(false)\r\n useEffect(() => {\r\n setIsClient(true)\r\n }, [])\r\n return isClient\r\n}\r\n","'use client'\r\n\r\n// ── Core component + ref ─────────────────────────────────\r\nexport { default as UpupUploader, type UploaderRef } from './upup-uploader'\r\n\r\n// ── Headless hook (v2) ───────────────────────────────────\r\nexport { useUpupUpload, type UseUpupUploadReturn } from './use-upup-upload'\r\nexport { useIsClient } from './use-is-client'\r\n\r\n// ── Headless context hooks (parity with @useupup/vue and @useupup/svelte) ──\r\nexport {\r\n useUploaderContext,\r\n useUploaderRuntime,\r\n useUploaderSource,\r\n useUploaderI18n,\r\n useUploaderFiles,\r\n useUploaderUploadControls,\r\n useUploaderView,\r\n useUploaderEditor,\r\n useUploaderOptions,\r\n useUploaderTheme,\r\n} from './context/UploaderContext'\r\n\r\nexport type {\r\n IUploaderContext,\r\n ContextRuntime,\r\n ContextSource,\r\n ContextI18n,\r\n ContextFiles,\r\n ContextUploadControls,\r\n ContextView,\r\n ContextEditor,\r\n ContextTheme,\r\n ContextProps,\r\n ContextUpload,\r\n} from './context/UploaderContext'\r\n\r\n// ── Canonical shared enums/types ─────────────────────────\r\nexport { FileSource, StorageProvider } from '@useupup/core'\r\n\r\n// ── Error taxonomy (#339) ────────────────────────────────\r\n// Re-exported verbatim from @useupup/core so catching a typed upload error\r\n// doesn't force a react-only consumer to add a direct @useupup/core dependency —\r\n// the error-handling docs point at these names, and `error` on the hook's\r\n// return value is already an `UpupError | null`. They are the SAME class\r\n// objects core exports, so `instanceof` narrows identically whichever package\r\n// you import from (pinned by tests/error-exports.test.ts).\r\nexport {\r\n UpupErrorCode,\r\n UpupError,\r\n UpupAuthError,\r\n UpupNetworkError,\r\n UpupValidationError,\r\n UpupQuotaError,\r\n UpupStorageError,\r\n UpupConfigError,\r\n uploadErrorFromResponse,\r\n} from '@useupup/core'\r\nexport type { RestrictionFailedReason } from '@useupup/core'\r\n\r\n// ── React types ──────────────────────────────────────────\r\nexport type {\r\n ImageEditorOptions,\r\n ResolvedImageEditorOptions,\r\n UploadSource,\r\n UploadProvider,\r\n GoogleDriveConfig,\r\n OneDriveConfig,\r\n DropboxConfig,\r\n BoxConfig,\r\n CloudDrivesConfig,\r\n ResumableUploadOptions,\r\n} from '@useupup/core'\r\nexport type { UploaderProps, UploaderIcons } from './shared/types'\r\n\r\n// ── v2 core contract re-exports ───────────────────────\r\nexport type {\r\n UploadFile,\r\n UploadFileWithProgress,\r\n UploadStatus,\r\n UpupThemeSlots,\r\n UpupSlotPath,\r\n} from '@useupup/core'\r\nexport type { DeepPartialSlots } from '@useupup/core/internal'\r\n\r\n// ── Brand icons (authentic colours, matches uploader adapter buttons) ──\r\nexport {\r\n MyDeviceIcon,\r\n BoxIcon,\r\n DropboxIcon,\r\n GoogleDriveIcon,\r\n OneDriveIcon,\r\n LinkIcon,\r\n CameraIcon,\r\n AudioIcon,\r\n ScreenCaptureIcon,\r\n} from './components/Icons'\r\n\r\n// ── Accept presets ──────────────────────────────────────\r\nexport { ACCEPT_PRESETS, resolveAccept } from '@useupup/core'\r\nexport type { AcceptPreset, AcceptPresetDefinition } from '@useupup/core'\r\n\r\n// ── Theme ────────────────────────────────────────────────\r\nexport { UpupThemeProvider } from './theme'\r\n","// Lazy materialization for the lanes===1 fast path. Backed by a\n// Float64Array (stride 2: start, size, …); VirtualItems are constructed on\n// first indexed read and cached. Saves the per-item object allocation at\n// large list counts where most items are never visible.\n\nimport type { VirtualItem } from './index'\n\ntype Key = number | string | bigint\n\nexport function createLazyMeasurementsView(\n count: number,\n flat: Float64Array,\n getItemKey: (i: number) => Key,\n): Array<VirtualItem> {\n const cache: Array<VirtualItem | undefined> = new Array(count)\n return new Proxy(cache as any, {\n get(target, prop, receiver) {\n if (typeof prop === 'string') {\n // Cheap digit-prefix sniff before number coerce.\n const c = prop.charCodeAt(0)\n if (c >= 48 && c <= 57) {\n const i = +prop\n if (Number.isInteger(i) && i >= 0 && i < count) {\n let v = target[i]\n if (!v) {\n const s = flat[i * 2]!\n v = target[i] = {\n index: i,\n key: getItemKey(i),\n start: s,\n size: flat[i * 2 + 1]!,\n end: s + flat[i * 2 + 1]!,\n lane: 0,\n }\n }\n return v\n }\n }\n if (prop === 'length') return count\n }\n return Reflect.get(target, prop, receiver)\n },\n }) as Array<VirtualItem>\n}\n","export type NoInfer<A extends any> = [A][A extends any ? 0 : never]\n\nexport type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\n\nexport function memo<TDeps extends ReadonlyArray<any>, TResult>(\n getDeps: () => [...TDeps],\n fn: (...args: NoInfer<[...TDeps]>) => TResult,\n opts: {\n key: false | string\n debug?: () => boolean\n onChange?: (result: TResult) => void\n initialDeps?: TDeps\n skipInitialOnChange?: boolean\n },\n) {\n let deps = opts.initialDeps ?? []\n let result: TResult | undefined\n let isInitial = true\n\n function memoizedFunction(): TResult {\n // Debug-only timing. In production builds, `process.env.NODE_ENV !==\n // 'production'` is constant-folded to `false` by downstream minifiers\n // (Terser/esbuild/swc with `define`), which DCEs the entire block.\n const debugEnabled =\n process.env.NODE_ENV !== 'production' && !!opts.key && !!opts.debug?.()\n let depTime = 0\n if (debugEnabled) depTime = Date.now()\n\n const newDeps = getDeps()\n\n const depsChanged =\n newDeps.length !== deps.length ||\n newDeps.some((dep: any, index: number) => deps[index] !== dep)\n\n if (!depsChanged) {\n return result!\n }\n\n deps = newDeps\n\n let resultTime = 0\n if (debugEnabled) resultTime = Date.now()\n\n result = fn(...newDeps)\n\n if (debugEnabled) {\n const depEndTime = Math.round((Date.now() - depTime) * 100) / 100\n const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100\n const resultFpsPercentage = resultEndTime / 16\n\n const pad = (str: number | string, num: number) => {\n str = String(str)\n while (str.length < num) {\n str = ' ' + str\n }\n return str\n }\n\n console.info(\n `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,\n `\n font-size: .6rem;\n font-weight: bold;\n color: hsl(${Math.max(\n 0,\n Math.min(120 - 120 * resultFpsPercentage, 120),\n )}deg 100% 31%);`,\n opts?.key,\n )\n }\n\n if (opts?.onChange && !(isInitial && opts.skipInitialOnChange)) {\n opts.onChange(result)\n }\n\n isInitial = false\n\n return result\n }\n\n // Attach updateDeps to the function itself\n memoizedFunction.updateDeps = (newDeps: [...TDeps]) => {\n deps = newDeps\n }\n\n return memoizedFunction\n}\n\nexport function notUndefined<T>(value: T | undefined, msg?: string): T {\n if (value === undefined) {\n throw new Error(`Unexpected undefined${msg ? `: ${msg}` : ''}`)\n } else {\n return value\n }\n}\n\nexport const approxEqual = (a: number, b: number) => Math.abs(a - b) < 1.01\n\nexport const debounce = (\n targetWindow: Window & typeof globalThis,\n fn: Function,\n ms: number,\n) => {\n let timeoutId: number\n return Object.assign(\n function (this: any, ...args: Array<any>) {\n targetWindow.clearTimeout(timeoutId)\n timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms)\n },\n {\n // The handle is closure-local, so a caller that has already\n // unsubscribed has no way to stop a queued call. Teardown paths use\n // this to drop the pending invocation instead of letting it land.\n cancel: () => {\n targetWindow.clearTimeout(timeoutId)\n },\n },\n )\n}\n","import { createLazyMeasurementsView } from './lazy-measurements'\nimport { approxEqual, debounce, memo, notUndefined } from './utils'\n\n// Browser-aware iOS detection. Programmatic `scrollTo`/`scrollTop` writes\n// during a momentum-scroll cancel the momentum on iOS WebKit, so we defer\n// scroll-position adjustments triggered by mid-scroll resizes until the\n// scroll settles. SSR-safe (returns false when navigator is unavailable).\nlet _isIOSResult: boolean | undefined\nconst isIOSWebKit = (): boolean => {\n if (_isIOSResult !== undefined) return _isIOSResult\n if (typeof navigator === 'undefined') return (_isIOSResult = false)\n if (/iP(hone|od|ad)/.test(navigator.userAgent)) return (_isIOSResult = true)\n // iPadOS 13+ reports as MacIntel; touch-points distinguishes it from desktop.\n const mtp = (navigator as Navigator & { maxTouchPoints?: number })\n .maxTouchPoints\n return (_isIOSResult =\n navigator.platform === 'MacIntel' && mtp !== undefined && mtp > 0)\n}\n\n// Test hook: reset the iOS detection cache. Not exported.\nexport const _resetIOSDetectionForTests = () => {\n _isIOSResult = undefined\n}\n\nexport { approxEqual, debounce, memo, notUndefined } from './utils'\nexport type { NoInfer, PartialKeys } from './utils'\n\n//\n\ntype ScrollDirection = 'forward' | 'backward'\n\ntype ScrollAlignment = 'start' | 'center' | 'end' | 'auto'\n\ntype ScrollBehavior = 'auto' | 'smooth' | 'instant'\n\ntype ScrollAnchor = 'start' | 'end'\n\ntype FollowOnAppend = boolean | ScrollBehavior\n\nexport interface ScrollToOptions {\n align?: ScrollAlignment\n behavior?: ScrollBehavior\n}\n\ntype ScrollToOffsetOptions = ScrollToOptions\n\ntype ScrollToIndexOptions = ScrollToOptions\n\ntype ScrollToEndOptions = Pick<ScrollToOptions, 'behavior'>\n\nexport interface Range {\n startIndex: number\n endIndex: number\n overscan: number\n count: number\n}\n\ntype Key = number | string | bigint\n\nexport interface VirtualItem {\n key: Key\n index: number\n start: number\n end: number\n size: number\n lane: number\n}\n\nexport interface Rect {\n width: number\n height: number\n}\n\n//\n\nconst getRect = (element: HTMLElement): Rect => {\n const { offsetWidth, offsetHeight } = element\n return { width: offsetWidth, height: offsetHeight }\n}\n\nexport const defaultKeyExtractor = (index: number) => index\n\nexport const defaultRangeExtractor = (range: Range) => {\n const start = Math.max(range.startIndex - range.overscan, 0)\n const end = Math.min(range.endIndex + range.overscan, range.count - 1)\n const len = end - start + 1\n\n const arr = new Array<number>(len)\n for (let i = 0; i < len; i++) {\n arr[i] = start + i\n }\n return arr\n}\n\nexport const observeElementRect = <T extends Element>(\n instance: Virtualizer<T, any>,\n cb: (rect: Rect) => void,\n) => {\n const element = instance.scrollElement\n if (!element) {\n return\n }\n const targetWindow = instance.targetWindow\n if (!targetWindow) {\n return\n }\n\n const handler = (rect: Rect) => {\n const { width, height } = rect\n cb({ width: Math.round(width), height: Math.round(height) })\n }\n\n handler(getRect(element as unknown as HTMLElement))\n\n if (!targetWindow.ResizeObserver) {\n return () => {}\n }\n\n const observer = new targetWindow.ResizeObserver((entries) => {\n const run = () => {\n const entry = entries[0]\n if (entry?.borderBoxSize) {\n const box = entry.borderBoxSize[0]\n if (box) {\n handler({ width: box.inlineSize, height: box.blockSize })\n return\n }\n }\n handler(getRect(element as unknown as HTMLElement))\n }\n\n instance.options.useAnimationFrameWithResizeObserver\n ? requestAnimationFrame(run)\n : run()\n })\n\n observer.observe(element, { box: 'border-box' })\n\n return () => {\n observer.unobserve(element)\n }\n}\n\nconst addEventListenerOptions = {\n passive: true,\n}\n\nexport const observeWindowRect = (\n instance: Virtualizer<Window, any>,\n cb: (rect: Rect) => void,\n) => {\n const element = instance.scrollElement\n if (!element) {\n return\n }\n\n const handler = () => {\n cb({ width: element.innerWidth, height: element.innerHeight })\n }\n handler()\n\n element.addEventListener('resize', handler, addEventListenerOptions)\n\n return () => {\n element.removeEventListener('resize', handler)\n }\n}\n\nconst supportsScrollend =\n typeof window == 'undefined' ? true : 'onscrollend' in window\n\ntype ObserveOffsetCallBack = (offset: number, isScrolling: boolean) => void\n\n// Shared core: both element and window variants attach scroll/scrollend\n// listeners with the same lifecycle; they only differ in how to read the\n// current offset from the scroll target.\nconst observeOffset = <T extends Element | Window>(\n instance: Virtualizer<T, any>,\n cb: ObserveOffsetCallBack,\n readOffset: (target: T) => number,\n) => {\n const element = instance.scrollElement\n if (!element) {\n return\n }\n const targetWindow = instance.targetWindow\n if (!targetWindow) {\n return\n }\n\n const registerScrollendEvent =\n instance.options.useScrollendEvent && supportsScrollend\n\n let offset = 0\n const fallback = registerScrollendEvent\n ? null\n : debounce(\n targetWindow,\n () => cb(offset, false),\n instance.options.isScrollingResetDelay,\n )\n\n const createHandler = (isScrolling: boolean) => () => {\n offset = readOffset(element)\n fallback?.()\n cb(offset, isScrolling)\n }\n const handler = createHandler(true)\n const endHandler = createHandler(false)\n\n element.addEventListener('scroll', handler, addEventListenerOptions)\n if (registerScrollendEvent) {\n element.addEventListener('scrollend', endHandler, addEventListenerOptions)\n }\n return () => {\n element.removeEventListener('scroll', handler)\n if (registerScrollendEvent) {\n element.removeEventListener('scrollend', endHandler)\n }\n // Removing the listener doesn't retract a reset already queued by the\n // last scroll, and that call would land on a virtualizer that has been\n // torn down — in React, a dispatch into an unmounted tree.\n fallback?.cancel()\n }\n}\n\nexport const observeElementOffset = <T extends Element>(\n instance: Virtualizer<T, any>,\n cb: ObserveOffsetCallBack,\n) =>\n observeOffset(instance, cb, (el) => {\n const { horizontal, isRtl } = instance.options\n return horizontal ? el.scrollLeft * ((isRtl && -1) || 1) : el.scrollTop\n })\n\nexport const observeWindowOffset = (\n instance: Virtualizer<Window, any>,\n cb: ObserveOffsetCallBack,\n) =>\n observeOffset(instance, cb, (win) =>\n instance.options.horizontal ? win.scrollX : win.scrollY,\n )\n\nexport const measureElement = <TItemElement extends Element>(\n element: TItemElement,\n entry: ResizeObserverEntry | undefined,\n instance: Virtualizer<any, TItemElement>,\n) => {\n // When useCachedMeasurements is enabled, return the cached size\n // (or estimateSize as fallback) instead of measuring the DOM.\n if (instance.options.useCachedMeasurements) {\n const index = instance.indexFromElement(element)\n const key = instance.options.getItemKey(index)\n return (\n instance.itemSizeCache.get(key) ?? instance.options.estimateSize(index)\n )\n }\n\n if (entry?.borderBoxSize) {\n const box = entry.borderBoxSize[0]\n if (box) {\n const size = Math.round(\n box[instance.options.horizontal ? 'inlineSize' : 'blockSize'],\n )\n return size\n }\n }\n\n // When called without a ResizeObserverEntry (sync measurement path),\n // return the previously measured size if available. This avoids a\n // synchronous layout read (offsetWidth/offsetHeight) on re-renders.\n // The ResizeObserver is already observing the element and will deliver\n // the accurate size asynchronously if it changed.\n // Users who need synchronous DOM reads can provide a custom measureElement.\n if (!entry) {\n const index = instance.indexFromElement(element)\n const key = instance.options.getItemKey(index)\n const cachedSize = instance.itemSizeCache.get(key)\n if (cachedSize !== undefined) {\n return cachedSize\n }\n }\n\n return (element as unknown as HTMLElement)[\n instance.options.horizontal ? 'offsetWidth' : 'offsetHeight'\n ]\n}\n\nconst scrollWithAdjustments = (\n offset: number,\n {\n adjustments = 0,\n behavior,\n }: { adjustments?: number; behavior?: ScrollBehavior },\n instance: Virtualizer<any, any>,\n) => {\n instance.scrollElement?.scrollTo?.({\n [instance.options.horizontal ? 'left' : 'top']: offset + adjustments,\n behavior,\n })\n}\n\nexport const windowScroll: <T extends Window>(\n offset: number,\n options: { adjustments?: number; behavior?: ScrollBehavior },\n instance: Virtualizer<T, any>,\n) => void = scrollWithAdjustments\n\nexport const elementScroll: <T extends Element>(\n offset: number,\n options: { adjustments?: number; behavior?: ScrollBehavior },\n instance: Virtualizer<T, any>,\n) => void = scrollWithAdjustments\n\ntype LaneAssignmentMode = 'estimate' | 'measured'\n\nexport interface VirtualizerOptions<\n TScrollElement extends Element | Window,\n TItemElement extends Element,\n> {\n // Required from the user\n count: number\n getScrollElement: () => TScrollElement | null\n estimateSize: (index: number) => number\n\n // Required from the framework adapter (but can be overridden)\n scrollToFn: (\n offset: number,\n options: { adjustments?: number; behavior?: ScrollBehavior },\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => void\n observeElementRect: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n cb: (rect: Rect) => void,\n ) => void | (() => void)\n observeElementOffset: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n cb: ObserveOffsetCallBack,\n ) => void | (() => void)\n // Optional\n debug?: boolean\n initialRect?: Rect\n onChange?: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n sync: boolean,\n ) => void\n measureElement?: (\n element: TItemElement,\n entry: ResizeObserverEntry | undefined,\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => number\n overscan?: number\n horizontal?: boolean\n paddingStart?: number\n paddingEnd?: number\n scrollPaddingStart?: number\n scrollPaddingEnd?: number\n initialOffset?: number | (() => number)\n getItemKey?: (index: number) => Key\n rangeExtractor?: (range: Range) => Array<number>\n scrollMargin?: number\n gap?: number\n indexAttribute?: string\n initialMeasurementsCache?: Array<VirtualItem>\n lanes?: number\n anchorTo?: ScrollAnchor\n followOnAppend?: FollowOnAppend\n scrollEndThreshold?: number\n isScrollingResetDelay?: number\n useScrollendEvent?: boolean\n enabled?: boolean\n isRtl?: boolean\n useAnimationFrameWithResizeObserver?: boolean\n laneAssignmentMode?: LaneAssignmentMode\n useCachedMeasurements?: boolean\n}\n\ntype ScrollState = {\n // what we want\n index: number | null\n align: ScrollAlignment\n behavior: ScrollBehavior\n\n // lifecycle\n startedAt: number\n\n // target tracking\n lastTargetOffset: number\n\n // settling\n stableFrames: number\n}\n\ntype PendingScrollAnchor = [\n key: Key | null,\n offset: number,\n followOnAppend: ScrollBehavior | null,\n anchorDelta: number,\n]\n\nexport class Virtualizer<\n TScrollElement extends Element | Window,\n TItemElement extends Element,\n> {\n private unsubs: Array<void | (() => void)> = []\n options!: Required<VirtualizerOptions<TScrollElement, TItemElement>>\n scrollElement: TScrollElement | null = null\n targetWindow: (Window & typeof globalThis) | null = null\n isScrolling = false\n private scrollState: ScrollState | null = null\n measurementsCache: Array<VirtualItem> = []\n // Flat backing store for the lanes===1 fast path: [start_0, size_0, start_1, size_1, ...].\n // null until the first single-lane build; reused (and grown) across rebuilds.\n private _flatMeasurements: Float64Array | null = null\n itemSizeCache = new Map<Key, number>()\n private itemSizeCacheVersion = 0\n private laneAssignments = new Map<number, number>() // index → lane cache\n // Earliest index dirtied since last getMeasurements() rebuild, or null.\n private pendingMin: number | null = null\n private prevLanes: number | undefined = undefined\n private lanesChangedFlag = false\n private lanesSettling = false\n private pendingScrollAnchor: PendingScrollAnchor | null = null\n scrollRect: Rect | null = null\n scrollOffset: number | null = null\n scrollDirection: ScrollDirection | null = null\n scrollAdjustments = 0\n // Sum of size-change deltas above-viewport that were skipped during\n // iOS momentum scroll (writing scrollTop mid-momentum cancels it).\n // Flushed in a single scrollTo when iOS is fully settled.\n private _iosDeferredAdjustment = 0\n // Touch state. iOS WebKit cancels momentum when scrollTop is written, so\n // we defer adjustments not only during `isScrolling` but also through the\n // touchstart→touchend window (active drag) and a short tail after\n // touchend (early-momentum window — iOS only fires touch events once at\n // the start of momentum, so we use a timer rather than another event).\n private _iosTouching = false\n private _iosJustTouchEnded = false\n private _iosTouchEndTimerId: number | null = null\n // Subpixel reconciliation. Safari (and Chrome/Firefox under certain DPRs)\n // round scrollTop/scrollLeft writes to integer pixels. If we wrote 12345.5\n // but the browser reports back 12346, the next reconcileScroll sees a\n // \"target changed\" and re-fires scrollTo — a feedback loop that the\n // approxEqual(<1.01) tolerance otherwise absorbs as a workaround.\n // By remembering the intended value of our most-recent self-driven\n // scrollTo, we can match the browser's rounded read back to the intended\n // value when the diff is < 1.5 px, distinguishing it from a real user\n // scroll. The +0.5 over Math.abs lets us also absorb the +1 / -1 cases.\n private _intendedScrollOffset: number | null = null\n shouldAdjustScrollPositionOnItemSizeChange:\n | undefined\n | ((\n item: VirtualItem,\n delta: number,\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => boolean)\n elementsCache = new Map<Key, TItemElement>()\n private now = () => this.targetWindow?.performance?.now?.() ?? Date.now()\n private observer = (() => {\n let _ro: ResizeObserver | null = null\n\n const get = () => {\n if (_ro) {\n return _ro\n }\n\n if (!this.targetWindow || !this.targetWindow.ResizeObserver) {\n return null\n }\n\n return (_ro = new this.targetWindow.ResizeObserver((entries) => {\n entries.forEach((entry) => {\n const run = () => {\n const node = entry.target as TItemElement\n const index = this.indexFromElement(node)\n\n if (!node.isConnected) {\n this.observer.unobserve(node)\n // Find the cache entry pointing to this exact node and remove\n // it. We can't call getItemKey(index) here because items may\n // have been removed since this node was rendered — the index\n // could be stale and out-of-bounds in the user's data array\n // (regression test in e2e/.../stale-index.spec.ts, fix #1148).\n // The === comparison naturally handles the React-replaced-\n // a-node-for-the-same-key case: that entry now points to a\n // different node, so this loop won't match.\n for (const [cacheKey, cachedNode] of this.elementsCache) {\n if (cachedNode === node) {\n this.elementsCache.delete(cacheKey)\n break\n }\n }\n return\n }\n\n if (!this.isIndexInRange(index)) return\n\n if (this.shouldMeasureDuringScroll(index)) {\n this.resizeItem(\n index,\n this.options.measureElement(node, entry, this),\n )\n }\n }\n this.options.useAnimationFrameWithResizeObserver\n ? requestAnimationFrame(run)\n : run()\n })\n }))\n }\n\n return {\n disconnect: () => {\n get()?.disconnect()\n _ro = null\n },\n observe: (target: Element) =>\n get()?.observe(target, { box: 'border-box' }),\n unobserve: (target: Element) => get()?.unobserve(target),\n }\n })()\n range: { startIndex: number; endIndex: number } | null = null\n\n constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {\n this.setOptions(opts)\n }\n\n setOptions = (opts: VirtualizerOptions<TScrollElement, TItemElement>) => {\n // Skip `{...defaults, ...opts}` because explicit `undefined` values in\n // opts would override defaults with `undefined`.\n const merged = {\n debug: false,\n initialOffset: 0,\n overscan: 1,\n paddingStart: 0,\n paddingEnd: 0,\n scrollPaddingStart: 0,\n scrollPaddingEnd: 0,\n horizontal: false,\n getItemKey: defaultKeyExtractor,\n rangeExtractor: defaultRangeExtractor,\n onChange: () => {},\n measureElement,\n initialRect: { width: 0, height: 0 },\n scrollMargin: 0,\n gap: 0,\n indexAttribute: 'data-index',\n initialMeasurementsCache: [],\n lanes: 1,\n anchorTo: 'start',\n followOnAppend: false,\n scrollEndThreshold: 1,\n isScrollingResetDelay: 150,\n enabled: true,\n isRtl: false,\n useScrollendEvent: false,\n useAnimationFrameWithResizeObserver: false,\n laneAssignmentMode: 'estimate',\n useCachedMeasurements: false,\n } as unknown as Required<VirtualizerOptions<TScrollElement, TItemElement>>\n\n for (const key in opts) {\n const v = (opts as any)[key]\n if (v !== undefined) (merged as any)[key] = v\n }\n\n const prevOptions = this.options as\n | Required<VirtualizerOptions<TScrollElement, TItemElement>>\n | undefined\n let anchor: [Key, number] | null = null\n let followOnAppend: ScrollBehavior | null = null\n let edgeKeysChanged = false\n\n if (\n prevOptions !== undefined &&\n prevOptions.enabled &&\n merged.enabled &&\n merged.anchorTo === 'end' &&\n this.scrollElement !== null\n ) {\n const prevCount = prevOptions.count\n const nextCount = merged.count\n const measurements = this.getMeasurements()\n const prevFirstKey =\n prevCount > 0\n ? (measurements[0]?.key ?? prevOptions.getItemKey(0))\n : null\n const prevLastKey =\n prevCount > 0\n ? (measurements[prevCount - 1]?.key ??\n prevOptions.getItemKey(prevCount - 1))\n : null\n const didCountChange = nextCount !== prevCount\n const didEdgeKeysChange =\n didCountChange ||\n (prevCount > 0 &&\n nextCount > 0 &&\n (merged.getItemKey(0) !== prevFirstKey ||\n merged.getItemKey(nextCount - 1) !== prevLastKey))\n\n if (didEdgeKeysChange) {\n edgeKeysChanged = true\n const item =\n prevCount > 0\n ? (this.getVirtualItemForOffset(this.getScrollOffset()) ??\n measurements[0])\n : null\n\n if (item) {\n anchor = [item.key, this.getScrollOffset() - item.start]\n }\n\n const behavior =\n merged.followOnAppend === true\n ? 'auto'\n : merged.followOnAppend || null\n\n if (\n behavior &&\n nextCount > prevCount &&\n this.isAtEnd(prevOptions.scrollEndThreshold) &&\n (prevCount === 0 || merged.getItemKey(nextCount - 1) !== prevLastKey)\n ) {\n followOnAppend = behavior\n }\n }\n }\n\n this.options = merged\n\n // When edge keys changed (prepend, trim, reorder, etc.) the key→index\n // mapping has shifted. Force a full measurement rebuild so the anchor\n // resolution below reads positions from the new layout, not the stale\n // memoised cache. Without this, a stable `getItemKey` reference +\n // unchanged `count` would let getMeasurements() return the old layout.\n if (edgeKeysChanged) {\n this.pendingMin = 0\n this.itemSizeCacheVersion++\n }\n\n // Eagerly adjust scrollOffset so the virtualizer computes the correct\n // visible range during the current render pass — before _willUpdate\n // syncs the DOM scroll position in a layout effect. Without this,\n // the virtualizer would render the wrong items for one frame (the\n // estimate-based positions are stale) and then correct in the next\n // frame, producing a visible \"jump\" on prepend with dynamic sizes.\n let anchorResolved = false\n let anchorDelta = 0\n if (anchor && this.scrollOffset !== null) {\n const [anchorKey, anchorOffset] = anchor\n const newMeasurements = this.getMeasurements()\n const { count, getItemKey } = this.options\n let idx = 0\n while (idx < count && getItemKey(idx) !== anchorKey) {\n idx++\n }\n if (idx < count) {\n const anchorItem = newMeasurements[idx]\n if (anchorItem) {\n // Clamp to the reachable range's lower bound — anchorOffset may\n // have been derived from a transiently negative scrollOffset\n // (rubber-band), and a negative tracked offset never self-heals\n // when the element cannot scroll (#1229).\n const newOffset = Math.max(0, anchorItem.start + anchorOffset)\n if (newOffset !== this.scrollOffset) {\n anchorDelta = newOffset - this.scrollOffset\n this.scrollOffset = newOffset\n anchorResolved = true\n }\n }\n }\n }\n\n if (anchorResolved || followOnAppend) {\n this.pendingScrollAnchor = [\n anchorResolved ? anchor![0] : null,\n anchorResolved ? anchor![1] : 0,\n followOnAppend,\n anchorDelta,\n ]\n }\n }\n\n private notify = (sync: boolean) => {\n this.options.onChange?.(this, sync)\n }\n\n // Returns `true` when it performed a synchronous `scrollTop` write this\n // tick, `false` when the delta was zero or the write was deferred (iOS).\n // `resizeItem` uses that to decide whether the follow-up `notify` must be\n // synchronous so the grown transforms commit in the same paint (#1227).\n private applyScrollAdjustment(\n delta: number,\n behavior?: ScrollBehavior,\n ): boolean {\n if (delta === 0) return false\n\n if (process.env.NODE_ENV !== 'production' && this.options.debug) {\n console.info('correction', delta)\n }\n\n if (\n isIOSWebKit() &&\n (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)\n ) {\n this._iosDeferredAdjustment += delta\n return false\n } else {\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: (this.scrollAdjustments += delta),\n behavior,\n })\n // Eagerly carry the intended target in `scrollOffset` so callers that\n // read it before the next scroll event — notably the next `resizeItem`\n // tick's `getVirtualDistanceFromEnd()` / `wasAtEnd` check — see the\n // post-adjustment position even when the DOM `scrollTop` write was\n // clamped because the consumer hasn't grown the sizer yet (`notify()`\n // runs after this in `resizeItem`). Same idea as the eager\n // `scrollOffset` adjustment for prepend in `setOptions` (#1176). The\n // adjustment is now baked into `scrollOffset`, so zero\n // `scrollAdjustments` to keep their sum invariant.\n if (this.scrollOffset !== null) {\n this.scrollOffset += this.scrollAdjustments\n // Clamp only the lower bound: a negative offset is unreachable, and\n // on an unscrollable element (content fits the viewport) no scroll\n // event ever fires to correct it, permanently skewing\n // getDistanceFromEnd() and wedging _flushIosDeferredIfReady (#1229).\n // Upper-bound overflow stays untouched — it is transiently\n // legitimate mid-prepend while the consumer's sizer catches up.\n if (this.scrollOffset < 0) this.scrollOffset = 0\n this.scrollAdjustments = 0\n }\n return true\n }\n }\n\n private maybeNotify = memo(\n () => {\n this.calculateRange()\n\n return [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null,\n ]\n },\n (isScrolling) => {\n this.notify(isScrolling)\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'maybeNotify',\n debug: () => this.options.debug,\n initialDeps: [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null,\n ] as [boolean, number | null, number | null],\n },\n )\n\n private cleanup = () => {\n this.unsubs.filter(Boolean).forEach((d) => d!())\n this.unsubs = []\n this.observer.disconnect()\n if (this.rafId != null && this.targetWindow) {\n this.targetWindow.cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n this.scrollState = null\n // The debounce cancelled above is the only thing that writes `isScrolling`\n // back to false, so a cleanup inside the reset window would strand it, and\n // the direction derived from it, as true. That matters because `cleanup`\n // also runs when the scroll element changes or `enabled` goes false, where\n // the instance lives on.\n this.isScrolling = false\n this.scrollDirection = null\n // The iOS gesture/deferral state is scoped to the current scroll\n // element: the touch listeners that maintain it were just removed, and\n // an in-flight touch keeps targeting the old element (implicit touch\n // capture), so the new element never reports it. Carrying the state\n // over would replay a stale deferred delta on the new element's first\n // flush, and a cleanup that lands mid-touch or inside the post-touchend\n // grace window would strand _iosTouching / _iosJustTouchEnded as true\n // (the listener unsub clears the grace timer, and with it the only\n // pending reset of the flag), deferring every adjustment on the new\n // element until its next touch cycle.\n this._iosDeferredAdjustment = 0\n this._iosTouching = false\n this._iosJustTouchEnded = false\n this.scrollElement = null\n this.targetWindow = null\n }\n\n _didMount = () => {\n return () => {\n this.cleanup()\n }\n }\n\n _willUpdate = () => {\n const scrollElement = this.options.enabled\n ? this.options.getScrollElement()\n : null\n\n if (this.scrollElement !== scrollElement) {\n this.cleanup()\n\n if (!scrollElement) {\n this.maybeNotify()\n return\n }\n\n this.scrollElement = scrollElement\n\n if (this.scrollElement && 'ownerDocument' in this.scrollElement) {\n this.targetWindow = this.scrollElement.ownerDocument.defaultView\n } else {\n this.targetWindow = this.scrollElement?.window ?? null\n }\n\n this.elementsCache.forEach((cached) => {\n this.observer.observe(cached)\n })\n\n this.unsubs.push(\n this.options.observeElementRect(this, (rect) => {\n this.scrollRect = rect\n this.maybeNotify()\n }),\n )\n\n this.unsubs.push(\n this.options.observeElementOffset(this, (offset, isScrolling) => {\n // A scroll event that reports movement but lands on the offset we\n // already hold — and isn't a self-write read-back — is a spurious\n // no-op re-emit that Safari/Firefox fire after a re-render's layout\n // (Chrome doesn't). Treating it as scrolling re-arms `isScrolling`,\n // which forces a render that triggers another such event: an\n // infinite re-render loop. Ignore it. (Self-writes are handled by\n // the `_intendedScrollOffset` reconciliation just below.)\n if (\n isScrolling &&\n this._intendedScrollOffset === null &&\n offset === this.scrollOffset\n ) {\n return\n }\n\n // If this scroll event looks like the browser's read-back of a\n // value we just wrote, prefer our intended (sub-pixel-accurate)\n // value over the browser's rounded one. The 1.5 px tolerance is\n // tight enough to avoid mistaking a real user scroll for a\n // self-write — by the time the user has moved 1.5 px, the\n // intended value will already have been consumed by a prior\n // scroll event and cleared.\n if (\n this._intendedScrollOffset !== null &&\n Math.abs(offset - this._intendedScrollOffset) < 1.5\n ) {\n offset = this._intendedScrollOffset\n }\n this._intendedScrollOffset = null\n\n this.scrollAdjustments = 0\n // If the offset hasn't moved, this is the echo of our own\n // adjustment write — `applyScrollAdjustment` already folded it\n // into `scrollOffset`. There's no direction to infer, so leave\n // it alone; a real gesture always moves the offset.\n const prevOffset = this.getScrollOffset()\n this.scrollDirection = isScrolling\n ? prevOffset === offset\n ? this.scrollDirection\n : prevOffset < offset\n ? 'forward'\n : 'backward'\n : null\n this.scrollOffset = offset\n this.isScrolling = isScrolling\n\n // Flush deferred iOS adjustments if we're now fully settled.\n // \"Fully settled\" means: not actively scrolling, no finger on\n // screen, and the post-touchend grace window has expired.\n this._flushIosDeferredIfReady()\n\n if (this.scrollState) {\n this.scheduleScrollReconcile()\n }\n this.maybeNotify()\n }),\n )\n\n // Touch event listeners (iOS-aware deferral). We attach unconditionally\n // — the listeners are passive and cheap; on non-touch devices they\n // simply never fire. The gating by isIOSWebKit() lives in resizeItem\n // and _flushIosDeferredIfReady so we only burn the path on iOS.\n if ('addEventListener' in this.scrollElement) {\n const scrollEl = this.scrollElement as unknown as EventTarget\n const onTouchStart = () => {\n this._iosTouching = true\n this._iosJustTouchEnded = false\n if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {\n this.targetWindow.clearTimeout(this._iosTouchEndTimerId)\n this._iosTouchEndTimerId = null\n }\n }\n const onTouchEnd = () => {\n this._iosTouching = false\n if (!isIOSWebKit() || this.targetWindow == null) {\n // Non-iOS: nothing more to track. Just clear the touching flag.\n return\n }\n this._iosJustTouchEnded = true\n // After ~150 ms with no scroll/touch events, momentum is done.\n this._iosTouchEndTimerId = this.targetWindow.setTimeout(() => {\n this._iosJustTouchEnded = false\n this._iosTouchEndTimerId = null\n // After the grace window, attempt to flush. The scroll event\n // for momentum decay may have already fired before our timer.\n this._flushIosDeferredIfReady()\n }, 150)\n }\n scrollEl.addEventListener(\n 'touchstart',\n onTouchStart,\n addEventListenerOptions,\n )\n scrollEl.addEventListener(\n 'touchend',\n onTouchEnd,\n addEventListenerOptions,\n )\n this.unsubs.push(() => {\n scrollEl.removeEventListener('touchstart', onTouchStart)\n scrollEl.removeEventListener('touchend', onTouchEnd)\n if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {\n this.targetWindow.clearTimeout(this._iosTouchEndTimerId)\n this._iosTouchEndTimerId = null\n }\n })\n }\n\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: undefined,\n behavior: undefined,\n })\n }\n\n const anchor = this.pendingScrollAnchor\n this.pendingScrollAnchor = null\n\n if (anchor && this.scrollElement && this.options.enabled) {\n const [key, _offset, followOnAppend, anchorDelta] = anchor\n\n if (key !== null && !followOnAppend) {\n // scrollOffset was eagerly adjusted in setOptions so the\n // virtualizer already computed the correct range during render.\n // Now sync the browser's actual scroll position to match.\n // Skip when followOnAppend is set — scrollToEnd will handle it.\n //\n // On iOS WebKit, writing scrollTop during touch/momentum cancels\n // the in-flight scroll. Defer the DOM sync the same way\n // applyScrollAdjustment does — accumulate the delta and let\n // _flushIosDeferredIfReady handle it once the scroll settles.\n if (\n isIOSWebKit() &&\n (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)\n ) {\n if (anchorDelta !== 0) {\n this._iosDeferredAdjustment += anchorDelta\n }\n } else {\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: undefined,\n behavior: undefined,\n })\n }\n }\n\n if (followOnAppend) {\n this.scrollToEnd({ behavior: followOnAppend })\n }\n }\n }\n\n // Apply any accumulated iOS-deferred scroll adjustment, but only when we're\n // truly settled — not actively scrolling, not under an active touch, and\n // past the post-touchend grace window. Called from the scroll callback\n // and the touchend grace-timer.\n private _flushIosDeferredIfReady = () => {\n if (this._iosDeferredAdjustment === 0) return\n if (this.isScrolling) return\n if (this._iosTouching) return\n if (this._iosJustTouchEnded) return\n // Phase 2b: Safari elastic-overscroll (rubber-band) lets scrollTop go\n // negative or beyond scrollHeight - clientHeight. Writing scrollTop\n // while in that zone snaps the page back to the clamped value at the\n // end of the bounce, often discarding the user's intent. Skip the\n // flush; the next in-bounds scroll event will retry.\n const cur = this.getScrollOffset()\n const max = this.getMaxScrollOffset()\n if (cur < 0 || cur > max) return\n // At the end clamp the browser already absorbed a shrink above the\n // viewport (it clamped scrollTop onto the new bottom), so replaying our\n // deferred negative delta would lift the view off the bottom — drop it.\n // Positive deltas still replay: growth above doesn't clamp. (#1233)\n if (this._iosDeferredAdjustment < 0 && cur >= max - 1) {\n this._iosDeferredAdjustment = 0\n return\n }\n const delta = this._iosDeferredAdjustment\n this._iosDeferredAdjustment = 0\n // Roll the deferred delta into the running accumulator so any resize\n // landing between now and the resulting scroll event computes from the\n // post-flush offset rather than the stale one.\n this._scrollToOffset(cur, {\n adjustments: (this.scrollAdjustments += delta),\n behavior: undefined,\n })\n }\n\n private rafId: number | null = null\n private scheduleScrollReconcile() {\n if (!this.targetWindow) {\n this.scrollState = null\n return\n }\n if (this.rafId != null) return\n this.rafId = this.targetWindow.requestAnimationFrame(() => {\n this.rafId = null\n this.reconcileScroll()\n })\n }\n private reconcileScroll() {\n if (!this.scrollState) return\n\n const el = this.scrollElement\n if (!el) return\n\n // Safety valve: bail out if reconciliation has been running too long\n const MAX_RECONCILE_MS = 5000\n if (this.now() - this.scrollState.startedAt > MAX_RECONCILE_MS) {\n this.scrollState = null\n return\n }\n\n const offsetInfo =\n this.scrollState.index != null\n ? this.getOffsetForIndex(this.scrollState.index, this.scrollState.align)\n : undefined\n const targetOffset = offsetInfo\n ? offsetInfo[0]\n : this.scrollState.lastTargetOffset\n\n // Require one stable frame where target matches scroll offset.\n // approxEqual() already tolerates minor fluctuations, so one frame is sufficient\n // to confirm scroll has reached its target without premature cleanup.\n const STABLE_FRAMES = 1\n\n const targetChanged = targetOffset !== this.scrollState.lastTargetOffset\n\n if (!targetChanged && approxEqual(targetOffset, this.getScrollOffset())) {\n this.scrollState.stableFrames++\n if (this.scrollState.stableFrames >= STABLE_FRAMES) {\n // Final-pass exact landing. The reconcile-stable check uses a 1.01px\n // tolerance (approxEqual) so we don't fight subpixel browser rounding\n // during the converging phase. Once we're definitively settled,\n // commit the exact target so consumers calling scrollToIndex(N)\n // end up at the EXACT computed position of item N — matching\n // virtuoso's 0px landing accuracy rather than our prior 0.5-1px.\n if (this.getScrollOffset() !== targetOffset) {\n this._scrollToOffset(targetOffset, {\n adjustments: undefined,\n behavior: 'auto',\n })\n }\n this.scrollState = null\n return\n }\n } else {\n this.scrollState.stableFrames = 0\n\n if (targetChanged) {\n // When the target moves during smooth scroll (because items came into\n // view and got measured, shifting positions), the original logic was\n // to immediately snap to 'auto' — visibly jarring on long\n // scroll-to-index calls. Now: keep smooth while we're still far\n // (more than a viewport) from the new target. Only fall back to\n // 'auto' for the final approach, so the user sees one continuous\n // motion that smoothly adjusts its endpoint as measurements arrive.\n const viewport = this.getSize() || 600\n const distance = Math.abs(targetOffset - this.getScrollOffset())\n const keepSmooth =\n this.scrollState.behavior === 'smooth' && distance > viewport\n\n this.scrollState.lastTargetOffset = targetOffset\n if (!keepSmooth) {\n this.scrollState.behavior = 'auto'\n }\n\n this._scrollToOffset(targetOffset, {\n adjustments: undefined,\n behavior: keepSmooth ? 'smooth' : 'auto',\n })\n }\n }\n\n // Always reschedule while scrollState is active to guarantee\n // the safety valve timeout runs even if no scroll events fire\n // (e.g. no-op scrollToFn, detached element)\n this.scheduleScrollReconcile()\n }\n\n private getSize = () => {\n if (!this.options.enabled) {\n this.scrollRect = null\n return 0\n }\n\n this.scrollRect = this.scrollRect ?? this.options.initialRect\n\n return this.scrollRect[this.options.horizontal ? 'width' : 'height']\n }\n\n private getScrollOffset = () => {\n if (!this.options.enabled) {\n this.scrollOffset = null\n return 0\n }\n\n this.scrollOffset =\n this.scrollOffset ??\n (typeof this.options.initialOffset === 'function'\n ? this.options.initialOffset()\n : this.options.initialOffset)\n\n return this.scrollOffset\n }\n\n private getMeasurementOptions = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.scrollMargin,\n this.options.getItemKey,\n this.options.enabled,\n this.options.lanes,\n this.options.laneAssignmentMode,\n this.options.gap,\n ],\n (\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n enabled,\n lanes,\n laneAssignmentMode,\n gap,\n ) => {\n const lanesChanged =\n this.prevLanes !== undefined && this.prevLanes !== lanes\n\n if (lanesChanged) {\n // Set flag for getMeasurements to handle\n this.lanesChangedFlag = true\n }\n\n this.prevLanes = lanes\n this.pendingMin = null\n\n return {\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n enabled,\n lanes,\n laneAssignmentMode,\n gap,\n }\n },\n {\n key: false,\n },\n )\n\n private isIndexInRange = (index: number): boolean =>\n index >= 0 && index < this.options.count\n\n private getMeasurements = memo(\n () => [this.getMeasurementOptions(), this.itemSizeCacheVersion],\n (\n {\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n enabled,\n lanes,\n laneAssignmentMode,\n gap,\n },\n _itemSizeCacheVersion,\n ) => {\n const itemSizeCache = this.itemSizeCache\n if (!enabled) {\n this.measurementsCache = []\n this.itemSizeCache.clear()\n this.laneAssignments.clear()\n return []\n }\n\n // Clean up stale lane cache entries when count decreases\n if (this.laneAssignments.size > count) {\n for (const index of this.laneAssignments.keys()) {\n if (index >= count) {\n this.laneAssignments.delete(index)\n }\n }\n }\n\n // ✅ Force complete recalculation when lanes change\n if (this.lanesChangedFlag) {\n this.lanesChangedFlag = false // Reset immediately\n this.lanesSettling = true // Start settling period\n this.measurementsCache = []\n this.itemSizeCache.clear()\n this.laneAssignments.clear() // Clear lane cache for new lane count\n // Force min = 0 on the rebuild\n this.pendingMin = null\n }\n\n // Don't restore from initialMeasurementsCache during lane changes\n // as it contains stale lane assignments from the previous lane count\n if (this.measurementsCache.length === 0 && !this.lanesSettling) {\n this.measurementsCache = this.options.initialMeasurementsCache\n this.measurementsCache.forEach((item) => {\n this.itemSizeCache.set(item.key, item.size)\n })\n }\n\n // During lanes settling, ignore pendingMin to prevent repositioning\n const min = this.lanesSettling ? 0 : (this.pendingMin ?? 0)\n this.pendingMin = null\n\n // ✅ End settling period when cache is fully built\n if (this.lanesSettling && this.measurementsCache.length === count) {\n this.lanesSettling = false\n }\n\n // ─── Fast path: single-lane lazy materialization ────────────────────\n // For lanes === 1 (the default and most common case), skip the\n // per-item VirtualItem object allocation. We write start/size pairs\n // into a Float64Array and return a Proxy that builds VirtualItem\n // objects on demand (only the indices a consumer actually reads).\n //\n // At n=100k this drops cold-mount cost from ~2.5ms (eager object\n // allocation) to roughly the cost of a single typed-array fill.\n if (lanes === 1) {\n // Reuse flat backing if large enough; else grow (preserving data\n // before `min` to mirror the slice-and-rebuild contract).\n const need = count * 2\n let flat = this._flatMeasurements\n if (!flat || flat.length < need) {\n const next = new Float64Array(need)\n if (flat && min > 0) next.set(flat.subarray(0, min * 2))\n flat = next\n this._flatMeasurements = flat\n }\n\n let runningStart: number\n if (min === 0) {\n runningStart = paddingStart + scrollMargin\n } else {\n // Continue from where we left off\n const prevIdx = min - 1\n runningStart = flat[prevIdx * 2]! + flat[prevIdx * 2 + 1]! + gap\n }\n\n for (let i = min; i < count; i++) {\n const key = getItemKey(i)\n const measuredSize = itemSizeCache.get(key)\n const size =\n typeof measuredSize === 'number'\n ? measuredSize\n : this.options.estimateSize(i)\n flat[i * 2] = runningStart\n flat[i * 2 + 1] = size\n runningStart += size + gap\n }\n\n const view = createLazyMeasurementsView(count, flat, getItemKey)\n this.measurementsCache = view\n return view\n }\n\n const measurements = this.measurementsCache.slice(0, min)\n\n // ✅ Performance: Track last item index per lane for O(1) lookup\n const laneLastIndex: Array<number | undefined> = new Array(lanes).fill(\n undefined,\n )\n // Running end position of each lane's last item, so the shortest lane\n // can be found with an O(lanes) argmin instead of the old backward walk\n // through `measurements` (getFurthestMeasurement). `filledLanes` tracks\n // how many lanes have at least one item, mirroring the previous\n // \"all lanes seen → shortest lane, else i % lanes\" branch.\n const laneEnds = new Float64Array(lanes)\n let filledLanes = 0\n\n // Initialize from existing measurements (before min)\n for (let m = 0; m < min; m++) {\n const item = measurements[m]\n if (item) {\n if (laneLastIndex[item.lane] === undefined) filledLanes++\n laneLastIndex[item.lane] = m\n laneEnds[item.lane] = item.end\n }\n }\n\n for (let i = min; i < count; i++) {\n const key = getItemKey(i)\n\n // Check for cached lane assignment\n const cachedLane = this.laneAssignments.get(i)\n let lane: number\n let start: number\n\n const shouldCacheLane =\n laneAssignmentMode === 'estimate' || itemSizeCache.has(key)\n\n if (cachedLane !== undefined && this.options.lanes > 1) {\n // Use cached lane - O(1) lookup for previous item in same lane\n lane = cachedLane\n const prevIndex = laneLastIndex[lane]\n const prevInLane =\n prevIndex !== undefined ? measurements[prevIndex] : undefined\n start = prevInLane\n ? prevInLane.end + gap\n : paddingStart + scrollMargin\n } else if (filledLanes === lanes) {\n // No cache, every lane seeded: place in the shortest lane.\n // Read the running per-lane ends (O(lanes) argmin) instead of the\n // old backward scan. Tie-break on the lane's last-item index to\n // preserve the previous sort-by-(end, index) placement exactly.\n let bestLane = 0\n let bestEnd = laneEnds[0]!\n let bestIdx = laneLastIndex[0]!\n for (let l = 1; l < lanes; l++) {\n const e = laneEnds[l]!\n if (e < bestEnd || (e === bestEnd && laneLastIndex[l]! < bestIdx)) {\n bestLane = l\n bestEnd = e\n bestIdx = laneLastIndex[l]!\n }\n }\n lane = bestLane\n start = bestEnd + gap\n\n if (shouldCacheLane) {\n this.laneAssignments.set(i, lane)\n }\n } else {\n // No cache and not every lane seeded yet — seed lanes in order,\n // matching the previous `i % lanes` fallback for the first row.\n lane = i % this.options.lanes\n start = paddingStart + scrollMargin\n\n if (shouldCacheLane) {\n this.laneAssignments.set(i, lane)\n }\n }\n\n const measuredSize = itemSizeCache.get(key)\n const size =\n typeof measuredSize === 'number'\n ? measuredSize\n : this.options.estimateSize(i)\n\n const end = start + size\n\n measurements[i] = {\n index: i,\n start,\n size,\n end,\n key,\n lane,\n }\n\n // ✅ Performance: Update lane's last item index + running end\n if (laneLastIndex[lane] === undefined) filledLanes++\n laneLastIndex[lane] = i\n laneEnds[lane] = end\n }\n\n this.measurementsCache = measurements\n\n return measurements\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'getMeasurements',\n debug: () => this.options.debug,\n },\n )\n\n calculateRange = memo(\n () => [\n this.getMeasurements(),\n this.getSize(),\n this.getScrollOffset(),\n this.options.lanes,\n ],\n (measurements, outerSize, scrollOffset, lanes) => {\n if (measurements.length === 0 || outerSize === 0) {\n this.range = null\n return null\n }\n this.range = calculateRangeImpl(\n measurements,\n outerSize,\n scrollOffset,\n lanes,\n // Pass the typed array so binary search + forward-walk can read\n // start/end directly from Float64Array, skipping the Proxy traps.\n lanes === 1 && this._flatMeasurements != null\n ? this._flatMeasurements\n : null,\n )\n return this.range\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'calculateRange',\n debug: () => this.options.debug,\n },\n )\n\n getVirtualIndexes = memo(\n () => {\n let startIndex: number | null = null\n let endIndex: number | null = null\n const range = this.calculateRange()\n if (range) {\n startIndex = range.startIndex\n endIndex = range.endIndex\n }\n this.maybeNotify.updateDeps([this.isScrolling, startIndex, endIndex])\n return [\n this.options.rangeExtractor,\n this.options.overscan,\n this.options.count,\n startIndex,\n endIndex,\n ]\n },\n (rangeExtractor, overscan, count, startIndex, endIndex) => {\n return startIndex === null || endIndex === null\n ? []\n : rangeExtractor({\n startIndex,\n endIndex,\n overscan,\n count,\n })\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'getVirtualIndexes',\n debug: () => this.options.debug,\n },\n )\n\n indexFromElement = (node: TItemElement) => {\n const attributeName = this.options.indexAttribute\n const indexStr = node.getAttribute(attributeName)\n\n if (!indexStr) {\n console.warn(\n `Missing attribute name '${attributeName}={index}' on measured element.`,\n )\n return -1\n }\n\n return parseInt(indexStr, 10)\n }\n\n /**\n * Determines if an item at the given index should be measured during smooth scroll.\n * During smooth scroll, only items within a buffer range around the target are measured\n * to prevent items far from the target from pushing it away.\n */\n private shouldMeasureDuringScroll = (index: number): boolean => {\n // No scroll state or not smooth scroll - always allow measurements\n if (!this.scrollState || this.scrollState.behavior !== 'smooth') {\n return true\n }\n\n const scrollIndex =\n this.scrollState.index ??\n this.getVirtualItemForOffset(this.scrollState.lastTargetOffset)?.index\n\n if (scrollIndex !== undefined && this.range) {\n // Allow measurements within a buffer range around the scroll target\n const bufferSize = Math.max(\n this.options.overscan,\n Math.ceil((this.range.endIndex - this.range.startIndex) / 2),\n )\n const minIndex = Math.max(0, scrollIndex - bufferSize)\n const maxIndex = Math.min(\n this.options.count - 1,\n scrollIndex + bufferSize,\n )\n return index >= minIndex && index <= maxIndex\n }\n\n return true\n }\n\n measureElement = (node: TItemElement | null) => {\n if (!node) {\n this.elementsCache.forEach((cached, key) => {\n if (!cached.isConnected) {\n this.observer.unobserve(cached)\n this.elementsCache.delete(key)\n }\n })\n return\n }\n\n const index = this.indexFromElement(node)\n if (!this.isIndexInRange(index)) return\n\n const key = this.options.getItemKey(index)\n const prevNode = this.elementsCache.get(key)\n\n if (prevNode !== node) {\n if (prevNode) {\n this.observer.unobserve(prevNode)\n }\n this.observer.observe(node)\n this.elementsCache.set(key, node)\n }\n\n // Sync-measure when idle (initial render) or during programmatic scrolling\n // (scrollToIndex/scrollToOffset) where reconcileScroll needs sizes in the same frame.\n // During normal user scrolling, skip sync measurement — the RO callback handles it async.\n if (\n (!this.isScrolling || this.scrollState) &&\n this.shouldMeasureDuringScroll(index)\n ) {\n this.resizeItem(index, this.options.measureElement(node, undefined, this))\n }\n }\n\n resizeItem = (index: number, size: number) => {\n if (!this.isIndexInRange(index)) return\n\n // Fast field reads. For lanes===1 we read raw start/size from the flat\n // typed array, avoiding a Proxy.get + VirtualItem allocation per call.\n // For lanes>1 we fall back to the cached VirtualItem array.\n let cachedSize: number\n let itemStart: number\n let key: Key\n const flat = this._flatMeasurements\n if (this.options.lanes === 1 && flat !== null) {\n key = this.options.getItemKey(index)\n itemStart = flat[index * 2]!\n cachedSize = flat[index * 2 + 1]!\n } else {\n const item = this.measurementsCache[index]\n if (!item) return\n key = item.key\n itemStart = item.start\n cachedSize = item.size\n }\n\n const itemSize = this.itemSizeCache.get(key) ?? cachedSize\n const delta = size - itemSize\n\n if (delta !== 0) {\n const wasAtEnd =\n this.options.anchorTo === 'end' &&\n this.scrollState?.behavior !== 'smooth' &&\n this.getVirtualDistanceFromEnd() <= this.options.scrollEndThreshold\n const prevTotalSize = wasAtEnd ? this.getTotalSize() : 0\n // Default anchoring predicate (used unless the consumer supplies a\n // custom shouldAdjustScrollPositionOnItemSizeChange).\n const scrollOffsetWithAdj =\n this.getScrollOffset() + this.scrollAdjustments\n const isFirstMeasure = !this.itemSizeCache.has(key)\n const defaultShouldAdjust = isFirstMeasure\n ? // First measurement: compensate any item whose top sits above the\n // fold — the estimate→actual delta must be corrected regardless of\n // scroll direction, since the whole estimated block was above it.\n itemStart < scrollOffsetWithAdj\n : // Re-measurement: only compensate an item that is ENTIRELY above the\n // fold. An item that merely *spans* the fold (top above, bottom\n // below — e.g. a streaming chat message growing at its bottom)\n // changes size *below* the anchor point, so shifting scrollTop by the\n // delta would drag the viewport downward on every growth (#1218).\n // Also skip during backward scroll to avoid the \"items jump while\n // scrolling up\" cascade.\n itemStart + itemSize <= scrollOffsetWithAdj &&\n this.scrollDirection !== 'backward'\n const shouldAdjustScroll =\n this.scrollState?.behavior !== 'smooth' &&\n (this.shouldAdjustScrollPositionOnItemSizeChange !== undefined\n ? this.shouldAdjustScrollPositionOnItemSizeChange(\n // The callback expects a VirtualItem; build one lazily only\n // when the consumer actually supplied a custom predicate.\n this.measurementsCache[index] ?? {\n index,\n key,\n start: itemStart,\n size: cachedSize,\n end: itemStart + cachedSize,\n lane: 0,\n },\n delta,\n this,\n )\n : defaultShouldAdjust)\n\n if (this.pendingMin === null || index < this.pendingMin) {\n this.pendingMin = index\n }\n this.itemSizeCache.set(key, size)\n this.itemSizeCacheVersion++\n\n let adjustedSync = false\n if (wasAtEnd) {\n adjustedSync = this.applyScrollAdjustment(\n this.getTotalSize() - prevTotalSize,\n )\n } else if (shouldAdjustScroll) {\n adjustedSync = this.applyScrollAdjustment(delta)\n }\n\n // When we just moved `scrollTop` to compensate for an above-viewport\n // resize, the grown item transforms must commit in the SAME frame as\n // that write. `applyScrollAdjustment` writes `scrollTop` synchronously\n // inside this ResizeObserver callback, but an async `notify` schedules\n // the transform render for a later commit — so the browser can paint\n // one frame with the new `scrollTop` and the old positions, and the\n // viewport visibly jumps by `delta` before snapping back (#1227). A\n // synchronous notify flushes the render in this same callback, so both\n // land in one paint. When nothing moved (or the write was deferred on\n // iOS), keep the cheaper async notify.\n this.notify(adjustedSync)\n }\n }\n\n getVirtualItems = memo(\n () => [this.getVirtualIndexes(), this.getMeasurements()],\n (indexes, measurements) => {\n const virtualItems: Array<VirtualItem> = []\n\n for (let k = 0, len = indexes.length; k < len; k++) {\n const i = indexes[k]!\n const measurement = measurements[i]!\n\n virtualItems.push(measurement)\n }\n\n return virtualItems\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'getVirtualItems',\n debug: () => this.options.debug,\n },\n )\n\n getVirtualItemForOffset = (offset: number) => {\n const measurements = this.getMeasurements()\n if (measurements.length === 0) {\n return undefined\n }\n // Same fast-path as calculateRange: read start values directly from the\n // typed array during binary search to skip the Proxy.get materialization\n // per probe.\n const flat = this._flatMeasurements\n const useFlat = this.options.lanes === 1 && flat != null\n const idx = findNearestBinarySearch(\n 0,\n measurements.length - 1,\n useFlat\n ? (i: number) => flat[i * 2]!\n : (i: number) => notUndefined(measurements[i]).start,\n offset,\n )\n return notUndefined(measurements[idx])\n }\n\n private getMaxScrollOffset = () => {\n if (!this.scrollElement) return 0\n\n if ('scrollHeight' in this.scrollElement) {\n // Element\n return this.options.horizontal\n ? this.scrollElement.scrollWidth - this.scrollElement.clientWidth\n : this.scrollElement.scrollHeight - this.scrollElement.clientHeight\n } else {\n // Window\n const doc = this.scrollElement.document.documentElement\n return this.options.horizontal\n ? doc.scrollWidth - this.scrollElement.innerWidth\n : doc.scrollHeight - this.scrollElement.innerHeight\n }\n }\n\n private getVirtualDistanceFromEnd = () => {\n return Math.max(\n this.getTotalSize() - this.getSize() - this.getScrollOffset(),\n 0,\n )\n }\n\n getDistanceFromEnd = () => {\n return Math.max(this.getMaxScrollOffset() - this.getScrollOffset(), 0)\n }\n\n isAtEnd = (threshold = this.options.scrollEndThreshold) => {\n return this.getDistanceFromEnd() <= threshold\n }\n\n getOffsetForAlignment = (\n toOffset: number,\n align: ScrollAlignment,\n itemSize = 0,\n ) => {\n if (!this.scrollElement) return 0\n\n const size = this.getSize()\n const scrollOffset = this.getScrollOffset()\n\n if (align === 'auto') {\n align = toOffset >= scrollOffset + size ? 'end' : 'start'\n }\n\n if (align === 'center') {\n // When aligning to a particular item (e.g. with scrollToIndex),\n // adjust offset by the size of the item to center on the item\n toOffset += (itemSize - size) / 2\n } else if (align === 'end') {\n toOffset -= size\n }\n\n const maxOffset = this.getMaxScrollOffset()\n\n return Math.max(Math.min(maxOffset, toOffset), 0)\n }\n\n getOffsetForIndex = (index: number, align: ScrollAlignment = 'auto') => {\n index = Math.max(0, Math.min(index, this.options.count - 1))\n\n const size = this.getSize()\n const scrollOffset = this.getScrollOffset()\n\n const item = this.measurementsCache[index]\n if (!item) return\n\n if (align === 'auto') {\n if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) {\n align = 'end'\n } else if (item.start <= scrollOffset + this.options.scrollPaddingStart) {\n align = 'start'\n } else {\n return [scrollOffset, align] as const\n }\n }\n\n // For the last item with 'end' alignment, use browser's actual max scroll\n // to account for borders/padding that aren't in our measurements\n if (align === 'end' && index === this.options.count - 1) {\n return [this.getMaxScrollOffset(), align] as const\n }\n\n const toOffset =\n align === 'end'\n ? item.end + this.options.scrollPaddingEnd\n : item.start - this.options.scrollPaddingStart\n\n return [\n this.getOffsetForAlignment(toOffset, align, item.size),\n align,\n ] as const\n }\n\n scrollToOffset = (\n toOffset: number,\n { align = 'start', behavior = 'auto' }: ScrollToOffsetOptions = {},\n ) => {\n // An absolute scroll command derives its target from current\n // measurements, so any iOS-deferred compensation still pending is stale by\n // definition — the command already accounts for the measurements the delta\n // was compensating for. Drop it so _flushIosDeferredIfReady doesn't replay\n // it onto the just-established position (relative commands like scrollBy\n // intentionally keep the deferral, since they build on the current offset).\n this._iosDeferredAdjustment = 0\n\n const offset = this.getOffsetForAlignment(toOffset, align)\n\n const now = this.now()\n this.scrollState = {\n index: null,\n align,\n behavior,\n startedAt: now,\n lastTargetOffset: offset,\n stableFrames: 0,\n }\n\n this._scrollToOffset(offset, { adjustments: undefined, behavior })\n\n this.scheduleScrollReconcile()\n }\n\n scrollToIndex = (\n index: number,\n {\n align: initialAlign = 'auto',\n behavior = 'auto',\n }: ScrollToIndexOptions = {},\n ) => {\n // See scrollToOffset: an absolute target invalidates any pending\n // iOS-deferred compensation.\n this._iosDeferredAdjustment = 0\n\n index = Math.max(0, Math.min(index, this.options.count - 1))\n\n const offsetInfo = this.getOffsetForIndex(index, initialAlign)\n if (!offsetInfo) {\n return\n }\n const [offset, align] = offsetInfo\n\n const now = this.now()\n this.scrollState = {\n index,\n align,\n behavior,\n startedAt: now,\n lastTargetOffset: offset,\n stableFrames: 0,\n }\n\n this._scrollToOffset(offset, { adjustments: undefined, behavior })\n\n this.scheduleScrollReconcile()\n }\n\n scrollBy = (\n delta: number,\n { behavior = 'auto' }: ScrollToOffsetOptions = {},\n ) => {\n const offset = this.getScrollOffset() + delta\n const now = this.now()\n\n this.scrollState = {\n index: null,\n align: 'start',\n behavior,\n startedAt: now,\n lastTargetOffset: offset,\n stableFrames: 0,\n }\n\n this._scrollToOffset(offset, { adjustments: undefined, behavior })\n\n this.scheduleScrollReconcile()\n }\n\n scrollToEnd = ({ behavior = 'auto' }: ScrollToEndOptions = {}) => {\n if (this.options.count > 0) {\n this.scrollToIndex(this.options.count - 1, {\n align: 'end',\n behavior,\n })\n return\n }\n\n this.scrollToOffset(Math.max(this.getTotalSize() - this.getSize(), 0), {\n behavior,\n })\n }\n\n getTotalSize = () => {\n const measurements = this.getMeasurements()\n\n let end: number\n // If there are no measurements, set the end to paddingStart\n // If there is only one lane, use the last measurement's end\n // Otherwise find the maximum end value among all measurements\n if (measurements.length === 0) {\n end = this.options.paddingStart\n } else if (this.options.lanes === 1) {\n // Fast path: read last item's end directly from the flat typed array\n // when available; avoids a Proxy.get + VirtualItem materialization\n // just to call getTotalSize (which React renders trigger every commit).\n const lastIdx = measurements.length - 1\n const flat = this._flatMeasurements\n if (flat != null) {\n end = flat[lastIdx * 2]! + flat[lastIdx * 2 + 1]!\n } else {\n end = measurements[lastIdx]?.end ?? 0\n }\n } else {\n const endByLane = Array<number | null>(this.options.lanes).fill(null)\n let endIndex = measurements.length - 1\n while (endIndex >= 0 && endByLane.some((val) => val === null)) {\n const item = measurements[endIndex]!\n if (endByLane[item.lane] === null) {\n endByLane[item.lane] = item.end\n }\n\n endIndex--\n }\n\n end = Math.max(...endByLane.filter((val): val is number => val !== null))\n }\n\n return Math.max(\n end - this.options.scrollMargin + this.options.paddingEnd,\n 0,\n )\n }\n\n /**\n * Returns a snapshot of currently-measured items suitable for round-\n * tripping through state storage (sessionStorage, history, etc.) and\n * passing back as `initialMeasurementsCache` on remount. Pair with the\n * current `scrollOffset` to restore exact scroll position after navigation.\n *\n * Only items the consumer has actually rendered (and thus measured) appear\n * in the snapshot; unmeasured items will fall back to `estimateSize` on\n * restore. Returns an empty array if no items have been measured.\n */\n takeSnapshot = (): Array<VirtualItem> => {\n const snapshot: Array<VirtualItem> = []\n if (this.itemSizeCache.size === 0) return snapshot\n // Iterate measurementsCache only for indices whose key is in itemSizeCache\n // (i.e., have been measured). We build VirtualItem objects with the\n // current start/size/end so they can be persisted as plain data.\n const m = this.getMeasurements()\n for (const item of m) {\n if (item && this.itemSizeCache.has(item.key)) {\n // Force materialization (lazy path) and copy plain fields.\n snapshot.push({\n index: item.index,\n key: item.key,\n start: item.start,\n size: item.size,\n end: item.end,\n lane: item.lane,\n })\n }\n }\n return snapshot\n }\n\n private _scrollToOffset = (\n offset: number,\n {\n adjustments,\n behavior,\n }: {\n adjustments: number | undefined\n behavior: ScrollBehavior | undefined\n },\n ) => {\n // Record the intended logical scroll target so the next scroll event\n // can reconcile against subpixel rounding by the browser.\n this._intendedScrollOffset = offset + (adjustments ?? 0)\n this.options.scrollToFn(offset, { behavior, adjustments }, this)\n }\n\n measure = () => {\n // Reset pendingMin so the next getMeasurements rebuilds from index 0.\n // Without this, a prior resizeItem() that left pendingMin > 0 would\n // cause the rebuild to preserve stale items before that index.\n this.pendingMin = null\n this.itemSizeCache.clear()\n this.laneAssignments.clear() // Clear lane cache for full re-layout\n this.itemSizeCacheVersion++\n this.notify(false)\n }\n}\n\nconst findNearestBinarySearch = (\n low: number,\n high: number,\n getCurrentValue: (i: number) => number,\n value: number,\n) => {\n while (low <= high) {\n const middle = ((low + high) / 2) | 0\n const currentValue = getCurrentValue(middle)\n\n if (currentValue < value) {\n low = middle + 1\n } else if (currentValue > value) {\n high = middle - 1\n } else {\n return middle\n }\n }\n\n if (low > 0) {\n return low - 1\n } else {\n return 0\n }\n}\n\n// Monomorphic Float64Array variant — reads start values directly at stride\n// 2 instead of through a getter closure. JITs the inner load to a typed-\n// array bounds-check + load with no indirect call.\nfunction findNearestBinarySearchFlat(\n flat: Float64Array,\n high: number,\n value: number,\n) {\n let low = 0\n while (low <= high) {\n const middle = ((low + high) / 2) | 0\n const currentValue = flat[middle * 2]!\n\n if (currentValue < value) {\n low = middle + 1\n } else if (currentValue > value) {\n high = middle - 1\n } else {\n return middle\n }\n }\n return low > 0 ? low - 1 : 0\n}\n\nfunction calculateRangeImpl(\n measurements: Array<VirtualItem>,\n outerSize: number,\n scrollOffset: number,\n lanes: number,\n flat: Float64Array | null,\n) {\n const lastIndex = measurements.length - 1\n\n // handle case when item count is less than or equal to lanes\n if (measurements.length <= lanes) {\n return { startIndex: 0, endIndex: lastIndex }\n }\n\n if (lanes === 1 && flat !== null) {\n // Hot single-lane path: typed-array reads, no closures, no Proxy traps.\n const startIndex = findNearestBinarySearchFlat(\n flat,\n lastIndex,\n scrollOffset,\n )\n let endIndex = startIndex\n const limit = scrollOffset + outerSize\n while (\n endIndex < lastIndex &&\n flat[endIndex * 2]! + flat[endIndex * 2 + 1]! < limit\n ) {\n endIndex++\n }\n return { startIndex, endIndex }\n }\n\n // Fallback (lanes > 1 or no flat array): closure-based reads.\n const getStart = (index: number) => measurements[index]!.start\n let startIndex = findNearestBinarySearch(0, lastIndex, getStart, scrollOffset)\n let endIndex = startIndex\n\n if (lanes === 1) {\n while (\n endIndex < lastIndex &&\n measurements[endIndex]!.end < scrollOffset + outerSize\n ) {\n endIndex++\n }\n } else if (lanes > 1) {\n // Expand forward until we include the visible items from all lanes\n // which are closer to the end of the virtualizer window\n const endPerLane = Array(lanes).fill(0)\n while (\n endIndex < lastIndex &&\n endPerLane.some((pos) => pos < scrollOffset + outerSize)\n ) {\n const item = measurements[endIndex]!\n endPerLane[item.lane] = item.end\n endIndex++\n }\n\n // Expand backward until we include all lanes' visible items\n // closer to the top\n const startPerLane = Array(lanes).fill(scrollOffset + outerSize)\n while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {\n const item = measurements[startIndex]!\n startPerLane[item.lane] = item.start\n startIndex--\n }\n\n // Align startIndex to the beginning of its lane\n startIndex = Math.max(0, startIndex - (startIndex % lanes))\n // Align endIndex to the end of its lane\n endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - (endIndex % lanes)))\n }\n\n return { startIndex, endIndex }\n}\n","import * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport {\n Virtualizer,\n elementScroll,\n observeElementOffset,\n observeElementRect,\n observeWindowOffset,\n observeWindowRect,\n windowScroll,\n} from '@tanstack/virtual-core'\nimport type { PartialKeys, VirtualizerOptions } from '@tanstack/virtual-core'\n\nexport * from '@tanstack/virtual-core'\n\nconst useIsomorphicLayoutEffect =\n typeof document !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\nexport type ReactVirtualizer<\n TScrollElement extends Element | Window,\n TItemElement extends Element,\n> = Virtualizer<TScrollElement, TItemElement> & {\n /**\n * Ref callback for the inner size container element. Only meaningful when\n * `directDomUpdates: true` — the virtualizer writes the container's\n * main-axis size (`height` or `width`) directly to skip React re-renders.\n */\n containerRef: (node: HTMLElement | null) => void\n}\n\nexport type ReactVirtualizerOptions<\n TScrollElement extends Element | Window,\n TItemElement extends Element,\n> = VirtualizerOptions<TScrollElement, TItemElement> & {\n useFlushSync?: boolean\n /**\n * Skip React re-renders for scroll-only updates. The virtualizer writes\n * item positions (`top`/`left`) and the container size (`height`/`width`)\n * directly to the DOM, and only re-renders when the visible index range\n * or `isScrolling` changes.\n *\n * Requirements when enabled:\n * - Item elements must be `position: absolute`; in `'transform'` mode they\n * must also be anchored with `top: 0` / `left: 0`.\n * - Item elements must NOT set the main-axis position in their style — the\n * virtualizer owns `top` / `left` in `'position'` mode and `transform` in\n * `'transform'` mode.\n * - The inner size container must receive `virtualizer.containerRef` and\n * must NOT set `height` / `width` in its style.\n * - For multi-lane layouts (grids / masonry), the cross-axis position\n * (e.g. `left: ${(item.lane * 100) / lanes}%`) is stable per item and\n * must still be set in your JSX — only the main axis is automated.\n *\n * This flag is intended to be set once at mount. Toggling it (or\n * `directDomUpdatesMode`) at runtime can leave stale inline styles on\n * items and the container.\n */\n directDomUpdates?: boolean\n /**\n * How `directDomUpdates` positions item elements.\n * - `'transform'` (default): writes `transform: translate3d(...)`.\n * Promotes items to their own compositor layer — usually smoother on long\n * lists, but creates a stacking context and can interfere with\n * `position: fixed` descendants. Item elements must still be anchored with\n * `position: absolute`, `top: 0`, and `left: 0`.\n * - `'position'`: writes `top` / `left`. Item elements must be\n * `position: absolute`.\n */\n directDomUpdatesMode?: 'position' | 'transform'\n}\n\nfunction useVirtualizerBase<\n TScrollElement extends Element | Window,\n TItemElement extends Element,\n>({\n useFlushSync = true,\n directDomUpdates = false,\n directDomUpdatesMode = 'transform',\n ...options\n}: ReactVirtualizerOptions<TScrollElement, TItemElement>): ReactVirtualizer<\n TScrollElement,\n TItemElement\n> {\n const rerender = React.useReducer((x: number) => x + 1, 0)[1]\n\n // Mutable across renders so the onChange closure captured by setOptions\n // always reads the latest values without us having to re-create it.\n const directRef = React.useRef({\n enabled: directDomUpdates,\n mode: directDomUpdatesMode,\n container: null as HTMLElement | null,\n lastSize: null as number | null,\n // Keyed by the element itself so a remounted node (same key, new DOM\n // node — e.g. when `enabled` is toggled off then on) is treated as fresh\n // and gets its style written.\n lastPositions: new WeakMap<HTMLElement, number>(),\n prevRange: null as {\n startIndex: number\n endIndex: number\n isScrolling: boolean\n } | null,\n })\n directRef.current.enabled = directDomUpdates\n directRef.current.mode = directDomUpdatesMode\n\n // Writes the size container's total extent to the DOM. Idempotent — guarded\n // by lastSize. Split out from applyDirectStyles so it can run *before* the\n // scroll-position sync in the _willUpdate effect: an end-anchored prepend\n // grows the total and bumps scrollOffset in the same pass, and if scrollTop\n // is written before the container has grown the browser clamps it to the\n // stale (shorter) scrollHeight, leaving a gap at the top until the next\n // scroll (visible only in directDomUpdates mode — React-rendered sizers get\n // their height during render).\n const applyContainerSize = (\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => {\n const state = directRef.current\n if (!state.enabled || !state.container) return\n\n const totalSize = instance.getTotalSize()\n if (totalSize !== state.lastSize) {\n state.lastSize = totalSize\n const sizeAxis = instance.options.horizontal ? 'width' : 'height'\n state.container.style[sizeAxis] = `${totalSize}px`\n }\n }\n\n // Writes container size + item positions to the DOM. Idempotent — guarded\n // by lastSize / lastPositions. Called from onChange (covers scroll-driven\n // updates) and from a layout effect (covers post-render commits when refs\n // have just registered new items in elementsCache).\n const applyDirectStyles = (\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => {\n const state = directRef.current\n if (!state.enabled || !state.container) return\n\n applyContainerSize(instance)\n\n const horizontal = !!instance.options.horizontal\n const useTransform = state.mode === 'transform'\n const posAxis = horizontal ? 'left' : 'top'\n const scrollMargin = instance.options.scrollMargin\n const items = instance.getVirtualItems()\n for (const item of items) {\n const next = item.start - scrollMargin\n const el = instance.elementsCache.get(item.key) as HTMLElement | undefined\n if (!el) continue\n if (state.lastPositions.get(el) === next) continue\n state.lastPositions.set(el, next)\n if (useTransform) {\n el.style.transform = horizontal\n ? `translate3d(${next}px, 0, 0)`\n : `translate3d(0, ${next}px, 0)`\n } else {\n el.style[posAxis] = `${next}px`\n }\n }\n }\n\n const resolvedOptions: VirtualizerOptions<TScrollElement, TItemElement> = {\n ...options,\n onChange: (instance, sync) => {\n const state = directRef.current\n let shouldRerender = true\n\n if (state.enabled) {\n applyDirectStyles(instance)\n\n // Only re-render on range / isScrolling changes\n const range = instance.range\n const prev = state.prevRange\n shouldRerender =\n !prev ||\n prev.isScrolling !== instance.isScrolling ||\n prev.startIndex !== range?.startIndex ||\n prev.endIndex !== range?.endIndex\n if (shouldRerender) {\n state.prevRange = range\n ? {\n startIndex: range.startIndex,\n endIndex: range.endIndex,\n isScrolling: instance.isScrolling,\n }\n : null\n }\n }\n\n if (shouldRerender) {\n if (useFlushSync && sync) {\n flushSync(rerender)\n } else {\n rerender()\n }\n }\n\n options.onChange?.(instance, sync)\n },\n }\n\n const [instance] = React.useState(() => {\n const v = new Virtualizer<TScrollElement, TItemElement>(resolvedOptions)\n return Object.assign(v, {\n containerRef: (node: HTMLElement | null) => {\n const state = directRef.current\n state.container = node\n state.lastSize = null\n if (node && state.enabled) {\n const total = v.getTotalSize()\n state.lastSize = total\n const axis = v.options.horizontal ? 'width' : 'height'\n node.style[axis] = `${total}px`\n }\n },\n })\n })\n\n instance.setOptions(resolvedOptions)\n\n useIsomorphicLayoutEffect(() => {\n return instance._didMount()\n }, [])\n\n useIsomorphicLayoutEffect(() => {\n // Grow the size container to the new total BEFORE _willUpdate syncs the\n // scroll position. On an end-anchored prepend the scroll target lands at\n // the new bottom; if the container is still at its old (shorter) height the\n // browser clamps the scrollTop write and the list is left with a gap at the\n // top until the next scroll. Positions are written afterwards by the\n // applyDirectStyles effect below.\n applyContainerSize(instance)\n return instance._willUpdate()\n })\n\n // After every render commit, newly mounted item refs have registered in\n // elementsCache; write their positions to the DOM so the user doesn't see\n // them at (0, 0) until the next onChange.\n useIsomorphicLayoutEffect(() => {\n applyDirectStyles(instance)\n })\n\n return instance\n}\n\nexport function useVirtualizer<\n TScrollElement extends Element,\n TItemElement extends Element,\n>(\n options: PartialKeys<\n ReactVirtualizerOptions<TScrollElement, TItemElement>,\n 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'\n >,\n): ReactVirtualizer<TScrollElement, TItemElement> {\n return useVirtualizerBase<TScrollElement, TItemElement>({\n observeElementRect: observeElementRect,\n observeElementOffset: observeElementOffset,\n scrollToFn: elementScroll,\n ...options,\n })\n}\n\nexport function useWindowVirtualizer<TItemElement extends Element>(\n options: PartialKeys<\n ReactVirtualizerOptions<Window, TItemElement>,\n | 'getScrollElement'\n | 'observeElementRect'\n | 'observeElementOffset'\n | 'scrollToFn'\n >,\n): ReactVirtualizer<Window, TItemElement> {\n return useVirtualizerBase<Window, TItemElement>({\n getScrollElement: () => (typeof document !== 'undefined' ? window : null),\n observeElementRect: observeWindowRect,\n observeElementOffset: observeWindowOffset,\n scrollToFn: windowScroll,\n initialOffset: () => (typeof document !== 'undefined' ? window.scrollY : 0),\n ...options,\n })\n}\n"],"mappings":"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","names":["cn","cn","UploadStatus","cn","FileSource","cn","_a","_a","opts","_b","key","startIndex","endIndex","instance","t","plural","cn","isUploadActive","UploadStatus","cn","cn","t","cn","cn","isFileRemovalLocked","UploadStatus","fileTypeIconName","cn","isFileRemovalLocked","UploadStatus","t","plural","cn","isUploadActive","UploadStatus","DragDropController","isUploadActive","resolveTheme","FileSource","jsx","useCallback","jsxs","cn","useState","memo","useMemo","Fragment","_a","_b","useEffect","forwardRef","t","fileTypeIconName","UploadStatus","isFileRemovalLocked","isUploadActive","plural","useRef","NOOP_SUBSCRIBE","core","DragDropController","_c","_d","u","useSyncExternalStore","resolveTheme","lazy","Suspense"]}
|