@massimo-cassandro/minimo 1.16.2 → 1.17.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.
Files changed (69) hide show
  1. package/design-tokens/_src/headings.minimo.tokens.mjs +8 -0
  2. package/design-tokens/_src/typography.minimo.tokens.mjs +1 -1
  3. package/design-tokens/tokens/{headings.minimo.tokens.jsonc → design-tokens/_src/headings.minimo.tokens.jsonc} +8 -0
  4. package/design-tokens/tokens/src/components/inner-nav/inner-nav.minimo.tokens.jsonc +20 -0
  5. package/design-tokens/tokens/src/components/modal-alert/modal-alert.minimo.tokens.jsonc +166 -0
  6. package/design-tokens/tokens/src/components/slide-up-down-toggle/slide-up-down-toggle.minimo.tokens.jsonc +14 -0
  7. package/design-tokens/utilities/build-tokens-src/formats/css.mjs +1 -1
  8. package/design-tokens/utilities/build-tokens-src/formats/penpot.mjs +1 -1
  9. package/design-tokens/utilities/check-unresolved-custom-props.mjs +11 -12
  10. package/design-tokens/utilities/tokens-config-sample.mjs +1 -1
  11. package/package.json +1 -1
  12. package/src/components/inner-nav/inner-nav.css +2 -2
  13. package/src/components/inner-nav/inner-nav.minimo.tokens.mjs +15 -0
  14. package/src/components/modal-alert/modal-alert.js +295 -165
  15. package/src/components/modal-alert/modal-alert.minimo.tokens.mjs +164 -0
  16. package/src/components/modal-alert/modal-alert.module.css +145 -0
  17. package/src/components/modal-alert/svg/confirm.svg +4 -1
  18. package/src/components/modal-alert/svg/danger.svg +4 -0
  19. package/src/components/modal-alert/svg/error.svg +4 -1
  20. package/src/components/modal-alert/svg/info.svg +4 -1
  21. package/src/components/modal-alert/svg/success.svg +4 -1
  22. package/src/components/modal-alert/svg/warning.svg +4 -1
  23. package/src/components/slide-up-down-toggle/slide-up-down-toggle.minimo.tokens.mjs +9 -0
  24. package/src/components/slide-up-down-toggle/slide-up-down-toggle.module.css +2 -2
  25. package/src/custom-properties.css +26 -0
  26. package/src/components/modal-alert/TODO modal-alert-demo/demo.css +0 -63
  27. package/src/components/modal-alert/TODO modal-alert-demo/demo.js +0 -155
  28. package/src/components/modal-alert/TODO.md +0 -3
  29. package/src/components/modal-alert/customization-templates/custom-modal-alert.css +0 -46
  30. package/src/components/modal-alert/customization-templates/custom-modal-alert.js +0 -89
  31. package/src/components/modal-alert/defaults.js +0 -58
  32. package/src/components/modal-alert/marks.js +0 -9
  33. package/src/components/modal-alert/modal-alert.css +0 -159
  34. package/src/components/modal-alert/svg/svg-to-js.mjs +0 -26
  35. /package/design-tokens/tokens/{alerts.minimo.tokens.jsonc → design-tokens/_src/alerts.minimo.tokens.jsonc} +0 -0
  36. /package/design-tokens/tokens/{badge.minimo.tokens.jsonc → design-tokens/_src/badge.minimo.tokens.jsonc} +0 -0
  37. /package/design-tokens/tokens/{btn-close.minimo.tokens.jsonc → design-tokens/_src/btn-close.minimo.tokens.jsonc} +0 -0
  38. /package/design-tokens/tokens/{btn-color-themes.minimo.tokens.jsonc → design-tokens/_src/btn-color-themes.minimo.tokens.jsonc} +0 -0
  39. /package/design-tokens/tokens/{btn.minimo.tokens.jsonc → design-tokens/_src/btn.minimo.tokens.jsonc} +0 -0
  40. /package/design-tokens/tokens/{color-accent.minimo.tokens.jsonc → design-tokens/_src/color-accent.minimo.tokens.jsonc} +0 -0
  41. /package/design-tokens/tokens/{color-neutral.minimo.tokens.jsonc → design-tokens/_src/color-neutral.minimo.tokens.jsonc} +0 -0
  42. /package/design-tokens/tokens/{color-primary.minimo.tokens.jsonc → design-tokens/_src/color-primary.minimo.tokens.jsonc} +0 -0
  43. /package/design-tokens/tokens/{color-secondary.minimo.tokens.jsonc → design-tokens/_src/color-secondary.minimo.tokens.jsonc} +0 -0
  44. /package/design-tokens/tokens/{flex-grid.minimo.tokens.jsonc → design-tokens/_src/flex-grid.minimo.tokens.jsonc} +0 -0
  45. /package/design-tokens/tokens/{form-validation.minimo.tokens.jsonc → design-tokens/_src/form-validation.minimo.tokens.jsonc} +0 -0
  46. /package/design-tokens/tokens/{form.minimo.tokens.jsonc → design-tokens/_src/form.minimo.tokens.jsonc} +0 -0
  47. /package/design-tokens/tokens/{layout.minimo.tokens.jsonc → design-tokens/_src/layout.minimo.tokens.jsonc} +0 -0
  48. /package/design-tokens/tokens/{link.minimo.tokens.jsonc → design-tokens/_src/link.minimo.tokens.jsonc} +0 -0
  49. /package/design-tokens/tokens/{modal-popup.minimo.tokens.jsonc → design-tokens/_src/modal-popup.minimo.tokens.jsonc} +0 -0
  50. /package/design-tokens/tokens/{radius.minimo.tokens.jsonc → design-tokens/_src/radius.minimo.tokens.jsonc} +0 -0
  51. /package/design-tokens/tokens/{shadows.minimo.tokens.jsonc → design-tokens/_src/shadows.minimo.tokens.jsonc} +0 -0
  52. /package/design-tokens/tokens/{size.minimo.tokens.jsonc → design-tokens/_src/size.minimo.tokens.jsonc} +0 -0
  53. /package/design-tokens/tokens/{status.minimo.tokens.jsonc → design-tokens/_src/status.minimo.tokens.jsonc} +0 -0
  54. /package/design-tokens/tokens/{switch.minimo.tokens.jsonc → design-tokens/_src/switch.minimo.tokens.jsonc} +0 -0
  55. /package/design-tokens/tokens/{table.minimo.tokens.jsonc → design-tokens/_src/table.minimo.tokens.jsonc} +0 -0
  56. /package/design-tokens/tokens/{text.minimo.tokens.jsonc → design-tokens/_src/text.minimo.tokens.jsonc} +0 -0
  57. /package/design-tokens/tokens/{typography.minimo.tokens.jsonc → design-tokens/_src/typography.minimo.tokens.jsonc} +0 -0
  58. /package/design-tokens/tokens/{utility.minimo.tokens.jsonc → design-tokens/_src/utility.minimo.tokens.jsonc} +0 -0
  59. /package/design-tokens/tokens/{z-index.minimo.tokens.jsonc → design-tokens/_src/z-index.minimo.tokens.jsonc} +0 -0
  60. /package/design-tokens/tokens/{components → src/components/sf-macro}/sf-macro.minimo.tokens.jsonc +0 -0
  61. /package/design-tokens/tokens/{components → src/components/snackbar}/snackbar.minimo.tokens.jsonc +0 -0
  62. /package/design-tokens/tokens/{components → src/components/spinner}/spinner.minimo.tokens.jsonc +0 -0
  63. /package/design-tokens/tokens/{components → src/components/unsplash-page}/unsplash-page.minimo.tokens.jsonc +0 -0
  64. /package/design-tokens/tokens/{web-components → src/web-components/s-datatable-component}/simple-datatable.minimo.tokens.jsonc +0 -0
  65. /package/{design-tokens/_src/components → src/components/sf-macro}/sf-macro.minimo.tokens.mjs +0 -0
  66. /package/{design-tokens/_src/components → src/components/snackbar}/snackbar.minimo.tokens.mjs +0 -0
  67. /package/{design-tokens/_src/components → src/components/spinner}/spinner.minimo.tokens.mjs +0 -0
  68. /package/{design-tokens/_src/components → src/components/unsplash-page}/unsplash-page.minimo.tokens.mjs +0 -0
  69. /package/{design-tokens/_src/web-components → src/web-components/s-datatable-component}/simple-datatable.minimo.tokens.mjs +0 -0
