img-upload-kit 1.1.1 → 2.0.1

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 (111) hide show
  1. package/CHANGELOG.md +89 -74
  2. package/MIGRATION.md +192 -0
  3. package/README.md +243 -259
  4. package/dist/bin.js +1186 -0
  5. package/dist/bin.js.map +1 -0
  6. package/dist/blur.cjs +40 -412
  7. package/dist/blur.cjs.map +1 -1
  8. package/dist/blur.d.cts +5 -5
  9. package/dist/blur.d.ts +5 -5
  10. package/dist/blur.js +39 -393
  11. package/dist/blur.js.map +1 -1
  12. package/dist/blurDataUtils-DveBRtqE.d.cts +43 -0
  13. package/dist/blurDataUtils-yx9Q6HlU.d.ts +43 -0
  14. package/dist/blurService-D5TpMNji.d.ts +83 -0
  15. package/dist/blurService-DacwylJx.d.cts +83 -0
  16. package/dist/chunk-25GYKQ6J.js +158 -0
  17. package/dist/chunk-25GYKQ6J.js.map +1 -0
  18. package/dist/chunk-34L4TEE3.cjs +226 -0
  19. package/dist/chunk-34L4TEE3.cjs.map +1 -0
  20. package/dist/chunk-DFCSN3X7.cjs +158 -0
  21. package/dist/chunk-DFCSN3X7.cjs.map +1 -0
  22. package/dist/chunk-EWVIL57J.js +294 -0
  23. package/dist/chunk-EWVIL57J.js.map +1 -0
  24. package/dist/chunk-FP5YIWG5.cjs +135 -0
  25. package/dist/chunk-FP5YIWG5.cjs.map +1 -0
  26. package/dist/chunk-HILELQGS.js +226 -0
  27. package/dist/chunk-HILELQGS.js.map +1 -0
  28. package/dist/chunk-IDLLCVGB.js +2370 -0
  29. package/dist/chunk-IDLLCVGB.js.map +1 -0
  30. package/dist/chunk-J6A44Y3W.js +514 -0
  31. package/dist/chunk-J6A44Y3W.js.map +1 -0
  32. package/dist/chunk-LOSVFO56.cjs +145 -0
  33. package/dist/chunk-LOSVFO56.cjs.map +1 -0
  34. package/dist/chunk-MBQJ6NVJ.cjs +294 -0
  35. package/dist/chunk-MBQJ6NVJ.cjs.map +1 -0
  36. package/dist/chunk-MHGQEBPW.js +145 -0
  37. package/dist/chunk-MHGQEBPW.js.map +1 -0
  38. package/dist/chunk-QHU7FUO4.cjs +37 -0
  39. package/dist/chunk-QHU7FUO4.cjs.map +1 -0
  40. package/dist/chunk-S2IFAWJK.js +37 -0
  41. package/dist/chunk-S2IFAWJK.js.map +1 -0
  42. package/dist/chunk-TA5Y64JM.cjs +2370 -0
  43. package/dist/chunk-TA5Y64JM.cjs.map +1 -0
  44. package/dist/chunk-VYVZVUNI.js +135 -0
  45. package/dist/chunk-VYVZVUNI.js.map +1 -0
  46. package/dist/chunk-XKQMCY5Z.cjs +514 -0
  47. package/dist/chunk-XKQMCY5Z.cjs.map +1 -0
  48. package/dist/cli.cjs +273 -76
  49. package/dist/cli.cjs.map +1 -1
  50. package/dist/cli.js +269 -73
  51. package/dist/cli.js.map +1 -1
  52. package/dist/headless.cjs +8 -1880
  53. package/dist/headless.cjs.map +1 -1
  54. package/dist/headless.d.cts +3 -1
  55. package/dist/headless.d.ts +3 -1
  56. package/dist/headless.js +25 -1886
  57. package/dist/headless.js.map +1 -1
  58. package/dist/index-BIdnqtW8.d.ts +234 -0
  59. package/dist/index-Brk_uHs6.d.cts +234 -0
  60. package/dist/{index-FVXXKf2v.d.ts → index-CPMlaQsC.d.ts} +76 -153
  61. package/dist/{index-FVXXKf2v.d.cts → index-DHINe-rA.d.cts} +76 -153
  62. package/dist/index.cjs +64 -532
  63. package/dist/index.cjs.map +1 -1
  64. package/dist/index.d.cts +7 -4
  65. package/dist/index.d.ts +7 -4
  66. package/dist/index.js +63 -504
  67. package/dist/index.js.map +1 -1
  68. package/dist/{memoryAdapter-CBu7_3Pp.d.ts → memoryAdapter-Ck0ccZbF.d.cts} +3 -2
  69. package/dist/{memoryAdapter-BJjyLR-1.d.cts → memoryAdapter-DxEKaG0b.d.ts} +3 -2
  70. package/dist/placeholders-C4ftwaII.d.ts +5 -0
  71. package/dist/placeholders-x_3rt65M.d.cts +5 -0
  72. package/dist/react.cjs +1952 -3257
  73. package/dist/react.cjs.map +1 -1
  74. package/dist/react.d.cts +188 -50
  75. package/dist/react.d.ts +188 -50
  76. package/dist/react.js +1763 -3013
  77. package/dist/react.js.map +1 -1
  78. package/dist/server-handler.cjs +14 -0
  79. package/dist/server-handler.cjs.map +1 -0
  80. package/dist/server-handler.d.cts +3 -0
  81. package/dist/server-handler.d.ts +3 -0
  82. package/dist/server-handler.js +14 -0
  83. package/dist/server-handler.js.map +1 -0
  84. package/dist/server.cjs +1096 -532
  85. package/dist/server.cjs.map +1 -1
  86. package/dist/server.d.cts +77 -154
  87. package/dist/server.d.ts +77 -154
  88. package/dist/server.js +1050 -448
  89. package/dist/server.js.map +1 -1
  90. package/dist/storage.cjs +239 -232
  91. package/dist/storage.cjs.map +1 -1
  92. package/dist/storage.d.cts +21 -5
  93. package/dist/storage.d.ts +21 -5
  94. package/dist/storage.js +227 -207
  95. package/dist/storage.js.map +1 -1
  96. package/dist/styles/animated-image.css +112 -0
  97. package/dist/styles/dropzone-and-tiles.css +247 -0
  98. package/dist/styles/modals-and-dock.css +248 -0
  99. package/dist/styles/primitives.css +197 -0
  100. package/dist/styles/quality-and-inputs.css +184 -0
  101. package/dist/styles/tokens.css +123 -0
  102. package/dist/styles.css +235 -220
  103. package/dist/types-BrP-o9nd.d.cts +85 -0
  104. package/dist/types-sZ3KoFQY.d.ts +85 -0
  105. package/dist/types-yShGNQnW.d.cts +61 -0
  106. package/dist/types-yShGNQnW.d.ts +61 -0
  107. package/dist/{types-CiLY0DwB.d.cts → upload-C5Trd6Dh.d.cts} +27 -53
  108. package/dist/{types-CiLY0DwB.d.ts → upload-C5Trd6Dh.d.ts} +27 -53
  109. package/package.json +92 -32
  110. package/dist/blurService-DqsnfPTd.d.cts +0 -172
  111. package/dist/blurService-DqsnfPTd.d.ts +0 -172
