img-upload-kit 0.0.0-stage → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/LICENSE +21 -0
  3. package/MIGRATION.md +192 -0
  4. package/README.md +242 -2
  5. package/dist/bin.js +1186 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/blur.cjs +41 -0
  8. package/dist/blur.cjs.map +1 -0
  9. package/dist/blur.d.cts +17 -0
  10. package/dist/blur.d.ts +17 -0
  11. package/dist/blur.js +41 -0
  12. package/dist/blur.js.map +1 -0
  13. package/dist/blurDataUtils-DveBRtqE.d.cts +43 -0
  14. package/dist/blurDataUtils-yx9Q6HlU.d.ts +43 -0
  15. package/dist/blurService-D5TpMNji.d.ts +83 -0
  16. package/dist/blurService-DacwylJx.d.cts +83 -0
  17. package/dist/chunk-2OVNXHTN.cjs +514 -0
  18. package/dist/chunk-2OVNXHTN.cjs.map +1 -0
  19. package/dist/chunk-3ICG2SLL.cjs +135 -0
  20. package/dist/chunk-3ICG2SLL.cjs.map +1 -0
  21. package/dist/chunk-4ASFG3KB.js +514 -0
  22. package/dist/chunk-4ASFG3KB.js.map +1 -0
  23. package/dist/chunk-AI3JJLSA.js +2370 -0
  24. package/dist/chunk-AI3JJLSA.js.map +1 -0
  25. package/dist/chunk-CV23O4YU.js +145 -0
  26. package/dist/chunk-CV23O4YU.js.map +1 -0
  27. package/dist/chunk-G7LLSKBV.js +158 -0
  28. package/dist/chunk-G7LLSKBV.js.map +1 -0
  29. package/dist/chunk-IB3TEDLR.js +294 -0
  30. package/dist/chunk-IB3TEDLR.js.map +1 -0
  31. package/dist/chunk-KJVYWKIG.cjs +158 -0
  32. package/dist/chunk-KJVYWKIG.cjs.map +1 -0
  33. package/dist/chunk-NEDBIIE3.cjs +226 -0
  34. package/dist/chunk-NEDBIIE3.cjs.map +1 -0
  35. package/dist/chunk-QHU7FUO4.cjs +37 -0
  36. package/dist/chunk-QHU7FUO4.cjs.map +1 -0
  37. package/dist/chunk-QQHZJKNA.js +135 -0
  38. package/dist/chunk-QQHZJKNA.js.map +1 -0
  39. package/dist/chunk-S2IFAWJK.js +37 -0
  40. package/dist/chunk-S2IFAWJK.js.map +1 -0
  41. package/dist/chunk-TT5C7K3Q.js +226 -0
  42. package/dist/chunk-TT5C7K3Q.js.map +1 -0
  43. package/dist/chunk-U2TWTEBY.cjs +2370 -0
  44. package/dist/chunk-U2TWTEBY.cjs.map +1 -0
  45. package/dist/chunk-WISG74VL.cjs +294 -0
  46. package/dist/chunk-WISG74VL.cjs.map +1 -0
  47. package/dist/chunk-YRXXQUDE.cjs +145 -0
  48. package/dist/chunk-YRXXQUDE.cjs.map +1 -0
  49. package/dist/cli.cjs +1241 -0
  50. package/dist/cli.cjs.map +1 -0
  51. package/dist/cli.d.cts +99 -0
  52. package/dist/cli.d.ts +99 -0
  53. package/dist/cli.js +1194 -0
  54. package/dist/cli.js.map +1 -0
  55. package/dist/headless.cjs +27 -0
  56. package/dist/headless.cjs.map +1 -0
  57. package/dist/headless.d.cts +4 -0
  58. package/dist/headless.d.ts +4 -0
  59. package/dist/headless.js +27 -0
  60. package/dist/headless.js.map +1 -0
  61. package/dist/index-BIdnqtW8.d.ts +234 -0
  62. package/dist/index-Brk_uHs6.d.cts +234 -0
  63. package/dist/index-CPMlaQsC.d.ts +635 -0
  64. package/dist/index-DHINe-rA.d.cts +635 -0
  65. package/dist/index.cjs +65 -0
  66. package/dist/index.cjs.map +1 -0
  67. package/dist/index.d.cts +43 -0
  68. package/dist/index.d.ts +43 -0
  69. package/dist/index.js +65 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/memoryAdapter-Ck0ccZbF.d.cts +25 -0
  72. package/dist/memoryAdapter-DxEKaG0b.d.ts +25 -0
  73. package/dist/placeholders-C4ftwaII.d.ts +5 -0
  74. package/dist/placeholders-x_3rt65M.d.cts +5 -0
  75. package/dist/react.cjs +3779 -0
  76. package/dist/react.cjs.map +1 -0
  77. package/dist/react.d.cts +476 -0
  78. package/dist/react.d.ts +476 -0
  79. package/dist/react.js +3779 -0
  80. package/dist/react.js.map +1 -0
  81. package/dist/server-handler.cjs +14 -0
  82. package/dist/server-handler.cjs.map +1 -0
  83. package/dist/server-handler.d.cts +3 -0
  84. package/dist/server-handler.d.ts +3 -0
  85. package/dist/server-handler.js +14 -0
  86. package/dist/server-handler.js.map +1 -0
  87. package/dist/server.cjs +1801 -0
  88. package/dist/server.cjs.map +1 -0
  89. package/dist/server.d.cts +142 -0
  90. package/dist/server.d.ts +142 -0
  91. package/dist/server.js +1801 -0
  92. package/dist/server.js.map +1 -0
  93. package/dist/storage.cjs +447 -0
  94. package/dist/storage.cjs.map +1 -0
  95. package/dist/storage.d.cts +163 -0
  96. package/dist/storage.d.ts +163 -0
  97. package/dist/storage.js +447 -0
  98. package/dist/storage.js.map +1 -0
  99. package/dist/styles/animated-image.css +112 -0
  100. package/dist/styles/dropzone-and-tiles.css +247 -0
  101. package/dist/styles/modals-and-dock.css +248 -0
  102. package/dist/styles/primitives.css +197 -0
  103. package/dist/styles/quality-and-inputs.css +184 -0
  104. package/dist/styles/tokens.css +123 -0
  105. package/dist/styles.css +1122 -0
  106. package/dist/types-BrP-o9nd.d.cts +85 -0
  107. package/dist/types-sZ3KoFQY.d.ts +85 -0
  108. package/dist/types-yShGNQnW.d.cts +61 -0
  109. package/dist/types-yShGNQnW.d.ts +61 -0
  110. package/dist/upload-C5Trd6Dh.d.cts +154 -0
  111. package/dist/upload-C5Trd6Dh.d.ts +154 -0
  112. package/package.json +198 -4