@@ -1,170 +1,297 @@
1
- import { marks as default_marks } from './marks.js';
2
- import {defaults} from './defaults.js';
3
-
4
- // https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement
1
+ import * as styles from './modal-alert.module.css';
2
+ import { domBuilder } from '../../utilities/dom-builder/dom-builder.js';
3
+ import { classnames } from '../../utilities/classnames.js';
4
+
5
+ import successIcon from './svg/success.svg?inline';
6
+ import infoIcon from './svg/info.svg?inline';
7
+ import confirmIcon from './svg/confirm.svg?inline';
8
+ import warningIcon from './svg/warning.svg?inline';
9
+ import errorIcon from './svg/error.svg?inline';
10
+ import dangerIcon from './svg/danger.svg?inline';
11
+
12
+ // backward compatibility: legacy snake_case param names mapped to their camelCase equivalent
13
+ const legacyParamNames = {
14
+ extra_class: 'extraClass',
15
+ heading_class: 'headingClass',
16
+ text_class: 'textClass',
17
+ extra_btn: 'extraBtn',
18
+ extra_btn_focus: 'extraBtnFocus',
19
+ ok_btn_text: 'okBtnText',
20
+ ok_btn_class: 'okBtnClass',
21
+ cancel_btn_text: 'cancelBtnText',
22
+ cancel_btn_class: 'cancelBtnClass',
23
+ cancel_focus: 'cancelBtnFocus',
24
+ use_warning_icon: 'useAltIcon'
25
+ };
26
+
27
+ const defaults = {
28
+
29
+ // settings applied to all dialog types; can be overridden per type
30
+ globals: {
31
+ extraClass: null,
32
+ onOpen: null,
33
+ onClose: null,
34
+ animation: true,
35
+ showMarks: true,
36
+ callback: null,
37
+ timer: null,
38
+ title: null,
39
+ mes: null,
40
+ headingClass: null,
41
+ textClass: null,
42
+ icon: null,
43
+ altIcon: null,
44
+ useAltIcon: false,
45
+ type: null,
46
+
47
+ // extra btn markup, ignored on confirm
48
+ extraBtn: null,
49
+ extraBtnFocus: true
50
+ },
51
+
52
+ success: {
53
+ type: 'success',
54
+ title: 'Operazione completata',
55
+ okBtnText: 'OK',
56
+ okBtnClass: 'btn',
57
+ timer: 4000, // ms
58
+ icon: successIcon
59
+ },
60
+ error: {
61
+ type: 'error',
62
+ title: 'Si è verificato un errore',
63
+ okBtnText: 'OK',
64
+ okBtnClass: 'btn',
65
+ icon: errorIcon
66
+ },
67
+ warning: {
68
+ type: 'warning',
69
+ title: 'Attenzione!',
70
+ okBtnText: 'OK',
71
+ okBtnClass: 'btn',
72
+ icon: warningIcon,
73
+ altIcon: dangerIcon,
74
+ useAltIcon: false // when true, uses altIcon (danger) instead of the default warning icon
75
+ },
76
+ info: {
77
+ type: 'info',
78
+ title: null,
79
+ okBtnText: 'OK',
80
+ okBtnClass: 'btn',
81
+ icon: infoIcon
82
+ },
83
+ confirm: {
84
+ type: 'confirm',
85
+ title: 'Confermi?',
86
+ okBtnText: 'OK',
87
+ cancelBtnText: 'Annulla',
88
+ cancelBtnFocus: true, // false to give focus to the ok button
89
+ okBtnClass: 'btn btn-outline',
90
+ cancelBtnClass: 'btn',
91
+ icon: confirmIcon,
92
+ altIcon: warningIcon,
93
+ useAltIcon: false // when true, uses altIcon (warning) instead of the default confirm icon
94
+ }
5
95
 
6
- // TODO rewrite as async
7
- // TODO refactor entirely, rewrite using domBuilder
96
+ };
8
97
 
