@massimo-cassandro/minimo 1.41.3 → 1.41.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/README.md +12 -12
- package/charts/src/node-helpers/create-svg-canvas-node.mjs +2 -2
- package/charts/src/node-helpers/svg-text-to-path.js +9 -9
- package/charts/src/rating-display/index.js +1 -1
- package/charts/src/rating-display/ratindDisplayAnimation.js +3 -3
- package/design-tokens/README.md +2 -2
- package/design-tokens/_src/_readme.md +26 -26
- package/dev-tools/README.md +16 -16
- package/dev-tools/create-favicons/README.md +31 -31
- package/dev-tools/create-favicons/src/create-ico.mjs +2 -2
- package/dev-tools/create-favicons/src/default-params.mjs +1 -1
- package/dev-tools/create-favicons/src/init.mjs +1 -1
- package/dev-tools/design-tokens-builder/README.md +102 -102
- package/dev-tools/design-tokens-builder/build-tokens-src/build-source-modes.mjs +85 -73
- package/dev-tools/design-tokens-builder/build-tokens-src/config.mjs +109 -85
- package/dev-tools/design-tokens-builder/build-tokens-src/formats/css.mjs +113 -90
- package/dev-tools/design-tokens-builder/build-tokens-src/formats/json.mjs +107 -95
- package/dev-tools/design-tokens-builder/build-tokens-src/legacy-tokens-parser.mjs +71 -64
- package/dev-tools/design-tokens-builder/build-tokens-src/light-dark.mjs +75 -65
- package/dev-tools/design-tokens-builder/build-tokens-src/merge-css.mjs +113 -102
- package/dev-tools/design-tokens-builder/build-tokens-src/platforms.mjs +36 -30
- package/dev-tools/design-tokens-builder/build-tokens-src/resolve-source-paths.mjs +15 -13
- package/dev-tools/design-tokens-builder/build-tokens-src/source-prefixes.mjs +44 -42
- package/dev-tools/design-tokens-builder/build-tokens-src/source-transforms.mjs +89 -83
- package/dev-tools/design-tokens-builder/build-tokens-src/token-rename-parser.mjs +99 -86
- package/dev-tools/design-tokens-builder/build-tokens-src/transforms.mjs +64 -48
- package/dev-tools/design-tokens-builder/build-tokens.mjs +80 -68
- package/dev-tools/design-tokens-builder/check-unresolved-custom-props.mjs +103 -77
- package/dev-tools/design-tokens-builder/tokens-config-sample.mjs +275 -238
- package/dev-tools/find-orphan-css-classes/find-orphan-css-classes.mjs +2 -2
- package/dev-tools/starter-kit/source_files/app/CLAUDE.md +4 -2
- package/dev-tools/starter-kit/source_files/app/index.css +10 -0
- package/dev-tools/starter-kit/source_files/app/index.js +1 -1
- package/dev-tools/starter-kit/source_files/root/_sf/controller/ImgViewerController.php +3 -3
- package/dev-tools/starter-kit/source_files/root/_sf/controller/ViewerController.php +2 -2
- package/dev-tools/starter-kit/source_files/root/stylelint.config.mjs +1 -1
- package/dev-tools/starter-kit/source_files/root/webpack-config-modules/css-rules.mjs +1 -1
- package/dev-tools/starter-kit/starter-install.sh +2 -2
- package/dev-tools/stylelint-config/README.md +7 -7
- package/dev-tools/svg-icons-tools/README.md +32 -32
- package/dev-tools/svg-icons-tools/src/config-manager.mjs +1 -1
- package/dev-tools/svg-icons-tools/src/default-config.mjs +118 -118
- package/dev-tools/svg-icons-tools/src/jsx-icon-file-builder.mjs +24 -24
- package/dev-tools/svg-icons-tools/src/parse-svg-filename.mjs +3 -3
- package/dev-tools/svg-icons-tools/src/parse-svg-files.mjs +1 -1
- package/dev-tools/svg-icons-tools/src/parse-svg-markup.mjs +4 -4
- package/dev-tools/svg-icons-tools/src/svg-to-jsx.mjs +2 -2
- package/dev-tools/svg-icons-tools/src/svg-to-optimized.mjs +2 -2
- package/dev-tools/svg-icons-tools/src/svg-to-symbols.mjs +2 -2
- package/dev-tools/upd@m/README.md +1 -1
- package/dev-tools/upd@m/index.mjs +1 -1
- package/dev-tools/update-version/README.md +9 -9
- package/index.js +1 -0
- package/package.json +3 -1
- package/snippets/unsplash-browser-app/README.md +1 -1
- package/snippets/unsplash-browser-app/unsplash-utilities.js +9 -9
- package/src/components/autocomplete/README.md +3 -3
- package/src/components/autocomplete/autocomplete-engine.js +75 -63
- package/src/components/autocomplete/check-autocomplete.js +3 -3
- package/src/components/dismiss-alerts.js +3 -3
- package/src/components/form-reset-submit.js +6 -6
- package/src/components/inner-nav/inner-nav.js +2 -2
- package/src/components/modal-alert/modal-alert.js +67 -65
- package/src/components/modal-alert/modal-alert.minimo.tokens.mjs +1 -1
- package/src/components/modal-popup/modal-popup.js +56 -56
- package/src/components/overlay/overlay.js +3 -3
- package/src/components/sf-macro/readme.md +1 -1
- package/src/components/sf-macro/sf-macro.js +27 -23
- package/src/components/slide-up-down-toggle/slide-up-down-toggle.js +83 -79
- package/src/components/slide-up-down-toggle/slide-up-down-toggle.module.css +44 -44
- package/src/components/snackbar/snackbar.js +19 -19
- package/src/components/spinner/spinner.js +3 -3
- package/src/components/unsplash-page/README.md +8 -8
- package/src/components/unsplash-page/fetch-unsplash-data.js +3 -3
- package/src/components/unsplash-page/unsplash-page.js +33 -33
- package/src/components/unsplash-page/unsplash-page.module.css +1 -1
- package/src/css/alerts.css +2 -2
- package/src/css/forms/forms.css +4 -4
- package/src/css/forms/validation.css +1 -1
- package/src/css/margin-padding-media.css +4 -4
- package/src/css/margin-padding.css +4 -4
- package/src/css/reset.css +11 -11
- package/src/icons/read-me.md +1 -1
- package/src/minimo.css +3 -9
- package/src/utilities/better-text-with-places.js +105 -105
- package/src/utilities/better-text.js +42 -35
- package/src/utilities/classnames.js +8 -8
- package/src/utilities/cookies.js +6 -6
- package/src/utilities/create-id.js +3 -3
- package/src/utilities/disable-btns-on-submit.js +2 -2
- package/src/utilities/dom-builder/dom-builder.js +89 -86
- package/src/utilities/dom-builder/domBuilderBasicSetup.js +9 -9
- package/src/utilities/dom-builder/parseDomString.js +23 -23
- package/src/utilities/dom-builder-helpers/README.md +2 -2
- package/src/utilities/dom-builder-helpers/form-tags.js +100 -100
- package/src/utilities/dom-builder-helpers/picture-tag.js +39 -39
- package/src/utilities/enable-submit-btns.js +1 -1
- package/src/utilities/escape-html.js +2 -2
- package/src/utilities/generate-pwd.js +4 -4
- package/src/utilities/linked-dates.js +13 -13
- package/src/utilities/parse-file-size.js +6 -6
- package/src/utilities/random-id.js +3 -3
- package/src/utilities/relative-date.js +40 -40
- package/src/utilities/sentence-case.js +1 -1
- package/src/utilities/strip-tags.js +1 -1
- package/src/utilities/title-case.js +1 -1
- package/src/utilities/truncate-string.js +5 -5
- package/src/utilities/validation-error-class.js +12 -12
- package/src/web-components/json-table/json-table-component.js +123 -121
- package/src/web-components/json-table/json-table-component.module.css +6 -6
- package/src/web-components/json-table/json-table.minimo.tokens.mjs +6 -6
- package/src/web-components/json-table/readme.md +76 -110
- package/src/web-components/json-table/src/cell-content.js +25 -25
- package/src/web-components/json-table/src/content-utils.js +21 -21
- package/src/web-components/json-table/src/data-types.js +32 -32
- package/src/web-components/json-table/src/defaults.js +230 -191
- package/src/web-components/json-table/src/get-data.js +55 -38
- package/src/web-components/json-table/src/icons.js +17 -17
- package/src/web-components/json-table/src/info-section.js +18 -18
- package/src/web-components/json-table/src/main-builder.js +45 -45
- package/src/web-components/json-table/src/pagination.js +32 -32
- package/src/web-components/json-table/src/parse-cols.js +18 -18
- package/src/web-components/json-table/src/parse-rows.js +17 -17
- package/src/web-components/json-table/src/resolve-params.js +53 -41
- package/src/web-components/json-table/src/search.js +13 -13
- package/src/web-components/json-table/src/sorting.js +20 -20
- package/src/web-components/json-table/src/table-body.js +13 -13
- package/src/web-components/json-table/src/table-builder.js +34 -34
- package/src/web-components/json-table/src/table-tfoot.js +8 -8
- package/src/web-components/json-table/src/table-thead.js +21 -21
- package/src/web-components/json-table/src/update-info.js +11 -11
- package/types/classes.d.ts +2 -2
- package/types/global.d.ts +18 -12
|
@@ -24,38 +24,38 @@ import { domBuilder } from '../../utilities/dom-builder/dom-builder.js';
|
|
|
24
24
|
/** @typedef {import('./src/main-builder.js').JsonTableElements} JsonTableElements */
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* Stato del rendering.
|
|
28
28
|
*
|
|
29
|
-
*
|
|
30
|
-
* `pageRows`
|
|
31
|
-
*
|
|
29
|
+
* Modalità client-side: `rows` contiene tutte le righe analizzate, `filtered` le righe dopo ricerca e ordinamento,
|
|
30
|
+
* `pageRows` la porzione della pagina corrente. Modalità server-side: i tre array contengono le righe
|
|
31
|
+
* restituite dall'ultima richiesta (la pagina corrente), `totRec`/`filteredRec` provengono dal JSON.
|
|
32
32
|
*
|
|
33
33
|
* @typedef {Object} JsonTableState
|
|
34
|
-
* @property {number} totRec -
|
|
35
|
-
* @property {number} filteredRec -
|
|
36
|
-
* @property {ParsedRow[]} rows -
|
|
37
|
-
* @property {ParsedRow[]} filtered -
|
|
38
|
-
* @property {ParsedRow[]} pageRows -
|
|
39
|
-
* @property {string} searchTerm -
|
|
40
|
-
* @property {SortDef|null} sort -
|
|
41
|
-
* @property {number} page -
|
|
42
|
-
* @property {number} totPages -
|
|
34
|
+
* @property {number} totRec - Numero totale di record (non filtrati, vedi `totRecField`)
|
|
35
|
+
* @property {number} filteredRec - Numero di record che corrispondono alla ricerca corrente
|
|
36
|
+
* @property {ParsedRow[]} rows - Tutte le righe analizzate (solo la pagina corrente in modalità server-side)
|
|
37
|
+
* @property {ParsedRow[]} filtered - Righe dopo ricerca e ordinamento
|
|
38
|
+
* @property {ParsedRow[]} pageRows - Righe della pagina corrente
|
|
39
|
+
* @property {string} searchTerm - Termine di ricerca attivo ('' = nessuno)
|
|
40
|
+
* @property {SortDef|null} sort - Ordinamento attivo (chiave della colonna e direzione), oppure null
|
|
41
|
+
* @property {number} page - Pagina corrente (da 1)
|
|
42
|
+
* @property {number} totPages - Numero totale di pagine (1 quando la paginazione è disattivata)
|
|
43
43
|
*/
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* Motivo di un aggiornamento dello stato, passato nel detail dell'evento `jt:update`.
|
|
47
47
|
* @typedef {'page'|'sort'|'search'} UpdateReason
|
|
48
48
|
*/
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
51
|
+
* Default a livello di progetto, impostati con `JsonTable.setDefaults()`.
|
|
52
|
+
* A livello di modulo, così da essere condivisi da ogni istanza.
|
|
53
53
|
* @type {Partial<JsonTableParams>}
|
|
54
54
|
*/
|
|
55
55
|
let projectDefaults = {};
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
58
|
+
* Stato vuoto.
|
|
59
59
|
* @returns {JsonTableState}
|
|
60
60
|
*/
|
|
61
61
|
const emptyState = () => ({
|
|
@@ -64,18 +64,18 @@ const emptyState = () => ({
|
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
|
-
* `<json-table>` – HTML
|
|
68
|
-
*
|
|
67
|
+
* `<json-table>` – generatore di tabelle HTML da dati JSON (inline o recuperati via fetch), custom element in light DOM,
|
|
68
|
+
* con ordinamento, ricerca e paginazione (client-side, oppure server-side con `serverSide: true`).
|
|
69
69
|
*
|
|
70
|
-
*
|
|
71
|
-
* `init()`;
|
|
70
|
+
* I parametri (vedi `src/defaults.js` → `JsonTableParams`) si possono impostare come attributi HTML o tramite
|
|
71
|
+
* `init()`; precedenza: `init()` > attributo HTML > `JsonTable.setDefaults()` > default predefinito.
|
|
72
72
|
*
|
|
73
|
-
*
|
|
74
|
-
* - `jt:ready`:
|
|
75
|
-
* - `jt:update`:
|
|
73
|
+
* Eventi (entrambi con bubbling, `event.detail.jsonTable` è l'istanza del componente):
|
|
74
|
+
* - `jt:ready`: emesso quando la struttura è stata costruita e i primi dati sono stati renderizzati
|
|
75
|
+
* - `jt:update`: emesso dopo ogni cambio di pagina / ordinamento / ricerca (`event.detail.reason`)
|
|
76
76
|
*
|
|
77
77
|
* @example
|
|
78
|
-
* // markup
|
|
78
|
+
* // solo markup
|
|
79
79
|
* // <json-table jsonurl="/api/rows.json" caption="Utenti" perpage="10"
|
|
80
80
|
* // cols='[{"key":"id","dataType":"id"},{"key":"name","title":"Nome"},{"key":"amount","dataType":"euro"}]'
|
|
81
81
|
* // ></json-table>
|
|
@@ -84,33 +84,34 @@ const emptyState = () => ({
|
|
|
84
84
|
* // script
|
|
85
85
|
* import { JsonTable } from '@massimo-cassandro/minimo/src/web-components/json-table/json-table-component.js';
|
|
86
86
|
*
|
|
87
|
-
* JsonTable.setDefaults({ classes: { table: 'table' } }); //
|
|
87
|
+
* JsonTable.setDefaults({ classes: { table: 'table' } }); // opzionale, a livello di progetto
|
|
88
88
|
*
|
|
89
89
|
* const el = document.querySelector('json-table');
|
|
90
90
|
* el.addEventListener('jt:ready', e => console.log(e.detail.jsonTable.data));
|
|
91
91
|
* el.init({
|
|
92
92
|
* debug: false, // default: false
|
|
93
93
|
* jsonUrl: '/api/rows.json', // default: null
|
|
94
|
+
* jqDatatableMode: false, // default: false (true: default compatibili con jQuery DataTables)
|
|
94
95
|
* jsonDataField: 'data', // default: 'data'
|
|
95
96
|
* totRecField: 'totRec', // default: 'totRec'
|
|
96
|
-
* filteredRecField: 'filteredRec', // default: 'filteredRec' (server-side
|
|
97
|
-
* data: null, // default: null (
|
|
98
|
-
* cols: [ //
|
|
97
|
+
* filteredRecField: 'filteredRec', // default: 'filteredRec' (modalità server-side)
|
|
98
|
+
* data: null, // default: null (ha la precedenza su jsonUrl quando impostato)
|
|
99
|
+
* cols: [ // obbligatorio
|
|
99
100
|
* { key: 'id', dataType: 'id' },
|
|
100
101
|
* { key: 'name', title: 'Nome', render: (row, tr, td) => `<a href="/users/${row.id}">${row.name}</a>` },
|
|
101
102
|
* { key: 'amount', dataType: 'euro', tfootRender: '@sum' },
|
|
102
103
|
* { key: 'active', dataType: 'bool' }
|
|
103
104
|
* ],
|
|
104
|
-
* dataTypes: {}, // default: {} (
|
|
105
|
+
* dataTypes: {}, // default: {} (tipi personalizzati, uniti a quelli predefiniti)
|
|
105
106
|
* caption: 'Utenti', // default: null
|
|
106
107
|
* search: true, // default: true
|
|
107
108
|
* searchDebounce: 300, // default: 300 (ms)
|
|
108
|
-
* perPage: 25, // default: 25 (0 =
|
|
109
|
+
* perPage: 25, // default: 25 (0 = nessuna paginazione)
|
|
109
110
|
* paginationDelta: 2, // default: 2
|
|
110
111
|
* serverSide: false, // default: false
|
|
111
112
|
* serverParams: { page: 'page', start: 'start', perPage: 'perPage', sort: 'sort', dir: 'dir', search: 'search' }, // default
|
|
112
113
|
* initialSort: { key: 'name', dir: 'asc' }, // default: null
|
|
113
|
-
* tfoot: true, // default: false (
|
|
114
|
+
* tfoot: true, // default: false (non disponibile in modalità server-side)
|
|
114
115
|
* updateFooterOnPageChange: false, // default: false
|
|
115
116
|
* infoText: null, // default: null → labels.info
|
|
116
117
|
* template: [{ slot: 'infoSection' }, { slot: 'table' }], // default
|
|
@@ -121,25 +122,25 @@ const emptyState = () => ({
|
|
|
121
122
|
* renderNaNAs: '—', // default: '—'
|
|
122
123
|
* trCallback: null, // default: null
|
|
123
124
|
* tableId: null, // default: null
|
|
124
|
-
* classes: { table: 'table' }, //
|
|
125
|
-
* labels: { noRows: 'Nessun utente' } //
|
|
125
|
+
* classes: { table: 'table' }, // unito ai default (vedi JsonTableClasses)
|
|
126
|
+
* labels: { noRows: 'Nessun utente' } // unito ai default (vedi JsonTableLabels)
|
|
126
127
|
* });
|
|
127
128
|
*/
|
|
128
129
|
export class JsonTable extends HTMLElement {
|
|
129
130
|
|
|
130
131
|
/**
|
|
131
|
-
*
|
|
132
|
-
* (
|
|
133
|
-
*
|
|
132
|
+
* Imposta i default a livello di progetto, condivisi da ogni istanza creata successivamente
|
|
133
|
+
* (le istanze già renderizzate non vengono aggiornate). Chiamarlo una sola volta, prima della creazione
|
|
134
|
+
* delle istanze, ad es. in uno script condiviso. I valori vengono uniti a quelli precedenti.
|
|
134
135
|
*
|
|
135
|
-
* @param {Partial<JsonTableParams>} [newDefaults={}] -
|
|
136
|
+
* @param {Partial<JsonTableParams>} [newDefaults={}] - Parametri da sovrascrivere (default: {})
|
|
136
137
|
* @returns {void}
|
|
137
138
|
*
|
|
138
139
|
* @example
|
|
139
140
|
* JsonTable.setDefaults({
|
|
140
141
|
* perPage: 50,
|
|
141
|
-
* classes: { searchInput: 'form-control', table: 'table' }, //
|
|
142
|
-
* labels: { searchPlaceholder: 'Cerca…' }, //
|
|
142
|
+
* classes: { searchInput: 'form-control', table: 'table' }, // unito alle classi predefinite
|
|
143
|
+
* labels: { searchPlaceholder: 'Cerca…' }, // unito alle label predefinite
|
|
143
144
|
* infoText: (start, end, totRec, filteredRec) => `${filteredRec} di ${totRec} record`
|
|
144
145
|
* });
|
|
145
146
|
*/
|
|
@@ -148,7 +149,7 @@ export class JsonTable extends HTMLElement {
|
|
|
148
149
|
}
|
|
149
150
|
|
|
150
151
|
/**
|
|
151
|
-
*
|
|
152
|
+
* Cancella i default a livello di progetto impostati con `setDefaults()`.
|
|
152
153
|
* @returns {void}
|
|
153
154
|
*/
|
|
154
155
|
static resetDefaults() {
|
|
@@ -156,7 +157,7 @@ export class JsonTable extends HTMLElement {
|
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
/**
|
|
159
|
-
*
|
|
160
|
+
* Restituisce i default predefiniti uniti a quelli a livello di progetto.
|
|
160
161
|
* @returns {JsonTableParams}
|
|
161
162
|
*
|
|
162
163
|
* @example
|
|
@@ -169,36 +170,36 @@ export class JsonTable extends HTMLElement {
|
|
|
169
170
|
|
|
170
171
|
constructor() {
|
|
171
172
|
super();
|
|
172
|
-
// light DOM:
|
|
173
|
+
// light DOM: nessun attachShadow
|
|
173
174
|
|
|
174
|
-
/** @type {Partial<JsonTableParams>|null}
|
|
175
|
+
/** @type {Partial<JsonTableParams>|null} configurazione passata tramite init()/reload() */
|
|
175
176
|
this._config = null;
|
|
176
177
|
this._initCalledProgrammatically = false;
|
|
177
178
|
this._isConnected = false;
|
|
178
179
|
this._loadStarted = false;
|
|
179
|
-
/**
|
|
180
|
+
/** incrementato a ogni init()/reload()/destroy(): un _load() in sospeso la cui generazione è obsoleta rinuncia */
|
|
180
181
|
this._loadGeneration = 0;
|
|
181
|
-
/**
|
|
182
|
+
/** incrementato a ogni richiesta server-side: una risposta obsoleta viene ignorata */
|
|
182
183
|
this._requestGeneration = 0;
|
|
183
|
-
/**
|
|
184
|
+
/** timer di debounce della ricerca in sospeso (vedi `search.js`) @type {ReturnType<typeof setTimeout>|undefined} */
|
|
184
185
|
this._searchTimer = undefined;
|
|
185
186
|
|
|
186
|
-
/**
|
|
187
|
+
/** Parametri risolti, disponibili dopo il primo caricamento. @type {JsonTableParams} */
|
|
187
188
|
this.params = /** @type {JsonTableParams} */ ({ ...defaults });
|
|
188
189
|
|
|
189
|
-
/**
|
|
190
|
+
/** Righe grezze, disponibili dopo il primo caricamento (solo la pagina corrente in modalità server-side). @type {Array<Object>|null} */
|
|
190
191
|
this.data = null;
|
|
191
192
|
|
|
192
|
-
/**
|
|
193
|
+
/** Mappa dei data type (predefiniti + personalizzati), disponibile dopo il primo caricamento. @type {Object<string, DataTypeDefinition>} */
|
|
193
194
|
this.dataTypes = {};
|
|
194
195
|
|
|
195
|
-
/**
|
|
196
|
+
/** Colonne visibili analizzate, disponibili dopo il primo caricamento. @type {ParsedCol[]} */
|
|
196
197
|
this.cols = [];
|
|
197
198
|
|
|
198
|
-
/**
|
|
199
|
+
/** Stato del rendering, disponibile dopo il primo caricamento. @type {JsonTableState} */
|
|
199
200
|
this.state = emptyState();
|
|
200
201
|
|
|
201
|
-
/**
|
|
202
|
+
/** Elementi generati, disponibili dopo il primo caricamento. @type {JsonTableElements} */
|
|
202
203
|
this.elements = {};
|
|
203
204
|
}
|
|
204
205
|
|
|
@@ -217,30 +218,30 @@ export class JsonTable extends HTMLElement {
|
|
|
217
218
|
}
|
|
218
219
|
|
|
219
220
|
|
|
220
|
-
// ───
|
|
221
|
+
// ─── API pubblica ─────────────────────────────────────────────────────────────
|
|
221
222
|
|
|
222
223
|
/**
|
|
223
|
-
*
|
|
224
|
-
*
|
|
224
|
+
* Avvia il componente tramite script, passando la configurazione come oggetto.
|
|
225
|
+
* Può essere chiamato prima o dopo che l'elemento è stato aggiunto al DOM.
|
|
225
226
|
*
|
|
226
|
-
*
|
|
227
|
-
* (
|
|
228
|
-
*
|
|
227
|
+
* I parametri non inclusi in `config` vengono letti dal corrispondente attributo HTML
|
|
228
|
+
* (se presente), poi dai default di progetto, poi dai default predefiniti.
|
|
229
|
+
* Per ignorare esplicitamente un attributo esistente passare `null` nella config.
|
|
229
230
|
*
|
|
230
|
-
* @param {Partial<JsonTableParams>} [config={}] -
|
|
231
|
+
* @param {Partial<JsonTableParams>} [config={}] - Vedi `JsonTableParams` (default: {})
|
|
231
232
|
* @returns {void}
|
|
232
233
|
*
|
|
233
234
|
* @example
|
|
234
235
|
* // <json-table caption="Utenti" search="false" cols='[...]'></json-table>
|
|
235
|
-
* el.init({ jsonUrl: '/api/rows.json' }); // jsonUrl
|
|
236
|
-
* el.init({ jsonUrl: '/api/rows.json', search: null }); // search → default (true),
|
|
236
|
+
* el.init({ jsonUrl: '/api/rows.json' }); // jsonUrl dallo script, caption, search e cols dagli attributi
|
|
237
|
+
* el.init({ jsonUrl: '/api/rows.json', search: null }); // search → default (true), l'attributo viene ignorato
|
|
237
238
|
*/
|
|
238
239
|
init(config = {}) {
|
|
239
240
|
this._config = config;
|
|
240
241
|
this._initCalledProgrammatically = true;
|
|
241
242
|
|
|
242
|
-
//
|
|
243
|
-
//
|
|
243
|
+
// un init() esplicito deve sempre riavviare, anche se connectedCallback ha già
|
|
244
|
+
// eseguito un _load() prematuro (ad es. quando domBuilder aggiunge l'elemento prima di init())
|
|
244
245
|
this._loadStarted = false;
|
|
245
246
|
this._loadGeneration++;
|
|
246
247
|
|
|
@@ -250,8 +251,8 @@ export class JsonTable extends HTMLElement {
|
|
|
250
251
|
}
|
|
251
252
|
|
|
252
253
|
/**
|
|
253
|
-
*
|
|
254
|
-
*
|
|
254
|
+
* Svuota il componente e ne azzera lo stato. Dopo si può richiamare `init()`
|
|
255
|
+
* per reinizializzarlo con nuovi parametri, senza ricreare l'elemento.
|
|
255
256
|
* @returns {void}
|
|
256
257
|
*/
|
|
257
258
|
destroy() {
|
|
@@ -267,16 +268,16 @@ export class JsonTable extends HTMLElement {
|
|
|
267
268
|
}
|
|
268
269
|
|
|
269
270
|
/**
|
|
270
|
-
*
|
|
271
|
-
* (
|
|
271
|
+
* Ricarica i dati e ricostruisce la struttura, sovrascrivendo opzionalmente alcuni parametri
|
|
272
|
+
* (uniti alla config passata a `init()`, se presente). Ricerca, ordinamento e pagina vengono azzerati.
|
|
272
273
|
*
|
|
273
|
-
* @param {Partial<JsonTableParams>} [overrides={}] -
|
|
274
|
+
* @param {Partial<JsonTableParams>} [overrides={}] - Parametri da sovrascrivere (default: {})
|
|
274
275
|
* @returns {Promise<void>}
|
|
275
276
|
*
|
|
276
277
|
* @example
|
|
277
|
-
* await el.reload(); //
|
|
278
|
-
* await el.reload({ jsonUrl: '/api/rows.json?y=2025' }); //
|
|
279
|
-
* await el.reload({ data: [{ id: 1 }] }); // inline
|
|
278
|
+
* await el.reload(); // stessa sorgente
|
|
279
|
+
* await el.reload({ jsonUrl: '/api/rows.json?y=2025' }); // nuovo URL
|
|
280
|
+
* await el.reload({ data: [{ id: 1 }] }); // dati inline (hanno la precedenza su jsonUrl)
|
|
280
281
|
*/
|
|
281
282
|
async reload(overrides = {}) {
|
|
282
283
|
this._config = { ...(this._config ?? {}), ...overrides };
|
|
@@ -286,12 +287,12 @@ export class JsonTable extends HTMLElement {
|
|
|
286
287
|
}
|
|
287
288
|
|
|
288
289
|
/**
|
|
289
|
-
*
|
|
290
|
-
*
|
|
290
|
+
* Mostra la pagina indicata (limitata all'intervallo disponibile). In modalità server-side viene inviata
|
|
291
|
+
* una nuova richiesta. Non succede nulla quando la pagina non cambia.
|
|
291
292
|
*
|
|
292
|
-
* @param {number} page -
|
|
293
|
-
* @param {string|null} [focusTarget=null] - `data-page`
|
|
294
|
-
* rendering (
|
|
293
|
+
* @param {number} page - Numero di pagina (da 1)
|
|
294
|
+
* @param {string|null} [focusTarget=null] - `data-page` del pulsante di paginazione a cui dare il focus dopo il
|
|
295
|
+
* rendering (usato dai pulsanti di paginazione stessi) (default: null)
|
|
295
296
|
* @returns {void}
|
|
296
297
|
*
|
|
297
298
|
* @example
|
|
@@ -307,17 +308,17 @@ export class JsonTable extends HTMLElement {
|
|
|
307
308
|
}
|
|
308
309
|
|
|
309
310
|
/**
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
* In server-side
|
|
311
|
+
* Ordina le righe per una colonna (`dir` null rimuove l'ordinamento) e torna alla prima pagina.
|
|
312
|
+
* La colonna deve esistere ed essere ordinabile, altrimenti la chiamata viene ignorata con un errore in console.
|
|
313
|
+
* In modalità server-side viene inviata una nuova richiesta.
|
|
313
314
|
*
|
|
314
|
-
* @param {string} key -
|
|
315
|
-
* @param {'asc'|'desc'|null} dir -
|
|
315
|
+
* @param {string} key - Chiave della colonna
|
|
316
|
+
* @param {'asc'|'desc'|null} dir - Direzione, oppure null per rimuovere l'ordinamento
|
|
316
317
|
* @returns {void}
|
|
317
318
|
*
|
|
318
319
|
* @example
|
|
319
320
|
* el.setSort('name', 'desc');
|
|
320
|
-
* el.setSort('name', null); //
|
|
321
|
+
* el.setSort('name', null); // ordine originale
|
|
321
322
|
*/
|
|
322
323
|
setSort(key, dir) {
|
|
323
324
|
if (dir != null) {
|
|
@@ -334,11 +335,11 @@ export class JsonTable extends HTMLElement {
|
|
|
334
335
|
}
|
|
335
336
|
|
|
336
337
|
/**
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
338
|
+
* Filtra le righe per un termine di ricerca (ogni parola separata da spazi deve corrispondere, senza distinzione tra maiuscole e minuscole)
|
|
339
|
+
* e torna alla prima pagina; un termine vuoto rimuove il filtro. L'input di ricerca, quando
|
|
340
|
+
* presente, resta sincronizzato. In modalità server-side viene inviata una nuova richiesta.
|
|
340
341
|
*
|
|
341
|
-
* @param {string} term -
|
|
342
|
+
* @param {string} term - Termine di ricerca
|
|
342
343
|
* @returns {void}
|
|
343
344
|
*
|
|
344
345
|
* @example
|
|
@@ -359,11 +360,11 @@ export class JsonTable extends HTMLElement {
|
|
|
359
360
|
}
|
|
360
361
|
|
|
361
362
|
|
|
362
|
-
// ───
|
|
363
|
+
// ─── Caricamento e costruzione ───────────────────────────────────────────────────────────
|
|
363
364
|
|
|
364
365
|
/**
|
|
365
|
-
*
|
|
366
|
-
*
|
|
366
|
+
* Risolve i parametri, analizza le colonne, recupera i dati e costruisce la struttura.
|
|
367
|
+
* Protetto da chiamate concorrenti/obsolete tramite `_loadStarted` e `_loadGeneration`.
|
|
367
368
|
* @returns {Promise<void>}
|
|
368
369
|
*/
|
|
369
370
|
async _load() {
|
|
@@ -378,7 +379,7 @@ export class JsonTable extends HTMLElement {
|
|
|
378
379
|
this.params = params;
|
|
379
380
|
this._validateParams(params);
|
|
380
381
|
|
|
381
|
-
//
|
|
382
|
+
// placeholder di caricamento (spinner di minimo)
|
|
382
383
|
domBuilder([
|
|
383
384
|
{
|
|
384
385
|
className: 'spinner',
|
|
@@ -386,7 +387,7 @@ export class JsonTable extends HTMLElement {
|
|
|
386
387
|
}
|
|
387
388
|
], this, { emptyParent: true });
|
|
388
389
|
|
|
389
|
-
//
|
|
390
|
+
// analisi delle colonne (gli errori di configurazione vengono segnalati e fermano il rendering)
|
|
390
391
|
try {
|
|
391
392
|
this.dataTypes = buildDataTypes(params);
|
|
392
393
|
this.cols = parseCols(params.cols, this.dataTypes, params);
|
|
@@ -397,7 +398,7 @@ export class JsonTable extends HTMLElement {
|
|
|
397
398
|
return;
|
|
398
399
|
}
|
|
399
400
|
|
|
400
|
-
//
|
|
401
|
+
// stato iniziale
|
|
401
402
|
this.state = emptyState();
|
|
402
403
|
if (params.initialSort && typeof params.initialSort === 'object') {
|
|
403
404
|
const { key, dir } = params.initialSort;
|
|
@@ -422,7 +423,7 @@ export class JsonTable extends HTMLElement {
|
|
|
422
423
|
console.error(err);
|
|
423
424
|
}
|
|
424
425
|
|
|
425
|
-
//
|
|
426
|
+
// un init()/reload()/destroy() più recente ha sostituito questo caricamento
|
|
426
427
|
if (generation !== this._loadGeneration) {
|
|
427
428
|
return;
|
|
428
429
|
}
|
|
@@ -433,7 +434,7 @@ export class JsonTable extends HTMLElement {
|
|
|
433
434
|
}
|
|
434
435
|
|
|
435
436
|
if (result === null) {
|
|
436
|
-
//
|
|
437
|
+
// nessuna sorgente: silenzioso quando creato da markup senza attributi (init() può seguire)
|
|
437
438
|
if (this._initCalledProgrammatically) {
|
|
438
439
|
// eslint-disable-next-line no-console
|
|
439
440
|
console.error('[json-table] Nessuna sorgente dati: specificare `data` o `jsonUrl`.');
|
|
@@ -464,17 +465,17 @@ export class JsonTable extends HTMLElement {
|
|
|
464
465
|
/* eslint-enable no-console */
|
|
465
466
|
}
|
|
466
467
|
|
|
467
|
-
//
|
|
468
|
+
// emesso nel microtask successivo così che i listener registrati subito dopo init() lo ricevano comunque
|
|
468
469
|
const event = new CustomEvent('jt:ready', { detail: { jsonTable: this }, bubbles: true });
|
|
469
470
|
Promise.resolve().then(() => this.dispatchEvent(event));
|
|
470
471
|
}
|
|
471
472
|
|
|
472
473
|
/**
|
|
473
|
-
*
|
|
474
|
-
* `perPage`/`paginationDelta`
|
|
475
|
-
* (
|
|
476
|
-
*
|
|
477
|
-
* @param {JsonTableParams} params -
|
|
474
|
+
* Normalizza i parametri risolti che dipendono l'uno dall'altro, segnalando le incoerenze:
|
|
475
|
+
* `perPage`/`paginationDelta` devono essere numeri non negativi, `serverSide` richiede `jsonUrl`
|
|
476
|
+
* (ignorato con `data` inline) e disattiva `tfoot` (gli aggregati verrebbero calcolati solo sulla
|
|
477
|
+
* pagina corrente).
|
|
478
|
+
* @param {JsonTableParams} params - Parametri risolti (modificati)
|
|
478
479
|
* @returns {void}
|
|
479
480
|
*/
|
|
480
481
|
_validateParams(params) {
|
|
@@ -498,7 +499,7 @@ export class JsonTable extends HTMLElement {
|
|
|
498
499
|
}
|
|
499
500
|
|
|
500
501
|
/**
|
|
501
|
-
*
|
|
502
|
+
* Stato corrente della richiesta server-side (vedi `get-data.js` → `ServerRequest`).
|
|
502
503
|
* @returns {import('./src/get-data.js').ServerRequest}
|
|
503
504
|
*/
|
|
504
505
|
_serverRequest() {
|
|
@@ -507,12 +508,13 @@ export class JsonTable extends HTMLElement {
|
|
|
507
508
|
page: state.page,
|
|
508
509
|
perPage: params.perPage > 0 ? params.perPage : 0,
|
|
509
510
|
sort: state.sort,
|
|
510
|
-
search: state.searchTerm
|
|
511
|
+
search: state.searchTerm,
|
|
512
|
+
cols: this.cols
|
|
511
513
|
};
|
|
512
514
|
}
|
|
513
515
|
|
|
514
516
|
/**
|
|
515
|
-
*
|
|
517
|
+
* Memorizza un risultato di dati: righe grezze, righe analizzate e totali.
|
|
516
518
|
* @param {import('./src/get-data.js').DataResult} result
|
|
517
519
|
* @returns {void}
|
|
518
520
|
*/
|
|
@@ -524,11 +526,11 @@ export class JsonTable extends HTMLElement {
|
|
|
524
526
|
}
|
|
525
527
|
|
|
526
528
|
/**
|
|
527
|
-
*
|
|
528
|
-
* `searchTerm`, `sort`
|
|
529
|
+
* Calcola `filtered`, `pageRows`, `filteredRec`, `totPages` e limita `page` a partire da `rows`,
|
|
530
|
+
* `searchTerm`, `sort` e `page`.
|
|
529
531
|
*
|
|
530
|
-
*
|
|
531
|
-
*
|
|
532
|
+
* Modalità client-side: ricerca e ordinamento vengono applicati a `rows`, poi viene estratta la pagina corrente.
|
|
533
|
+
* Modalità server-side: `rows` è già la pagina richiesta, `filteredRec` proviene dal JSON.
|
|
532
534
|
* @returns {void}
|
|
533
535
|
*/
|
|
534
536
|
_computeState() {
|
|
@@ -553,12 +555,12 @@ export class JsonTable extends HTMLElement {
|
|
|
553
555
|
}
|
|
554
556
|
|
|
555
557
|
/**
|
|
556
|
-
*
|
|
557
|
-
* server-side
|
|
558
|
-
*
|
|
558
|
+
* Applica un cambio di stato (pagina, ordinamento o ricerca): ricalcola lo stato e rieffettua il rendering oppure, in
|
|
559
|
+
* modalità server-side, invia una nuova richiesta (le risposte obsolete vengono ignorate) e ne renderizza il risultato.
|
|
560
|
+
* Emette `jt:update` alla fine.
|
|
559
561
|
*
|
|
560
|
-
* @param {UpdateReason} reason -
|
|
561
|
-
* @param {string|null} [focusTarget=null] -
|
|
562
|
+
* @param {UpdateReason} reason - Cosa è cambiato
|
|
563
|
+
* @param {string|null} [focusTarget=null] - Passato a `renderPagination()` (default: null)
|
|
562
564
|
* @returns {Promise<void>}
|
|
563
565
|
*/
|
|
564
566
|
async _update(reason, focusTarget = null) {
|
|
@@ -579,7 +581,7 @@ export class JsonTable extends HTMLElement {
|
|
|
579
581
|
}
|
|
580
582
|
|
|
581
583
|
if (generation !== this._requestGeneration || loadGeneration !== this._loadGeneration) {
|
|
582
|
-
return; //
|
|
584
|
+
return; // sostituita da una richiesta più recente o da un reload/destroy
|
|
583
585
|
}
|
|
584
586
|
this.elements.wrapper?.removeAttribute('aria-busy');
|
|
585
587
|
|
|
@@ -589,8 +591,8 @@ export class JsonTable extends HTMLElement {
|
|
|
589
591
|
this._setData(result);
|
|
590
592
|
this._computeState();
|
|
591
593
|
|
|
592
|
-
//
|
|
593
|
-
// `_computeState`
|
|
594
|
+
// la pagina richiesta non esiste più (l'insieme di dati si è ridotto dall'ultima richiesta):
|
|
595
|
+
// `_computeState` ha limitato la pagina, recupera l'ultima disponibile
|
|
594
596
|
if (!this.state.rows.length && this.state.filteredRec > 0 && this.state.page !== requestedPage) {
|
|
595
597
|
this._update(reason, focusTarget);
|
|
596
598
|
return;
|
|
@@ -606,12 +608,12 @@ export class JsonTable extends HTMLElement {
|
|
|
606
608
|
}
|
|
607
609
|
|
|
608
610
|
/**
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
* (
|
|
611
|
+
* Renderizza le parti che dipendono dallo stato: righe del body, footer, indicatori di ordinamento, paginazione e
|
|
612
|
+
* testo informativo. Il footer viene saltato ai cambi di pagina quando `updateFooterOnPageChange` è false
|
|
613
|
+
* (il suo contenuto non cambierebbe).
|
|
612
614
|
*
|
|
613
|
-
* @param {UpdateReason|null} [reason=null] -
|
|
614
|
-
* @param {string|null} [focusTarget=null] -
|
|
615
|
+
* @param {UpdateReason|null} [reason=null] - Cosa è cambiato (null al primo rendering) (default: null)
|
|
616
|
+
* @param {string|null} [focusTarget=null] - Passato a `renderPagination()` (default: null)
|
|
615
617
|
* @returns {void}
|
|
616
618
|
*/
|
|
617
619
|
_render(reason = null, focusTarget = null) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*! minimo - json-table */
|
|
2
2
|
|
|
3
|
-
/*
|
|
4
|
-
|
|
3
|
+
/* Le custom properties (`--jt-*`) sono definite in `json-table.minimo.tokens.mjs`
|
|
4
|
+
e compilate da build-tokens nel custom-properties.css di minimo */
|
|
5
5
|
|
|
6
6
|
/* purgecss start ignore */
|
|
7
7
|
|
|
@@ -68,15 +68,15 @@ json-table {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
.table {
|
|
71
|
-
/*
|
|
71
|
+
/* la spaziatura verticale è gestita dal wrapper */
|
|
72
72
|
margin-block: 0;
|
|
73
73
|
|
|
74
|
-
/*
|
|
74
|
+
/* il pulsante di ordinamento riempie l'intera cella: il padding della cella passa al pulsante */
|
|
75
75
|
th.sortable {
|
|
76
76
|
padding: 0;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
/*
|
|
79
|
+
/* cella mostrata quando non ci sono righe */
|
|
80
80
|
.empty {
|
|
81
81
|
padding-block: var(--jt-empty-padding-block);
|
|
82
82
|
font-style: italic;
|
|
@@ -238,7 +238,7 @@ json-table {
|
|
|
238
238
|
fill: currentColor;
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
/*
|
|
241
|
+
/* un ordinamento attivo (aria-sort sul th) mostra l'icona a piena opacità */
|
|
242
242
|
[aria-sort] & {
|
|
243
243
|
opacity: 1;
|
|
244
244
|
}
|