@massimo-cassandro/minimo 1.14.6 → 1.15.1
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.
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
#!/bin/zsh
|
|
2
2
|
|
|
3
|
+
# Questo script richiede zsh: se lanciato con sh/bash blocca l'esecuzione
|
|
4
|
+
if [ -z "$ZSH_VERSION" ]; then
|
|
5
|
+
echo "Errore: lanciare con 'zsh starter-install.sh', non con sh/bash." >&2
|
|
6
|
+
exit 1
|
|
7
|
+
fi
|
|
8
|
+
|
|
3
9
|
# Configurazione variabili
|
|
4
10
|
# BASE_URL="https://raw.githubusercontent.com/massimo-cassandro/minimo/refs/heads/main"
|
|
5
11
|
|
|
@@ -24,33 +30,38 @@ NC='\033[0m' # No Color
|
|
|
24
30
|
# protezione contro la sovrascrittura
|
|
25
31
|
set -C
|
|
26
32
|
|
|
27
|
-
# Array per tracciare
|
|
33
|
+
# Array per tracciare i file già esistenti
|
|
28
34
|
BLOCKED_FILES=()
|
|
29
35
|
|
|
30
|
-
# Wrapper: copia solo se il file non esiste, altrimenti registra il blocco
|
|
36
|
+
# Wrapper: copia solo se il file non esiste, altrimenti registra il blocco.
|
|
37
|
+
# Con terzo argomento "new", se la destinazione esiste già la copia viene
|
|
38
|
+
# comunque creata con prefisso NEW- (da integrare manualmente o rimuovere)
|
|
31
39
|
safe_cat() {
|
|
32
40
|
local src="$1"
|
|
33
41
|
local dest="$2"
|
|
42
|
+
local mode="$3"
|
|
43
|
+
if [ ! -f "$src" ]; then
|
|
44
|
+
echo -e "${RED}Sorgente mancante: $src${NC}"
|
|
45
|
+
return 1
|
|
46
|
+
fi
|
|
34
47
|
if [ -e "$dest" ]; then
|
|
35
|
-
|
|
48
|
+
if [ "$mode" = "new" ]; then
|
|
49
|
+
local new_dest="$(dirname "$dest")/NEW-$(basename "$dest")"
|
|
50
|
+
cat "$src" >| "$new_dest"
|
|
51
|
+
BLOCKED_FILES+=("$dest → copiato come $new_dest")
|
|
52
|
+
else
|
|
53
|
+
BLOCKED_FILES+=("$dest")
|
|
54
|
+
fi
|
|
36
55
|
else
|
|
37
56
|
cat "$src" > "$dest"
|
|
38
57
|
fi
|
|
39
58
|
}
|
|
40
59
|
|
|
41
60
|
echo -e "${GREEN}...package.json${NC}"
|
|
42
|
-
|
|
43
|
-
safe_cat "${TEMPLATES_DIR}/package-tpl.json" package.json
|
|
44
|
-
else
|
|
45
|
-
echo -e "${GREEN}package.json already exists${NC}"
|
|
46
|
-
fi
|
|
61
|
+
safe_cat "${TEMPLATES_DIR}/package-tpl.json" package.json new
|
|
47
62
|
|
|
48
63
|
echo -e "${GREEN}...gitignore${NC}"
|
|
49
|
-
|
|
50
|
-
safe_cat "${TEMPLATES_DIR}/_gitignore" .gitignore
|
|
51
|
-
else
|
|
52
|
-
echo -e "${GREEN}.gitignore already exists${NC}"
|
|
53
|
-
fi
|
|
64
|
+
safe_cat "${TEMPLATES_DIR}/_gitignore" .gitignore new
|
|
54
65
|
|
|
55
66
|
echo -e "\n${GREEN}Where do you want to install the frontend configuration?${NC}"
|
|
56
67
|
echo "1) Root directory"
|
|
@@ -73,20 +84,20 @@ fi
|
|
|
73
84
|
|
|
74
85
|
echo -e "\n${GREEN}...config files & utilities${NC}"
|
|
75
86
|
|
|
76
|
-
safe_cat "${TEMPLATES_DIR}/_browserslistrc" .browserslistrc
|
|
77
|
-
safe_cat "${TEMPLATES_DIR}/_editorconfig" .editorconfig
|
|
78
|
-
safe_cat "${TEMPLATES_DIR}/_prettierrc" .prettierrc
|
|
79
|
-
safe_cat "${TEMPLATES_DIR}/jsconfig.json" jsconfig.json
|
|
80
|
-
safe_cat "${TEMPLATES_DIR}/__project__.code-workspace" __project__.code-workspace
|
|
87
|
+
safe_cat "${TEMPLATES_DIR}/_browserslistrc" .browserslistrc new
|
|
88
|
+
safe_cat "${TEMPLATES_DIR}/_editorconfig" .editorconfig new
|
|
89
|
+
safe_cat "${TEMPLATES_DIR}/_prettierrc" .prettierrc new
|
|
90
|
+
safe_cat "${TEMPLATES_DIR}/jsconfig.json" jsconfig.json new
|
|
91
|
+
safe_cat "${TEMPLATES_DIR}/__project__.code-workspace" __project__.code-workspace new
|
|
81
92
|
|
|
82
93
|
|
|
83
94
|
echo -e "\n${GREEN}...eslint${NC}"
|
|
84
95
|
npm i -D @massimo-cassandro/eslint-config
|
|
85
|
-
safe_cat "${TEMPLATES_DIR}/eslint.config.mjs" eslint.config.mjs
|
|
96
|
+
safe_cat "${TEMPLATES_DIR}/eslint.config.mjs" eslint.config.mjs new
|
|
86
97
|
|
|
87
98
|
echo -e "\n${GREEN}...stylelint${NC}"
|
|
88
99
|
npm i -D @massimo-cassandro/stylelint-config
|
|
89
|
-
safe_cat "${TEMPLATES_DIR}/stylelint.config.mjs" stylelint.config.mjs
|
|
100
|
+
safe_cat "${TEMPLATES_DIR}/stylelint.config.mjs" stylelint.config.mjs new
|
|
90
101
|
|
|
91
102
|
echo -e "\n${GREEN}...webpack${NC}"
|
|
92
103
|
npm i -D webpack-cli webpack-dev-server webpack-manifest-plugin webpack
|
|
@@ -117,15 +128,19 @@ FILES=(
|
|
|
117
128
|
'postcss.config.mjs'
|
|
118
129
|
)
|
|
119
130
|
|
|
120
|
-
|
|
121
|
-
|
|
131
|
+
# se la cartella esiste già, i moduli vengono copiati in NEW-webpack-modules
|
|
132
|
+
# (da integrare manualmente o rimuovere)
|
|
133
|
+
if [ -d "$WEBPACK_LOCAL_DIR" ]; then
|
|
134
|
+
NEW_WEBPACK_LOCAL_DIR="$(dirname "$WEBPACK_LOCAL_DIR")/NEW-$(basename "$WEBPACK_LOCAL_DIR")"
|
|
135
|
+
BLOCKED_FILES+=("$WEBPACK_LOCAL_DIR → copiata come $NEW_WEBPACK_LOCAL_DIR")
|
|
136
|
+
WEBPACK_LOCAL_DIR="$NEW_WEBPACK_LOCAL_DIR"
|
|
137
|
+
fi
|
|
122
138
|
|
|
123
|
-
|
|
124
|
-
# echo "Scaricamento di $FILE..."
|
|
125
|
-
safe_cat "${WEBPACK_MODULES_REMOTE_URL}/${FILE}" "${WEBPACK_LOCAL_DIR}/${FILE}"
|
|
126
|
-
done
|
|
139
|
+
mkdir -p "$WEBPACK_LOCAL_DIR"
|
|
127
140
|
|
|
128
|
-
|
|
141
|
+
for FILE in "${FILES[@]}"; do
|
|
142
|
+
safe_cat "${WEBPACK_MODULES_REMOTE_URL}/${FILE}" "${WEBPACK_LOCAL_DIR}/${FILE}"
|
|
143
|
+
done
|
|
129
144
|
|
|
130
145
|
echo -e "\n${GREEN}Creating a template of your frontend application's folder structured${NC}"
|
|
131
146
|
|
|
@@ -136,9 +151,9 @@ mkdir -p error-pages imgs icons src src/css favicons design-tokens
|
|
|
136
151
|
cd ..
|
|
137
152
|
set +C
|
|
138
153
|
|
|
139
|
-
# Riepilogo finale dei file
|
|
154
|
+
# Riepilogo finale dei file già esistenti
|
|
140
155
|
if [ ${#BLOCKED_FILES[@]} -gt 0 ]; then
|
|
141
|
-
echo -e "\n${YELLOW}*** File non copiati
|
|
156
|
+
echo -e "\n${YELLOW}*** File già esistenti (non copiati o copiati con prefisso NEW-): ***${NC}"
|
|
142
157
|
for F in "${BLOCKED_FILES[@]}"; do
|
|
143
158
|
echo -e "${YELLOW} ✗ $F${NC}"
|
|
144
159
|
done
|
package/index.js
CHANGED
|
@@ -11,6 +11,7 @@ export { escapeHTML, unescapeHTML } from './src/utilities/escape-html.js';
|
|
|
11
11
|
export { generatePwd } from './src/utilities/generate-pwd.js';
|
|
12
12
|
export { getCookie, setCookie } from './src/utilities/cookies.js';
|
|
13
13
|
export { linkedDates } from './src/utilities/linked-dates.js';
|
|
14
|
+
export { parseFileSize } from './src/utilities/parse-file-size.js';
|
|
14
15
|
export { randomId } from './src/utilities/random-id.js';
|
|
15
16
|
export { relativeDate } from './src/utilities/relative-date.js';
|
|
16
17
|
export { sentenceCase } from './src/utilities/sentence-case.js';
|
package/package.json
CHANGED
|
@@ -15,6 +15,7 @@ References
|
|
|
15
15
|
|
|
16
16
|
// TODO snackbar action
|
|
17
17
|
// TODO handle multiple simultaneous snackbars (no stacking)
|
|
18
|
+
// TODO test con prefers-reduced-motion
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Displays a snackbar / toast notification using the Popover API.
|
|
@@ -53,12 +54,22 @@ export function snackbar(message, options = {}){
|
|
|
53
54
|
|
|
54
55
|
if (_timeoutID) clearTimeout(_timeoutID);
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
_popover?.addEventListener('animationend', () => {
|
|
57
|
+
const remove = () => {
|
|
59
58
|
_popover?.hidePopover();
|
|
60
59
|
_popover?.remove();
|
|
61
|
-
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
_popover?.classList.add(styles.isHiding);
|
|
63
|
+
|
|
64
|
+
// with `prefers-reduced-motion` (or any override disabling animations) no animation
|
|
65
|
+
// runs and `animationend` would never fire: in that case remove immediately
|
|
66
|
+
if (_popover?.getAnimations().length) {
|
|
67
|
+
// 'once' prevents duplicate listeners; the flag guards against calls before animation ends
|
|
68
|
+
_popover.addEventListener('animationend', remove, { once: true });
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
remove();
|
|
72
|
+
}
|
|
62
73
|
};
|
|
63
74
|
|
|
64
75
|
_popover = domBuilder([
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts a file size in bytes to a human readable string,
|
|
5
|
+
* using the most appropriate unit (bytes, KB, MB or GB).
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* parseFileSize(1536); // "1.5 KB"
|
|
9
|
+
* parseFileSize(10485760); // "10 MB"
|
|
10
|
+
*
|
|
11
|
+
* @param {number} bytes - file size in bytes
|
|
12
|
+
* @param {number} [decimals=1] - max number of decimal digits
|
|
13
|
+
* @returns {string} formatted size (e.g. "1.5 MB")
|
|
14
|
+
*/
|
|
15
|
+
export function parseFileSize(bytes, decimals = 1) {
|
|
16
|
+
|
|
17
|
+
if(typeof bytes !== 'number' || isNaN(bytes) || bytes < 0) {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const units = ['bytes', 'KB', 'MB', 'GB'],
|
|
22
|
+
k = 1024;
|
|
23
|
+
|
|
24
|
+
const exp = bytes === 0
|
|
25
|
+
? 0
|
|
26
|
+
: Math.min(Math.floor(Math.log(bytes) / Math.log(k)), units.length - 1);
|
|
27
|
+
|
|
28
|
+
const value = bytes / Math.pow(k, exp);
|
|
29
|
+
|
|
30
|
+
// \u202f = narrow no-break space
|
|
31
|
+
return `${parseFloat(value.toFixed(decimals))}\u202f${units[exp]}`;
|
|
32
|
+
}
|