9
98
  /**
10
99
  * @typedef {Object} ModalAlertParams
11
- * @property {string} type - Dialog type: `success`, `error`, `warning`, `info`, or `confirm`.
12
- * @property {string | null} [extra_class]
13
- * @property {(() => void) | null} [onOpen]
14
- * @property {(() => void) | null} [onClose]
15
- * @property {string | null} [cssFile]
16
- * @property {boolean} [animation]
17
- * @property {boolean} [showMarks]
18
- * @property {((arg?: *) => void) | null} [callback]
19
- * @property {number | null} [timer]
20
- * @property {string | null} [mes]
21
- * @property {string | null} [heading_class]
22
- * @property {string | null} [text_class]
23
- * @property {string | null} [extra_btn]
24
- * @property {string | null} [extra_btn_selector]
25
- * @property {boolean} [extra_btn_focus]
26
- * @property {string | null} [title]
27
- * @property {string} [ok_btn_text]
28
- * @property {string} [ok_btn_class]
29
- * @property {string} [cancel_btn_text]
30
- * @property {string} [cancel_btn_class]
31
- * @property {boolean} [cancel_focus]
32
- * @property {boolean} [use_warning_icon]
33
- */
34
-
35
- /**
100
+ * @property {string} [type] - Dialog type: `success`, `error`, `warning`, `info`, or `confirm`.
101
+ * @property {string | null} [extraClass] - optional dialog extra class
102
+ * @property {(() => void) | null} [onOpen] - optional callback on dialog open
103
+ * @property {(() => void) | null} [onClose] - optional callback on dialog close
104
+ * @property {boolean} [animation] - if true, dialog will be animated
105
+ * @property {boolean} [showMarks] - if true, mark iconswill be showed
106
+ * @property {((arg?: *) => void) | null} [callback] - optional callback dialog after user choice
107
+ * @property {number | null} [timer] - timer for autoclose (ms). `null` for disable
108
+ * @property {string | null} [title] - title text
109
+ * @property {string | null} [mes] - text message (plain or html)
110
+ * @property {string | null} [headingClass] - optional extra class for heading
111
+ * @property {string | null} [textClass] - optional extra class for text
112
+ * @property {string | null} [icon] - Icon markup used for the dialog; defaults to the type's icon.
113
+ * @property {string | null} [altIcon] - Alternate icon markup, used instead of `icon` when `useAltIcon` is `true`.
114
+ * @property {boolean} [useAltIcon] - When `true`, uses `altIcon` instead of `icon` (e.g. the `danger` icon on a `warning` dialog, or the `warning` icon on a `confirm` dialog).
115
+ * @property {DomBuilderItem | null} [extraBtn] - optional extra button (as domBuilder object)
116
+ * @property {boolean} [extraBtnFocus] - true if the extra button should be focused when the dialog box opens (overrides any focus assigned to the 'cancel' button)
117
+ * @property {string} [okBtnText] - text for 'ok' button
118
+ * @property {string} [okBtnClass] - alternative class for 'ok' button. It replaces the default one
119
+ * @property {string} [cancelBtnText] - text for 'cancel' button
120
+ * @property {string} [cancelBtnClass] - alternative class for 'cancel' button. It replaces the default one
121
+ * @property {boolean} [cancelBtnFocus] - true if the cancel button should be focused when the dialog box opens. It has no effect if an extraBtn is set
122
+ *
36
123
  * Renders and opens a modal alert dialog.
124
+ *
125
+ * Backward compatibility: legacy snake_case parameter names (`extra_class`, `heading_class`,
126
+ * `text_class`, `extra_btn`, `extra_btn_selector`, `extra_btn_focus`, `ok_btn_text`,
127
+ * `ok_btn_class`, `cancel_btn_text`, `cancel_btn_class`, `cancel_focus`, `use_warning_icon`)
128
+ * are still accepted and internally mapped to their camelCase equivalent, see `legacyParamNames`.
129
+ *
37
130
  * @param {ModalAlertParams} params - Dialog parameters (merged with defaults by type).
38
- * @param {Record<string, any>} [custom_defaults={}] - Per-project overrides for the default settings.
39
- * @param {Record<string, string>} [marks=default_marks] - SVG icon map keyed by dialog type.
40
- * @returns {void}
131
+ * @returns {Promise<string | boolean | undefined>} Resolves when the dialog closes. If the
132
+ * dismissing button has a `data-malert-result` attribute, that string is used; otherwise, for
133
+ * `confirm` dialogs, resolves `true`/`false` for the OK/Cancel button; otherwise `undefined`.
41
134
  */
