@swr-data-lab/components 2.39.1 → 2.40.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.
@@ -9,85 +9,65 @@ export {};
9
9
  <style>.container {
10
10
  --margin: 16px;
11
11
  --column-gap: 16px;
12
- --column-width: calc((var(--grid-width) - var(--column-gap) * 11) / 12);
13
- --grid-width: calc(100vw - var(--margin) * 2);
14
- }
15
- @media (min-width: 640px) {
16
- .container {
17
- --margin: 40px;
18
- }
19
- }
20
- @media (min-width: 768px) {
21
- .container {
22
- --margin: 40px;
23
- }
24
- }
25
- @media (min-width: 1024px) {
26
- .container {
27
- --margin: 48px;
28
- --column-gap: 32px;
29
- }
30
- }
31
- @media (min-width: 1440px) {
32
- .container {
33
- --grid-width: calc(Min(1312px, 100vw));
34
- --margin: calc((100vw - var(--grid-width)) * 0.5);
35
- }
12
+ --grid-width: min(calc(100vw - var(--margin) * 2), 1312px);
13
+ --column-width: calc(
14
+ (var(--grid-width) - var(--column-gap) * 11) / 12
15
+ );
16
+ max-width: 100vw;
17
+ margin: 0 auto;
36
18
  }
37
19
 
38
20
  .small {
39
- width: calc(var(--column-width) * 10 + var(--column-gap) * 8);
40
- margin-left: calc(var(--column-width) * 1 + (var(--column-gap)) * 1);
21
+ width: calc(var(--column-width) * 10 + var(--column-gap) * 9);
41
22
  }
42
23
  @media (min-width: 640px) {
43
24
  .small {
44
- width: calc(var(--column-width) * 8 + var(--column-gap) * 6);
45
- margin-left: calc(var(--column-width) * 1 + (var(--column-gap)) * 1);
25
+ width: calc(var(--column-width) * 8 + var(--column-gap) * 7);
46
26
  }
47
27
  }
48
28
  @media (min-width: 1024px) {
49
29
  .small {
50
30
  width: calc(var(--column-width) * 6 + var(--column-gap) * 5);
51
- margin-left: calc(var(--column-width) * 1 + (var(--column-gap)) * 1);
52
31
  }
53
32
  }
54
33
 
55
34
  @media (min-width: 1024px) {
56
35
  .medium {
57
36
  width: calc(var(--column-width) * 10 + var(--column-gap) * 9);
58
- margin-left: calc(var(--column-width) * -1 + (var(--column-gap)) * -1);
37
+ margin-left: calc((var(--column-width) + var(--column-gap)) * -1);
59
38
  }
60
39
  }
61
40
 
41
+ .large {
42
+ width: calc(var(--column-width) * 12 + var(--column-gap) * 11);
43
+ }
62
44
  @media (min-width: 640px) {
63
45
  .large {
64
- width: calc(var(--column-width) * 12 + var(--column-gap) * 11);
65
- margin-left: calc(var(--column-width) * -1 + var(--column-gap) * -1);
46
+ margin-left: calc((var(--column-width) + var(--column-gap)) * -1);
66
47
  }
67
48
  }
68
49
  @media (min-width: 1024px) {
69
50
  .large {
70
- width: calc(var(--column-width) * 12 + var(--column-gap) * 11);
71
- margin-left: calc(var(--column-width) * -2 + var(--column-gap) * -2);
51
+ margin-left: calc((var(--column-width) + var(--column-gap)) * -2);
72
52
  }
73
53
  }
74
54
 
75
55
  .bleed {
76
56
  width: 100vw;
77
- margin-left: calc(var(--margin) * -1);
57
+ margin-left: calc((var(--column-width) + var(--column-gap)) * -0 - var(--margin));
78
58
  }
79
59
  @media (min-width: 640px) {
80
60
  .bleed {
81
- margin-left: calc(var(--column-width) * -1 + (var(--column-gap)) * -1 - var(--margin) * 1);
61
+ margin-left: calc((var(--column-width) + var(--column-gap)) * -1 - var(--margin));
82
62
  }
83
63
  }
