@massimo-cassandro/minimo 1.21.9 → 1.22.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/design-tokens/_src/switch.minimo.tokens.mjs +24 -0
- package/dev-tools/starter-kit/starter-install.sh +34 -16
- package/dev-tools/starter-kit/templates/package-tpl.json +1 -1
- package/package.json +1 -1
- package/src/css/forms/switch.css +86 -82
- package/src/custom-properties.css +6 -2
- package/src/minimo.css +1 -0
- package/types/classes.d.ts +2 -2
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
switch: {
|
|
3
|
+
width: {
|
|
4
|
+
$value: '2.25em',
|
|
5
|
+
$type: 'dimension'
|
|
6
|
+
},
|
|
7
|
+
|
|
8
|
+
height: {
|
|
9
|
+
$value: '1.25em',
|
|
10
|
+
$type: 'dimension'
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
thumb: {
|
|
14
|
+
inset: {
|
|
15
|
+
$value: '.125em',
|
|
16
|
+
$type: 'dimension'
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
transition: {
|
|
21
|
+
duration: {
|
|
22
|
+
$value: '.2s',
|
|
23
|
+
$type: 'duration'
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
|
|
3
27
|
background: {
|
|
4
28
|
color: {
|
|
5
29
|
$value: '{neutral.100}',
|
|
@@ -141,21 +141,22 @@ safe_cat "${TEMPLATES_DIR}/_prettierrc" .prettierrc new
|
|
|
141
141
|
safe_cat "${TEMPLATES_DIR}/_root_htaccess" _root_htaccess
|
|
142
142
|
safe_cat "${TEMPLATES_DIR}/_root_robots.txt" _root_robots.txt
|
|
143
143
|
|
|
144
|
-
# jsconfig.json:
|
|
145
|
-
#
|
|
146
|
-
#
|
|
144
|
+
# jsconfig.json: sta SEMPRE nella root del progetto (è anche il file di
|
|
145
|
+
# riferimento di vscode). I suoi path sono quindi relativi alla root: il
|
|
146
|
+
# placeholder __FRONTEND__ viene risolto in base alla posizione scelta.
|
|
147
|
+
# NB: webpack.config.mjs lo cerca in root anche quando è in una sottodirectory
|
|
147
148
|
if [ "$FRONTEND_INSTALL_PATH" = "." ]; then
|
|
148
|
-
|
|
149
|
+
FRONTEND_REL="./"
|
|
149
150
|
else
|
|
150
|
-
|
|
151
|
+
FRONTEND_REL="./frontend/"
|
|
151
152
|
fi
|
|
152
153
|
JSCONFIG_TPL="${TEMPLATES_DIR}/jsconfig.json"
|
|
153
154
|
if [ ! -f "$JSCONFIG_TPL" ]; then
|
|
154
155
|
echo -e "${RED}Sorgente mancante: ${JSCONFIG_TPL}${NC}"
|
|
155
156
|
else
|
|
156
157
|
JSCONFIG_TMP="$(mktemp)"
|
|
157
|
-
sed "s|
|
|
158
|
-
safe_cat "$JSCONFIG_TMP"
|
|
158
|
+
sed "s|__FRONTEND__|${FRONTEND_REL}|g" "$JSCONFIG_TPL" >| "$JSCONFIG_TMP"
|
|
159
|
+
safe_cat "$JSCONFIG_TMP" jsconfig.json new
|
|
159
160
|
rm -f "$JSCONFIG_TMP"
|
|
160
161
|
fi
|
|
161
162
|
|
|
@@ -247,17 +248,34 @@ mkdir -p \
|
|
|
247
248
|
# template html di webpack (HtmlWebpackPlugin: `./src/tpl/index.ejs`)
|
|
248
249
|
safe_cat "${WEBPACK_SOURCE_DIR}/webpack-template.ejs" "${FRONTEND_INSTALL_PATH}/src/tpl/index.ejs"
|
|
249
250
|
|
|
250
|
-
#
|
|
251
|
-
#
|
|
252
|
-
#
|
|
253
|
-
|
|
254
|
-
for
|
|
255
|
-
|
|
251
|
+
# Sorgenti di minimo da copiare nel progetto: si usa il pacchetto appena
|
|
252
|
+
# installato in node_modules (stessa versione che userà il progetto) e, in
|
|
253
|
+
# fallback, la dir da cui è lanciato questo script (repo o pacchetto estratto)
|
|
254
|
+
MINIMO_PKG_DIR=""
|
|
255
|
+
for CANDIDATE in "./node_modules/@massimo-cassandro/minimo" "${BASE_URL}/../.."; do
|
|
256
|
+
if [ -f "${CANDIDATE}/src/custom-properties.css" ]; then
|
|
257
|
+
MINIMO_PKG_DIR="$CANDIDATE"
|
|
258
|
+
break
|
|
259
|
+
fi
|
|
256
260
|
done
|
|
257
261
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
262
|
+
if [ -z "$MINIMO_PKG_DIR" ]; then
|
|
263
|
+
echo -e "${RED}Sorgenti di minimo non trovati (né in ./node_modules/@massimo-cassandro/minimo né in ${BASE_URL}/../..): css di base e tokens-config non copiati${NC}"
|
|
264
|
+
BLOCKED_FILES+=("css di base + tokens-config.mjs → sorgenti minimo non trovati")
|
|
265
|
+
else
|
|
266
|
+
echo "sorgenti minimo: ${MINIMO_PKG_DIR}"
|
|
267
|
+
|
|
268
|
+
# css di partenza del progetto: solo i file destinati a essere personalizzati.
|
|
269
|
+
# minimo.css NON viene copiato: i moduli css del framework vanno importati dal
|
|
270
|
+
# pacchetto (`@import '@minimo/css/...'`, vedi entry-tpl.css)
|
|
271
|
+
for FILE in custom-properties.css custom-media.css fonts.css; do
|
|
272
|
+
safe_cat "${MINIMO_PKG_DIR}/src/${FILE}" "${FRONTEND_INSTALL_PATH}/src/css/${FILE}"
|
|
273
|
+
done
|
|
274
|
+
|
|
275
|
+
# config di build-tokens: collocato accanto al css generato (custom-properties.css).
|
|
276
|
+
# NB: i percorsi relativi nel file vanno adattati alla sua posizione effettiva
|
|
277
|
+
safe_cat "${MINIMO_PKG_DIR}/design-tokens/tokens-config-sample.mjs" "${FRONTEND_INSTALL_PATH}/src/css/tokens-config.mjs"
|
|
278
|
+
fi
|
|
261
279
|
|
|
262
280
|
# template delle entry css (globale/di pagina e critical): ogni entry deve
|
|
263
281
|
# importare direttamente custom-properties.css (vedi commenti nei file stessi)
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"launchChrome": "open -n -a 'Google Chrome' --args --profile-directory='Profile 3'",
|
|
29
29
|
"python server": "python3 -m http.server 8000 # --directory __dirname__ # 8000 = default port",
|
|
30
30
|
"php server": "php -S localhost:8000 # -t root_dir/",
|
|
31
|
-
"symfony server": "symfony serve --port=
|
|
31
|
+
"symfony server": "symfony serve --port=810X --listen-ip=0.0.0.0 # http://192.168.1.135:810X # -d (deamon): rimane aperto anche dopo la chiusura del terminale, terminare con `symfony server:stop`",
|
|
32
32
|
"node server": "node serve # richiede ‘npm i serve’",
|
|
33
33
|
"build tokens": "npx buildTokens --config ./src/css/tokens-config.mjs # o ./frontend/src/css/tokens-config.mjs",
|
|
34
34
|
"check unresolved props": "npx checkUnresolvedProps --config ./src/css/tokens-config.mjs # o ./frontend/src/css/tokens-config.mjs",
|
package/package.json
CHANGED
package/src/css/forms/switch.css
CHANGED
|
@@ -1,106 +1,110 @@
|
|
|
1
|
+
/* TODO aggiungere esempi di uso */
|
|
2
|
+
/* TODO valutare versione con label a sinistra (form-check-reverse) */
|
|
1
3
|
|
|
2
|
-
/*
|
|
4
|
+
/*
|
|
5
|
+
Markup (come bootstrap 5, con l'aggiunta dell'attributo nativo `switch`):
|
|
3
6
|
|
|
7
|
+
<div class="form-check form-switch">
|
|
8
|
+
<input class="form-check-input" type="checkbox" role="switch" switch id="my-switch">
|
|
9
|
+
<label class="form-check-label" for="my-switch">Abilita notifiche</label>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
L'attributo `switch` (per ora solo WebKit) fa sì che il browser generi un vero
|
|
13
|
+
controllo switch nativo, modellabile con gli pseudo-elementi `::track` e `::thumb`.
|
|
14
|
+
Dove non è supportato (o dove l'attributo è assente) si applica il fallback
|
|
15
|
+
`appearance: none` con la pallina disegnata come background-image.
|
|
16
|
+
*/
|
|
4
17
|
|
|
5
18
|
.form-switch {
|
|
6
|
-
padding-left: $form-switch-padding-start;
|
|
7
19
|
|
|
8
|
-
|
|
9
|
-
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image)};
|
|
20
|
+
--_switch-thumb-size: calc(var(--switch-height) - var(--switch-thumb-inset) * 2);
|
|
10
21
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@include transition($form-switch-transition);
|
|
22
|
+
/* annulla il layout con float di `.form-check` */
|
|
23
|
+
display: flex;
|
|
24
|
+
column-gap: var(--size-sm);
|
|
25
|
+
align-items: center;
|
|
26
|
+
padding-left: 0;
|
|
17
27
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
28
|
+
.form-check-input {
|
|
29
|
+
float: none;
|
|
30
|
+
flex: none;
|
|
31
|
+
width: var(--switch-width);
|
|
32
|
+
height: var(--switch-height);
|
|
33
|
+
margin: 0;
|
|
34
|
+
appearance: none;
|
|
35
|
+
cursor: pointer;
|
|
36
|
+
background-color: var(--switch-background-color);
|
|
37
|
+
background-image: radial-gradient(
|
|
38
|
+
circle closest-side,
|
|
39
|
+
var(--switch-cursor-background-color) 98%,
|
|
40
|
+
transparent
|
|
41
|
+
);
|
|
42
|
+
background-repeat: no-repeat;
|
|
43
|
+
background-position: var(--switch-thumb-inset) center;
|
|
44
|
+
background-size: var(--_switch-thumb-size) var(--_switch-thumb-size);
|
|
45
|
+
border: none;
|
|
46
|
+
border-radius: var(--switch-height);
|
|
47
|
+
|
|
48
|
+
/* annulla lo `scale` applicato a tutti i checkbox */
|
|
49
|
+
scale: none;
|
|
50
|
+
|
|
51
|
+
&:checked {
|
|
52
|
+
background-color: var(--switch-checked-background-color);
|
|
53
|
+
background-position: calc(100% - var(--switch-thumb-inset)) center;
|
|
54
|
+
}
|
|
21
55
|
|
|
22
|
-
|
|
23
|
-
|
|
56
|
+
&:focus {
|
|
57
|
+
outline: none;
|
|
58
|
+
}
|
|
24
59
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)};
|
|
60
|
+
&:focus-visible {
|
|
61
|
+
outline: var(--form-control-focus-outline-width) solid var(--form-control-focus-color);
|
|
62
|
+
outline-offset: var(--form-control-focus-outline-offset);
|
|
29
63
|
}
|
|
30
64
|
}
|
|
31
|
-
}
|
|
32
65
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.form-check-input {
|
|
38
|
-
margin-right: $form-switch-padding-start * -1;
|
|
39
|
-
margin-left: 0;
|
|
66
|
+
.form-check-label {
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
user-select: none;
|
|
40
69
|
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
*/
|
|
46
70
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<input type="checkbox">
|
|
50
|
-
<span class="switch-track"></span>
|
|
51
|
-
<label>Abilita notifiche</label>
|
|
52
|
-
</div>
|
|
53
|
-
*/
|
|
71
|
+
&:has(.form-check-input:disabled) {
|
|
72
|
+
opacity: var(--form-control-disabled-opacity);
|
|
54
73
|
|
|
55
|
-
.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.switch input {
|
|
62
|
-
position: absolute;
|
|
63
|
-
width: 0;
|
|
64
|
-
height: 0;
|
|
65
|
-
opacity: 0;
|
|
74
|
+
.form-check-input, .form-check-label {
|
|
75
|
+
cursor: not-allowed;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
66
78
|
}
|
|
67
79
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
transition: background-color .2s;
|
|
80
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
81
|
+
.form-switch .form-check-input {
|
|
82
|
+
transition:
|
|
83
|
+
background-color var(--switch-transition-duration) linear,
|
|
84
|
+
background-position var(--switch-transition-duration) ease-in-out;
|
|
85
|
+
}
|
|
75
86
|
}
|
|
76
87
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
88
|
+
/* switch nativo: si lascia il rendering al browser e si interviene sui suoi pseudo-elementi */
|
|
89
|
+
/* stylelint-disable selector-pseudo-element-no-unknown */
|
|
90
|
+
@supports selector(input[switch]::thumb) {
|
|
81
91
|
|
|
82
|
-
.switch-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
width: 2em;
|
|
87
|
-
height: 2em;
|
|
88
|
-
content: '';
|
|
89
|
-
background: var(--switch-cursor-background-color);
|
|
90
|
-
border-radius: 50%;
|
|
91
|
-
transition: translate .2s;
|
|
92
|
-
}
|
|
92
|
+
.form-switch .form-check-input[switch] {
|
|
93
|
+
appearance: auto;
|
|
94
|
+
background: none;
|
|
95
|
+
border-radius: 0; /* gestito da ::track */
|
|
93
96
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
+
&::track {
|
|
98
|
+
background-color: var(--switch-background-color);
|
|
99
|
+
}
|
|
97
100
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
+
&::thumb {
|
|
102
|
+
background-color: var(--switch-cursor-background-color);
|
|
103
|
+
}
|
|
101
104
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
&:checked::track {
|
|
106
|
+
background-color: var(--switch-checked-background-color);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
106
109
|
}
|
|
110
|
+
/* stylelint-enable selector-pseudo-element-no-unknown */
|
|
@@ -284,10 +284,10 @@
|
|
|
284
284
|
--mpopup-header-color: var(--text-color);
|
|
285
285
|
--mpopup-header-font-size: var(--font-size-xl);
|
|
286
286
|
--mpopup-header-padding: var(--size-xs);
|
|
287
|
-
--mpopup-height:
|
|
287
|
+
--mpopup-height: fit-content;
|
|
288
288
|
--mpopup-max-height: 90dvh;
|
|
289
289
|
--mpopup-max-width: 70dvw;
|
|
290
|
-
--mpopup-min-height:
|
|
290
|
+
--mpopup-min-height: 40dvw;
|
|
291
291
|
--mpopup-min-width: 400px;
|
|
292
292
|
--mpopup-width: max-content;
|
|
293
293
|
|
|
@@ -383,6 +383,10 @@
|
|
|
383
383
|
--switch-background-color: var(--neutral-100);
|
|
384
384
|
--switch-checked-background-color: var(--primary-100);
|
|
385
385
|
--switch-cursor-background-color: var(--body-background-color);
|
|
386
|
+
--switch-height: 1.25em;
|
|
387
|
+
--switch-thumb-inset: .125em;
|
|
388
|
+
--switch-transition-duration: .2s;
|
|
389
|
+
--switch-width: 2.25em;
|
|
386
390
|
|
|
387
391
|
--table-body-border-width: 1px;
|
|
388
392
|
--table-body-tr-alt-bg-color: #efefef;
|
package/src/minimo.css
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
@import '@minimo/css/forms/form-disabled-readonly.css';
|
|
18
18
|
@import '@minimo/css/forms/validation.css';
|
|
19
19
|
@import '@minimo/css/forms/form-utilities.css';
|
|
20
|
+
@import '@minimo/css/forms/switch.css';
|
|
20
21
|
|
|
21
22
|
@import '@minimo/css/buttons/buttons.css';
|
|
22
23
|
@import '@minimo/css/buttons/buttons-primary.css';
|
package/types/classes.d.ts
CHANGED
|
@@ -59,6 +59,7 @@ export type MinimoClass =
|
|
|
59
59
|
| 'font-semibold'
|
|
60
60
|
| 'form-check'
|
|
61
61
|
| 'form-check-input'
|
|
62
|
+
| 'form-check-label'
|
|
62
63
|
| 'form-check-top-label'
|
|
63
64
|
| 'form-collection'
|
|
64
65
|
| 'form-collection-fset'
|
|
@@ -70,6 +71,7 @@ export type MinimoClass =
|
|
|
70
71
|
| 'form-group'
|
|
71
72
|
| 'form-help-text'
|
|
72
73
|
| 'form-label'
|
|
74
|
+
| 'form-switch'
|
|
73
75
|
| 'form-user-info'
|
|
74
76
|
| 'fset'
|
|
75
77
|
| 'gap-0'
|
|
@@ -1378,8 +1380,6 @@ export type MinimoClass =
|
|
|
1378
1380
|
| 'span-3'
|
|
1379
1381
|
| 'span-4'
|
|
1380
1382
|
| 'spinner'
|
|
1381
|
-
| 'switch'
|
|
1382
|
-
| 'switch-track'
|
|
1383
1383
|
| 'table'
|
|
1384
1384
|
| 'table-bordered'
|
|
1385
1385
|
| 'table-responsive'
|