135
+ export function modalAlert(params = {}) {
42
136
 
43
- //TODO refactoring
137
+ return new Promise((resolve) => {
44
138
 
45
- export function modalAlert(params, custom_defaults = {}, marks = default_marks) {
139
+ try {
46
140
 
47
- try {
141
+ // garbage collection
142
+ document.querySelector('.modal-alert')?.remove();
48
143
 
49
- // garbage collection
50
- document.querySelector('.modal-alert')?.remove();
51
-
52
- const typedDefaults = /** @type {Record<string, any>} */ (defaults);
144
+ // backward compatibility: map legacy snake_case keys to their camelCase equivalent
145
+ const rawParams = /** @type {Record<string, any>} */ (params);
146
+ Object.entries(legacyParamNames).forEach(([legacyKey, newKey]) => {
147
+ if(legacyKey in rawParams && !(newKey in rawParams)) {
148
+ rawParams[newKey] = rawParams[legacyKey];
149
+ }
150
+ });
53
151
 
54
- params = /** @type {ModalAlertParams} */ ({
55
- ...(typedDefaults.globals ?? {}),
56
- ...(custom_defaults.globals ?? {}),
57
- ...(typedDefaults[params.type] ?? {}),
58
- ...(custom_defaults[params.type] ?? {}),
59
- ...params
60
- });
152
+ const typedDefaults = /** @type {Record<string, any>} */ (defaults);
61
153
 
62
- // backwards compatibility: 'danger' is an alias for 'error'
63
- if(params.type === 'danger') {
64
- params.type = 'error';
65
- }
154
+ params = /** @type {ModalAlertParams} */ ({
155
+ ...(typedDefaults.globals ?? {}),
156
+ ...(typedDefaults[params.type ?? ''] ?? {}),
157
+ ...params
158
+ });
66
159
 
67
- if(!params.type || Object.keys(defaults).filter(item => item !== 'global').indexOf(params.type) === -1) {
68
- throw 'Missing or incorrect `type` parameter';
69
- }
160
+ // backwards compatibility: 'danger' is an alias for 'error'
161
+ if(params.type === 'danger') {
162
+ params.type = 'error';
163
+ }
70
164
 
71
- if(params.callback && typeof params.callback !== 'function') {
72
- throw 'Incorrect `callback` parameter';
73
- }
74
- if(params.onOpen && typeof params.onOpen !== 'function') {
75
- throw 'Incorrect `onOpen` parameter';
76
- }
77
- if(params.onClose && typeof params.onClose !== 'function') {
78
- throw 'Incorrect `onClose` parameter';
79
- }
80
- if(params.extra_btn && !params.extra_btn_selector) {
81
- throw 'Incorrect `extra_btn` parameter: missing `extra_btn_selector`';
82
- }
165
+ if(!params.type || Object.keys(defaults).filter(item => item !== 'globals').indexOf(params.type) === -1) {
166
+ throw 'Missing or incorrect `type` parameter';
167
+ }
83
168
 
84
- if(params.cssFile && !document.querySelector(`link[href='${params.cssFile}']`)) {
85
- document.head.insertAdjacentHTML('beforeend',
86
- `<link rel="stylesheet" href="${params.cssFile}" type="text/css">`
87
- );
88
- }
169
+ if(params.callback && typeof params.callback !== 'function') {
170
+ throw 'Incorrect `callback` parameter';
171
+ }
172
+ if(params.onOpen && typeof params.onOpen !== 'function') {
173
+ throw 'Incorrect `onOpen` parameter';
174
+ }
175
+ if(params.onClose && typeof params.onClose !== 'function') {
176
+ throw 'Incorrect `onClose` parameter';
177
+ }
89
178
 
90
- // confirm type can optionally use the warning icon instead of the confirm icon
91
- let icon = marks[params.type];
92
- if(params.type === 'confirm' && params.use_warning_icon) {
93
- icon = marks.warning;
94
- }
179
+ /** @type {HTMLElement | undefined} */
180
+ let okBtn;
181
+ /** @type {HTMLElement | undefined} */
182
+ let cancelBtn;
183
+ /** @type {HTMLElement | undefined} */
184
+ let extraBtn;
185
+
186
+ const focusTarget = (params.extraBtn != null && params.extraBtnFocus)
187
+ ? 'extra'
188
+ : (params.type === 'confirm' && params.cancelBtnFocus)
189
+ ? 'cancel'
190
+ : 'ok';
191
+
192
+ const dialog = /** @type {HTMLDialogElement} */ (domBuilder([
193
+ {
194
+ tag: 'dialog',
195
+ className: classnames(
196
+ styles.malert,
197
+ styles[params.type],
198
+ params.animation && styles.mAnimated,
199
+ params.extraClass
200
+ ),
201
+ attrs: {
202
+ closedBy: ['success', 'info'].includes(params.type)? 'any' : null
203
+ },
204
+ children: [
205
+ {
206
+ className: styles.innerWrapper,
207
+ children: [
208
+ {
209
+ condition: params.showMarks,
210
+ className: styles.mMark,
211
+ content: (params.useAltIcon && params.altIcon)? params.altIcon : params.icon
212
+ },
213
+ {
214
+ className: styles.mBody,
215
+ children: [
216
+ {
217
+ condition: !!params.title,
218
+ className: classnames(styles.mHeading, params.headingClass),
219
+ content: params.title
220
+ },
221
+ {
222
+ className: classnames(styles.mText, params.textClass),
223
+ content: params.mes
224
+ },
225
+ {
226
+ className: styles.mBtns,
227
+ children: [
228
+ {
229
+ tag: 'button',
230
+ className: params.okBtnClass? params.okBtnClass : 'btn btn-secondary',
231
+ attrs: {
232
+ type: 'button',
233
+ autofocus: focusTarget === 'ok'
234
+ },
235
+ callback: el => okBtn = el
236
+ },
237
+ {
238
+ condition: params.type === 'confirm',
239
+ tag: 'button',
240
+ className: params.cancelBtnClass? params.cancelBtnClass : 'btn btn-secondary btn-hollow',
241
+ attrs: {
242
+ type: 'button',
243
+ autofocus: focusTarget === 'cancel'
244
+ },
245
+ callback: el => cancelBtn = el
246
+ },
247
+ {
248
+ ...(params.extraBtn?? {}),
249
+ condition: params.extraBtn != null,
250
+ callback: el => {
251
+ extraBtn = el;
252
+ if(typeof params.extraBtn?.callback === 'function') {
253
+ params.extraBtn.callback(el);
254
+ }
255
+ },
256
+ attrs: {
257
+ ...(params.extraBtn?.attrs?? {}),
258
+ autofocus: focusTarget === 'extra'
259
+ }
260
+ },
261
+ ]
262
+ },
263
+ ]
264
+ }
265
+ ]
266
+ }
267
+ ]
95
268
 
269
+ }
270
+ ], document.body));
96
271
 
97
- // if(!params.title) {
98
- // throw '`title` parameter not present';
99
- // }
100
- const closedByAny = ['success', 'info'].indexOf(params.type) !== -1? ' closedBy="any"' : '';
101
-
102
- document.body.insertAdjacentHTML('beforeend',
103
- `<dialog class="modal-alert modal-alert-${params.type}${params.animation? ' modal-alert-animated' : ''} ${params.extra_class??''}"${closedByAny}>
104
- <div class="malert-inner">
105
- ${params.showMarks? `<div class="malert-mark">${icon}</div>` : ''}
106
- <div class="malert-body">
107
- ${params.title? `<div class="malert-heading ${params.heading_class?? ''}">${params.title}</div>` : ''}
108
- <div class="malert-text ${params.text_class?? ''}">${params.mes?? ''}</div>
109
- <div class="malert-btns">
110
- <button type="button" class="malert-ok ${params.ok_btn_class}">
111
- ${params.ok_btn_text}
112
- </button>
113
- ${params.type === 'confirm'?
114
- `<button type="button" class="malert-cancel ${params.cancel_btn_class}">
115
- ${params.cancel_btn_text}
116
- </button>`
117
- : ''}
118
- ${params.extra_btn?? ''}
119
- </div>
120
- </div>
121
- </div>
122
- </dialog>`
123
- );
124
-
125
- const dialog = /** @type {HTMLDialogElement} */ (document.querySelector('.modal-alert'));
126
-
127
- dialog.showModal();
128
-
129
- // button focus
130
- const ok_btn = /** @type {HTMLElement | null} */ (dialog.querySelector('.malert-ok')),
131
- cancel_btn = /** @type {HTMLElement | null} */ (dialog.querySelector('.malert-cancel')),
132
- extra_btn = /** @type {HTMLElement | null} */ (
133
- (params.extra_btn && params.extra_btn_selector)? dialog.querySelector(params.extra_btn_selector) : null
134
- );
135
-
136
- if(extra_btn && params.extra_btn_focus) {
137
- extra_btn.focus();
138
-
139
- } else if(cancel_btn && params.cancel_focus) { // confirm
140
- cancel_btn.focus();
141
-
142
- } else {
143
- ok_btn?.focus();
144
- }
272
+ dialog.showModal();
145
273
 
146
- if(params.onOpen && typeof params.onOpen === 'function') {
147
- params.onOpen();
148
- }
274
+ if(params.onOpen && typeof params.onOpen === 'function') {
275
+ params.onOpen();
276
+ }
149
277
 
150
- /** @type {number | undefined} */
151
- let timeoutID;
278
+ /** @type {number | undefined} */
279
+ let timeoutID;
152
280
 
153
- /**
154
- * @param {HTMLElement | null} [btn]
155
- * @returns {void}
156
- */
157
- const dialogDismiss = (btn = null) => {
158
- dialog.remove();
281
+ /**
282
+ * @param {HTMLElement | null} [btn]
283
+ * @returns {void}
284
+ */
285
+ const dialogDismiss = (btn = null) => {
286
+ dialog.remove();
159
287
 
160
- if(params.onClose && typeof params.onClose === 'function') {
161
- params.onClose();
162
- }
288
+ if(params.onClose && typeof params.onClose === 'function') {
289
+ params.onClose();
290
+ }
163
291
 
164
- // If present, the callback argument is `btn.dataset.malertResult`
165
- // Otherwise, if the modal type is `confirm`, it is `true` for the OK button, `false` for the Cancel button
166
- // Otherwise, for all other modal types, it is `undefined`
167
- if(params.callback && typeof params.callback === 'function') {
292
+ // If present, the resolved/callback argument is `btn.dataset.malertResult`
293
+ // Otherwise, if the modal type is `confirm`, it is `true` for the OK button, `false` for the Cancel button
294
+ // Otherwise, for all other modal types, it is `undefined`
168
295
  let arg;
169
296
  if(btn) {
170
297
  if(btn.dataset?.malertResult) {
@@ -173,39 +300,42 @@ export function modalAlert(params, custom_defaults = {}, marks = default_marks)
173
300
  } else if(params.type === 'confirm') {
174
301
  arg = btn.classList.contains('malert-ok');
175
302
  }
176
- } else {
177
- arg = undefined;
178
303
  }
179
304
 
180
- params.callback(arg);
181
- }
305
+ if(params.callback && typeof params.callback === 'function') {
306
+ params.callback(arg);
307
+ }
308
+ resolve(arg);
309
+
310
+ if(timeoutID) {
311
+ window.clearTimeout(timeoutID);
312
+ }
313
+ };
182
314
 
183
- if(timeoutID) {
184
- window.clearTimeout(timeoutID);
315
+ if( params.timer != null && params.type !== 'confirm') {
316
+ timeoutID = window.setTimeout( function() {
317
+ dialogDismiss();
318
+ }, params.timer);
185
319
  }
186
- };
187
320
 
188
- if( params.timer && params.type !== 'confirm') {
189
- timeoutID = window.setTimeout( function() {
321
+ dialog.addEventListener('close', () => {
190
322
  dialogDismiss();
191
- }, params.timer);
192
- }
323
+ }, false);
193
324
 
194
- dialog.addEventListener('close', () => {
195
- dialogDismiss();
196
- }, false);
325
+ [okBtn, cancelBtn, ...(extraBtn? [extraBtn] : [])].forEach(btn => {
197
326
 
198
- [ok_btn, cancel_btn, ...(extra_btn? [extra_btn] : [])].forEach(btn => {
327
+ btn?.addEventListener('click', () => {
328
+ dialogDismiss(btn);
329
+ }, false);
199
330
 
200
- btn?.addEventListener('click', () => {
201
- dialogDismiss(btn);
202
- }, false);
331
+ });
203
332
 
204
- });
205
333
 
334
+ } catch(e) {
335
+ console.error( '[modal-alert] ' + e ); // eslint-disable-line
336
+ resolve(undefined);
337
+ }
206
338
 
207
- } catch(e) {
208
- console.error( e ); // eslint-disable-line
209
- }
339
+ });
210
340
 
211
341
  }
@@ -0,0 +1,164 @@
1
+ export default {
2
+ 'malert': {
3
+ background: {
4
+ color: {
5
+ $type: 'color',
6
+ $value: '#fff'
7
+ }
8
+ },
9
+ border: {
10
+ radius: {
11
+ $type: 'dimension',
12
+ $value: '{radius.xs}'
13
+ },
14
+ },
15
+ 'box-shadow-color': {
16
+ $type: 'color',
17
+ $value: '#000'
18
+ },
19
+ // https://www.joshwcomeau.com/shadow-palette/
20
+ 'box-shadow': {
21
+ $type: 'shadow',
22
+ $value: [
23
+ {
24
+ offsetX: '0',
25
+ offsetY: '.4px',
26
+ blur: '4px',
27
+ spread: '0',
28
+ color: 'color-mix(in srgb, {malert.box-shadow-color} 15%, transparent)'
29
+ },
30
+ {
31
+ offsetX: '-.3px',
32
+ offsetY: '3px',
33
+ blur: '3.3px',
34
+ spread: '-.5px',
35
+ color: 'color-mix(in srgb, {malert.box-shadow-color} 15%, transparent)'
36
+ },
37
+ {
38
+ offsetX: '-.5px',
39
+ offsetY: '6.1px',
40
+ blur: '6.6px',
41
+ spread: '-.9px',
42
+ color: 'color-mix(in srgb, {malert.box-shadow-color} 14%, transparent)'
43
+ },
44
+ {
45
+ offsetX: '-.9px',
46
+ offsetY: '11.2px',
47
+ blur: '12.1px',
48
+ spread: '-1.4px',
49
+ color: 'color-mix(in srgb, {malert.box-shadow-color} 14%, transparent)'
50
+ },
51
+ {
52
+ offsetX: '-1.6px',
53
+ offsetY: '19.5px',
54
+ blur: '21.1px',
55
+ spread: '-1.9px',
56
+ color: 'color-mix(in srgb, {malert.box-shadow-color} 13%, transparent)'
57
+ },
58
+ {
59
+ offsetX: '-2.7px',
60
+ offsetY: '32.7px',
61
+ blur: '35.4px',
62
+ spread: '-2.3px',
63
+ color: 'color-mix(in srgb, {malert.box-shadow-color} 13%, transparent)'
64
+ },
65
+ {
66
+ offsetX: '-4.3px',
67
+ offsetY: '52px',
68
+ blur: '56.4px',
69
+ spread: '-2.8px',
70
+ color: 'color-mix(in srgb, {malert.box-shadow-color} 12%, transparent)'
71
+ }
72
+ ]
73
+ },
74
+ backdrop: {
75
+ $type: 'color',
76
+ $value: 'rgb(0 0 0 / .7)'
77
+ },
78
+
79
+ success: {
80
+ bg: {
81
+ $type: 'color',
82
+ $value: '{status.success.background.color}'
83
+ },
84
+ fg: {
85
+ $type: 'color',
86
+ $value: '{status.success.fg}'
87
+ }
88
+ },
89
+ info: {
90
+ bg: {
91
+ $type: 'color',
92
+ $value: '{status.info.background.color}'
93
+ },
94
+ fg: {
95
+ $type: 'color',
96
+ $value: '{status.info.fg}'
97
+ }
98
+ },
99
+ warning: {
100
+ bg: {
101
+ $type: 'color',
102
+ $value: '{status.warning.background.color}'
103
+ },
104
+ fg: {
105
+ $type: 'color',
106
+ $value: '{status.warning.fg}'
107
+ }
108
+ },
109
+ error: {
110
+ bg: {
111
+ $type: 'color',
112
+ $value: '{status.danger.background.color}'
113
+ },
114
+ fg: {
115
+ $type: 'color',
116
+ $value: '{status.danger.fg}'
117
+ }
118
+ },
119
+ confirm: {
120
+ bg: {
121
+ $type: 'color',
122
+ $value: 'hsl(277deg 72% 45%)'
123
+ },
124
+ fg: {
125
+ $type: 'color',
126
+ $value: '#fff'
127
+ }
128
+ },
129
+
130
+ heading: {
131
+ font: {
132
+ family: {
133
+ $type: 'fontFamily',
134
+ $value: '{headings.font.family}'
135
+ },
136
+ size: {
137
+ $type: 'dimension',
138
+ $value: '{headings.h2.font.size}'
139
+ },
140
+ weight: {
141
+ $type: 'dimension',
142
+ $value: '{headings.font.weight}'
143
+ },
144
+ },
145
+ 'line-height': {
146
+ $type: 'dimension',
147
+ $value: '{headings.line-height}'
148
+ }
149
+ },
150
+ text: {
151
+ font: {
152
+ family: {
153
+ $type: 'fontFamily',
154
+ $value: '{font.family}'
155
+ },
156
+ size: {
157
+ $type: 'dimension',
158
+ $value: '{font.size.base}'
159
+ },
160
+ }
161
+ }
162
+ }
163
+ };
164
+