@massimo-cassandro/minimo 1.41.4 → 1.41.5
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 +12 -12
- package/charts/src/node-helpers/create-svg-canvas-node.mjs +2 -2
- package/charts/src/node-helpers/svg-text-to-path.js +9 -9
- package/charts/src/rating-display/index.js +1 -1
- package/charts/src/rating-display/ratindDisplayAnimation.js +3 -3
- package/design-tokens/README.md +2 -2
- package/design-tokens/_src/_readme.md +26 -26
- package/dev-tools/README.md +16 -16
- package/dev-tools/create-favicons/README.md +31 -31
- package/dev-tools/create-favicons/src/create-ico.mjs +2 -2
- package/dev-tools/create-favicons/src/default-params.mjs +1 -1
- package/dev-tools/create-favicons/src/init.mjs +1 -1
- package/dev-tools/design-tokens-builder/README.md +102 -102
- package/dev-tools/design-tokens-builder/build-tokens-src/build-source-modes.mjs +85 -73
- package/dev-tools/design-tokens-builder/build-tokens-src/config.mjs +109 -85
- package/dev-tools/design-tokens-builder/build-tokens-src/formats/css.mjs +113 -90
- package/dev-tools/design-tokens-builder/build-tokens-src/formats/json.mjs +107 -95
- package/dev-tools/design-tokens-builder/build-tokens-src/legacy-tokens-parser.mjs +71 -64
- package/dev-tools/design-tokens-builder/build-tokens-src/light-dark.mjs +75 -65
- package/dev-tools/design-tokens-builder/build-tokens-src/merge-css.mjs +113 -102
- package/dev-tools/design-tokens-builder/build-tokens-src/platforms.mjs +36 -30
- package/dev-tools/design-tokens-builder/build-tokens-src/resolve-source-paths.mjs +15 -13
- package/dev-tools/design-tokens-builder/build-tokens-src/source-prefixes.mjs +44 -42
- package/dev-tools/design-tokens-builder/build-tokens-src/source-transforms.mjs +89 -83
- package/dev-tools/design-tokens-builder/build-tokens-src/token-rename-parser.mjs +99 -86
- package/dev-tools/design-tokens-builder/build-tokens-src/transforms.mjs +64 -48
- package/dev-tools/design-tokens-builder/build-tokens.mjs +80 -68
- package/dev-tools/design-tokens-builder/check-unresolved-custom-props.mjs +103 -77
- package/dev-tools/design-tokens-builder/tokens-config-sample.mjs +275 -238
- package/dev-tools/find-orphan-css-classes/find-orphan-css-classes.mjs +2 -2
- package/dev-tools/starter-kit/source_files/app/CLAUDE.md +4 -2
- package/dev-tools/starter-kit/source_files/app/{css/index.css → index.css} +2 -2
- package/dev-tools/starter-kit/source_files/app/index.js +1 -1
- package/dev-tools/starter-kit/source_files/root/_sf/controller/ImgViewerController.php +3 -3
- package/dev-tools/starter-kit/source_files/root/_sf/controller/ViewerController.php +2 -2
- package/dev-tools/starter-kit/source_files/root/stylelint.config.mjs +1 -1
- package/dev-tools/starter-kit/source_files/root/webpack-config-modules/css-rules.mjs +1 -1
- package/dev-tools/stylelint-config/README.md +7 -7
- package/dev-tools/svg-icons-tools/README.md +32 -32
- package/dev-tools/svg-icons-tools/src/config-manager.mjs +1 -1
- package/dev-tools/svg-icons-tools/src/default-config.mjs +118 -118
- package/dev-tools/svg-icons-tools/src/jsx-icon-file-builder.mjs +24 -24
- package/dev-tools/svg-icons-tools/src/parse-svg-filename.mjs +3 -3
- package/dev-tools/svg-icons-tools/src/parse-svg-files.mjs +1 -1
- package/dev-tools/svg-icons-tools/src/parse-svg-markup.mjs +4 -4
- package/dev-tools/svg-icons-tools/src/svg-to-jsx.mjs +2 -2
- package/dev-tools/svg-icons-tools/src/svg-to-optimized.mjs +2 -2
- package/dev-tools/svg-icons-tools/src/svg-to-symbols.mjs +2 -2
- package/dev-tools/upd@m/README.md +1 -1
- package/dev-tools/upd@m/index.mjs +1 -1
- package/dev-tools/update-version/README.md +9 -9
- package/package.json +1 -1
- package/snippets/unsplash-browser-app/README.md +1 -1
- package/snippets/unsplash-browser-app/unsplash-utilities.js +9 -9
- package/src/components/autocomplete/README.md +3 -3
- package/src/components/autocomplete/autocomplete-engine.js +75 -63
- package/src/components/autocomplete/check-autocomplete.js +3 -3
- package/src/components/dismiss-alerts.js +3 -3
- package/src/components/form-reset-submit.js +6 -6
- package/src/components/inner-nav/inner-nav.js +2 -2
- package/src/components/modal-alert/modal-alert.js +67 -65
- package/src/components/modal-alert/modal-alert.minimo.tokens.mjs +1 -1
- package/src/components/modal-popup/modal-popup.js +56 -56
- package/src/components/overlay/overlay.js +3 -3
- package/src/components/sf-macro/readme.md +1 -1
- package/src/components/sf-macro/sf-macro.js +27 -23
- package/src/components/slide-up-down-toggle/slide-up-down-toggle.js +83 -79
- package/src/components/slide-up-down-toggle/slide-up-down-toggle.module.css +44 -44
- package/src/components/snackbar/snackbar.js +19 -19
- package/src/components/spinner/spinner.js +3 -3
- package/src/components/unsplash-page/README.md +8 -8
- package/src/components/unsplash-page/fetch-unsplash-data.js +3 -3
- package/src/components/unsplash-page/unsplash-page.js +33 -33
- package/src/components/unsplash-page/unsplash-page.module.css +1 -1
- package/src/css/alerts.css +2 -2
- package/src/css/forms/forms.css +4 -4
- package/src/css/forms/validation.css +1 -1
- package/src/css/margin-padding-media.css +4 -4
- package/src/css/margin-padding.css +4 -4
- package/src/css/reset.css +11 -11
- package/src/icons/read-me.md +1 -1
- package/src/minimo.css +3 -3
- package/src/utilities/better-text-with-places.js +22 -22
- package/src/utilities/better-text.js +42 -35
- package/src/utilities/classnames.js +8 -8
- package/src/utilities/cookies.js +6 -6
- package/src/utilities/create-id.js +3 -3
- package/src/utilities/disable-btns-on-submit.js +2 -2
- package/src/utilities/dom-builder/dom-builder.js +89 -86
- package/src/utilities/dom-builder/domBuilderBasicSetup.js +9 -9
- package/src/utilities/dom-builder/parseDomString.js +23 -23
- package/src/utilities/dom-builder-helpers/README.md +2 -2
- package/src/utilities/dom-builder-helpers/form-tags.js +100 -100
- package/src/utilities/dom-builder-helpers/picture-tag.js +39 -39
- package/src/utilities/enable-submit-btns.js +1 -1
- package/src/utilities/escape-html.js +2 -2
- package/src/utilities/generate-pwd.js +4 -4
- package/src/utilities/linked-dates.js +13 -13
- package/src/utilities/parse-file-size.js +6 -6
- package/src/utilities/random-id.js +3 -3
- package/src/utilities/relative-date.js +40 -40
- package/src/utilities/sentence-case.js +1 -1
- package/src/utilities/strip-tags.js +1 -1
- package/src/utilities/title-case.js +1 -1
- package/src/utilities/truncate-string.js +5 -5
- package/src/utilities/validation-error-class.js +12 -12
- package/src/web-components/json-table/json-table-component.js +123 -121
- package/src/web-components/json-table/json-table-component.module.css +6 -6
- package/src/web-components/json-table/json-table.minimo.tokens.mjs +6 -6
- package/src/web-components/json-table/readme.md +72 -108
- package/src/web-components/json-table/src/cell-content.js +25 -25
- package/src/web-components/json-table/src/content-utils.js +21 -21
- package/src/web-components/json-table/src/data-types.js +32 -32
- package/src/web-components/json-table/src/defaults.js +230 -191
- package/src/web-components/json-table/src/get-data.js +55 -38
- package/src/web-components/json-table/src/icons.js +17 -17
- package/src/web-components/json-table/src/info-section.js +18 -18
- package/src/web-components/json-table/src/main-builder.js +45 -45
- package/src/web-components/json-table/src/pagination.js +32 -32
- package/src/web-components/json-table/src/parse-cols.js +18 -18
- package/src/web-components/json-table/src/parse-rows.js +17 -17
- package/src/web-components/json-table/src/resolve-params.js +53 -41
- package/src/web-components/json-table/src/search.js +13 -13
- package/src/web-components/json-table/src/sorting.js +20 -20
- package/src/web-components/json-table/src/table-body.js +13 -13
- package/src/web-components/json-table/src/table-builder.js +34 -34
- package/src/web-components/json-table/src/table-tfoot.js +8 -8
- package/src/web-components/json-table/src/table-thead.js +21 -21
- package/src/web-components/json-table/src/update-info.js +11 -11
- package/types/classes.d.ts +2 -2
- package/types/global.d.ts +18 -12
|
@@ -3,17 +3,17 @@ import { randomId } from '../random-id.js';
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* `condition
|
|
8
|
-
*
|
|
9
|
-
* (
|
|
6
|
+
* Wrapper `.form-group` condiviso dai builder di tag qui sotto: gestisce il controllo
|
|
7
|
+
* `condition`, `wrapperClass`, il testo di aiuto opzionale e `callback` in
|
|
8
|
+
* un unico punto, così che ogni builder debba fornire solo i propri `children`
|
|
9
|
+
* (tipicamente label + controllo).
|
|
10
10
|
*
|
|
11
11
|
* @param {Object} args
|
|
12
|
-
* @param {boolean} [args.condition=true] -
|
|
13
|
-
* @param {string | null} [args.wrapperClass=null] -
|
|
14
|
-
* @param {string | HTMLElement | null} [args.help=null] -
|
|
15
|
-
* @param {Array<Object>} args.children - domBuilder
|
|
16
|
-
* @returns {DomBuilderItem|null}
|
|
12
|
+
* @param {boolean} [args.condition=true] - Se false, restituisce `null` senza costruire nulla (default: true)
|
|
13
|
+
* @param {string | null} [args.wrapperClass=null] - classe opzionale da aggiungere al wrapper `.form-group` (default: null)
|
|
14
|
+
* @param {string | HTMLElement | null} [args.help=null] - Testo di aiuto opzionale (default: null)
|
|
15
|
+
* @param {Array<Object>} args.children - figli domBuilder da renderizzare dentro il `.form-group` (prima del testo di aiuto).
|
|
16
|
+
* @returns {DomBuilderItem|null} L'elemento domBuilder `.form-group`, oppure `null` quando `condition` è false.
|
|
17
17
|
*/
|
|
18
18
|
function buildFormGroup({
|
|
19
19
|
condition = true,
|
|
@@ -41,23 +41,23 @@ function buildFormGroup({
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
44
|
+
* Builder del tag input
|
|
45
45
|
*
|
|
46
46
|
* @param {Object} args
|
|
47
|
-
* @param {string} args.label - input
|
|
48
|
-
* @param {string | null} args.name -
|
|
49
|
-
* @param {string | null} args.id - `id
|
|
50
|
-
* @param {string | number | null} args.value -
|
|
51
|
-
* @param {string | null} [args.type='text'] -
|
|
52
|
-
* @param {string | null} [args.wrapperClass=null] -
|
|
53
|
-
* @param {string | null} [args.class=null] -
|
|
54
|
-
* @param {string | null} [args.classname=null] - Alias
|
|
55
|
-
* @param {string | null} [args.className=null] - Alias
|
|
56
|
-
* @param {boolean} [args.condition=true] -
|
|
57
|
-
* @param {string | HTMLElement | null} args.help -
|
|
58
|
-
* @param {(function(HTMLElement|Text): void) | null} args.callback -
|
|
59
|
-
* @param {Record<string, any> | null} [args.attrs={}] -
|
|
60
|
-
* @returns {DomBuilderItem|null}
|
|
47
|
+
* @param {string} args.label - label dell'input.
|
|
48
|
+
* @param {string | null} args.name - attributo `name` dell'input.
|
|
49
|
+
* @param {string | null} args.id - attributo `id`.
|
|
50
|
+
* @param {string | number | null} args.value - attributo `value` dell'input.
|
|
51
|
+
* @param {string | null} [args.type='text'] - attributo `type` dell'input (default: 'text')
|
|
52
|
+
* @param {string | null} [args.wrapperClass=null] - classe opzionale da aggiungere al wrapper `.form-group` (default: null)
|
|
53
|
+
* @param {string | null} [args.class=null] - classe opzionale da aggiungere all'`input` (default: null)
|
|
54
|
+
* @param {string | null} [args.classname=null] - Alias di `class` (default: null)
|
|
55
|
+
* @param {string | null} [args.className=null] - Alias di `class` (default: null)
|
|
56
|
+
* @param {boolean} [args.condition=true] - Se false, la funzione restituisce `null` senza costruire nulla (default: true)
|
|
57
|
+
* @param {string | HTMLElement | null} args.help - Testo di aiuto opzionale.
|
|
58
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Funzione callback opzionale.
|
|
59
|
+
* @param {Record<string, any> | null} [args.attrs={}] - Oggetto di attributi opzionale (default: {})
|
|
60
|
+
* @returns {DomBuilderItem|null} L'elemento domBuilder `input`, oppure `null` quando `condition` è false.
|
|
61
61
|
*/
|
|
62
62
|
export function buildInput({
|
|
63
63
|
label,
|
|
@@ -102,27 +102,27 @@ export function buildInput({
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
|
-
*
|
|
105
|
+
* Builder del tag select
|
|
106
106
|
*
|
|
107
107
|
* @param {Object} args
|
|
108
|
-
* @param {string} args.label - select
|
|
109
|
-
* @param {string | null} args.name -
|
|
110
|
-
* @param {string | null} args.id - `id
|
|
111
|
-
* @param {string | number | null} args.selectedValue -
|
|
108
|
+
* @param {string} args.label - label della select.
|
|
109
|
+
* @param {string | null} args.name - attributo `name` della select.
|
|
110
|
+
* @param {string | null} args.id - attributo `id`.
|
|
111
|
+
* @param {string | number | null} args.selectedValue - valore selezionato (nota: confrontato con i valori di 'options' tramite uguaglianza debole '=='):
|
|
112
112
|
* @param {Array<[string|number, string]> | Array<Record<string, string>> | Record<string, string> | null} args.options -
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* @param {boolean} [args.addEmptyOption=true] -
|
|
116
|
-
* @param {string | null} [args.wrapperClass=null] -
|
|
117
|
-
* @param {string | null} [args.class=null] -
|
|
118
|
-
* @param {string | null} [args.classname=null] - Alias
|
|
119
|
-
* @param {string | null} [args.className=null] - Alias
|
|
120
|
-
* @param {boolean} [args.condition=true] -
|
|
121
|
-
* @param {boolean} [args.useBsClass=false] -
|
|
122
|
-
* @param {string | HTMLElement | null} args.help -
|
|
123
|
-
* @param {(function(HTMLElement|Text): void) | null} args.callback -
|
|
124
|
-
* @param {Record<string, any> | null} [args.attrs={}] -
|
|
125
|
-
* @returns {DomBuilderItem|null}
|
|
113
|
+
* coppie valore/testo delle opzioni, come array di array a due elementi `[[value, text], ...]`,
|
|
114
|
+
* come array di oggetti `[{somekey: value, somekey2: text},...]`, oppure come singolo oggetto `{value: text, ...}`
|
|
115
|
+
* @param {boolean} [args.addEmptyOption=true] - Se true, viene aggiunto in cima un tag option vuoto (default: true)
|
|
116
|
+
* @param {string | null} [args.wrapperClass=null] - classe opzionale da aggiungere al wrapper `.form-group` (default: null)
|
|
117
|
+
* @param {string | null} [args.class=null] - classe opzionale da aggiungere all'`input` (default: null)
|
|
118
|
+
* @param {string | null} [args.classname=null] - Alias di `class` (default: null)
|
|
119
|
+
* @param {string | null} [args.className=null] - Alias di `class` (default: null)
|
|
120
|
+
* @param {boolean} [args.condition=true] - Se false, la funzione restituisce `null` senza costruire nulla (default: true)
|
|
121
|
+
* @param {boolean} [args.useBsClass=false] - Se true, usa la classe BS5 (`form-select`) al posto di `form-control` (default: false)
|
|
122
|
+
* @param {string | HTMLElement | null} args.help - Testo di aiuto opzionale.
|
|
123
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Funzione callback opzionale.
|
|
124
|
+
* @param {Record<string, any> | null} [args.attrs={}] - Oggetto di attributi opzionale (default: {})
|
|
125
|
+
* @returns {DomBuilderItem|null} L'elemento domBuilder `input`, oppure `null` quando `condition` è false.
|
|
126
126
|
*/
|
|
127
127
|
export function buildSelect({
|
|
128
128
|
label,
|
|
@@ -146,7 +146,7 @@ export function buildSelect({
|
|
|
146
146
|
|
|
147
147
|
id = id || randomId();
|
|
148
148
|
|
|
149
|
-
//
|
|
149
|
+
// normalizza le opzioni come array di coppie [value, text]
|
|
150
150
|
/** @type {Array<[string|number, string]>} */
|
|
151
151
|
let optionsList = [];
|
|
152
152
|
|
|
@@ -198,23 +198,23 @@ export function buildSelect({
|
|
|
198
198
|
|
|
199
199
|
|
|
200
200
|
/**
|
|
201
|
-
*
|
|
201
|
+
* Builder del tag checkbox
|
|
202
202
|
*
|
|
203
203
|
* @param {Object} args
|
|
204
|
-
* @param {string} args.label - checkbox
|
|
205
|
-
* @param {string | null} args.name -
|
|
206
|
-
* @param {string | null} args.id - `id
|
|
207
|
-
* @param {string | number | null} [args.value=1] -
|
|
208
|
-
* @param {boolean} [args.checked=false] -
|
|
209
|
-
* @param {boolean} [args.switch=false] -
|
|
210
|
-
* (`.form-switch
|
|
211
|
-
* @param {string | null} [args.wrapperClass=null] -
|
|
212
|
-
* @param {boolean} [args.addFormGroup=true] -
|
|
213
|
-
* @param {boolean} [args.condition=true] -
|
|
214
|
-
* @param {string | HTMLElement | null} args.help -
|
|
215
|
-
* @param {(function(HTMLElement|Text): void) | null} args.callback -
|
|
216
|
-
* @param {Record<string, any> | null} [args.attrs={}] -
|
|
217
|
-
* @returns {DomBuilderItem|null}
|
|
204
|
+
* @param {string} args.label - label della checkbox.
|
|
205
|
+
* @param {string | null} args.name - attributo `name` della checkbox.
|
|
206
|
+
* @param {string | null} args.id - attributo `id`.
|
|
207
|
+
* @param {string | number | null} [args.value=1] - attributo `value` della checkbox (default: 1)
|
|
208
|
+
* @param {boolean} [args.checked=false] - attributo `checked` della checkbox (default: false)
|
|
209
|
+
* @param {boolean} [args.switch=false] - Se true, la checkbox viene resa come switch
|
|
210
|
+
* (wrapper `.form-switch`, `role="switch"` e attributo nativo `switch`) (default: false)
|
|
211
|
+
* @param {string | null} [args.wrapperClass=null] - classe opzionale da aggiungere al wrapper `.form-group` (usata solo quando `addFormGroup` è true) (default: null)
|
|
212
|
+
* @param {boolean} [args.addFormGroup=true] - Se true, racchiude la checkbox in un elemento `.form-group` (default: true)
|
|
213
|
+
* @param {boolean} [args.condition=true] - Se false, la funzione restituisce `null` senza costruire nulla (default: true)
|
|
214
|
+
* @param {string | HTMLElement | null} args.help - Testo di aiuto opzionale.
|
|
215
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Funzione callback opzionale.
|
|
216
|
+
* @param {Record<string, any> | null} [args.attrs={}] - Oggetto di attributi opzionale (default: {})
|
|
217
|
+
* @returns {DomBuilderItem|null} L'elemento domBuilder `.form-check` (o racchiuso in `.form-group`), oppure `null` quando `condition` è false.
|
|
218
218
|
*/
|
|
219
219
|
export function buildCheckbox({
|
|
220
220
|
label,
|
|
@@ -236,14 +236,14 @@ export function buildCheckbox({
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
/*
|
|
239
|
-
<div class="form-group"> <-
|
|
239
|
+
<div class="form-group"> <- opzionale
|
|
240
240
|
<div class="form-check">
|
|
241
241
|
<input type="checkbox" id="..." name="..." class="form-check-input" value="1">
|
|
242
242
|
<label for="..." class="form-label">...</label>
|
|
243
243
|
</div>
|
|
244
244
|
</div>
|
|
245
245
|
|
|
246
|
-
<div class="form-group"> <-
|
|
246
|
+
<div class="form-group"> <- opzionale
|
|
247
247
|
<div class="form-check form-switch">
|
|
248
248
|
<input class="form-check-input" type="checkbox" role="switch" switch id="my-switch">
|
|
249
249
|
<label class="form-label" for="my-switch">My label</label>
|
|
@@ -265,7 +265,7 @@ export function buildCheckbox({
|
|
|
265
265
|
value: value,
|
|
266
266
|
name: name,
|
|
267
267
|
checked: checked,
|
|
268
|
-
//
|
|
268
|
+
// controllo switch nativo (per ora solo WebKit), con ripiego css altrove
|
|
269
269
|
...(isSwitch? {role: 'switch', switch: ''} : {})
|
|
270
270
|
},
|
|
271
271
|
callback: callback
|
|
@@ -289,23 +289,23 @@ export function buildCheckbox({
|
|
|
289
289
|
|
|
290
290
|
|
|
291
291
|
/**
|
|
292
|
-
*
|
|
292
|
+
* Builder del tag textarea
|
|
293
293
|
*
|
|
294
294
|
* @param {Object} args
|
|
295
|
-
* @param {string} args.label - textarea
|
|
296
|
-
* @param {string | null} args.name -
|
|
297
|
-
* @param {string | null} args.id - `id
|
|
298
|
-
* @param {string | number | null} args.value - textarea
|
|
299
|
-
* @param {boolean} [args.autosize=true] -
|
|
300
|
-
* @param {string | null} [args.wrapperClass=null] -
|
|
301
|
-
* @param {string | null} [args.class=null] -
|
|
302
|
-
* @param {string | null} [args.classname=null] - Alias
|
|
303
|
-
* @param {string | null} [args.className=null] - Alias
|
|
304
|
-
* @param {boolean} [args.condition=true] -
|
|
305
|
-
* @param {string | HTMLElement | null} args.help -
|
|
306
|
-
* @param {(function(HTMLElement|Text): void) | null} args.callback -
|
|
307
|
-
* @param {Record<string, any> | null} [args.attrs={}] -
|
|
308
|
-
* @returns {DomBuilderItem|null}
|
|
295
|
+
* @param {string} args.label - label della textarea.
|
|
296
|
+
* @param {string | null} args.name - attributo `name` della textarea.
|
|
297
|
+
* @param {string | null} args.id - attributo `id`.
|
|
298
|
+
* @param {string | number | null} args.value - contenuto della textarea.
|
|
299
|
+
* @param {boolean} [args.autosize=true] - aggiunge la classe `autosize` (default: true)
|
|
300
|
+
* @param {string | null} [args.wrapperClass=null] - classe opzionale da aggiungere al wrapper `.form-group` (default: null)
|
|
301
|
+
* @param {string | null} [args.class=null] - classe opzionale da aggiungere all'elemento textarea (default: null)
|
|
302
|
+
* @param {string | null} [args.classname=null] - Alias di `class` (default: null)
|
|
303
|
+
* @param {string | null} [args.className=null] - Alias di `class` (default: null)
|
|
304
|
+
* @param {boolean} [args.condition=true] - Se false, la funzione restituisce `null` senza costruire nulla (default: true)
|
|
305
|
+
* @param {string | HTMLElement | null} args.help - Testo di aiuto opzionale.
|
|
306
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Funzione callback opzionale.
|
|
307
|
+
* @param {Record<string, any> | null} [args.attrs={}] - Oggetto di attributi opzionale (default: {})
|
|
308
|
+
* @returns {DomBuilderItem|null} L'elemento domBuilder `textarea`, oppure `null` quando `condition` è false.
|
|
309
309
|
*/
|
|
310
310
|
export function buildTextarea({
|
|
311
311
|
label,
|
|
@@ -349,21 +349,21 @@ export function buildTextarea({
|
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
/**
|
|
352
|
-
*
|
|
352
|
+
* Campo finto (testo semplice mostrato come campo input)
|
|
353
353
|
*
|
|
354
354
|
* @param {Object} args
|
|
355
355
|
* @param {string} args.label - label.
|
|
356
|
-
* @param {string | number | null} args.value -
|
|
357
|
-
* @param {string | null} [args.wrapperClass=null] -
|
|
358
|
-
* @param {boolean} [args.noBorder=true] -
|
|
359
|
-
* @param {string | null} [args.class=null] -
|
|
360
|
-
* @param {string | null} [args.classname=null] - Alias
|
|
361
|
-
* @param {string | null} [args.className=null] - Alias
|
|
362
|
-
* @param {boolean} [args.condition=true] -
|
|
363
|
-
* @param {string | HTMLElement | null} args.help -
|
|
364
|
-
* @param {(function(HTMLElement|Text): void) | null} args.callback -
|
|
365
|
-
* @param {Record<string, any> | null} [args.attrs={}] -
|
|
366
|
-
* @returns {DomBuilderItem|null}
|
|
356
|
+
* @param {string | number | null} args.value - contenuto testuale.
|
|
357
|
+
* @param {string | null} [args.wrapperClass=null] - classe opzionale da aggiungere al wrapper `.form-group` (default: null)
|
|
358
|
+
* @param {boolean} [args.noBorder=true] - aggiunge la classe `no-border` (default: true)
|
|
359
|
+
* @param {string | null} [args.class=null] - classe opzionale da aggiungere al campo finto (default: null)
|
|
360
|
+
* @param {string | null} [args.classname=null] - Alias di `class` (default: null)
|
|
361
|
+
* @param {string | null} [args.className=null] - Alias di `class` (default: null)
|
|
362
|
+
* @param {boolean} [args.condition=true] - Se false, la funzione restituisce `null` senza costruire nulla (default: true)
|
|
363
|
+
* @param {string | HTMLElement | null} args.help - Testo di aiuto opzionale.
|
|
364
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Funzione callback opzionale.
|
|
365
|
+
* @param {Record<string, any> | null} [args.attrs={}] - Oggetto di attributi opzionale (default: {})
|
|
366
|
+
* @returns {DomBuilderItem|null} L'elemento domBuilder del campo finto, oppure `null` quando `condition` è false.
|
|
367
367
|
*/
|
|
368
368
|
export function buildFakeField({
|
|
369
369
|
label,
|
|
@@ -402,20 +402,20 @@ export function buildFakeField({
|
|
|
402
402
|
|
|
403
403
|
|
|
404
404
|
/**
|
|
405
|
-
*
|
|
405
|
+
* Builder del tag button
|
|
406
406
|
*
|
|
407
407
|
* @param {Object} args
|
|
408
|
-
* @param {string|HTMLElement|Array<DomBuilderItem>} args.content - button
|
|
409
|
-
* domBuilder
|
|
410
|
-
* @param {string} [args.type=button] - button
|
|
411
|
-
* @param {string | null} args.id - `id
|
|
412
|
-
* @param {string | null} [args.class=null] -
|
|
413
|
-
* @param {string | null} [args.classname=null] - Alias
|
|
414
|
-
* @param {string | null} [args.className=null] - Alias
|
|
415
|
-
* @param {boolean} [args.condition=true] -
|
|
416
|
-
* @param {(function(HTMLElement|Text): void) | null} args.callback -
|
|
417
|
-
* @param {Record<string, any> | null} [args.attrs={}] -
|
|
418
|
-
* @returns {DomBuilderItem|null}
|
|
408
|
+
* @param {string|HTMLElement|Array<DomBuilderItem>} args.content - contenuto del button. Quando viene passato un array di
|
|
409
|
+
* elementi domBuilder, viene renderizzato tramite `children` invece di `content`.
|
|
410
|
+
* @param {string} [args.type=button] - tipo del button (default: 'button')
|
|
411
|
+
* @param {string | null} args.id - attributo `id`.
|
|
412
|
+
* @param {string | null} [args.class=null] - classe opzionale da aggiungere all'elemento button (default: null)
|
|
413
|
+
* @param {string | null} [args.classname=null] - Alias di `class` (default: null)
|
|
414
|
+
* @param {string | null} [args.className=null] - Alias di `class` (default: null)
|
|
415
|
+
* @param {boolean} [args.condition=true] - Se false, la funzione restituisce `null` senza costruire nulla (default: true)
|
|
416
|
+
* @param {(function(HTMLElement|Text): void) | null} args.callback - Funzione callback opzionale.
|
|
417
|
+
* @param {Record<string, any> | null} [args.attrs={}] - Oggetto di attributi opzionale (default: {})
|
|
418
|
+
* @returns {DomBuilderItem|null} L'elemento domBuilder `button`, oppure `null` quando `condition` è false.
|
|
419
419
|
*/
|
|
420
420
|
export function buildButton({
|
|
421
421
|
content,
|
|
@@ -3,8 +3,8 @@ import { classnames } from '../classnames.js';
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @typedef {Object} PictureSizeEntry
|
|
6
|
-
* @property {number} [from] - Breakpoint (px)
|
|
7
|
-
* @property {number | [number, number]} size -
|
|
6
|
+
* @property {number} [from] - Breakpoint (px) da cui si applica la size (condizione media `width >=`); omesso nell'(unica) entry predefinita mobile-first.
|
|
7
|
+
* @property {number | [number, number]} size - Larghezza renderizzata (px, altezza calcolata con `ratio`, se impostato) oppure coppia esplicita `[width, height]` (px).
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
// TODO aggiungere compatibilità con immagini Unsplash basate su imgix
|
|
@@ -13,25 +13,25 @@ import { classnames } from '../classnames.js';
|
|
|
13
13
|
// per altri servizi con parametri diversi (es. imgix/Unsplash)
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* Crea un elemento domBuilder `picture` per un'immagine servita tramite il viewer.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* default
|
|
22
|
-
* `(width >= …)`
|
|
18
|
+
* Ogni `srcset` di `source`/`img` è costruito con descrittori di larghezza (`w`): per ogni entry
|
|
19
|
+
* di `sizes` viene generato un candidato per ogni densità intera da 1 a `dpr`.
|
|
20
|
+
* L'attributo `sizes` è costruito in modalità mobile-first: l'entry senza `from` è il
|
|
21
|
+
* default e ogni altra entry si applica dal proprio breakpoint `from` in su, come
|
|
22
|
+
* condizione media `(width >= …)` (sintassi range).
|
|
23
23
|
*
|
|
24
24
|
* @example
|
|
25
|
-
* //
|
|
26
|
-
* //
|
|
27
|
-
* // `height`
|
|
28
|
-
* buildPictureTag({ baseSrc: 'https://img-viewer.example.com/abc123', alt: '
|
|
25
|
+
* // thumb a larghezza fissa (250px, candidati 1x e 2x); senza `ratio` né altezze
|
|
26
|
+
* // esplicite, il viewer riceve un resize solo in larghezza (bb=250x) e l'`img` non ha
|
|
27
|
+
* // l'attributo `height`
|
|
28
|
+
* buildPictureTag({ baseSrc: 'https://img-viewer.example.com/abc123', alt: '...' });
|
|
29
29
|
* // sizes="250px", srcset="… 250w, … 500w"
|
|
30
30
|
*
|
|
31
31
|
* @example
|
|
32
|
-
* // responsive
|
|
33
|
-
* // NB:
|
|
34
|
-
* //
|
|
32
|
+
* // immagine responsive: 250px di default, 500px da 576px, 800px da 992px.
|
|
33
|
+
* // NB: l'entry senza `from` è il default mobile-first (ne è attesa esattamente
|
|
34
|
+
* // una); un numero semplice o una coppia [width, height] ne è la scorciatoia
|
|
35
35
|
* buildPictureTag({
|
|
36
36
|
* baseSrc,
|
|
37
37
|
* sizes: [250, { from: 576, size: 500 }, { from: 992, size: 800 }],
|
|
@@ -39,7 +39,7 @@ import { classnames } from '../classnames.js';
|
|
|
39
39
|
* // sizes="(width >= 992px) 800px, (width >= 576px) 500px, 250px"
|
|
40
40
|
*
|
|
41
41
|
* @example
|
|
42
|
-
* //
|
|
42
|
+
* // ratio personalizzato per le size numeriche e candidati fino a 3x
|
|
43
43
|
* buildPictureTag({
|
|
44
44
|
* baseSrc,
|
|
45
45
|
* sizes: [250, { from: 768, size: 500 }],
|
|
@@ -48,19 +48,19 @@ import { classnames } from '../classnames.js';
|
|
|
48
48
|
* });
|
|
49
49
|
*
|
|
50
50
|
* @example
|
|
51
|
-
* //
|
|
52
|
-
* // (
|
|
51
|
+
* // aspect ratio diverso per breakpoint: coppie [width, height] esplicite
|
|
52
|
+
* // (si possono mescolare con size numeriche, che usano `ratio`)
|
|
53
53
|
* buildPictureTag({
|
|
54
54
|
* baseSrc,
|
|
55
|
-
* sizes: [[250, 250], { from: 576, size: [800, 450] }], //
|
|
55
|
+
* sizes: [[250, 250], { from: 576, size: [800, 450] }], // quadrato su mobile, 16:9 su desktop
|
|
56
56
|
* });
|
|
57
57
|
*
|
|
58
58
|
* @example
|
|
59
|
-
* //
|
|
59
|
+
* // ambiente di sviluppo (senza avif) e img above-the-fold (senza loading="lazy")
|
|
60
60
|
* buildPictureTag({ baseSrc, devMode: true, lazy: false });
|
|
61
61
|
*
|
|
62
62
|
* @example
|
|
63
|
-
* // onLoad
|
|
63
|
+
* // callback onLoad: mostra l'immagine al termine del caricamento
|
|
64
64
|
* buildPictureTag({
|
|
65
65
|
* baseSrc,
|
|
66
66
|
* imgExtraClass: 'img-loading',
|
|
@@ -68,24 +68,24 @@ import { classnames } from '../classnames.js';
|
|
|
68
68
|
* });
|
|
69
69
|
*
|
|
70
70
|
* @param {Object} args
|
|
71
|
-
* @param {string} args.baseSrc -
|
|
72
|
-
* @param {(number | [number, number] | PictureSizeEntry)[]} [args.sizes=[250]] -
|
|
73
|
-
* @param {number|null} [args.ratio=null] -
|
|
74
|
-
* @param {number} [args.dpr=2] -
|
|
75
|
-
* @param {[string, string|number][]} [args.img_params=[['q','60']]] -
|
|
76
|
-
* @param {string[]} [args.formats=['avif','webp','pjpg']] -
|
|
77
|
-
* @param {boolean} [args.devMode=false] -
|
|
78
|
-
* @param {boolean} [args.lazy=true] -
|
|
79
|
-
* @param {'high'|'low'|null} [args.fetchpriority=null] - `fetchpriority`
|
|
80
|
-
* @param {((img: HTMLImageElement) => void) | null} [args.onLoad=null] -
|
|
81
|
-
* @param {boolean} [args.condition=true] -
|
|
82
|
-
* @param {boolean} [args.legacyMediaSyntax=false] -
|
|
83
|
-
* @param {string|null} [args.pictureExtraClass=null] -
|
|
84
|
-
* @param {Object<string, *>} [args.pictureExtraAttrs={}] -
|
|
85
|
-
* @param {string|null} [args.imgExtraClass=null] -
|
|
86
|
-
* @param {Object<string, *>} [args.imgExtraAttrs={}] -
|
|
87
|
-
* @param {string} [args.alt=''] - `alt`
|
|
88
|
-
* @returns {DomBuilderItem|null}
|
|
71
|
+
* @param {string} args.baseSrc - URL base dell'immagine (endpoint del viewer); i suoi parametri di query vengono conservati.
|
|
72
|
+
* @param {(number | [number, number] | PictureSizeEntry)[]} [args.sizes=[250]] - Dimensioni renderizzate dell'immagine, in qualsiasi ordine. Ogni entry è un oggetto `{from, size}` (vedi {@link PictureSizeEntry}); un numero semplice o una coppia `[width, height]` è la scorciatoia per l'entry predefinita mobile-first (quella senza `from`), attesa esattamente una volta (default: [250])
|
|
73
|
+
* @param {number|null} [args.ratio=null] - Aspect ratio predefinito (larghezza / altezza, come nella proprietà CSS `aspect-ratio`) usato per calcolare l'altezza delle size numeriche. Se null, l'altezza non viene calcolata: gli output legati all'altezza (attributo `height`, altezza nel parametro `bb`) vengono omessi e il viewer mantiene il ratio originale dell'immagine (default: null)
|
|
74
|
+
* @param {number} [args.dpr=2] - Densità di pixel massima (intero): i candidati di `srcset` vengono generati per ogni densità da 1 a `dpr` (default: 2)
|
|
75
|
+
* @param {[string, string|number][]} [args.img_params=[['q','60']]] - Parametri di query (coppie `[name, value]`) aggiunti a ogni URL generato (default: [['q','60']])
|
|
76
|
+
* @param {string[]} [args.formats=['avif','webp','pjpg']] - Formati dell'immagine: l'ultimo viene usato per l'elemento `img` di fallback, gli altri per gli elementi `source` (default: ['avif','webp','pjpg'])
|
|
77
|
+
* @param {boolean} [args.devMode=false] - Se true, `avif` viene escluso da `formats` (non supportato dall'ambiente di sviluppo locale) (default: false)
|
|
78
|
+
* @param {boolean} [args.lazy=true] - Se true, l'elemento `img` riceve `loading="lazy"` (default: true)
|
|
79
|
+
* @param {'high'|'low'|null} [args.fetchpriority=null] - Attributo `fetchpriority` per l'elemento `img`: usare `high` per l'immagine LCP/above-the-fold (tipicamente con `lazy: false`). Se null l'attributo viene omesso (default del browser `auto`) (default: null)
|
|
80
|
+
* @param {((img: HTMLImageElement) => void) | null} [args.onLoad=null] - Chiamata al termine del caricamento dell'immagine, riceve l'elemento `img` (chiamata subito se l'immagine è già completa) (default: null)
|
|
81
|
+
* @param {boolean} [args.condition=true] - Se false, la funzione restituisce `null` senza costruire nulla (default: true)
|
|
82
|
+
* @param {boolean} [args.legacyMediaSyntax=false] - Se true, le condizioni media di `sizes` usano `(min-width: …)` invece della sintassi range `(width >= …)`, per i browser più vecchi (precedenti a Chrome/Edge 104, Firefox 102, Safari 16.4) (default: false)
|
|
83
|
+
* @param {string|null} [args.pictureExtraClass=null] - Classe/i extra per l'elemento `picture`. (default: null)
|
|
84
|
+
* @param {Object<string, *>} [args.pictureExtraAttrs={}] - Attributi extra per l'elemento `picture`. (default: {})
|
|
85
|
+
* @param {string|null} [args.imgExtraClass=null] - Classe/i extra per l'elemento `img`. (default: null)
|
|
86
|
+
* @param {Object<string, *>} [args.imgExtraAttrs={}] - Attributi extra per l'elemento `img`. (default: {})
|
|
87
|
+
* @param {string} [args.alt=''] - Testo `alt` per l'elemento `img`. (default: '')
|
|
88
|
+
* @returns {DomBuilderItem|null} L'elemento domBuilder `picture`, oppure `null` quando `baseSrc` manca o `condition` è false.
|
|
89
89
|
*/
|
|
90
90
|
export function buildPictureTag({
|
|
91
91
|
baseSrc,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*! minimo - Enable Submit Buttons */
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Riabilita tutti i pulsanti submit e i pulsanti non disabilitati all'interno del contesto indicato.
|
|
4
4
|
* @param {Document | Element} [context=document] (default: document)
|
|
5
5
|
* @returns {void}
|
|
6
6
|
*/
|
|
@@ -14,14 +14,14 @@ const ESCAPE_RE = /[&"'<>]/g;
|
|
|
14
14
|
const UNESCAPE_RE = /&|"|'|<|>/g;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* Esegue l'escape dei caratteri HTML speciali di una stringa.
|
|
18
18
|
* @param {string | null | undefined} str
|
|
19
19
|
* @returns {string}
|
|
20
20
|
*/
|
|
21
21
|
export const escapeHTML = str => str?.replace(ESCAPE_RE, m => ESCAPE_MAP[m]) ?? '';
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* Riconverte le entità HTML nei caratteri originali.
|
|
25
25
|
* @param {string | null | undefined} str
|
|
26
26
|
* @returns {string}
|
|
27
27
|
*/
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/*! minimo - Generate Password */
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Genera una password casuale con lettere maiuscole e cifre,
|
|
4
|
+
* escludendo i caratteri visivamente ambigui (O, I, 0).
|
|
5
5
|
*
|
|
6
|
-
* @param {number} [min_length=8] -
|
|
7
|
-
* @returns {string}
|
|
6
|
+
* @param {number} [min_length=8] - Lunghezza minima della password (corrisponde all'attributo `minlength`) (default: 8)
|
|
7
|
+
* @returns {string} La password generata.
|
|
8
8
|
*/
|
|
9
9
|
export function generatePwd(min_length = 8) {
|
|
10
10
|
|
|
@@ -2,23 +2,23 @@
|
|
|
2
2
|
/*! minimo - Linked Dates */
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Collega i campi input date/datetime-local in modo che un campo vincoli
|
|
6
|
+
* il min/max di un altro.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* L'attributo `data-max` di un campo data deve contenere l'`id` del campo
|
|
9
|
+
* il cui valore imposta il vincolo `max` del campo corrente (data di inizio).
|
|
10
|
+
* L'attributo `data-min` di un campo data deve contenere l'`id` del campo
|
|
11
|
+
* il cui valore imposta il vincolo `min` del campo corrente (data di fine).
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* Se il campo collegato è disabilitato, il vincolo viene rimosso al focus
|
|
14
|
+
* e ripristinato quando il campo collegato viene riabilitato.
|
|
15
15
|
*
|
|
16
|
-
* @param {Document|Element} context -
|
|
16
|
+
* @param {Document|Element} context - elemento radice in cui cercare (default: document)
|
|
17
17
|
* @returns {void}
|
|
18
18
|
*/
|
|
19
19
|
export function linkedDates(context = document) {
|
|
20
20
|
|
|
21
|
-
//
|
|
21
|
+
// campi data di inizio: vincolati da un valore max proveniente da un campo collegato
|
|
22
22
|
context.querySelectorAll('input[type="date"][data-max], input[type="datetime-local"][data-max]').forEach(el => {
|
|
23
23
|
const maxId = /** @type {HTMLInputElement} */ (el).dataset.max;
|
|
24
24
|
let linked_field = maxId ? document.getElementById(maxId) : null;
|
|
@@ -30,7 +30,7 @@ export function linkedDates(context = document) {
|
|
|
30
30
|
el.setAttribute('max', /** @type {HTMLInputElement} */ (linked_field).value);
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
//
|
|
33
|
+
// rimuove max se il campo collegato è disabilitato; lo ripristina quando riceve di nuovo il focus da abilitato
|
|
34
34
|
el.addEventListener('focus', () => {
|
|
35
35
|
if(/** @type {HTMLInputElement} */ (linked_field).disabled) {
|
|
36
36
|
el.removeAttribute('max');
|
|
@@ -41,7 +41,7 @@ export function linkedDates(context = document) {
|
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
//
|
|
44
|
+
// campi data di fine: vincolati da un valore min proveniente da un campo collegato
|
|
45
45
|
context.querySelectorAll('input[type="date"][data-min], input[type="datetime-local"][data-min]').forEach(el => {
|
|
46
46
|
const minId = /** @type {HTMLInputElement} */ (el).dataset.min;
|
|
47
47
|
let linked_field = minId ? document.getElementById(minId) : null;
|
|
@@ -51,7 +51,7 @@ export function linkedDates(context = document) {
|
|
|
51
51
|
el.setAttribute('min', /** @type {HTMLInputElement} */ (linked_field).value);
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
//
|
|
54
|
+
// rimuove min se il campo collegato è disabilitato; lo ripristina quando riceve di nuovo il focus da abilitato
|
|
55
55
|
el.addEventListener('focus', () => {
|
|
56
56
|
if(/** @type {HTMLInputElement} */ (linked_field).disabled) {
|
|
57
57
|
el.removeAttribute('min');
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
/*! minimo - Parse File Size */
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Converte una dimensione di file in byte in una stringa leggibile,
|
|
6
|
+
* usando l'unità più appropriata (bytes, KB, MB o GB).
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* parseFileSize(1536); // "1.5 KB"
|
|
10
10
|
* parseFileSize(10485760); // "10 MB"
|
|
11
11
|
*
|
|
12
|
-
* @param {number} bytes - file
|
|
13
|
-
* @param {number} [decimals=1] -
|
|
14
|
-
* @returns {string}
|
|
12
|
+
* @param {number} bytes - dimensione del file in byte
|
|
13
|
+
* @param {number} [decimals=1] - numero massimo di cifre decimali (default: 1)
|
|
14
|
+
* @returns {string} dimensione formattata (es. "1.5 MB")
|
|
15
15
|
*/
|
|
16
16
|
export function parseFileSize(bytes, decimals = 1) {
|
|
17
17
|
|
|
@@ -28,6 +28,6 @@ export function parseFileSize(bytes, decimals = 1) {
|
|
|
28
28
|
|
|
29
29
|
const value = bytes / Math.pow(k, exp);
|
|
30
30
|
|
|
31
|
-
// \u202f = narrow no-break space
|
|
31
|
+
// \u202f = narrow no-break space (spazio sottile non separabile)
|
|
32
32
|
return `${parseFloat(value.toFixed(decimals))}\u202f${units[exp]}`;
|
|
33
33
|
}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
/*! minimo - Random Id */
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @returns {string}
|
|
5
|
+
* Genera una stringa ID casuale.
|
|
6
|
+
* @returns {string} Stringa casuale codificata in Base64
|
|
7
7
|
*/
|
|
8
8
|
export function randomId() {
|
|
9
9
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_';
|
|
10
10
|
const bytes = crypto.getRandomValues(new Uint8Array(12));
|
|
11
|
-
return chars[bytes[0] % 52] //
|
|
11
|
+
return chars[bytes[0] % 52] // il primo carattere proviene dai primi 52 (A-Za-z)
|
|
12
12
|
+ Array.from(bytes.slice(1), b => chars[b % 63]).join('');
|
|
13
13
|
}
|
|
14
14
|
|