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

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,49 +1,117 @@
1
1
  "use strict";
2
- // Shared template utilities
2
+ // Shared utilities
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.getTemplateData = getTemplateData;
4
+ exports.cleanImagePath = void 0;
5
5
  exports.generateImageClassName = generateImageClassName;
6
- exports.getSharedLogic = getSharedLogic;
7
- function getTemplateData(imagePrefix) {
8
- return {
9
- imagePrefix,
10
- baseClassName: `${imagePrefix}block`,
11
- wrapperClassName: `${imagePrefix}wrapper`
12
- };
6
+ exports.resolveAssetPath = resolveAssetPath;
7
+ exports.getImageClass = getImageClass;
8
+ exports.getWrapperClass = getWrapperClass;
9
+ exports.getLazyClass = getLazyClass;
10
+ exports.createLazyObserver = createLazyObserver;
11
+ const index_1 = require("../constants/index");
12
+ /**
13
+ * Converts any image URL or path into a CSS-safe kebab-case string.
14
+ * Used at build time by generateImageClassName() and at runtime by
15
+ * the Vue/React components to derive the CSS class from the src prop.
16
+ */
17
+ const cleanImagePath = (src) => src
18
+ .replace(/^https?:\/\/[^/]+/, '') // Strip protocol + domain
19
+ .replace(/^[/\\]+/, '') // Strip leading slashes
20
+ .replace(/\.[^/.]+$/, '') // Remove file extension
21
+ .toLowerCase()
22
+ .replace(/[^a-z0-9/-]/g, '-') // Special chars → hyphens (keep / and -)
23
+ .replace(/\//g, '-') // Path separators → hyphens
24
+ .replace(/-+/g, '-') // Collapse duplicate hyphens
25
+ .replace(/^-|-$/g, ''); // Trim leading/trailing hyphens
26
+ exports.cleanImagePath = cleanImagePath;
27
+ /**
28
+ * Generate CSS class name from a file path — path-agnostic, works with any URL format.
29
+ * Matches the runtime getImageClassName logic emitted by getSharedLogic().
30
+ *
31
+ * @param filePath - Relative path from imageDir (e.g. "story/accent-orchid.png")
32
+ * @param imagePrefix - The prefix to add to the class name (e.g. "image-")
33
+ * @param outputPrefix - Optional output path prefix prepended before filePath to mirror
34
+ * the served URL (e.g. "images/" when assetModuleFilename outputs
35
+ * to "images/…" so the browser requests "/images/story/…")
36
+ * @returns The generated CSS class name (e.g. "image-images-story-accent-orchid")
37
+ */
38
+ function generateImageClassName(filePath, imagePrefix, outputPrefix = '') {
39
+ const fullPath = outputPrefix
40
+ ? `${outputPrefix.replace(/\/$/, '')}/${filePath}`
41
+ : filePath;
42
+ return `${imagePrefix}${(0, exports.cleanImagePath)(fullPath)}`;
13
43
  }
14
44
  /**
15
- * Generate CSS class name from file path - shared logic for both webpack plugin and templates
16
- * @param filePath - The file path (can be relative path from images dir or full path)
17
- * @param imagePrefix - The prefix to add to the class name
18
- * @returns The generated CSS class name
45
+ * Strips the Vite/webpack plugin's injected asset-path prefix from a src string
46
+ * so the remaining path matches what the plugin used when generating CSS classes.
47
+ *
48
+ * @param src - The raw src value (may include the asset path prefix)
49
+ * @param assetPath - The value of __PLUGIN_ASSET_PATH__ (empty string if undefined)
19
50
  */
20
- function generateImageClassName(filePath, imagePrefix) {
21
- // Remove file extension and convert to kebab-case
22
- const cleanName = filePath
23
- .replace(/\.[^/.]+$/, '') // Remove file extension
24
- .toLowerCase()
25
- .replace(/[^a-z0-9-]/g, '-') // Convert special chars to hyphens
26
- .replace(/-+/g, '-') // Remove duplicate hyphens
27
- .replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
28
- return `${imagePrefix}${cleanName}`;
51
+ function resolveAssetPath(src, assetPath) {
52
+ if (!assetPath)
53
+ return src;
54
+ return src.replace(new RegExp(`^${assetPath.replace(/\//g, '\\/')}\\/?`), '');
29
55
  }
30
- function getSharedLogic(imagePrefix) {
31
- return `
32
- // Extract filename from src to generate class name
33
- const getImageClassName = (imageSrc) => {
34
- // Remove /images/ prefix and file extension, convert to kebab-case
35
- const filename = imageSrc
36
- .replace(/^.*\\/images\\//, '') // Remove path up to /images/
37
- .replace(/\\.[^/.]+$/, '') // Remove file extension
38
- .toLowerCase()
39
- .replace(/[^a-z0-9-]/g, '-') // Convert special chars to hyphens
40
- .replace(/-+/g, '-') // Remove duplicate hyphens
41
- .replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
42
-
43
- return \`${imagePrefix}\${filename}\`;
44
- };
45
-
46
- const imageClassName = getImageClassName(src);
47
- const wrapperClassName = \`${imagePrefix}wrapper \${imageClassName}\`;`;
56
+ /**
57
+ * Derives the per-image CSS class from a src URL, stripping the asset-path
58
+ * prefix first so the class matches what the plugin generated at build time.
59
+ *
60
+ * @param src - Raw src prop value
61
+ * @param imagePrefix - e.g. "image-"
62
+ * @param assetPath - Value of __PLUGIN_ASSET_PATH__ (pass '' if not defined)
63
+ */
64
+ function getImageClass(src, imagePrefix, assetPath) {
65
+ if (!src)
66
+ return '';
67
+ return `${imagePrefix}${(0, exports.cleanImagePath)(resolveAssetPath(src, assetPath))}`;
68
+ }
69
+ /**
70
+ * Builds the full className string for the <picture> wrapper element.
71
+ *
72
+ * @param src - Raw src prop value
73
+ * @param imagePrefix - e.g. "image-"
74
+ * @param assetPath - Value of __PLUGIN_ASSET_PATH__ (pass '' if not defined)
75
+ * @param extraClass - Any additional class(es) passed by the consumer (e.g. className prop)
76
+ */
77
+ function getWrapperClass(src, imagePrefix, assetPath, extraClass = '') {
78
+ const parts = [
79
+ `${imagePrefix}${index_1.CLASS_NAMES.WRAPPER_SUFFIX}`,
80
+ getImageClass(src, imagePrefix, assetPath),
81
+ extraClass,
82
+ ].filter(Boolean);
83
+ return parts.join(' ');
84
+ }
85
+ /**
86
+ * Returns the CSS class string for the <img> element based on lazy-load state.
87
+ *
88
+ * @param lazy - Whether lazy loading is enabled
89
+ * @param isLoaded - Whether the image has been loaded (intersected)
90
+ */
91
+ function getLazyClass(lazy, isLoaded) {
92
+ if (!lazy)
93
+ return '';
94
+ return isLoaded ? `${index_1.CLASS_NAMES.LAZY} ${index_1.CLASS_NAMES.LOADED}` : index_1.CLASS_NAMES.LAZY;
95
+ }
96
+ /**
97
+ * Creates an IntersectionObserver that fires `onIntersect` once when the given
98
+ * element enters the viewport, then automatically stops observing.
99
+ *
100
+ * @param element - The DOM element to observe
101
+ * @param onIntersect - Callback invoked when the element intersects
102
+ * @param threshold - Intersection threshold (default 0.1)
103
+ * @returns The created IntersectionObserver (call .disconnect() to clean up early)
104
+ */
105
+ function createLazyObserver(element, onIntersect, threshold = 0.1) {
106
+ const observer = new IntersectionObserver((entries) => {
107
+ entries.forEach((entry) => {
108
+ if (entry.isIntersecting) {
109
+ onIntersect();
110
+ observer.unobserve(entry.target);
111
+ }
112
+ });
113
+ }, { threshold });
114
+ observer.observe(element);
115
+ return observer;
48
116
  }
49
117
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";AAAA,4BAA4B;;AAQ5B,0CAMC;AAQD,wDAUC;AAED,wCAkBC;AA5CD,SAAgB,eAAe,CAAC,WAAmB;IACjD,OAAO;QACL,WAAW;QACX,aAAa,EAAE,GAAG,WAAW,OAAO;QACpC,gBAAgB,EAAE,GAAG,WAAW,SAAS;KAC1C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,QAAgB,EAAE,WAAmB;IAC1E,kDAAkD;IAClD,MAAM,SAAS,GAAG,QAAQ;SACvB,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,wBAAwB;SACjD,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,mCAAmC;SAC/D,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,2BAA2B;SAC/C,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,kCAAkC;IAE5D,OAAO,GAAG,WAAW,GAAG,SAAS,EAAE,CAAC;AACtC,CAAC;AAED,SAAgB,cAAc,CAAC,WAAmB;IAChD,OAAO;;;;;;;;;;;;eAYM,WAAW;;;;+BAIK,WAAW,+BAA+B,CAAC;AAC1E,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ "use strict";const e=require("vue"),d="image-",i={LAZY:"lazy",LOADED:"loaded",WRAPPER_SUFFIX:"wrapper"},A=r=>r.replace(/^https?:\/\/[^/]+/,"").replace(/^[/\\]+/,"").replace(/\.[^/.]+$/,"").toLowerCase().replace(/[^a-z0-9/-]/g,"-").replace(/\//g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");function y(r,a){return a?r.replace(new RegExp(`^${a.replace(/\//g,"\\/")}\\/?`),""):r}function L(r,a,t){return r?`${a}${A(y(r,t))}`:""}function P(r,a,t,s=""){return[`${a}${i.WRAPPER_SUFFIX}`,L(r,a,t),s].filter(Boolean).join(" ")}function E(r,a){return r?a?`${i.LAZY} ${i.LOADED}`:i.LAZY:""}function S(r,a,t=.1){const s=new IntersectionObserver(l=>{l.forEach(n=>{n.isIntersecting&&(a(),s.unobserve(n.target))})},{threshold:t});return s.observe(r),s}const z=["src","alt"],I=e.defineComponent({inheritAttrs:!1,__name:"PlaceBlockImage",props:{src:{type:String,required:!0},alt:{type:String,required:!0},imagePrefix:{type:String,default:()=>d},lazy:{type:Boolean,default:!1}},setup(r){const a=e.useAttrs(),t=r,s=e.computed(()=>{const{class:o,...g}=a;return g}),l=e.ref(null),n=e.ref(t.lazy?"":t.src),c=e.ref(!t.lazy);let u=null;const m=typeof __PLUGIN_ASSET_PATH__<"u"?__PLUGIN_ASSET_PATH__:"",_=e.computed(()=>P(t.src,t.imagePrefix,m)),v=e.computed(()=>E(t.lazy,c.value)),f=()=>{!t.lazy||c.value||!l.value||(u=S(l.value,()=>{n.value=t.src,c.value=!0}))},p=()=>{u&&(u.disconnect(),u=null)};return e.onMounted(()=>{f()}),e.onUnmounted(()=>{p()}),e.watch(()=>t.src,o=>{t.lazy?c.value||(p(),f()):n.value=o}),e.watch(c,o=>{o&&(n.value=t.src,p())}),(o,g)=>(e.openBlock(),e.createElementBlock("picture",{class:e.normalizeClass([_.value,e.unref(a).class])},[e.createElementVNode("img",e.mergeProps({ref_key:"imgRef",ref:l,src:n.value,alt:r.alt,class:v.value},s.value),null,16,z)],2))}});module.exports=I;
@@ -0,0 +1,83 @@
1
+ import { defineComponent as y, useAttrs as L, computed as p, ref as f, onMounted as P, onUnmounted as E, watch as _, openBlock as S, createElementBlock as z, normalizeClass as I, unref as C, createElementVNode as $, mergeProps as h } from "vue";
2
+ const R = "image-", u = {
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
+ }, b = (t) => t.replace(/^https?:\/\/[^/]+/, "").replace(/^[/\\]+/, "").replace(/\.[^/.]+$/, "").toLowerCase().replace(/[^a-z0-9/-]/g, "-").replace(/\//g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
9
+ function w(t, r) {
10
+ return r ? t.replace(new RegExp(`^${r.replace(/\//g, "\\/")}\\/?`), "") : t;
11
+ }
12
+ function N(t, r, e) {
13
+ return t ? `${r}${b(w(t, e))}` : "";
14
+ }
15
+ function B(t, r, e, a = "") {
16
+ return [
17
+ `${r}${u.WRAPPER_SUFFIX}`,
18
+ N(t, r, e),
19
+ a
20
+ ].filter(Boolean).join(" ");
21
+ }
22
+ function F(t, r) {
23
+ return t ? r ? `${u.LAZY} ${u.LOADED}` : u.LAZY : "";
24
+ }
25
+ function O(t, r, e = 0.1) {
26
+ const a = new IntersectionObserver(
27
+ (s) => {
28
+ s.forEach((n) => {
29
+ n.isIntersecting && (r(), a.unobserve(n.target));
30
+ });
31
+ },
32
+ { threshold: e }
33
+ );
34
+ return a.observe(t), a;
35
+ }
36
+ const U = ["src", "alt"], x = /* @__PURE__ */ y({
37
+ inheritAttrs: !1,
38
+ __name: "PlaceBlockImage",
39
+ props: {
40
+ src: { type: String, required: !0 },
41
+ alt: { type: String, required: !0 },
42
+ imagePrefix: { type: String, default: () => R },
43
+ lazy: { type: Boolean, default: !1 }
44
+ },
45
+ setup(t) {
46
+ const r = L(), e = t, a = p(() => {
47
+ const { class: c, ...m } = r;
48
+ return m;
49
+ }), s = f(null), n = f(e.lazy ? "" : e.src), l = f(!e.lazy);
50
+ let o = null;
51
+ const v = typeof __PLUGIN_ASSET_PATH__ < "u" ? __PLUGIN_ASSET_PATH__ : "", d = p(
52
+ () => B(e.src, e.imagePrefix, v)
53
+ ), A = p(() => F(e.lazy, l.value)), g = () => {
54
+ !e.lazy || l.value || !s.value || (o = O(s.value, () => {
55
+ n.value = e.src, l.value = !0;
56
+ }));
57
+ }, i = () => {
58
+ o && (o.disconnect(), o = null);
59
+ };
60
+ return P(() => {
61
+ g();
62
+ }), E(() => {
63
+ i();
64
+ }), _(() => e.src, (c) => {
65
+ e.lazy ? l.value || (i(), g()) : n.value = c;
66
+ }), _(l, (c) => {
67
+ c && (n.value = e.src, i());
68
+ }), (c, m) => (S(), z("picture", {
69
+ class: I([d.value, C(r).class])
70
+ }, [
71
+ $("img", h({
72
+ ref_key: "imgRef",
73
+ ref: s,
74
+ src: n.value,
75
+ alt: t.alt,
76
+ class: A.value
77
+ }, a.value), null, 16, U)
78
+ ], 2));
79
+ }
80
+ });
81
+ export {
82
+ x as default
83
+ };
@@ -3,9 +3,26 @@ export interface PlaceBlockImagePluginOptions {
3
3
  imagePrefix?: string;
4
4
  imageDir: string;
5
5
  scssPath: string;
6
- componentPath?: string;
7
- componentType?: 'tsx' | 'jsx' | 'vue';
8
- generateComponent?: boolean;
6
+ /**
7
+ * The URL path at which images are served (e.g. '/images').
8
+ * Used by the webpack plugin to inject a __PLACE_ASSET_PATH__ constant
9
+ * that the React/Vue components use to strip the prefix from src before
10
+ * generating the CSS class name — ensuring it matches what the plugin
11
+ * generates from the file path relative to imageDir.
12
+ *
13
+ * Defaults to the basename of imageDir prefixed with '/' (e.g. '/images').
14
+ */
15
+ assetPath?: string;
16
+ /**
17
+ * Output path prefix prepended to the relative image path when generating
18
+ * CSS class names — must match the prefix used in assetModuleFilename so
19
+ * the class name the plugin writes into the SCSS matches what the component
20
+ * derives from the served URL at runtime.
21
+ *
22
+ * e.g. if assetModuleFilename outputs "images/story/foo.png" (served as
23
+ * "/images/story/foo.png"), set outputPathPrefix: 'images'
24
+ */
25
+ outputPathPrefix?: string;
9
26
  }
10
27
  export interface ImageDimensions {
11
28
  width: number;
@@ -34,10 +51,6 @@ export declare class PlaceBlockImagePlugin {
34
51
  * Write SCSS file
35
52
  */
36
53
  private writeScssFile;
37
- /**
38
- * Generate and write component file
39
- */
40
- private writeComponentFile;
41
54
  /**
42
55
  * Check if images have changed since last generation
43
56
  */
@@ -1 +1 @@
1
- {"version":3,"file":"webpack-plugin.d.ts","sourceRoot":"","sources":["../src/webpack-plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAInC,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IAEjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,OAAO,CAAyD;IACxE,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,kBAAkB,CAAa;gBAE3B,OAAO,EAAE,4BAA4B;IASjD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;YACW,UAAU;IA8BxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAmCpB;;OAEG;YACW,aAAa;IAY3B;;OAEG;YACW,kBAAkB;IA0BhC;;OAEG;YACW,gBAAgB;IAyB9B,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;YA4BjB,mBAAmB;CA8ClC;AAED,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"webpack-plugin.d.ts","sourceRoot":"","sources":["../src/webpack-plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAgB,MAAM,SAAS,CAAC;AAGjD,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,OAAO,CAAyD;IACxE,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,kBAAkB,CAAa;gBAE3B,OAAO,EAAE,4BAA4B;IASjD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IASzB;;OAEG;YACW,UAAU;IA8BxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAmCpB;;OAEG;YACW,aAAa;IAY3B;;OAEG;YACW,gBAAgB;IAyB9B,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;YA2CjB,mBAAmB;CA6ClC;AAED,eAAe,qBAAqB,CAAC"}
@@ -41,7 +41,7 @@ const fs = __importStar(require("fs"));
41
41
  const path = __importStar(require("path"));
42
42
  const glob_1 = require("glob");
43
43
  const image_size_1 = __importDefault(require("image-size"));
44
- const templates_1 = require("./templates");
44
+ const webpack_1 = require("webpack");
45
45
  const utils_1 = require("./utils");
46
46
  class PlaceBlockImagePlugin {
47
47
  constructor(options) {
@@ -49,8 +49,8 @@ class PlaceBlockImagePlugin {
49
49
  this.lastGenerationTime = 0;
50
50
  this.options = {
51
51
  imagePrefix: 'image-',
52
- generateComponent: true,
53
- componentType: 'tsx',
52
+ outputPathPrefix: '',
53
+ assetPath: `/${path.basename(options.imageDir)}`,
54
54
  ...options
55
55
  };
56
56
  }
@@ -58,7 +58,12 @@ class PlaceBlockImagePlugin {
58
58
  * Generate CSS class name from filename - uses shared logic
59
59
  */
60
60
  generateClassName(filename) {
61
- return (0, utils_1.generateImageClassName)(filename, this.options.imagePrefix);
61
+ // When outputPathPrefix is set the asset output is flat (just basename),
62
+ // so use only the basename to mirror the served URL: /assets/accent-orchid.png
63
+ const name = this.options.outputPathPrefix
64
+ ? path.basename(filename)
65
+ : filename;
66
+ return (0, utils_1.generateImageClassName)(name, this.options.imagePrefix, this.options.outputPathPrefix);
62
67
  }
63
68
  /**
64
69
  * Scan directory for images and get their dimensions
@@ -134,29 +139,6 @@ class PlaceBlockImagePlugin {
134
139
  }
135
140
  fs.writeFileSync(this.options.scssPath, scssContent);
136
141
  }
137
- /**
138
- * Generate and write component file
139
- */
140
- async writeComponentFile() {
141
- if (!this.options.generateComponent || !this.options.componentPath || !this.options.componentType) {
142
- return;
143
- }
144
- const componentFileName = `PlaceBlockImage.${this.options.componentType}`;
145
- const componentFilePath = path.resolve(this.options.componentPath, componentFileName);
146
- // Check if component already exists
147
- if (fs.existsSync(componentFilePath)) {
148
- console.log(`📦 Component already exists, skipping: ${componentFilePath}`);
149
- return;
150
- }
151
- const componentContent = (0, templates_1.getTemplate)(this.options.componentType, this.options.imagePrefix);
152
- const outputDir = path.dirname(componentFilePath);
153
- // Ensure output directory exists
154
- if (!fs.existsSync(outputDir)) {
155
- fs.mkdirSync(outputDir, { recursive: true });
156
- }
157
- fs.writeFileSync(componentFilePath, componentContent);
158
- console.log(`📦 Generated component: ${componentFilePath}`);
159
- }
160
142
  /**
161
143
  * Check if images have changed since last generation
162
144
  */
@@ -182,6 +164,19 @@ class PlaceBlockImagePlugin {
182
164
  }
183
165
  }
184
166
  apply(compiler) {
167
+ // Inject @place-block-image alias so the Vue/React source components can
168
+ // resolve their shared utils/constants imports without requiring the
169
+ // consuming app to configure anything manually.
170
+ const pkgSrc = path.resolve(__dirname, '../src');
171
+ compiler.options.resolve.alias = {
172
+ ...(compiler.options.resolve.alias || {}),
173
+ '@place-block-image': pkgSrc,
174
+ };
175
+ // Inject __PLUGIN_ASSET_PATH__ so the React/Vue components can strip the
176
+ // served URL prefix from src before generating the CSS class name.
177
+ new webpack_1.DefinePlugin({
178
+ __PLUGIN_ASSET_PATH__: JSON.stringify(this.options.assetPath),
179
+ }).apply(compiler);
185
180
  // Use environment hook to run only once at startup
186
181
  compiler.hooks.environment.tap('PlaceBlockImagePlugin', () => {
187
182
  this.generateImageStyles();
@@ -226,7 +221,6 @@ class PlaceBlockImagePlugin {
226
221
  return;
227
222
  }
228
223
  await this.writeScssFile(images);
229
- await this.writeComponentFile();
230
224
  console.log(`✅ Generated CSS custom properties for ${images.length} images`);
231
225
  console.log(`📝 Output: ${this.options.scssPath}`);
232
226
  // Log some examples
@@ -1 +1 @@
1
- {"version":3,"file":"webpack-plugin.js","sourceRoot":"","sources":["../src/webpack-plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webpack-plugin.js","sourceRoot":"","sources":["../src/webpack-plugin.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,36 @@
1
1
  {
2
2
  "name": "@place-framework/place-block-image",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "A utility package for generating CSS custom properties from image dimensions to prevent layout shift",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ },
12
+ "./utils": {
13
+ "require": "./dist/utils/index.js",
14
+ "types": "./dist/utils/index.d.ts"
15
+ },
16
+ "./constants": {
17
+ "require": "./dist/constants/index.js",
18
+ "types": "./dist/constants/index.d.ts"
19
+ },
20
+ "./vue": {
21
+ "import": "./dist/vue/PlaceBlockImage.js",
22
+ "require": "./dist/vue/PlaceBlockImage.cjs",
23
+ "types": "./dist/vue/PlaceBlockImage.d.ts"
24
+ },
25
+ "./react": {
26
+ "import": "./dist/react/PlaceBlockImage.js",
27
+ "require": "./dist/react/PlaceBlockImage.cjs",
28
+ "types": "./dist/react/PlaceBlockImage.d.ts"
29
+ }
30
+ },
7
31
  "scripts": {
8
- "build": "tsc",
32
+ "build": "tsc && vite build",
9
33
  "dev": "tsc --watch",
10
- "generate": "node dist/generate.js",
11
34
  "test": "echo \"Error: no test specified\" && exit 1"
12
35
  },
13
36
  "keywords": [
@@ -22,18 +45,21 @@
22
45
  "author": "Brian Kelley",
23
46
  "license": "MIT",
24
47
  "devDependencies": {
25
- "@types/node": "^20.0.0",
26
48
  "@types/glob": "^8.1.0",
27
- "typescript": "^5.0.0"
49
+ "@types/node": "^20.0.0",
50
+ "@types/react": "^18.0.0",
51
+ "@vitejs/plugin-vue": "^5.2.4",
52
+ "typescript": "^5.0.0",
53
+ "vite": "^5.4.21"
28
54
  },
29
55
  "dependencies": {
30
- "image-size": "^1.0.2",
31
- "glob": "^10.0.0"
56
+ "glob": "^10.0.0",
57
+ "image-size": "^1.0.2"
32
58
  },
33
59
  "peerDependencies": {
34
- "webpack": ">=5.0.0",
35
60
  "react": ">=16.8.0",
36
- "vue": ">=3.0.0"
61
+ "vue": ">=3.0.0",
62
+ "webpack": ">=5.0.0"
37
63
  },
38
64
  "peerDependenciesMeta": {
39
65
  "react": {
@@ -46,4 +72,4 @@
46
72
  "optional": false
47
73
  }
48
74
  }
49
- }
75
+ }
@@ -1,13 +1,12 @@
1
+ export const IMAGE_PREFIX = 'image-';
2
+
1
3
  export const CLASS_NAMES = {
2
4
  // Lazy loading states
3
5
  LAZY: 'lazy',
4
6
  LOADED: 'loaded',
5
-
6
- // Wrapper classes
7
- IMAGE_WRAPPER: 'image-wrapper',
8
-
9
- // Base image class
10
- IMAGE_BLOCK: 'image-block'
7
+
8
+ // Suffix appended to imagePrefix to form the wrapper class (e.g. 'image-wrapper')
9
+ WRAPPER_SUFFIX: 'wrapper',
11
10
  } as const;
12
11
 
13
12
  export const getWrapperClassName = (imagePrefix: string) => `${imagePrefix}wrapper`;
@@ -0,0 +1,63 @@
1
+ declare const __PLUGIN_ASSET_PATH__: string;
2
+
3
+ import React, { useRef, useEffect, useState } from 'react';
4
+ import { getWrapperClass, getLazyClass, createLazyObserver } from '../utils/index';
5
+ import { IMAGE_PREFIX } from '../constants/index';
6
+
7
+ interface PlaceBlockImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {
8
+ src: string;
9
+ alt: string;
10
+ imagePrefix?: string;
11
+ lazy?: boolean;
12
+ }
13
+
14
+ /**
15
+ * PlaceBlockImage — prevents layout shift using CSS custom properties.
16
+ * Import: import PlaceBlockImage from '@place-framework/place-block-image/react'
17
+ *
18
+ * Usage:
19
+ * <PlaceBlockImage src="/assets/logo.png" alt="Logo" />
20
+ * <PlaceBlockImage src="/assets/hero.jpg" alt="Hero" lazy={true} />
21
+ */
22
+ export const PlaceBlockImage: React.FC<PlaceBlockImageProps> = ({
23
+ src,
24
+ alt,
25
+ imagePrefix = IMAGE_PREFIX,
26
+ lazy = false,
27
+ className = '',
28
+ ...props
29
+ }) => {
30
+ const imgRef = useRef<HTMLImageElement>(null);
31
+ const [imageSrc, setImageSrc] = useState(lazy ? '' : src);
32
+ const [isLoaded, setIsLoaded] = useState(!lazy);
33
+
34
+ const assetPath: string = typeof __PLUGIN_ASSET_PATH__ !== 'undefined' ? __PLUGIN_ASSET_PATH__ : '';
35
+
36
+ useEffect(() => {
37
+ if (!lazy || isLoaded || !imgRef.current) return;
38
+
39
+ const observer = createLazyObserver(imgRef.current, () => {
40
+ setImageSrc(src);
41
+ setIsLoaded(true);
42
+ });
43
+
44
+ return () => observer.disconnect();
45
+ }, [src, lazy, isLoaded]);
46
+
47
+ const wrapperClassName = getWrapperClass(src, imagePrefix, assetPath, className);
48
+ const imgClassName = getLazyClass(lazy, isLoaded);
49
+
50
+ return (
51
+ <picture className={wrapperClassName}>
52
+ <img
53
+ ref={imgRef}
54
+ src={imageSrc}
55
+ alt={alt}
56
+ className={imgClassName}
57
+ {...props}
58
+ />
59
+ </picture>
60
+ );
61
+ };
62
+
63
+ export default PlaceBlockImage;
@@ -0,0 +1 @@
1
+ export { PlaceBlockImage, default } from './PlaceBlockImage';