@massimo-cassandro/minimo 1.30.0 → 1.31.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/package.json
CHANGED
|
@@ -27,6 +27,54 @@ function closeDialog(el) {
|
|
|
27
27
|
}, { once: true });
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Wraps a single domBuilder object (not an array, not a DOM Node) into an array,
|
|
32
|
+
* so `content`/`headerContent`/`footerContent` can be handled uniformly with domBuilder arrays.
|
|
33
|
+
* @param {*} value
|
|
34
|
+
* @returns {*}
|
|
35
|
+
*/
|
|
36
|
+
function normalizeContentParam(value) {
|
|
37
|
+
if(value != null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Node)) {
|
|
38
|
+
return [value];
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {*} value - a non-null `content`/`headerContent`/`footerContent` value
|
|
45
|
+
* @returns {'domBuilder' | 'node' | 'function' | 'html'}
|
|
46
|
+
*/
|
|
47
|
+
function getContentKind(value) {
|
|
48
|
+
if(Array.isArray(value)) {
|
|
49
|
+
return 'domBuilder';
|
|
50
|
+
}
|
|
51
|
+
if(value instanceof Node) {
|
|
52
|
+
return 'node';
|
|
53
|
+
}
|
|
54
|
+
if(typeof value === 'function') {
|
|
55
|
+
return 'function';
|
|
56
|
+
}
|
|
57
|
+
return 'html';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Resolves the `content`/`children` domBuilder props for a `headerContent`/`footerContent` value.
|
|
62
|
+
* The `function` kind is not handled here: it is invoked separately, from the item's `callback`,
|
|
63
|
+
* once the container element exists.
|
|
64
|
+
* @param {*} value
|
|
65
|
+
* @returns {{content: string | Node | null, children: DomBuilderItem[] | undefined}}
|
|
66
|
+
*/
|
|
67
|
+
function getDomBuilderContentProps(value) {
|
|
68
|
+
if(value == null) {
|
|
69
|
+
return { content: null, children: undefined };
|
|
70
|
+
}
|
|
71
|
+
const kind = getContentKind(value);
|
|
72
|
+
return {
|
|
73
|
+
content: (kind === 'html' || kind === 'node') ? value : null,
|
|
74
|
+
children: kind === 'domBuilder' ? value : undefined
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
30
78
|
/**
|
|
31
79
|
* modalPopup
|
|
32
80
|
* Opens a popup dialog with the given content.
|
|
@@ -40,7 +88,7 @@ function closeDialog(el) {
|
|
|
40
88
|
*
|
|
41
89
|
* @param {Object} params
|
|
42
90
|
* @param {string | null} [params.dialogExtraClassName=null] - Extra class added to the dialog element. (default: null)
|
|
43
|
-
* @param {string | DomBuilderItem | DomBuilderItem[] | null} [params.content=null] - Plain text, HTML, a domBuilder object, or a
|
|
91
|
+
* @param {string | DomBuilderItem | DomBuilderItem[] | Node | ((container: HTMLElement) => void) | null} [params.content=null] - Plain text, HTML, a domBuilder object, a domBuilder array, a DOM node (appended as-is), or a function invoked with the content container element to populate it directly (`content(dialogContentEl)`). (default: null)
|
|
44
92
|
* @param {string | null} [params.contentExtraClassName=null] - Extra class added to the content wrapper. (default: null)
|
|
45
93
|
* @param {HTMLElement | null} [params.triggerElement=null] - Optional element that triggered the popup; when set, `aria-haspopup`, `aria-controls` and `aria-expanded` are managed on it. (default: null)
|
|
46
94
|
* @param {boolean} [params.addFocus=true] - if true, dialog receives focus after opening (default: true)
|
|
@@ -58,8 +106,8 @@ function closeDialog(el) {
|
|
|
58
106
|
* @param {((el: HTMLDialogElement) => void) | null} [params.closeCallback=null] - Called with the dialog element just before it is removed, receives the dialog element (`closeCallback(dialogEl)`). NB: `dialogEl` is removed immediately after closing. (default: null)
|
|
59
107
|
* @param {((data: *, el: Element) => void) | null} [params.ajaxCallback=null] - Called with the Ajax response and the content element. (default: null)
|
|
60
108
|
* @param {boolean} [params.addScrollbarPadding=false] - Adds right padding to compensate for the scrollbar. (default: false)
|
|
61
|
-
* @param {string | DomBuilderItem | DomBuilderItem[] | null} [params.headerContent=null] - Header content: plain text, HTML, a domBuilder object, or a
|
|
62
|
-
* @param {string | DomBuilderItem | DomBuilderItem[] | null} [params.footerContent=null] - Footer content:
|
|
109
|
+
* @param {string | DomBuilderItem | DomBuilderItem[] | Node | ((container: HTMLElement) => void) | null} [params.headerContent=null] - Header content: plain text, HTML, a domBuilder object, a domBuilder array, a DOM node, or a function invoked with the header container element to populate it directly. (default: null)
|
|
110
|
+
* @param {string | DomBuilderItem | DomBuilderItem[] | Node | ((container: HTMLElement) => void) | null} [params.footerContent=null] - Footer content: same accepted types as `headerContent`, invoked with the footer container element. (default: null)
|
|
63
111
|
* @returns {HTMLDialogElement} The dialog element.
|
|
64
112
|
*/
|
|
65
113
|
|
|
@@ -84,7 +132,7 @@ export function modalPopup({
|
|
|
84
132
|
/** iframe url */
|
|
85
133
|
iframeUrl = null,
|
|
86
134
|
|
|
87
|
-
/** content: plain text, html, domBuilder object or
|
|
135
|
+
/** content: plain text, html, domBuilder object/array, DOM node, or function(container) */
|
|
88
136
|
content = null,
|
|
89
137
|
|
|
90
138
|
/** Ajax url and callback.
|
|
@@ -98,13 +146,13 @@ export function modalPopup({
|
|
|
98
146
|
closeCallback = null,
|
|
99
147
|
addScrollbarPadding = false, // adds extra right padding to compensate for the scrollbar
|
|
100
148
|
|
|
101
|
-
/** header content: plain text, HTML, domBuilder object or
|
|
149
|
+
/** header content: plain text, HTML, domBuilder object/array, DOM node, or function(container) */
|
|
102
150
|
headerContent = null,
|
|
103
151
|
|
|
104
152
|
/** extra classname added to header */
|
|
105
153
|
headerExtraClassName = null,
|
|
106
154
|
|
|
107
|
-
/** footer content: plain text, HTML, domBuilder object or
|
|
155
|
+
/** footer content: plain text, HTML, domBuilder object/array, DOM node, or function(container) */
|
|
108
156
|
footerContent = null,
|
|
109
157
|
|
|
110
158
|
/** extra classname added to footer */
|
|
@@ -121,22 +169,13 @@ export function modalPopup({
|
|
|
121
169
|
}
|
|
122
170
|
|
|
123
171
|
// allow a single domBuilder object (in addition to a domBuilder array) by wrapping it in an array
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if(headerContent != null && typeof headerContent === 'object' && !Array.isArray(headerContent)) {
|
|
128
|
-
headerContent = [headerContent];
|
|
129
|
-
}
|
|
130
|
-
if(footerContent != null && typeof footerContent === 'object' && !Array.isArray(footerContent)) {
|
|
131
|
-
footerContent = [footerContent];
|
|
132
|
-
}
|
|
172
|
+
content = normalizeContentParam(content);
|
|
173
|
+
headerContent = normalizeContentParam(headerContent);
|
|
174
|
+
footerContent = normalizeContentParam(footerContent);
|
|
133
175
|
|
|
134
176
|
let mode;
|
|
135
|
-
if(content != null
|
|
136
|
-
mode =
|
|
137
|
-
|
|
138
|
-
} else if (content != null) {
|
|
139
|
-
mode = 'html';
|
|
177
|
+
if(content != null) {
|
|
178
|
+
mode = getContentKind(content);
|
|
140
179
|
|
|
141
180
|
} else if (ajaxUrl != null && ajaxCallback != null) {
|
|
142
181
|
mode = 'ajax';
|
|
@@ -210,13 +249,17 @@ export function modalPopup({
|
|
|
210
249
|
id: headerId,
|
|
211
250
|
className: classnames(styles.header, headerExtraClassName),
|
|
212
251
|
condition: headerContent != null,
|
|
213
|
-
|
|
214
|
-
|
|
252
|
+
...getDomBuilderContentProps(headerContent),
|
|
253
|
+
callback: el => {
|
|
254
|
+
if(headerContent != null && getContentKind(headerContent) === 'function') {
|
|
255
|
+
/** @type {(container: HTMLElement) => void} */ (headerContent)(/** @type {HTMLElement} */ (el));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
215
258
|
},
|
|
216
259
|
{
|
|
217
260
|
className: classnames(styles.content, contentExtraClassName),
|
|
218
|
-
content: mode === 'html'
|
|
219
|
-
? content
|
|
261
|
+
content: (mode === 'html' || mode === 'node')
|
|
262
|
+
? /** @type {string | Node} */ (content)
|
|
220
263
|
: mode === 'ajax'
|
|
221
264
|
? spinner()
|
|
222
265
|
: null,
|
|
@@ -233,7 +276,11 @@ export function modalPopup({
|
|
|
233
276
|
}
|
|
234
277
|
],
|
|
235
278
|
callback: el => {
|
|
236
|
-
dialogContentEl = el;
|
|
279
|
+
dialogContentEl = /** @type {HTMLElement} */ (el);
|
|
280
|
+
|
|
281
|
+
if(mode === 'function') {
|
|
282
|
+
/** @type {(container: HTMLElement) => void} */ (content)(dialogContentEl);
|
|
283
|
+
}
|
|
237
284
|
|
|
238
285
|
if(mode === 'ajax') {
|
|
239
286
|
try {
|
|
@@ -241,7 +288,7 @@ export function modalPopup({
|
|
|
241
288
|
(async () => {
|
|
242
289
|
const response = await fetch(safeAjaxUrl),
|
|
243
290
|
data = await response.json();
|
|
244
|
-
|
|
291
|
+
dialogContentEl.innerHTML = '';
|
|
245
292
|
ajaxCallback?.(data, dialogContentEl);
|
|
246
293
|
})();
|
|
247
294
|
|
|
@@ -258,8 +305,12 @@ export function modalPopup({
|
|
|
258
305
|
{
|
|
259
306
|
className: classnames(styles.footer, footerExtraClassName),
|
|
260
307
|
condition: footerContent != null,
|
|
261
|
-
|
|
262
|
-
|
|
308
|
+
...getDomBuilderContentProps(footerContent),
|
|
309
|
+
callback: el => {
|
|
310
|
+
if(footerContent != null && getContentKind(footerContent) === 'function') {
|
|
311
|
+
/** @type {(container: HTMLElement) => void} */ (footerContent)(/** @type {HTMLElement} */ (el));
|
|
312
|
+
}
|
|
313
|
+
}
|
|
263
314
|
},
|
|
264
315
|
]
|
|
265
316
|
}
|