@massimo-cassandro/minimo 1.43.1 → 1.43.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.
- package/charts/src/helpers/parse-std-axis-opts.js +2 -1
- package/charts/src/lines.js +12 -0
- package/dev-tools/starter-kit/source_files/root/package-tpl.json +2 -1
- package/dev-tools/starter-kit/source_files/root/{webpack.config.mjs → webpack.config-tpl.mjs} +24 -17
- package/dev-tools/starter-kit/webpack-config-upg.md +4 -0
- package/package.json +1 -1
- package/src/components/sf-macro/sf-macro.js +16 -0
- package/src/css/grid.css +16 -4
- package/src/utilities/dom-builder-helpers/picture-tag.js +40 -3
- package/types/classes.d.ts +5 -0
|
@@ -25,6 +25,7 @@ export function parseStdAxisOpts(params = {} ) {
|
|
|
25
25
|
values: [], // array flat dei valori per il calcolo di maxValues e minValues, qualora fossero null
|
|
26
26
|
legenda: null,
|
|
27
27
|
padding: 0, // spazio intorno ai bordi del grafico
|
|
28
|
+
padding_right: null, // padding del solo lato destro; se null viene usato `padding`
|
|
28
29
|
width: null, // width e height non possono essere null, vanno verificate prima
|
|
29
30
|
height: null,
|
|
30
31
|
eti_asseX_height: null, // non può essere null, va verificato prima
|
|
@@ -96,7 +97,7 @@ export function parseStdAxisOpts(params = {} ) {
|
|
|
96
97
|
// i lati sx e inferiore corrispondono agli assi
|
|
97
98
|
parsed.chart_area = {
|
|
98
99
|
top : legenda_height + gap_legenda + params.padding, // coordinata y superiore
|
|
99
|
-
right : params.width - params.padding, // coordinata x dx
|
|
100
|
+
right : params.width - (params.padding_right?? params.padding), // coordinata x dx
|
|
100
101
|
bottom : params.height - params.eti_asseX_height - params.ticksLength - params.padding, // coordinata y inferiore
|
|
101
102
|
left : params.eti_asseY_width + params.ticksLength + params.padding // coordinata x sx
|
|
102
103
|
};
|
package/charts/src/lines.js
CHANGED
|
@@ -274,6 +274,17 @@ export async function lines(params) {
|
|
|
274
274
|
.viewbox(0, 0, params.width, params.height)
|
|
275
275
|
.attr({...params.svgAttrs});
|
|
276
276
|
|
|
277
|
+
/*
|
|
278
|
+
L'ultimo punto di ogni linea cade sul limite destro della chart area:
|
|
279
|
+
se il padding è inferiore al raggio massimo dei punti, il cerchio verrebbe tagliato dal bordo dell'svg.
|
|
280
|
+
In tal caso il padding destro viene portato al raggio massimo.
|
|
281
|
+
*/
|
|
282
|
+
const radii = Array.isArray(params.data_points_attrs.r)
|
|
283
|
+
? params.data_points_attrs.r
|
|
284
|
+
: [params.data_points_attrs.r];
|
|
285
|
+
const maxPointRadius = Math.max(0, ...radii.map(r => Number(r) || 0));
|
|
286
|
+
const paddingRight = Math.max(params.padding, maxPointRadius);
|
|
287
|
+
|
|
277
288
|
// pre-elaborazione e calcolo di alcuni elementi (chartArea)
|
|
278
289
|
// nuove variabili definite da parseStdAxisOpts
|
|
279
290
|
const {
|
|
@@ -291,6 +302,7 @@ export async function lines(params) {
|
|
|
291
302
|
values: flatValues,
|
|
292
303
|
legenda: params.legenda,
|
|
293
304
|
padding: params.padding,
|
|
305
|
+
padding_right: paddingRight,
|
|
294
306
|
width: params.width,
|
|
295
307
|
height: params.height,
|
|
296
308
|
eti_asseX_height: params.xAxisLabelHeight,
|
package/dev-tools/starter-kit/source_files/root/{webpack.config.mjs → webpack.config-tpl.mjs}
RENAMED
|
@@ -103,21 +103,27 @@ const isDevelopment = process.env.NODE_ENV === 'development'
|
|
|
103
103
|
,minimo_path = './node_modules/@massimo-cassandro/minimo' // fromProjectRoot('node_modules/@massimo-cassandro/minimo')
|
|
104
104
|
|
|
105
105
|
,usePurgeCss = true // false per disattivare PurgeCSS (debug rapido di problemi legati al purge)
|
|
106
|
+
,purgeCssInDev = false
|
|
106
107
|
,purgeCSSOptions = {
|
|
107
108
|
keyframes: true, // rimuove i @keyframes non referenziati
|
|
108
109
|
debug: false // true per loggare i selettori rimossi da PurgeCSS a fine build
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
/*
|
|
113
|
+
plugin per l'estrazione ottimizzata delle custom properties (vedi
|
|
114
|
+
webpack-config-modules/custom-props-purgecss-plugin.mjs): dopo la
|
|
115
|
+
minificazione inietta nei css compilati SOLO le definizioni di custom
|
|
116
|
+
properties effettivamente usate, prese dal file master. I css del progetto
|
|
117
|
+
contengono quindi solo usi `var(--nome)`, mai definizioni (custom-properties.css
|
|
118
|
+
NON va importato nelle entry css). Se false il plugin non viene nemmeno
|
|
119
|
+
caricato e la gestione delle custom properties resta a carico del progetto
|
|
120
|
+
*/
|
|
118
121
|
,useCustomPropsPlugin = true
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
|
|
123
|
+
/*
|
|
124
|
+
file master con TUTTE le definizioni di custom properties disponibili
|
|
125
|
+
(copiato da minimo da starter-install.sh, generato da `npm run 'build tokens'`)
|
|
126
|
+
*/
|
|
121
127
|
,customPropsFile = path.resolve(__dirname, './app/css/custom-properties.css')
|
|
122
128
|
|
|
123
129
|
/*
|
|
@@ -143,14 +149,15 @@ const isDevelopment = process.env.NODE_ENV === 'development'
|
|
|
143
149
|
*/
|
|
144
150
|
,standaloneEntries = []
|
|
145
151
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
/*
|
|
153
|
+
PurgeCSS e plugin custom properties lavorano sugli asset css finali:
|
|
154
|
+
in dev, con `false`, sono entrambi disattivati (build più veloce, css
|
|
155
|
+
iniettato con style-loader; se `useCustomPropsPlugin` è true le definizioni
|
|
156
|
+
vengono aggiunte per intero alle entry, vedi `parsedEntries`).
|
|
157
|
+
Con `purgeCssInDev = true` (a scopo di test) sono attivi come in produzione (secondo i
|
|
158
|
+
rispettivi flag `usePurgeCss` / `useCustomPropsPlugin`) e `inlineCssInDevMode`
|
|
159
|
+
viene forzato a false
|
|
160
|
+
*/
|
|
154
161
|
,runCustomPropsPlugin = useCustomPropsPlugin && (!isDevelopment || purgeCssInDev)
|
|
155
162
|
// ,manifest_shared_seed = {}
|
|
156
163
|
;
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
La versione della configurazione in uso è indicata dal commento `// v.N` alla riga 2 di `webpack.config.mjs` e di ogni file in `webpack-config-modules/`.
|
|
4
4
|
|
|
5
|
+
Dove non esiste il commento, si intende una configurazione v2 o precedente.
|
|
6
|
+
|
|
5
7
|
Le versioni precedenti sono conservate in `archived/webpack-config-v2/` del repository di minimo.
|
|
6
8
|
|
|
7
9
|
> **Alternativa rapida:** rilanciare `starter-install.sh` (è idempotente): i file diversi dai sorgenti vengono rinominati `OLD-<nome>` e sostituiti dalla nuova versione. Poi si riportano nel nuovo `webpack.config.mjs` le personalizzazioni del progetto (entry, glob dei contenuti, safelist, template html, regole custom) copiandole da `OLD-webpack.config.mjs`. Le istruzioni seguenti servono per aggiornare a mano un progetto già esistente.
|
|
@@ -30,6 +32,8 @@ Riepilogo delle modifiche:
|
|
|
30
32
|
|
|
31
33
|
### 1. Moduli in `webpack-config-modules/`
|
|
32
34
|
|
|
35
|
+
- aggiornare tutti i moduli con versione precedente a quella presente nello starter-kit
|
|
36
|
+
- cssnano non è più utilizzato, se presente effettuare un `npm uninstall`
|
|
33
37
|
- **Aggiungere** `custom-props-purgecss-plugin.mjs`.
|
|
34
38
|
- **Sostituire** `purgecss-setup.mjs` con la versione v3 (non gestisce più `variables` né `variablesSafelist`; la firma di `createPurgeCSSPlugins` non accetta più `variablesSafelist` e `variables`).
|
|
35
39
|
- **Eliminare** `purgecss-variables-safelist.mjs` (sostituito dal plugin).
|
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ import './sf-macro.css';
|
|
|
4
4
|
// TODO[epic=v2] in una v. 2 di minimo, rinominare wrapper_selector e row_selector in
|
|
5
5
|
// wrapperClass e rowClass (NB: classi, non selettori, per uniformità con closeBtnClass/addBtnClass/containerClass
|
|
6
6
|
// aggiunti sotto) e rendere tutti i parametri camelCase.
|
|
7
|
+
// TODO[epic=v2] rendere tutti i parametri camelCase, predisporre script di conversione automatica
|
|
7
8
|
// TODO[epic=v2] valutare se rendere opzionale, tramite parametro, l'importazione statica
|
|
8
9
|
// di sf-macro.css qui sopra (questione lasciata in sospeso).
|
|
9
10
|
|
|
@@ -20,6 +21,21 @@ import './sf-macro.css';
|
|
|
20
21
|
* @param {((row: Element | null, closeBtn: Element | null) => void) | null} [options.del_callback=null] - Chiamata dopo la rimozione di una riga; riceve la riga rimossa (ormai scollegata) e il pulsante di chiusura. (default: null)
|
|
21
22
|
* @param {boolean} [options.insertAtTop=false] - Se true, le nuove righe vengono inserite in cima. (default: false)
|
|
22
23
|
* @returns {void}
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* sf_macro({
|
|
27
|
+
* wrapper_selector: '.sf-macro-wrapper',
|
|
28
|
+
* row_selector: '.sf-macro-riga',
|
|
29
|
+
* closeBtnClass: 'sf-macro-close-btn',
|
|
30
|
+
* addBtnClass: 'sf-macro-riga-add',
|
|
31
|
+
* containerClass: 'sf-macro-container',
|
|
32
|
+
* insertAtTop: false,
|
|
33
|
+
* // addBtn è il pulsante di aggiunta (action_btn) su cui è avvenuto il click
|
|
34
|
+
* add_callback: (newRow, addBtn) => {},
|
|
35
|
+
* // closeBtn è il pulsante di rimozione (action_btn) su cui è avvenuto il click
|
|
36
|
+
* preDelCallback: async (row, closeBtn) => true,
|
|
37
|
+
* del_callback: (row, closeBtn) => {}
|
|
38
|
+
* });
|
|
23
39
|
*/
|
|
24
40
|
export function sf_macro({
|
|
25
41
|
wrapper_selector = '.sf-macro-wrapper',
|
package/src/css/grid.css
CHANGED
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
.grid {
|
|
4
4
|
--_cols: 1;
|
|
5
|
-
/* --_min-col-width: calc((100% - calc(var(--_cols) * var(--flex-grid-gap))) / var(--grid-cols)); NB custom prop rimossa */
|
|
6
5
|
|
|
7
6
|
display: grid;
|
|
8
|
-
/* grid-template-columns: repeat(var(--_cols), minmax(var(--grid-min-col-width), 1fr)); NB custom prop rimossa */
|
|
9
7
|
grid-template-columns: repeat(var(--_cols), minmax(0, 1fr));
|
|
10
8
|
grid-auto-flow: row;
|
|
11
9
|
gap: var(--flex-grid-gap);
|
|
@@ -28,7 +26,7 @@
|
|
|
28
26
|
@media (--media-large-viewport-up) {
|
|
29
27
|
--_cols: 4;
|
|
30
28
|
|
|
31
|
-
/* versione a
|
|
29
|
+
/* versione a 2-10 colonne */
|
|
32
30
|
&.grid-2 {
|
|
33
31
|
--_cols: 2;
|
|
34
32
|
}
|
|
@@ -44,9 +42,18 @@
|
|
|
44
42
|
&.grid-6 {
|
|
45
43
|
--_cols: 6;
|
|
46
44
|
}
|
|
45
|
+
&.grid-7 {
|
|
46
|
+
--_cols: 6;
|
|
47
|
+
}
|
|
47
48
|
&.grid-8 {
|
|
48
49
|
--_cols: 8;
|
|
49
50
|
}
|
|
51
|
+
&.grid-9 {
|
|
52
|
+
--_cols: 9;
|
|
53
|
+
}
|
|
54
|
+
&.grid-10 {
|
|
55
|
+
--_cols: 10;
|
|
56
|
+
}
|
|
50
57
|
|
|
51
58
|
> .span-2 {
|
|
52
59
|
grid-column-end: span 2;
|
|
@@ -54,10 +61,15 @@
|
|
|
54
61
|
> .span-3 {
|
|
55
62
|
grid-column-end: span 3;
|
|
56
63
|
}
|
|
57
|
-
|
|
58
64
|
> .span-4 {
|
|
59
65
|
grid-column-end: span 4;
|
|
60
66
|
}
|
|
67
|
+
> .span-5 {
|
|
68
|
+
grid-column-end: span 5;
|
|
69
|
+
}
|
|
70
|
+
> .span-6 {
|
|
71
|
+
grid-column-end: span 6;
|
|
72
|
+
}
|
|
61
73
|
} /* end @media */
|
|
62
74
|
|
|
63
75
|
/* grid items */
|
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
/*! minimo - buildPictureTag */
|
|
2
2
|
import { classnames } from '../classnames.js';
|
|
3
3
|
|
|
4
|
+
/*
|
|
5
|
+
* TODO valori di `sizes` in rem/em: permettere di indicare `from` e `size` anche in unità relative
|
|
6
|
+
* (es. `'40rem'`), oltre ai px numerici, sia nell'attributo `sizes` sia nelle condizioni media.
|
|
7
|
+
* Da definire come calcolare le dimensioni in px dei candidati `srcset` (es. base font-size configurabile).
|
|
8
|
+
*
|
|
9
|
+
*
|
|
10
|
+
* TODO rivedere e semplificare l'intera funzione (parametri, normalizzazione di `sizes`, calcolo dei
|
|
11
|
+
* candidati) e ampliare gli esempi iniziali del JSDoc, coprendo un numero maggiore di casi d'uso.
|
|
12
|
+
*
|
|
13
|
+
*
|
|
14
|
+
* TODO URL autonomo per singola size (override di `baseSrc`) — da valutare
|
|
15
|
+
*
|
|
16
|
+
* Obiettivo: permettere che ogni candidato dello `srcset` (per entry di `sizes`) ignori `baseSrc`
|
|
17
|
+
* e usi un URL completamente autonomo.
|
|
18
|
+
*
|
|
19
|
+
* Ipotesi A (array parallelo): nuovo parametro `baseSrcset`, array di stringhe o `{src, isViewer}`;
|
|
20
|
+
* per ogni entry di `sizes` si usa `baseSrcset[i]` al posto di `baseSrc`; se manca o è null, si usa `baseSrc`.
|
|
21
|
+
* Se `isViewer` è true (default) si aggiungono i parametri `bb`/`q`/`f`, altrimenti l'URL è usato tal quale.
|
|
22
|
+
*
|
|
23
|
+
* Ipotesi B (consigliata): proprietà `src` direttamente nella entry di `sizes`,
|
|
24
|
+
* `{ from, size, src: string | {src, isViewer} }`, senza array parallelo.
|
|
25
|
+
* Contro: le entry con override non possono usare la scorciatoia numerica.
|
|
26
|
+
*
|
|
27
|
+
* Dubbi da sciogliere:
|
|
28
|
+
* - A vs B: in A `sizes` viene riordinato per breakpoint, quindi `baseSrcset[i]` richiede di tracciare
|
|
29
|
+
* l'indice originale prima del sort (fragile).
|
|
30
|
+
* - `isViewer: false` e `formats`: un URL non gestito dal viewer non può essere convertito in
|
|
31
|
+
* avif/webp/pjpg. Proposta: usarlo tal quale in tutti gli `srcset` (`source` e `img`), con il formato
|
|
32
|
+
* a carico di chi lo passa. Alternative: solo nell'`img` di fallback, oppure omettere i `source`.
|
|
33
|
+
* - `dpr`: un URL non-viewer non è ridimensionabile, quindi un solo candidato per entry
|
|
34
|
+
* (descrittore `w` = larghezza della size) invece di uno per densità.
|
|
35
|
+
* - `baseSrc` obbligatorio solo se almeno una entry non ha override (oggi `null` se manca).
|
|
36
|
+
* - Una stringa semplice vale come `{src, isViewer: true}`: per un URL non-viewer serve sempre l'oggetto.
|
|
37
|
+
* - Aggiornare JSDoc (typedef, `@param baseSrc`, `@example` con caso misto).
|
|
38
|
+
*/
|
|
39
|
+
|
|
4
40
|
/**
|
|
5
41
|
* @typedef {Object} PictureSizeEntry
|
|
6
42
|
* @property {number} [from] - Breakpoint (px) da cui si applica la size (condizione media `width >=`); omesso nell'(unica) entry predefinita mobile-first.
|
|
@@ -68,7 +104,7 @@ import { classnames } from '../classnames.js';
|
|
|
68
104
|
* });
|
|
69
105
|
*
|
|
70
106
|
* @param {Object} args
|
|
71
|
-
* @param {string} args.baseSrc - URL base dell'immagine (endpoint del viewer); i suoi parametri di query vengono conservati.
|
|
107
|
+
* @param {string} args.baseSrc - URL base dell'immagine (endpoint del viewer); i suoi parametri di query vengono conservati. Un URL relativo (es. `/img/abc123`) viene risolto rispetto alla location corrente.
|
|
72
108
|
* @param {(number | [number, number] | PictureSizeEntry)[]} [args.sizes=[250]] - Dimensioni renderizzate dell'immagine, in qualsiasi ordine. Ogni entry è un oggetto `{from, size}` (vedi {@link PictureSizeEntry}); un numero semplice o una coppia `[width, height]` è la scorciatoia per l'entry predefinita mobile-first (quella senza `from`), attesa esattamente una volta (default: [250])
|
|
73
109
|
* @param {number|null} [args.ratio=null] - Aspect ratio predefinito (larghezza / altezza, come nella proprietà CSS `aspect-ratio`) usato per calcolare l'altezza delle size numeriche. Se null, l'altezza non viene calcolata: gli output legati all'altezza (attributo `height`, altezza nel parametro `bb`) vengono omessi e il viewer mantiene il ratio originale dell'immagine (default: null)
|
|
74
110
|
* @param {number} [args.dpr=2] - Densità di pixel massima (intero): i candidati di `srcset` vengono generati per ogni densità da 1 a `dpr` (default: 2)
|
|
@@ -143,7 +179,8 @@ export function buildPictureTag({
|
|
|
143
179
|
console.warn('[buildPictureTag] `sizes` must contain exactly one entry without `from` (the mobile-first default)');
|
|
144
180
|
}
|
|
145
181
|
|
|
146
|
-
|
|
182
|
+
// gli URL relativi (es. `/img/abc123`) vengono risolti rispetto alla location corrente
|
|
183
|
+
const base_url = new URL(baseSrc, globalThis.location?.href)
|
|
147
184
|
,searchParams = new URLSearchParams(base_url.search)
|
|
148
185
|
|
|
149
186
|
// dimensioni dei candidati srcset (una per ogni densità da 1 a `dpr`),
|
|
@@ -200,7 +237,7 @@ export function buildPictureTag({
|
|
|
200
237
|
searchParams.set('f', fmt);
|
|
201
238
|
|
|
202
239
|
srcsetSizes.forEach(([w, h]) => {
|
|
203
|
-
// TODO senza altezza `bb=<w>x` vale per
|
|
240
|
+
// TODO senza altezza `bb=<w>x` vale per il viewer di default: prevedere altre convenzioni (es. imgix)
|
|
204
241
|
searchParams.set('bb', `${w}x${h ?? ''}`);
|
|
205
242
|
base_url.search = searchParams.toString();
|
|
206
243
|
srcsetArray.push(`${base_url.toString()} ${w}w`);
|
package/types/classes.d.ts
CHANGED
|
@@ -76,12 +76,15 @@ export type MinimoClass =
|
|
|
76
76
|
| 'gap-0'
|
|
77
77
|
| 'gap-2'
|
|
78
78
|
| 'grid'
|
|
79
|
+
| 'grid-10'
|
|
79
80
|
| 'grid-2'
|
|
80
81
|
| 'grid-3'
|
|
81
82
|
| 'grid-4'
|
|
82
83
|
| 'grid-5'
|
|
83
84
|
| 'grid-6'
|
|
85
|
+
| 'grid-7'
|
|
84
86
|
| 'grid-8'
|
|
87
|
+
| 'grid-9'
|
|
85
88
|
| 'grid-full-row'
|
|
86
89
|
| 'grid-item-last'
|
|
87
90
|
| 'grid-new-row'
|
|
@@ -854,6 +857,8 @@ export type MinimoClass =
|
|
|
854
857
|
| 'span-2'
|
|
855
858
|
| 'span-3'
|
|
856
859
|
| 'span-4'
|
|
860
|
+
| 'span-5'
|
|
861
|
+
| 'span-6'
|
|
857
862
|
| 'spinner'
|
|
858
863
|
| 'table'
|
|
859
864
|
| 'table-bordered'
|