@massimo-cassandro/minimo 1.41.4 → 1.41.6
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/starter-kit/source_files/root/webpack.config.mjs +15 -1
- package/dev-tools/starter-kit/webpack-config-upg.md +12 -0
- 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/jt-docs/parametri.md +124 -0
- package/src/web-components/json-table/jt-docs.md +622 -0
- package/src/web-components/json-table/readme.md +3 -763
- 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
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* Recupera e normalizza i dati di una foto Unsplash dall'URL indicato.
|
|
20
20
|
* @param {{ unsplash_data_url: string | null }} settings
|
|
21
21
|
* @returns {Promise<UnsplashPhoto | undefined>}
|
|
22
22
|
*/
|
|
@@ -34,7 +34,7 @@ export async function fetchUnsplashData(settings) {
|
|
|
34
34
|
throw new Error( 'Unsplash data url must be defined' );
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
const url = settings.unsplash_data_url; // const
|
|
37
|
+
const url = settings.unsplash_data_url; // const mantiene il narrowing dentro la closure dell'IIFE
|
|
38
38
|
|
|
39
39
|
const imgData = await (async () => {
|
|
40
40
|
const response = await fetch(url);
|
|
@@ -52,7 +52,7 @@ export async function fetchUnsplashData(settings) {
|
|
|
52
52
|
|
|
53
53
|
// console.log(data);
|
|
54
54
|
|
|
55
|
-
//
|
|
55
|
+
// dati utilizzati
|
|
56
56
|
return {
|
|
57
57
|
id : data.id,
|
|
58
58
|
color : data.color,
|
|
@@ -9,21 +9,21 @@ import { decode } from 'blurhash';
|
|
|
9
9
|
import * as styles from './unsplash-page.module.css';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Inizializza una foto Unsplash a pagina intera con placeholder blurhash, elemento picture responsive
|
|
13
|
+
* e overlay di attribuzione.
|
|
14
14
|
* @param {Object} settings
|
|
15
|
-
* @param {HTMLElement | null} settings.targetElement -
|
|
16
|
-
* @param {string | null} [settings.className=null] -
|
|
17
|
-
* @param {string | null} settings.unsplashDataUrl - URL
|
|
18
|
-
* @param {string | null} settings.utmSource -
|
|
19
|
-
* @param {string | null} settings.title -
|
|
20
|
-
* @param {string | null} [settings.text=null] -
|
|
21
|
-
* @param {string | null} [settings.backLink=null] -
|
|
22
|
-
* @param {boolean} [settings.hidePhotoLink=true] -
|
|
15
|
+
* @param {HTMLElement | null} settings.targetElement - Elemento contenitore in cui verrà renderizzata la foto.
|
|
16
|
+
* @param {string | null} [settings.className=null] - Classe extra aggiunta al contenitore (default: null)
|
|
17
|
+
* @param {string | null} settings.unsplashDataUrl - URL che restituisce il JSON della foto Unsplash.
|
|
18
|
+
* @param {string | null} settings.utmSource - Valore utm_source per i link di attribuzione.
|
|
19
|
+
* @param {string | null} settings.title - Testo del titolo principale.
|
|
20
|
+
* @param {string | null} [settings.text=null] - Testo opzionale del corpo (default: null)
|
|
21
|
+
* @param {string | null} [settings.backLink=null] - HTML opzionale del link di ritorno (default: null)
|
|
22
|
+
* @param {boolean} [settings.hidePhotoLink=true] - Se true, il link a Unsplash viene mostrato solo al passaggio del mouse (default: true)
|
|
23
23
|
* @returns {Promise<void>}
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
// TODO
|
|
26
|
+
// TODO aggiungere la personalizzazione del file dell'icona e altre custom props per il box del messaggio
|
|
27
27
|
|
|
28
28
|
export async function unsplashPage(settings) {
|
|
29
29
|
|
|
@@ -87,23 +87,23 @@ export async function unsplashPage(settings) {
|
|
|
87
87
|
|
|
88
88
|
container.insertAdjacentElement('afterbegin', canvas);
|
|
89
89
|
|
|
90
|
-
const formats = ['avif', 'webp', 'pjpg']; // `fm
|
|
90
|
+
const formats = ['avif', 'webp', 'pjpg']; // parametro `fm`, in ordine di utilizzo
|
|
91
91
|
|
|
92
92
|
/*
|
|
93
|
-
-
|
|
94
|
-
per
|
|
95
|
-
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
`widths`
|
|
100
|
-
-
|
|
93
|
+
- dimensioni dell'immagine raggruppate per aspect ratio: ogni gruppo diventa un tag <source>
|
|
94
|
+
per formato (avif/webp/pjpg)
|
|
95
|
+
- ogni aspect ratio è espresso come [w, h] (es. [16, 9]); `widths` elenca le larghezze
|
|
96
|
+
di rendering di destinazione per quel gruppo, usate sia come parametro imgix `w` sia come
|
|
97
|
+
descrittore `Nw` in `srcset`. L'altezza è derivata per ogni larghezza dal ratio del gruppo e
|
|
98
|
+
passata a imgix come `h` (vedi buildImgixUrl), quindi i gruppi possono riutilizzare senza problemi lo stesso
|
|
99
|
+
elenco `widths` (es. 9/16 e 9/20) richiedendo comunque un'altezza di crop diversa
|
|
100
|
+
- l'orientamento e la media feature aspect-ratio sono derivati dal ratio stesso:
|
|
101
101
|
ratio >= 1 -> landscape + min-aspect-ratio, ratio < 1 -> portrait + max-aspect-ratio
|
|
102
|
-
- NB:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
- NB: l'ordine conta. <picture> usa "vince il primo <source> che corrisponde" (a differenza della
|
|
103
|
+
cascata CSS, dove vince l'ultima regola corrispondente), quindi i gruppi devono essere ordinati dal più al
|
|
104
|
+
meno restrittivo: i gruppi landscape dal ratio più largo al più stretto, i gruppi portrait
|
|
105
|
+
dal ratio più stretto al più largo. L'orientamento rende le due famiglie
|
|
106
|
+
mutuamente esclusive, quindi il loro ordine relativo non conta
|
|
107
107
|
*/
|
|
108
108
|
const sizes = [
|
|
109
109
|
// landscape 16/9
|
|
@@ -126,23 +126,23 @@ export async function unsplashPage(settings) {
|
|
|
126
126
|
ar: [9,16],
|
|
127
127
|
widths: [1080, 960, 768, 570, 400]
|
|
128
128
|
},
|
|
129
|
-
// portrait 3/4 (
|
|
129
|
+
// portrait 3/4 (tablet)
|
|
130
130
|
{
|
|
131
131
|
ar: [3,4],
|
|
132
132
|
widths: [1200, 1024, 840]
|
|
133
133
|
}
|
|
134
134
|
];
|
|
135
135
|
|
|
136
|
-
// `url`/`searchParams`
|
|
137
|
-
//
|
|
138
|
-
//
|
|
136
|
+
// `url`/`searchParams` e i parametri imgix statici (fit/crop/q) vengono impostati una sola volta qui
|
|
137
|
+
// e riutilizzati a ogni chiamata: `fm`/`w`/`h` sono le uniche parti che cambiano per immagine, e
|
|
138
|
+
// la stringa restituita viene sempre consumata in modo sincrono prima che la chiamata successiva le modifichi
|
|
139
139
|
/** @type {(w: number, h: number, fmt: string) => string} */
|
|
140
140
|
const buildImgixUrl = (() => {
|
|
141
141
|
const url = new URL(imgData.base_url),
|
|
142
142
|
searchParams = new URLSearchParams(url.search);
|
|
143
143
|
|
|
144
144
|
searchParams.set('fit', 'crop');
|
|
145
|
-
searchParams.set('crop', 'faces,entropy,edges'); // top, bottom, left, right, faces, focalpoint, edges
|
|
145
|
+
searchParams.set('crop', 'faces,entropy,edges'); // top, bottom, left, right, faces, focalpoint, edges ed entropy
|
|
146
146
|
searchParams.set('q', '60');
|
|
147
147
|
|
|
148
148
|
return (w, h, fmt) => {
|
|
@@ -155,8 +155,8 @@ export async function unsplashPage(settings) {
|
|
|
155
155
|
};
|
|
156
156
|
})();
|
|
157
157
|
|
|
158
|
-
//
|
|
159
|
-
//
|
|
158
|
+
// larghezza minima del gruppo più largo (il più comune), usata come semplice <img> di fallback
|
|
159
|
+
// per i browser senza supporto a <picture>: i tag <source> qui sopra coprono tutto il resto
|
|
160
160
|
const default_group = sizes[0],
|
|
161
161
|
default_w = default_group.widths[default_group.widths.length - 1],
|
|
162
162
|
default_h = Math.round(default_w * default_group.ar[1] / default_group.ar[0]);
|
|
@@ -199,7 +199,7 @@ export async function unsplashPage(settings) {
|
|
|
199
199
|
});
|
|
200
200
|
}),
|
|
201
201
|
|
|
202
|
-
// =>> img
|
|
202
|
+
// =>> img e il suo listener
|
|
203
203
|
{
|
|
204
204
|
tag: 'img',
|
|
205
205
|
className: styles.unsplashPhoto,
|
package/src/css/alerts.css
CHANGED
package/src/css/forms/forms.css
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
.form-group:has([required]):not(:has([disabled])) {
|
|
10
10
|
|
|
11
|
-
/* `>`
|
|
11
|
+
/* `>` esclude le label all'interno delle form-collection */
|
|
12
12
|
> .form-label {
|
|
13
13
|
position: relative;
|
|
14
14
|
padding-inline-start: var(--form-control-required-label-padding-inline-start);
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/*
|
|
27
|
+
/* le singole checkbox e radio sono centrate verticalmente */
|
|
28
28
|
.form-group:not(.form-collection-fset):has(.form-check:not(.form-check-top-label)) {
|
|
29
29
|
align-self: center;
|
|
30
30
|
.form-check {
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/*
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
con label implicita, senza id e for.
|
|
44
|
+
Esempio:
|
|
45
45
|
|
|
46
46
|
<div class="form-group">
|
|
47
47
|
<label>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* da BS5 */
|
|
2
2
|
.was-validated {
|
|
3
3
|
|
|
4
|
-
/*
|
|
4
|
+
/* include il campo statico il cui contenitore ha la classe is-valid / is-invalid */
|
|
5
5
|
.form-group:has(:valid), .form-group:has(.is-valid), .form-group.is-valid .form-control-static{
|
|
6
6
|
--_status-color: var(--status-success-color);
|
|
7
7
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* stylelint-disable selector-class-pattern */
|
|
2
2
|
|
|
3
|
-
/*
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/* FILE GENERATO AUTOMATICAMENTE — non modificare a mano.
|
|
4
|
+
Generato da `node scripts/build-margin-padding-css.mjs`.
|
|
5
|
+
Modificare invece le mappe `sizes` / `classes` / `media` dello script.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Controparte responsive di `margin-padding.css`, un blocco @media per breakpoint. */
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@media (--media-xlarge-viewport-up) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* stylelint-disable selector-class-pattern */
|
|
2
2
|
|
|
3
|
-
/*
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/* FILE GENERATO AUTOMATICAMENTE — non modificare a mano.
|
|
4
|
+
Generato da `node scripts/build-margin-padding-css.mjs`.
|
|
5
|
+
Modificare invece le mappe `sizes` / `classes` / `media` dello script.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Le varianti responsive sono in `margin-padding-media.css`. */
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
.m-0 {
|
package/src/css/reset.css
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/*
|
|
2
|
-
|
|
2
|
+
Reset CSS personalizzato di Josh
|
|
3
3
|
https://www.joshwcomeau.com/css/custom-css-reset/
|
|
4
4
|
*/
|
|
5
|
-
/* 1.
|
|
5
|
+
/* 1. Usa un modello di box-sizing più intuitivo */
|
|
6
6
|
|
|
7
7
|
*, *::before, *::after {
|
|
8
8
|
box-sizing: border-box;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
/* 2.
|
|
11
|
+
/* 2. Rimuove il margin predefinito */
|
|
12
12
|
* {
|
|
13
13
|
margin: 0;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
/* 3.
|
|
16
|
+
/* 3. Abilita le animazioni con keyword */
|
|
17
17
|
@media (prefers-reduced-motion: no-preference) {
|
|
18
18
|
html {
|
|
19
19
|
interpolate-size: allow-keywords;
|
|
@@ -21,29 +21,29 @@ https://www.joshwcomeau.com/css/custom-css-reset/
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
body {
|
|
24
|
-
/* 4.
|
|
24
|
+
/* 4. Aggiunge un line-height accessibile */
|
|
25
25
|
line-height: 1.5;
|
|
26
|
-
/* 5.
|
|
26
|
+
/* 5. Migliora il rendering del testo */
|
|
27
27
|
-webkit-font-smoothing: antialiased;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
/* 6.
|
|
30
|
+
/* 6. Migliora i default dei media */
|
|
31
31
|
img, picture, video, canvas, svg {
|
|
32
32
|
display: block;
|
|
33
33
|
max-width: 100%;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
/* 7.
|
|
36
|
+
/* 7. Eredita i font per i controlli dei form */
|
|
37
37
|
input, button, textarea, select {
|
|
38
38
|
font: inherit;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
/* 8.
|
|
41
|
+
/* 8. Evita l'overflow del testo */
|
|
42
42
|
p, h1, h2, h3, h4, h5, h6 {
|
|
43
43
|
overflow-wrap: break-word;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
/* 9.
|
|
46
|
+
/* 9. Migliora l'a capo del testo */
|
|
47
47
|
p {
|
|
48
48
|
text-wrap: pretty;
|
|
49
49
|
}
|
|
@@ -52,7 +52,7 @@ h1, h2, h3, h4, h5, h6 {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/*
|
|
55
|
-
10.
|
|
55
|
+
10. Crea uno stacking context alla radice
|
|
56
56
|
*/
|
|
57
57
|
/* stylelint-disable-next-line selector-id-pattern, selector-max-id */
|
|
58
58
|
#root, #__next {
|
package/src/icons/read-me.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
Quasi tutte le icone provengono da <https://phosphoricons.com/>
|
package/src/minimo.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* decommentare per usare i layer. Vedi https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@layer */
|
|
2
2
|
/* @layer reset, base, components, utilities, project, overrides; */
|
|
3
3
|
|
|
4
4
|
@import '@minimoSrc/css/reset.css';
|
|
@@ -36,13 +36,13 @@
|
|
|
36
36
|
@import '@minimoSrc/css/sizes.css';
|
|
37
37
|
@import '@minimoSrc/css/display.css';
|
|
38
38
|
@import '@minimoSrc/css/margin-padding.css';
|
|
39
|
-
/* @import '@minimoSrc/css/margin-padding-media.css'; responsive
|
|
39
|
+
/* @import '@minimoSrc/css/margin-padding-media.css'; versione responsive */
|
|
40
40
|
|
|
41
41
|
@import '@minimoSrc/css/overflow.css';
|
|
42
42
|
@import '@minimoSrc/css/position.css';
|
|
43
43
|
@import '@minimoSrc/css/visibility.css';
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
/* spinner:
|
|
46
|
+
/* spinner: includere solo il css dello spinner scelto */
|
|
47
47
|
@import '@minimoSrc/components/spinner/spinner-circle-basic.css';
|
|
48
48
|
|
|
@@ -404,7 +404,7 @@ const places = [
|
|
|
404
404
|
|
|
405
405
|
|
|
406
406
|
// --------------------
|
|
407
|
-
//
|
|
407
|
+
// luoghi non legati a un singolo paese (mari, oceani, regioni, aree polari)
|
|
408
408
|
'Ande', 'Amazzonia', 'Terra del Fuoco',
|
|
409
409
|
'Artide', 'Polo Nord', 'Antartide', 'Polo Sud',
|
|
410
410
|
'Groenlandia', 'Lapponia', 'Siberia',
|
|
@@ -416,20 +416,20 @@ const places = [
|
|
|
416
416
|
|
|
417
417
|
|
|
418
418
|
/**
|
|
419
|
-
*
|
|
419
|
+
* Chiave usata per far corrispondere un luogo indipendentemente da maiuscole/minuscole, spaziatura e stile dell'apostrofo
|
|
420
420
|
* @param {string} str
|
|
421
421
|
* @returns {string}
|
|
422
422
|
*/
|
|
423
423
|
const placeKey = str => str.toLowerCase().replace(/[ \u00A0]+/g, ' ').replace(/['‘’]/g, '’');
|
|
424
424
|
|
|
425
425
|
/**
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
426
|
+
* Costruisce il matcher per un elenco di luoghi: una singola regex (prima i luoghi più lunghi, così che
|
|
427
|
+
* ad es. "Lago di Como" prevalga su un nome più corto sovrapposto) e una mappa chiave → forma canonica.
|
|
428
|
+
* La forma canonica usa l'apostrofo tipografico e gli spazi non separabili dopo le particelle,
|
|
429
|
+
* in modo coerente con betterText().
|
|
430
430
|
*
|
|
431
|
-
* @param {string[]} list -
|
|
432
|
-
* @returns {{regex: RegExp, canonical: Map<string, string>} | null} null
|
|
431
|
+
* @param {string[]} list - elenco dei luoghi
|
|
432
|
+
* @returns {{regex: RegExp, canonical: Map<string, string>} | null} null se l'elenco è vuoto
|
|
433
433
|
*/
|
|
434
434
|
function buildPlacesMatcher(list) {
|
|
435
435
|
const canonical = new Map();
|
|
@@ -459,7 +459,7 @@ function buildPlacesMatcher(list) {
|
|
|
459
459
|
);
|
|
460
460
|
|
|
461
461
|
return {
|
|
462
|
-
//
|
|
462
|
+
// delimitatori personalizzati al posto di \b, che non funziona con lettere accentate ai bordi (es. "Perù")
|
|
463
463
|
regex: new RegExp(`(?<![\\p{L}\\p{N}])(?:${patterns.join('|')})(?![\\p{L}\\p{N}])`, 'giu'),
|
|
464
464
|
canonical
|
|
465
465
|
};
|
|
@@ -468,21 +468,21 @@ function buildPlacesMatcher(list) {
|
|
|
468
468
|
const defaultMatcher = buildPlacesMatcher(places);
|
|
469
469
|
|
|
470
470
|
/**
|
|
471
|
-
*
|
|
472
|
-
* (
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
471
|
+
* Versione di betterText() che normalizza anche le occorrenze di luoghi noti
|
|
472
|
+
* (paesi, città, fiumi, monti, località turistiche) presenti nel testo:
|
|
473
|
+
* il confronto non distingue maiuscole/minuscole ed è tollerante su spaziatura e stile
|
|
474
|
+
* dell'apostrofo, e ogni corrispondenza viene sostituita dalla forma canonica elencata in `places`
|
|
475
|
+
* (capitalizzazione, apostrofo tipografico, spazi non separabili dopo le particelle).
|
|
476
|
+
* La sostituzione dei luoghi viene eseguita dopo betterText(), quindi ha la precedenza sulla
|
|
477
|
+
* capitalizzazione imposta a particelle e parole personalizzate.
|
|
478
478
|
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
479
|
+
* NOTA: i luoghi che sono anche parole comuni (es. "Meno", "Po", "Reno") vengono messi in maiuscolo
|
|
480
|
+
* ovunque compaiano.
|
|
481
481
|
*
|
|
482
|
-
* @param {string} str -
|
|
483
|
-
* @param {string[]} [custom_words] -
|
|
484
|
-
* @param {string[]} [extra_places] -
|
|
485
|
-
* @returns {string}
|
|
482
|
+
* @param {string} str - stringa da elaborare
|
|
483
|
+
* @param {string[]} [custom_words] - elenco di parole di cui va mantenuta la capitalizzazione esatta (es. `['iPhone', 'macOS']`) (default: [])
|
|
484
|
+
* @param {string[]} [extra_places] - luoghi aggiuntivi, uniti all'elenco predefinito (default: [])
|
|
485
|
+
* @returns {string} stringa elaborata, oppure stringa vuota se l'input è falsy
|
|
486
486
|
*
|
|
487
487
|
* @example
|
|
488
488
|
* betterTextWithPlaces("vacanza a new york e nel lago di como ,l'avana");
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
/*! minimo - Better Text */
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
/*
|
|
6
|
+
Particelle/articoli italiani (più alcuni termini inglesi e toponomastici) di cui viene
|
|
7
|
+
imposta la capitalizzazione e dopo i quali gli spazi vengono trasformati in spazi non
|
|
8
|
+
separabili. Portati a livello di modulo insieme alle regex/lookup costruite qui sotto, dato
|
|
9
|
+
che nulla di tutto ciò dipende dagli argomenti della funzione e in precedenza veniva
|
|
10
|
+
ricostruito a ogni singola chiamata di betterText().
|
|
11
|
+
*/
|
|
9
12
|
const PARTICELLE = [
|
|
10
13
|
'e', 'ed',
|
|
11
14
|
'di', 'a', 'da', 'in', 'per', 'con', 'su', 'per', 'tra', 'fra',
|
|
@@ -18,72 +21,76 @@ const PARTICELLE = [
|
|
|
18
21
|
'col', 'collo', 'colla', 'con', 'coi', 'cogli', 'colle',
|
|
19
22
|
'sul', 'sullo', 'sulla', 'sui', 'sugli', 'sulle',
|
|
20
23
|
|
|
21
|
-
//
|
|
24
|
+
// termini toponomastici
|
|
22
25
|
'C.so', 'Corso', 'Via', 'P.za', 'Piazza', 'L.go', 'Largo', 'V.le', 'Viale',
|
|
23
26
|
'De', 'San', 'c/o', 'Loc.',
|
|
24
27
|
|
|
25
|
-
//
|
|
28
|
+
// inglese
|
|
26
29
|
'the', 'a', 'an', 'at', 'out', 'of',
|
|
27
30
|
|
|
28
|
-
//
|
|
31
|
+
// parole usate nei geonames
|
|
29
32
|
'isola', 'isole'
|
|
30
33
|
];
|
|
31
34
|
|
|
32
|
-
//
|
|
35
|
+
// corrisponde a una particella seguita da uno o più spazi, da trasformare in spazi non separabili
|
|
33
36
|
export const NBSP_AFTER_PARTICLE_REGEX =new RegExp('\\b(' + PARTICELLE.join('|') + ')\\b +', 'gmi');
|
|
34
37
|
|
|
35
|
-
//
|
|
38
|
+
// corrisponde a qualsiasi particella indipendentemente dal maiuscolo/minuscolo, per imporne la capitalizzazione esatta in un solo passaggio
|
|
36
39
|
const PARTICLE_CASING_REGEX = new RegExp('\\b(' + PARTICELLE.join('|') + ')\\b', 'gmi');
|
|
37
40
|
|
|
38
|
-
//
|
|
41
|
+
// particella in minuscolo → sua capitalizzazione esatta, per il replacer usato con PARTICLE_CASING_REGEX
|
|
39
42
|
const PARTICLE_CASING_MAP = new Map(PARTICELLE.map(term => [term.toLowerCase(), term]));
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
45
|
+
* Migliora una stringa di testo correggendo la spaziatura della punteggiatura, gli spazi
|
|
46
|
+
* multipli, le virgolette tipografiche, gli spazi non separabili dopo le particelle/articoli
|
|
47
|
+
* italiani e, opzionalmente, imponendo la capitalizzazione esatta di parole personalizzate.
|
|
48
|
+
* Le particelle vengono forzate alla capitalizzazione elencata, tranne all'inizio del testo
|
|
49
|
+
* dove la prima lettera è maiuscola.
|
|
47
50
|
*
|
|
48
|
-
* @param {string} str -
|
|
49
|
-
* @param {string[]} [custom_words] -
|
|
50
|
-
* @returns {string}
|
|
51
|
+
* @param {string} str - stringa da elaborare
|
|
52
|
+
* @param {string[]} [custom_words] - elenco di parole di cui va mantenuta la capitalizzazione esatta (es. `['iPhone', 'macOS']`) (default: [])
|
|
53
|
+
* @returns {string} stringa elaborata, oppure stringa vuota se l'input è falsy
|
|
51
54
|
*/
|
|
52
55
|
export function betterText(str, custom_words = []) {
|
|
53
56
|
|
|
54
57
|
if(str) {
|
|
55
58
|
str = str.trim();
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
/*
|
|
61
|
+
punteggiatura: rimuove lo spazio prima, garantisce un solo spazio dopo
|
|
62
|
+
NOTA: deve essere eseguito prima di qualsiasi sostituzione di entità HTML per evitare conflitti con `;`
|
|
63
|
+
(?!$): negative lookahead per saltare la punteggiatura a fine stringa
|
|
64
|
+
*/
|
|
60
65
|
str = str.replace(/ +(,|;|\.|:|!|\?)/g, '$1');
|
|
61
66
|
str = str.replace(/(,|;|\.|:|!|\?)(?!$) +/g, '$1 ');
|
|
62
67
|
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
/*
|
|
69
|
+
aggiunge lo spazio mancante dopo , ; ! ? quando seguiti direttamente da una lettera o da una virgoletta;
|
|
70
|
+
le cifre vengono saltate di proposito (decimali come 1,5), così come . e : (abbreviazioni, orari, URL)
|
|
71
|
+
*/
|
|
65
72
|
str = str.replace(/([,;!?])(?=[\p{L}"'“‘])/gu, '$1 ');
|
|
66
73
|
|
|
67
|
-
//
|
|
74
|
+
// comprime spazi e tabulazioni multipli (inclusi gli spazi non separabili)
|
|
68
75
|
str = str.replace(/[ \t\u00A0]+/g, ' ');
|
|
69
76
|
|
|
70
|
-
//
|
|
71
|
-
str = str.replace(/(^| )"/g, '$1“') //
|
|
72
|
-
.replace(/"/g, '”') //
|
|
73
|
-
.replace(/(^| )'/g, '$1‘') //
|
|
74
|
-
.replace(/'/g, '’') //
|
|
77
|
+
// virgolette tipografiche
|
|
78
|
+
str = str.replace(/(^| )"/g, '$1“') // virgolette doppie di apertura
|
|
79
|
+
.replace(/"/g, '”') // virgolette doppie rimanenti → chiusura
|
|
80
|
+
.replace(/(^| )'/g, '$1‘') // virgolette singole di apertura
|
|
81
|
+
.replace(/'/g, '’') // virgolette singole rimanenti e apostrofi
|
|
75
82
|
;
|
|
76
83
|
|
|
77
|
-
//
|
|
84
|
+
// rimuove lo spazio dopo l'apostrofo preceduto da articoli elisi (l', un', d', all', ...)
|
|
78
85
|
str = str.replace(/((^| )(l|un|d|all|dell|nell|sull)('|')) /gi, '$1' );
|
|
79
86
|
|
|
80
|
-
//
|
|
87
|
+
// sostituisce gli spazi normali con spazi non separabili dopo le particelle/articoli italiani
|
|
81
88
|
str = str.replace(NBSP_AFTER_PARTICLE_REGEX, function (match) {
|
|
82
89
|
return match.replace(/ +/g, '\u00A0');
|
|
83
90
|
});
|
|
84
91
|
|
|
85
|
-
//
|
|
86
|
-
//
|
|
92
|
+
// impone la capitalizzazione esatta di ogni particella in un solo passaggio;
|
|
93
|
+
// una particella all'inizio del testo (eventualmente dopo una virgoletta di apertura) viene messa in maiuscolo
|
|
87
94
|
str = str.replace(PARTICLE_CASING_REGEX, (match, _p1, offset, whole) => {
|
|
88
95
|
const exact = PARTICLE_CASING_MAP.get(match.toLowerCase()) ?? match;
|
|
89
96
|
return /^[“‘]?$/.test(whole.slice(0, offset))
|
|
@@ -91,8 +98,8 @@ export function betterText(str, custom_words = []) {
|
|
|
91
98
|
: exact;
|
|
92
99
|
});
|
|
93
100
|
|
|
94
|
-
//
|
|
95
|
-
//
|
|
101
|
+
// mette in maiuscolo la prima lettera dopo ! ? e i puntini di sospensione (... o …), eventualmente dopo una virgoletta di apertura;
|
|
102
|
+
// viene eseguito dopo la capitalizzazione delle particelle così che una maiuscola non venga annullata per particelle come "e" o "di"
|
|
96
103
|
str = str.replace(/([!?]|\.{3}|…) +([“‘]?)(\p{Ll})/gu, (_match, punct, quote, letter) =>
|
|
97
104
|
`${punct} ${quote}${letter.toUpperCase()}`
|
|
98
105
|
);
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/*! minimo - Classnames */
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* `MinimoClass |
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* `MinimoClass | qualsiasi altra stringa`: mantiene l'autocomplete dell'editor per i nomi
|
|
5
|
+
* di classe di minimo (vedi ../../types/classes.d.ts, generato automaticamente) pur
|
|
6
|
+
* accettando nomi di classe arbitrari definiti dal consumer. Il branding `string & {}`
|
|
7
|
+
* è un trucco TS che impedisce all'union di ridursi a semplice `string`,
|
|
8
|
+
* cosa che disattiverebbe in silenzio l'autocomplete.
|
|
9
9
|
* @typedef {import('../../types/classes.js').MinimoClass | (string & {})} ClassName
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
/** @typedef {ClassName | null | undefined | false | 0} ClassValue */
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* Unisce i nomi di classe CSS, scartando i valori falsy e non stringa.
|
|
16
|
+
* Accetta stringhe, valori falsy e array (anche annidati) degli stessi.
|
|
17
17
|
* @param {...(ClassValue | ClassValue[])} args
|
|
18
18
|
* @returns {string}
|
|
19
19
|
*/
|
|
@@ -29,7 +29,7 @@ export function classnames(...args) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
32
|
+
* Come {@link classnames}, ma restituisce `null` quando il risultato è una stringa vuota.
|
|
33
33
|
* @param {...(ClassValue | ClassValue[])} args
|
|
34
34
|
* @returns {string | null}
|
|
35
35
|
*/
|