package/dist/react.d.ts CHANGED
@@ -1,13 +1,24 @@
1
- import { U as UploadTranslations, a as UploadLocale, b as UploadVisualState, B as BlurPlaceholderType, c as BlurSize, E as ExplicitOutputFormat, I as ImageDimensions, d as UploadedImageData, C as CustomImageRenderer, e as UploadPresetName, f as ImageUploadProps, M as MultiImageUploadProps, g as ImagePreview, Q as QualityLevel, S as SingleImageUploadProps } from './index-FVXXKf2v.js';
2
- export { h as BaseImageUploadProps, i as BlurModalTranslations, j as BlurServiceDebugger, k as ClientUploadRequestParams, l as CustomUploaderFn, H as HeadlessDropzoneProps, m as HeadlessFileInputProps, n as HeadlessMultiUpload, o as HeadlessMultiUploadProps, p as HeadlessSingleUpload, q as HeadlessSingleUploadProps, r as ImageUploadContextValue, s as ImageUploadProvider, t as ImageUploadProviderProps, u as MultiAddMoreRenderContext, v as MultiCustomRenderers, w as MultiEmptyRenderContext, x as MultiHeaderRenderContext, y as MultiTileRenderContext, z as MultiUploadClassNames, A as MultiUploadController, D as MultiUploadSlot, F as MultiUploadStats, G as MultiUploadStyles, R as RenderImageProps, J as SingleCustomRenderers, K as SingleDropzoneRenderContext, L as SinglePreviewRenderContext, N as SingleUploadClassNames, O as SingleUploadController, P as SingleUploadSlot, T as SingleUploadStyles, V as SizeInfo, W as UploadStatus, X as UseDragAndDropOptions, X as UseDropzoneOptions, Y as UseImageUploadOptions, Z as UseMultiUploadOptions, _ as UseSingleUploadOptions, $ as blurService, a0 as useDragAndDrop, a0 as useDropzone, a1 as useFilePreview, a2 as useImageUpload, a3 as useImageUploadContext, a4 as useMultiUpload, a5 as useSingleUpload } from './index-FVXXKf2v.js';
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-CPMlaQsC.js';
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-CPMlaQsC.js';
3
3
  import * as react from 'react';
