@massimo-cassandro/minimo 1.41.7 → 1.41.9
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/design-tokens/_src/flex-grid.minimo.tokens.mjs +10 -10
- package/dev-tools/starter-kit/source_files/app/index.js +6 -0
- package/dev-tools/starter-kit/source_files/root/CLAUDE.md +9 -0
- package/dev-tools/starter-kit/source_files/root/webpack.config.mjs +24 -23
- package/dev-tools/starter-kit/webpack-config-upg.md +34 -12
- package/package.json +1 -1
- package/src/css/grid.css +2 -2
- package/src/css/headings.css +2 -1
- package/src/css/text.css +6 -0
- package/src/custom-media.css +2 -2
- package/src/custom-properties.css +0 -3
- package/src/web-components/json-table/jt-docs/parametri-colonne.md +100 -0
- package/src/web-components/json-table/jt-docs.md +3 -99
- package/types/classes.d.ts +2 -0
|
@@ -5,14 +5,14 @@ export default {
|
|
|
5
5
|
$type: 'dimension'
|
|
6
6
|
}
|
|
7
7
|
},
|
|
8
|
-
grid: {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
8
|
+
// grid: {
|
|
9
|
+
// cols: {
|
|
10
|
+
// $value: 3,
|
|
11
|
+
// $type: 'number'
|
|
12
|
+
// },
|
|
13
|
+
// 'min-col-width': {
|
|
14
|
+
// $value: '6rem',
|
|
15
|
+
// $type: 'dimension'
|
|
16
|
+
// }
|
|
17
|
+
// }
|
|
18
18
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// webpack.config.mjs __project_name__
|
|
2
|
-
// v.3.
|
|
2
|
+
// v.3.2
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import webpack from 'webpack';
|
|
@@ -30,6 +30,20 @@ import { svgRules } from './webpack-config-modules/svg-rules.mjs';
|
|
|
30
30
|
// import { InlineCriticalCssPlugin } from './webpack-config-modules/inline-critical-css.mjs';
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
// =>> entries
|
|
34
|
+
// NB: percorsi dalla root del progetto
|
|
35
|
+
const entries = {
|
|
36
|
+
'index': './app/index.js',
|
|
37
|
+
|
|
38
|
+
'error-pages': './app/error-pages/error-pages.js',
|
|
39
|
+
|
|
40
|
+
// css critici da includere inline nei template html: il suffisso `.critical` nel nome
|
|
41
|
+
// della entry attiva l'istanza PurgeCSS dedicata con purge stretto
|
|
42
|
+
// (vedi purgecss-setup.mjs) e la regola dedicata in css-rules.mjs
|
|
43
|
+
'layout.critical': './app/css/layout.critical.css'
|
|
44
|
+
|
|
45
|
+
};
|
|
46
|
+
|
|
33
47
|
// --- config ---
|
|
34
48
|
const __filename = fileURLToPath(import.meta.url)
|
|
35
49
|
,__dirname = path.dirname(__filename);
|
|
@@ -132,7 +146,7 @@ const isDevelopment = process.env.NODE_ENV === 'development'
|
|
|
132
146
|
// PurgeCSS e plugin custom properties lavorano sugli asset css finali:
|
|
133
147
|
// in dev, con `false`, sono entrambi disattivati (build più veloce, css
|
|
134
148
|
// iniettato con style-loader; se `useCustomPropsPlugin` è true le definizioni
|
|
135
|
-
// vengono aggiunte per intero alle entry, vedi `
|
|
149
|
+
// vengono aggiunte per intero alle entry, vedi `parsedEntries`).
|
|
136
150
|
// Con `true` (a scopo di test) sono attivi come in produzione (secondo i
|
|
137
151
|
// rispettivi flag `usePurgeCss` / `useCustomPropsPlugin`) e `inlineCssInDevMode`
|
|
138
152
|
// viene forzato a false
|
|
@@ -256,31 +270,18 @@ const CopyWebpackPluginPatterns = [
|
|
|
256
270
|
/******************************/
|
|
257
271
|
/** CONFIG **/
|
|
258
272
|
|
|
259
|
-
// =>> entries
|
|
260
|
-
// NB: percorsi dalla root del progetto
|
|
261
|
-
const projectEntries = {
|
|
262
|
-
'index': './app/index.js',
|
|
263
|
-
|
|
264
|
-
'error-pages': './app/error-pages/error-pages.js',
|
|
265
|
-
|
|
266
|
-
// css critici da includere inline nei template html: il suffisso `.critical` nel nome
|
|
267
|
-
// della entry attiva l'istanza PurgeCSS dedicata con purge stretto
|
|
268
|
-
// (vedi purgecss-setup.mjs) e la regola dedicata in css-rules.mjs
|
|
269
|
-
'layout.critical': './app/css/layout.critical.css'
|
|
270
|
-
|
|
271
|
-
};
|
|
272
273
|
|
|
273
274
|
// dev senza plugin custom properties (`purgeCssInDev: false`, css iniettato con
|
|
274
275
|
// style-loader, quindi nessun asset css in cui il plugin possa inserire le
|
|
275
276
|
// definizioni): il file master con TUTTE le custom properties viene aggiunto come
|
|
276
277
|
// primo modulo di ogni entry (escluse le `.critical`). Non serve nessuna
|
|
277
278
|
// modifica ai template
|
|
278
|
-
const
|
|
279
|
-
? Object.fromEntries(Object.entries(
|
|
279
|
+
const parsedEntries = (useCustomPropsPlugin && isDevelopment && !purgeCssInDev)
|
|
280
|
+
? Object.fromEntries(Object.entries(entries).map(([name, entry]) => [
|
|
280
281
|
name,
|
|
281
282
|
/\.critical/.test(name) ? entry : [customPropsFile, ...[entry].flat()]
|
|
282
283
|
]))
|
|
283
|
-
:
|
|
284
|
+
: entries;
|
|
284
285
|
|
|
285
286
|
|
|
286
287
|
// regexp per gli asset css compilati di una entry: corrisponde a `nome.css` (dev con
|
|
@@ -291,9 +292,9 @@ const cssAssetRegexp = (entryName) =>
|
|
|
291
292
|
new RegExp(`^${entryName.replace(/[.+?^${}()|[\]\\]/g, '\\$&')}(\\.[^./]+)?\\.css$`);
|
|
292
293
|
|
|
293
294
|
// set del CustomPropsPurgeCssPlugin (vedi `sets` nei `plugins`). L'elenco delle entry
|
|
294
|
-
// css è derivato da `
|
|
295
|
-
const cssEntries = Object.keys(
|
|
296
|
-
,criticalEntries = Object.keys(
|
|
295
|
+
// css è derivato da `entries`: aggiungere una entry lì è sufficiente
|
|
296
|
+
const cssEntries = Object.keys(entries).filter(name => !/\.critical/.test(name))
|
|
297
|
+
,criticalEntries = Object.keys(entries).filter(name => /\.critical/.test(name))
|
|
297
298
|
,customPropsSets = [
|
|
298
299
|
|
|
299
300
|
// i critical css sono inline nei template: restano autosufficienti
|
|
@@ -343,7 +344,7 @@ const config = {
|
|
|
343
344
|
|
|
344
345
|
devtool: isDevelopment ? 'inline-source-map' : false,
|
|
345
346
|
|
|
346
|
-
entry:
|
|
347
|
+
entry: parsedEntries,
|
|
347
348
|
|
|
348
349
|
output: {
|
|
349
350
|
path: output_dir,
|
|
@@ -687,7 +688,7 @@ const config = {
|
|
|
687
688
|
// NB: evitare i wildcard `*`: 'index.*.css' non corrisponde a 'index.css'
|
|
688
689
|
// (dev con WEBPACK_SERVE) e corrisponde invece a 'index.critical.<hash>.css'.
|
|
689
690
|
// I set sono costruiti in `customPropsSets` (sopra) a partire da
|
|
690
|
-
// `
|
|
691
|
+
// `entries`, in base a `useSharedChunk`: aggiungendo una entry
|
|
691
692
|
// non serve modificare nulla qui
|
|
692
693
|
sets: customPropsSets,
|
|
693
694
|
|
|
@@ -10,18 +10,6 @@ Le versioni precedenti sono conservate in `archived/webpack-config-v2/` del repo
|
|
|
10
10
|
|
|
11
11
|
## Fix e upg da verificare e applicare a tutte le versioni
|
|
12
12
|
* WebpackManifestPlugin: impostare `removeKeyHash: /\?.*$/, // /([a-f0-9]{32}\.?)/gi, // /(\?as_asset)$/,`, sostituendo eventuali impostazione `removeKeyHash: true` se presente
|
|
13
|
-
* cacheGroup `shared` (solo con `useSharedChunk: true`): escludere `unsplash-page` e `blurhash` dal chunk condiviso, in modo che js e css restino nella entry che li importa. In `webpack.config.mjs`, nella funzione `shared_chunk_paths`, prima del `return` aggiungere:
|
|
14
|
-
```js
|
|
15
|
-
const excluded_paths = [
|
|
16
|
-
'minimo/src/components/unsplash-page',
|
|
17
|
-
'node_modules/blurhash', // peer dep usata solo da unsplash-page
|
|
18
|
-
];
|
|
19
|
-
const excludedRegexp = new RegExp(
|
|
20
|
-
excluded_paths.map(p => `${sep}${p.replace(/\//g, sep)}${sep}`).join('|')
|
|
21
|
-
);
|
|
22
|
-
const modulePath = module.nameForCondition?.() ?? '';
|
|
23
|
-
```
|
|
24
|
-
e sostituire il `return` con `return !excludedRegexp.test(modulePath) && pathsRegexp.test(modulePath);`. Aggiungere anche al commento sopra il cacheGroup la nota sull'esclusione.
|
|
25
13
|
|
|
26
14
|
|
|
27
15
|
## Da v2 a v3
|
|
@@ -255,3 +243,37 @@ Con `useSharedChunk = false` i template **non** devono referenziare `shared.css`
|
|
|
255
243
|
1. `NODE_ENV=production npx webpack --config ./webpack.config.mjs --stats minimal`: nessun errore o warning del plugin.
|
|
256
244
|
2. Nel css con le definizioni non compaiono props di web components non importati (es. `--jt-*`, `--sdt-*`); per un componente importato con `?raw` le sue props sono presenti.
|
|
257
245
|
3. Con `useSharedChunk = false`: in `build/` non esistono `shared.*` né `runtime.*` e le definizioni sono nel solo css di `mainEntry`.
|
|
246
|
+
|
|
247
|
+
### 6. Fix da applicare (solo con `useSharedChunk: true`)
|
|
248
|
+
|
|
249
|
+
* cacheGroup `shared` (solo con `useSharedChunk: true`): escludere `unsplash-page` e `blurhash` dal chunk condiviso, in modo che js e css restino nella entry che li importa. In `webpack.config.mjs`, nella funzione `shared_chunk_paths`, prima del `return` aggiungere:
|
|
250
|
+
```js
|
|
251
|
+
const excluded_paths = [
|
|
252
|
+
'minimo/src/components/unsplash-page',
|
|
253
|
+
'node_modules/blurhash', // peer dep usata solo da unsplash-page
|
|
254
|
+
];
|
|
255
|
+
const excludedRegexp = new RegExp(
|
|
256
|
+
excluded_paths.map(p => `${sep}${p.replace(/\//g, sep)}${sep}`).join('|')
|
|
257
|
+
);
|
|
258
|
+
const modulePath = module.nameForCondition?.() ?? '';
|
|
259
|
+
```
|
|
260
|
+
e sostituire il `return` con `return !excludedRegexp.test(modulePath) && pathsRegexp.test(modulePath);`. Aggiungere anche al commento sopra il cacheGroup la nota sull'esclusione.
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
## Da v3.1 a v3.2
|
|
264
|
+
|
|
265
|
+
Novità della v3.2: nessuna modifica di comportamento, solo riorganizzazione per rendere più agevole l'uso del config. Il blocco delle entry del progetto è spostato in cima al file (subito dopo gli import, prima di `// --- config ---`) e rinominato da `projectEntries` a `entries`; la costante `entries` che conteneva le entry elaborate per il dev (con il file master delle custom properties) è rinominata `parsedEntries`. Così le entry, che sono la parte da personalizzare in ogni progetto, si trovano subito e non vanno cercate a metà file. I moduli in `webpack-config-modules/` non cambiano.
|
|
266
|
+
|
|
267
|
+
Prompt per aggiornare un progetto esistente:
|
|
268
|
+
|
|
269
|
+
```text
|
|
270
|
+
Aggiorna il mio webpack.config.mjs dalla v.3.1 alla v.3.2 con queste modifiche, senza toccare altro:
|
|
271
|
+
|
|
272
|
+
1. Riga 2: `// v.3.1` → `// v.3.2`.
|
|
273
|
+
2. Rinomina l'attuale costante `entries` (quella con la logica `useCustomPropsPlugin && isDevelopment && !purgeCssInDev`, che aggiunge `customPropsFile` come primo modulo delle entry non `.critical`) in `parsedEntries`. Aggiorna i riferimenti: `entry: entries` → `entry: parsedEntries` nella config e i commenti che citano `entries` in questo senso (es. nel commento sopra `purgeCssInDev`: "vedi `entries`" → "vedi `parsedEntries`").
|
|
274
|
+
3. Rinomina `projectEntries` in `entries` in tutto il file (definizione, uso in `parsedEntries`, `cssEntries`, `criticalEntries` e commenti).
|
|
275
|
+
4. Sposta l'intero blocco `// =>> entries` + `const entries = { ... };` (con le entry già presenti nel progetto, che vanno mantenute così come sono) in cima al file, subito dopo gli import e prima di `// --- config ---`, lasciando due righe vuote prima del blocco e una dopo.
|
|
276
|
+
5. Verifica con `grep -n "projectEntries" webpack.config.mjs` (nessun risultato) e con `NODE_ENV=production npx webpack --config ./webpack.config.mjs --stats minimal` (nessun errore).
|
|
277
|
+
|
|
278
|
+
Mostrami il diff prima di salvare.
|
|
279
|
+
```
|
package/package.json
CHANGED
package/src/css/grid.css
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
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)); */
|
|
5
|
+
/* --_min-col-width: calc((100% - calc(var(--_cols) * var(--flex-grid-gap))) / var(--grid-cols)); NB custom prop rimossa */
|
|
6
6
|
|
|
7
7
|
display: grid;
|
|
8
|
-
/* grid-template-columns: repeat(var(--_cols), minmax(var(--grid-min-col-width), 1fr)); */
|
|
8
|
+
/* grid-template-columns: repeat(var(--_cols), minmax(var(--grid-min-col-width), 1fr)); NB custom prop rimossa */
|
|
9
9
|
grid-template-columns: repeat(var(--_cols), minmax(0, 1fr));
|
|
10
10
|
grid-auto-flow: row;
|
|
11
11
|
gap: var(--flex-grid-gap);
|
package/src/css/headings.css
CHANGED
package/src/css/text.css
CHANGED
package/src/custom-media.css
CHANGED
|
@@ -21,7 +21,7 @@ tablet alt:
|
|
|
21
21
|
53.75rem : 860px medium (tablet)
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
@custom-media --media-xxlarge-viewport-up (width >= 90rem);
|
|
25
25
|
@custom-media --media-xlarge-viewport-up (width >= 80rem);
|
|
26
26
|
@custom-media --media-large-viewport-up (width >= 64rem);
|
|
27
27
|
@custom-media --media-medium-viewport-up (width >= 47.5rem);
|
|
@@ -37,4 +37,4 @@ tablet alt:
|
|
|
37
37
|
@custom-media --media-xlarge-viewport-down (max-width: 80rem);
|
|
38
38
|
@custom-media --media-large-viewport-down (max-width: 64rem);
|
|
39
39
|
@custom-media --media-medium-viewport-down (max-width: 47.5rem);
|
|
40
|
-
|
|
40
|
+
@custom-media --media-small-viewport-down (max-width: 25rem);
|
|
@@ -205,9 +205,6 @@
|
|
|
205
205
|
--form-validation-outline-offset: -3px;
|
|
206
206
|
--form-validation-outline-width: 3px;
|
|
207
207
|
|
|
208
|
-
--grid-cols: 3;
|
|
209
|
-
--grid-min-col-width: 6rem;
|
|
210
|
-
|
|
211
208
|
--headings-color: var(--text-color);
|
|
212
209
|
--headings-font-family: var(--font-family);
|
|
213
210
|
--headings-font-weight: var(--font-weight-semibold);
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
# Parametri Colonne – `cols`
|
|
4
|
+
|
|
5
|
+
Parametro **obbligatorio**: array di oggetti, uno per colonna:
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
cols: [
|
|
9
|
+
{
|
|
10
|
+
key, // string – OBBLIGATORIO: chiave dell'oggetto riga (ammessa la notazione con
|
|
11
|
+
// punto per valori annidati, es. 'owner.name')
|
|
12
|
+
title, // contenuto del <th>: testo, HTML, Node, array domBuilder o funzione.
|
|
13
|
+
// Nelle colonne ordinabili è il testo del pulsante. Default: la chiave
|
|
14
|
+
dataType, // string – tipo di dato, una delle chiavi di `dataTypes`; `type` è un alias
|
|
15
|
+
// equivalente. Default: 'string'
|
|
16
|
+
render, // (row, tr, td) => contenuto | stringa mustache-like – vedi sotto. Default: null
|
|
17
|
+
tfootRender, // (rows, td) => contenuto | aggregato '@…' | stringa statica – contenuto della
|
|
18
|
+
// cella del tfoot (solo se `tfoot` è true). null = cella vuota. Default: null
|
|
19
|
+
rowHeading, // boolean – se true la cella è un'intestazione di riga (th[scope=row]).
|
|
20
|
+
// Default: false
|
|
21
|
+
searchable, // boolean – abilita la ricerca sulla colonna. Default: true
|
|
22
|
+
sortable, // boolean – abilita l'ordinamento sulla colonna. Default: true
|
|
23
|
+
sortValue, // valore | row => valore – valore usato per l'ordinamento; prevale su quello
|
|
24
|
+
// del tipo di dato. Default: non impostato (tipo di dato / valore grezzo)
|
|
25
|
+
searchValue, // idem, per la ricerca. Default: non impostato
|
|
26
|
+
condition, // boolean | params => boolean – se false la colonna non viene renderizzata.
|
|
27
|
+
// Default: true
|
|
28
|
+
headerClass, // string – classi del <th>, in sostituzione di quelle del tipo di dato
|
|
29
|
+
cellClass // string – classi delle celle body/tfoot, in sostituzione di quelle del tipo.
|
|
30
|
+
// Se solo una tra `headerClass` e `cellClass` è presente, l'altra assume lo
|
|
31
|
+
// stesso valore. Default: null (classi del tipo di dato)
|
|
32
|
+
},
|
|
33
|
+
...
|
|
34
|
+
]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## `render`
|
|
38
|
+
|
|
39
|
+
Funzione con argomenti posizionali, tutti facoltativi:
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
render: (row, tr, td) => contenuto
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- `row` – l'oggetto dati della riga
|
|
46
|
+
- `tr` – l'elemento `<tr>` della riga
|
|
47
|
+
- `td` – l'elemento della cella (`<td>` o `<th scope="row">`)
|
|
48
|
+
|
|
49
|
+
Il valore restituito è il contenuto della cella: testo, stringa HTML, numero, Node o array
|
|
50
|
+
domBuilder. Casi particolari:
|
|
51
|
+
|
|
52
|
+
- `undefined` (nessun `return`): la cella viene renderizzata dal tipo di dato, come se `render`
|
|
53
|
+
non fosse definito. Utile per decorare soltanto `td`/`tr` (classi, attributi, `title`):
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
render: (row, tr, td) => { if (row.amount < 0) td.classList.add('text-danger'); }
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- `null`: viene mostrato `renderNullAs`
|
|
60
|
+
|
|
61
|
+
Da attributo HTML (o da script, per i casi semplici) `render` può essere una stringa
|
|
62
|
+
mustache-like: ogni segnaposto `[[key]]` viene sostituito con il valore corrispondente della
|
|
63
|
+
riga (chiavi annidate ammesse; i valori null diventano `renderNullAs`):
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
render: '<a href="/users/[[id]]">[[owner.name]]</a>'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Le stringhe HTML vengono inserite tramite la Sanitizer API (`Element.setHTML`, dove supportata):
|
|
70
|
+
script, attributi handler di eventi e URL `javascript:` vengono rimossi, mentre `class`, `id`,
|
|
71
|
+
`style` e `data-*` sono conservati.
|
|
72
|
+
|
|
73
|
+
## `tfootRender`
|
|
74
|
+
|
|
75
|
+
Con `tfoot: true` ogni colonna produce una cella nel footer, il cui contenuto è dato da
|
|
76
|
+
`tfootRender`:
|
|
77
|
+
|
|
78
|
+
- funzione `(rows, td) => contenuto`, dove `rows` è l'intero set filtrato (oppure i soli record
|
|
79
|
+
della pagina corrente se `updateFooterOnPageChange` è true)
|
|
80
|
+
- uno degli aggregati predefiniti (vedi sotto)
|
|
81
|
+
- qualsiasi altra stringa: contenuto statico (es. l'etichetta `'Totale'`)
|
|
82
|
+
- `null`: cella vuota
|
|
83
|
+
|
|
84
|
+
Aggregati predefiniti, calcolati sui valori **numerici** della colonna (i valori non numerici
|
|
85
|
+
vengono ignorati) e, tranne `@count`, formattati dal tipo di dato della colonna (es. come valuta
|
|
86
|
+
per `euro`, con `%` per `perc`):
|
|
87
|
+
|
|
88
|
+
| Aggregato | Valore |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `'@sum'` | somma |
|
|
91
|
+
| `'@avg'` | media aritmetica |
|
|
92
|
+
| `'@min'` | minimo |
|
|
93
|
+
| `'@max'` | massimo |
|
|
94
|
+
| `'@count'` | numero di valori numerici (formattato con `locale`, senza il tipo di dato) |
|
|
95
|
+
|
|
96
|
+
Un aggregato non riconosciuto viene segnalato in console e produce una cella vuota. Le celle del
|
|
97
|
+
footer ricevono le stesse classi (`cellClass`) delle celle del body.
|
|
98
|
+
|
|
99
|
+
Il `tfoot` non è disponibile in modalità server-side (il componente riceve solo la pagina
|
|
100
|
+
corrente, gli aggregati sarebbero parziali): se richiesto viene ignorato con un avviso in console.
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# `<json-table>` – datatable da JSON
|
|
2
2
|
|
|
3
3
|
* [Parametri (include `classes` e `labels`)](jt-docs/parametri.md)
|
|
4
|
+
* [Parametri colonne](jt-docs/parametri-colonne.md)
|
|
5
|
+
|
|
6
|
+
---
|
|
4
7
|
|
|
5
8
|
**json-table** costruisce una tabella HTML da un array di dati JSON (inline o caricato via fetch), a partire da una definizione delle colonne (`cols`) e da un insieme di tipi di dato predefiniti ed estendibili, con ordinamento, ricerca e paginazione (lato client oppure, con `serverSide: true`, delegati al server). È un web component light DOM senza dipendenze esterne: può quindi essere stilizzato direttamente dal CSS del progetto in cui è utilizzato.
|
|
6
9
|
|
|
@@ -216,105 +219,6 @@ el.init({ jsonUrl: '/api/rows.json', cols: [...] });
|
|
|
216
219
|
|
|
217
220
|
|
|
218
221
|
|
|
219
|
-
## Colonne – `cols`
|
|
220
|
-
|
|
221
|
-
Parametro **obbligatorio**: array di oggetti, uno per colonna:
|
|
222
|
-
|
|
223
|
-
```javascript
|
|
224
|
-
cols: [
|
|
225
|
-
{
|
|
226
|
-
key, // string – OBBLIGATORIO: chiave dell'oggetto riga (ammessa la notazione con
|
|
227
|
-
// punto per valori annidati, es. 'owner.name')
|
|
228
|
-
title, // contenuto del <th>: testo, HTML, Node, array domBuilder o funzione.
|
|
229
|
-
// Nelle colonne ordinabili è il testo del pulsante. Default: la chiave
|
|
230
|
-
dataType, // string – tipo di dato, una delle chiavi di `dataTypes`; `type` è un alias
|
|
231
|
-
// equivalente. Default: 'string'
|
|
232
|
-
render, // (row, tr, td) => contenuto | stringa mustache-like – vedi sotto. Default: null
|
|
233
|
-
tfootRender, // (rows, td) => contenuto | aggregato '@…' | stringa statica – contenuto della
|
|
234
|
-
// cella del tfoot (solo se `tfoot` è true). null = cella vuota. Default: null
|
|
235
|
-
rowHeading, // boolean – se true la cella è un'intestazione di riga (th[scope=row]).
|
|
236
|
-
// Default: false
|
|
237
|
-
searchable, // boolean – abilita la ricerca sulla colonna. Default: true
|
|
238
|
-
sortable, // boolean – abilita l'ordinamento sulla colonna. Default: true
|
|
239
|
-
sortValue, // valore | row => valore – valore usato per l'ordinamento; prevale su quello
|
|
240
|
-
// del tipo di dato. Default: non impostato (tipo di dato / valore grezzo)
|
|
241
|
-
searchValue, // idem, per la ricerca. Default: non impostato
|
|
242
|
-
condition, // boolean | params => boolean – se false la colonna non viene renderizzata.
|
|
243
|
-
// Default: true
|
|
244
|
-
headerClass, // string – classi del <th>, in sostituzione di quelle del tipo di dato
|
|
245
|
-
cellClass // string – classi delle celle body/tfoot, in sostituzione di quelle del tipo.
|
|
246
|
-
// Se solo una tra `headerClass` e `cellClass` è presente, l'altra assume lo
|
|
247
|
-
// stesso valore. Default: null (classi del tipo di dato)
|
|
248
|
-
},
|
|
249
|
-
...
|
|
250
|
-
]
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### `render`
|
|
254
|
-
|
|
255
|
-
Funzione con argomenti posizionali, tutti facoltativi:
|
|
256
|
-
|
|
257
|
-
```javascript
|
|
258
|
-
render: (row, tr, td) => contenuto
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
- `row` – l'oggetto dati della riga
|
|
262
|
-
- `tr` – l'elemento `<tr>` della riga
|
|
263
|
-
- `td` – l'elemento della cella (`<td>` o `<th scope="row">`)
|
|
264
|
-
|
|
265
|
-
Il valore restituito è il contenuto della cella: testo, stringa HTML, numero, Node o array
|
|
266
|
-
domBuilder. Casi particolari:
|
|
267
|
-
|
|
268
|
-
- `undefined` (nessun `return`): la cella viene renderizzata dal tipo di dato, come se `render`
|
|
269
|
-
non fosse definito. Utile per decorare soltanto `td`/`tr` (classi, attributi, `title`):
|
|
270
|
-
|
|
271
|
-
```javascript
|
|
272
|
-
render: (row, tr, td) => { if (row.amount < 0) td.classList.add('text-danger'); }
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
- `null`: viene mostrato `renderNullAs`
|
|
276
|
-
|
|
277
|
-
Da attributo HTML (o da script, per i casi semplici) `render` può essere una stringa
|
|
278
|
-
mustache-like: ogni segnaposto `[[key]]` viene sostituito con il valore corrispondente della
|
|
279
|
-
riga (chiavi annidate ammesse; i valori null diventano `renderNullAs`):
|
|
280
|
-
|
|
281
|
-
```javascript
|
|
282
|
-
render: '<a href="/users/[[id]]">[[owner.name]]</a>'
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
Le stringhe HTML vengono inserite tramite la Sanitizer API (`Element.setHTML`, dove supportata):
|
|
286
|
-
script, attributi handler di eventi e URL `javascript:` vengono rimossi, mentre `class`, `id`,
|
|
287
|
-
`style` e `data-*` sono conservati.
|
|
288
|
-
|
|
289
|
-
### `tfootRender`
|
|
290
|
-
|
|
291
|
-
Con `tfoot: true` ogni colonna produce una cella nel footer, il cui contenuto è dato da
|
|
292
|
-
`tfootRender`:
|
|
293
|
-
|
|
294
|
-
- funzione `(rows, td) => contenuto`, dove `rows` è l'intero set filtrato (oppure i soli record
|
|
295
|
-
della pagina corrente se `updateFooterOnPageChange` è true)
|
|
296
|
-
- uno degli aggregati predefiniti (vedi sotto)
|
|
297
|
-
- qualsiasi altra stringa: contenuto statico (es. l'etichetta `'Totale'`)
|
|
298
|
-
- `null`: cella vuota
|
|
299
|
-
|
|
300
|
-
Aggregati predefiniti, calcolati sui valori **numerici** della colonna (i valori non numerici
|
|
301
|
-
vengono ignorati) e, tranne `@count`, formattati dal tipo di dato della colonna (es. come valuta
|
|
302
|
-
per `euro`, con `%` per `perc`):
|
|
303
|
-
|
|
304
|
-
| Aggregato | Valore |
|
|
305
|
-
|---|---|
|
|
306
|
-
| `'@sum'` | somma |
|
|
307
|
-
| `'@avg'` | media aritmetica |
|
|
308
|
-
| `'@min'` | minimo |
|
|
309
|
-
| `'@max'` | massimo |
|
|
310
|
-
| `'@count'` | numero di valori numerici (formattato con `locale`, senza il tipo di dato) |
|
|
311
|
-
|
|
312
|
-
Un aggregato non riconosciuto viene segnalato in console e produce una cella vuota. Le celle del
|
|
313
|
-
footer ricevono le stesse classi (`cellClass`) delle celle del body.
|
|
314
|
-
|
|
315
|
-
Il `tfoot` non è disponibile in modalità server-side (il componente riceve solo la pagina
|
|
316
|
-
corrente, gli aggregati sarebbero parziali): se richiesto viene ignorato con un avviso in console.
|
|
317
|
-
|
|
318
222
|
## Tipi di dato – `dataTypes`
|
|
319
223
|
|
|
320
224
|
Ogni colonna ha un tipo di dato (`dataType`, default `string`) che ne definisce classi, rendering
|
package/types/classes.d.ts
CHANGED
|
@@ -863,6 +863,7 @@ export type MinimoClass =
|
|
|
863
863
|
| 'text-danger'
|
|
864
864
|
| 'text-end'
|
|
865
865
|
| 'text-info'
|
|
866
|
+
| 'text-lower'
|
|
866
867
|
| 'text-md'
|
|
867
868
|
| 'text-monospace'
|
|
868
869
|
| 'text-muted'
|
|
@@ -874,6 +875,7 @@ export type MinimoClass =
|
|
|
874
875
|
| 'text-sm'
|
|
875
876
|
| 'text-success'
|
|
876
877
|
| 'text-truncate'
|
|
878
|
+
| 'text-upper'
|
|
877
879
|
| 'text-warning'
|
|
878
880
|
| 'text-xs'
|
|
879
881
|
| 'valign-middle'
|