@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.
@@ -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
- srcSets: ""
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.placeholderUrl = placeholderIdentifier;
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.srcSets = srcSets.join(", ");
335
+ src.srcSet = srcSets.join(", ");
336
336
  }
337
- return `export default ${JSON.stringify(src)};`;
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;