@place-framework/place-block-image 1.0.1 → 1.0.3

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 (48) hide show
  1. package/dist/constants/index.d.ts +2 -2
  2. package/dist/constants/index.d.ts.map +1 -1
  3. package/dist/constants/index.js +4 -5
  4. package/dist/constants/index.js.map +1 -1
  5. package/dist/generate-components.d.ts +16 -0
  6. package/dist/generate-components.d.ts.map +1 -0
  7. package/dist/generate-components.js +93 -0
  8. package/dist/generate-components.js.map +1 -0
  9. package/dist/react/PlaceBlockImage.cjs +1 -0
  10. package/dist/react/PlaceBlockImage.js +67 -0
  11. package/dist/templates/shared/index.d.ts.map +1 -1
  12. package/dist/templates/shared/index.js +8 -16
  13. package/dist/templates/shared/index.js.map +1 -1
  14. package/dist/templates/shared/vue.d.ts +6 -0
  15. package/dist/templates/shared/vue.d.ts.map +1 -0
  16. package/dist/templates/shared/vue.js +26 -0
  17. package/dist/templates/shared/vue.js.map +1 -0
  18. package/dist/templates/vue.d.ts.map +1 -1
  19. package/dist/templates/vue.js +14 -19
  20. package/dist/templates/vue.js.map +1 -1
  21. package/dist/utils/index.d.ts +61 -14
  22. package/dist/utils/index.d.ts.map +1 -1
  23. package/dist/utils/index.js +108 -40
  24. package/dist/utils/index.js.map +1 -1
  25. package/dist/vue/PlaceBlockImage.cjs +1 -0
  26. package/dist/vue/PlaceBlockImage.js +83 -0
  27. package/dist/webpack-plugin.d.ts +20 -7
  28. package/dist/webpack-plugin.d.ts.map +1 -1
  29. package/dist/webpack-plugin.js +22 -28
  30. package/dist/webpack-plugin.js.map +1 -1
  31. package/package.json +36 -10
  32. package/src/constants/index.ts +5 -6
  33. package/src/react/PlaceBlockImage.tsx +63 -0
  34. package/src/react/index.ts +1 -0
  35. package/src/utils/index.ts +121 -44
  36. package/src/vue/PlaceBlockImage.vue +98 -0
  37. package/src/vue/index.ts +1 -0
  38. package/src/webpack-plugin.ts +45 -40
  39. package/tsconfig.json +8 -3
  40. package/vite.config.mts +27 -0
  41. package/vite.react.config.mts +25 -0
  42. package/vite.vue.config.mts +26 -0
  43. package/src/templates/react-jsx.ts +0 -27
  44. package/src/templates/react-tsx.ts +0 -33
  45. package/src/templates/shared/index.ts +0 -47
  46. package/src/templates/shared/react.ts +0 -51
  47. package/src/templates/vue.ts +0 -98
  48. package/src/templates.ts +0 -29
@@ -1,8 +1,8 @@
1
+ export declare const IMAGE_PREFIX = "image-";
1
2
  export declare const CLASS_NAMES: {
2
3
  readonly LAZY: "lazy";
3
4
  readonly LOADED: "loaded";
4
- readonly IMAGE_WRAPPER: "image-wrapper";
5
- readonly IMAGE_BLOCK: "image-block";
5
+ readonly WRAPPER_SUFFIX: "wrapper";
6
6
  };
7
7
  export declare const getWrapperClassName: (imagePrefix: string) => string;
8
8
  export declare const getImageClassName: (imagePrefix: string, filename: string) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW;;;;;CAUd,CAAC;AAEX,eAAO,MAAM,mBAAmB,GAAI,aAAa,MAAM,WAA4B,CAAC;AACpF,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,EAAE,UAAU,MAAM,WAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC,eAAO,MAAM,WAAW;;;;CAOd,CAAC;AAEX,eAAO,MAAM,mBAAmB,GAAI,aAAa,MAAM,WAA4B,CAAC;AACpF,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,EAAE,UAAU,MAAM,WAAgC,CAAC"}
