@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.
- package/design-tokens/_src/headings.minimo.tokens.mjs +8 -0
- package/design-tokens/_src/typography.minimo.tokens.mjs +1 -1
- package/design-tokens/tokens/{headings.minimo.tokens.jsonc → design-tokens/_src/headings.minimo.tokens.jsonc} +8 -0
- package/design-tokens/tokens/src/components/inner-nav/inner-nav.minimo.tokens.jsonc +20 -0
- package/design-tokens/tokens/src/components/modal-alert/modal-alert.minimo.tokens.jsonc +166 -0
- package/design-tokens/tokens/src/components/slide-up-down-toggle/slide-up-down-toggle.minimo.tokens.jsonc +14 -0
- package/design-tokens/utilities/build-tokens-src/formats/css.mjs +1 -1
- package/design-tokens/utilities/build-tokens-src/formats/penpot.mjs +1 -1
- package/design-tokens/utilities/check-unresolved-custom-props.mjs +11 -12
- package/design-tokens/utilities/tokens-config-sample.mjs +1 -1
- package/package.json +1 -1
- package/src/components/inner-nav/inner-nav.css +2 -2
- package/src/components/inner-nav/inner-nav.minimo.tokens.mjs +15 -0
- package/src/components/modal-alert/modal-alert.js +295 -165
- package/src/components/modal-alert/modal-alert.minimo.tokens.mjs +164 -0
- package/src/components/modal-alert/modal-alert.module.css +145 -0
- package/src/components/modal-alert/svg/confirm.svg +4 -1
- package/src/components/modal-alert/svg/danger.svg +4 -0
- package/src/components/modal-alert/svg/error.svg +4 -1
- package/src/components/modal-alert/svg/info.svg +4 -1
- package/src/components/modal-alert/svg/success.svg +4 -1
- package/src/components/modal-alert/svg/warning.svg +4 -1
- package/src/components/slide-up-down-toggle/slide-up-down-toggle.minimo.tokens.mjs +9 -0
- package/src/components/slide-up-down-toggle/slide-up-down-toggle.module.css +2 -2
- package/src/custom-properties.css +26 -0
- package/src/components/modal-alert/TODO modal-alert-demo/demo.css +0 -63
- package/src/components/modal-alert/TODO modal-alert-demo/demo.js +0 -155
- package/src/components/modal-alert/TODO.md +0 -3
- package/src/components/modal-alert/customization-templates/custom-modal-alert.css +0 -46
- package/src/components/modal-alert/customization-templates/custom-modal-alert.js +0 -89
- package/src/components/modal-alert/defaults.js +0 -58
- package/src/components/modal-alert/marks.js +0 -9
- package/src/components/modal-alert/modal-alert.css +0 -159
- package/src/components/modal-alert/svg/svg-to-js.mjs +0 -26
- /package/design-tokens/tokens/{alerts.minimo.tokens.jsonc → design-tokens/_src/alerts.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{badge.minimo.tokens.jsonc → design-tokens/_src/badge.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{btn-close.minimo.tokens.jsonc → design-tokens/_src/btn-close.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{btn-color-themes.minimo.tokens.jsonc → design-tokens/_src/btn-color-themes.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{btn.minimo.tokens.jsonc → design-tokens/_src/btn.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{color-accent.minimo.tokens.jsonc → design-tokens/_src/color-accent.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{color-neutral.minimo.tokens.jsonc → design-tokens/_src/color-neutral.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{color-primary.minimo.tokens.jsonc → design-tokens/_src/color-primary.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{color-secondary.minimo.tokens.jsonc → design-tokens/_src/color-secondary.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{flex-grid.minimo.tokens.jsonc → design-tokens/_src/flex-grid.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{form-validation.minimo.tokens.jsonc → design-tokens/_src/form-validation.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{form.minimo.tokens.jsonc → design-tokens/_src/form.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{layout.minimo.tokens.jsonc → design-tokens/_src/layout.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{link.minimo.tokens.jsonc → design-tokens/_src/link.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{modal-popup.minimo.tokens.jsonc → design-tokens/_src/modal-popup.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{radius.minimo.tokens.jsonc → design-tokens/_src/radius.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{shadows.minimo.tokens.jsonc → design-tokens/_src/shadows.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{size.minimo.tokens.jsonc → design-tokens/_src/size.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{status.minimo.tokens.jsonc → design-tokens/_src/status.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{switch.minimo.tokens.jsonc → design-tokens/_src/switch.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{table.minimo.tokens.jsonc → design-tokens/_src/table.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{text.minimo.tokens.jsonc → design-tokens/_src/text.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{typography.minimo.tokens.jsonc → design-tokens/_src/typography.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{utility.minimo.tokens.jsonc → design-tokens/_src/utility.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{z-index.minimo.tokens.jsonc → design-tokens/_src/z-index.minimo.tokens.jsonc} +0 -0
- /package/design-tokens/tokens/{components → src/components/sf-macro}/sf-macro.minimo.tokens.jsonc +0 -0
- /package/design-tokens/tokens/{components → src/components/snackbar}/snackbar.minimo.tokens.jsonc +0 -0
- /package/design-tokens/tokens/{components → src/components/spinner}/spinner.minimo.tokens.jsonc +0 -0
- /package/design-tokens/tokens/{components → src/components/unsplash-page}/unsplash-page.minimo.tokens.jsonc +0 -0
- /package/design-tokens/tokens/{web-components → src/web-components/s-datatable-component}/simple-datatable.minimo.tokens.jsonc +0 -0
- /package/{design-tokens/_src/components → src/components/sf-macro}/sf-macro.minimo.tokens.mjs +0 -0
- /package/{design-tokens/_src/components → src/components/snackbar}/snackbar.minimo.tokens.mjs +0 -0
- /package/{design-tokens/_src/components → src/components/spinner}/spinner.minimo.tokens.mjs +0 -0
- /package/{design-tokens/_src/components → src/components/unsplash-page}/unsplash-page.minimo.tokens.mjs +0 -0
- /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
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
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} [
|
|
13
|
-
* @property {(() => void) | null} [onOpen]
|
|
14
|
-
* @property {(() => void) | null} [onClose]
|
|
15
|
-
* @property {
|
|
16
|
-
* @property {boolean} [
|
|
17
|
-
* @property {
|
|
18
|
-
* @property {
|
|
19
|
-
* @property {
|
|
20
|
-
* @property {string | null} [mes]
|
|
21
|
-
* @property {string | null} [
|
|
22
|
-
* @property {string | null} [
|
|
23
|
-
* @property {string | null} [
|
|
24
|
-
* @property {string | null} [
|
|
25
|
-
* @property {boolean} [
|
|
26
|
-
* @property {
|
|
27
|
-
* @property {
|
|
28
|
-
* @property {string} [
|
|
29
|
-
* @property {string} [
|
|
30
|
-
* @property {string} [
|
|
31
|
-
* @property {
|
|
32
|
-
* @property {boolean} [
|
|
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
|
-
* @
|
|
39
|
-
*
|
|
40
|
-
*
|
|
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
|
-
|
|
137
|
+
return new Promise((resolve) => {
|
|
44
138
|
|
|
45
|
-
|
|
139
|
+
try {
|
|
46
140
|
|
|
47
|
-
|
|
141
|
+
// garbage collection
|
|
142
|
+
document.querySelector('.modal-alert')?.remove();
|
|
48
143
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
154
|
+
params = /** @type {ModalAlertParams} */ ({
|
|
155
|
+
...(typedDefaults.globals ?? {}),
|
|
156
|
+
...(typedDefaults[params.type ?? ''] ?? {}),
|
|
157
|
+
...params
|
|
158
|
+
});
|
|
66
159
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
160
|
+
// backwards compatibility: 'danger' is an alias for 'error'
|
|
161
|
+
if(params.type === 'danger') {
|
|
162
|
+
params.type = 'error';
|
|
163
|
+
}
|
|
70
164
|
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
274
|
+
if(params.onOpen && typeof params.onOpen === 'function') {
|
|
275
|
+
params.onOpen();
|
|
276
|
+
}
|
|
149
277
|
|
|
150
|
-
|
|
151
|
-
|
|
278
|
+
/** @type {number | undefined} */
|
|
279
|
+
let timeoutID;
|
|
152
280
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
281
|
+
/**
|
|
282
|
+
* @param {HTMLElement | null} [btn]
|
|
283
|
+
* @returns {void}
|
|
284
|
+
*/
|
|
285
|
+
const dialogDismiss = (btn = null) => {
|
|
286
|
+
dialog.remove();
|
|
159
287
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
288
|
+
if(params.onClose && typeof params.onClose === 'function') {
|
|
289
|
+
params.onClose();
|
|
290
|
+
}
|
|
163
291
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
|
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(
|
|
184
|
-
window.
|
|
315
|
+
if( params.timer != null && params.type !== 'confirm') {
|
|
316
|
+
timeoutID = window.setTimeout( function() {
|
|
317
|
+
dialogDismiss();
|
|
318
|
+
}, params.timer);
|
|
185
319
|
}
|
|
186
|
-
};
|
|
187
320
|
|
|
188
|
-
|
|
189
|
-
timeoutID = window.setTimeout( function() {
|
|
321
|
+
dialog.addEventListener('close', () => {
|
|
190
322
|
dialogDismiss();
|
|
191
|
-
},
|
|
192
|
-
}
|
|
323
|
+
}, false);
|
|
193
324
|
|
|
194
|
-
|
|
195
|
-
dialogDismiss();
|
|
196
|
-
}, false);
|
|
325
|
+
[okBtn, cancelBtn, ...(extraBtn? [extraBtn] : [])].forEach(btn => {
|
|
197
326
|
|
|
198
|
-
|
|
327
|
+
btn?.addEventListener('click', () => {
|
|
328
|
+
dialogDismiss(btn);
|
|
329
|
+
}, false);
|
|
199
330
|
|
|
200
|
-
|
|
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
|
-
}
|
|
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
|
+
|