@massimo-cassandro/minimo 0.10.11 → 0.11.0

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.
Files changed (27) hide show
  1. package/design-tokens/components/snackbar.minimo.tokens.jsonc +106 -12
  2. package/design-tokens/shadows.minimo.tokens.jsonc +19 -0
  3. package/design-tokens/z-index.minimo.tokens.jsonc +4 -0
  4. package/design-tokens-src/_readme.md +1 -1
  5. package/design-tokens-src/badge.minimo.tokens.mjs +36 -0
  6. package/design-tokens-src/btn-close.minimo.tokens.mjs +101 -0
  7. package/design-tokens-src/components/snackbar.minimo.tokens.mjs +113 -21
  8. package/design-tokens-src/flex-grid.minimo.tokens.mjs +18 -0
  9. package/design-tokens-src/shadows.minimo.tokens.mjs +16 -0
  10. package/design-tokens-src/z-index.minimo.tokens.mjs +14 -0
  11. package/design-tokens-utilities/build-tokens-src/transforms.mjs +2 -1
  12. package/package.json +1 -1
  13. package/src/components/snackbar/snackbar.js +56 -62
  14. package/src/components/snackbar/snackbar.module.css +79 -49
  15. package/src/css/buttons/btn-close.css +3 -2
  16. package/src/css/forms/forms.css +1 -0
  17. package/src/custom-properties.css +22 -4
  18. package/src/web-components/s-datatable-component/docs.md +187 -0
  19. package/src/web-components/s-datatable-component/s-datatable-component.js +517 -0
  20. package/src/web-components/{simple-datatable/simple-datatable.module.css → s-datatable-component/s-datatable-component.module.css} +1 -1
  21. package/src/web-components/{simple-datatable → s-datatable-component}/src/parse-cols.js +1 -1
  22. package/design-tokens-src/badge.minimo.tokens.jsonc +0 -36
  23. package/design-tokens-src/btn-close.minimo.tokens.jsonc +0 -101
  24. package/design-tokens-src/flex-grid.minimo.tokens.jsonc +0 -18
  25. package/design-tokens-src/gradients-shadowes.minimo.tokens.jsonc +0 -4
  26. package/design-tokens-src/z-index.minimo.tokens.jsonc +0 -8
  27. package/src/web-components/simple-datatable/simple-datatable.js +0 -218
@@ -1,75 +1,105 @@
1
1
  /* purgecss start ignore */
2
2
 
