@massimo-cassandro/minimo 1.25.0 → 1.27.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/dev-tools/starter-kit/starter-install.sh +1 -0
- package/dev-tools/starter-kit/templates/CLAUDE-frontend.md +13 -0
- package/dev-tools/starter-kit/webpack.config.mjs +13 -0
- package/index.js +1 -1
- package/package.json +1 -1
- package/src/utilities/dom-builder/dom-builder.js +32 -4
- package/src/utilities/dom-builder-helpers/form-tags.js +88 -14
|
@@ -139,6 +139,7 @@ safe_cat "${TEMPLATES_DIR}/_editorconfig" .editorconfig new
|
|
|
139
139
|
safe_cat "${TEMPLATES_DIR}/_prettierrc" .prettierrc new
|
|
140
140
|
safe_cat "${TEMPLATES_DIR}/_root_htaccess" "${FRONTEND_INSTALL_PATH}/_root_htaccess"
|
|
141
141
|
safe_cat "${TEMPLATES_DIR}/_root_robots.txt" "${FRONTEND_INSTALL_PATH}/_root_robots.txt"
|
|
142
|
+
safe_cat "${TEMPLATES_DIR}/CLAUDE-frontend.md" "${FRONTEND_INSTALL_PATH}/CLAUDE.md"
|
|
142
143
|
|
|
143
144
|
# jsconfig.json: sta SEMPRE nella root del progetto (è anche il file di
|
|
144
145
|
# riferimento di vscode). I suoi path sono quindi relativi alla root: il
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# CLAUDE.md - frontend
|
|
2
|
+
|
|
3
|
+
## Contesto di dominio
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## Stile di lavoro
|
|
8
|
+
|
|
9
|
+
- Conferma la comprensione prima di agire su richieste ambigue
|
|
10
|
+
- Il progetto usa ES modules (import/export), evitare sioluzioni che utilizzano commonJs
|
|
11
|
+
- In linea di massima non proporre soluzioni che richiedano modifiche alla parte back-end, a meno che non sia esplicitamente richiesto
|
|
12
|
+
- nella chat evitare neologismi come parsare, committare ecc., usare i termini corrispondi in italiano o il termine originale in inglese dove non sia possibile un equivalente in italiano
|
|
13
|
+
- nei commenti su più righe preferire `/* ... */` piuttosto che ripetere `//` ad igni inizio riga
|
|
@@ -252,6 +252,19 @@ const config = {
|
|
|
252
252
|
directory: path.join(__dirname, '/'),
|
|
253
253
|
serveIndex: true
|
|
254
254
|
},
|
|
255
|
+
/*
|
|
256
|
+
proxy: [
|
|
257
|
+
{
|
|
258
|
+
// /login, /logout (redirect Google) e /api/... (fetch AJAX) vanno
|
|
259
|
+
// inoltrati al server PHP reale (npm run "php server", vedi
|
|
260
|
+
// package.json e app/router.php), che webpack-dev-server non può
|
|
261
|
+
// eseguire da solo.
|
|
262
|
+
context: ['/api', '/login', '/logout'],
|
|
263
|
+
target: process.env.PHP_BASE_URL || 'http://localhost:8000'
|
|
264
|
+
}
|
|
265
|
+
],
|
|
266
|
+
static: false,
|
|
267
|
+
*/
|
|
255
268
|
open: { app: { name: 'Google Chrome' } },
|
|
256
269
|
compress: true,
|
|
257
270
|
hot: true,
|
package/index.js
CHANGED
|
@@ -20,7 +20,7 @@ export { ValidationError } from './src/utilities/validation-error-class.js';
|
|
|
20
20
|
|
|
21
21
|
// domBuilder helpers
|
|
22
22
|
export { buildPictureTag } from './src/utilities/dom-builder-helpers/picture-tag.js';
|
|
23
|
-
export { buildInput, buildCheckbox, buildTextarea, buildFakeField, buildSelect } from './src/utilities/dom-builder-helpers/form-tags.js';
|
|
23
|
+
export { buildInput, buildCheckbox, buildTextarea, buildFakeField, buildSelect, buildButton } from './src/utilities/dom-builder-helpers/form-tags.js';
|
|
24
24
|
|
|
25
25
|
// components
|
|
26
26
|
export { dismissAlerts } from './src/components/dismiss-alerts.js';
|
package/package.json
CHANGED
|
@@ -25,7 +25,7 @@ import { parseDomString } from './parseDomString.js';
|
|
|
25
25
|
* property except `condition` and `callback` is ignored.
|
|
26
26
|
* @property {boolean} [condition=true] - When false, the element (or text node) is skipped.
|
|
27
27
|
* @property {(function(HTMLElement|Text): void) | null} [callback] - Callback invoked after the element (or text node) is created.
|
|
28
|
-
* @property {Array<DomBuilderItem|string>} [children] - Configuration array for child elements. Accepts strings (shorthand per `parseDomString`) and/or
|
|
28
|
+
* @property {Array<DomBuilderItem|string|Node>} [children] - Configuration array for child elements. Accepts strings (shorthand per `parseDomString`), configuration objects, and/or `Node`s (an `Element`, a `DocumentFragment`, ...) inserted as-is.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
/**
|
|
@@ -85,7 +85,7 @@ import { parseDomString } from './parseDomString.js';
|
|
|
85
85
|
* object-level properties take precedence.
|
|
86
86
|
*
|
|
87
87
|
* @function domBuilder
|
|
88
|
-
* @param {Array<DomBuilderItem|string>} [structureArray=[]] - Configuration array. Accepts strings (shorthand per `parseDomString`) and/or
|
|
88
|
+
* @param {Array<DomBuilderItem|string|Node>} [structureArray=[]] - Configuration array. Accepts strings (shorthand per `parseDomString`), configuration objects, and/or `Node`s (an `Element`, a `DocumentFragment`, ...) inserted as-is; each configuration object supports:
|
|
89
89
|
* - `tag` / `tagName` {string | string[]} - HTML tag name, or array of nested tags (each is parent of the next). Default `'div'`.
|
|
90
90
|
* - `className` / `class` / `classname` {string | string[]} - CSS class(es): a single string or an array (falsy values filtered out).
|
|
91
91
|
* - `id` {string | null} - Unique element ID.
|
|
@@ -94,7 +94,7 @@ import { parseDomString } from './parseDomString.js';
|
|
|
94
94
|
* - `text` {string | number} - Literal text node shorthand: inserts a plain `Text` node (never parsed as markup) as a sibling of other items, in place of an element. Mutually exclusive with `tag`/`content`/`children`.
|
|
95
95
|
* - `condition` {boolean} - When false, the element (or text node) is skipped. Default `true`.
|
|
96
96
|
* - `callback` {(function(HTMLElement|Text): void) | null} - Invoked after the element (or text node) is created.
|
|
97
|
-
* - `children` {Array<DomBuilderItem|string>} - Configuration array for child elements (same format, nested).
|
|
97
|
+
* - `children` {Array<DomBuilderItem|string|Node>} - Configuration array for child elements (same format, nested; also accepts `Node`s inserted as-is).
|
|
98
98
|
*
|
|
99
99
|
* IDs and classes can be specified either as top-level object keys or inside `attrs`; top-level properties take precedence.
|
|
100
100
|
* @param {HTMLElement} [parent] - Parent element the structure is attached to (see `options.insertMode`).
|
|
@@ -106,7 +106,7 @@ import { parseDomString } from './parseDomString.js';
|
|
|
106
106
|
*/
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
export function domBuilder(structureArray = [], parent, options = {}) {
|
|
109
|
+
export function domBuilder(/** @type {Array<DomBuilderItem|string|Node>} */ structureArray = [], parent, options = {}) {
|
|
110
110
|
|
|
111
111
|
options = {
|
|
112
112
|
emptyParent: false,
|
|
@@ -144,6 +144,34 @@ export function domBuilder(structureArray = [], parent, options = {}) {
|
|
|
144
144
|
|
|
145
145
|
structureArray.forEach(inputItem => {
|
|
146
146
|
|
|
147
|
+
// A DOM Node (Element, DocumentFragment, ...) passed directly: inserted as-is,
|
|
148
|
+
// bypassing element creation and config parsing entirely.
|
|
149
|
+
if (inputItem instanceof Node) {
|
|
150
|
+
|
|
151
|
+
elaboratedStructureArray.push(/** @type {DomBuilderItem} */ (/** @type {unknown} */ (inputItem)));
|
|
152
|
+
|
|
153
|
+
if (target) {
|
|
154
|
+
if (options.insertMode === 'before') {
|
|
155
|
+
const anchor = /** @type {HTMLElement} */ (target);
|
|
156
|
+
anchor.parentNode?.insertBefore(inputItem, anchor);
|
|
157
|
+
|
|
158
|
+
} else if (options.insertMode === 'after') {
|
|
159
|
+
const anchor = afterAnchors.get(/** @type {HTMLElement} */ (target)) ?? /** @type {HTMLElement} */ (target);
|
|
160
|
+
anchor.parentNode?.insertBefore(inputItem, anchor.nextSibling);
|
|
161
|
+
afterAnchors.set(/** @type {HTMLElement} */ (target), inputItem);
|
|
162
|
+
|
|
163
|
+
} else {
|
|
164
|
+
target.appendChild(inputItem);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (mainElement == null && inputItem instanceof Element) {
|
|
169
|
+
mainElement = /** @type {HTMLElement} */ (inputItem);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
147
175
|
/** @type {DomBuilderItem | null} */
|
|
148
176
|
let item;
|
|
149
177
|
if (inputItem != null && typeof inputItem === 'string' && inputItem !== '') {
|
|
@@ -50,10 +50,12 @@ function buildFormGroup({
|
|
|
50
50
|
* @param {string | number | null} args.value - input `value` attribute.
|
|
51
51
|
* @param {string | null} [args.type='text'] - input `type` attribute.
|
|
52
52
|
* @param {string | null} [args.wrapperClass=null] - optional class to be added to the `.form-group` wrapper.
|
|
53
|
-
* @param {string | null} [args.
|
|
53
|
+
* @param {string | null} [args.class=null] - optional class to be added to the `input`.
|
|
54
|
+
* @param {string | null} [args.classname=null] - Alias for `class`.
|
|
55
|
+
* @param {string | null} [args.className=null] - Alias for `class`.
|
|
54
56
|
* @param {boolean} [args.condition=true] - When false, the function returns `null` without building anything.
|
|
55
57
|
* @param {string | HTMLElement | null} args.help - Optional help text.
|
|
56
|
-
* @param {(function(HTMLElement): void) | null} args.callback - Optional callback function.
|
|
58
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Optional callback function.
|
|
57
59
|
* @param {Record<string, any> | null} [args.attrs={}] - Optional attributes object.
|
|
58
60
|
* @returns {DomBuilderItem|null} The `input` domBuilder item, or `null` when `condition` is false.
|
|
59
61
|
*/
|
|
@@ -64,13 +66,17 @@ export function buildInput({
|
|
|
64
66
|
value = null,
|
|
65
67
|
type = 'text',
|
|
66
68
|
wrapperClass = null,
|
|
67
|
-
|
|
69
|
+
class: classArg = null,
|
|
70
|
+
classname: classnameArg = null,
|
|
71
|
+
className: classNameArg = null,
|
|
68
72
|
condition = true,
|
|
69
73
|
help = null,
|
|
70
74
|
attrs = {},
|
|
71
75
|
callback = null
|
|
72
76
|
}){
|
|
73
77
|
|
|
78
|
+
const className = classArg ?? classnameArg ?? classNameArg;
|
|
79
|
+
|
|
74
80
|
id = id || randomId();
|
|
75
81
|
|
|
76
82
|
return buildFormGroup({
|
|
@@ -108,11 +114,13 @@ export function buildInput({
|
|
|
108
114
|
* as an array of objects `[{somekey: value, somekey2: text},...]` objects, or as a single `{value: text, ...}` object
|
|
109
115
|
* @param {boolean} [args.addEmptyOption=true] - When true, and empty option tag is added at top
|
|
110
116
|
* @param {string | null} [args.wrapperClass=null] - optional class to be added to the `.form-group` wrapper.
|
|
111
|
-
* @param {string | null} [args.
|
|
117
|
+
* @param {string | null} [args.class=null] - optional class to be added to the `input`.
|
|
118
|
+
* @param {string | null} [args.classname=null] - Alias for `class`.
|
|
119
|
+
* @param {string | null} [args.className=null] - Alias for `class`.
|
|
112
120
|
* @param {boolean} [args.condition=true] - When false, the function returns `null` without building anything.
|
|
113
121
|
* @param {boolean} [args.useBsClass=false] - When true, uses BS5 class (`form-select`) instead of `form-control`
|
|
114
122
|
* @param {string | HTMLElement | null} args.help - Optional help text.
|
|
115
|
-
* @param {(function(HTMLElement): void) | null} args.callback - Optional callback function.
|
|
123
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Optional callback function.
|
|
116
124
|
* @param {Record<string, any> | null} [args.attrs={}] - Optional attributes object.
|
|
117
125
|
* @returns {DomBuilderItem|null} The `input` domBuilder item, or `null` when `condition` is false.
|
|
118
126
|
*/
|
|
@@ -124,7 +132,9 @@ export function buildSelect({
|
|
|
124
132
|
options = null,
|
|
125
133
|
addEmptyOption = true,
|
|
126
134
|
wrapperClass = null,
|
|
127
|
-
|
|
135
|
+
class: classArg = null,
|
|
136
|
+
classname: classnameArg = null,
|
|
137
|
+
className: classNameArg = null,
|
|
128
138
|
useBsClass = false,
|
|
129
139
|
condition = true,
|
|
130
140
|
help = null,
|
|
@@ -132,6 +142,8 @@ export function buildSelect({
|
|
|
132
142
|
callback = null
|
|
133
143
|
}){
|
|
134
144
|
|
|
145
|
+
const className = classArg ?? classnameArg ?? classNameArg;
|
|
146
|
+
|
|
135
147
|
id = id || randomId();
|
|
136
148
|
|
|
137
149
|
// normalizing options as an array of [value, text] pairs
|
|
@@ -200,7 +212,7 @@ export function buildSelect({
|
|
|
200
212
|
* @param {boolean} [args.addFormGroup=true] - When true, wraps the checkbox in a `.form-group` element.
|
|
201
213
|
* @param {boolean} [args.condition=true] - When false, the function returns `null` without building anything.
|
|
202
214
|
* @param {string | HTMLElement | null} args.help - Optional help text.
|
|
203
|
-
* @param {(function(HTMLElement): void) | null} args.callback - Optional callback function.
|
|
215
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Optional callback function.
|
|
204
216
|
* @param {Record<string, any> | null} [args.attrs={}] - Optional attributes object.
|
|
205
217
|
* @returns {DomBuilderItem|null} The `.form-check` (or `.form-group`-wrapped) domBuilder item, or `null` when `condition` is false.
|
|
206
218
|
*/
|
|
@@ -286,10 +298,12 @@ export function buildCheckbox({
|
|
|
286
298
|
* @param {string | number | null} args.value - textarea content.
|
|
287
299
|
* @param {boolean} [args.autosize=true] - adds `autosize` class
|
|
288
300
|
* @param {string | null} [args.wrapperClass=null] - optional class to be added to the `.form-group` wrapper.
|
|
289
|
-
* @param {string | null} [args.
|
|
301
|
+
* @param {string | null} [args.class=null] - optional class to be added to the textarea element.
|
|
302
|
+
* @param {string | null} [args.classname=null] - Alias for `class`.
|
|
303
|
+
* @param {string | null} [args.className=null] - Alias for `class`.
|
|
290
304
|
* @param {boolean} [args.condition=true] - When false, the function returns `null` without building anything.
|
|
291
305
|
* @param {string | HTMLElement | null} args.help - Optional help text.
|
|
292
|
-
* @param {(function(HTMLElement): void) | null} args.callback - Optional callback function.
|
|
306
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Optional callback function.
|
|
293
307
|
* @param {Record<string, any> | null} [args.attrs={}] - Optional attributes object.
|
|
294
308
|
* @returns {DomBuilderItem|null} The `textarea` domBuilder item, or `null` when `condition` is false.
|
|
295
309
|
*/
|
|
@@ -299,7 +313,9 @@ export function buildTextarea({
|
|
|
299
313
|
id = null,
|
|
300
314
|
value = null,
|
|
301
315
|
wrapperClass = null,
|
|
302
|
-
|
|
316
|
+
class: classArg = null,
|
|
317
|
+
classname: classnameArg = null,
|
|
318
|
+
className: classNameArg = null,
|
|
303
319
|
condition = true,
|
|
304
320
|
help = null,
|
|
305
321
|
callback = null,
|
|
@@ -307,6 +323,8 @@ export function buildTextarea({
|
|
|
307
323
|
autosize = true
|
|
308
324
|
}) {
|
|
309
325
|
|
|
326
|
+
const className = classArg ?? classnameArg ?? classNameArg;
|
|
327
|
+
|
|
310
328
|
id = id || randomId();
|
|
311
329
|
|
|
312
330
|
return buildFormGroup({
|
|
@@ -338,10 +356,12 @@ export function buildTextarea({
|
|
|
338
356
|
* @param {string | number | null} args.value - text content.
|
|
339
357
|
* @param {string | null} [args.wrapperClass=null] - optional class to be added to the `.form-group` wrapper.
|
|
340
358
|
* @param {boolean} [args.noBorder=true] - adds `no-border` class.
|
|
341
|
-
* @param {string | null} [args.
|
|
359
|
+
* @param {string | null} [args.class=null] - optional class to be added to the fake field.
|
|
360
|
+
* @param {string | null} [args.classname=null] - Alias for `class`.
|
|
361
|
+
* @param {string | null} [args.className=null] - Alias for `class`.
|
|
342
362
|
* @param {boolean} [args.condition=true] - When false, the function returns `null` without building anything.
|
|
343
363
|
* @param {string | HTMLElement | null} args.help - Optional help text.
|
|
344
|
-
* @param {(function(HTMLElement): void) | null} args.callback - Optional callback function.
|
|
364
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Optional callback function.
|
|
345
365
|
* @param {Record<string, any> | null} [args.attrs={}] - Optional attributes object.
|
|
346
366
|
* @returns {DomBuilderItem|null} The fake field domBuilder item, or `null` when `condition` is false.
|
|
347
367
|
*/
|
|
@@ -349,7 +369,9 @@ export function buildFakeField({
|
|
|
349
369
|
label,
|
|
350
370
|
value = null,
|
|
351
371
|
wrapperClass = null,
|
|
352
|
-
|
|
372
|
+
class: classArg = null,
|
|
373
|
+
classname: classnameArg = null,
|
|
374
|
+
className: classNameArg = null,
|
|
353
375
|
condition = true,
|
|
354
376
|
help = null,
|
|
355
377
|
callback = null,
|
|
@@ -357,6 +379,7 @@ export function buildFakeField({
|
|
|
357
379
|
noBorder = true
|
|
358
380
|
}) {
|
|
359
381
|
|
|
382
|
+
const className = classArg ?? classnameArg ?? classNameArg;
|
|
360
383
|
|
|
361
384
|
return buildFormGroup({
|
|
362
385
|
condition,
|
|
@@ -368,7 +391,6 @@ export function buildFakeField({
|
|
|
368
391
|
className: classnames('form-control-static', className, attrs?.class, noBorder && 'no-border'),
|
|
369
392
|
attrs: {
|
|
370
393
|
...(attrs??{}),
|
|
371
|
-
name: name,
|
|
372
394
|
},
|
|
373
395
|
content: value,
|
|
374
396
|
callback: callback
|
|
@@ -376,3 +398,55 @@ export function buildFakeField({
|
|
|
376
398
|
]
|
|
377
399
|
});
|
|
378
400
|
}
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* button tag builder
|
|
406
|
+
*
|
|
407
|
+
* @param {Object} args
|
|
408
|
+
* @param {string|HTMLElement|Array<DomBuilderItem>} args.content - button content. When an array of
|
|
409
|
+
* domBuilder items is passed, it is rendered via `children` instead of `content`.
|
|
410
|
+
* @param {string} [args.type=button] - button type.
|
|
411
|
+
* @param {string | null} args.id - `id` attribute.
|
|
412
|
+
* @param {string | number | null} [args.value=null] - button `value` attribute.
|
|
413
|
+
* @param {string | null} [args.class=null] - optional class to be added to the button element.
|
|
414
|
+
* @param {string | null} [args.classname=null] - Alias for `class`.
|
|
415
|
+
* @param {string | null} [args.className=null] - Alias for `class`.
|
|
416
|
+
* @param {boolean} [args.condition=true] - When false, the function returns `null` without building anything.
|
|
417
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Optional callback function.
|
|
418
|
+
* @param {Record<string, any> | null} [args.attrs={}] - Optional attributes object.
|
|
419
|
+
* @returns {DomBuilderItem|null} The `button` domBuilder item, or `null` when `condition` is false.
|
|
420
|
+
*/
|
|
421
|
+
export function buildButton({
|
|
422
|
+
content,
|
|
423
|
+
type = 'button',
|
|
424
|
+
id = null,
|
|
425
|
+
value = null,
|
|
426
|
+
class: classArg = null,
|
|
427
|
+
classname: classnameArg = null,
|
|
428
|
+
className: classNameArg = null,
|
|
429
|
+
condition = true,
|
|
430
|
+
callback = null,
|
|
431
|
+
attrs = {},
|
|
432
|
+
}) {
|
|
433
|
+
|
|
434
|
+
const className = classArg ?? classnameArg ?? classNameArg;
|
|
435
|
+
|
|
436
|
+
return {
|
|
437
|
+
condition: condition,
|
|
438
|
+
tag: 'button',
|
|
439
|
+
className: classnames(className, attrs?.class),
|
|
440
|
+
id: id,
|
|
441
|
+
attrs: {
|
|
442
|
+
...(attrs??{}),
|
|
443
|
+
type: type,
|
|
444
|
+
value: value
|
|
445
|
+
},
|
|
446
|
+
...(Array.isArray(content)
|
|
447
|
+
? { children: content }
|
|
448
|
+
: { content: content }
|
|
449
|
+
),
|
|
450
|
+
callback: callback
|
|
451
|
+
};
|
|
452
|
+
}
|