@massimo-cassandro/minimo 1.14.3 → 1.14.5

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.3",
3
+ "version": "1.14.5",
4
4
  "description": "Light css framework & utilities",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -4,7 +4,7 @@ import { classnames } from './classnames.js';
4
4
 
5
5
  /**
6
6
  * @typedef {Object} PictureSizeEntry
7
- * @property {number} [from] - `min-width` breakpoint (px) the size applies from; omitted in the (single) mobile-first default entry.
7
+ * @property {number} [from] - Breakpoint (px) the size applies from (`width >=` media condition); omitted in the (single) mobile-first default entry.
8
8
  * @property {number | [number, number]} size - Rendered width (px, height computed with `ratio`) or explicit `[width, height]` pair (px).
9
9
  */
10
10
 
@@ -17,7 +17,7 @@ import { classnames } from './classnames.js';
17
17
  * of `sizes`, a candidate is generated for every integer density from 1 to `dpr`.
18
18
  * The `sizes` attribute is built mobile-first: the entry without `from` is the
19
19
  * default, and every other entry applies from its `from` breakpoint up, as a
20
- * `(min-width: …)` media condition.
20
+ * `(width >= …)` media condition (range syntax).
21
21
  *
22
22
  * @example
23
23
  * // fixed-width thumb (250px, 16:9 ratio, 1x and 2x candidates)
@@ -32,7 +32,7 @@ import { classnames } from './classnames.js';
32
32
  * baseSrc,
33
33
  * sizes: [250, { from: 576, size: 500 }, { from: 992, size: 800 }],
34
34
  * });
35
- * // sizes="(min-width: 992px) 800px, (min-width: 576px) 500px, 250px"
35
+ * // sizes="(width >= 992px) 800px, (width >= 576px) 500px, 250px"
36
36
  *
37
37
  * @example
38
38
  * // custom ratio for numeric sizes and candidates up to 3x
@@ -64,7 +64,9 @@ import { classnames } from './classnames.js';
64
64
  * @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.
65
65
  * @param {boolean} [args.devMode=false] - When true, `avif` is excluded from `formats` (not supported by the local dev environment).
66
66
  * @param {boolean} [args.lazy=true] - When true, the `img` element gets `loading="lazy"`.
67
+ * @param {((img: HTMLImageElement) => void) | null} [args.onLoad=null] - Called once the image has finished loading, receiving the `img` element (called immediately if the image is already complete).
67
68
  * @param {boolean} [args.condition=true] - When false, the function returns `null` without building anything.
69
+ * @param {boolean} [args.legacyMediaSyntax=false] - When true, the `sizes` media conditions use `(min-width: …)` instead of the range syntax `(width >= …)`, for older browsers (pre Chrome/Edge 104, Firefox 102, Safari 16.4).
68
70
  * @param {string|null} [args.pictureExtraClass=null] - Extra class(es) for the `picture` element.
69
71
  * @param {Object<string, *>} [args.pictureExtraAttrs={}] - Extra attributes for the `picture` element.
70
72
  * @param {string|null} [args.imgExtraClass=null] - Extra class(es) for the `img` element.
@@ -81,7 +83,9 @@ export function buildPictureTag({
81
83
  formats = ['avif', 'webp', 'pjpg'],
82
84
  devMode = false,
83
85
  lazy = true,
86
+ onLoad = null,
84
87
  condition = true,
88
+ legacyMediaSyntax = false,
85
89
  pictureExtraClass = null,
86
90
  pictureExtraAttrs = {},
87
91
  imgExtraClass = null,
@@ -138,7 +142,10 @@ export function buildPictureTag({
138
142
  // attributo `sizes` (mobile-first): le entry con breakpoint in ordine decrescente
139
143
  // (vince la prima condizione che matcha), il default per ultimo
140
144
  ,sizesAttr = brkEntries
141
- .map(({from, width}) => `(min-width: ${from}px) ${width}px`)
145
+ .map(({from, width}) => legacyMediaSyntax
146
+ ? `(min-width: ${from}px) ${width}px`
147
+ : `(width >= ${from}px) ${width}px`
148
+ )
142
149
  .reverse()
143
150
  .concat(`${defaultEntry.width}px`)
144
151
  .join(', ')
@@ -199,6 +206,14 @@ export function buildPictureTag({
199
206
  loading: lazy? 'lazy' : null,
200
207
  ...imgExtraAttrs
201
208
  },
209
+ callback: onLoad == null? undefined : el => {
210
+ const img = /** @type {HTMLImageElement} */ (el);
211
+ if(img.complete) {
212
+ onLoad(img);
213
+ } else {
214
+ img.addEventListener('load', () => onLoad(img), {once: true});
215
+ }
216
+ },
202
217
  // TODO classe popover, se attivato
203
218
  // callback: options.addPopover
204
219
  // ? el => el.addEventListener('click', () => zoomPopoverEl.togglePopover())