@massimo-cassandro/minimo 1.4.13 → 1.5.1

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.
@@ -0,0 +1,82 @@
1
+ // -----------------------------------------------------------------------
2
+ // Generated file — do not edit manually.
3
+ // This file is produced by the design-token build pipeline.
4
+ // Source of truth: the token files in the project source directory.
5
+ // Re-generate with: node build-tokens.mjs --config <path/to/config>
6
+ // -----------------------------------------------------------------------
7
+ {
8
+ "modal-popup": {
9
+ "drop-shadow": {
10
+ "$type": "shadow",
11
+ "$value": [
12
+ {
13
+ "offsetX": "0",
14
+ "offsetY": "0",
15
+ "blur": "12px",
16
+ "spread": "2px",
17
+ "color": "rgba(0 0 0 / .25)"
18
+ }
19
+ ]
20
+ },
21
+ "backdrop-color": {
22
+ "$type": "color",
23
+ "$value": "rgb(0 0 0 / .6)"
24
+ },
25
+ "border": {
26
+ "radius": {
27
+ "$type": "dimension",
28
+ "$value": "{size.base}"
29
+ }
30
+ },
31
+ "btn-close": {
32
+ "size": {
33
+ "$type": "dimension",
34
+ "$value": "1.6rem"
35
+ }
36
+ },
37
+ "header": {
38
+ "padding": {
39
+ "$type": "dimension",
40
+ "$value": "{size.xs}"
41
+ },
42
+ "color": {
43
+ "$type": "color",
44
+ "$value": "{text.color}"
45
+ },
46
+ "background": {
47
+ "color": {
48
+ "$type": "color",
49
+ "$value": "#ddd"
50
+ }
51
+ },
52
+ "font": {
53
+ "size": {
54
+ "$type": "dimension",
55
+ "$value": "{font.size.xl}"
56
+ }
57
+ }
58
+ },
59
+ "footer": {
60
+ "padding": {
61
+ "$type": "dimension",
62
+ "$value": "{size.xs}"
63
+ },
64
+ "color": {
65
+ "$type": "color",
66
+ "$value": "{text.color}"
67
+ },
68
+ "background": {
69
+ "color": {
70
+ "$type": "color",
71
+ "$value": "#ddd"
72
+ }
73
+ },
74
+ "font": {
75
+ "size": {
76
+ "$type": "dimension",
77
+ "$value": "{font.size.base}"
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,78 @@
1
+ export default {
2
+ 'modal-popup': {
3
+ 'drop-shadow': {
4
+ $type: 'shadow',
5
+ $value: [
6
+ {
7
+ offsetX: '0',
8
+ offsetY: '0',
9
+ blur: '12px',
10
+ spread: '2px',
11
+ color: 'rgba(0 0 0 / .25)'
12
+ }
13
+ ]
14
+ },
15
+ 'backdrop-color': {
16
+ $value: 'rgb(0 0 0 / .6)',
17
+ $type: 'color',
18
+ },
19
+ border: {
20
+ radius: {
21
+ $type: 'dimension',
22
+ $value: '{size.base}',
23
+ }
24
+ },
25
+
26
+ 'btn-close': {
27
+ size: {
28
+ $type: 'dimension',
29
+ $value: '1.6rem'
30
+ }
31
+
32
+ },
33
+ header: {
34
+ padding: {
35
+ $type: 'dimension',
36
+ $value: '{size.xs}',
37
+ },
38
+ color: {
39
+ $type: 'color',
40
+ $value: '{text.color}'
41
+ },
42
+ background: {
43
+ color: {
44
+ $type: 'color',
45
+ $value: '#ddd'
46
+ }
47
+ },
48
+ font: {
49
+ size: {
50
+ $type: 'dimension',
51
+ $value: '{font.size.xl}'
52
+ }
53
+ }
54
+ },
55
+ footer: {
56
+ padding: {
57
+ $type: 'dimension',
58
+ $value: '{size.xs}',
59
+ },
60
+ color: {
61
+ $type: 'color',
62
+ $value: '{text.color}'
63
+ },
64
+ background: {
65
+ color: {
66
+ $type: 'color',
67
+ $value: '#ddd'
68
+ }
69
+ },
70
+ font: {
71
+ size: {
72
+ $type: 'dimension',
73
+ $value: '{font.size.base}'
74
+ }
75
+ }
76
+ }
77
+ }
78
+ };
package/index.js CHANGED
@@ -15,4 +15,5 @@ export { innerNav } from './src/components/inner-nav/inner-nav.js';
15
15
  export { overlay, removeOverlay } from './src/components/overlay/overlay.js';
16
16
  export { sf_macro } from './src/components/sf-macro/sf-macro.js';
17
17
  export { snackbar } from './src/components/snackbar/snackbar.js';
18
+ export { modalPopup } from './src/components/modal-popup/modal-popup.js';
18
19
  export { unsplashPageJS } from './src/components/unsplash-page/unsplash-page.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massimo-cassandro/minimo",
3
- "version": "1.4.13",
3
+ "version": "1.5.1",
4
4
  "description": "Light css framework & utilities",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/massimo-cassandro/minimo#readme",
@@ -1,152 +1,203 @@
1
- import { domBuilder, classnames } from '../index.js';
2
- import { spinner } from '@minimo/spinner.js';
3
- import * as styles from './modal-content.module.css?inline';
1
+ import { domBuilder } from '../../utilities/dom-builder/dom-builder.js';
2
+ import { classnames } from '../../utilities/classnames.js';
3
+ import { spinner } from '../spinner/spinner.js';
4
+ import * as styles from './modal-popup.module.css';
4
5
 
5
6
 
7
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement
6
8
 
7
9
 
8
- // https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement
10
+ // TODO testare la modalità iframe
11
+
12
+ let dialogEl, dialogContentEl;
13
+
14
+ function closeDialog() {
15
+ dialogEl.classList.remove(styles.on);
9
16
 
10
- export function modalContent({
17
+ dialogEl.addEventListener('transitionend', () => {
18
+ dialogEl.close();
19
+ }, { once: true });
20
+ }
21
+
22
+ /**
23
+ * modalPopup
24
+ * Mostra un popup con il contenuto indicato
25
+ * il contentuo può essere in forma di:
26
+ * - array domBuilder oppure plain text oppure HTML (parametro `content`)
27
+ * - contenuto caricato via Ajax (parametri `ajaxUrl` e `ajaxCallback`)
28
+ * - iframe (parametro `iframeUrl`)
29
+ *
30
+ * in presenza di più impostazioni in conflitto, viene scelta la prima opzione utile
31
+ * nell'ordine di priorità riportato nella lista precedente.
32
+ */
11
33
 
12
- /** iframe | content */
13
- mode = 'iframe',
34
+ export function modalPopup({
14
35
 
15
36
  /** dialog extra class */
16
- dialogClassName = null,
37
+ dialogExtraClassName = null,
38
+
39
+ /** extra classname added to dialogInner */
40
+ contentExtraClassName = null,
17
41
 
18
42
  /** iframe url */
19
43
  iframeUrl = null,
20
44
 
21
- /** content string (markup) o array */
45
+ /** content: plain text, html or domBuilder array */
22
46
  content = null,
23
47
 
24
- /** content extra classname */
25
- contentClassName = null,
48
+ /** url ajax e relatuva funzione di callback.
49
+ * Quest'ultima viene invocata con argomenti i dati restituiti dalla chiamata ajax
50
+ * e con l''elemento contenitore (`ajaxCallback(data, dialogContentEl)`)
51
+ */
52
+ ajaxUrl = null,
53
+ ajaxCallback = null,
54
+
55
+ /** eventuale callback da invocare alla chiusra del dialog
56
+ * Viene invocato con il le'elento dialog (`closeCallback(dialogEl)`)
57
+ * NB: `dialogEl` viene eliminato subito dopo
58
+ */
59
+ closeCallback = null,
60
+ addScrollbarPadding = false, // aggiunge un padding extra a destra per la barra di scorrimento
61
+
62
+ /** header content: plain text or HTML */
63
+ headerContent = null,
64
+
65
+ /** footer content: plain text or HTML */
66
+ footerContent = null,
67
+ }) {
26
68
 
27
- /** dimensione modal: full, large, medium o small */
28
- size = 'large',
29
69
 
30
- /** padding: std (var(--size-md) 0) o none */
31
- padding = 'std'
32
- }) {
33
70
 
34
- if(!['content', 'iframe'].includes(mode)) {
35
- throw `modalContent: parametro 'mode' non corretto (${mode})`;
36
- }
37
- if(!iframeUrl && mode === 'iframe') {
38
- throw 'modalContent: parametro `iframeUrl` mancante';
39
- }
40
- if(content == null && mode === 'content') {
41
- throw 'modalContent: parametro `content` mancante';
42
- }
43
- if(!['full', 'large', 'medium', 'small'].includes(size)) {
44
- throw `modalContent: parametro 'size' non corretto (${size})`;
45
- }
46
- if(!['std', 'none'].includes(padding)) {
47
- throw `modalContent: parametro 'padding' non corretto (${padding})`;
71
+ if(content == null && (ajaxUrl == null || ajaxCallback == null) && iframeUrl == null) {
72
+ throw '[modalContent] parametri `content`, `ajaxUrl`/ `ajaxCallback` e `iframeUrl` mancanti';
48
73
  }
49
74
 
50
- let dialog_element, dialog_inner, iframe_element = null, content_element = null;
51
- const iframeLoadEventHandler = () => {
52
- dialog_element.classList.add(styles.on);
53
- };
75
+ let mode;
76
+ if(content != null && Array.isArray(content)) {
77
+ mode = 'domBuilder';
54
78
 
55
- if(!dialog_element) {
79
+ } else if (content != null) {
80
+ mode = 'html';
56
81
 
57
- domBuilder([
58
- {
59
- tag: 'dialog',
60
- className: styles.dialog,
61
- attrs: {
62
- 'closedby': 'any'
63
- },
64
- children: [
65
- {
66
- tag: 'button',
67
- className: styles.closeButton, // TODO standardizzare close btn
68
- attrs: {
69
- 'aria-label': 'Chiudi'
70
- }
71
- },
72
- {
73
- className: styles.dialogInner,
74
- children: [
75
- {
76
- className: styles.modalSpinner,
77
- content: spinner({container: null, withOverlay: false })
78
- }
79
-
80
- ]
81
- }
82
- ]
83
- }
84
- ], document.body);
82
+ } else if (ajaxUrl != null && ajaxCallback != null) {
83
+ mode = 'ajax';
85
84
 
85
+ } else {
86
+ mode = 'iframe';
87
+ }
86
88
 
87
- dialog_element = document.querySelector(`.${styles.dialog}`);
88
- dialog_inner = dialog_element.querySelector(`.${styles.dialogInner}`);
89
+ domBuilder([
90
+ {
91
+ tag: 'dialog',
92
+ className: classnames(styles.dialog, dialogExtraClassName, addScrollbarPadding && styles.scrollBarPadding),
93
+ attrs: {
94
+ 'closedby': 'any'
95
+ },
96
+ callback: el => dialogEl = el,
97
+ children: [
98
+ {
99
+ tag: 'button',
100
+ className: classnames('btn-close', styles.closeButton),
101
+ attrs: {
102
+ type: 'button',
103
+ 'aria-label': 'Chiudi'
104
+ }
105
+ },
106
+ {
107
+ className: styles.contentWrapper,
108
+ children: [
109
+ {
110
+ className: styles.header,
111
+ condition: headerContent != null,
112
+ content: headerContent
113
+ },
114
+ {
115
+ className: classnames(styles.content, contentExtraClassName),
116
+
117
+ content: mode === 'html'
118
+ ? content
119
+ : mode === 'ajax'
120
+ ? spinner()
121
+ : null,
122
+
123
+ children: [
124
+ ...(mode === 'domBuilder'? content : []),
125
+ {
126
+ condition: mode === 'iframe',
127
+ className: styles.iframe,
128
+ tag: 'iframe',
129
+ attrs: {
130
+ src: iframeUrl
131
+ }
132
+ }
133
+ ],
134
+ callback: el => {
135
+ dialogContentEl = el;
136
+
137
+ if(mode === 'ajax') {
138
+ try {
139
+
140
+ (async () => {
141
+ const response = await fetch(ajaxUrl),
142
+ data = await response.json();
143
+ el.innerHTML = '';
144
+ ajaxCallback(data, dialogContentEl);
145
+ })();
146
+
147
+ } catch(err) {
148
+ /* eslint-disable no-console */
149
+ console.error(ajaxUrl);
150
+ console.error(err);
151
+ /* eslint-enable no-console */
152
+ }
153
+ }
154
+
155
+ },
156
+ },
157
+ {
158
+ className: styles.footer,
159
+ condition: footerContent != null,
160
+ content: footerContent
161
+ },
162
+ ]
163
+ }
164
+ ]
165
+ }
166
+ ], document.body);
89
167
 
90
- dialog_element.querySelector(`.${styles.closeButton}`).addEventListener('click', () => {
91
- dialog_element.close();
92
- }, false);
93
168
 
94
- // listener chiusura
95
- dialog_element.addEventListener('close', () => {
169
+ // listener sul pulsante di chiusura
170
+ dialogEl.querySelector(`.${styles.closeButton}`).addEventListener('click', () => {
171
+ closeDialog();
172
+ }, false);
96
173
 
97
- iframe_element?.removeEventListener('load', iframeLoadEventHandler, false);
98
- iframe_element?.remove();
99
- content_element?.remove();
174
+ // // Esc e clic sul backdrop
175
+ // dialogEl.addEventListener('cancel', (e) => {
176
+ // e.preventDefault();
177
+ // closeDialog();
178
+ // }, false);
100
179
 
101
- document.body.classList.remove('overflow-hidden');
102
- dialog_element.classList.remove(styles.on);
103
- }, false);
104
180
 
105
- }
106
181
 
182
+ dialogEl.addEventListener('close', () => {
107
183
 
108
- // aggiunta classi extra
109
- dialog_element.className = classnames(
110
- styles.dialog,
111
- dialogClassName,
112
- styles[`size-${size}`],
113
- styles[`padding-${padding}`]
114
- );
184
+ document.body.classList.remove('overflow-hidden');
115
185
 
116
- domBuilder([
117
- {
118
- condition: mode === 'iframe',
119
- className: styles.iframeEl,
120
- tag: 'iframe',
121
- attrs: {
122
- src: ''
123
- }
124
- },
125
- {
126
- condition: mode === 'content',
127
- className: classnames(styles.contentEl, contentClassName),
128
- content: (content && !Array.isArray(content))? content : null,
129
- children: (content && Array.isArray(content))? content : null
186
+ if(closeCallback) {
187
+ closeCallback(dialogEl);
130
188
  }
131
- ], dialog_inner);
189
+ dialogEl.remove();
132
190
 
191
+ }, false);
133
192
 
134
- document.body.classList.add('overflow-hidden');
135
- dialog_element.showModal();
136
- dialog_element.focus();
137
193
 
194
+ document.body.classList.add('overflow-hidden');
195
+ dialogEl.showModal();
196
+ dialogEl.focus();
138
197
 
139
- if(mode === 'iframe') {
140
- iframe_element = dialog_element.querySelector(`.${styles.iframeEl}`);
141
- iframe_element.src = iframeUrl;
142
-
143
- // listener load per i frame
144
- iframe_element?.addEventListener('load', iframeLoadEventHandler, false);
198
+ dialogEl.classList.add(styles.on);
145
199
 
146
200
 
147
- } else if (mode === 'content') {
148
- content_element = dialog_element.querySelector(`.${styles.contentEl}`);
149
- dialog_element.classList.add(styles.on);
150
- }
201
+ return dialogEl;
151
202
 
152
203
  }
@@ -1,142 +1,104 @@
1
- /* TODO custom props nel file generale */
2
- /* TODO prevedere opzione con bordo del pulsante di chiusura (NB: si disallinea) */
3
- /* TODO cambiare icona chiusura con svg? */
4
- /* TODO aggiungere wrapper intorno a dialogInner (a filo con il dialog) per la scroll bar */
1
+ /*
2
+ NB:
3
+ `--_modal-popup-width` and `--_modal-popup-height` are used with a fallback value
4
+ but can be set with a desired value caso per caso
5
+
6
+ */
7
+
8
+ .dialog {
5
9
 
6
- .dialog { /* dialog */
7
- --modal-border-radius: var(--radius-md, 1.2rem);
8
10
  position: fixed;
9
- max-width: 80dvw;
11
+
12
+ display: flex;
13
+ flex-direction: column;
14
+
15
+ width: var(--_modal-popup-width, max-content);
16
+ min-width: 400px;
17
+ max-width: 98dvw;
18
+ height: var(--_modal-popup-height, max-content);
19
+ min-height: 300px;
10
20
  max-height: 90dvh;
11
21
  padding: 0;
12
22
  margin: auto;
13
23
  overflow: visible;
14
- background-color: var(--body-bg-color, #fff);
24
+ background-color: var(--body-background-color);
15
25
  border: none;
16
- border-radius: var(--modal-border-radius);
17
- box-shadow: 0 0 2rem .5rem rgb(0 0 0 / .5);
26
+ border-radius: var(--modal-popup-border-radius);
27
+ box-shadow: var(--modal-popup-drop-shadow);
18
28
  scale: 0;
19
29
  transition: scale .2s ease-out;
20
30
 
21
- /* stylelint-disable selector-class-pattern */
22
- &.size-full {
23
- width: 80dvw;
24
- height: 90dvh;
25
- }
26
- /* dimensioni std -> size == 'large' */
27
- &.size-large {
28
- width: 50rem; /* 800px */
29
- height: auto;
30
- }
31
- &.size-medium {
32
- width: 37.5rem; /* 600px */
33
- height: 37.5rem;
34
- }
35
- &.size-small {
36
- width: 32rem; /* ~500 x 400 */
37
- height: 25rem;
31
+ &::backdrop {
32
+ overscroll-behavior: contain;
33
+ background-color: var(--modal-popup-backdrop-color);
38
34
  }
39
- /* stylelint-enable selector-class-pattern */
40
35
 
41
36
  &.on {
42
37
  scale: 1;
43
38
  }
44
39
 
45
- &::backdrop {
46
- overscroll-behavior: contain;
47
- background-color: rgb(0 0 0 / .7);
48
- }
40
+ }
41
+
42
+ .closeButton {
43
+
44
+ position: absolute;
45
+ top: calc(-1 * var(--modal-popup-btn-close-size) / 3);
46
+ right: calc(-1 * var(--modal-popup-btn-close-size) / 3);
47
+ }
49
48
 
49
+ .contentWrapper {
50
+ display: flex;
51
+ flex: 1;
52
+ flex-flow: column nowrap;
53
+ gap: 0;
54
+ align-items: stretch;
55
+ justify-content: flex-start;
56
+ min-height: 0;
50
57
  }
51
58
 
52
- .dialogInner {
53
- width: 100%;
54
- height: 100%;
55
- padding-inline-end: var(--size-md);
59
+
60
+ .content {
61
+ flex: 1;
62
+ /* width: 100%;
63
+ height: 100%; */
64
+ min-height: 0;
65
+ padding: var(--size-base) var(--size-sm) var(--size-sm);
56
66
  overflow-x: hidden;
57
67
  overflow-y: auto;
58
- /* scrollbar-gutter: stable; */
59
- border-radius: var(--modal-border-radius);
68
+ scrollbar-gutter: stable;
60
69
 
61
- /* stylelint-disable selector-class-pattern */
62
- .padding-std & {
63
- padding: var(--size-md) 0;
70
+ .scrollBarPadding & {
71
+ padding-inline-end: var(--size-md);
64
72
  }
65
- .padding-none & {
66
- padding: 0;
67
- }
68
- /* stylelint-enable selector-class-pattern */
69
- }
70
-
71
- .modalSpinner {
72
- position: relative;
73
- padding-block-start: var(--size-2xl);
74
73
 
75
- .dialog.on & {
76
- display: none;
77
- }
78
74
  }
79
75
 
80
- .iframeEl, .contentEl {
76
+ .iframe {
81
77
  width: 100%;
82
- overscroll-behavior: contain;
83
- }
84
-
85
- .iframeEl {
86
78
  height: 100%;
87
79
  padding: 0;
88
80
  margin: 0;
81
+ overscroll-behavior: contain;
89
82
  border: none;
90
83
  }
91
84
 
92
- .contentEl {
93
- min-height: 100%;
85
+ .header {
86
+ padding: var(--modal-popup-header-padding);
87
+ font-size: var(--modal-popup-header-font-size);
88
+ color: var(--modal-popup-header-color);
89
+ background-color: var(--modal-popup-header-background-color);
90
+ border-radius: var(--modal-popup-border-radius) var(--modal-popup-border-radius) 0 0;
91
+ }
92
+ .footer {
93
+ padding: var(--modal-popup-footer-padding);
94
+ font-size: var(--modal-popup-footer-font-size);
95
+ color: var(--modal-popup-footer-color);
96
+ background-color: var(--modal-popup-footer-background-color);
97
+ border-radius: 0 0 var(--modal-popup-border-radius) var(--modal-popup-border-radius);
94
98
  }
95
99
 
96
- .closeButton {
97
- --btn-color: var(--secondary-fg, #000);
98
- --btn-bg-color: var(--secondary, #fff);
99
- --btn-hover-color: var(--secondary, #fff);
100
- --btn-hover-bg-color: var(--secondary-fg, #000);
101
- --icon-size: 2.5rem;
102
- --btn-padding: var(--size-xs, .5rem);
103
- --icon-bars-thickness: 3px;
104
-
105
- position: absolute;
106
- top: calc(-1 * var(--icon-size) / 3);
107
- right: calc(-1 * var(--icon-size) / 3);
108
- display: block;
109
- width: var(--icon-size);
110
- height: var(--icon-size);
111
- padding: var(--btn-padding);
112
- color: var(--btn-color);
113
- cursor: pointer;
114
- background-color: var(--btn-bg-color);
115
- /* border: var(--icon-bars-thickness) solid currentColor; */
116
- border: none;
117
- border-radius: 50%;
118
-
119
-
120
- &:hover {
121
- --btn-color: var(--btn-hover-color);
122
- --btn-bg-color: var(--btn-hover-bg-color);
123
- }
124
-
125
- &::before, &::after {
126
- position: absolute;
127
- top: 50%;
128
- left: var(--btn-padding);
129
- display: block;
130
- width: calc(var(--icon-size) - (var(--btn-padding) * 2));
131
- height: var(--icon-bars-thickness);
132
- content: '';
133
- background: currentColor;
134
- }
135
- &::before {
136
- transform: translateY(-50%) rotate(45deg);
137
- }
138
- &::after {
139
- transform: translateY(-50%) rotate(-45deg);
100
+ .header, .footer {
101
+ * {
102
+ color: inherit;
140
103
  }
141
104
  }
142
-
@@ -0,0 +1,8 @@
1
+ import * as styles from './spinner.module.css';
2
+
3
+ // NB la classe spinner è legata al tipo di spinner che si decide di usare, il cui file va incluso
4
+ // TODO sistema per coinfigurare il tipo di spinner da utilizzare, per permettere l'uso di più tipi di spinner nello stesso progetto
5
+
6
+ export function spinner() {
7
+ return `<div class="${styles.spinnerWrapper}"><div class="spinner">Loading...</div></div>`;
8
+ }
@@ -0,0 +1,5 @@
1
+ .spinnerWrapper {
2
+ display: grid;
3
+ place-content: center;
4
+ padding: 2rem;
5
+ }
@@ -190,6 +190,18 @@
190
190
  --link-focus-outline-color: var(--link-color);
191
191
  --link-focus-outline-width: .125rem;
192
192
  --link-visited-color: #ae0da3;
193
+ --modal-popup-backdrop-color: rgb(0 0 0 / .6);
194
+ --modal-popup-border-radius: var(--size-base);
195
+ --modal-popup-btn-close-size: 1.6rem;
196
+ --modal-popup-drop-shadow: 0 0 .75rem .125rem rgb(0 0 0 / .25);
197
+ --modal-popup-footer-background-color: #ddd;
198
+ --modal-popup-footer-color: var(--text-color);
199
+ --modal-popup-footer-font-size: var(--font-size-base);
200
+ --modal-popup-footer-padding: var(--size-xs);
201
+ --modal-popup-header-background-color: #ddd;
202
+ --modal-popup-header-color: var(--text-color);
203
+ --modal-popup-header-font-size: var(--font-size-xl);
204
+ --modal-popup-header-padding: var(--size-xs);
193
205
  --neutral-100: #666;
194
206
  --neutral-100-fg: #fff;
195
207
  --overlay-color: rgb(0 0 0 / .6);
package/src/minimo.css CHANGED
@@ -41,3 +41,6 @@
41
41
  @import '@minimo/css/position.css';
42
42
  @import '@minimo/css/visibility.css';
43
43
 
44
+
45
+ /* spinner: include the css of the choosen spinner only */
46
+ @import '@minimo/components/spinner/spinner-circle-basic.css';
@@ -23,7 +23,7 @@ import { parseDomString } from './parseDomString.js';
23
23
  * className: 'xxx' | ['class1', 'class2'], // anche `class`
24
24
  * id: 'element-id',
25
25
  * attrs: [attr_name, attr_value] | [[...], [...]] | {name: value},
26
- * content: 'xxx' | 123 | function | Element,
26
+ * content: 'xxx' | 123 | domBuilder Array | function | Element,
27
27
  * condition: true | false,
28
28
  * callback: el => ...,
29
29
  * children: [...]
@@ -137,6 +137,9 @@ export function domBuilder(structureArray = [], parent, options = {}) {
137
137
  if (typeof item.content === 'function') {
138
138
  content = item.content();
139
139
 
140
+ } else if (Array.isArray(item.content)) {
141
+ content = domBuilder(item.content);
142
+
140
143
  } else if (item.content != null) {
141
144
  content = String(item.content);
142
145
  }
@@ -120,7 +120,7 @@ export function parseCols(col_obj){
120
120
 
121
121
  } else if(col_obj._renderMode === 'numeric') {
122
122
  return {
123
-
123
+ // TODO implementare merge con classi presenti nei parametri definiti dall'utente
124
124
  cellClass: 'text-end text-numeric',
125
125
  headerClass: 'text-end text-numeric', // NB: usata anche per il footer
126
126
  };