@massimo-cassandro/minimo 1.16.1 → 1.17.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.
- package/README.md +9 -0
- package/design-tokens/_src/components/modal-alert.minimo.tokens.mjs +164 -0
- package/design-tokens/_src/components/slide-up-down-toggle.minimo.tokens.mjs +9 -0
- package/design-tokens/_src/headings.minimo.tokens.mjs +8 -0
- package/design-tokens/_src/typography.minimo.tokens.mjs +1 -1
- package/design-tokens/tokens/components/modal-alert.minimo.tokens.jsonc +166 -0
- package/design-tokens/tokens/components/slide-up-down-toggle.minimo.tokens.jsonc +14 -0
- package/design-tokens/tokens/headings.minimo.tokens.jsonc +8 -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/dev-tools/README.md +1 -1
- package/dev-tools/starter-kit/webpack.config.mjs +0 -22
- package/package.json +2 -1
- package/src/components/modal-alert/modal-alert.js +295 -165
- 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.module.css +2 -2
- package/src/css/dimensions.css +3 -0
- package/src/css/margin-padding-bootstrap-media.css +1844 -0
- package/src/css/margin-padding-bootstrap.css +464 -0
- package/src/css/margin-padding-media.css +1843 -0
- package/src/css/margin-padding.css +405 -45
- package/src/custom-media.css +12 -0
- package/src/custom-properties.css +24 -0
- package/src/minimo.css +5 -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
|
@@ -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,145 @@
|
|
|
1
|
+
.malert {
|
|
2
|
+
width: 600px;
|
|
3
|
+
max-width: 90vw;
|
|
4
|
+
padding: 0;
|
|
5
|
+
background-color: var(--malert-background-color);
|
|
6
|
+
border: none;
|
|
7
|
+
border-radius: var(--malert-border-radius);
|
|
8
|
+
box-shadow: var(--malert-box-shadow, var(--default-box-shadow));
|
|
9
|
+
/* box-shadow: 2px 2px 12px #000; */
|
|
10
|
+
|
|
11
|
+
&::backdrop {
|
|
12
|
+
overscroll-behavior: contain;
|
|
13
|
+
background-color: var(--malert-backdrop);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&, * {
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.success {
|
|
22
|
+
--_malert-color: var(--malert-success-bg);
|
|
23
|
+
--_malert-color-fg: var(--malert-success-fg);
|
|
24
|
+
}
|
|
25
|
+
.info {
|
|
26
|
+
--_malert-color: var(--malert-info-bg);
|
|
27
|
+
--_malert-color-fg: var(--malert-info-fg);
|
|
28
|
+
}
|
|
29
|
+
.warning {
|
|
30
|
+
--_malert-color: var(--malert-warning-bg);
|
|
31
|
+
--_malert-color-fg: var(--malert-warning-fg);
|
|
32
|
+
}
|
|
33
|
+
.error {
|
|
34
|
+
--_malert-color: var(--malert-error-bg);
|
|
35
|
+
--_malert-color-fg: var(--malert-error-fg);
|
|
36
|
+
}
|
|
37
|
+
.confirm {
|
|
38
|
+
--_malert-color: var(--malert-confirm-bg);
|
|
39
|
+
--_malert-color-fg: var(--malert-confirm-fg);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
.innerWrapper{
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-flow: column nowrap;
|
|
46
|
+
/* gap: .7rem; */
|
|
47
|
+
align-items: stretch;
|
|
48
|
+
justify-content: flex-start;
|
|
49
|
+
|
|
50
|
+
@media screen and (min-width: 600px) {
|
|
51
|
+
flex-direction: row;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
.mMark {
|
|
57
|
+
display: flex;
|
|
58
|
+
flex: 0;
|
|
59
|
+
align-items: center;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
width: 100%;
|
|
62
|
+
padding: .4rem;
|
|
63
|
+
background-color: var(--_malert-color-bg);
|
|
64
|
+
|
|
65
|
+
svg {
|
|
66
|
+
width: 100px;
|
|
67
|
+
aspect-ratio: 1;
|
|
68
|
+
fill: var(--_malert-color-fg);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media screen and (min-width: 600px) {
|
|
72
|
+
flex-direction: row;
|
|
73
|
+
align-items: flex-start;
|
|
74
|
+
width: auto;
|
|
75
|
+
padding: 1rem;
|
|
76
|
+
/* svg {
|
|
77
|
+
width: 100px;
|
|
78
|
+
} */
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.mBody {
|
|
83
|
+
display: flex;
|
|
84
|
+
flex: 1;
|
|
85
|
+
flex-flow: column nowrap;
|
|
86
|
+
gap: .5rem;
|
|
87
|
+
align-items: stretch;
|
|
88
|
+
justify-content: flex-start;
|
|
89
|
+
padding: .5rem;
|
|
90
|
+
|
|
91
|
+
text-align: center;
|
|
92
|
+
|
|
93
|
+
@media screen and (min-width: 600px) {
|
|
94
|
+
padding: 1rem;
|
|
95
|
+
text-align: left;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.mHeading {
|
|
100
|
+
font-family: var(--malert-heading-font-family);
|
|
101
|
+
font-size: var(--malert-heading-font-size);
|
|
102
|
+
font-weight: var(--malert-heading-font-weight);
|
|
103
|
+
line-height: var(--malert-heading-line-height);
|
|
104
|
+
}
|
|
105
|
+
.mText {
|
|
106
|
+
font-family: var(--malert-text-font-family);
|
|
107
|
+
font-size: var(--malert-text-font-size);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.mBtns {
|
|
111
|
+
display: flex;
|
|
112
|
+
flex-flow: column nowrap;
|
|
113
|
+
gap: 1rem;
|
|
114
|
+
align-items: center;
|
|
115
|
+
justify-content: flex-start;
|
|
116
|
+
|
|
117
|
+
padding-top: 1rem;
|
|
118
|
+
margin-top: auto;
|
|
119
|
+
|
|
120
|
+
@media screen and (min-width: 600px) {
|
|
121
|
+
flex-direction: row;
|
|
122
|
+
justify-content: space-between;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
.mAnimated {
|
|
128
|
+
transform: translateY(-500%);
|
|
129
|
+
animation: dialog-in .3s ease-out;
|
|
130
|
+
|
|
131
|
+
&[open] {
|
|
132
|
+
transform: none;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@keyframes dialog-in {
|
|
137
|
+
from {
|
|
138
|
+
opacity: 0;
|
|
139
|
+
transform: translateY(-50%);
|
|
140
|
+
}
|
|
141
|
+
to {
|
|
142
|
+
opacity: 1;
|
|
143
|
+
transform: translateY(0);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
<svg
|
|
1
|
+
<svg width="134" height="134" viewBox="0 0 134 134" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M126.5 67C126.5 34.1391 99.8609 7.5 67 7.5C34.1391 7.5 7.5 34.1391 7.5 67C7.5 99.8609 34.1391 126.5 67 126.5C99.8609 126.5 126.5 99.8609 126.5 67ZM133.5 67C133.5 103.727 103.727 133.5 67 133.5C30.2731 133.5 0.5 103.727 0.5 67C0.5 30.2731 30.2731 0.5 67 0.5C103.727 0.5 133.5 30.2731 133.5 67Z" fill="#8720C5"/>
|
|
3
|
+
<path d="M66.2711 92.088C70.854 92.0881 74.5417 95.761 74.569 100.238C74.5416 104.716 70.8539 108.389 66.2711 108.389C55.2711 107.989 55.2711 92.488 66.2711 92.088ZM74.5709 100.288C74.5709 100.272 74.5691 100.255 74.569 100.238C74.5691 100.222 74.5709 100.205 74.5709 100.189V100.288ZM43.4703 35.2882C52.9703 22.6882 80.7705 23.0887 90.1705 35.3887L90.4703 35.2882C94.4703 40.1882 95.2711 49.7885 92.2711 55.6885C91.0711 58.1885 89.4705 60.288 87.6705 62.088C84.2705 65.488 79.7707 68.0884 75.8707 70.4884C74.0708 71.5883 72.6705 72.6884 71.6705 73.9884C69.4707 77.0883 69.2711 80.1883 69.2711 84.2882H63.4703C60.9704 75.8883 61.6711 68.8887 69.0709 63.8887C75.2709 59.3887 82.8707 54.9882 82.3707 46.2882C82.4707 42.8883 81.6708 40.1883 80.0709 37.9884C78.5709 35.7884 76.4707 34.1885 73.8707 33.1885C68.7709 30.9886 61.5711 30.9881 56.2711 33.088C51.5712 34.7879 47.8706 38.1881 46.6705 43.088C48.9705 43.088 50.8707 43.4887 52.3707 44.3887C55.5705 46.1888 55.6707 50.9881 53.0709 53.2882C50.4709 55.5882 45.1703 55.2885 42.4703 52.6885C38.0705 48.5885 40.2704 39.2882 43.4703 35.2882Z" fill="#8720C5"/>
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="134" height="134" viewBox="0 0 134 134" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M61.16 100.44C61.16 98.7867 61.72 97.4 62.84 96.28C63.96 95.16 65.32 94.6 66.92 94.6C68.5733 94.6 69.96 95.16 71.08 96.28C72.2 97.4 72.76 98.7867 72.76 100.44C72.76 102.04 72.2 103.4 71.08 104.52C69.96 105.64 68.5733 106.2 66.92 106.2C65.32 106.2 63.96 105.667 62.84 104.6C61.72 103.48 61.16 102.093 61.16 100.44ZM69.16 88.84H64.68C64.68 85.8533 64.6267 83.1867 64.52 80.84C64.4667 78.44 64.3333 76.3333 64.12 74.52C63.96 72.6533 63.7733 70.9467 63.56 69.4C63.3467 67.8 63.1333 66.2533 62.92 64.76C62.5467 62.6267 62.2267 60.7867 61.96 59.24C61.6933 57.64 61.4533 56.0933 61.24 54.6C61.08 53.1067 61 51.4267 61 49.56C61 47.48 61.5067 45.88 62.52 44.76C63.5333 43.5867 65 43 66.92 43C68.84 43 70.3067 43.5867 71.32 44.76C72.3333 45.88 72.84 47.48 72.84 49.56C72.84 51.3733 72.7333 53.0267 72.52 54.52C72.36 56.0133 72.1467 57.5867 71.88 59.24C71.6133 60.84 71.2933 62.7333 70.92 64.92C70.6533 66.3067 70.4133 67.8 70.2 69.4C69.9867 70.9467 69.8 72.6533 69.64 74.52C69.48 76.3867 69.3467 78.4933 69.24 80.84C69.1867 83.1333 69.16 85.8 69.16 88.84Z" fill="#CC0000"/>
|
|
3
|
+
<path d="M62.8659 12.5C64.7904 9.16666 69.6015 9.16668 71.526 12.5L131.715 116.75C133.639 120.083 131.233 124.25 127.384 124.25H7.00747L6.65102 124.238C3.01218 123.991 0.812961 119.979 2.67739 116.75L62.8659 12.5ZM10.4713 117.25H123.921L67.1959 19L10.4713 117.25Z" fill="#CC0000"/>
|
|
4
|
+
</svg>
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
<svg
|
|
1
|
+
<svg width="134" height="134" viewBox="0 0 134 134" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M126.5 67C126.5 34.1391 99.8609 7.5 67 7.5C34.1391 7.5 7.5 34.1391 7.5 67C7.5 99.8609 34.1391 126.5 67 126.5C99.8609 126.5 126.5 99.8609 126.5 67ZM133.5 67C133.5 103.727 103.727 133.5 67 133.5C30.2731 133.5 0.5 103.727 0.5 67C0.5 30.2731 30.2731 0.5 67 0.5C103.727 0.5 133.5 30.2731 133.5 67Z" fill="#CC0000"/>
|
|
3
|
+
<path d="M33.3795 37.6783C34.6613 36.2317 36.8741 36.0981 38.3209 37.3795L66.6471 62.4762L95.0836 37.3756C96.5327 36.0967 98.7448 36.2345 100.024 37.6832C101.303 39.1324 101.165 41.3445 99.7155 42.6237L71.9264 67.1539L99.7203 91.7799C101.167 93.0617 101.301 95.2735 100.019 96.7203C98.7373 98.1672 96.5256 98.301 95.0787 97.0192L66.6383 71.8219L38.316 96.8239C36.8669 98.103 34.6548 97.9652 33.3756 96.5162C32.0968 95.0671 32.2344 92.8549 33.6832 91.5758L61.359 67.1442L33.6783 42.6198C32.2319 41.3379 32.0978 39.125 33.3795 37.6783Z" fill="#CC0000"/>
|
|
4
|
+
</svg>
|