@@ -1,14 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getImageClassName = exports.getWrapperClassName = exports.CLASS_NAMES = void 0;
3
+ exports.getImageClassName = exports.getWrapperClassName = exports.CLASS_NAMES = exports.IMAGE_PREFIX = void 0;
4
+ exports.IMAGE_PREFIX = 'image-';
4
5
  exports.CLASS_NAMES = {
5
6
  // Lazy loading states
6
7
  LAZY: 'lazy',
7
8
  LOADED: 'loaded',
8
- // Wrapper classes
9
- IMAGE_WRAPPER: 'image-wrapper',
10
- // Base image class
11
- IMAGE_BLOCK: 'image-block'
9
+ // Suffix appended to imagePrefix to form the wrapper class (e.g. 'image-wrapper')
10
+ WRAPPER_SUFFIX: 'wrapper',
12
11
  };
13
12
  const getWrapperClassName = (imagePrefix) => `${imagePrefix}wrapper`;
14
13
  exports.getWrapperClassName = getWrapperClassName;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":";;;AAAa,QAAA,WAAW,GAAG;IACzB,sBAAsB;IACtB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAEhB,kBAAkB;IAClB,aAAa,EAAE,eAAe;IAE9B,mBAAmB;IACnB,WAAW,EAAE,aAAa;CAClB,CAAC;AAEJ,MAAM,mBAAmB,GAAG,CAAC,WAAmB,EAAE,EAAE,CAAC,GAAG,WAAW,SAAS,CAAC;AAAvE,QAAA,mBAAmB,uBAAoD;AAC7E,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAE,QAAgB,EAAE,EAAE,CAAC,GAAG,WAAW,GAAG,QAAQ,EAAE,CAAC;AAA3F,QAAA,iBAAiB,qBAA0E"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":";;;AAAa,QAAA,YAAY,GAAG,QAAQ,CAAC;AAExB,QAAA,WAAW,GAAG;IACzB,sBAAsB;IACtB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAEhB,kFAAkF;IAClF,cAAc,EAAE,SAAS;CACjB,CAAC;AAEJ,MAAM,mBAAmB,GAAG,CAAC,WAAmB,EAAE,EAAE,CAAC,GAAG,WAAW,SAAS,CAAC;AAAvE,QAAA,mBAAmB,uBAAoD;AAC7E,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAE,QAAgB,EAAE,EAAE,CAAC,GAAG,WAAW,GAAG,QAAQ,EAAE,CAAC;AAA3F,QAAA,iBAAiB,qBAA0E"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Generates Vue and React component source files from templates.
