@klodd/ds 5.2.2 → 5.2.4
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/components/hero.css
CHANGED
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
sentence-case i template ("Din dagsbudget", inte "DIN DAGSBUDGET").
|
|
46
46
|
Det matchar svensk grafisk konvention + var hero-hierarki kommer
|
|
47
47
|
fran font-size och weight, inte fran caps. */
|
|
48
|
-
font-size: var(--fs-
|
|
48
|
+
font-size: var(--fs-16);
|
|
49
49
|
font-weight: var(--fw-medium);
|
|
50
|
-
color: var(--text-
|
|
50
|
+
color: var(--text-subtle);
|
|
51
51
|
letter-spacing: var(--ls-tight);
|
|
52
52
|
margin: 0 0 var(--space-12);
|
|
53
53
|
}
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
|
|
107
107
|
.hero__meta {
|
|
108
108
|
font-size: var(--fs-13);
|
|
109
|
-
color: var(--text-
|
|
109
|
+
color: var(--text-muted);
|
|
110
110
|
margin: 0 0 var(--space-20);
|
|
111
111
|
}
|
|
112
112
|
|
|
@@ -57,6 +57,25 @@ dialog.sheet::backdrop {
|
|
|
57
57
|
inset: auto;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/* Native <dialog class="dialog"> via showModal() far :modal-pseudo-class
|
|
61
|
+
som triggar UA-stylesheet med high-specificity inset:0 + margin:auto.
|
|
62
|
+
Den vinner over .dialog's transform-baserade centrering ovan (UA
|
|
63
|
+
regel ar 0,1,1 mot .dialog 0,1,0) sa transform forsvinner men
|
|
64
|
+
inset:0 + margin:auto inte appliceras pa rad sa elementet hamnar
|
|
65
|
+
i top-left. Fix: matcha UA's metod med dialog.dialog:modal-selectorn
|
|
66
|
+
(specificity 0,2,1) som vinner. inset:0 + margin:auto ar native-
|
|
67
|
+
metoden for dialog-centrering per MDN 2024+.
|
|
68
|
+
.dialog-regeln ovanfor bevaras for icke-modal <div role="dialog">-
|
|
69
|
+
anvandning som inte triggrar :modal. Verifierat Jubb v192
|
|
70
|
+
(2026-05-19) - se ADR 0009-turbo-nav-script-init.md for
|
|
71
|
+
diagnos-spar via Chrome MCP. */
|
|
72
|
+
dialog.dialog:modal {
|
|
73
|
+
position: fixed;
|
|
74
|
+
inset: 0;
|
|
75
|
+
margin: auto;
|
|
76
|
+
transform: none;
|
|
77
|
+
}
|
|
78
|
+
|
|
60
79
|
.dialog__header {
|
|
61
80
|
display: flex;
|
|
62
81
|
align-items: center;
|
package/package.json
CHANGED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# 0009 - Per-page-JS-init under turbo-nav
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Locked. Upptäckt v192 (2026-05-19) under Chrome MCP-diagnos av
|
|
6
|
+
brief-progress-flödet i Jubb.
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
`turbo-nav.js` (paketet) implementerar same-document-navigation
|
|
11
|
+
istället för full document-load. Vid klick på en intern länk:
|
|
12
|
+
|
|
13
|
+
1. Fetchar måldokumentets HTML
|
|
14
|
+
2. Swappar **bara `<main id="main">` + `<title>` + body-data-attribut**
|
|
15
|
+
3. Behåller resten av `<body>` oförändrad mellan sidor (bottom-nav,
|
|
16
|
+
pwa-overlay, scripts efter `</main>` etc)
|
|
17
|
+
|
|
18
|
+
Den arkitekturen är dokumenterad i JSDoc-header av `turbo-nav.js`
|
|
19
|
+
("Vad vi swappar"). Den ger snabbare upplevd navigation + bevarar
|
|
20
|
+
JS-state som inte är page-specifik.
|
|
21
|
+
|
|
22
|
+
**Konsekvens som inte var explicit dokumenterad innan denna ADR:**
|
|
23
|
+
Scripts som ligger i Jinja-mönstret `{% block scripts %}` (typiskt
|
|
24
|
+
placerat efter `</main>` i base.html, paritet med shadcn/Rails-
|
|
25
|
+
turbo-konventionen) re-exekveras **aldrig** efter turbo-swap. Block
|
|
26
|
+
scripts är utanför swap-region. Vid initial full-load körs blocket
|
|
27
|
+
en gång på den första sidan; om den sidan inte har scripten är
|
|
28
|
+
tagget tom; vid senare turbo-nav till en sida som DEFINIERAR `{%
|
|
29
|
+
block scripts %}` med en script-tag, swappas bara `<main>`-content
|
|
30
|
+
och scripten visas aldrig i körd DOM.
|
|
31
|
+
|
|
32
|
+
Symptom (Jubb 2026-05-19):
|
|
33
|
+
|
|
34
|
+
- `brief-progress.js` lades i `{% block scripts %}` i `job_detail.html`
|
|
35
|
+
efter att en tidigare diagnos felaktigt identifierat
|
|
36
|
+
`<main>`-position som rotorsak
|
|
37
|
+
- v191 deploy
|
|
38
|
+
- Calle navigerade till `/jobb/X` via klick från `/jobb-listan` (turbo)
|
|
39
|
+
- `window.JubbBriefProgress` förblev `undefined` på destination-sidan
|
|
40
|
+
- Diagnos via Chrome MCP: Performance API visade ingen
|
|
41
|
+
`initiatorType: "script"`-entry för brief-progress.js. Filen
|
|
42
|
+
hämtades aldrig som script. Block scripts var utanför swap-region
|
|
43
|
+
|
|
44
|
+
## Decision
|
|
45
|
+
|
|
46
|
+
**Per-page-JS som behöver re-init på navigation skall laddas globalt
|
|
47
|
+
i base.html, inte via `{% block scripts %}`.** Globalt laddat script
|
|
48
|
+
exekveras en gång vid full-reload och förblir tillgängligt över alla
|
|
49
|
+
turbo-swaps. Per-page-init görs genom att lyssna på
|
|
50
|
+
`turbo:navigated`-event:
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<!-- base.html, efter alla andra defer-scripts, före {% block scripts %}: -->
|
|
54
|
+
<script src="/static/js/per-page-feature.js?v={{ static_version }}" defer></script>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
// per-page-feature.js
|
|
59
|
+
(function () {
|
|
60
|
+
function maybeInit() {
|
|
61
|
+
// Defensive: kör bara om relevant DOM-element finns på nuvarande sida.
|
|
62
|
+
const root = document.getElementById("feature-root");
|
|
63
|
+
if (!root) return;
|
|
64
|
+
// ... init-logik (idempotent) ...
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Initial-load
|
|
68
|
+
if (document.readyState === "loading") {
|
|
69
|
+
document.addEventListener("DOMContentLoaded", maybeInit);
|
|
70
|
+
} else {
|
|
71
|
+
maybeInit();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Turbo-aware re-init vid varje same-document-swap
|
|
75
|
+
document.addEventListener("turbo:navigated", maybeInit);
|
|
76
|
+
})();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Krav på det globala scriptet
|
|
80
|
+
|
|
81
|
+
1. **Idempotent init.** Eftersom `maybeInit` körs en gång vid
|
|
82
|
+
initial-load och en gång per turbo:navigated, måste den vara
|
|
83
|
+
safe att köra flera gånger utan side-effects (dubbla handlers,
|
|
84
|
+
dubbla pollers, etc).
|
|
85
|
+
2. **Defensive DOM-checks.** Scriptet exekveras på alla sidor (inkl.
|
|
86
|
+
sidor som inte använder featuren). Init-logik måste kolla att
|
|
87
|
+
relevant DOM-element finns innan den agerar.
|
|
88
|
+
3. **Document-level event-delegation för clicks.** addEventListener
|
|
89
|
+
på elements som swappas av Turbo försvinner med swap (gamla
|
|
90
|
+
elementet GC:as). Använd antingen document-level delegation
|
|
91
|
+
(single global listener som filtrerar på event.target.id/class)
|
|
92
|
+
eller re-registrera handlers i maybeInit.
|
|
93
|
+
|
|
94
|
+
### Förbjudet mönster
|
|
95
|
+
|
|
96
|
+
```jinja2
|
|
97
|
+
{# job_detail.html - DETTA FUNGERAR INTE under Turbo #}
|
|
98
|
+
{% block scripts %}
|
|
99
|
+
<script src="/static/js/per-page-feature.js?v={{ static_version }}" defer></script>
|
|
100
|
+
{% endblock %}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`{% block scripts %}` är användbart för att lägga in **markup**
|
|
104
|
+
(t.ex. en `<noscript>` eller en page-specifik `<meta>`-tag) i base.html-
|
|
105
|
+
strukturen, men för scripts måste path:en gå genom base.html.
|
|
106
|
+
|
|
107
|
+
## Undantag - data-turbo="false"
|
|
108
|
+
|
|
109
|
+
Sidor vars länkar har `data-turbo="false"` är utanför Turbo-scopet
|
|
110
|
+
och får full document-reload. Per-page-scripts inom `<main>` kan
|
|
111
|
+
användas för sådana sidor eftersom hela dokumentet laddas om vid
|
|
112
|
+
navigation.
|
|
113
|
+
|
|
114
|
+
Triage-vyn i Jubb är det enda kända undantaget i klodd-ds-portfolion
|
|
115
|
+
(2026-05-19). Triage-länken har `data-turbo="false"` per
|
|
116
|
+
`partials/_bottom_nav.html` eftersom triage-vyn har komplexa
|
|
117
|
+
per-page-scripts (swipe-cards, decision-overlays) som inte tål
|
|
118
|
+
re-init via turbo:navigated på den volymen.
|
|
119
|
+
|
|
120
|
+
Nya per-page-scripts ska DEFAULT följa det globalt-laddade-med-
|
|
121
|
+
turbo:navigated-mönstret. Disable Turbo bara om det finns en
|
|
122
|
+
dokumenterad anledning att inte göra det.
|
|
123
|
+
|
|
124
|
+
## Consequences
|
|
125
|
+
|
|
126
|
+
- Alla per-page-JS som behöver init på `/jobb/X`, `/insikter`,
|
|
127
|
+
`/körningar` etc måste flyttas till global laddning i base.html
|
|
128
|
+
om de inte redan är där. Dokumentera med JSDoc-header som
|
|
129
|
+
refererar till denna ADR.
|
|
130
|
+
- `{% block scripts %}` i base.html bevaras för markup-injection
|
|
131
|
+
(t.ex. `<script type="application/ld+json">` med page-specifik
|
|
132
|
+
data) men inte för script-src-tags.
|
|
133
|
+
- Future audit: scanna app/templates/ för `{% block scripts %}`
|
|
134
|
+
med `<script src="...">`-mönster och migrera dem.
|
|
135
|
+
- I Jubb (2026-05-19): `brief-progress.js` migrerad till global
|
|
136
|
+
laddning per denna ADR. Inga andra per-page-scripts identifierade
|
|
137
|
+
som drabbade.
|
|
138
|
+
|
|
139
|
+
## Diagnos-spår för framtida förebyggning
|
|
140
|
+
|
|
141
|
+
Chrome DevTools Performance API var nyckeln till diagnos:
|
|
142
|
+
`performance.getEntriesByType('resource')` filtrerad på
|
|
143
|
+
`initiatorType` visar exakt hur en resurs laddades. Saknas
|
|
144
|
+
`initiatorType: "script"`-entry för en `<script src>`-tag som
|
|
145
|
+
syns i DOM, är scriptet aldrig exekverat. Möjliga orsaker
|
|
146
|
+
inkluderar block-scripts efter turbo-swap, CSP-block, eller MIME-
|
|
147
|
+
type-fel. Performance API är trusted-truth - DOM-inspection ensam
|
|
148
|
+
räcker inte.
|