@klodd/ds 3.12.4 → 3.13.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/css/00-primitives.css +0 -2
- package/css/10-semantic.css +2 -2
- package/css/components/chip.css +4 -110
- package/js/pwa-register.js +6 -97
- package/package.json +1 -1
package/css/00-primitives.css
CHANGED
package/css/10-semantic.css
CHANGED
|
@@ -226,8 +226,8 @@
|
|
|
226
226
|
--shadow-card: 0 8px 16px color-mix(in oklch, var(--gray-12) 8%, transparent);
|
|
227
227
|
|
|
228
228
|
/* Bakat-kompat: --shadow-float ar nu alias till --shadow-card.
|
|
229
|
-
Befintliga komponenter (
|
|
230
|
-
|
|
229
|
+
Befintliga komponenter (overlay.dialog/sheet, feedback.toast,
|
|
230
|
+
nav.bottom-nav) fortsatter funka utan andring. Migration till
|
|
231
231
|
--shadow-card per komponent kan ske gradvis. */
|
|
232
232
|
--shadow-float: var(--shadow-card);
|
|
233
233
|
|
package/css/components/chip.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* ================================================================
|
|
2
2
|
components/chip.css
|
|
3
|
-
Pills- och chips-familjen:
|
|
3
|
+
Pills- och chips-familjen: fyra fristående blocks som delar
|
|
4
4
|
form-språket (rounded-full, kompakt padding, inline-flex).
|
|
5
5
|
|
|
6
6
|
Blocks:
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
.chip-list - sibling-wrapper för chips i rad (har __item/__delete/__add)
|
|
9
9
|
.brand-pill - projekt-namn-pill i topbar
|
|
10
10
|
.month-pill - navigations-pill för månadsbyte (Ekonom)
|
|
11
|
-
.install-chip - PWA install-prompt som flyter ovan bottom-nav
|
|
12
11
|
|
|
13
12
|
HTML-relationer:
|
|
14
13
|
.chip-list innehåller .chip-list__item (egna BEM-element, ej .chip)
|
|
@@ -17,8 +16,8 @@
|
|
|
17
16
|
Modifiers:
|
|
18
17
|
.chip --accent/-positive/-negative/-warning/-faint
|
|
19
18
|
|
|
20
|
-
.install-chip
|
|
21
|
-
|
|
19
|
+
v3.13.0: .install-chip (PWA install-prompt) borttagen tillsammans
|
|
20
|
+
med tillhörande JS i pwa-register.js.
|
|
22
21
|
================================================================ */
|
|
23
22
|
.chip {
|
|
24
23
|
display: inline-flex;
|
|
@@ -206,112 +205,7 @@
|
|
|
206
205
|
}
|
|
207
206
|
|
|
208
207
|
|
|
209
|
-
/* ================================================================
|
|
210
|
-
==== INSTALL-CHIP
|
|
211
|
-
PWA install-prompt som flyter ovan bottom-nav.
|
|
212
|
-
================================================================ */
|
|
213
|
-
.install-chip {
|
|
214
|
-
position: fixed;
|
|
215
|
-
bottom: calc(84px + var(--safe-bottom));
|
|
216
|
-
left: var(--space-12);
|
|
217
|
-
right: var(--space-12);
|
|
218
|
-
max-width: 480px;
|
|
219
|
-
margin: 0 auto;
|
|
220
|
-
background: var(--surface-raised);
|
|
221
|
-
border: 1px solid var(--border-subtle);
|
|
222
|
-
border-radius: var(--radius-full);
|
|
223
|
-
padding: var(--space-10) var(--space-10) var(--space-10) var(--space-18);
|
|
224
|
-
display: flex;
|
|
225
|
-
align-items: center;
|
|
226
|
-
gap: var(--space-10);
|
|
227
|
-
font-size: var(--fs-13);
|
|
228
|
-
color: var(--text-default);
|
|
229
|
-
z-index: var(--z-overlay, 60);
|
|
230
|
-
animation: install-chip-up 0.28s var(--ease-out);
|
|
231
|
-
box-shadow: var(--shadow-float);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
.install-chip__text { flex: 1; min-width: 0; }
|
|
235
|
-
|
|
236
|
-
.install-chip__install {
|
|
237
|
-
background: var(--accent-9);
|
|
238
|
-
color: var(--text-on-accent);
|
|
239
|
-
border: none;
|
|
240
|
-
padding: var(--space-8) var(--space-14);
|
|
241
|
-
border-radius: var(--radius-full);
|
|
242
|
-
font-size: var(--fs-12);
|
|
243
|
-
font-weight: var(--fw-medium);
|
|
244
|
-
font-family: inherit;
|
|
245
|
-
cursor: pointer;
|
|
246
|
-
white-space: nowrap;
|
|
247
|
-
transition: background var(--dur-fast) var(--ease-default);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
@media (hover: hover) and (pointer: fine) {
|
|
251
|
-
.install-chip__install:hover { background: var(--accent-10); }
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
.install-chip__install:focus-visible {
|
|
255
|
-
outline: 2px solid var(--border-focus);
|
|
256
|
-
outline-offset: 2px;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
.install-chip__install:active {
|
|
260
|
-
background: var(--surface-active);
|
|
261
|
-
transform: scale(0.97);
|
|
262
|
-
transition: transform 80ms var(--ease-spring-snappy);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
.install-chip__install:disabled,
|
|
266
|
-
.install-chip__install[aria-disabled="true"] {
|
|
267
|
-
opacity: 0.5;
|
|
268
|
-
cursor: not-allowed;
|
|
269
|
-
pointer-events: none;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
.install-chip__dismiss {
|
|
273
|
-
background: transparent;
|
|
274
|
-
border: none;
|
|
275
|
-
color: var(--text-subtle);
|
|
276
|
-
font-size: var(--fs-18);
|
|
277
|
-
line-height: 1;
|
|
278
|
-
padding: var(--space-6) var(--space-10);
|
|
279
|
-
cursor: pointer;
|
|
280
|
-
min-width: 36px;
|
|
281
|
-
transition: color var(--dur-fast) var(--ease-default);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
@media (hover: hover) and (pointer: fine) {
|
|
285
|
-
.install-chip__dismiss:hover { color: var(--text-default); }
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
.install-chip__dismiss:focus-visible {
|
|
289
|
-
outline: 2px solid var(--border-focus);
|
|
290
|
-
outline-offset: 2px;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
.install-chip__dismiss:active {
|
|
294
|
-
background: var(--surface-active);
|
|
295
|
-
transform: scale(0.97);
|
|
296
|
-
transition: transform 80ms var(--ease-spring-snappy);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
.install-chip__dismiss:disabled,
|
|
300
|
-
.install-chip__dismiss[aria-disabled="true"] {
|
|
301
|
-
opacity: 0.5;
|
|
302
|
-
cursor: not-allowed;
|
|
303
|
-
pointer-events: none;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
@keyframes install-chip-up {
|
|
307
|
-
from { transform: translateY(calc(100% + 100px)); opacity: 0; }
|
|
308
|
-
to { transform: translateY(0); opacity: 1; }
|
|
309
|
-
}
|
|
310
|
-
|
|
311
208
|
@media (prefers-reduced-motion: reduce) {
|
|
312
|
-
.install-chip { animation: none; }
|
|
313
209
|
.chip-list__delete:active,
|
|
314
|
-
.chip-list__add:active
|
|
315
|
-
.install-chip__install:active,
|
|
316
|
-
.install-chip__dismiss:active { transform: none; }
|
|
210
|
+
.chip-list__add:active { transform: none; }
|
|
317
211
|
}
|
package/js/pwa-register.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
/*--------------------------------------------------------------
|
|
2
|
-
@klodd/ds - PWA-registrering
|
|
2
|
+
@klodd/ds - PWA-registrering
|
|
3
3
|
|
|
4
4
|
Auto-detekterar app-namn fran <html data-app="X">-attributet.
|
|
5
|
-
Defaults: appName = capitalize(data-app),
|
|
5
|
+
Defaults: appName = capitalize(data-app), swPath = "/sw.js".
|
|
6
6
|
Funkar identiskt for Jubb och Ekonom utan konfiguration.
|
|
7
7
|
|
|
8
|
-
Manuell override: KloddPWA.init({ appName,
|
|
8
|
+
Manuell override: KloddPWA.init({ appName, swPath }) innan load.
|
|
9
9
|
|
|
10
10
|
Funktioner:
|
|
11
11
|
- isNetworkError() - iOS-saker nat-detektering (window.isNetworkError)
|
|
12
12
|
- SW-registrering med updateViaCache: 'none'
|
|
13
|
-
|
|
14
|
-
- iOS
|
|
13
|
+
|
|
14
|
+
Install-prompts (beforeinstallprompt + iOS-hint) borttagna 3.13.0.
|
|
15
|
+
PWA-installation sker numera enbart via browserns inbyggda meny.
|
|
15
16
|
--------------------------------------------------------------*/
|
|
16
17
|
(function (root, doc) {
|
|
17
18
|
'use strict';
|
|
@@ -25,9 +26,7 @@
|
|
|
25
26
|
const cap = dataApp.charAt(0).toUpperCase() + dataApp.slice(1);
|
|
26
27
|
return {
|
|
27
28
|
appName: userCfg.appName || cap,
|
|
28
|
-
appKey: userCfg.appKey || dataApp,
|
|
29
29
|
swPath: userCfg.swPath || '/sw.js',
|
|
30
|
-
minVisits: userCfg.minVisits || 3,
|
|
31
30
|
};
|
|
32
31
|
}
|
|
33
32
|
|
|
@@ -62,94 +61,6 @@
|
|
|
62
61
|
});
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
/*------------------------------------------------------------
|
|
66
|
-
Install-prompt (Android / Chrome / Edge)
|
|
67
|
-
------------------------------------------------------------*/
|
|
68
|
-
let deferredInstallPrompt = null;
|
|
69
|
-
|
|
70
|
-
function setupInstallPrompt(cfg) {
|
|
71
|
-
root.addEventListener('beforeinstallprompt', function (e) {
|
|
72
|
-
e.preventDefault();
|
|
73
|
-
deferredInstallPrompt = e;
|
|
74
|
-
maybeShowInstallChip(cfg);
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function maybeShowInstallChip(cfg) {
|
|
79
|
-
if (sessionStorage.getItem(cfg.appKey + '_install_dismissed')) return;
|
|
80
|
-
if (root.matchMedia('(display-mode: standalone)').matches) return;
|
|
81
|
-
const visits = parseInt(localStorage.getItem(cfg.appKey + '_visits') || '0', 10) + 1;
|
|
82
|
-
localStorage.setItem(cfg.appKey + '_visits', String(visits));
|
|
83
|
-
if (visits < cfg.minVisits) return;
|
|
84
|
-
showInstallChip(cfg);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function showInstallChip(cfg) {
|
|
88
|
-
const id = cfg.appKey + '-install-chip';
|
|
89
|
-
if (doc.getElementById(id)) return;
|
|
90
|
-
|
|
91
|
-
const chip = doc.createElement('div');
|
|
92
|
-
chip.className = 'install-chip';
|
|
93
|
-
chip.id = id;
|
|
94
|
-
chip.setAttribute('role', 'dialog');
|
|
95
|
-
chip.setAttribute('aria-label', 'Installera ' + cfg.appName);
|
|
96
|
-
chip.innerHTML =
|
|
97
|
-
'<span>Installera ' + cfg.appName + ' på hemskärmen</span>' +
|
|
98
|
-
'<button type="button" data-install>Installera</button>' +
|
|
99
|
-
'<button type="button" data-dismiss aria-label="Stäng">×</button>';
|
|
100
|
-
doc.body.appendChild(chip);
|
|
101
|
-
|
|
102
|
-
chip.querySelector('[data-install]').addEventListener('click', async function () {
|
|
103
|
-
if (!deferredInstallPrompt) { chip.remove(); return; }
|
|
104
|
-
deferredInstallPrompt.prompt();
|
|
105
|
-
try { await deferredInstallPrompt.userChoice; } catch (e) {}
|
|
106
|
-
deferredInstallPrompt = null;
|
|
107
|
-
chip.remove();
|
|
108
|
-
});
|
|
109
|
-
chip.querySelector('[data-dismiss]').addEventListener('click', function () {
|
|
110
|
-
sessionStorage.setItem(cfg.appKey + '_install_dismissed', '1');
|
|
111
|
-
chip.remove();
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/*------------------------------------------------------------
|
|
116
|
-
iOS install-hint
|
|
117
|
-
Safari har ingen beforeinstallprompt - manuell flow via "Dela" ->
|
|
118
|
-
"Lagg till pa hemskarmen". Visa diskret hint efter N besok.
|
|
119
|
-
------------------------------------------------------------*/
|
|
120
|
-
function setupIOSHint(cfg) {
|
|
121
|
-
root.addEventListener('load', function () {
|
|
122
|
-
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !root.MSStream;
|
|
123
|
-
const inStandalone = root.matchMedia('(display-mode: standalone)').matches
|
|
124
|
-
|| root.navigator.standalone;
|
|
125
|
-
if (!isIOS || inStandalone) return;
|
|
126
|
-
if (sessionStorage.getItem(cfg.appKey + '_ios_install_dismissed')) return;
|
|
127
|
-
const visits = parseInt(localStorage.getItem(cfg.appKey + '_visits') || '0', 10);
|
|
128
|
-
if (visits < cfg.minVisits) return;
|
|
129
|
-
showIOSInstallHint(cfg);
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function showIOSInstallHint(cfg) {
|
|
134
|
-
const id = cfg.appKey + '-ios-install-hint';
|
|
135
|
-
if (doc.getElementById(id)) return;
|
|
136
|
-
|
|
137
|
-
const hint = doc.createElement('div');
|
|
138
|
-
hint.className = 'install-chip install-chip-ios';
|
|
139
|
-
hint.id = id;
|
|
140
|
-
hint.setAttribute('role', 'dialog');
|
|
141
|
-
hint.setAttribute('aria-label', 'Installera ' + cfg.appName + ' pa iOS');
|
|
142
|
-
hint.innerHTML =
|
|
143
|
-
'<span>Tryck <strong>Dela</strong> → <strong>Lägg till på hemskärmen</strong></span>' +
|
|
144
|
-
'<button type="button" data-dismiss aria-label="Stäng">×</button>';
|
|
145
|
-
doc.body.appendChild(hint);
|
|
146
|
-
|
|
147
|
-
hint.querySelector('[data-dismiss]').addEventListener('click', function () {
|
|
148
|
-
sessionStorage.setItem(cfg.appKey + '_ios_install_dismissed', '1');
|
|
149
|
-
hint.remove();
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
|
|
153
64
|
/*------------------------------------------------------------
|
|
154
65
|
Public API. Anvand KloddPWA.init({...}) FORE script-laddning av
|
|
155
66
|
denna fil (sa _cfg ar satt nar getCfg() koras), eller bara lat
|
|
@@ -160,6 +71,4 @@
|
|
|
160
71
|
root.KloddPWA.config = cfg;
|
|
161
72
|
|
|
162
73
|
registerSW(cfg);
|
|
163
|
-
setupInstallPrompt(cfg);
|
|
164
|
-
setupIOSHint(cfg);
|
|
165
74
|
})(typeof window !== 'undefined' ? window : globalThis, document);
|