@massimo-cassandro/minimo 0.16.0 → 0.16.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/design-tokens/table.minimo.tokens.jsonc +20 -0
- package/design-tokens-src/table.minimo.tokens.mjs +86 -0
- package/package.json +1 -1
- package/src/css/table.css +11 -0
- package/src/custom-properties.css +3 -0
- package/src/web-components/s-datatable-component/docs.md +26 -11
- package/src/web-components/s-datatable-component/s-datatable-component.js +126 -61
- package/src/web-components/s-datatable-component/s-datatable-component.module.css +5 -0
- package/design-tokens-src/table.minimo.tokens.jsonc +0 -66
|
@@ -20,6 +20,26 @@
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
|
+
"tfoot": {
|
|
24
|
+
"background": {
|
|
25
|
+
"color": {
|
|
26
|
+
"$type": "color",
|
|
27
|
+
"$value": "{table.thead.background.color}"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"border": {
|
|
31
|
+
"width": {
|
|
32
|
+
"$type": "dimension",
|
|
33
|
+
"$value": "{table.thead.border.width}"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"font": {
|
|
37
|
+
"weight": {
|
|
38
|
+
"$type": "fontWeight",
|
|
39
|
+
"$value": "{font.weight.semibold}"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
23
43
|
"body": {
|
|
24
44
|
"border": {
|
|
25
45
|
"width": {
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
table: {
|
|
3
|
+
thead: {
|
|
4
|
+
background: {
|
|
5
|
+
color: {
|
|
6
|
+
$type: 'color',
|
|
7
|
+
$value: '#ddd'
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
border: {
|
|
11
|
+
width : {
|
|
12
|
+
$type: 'dimension',
|
|
13
|
+
$value: '3px'
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
tfoot: {
|
|
18
|
+
background: {
|
|
19
|
+
color: {
|
|
20
|
+
$type: 'color',
|
|
21
|
+
$value: '{table.thead.background.color}'
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
border: {
|
|
25
|
+
width : {
|
|
26
|
+
$type: 'dimension',
|
|
27
|
+
$value: '{table.thead.border.width}'
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
font: {
|
|
31
|
+
weight: {
|
|
32
|
+
$type: 'fontWeight',
|
|
33
|
+
$value: '{font.weight.semibold}',
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
body: {
|
|
39
|
+
background: {
|
|
40
|
+
color: null
|
|
41
|
+
},
|
|
42
|
+
border: {
|
|
43
|
+
'width' : {
|
|
44
|
+
$type: 'dimension',
|
|
45
|
+
$value: '1px'
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
tr: {
|
|
49
|
+
'alt-bg-color': {
|
|
50
|
+
$type: 'color',
|
|
51
|
+
$value: '#efefef'
|
|
52
|
+
},
|
|
53
|
+
'hover-bg-color': {
|
|
54
|
+
$type: 'color',
|
|
55
|
+
$value: '#cbcbcb'
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
border: {
|
|
61
|
+
'color' : {
|
|
62
|
+
$type: 'color',
|
|
63
|
+
$value: '#333'
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
cell: {
|
|
68
|
+
'padding' : {
|
|
69
|
+
block: {
|
|
70
|
+
$type: 'dimension',
|
|
71
|
+
$value: '.3rem'
|
|
72
|
+
},
|
|
73
|
+
inline: {
|
|
74
|
+
$type: 'dimension',
|
|
75
|
+
$value: '.6rem'
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
'line-height': {
|
|
79
|
+
$type: 'number',
|
|
80
|
+
$value: '1.3'
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
};
|
package/package.json
CHANGED
package/src/css/table.css
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
tr {
|
|
23
23
|
border-bottom: var(--_border);
|
|
24
24
|
}
|
|
25
|
+
|
|
25
26
|
thead {
|
|
26
27
|
background-color: var(--table-thead-background-color);
|
|
27
28
|
tr:last-child {
|
|
@@ -29,6 +30,16 @@
|
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
tfoot {
|
|
34
|
+
background-color: var(--table-tfoot-background-color);
|
|
35
|
+
tr:first-child {
|
|
36
|
+
border-block-start: var(--table-tfoot-border-width) solid var(--_border-color);
|
|
37
|
+
}
|
|
38
|
+
th, td {
|
|
39
|
+
font-weight: var(--table-tfoot-font-weight);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
32
43
|
tbody {
|
|
33
44
|
tr:nth-child(even) {
|
|
34
45
|
background-color: var(--_alternate-row-bg);
|
|
@@ -276,6 +276,9 @@
|
|
|
276
276
|
--table-cell-line-height: 1.3;
|
|
277
277
|
--table-cell-padding-block: .3rem;
|
|
278
278
|
--table-cell-padding-inline: .6rem;
|
|
279
|
+
--table-tfoot-background-color: var(--table-thead-background-color);
|
|
280
|
+
--table-tfoot-border-width: var(--table-thead-border-width);
|
|
281
|
+
--table-tfoot-font-weight: var(--font-weight-semibold);
|
|
279
282
|
--table-thead-background-color: #ddd;
|
|
280
283
|
--table-thead-border-width: .1875rem;
|
|
281
284
|
--text-color: #000;
|
|
@@ -354,28 +354,43 @@ Ricerca senza risultati:
|
|
|
354
354
|
|
|
355
355
|
Il testo si aggiorna automaticamente ad ogni cambio pagina, ricerca e multisearch.
|
|
356
356
|
|
|
357
|
-
##
|
|
357
|
+
## Parametri `topSlot` e `showInfoAtTop`
|
|
358
358
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
o qualsiasi controllo da affiancare alla search box.
|
|
359
|
+
Entrambi occupano l'area in alto a sinistra del datatable — lo spazio normalmente
|
|
360
|
+
riservato al selettore "righe per pagina" (qui disabilitato). I due parametri si
|
|
361
|
+
escludono: se `showInfoAtTop` è `true` (default), `topSlot` viene ignorato.
|
|
363
362
|
|
|
364
|
-
|
|
365
|
-
come primo figlio dell'area superiore, prima della search box.
|
|
363
|
+
### `showInfoAtTop`
|
|
366
364
|
|
|
367
|
-
|
|
368
|
-
|
|
365
|
+
Replica nell'area superiore lo stesso testo dell'area `.info` in basso,
|
|
366
|
+
mantenuto in sincronia ad ogni cambio pagina o filtro. Il nodo viene nascosto
|
|
367
|
+
automaticamente quando non ci sono record o la ricerca non produce risultati
|
|
368
|
+
(evita di mostrare "Nessun risultato…" in due posti).
|
|
369
|
+
|
|
370
|
+
```javascript
|
|
371
|
+
el.init({
|
|
372
|
+
json: '/api/data.json',
|
|
373
|
+
cols: [...],
|
|
374
|
+
showInfoAtTop: true,
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### `topSlot`
|
|
379
|
+
|
|
380
|
+
Inserisce un elemento DOM o markup HTML arbitrario, avvolto in un
|
|
381
|
+
`<div class="datatable-top-slot">`. Accetta sia una stringa HTML che un `Element`
|
|
382
|
+
già costruito (utile per mantenere un riferimento al nodo e aggiungervi listener).
|
|
383
|
+
Non è leggibile da attributo HTML, solo via `init()`.
|
|
369
384
|
|
|
370
385
|
```javascript
|
|
371
386
|
// Stringa HTML
|
|
372
387
|
el.init({
|
|
373
388
|
json: '/api/data.json',
|
|
374
389
|
cols: [...],
|
|
375
|
-
topSlot: '<button class="btn btn-sm btn-primary"
|
|
390
|
+
topSlot: '<button class="btn btn-sm btn-primary">Esporta CSV</button>',
|
|
376
391
|
});
|
|
377
392
|
|
|
378
|
-
// Elemento DOM
|
|
393
|
+
// Elemento DOM
|
|
379
394
|
const btn = document.createElement('button');
|
|
380
395
|
btn.className = 'btn btn-sm btn-outline-secondary';
|
|
381
396
|
btn.textContent = 'Nuova commessa';
|
|
@@ -114,8 +114,17 @@ import caretRightIcon from '../../icons/caret-right.svg?inline';
|
|
|
114
114
|
* Accetta:
|
|
115
115
|
* - `Element`: un nodo DOM già costruito
|
|
116
116
|
* - stringa HTML: parsata via innerHTML
|
|
117
|
+
* Ignorato se `showInfoAtTop` è true.
|
|
117
118
|
* Non è leggibile da attributo HTML (solo via script).
|
|
118
119
|
*
|
|
120
|
+
* @param {boolean} showInfoAtTop Se true, mostra nell'area superiore (spazio top-sinistra)
|
|
121
|
+
* lo stesso testo dell'area `.info` in basso, mantenuto in
|
|
122
|
+
* sync ad ogni cambio pagina/filtro. Il nodo viene nascosto
|
|
123
|
+
* automaticamente quando non ci sono record o la ricerca
|
|
124
|
+
* non produce risultati. Ha precedenza su `topSlot`:
|
|
125
|
+
* se entrambi sono definiti, `topSlot` viene ignorato.
|
|
126
|
+
* Default: true.
|
|
127
|
+
*
|
|
119
128
|
* @param {string[]} refs Elenco di percorsi URL da cui, se si proviene,
|
|
120
129
|
* la pagina corrente viene ripristinata dal cookie
|
|
121
130
|
* di sessione `sd-pag`. Se il referrer non è tra
|
|
@@ -404,8 +413,27 @@ class SimpleDatatableAdapter extends HTMLElement {
|
|
|
404
413
|
// 2. Attributo HTML
|
|
405
414
|
const attr = this.getAttribute(name);
|
|
406
415
|
if (attr !== null) {
|
|
407
|
-
// Auto-parse
|
|
416
|
+
// Auto-parse booleani quando il defaultValue è boolean e il valore
|
|
417
|
+
// è una delle stringhe canoniche true/false/0/1, oppure true/false.
|
|
418
|
+
// Casi supportati:
|
|
419
|
+
// showInfoAtTop (attributo senza valore → attr === '') → true
|
|
420
|
+
// showInfoAtTop="true" / showInfoAtTop="1" → true
|
|
421
|
+
// showInfoAtTop="false" / showInfoAtTop="0" → false
|
|
422
|
+
// Auto-parse booleani solo quando il parametro è dichiaratamente booleano
|
|
423
|
+
// (defaultValue === true | false). Copre tutti i formati HTML idiomatici:
|
|
424
|
+
// showInfoAtTop (attributo senza valore → '') → true
|
|
425
|
+
// showInfoAtTop="true" / showInfoAtTop="1" → true
|
|
426
|
+
// showInfoAtTop="false" / showInfoAtTop="0" → false
|
|
427
|
+
// I valori "1" e "0" NON vengono intercettati qui se defaultValue non è
|
|
428
|
+
// boolean, per non interferire con parametri numerici (es. perPage="1").
|
|
408
429
|
const trimmed = attr.trim();
|
|
430
|
+
if (typeof defaultValue === 'boolean') {
|
|
431
|
+
const lower = trimmed.toLowerCase();
|
|
432
|
+
// Stringa vuota '' = attributo presente senza valore → true (standard HTML)
|
|
433
|
+
return lower !== 'false' && lower !== '0';
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Auto-parse JSON per array e oggetti (es. cols='[…]')
|
|
409
437
|
if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
|
|
410
438
|
try { return JSON.parse(trimmed); } catch { /* restituisce la stringa grezza */ }
|
|
411
439
|
}
|
|
@@ -760,24 +788,25 @@ class SimpleDatatableAdapter extends HTMLElement {
|
|
|
760
788
|
});
|
|
761
789
|
|
|
762
790
|
this._dt.on('datatable.init', () => {
|
|
791
|
+
// ── Icone paginazione ─────────────────────────────────────────────────
|
|
763
792
|
const pagination = this.querySelector(`.${styles.paginationList}`);
|
|
764
|
-
if (
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
793
|
+
if (pagination) {
|
|
794
|
+
const items = pagination.querySelectorAll(`.${styles.paginationListItem}`);
|
|
795
|
+
if (items.length) {
|
|
796
|
+
pagination.querySelector(
|
|
797
|
+
`.${styles.paginationListItem}:first-child .${styles.paginationListItemBtn}`
|
|
798
|
+
).innerHTML = caretLeftIcon;
|
|
799
|
+
|
|
800
|
+
pagination.querySelector(
|
|
801
|
+
`.${styles.paginationListItem}:last-child .${styles.paginationListItemBtn}`
|
|
802
|
+
).innerHTML = caretRightIcon;
|
|
803
|
+
|
|
804
|
+
pagination.querySelectorAll(`.${styles.paginationListItemBtn}:has(svg)`)
|
|
805
|
+
.forEach(btn => btn.classList.add(styles.hasSvg));
|
|
806
|
+
}
|
|
807
|
+
}
|
|
779
808
|
|
|
780
|
-
// Ripristino pagina dal cookie di sessione (se referrer autorizzato)
|
|
809
|
+
// ── Ripristino pagina dal cookie di sessione (se referrer autorizzato) ─
|
|
781
810
|
// const isRefUrl = this._isReferrer(), refsCallback = this._getParam('refsCallback', null);
|
|
782
811
|
// if (isRefUrl) {
|
|
783
812
|
if (this._isReferrer()) {
|
|
@@ -793,6 +822,7 @@ class SimpleDatatableAdapter extends HTMLElement {
|
|
|
793
822
|
// refsCallback(isRefUrl);
|
|
794
823
|
// }
|
|
795
824
|
|
|
825
|
+
// ── Filtro contestuale post-reload ────────────────────────────────────
|
|
796
826
|
// Applica eventuale filtro contestuale passato via reload({ search: … })
|
|
797
827
|
// Lo facciamo qui, dentro datatable.init, per essere certi che
|
|
798
828
|
// simple-datatables abbia completato il render dei nuovi dati.
|
|
@@ -807,14 +837,11 @@ class SimpleDatatableAdapter extends HTMLElement {
|
|
|
807
837
|
}
|
|
808
838
|
}
|
|
809
839
|
|
|
810
|
-
//
|
|
840
|
+
// ── Tfoot, info, top slot ─────────────────────────────────────────────
|
|
841
|
+
// Eseguiti sempre, indipendentemente dalla presenza della paginazione.
|
|
811
842
|
this._renderTfoot();
|
|
812
|
-
|
|
813
|
-
// Aggiorna il testo info con il totale assoluto
|
|
843
|
+
this._injectTopSlot(); // va prima di _updateInfo per creare il nodo top-info
|
|
814
844
|
this._updateInfo();
|
|
815
|
-
|
|
816
|
-
// Inietta l'elemento nello slot top-sinistra (se configurato)
|
|
817
|
-
this._injectTopSlot();
|
|
818
845
|
});
|
|
819
846
|
|
|
820
847
|
// Salva la pagina corrente nel cookie ad ogni cambio di pagina;
|
|
@@ -927,84 +954,123 @@ class SimpleDatatableAdapter extends HTMLElement {
|
|
|
927
954
|
/**
|
|
928
955
|
* Sovrascrive il testo dell'area `.info` generato da simple-datatables per
|
|
929
956
|
* includere sempre il totale assoluto dei record (indipendente dal filtro).
|
|
957
|
+
* Se `showInfoAtTop` è attivo, aggiorna in sincronia anche il nodo `.info`
|
|
958
|
+
* nell'area superiore (creato da `_injectTopSlot`).
|
|
959
|
+
*
|
|
960
|
+
* Calcolo di start/end: si conta il numero di righe renderizzate nel tbody
|
|
961
|
+
* (`dt.pages[currentPage - 1]`) invece di fare aritmetica su perPage,
|
|
962
|
+
* perché `dt.currentPage` può essere undefined al primo render.
|
|
930
963
|
*
|
|
931
964
|
* Comportamento:
|
|
932
965
|
* - Senza ricerca attiva:
|
|
933
966
|
* "Stai visualizzando le righe da {start} a {end}, su un totale di {total}."
|
|
934
|
-
* - Con ricerca attiva:
|
|
935
|
-
* "Stai visualizzando le righe da {start} a {end} dei {filtered} record
|
|
936
|
-
* su un totale di {total}."
|
|
967
|
+
* - Con ricerca attiva (risultati > 0):
|
|
968
|
+
* "Stai visualizzando le righe da {start} a {end} dei {filtered} record
|
|
969
|
+
* filtrati, su un totale di {total}."
|
|
937
970
|
* - Nessun risultato (ricerca attiva, 0 match):
|
|
938
971
|
* "Nessun risultato per la ricerca corrente (totale record: {total})."
|
|
939
972
|
*
|
|
940
|
-
*
|
|
941
|
-
* datatable.multisearch.
|
|
973
|
+
* Il nodo top-info viene nascosto quando filtered = 0 o total = 0.
|
|
942
974
|
*/
|
|
943
975
|
_updateInfo() {
|
|
944
|
-
const infoEl
|
|
945
|
-
|
|
976
|
+
const infoEl = this.querySelector(`.${styles.info}`);
|
|
977
|
+
const topInfoEl = this.querySelector('.datatable-top-info');
|
|
946
978
|
|
|
947
|
-
|
|
948
|
-
const total = this._rawData?.length ?? 0;
|
|
979
|
+
if (!infoEl && !topInfoEl) return;
|
|
949
980
|
|
|
950
|
-
|
|
981
|
+
const dt = this._dt;
|
|
982
|
+
const total = this._rawData?.length ?? 0;
|
|
951
983
|
const filtered = dt.searching ? dt.searchData.length : total;
|
|
952
984
|
|
|
953
|
-
|
|
954
|
-
|
|
985
|
+
let text;
|
|
986
|
+
|
|
987
|
+
if (total === 0 || (filtered === 0 && dt.searching)) {
|
|
988
|
+
// Nessun risultato — nasconde il nodo top-info se presente
|
|
989
|
+
if (topInfoEl) topInfoEl.hidden = true;
|
|
990
|
+
|
|
991
|
+
text = filtered === 0 && dt.searching
|
|
992
|
+
? `Nessun risultato per la ricerca corrente (totale record: ${total}).`
|
|
993
|
+
: `Nessun record trovato.`;
|
|
994
|
+
|
|
995
|
+
if (infoEl) infoEl.textContent = text;
|
|
955
996
|
return;
|
|
956
997
|
}
|
|
957
998
|
|
|
958
|
-
// Calcola start/end
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
const
|
|
962
|
-
const
|
|
999
|
+
// Calcola start/end dalla pagina corrente in dt.pages (più affidabile di
|
|
1000
|
+
// currentPage * perPage, che può dare NaN se currentPage è undefined
|
|
1001
|
+
// al primo render oppure quando non c'è paginazione).
|
|
1002
|
+
const currentPage = dt.currentPage ?? 1;
|
|
1003
|
+
const pageRows = dt.pages?.[currentPage - 1] ?? [];
|
|
1004
|
+
const perPage = dt.options?.perPage ?? filtered;
|
|
1005
|
+
const start = pageRows.length > 0
|
|
1006
|
+
? (currentPage - 1) * perPage + 1
|
|
1007
|
+
: 1;
|
|
1008
|
+
const end = pageRows.length > 0
|
|
1009
|
+
? start + pageRows.length - 1
|
|
1010
|
+
: filtered;
|
|
963
1011
|
|
|
964
1012
|
if (dt.searching) {
|
|
965
|
-
|
|
1013
|
+
text =
|
|
966
1014
|
`Stai visualizzando le righe da ${start} a ${end} ` +
|
|
967
1015
|
`dei ${filtered} record filtrati, su un totale di ${total}.`;
|
|
968
1016
|
} else {
|
|
969
|
-
|
|
1017
|
+
text =
|
|
970
1018
|
`Stai visualizzando le righe da ${start} a ${end}, ` +
|
|
971
1019
|
`su un totale di ${total}.`;
|
|
972
1020
|
}
|
|
1021
|
+
|
|
1022
|
+
if (infoEl) infoEl.textContent = text;
|
|
1023
|
+
if (topInfoEl) { topInfoEl.textContent = text; topInfoEl.hidden = false; }
|
|
973
1024
|
}
|
|
974
1025
|
|
|
975
1026
|
|
|
976
1027
|
// ─── Top slot ────────────────────────────────────────────────────────────────
|
|
977
1028
|
|
|
978
1029
|
/**
|
|
979
|
-
* Inietta
|
|
980
|
-
*
|
|
981
|
-
*
|
|
1030
|
+
* Inietta nell'area in alto a sinistra del datatable il contenuto configurato.
|
|
1031
|
+
*
|
|
1032
|
+
* Modalità:
|
|
1033
|
+
*
|
|
1034
|
+
* showInfoAtTop: true (ha precedenza su topSlot)
|
|
1035
|
+
* Inserisce un nodo `.datatable-top-info` con la stessa stringa dell'area
|
|
1036
|
+
* `.info` in basso, mantenuta in sync da `_updateInfo`. Viene nascosto
|
|
1037
|
+
* automaticamente quando filtered = 0 o total = 0.
|
|
1038
|
+
* Il parametro `topSlot`, se presente, viene ignorato.
|
|
982
1039
|
*
|
|
983
|
-
*
|
|
984
|
-
*
|
|
985
|
-
*
|
|
1040
|
+
* topSlot: Element | string (usato solo se showInfoAtTop è false/assente)
|
|
1041
|
+
* Inserisce un elemento DOM o markup HTML arbitrario, avvolto in un
|
|
1042
|
+
* `<div class="datatable-top-slot">`.
|
|
986
1043
|
*
|
|
987
|
-
*
|
|
988
|
-
* prima della search box
|
|
989
|
-
* Se `topSlot` non è definito, non viene inserito nulla.
|
|
1044
|
+
* In entrambi i casi l'elemento viene inserito come primo figlio di `.topArea`,
|
|
1045
|
+
* prima della search box.
|
|
990
1046
|
*
|
|
991
|
-
*
|
|
992
|
-
* el.init({
|
|
993
|
-
*
|
|
994
|
-
* });
|
|
1047
|
+
* Esempi:
|
|
1048
|
+
* el.init({ showInfoAtTop: true });
|
|
1049
|
+
*
|
|
1050
|
+
* el.init({ topSlot: '<button class="btn btn-sm btn-primary">Esporta</button>' });
|
|
995
1051
|
*
|
|
996
|
-
* Esempio – elemento DOM:
|
|
997
1052
|
* const btn = document.createElement('button');
|
|
998
|
-
* btn.textContent = '
|
|
1053
|
+
* btn.textContent = 'Nuovo';
|
|
999
1054
|
* el.init({ topSlot: btn });
|
|
1000
1055
|
*/
|
|
1001
1056
|
_injectTopSlot() {
|
|
1002
|
-
const topSlot = this._getParam('topSlot', null);
|
|
1003
|
-
if (topSlot == null) return;
|
|
1004
|
-
|
|
1005
1057
|
const topArea = this.querySelector(`.${styles.topArea}`);
|
|
1006
1058
|
if (!topArea) return;
|
|
1007
1059
|
|
|
1060
|
+
const showInfoAtTop = this._getParam('showInfoAtTop', true);
|
|
1061
|
+
|
|
1062
|
+
if (showInfoAtTop) {
|
|
1063
|
+
// Crea il nodo info top (il testo verrà scritto da _updateInfo)
|
|
1064
|
+
const infoTop = document.createElement('div');
|
|
1065
|
+
infoTop.className = `datatable-top-info ${styles.info}`;
|
|
1066
|
+
infoTop.hidden = true; // nascosto finché _updateInfo non lo popola
|
|
1067
|
+
topArea.insertBefore(infoTop, topArea.firstChild);
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
const topSlot = this._getParam('topSlot', null);
|
|
1072
|
+
if (topSlot == null) return;
|
|
1073
|
+
|
|
1008
1074
|
const wrapper = document.createElement('div');
|
|
1009
1075
|
wrapper.className = 'datatable-top-slot';
|
|
1010
1076
|
|
|
@@ -1014,7 +1080,6 @@ class SimpleDatatableAdapter extends HTMLElement {
|
|
|
1014
1080
|
wrapper.innerHTML = topSlot;
|
|
1015
1081
|
}
|
|
1016
1082
|
|
|
1017
|
-
// Inserisce prima della search box (primo figlio esistente)
|
|
1018
1083
|
topArea.insertBefore(wrapper, topArea.firstChild);
|
|
1019
1084
|
}
|
|
1020
1085
|
|
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
align-items: center;
|
|
20
20
|
justify-content: flex-end;
|
|
21
21
|
padding-block-end: var(--size-xs);
|
|
22
|
+
|
|
23
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
24
|
+
&:has(:global(.datatable-top-info)), &:has(:global(.datatable-top-slot)) {
|
|
25
|
+
justify-content: space-between;
|
|
26
|
+
}
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
.searchWrapper {
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"table": {
|
|
3
|
-
"thead": {
|
|
4
|
-
"background": {
|
|
5
|
-
"color": {
|
|
6
|
-
"$type": "color",
|
|
7
|
-
"$value": "#ddd"
|
|
8
|
-
}
|
|
9
|
-
},
|
|
10
|
-
"border": {
|
|
11
|
-
"width" : {
|
|
12
|
-
"$type": "dimension",
|
|
13
|
-
"$value": "3px"
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
"body": {
|
|
19
|
-
"background": {
|
|
20
|
-
"color": null
|
|
21
|
-
},
|
|
22
|
-
"border": {
|
|
23
|
-
"width" : {
|
|
24
|
-
"$type": "dimension",
|
|
25
|
-
"$value": "1px"
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"tr": {
|
|
29
|
-
"alt-bg-color": {
|
|
30
|
-
"$type": "color",
|
|
31
|
-
"$value": "#efefef"
|
|
32
|
-
},
|
|
33
|
-
"hover-bg-color": {
|
|
34
|
-
"$type": "color",
|
|
35
|
-
"$value": "#cbcbcb"
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
"border": {
|
|
41
|
-
"color" : {
|
|
42
|
-
"$type": "color",
|
|
43
|
-
"$value": "#333"
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
"cell": {
|
|
48
|
-
"padding" : {
|
|
49
|
-
"block": {
|
|
50
|
-
"$type": "dimension",
|
|
51
|
-
"$value": ".3rem"
|
|
52
|
-
},
|
|
53
|
-
"inline": {
|
|
54
|
-
"$type": "dimension",
|
|
55
|
-
"$value": ".6rem"
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
"line-height": {
|
|
59
|
-
"$type": "number",
|
|
60
|
-
"$value": "1.3"
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
}
|