3
+ *
4
+ * Usage:
5
+ * node dist/generate-components.js [imagePrefix]
6
+ *
7
+ * imagePrefix defaults to 'image-' if not provided.
8
+ * The webpack plugin calls this automatically with the configured imagePrefix.
9
+ *
10
+ * Generated files are written to src/vue/ and src/react/ so they are
11
+ * shipped as source and consumers can import directly:
12
+ * import { PlaceBlockImage } from '@place-framework/place-block-image/vue'
13
+ * import { PlaceBlockImage } from '@place-framework/place-block-image/react'
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=generate-components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-components.d.ts","sourceRoot":"","sources":["../src/generate-components.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ /**
3
+ * Generates Vue and React component source files from templates.
4
+ *
5
+ * Usage:
6
+ * node dist/generate-components.js [imagePrefix]
7
+ *
8
+ * imagePrefix defaults to 'image-' if not provided.
9
+ * The webpack plugin calls this automatically with the configured imagePrefix.
10
+ *
11
+ * Generated files are written to src/vue/ and src/react/ so they are
12
+ * shipped as source and consumers can import directly:
13
+ * import { PlaceBlockImage } from '@place-framework/place-block-image/vue'
14
+ * import { PlaceBlockImage } from '@place-framework/place-block-image/react'
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || (function () {
33
+ var ownKeys = function(o) {
34
+ ownKeys = Object.getOwnPropertyNames || function (o) {
35
+ var ar = [];
36
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
+ return ar;
38
+ };
39
+ return ownKeys(o);
40
+ };
41
+ return function (mod) {
42
+ if (mod && mod.__esModule) return mod;
43
+ var result = {};
44
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
+ __setModuleDefault(result, mod);
46
+ return result;
47
+ };
48
+ })();
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ const fs = __importStar(require("fs"));
51
+ const path = __importStar(require("path"));
52
+ const vue_1 = require("./templates/vue");
53
+ const react_tsx_1 = require("./templates/react-tsx");
54
+ const imagePrefix = process.argv[2] || 'image-';
55
+ const frameworks = [
56
+ {
57
+ name: 'vue',
58
+ dir: path.resolve(__dirname, '../src/vue'),
59
+ files: [
60
+ {
61
+ filename: 'PlaceBlockImage.vue',
62
+ content: () => (0, vue_1.getVueTemplate)(imagePrefix),
63
+ },
64
+ {
65
+ filename: 'index.ts',
66
+ content: () => `export { default as PlaceBlockImage } from './PlaceBlockImage.vue';\n`,
67
+ },
68
+ ],
69
+ },
70
+ {
71
+ name: 'react',
72
+ dir: path.resolve(__dirname, '../src/react'),
73
+ files: [
74
+ {
75
+ filename: 'PlaceBlockImage.tsx',
76
+ content: () => (0, react_tsx_1.getReactTsxTemplate)(imagePrefix),
77
+ },
78
+ {
79
+ filename: 'index.ts',
80
+ content: () => `export { PlaceBlockImage, default } from './PlaceBlockImage';\n`,
81
+ },
82
+ ],
83
+ },
84
+ ];
85
+ for (const framework of frameworks) {
86
+ fs.mkdirSync(framework.dir, { recursive: true });
87
+ for (const file of framework.files) {
88
+ const filePath = path.join(framework.dir, file.filename);
89
+ fs.writeFileSync(filePath, file.content(), 'utf-8');
90
+ console.log(`✅ Generated src/${framework.name}/${file.filename}`);
91
+ }
92
+ }
93
+ //# sourceMappingURL=generate-components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-components.js","sourceRoot":"","sources":["../src/generate-components.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,uCAAyB;AACzB,2CAA6B;AAC7B,yCAAiD;AACjD,qDAA4D;AAE5D,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC;AAEhD,MAAM,UAAU,GAAG;IACjB;QACE,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC;QAC1C,KAAK,EAAE;YACL;gBACE,QAAQ,EAAE,qBAAqB;gBAC/B,OAAO,EAAE,GAAG,EAAE,CAAC,IAAA,oBAAc,EAAC,WAAW,CAAC;aAC3C;YACD;gBACE,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,GAAG,EAAE,CAAC,uEAAuE;aACvF;SACF;KACF;IACD;QACE,IAAI,EAAE,OAAO;QACb,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC;QAC5C,KAAK,EAAE;YACL;gBACE,QAAQ,EAAE,qBAAqB;gBAC/B,OAAO,EAAE,GAAG,EAAE,CAAC,IAAA,+BAAmB,EAAC,WAAW,CAAC;aAChD;YACD;gBACE,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,GAAG,EAAE,CAAC,iEAAiE;aACjF;SACF;KACF;CACF,CAAC;AAEF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;IACnC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEjD,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,mBAAmB,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("react"),E="image-",o={LAZY:"lazy",LOADED:"loaded",WRAPPER_SUFFIX:"wrapper"},I=e=>e.replace(/^https?:\/\/[^/]+/,"").replace(/^[/\\]+/,"").replace(/\.[^/.]+$/,"").toLowerCase().replace(/[^a-z0-9/-]/g,"-").replace(/\//g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");function d(e,t){return t?e.replace(new RegExp(`^${t.replace(/\//g,"\\/")}\\/?`),""):e}function L(e,t,n){return e?`${t}${I(d(e,n))}`:""}function P(e,t,n,r=""){return[`${t}${o.WRAPPER_SUFFIX}`,L(e,t,n),r].filter(Boolean).join(" ")}function v(e,t){return e?t?`${o.LAZY} ${o.LOADED}`:o.LAZY:""}function R(e,t,n=.1){const r=new IntersectionObserver(s=>{s.forEach(c=>{c.isIntersecting&&(t(),r.unobserve(c.target))})},{threshold:n});return r.observe(e),r}const i=({src:e,alt:t,imagePrefix:n=E,lazy:r=!1,className:s="",...c})=>{const u=a.useRef(null),[g,p]=a.useState(r?"":e),[l,f]=a.useState(!r),_=typeof __PLUGIN_ASSET_PATH__<"u"?__PLUGIN_ASSET_PATH__:"";a.useEffect(()=>{if(!r||l||!u.current)return;const S=R(u.current,()=>{p(e),f(!0)});return()=>S.disconnect()},[e,r,l]);const m=P(e,n,_,s),A=v(r,l);return a.createElement("picture",{className:m},a.createElement("img",{ref:u,src:g,alt:t,className:A,...c}))};exports.PlaceBlockImage=i;exports.default=i;
@@ -0,0 +1,67 @@
1
+ import l, { useRef as I, useState as i, useEffect as L } from "react";
2
+ const S = "image-", c = {
3
+ // Lazy loading states
4
+ LAZY: "lazy",
5
+ LOADED: "loaded",
6
+ // Suffix appended to imagePrefix to form the wrapper class (e.g. 'image-wrapper')
7
+ WRAPPER_SUFFIX: "wrapper"
8
+ }, P = (e) => e.replace(/^https?:\/\/[^/]+/, "").replace(/^[/\\]+/, "").replace(/\.[^/.]+$/, "").toLowerCase().replace(/[^a-z0-9/-]/g, "-").replace(/\//g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
9
+ function d(e, t) {
10
+ return t ? e.replace(new RegExp(`^${t.replace(/\//g, "\\/")}\\/?`), "") : e;
11
+ }
12
+ function R(e, t, n) {
13
+ return e ? `${t}${P(d(e, n))}` : "";
14
+ }
15
+ function $(e, t, n, r = "") {
16
+ return [
17
+ `${t}${c.WRAPPER_SUFFIX}`,
18
+ R(e, t, n),
19
+ r
20
+ ].filter(Boolean).join(" ");
21
+ }
22
+ function v(e, t) {
23
+ return e ? t ? `${c.LAZY} ${c.LOADED}` : c.LAZY : "";
24
+ }
25
+ function C(e, t, n = 0.1) {
26
+ const r = new IntersectionObserver(
27
+ (a) => {
28
+ a.forEach((s) => {
29
+ s.isIntersecting && (t(), r.unobserve(s.target));
30
+ });
31
+ },
32
+ { threshold: n }
33
+ );
34
+ return r.observe(e), r;
35
+ }
36
+ const b = ({
37
+ src: e,
38
+ alt: t,
39
+ imagePrefix: n = S,
40
+ lazy: r = !1,
41
+ className: a = "",
42
+ ...s
43
+ }) => {
44
+ const o = I(null), [p, f] = i(r ? "" : e), [u, g] = i(!r), m = typeof __PLUGIN_ASSET_PATH__ < "u" ? __PLUGIN_ASSET_PATH__ : "";
45
+ L(() => {
46
+ if (!r || u || !o.current) return;
47
+ const E = C(o.current, () => {
48
+ f(e), g(!0);
49
+ });
50
+ return () => E.disconnect();
51
+ }, [e, r, u]);
52
+ const _ = $(e, n, m, a), A = v(r, u);
53
+ return /* @__PURE__ */ l.createElement("picture", { className: _ }, /* @__PURE__ */ l.createElement(
54
+ "img",
55
+ {
56
+ ref: o,
57
+ src: p,
58
+ alt: t,
59
+ className: A,
60
+ ...s
61
+ }
62
+ ));
63
+ };
64
+ export {
65
+ b as PlaceBlockImage,
66
+ b as default
67
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/shared/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM;;;;CA4CnD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/shared/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM;;;;CAmCnD,CAAC"}
@@ -2,35 +2,27 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getSharedTemplate = void 0;
4
4
  const constants_1 = require("../../constants");
5
+ const utils_1 = require("../../utils");
5
6
  const getSharedTemplate = (imagePrefix) => ({
6
7
  // Common comment block
7
8
  comment: `/**
8
9
  * PlaceBlockImage component that prevents layout shift using CSS custom properties
9
10
  * Generated by place-block-image webpack plugin
10
- *
11
+ *
11
12
  * Usage:
12
13
  * <PlaceBlockImage src="/images/logo.svg" alt="Logo" />
13
14
  * <PlaceBlockImage src="/images/hero.jpg" alt="Hero" lazy={true} />
14
- *
15
+ *
15
16
  * This will automatically apply:
16
17
  * - .${imagePrefix}wrapper class on picture (for dimensions)
17
18
  * - .${imagePrefix}logo class on picture (specific dimensions via CSS custom properties)
18
19
  * - ${constants_1.CLASS_NAMES.LAZY}/${constants_1.CLASS_NAMES.LAZY}.${constants_1.CLASS_NAMES.LOADED} classes for lazy loading states
19
20
  */`,
20
- // Common filename extraction logic (as string for interpolation)
21
- getImageClassNameTemplate: `// Extract filename from src to generate class name
22
- const getImageClassName = (imageSrc: string): string => {
23
- // Remove /images/ prefix and file extension, convert to kebab-case
24
- const filename = imageSrc
25
- .replace(/^.*\\/images\\//, '') // Remove path up to /images/
26
- .replace(/\\.[^/.]+$/, '') // Remove file extension
27
- .toLowerCase()
28
- .replace(/[^a-z0-9-]/g, '-') // Convert special chars to hyphens
29
- .replace(/-+/g, '-') // Remove duplicate hyphens
30
- .replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
31
-
32
- return \`${imagePrefix}\${filename}\`;
33
- };`,
21
+ // Serialises cleanImagePath from utils so the generated component uses the
22
+ // exact same function single source of truth, no duplicated regex.
23
+ getImageClassNameTemplate: `// Serialised from cleanImagePath in utils/index.ts — single source of truth.
24
+ const cleanImagePath = ${utils_1.cleanImagePath.toString()};
25
+ const getImageClassName = (imageSrc) => imageSrc ? \`${imagePrefix}\${cleanImagePath(imageSrc)}\` : '';`,
34
26
  // Common intersection observer logic
35
27
  intersectionObserverTemplate: `const observer = new IntersectionObserver(
36
28
  (entries) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/shared/index.ts"],"names":[],"mappings":";;;AAAA,+CAA8C;AAEvC,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAE,EAAE,CAAC,CAAC;IACzD,uBAAuB;IACvB,OAAO,EAAE;;;;;;;;;QASH,WAAW;QACX,WAAW;OACZ,uBAAW,CAAC,IAAI,IAAI,uBAAW,CAAC,IAAI,IAAI,uBAAW,CAAC,MAAM;IAC7D;IAEF,iEAAiE;IACjE,yBAAyB,EAAE;;;;;;;;;;;eAWd,WAAW;KACrB;IAEH,qCAAqC;IACrC,4BAA4B,EAAE;;;;;;;;;;;OAWzB;CACN,CAAC,CAAC;AA5CU,QAAA,iBAAiB,qBA4C3B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/shared/index.ts"],"names":[],"mappings":";;;AAAA,+CAA8C;AAC9C,uCAA6C;AAEtC,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAE,EAAE,CAAC,CAAC;IACzD,uBAAuB;IACvB,OAAO,EAAE;;;;;;;;;QASH,WAAW;QACX,WAAW;OACZ,uBAAW,CAAC,IAAI,IAAI,uBAAW,CAAC,IAAI,IAAI,uBAAW,CAAC,MAAM;IAC7D;IAEF,2EAA2E;IAC3E,qEAAqE;IACrE,yBAAyB,EAAE;2BACF,sBAAc,CAAC,QAAQ,EAAE;yDACK,WAAW,sCAAsC;IAExG,qCAAqC;IACrC,4BAA4B,EAAE;;;;;;;;;;;OAWzB;CACN,CAAC,CAAC;AAnCU,QAAA,iBAAiB,qBAmC3B"}
@@ -0,0 +1,6 @@
1
+ export declare const getSharedVueTemplate: (imagePrefix: string) => {
2
+ comment: string;
3
+ getImageClassName: string;
4
+ intersectionObserverTemplate: string;
5
+ };
6
+ //# sourceMappingURL=vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../../../src/templates/shared/vue.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,GAAI,aAAa,MAAM;;;;CAsBvD,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSharedVueTemplate = void 0;
4
+ const index_1 = require("./index");
5
+ const getSharedVueTemplate = (imagePrefix) => {
6
+ const shared = (0, index_1.getSharedTemplate)(imagePrefix);
7
+ return {
8
+ comment: shared.comment,
9
+ getImageClassName: shared.getImageClassNameTemplate,
10
+ // Vue Composition API intersection observer - uses refs instead of React state setters
11
+ intersectionObserverTemplate: `observer = new IntersectionObserver(
12
+ (entries) => {
13
+ entries.forEach((entry) => {
14
+ if (entry.isIntersecting) {
15
+ imageSrc.value = props.src;
16
+ isLoaded.value = true;
17
+ observer?.unobserve(entry.target);
18
+ }
19
+ });
20
+ },
21
+ { threshold: 0.1 }
22
+ );`,
23
+ };
24
+ };
25
+ exports.getSharedVueTemplate = getSharedVueTemplate;
26
+ //# sourceMappingURL=vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.js","sourceRoot":"","sources":["../../../src/templates/shared/vue.ts"],"names":[],"mappings":";;;AAAA,mCAA4C;AAErC,MAAM,oBAAoB,GAAG,CAAC,WAAmB,EAAE,EAAE;IAC1D,MAAM,MAAM,GAAG,IAAA,yBAAiB,EAAC,WAAW,CAAC,CAAC;IAE9C,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QAEvB,iBAAiB,EAAE,MAAM,CAAC,yBAAyB;QAEnD,uFAAuF;QACvF,4BAA4B,EAAE;;;;;;;;;;;OAW3B;KACJ,CAAC;AACJ,CAAC,CAAC;AAtBW,QAAA,oBAAoB,wBAsB/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../../src/templates/vue.ts"],"names":[],"mappings":"AAGA,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA8F1D"}
1
+ {"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../../src/templates/vue.ts"],"names":[],"mappings":"AAGA,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAyF1D"}
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getVueTemplate = getVueTemplate;
4
- const shared_1 = require("./shared/");
4
+ const vue_1 = require("./shared/vue");
5
5
  const constants_1 = require("../constants");
6
6
  function getVueTemplate(imagePrefix) {
7
- const shared = (0, shared_1.getSharedTemplate)(imagePrefix);
7
+ const shared = (0, vue_1.getSharedVueTemplate)(imagePrefix);
8
8
  return `<template>
9
9
  <picture :class="wrapperClassName">
10
10
  <img
@@ -17,40 +17,35 @@ function getVueTemplate(imagePrefix) {
17
17
  </picture>
18
18
  </template>
19
19
 
20
- <script setup lang="ts">
20
+ <script setup>
21
21
  import { computed, ref, onMounted, onUnmounted, watch } from 'vue';
22
22
 
23
- interface Props {
24
- src: string;
25
- alt: string;
26
- lazy?: boolean;
27
- class?: string;
28
- }
29
-
30
- const props = withDefaults(defineProps<Props>(), {
31
- lazy: false,
32
- class: ''
23
+ const props = defineProps({
24
+ src: { type: String, required: true },
25
+ alt: { type: String, required: true },
26
+ lazy: { type: Boolean, default: false },
27
+ class: { type: String, default: '' }
33
28
  });
34
29
 
35
30
  ${shared.comment}
36
31
 
37
- const imgRef = ref<HTMLImageElement | null>(null);
32
+ const imgRef = ref(null);
38
33
  const imageSrc = ref(props.lazy ? '' : props.src);
39
34
  const isLoaded = ref(!props.lazy);
40
- let observer: IntersectionObserver | null = null;
35
+ let observer = null;
41
36
 
42
- ${shared.getImageClassNameTemplate}
37
+ ${shared.getImageClassName}
43
38
 
44
39
  const imageClassName = computed(() => getImageClassName(props.src));
45
- const wrapperClassName = computed(() =>
40
+ const wrapperClassName = computed(() =>
46
41
  \`${imagePrefix}wrapper \${imageClassName.value}\`
47
42
  );
48
43
 
49
- const lazyClass = computed(() =>
44
+ const lazyClass = computed(() =>
50
45
  props.lazy ? (isLoaded.value ? '${constants_1.CLASS_NAMES.LAZY} ${constants_1.CLASS_NAMES.LOADED}' : '${constants_1.CLASS_NAMES.LAZY}') : ''
51
46
  );
52
47
 
53
- const imgClassName = computed(() =>
48
+ const imgClassName = computed(() =>
54
49
  \`\${props.class} \${lazyClass.value}\`.trim()
55
50
  );
56
51
 
@@ -1 +1 @@
1
- {"version":3,"file":"vue.js","sourceRoot":"","sources":["../../src/templates/vue.ts"],"names":[],"mappings":";;AAGA,wCA8FC;AAjGD,sCAA8C;AAC9C,4CAA2C;AAE3C,SAAgB,cAAc,CAAC,WAAmB;IAChD,MAAM,MAAM,GAAG,IAAA,0BAAiB,EAAC,WAAW,CAAC,CAAC;IAE9C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BP,MAAM,CAAC,OAAO;;;;;;;EAOd,MAAM,CAAC,yBAAyB;;;;MAI5B,WAAW;;;;oCAImB,uBAAW,CAAC,IAAI,IAAI,uBAAW,CAAC,MAAM,QAAQ,uBAAW,CAAC,IAAI;;;;;;;;;;IAU9F,MAAM,CAAC,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCtC,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"vue.js","sourceRoot":"","sources":["../../src/templates/vue.ts"],"names":[],"mappings":";;AAGA,wCAyFC;AA5FD,sCAAoD;AACpD,4CAA2C;AAE3C,SAAgB,cAAc,CAAC,WAAmB;IAChD,MAAM,MAAM,GAAG,IAAA,0BAAoB,EAAC,WAAW,CAAC,CAAC;IAEjD,OAAO;;;;;;;;;;;;;;;;;;;;;;EAsBP,MAAM,CAAC,OAAO;;;;;;;EAOd,MAAM,CAAC,iBAAiB;;;;MAIpB,WAAW;;;;oCAImB,uBAAW,CAAC,IAAI,IAAI,uBAAW,CAAC,MAAM,QAAQ,uBAAW,CAAC,IAAI;;;;;;;;;;IAU9F,MAAM,CAAC,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCtC,CAAC;AACF,CAAC"}
@@ -1,15 +1,62 @@
1
- export interface TemplateData {
2
- imagePrefix: string;
3
- baseClassName: string;
4
- wrapperClassName: string;
5
- }
6
- export declare function getTemplateData(imagePrefix: string): TemplateData;
7
- /**
8
- * Generate CSS class name from file path - shared logic for both webpack plugin and templates
9
- * @param filePath - The file path (can be relative path from images dir or full path)
10
- * @param imagePrefix - The prefix to add to the class name
11
- * @returns The generated CSS class name
12
- */
13
- export declare function generateImageClassName(filePath: string, imagePrefix: string): string;
14
- export declare function getSharedLogic(imagePrefix: string): string;
1
+ /**
2
+ * Converts any image URL or path into a CSS-safe kebab-case string.
3
+ * Used at build time by generateImageClassName() and at runtime by
4
+ * the Vue/React components to derive the CSS class from the src prop.
5
+ */
6
+ export declare const cleanImagePath: (src: string) => string;
7
+ /**
8
+ * Generate CSS class name from a file path — path-agnostic, works with any URL format.
9
+ * Matches the runtime getImageClassName logic emitted by getSharedLogic().
10
+ *
11
+ * @param filePath - Relative path from imageDir (e.g. "story/accent-orchid.png")
12
+ * @param imagePrefix - The prefix to add to the class name (e.g. "image-")
13
+ * @param outputPrefix - Optional output path prefix prepended before filePath to mirror
14
+ * the served URL (e.g. "images/" when assetModuleFilename outputs
15
+ * to "images/…" so the browser requests "/images/story/…")
16
+ * @returns The generated CSS class name (e.g. "image-images-story-accent-orchid")
17
+ */
18
+ export declare function generateImageClassName(filePath: string, imagePrefix: string, outputPrefix?: string): string;
19
+ /**
20
+ * Strips the Vite/webpack plugin's injected asset-path prefix from a src string
21
+ * so the remaining path matches what the plugin used when generating CSS classes.
22
+ *
23
+ * @param src - The raw src value (may include the asset path prefix)
24
+ * @param assetPath - The value of __PLUGIN_ASSET_PATH__ (empty string if undefined)
25
+ */
26
+ export declare function resolveAssetPath(src: string, assetPath: string): string;
27
+ /**
28
+ * Derives the per-image CSS class from a src URL, stripping the asset-path
29
+ * prefix first so the class matches what the plugin generated at build time.
30
+ *
31
+ * @param src - Raw src prop value
32
+ * @param imagePrefix - e.g. "image-"
33
+ * @param assetPath - Value of __PLUGIN_ASSET_PATH__ (pass '' if not defined)
34
+ */
35
+ export declare function getImageClass(src: string, imagePrefix: string, assetPath: string): string;
36
+ /**
37
+ * Builds the full className string for the <picture> wrapper element.
38
+ *
39
+ * @param src - Raw src prop value
40
+ * @param imagePrefix - e.g. "image-"
41
+ * @param assetPath - Value of __PLUGIN_ASSET_PATH__ (pass '' if not defined)
42
+ * @param extraClass - Any additional class(es) passed by the consumer (e.g. className prop)
43
+ */
44
+ export declare function getWrapperClass(src: string, imagePrefix: string, assetPath: string, extraClass?: string): string;
45
+ /**
46
+ * Returns the CSS class string for the <img> element based on lazy-load state.
47
+ *
48
+ * @param lazy - Whether lazy loading is enabled
49
+ * @param isLoaded - Whether the image has been loaded (intersected)
50
+ */
51
+ export declare function getLazyClass(lazy: boolean, isLoaded: boolean): string;
52
+ /**
53
+ * Creates an IntersectionObserver that fires `onIntersect` once when the given
54
+ * element enters the viewport, then automatically stops observing.
55
+ *
56
+ * @param element - The DOM element to observe
57
+ * @param onIntersect - Callback invoked when the element intersects
58
+ * @param threshold - Intersection threshold (default 0.1)
59
+ * @returns The created IntersectionObserver (call .disconnect() to clean up early)
60
+ */
61
+ export declare function createLazyObserver(element: Element, onIntersect: () => void, threshold?: number): IntersectionObserver;
15
62
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAMjE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAUpF;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAkB1D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,MASnB,CAAC;AAE3B;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,MAAW,GACxB,MAAM,CAMR;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGvE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGzF;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,GAAE,MAAW,GACtB,MAAM,CAOR;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAGrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,MAAM,IAAI,EACvB,SAAS,GAAE,MAAY,GACtB,oBAAoB,CActB"}