4
- import { CSSProperties, ImgHTMLAttributes, ElementType, HTMLAttributes, SyntheticEvent, ButtonHTMLAttributes, ReactNode } 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.js';
6
+ import { f as BlurPlaceholderType, i as BlurSize } from './types-yShGNQnW.js';
7
+ export { D as DEFAULT_PLACEHOLDERS } from './placeholders-C4ftwaII.js';
8
+ export { b as blurService } from './blurService-D5TpMNji.js';
5
9
 
6
10
  declare const arTranslations: UploadTranslations;
7
11
 
8
12
  declare const enTranslations: UploadTranslations;
9
13
 
14
+ declare const DEFAULT_UPLOAD_TRANSLATIONS: UploadTranslations;
15
+ declare const ARABIC_UPLOAD_TRANSLATIONS: UploadTranslations;
16
+
10
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;
11
22
  declare const uploadText: Record<UploadLocale, UploadTranslations>;
12
23
  declare function resolveTranslations(locale?: UploadLocale, overrides?: Partial<UploadTranslations>): UploadTranslations;
13
24
 
@@ -42,8 +53,6 @@ declare function resolveUploadDataState(flags: {
42
53
  hasContent?: boolean;
43
54
  }): UploadVisualState;
44
55
 
45
- declare const DEFAULT_PLACEHOLDERS: Record<BlurPlaceholderType, string>;
46
-
47
56
  declare function useBlurDataURL(imageSrc: string | undefined, options?: {
48
57
  type?: BlurPlaceholderType;
49
58
  size?: BlurSize;
@@ -80,10 +89,45 @@ declare function useBlurDataWithColor(imageSrc: string | undefined, size?: BlurS
80
89
  };
81
90
  declare function useBlurVariant(imageSrc: string | undefined, size?: BlurSize, type?: BlurPlaceholderType): string;
82
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
+
83
123
  interface XhrUploadOptions {
84
124
  headers?: Record<string, string>;
85
125
  withCredentials?: boolean;
126
+ signal?: AbortSignal;
86
127
  fallbackErrorLabel?: string;
128
+ networkErrorLabel?: string;
129
+ invalidResponseLabel?: string;
130
+ abortedErrorLabel?: string;
87
131
  onUploadProgress?: (percent: number) => void;
88
132
  }
89
133
  interface UploadFormFields {
@@ -97,6 +141,8 @@ interface UploadFormFields {
97
141
  maxDimensions?: ImageDimensions;
98
142
  metadata?: Record<string, string>;
99
143
  }
144
+ declare function createUploadAbortError(message?: string): Error;
145
+ declare function isUploadAbortError(err: unknown): boolean;
100
146
  declare function parseErrorPayload(status: number, rawBody: string, fallbackLabel?: string): string;
101
147
  declare function buildUploadFormData(file: File | Blob, fields?: UploadFormFields): FormData;
102
148
  declare function uploadViaXhr(endpoint: string, formData: FormData, options?: XhrUploadOptions): Promise<UploadedImageData>;
@@ -114,8 +160,9 @@ interface AltTextInputProps {
114
160
  showHint?: boolean;
115
161
  locale?: UploadLocale;
116
162
  translations?: Partial<UploadTranslations>;
163
+ unstyled?: boolean;
117
164
  }
118
- declare function AltTextInput({ value, onChange, disabled, placeholder, maxLength, label, showHint, locale: propLocale, translations, }: AltTextInputProps): react.JSX.Element;
165
+ declare function AltTextInput({ value, onChange, disabled, placeholder, maxLength, label, showHint, locale: propLocale, translations, unstyled: propUnstyled, }: AltTextInputProps): react.JSX.Element;
119
166
 
120
167
  interface AltTextModalProps {
121
168
  imageUrl: string;
@@ -125,10 +172,12 @@ interface AltTextModalProps {
125
172
  locale?: UploadLocale;
126
173
  translations?: Partial<UploadTranslations>;
127
174
  renderImage?: CustomImageRenderer;
175
+ unstyled?: boolean;
128
176
  }
129
- declare function AltTextModal({ imageUrl, initialAltText, onSave, onClose, locale: propLocale, translations, renderImage, }: AltTextModalProps): react.JSX.Element;
177
+ declare function AltTextModal({ imageUrl, initialAltText, onSave, onClose, locale: propLocale, translations, renderImage, unstyled: propUnstyled, }: AltTextModalProps): react.JSX.Element;
130
178
 
131
179
  type AnimatedImageObjectFit = 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
180
+ type AnimatedImageColorPlaceholder = 'flat' | 'gradient';
132
181
  interface AnimatedImageSource {
133
182
  url: string;
134
183
  altText?: string | null;
@@ -137,25 +186,59 @@ interface AnimatedImageSource {
137
186
  blurColor?: string | null;
138
187
  width?: number;
139
188
  height?: number;
189
+ variants?: ImageVariant[];
190
+ srcSet?: string;
191
+ }
192
+ interface AnimatedImageErrorContext {
193
+ src: string;
194
+ retry: () => void;
140
195
  }
141
196
  interface AnimatedImageBaseProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 'src' | 'alt' | 'onLoad' | 'onError' | 'placeholder'> {
142
197
  /** LQIP data URL (e.g. `UploadedImageData.blurDataUrl`). Highest priority placeholder. */
143
198
  blurDataUrl?: string | null;
144
199
  /** BlurHash string, decoded client-side when no `blurDataUrl` is given. */
145
200
  blurHash?: string | null;
146
- /** Dominant color (e.g. `UploadedImageData.blurColor`) used as background & gradient fallback. */
201
+ /** Dominant color or CSS variable (e.g. `'#3b82f6'` or `'var(--background-card)'`) used as wrapper background. */
147
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[];
148
214
  /** Absolutely fill the nearest positioned parent (like `next/image` `fill`). */
149
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;
150
227
  objectFit?: AnimatedImageObjectFit;
151
228
  objectPosition?: CSSProperties['objectPosition'];
152
- /** Show an animated shimmer while loading. Default `false`. */
229
+ /** Show an animated shimmer while loading. Unmounted once loaded. Default `false`. */
153
230
  showShimmer?: boolean;
154
- /** Crossfade duration in ms. Default `700`. */
231
+ /** Reveal transition duration in ms. Default `600`. */
155
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;
156
239
  /** Render a custom image component (e.g. `next/image`, Gatsby, Astro). Receives all img props. */
157
240
  as?: ElementType;
158
- /** Extra props forwarded only to the `as` component (e.g. `{ quality: 80, priority: true }`). */
241
+ /** Extra props forwarded only to the `as` component. */
159
242
  imageComponentProps?: Record<string, unknown>;
160
243
  /** Strip all default `iuk-animated-image*` classes (bring your own CSS). */
161
244
  unstyled?: boolean;
@@ -179,60 +262,93 @@ type AnimatedImageProps = AnimatedImageBaseProps & ({
179
262
  /** Accessible alt text (use `""` for decorative images). */
180
263
  alt: string;
181
264
  });
265
+
182
266
  /**
183
- * Blur-up image with a smooth, GPU-friendly crossfade from placeholder to sharp image.
184
- * Pure React, SSR-safe, framework-agnostic — plug in `next/image` via `as`.
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`.
185
270
  */
186
- declare function AnimatedImage({ image, src: srcProp, alt: altProp, blurDataUrl: blurDataUrlProp, blurHash: blurHashProp, blurColor: blurColorProp, width: widthProp, height: heightProp, fill, objectFit, objectPosition, showShimmer, animationDuration, as: ImageComponent, imageComponentProps, unstyled, wrapperClassName, wrapperStyle, wrapperProps, placeholderClassName, className, style, loading, decoding, draggable, onLoad, onError, ...imgProps }: AnimatedImageProps): react.JSX.Element;
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;
187
314
 
188
315
  interface UseImageRevealOptions {
189
- /** Identity of the current source; a change resets the reveal state. */
316
+ /** Identity of the primary source; a change resets the reveal state. */
190
317
  srcKey: string;
318
+ /** Optional fallback URL tried once if `srcKey` fails to load. */
319
+ fallbackSrc?: string;
191
320
  /** Crossfade duration in ms. */
192
321
  animationDuration: number;
193
322
  onLoad?: (img: HTMLImageElement | null) => void;
194
323
  }
195
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;
196
329
  /** True once the sharp image is decoded and ready to fade in. */
197
330
  isLoaded: boolean;
198
- /** Whether the placeholder layer is still mounted (kept until fade completes). */
331
+ /** Whether the placeholder layer is still mounted (kept until fade completes, or on error). */
199
332
  showPlaceholder: boolean;
200
- /** True when the image failed to load. */
333
+ /** True when the image (and optional `fallbackSrc`) failed to load. */
201
334
  hasError: boolean;
202
335
  /** Callback ref to attach to the underlying `<img>` element. */
203
336
  imgRef: (node: HTMLImageElement | null) => void;
204
337
  handleLoad: (img?: HTMLImageElement | null) => void;
205
- handleError: () => 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;
206
342
  }
207
343
  /**
208
344
  * Framework-agnostic reveal state machine for blur-up images:
209
345
  * - resets synchronously when `srcKey` changes (no stale 1-frame flash)
210
346
  * - pre-decodes via `HTMLImageElement.decode()` before crossfading
211
347
  * - detects already-cached images after the first paint
212
- * - keeps the placeholder mounted until the crossfade finishes, then unmounts it
213
- * - clears all timers / animation frames on unmount
214
- */
215
- declare function useImageReveal({ srcKey, animationDuration, onLoad }: UseImageRevealOptions): ImageRevealState;
216
-
217
- /** Returns a safe, meaningful color or `undefined` when the value is empty/neutral/invalid. */
218
- declare function resolveMeaningfulColor(color?: string | null): string | undefined;
219
- /**
220
- * Inline SVG data URL that renders a soft gradient placeholder.
221
- * Uses the dominant color when provided, otherwise a neutral slate gradient.
222
- */
223
- declare function createFallbackBlurSvg(color?: string | null): string;
224
- interface PlaceholderSources {
225
- blurDataUrl?: string | null;
226
- blurHash?: string | null;
227
- blurColor?: string | null;
228
- }
229
- /**
230
- * Resolves the best available placeholder in priority order:
231
- * 1. `blurDataUrl` (LQIP data URL / remote URL)
232
- * 2. `blurHash` (decoded client-side; browser only)
233
- * 3. Gradient SVG derived from `blurColor` (or neutral fallback)
348
+ * - unmounts placeholder after crossfade (`animationDuration + 50ms`)
349
+ * - on error: tries `fallbackSrc` once if provided; on terminal error keeps placeholder visible
234
350
  */
235
- declare function resolvePlaceholderUrl({ blurDataUrl, blurHash, blurColor }: PlaceholderSources): string;
351
+ declare function useImageReveal({ srcKey, fallbackSrc, animationDuration, onLoad, }: UseImageRevealOptions): ImageRevealState;
236
352
 
237
353
  interface BlurImageProps {
238
354
  src: string;
@@ -249,6 +365,13 @@ interface BlurImageProps {
249
365
  }
250
366
  declare function BlurImage({ src, alt, blurDataUrl, blurColor, blurHash, objectFit, className, imageClassName, style, renderImage: propRenderImage, onImageLoad, }: BlurImageProps): react.JSX.Element;
251
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
+
252
375
  interface BlurVisualizationModalProps {
253
376
  isOpen: boolean;
254
377
  onClose: () => void;
@@ -265,17 +388,26 @@ interface BlurVisualizationModalProps {
265
388
  locale?: UploadLocale;
266
389
  translations?: Partial<UploadTranslations>;
267
390
  renderImage?: CustomImageRenderer;
391
+ unstyled?: boolean;
268
392
  }
269
- declare function BlurVisualizationModal({ isOpen, onClose, imageUrl, blurDataUrl, blurColor, altText, originalSize, optimizedSize, detectedColor, onChangeColor, onUseDetectedColor, onChangeAltText, locale: propLocale, translations, renderImage, }: BlurVisualizationModalProps): react.ReactPortal | null;
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;
270
394
 
271
- declare function ImageUpload<TPreset extends string = UploadPresetName>(props: ImageUploadProps<TPreset>): react.JSX.Element | null;
272
- declare const UnifiedImageUpload: typeof ImageUpload;
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;
273
401
 
274
- declare function MultiImageUpload<TPreset extends string = UploadPresetName>(props: MultiImageUploadProps<TPreset>): react.JSX.Element;
402
+ declare const MultiImageUpload: <TPreset extends string = UploadPresetName>(props: MultiImageUploadProps<TPreset> & {
403
+ ref?: Ref<ImageUploadHandle>;
404
+ }) => ReactElement | null;
275
405
 
276
406
  interface PreviewTileProps {
277
407
  preview: ImagePreview;
278
408
  onRemove: (id: string) => void;
409
+ onCancel?: (id: string) => void;
410
+ onRetry?: (id: string) => void;
279
411
  disabled?: boolean;
280
412
  blurType?: BlurPlaceholderType;
281
413
  isSelected?: boolean;
@@ -285,6 +417,7 @@ interface PreviewTileProps {
285
417
  onAdjustColor?: (id: string) => void;
286
418
  onChangeColor?: (id: string, color: string) => void;
287
419
  onChangeAltText?: (id: string, altText: string) => void;
420
+ appendCacheBuster?: boolean;
288
421
  locale?: UploadLocale;
289
422
  translations?: Partial<UploadTranslations>;
290
423
  renderImage?: CustomImageRenderer;
@@ -292,7 +425,7 @@ interface PreviewTileProps {
292
425
  className?: string;
293
426
  style?: CSSProperties;
294
427
  }
295
- declare function PreviewTile({ preview, onRemove, disabled, blurType, isSelected, onToggleSelect, onEditAltText, showCheckbox, onAdjustColor, onChangeColor, onChangeAltText, locale: propLocale, translations, renderImage, unstyled: propUnstyled, className, style, }: PreviewTileProps): react.JSX.Element;
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;
296
429
 
297
430
  interface QualitySelectorProps {
298
431
  value: QualityLevel;
@@ -305,9 +438,11 @@ interface QualitySelectorProps {
305
438
  };
306
439
  originalFileSize?: number;
307
440
  locale?: UploadLocale;
441
+ translations?: Partial<UploadTranslations>;
308
442
  disabled?: boolean;
443
+ unstyled?: boolean;
309
444
  }
310
- declare function QualitySelector({ value, onChange, preset, recommendedLevel, recommendationNote, originalFileSize, locale, disabled, }: QualitySelectorProps): react.JSX.Element;
445
+ declare function QualitySelector({ value, onChange, preset, recommendedLevel, recommendationNote, originalFileSize, locale, translations, disabled, unstyled, }: QualitySelectorProps): react.JSX.Element;
311
446
 
312
447
  interface SaveButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
313
448
  icon?: ReactNode;
@@ -316,7 +451,9 @@ interface SaveButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
316
451
  }
317
452
  declare function SaveButton({ icon, unstyled, children, className, type, ...rest }: SaveButtonProps): react.JSX.Element;
318
453
 
319
- declare function SingleImageUpload<TPreset extends string = UploadPresetName>(props: SingleImageUploadProps<TPreset>): react.JSX.Element;
454
+ declare const SingleImageUpload: <TPreset extends string = UploadPresetName>(props: SingleImageUploadProps<TPreset> & {
455
+ ref?: Ref<ImageUploadHandle>;
456
+ }) => ReactElement | null;
320
457
 
321
458
  interface UploadItem {
322
459
  id: string;
@@ -332,7 +469,8 @@ interface UploadProgressPanelProps {
332
469
  locale?: UploadLocale;
333
470
  translations?: Partial<UploadTranslations>;
334
471
  renderImage?: CustomImageRenderer;
472
+ unstyled?: boolean;
335
473
  }
336
- declare function UploadProgressPanel({ items, completedCount, totalCount, locale: propLocale, translations, renderImage, }: UploadProgressPanelProps): react.JSX.Element | null;
474
+ declare function UploadProgressPanel({ items, completedCount, totalCount, locale: propLocale, translations, renderImage, unstyled: propUnstyled, }: UploadProgressPanelProps): react.JSX.Element | null;
337
475
 
338
- export { AltTextInput, type AltTextInputProps, AltTextModal, type AltTextModalProps, AnimatedImage, type AnimatedImageObjectFit, type AnimatedImageProps, type AnimatedImageSource, BlurImage, type BlurImageProps, BlurPlaceholderType, BlurSize, BlurVisualizationModal, type BlurVisualizationModalProps, CustomImageRenderer, DEFAULT_PLACEHOLDERS, HIDDEN_INPUT_STYLE, ImagePreview, type ImageRevealState, ImageUpload, ImageUploadProps, MultiImageUpload, MultiImageUploadProps, PreviewTile, type PreviewTileProps, QualitySelector, type QualitySelectorProps, SaveButton, type SaveButtonProps, SingleImageUpload, SingleImageUploadProps, UnifiedImageUpload, type UploadFormFields, type UploadItem, UploadProgressPanel, type UploadProgressPanelProps, UploadTranslations, UploadVisualState, type UseImageRevealOptions, type XhrUploadOptions, arTranslations, buildUploadFormData, createFallbackBlurSvg, cx, enTranslations, normalizeUploadLocale, parseErrorPayload, resolveMeaningfulColor, resolvePlaceholderUrl, resolveSlotClass, resolveSlotStyle, resolveTranslations, resolveUploadDataState, uploadText, uploadViaXhr, useBlurDataURL, useBlurDataWithColor, useBlurHash, useBlurMetadata, useBlurPreload, useBlurVariant, useBulkBlurData, useDominantColor, useHasBlurHash, useImageReveal, useProgressiveBlur, useProgressiveImage };
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 };