@lonik/oh-image 2.1.2 → 2.2.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/dist/base-loader-options-C1EZVxmE.d.ts +13 -0
- package/dist/client.d.ts +29 -15
- package/dist/cloudflare.d.ts +40 -0
- package/dist/cloudflare.js +16 -0
- package/dist/cloudinary.d.ts +111 -0
- package/dist/cloudinary.js +76 -0
- package/dist/imgproxy.d.ts +376 -0
- package/dist/imgproxy.js +100 -0
- package/dist/index-DG8i2dGY.d.ts +80 -0
- package/dist/loader-factory-dkIeg239.js +101 -0
- package/dist/plugin.js +16 -5
- package/dist/react.d.ts +2 -504
- package/dist/react.js +19 -386
- package/package.json +19 -5
package/dist/imgproxy.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { t as loaderFactory } from "./loader-factory-dkIeg239.js";
|
|
2
|
+
|
|
3
|
+
//#region src/loaders/imgproxy/imgproxy-loader.tsx
|
|
4
|
+
const { useLoaderContext: useImgproxyContext, LoaderProvider: ImgproxyLoaderProvider, useLoader: useImgproxyLoader } = loaderFactory({
|
|
5
|
+
transforms: { format: "webp" },
|
|
6
|
+
placeholder: {
|
|
7
|
+
quality: 10,
|
|
8
|
+
format: "webp"
|
|
9
|
+
}
|
|
10
|
+
}, {
|
|
11
|
+
optionSeparator: ":",
|
|
12
|
+
paramSeparator: "/",
|
|
13
|
+
orders: {
|
|
14
|
+
resize: [
|
|
15
|
+
"resizing_type",
|
|
16
|
+
"width",
|
|
17
|
+
"height",
|
|
18
|
+
"enlarge",
|
|
19
|
+
"extend"
|
|
20
|
+
],
|
|
21
|
+
size: [
|
|
22
|
+
"width",
|
|
23
|
+
"height",
|
|
24
|
+
"enlarge",
|
|
25
|
+
"extend"
|
|
26
|
+
],
|
|
27
|
+
extend: ["extend", "gravity"],
|
|
28
|
+
gravity: [
|
|
29
|
+
"type",
|
|
30
|
+
"x_offset",
|
|
31
|
+
"y_offset"
|
|
32
|
+
],
|
|
33
|
+
crop: [
|
|
34
|
+
"width",
|
|
35
|
+
"height",
|
|
36
|
+
"gravity"
|
|
37
|
+
],
|
|
38
|
+
trim: [
|
|
39
|
+
"threshold",
|
|
40
|
+
"color",
|
|
41
|
+
"equal_hor",
|
|
42
|
+
"equal_ver"
|
|
43
|
+
],
|
|
44
|
+
padding: [
|
|
45
|
+
"top",
|
|
46
|
+
"right",
|
|
47
|
+
"bottom",
|
|
48
|
+
"left"
|
|
49
|
+
],
|
|
50
|
+
background: [
|
|
51
|
+
"r",
|
|
52
|
+
"g",
|
|
53
|
+
"b"
|
|
54
|
+
],
|
|
55
|
+
adjust: [
|
|
56
|
+
"brightness",
|
|
57
|
+
"contrast",
|
|
58
|
+
"saturation"
|
|
59
|
+
],
|
|
60
|
+
blur_detections: ["sigma", "class_names"],
|
|
61
|
+
draw_detections: ["draw", "class_names"],
|
|
62
|
+
watermark: [
|
|
63
|
+
"opacity",
|
|
64
|
+
"position",
|
|
65
|
+
"x_offset",
|
|
66
|
+
"y_offset",
|
|
67
|
+
"scale"
|
|
68
|
+
],
|
|
69
|
+
watermark_size: ["width", "height"],
|
|
70
|
+
unsharpening: [
|
|
71
|
+
"mode",
|
|
72
|
+
"weight",
|
|
73
|
+
"dividor"
|
|
74
|
+
],
|
|
75
|
+
autoquality: [
|
|
76
|
+
"method",
|
|
77
|
+
"target",
|
|
78
|
+
"min_quality",
|
|
79
|
+
"max_quality",
|
|
80
|
+
"allowed_error"
|
|
81
|
+
],
|
|
82
|
+
jpeg_options: [
|
|
83
|
+
"progressive",
|
|
84
|
+
"no_subsample",
|
|
85
|
+
"trellis_quant",
|
|
86
|
+
"overshoot_deringing",
|
|
87
|
+
"optimize_scans",
|
|
88
|
+
"quant_table"
|
|
89
|
+
],
|
|
90
|
+
png_options: [
|
|
91
|
+
"interlaced",
|
|
92
|
+
"quantize",
|
|
93
|
+
"quantization_colors"
|
|
94
|
+
],
|
|
95
|
+
zoom: ["x", "y"]
|
|
96
|
+
}
|
|
97
|
+
}, ({ path, params, imageOptions }) => `${path}/${params}/plain/${imageOptions.src}`);
|
|
98
|
+
|
|
99
|
+
//#endregion
|
|
100
|
+
export { ImgproxyLoaderProvider, useImgproxyContext, useImgproxyLoader };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ImgHTMLAttributes } from "react";
|
|
2
|
+
import * as react_jsx_runtime3 from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/react/types.d.ts
|
|
5
|
+
interface ImageLoaderOptions {
|
|
6
|
+
src: string;
|
|
7
|
+
width?: number | null | undefined;
|
|
8
|
+
height?: number | null | undefined;
|
|
9
|
+
isPlaceholder?: boolean;
|
|
10
|
+
}
|
|
11
|
+
type ImageLoader = (options: ImageLoaderOptions) => string | undefined;
|
|
12
|
+
interface ImageProps extends Partial<Pick<ImgHTMLAttributes<HTMLImageElement>, "fetchPriority" | "decoding" | "loading" | "srcSet" | "className" | "sizes" | "style">> {
|
|
13
|
+
/** Alternative text for the image, required for accessibility. Use an empty string for decorative images. */
|
|
14
|
+
alt: string;
|
|
15
|
+
/** Configures the Image component to load the image immediately. */
|
|
16
|
+
priority?: boolean;
|
|
17
|
+
/** */
|
|
18
|
+
src: string;
|
|
19
|
+
/** The URL of the placeholder image to display while loading. */
|
|
20
|
+
placeholder?: string | undefined | boolean | null;
|
|
21
|
+
/**
|
|
22
|
+
* Sets the image to "fill mode", which eliminates the height/width requirement and adds
|
|
23
|
+
* styles such that the image fills its containing element.
|
|
24
|
+
*/
|
|
25
|
+
fill?: boolean;
|
|
26
|
+
loader?: ImageLoader | null;
|
|
27
|
+
width?: number | undefined;
|
|
28
|
+
height?: number | undefined;
|
|
29
|
+
breakpoints?: number[];
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/react/image.d.ts
|
|
33
|
+
declare function Image(props: ImageProps): react_jsx_runtime3.JSX.Element;
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/react/image-factory.d.ts
|
|
36
|
+
declare function __imageFactory(defaultProps: any): (props: any) => react_jsx_runtime3.JSX.Element;
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/react/use-img-loaded.d.ts
|
|
39
|
+
/**
|
|
40
|
+
* A hook that tracks whether an image element has finished loading.
|
|
41
|
+
*
|
|
42
|
+
* Handles all edge cases:
|
|
43
|
+
* - Image already cached/complete on mount
|
|
44
|
+
* - Normal load via event listener
|
|
45
|
+
* - Errors (resets to `false`)
|
|
46
|
+
* - `src` changes (resets to `false` until the new source loads)
|
|
47
|
+
* - Element unmount / ref set to `null`
|
|
48
|
+
*
|
|
49
|
+
* @returns `[ref, isLoaded]` — attach the ref callback to an `<img>` element.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```tsx
|
|
53
|
+
* function Avatar({ src }: { src: string }) {
|
|
54
|
+
* const [imgRef, isLoaded] = useImgLoaded(src);
|
|
55
|
+
* return (
|
|
56
|
+
* <img
|
|
57
|
+
* ref={imgRef}
|
|
58
|
+
* src={src}
|
|
59
|
+
* style={{ opacity: isLoaded ? 1 : 0 }}
|
|
60
|
+
* />
|
|
61
|
+
* );
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
declare function useImgLoaded(src: string | undefined): [(img: HTMLImageElement | null) => void, boolean];
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/react/image-context.d.ts
|
|
68
|
+
interface ImageContextValue extends Pick<ImageProps, "placeholder" | "breakpoints" | "loader"> {
|
|
69
|
+
breakpoints: number[];
|
|
70
|
+
loader: ImageLoader | null;
|
|
71
|
+
}
|
|
72
|
+
declare function useImageContext(): ImageContextValue;
|
|
73
|
+
declare function ImageProvider({
|
|
74
|
+
children,
|
|
75
|
+
...props
|
|
76
|
+
}: {
|
|
77
|
+
children: React.ReactNode;
|
|
78
|
+
} & Partial<ImageContextValue>): react_jsx_runtime3.JSX.Element;
|
|
79
|
+
//#endregion
|
|
80
|
+
export { Image as a, ImageProps as c, __imageFactory as i, useImageContext as n, ImageLoader as o, useImgLoaded as r, ImageLoaderOptions as s, ImageProvider as t };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/loaders/transforms-resolver.ts
|
|
5
|
+
const stringifyOptions = (opCode, values, separator) => {
|
|
6
|
+
return [opCode, ...values.map((v) => v == null ? "" : encodeURIComponent(v))].join(separator);
|
|
7
|
+
};
|
|
8
|
+
const resolveObjectParam = (key, value, order, separator) => {
|
|
9
|
+
if (!order) return;
|
|
10
|
+
return stringifyOptions(key, order.map((k) => value[k]), separator);
|
|
11
|
+
};
|
|
12
|
+
function resolveTransform(transforms, config) {
|
|
13
|
+
if (!transforms) return [];
|
|
14
|
+
const params = [];
|
|
15
|
+
for (const key of Object.keys(transforms)) {
|
|
16
|
+
const value = transforms[key];
|
|
17
|
+
if (value === void 0) continue;
|
|
18
|
+
const type = typeof value;
|
|
19
|
+
if (config.customResolver) {
|
|
20
|
+
const resolverFn = config.customResolver[key];
|
|
21
|
+
if (resolverFn) {
|
|
22
|
+
const resolvedValue = resolverFn(key, value);
|
|
23
|
+
if (resolvedValue !== void 0) params.push(resolvedValue);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
switch (type) {
|
|
28
|
+
case "boolean":
|
|
29
|
+
if (value === true) params.push(key);
|
|
30
|
+
break;
|
|
31
|
+
case "object": {
|
|
32
|
+
const objectParams = resolveObjectParam(key, value, config?.orders?.[key], config.optionSeparator);
|
|
33
|
+
if (objectParams) params.push(objectParams);
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
default:
|
|
37
|
+
params.push(stringifyOptions(key, [value], config.optionSeparator));
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return params;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/loaders/loader-factory.tsx
|
|
46
|
+
function loaderFactory(defaults, config, urlResolver) {
|
|
47
|
+
const loaderContext = createContext(defaults);
|
|
48
|
+
function useLoaderContext() {
|
|
49
|
+
return useContext(loaderContext);
|
|
50
|
+
}
|
|
51
|
+
function LoaderProvider({ children, ...props }) {
|
|
52
|
+
const ctx = useLoaderContext();
|
|
53
|
+
return /* @__PURE__ */ jsx(loaderContext.Provider, {
|
|
54
|
+
value: {
|
|
55
|
+
...ctx,
|
|
56
|
+
...props
|
|
57
|
+
},
|
|
58
|
+
children
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const loader = () => (options) => {
|
|
62
|
+
const context = useLoaderContext();
|
|
63
|
+
const path = options?.path || context.path;
|
|
64
|
+
if (!path) {
|
|
65
|
+
console.warn("Path is not provided");
|
|
66
|
+
return () => void 0;
|
|
67
|
+
}
|
|
68
|
+
return (imageOptions) => {
|
|
69
|
+
const defaultTransform = imageOptions.isPlaceholder ? context.placeholder : context.transforms;
|
|
70
|
+
const optionTransforms = imageOptions.isPlaceholder ? options?.placeholder : options?.transforms;
|
|
71
|
+
const transforms = {
|
|
72
|
+
...defaultTransform,
|
|
73
|
+
...optionTransforms
|
|
74
|
+
};
|
|
75
|
+
const params = [];
|
|
76
|
+
if (imageOptions.width) {
|
|
77
|
+
const widthKey = config.widthKey ?? "width";
|
|
78
|
+
params.push(widthKey + config.optionSeparator + imageOptions.width);
|
|
79
|
+
}
|
|
80
|
+
if (imageOptions.height) {
|
|
81
|
+
const heightKey = config.heightKey ?? "height";
|
|
82
|
+
params.push(heightKey + config.optionSeparator + imageOptions.height);
|
|
83
|
+
}
|
|
84
|
+
const resolvedTransforms = resolveTransform(transforms, config);
|
|
85
|
+
return urlResolver({
|
|
86
|
+
imageOptions,
|
|
87
|
+
params: [...params, ...resolvedTransforms].join(config.paramSeparator),
|
|
88
|
+
path
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
LoaderProvider,
|
|
94
|
+
loaderContext,
|
|
95
|
+
useLoaderContext,
|
|
96
|
+
useLoader: loader()
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
//#endregion
|
|
101
|
+
export { loaderFactory as t };
|
package/dist/plugin.js
CHANGED
|
@@ -202,7 +202,7 @@ const DEFAULT_CONFIGS = {
|
|
|
202
202
|
format: "webp",
|
|
203
203
|
placeholder: true
|
|
204
204
|
};
|
|
205
|
-
const PROCESS_KEY = "oh";
|
|
205
|
+
const PROCESS_KEY = "$oh";
|
|
206
206
|
const SUPPORTED_IMAGE_FORMATS = /\.(jpe?g|png|webp|avif|gif|svg)(\?.*)?$/i;
|
|
207
207
|
const DEV_DIR = "/@oh-images/";
|
|
208
208
|
function ohImage(options) {
|
|
@@ -290,7 +290,7 @@ function ohImage(options) {
|
|
|
290
290
|
width: metadata.width,
|
|
291
291
|
height: metadata.height,
|
|
292
292
|
src: mainIdentifier,
|
|
293
|
-
|
|
293
|
+
srcSet: ""
|
|
294
294
|
};
|
|
295
295
|
if (mergedOptions.placeholder) {
|
|
296
296
|
const placeholderIdentifier = identifier.placeholder(DEFAULT_IMAGE_FORMAT);
|
|
@@ -309,7 +309,7 @@ function ohImage(options) {
|
|
|
309
309
|
normalize: mergedOptions.normalize,
|
|
310
310
|
threshold: mergedOptions.threshold
|
|
311
311
|
});
|
|
312
|
-
src.
|
|
312
|
+
src.placeholder = placeholderIdentifier;
|
|
313
313
|
}
|
|
314
314
|
if (mergedOptions.breakpoints) {
|
|
315
315
|
const srcSets = [];
|
|
@@ -332,9 +332,20 @@ function ohImage(options) {
|
|
|
332
332
|
});
|
|
333
333
|
srcSets.push(`${srcSetIdentifier} ${breakpoint}w`);
|
|
334
334
|
}
|
|
335
|
-
src.
|
|
335
|
+
src.srcSet = srcSets.join(", ");
|
|
336
336
|
}
|
|
337
|
-
return `
|
|
337
|
+
return `
|
|
338
|
+
import { __imageFactory } from "@lonik/oh-image/react";
|
|
339
|
+
|
|
340
|
+
export default __imageFactory(${JSON.stringify({
|
|
341
|
+
width: src.width,
|
|
342
|
+
height: src.height,
|
|
343
|
+
src: src.src,
|
|
344
|
+
srcSet: src.srcSet,
|
|
345
|
+
placeholder: src.placeholder,
|
|
346
|
+
alt: ""
|
|
347
|
+
})})
|
|
348
|
+
`;
|
|
338
349
|
} catch (err) {
|
|
339
350
|
console.error(`Couldn't load image with id: ${id} error:${err}`);
|
|
340
351
|
return null;
|