84
- @media (min-width: 768px) {
64
+ @media (min-width: 1024px) {
85
65
  .bleed {
86
- margin-left: calc(var(--column-width) * -1 + (var(--column-gap)) * -1 - var(--margin) * 1);
66
+ margin-left: calc((var(--column-width) + var(--column-gap)) * -2 - var(--margin));
87
67
  }
88
68
  }
89
- @media (min-width: 1024px) {
69
+ @media (min-width: 1280px) {
90
70
  .bleed {
91
- margin-left: calc(var(--column-width) * -2 + (var(--column-gap)) * -2 - var(--margin) * 1);
71
+ margin-left: calc((var(--column-width) + var(--column-gap)) * -2 - max(0px, (100vw - 1312px) / 2));
92
72
  }
93
73
  }</style>
@@ -62,7 +62,7 @@ h1 {
62
62
  margin-bottom: 0.2em;
63
63
  }
64
64
  h1 em {
65
- background: rgba(134, 139, 84, 0.4);
65
+ background: rgba(134, 139, 84, 0.25);
66
66
  font-style: normal;
67
67
  padding: 0 0.3em;
68
68
  border-radius: 2px;
@@ -83,11 +83,18 @@ a {
83
83
 
84
84
  th,
85
85
  td {
86
- padding: 0.2em 0.4em;
86
+ padding: 0 0.4em;
87
87
  text-align: left;
88
+ border-right: 1px solid var(--color-surfaceBorder);
89
+ }
90
+ th:last-child,
91
+ td:last-child {
92
+ border-right: 0;
88
93
  }
89
94
 
90
95
  th {
96
+ padding: 0.2em 0.4em;
97
+ border-right: 1px solid var(--color-textSecondary);
91
98
  border-bottom: 1px solid var(--color-textSecondary);
92
99
  }
93
100
 
@@ -101,12 +108,12 @@ tr:last-child {
101
108
  input {
102
109
  display: block;
103
110
  font-family: monospace;
104
- width: calc(100% - 0.6em);
105
- padding: 0.2em 0.4em;
111
+ width: 100%;
112
+ padding: 0.35em 0;
106
113
  font-size: 0.9rem;
107
114
  background: var(--color-pageFill);
108
- border: 1px solid var(--color-surfaceBorder);
109
115
  color: var(--color-textSecondary);
116
+ border: 0;
110
117
  }
111
118
 
112
119
  a:hover,
@@ -83,7 +83,7 @@ const rules = [
83
83
  --fs-base: 1.25rem;
84
84
  --fs-large-1: 1.5rem;
85
85
  --fs-large-2: 2rem;
86
- --fs-large-3: 3rem;
86
+ --fs-large-3: 2.5rem;
87
87
  --fs-large-4: 3.5rem;
88
88
  }
89
89
  }</style>
@@ -0,0 +1,10 @@
1
+ <svg width="6" height="14" viewBox="0 0 6 14" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path
3
+ d="M1.00065 12.333L4.33398 6.99967L1.00065 1.66634"
4
+ stroke="black"
5
+ stroke-opacity="0.2"
6
+ stroke-width="1.5"
7
+ stroke-linecap="round"
8
+ stroke-linejoin="round"
9
+ />
10
+ </svg>
@@ -0,0 +1,26 @@
1
+ export default ArrowRight;
2
+ type ArrowRight = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const ArrowRight: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
+ $$bindings?: Bindings;
17
+ } & Exports;
18
+ (internal: unknown, props: {
19
+ $$events?: Events;
20
+ $$slots?: Slots;
21
+ }): Exports & {
22
+ $set?: any;
23
+ $on?: any;
24
+ };
25
+ z_$$bindings?: Bindings;
26
+ }
@@ -1,4 +1,6 @@
1
1
  <script lang="ts">import SwrLogo from './SwrLogo.svg.svelte';
2
+ import Home from './Home.svg.svelte';
3
+ import ArrowRight from './ArrowRight.svg.svelte';
2
4
  import GridInspector from './GridInspector.svelte';
3
5
  import DesignTokens from '../DesignTokens/DesignTokens.svelte';
4
6
  import Copy from '../Copy/Copy.svelte';
@@ -36,7 +38,15 @@ let articleEl = $state();
36
38
  </div>
37
39
  {/if}
38
40
  {#if showBreadcrumbs}
39
- <div class="breadcrumbs"></div>
41
+ <div class="breadcrumbs">
42
+ <span class="home">
43
+ <Home />
44
+ </span>
45
+ <ArrowRight />
46
+ <span>SWR Aktuell</span>
47
+ <ArrowRight />
48
+ <span>Bundesland</span>
49
+ </div>
40
50
  {/if}
41
51
 
42
52
  {#if showPlayer}
@@ -69,6 +79,9 @@ let articleEl = $state();
69
79
  <i class="byline-image"></i>
70
80
  </div>
71
81
  </div>
82
+ <div class="article-byline-names">
83
+ Von Autor:in 1, Autor:in 2, Autor:in 3, SWR Data Lab
84
+ </div>
72
85
  </div>
73
86
  <div class="article-actions">
74
87
  <i class="action-button"></i>
@@ -120,7 +133,44 @@ let articleEl = $state();
120
133
  .container {
121
134
  color: var(--blue);
122
135
  background: var(--color-pageFill);
123
- font-family: "SWR-VAR-Sans", sans-serif;
136
+ font-family: var(--swr-sans);
137
+ width: 100%;
138
+ max-width: none;
139
+ }
140
+
141
+ header,
142
+ .nav,
143
+ .breadcrumbs {
144
+ width: 100%;
145
+ padding: 0 16px;
146
+ }
147
+ @media (min-width: 640px) {
148
+ header,
149
+ .nav,
150
+ .breadcrumbs {
151
+ padding: 0 40px;
152
+ }
153
+ }
154
+ @media (min-width: 768px) {
155
+ header,
156
+ .nav,
157
+ .breadcrumbs {
158
+ padding: 0 32px;
159
+ }
160
+ }
161
+ @media (min-width: 1024px) {
162
+ header,
163
+ .nav,
164
+ .breadcrumbs {
165
+ padding: 0 max(48px, (100% - 1312px) / 2);
166
+ }
167
+ }
168
+ @media (min-width: 1280px) {
169
+ header,
170
+ .nav,
171
+ .breadcrumbs {
172
+ padding: 0 max(64px, (100% - 1312px) / 2);
173
+ }
124
174
  }
125
175
 
126
176
  header {
@@ -129,18 +179,15 @@ header {
129
179
  background: var(--blue-light);
130
180
  border-bottom: 1px solid var(--blue);
131
181
  height: 48px;
132
- padding: 0 16px;
133
182
  }
134
183
  @media (min-width: 640px) {
135
184
  header {
136
- padding: 0 40px;
137
185
  height: 64px;
138
186
  }
139
187
  }
140
188
 
141
189
  .header-inner {
142
190
  width: 100%;
143
- max-width: 1312px;
144
191
  margin: 0 auto;
145
192
  }
146
193
 
@@ -148,7 +195,7 @@ header {
148
195
  display: block;
149
196
  height: 24px;
150
197
  }
151
- @media (min-width: 1440px) {
198
+ @media (min-width: 1280px) {
152
199
  .logo {
153
200
  height: 28px;
154
201
  }
@@ -172,7 +219,7 @@ header {
172
219
  white-space: nowrap;
173
220
  overflow: hidden;
174
221
  }
175
- @media (min-width: 1440px) {
222
+ @media (min-width: 1280px) {
176
223
  .nav ul {
177
224
  margin-left: -32px;
178
225
  }
@@ -183,13 +230,14 @@ header {
183
230
  height: 48px;
184
231
  display: flex;
185
232
  align-items: center;
186
- padding: 0 16px;
187
233
  }
188
- @media (min-width: 640px) {
189
- .nav,
190
- .breadcrumbs {
191
- padding: 0 40px;
192
- }
234
+
235
+ .breadcrumbs {
236
+ font-size: var(--fs-small-3);
237
+ gap: 12px;
238
+ }
239
+ .breadcrumbs .home {
240
+ padding: 0 8px;
193
241
  }
194
242
 
195
243
  .circle {
@@ -209,20 +257,28 @@ header {
209
257
  }
210
258
 
211
259
  .player {
212
- width: 638px;
213
- height: 58px;
214
- bottom: 16px;
215
- left: 50%;
216
- border-radius: 4px;
260
+ position: fixed;
261
+ z-index: 100;
262
+ height: 56px;
263
+ bottom: 8px;
264
+ left: 8px;
265
+ right: 8px;
217
266
  padding: 8px;
218
267
  display: flex;
219
268
  align-items: center;
220
269
  justify-content: space-between;
221
- transform: translateX(-50%);
222
270
  background: var(--blue-light);
223
271
  border: 1px solid var(--blue);
224
- z-index: 100;
225
- position: fixed;
272
+ border-radius: 4px;
273
+ max-width: 640px;
274
+ margin: 0 auto;
275
+ }
276
+ @media (min-width: 640px) {
277
+ .player {
278
+ left: 10.5px;
279
+ right: 10.5px;
280
+ bottom: 8px;
281
+ }
226
282
  }
227
283
 
228
284
  .player-buttons {
@@ -233,34 +289,19 @@ header {
233
289
  .grid {
234
290
  display: grid;
235
291
  grid-template-columns: repeat(12, 1fr);
292
+ position: relative;
236
293
  column-gap: 16px;
237
- max-width: 1312px;
238
294
  width: auto;
239
- position: relative;
240
- }
241
- @media (min-width: 1440px) {
242
- .grid {
243
- column-gap: 32px;
244
- margin: 0 auto;
245
- }
295
+ max-width: 1312px;
246
296
  }
247
297
 
248
298
  .article {
249
299
  margin: 0 16px;
250
300
  }
251
- @media (min-width: 640px) {
252
- .article {
253
- margin: 0 40px;
254
- }
255
- }
256
- @media (min-width: 1024px) {
257
- .article {
258
- margin: 0 48px;
259
- }
260
- }
261
- @media (min-width: 1440px) {
301
+ @media (min-width: 1280px) {
262
302
  .article {
263
303
  margin: 0 auto;
304
+ width: calc(100% - 32px);
264
305
  }
265
306
  }
266
307
 
@@ -317,26 +358,23 @@ header {
317
358
  }
318
359
 
319
360
  .article-title {
320
- font-size: 2rem;
321
- line-height: 1.3;
361
+ font-size: 1.75rem;
362
+ line-height: 1.25;
363
+ font-weight: 700;
322
364
  }
323
365
  @media (min-width: 1024px) {
324
366
  .article-title {
325
367
  line-height: 1.25;
326
- font-size: 3rem;
368
+ font-size: 2.5rem;
327
369
  }
328
370
  }
329
371
 
330
372
  .article-intro {
331
373
  margin-top: 0.5em;
332
374
  hyphens: auto;
333
- font-size: 1.25rem;
375
+ font-size: 1.125rem;
334
376
  line-height: 1.25;
335
- }
336
- @media (min-width: 1024px) {
337
- .article-intro {
338
- font-size: 1.5rem;
339
- }
377
+ font-weight: 500;
340
378
  }
341
379
 
342
380
  .article-meta {
@@ -375,6 +413,11 @@ header {
375
413
  gap: 10px;
376
414
  }
377
415
 
416
+ .article-byline-names {
417
+ font-size: var(--fs-small-2);
418
+ font-weight: 700;
419
+ }
420
+
378
421
  .byline-images {
379
422
  display: flex;
380
423
  flex-flow: row-reverse;
@@ -29,6 +29,7 @@ let cols = $derived.by(() => {
29
29
  opacity: 0.1;
30
30
  pointer-events: none;
31
31
  z-index: 0;
32
+ max-width: none;
32
33
  }
33
34
  .col {
34
35
  background: rgb(104, 120, 179);
@@ -0,0 +1,8 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path
3
+ fill-rule="evenodd"
4
+ clip-rule="evenodd"
5
+ d="M0.899895 7.63727C0.688729 7.33565 0.762054 6.91996 1.06367 6.70879L7.60442 2.12953C7.64021 2.1032 7.67826 2.08076 7.71793 2.06233C7.80789 2.02029 7.90406 1.99992 7.99953 2C8.09502 1.99992 8.19122 2.0203 8.2812 2.06236C8.32084 2.08079 8.35886 2.10322 8.39462 2.12952L14.9354 6.70879C15.237 6.91996 15.3103 7.33565 15.0992 7.63727C14.888 7.93889 14.4723 8.01221 14.1707 7.80105L13.3329 7.21447V13.3334C13.3329 13.7016 13.0344 14.0001 12.6662 14.0001H9.33286H6.66619H3.33286C2.96467 14.0001 2.66619 13.7016 2.66619 13.3334V7.21447L1.82837 7.80105C1.52675 8.01221 1.11106 7.93889 0.899895 7.63727ZM11.9995 6.28099L7.99953 3.48054L3.99953 6.28099V12.6667H5.99953V9.33339C5.99953 8.9652 6.298 8.66672 6.66619 8.66672H9.33286C9.70105 8.66672 9.99953 8.9652 9.99953 9.33339V12.6667H11.9995V6.28099ZM8.66619 12.6667V10.0001H7.33286V12.6667H8.66619Z"
6
+ fill="#515152"
7
+ />
8
+ </svg>
@@ -0,0 +1,26 @@
1
+ export default Home;
2
+ type Home = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const Home: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
+ $$bindings?: Bindings;
17
+ } & Exports;
18
+ (internal: unknown, props: {
19
+ $$events?: Events;
20
+ $$slots?: Slots;
21
+ }): Exports & {
22
+ $set?: any;
23
+ $on?: any;
24
+ };
25
+ z_$$bindings?: Bindings;
26
+ }
@@ -1,10 +1,11 @@
1
1
  <script lang="ts">import {} from 'svelte';
2
2
  import Caption from '../Caption/Caption.svelte';
3
- const { title, subtitle, eyebrow, imageModules, updated, bylines = [] } = $props();
3
+ import dataLabImage from '../assets/data_lab.jpg?enhanced&w=200';
4
+ const { title, subtitle, eyebrow, imageModules, updated, bylines = [], showTextShadow = false } = $props();
4
5
  const updated_on = updated ? (updated instanceof Date ? updated : new Date(updated)) : null;
5
6
  </script>
6
7
 
7
- <header class="container">
8
+ <header class="container" class:show-text-shadow={showTextShadow}>
8
9
  {#if eyebrow}
9
10
  <p class="eyebrow">{eyebrow}</p>
10
11
  {/if}
@@ -15,27 +16,42 @@ const updated_on = updated ? (updated instanceof Date ? updated : new Date(updat
15
16
  </p>
16
17
  {/if}
17
18
  <div class="meta">
19
+ {#if updated_on}
20
+ <dl class="date">
21
+ <dt>Stand:</dt>
22
+ <dd data-testid="updated">{updated_on.toLocaleDateString('de-DE')}</dd>
23
+ </dl>
24
+ {/if}
18
25
  {#if bylines && bylines.length > 0}
19
- {@const nameString = `Von ${bylines.map((el) => (el.url ? `<a href='${el.url}'>${el.name}</a>` : el.name)).join(', ')}, <a href="https://www.swr.de/home/swr-data-lab-team-100.html">SWR Data Lab</a>`}
20
26
  <div class="bylines">
21
27
  {#if imageModules}
22
28
  <ul class="byline-images">
23
29
  {#each bylines.filter((el) => el.image && el.image in imageModules) as b, i}
24
30
  {@const src = imageModules[b.image].default}
25
- <li class="byline-image" style:z-index={bylines.length - i}>
31
+ <li class="byline-image" style:z-index={bylines.length - i + 1}>
26
32
  <enhanced:img {src} alt={b.name} />
27
33
  </li>
28
34
  {/each}
35
+ <li class="byline-image" style:z-index={0}>
36
+ <enhanced:img src={dataLabImage} alt="SWR Data Lab" />
37
+ </li>
29
38
  </ul>
30
39
  {/if}
31
40
  <Caption>
32
- <p data-testid="byline-names" class="byline-names">{@html nameString}</p>
41
+ <p data-testid="byline-names" class="byline-names">
42
+ <span class="byline-prefix">Von</span>
43
+ {#each bylines as byline, i}
44
+ {#if i > 0},{/if}
45
+ {#if byline.url}
46
+ <a href={byline.url}>{byline.name}</a>
47
+ {:else}
48
+ {byline.name}
49
+ {/if}
50
+ {/each}, <a href="https://www.swr.de/home/swr-data-lab-team-100.html">SWR Data Lab</a>
51
+ </p>
33
52
  </Caption>
34
53
  </div>
35
54
  {/if}
36
- {#if updated_on}
37
- <p class="updated" data-testid="updated">Stand: {updated_on.toLocaleDateString('de-DE')}</p>
38
- {/if}
39
55
  </div>
40
56
  </header>
41
57
 
@@ -44,15 +60,38 @@ const updated_on = updated ? (updated instanceof Date ? updated : new Date(updat
44
60
  font-family: var(--swr-sans);
45
61
  margin: 0 auto;
46
62
  margin-bottom: 1rem;
47
- max-width: 44rem;
48
- text-shadow: 0 0 6px var(--color-pageFill);
63
+ }
64
+ .container.show-text-shadow {
65
+ text-shadow: 0 0 6px color-mix(in srgb, var(--color-textPrimary) 50%, transparent);
66
+ }
67
+ :global([data-theme="dark"]) .container.show-text-shadow {
68
+ text-shadow: 0 0 6px color-mix(in srgb, var(--color-textPrimary) 70%, transparent);
69
+ }
70
+ .container {
71
+ --margin: 16px;
72
+ --column-gap: 16px;
73
+ --grid-width: min(calc(100vw - var(--margin) * 2), 1312px);
74
+ --column-width: calc(
75
+ (var(--grid-width) - var(--column-gap) * 11) / 12
76
+ );
77
+ }
78
+ @media (min-width: 640px) {
79
+ .container {
80
+ max-width: calc(var(--column-width) * 10 + var(--column-gap) * 9);
81
+ }
82
+ }
83
+ @media (min-width: 1024px) {
84
+ .container {
85
+ max-width: calc(var(--column-width) * 8 + var(--column-gap) * 7);
86
+ }
49
87
  }
50
88
 
51
89
  .eyebrow {
52
- font-size: var(--fs-small-1);
53
- margin-bottom: 1.3em;
54
- line-height: 1;
90
+ font-size: var(--fs-base);
91
+ margin-bottom: 4px;
92
+ line-height: 1.25;
55
93
  letter-spacing: 0.025em;
94
+ font-weight: 600;
56
95
  }
57
96
 
58
97
  .title {
@@ -67,30 +106,57 @@ const updated_on = updated ? (updated instanceof Date ? updated : new Date(updat
67
106
  .subtitle {
68
107
  margin-top: 1.15em;
69
108
  font-family: var(--swr-sans);
70
- line-height: 1.4;
109
+ line-height: 1.25;
71
110
  font-size: var(--fs-base);
72
- font-weight: 400;
111
+ font-weight: 500;
73
112
  hyphens: auto;
74
113
  }
75
114
 
76
115
  .meta {
77
116
  margin-top: 1.5em;
78
117
  display: flex;
79
- align-items: center;
80
- column-gap: 2em;
81
- flex-wrap: wrap;
118
+ flex-flow: column;
119
+ gap: 0.75em;
120
+ }
121
+ @media (min-width: 768px) {
122
+ .meta {
123
+ flex-flow: row;
124
+ gap: var(--column-gap);
125
+ }
126
+ }
127
+
128
+ .date {
129
+ font-size: var(--fs-small-1);
130
+ }
131
+ .date dt {
132
+ color: var(--color-textSecondary);
133
+ font-weight: 400;
134
+ }
135
+ .date dd {
136
+ margin: 0;
137
+ color: var(--color-textPrimary);
138
+ font-weight: 700;
139
+ }
140
+ @media (min-width: 768px) {
141
+ .date {
142
+ flex: 0 0 calc(var(--column-width) * 3 + var(--column-gap) * 2);
143
+ }
144
+ }
145
+ @media (min-width: 1200px) {
146
+ .date {
147
+ flex: 0 0 calc(var(--column-width) * 2 + var(--column-gap) * 1);
148
+ }
82
149
  }
83
150
 
84
151
  .bylines {
85
152
  display: flex;
86
153
  flex-flow: column;
87
- gap: 0.5em;
154
+ gap: 8px;
155
+ align-self: start;
88
156
  }
89
- @media (min-width: 500px) {
157
+ @media (min-width: 640px) {
90
158
  .bylines {
91
- gap: 1em;
92
- align-items: center;
93
- flex-flow: row;
159
+ flex: 1;
94
160
  }
95
161
  }
96
162
 
@@ -102,28 +168,29 @@ const updated_on = updated ? (updated instanceof Date ? updated : new Date(updat
102
168
  position: relative;
103
169
  list-style: none;
104
170
  overflow: hidden;
105
- margin-right: -0.5em;
106
- box-shadow: 0 1px 2px 1px rgba(0, 0, 0, 0.15);
171
+ margin-right: -1em;
107
172
  border-radius: 1000px;
108
- border: 1px solid var(--color-pageFill);
173
+ border: 0.5px solid var(--color-surfaceBorder);
109
174
  }
110
175
  .byline-image img {
111
- width: 2.25rem;
112
- height: auto;
176
+ width: 48px;
177
+ height: 48px;
178
+ max-width: none;
113
179
  display: block;
180
+ object-fit: cover;
114
181
  }
115
182
 
116
183
  .byline-names {
117
- line-height: 1.35;
184
+ font-weight: 700;
185
+ line-height: 1.25;
118
186
  }
119
187
 
120
- .updated {
121
- color: var(--color-textSecondary);
122
- font-size: var(--fs-small-2);
123
- letter-spacing: 0.025em;
188
+ .byline-prefix {
189
+ font-weight: 400;
124
190
  }
125
191
 
126
192
  :global(a) {
193
+ text-decoration: underline;
127
194
  text-underline-offset: 0.25em;
128
195
  text-decoration-color: var(--gray-light-1);
129
196
  }
@@ -2,6 +2,7 @@ import { type Snippet } from 'svelte';
2
2
  interface Byline {
3
3
  name: string;
4
4
  image?: string;
5
+ url?: string;
5
6
  }
6
7
  interface SwrHeaderProps {
7
8
  title: string;
@@ -10,6 +11,7 @@ interface SwrHeaderProps {
10
11
  imageModules?: Record<string, any>;
11
12
  updated?: Date | string;
12
13
  bylines?: Byline[];
14
+ showTextShadow?: boolean;
13
15
  }
14
16
  declare const SwrHeader: import("svelte").Component<SwrHeaderProps, {}, "">;
15
17
  type SwrHeader = ReturnType<typeof SwrHeader>;
Binary file
@@ -1,6 +1,34 @@
1
1
  import { MediaQuery } from 'svelte/reactivity';
2
2
 
3
3
  const dm = new MediaQuery('prefers-color-scheme: dark', false);
4
- export default () => {
5
- return dm.current;
6
- };
4
+
5
+ // Create a reactive state for dark mode
6
+ let isDark = $state(false);
7
+
8
+ // Initialize and observe body class changes
9
+ if (typeof document !== 'undefined') {
10
+ const checkDarkMode = () => {
11
+ if (document.body?.classList.contains('dark')) {
12
+ return true;
13
+ }
14
+ if (document.body?.classList.contains('light')) {
15
+ return false;
16
+ }
17
+ return dm.current;
18
+ };
19
+
20
+ isDark = checkDarkMode();
21
+
22
+ const observer = new MutationObserver(() => {
23
+ isDark = checkDarkMode();
24
+ });
25
+
26
+ observer.observe(document.body, {
27
+ attributes: true,
28
+ attributeFilter: ['class']
29
+ });
30
+ } else {
31
+ isDark = dm.current;
32
+ }
33
+
34
+ export default () => isDark;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@swr-data-lab/components",
3
3
  "description": "SWR Data Lab component library",
4
- "version": "2.39.1",
4
+ "version": "2.40.0",
5
5
  "author": "SWR Data Lab",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",
@@ -16,6 +16,8 @@
16
16
  "build": "vite build",
17
17
  "preview": "vite preview",
18
18
  "package": "svelte-kit sync && svelte-package -i src && publint",
19
+ "package:dev": "svelte-kit sync && svelte-package -i src",
20
+ "package:watch": "nodemon --watch src --ext svelte,js,ts,css --ignore '**/*.test.*' --ignore '**/*.spec.*' --ignore '**/*.stories.*' --exec 'npm run package:dev'",
19
21
  "prepublishOnly": "npm run package",
20
22
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
21
23
  "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
@@ -37,42 +39,43 @@
37
39
  "svelte-select": "5.8.3"
38
40
  },
39
41
  "devDependencies": {
40
- "layercake": "^10.0.2",
41
42
  "@semantic-release/changelog": "6.0.3",
42
43
  "@semantic-release/git": "10.0.1",
43
44
  "@semantic-release/npm": "13.1.3",
44
- "@storybook/addon-docs": "10.1.11",
45
- "@storybook/addon-links": "10.1.11",
45
+ "@storybook/addon-docs": "10.2.3",
46
+ "@storybook/addon-links": "10.2.3",
46
47
  "@storybook/addon-svelte-csf": "^5.0.10",
47
- "@storybook/addon-vitest": "10.1.11",
48
- "@storybook/sveltekit": "10.1.11",
48
+ "@storybook/addon-vitest": "10.2.3",
49
+ "@storybook/sveltekit": "10.2.3",
49
50
  "@storybook/test-runner": "^0.24.2",
50
51
  "@sveltejs/adapter-auto": "7.0.0",
51
- "@sveltejs/enhanced-img": "0.9.2",
52
- "@sveltejs/kit": "2.49.5",
52
+ "@sveltejs/enhanced-img": "0.9.3",
53
+ "@sveltejs/kit": "2.50.1",
53
54
  "@sveltejs/package": "2.5.7",
54
- "@sveltejs/vite-plugin-svelte": "6.2.1",
55
+ "@sveltejs/vite-plugin-svelte": "6.2.4",
55
56
  "@types/geojson": "7946.0.16",
56
57
  "@versatiles/style": "5.7.0",
57
- "@vitest/browser": "4.0.16",
58
- "@vitest/coverage-v8": "4.0.16",
58
+ "@vitest/browser": "4.0.18",
59
+ "@vitest/browser-playwright": "4.0.18",
60
+ "@vitest/coverage-v8": "4.0.18",
59
61
  "@vueless/storybook-dark-mode": "9.0.8",
60
62
  "concurrently": "9.2.1",
61
63
  "http-server": "14.1.1",
64
+ "layercake": "^10.0.2",
62
65
  "mdx-mermaid": "2.0.3",
63
- "playwright": "1.56.1",
64
- "publint": "0.3.12",
66
+ "nodemon": "^3.1.11",
67
+ "playwright": "1.58.1",
68
+ "publint": "0.3.17",
65
69
  "sass": "1.93.2",
66
- "sass-embedded": "1.93.2",
67
- "semantic-release": "25.0.2",
68
- "storybook": "10.1.11",
69
- "svelte": "5.33.6",
70
+ "sass-embedded": "1.97.3",
71
+ "semantic-release": "25.0.3",
72
+ "storybook": "10.2.4",
73
+ "svelte": "5.49.1",
70
74
  "svelte-check": "4.3.2",
71
75
  "svelte-preprocess": "6.0.3",
72
76
  "typescript": "5.9.3",
73
77
  "vite": "7.3.0",
74
- "vitest": "4.0.16",
75
- "@vitest/browser-playwright": "4.0.16",
78
+ "vitest": "4.0.18",
76
79
  "wait-on": "8.0.3"
77
80
  },
78
81
  "overrides": {