@massimo-cassandro/minimo 1.14.0 → 1.14.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massimo-cassandro/minimo",
3
- "version": "1.14.0",
3
+ "version": "1.14.2",
4
4
  "description": "Light css framework & utilities",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -54,7 +54,7 @@ import { classnames } from './classnames.js';
54
54
  *
55
55
  * @param {Object} args
56
56
  * @param {string} args.baseSrc - Image base URL (viewer endpoint); its query params are preserved.
57
- * @param {(number | [number, number])[]} [args.sizes=[250]] - Rendered image sizes, in ascending width order, one per breakpoint plus the default. Each entry is a width (px, height computed with `ratio`) or an explicit `[width, height]` pair (px), allowing a different aspect ratio per breakpoint.
57
+ * @param {(number | [number, number])[]} [args.sizes=[250]] - Rendered image sizes, in ascending width order, one per breakpoint plus the default (entries beyond `breakpoints.length + 1` are ignored in the `sizes` attribute). Each entry is a width (px, height computed with `ratio`) or an explicit `[width, height]` pair (px), allowing a different aspect ratio per breakpoint.
58
58
  * @param {number} [args.ratio=16/9] - Default aspect ratio (width / height, as in the CSS `aspect-ratio` property) used to compute the height of numeric `sizes` entries.
59
59
  * @param {number} [args.dpr=2] - Maximum pixel density (integer): `srcset` candidates are generated for every density from 1 to `dpr`.
60
60
  * @param {number[]} [args.breakpoints=[]] - `max-width` breakpoints (px) paired with `sizes` (one element less than `sizes`).
@@ -62,12 +62,13 @@ import { classnames } from './classnames.js';
62
62
  * @param {string[]} [args.formats=['avif','webp','pjpg']] - Image formats: the last one is used for the `img` fallback element, the others for the `source` elements.
63
63
  * @param {boolean} [args.devMode=false] - When true, `avif` is excluded from `formats` (not supported by the local dev environment).
64
64
  * @param {boolean} [args.lazy=true] - When true, the `img` element gets `loading="lazy"`.
65
+ * @param {boolean} [args.condition=true] - When false, the function returns `null` without building anything.
65
66
  * @param {string|null} [args.pictureExtraClass=null] - Extra class(es) for the `picture` element.
66
67
  * @param {Object<string, *>} [args.pictureExtraAttrs={}] - Extra attributes for the `picture` element.
67
68
  * @param {string|null} [args.imgExtraClass=null] - Extra class(es) for the `img` element.
68
69
  * @param {Object<string, *>} [args.imgExtraAttrs={}] - Extra attributes for the `img` element.
69
70
  * @param {string} [args.alt=''] - `alt` text for the `img` element.
70
- * @returns {DomBuilderItem|null} The `picture` domBuilder item, or `null` when `baseSrc` is missing.
71
+ * @returns {DomBuilderItem|null} The `picture` domBuilder item, or `null` when `baseSrc` is missing or `condition` is false.
71
72
  */
72
73
  export function buildPictureTag({
73
74
  baseSrc,
@@ -79,6 +80,7 @@ export function buildPictureTag({
79
80
  formats = ['avif', 'webp', 'pjpg'],
80
81
  devMode = false,
81
82
  lazy = true,
83
+ condition = true,
82
84
  pictureExtraClass = null,
83
85
  pictureExtraAttrs = {},
84
86
  imgExtraClass = null,
@@ -89,7 +91,7 @@ export function buildPictureTag({
89
91
 
90
92
  }){
91
93
 
92
- if(baseSrc == null) {
94
+ if(baseSrc == null || !condition) {
93
95
  return null;
94
96
  }
95
97
 
@@ -98,6 +100,11 @@ export function buildPictureTag({
98
100
  formats = formats.filter(fmt => fmt !== 'avif');
99
101
  }
100
102
 
103
+ if(sizes.length > breakpoints.length + 1) {
104
+ // eslint-disable-next-line no-console
105
+ console.warn('[buildPictureTag] `sizes` should have one entry more than `breakpoints`: extra entries are ignored in the `sizes` attribute');
106
+ }
107
+
101
108
  // densità generate: da 1 a `dpr`
102
109
  const dprList = Array.from({length: dpr}, (_, i) => i + 1);
103
110
 
@@ -119,17 +126,23 @@ export function buildPictureTag({
119
126
  .sort((a, b) => a[0] - b[0])
120
127
 
121
128
  // attributo `sizes`: ogni size è abbinata al breakpoint corrispondente (max-width),
122
- // l'ultima (senza breakpoint) è il valore di default
129
+ // quella successiva all'ultimo breakpoint è il valore di default
130
+ // (le eventuali entry oltre `breakpoints.length + 1` vengono ignorate)
123
131
  ,sizesAttr = sizePairs
132
+ .slice(0, breakpoints.length + 1)
124
133
  .map(([w], i) => i < breakpoints.length? `(max-width: ${breakpoints[i]}px) ${w}px` : `${w}px`)
125
134
  .join(', ')
126
135
 
127
- // dimensioni intrinseche dell'elemento img (la size più grande)
128
- ,[imgWidth, imgHeight] = sizePairs[sizePairs.length - 1]
136
+ // dimensioni intrinseche dell'elemento img: la size più grande,
137
+ // indipendentemente dall'ordine delle entry
138
+ ,[imgWidth, imgHeight] = sizePairs.reduce((max, pair) => pair[0] > max[0]? pair : max)
139
+
140
+ // larghezza 1x della size mediana (mediana inferiore se le size sono pari),
141
+ // indipendentemente dall'ordine delle entry
142
+ ,medianWidth = sizePairs.map(([w]) => w).sort((a, b) => a - b)[Math.floor((sizePairs.length - 1) / 2)]
129
143
 
130
- // indice del candidato srcset usato come src di default dell'img:
131
- // il candidato 1x della size mediana (mediana inferiore se le size sono pari)
132
- ,defaultSrcIdx = srcsetSizes.findIndex(([w]) => w === sizePairs[Math.floor((sizePairs.length - 1) / 2)][0])
144
+ // indice del candidato srcset usato come src di default dell'img
145
+ ,defaultSrcIdx = srcsetSizes.findIndex(([w]) => w === medianWidth)
133
146
  ;
134
147
 
135
148
  img_params.forEach(([name, value]) => searchParams.set(name, String(value)));