3
- .snackbar {
3
+ .snackbarOuter {
4
+ position: fixed;
5
+ inset-block: auto var(--size-md);
6
+ /* inset-inline: 0 auto; */
7
+ z-index: var(--z-index-snackbar);
8
+ inline-size: 20dvw;
9
+ min-inline-size: min(100%, 37ch);
10
+ padding: var(--snackbar-outer-padding-block) var(--snackbar-outer-padding-inline);
11
+ margin-inline: auto;
12
+ background-color: var(--snackbar-outer-background-color);
13
+ border: var(--snackbar-outer-border);
14
+ border-radius: var(--snackbar-outer-border-radius);
15
+ box-shadow: var(--snackbar-outer-drop-shadow);
16
+ animation: slide-in .3s cubic-bezier(.34, 1.56, .64, 1) forwards;
17
+
18
+ &.isHiding {
19
+ animation: slide-out .25s ease-in forwards;
20
+ }
4
21
 
5
22
  }
6
23
 
7
- .text {}
8
- .action {}
9
- .closeBtn {}
24
+ .snackbar {
25
+ display: flex;
26
+ gap: var(--size-xs);
27
+ align-items: center;
28
+ justify-content: space-between;
29
+ padding: var(--size-xs) var(--size-sm);
30
+ font-size: var(--snackbar-font-size);
31
+ color: var(--snackbar-text-color);
32
+ background-color: var(--snackbar-background-color);
33
+ border-radius: var(--snackbar-border-radius);
34
+
35
+ &::backdrop {
36
+ display: none;
37
+ }
10
38
 
39
+ * {
40
+ overflow-wrap: break-word;
41
+ }
42
+ }
11
43
 
12
- /* purgecss end ignore */
44
+ /* .text {} */
13
45
 
46
+ .action {
47
+ margin-inline-start: auto;
48
+ }
49
+ .closeBtn {
50
+ --_icon-bar-width: var(--snackbar-btn-close-size); /* --_icon-bar-width is defined in buttons/btn-close.css */
14
51
 
15
- /*
52
+ --btn-close-background-color: var(--snackbar-btn-close-background-color);
53
+ --btn-close-icon-color: var(--snackbar-btn-close-icon-color);
54
+ --btn-close-icon-bar-size: 2px;
16
55
 
17
56
 
57
+ --btn-close-hover-background-color: var(--snackbar-btn-close-hover-background-color);
58
+ --btn-close-hover-border-color: var(--snackbar-btn-close-hover-border-color);
59
+ --btn-close-hover-icon-color: var(--snackbar-btn-close-hover-icon-color);
18
60
 
61
+ --btn-close-focus-outline-color: var(--snackbar-btn-close-focus-outline-color);
62
+ --btn-close-focus-outline-offset: var(--snackbar-btn-close-focus-outline-offset);
63
+ --btn-close-focus-outline-width: var(--snackbar-btn-close-focus-outline-width);
19
64
 
65
+ --btn-close-active-background-color: var(--snackbar-btn-close-active-background-color);
66
+ --btn-close-active-icon-color: var(--snackbar-btn-close-active-icon-color);
20
67
 
21
- .toastWrapper {
22
- position: fixed;
23
- inset-block-end: 0;
24
- inset-inline: 0;
25
- z-index: 1;
26
68
 
27
- display: grid;
28
- gap: 1vh;
29
- justify-content: center;
30
- justify-items: stretch;
31
- padding-block-end: 5vh;
69
+ border: none;
32
70
 
33
- pointer-events: none;
71
+ &:active {
72
+ scale: .6;
73
+ }
34
74
  }
35
75
 
36
- .toast {
37
- --_bg-lightness: 90%;
38
- --_travel-distance: 0;
39
-
40
- max-inline-size: min(25ch, 90vw);
41
- padding-block: .5ch;
42
- padding-inline: 1ch;
43
-
44
- font-size: var(--toast-font-size);
45
- color: var(--toast-text-color);
46
- background: hsl(0 0% var(--_bg-lightness) / 90%);
47
- border-radius: var(--toast-border-radius);
48
- animation:
49
- fade-in .3s ease,
50
- slide-in .3s ease,
51
- fade-out .3s ease var(--toast-duration);
52
-
53
- will-change: transform;
54
-
55
- @media (--dark) {
56
- --_bg-lightness: 20%;
76
+ @keyframes slide-in {
77
+ from {
78
+ opacity: 0;
79
+ translate: 0 calc(100% + var(--size-md));
57
80
  }
58
-
59
- @media (--motionOK) {
60
- --_travel-distance: 5vh;
81
+ to {
82
+ opacity: 1;
83
+ translate: 0 0;
61
84
  }
62
85
  }
63
86
 
64
- @keyframes fade-in {
65
- from { opacity: 0; }
87
+ @keyframes slide-out {
88
+ from {
89
+ opacity: 1;
90
+ translate: 0 0;
91
+ }
92
+ to {
93
+ opacity: 0;
94
+ translate: 0 calc(100% + var(--size-md));
95
+ }
66
96
  }
67
97
 
68
- @keyframes fade-out {
69
- to { opacity: 0; }
98
+ @media (prefers-reduced-motion: reduce) {
99
+ .snackbarOuter,
100
+ .snackbarOuter.isHiding {
101
+ animation: none;
102
+ }
70
103
  }
71
104
 
72
- @keyframes slide-in {
73
- from { transform: translateY(var(--_travel-distance, 10px)); }
74
- }
75
- */
105
+ /* purgecss end ignore */
@@ -24,14 +24,15 @@
24
24
  &::before, &::after {
25
25
  position: absolute;
26
26
  top: 50%;
27
- left: 0; /* calc(var(--btn-close-icon-bar-size) / 2); */
27
+ left: 50%;
28
28
  display: block;
29
29
  width: var(--_icon-bar-width);
30
30
  height: var(--btn-close-icon-bar-size);
31
31
  content: '';
32
32
  background: currentColor;
33
33
  transform-origin: center;
34
- translate: var(--btn-close-padding) -50%;
34
+ /* translate: var(--btn-close-padding) -50%; */
35
+ translate: -50% -50%;
35
36
  }
36
37
  &::before {
37
38
  rotate: 45deg;
@@ -3,6 +3,7 @@
3
3
  /* TODO multiselect */
4
4
  /* TODO classe grid specifica per i form ?? (.form-grid?) */
5
5
  /* TODO customizable select */
6
+ /* TODO form-check: rifare come flex, separare? */
6
7
 
7
8
  .form-group:has([required]):not(:has([disabled])) {
8
9
 
@@ -12,13 +12,14 @@
12
12
  --badge-lg-font-weight: var(--badge-font-weight);
13
13
  --body-background-color: #fff;
14
14
  --body-text: var(--text-color);
15
+ --box-shadow-base: 0 0 .75rem 0 rgb(0 0 0 / .25);
15
16
  --btn-border-radius: var(--form-control-border-radius);
16
17
  --btn-border-width: var(--form-control-border-width);
17
18
  --btn-close-active-background-color: var(--btn-close-background-color);
18
19
  --btn-close-active-icon-color: var(--link-active-color);
19
20
  --btn-close-background-color: var(--body-background-color);
20
21
  --btn-close-border-color: var(--btn-close-icon-color);
21
- --btn-close-border-radius: 3.125rem;
22
+ --btn-close-border-radius: 50%;
22
23
  --btn-close-border-width: .125rem;
23
24
  --btn-close-focus-outline-color: var(--link-focus-outline-color);
24
25
  --btn-close-focus-outline-offset: .125rem;
@@ -227,10 +228,26 @@
227
228
  --size-xl: 2rem;
228
229
  --size-xs: .5rem;
229
230
  --size-xxs: .25rem;
230
- --snackbar-border-radius: var(--radius-sm);
231
- --snackbar-duration: 5s;
231
+ --snackbar-background-color: var(--secondary-100);
232
+ --snackbar-border-radius: var(--radius-xs);
233
+ --snackbar-btn-close-active-background-color: transparent;
234
+ --snackbar-btn-close-active-icon-color: var(--snackbar-text-color);
235
+ --snackbar-btn-close-focus-outline-color: color-mix(in srgb, var(--snackbar-text-color) 50%, transparent);
236
+ --snackbar-btn-close-focus-outline-offset: .125rem;
237
+ --snackbar-btn-close-focus-outline-width: .125rem;
238
+ --snackbar-btn-close-hover-background-color: color-mix(in srgb, var(--snackbar-text-color) 40%, transparent);
239
+ --snackbar-btn-close-hover-border-color: transparent;
240
+ --snackbar-btn-close-hover-icon-color: var(--snackbar-background-color);
241
+ --snackbar-btn-close-icon-color: var(--snackbar-text-color);
242
+ --snackbar-btn-close-size: 1rem;
232
243
  --snackbar-font-size: var(--font-size-sm);
233
- --snackbar-text-color: var(--text-color);
244
+ --snackbar-outer-background-color: var(--secondary-100);
245
+ --snackbar-outer-border: none;
246
+ --snackbar-outer-border-radius: var(--radius-xs);
247
+ --snackbar-outer-drop-shadow: var(--box-shadow-base);
248
+ --snackbar-outer-padding-block: 0;
249
+ --snackbar-outer-padding-inline: 0;
250
+ --snackbar-text-color: var(--secondary-100-fg);
234
251
  --spinner-color: var(--primary-100);
235
252
  --spinner-size: var(--size-lg);
236
253
  --spinner-stroke-width: .125rem;
@@ -266,4 +283,5 @@
266
283
  --text-selected-background-color: #ddd;
267
284
  --text-selected-color: var(--body-text);
268
285
  --z-index-overlay: 99;
286
+ --z-index-snackbar: 100;
269
287
  }
@@ -0,0 +1,187 @@
1
+ # `s-datatable` web-component for simple-datatatble
2
+
3
+ </https://fiduswriter.github.io/simple-datatables/documentation/>
4
+
5
+
6
+ ## Utilizzo da markup
7
+
8
+ ```html
9
+ <s-datatable
10
+ json="/api/data.json"
11
+ cols='[{"_heading":"Nome","_field":"name"}, ...]'
12
+ perPage="10"
13
+ ></s-datatable>
14
+
15
+ <!-- Alternativa: dati inline via attributo (utile per SSR/Twig/Blade).
16
+ Se presenti entrambi, `data` ha la precedenza su `json`. -->
17
+ <s-datatable
18
+ data='[{"name":"Mario","city":"Roma"}, ...]'
19
+ cols='[{"_heading":"Nome","_field":"name"}, ...]'
20
+ perPage="10"
21
+ ></s-datatable>
22
+ ```
23
+
24
+ ## Utilizzo da script
25
+
26
+ ```javascript
27
+ const el = document.querySelector('s-datatable');
28
+ // oppure: const el = document.createElement('s-datatable');
29
+
30
+ el.init({
31
+ json: '/api/data.json',
32
+ cols: [{ _heading: 'Nome', _field: 'name' }, ...],
33
+ perPage: 10
34
+ });
35
+
36
+ // Alternativa: dati inline (array di oggetti) al posto di json
37
+ el.init({
38
+ data: [{ name: 'Mario', city: 'Roma' }, ...],
39
+ cols: [{ _heading: 'Nome', _field: 'name' }, ...],
40
+ });
41
+ // Se presenti entrambi, `data` ha la precedenza su `json`.
42
+
43
+ // Se appena creato, appendere dopo init():
44
+ document.body.appendChild(el);
45
+ ```
46
+
47
+ ## Utilizzo misto – attributi HTML + script
48
+
49
+ I parametri non inclusi in init() vengono letti dall'attributo HTML corrispondente. Si possono quindi separare configurazione statica (`cols`, `perPage`) nel markup e dati dinamici (json) nello script:
50
+
51
+ ```html
52
+ <s-datatable
53
+ id="table-utenti"
54
+ cols='[{"_heading":"Nome","_field":"name"},{"_heading":"Città","_field":"city"}]'
55
+ perPage="20"
56
+ ></s-datatable>
57
+ ```
58
+
59
+ ```javascript
60
+ el.init({ json: '/api/utenti.json' }); // → json da script, cols e perPage da attributo
61
+ ```
62
+
63
+ Ordine di precedenza: config (script) > attributo HTML > default interno.
64
+
65
+ Per ignorare esplicitamente un attributo e ricadere sul default, passare `null` nel config:
66
+
67
+ ```javascript
68
+ el.init({ json: '/api/data.json', cols: null }); // → cols = null, l'attributo viene saltato
69
+ ```
70
+
71
+ ## Reazione ad eventi esterni
72
+
73
+ Il componente ascolta tre CustomEvent che altri componenti possono emettere sul `document` (o su qualsiasi antenato del componente nel DOM):
74
+
75
+ ### `datatable:search`
76
+
77
+ Applica una ricerca su una o più colonne.
78
+
79
+ `detail: { term: string, columns?: number[] }`
80
+
81
+ Esempio – ricerca globale:
82
+
83
+ ```javascript
84
+ document.dispatchEvent(new CustomEvent('datatable:search', {
85
+ detail: { term: 'mario' }
86
+ }));
87
+ ```
88
+
89
+ Esempio – ricerca su colonna 0 e 2:
90
+
91
+ ```javascript
92
+ document.dispatchEvent(new CustomEvent('datatable:search', {
93
+ detail: { term: 'mario', columns: [0, 2] }
94
+ }));
95
+ ```
96
+
97
+ ### `datatable:multisearch`
98
+
99
+ Applica più filtri contemporaneamente (uno per colonna).
100
+
101
+ `detail: { queries: Array<{ terms: string[], columns?: number[] }> }`
102
+
103
+ Esempio – filtra colonna 1 per "mario" E colonna 3 per "roma":
104
+
105
+ ```javascript
106
+ document.dispatchEvent(new CustomEvent('datatable:multisearch', {
107
+ detail: {
108
+ queries: [
109
+ { terms: ['gino'], columns: [1] },
110
+ { terms: ['roma'], columns: [3] }
111
+ ]
112
+ }
113
+ }));
114
+ ```
115
+
116
+ ### `datatable:reload`
117
+
118
+ Ricarica i dati da un nuovo URL JSON (o dallo stesso URL originale se json è omesso), opzionalmente con nuove colonne o dati inline.
119
+
120
+ `detail: { json?: string, data?: Array, cols?: Array }`
121
+
122
+ Esempio – reload stesso URL:
123
+
124
+ ```javascript
125
+ document.dispatchEvent(new CustomEvent('datatable:reload', {
126
+ detail: {}
127
+ }));
128
+ ```
129
+
130
+ Esempio – nuovo endpoint + nuove colonne:
131
+
132
+
133
+ ```javascript
134
+ document.dispatchEvent(new CustomEvent('datatable:reload', {
135
+ detail: {
136
+ json: '/api/data-filtered.json',
137
+ cols: [{ _heading: 'Nome', _field: 'name' }]
138
+ }
139
+ }));
140
+ ```
141
+
142
+ Esempio – dati inline (senza fetch):
143
+
144
+ ```javascript
145
+ document.dispatchEvent(new CustomEvent('datatable:reload', {
146
+ detail: {
147
+ data: [{ name: 'Mario', city: 'Roma' }],
148
+ cols: [{ _heading: 'Nome', _field: 'name' }]
149
+ }
150
+ }));
151
+ ```
152
+
153
+
154
+ ## Targeting – se nella pagina ci sono più istanze di s-datatable
155
+
156
+
157
+ Aggiungere l'attributo `id` al componente e includere `target` nel detail:
158
+
159
+ `<s-datatable id="table-utenti" ...></s-datatable>`
160
+
161
+ ```javascript
162
+ document.dispatchEvent(new CustomEvent('datatable:search', {
163
+ detail: { term: 'mario', target: 'table-utenti' }
164
+ }));
165
+ ```
166
+
167
+ Se `target` è assente, l'evento viene raccolto da TUTTE le istanze.
168
+
169
+ ## Esempio parametro `cols`
170
+
171
+ ```javascript
172
+ {
173
+
174
+ cols: [
175
+ {
176
+ _field // chiave campo json (anche composta es: `key1.key2`),
177
+ _heading // testo th
178
+ _title // testo `title` del `th`
179
+ _renderMode // preset rendering predefiniti
180
+ _renderTpl // stringa mustache-like per la composizione della cella (chiavi indicate forma `[[chiave]]`)
181
+ type // parametri simple-datatable (senza `_`)
182
+ searchable // ...
183
+ sortable // ...
184
+ // ...
185
+ }
186
+ ]
187
+ }