@swr-data-lab/components 1.6.0 → 1.8.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/.storybook/main.ts +13 -16
- package/.storybook/preview.ts +3 -0
- package/.storybook/vitest.setup.ts +9 -0
- package/package.json +8 -5
- package/src/Autocomplete/Autocomplete.stories.svelte +61 -0
- package/src/Autocomplete/Autocomplete.svelte +9 -7
- package/src/Button/Button.svelte +14 -10
- package/src/Card/Card.stories.svelte +5 -20
- package/src/Card/Card.svelte +17 -4
- package/src/ChartFooter/ChartFooter.mdx +17 -0
- package/src/ChartFooter/ChartFooter.stories.svelte +12 -20
- package/src/ChartFooter/ChartFooter.svelte +30 -22
- package/src/ChartHeader/ChartHeader.mdx +15 -0
- package/src/ChartHeader/ChartHeader.stories.svelte +14 -11
- package/src/ChartHeader/ChartHeader.svelte +19 -13
- package/src/DesignTokens/DesignTokens.mdx +15 -9
- package/src/DesignTokens/DesignTokens.svelte +2 -1
- package/src/DesignTokens/index.js +8 -1
- package/src/HighlightCard/HighlightCard.stories.svelte +5 -20
- package/src/HighlightCard/HighlightCard.svelte +15 -11
- package/src/Input/Input.svelte +1 -1
- package/src/Intro.mdx +2 -2
- package/src/Logotype/Logotype.stories.svelte +16 -0
- package/src/Logotype/Logotype.svelte +1 -0
- package/src/Middot/Middot.stories.svelte +16 -0
- package/src/Select/Select.mdx +25 -0
- package/src/Select/Select.stories.svelte +87 -147
- package/src/Select/Select.svelte +65 -73
- package/src/Select/Select.types.ts +8 -0
- package/src/Select/SelectStoriesTemplate.svelte +35 -0
- package/src/Switcher/Switcher.mdx +13 -0
- package/src/Switcher/Switcher.stories.svelte +29 -41
- package/src/Switcher/Switcher.svelte +58 -51
- package/src/index.js +1 -0
- package/src/styles/base.scss +52 -5
- package/vitest.workspace.ts +32 -0
- package/src/Autocomplete/Autocomplete.stories.js +0 -61
- package/src/Container/Container.svelte +0 -12
- package/src/Container/index.js +0 -2
- package/src/styles/_typography.scss +0 -49
- package/src/styles/_vars.scss +0 -30
package/.storybook/main.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { dirname, join } from
|
|
2
|
-
import type { StorybookConfig } from
|
|
1
|
+
import { dirname, join } from 'path';
|
|
2
|
+
import type { StorybookConfig } from '@storybook/sveltekit';
|
|
3
3
|
|
|
4
4
|
function getAbsolutePath(value: string): any {
|
|
5
|
-
return dirname(require.resolve(join(value,
|
|
5
|
+
return dirname(require.resolve(join(value, 'package.json')));
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
const config: StorybookConfig = {
|
|
9
9
|
stories: [
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
'../src/**/*.stories.@(js|ts|svelte)',
|
|
11
|
+
'../src/**/*.mdx'
|
|
12
12
|
],
|
|
13
13
|
|
|
14
14
|
addons: [
|
|
@@ -18,20 +18,17 @@ const config: StorybookConfig = {
|
|
|
18
18
|
legacyTemplate: true
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
|
-
getAbsolutePath(
|
|
22
|
-
getAbsolutePath(
|
|
23
|
-
getAbsolutePath(
|
|
24
|
-
getAbsolutePath(
|
|
25
|
-
getAbsolutePath("@storybook/addon-mdx-gfm")
|
|
21
|
+
getAbsolutePath('@storybook/addon-links'),
|
|
22
|
+
getAbsolutePath('@storybook/addon-essentials'),
|
|
23
|
+
getAbsolutePath('@chromatic-com/storybook'),
|
|
24
|
+
getAbsolutePath('@storybook/experimental-addon-test')
|
|
26
25
|
],
|
|
27
26
|
framework: {
|
|
28
|
-
name:
|
|
29
|
-
options: {}
|
|
27
|
+
name: '@storybook/sveltekit',
|
|
28
|
+
options: {}
|
|
30
29
|
},
|
|
31
30
|
|
|
32
|
-
docs: {
|
|
33
|
-
autodocs: true
|
|
34
|
-
}
|
|
31
|
+
docs: {}
|
|
35
32
|
};
|
|
36
33
|
|
|
37
|
-
export default config;
|
|
34
|
+
export default config;
|
package/.storybook/preview.ts
CHANGED
|
@@ -2,6 +2,9 @@ import type { Preview } from "@storybook/svelte";
|
|
|
2
2
|
|
|
3
3
|
const preview: Preview = {
|
|
4
4
|
parameters: {
|
|
5
|
+
options: {
|
|
6
|
+
storySort: { order: ['About', 'Design Tokens', "Display", "Chart", ["ChartHeader"], "Form", "Deprecated"] },
|
|
7
|
+
},
|
|
5
8
|
controls: {
|
|
6
9
|
matchers: {
|
|
7
10
|
color: /(background|color)$/i,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { beforeAll } from 'vitest';
|
|
2
|
+
import { setProjectAnnotations } from '@storybook/sveltekit';
|
|
3
|
+
import * as projectAnnotations from './preview';
|
|
4
|
+
|
|
5
|
+
// This is an important step to apply the right configuration when testing your stories.
|
|
6
|
+
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
|
|
7
|
+
const project = setProjectAnnotations([projectAnnotations]);
|
|
8
|
+
|
|
9
|
+
beforeAll(project.beforeAll);
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"storybook": "storybook dev -p 6006",
|
|
15
15
|
"start": "storybook dev -p 6006",
|
|
16
16
|
"build-storybook": "storybook build --disable-telemetry",
|
|
17
|
-
"test-storybook": "
|
|
17
|
+
"test-storybook": "vitest run --project=storybook",
|
|
18
18
|
"test-storybook:ci": "concurrently -k -s first -n \"Storybook,Test\" -c \"magenta,blue\" \"npm run build-storybook --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && npm run test-storybook\"",
|
|
19
19
|
"semantic-release": "semantic-release"
|
|
20
20
|
},
|
|
@@ -27,21 +27,23 @@
|
|
|
27
27
|
"@semantic-release/git": "^10.0.1",
|
|
28
28
|
"@semantic-release/npm": "^12.0.1",
|
|
29
29
|
"@storybook/addon-essentials": "^8.6.4",
|
|
30
|
-
"@storybook/addon-interactions": "^8.6.4",
|
|
31
30
|
"@storybook/addon-links": "^8.6.4",
|
|
32
|
-
"@storybook/addon-mdx-gfm": "^8.6.4",
|
|
33
31
|
"@storybook/addon-svelte-csf": "^5.0.0-next.27",
|
|
34
32
|
"@storybook/blocks": "^8.6.4",
|
|
35
33
|
"@storybook/docs-tools": "^8.6.4",
|
|
34
|
+
"@storybook/experimental-addon-test": "^8.6.12",
|
|
36
35
|
"@storybook/svelte": "^8.6.4",
|
|
37
36
|
"@storybook/sveltekit": "^8.6.4",
|
|
38
37
|
"@storybook/test": "^8.6.4",
|
|
39
|
-
"@storybook/test-runner": "^0.
|
|
38
|
+
"@storybook/test-runner": "^0.22.0",
|
|
40
39
|
"@sveltejs/adapter-auto": "^3.0.0",
|
|
41
40
|
"@sveltejs/kit": "^2.0.0",
|
|
42
41
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
42
|
+
"@vitest/browser": "^3.1.1",
|
|
43
|
+
"@vitest/coverage-v8": "^3.1.1",
|
|
43
44
|
"concurrently": "^9.0.1",
|
|
44
45
|
"http-server": "^14.1.1",
|
|
46
|
+
"playwright": "^1.51.1",
|
|
45
47
|
"sass-embedded": "^1.78.0",
|
|
46
48
|
"semantic-release": "^24.1.2",
|
|
47
49
|
"storybook": "^8.6.4",
|
|
@@ -49,6 +51,7 @@
|
|
|
49
51
|
"svelte-check": "^4.0.0",
|
|
50
52
|
"typescript": "^5.0.0",
|
|
51
53
|
"vite": "^6.0.0",
|
|
54
|
+
"vitest": "^3.1.1",
|
|
52
55
|
"wait-on": "^8.0.1"
|
|
53
56
|
},
|
|
54
57
|
"type": "module",
|
|
@@ -64,5 +67,5 @@
|
|
|
64
67
|
"svelte": "./src/index.js"
|
|
65
68
|
}
|
|
66
69
|
},
|
|
67
|
-
"version": "1.
|
|
70
|
+
"version": "1.8.0"
|
|
68
71
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import { userEvent, within, expect } from '@storybook/test';
|
|
4
|
+
import DesignTokens from '../DesignTokens/DesignTokens.svelte';
|
|
5
|
+
|
|
6
|
+
import Autocomplete from './Autocomplete.svelte';
|
|
7
|
+
|
|
8
|
+
const { Story } = defineMeta({
|
|
9
|
+
title: 'Deprecated/Autocomplete',
|
|
10
|
+
component: Autocomplete
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const testData = ['Apples', 'Oranges', 'Pears', 'Peaches', 'Bananas'].map((el) => {
|
|
14
|
+
return {
|
|
15
|
+
value: el,
|
|
16
|
+
label: el,
|
|
17
|
+
details: {}
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<Story
|
|
23
|
+
name="Basic"
|
|
24
|
+
tags={['autodocs']}
|
|
25
|
+
play={async ({ canvasElement, step }) => {
|
|
26
|
+
const canvas = within(canvasElement);
|
|
27
|
+
const input = canvas.getByTestId('autocomplete-input');
|
|
28
|
+
await step('Select using the mouse', async () => {
|
|
29
|
+
await userEvent.click(input);
|
|
30
|
+
expect(input).toHaveFocus();
|
|
31
|
+
await userEvent.keyboard('ba');
|
|
32
|
+
const bananasOption = canvas.getByText('Bananas');
|
|
33
|
+
await userEvent.click(bananasOption);
|
|
34
|
+
expect(input).toHaveValue('Bananas');
|
|
35
|
+
});
|
|
36
|
+
await userEvent.clear(input);
|
|
37
|
+
await step('Select using the keyboard', async () => {
|
|
38
|
+
await userEvent.click(input);
|
|
39
|
+
expect(input).toHaveFocus();
|
|
40
|
+
await userEvent.keyboard('ap');
|
|
41
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
42
|
+
await userEvent.keyboard('{Enter}');
|
|
43
|
+
expect(input).toHaveValue('Apples');
|
|
44
|
+
});
|
|
45
|
+
await userEvent.clear(input);
|
|
46
|
+
}}
|
|
47
|
+
>
|
|
48
|
+
<DesignTokens>
|
|
49
|
+
<div class="container">
|
|
50
|
+
<Autocomplete label="" name="test" data={testData} query="" placeholder="Select a fruit"
|
|
51
|
+
></Autocomplete>
|
|
52
|
+
</div>
|
|
53
|
+
</DesignTokens>
|
|
54
|
+
</Story>
|
|
55
|
+
|
|
56
|
+
<style>
|
|
57
|
+
.container {
|
|
58
|
+
background: var(--violet-dark-5);
|
|
59
|
+
padding: 5%;
|
|
60
|
+
}
|
|
61
|
+
</style>
|
|
@@ -108,8 +108,8 @@ Data should be provided as array of objects. Each object contains the informatio
|
|
|
108
108
|
autocapitalize="off"
|
|
109
109
|
data-testid="autocomplete-input"
|
|
110
110
|
bind:this={inputRef}
|
|
111
|
-
on:keydown={handleKeyDown}
|
|
112
111
|
bind:value={query}
|
|
112
|
+
on:keydown={handleKeyDown}
|
|
113
113
|
on:input={handleInput}
|
|
114
114
|
on:focus={() => {
|
|
115
115
|
isActive = true;
|
|
@@ -150,28 +150,30 @@ Data should be provided as array of objects. Each object contains the informatio
|
|
|
150
150
|
</div>
|
|
151
151
|
|
|
152
152
|
<style lang="scss">
|
|
153
|
-
@
|
|
153
|
+
@use '../styles/base.scss';
|
|
154
154
|
|
|
155
155
|
.autocomplete {
|
|
156
156
|
position: relative;
|
|
157
157
|
display: block;
|
|
158
158
|
color: white;
|
|
159
|
-
|
|
159
|
+
display: flex;
|
|
160
|
+
flex-flow: column;
|
|
160
161
|
label {
|
|
161
162
|
@extend %form-label;
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
input {
|
|
165
166
|
@extend %form-input;
|
|
167
|
+
width: auto;
|
|
166
168
|
}
|
|
167
169
|
|
|
168
170
|
ul {
|
|
169
171
|
position: absolute;
|
|
170
172
|
top: 100%;
|
|
171
173
|
border: 1px solid currentColor;
|
|
172
|
-
background:
|
|
173
|
-
border-bottom-left-radius:
|
|
174
|
-
border-bottom-right-radius:
|
|
174
|
+
background: var(--violet-dark-3);
|
|
175
|
+
border-bottom-left-radius: var(--br-small);
|
|
176
|
+
border-bottom-right-radius: var(--br-small);
|
|
175
177
|
border-top: 0;
|
|
176
178
|
left: 0;
|
|
177
179
|
right: 0;
|
|
@@ -218,7 +220,7 @@ Data should be provided as array of objects. Each object contains the informatio
|
|
|
218
220
|
}
|
|
219
221
|
&:hover,
|
|
220
222
|
&:focus {
|
|
221
|
-
color:
|
|
223
|
+
color: var(--red-base);
|
|
222
224
|
cursor: pointer;
|
|
223
225
|
}
|
|
224
226
|
}
|
package/src/Button/Button.svelte
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
interface ButtonProps {
|
|
3
|
+
as: 'button' | 'a';
|
|
4
|
+
label: string;
|
|
5
|
+
href?: string;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
onclick?: (e: MouseEvent) => any | void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { as = 'button', label, href, disabled, onclick }: ButtonProps = $props();
|
|
6
11
|
</script>
|
|
7
12
|
|
|
8
13
|
{#if as === 'a'}
|
|
9
14
|
<a class="button" class:disabled {href}>{label}</a>
|
|
10
15
|
{:else}
|
|
11
|
-
<button class="button"
|
|
16
|
+
<button class="button" {onclick} {disabled}>{label}</button>
|
|
12
17
|
{/if}
|
|
13
18
|
|
|
14
19
|
<style lang="scss">
|
|
15
|
-
@
|
|
20
|
+
@use '../styles/base.scss';
|
|
16
21
|
.button {
|
|
17
22
|
@extend %copy-bold;
|
|
18
|
-
background:
|
|
23
|
+
background: var(--violet-dark-3);
|
|
19
24
|
display: inline-flex;
|
|
20
25
|
align-items: center;
|
|
21
26
|
justify-self: flex-start;
|
|
@@ -24,11 +29,11 @@
|
|
|
24
29
|
color: white;
|
|
25
30
|
border: 1px solid rgba(white, 0.1);
|
|
26
31
|
box-shadow: 0px 0px 10px rgba(black, 0.05);
|
|
27
|
-
border-radius:
|
|
32
|
+
border-radius: var(--br-small);
|
|
28
33
|
text-shadow: 0px 0px 5px rgba(black, 0.05);
|
|
29
34
|
font-size: 1.2rem;
|
|
30
35
|
text-decoration: none;
|
|
31
|
-
@
|
|
36
|
+
@media (min-width: base.$break-tablet) {
|
|
32
37
|
font-size: 1.4rem;
|
|
33
38
|
}
|
|
34
39
|
&:hover,
|
|
@@ -39,7 +44,6 @@
|
|
|
39
44
|
&.disabled,
|
|
40
45
|
&:disabled {
|
|
41
46
|
opacity: 0.5;
|
|
42
|
-
/* pointer-events: none; */
|
|
43
47
|
}
|
|
44
48
|
}
|
|
45
49
|
</style>
|
|
@@ -1,27 +1,12 @@
|
|
|
1
|
-
<script context="module">
|
|
1
|
+
<script context="module" lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
2
3
|
import Card from './Card.svelte';
|
|
3
4
|
import DesignTokens from '../DesignTokens/DesignTokens.svelte';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
title: '
|
|
6
|
+
const { Story } = defineMeta({
|
|
7
|
+
title: 'Display/Card/Base',
|
|
7
8
|
component: Card
|
|
8
|
-
};
|
|
9
|
-
</script>
|
|
10
|
-
|
|
11
|
-
<script>
|
|
12
|
-
import { Story, Template } from '@storybook/addon-svelte-csf';
|
|
13
|
-
import {
|
|
14
|
-
userEvent,
|
|
15
|
-
within,
|
|
16
|
-
expect,
|
|
17
|
-
getByTestId,
|
|
18
|
-
getAllByLabelText,
|
|
19
|
-
getByText
|
|
20
|
-
} from '@storybook/test';
|
|
21
|
-
import { hasContext } from 'svelte';
|
|
22
|
-
import Input from '../Input/Input.svelte';
|
|
23
|
-
|
|
24
|
-
let component;
|
|
9
|
+
});
|
|
25
10
|
</script>
|
|
26
11
|
|
|
27
12
|
<Story name="Basic card">
|
package/src/Card/Card.svelte
CHANGED
|
@@ -1,18 +1,31 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface CardProps {
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
let { children }: CardProps = $props();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
1
11
|
<div class="card">
|
|
2
|
-
|
|
12
|
+
{#if children}
|
|
13
|
+
{@render children()}
|
|
14
|
+
{/if}
|
|
3
15
|
</div>
|
|
4
16
|
|
|
5
17
|
<style lang="scss">
|
|
6
|
-
@
|
|
18
|
+
@use '../styles/base.scss';
|
|
19
|
+
|
|
7
20
|
.card {
|
|
8
21
|
@extend %copy;
|
|
9
22
|
color: white;
|
|
10
23
|
width: auto;
|
|
11
|
-
max-width:
|
|
24
|
+
max-width: var(--app-max-width);
|
|
12
25
|
background: var(--violet-dark-5);
|
|
13
26
|
border-radius: var(--br-large);
|
|
14
27
|
padding: 1.5rem;
|
|
15
|
-
@
|
|
28
|
+
@media (min-width: base.$break-tablet) {
|
|
16
29
|
padding: 2.5rem;
|
|
17
30
|
}
|
|
18
31
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Story, Meta, Primary, Controls, Stories } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
import * as ChartFooterStories from './ChartFooter.stories.svelte';
|
|
4
|
+
|
|
5
|
+
<Meta of={ChartFooterStories}/>
|
|
6
|
+
|
|
7
|
+
# Chart Footer
|
|
8
|
+
|
|
9
|
+
Standard chart footer.
|
|
10
|
+
|
|
11
|
+
- Nest arbitrary HTML inside component to render your notes
|
|
12
|
+
- Use `one-up` layout unless your footnotes fit two lines or fewer.
|
|
13
|
+
- Use `<Middot/>` to separate sentences
|
|
14
|
+
|
|
15
|
+
<Controls />
|
|
16
|
+
|
|
17
|
+
<Stories/>
|
|
@@ -1,40 +1,32 @@
|
|
|
1
1
|
<script context="module">
|
|
2
|
-
import
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
3
|
import DesignTokens from '../DesignTokens/DesignTokens.svelte';
|
|
4
|
+
|
|
5
|
+
import ChartFooter from './ChartFooter.svelte';
|
|
4
6
|
import Middot from '../Middot/Middot.svelte';
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
const { Story } = defineMeta({
|
|
7
9
|
title: 'Chart/ChartFooter',
|
|
8
10
|
component: ChartFooter
|
|
9
|
-
};
|
|
11
|
+
});
|
|
10
12
|
</script>
|
|
11
13
|
|
|
12
|
-
<
|
|
13
|
-
import { Story } from '@storybook/addon-svelte-csf';
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
<Story name="One-up">
|
|
14
|
+
<Story name="One-up" tags={['autodocs']}>
|
|
17
15
|
<DesignTokens>
|
|
18
16
|
<ChartFooter layout="one-up">
|
|
19
|
-
Daten: <a href="
|
|
20
|
-
>Zensus 2022</a
|
|
21
|
-
>
|
|
17
|
+
Daten: <a href="#1">Zensus 2022</a>
|
|
22
18
|
(Durchschnittsmieten und Einwohnerzahlen),
|
|
23
|
-
<a href="
|
|
24
|
-
|
|
25
|
-
>
|
|
19
|
+
<a href="#1">OpenStreetMap</a> (Kartenmaterial) <Middot /> In unserer Darstellung wurde das Zensusgitter
|
|
20
|
+
auf bewohnte Gebiete begrenzt.
|
|
21
|
+
</ChartFooter>
|
|
26
22
|
</DesignTokens>
|
|
27
23
|
</Story>
|
|
28
24
|
|
|
29
25
|
<Story name="Two-up">
|
|
30
26
|
<DesignTokens>
|
|
31
27
|
<ChartFooter layout="two-up">
|
|
32
|
-
Daten: <a href="
|
|
33
|
-
|
|
34
|
-
>
|
|
35
|
-
(Durchschnittsmieten und Einwohnerzahlen),
|
|
36
|
-
<a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> (Kartenmaterial) <Middot
|
|
37
|
-
/> In unserer Darstellung wurde das Zensusgitter auf bewohnte Gebiete begrenzt.
|
|
28
|
+
Daten: <a href="#1">Zensus 2022</a>
|
|
29
|
+
(Durchschnittsmieten und Einwohnerzahlen)
|
|
38
30
|
</ChartFooter>
|
|
39
31
|
</DesignTokens>
|
|
40
32
|
</Story>
|
|
@@ -1,17 +1,26 @@
|
|
|
1
|
-
<script>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import Logotype from '../Logotype/Logotype.svelte';
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
interface ChartFooterProps {
|
|
6
|
+
layout: 'one-up' | 'two-up';
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { layout = 'one-up', children }: ChartFooterProps = $props();
|
|
4
11
|
</script>
|
|
5
12
|
|
|
6
13
|
<footer class={`container ${layout}`}>
|
|
7
|
-
|
|
8
|
-
<
|
|
9
|
-
|
|
14
|
+
{#if children}
|
|
15
|
+
<div class="notes">
|
|
16
|
+
{@render children()}
|
|
17
|
+
</div>
|
|
18
|
+
{/if}
|
|
10
19
|
<Logotype />
|
|
11
20
|
</footer>
|
|
12
21
|
|
|
13
22
|
<style lang="scss">
|
|
14
|
-
@use '../styles/
|
|
23
|
+
@use '../styles/base.scss';
|
|
15
24
|
|
|
16
25
|
.container {
|
|
17
26
|
gap: 0.5rem;
|
|
@@ -19,21 +28,6 @@
|
|
|
19
28
|
font-family: var(--swr-sans);
|
|
20
29
|
line-height: 1.4;
|
|
21
30
|
}
|
|
22
|
-
.notes {
|
|
23
|
-
width: 100%;
|
|
24
|
-
}
|
|
25
|
-
footer :global(*) {
|
|
26
|
-
margin-bottom: 0;
|
|
27
|
-
color: var(--gray-base);
|
|
28
|
-
}
|
|
29
|
-
footer :global(a),
|
|
30
|
-
footer :global(summary) {
|
|
31
|
-
&:hover,
|
|
32
|
-
&:focus-visible {
|
|
33
|
-
color: rgb(50, 50, 50);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
31
|
.one-up {
|
|
38
32
|
display: flex;
|
|
39
33
|
flex-flow: column;
|
|
@@ -42,10 +36,24 @@
|
|
|
42
36
|
.two-up {
|
|
43
37
|
display: grid;
|
|
44
38
|
grid-template-columns: 1fr;
|
|
45
|
-
@
|
|
39
|
+
@media (min-width: base.$break-phone) {
|
|
46
40
|
grid-template-columns: 2.5fr 1fr;
|
|
47
41
|
align-items: last baseline;
|
|
48
42
|
justify-items: flex-end;
|
|
49
43
|
}
|
|
50
44
|
}
|
|
45
|
+
.notes {
|
|
46
|
+
width: 100%;
|
|
47
|
+
}
|
|
48
|
+
footer :global(*) {
|
|
49
|
+
margin-bottom: 0;
|
|
50
|
+
color: var(--gray-base);
|
|
51
|
+
}
|
|
52
|
+
footer :global(a),
|
|
53
|
+
footer :global(summary) {
|
|
54
|
+
&:hover,
|
|
55
|
+
&:focus-visible {
|
|
56
|
+
color: var(--gray-dark-3);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
51
59
|
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Story, Meta, Primary, Controls, Stories } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
import * as ChartHeaderStories from './ChartHeader.stories.svelte';
|
|
4
|
+
|
|
5
|
+
<Meta of={ChartHeaderStories}/>
|
|
6
|
+
|
|
7
|
+
# Chart header
|
|
8
|
+
|
|
9
|
+
Standard chart header.
|
|
10
|
+
|
|
11
|
+
- Any nested HTML will render under the description (useful for i.e colour keys and interactives controls).
|
|
12
|
+
|
|
13
|
+
<Controls />
|
|
14
|
+
|
|
15
|
+
<Stories/>
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
<script context="module">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import DesignTokens from '../DesignTokens/DesignTokens.svelte';
|
|
4
|
+
|
|
2
5
|
import ChartHeader from './ChartHeader.svelte';
|
|
3
6
|
|
|
4
|
-
|
|
7
|
+
const { Story } = defineMeta({
|
|
5
8
|
title: 'Chart/ChartHeader',
|
|
6
9
|
component: ChartHeader
|
|
7
|
-
};
|
|
8
|
-
</script>
|
|
9
|
-
|
|
10
|
-
<script>
|
|
11
|
-
import { Story } from '@storybook/addon-svelte-csf';
|
|
10
|
+
});
|
|
12
11
|
</script>
|
|
13
12
|
|
|
14
|
-
<Story name="
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
<Story name="Default">
|
|
14
|
+
<DesignTokens>
|
|
15
|
+
<ChartHeader
|
|
16
|
+
title="Mehr über-60-Jährige in allen Berufen"
|
|
17
|
+
subtitle="Veränderung des Anteils der Beschäftigen über 60 Jahren in allen Berufsgruppen seit 2013 (Bundesweit)"
|
|
18
|
+
>
|
|
19
|
+
Arbitrary HTML content can go here
|
|
20
|
+
</ChartHeader>
|
|
21
|
+
</DesignTokens>
|
|
19
22
|
</Story>
|
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
interface ChartHeaderProps {
|
|
5
|
+
title: string;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
}
|
|
9
|
+
let { title, subtitle, children }: ChartHeaderProps = $props();
|
|
6
10
|
</script>
|
|
7
11
|
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
|
|
12
|
+
<header class="container">
|
|
13
|
+
<h2 class="title">{title}</h2>
|
|
14
|
+
{#if subtitle}
|
|
11
15
|
<p class="subtitle">{subtitle}</p>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
{/if}
|
|
17
|
+
{#if children}
|
|
18
|
+
<div class="content">
|
|
19
|
+
{@render children()}
|
|
20
|
+
</div>
|
|
21
|
+
{/if}
|
|
22
|
+
</header>
|
|
18
23
|
|
|
24
|
+
<style>
|
|
19
25
|
.container {
|
|
20
26
|
color: var(--violet-blue);
|
|
21
27
|
font-family: var(--swr-sans);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Title, Story, ColorPalette, ColorItem, Meta, Typeset } from '@storybook/blocks';
|
|
2
|
-
import {shades, scales} from "./Tokens"
|
|
2
|
+
import { shades, scales } from "./Tokens"
|
|
3
3
|
|
|
4
4
|
<Meta title='Design Tokens'/>
|
|
5
5
|
|
|
@@ -7,11 +7,13 @@ import {shades, scales} from "./Tokens"
|
|
|
7
7
|
|
|
8
8
|
## Usage
|
|
9
9
|
|
|
10
|
+
### Web
|
|
11
|
+
|
|
10
12
|
The `<DesignTokens>` component makes colours, type sizes and other design tokens available to its children as CSS variables.
|
|
11
13
|
|
|
12
|
-
```
|
|
14
|
+
```html
|
|
13
15
|
<script>
|
|
14
|
-
import DesignTokens from "components"
|
|
16
|
+
import DesignTokens from "@swr-data-lab/components"
|
|
15
17
|
</script>
|
|
16
18
|
|
|
17
19
|
<DesignTokens>
|
|
@@ -25,14 +27,18 @@ The `<DesignTokens>` component makes colours, type sizes and other design tokens
|
|
|
25
27
|
</style>
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
You can also import
|
|
30
|
+
You can also import `tokens` directly to use them in Javascript:
|
|
29
31
|
|
|
30
|
-
```
|
|
31
|
-
import
|
|
32
|
+
```jsx
|
|
33
|
+
import tokens from "@swr-data-lab/components"
|
|
32
34
|
import { scaleThreshold } from 'd3-scale';
|
|
33
|
-
const sampleScale = scaleThreshold([0, 10], scales.red_blue);
|
|
35
|
+
const sampleScale = scaleThreshold([0, 10], tokens.scales.red_blue);
|
|
34
36
|
```
|
|
35
37
|
|
|
38
|
+
### Figma
|
|
39
|
+
|
|
40
|
+
The tokens on this page are available as a [Figma library](https://www.figma.com/design/Wrd7uUV3GxpNXXkM5ozuHk/Datalab-Design-Tokens?node-id=0-1&t=iOqDxhuMdvEyY8VK-1). This is enabled by default for any file in the [SWR Data Lab team](https://www.figma.com/files/1125823985461580916/team/1415988138343592768).
|
|
41
|
+
|
|
36
42
|
## Available Tokens
|
|
37
43
|
|
|
38
44
|
### Typography
|
|
@@ -40,7 +46,7 @@ const sampleScale = scaleThreshold([0, 10], scales.red_blue);
|
|
|
40
46
|
### Colours
|
|
41
47
|
|
|
42
48
|
<ColorPalette>
|
|
43
|
-
{["violet", "
|
|
49
|
+
{["violet", "plum", "pink", "red", "orange", "yellow", "apple" , "forest","teal", "blue", "gray"].map((el, i) => {
|
|
44
50
|
return(
|
|
45
51
|
<ColorItem
|
|
46
52
|
title={`${el.split("")[0].toUpperCase()}${el.slice(1)}`}
|
|
@@ -59,7 +65,7 @@ const sampleScale = scaleThreshold([0, 10], scales.red_blue);
|
|
|
59
65
|
return(
|
|
60
66
|
<ColorItem
|
|
61
67
|
|
|
62
|
-
title={`${el.split("_").join("
|
|
68
|
+
title={`${el.split("_").map(c => {return c[0].toUpperCase() + c.slice(1)}).join("-")}`}
|
|
63
69
|
subtitle={el}
|
|
64
70
|
colors={scales[el]}
|
|
65
71
|
/>
|