@@ -0,0 +1,476 @@
1
+ import { U as UploadTranslations, a as UploadVisualState, C as CustomImageRenderer, I as ImageUploadProps, b as ImageUploadHandle, M as MultiImageUploadProps, c as ImagePreview, S as SingleImageUploadProps } from './index-DHINe-rA.cjs';
2
+ export { B as BaseImageUploadProps, d as BlurModalTranslations, e as ClientUploadRequestParams, f as CustomUploaderFn, H as HeadlessDropzoneProps, g as HeadlessFileInputProps, h as HeadlessMultiUpload, i as HeadlessMultiUploadProps, j as HeadlessSingleUpload, k as HeadlessSingleUploadProps, l as ImageUploadContextValue, m as ImageUploadProvider, n as ImageUploadProviderProps, o as MultiAddMoreRenderContext, p as MultiCustomRenderers, q as MultiEmptyRenderContext, r as MultiHeaderRenderContext, s as MultiTileRenderContext, t as MultiUploadClassNames, u as MultiUploadController, v as MultiUploadSlot, w as MultiUploadStats, x as MultiUploadStyles, R as RenderImageProps, y as SingleCustomRenderers, z as SingleDropzoneRenderContext, A as SinglePreviewRenderContext, D as SingleUploadClassNames, E as SingleUploadController, F as SingleUploadSlot, G as SingleUploadStyles, J as SizeInfo, K as UploadCallOptions, L as UploadStatus, N as UseDragAndDropOptions, N as UseDropzoneOptions, O as UseFilePreviewOptions, P as UseImageUploadOptions, Q as UseMultiUploadOptions, T as UseSingleUploadOptions, V as useDragAndDrop, V as useDropzone, W as useFilePreview, X as useImageUpload, Y as useImageUploadContext, Z as useMultiUpload, _ as useSingleUpload } from './index-DHINe-rA.cjs';
3
+ import * as react from 'react';
4
+ import { CSSProperties, ClipboardEvent, RefObject, ImgHTMLAttributes, ReactNode, ElementType, HTMLAttributes, SyntheticEvent, Ref, ReactElement, ButtonHTMLAttributes } from 'react';
5
+ import { U as UploadLocale, E as ExplicitOutputFormat, b as ImageDimensions, m as UploadedImageData, e as ImageVariant, l as UploadPresetName, i as StandardPresetName, Q as QualityLevel } from './upload-C5Trd6Dh.cjs';
6
+ import { f as BlurPlaceholderType, i as BlurSize } from './types-yShGNQnW.cjs';
7
+ export { D as DEFAULT_PLACEHOLDERS } from './placeholders-x_3rt65M.cjs';
8
+ export { b as blurService } from './blurService-DacwylJx.cjs';
9
+
10
+ declare const arTranslations: UploadTranslations;
11
+
12
+ declare const enTranslations: UploadTranslations;
13
+
14
+ declare const DEFAULT_UPLOAD_TRANSLATIONS: UploadTranslations;
15
+ declare const ARABIC_UPLOAD_TRANSLATIONS: UploadTranslations;
16
+
17
+ declare function normalizeUploadLocale(locale?: string): UploadLocale;
18
+ declare function selectPluralCategory(locale: UploadLocale, count: number): Intl.LDMLPluralRule;
19
+ declare function formatUploadingCount(ui: UploadTranslations, count: number, locale: UploadLocale, overrides?: Partial<UploadTranslations>): string;
20
+ declare function formatNeedsAltMessage(ui: UploadTranslations, count: number, locale: UploadLocale): string;
21
+ declare function formatSkippedImagesMessage(ui: UploadTranslations, imageCount: number, skippedCount: number, locale: UploadLocale): string;
22
+ declare const uploadText: Record<UploadLocale, UploadTranslations>;
23
+ declare function resolveTranslations(locale?: UploadLocale, overrides?: Partial<UploadTranslations>): UploadTranslations;
24
+
25
+ /**
26
+ * Inline style applied to `<input type="file">` when `unstyled` mode is active
27
+ * so hidden file inputs remain invisible even when `image-upload-kit/styles.css` is not imported.
28
+ */
29
+ declare const HIDDEN_INPUT_STYLE: CSSProperties;
30
+ /**
31
+ * Joins truthy CSS class names cleanly.
32
+ */
33
+ declare function cx(...classes: Array<string | false | null | undefined>): string;
34
+ /**
35
+ * Resolves a component slot's final `className`:
36
+ * - When `unstyled` is `false` (default): includes `defaultClass` followed by provider & prop overrides.
37
+ * - When `unstyled` is `true`: strips `defaultClass` (`iuk-*`) and applies only user-supplied classes.
38
+ */
39
+ declare function resolveSlotClass(defaultClass: string | undefined, unstyled: boolean | undefined, ...customClasses: Array<string | false | null | undefined>): string | undefined;
40
+ /**
41
+ * Merges multiple optional inline `CSSProperties` objects for a slot.
42
+ */
43
+ declare function resolveSlotStyle(...styles: Array<CSSProperties | undefined>): CSSProperties | undefined;
44
+ /**
45
+ * Computes a deterministic semantic state string for `data-state="..."` styling
46
+ * (e.g. Tailwind `data-[state=dragging]:border-indigo-500` or CSS `[data-state="uploading"]`).
47
+ */
48
+ declare function resolveUploadDataState(flags: {
49
+ disabled?: boolean;
50
+ hasError?: boolean;
51
+ isUploading?: boolean;
52
+ isDragging?: boolean;
53
+ hasContent?: boolean;
54
+ }): UploadVisualState;
55
+
56
+ declare function useBlurDataURL(imageSrc: string | undefined, options?: {
57
+ type?: BlurPlaceholderType;
58
+ size?: BlurSize;
59
+ }): string;
60
+ declare function useBulkBlurData(imageSrcs: string[], options?: {
61
+ type?: BlurPlaceholderType;
62
+ size?: BlurSize;
63
+ }): Record<string, string>;
64
+ declare function useProgressiveBlur(imageSrc: string | undefined, size?: BlurSize): {
65
+ color: string;
66
+ blur: string;
67
+ hasBlur: boolean;
68
+ };
69
+ declare function useHasBlurHash(imageSrc: string | undefined): boolean;
70
+ declare function useDominantColor(imageSrc: string | undefined): string;
71
+ declare function useBlurMetadata(): {
72
+ cacheSize: number;
73
+ metrics: {
74
+ cacheHitRate: string;
75
+ totalRequests: number;
76
+ cacheHits: number;
77
+ cacheMisses: number;
78
+ errors: number;
79
+ };
80
+ version: string;
81
+ generatedAt: string;
82
+ totalImages: number;
83
+ };
84
+ declare function useBlurHash(imageSrc: string | undefined): string | null;
85
+ declare function useBlurDataWithColor(imageSrc: string | undefined, size?: BlurSize): {
86
+ blurDataUrl: string;
87
+ blurColor: string;
88
+ hasBlur: boolean;
89
+ };
90
+ declare function useBlurVariant(imageSrc: string | undefined, size?: BlurSize, type?: BlurPlaceholderType): string;
91
+
92
+ type PasteTargetMode = 'dropzone' | 'document';
93
+ interface UseClipboardPasteOptions {
94
+ /** Enable clipboard image paste handling (defaults to `true`) */
95
+ enabled?: boolean;
96
+ /** Listen on the focused dropzone (`'dropzone'`) or globally on `document` (`'document'`). Defaults to `'dropzone'`. */
97
+ pasteTarget?: PasteTargetMode;
98
+ /** Disable paste handling when the uploader is disabled */
99
+ disabled?: boolean;
100
+ /** Allow pasting multiple images at once (defaults to `false` for single upload, `true` for multi upload) */
101
+ multiple?: boolean;
102
+ /** Callback invoked when one or more image files are pasted */
103
+ onPasteFiles: (files: FileList) => void;
104
+ }
105
+ declare function extractClipboardImageFiles(clipboardData: DataTransfer | null | undefined, multiple: boolean): File[];
106
+ declare function toFileListLike(files: File[]): FileList;
107
+ declare function useClipboardPaste({ enabled, pasteTarget, disabled, multiple, onPasteFiles, }: UseClipboardPasteOptions): {
108
+ onPaste: (event: ClipboardEvent<HTMLElement>) => void;
109
+ };
110
+
111
+ interface UseDialogOptions {
112
+ isOpen: boolean;
113
+ onClose?: () => void;
114
+ initialFocusRef?: RefObject<HTMLElement | null>;
115
+ lockScroll?: boolean;
116
+ }
117
+ declare function useDialog({ isOpen, onClose, initialFocusRef, lockScroll, }: UseDialogOptions): {
118
+ dialogRef: RefObject<HTMLDivElement | null>;
119
+ titleId: string;
120
+ descriptionId: string;
121
+ };
122
+
123
+ interface XhrUploadOptions {
124
+ headers?: Record<string, string>;
125
+ withCredentials?: boolean;
126
+ signal?: AbortSignal;
127
+ fallbackErrorLabel?: string;
128
+ networkErrorLabel?: string;
129
+ invalidResponseLabel?: string;
130
+ abortedErrorLabel?: string;
131
+ onUploadProgress?: (percent: number) => void;
132
+ }
133
+ interface UploadFormFields {
134
+ preset?: string;
135
+ folder?: string;
136
+ bucket?: string;
137
+ altText?: string;
138
+ customFilename?: string;
139
+ outputFormat?: ExplicitOutputFormat;
140
+ quality?: number;
141
+ maxDimensions?: ImageDimensions;
142
+ metadata?: Record<string, string>;
143
+ }
144
+ declare function createUploadAbortError(message?: string): Error;
145
+ declare function isUploadAbortError(err: unknown): boolean;
146
+ declare function parseErrorPayload(status: number, rawBody: string, fallbackLabel?: string): string;
147
+ declare function buildUploadFormData(file: File | Blob, fields?: UploadFormFields): FormData;
148
+ declare function uploadViaXhr(endpoint: string, formData: FormData, options?: XhrUploadOptions): Promise<UploadedImageData>;
149
+
150
+ declare const useProgressiveImage: typeof useProgressiveBlur;
151
+ declare function useBlurPreload(imageSrcs: string[], size?: BlurSize): void;
152
+
153
+ interface AltTextInputProps {
154
+ value: string;
155
+ onChange: (value: string) => void;
156
+ disabled?: boolean;
157
+ placeholder?: string;
158
+ maxLength?: number;
159
+ label?: string;
160
+ showHint?: boolean;
161
+ locale?: UploadLocale;
162
+ translations?: Partial<UploadTranslations>;
163
+ unstyled?: boolean;
164
+ }
165
+ declare function AltTextInput({ value, onChange, disabled, placeholder, maxLength, label, showHint, locale: propLocale, translations, unstyled: propUnstyled, }: AltTextInputProps): react.JSX.Element;
166
+
167
+ interface AltTextModalProps {
168
+ imageUrl: string;
169
+ initialAltText?: string;
170
+ onSave: (altText: string) => void;
171
+ onClose: () => void;
172
+ locale?: UploadLocale;
173
+ translations?: Partial<UploadTranslations>;
174
+ renderImage?: CustomImageRenderer;
175
+ unstyled?: boolean;
176
+ }
177
+ declare function AltTextModal({ imageUrl, initialAltText, onSave, onClose, locale: propLocale, translations, renderImage, unstyled: propUnstyled, }: AltTextModalProps): react.JSX.Element;
178
+
179
+ type AnimatedImageObjectFit = 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
180
+ type AnimatedImageColorPlaceholder = 'flat' | 'gradient';
181
+ interface AnimatedImageSource {
182
+ url: string;
183
+ altText?: string | null;
184
+ blurDataUrl?: string | null;
185
+ blurHash?: string | null;
186
+ blurColor?: string | null;
187
+ width?: number;
188
+ height?: number;
189
+ variants?: ImageVariant[];
190
+ srcSet?: string;
191
+ }
192
+ interface AnimatedImageErrorContext {
193
+ src: string;
194
+ retry: () => void;
195
+ }
196
+ interface AnimatedImageBaseProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 'src' | 'alt' | 'onLoad' | 'onError' | 'placeholder'> {
197
+ /** LQIP data URL (e.g. `UploadedImageData.blurDataUrl`). Highest priority placeholder. */
198
+ blurDataUrl?: string | null;
199
+ /** BlurHash string, decoded client-side when no `blurDataUrl` is given. */
200
+ blurHash?: string | null;
201
+ /** Dominant color or CSS variable (e.g. `'#3b82f6'` or `'var(--background-card)'`) used as wrapper background. */
202
+ blurColor?: string | null;
203
+ /**
204
+ * Placeholder behavior when only `blurColor` is available (no `blurDataUrl` or `blurHash`):
205
+ * - `'flat'` (default): uses flat `blurColor` wrapper background with no extra placeholder `<img>` layer (Imagine-Global parity).
206
+ * - `'gradient'`: mounts an inline SVG gradient placeholder `<img>`.
207
+ */
208
+ colorPlaceholder?: AnimatedImageColorPlaceholder;
209
+ /**
210
+ * Neutral colors ignored by `resolveBackgroundColor` / `resolveMeaningfulColor`.
211
+ * Defaults to `DEFAULT_NEUTRAL_COLORS`. Pass `[]` to allow all colors (including `#000000` / `#ffffff`).
212
+ */
213
+ neutralColors?: readonly string[];
214
+ /** Absolutely fill the nearest positioned parent (like `next/image` `fill`). */
215
+ fill?: boolean;
216
+ /**
217
+ * Mark image as high-priority above-the-fold content:
218
+ * - Native `<img>`: sets `loading="eager"` and `fetchPriority="high"`.
219
+ * - Custom `as={Image}`: forwards `priority={true}` and omits default `loading="lazy"`.
220
+ */
221
+ priority?: boolean;
222
+ /**
223
+ * Image quality hint (1–100) forwarded only when `as` is provided (e.g. `next/image`).
224
+ * Never rendered as a DOM attribute on a native `<img>`.
225
+ */
226
+ quality?: number;
227
+ objectFit?: AnimatedImageObjectFit;
228
+ objectPosition?: CSSProperties['objectPosition'];
229
+ /** Show an animated shimmer while loading. Unmounted once loaded. Default `false`. */
230
+ showShimmer?: boolean;
231
+ /** Reveal transition duration in ms. Default `600`. */
232
+ animationDuration?: number;
233
+ /** Initial scale of the image before reveal (`scale(revealScale) -> scale(1)`). Default `1.02` (`1` = pure fade). */
234
+ revealScale?: number;
235
+ /** Optional fallback image URL tried once if the primary `src` fails to load. */
236
+ fallbackSrc?: string;
237
+ /** Optional custom error overlay rendered when image loading fails. */
238
+ renderError?: (ctx: AnimatedImageErrorContext) => ReactNode;
239
+ /** Render a custom image component (e.g. `next/image`, Gatsby, Astro). Receives all img props. */
240
+ as?: ElementType;
241
+ /** Extra props forwarded only to the `as` component. */
242
+ imageComponentProps?: Record<string, unknown>;
243
+ /** Strip all default `iuk-animated-image*` classes (bring your own CSS). */
244
+ unstyled?: boolean;
245
+ wrapperClassName?: string;
246
+ wrapperStyle?: CSSProperties;
247
+ wrapperProps?: HTMLAttributes<HTMLDivElement>;
248
+ placeholderClassName?: string;
249
+ /** Called after the image is decoded and the fade-in starts. */
250
+ onLoad?: (img: HTMLImageElement | null) => void;
251
+ onError?: (event: SyntheticEvent<HTMLImageElement, Event>) => void;
252
+ }
253
+ type AnimatedImageProps = AnimatedImageBaseProps & ({
254
+ /** Direct `UploadedImageData` object returned by `<SingleImageUpload>` or `<MultiImageUpload>`. */
255
+ image: AnimatedImageSource;
256
+ src?: string;
257
+ alt?: string;
258
+ } | {
259
+ image?: undefined;
260
+ /** Image URL. */
261
+ src: string;
262
+ /** Accessible alt text (use `""` for decorative images). */
263
+ alt: string;
264
+ });
265
+
266
+ /**
267
+ * Blur-up image with a smooth, GPU-friendly crossfade and subtle zoom reveal.
268
+ * Matches the Imagine-Global reference design while remaining pure React,
269
+ * SSR-safe, and framework-agnostic — plug in `next/image` via `as`.
270
+ */
271
+ declare function AnimatedImage({ image, src: srcProp, alt: altProp, blurDataUrl: blurDataUrlProp, blurHash: blurHashProp, blurColor: blurColorProp, colorPlaceholder, neutralColors, width: widthProp, height: heightProp, fill, priority, quality, objectFit, objectPosition, showShimmer, animationDuration, revealScale, fallbackSrc, renderError, as: ImageComponent, imageComponentProps, unstyled, wrapperClassName, wrapperStyle, wrapperProps, placeholderClassName, className, style, loading: loadingProp, decoding, draggable, onLoad, onError, ...imgProps }: AnimatedImageProps): react.JSX.Element;
272
+
273
+ /**
274
+ * Default neutral colors that carry no real information about the image (common
275
+ * DB defaults or "empty" values). Ignored by default so placeholders never
276
+ * flash pitch-black or stark white unless `neutralColors={[]}` is passed.
277
+ */
278
+ declare const DEFAULT_NEUTRAL_COLORS: readonly ["#1a1a1a", "#121212", "#000000", "#000", "#e5e7eb", "#ffffff", "#fff"];
279
+ /**
280
+ * Returns a safe, meaningful literal color (`#hex`, `rgb(...)`, `hsl(...)`, `oklch(...)`)
281
+ * suitable for inline SVG embedding, or `undefined` when empty/neutral/invalid.
282
+ * Rejects CSS variables (`var(--*)`) because SVG data URLs cannot resolve host DOM tokens.
283
+ */
284
+ declare function resolveMeaningfulColor(color?: string | null, neutralColors?: readonly string[]): string | undefined;
285
+ /**
286
+ * Returns a safe CSS background-color value for the wrapper element.
287
+ * Accepts literal colors AND safe CSS custom property expressions (`var(--token)`),
288
+ * while rejecting neutral defaults and CSS injection payloads.
289
+ */
290
+ declare function resolveBackgroundColor(color?: string | null, neutralColors?: readonly string[]): string | undefined;
291
+ /**
292
+ * Inline SVG data URL that renders a soft gradient placeholder.
293
+ * Uses the dominant color when provided, otherwise a neutral slate gradient.
294
+ */
295
+ declare function createFallbackBlurSvg(color?: string | null, neutralColors?: readonly string[]): string;
296
+ interface PlaceholderSources {
297
+ blurDataUrl?: string | null;
298
+ blurHash?: string | null;
299
+ blurColor?: string | null;
300
+ neutralColors?: readonly string[];
301
+ }
302
+ /**
303
+ * Resolves an intrinsic image placeholder (`blurDataUrl` or decoded `blurHash`)
304
+ * without falling back to an SVG gradient. Returns `undefined` when neither is present.
305
+ */
306
+ declare function resolveIntrinsicPlaceholderUrl({ blurDataUrl, blurHash, }: Pick<PlaceholderSources, 'blurDataUrl' | 'blurHash'>): string | undefined;
307
+ /**
308
+ * Resolves the best available placeholder URL in priority order:
309
+ * 1. `blurDataUrl` (LQIP data URL / remote URL)
310
+ * 2. `blurHash` (decoded client-side; browser only)
311
+ * 3. Gradient SVG derived from `blurColor` (or neutral fallback)
312
+ */
313
+ declare function resolvePlaceholderUrl({ blurDataUrl, blurHash, blurColor, neutralColors, }: PlaceholderSources): string;
314
+
315
+ interface UseImageRevealOptions {
316
+ /** Identity of the primary source; a change resets the reveal state. */
317
+ srcKey: string;
318
+ /** Optional fallback URL tried once if `srcKey` fails to load. */
319
+ fallbackSrc?: string;
320
+ /** Crossfade duration in ms. */
321
+ animationDuration: number;
322
+ onLoad?: (img: HTMLImageElement | null) => void;
323
+ }
324
+ interface ImageRevealState {
325
+ /** Active image URL (`srcKey` initially, or `fallbackSrc` after primary failure). */
326
+ activeSrc: string;
327
+ /** Monotonic counter incremented when `retry()` is invoked. */
328
+ retryKey: number;
329
+ /** True once the sharp image is decoded and ready to fade in. */
330
+ isLoaded: boolean;
331
+ /** Whether the placeholder layer is still mounted (kept until fade completes, or on error). */
332
+ showPlaceholder: boolean;
333
+ /** True when the image (and optional `fallbackSrc`) failed to load. */
334
+ hasError: boolean;
335
+ /** Callback ref to attach to the underlying `<img>` element. */
336
+ imgRef: (node: HTMLImageElement | null) => void;
337
+ handleLoad: (img?: HTMLImageElement | null) => void;
338
+ /** Returns `true` if the error is terminal, or `false` if switching to `fallbackSrc`. */
339
+ handleError: () => boolean;
340
+ /** Resets error state and retries loading from the primary `srcKey`. */
341
+ retry: () => void;
342
+ }
343
+ /**
344
+ * Framework-agnostic reveal state machine for blur-up images:
345
+ * - resets synchronously when `srcKey` changes (no stale 1-frame flash)
346
+ * - pre-decodes via `HTMLImageElement.decode()` before crossfading
347
+ * - detects already-cached images after the first paint
348
+ * - unmounts placeholder after crossfade (`animationDuration + 50ms`)
349
+ * - on error: tries `fallbackSrc` once if provided; on terminal error keeps placeholder visible
350
+ */
351
+ declare function useImageReveal({ srcKey, fallbackSrc, animationDuration, onLoad, }: UseImageRevealOptions): ImageRevealState;
352
+
353
+ interface BlurImageProps {
354
+ src: string;
355
+ alt: string;
356
+ blurDataUrl?: string | null;
357
+ blurColor?: string | null;
358
+ blurHash?: string | null;
359
+ objectFit?: CSSProperties['objectFit'];
360
+ className?: string;
361
+ imageClassName?: string;
362
+ style?: CSSProperties;
363
+ renderImage?: CustomImageRenderer;
364
+ onImageLoad?: (img: HTMLImageElement | null) => void;
365
+ }
366
+ declare function BlurImage({ src, alt, blurDataUrl, blurColor, blurHash, objectFit, className, imageClassName, style, renderImage: propRenderImage, onImageLoad, }: BlurImageProps): react.JSX.Element;
367
+
368
+ /**
369
+ * Development helper: exposes the shared `blurService` singleton as
370
+ * `window.blurService` while mounted, for inspection in the browser console.
371
+ * Does not augment the global `Window` type of consuming apps.
372
+ */
373
+ declare function BlurServiceDebugger(): null;
374
+
375
+ interface BlurVisualizationModalProps {
376
+ isOpen: boolean;
377
+ onClose: () => void;
378
+ imageUrl: string;
379
+ blurDataUrl?: string;
380
+ blurColor?: string;
381
+ altText?: string;
382
+ originalSize?: number;
383
+ optimizedSize?: number | null;
384
+ detectedColor?: string;
385
+ onChangeColor?: (hex: string) => void;
386
+ onUseDetectedColor?: () => void;
387
+ onChangeAltText?: (altText: string) => void;
388
+ locale?: UploadLocale;
389
+ translations?: Partial<UploadTranslations>;
390
+ renderImage?: CustomImageRenderer;
391
+ unstyled?: boolean;
392
+ }
393
+ declare function BlurVisualizationModal({ isOpen, onClose, imageUrl, blurDataUrl, blurColor, altText, originalSize, optimizedSize, detectedColor, onChangeColor, onUseDetectedColor, onChangeAltText, locale: propLocale, translations, renderImage, unstyled: propUnstyled, }: BlurVisualizationModalProps): react.ReactPortal | null;
394
+
395
+ declare const ImageUpload: <TPreset extends string = UploadPresetName>(props: ImageUploadProps<TPreset> & {
396
+ ref?: Ref<ImageUploadHandle>;
397
+ }) => ReactElement | null;
398
+ declare const UnifiedImageUpload: <TPreset extends string = StandardPresetName | (string & {})>(props: ImageUploadProps<TPreset> & {
399
+ ref?: Ref<ImageUploadHandle>;
400
+ }) => ReactElement | null;
401
+
402
+ declare const MultiImageUpload: <TPreset extends string = UploadPresetName>(props: MultiImageUploadProps<TPreset> & {
403
+ ref?: Ref<ImageUploadHandle>;
404
+ }) => ReactElement | null;
405
+
406
+ interface PreviewTileProps {
407
+ preview: ImagePreview;
408
+ onRemove: (id: string) => void;
409
+ onCancel?: (id: string) => void;
410
+ onRetry?: (id: string) => void;
411
+ disabled?: boolean;
412
+ blurType?: BlurPlaceholderType;
413
+ isSelected?: boolean;
414
+ onToggleSelect?: (id: string) => void;
415
+ onEditAltText?: (id: string) => void;
416
+ showCheckbox?: boolean;
417
+ onAdjustColor?: (id: string) => void;
418
+ onChangeColor?: (id: string, color: string) => void;
419
+ onChangeAltText?: (id: string, altText: string) => void;
420
+ appendCacheBuster?: boolean;
421
+ locale?: UploadLocale;
422
+ translations?: Partial<UploadTranslations>;
423
+ renderImage?: CustomImageRenderer;
424
+ unstyled?: boolean;
425
+ className?: string;
426
+ style?: CSSProperties;
427
+ }
428
+ declare function PreviewTile({ preview, onRemove, onCancel, onRetry, disabled, blurType, isSelected, onToggleSelect, onEditAltText, showCheckbox, onAdjustColor, onChangeColor, onChangeAltText, appendCacheBuster: appendBuster, locale: propLocale, translations, renderImage, unstyled: propUnstyled, className, style, }: PreviewTileProps): react.JSX.Element;
429
+
430
+ interface QualitySelectorProps {
431
+ value: QualityLevel;
432
+ onChange: (level: QualityLevel) => void;
433
+ preset?: string;
434
+ recommendedLevel?: QualityLevel;
435
+ recommendationNote?: {
436
+ en: string;
437
+ ar?: string;
438
+ };
439
+ originalFileSize?: number;
440
+ locale?: UploadLocale;
441
+ translations?: Partial<UploadTranslations>;
442
+ disabled?: boolean;
443
+ unstyled?: boolean;
444
+ }
445
+ declare function QualitySelector({ value, onChange, preset, recommendedLevel, recommendationNote, originalFileSize, locale, translations, disabled, unstyled, }: QualitySelectorProps): react.JSX.Element;
446
+
447
+ interface SaveButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
448
+ icon?: ReactNode;
449
+ unstyled?: boolean;
450
+ children: ReactNode;
451
+ }
452
+ declare function SaveButton({ icon, unstyled, children, className, type, ...rest }: SaveButtonProps): react.JSX.Element;
453
+
454
+ declare const SingleImageUpload: <TPreset extends string = UploadPresetName>(props: SingleImageUploadProps<TPreset> & {
455
+ ref?: Ref<ImageUploadHandle>;
456
+ }) => ReactElement | null;
457
+
458
+ interface UploadItem {
459
+ id: string;
460
+ url: string;
461
+ fileName?: string;
462
+ message?: string;
463
+ progress?: number;
464
+ }
465
+ interface UploadProgressPanelProps {
466
+ items: UploadItem[];
467
+ completedCount: number;
468
+ totalCount: number;
469
+ locale?: UploadLocale;
470
+ translations?: Partial<UploadTranslations>;
471
+ renderImage?: CustomImageRenderer;
472
+ unstyled?: boolean;
473
+ }
474
+ declare function UploadProgressPanel({ items, completedCount, totalCount, locale: propLocale, translations, renderImage, unstyled: propUnstyled, }: UploadProgressPanelProps): react.JSX.Element | null;
475
+
476
+ export { ARABIC_UPLOAD_TRANSLATIONS, AltTextInput, type AltTextInputProps, AltTextModal, type AltTextModalProps, AnimatedImage, type AnimatedImageBaseProps, type AnimatedImageColorPlaceholder, type AnimatedImageErrorContext, type AnimatedImageObjectFit, type AnimatedImageProps, type AnimatedImageSource, BlurImage, type BlurImageProps, BlurPlaceholderType, BlurServiceDebugger, BlurSize, BlurVisualizationModal, type BlurVisualizationModalProps, CustomImageRenderer, DEFAULT_NEUTRAL_COLORS, DEFAULT_UPLOAD_TRANSLATIONS, HIDDEN_INPUT_STYLE, ImagePreview, type ImageRevealState, ImageUpload, ImageUploadHandle, ImageUploadProps, MultiImageUpload, MultiImageUploadProps, type PasteTargetMode, type PlaceholderSources, PreviewTile, type PreviewTileProps, QualitySelector, type QualitySelectorProps, SaveButton, type SaveButtonProps, SingleImageUpload, SingleImageUploadProps, UnifiedImageUpload, type UploadFormFields, type UploadItem, UploadLocale, UploadProgressPanel, type UploadProgressPanelProps, UploadTranslations, UploadVisualState, type UseClipboardPasteOptions, type UseDialogOptions, type UseImageRevealOptions, type XhrUploadOptions, arTranslations, buildUploadFormData, createFallbackBlurSvg, createUploadAbortError, cx, enTranslations, extractClipboardImageFiles, formatNeedsAltMessage, formatSkippedImagesMessage, formatUploadingCount, isUploadAbortError, normalizeUploadLocale, parseErrorPayload, resolveBackgroundColor, resolveIntrinsicPlaceholderUrl, resolveMeaningfulColor, resolvePlaceholderUrl, resolveSlotClass, resolveSlotStyle, resolveTranslations, resolveUploadDataState, selectPluralCategory, toFileListLike, uploadText, uploadViaXhr, useBlurDataURL, useBlurDataWithColor, useBlurHash, useBlurMetadata, useBlurPreload, useBlurVariant, useBulkBlurData, useClipboardPaste, useDialog, useDominantColor, useHasBlurHash, useImageReveal, useProgressiveBlur, useProgressiveImage };