@klodd/ds 3.15.1 → 3.16.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/components/nav.css +15 -0
- package/css/components/pill-nav.css +102 -0
- package/css/index.css +1 -0
- package/package.json +1 -1
- package/references/02-components.md +23 -2
- package/references/DESIGN-LANGUAGE.md +57 -0
package/css/components/nav.css
CHANGED
|
@@ -113,6 +113,14 @@
|
|
|
113
113
|
/* ================================================================
|
|
114
114
|
==== TOPBAR (in-flow header)
|
|
115
115
|
Tre slots: back-knapp / titel / action. Display flex, full bredd.
|
|
116
|
+
|
|
117
|
+
Layout-doktrin (2026-05-12):
|
|
118
|
+
- Avatar (.avatar) ar ALLTID hogerstalld via margin-left: auto.
|
|
119
|
+
- Gor month-pill, brand-pill, topbar__logo eller back-knapp pa
|
|
120
|
+
vanster sida automatiskt vanster-positionerade.
|
|
121
|
+
- Galler aven nar avatar ar wrappad i <a href> for navigation.
|
|
122
|
+
- Doktrin gemensam for alla Klodd-appar (Ekonom, Jubb, framtida).
|
|
123
|
+
Se DESIGN-LANGUAGE.md sektion 13.
|
|
116
124
|
================================================================ */
|
|
117
125
|
.topbar {
|
|
118
126
|
display: flex;
|
|
@@ -123,6 +131,13 @@
|
|
|
123
131
|
margin-bottom: var(--space-16);
|
|
124
132
|
}
|
|
125
133
|
|
|
134
|
+
/* Avatar alltid hogerstalld. Galler bade direkt <.avatar> och
|
|
135
|
+
wrapped <a href="/profil"><span class="avatar"></span></a>. */
|
|
136
|
+
.topbar > .avatar,
|
|
137
|
+
.topbar > a:has(> .avatar) {
|
|
138
|
+
margin-left: auto;
|
|
139
|
+
}
|
|
140
|
+
|
|
126
141
|
.topbar__back {
|
|
127
142
|
display: inline-flex;
|
|
128
143
|
align-items: center;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/* ================================================================
|
|
2
|
+
components/pill-nav.css
|
|
3
|
+
Horizontal scrollbar pill-navigation. Anvands for filter/status-
|
|
4
|
+
val nar tab-bar (segmented control) blir for trang.
|
|
5
|
+
|
|
6
|
+
Patterns:
|
|
7
|
+
- 4+ filter-options som inte far plats pa skarmen
|
|
8
|
+
- Status-filter, kategori-filter, datum-filter
|
|
9
|
+
- iOS App Store / Netflix / Spotify-stil chip-row
|
|
10
|
+
|
|
11
|
+
Skiljer sig fran .tab-bar (segmented control):
|
|
12
|
+
- .tab-bar: fixed bredd, items delar plats lika (flex: 1)
|
|
13
|
+
- .pill-nav: variable bredd, items scrollar horizontellt
|
|
14
|
+
|
|
15
|
+
Blocks:
|
|
16
|
+
.pill-nav - <nav>-wrapper med horizontal scroll
|
|
17
|
+
.pill-nav__item - individuell pill (a, button)
|
|
18
|
+
|
|
19
|
+
States:
|
|
20
|
+
.pill-nav__item.is-active - aktiv-state (accent-bg + on-accent-text)
|
|
21
|
+
|
|
22
|
+
Layout:
|
|
23
|
+
- Item-hojd 36px (matchar .avatar default + .month-pill)
|
|
24
|
+
- Border-radius: full (pill-form)
|
|
25
|
+
- Negative margin LR = main-padding for scroll-area edge-to-edge
|
|
26
|
+
================================================================ */
|
|
27
|
+
.pill-nav {
|
|
28
|
+
display: flex;
|
|
29
|
+
gap: var(--space-8);
|
|
30
|
+
margin: 0 0 var(--space-16);
|
|
31
|
+
/* Edge-to-edge scroll: extender utanfor main-padding (14) sa
|
|
32
|
+
forsta/sista pill kan scrollas in i bild. Sidan i sig
|
|
33
|
+
ska inte scrolla horizontellt - bara pill-nav-en. */
|
|
34
|
+
margin-left: calc(-1 * var(--space-14));
|
|
35
|
+
margin-right: calc(-1 * var(--space-14));
|
|
36
|
+
padding: var(--space-2) var(--space-14);
|
|
37
|
+
overflow-x: auto;
|
|
38
|
+
overflow-y: hidden;
|
|
39
|
+
scrollbar-width: none;
|
|
40
|
+
-webkit-overflow-scrolling: touch;
|
|
41
|
+
scroll-behavior: smooth;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.pill-nav::-webkit-scrollbar {
|
|
45
|
+
display: none;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.pill-nav__item {
|
|
49
|
+
display: inline-flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
justify-content: center;
|
|
52
|
+
height: 36px;
|
|
53
|
+
padding: 0 var(--space-16);
|
|
54
|
+
background: var(--surface-default);
|
|
55
|
+
border: 1px solid var(--border-subtle);
|
|
56
|
+
border-radius: var(--radius-full);
|
|
57
|
+
color: var(--text-subtle);
|
|
58
|
+
font-family: inherit;
|
|
59
|
+
font-size: var(--fs-13);
|
|
60
|
+
font-weight: var(--fw-medium);
|
|
61
|
+
text-decoration: none;
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
flex-shrink: 0;
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
-webkit-tap-highlight-color: transparent;
|
|
66
|
+
touch-action: manipulation;
|
|
67
|
+
transition:
|
|
68
|
+
background var(--dur-fast) var(--ease-spring-snappy),
|
|
69
|
+
color var(--dur-fast) var(--ease-spring-snappy),
|
|
70
|
+
border-color var(--dur-fast) var(--ease-spring-snappy);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.pill-nav__item.is-active {
|
|
74
|
+
background: var(--accent-9);
|
|
75
|
+
border-color: var(--accent-9);
|
|
76
|
+
color: var(--text-on-accent);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@media (hover: hover) and (pointer: fine) {
|
|
80
|
+
.pill-nav__item:not(.is-active):hover {
|
|
81
|
+
background: var(--surface-hover);
|
|
82
|
+
color: var(--text-default);
|
|
83
|
+
border-color: var(--border-default);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.pill-nav__item:active:not(.is-active) {
|
|
88
|
+
transform: scale(0.97);
|
|
89
|
+
transition: transform 80ms var(--ease-spring-snappy);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.pill-nav__item:focus-visible {
|
|
93
|
+
outline: 2px solid var(--border-focus);
|
|
94
|
+
outline-offset: 2px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.pill-nav__item:disabled,
|
|
98
|
+
.pill-nav__item[aria-disabled="true"] {
|
|
99
|
+
opacity: 0.5;
|
|
100
|
+
cursor: not-allowed;
|
|
101
|
+
pointer-events: none;
|
|
102
|
+
}
|
package/css/index.css
CHANGED
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
@import './components/inline-edit.css';
|
|
59
59
|
@import './components/upload-spinner.css';
|
|
60
60
|
@import './components/tab-bar.css';
|
|
61
|
+
@import './components/pill-nav.css';
|
|
61
62
|
|
|
62
63
|
/* v3.1.0 - generic kategori-monster (token-binding via app-domain-CSS) */
|
|
63
64
|
@import './components/colored-row.css';
|
package/package.json
CHANGED
|
@@ -250,10 +250,31 @@ För varje entry gäller:
|
|
|
250
250
|
- **Blocks:** `.tab-bar` (definieras aven i `nav.css` med 5 identiska properties + skillnad i margin)
|
|
251
251
|
- **Element:** `.tab-bar__item`
|
|
252
252
|
- **States:** `.tab-bar__item.is-active`
|
|
253
|
-
- **Anvand:** Inline
|
|
254
|
-
|
|
253
|
+
- **Anvand:** Inline segmented control for format-val med 2-3 alternativ
|
|
254
|
+
som alla far plats utan scroll - t.ex. CSV/Avi. Items har `flex: 1`
|
|
255
|
+
(lika bredd), 44px touch-target.
|
|
256
|
+
- **INTE:** Filter-listor med 4+ items (anvand `.pill-nav` istallet).
|
|
257
|
+
Bottom-nav (anvand `.bottom-nav`).
|
|
255
258
|
- **Special:** Importordning i `index.css`: `nav.css` fore `tab-bar.css`. `.tab-bar`-block-styling fran tab-bar.css vinner via cascade.
|
|
256
259
|
|
|
260
|
+
### pill-nav (`pill-nav.css`) - v3.16.0
|
|
261
|
+
- **Blocks:** `.pill-nav` (horizontal scroll-container)
|
|
262
|
+
- **Element:** `.pill-nav__item`
|
|
263
|
+
- **States:** `.pill-nav__item.is-active` (accent-bg + on-accent-text)
|
|
264
|
+
- **Anvand:** Horizontal scrollbar filter-pills nar 4+ alternativ inte
|
|
265
|
+
far plats pa skarmen. iOS App Store / Netflix-stil chip-row. Pill-
|
|
266
|
+
hojd 36px (matchar .avatar default + .month-pill). Items har
|
|
267
|
+
variable bredd, scrollar horizontellt med touch/swipe.
|
|
268
|
+
- **INTE:** Segmented control 2-3 items (anvand `.tab-bar`). Permanent
|
|
269
|
+
bottom-nav (anvand `.bottom-nav`).
|
|
270
|
+
- **Tokens:** `--surface-default` + `--border-subtle` (default state),
|
|
271
|
+
`--accent-9` + `--text-on-accent` (active), `--radius-full`,
|
|
272
|
+
`--fs-13`, height 36px.
|
|
273
|
+
- **Special:** `.pill-nav` har negativa LR-marginer (-14px) for att
|
|
274
|
+
scroll-area ska natta kant-till-kant pa mobile - sidan i sig
|
|
275
|
+
scrollar inte horizontellt, bara pill-nav-en. Scrollbar dold via
|
|
276
|
+
`scrollbar-width: none` + `::-webkit-scrollbar { display: none }`.
|
|
277
|
+
|
|
257
278
|
### colored-row (`colored-row.css`) - v3.1.0
|
|
258
279
|
- **Blocks:** `.colored-row`
|
|
259
280
|
- **Modifiers:** `.colored-row--sm`, `.colored-row--lg`
|
|
@@ -294,6 +294,63 @@ Future custom stylelint-plugin kan enforce:
|
|
|
294
294
|
Tills sådan plugin finns: visual-coherence är CC-disciplin baserat
|
|
295
295
|
på denna fil.
|
|
296
296
|
|
|
297
|
+
## 13. Topbar-layout-doktrin (alla appar)
|
|
298
|
+
|
|
299
|
+
**Regel:** topbar-elementen positioneras enligt strikt mall:
|
|
300
|
+
|
|
301
|
+
| Position | Element | Användning |
|
|
302
|
+
|---|---|---|
|
|
303
|
+
| Vänster | `.month-pill`, `.brand-pill`, `.topbar__logo`, `.topbar__back` | Kontext/navigation per vy |
|
|
304
|
+
| Höger | `.avatar` (ev. wrappad i `<a href="/jag">`) | Persistent profil-länk |
|
|
305
|
+
|
|
306
|
+
**CSS-implementation** (paketets `nav.css`):
|
|
307
|
+
|
|
308
|
+
```css
|
|
309
|
+
.topbar > .avatar,
|
|
310
|
+
.topbar > a:has(> .avatar) {
|
|
311
|
+
margin-left: auto;
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Avatar pushas automatiskt högerställd. Övriga element grupperas
|
|
316
|
+
vänster med `gap: var(--space-12)`.
|
|
317
|
+
|
|
318
|
+
**HTML-pattern:**
|
|
319
|
+
|
|
320
|
+
```html
|
|
321
|
+
<!-- Standard topbar med kontext + avatar -->
|
|
322
|
+
<div class="topbar">
|
|
323
|
+
<span class="brand-pill">Jubb</span> <!-- vänster -->
|
|
324
|
+
<a href="/jag"><span class="avatar">CE</span></a> <!-- höger -->
|
|
325
|
+
</div>
|
|
326
|
+
|
|
327
|
+
<!-- Topbar med back-knapp + avatar -->
|
|
328
|
+
<div class="topbar">
|
|
329
|
+
<a href="/jobb" class="topbar__back">←</a> <!-- vänster -->
|
|
330
|
+
<span class="topbar__logo">Jobbdetalj</span> <!-- center-ish -->
|
|
331
|
+
<a href="/jag"><span class="avatar">CE</span></a> <!-- höger -->
|
|
332
|
+
</div>
|
|
333
|
+
|
|
334
|
+
<!-- Topbar utan avatar (back-only-vyer som /installningar/X) -->
|
|
335
|
+
<div class="topbar">
|
|
336
|
+
<a href="/installningar" class="topbar__back">←</a>
|
|
337
|
+
<span class="topbar__logo">Vart hushall</span>
|
|
338
|
+
</div>
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**Förbjudet:**
|
|
342
|
+
- Avatar någon annanstans än i topbar
|
|
343
|
+
- Två avatar-element i samma topbar
|
|
344
|
+
- Manual flexbox-positioning som strider mot auto-margin-pattern
|
|
345
|
+
- Hardkodad `margin-left: auto` på avatar i app-domain-CSS (paketet
|
|
346
|
+
hanterar det)
|
|
347
|
+
|
|
348
|
+
**Konsekvens:** alla Klodd-appar (Ekonom, Jubb, framtida) får identisk
|
|
349
|
+
topbar-layout. Användaren får visuell anchor: "avatar = mitt konto =
|
|
350
|
+
alltid uppe höger".
|
|
351
|
+
|
|
352
|
+
**Etablerad 2026-05-12.** Lagt till paketets nav.css i samma commit.
|
|
353
|
+
|
|
297
354
|
## 12. När ändra regler
|
|
298
355
|
|
|
299
356
|
Denna fil är **locked**. Ändringar kräver:
|