@oslokommune/punkt-css 16.16.0 → 16.17.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.
@@ -6,7 +6,7 @@
6
6
  @forward 'spacing';
7
7
 
8
8
  // Default icon path
9
- $icon-path: 'https://punkt-cdn.oslo.kommune.no/16.16/icons' !default;
9
+ $icon-path: 'https://punkt-cdn.oslo.kommune.no/16.17/icons' !default;
10
10
 
11
11
  // Borders
12
12
  $border-width: (
@@ -219,6 +219,69 @@ pkt-accordion[compact] {
219
219
  @include pkt-accordion-item-compact-content;
220
220
  }
221
221
  }
222
+
223
+ // "plus-minus" skin
224
+ //
225
+ // Minimal-chrome accordion used in dense surfaces like the global mega
226
+ // menu. The chevron is replaced with a plus icon when collapsed and a
227
+ // minus icon when expanded — both icons live in the DOM so the swap is
228
+ // purely CSS, no JS state needed.
229
+ .pkt-accordion--plus-minus,
230
+ pkt-accordion[skin='plus-minus'] {
231
+ row-gap: 0;
232
+ }
233
+
234
+ .pkt-accordion-item--plus-minus,
235
+ pkt-accordion-item[skin='plus-minus'] > .pkt-accordion-item {
236
+ background-color: transparent;
237
+ border: none;
238
+ padding: 0;
239
+
240
+ > .pkt-accordion-item__title {
241
+ padding: map.get(variables.$spacing, 'size-8') map.get(variables.$spacing, 'size-16');
242
+ justify-content: flex-start;
243
+
244
+ &:hover {
245
+ text-decoration: underline;
246
+
247
+ .pkt-accordion-item__icon {
248
+ transform: none;
249
+ }
250
+ }
251
+ }
252
+
253
+ > .pkt-accordion-item__content {
254
+ padding: map.get(variables.$spacing, 'size-16');
255
+ background-color: var(--pkt-color-brand-neutrals-200);
256
+ }
257
+
258
+ .pkt-accordion-item__icon--plus,
259
+ .pkt-accordion-item__icon--minus {
260
+ transition: none;
261
+ transform: none;
262
+ }
263
+
264
+ // Default (closed): show plus, hide minus.
265
+ .pkt-accordion-item__icon--minus {
266
+ display: none;
267
+ }
268
+
269
+ // Open: hide plus, show minus.
270
+ &[open] {
271
+ > .pkt-accordion-item__title {
272
+ .pkt-accordion-item__icon--plus {
273
+ display: none;
274
+ }
275
+ .pkt-accordion-item__icon--minus {
276
+ display: inline-flex;
277
+ transform: none;
278
+ }
279
+ &:hover .pkt-accordion-item__icon--minus {
280
+ transform: none;
281
+ }
282
+ }
283
+ }
284
+ }
222
285
  .pkt-accordion-item[open] {
223
286
  @supports (interpolate-size: allow-keywords) {
224
287
  &::details-content {
@@ -0,0 +1,295 @@
1
+ /*
2
+ * Header menu (global mega menu)
3
+ */
4
+
5
+ @use 'sass:map';
6
+ @use '../abstracts/variables';
7
+ @use '../abstracts/mixins/breakpoints' as *;
8
+ @use '../abstracts/mixins/typography';
9
+
10
+ $pkt-header-menu-breakpoint: 48rem;
11
+
12
+ @mixin pkt-header-menu-region-inner {
13
+ max-width: 75.25rem;
14
+ margin: 0 auto;
15
+ padding-top: map.get(variables.$spacing, 'size-32');
16
+ padding-bottom: map.get(variables.$spacing, 'size-16');
17
+
18
+ @include bp('tablet-up') {
19
+ padding: map.get(variables.$spacing, 'size-52');
20
+ }
21
+ }
22
+
23
+ .pkt-header-menu {
24
+ display: none;
25
+ background-color: var(--pkt-color-background-default);
26
+ color: var(--pkt-color-text-body-default);
27
+ width: 100%;
28
+ padding-bottom: map.get(variables.$spacing, 'size-32');
29
+
30
+ @include bp('tablet-up') {
31
+ padding-bottom: 0;
32
+ }
33
+
34
+ &--open {
35
+ display: block;
36
+ }
37
+
38
+ &__services {
39
+ @include pkt-header-menu-region-inner;
40
+ }
41
+
42
+ &__services-title,
43
+ &__section-title {
44
+ @include typography.get-text('pkt-txt-20-medium');
45
+ margin: 0 0 map.get(variables.$spacing, 'size-32');
46
+ display: none;
47
+
48
+ @include bp('tablet-up') {
49
+ display: block;
50
+ }
51
+
52
+ @include bp('tablet-big-up') {
53
+ @include typography.get-text('pkt-txt-22-medium');
54
+ }
55
+ }
56
+
57
+ &__services-title {
58
+ margin-bottom: map.get(variables.$spacing, 'size-32');
59
+ }
60
+
61
+ &__services-list {
62
+ list-style: none;
63
+ margin: 0;
64
+ padding: 0;
65
+ display: grid;
66
+ grid-template-columns: 1fr;
67
+ gap: map.get(variables.$spacing, 'size-20');
68
+
69
+ @include bp('tablet-up') {
70
+ grid-template-columns: repeat(4, 1fr);
71
+ row-gap: map.get(variables.$spacing, 'size-40');
72
+ }
73
+ }
74
+
75
+ &__buttons {
76
+ display: none;
77
+
78
+ @include pkt-header-menu-region-inner;
79
+ @include bp('tablet-up') {
80
+ display: flex;
81
+ gap: map.get(variables.$spacing, 'size-16');
82
+ flex-wrap: wrap;
83
+ padding-top: 0;
84
+ }
85
+
86
+ // Step the button label up at the same breakpoint as the link text.
87
+ @include bp('tablet-big-up') {
88
+ .pkt-btn__text {
89
+ @include typography.get-text('pkt-txt-18-medium');
90
+ }
91
+ }
92
+ }
93
+
94
+ &__buttons--mobile {
95
+ padding: 0 map.get(variables.$spacing, 'size-16');
96
+ display: flex;
97
+
98
+ @include bp('tablet-up') {
99
+ display: none;
100
+ }
101
+ }
102
+
103
+ &__sections {
104
+ @include bp('tablet-up') {
105
+ background-color: var(--pkt-color-surface-strong-gray);
106
+ [data-mode='dark'] & {
107
+ background-color: var(--pkt-color-background-default);
108
+ }
109
+ }
110
+ }
111
+
112
+ &__sections-inner {
113
+ @include pkt-header-menu-region-inner;
114
+
115
+ @include bp('tablet-up') {
116
+ display: grid;
117
+ grid-template-columns: repeat(4, 1fr);
118
+ gap: map.get(variables.$spacing, 'size-32');
119
+ }
120
+ }
121
+
122
+ &__section {
123
+ @include bp('mobile-to-tablet') {
124
+ .pkt-accordion-item__title {
125
+ @include typography.get-text('pkt-txt-18-medium');
126
+ padding: map.get(variables.$spacing, 'size-16') 0;
127
+ }
128
+ }
129
+ }
130
+
131
+ &__section-list {
132
+ list-style: none;
133
+ margin: 0;
134
+ padding: 0;
135
+ display: flex;
136
+ flex-direction: column;
137
+ gap: map.get(variables.$spacing, 'size-16');
138
+ @include bp('tablet-up') {
139
+ row-gap: map.get(variables.$spacing, 'size-16');
140
+ }
141
+ }
142
+
143
+ &__section-link {
144
+ display: block;
145
+ @include typography.get-text('pkt-txt-16-light');
146
+ color: var(--pkt-color-text-body-default);
147
+ text-decoration: underline;
148
+ text-underline-position: from-font;
149
+ line-height: 1.5;
150
+
151
+ @include bp('tablet-big-up') {
152
+ @include typography.get-text('pkt-txt-18-light');
153
+ }
154
+
155
+ &:hover,
156
+ &:focus-visible {
157
+ text-decoration: underline;
158
+ }
159
+ }
160
+
161
+ &__service {
162
+ list-style: none;
163
+ }
164
+
165
+ &__service-link {
166
+ display: flex;
167
+ align-items: center;
168
+ gap: map.get(variables.$spacing, 'size-12');
169
+ color: var(--pkt-color-text-body-default);
170
+ text-decoration: none;
171
+
172
+ @include typography.get-text('pkt-txt-16-light');
173
+
174
+ @include bp('tablet-big-up') {
175
+ @include typography.get-text('pkt-txt-18-light');
176
+ }
177
+
178
+ &:hover,
179
+ &:focus-visible {
180
+ .pkt-header-menu__service-text {
181
+ text-decoration: underline;
182
+ text-underline-position: from-font;
183
+ }
184
+ }
185
+ }
186
+
187
+ &__service-icon {
188
+ flex: 0 0 auto;
189
+ --fg-color: var(--pkt-color-text-body-default);
190
+ width: map.get(variables.$spacing, 'size-24');
191
+ height: map.get(variables.$spacing, 'size-24');
192
+
193
+ @include bp('tablet-up') {
194
+ width: map.get(variables.$spacing, 'size-32');
195
+ height: map.get(variables.$spacing, 'size-32');
196
+ }
197
+
198
+ svg {
199
+ width: 100%;
200
+ height: 100%;
201
+ }
202
+ }
203
+
204
+ &__service-text {
205
+ min-width: 0;
206
+ }
207
+
208
+ &__footer {
209
+ @include pkt-header-menu-region-inner;
210
+ padding: map.get(variables.$spacing, 'size-24') map.get(variables.$spacing, 'size-16')
211
+ map.get(variables.$spacing, 'size-16');
212
+ display: flex;
213
+ flex-direction: column;
214
+ gap: map.get(variables.$spacing, 'size-24');
215
+
216
+ @include bp('tablet-up') {
217
+ flex-direction: row;
218
+ justify-content: space-between;
219
+ align-items: center;
220
+ padding: map.get(variables.$spacing, 'size-32') map.get(variables.$spacing, 'size-52');
221
+ }
222
+ }
223
+
224
+ &__footer-list {
225
+ list-style: none;
226
+ margin: 0;
227
+ padding: 0;
228
+ display: flex;
229
+ flex-direction: column;
230
+ gap: map.get(variables.$spacing, 'size-12');
231
+
232
+ @include bp('tablet-up') {
233
+ flex-direction: row;
234
+ gap: map.get(variables.$spacing, 'size-0');
235
+ &:not(.pkt-header-menu__footer-list--social) {
236
+ line-height: 1;
237
+ > * {
238
+ border-right: 1px solid currentColor;
239
+ padding: 0 map.get(variables.$spacing, 'size-32');
240
+ &:first-child {
241
+ padding-left: 0;
242
+ }
243
+ &:last-child {
244
+ border-right: none;
245
+ padding-right: 0;
246
+ }
247
+ }
248
+ }
249
+ }
250
+ }
251
+
252
+ &__footer-list--social {
253
+ flex-direction: row;
254
+ gap: map.get(variables.$spacing, 'size-16');
255
+
256
+ @include bp('tablet-up') {
257
+ gap: map.get(variables.$spacing, 'size-32');
258
+ }
259
+ }
260
+
261
+ &__footer-link {
262
+ @include typography.get-text('pkt-txt-16-light');
263
+ color: var(--pkt-color-text-body-default);
264
+ text-decoration: none;
265
+
266
+ @include bp('tablet-big-up') {
267
+ @include typography.get-text('pkt-txt-18-light');
268
+ }
269
+
270
+ &:hover,
271
+ &:focus-visible {
272
+ text-decoration: underline;
273
+ text-underline-position: from-font;
274
+ }
275
+ }
276
+
277
+ &__social-link {
278
+ --fg-color: var(--pkt-color-text-body-default);
279
+ color: var(--pkt-color-text-body-default);
280
+ display: inline-flex;
281
+ align-items: center;
282
+
283
+ svg {
284
+ width: map.get(variables.$spacing, 'size-32');
285
+ height: map.get(variables.$spacing, 'size-32');
286
+ }
287
+ }
288
+
289
+ &__loading,
290
+ &__error {
291
+ @include pkt-header-menu-region-inner;
292
+ text-align: center;
293
+ color: var(--pkt-color-text-body-default);
294
+ }
295
+ }
@@ -1,74 +1,71 @@
1
1
  /*
2
2
  * HeaderService component
3
- * Uses container queries with media query fallback for responsive behavior
3
+ *
4
+ * Layout breakpoints are driven by the `mobileBreakpoint` /
5
+ * `tabletBreakpoint` props on <PktHeader>; the component measures its
6
+ * own width via ResizeObserver and toggles `--mobile` / `--tablet`
7
+ * modifier classes on the root accordingly. The SCSS below keys off
8
+ * those classes — never off a fixed media/container threshold — so the
9
+ * breakpoints follow the JS configuration.
10
+ *
11
+ * Class semantics (set by JS):
12
+ * --mobile : header width < mobileBreakpoint
13
+ * --tablet : header width < tabletBreakpoint
14
+ * (always also true when --mobile is true)
15
+ * neither : header width ≥ tabletBreakpoint ("laptop" state)
16
+ *
17
+ * The "laptop" state is the default in the SCSS; --tablet and --mobile
18
+ * override downward. --mobile blocks come after --tablet so they win on
19
+ * source order when both are present.
4
20
  */
5
21
 
6
22
  @use 'sass:map';
7
23
  @use '../abstracts/variables';
8
24
  @use '../abstracts/mixins/breakpoints' as *;
9
- @use '../abstracts/mixins/container-queries' as *;
10
25
  @use '../abstracts/mixins/' as *;
11
26
 
12
- @mixin header-cq($min-width) {
13
- @include cq('header-service', $min-width) {
14
- @content;
15
- }
16
- }
17
-
18
27
  .pkt-header-service-spacer {
19
- height: 80px;
28
+ height: map.get(variables.$spacing, 'size-104');
20
29
 
21
- @include header-cq($cq-bp-tablet) {
30
+ &--tablet {
22
31
  height: map.get(variables.$spacing, 'size-88');
23
32
  }
24
33
 
25
- @include header-cq($cq-bp-laptop) {
26
- height: map.get(variables.$spacing, 'size-104');
27
- }
28
-
29
34
  &--mobile {
30
35
  height: 5rem;
31
36
  }
32
37
 
33
38
  &--has-user {
34
- height: 7.5rem;
39
+ height: map.get(variables.$spacing, 'size-104');
35
40
 
36
- @include header-cq($cq-bp-tablet) {
41
+ &.pkt-header-service-spacer--tablet {
37
42
  height: map.get(variables.$spacing, 'size-88');
38
43
  }
39
44
 
40
- @include header-cq($cq-bp-laptop) {
41
- height: map.get(variables.$spacing, 'size-104');
45
+ &.pkt-header-service-spacer--mobile {
46
+ height: 7.5rem;
42
47
  }
43
48
  }
44
49
 
45
50
  &--compact {
46
- height: map.get(variables.$spacing, 'size-64');
51
+ height: map.get(variables.$spacing, 'size-72');
47
52
 
48
- @include header-cq($cq-bp-tablet) {
53
+ &.pkt-header-service-spacer--tablet {
49
54
  height: map.get(variables.$spacing, 'size-64');
50
55
  }
51
56
 
52
- @include header-cq($cq-bp-laptop) {
53
- height: map.get(variables.$spacing, 'size-72');
54
- }
55
-
56
57
  &.pkt-header-service-spacer--mobile {
57
58
  height: map.get(variables.$spacing, 'size-64');
58
59
  }
59
60
  }
60
61
 
61
62
  &--compact#{&}--has-user {
62
- height: 104px;
63
+ height: map.get(variables.$spacing, 'size-72');
63
64
 
64
- @include header-cq($cq-bp-tablet) {
65
+ &.pkt-header-service-spacer--tablet {
65
66
  height: map.get(variables.$spacing, 'size-64');
66
67
  }
67
68
 
68
- @include header-cq($cq-bp-laptop) {
69
- height: map.get(variables.$spacing, 'size-72');
70
- }
71
-
72
69
  &.pkt-header-service-spacer--mobile {
73
70
  height: 104px;
74
71
  }
@@ -76,29 +73,25 @@
76
73
  }
77
74
 
78
75
  .pkt-header-service {
79
- --pkt-header-height: #{map.get(variables.$spacing, 'size-72')};
76
+ --pkt-header-height: #{map.get(variables.$spacing, 'size-104')};
80
77
 
81
- @include header-cq($cq-bp-tablet) {
78
+ &--tablet {
82
79
  --pkt-header-height: #{map.get(variables.$spacing, 'size-88')};
83
80
  }
84
81
 
85
- @include header-cq($cq-bp-laptop) {
86
- --pkt-header-height: #{map.get(variables.$spacing, 'size-104')};
87
- }
88
-
89
- &--compact {
82
+ &--mobile {
90
83
  --pkt-header-height: #{map.get(variables.$spacing, 'size-64')};
91
84
 
92
- @include header-cq($cq-bp-laptop) {
85
+ @include bp('laptop-up') {
93
86
  --pkt-header-height: #{map.get(variables.$spacing, 'size-72')};
94
87
  }
95
88
  }
96
89
 
97
- &--mobile {
98
- --pkt-header-height: #{map.get(variables.$spacing, 'size-64')};
90
+ &--compact {
91
+ --pkt-header-height: #{map.get(variables.$spacing, 'size-72')};
99
92
 
100
- @include bp('laptop-up') {
101
- --pkt-header-height: #{map.get(variables.$spacing, 'size-72')};
93
+ &.pkt-header-service--tablet {
94
+ --pkt-header-height: #{map.get(variables.$spacing, 'size-64')};
102
95
  }
103
96
  }
104
97
 
@@ -106,22 +99,20 @@
106
99
  z-index: 10;
107
100
  background-color: var(--pkt-color-background-default);
108
101
  border-bottom: 1px solid var(--pkt-color-border-subtle);
109
- container-type: inline-size;
110
- container-name: header-service;
111
102
  display: grid;
112
103
  align-items: center;
113
104
  grid-template-columns: 1fr auto auto;
114
- grid-template-rows: map.get(variables.$spacing, 'size-72') auto;
115
- column-gap: map.get(variables.$spacing, 'size-8');
105
+ grid-template-rows: map.get(variables.$spacing, 'size-104') auto;
106
+ column-gap: map.get(variables.$spacing, 'size-32');
116
107
 
117
- @include header-cq($cq-bp-tablet) {
108
+ &--tablet {
118
109
  grid-template-rows: map.get(variables.$spacing, 'size-88') auto;
119
110
  column-gap: map.get(variables.$spacing, 'size-24');
120
111
  }
121
112
 
122
- @include header-cq($cq-bp-laptop) {
123
- grid-template-rows: map.get(variables.$spacing, 'size-104') auto;
124
- column-gap: map.get(variables.$spacing, 'size-32');
113
+ &--mobile {
114
+ grid-template-rows: map.get(variables.$spacing, 'size-72') auto;
115
+ column-gap: map.get(variables.$spacing, 'size-8');
125
116
  }
126
117
 
127
118
  &--compact {
@@ -148,15 +139,15 @@
148
139
  &__content,
149
140
  &__user {
150
141
  display: inline-flex;
151
- column-gap: map.get(variables.$spacing, 'size-4');
142
+ column-gap: map.get(variables.$spacing, 'size-32');
152
143
  min-width: 0;
153
144
 
154
- @include header-cq($cq-bp-tablet) {
145
+ .pkt-header-service--tablet & {
155
146
  column-gap: map.get(variables.$spacing, 'size-24');
156
147
  }
157
148
 
158
- @include header-cq($cq-bp-laptop) {
159
- column-gap: map.get(variables.$spacing, 'size-32');
149
+ .pkt-header-service--mobile & {
150
+ column-gap: map.get(variables.$spacing, 'size-4');
160
151
  }
161
152
  }
162
153
 
@@ -165,14 +156,14 @@
165
156
  grid-row: 1;
166
157
  align-items: center;
167
158
  display: inline-flex;
168
- padding-left: map.get(variables.$spacing, 'size-8');
159
+ padding-left: map.get(variables.$spacing, 'size-32');
169
160
 
170
- @include header-cq($cq-bp-tablet) {
161
+ .pkt-header-service--tablet & {
171
162
  padding-left: map.get(variables.$spacing, 'size-16');
172
163
  }
173
164
 
174
- @include header-cq($cq-bp-laptop) {
175
- padding-left: map.get(variables.$spacing, 'size-32');
165
+ .pkt-header-service--mobile & {
166
+ padding-left: map.get(variables.$spacing, 'size-8');
176
167
  }
177
168
  }
178
169
 
@@ -200,10 +191,10 @@
200
191
  &__user {
201
192
  grid-column: 3;
202
193
  justify-self: end;
203
- padding-right: map.get(variables.$spacing, 'size-16');
194
+ padding-right: map.get(variables.$spacing, 'size-32');
204
195
 
205
- @include header-cq($cq-bp-laptop) {
206
- padding-right: map.get(variables.$spacing, 'size-32');
196
+ .pkt-header-service--tablet & {
197
+ padding-right: map.get(variables.$spacing, 'size-16');
207
198
  }
208
199
  }
209
200
 
@@ -11,6 +11,7 @@
11
11
  @forward 'fileupload';
12
12
  @forward 'footer';
13
13
  @forward 'header';
14
+ @forward 'header-menu';
14
15
  @forward 'header-service';
15
16
  @forward 'header-service-mobile';
16
17
  @forward 'header-user-menu';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslokommune/punkt-css",
3
- "version": "16.16.0",
3
+ "version": "16.17.0",
4
4
  "description": "CSS-rammeverket til Punkt, et designsystem laget av Oslo Origo",
5
5
  "homepage": "https://punkt.oslo.kommune.no",
6
6
  "author": "Team Designsystem, Oslo Origo",
@@ -25,7 +25,7 @@
25
25
  ]
26
26
  },
27
27
  "devDependencies": {
28
- "@oslokommune/punkt-assets": "^16.13.2",
28
+ "@oslokommune/punkt-assets": "^16.16.1",
29
29
  "astro": "^5.7.5",
30
30
  "edit-json-file": "^1.8.0",
31
31
  "fs-extra": "^11.2.0",
@@ -60,5 +60,5 @@
60
60
  "url": "https://github.com/oslokommune/punkt/issues"
61
61
  },
62
62
  "license": "MIT",
63
- "gitHead": "10f6a1f8951e4bbce37ff34f8ad4bcb836d922a7"
63
+ "gitHead": "b9024738acca3ed6dd938238ff2a2d4219cd3c0c"
64
64
  }