@swr-data-lab/components 1.0.9 → 1.0.10

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/package.json CHANGED
@@ -55,5 +55,5 @@
55
55
  "@semantic-release/npm"
56
56
  ]
57
57
  },
58
- "version": "1.0.9"
58
+ "version": "1.0.10"
59
59
  }
@@ -1,86 +1,90 @@
1
1
  <script lang="ts">
2
- import { createEventDispatcher } from 'svelte';
3
- import Circle from '../assets/icons/times-circle-solid.svg.svelte';
4
-
5
- export let data = [];
6
- export let query = '';
7
- export let placeholder = 'Platzhalter';
8
-
9
-
10
- const sortData = (a, b) => {
11
- return a.value.localeCompare(b.value);
12
- }
13
-
14
- let listRef;
15
- let controlsRef;
16
- let inputRef;
17
- const dispatch = createEventDispatcher();
18
-
19
- let highlightedItemIndex = -1;
20
- $: suggestions = data.sort(sortData).slice(0, 50);
21
- $: isActive = false;
22
-
23
- // Insert clicked item into search input,
24
- // dispatch it as select event and close the dropdown
25
- const handleItemClick = (index) => {
26
- highlightedItemIndex = index;
27
- setSelectedItem(suggestions[highlightedItemIndex]);
28
- };
29
-
30
- const setSelectedItem = (item) => {
31
- query = item.value;
32
- isActive = false;
33
- dispatch('select', { item });
34
- };
35
-
36
- // Register keyboard events
37
- const handleKeyDown = (e) => {
38
- if (e.key === 'ArrowDown') {
39
- e.preventDefault();
40
- highlightedItemIndex =
41
- highlightedItemIndex < suggestions.length - 1 ? highlightedItemIndex + 1 : 0;
42
- const target = listRef.querySelector(`ul li:nth-child(${highlightedItemIndex + 1})`);
43
- target.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
44
- } else if (e.key === 'ArrowUp') {
45
- e.preventDefault();
46
- highlightedItemIndex =
47
- highlightedItemIndex > 0 ? highlightedItemIndex - 1 : suggestions.length - 1;
48
- const target = listRef.querySelector(`ul li:nth-child(${highlightedItemIndex + 1})`);
49
- target.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
50
- } else if (e.key === 'Enter') {
51
- if (highlightedItemIndex > -1){
52
- setSelectedItem(suggestions[highlightedItemIndex]);
53
- isActive = false;
54
- }
55
- }
56
- };
57
-
58
- const handleClear = (e) => {
59
- query = '';
60
- inputRef.focus()
61
- setSuggestions()
62
- dispatch('select', {
63
- item: null
64
- });
65
- };
66
-
67
-
68
- const setSuggestions = () => {
69
- suggestions = data.filter((el) =>{
70
- return el.value.toLowerCase().startsWith(query.toLowerCase())
71
- }).sort(sortData);
72
- }
73
-
74
- // update dropdown list if input value changes
75
- const handleInput = () => {
76
- isActive = true;
77
- if (query.length === 0){
78
- suggestions = data
79
- } else {
80
- setSuggestions()
81
- highlightedItemIndex = -1;
82
- }
83
- }
2
+ import { createEventDispatcher } from 'svelte';
3
+ import Circle from '../assets/times-circle-solid.svg.svelte';
4
+
5
+ export let data = [];
6
+ export let query: string = '';
7
+ export let placeholder: string = 'Platzhalter';
8
+ export let label: string;
9
+ export let name: string;
10
+
11
+ const sortData = (a, b) => {
12
+ return a.value.localeCompare(b.value);
13
+ };
14
+
15
+ let listRef;
16
+ let inputRef;
17
+ let controlsRef;
18
+ const dispatch = createEventDispatcher();
19
+ const maxSuggestions = 100;
20
+
21
+ let highlightedItemIndex = -1;
22
+ $: suggestions = data.sort(sortData).slice(0, maxSuggestions);
23
+ $: isActive = false;
24
+
25
+ // Insert clicked item into search input,
26
+ // dispatch it as select event and close the dropdown
27
+ const handleItemClick = (index) => {
28
+ highlightedItemIndex = index;
29
+ setSelectedItem(suggestions[highlightedItemIndex]);
30
+ };
31
+
32
+ const setSelectedItem = (item) => {
33
+ query = item.value;
34
+ isActive = false;
35
+ dispatch('select', { item });
36
+ };
37
+
38
+ // Register keyboard events
39
+ const handleKeyDown = (e) => {
40
+ if (e.key === 'ArrowDown') {
41
+ e.preventDefault();
42
+ highlightedItemIndex =
43
+ highlightedItemIndex < suggestions.length - 1 ? highlightedItemIndex + 1 : 0;
44
+ const target = listRef.querySelector(`ul li:nth-child(${highlightedItemIndex + 1})`);
45
+ target.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
46
+ } else if (e.key === 'ArrowUp') {
47
+ e.preventDefault();
48
+ highlightedItemIndex =
49
+ highlightedItemIndex > 0 ? highlightedItemIndex - 1 : suggestions.length - 1;
50
+ const target = listRef.querySelector(`ul li:nth-child(${highlightedItemIndex + 1})`);
51
+ target.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
52
+ } else if (e.key === 'Enter') {
53
+ if (highlightedItemIndex > -1) {
54
+ setSelectedItem(suggestions[highlightedItemIndex]);
55
+ isActive = false;
56
+ }
57
+ }
58
+ };
59
+
60
+ const handleClear = () => {
61
+ query = '';
62
+ inputRef.focus();
63
+ setSuggestions();
64
+ dispatch('select', {
65
+ item: null
66
+ });
67
+ };
68
+
69
+ const setSuggestions = () => {
70
+ suggestions = data
71
+ .filter((el) => {
72
+ return el.value.toLowerCase().startsWith(query.toLowerCase());
73
+ })
74
+ .slice(0, maxSuggestions)
75
+ .sort(sortData);
76
+ };
77
+
78
+ // update dropdown list if input value changes
79
+ const handleInput = () => {
80
+ isActive = true;
81
+ if (query.length === 0) {
82
+ suggestions = data;
83
+ } else {
84
+ setSuggestions();
85
+ highlightedItemIndex = -1;
86
+ }
87
+ };
84
88
  </script>
85
89
 
86
90
  <!--
@@ -93,140 +97,140 @@ Data should be provided as array of objects. Each object contains the informatio
93
97
  @component
94
98
  -->
95
99
 
96
- <div class="autocomplete">
97
- <input
98
- type="text"
99
- {placeholder}
100
- autocomplete="off"
101
- autocorrect="off"
102
- autocapitalize="off"
103
- data-testid="autocomplete-input"
104
- bind:this={inputRef}
105
- on:keydown={handleKeyDown}
106
- bind:value={query}
107
- on:input={handleInput}
108
- on:focus={() => {
109
- isActive = true;
110
- }}
111
- on:blur={(e) => {
112
- if (listRef.contains(e.relatedTarget)){
113
- window.setTimeout(()=>{
114
- isActive = false;
115
- }, 100)
116
- } else if (!controlsRef.contains(e.relatedTarget)){
117
- isActive = false
118
- }
119
- }}
120
- />
121
-
122
- <ul tabindex="-1" bind:this={listRef} class:active={isActive}>
123
- {#each suggestions as item, i (item.value)}
124
- <li>
125
- <button
126
- class={`item ${i === highlightedItemIndex ? 'active' : ''}`}
127
- tabindex="-1"
128
- type="button"
129
- on:click={(e) => {
130
- e.preventDefault();
131
- handleItemClick(i);
132
- }}
133
- >
134
- {item.label}
135
- </button>
136
- </li>
137
- {/each}
138
- </ul>
139
- <div class="controls" bind:this={controlsRef}>
140
- <button type="button" on:click={handleClear} class="clear" class:active={query.length > 0}>
141
- <Circle />
142
- </button>
143
- </div>
100
+ <div class="autocomplete" class:active={isActive}>
101
+ <label for={name}>{label}</label>
102
+ <input
103
+ type="text"
104
+ {name}
105
+ {placeholder}
106
+ autocomplete="off"
107
+ autocorrect="off"
108
+ autocapitalize="off"
109
+ data-testid="autocomplete-input"
110
+ bind:this={inputRef}
111
+ on:keydown={handleKeyDown}
112
+ bind:value={query}
113
+ on:input={handleInput}
114
+ on:focus={() => {
115
+ isActive = true;
116
+ }}
117
+ on:blur={(e) => {
118
+ if (listRef.contains(e.relatedTarget)) {
119
+ window.setTimeout(() => {
120
+ isActive = false;
121
+ }, 100);
122
+ } else if (!controlsRef.contains(e.relatedTarget)) {
123
+ isActive = false;
124
+ }
125
+ }}
126
+ />
127
+
128
+ <ul tabindex="-1" bind:this={listRef}>
129
+ {#each suggestions as item, i (item.value)}
130
+ <li>
131
+ <button
132
+ class={`item ${i === highlightedItemIndex ? 'active' : ''}`}
133
+ tabindex="-1"
134
+ type="button"
135
+ on:click={(e) => {
136
+ e.preventDefault();
137
+ handleItemClick(i);
138
+ }}
139
+ >
140
+ {item.label}
141
+ </button>
142
+ </li>
143
+ {/each}
144
+ </ul>
145
+ <div class="controls" bind:this={controlsRef}>
146
+ <button type="button" on:click={handleClear} class="clear" class:active={query.length > 0}>
147
+ <Circle />
148
+ </button>
149
+ </div>
144
150
  </div>
145
151
 
146
152
  <style lang="scss">
147
- @import '../styles/scss/base.scss';
148
-
149
- .autocomplete {
150
- position: relative;
151
- display: block;
152
- color: white;
153
-
154
- input {
155
- @extend %copy;
156
- border: 1px solid black;
157
- border-radius: $border-radius-input;
158
- background: transparent;
159
- padding: 0 0.5em;
160
- height: $input-height;
161
- margin: 0;
162
- display: block;
163
- width: 100%;
164
- &:focus-visible {
165
- border-bottom-right-radius: 0;
166
- border-bottom-left-radius: 0;
167
- }
168
- }
169
- input[type='text'] {
170
- text-size-adjust: none;
171
- }
172
-
173
- ul {
174
- position: absolute;
175
- top: 100%;
176
- border: 1px solid black;
177
- border-bottom-left-radius: $border-radius-input;
178
- border-bottom-right-radius: $border-radius-input;
179
- border-top: 0;
180
- left: 0;
181
- right: 0;
182
- max-height: 10rem;
183
- overflow-y: scroll;
184
- z-index: 1000;
185
- opacity: 0;
186
- transition: 100ms;
187
- pointer-events: none;
188
- &:empty {
189
- box-shadow: none;
190
- }
191
- &.active {
192
- opacity: 1;
193
- pointer-events: all;
194
- }
195
-
196
- .item {
197
- @extend %caption;
198
- padding: 0.5em;
199
- width: 100%;
200
- background: transparent;
201
- border: 0;
202
- text-align: left;
203
- border-bottom: 1px solid rgba(black, 0.5);
204
- cursor: pointer;
205
- &.active, &:hover {
206
- text-decoration: underline;
207
- background-color: rgba(black, .1);
208
- }
209
- }
210
- }
211
-
212
- .clear {
213
- position: absolute;
214
- transform: translateY(-50%);
215
- top: 50%;
216
- right: 0.75rem;
217
- width: 1.2rem;
218
- height: 1.2rem;
219
- background: transparent;
220
- border: 0;
221
- display: none;
222
- &.active {
223
- display: block;
224
- }
225
- &:hover,
226
- &:focus {
227
- color: $orange--1;
228
- cursor: pointer;
229
- }
230
- }
231
- }
153
+ @import '../styles/base.scss';
154
+
155
+ .autocomplete {
156
+ position: relative;
157
+ display: block;
158
+ color: white;
159
+
160
+ label {
161
+ @extend %form-label;
162
+ }
163
+
164
+ input {
165
+ @extend %form-input;
166
+ }
167
+
168
+ ul {
169
+ position: absolute;
170
+ top: 100%;
171
+ border: 1px solid currentColor;
172
+ background: $reanimation-violetblue;
173
+ border-bottom-left-radius: $border-radius-input;
174
+ border-bottom-right-radius: $border-radius-input;
175
+ border-top: 0;
176
+ left: 0;
177
+ right: 0;
178
+ max-height: 10rem;
179
+ overflow-y: scroll;
180
+ z-index: 1000;
181
+ opacity: 0;
182
+ transition: 100ms;
183
+ pointer-events: none;
184
+ &:empty {
185
+ box-shadow: none;
186
+ }
187
+
188
+ .item {
189
+ @extend %caption;
190
+ padding: 0.5em;
191
+ width: 100%;
192
+ background: transparent;
193
+ border: 0;
194
+ text-align: left;
195
+ color: currentColor;
196
+ border-bottom: 1px solid rgba(white, 0.25);
197
+ cursor: pointer;
198
+ &.active,
199
+ &:hover {
200
+ text-decoration: underline;
201
+ background-color: rgba(white, 0.05);
202
+ }
203
+ }
204
+ }
205
+
206
+ .clear {
207
+ position: absolute;
208
+ top: 50%;
209
+ right: 0.75rem;
210
+ width: 1.2rem;
211
+ height: 1.2rem;
212
+ background: transparent;
213
+ border: 0;
214
+ display: none;
215
+ color: white;
216
+ &.active {
217
+ display: block;
218
+ }
219
+ &:hover,
220
+ &:focus {
221
+ color: $orange;
222
+ cursor: pointer;
223
+ }
224
+ }
225
+ &.active {
226
+ ul {
227
+ opacity: 1;
228
+ pointer-events: all;
229
+ }
230
+ input {
231
+ border-bottom-right-radius: 0;
232
+ border-bottom-left-radius: 0;
233
+ }
234
+ }
235
+ }
232
236
  </style>
@@ -1,2 +1,2 @@
1
- import AutoComplete from "./Autocomplete.svelte"
2
- export default AutoComplete
1
+ import Autocomplete from './Autocomplete.svelte';
2
+ export default Autocomplete;
@@ -0,0 +1,45 @@
1
+ <script lang="ts">
2
+ export let as: string = 'button';
3
+ export let label: string = '';
4
+ export let href: string = '';
5
+ export let disabled: boolean = false;
6
+ </script>
7
+
8
+ {#if as === 'a'}
9
+ <a class="button" class:disabled {href}>{label}</a>
10
+ {:else}
11
+ <button class="button" on:click {disabled}>{label}</button>
12
+ {/if}
13
+
14
+ <style lang="scss">
15
+ @import '../styles/base.scss';
16
+ .button {
17
+ @extend %copy-bold;
18
+ background: $reanimation-violet;
19
+ display: inline-flex;
20
+ align-items: center;
21
+ justify-self: flex-start;
22
+ padding: 0.25em 1.25em;
23
+ padding-bottom: 0.35em;
24
+ color: white;
25
+ border: 1px solid rgba(white, 0.1);
26
+ box-shadow: 0px 0px 10px rgba(black, 0.05);
27
+ border-radius: $border-radius-input;
28
+ text-shadow: 0px 0px 5px rgba(black, 0.05);
29
+ font-size: 1.2rem;
30
+ text-decoration: none;
31
+ @include bp($break-tablet) {
32
+ font-size: 1.4rem;
33
+ }
34
+ &:hover,
35
+ &:focus-visible {
36
+ text-decoration: underline;
37
+ text-underline-offset: 0.15em;
38
+ }
39
+ &.disabled,
40
+ &:disabled {
41
+ opacity: 0.5;
42
+ /* pointer-events: none; */
43
+ }
44
+ }
45
+ </style>
@@ -0,0 +1,2 @@
1
+ import Button from './Button.svelte';
2
+ export default Button;
@@ -0,0 +1,19 @@
1
+ <div class="card">
2
+ <slot />
3
+ </div>
4
+
5
+ <style lang="scss">
6
+ @import '../styles/base.scss';
7
+ .card {
8
+ width: auto;
9
+ max-width: $app-max-width;
10
+ color: white;
11
+ background: $reanimation-violetblue;
12
+ border-radius: $border-radius-container;
13
+ margin: 0 1rem;
14
+ padding: 1.5rem;
15
+ @include bp($break-tablet) {
16
+ padding: 2.5rem;
17
+ }
18
+ }
19
+ </style>
@@ -0,0 +1,2 @@
1
+ import Card from './Card.svelte';
2
+ export default Card;
@@ -0,0 +1,12 @@
1
+ <div>
2
+ <slot />
3
+ </div>
4
+
5
+ <style lang="scss">
6
+ @import '../styles/base.scss';
7
+ :host {
8
+ --swr-sans: #{$swr-sans};
9
+ --swr-text: #{$swr-text};
10
+ --orange: #{$orange};
11
+ }
12
+ </style>
@@ -0,0 +1,2 @@
1
+ import Container from './Container.svelte';
2
+ export default Container;
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ export let label: string = '';
3
+ export let name: string = '';
4
+ export let placeholder: string = '';
5
+ export let value: string = '';
6
+ </script>
7
+
8
+ <div class="container">
9
+ <label for={name}>{label}</label>
10
+ <input {name} type="text" {placeholder} bind:value />
11
+ </div>
12
+
13
+ <style lang="scss">
14
+ @import '../styles/base.scss';
15
+
16
+ label {
17
+ @extend %form-label;
18
+ }
19
+ input {
20
+ @extend %form-input;
21
+ }
22
+ </style>
@@ -0,0 +1,2 @@
1
+ import Input from './Input.svelte';
2
+ export default Input;
@@ -1,20 +1,21 @@
1
1
  <script lang="ts">
2
+ export let label: string = '';
2
3
 
3
- // The options available in the switcher.
4
- export let options: string[] = [];
5
-
6
- // Machine-readable name for the form field. Should be unique to other fields in the form.
7
- export let groupName: string = "";
8
-
9
- // The currently selected option
10
- export let value : string = options[0];
11
-
12
- function optionToID(o:string) {
13
- // TODO: This should use $id() when it comes out, so
14
- // input IDs are guaranteed unique across the app
15
- // See: https://github.com/sveltejs/svelte/issues/13108
16
- return `${groupName}-option-${o.replace(/ /g, '-').toLowerCase()}`;
17
- }
4
+ // The options available in the switcher.
5
+ export let options: string[] = [];
6
+
7
+ // Machine-readable name for the form field. Should be unique to other fields in the form.
8
+ export let groupName: string = '';
9
+
10
+ // The currently selected option
11
+ export let value: string = options[0];
12
+
13
+ function optionToID(o: string) {
14
+ // TODO: This should use $id() when it comes out, so
15
+ // input IDs are guaranteed unique across the app
16
+ // See: https://github.com/sveltejs/svelte/issues/13108
17
+ return `${groupName}-option-${o.replace(/ /g, '-').toLowerCase()}`;
18
+ }
18
19
  </script>
19
20
 
20
21
  <!--
@@ -22,89 +23,98 @@ Radio-like form component to choose exactly one of a given set of options.
22
23
  @component
23
24
  -->
24
25
 
25
- <ol class="container">
26
- {#each options as o (o)}
27
- <li class:is-selected={o === value}>
28
- <label for={optionToID(o)}>
29
- {o}
30
- <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
31
- <path
32
- d="M19.7054 6.29119C20.0969 6.68077 20.0984 7.31393 19.7088 7.7054L9.75697 17.7054C9.56928 17.894 9.31416 18 9.04809 18C8.78201 18 8.52691 17.8939 8.33925 17.7053L4.2911 13.6365C3.90157 13.245 3.90318 12.6118 4.2947 12.2223C4.68621 11.8327 5.31938 11.8344 5.7089 12.2259L9.04825 15.5823L18.2912 6.2946C18.6808 5.90314 19.3139 5.90161 19.7054 6.29119Z"
33
- fill="currentColor"
34
- />
35
- </svg>
36
- </label>
37
- <input id={optionToID(o)} name={groupName} value={o} type="radio" bind:group={value} />
38
- </li>
39
- {/each}
40
- </ol>
26
+ <fieldset class="container">
27
+ <legend>{label}</legend>
28
+ <ul>
29
+ {#each options as o (o)}
30
+ <li class:is-selected={o === value}>
31
+ <label for={optionToID(o)}>
32
+ {o}
33
+ <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
34
+ <path
35
+ d="M19.7054 6.29119C20.0969 6.68077 20.0984 7.31393 19.7088 7.7054L9.75697 17.7054C9.56928 17.894 9.31416 18 9.04809 18C8.78201 18 8.52691 17.8939 8.33925 17.7053L4.2911 13.6365C3.90157 13.245 3.90318 12.6118 4.2947 12.2223C4.68621 11.8327 5.31938 11.8344 5.7089 12.2259L9.04825 15.5823L18.2912 6.2946C18.6808 5.90314 19.3139 5.90161 19.7054 6.29119Z"
36
+ fill="currentColor"
37
+ />
38
+ </svg>
39
+ </label>
40
+ <input id={optionToID(o)} name={groupName} value={o} type="radio" bind:group={value} />
41
+ </li>
42
+ {/each}
43
+ </ul>
44
+ </fieldset>
41
45
 
42
46
  <style lang="scss">
43
- @import "../styles/scss/base.scss";
47
+ @import '../styles/base.scss';
48
+
49
+ fieldset {
50
+ border: 0;
51
+ }
52
+
53
+ legend {
54
+ @extend %form-label;
55
+ }
44
56
 
45
- .container {
46
- width: 100%;
47
- display: flex;
48
- flex-direction: row;
49
- border-radius: $border-radius-input;
50
- overflow: hidden;
51
- padding: 0;
52
- margin: 0;
53
- overflow: hidden;
54
- border: 1px solid black;
55
- outline-offset: 2px;
57
+ ul {
58
+ width: 100%;
59
+ display: flex;
60
+ flex-direction: row;
61
+ border-radius: $border-radius-input;
62
+ overflow: hidden;
63
+ padding: 0;
64
+ margin: 0;
65
+ overflow: hidden;
66
+ border: 1px solid currentColor;
56
67
 
57
- &:focus-within,
58
- &:active {
59
- outline: 2px solid lightgray;
60
- }
61
- }
62
- li {
63
- display: contents;
64
- &:last-child label {
65
- border-right: 0;
66
- }
67
- }
68
- input {
69
- position: absolute;
70
- left: -999px;
71
- }
72
- label {
73
- @extend %copy;
74
- line-height: 1;
75
- padding-top: 0.1em;
76
- height: $input-height;
77
- cursor: pointer;
78
- margin: 0;
79
- flex-basis: 0;
80
- flex-grow: 1;
81
- align-items: center;
82
- display: flex;
83
- justify-content: center;
84
- color: black;
85
- position: relative;
86
- transition: $transition-fast;
87
- text-underline-offset: 0.1em;
88
- border-right: 1px solid black;
89
- &:hover,
90
- &:focus-visible {
91
- text-decoration: underline;
92
- }
93
- svg {
94
- position: absolute;
95
- left: 0.65em;
96
- width: 1em;
97
- height: auto;
98
- opacity: 0;
99
- transition: $transition-fast;
100
- display: block;
101
- }
102
- .is-selected & {
103
- background: black;
104
- color: white;
105
- svg {
106
- opacity: 1;
107
- }
108
- }
109
- }
68
+ &:focus-within,
69
+ &:active {
70
+ outline: 3px solid rgba(white, 0.5);
71
+ }
72
+ }
73
+ li {
74
+ display: contents;
75
+ &:last-child label {
76
+ border-right: 0;
77
+ }
78
+ }
79
+ input {
80
+ position: absolute;
81
+ left: -999px;
82
+ }
83
+ label {
84
+ @extend %copy;
85
+ line-height: 1;
86
+ height: $input-height;
87
+ cursor: pointer;
88
+ margin: 0;
89
+ flex-basis: 0;
90
+ flex-grow: 1;
91
+ align-items: center;
92
+ display: flex;
93
+ justify-content: center;
94
+ color: currentColor;
95
+ position: relative;
96
+ transition: $transition-fast;
97
+ text-underline-offset: 0.1em;
98
+ border-right: 1px solid currentColor;
99
+ &:hover,
100
+ &:focus-visible {
101
+ text-decoration: underline;
102
+ }
103
+ svg {
104
+ position: absolute;
105
+ left: 0.65em;
106
+ width: 1em;
107
+ height: auto;
108
+ opacity: 0;
109
+ transition: $transition-fast;
110
+ display: block;
111
+ }
112
+ .is-selected & {
113
+ background: white;
114
+ color: black;
115
+ svg {
116
+ opacity: 1;
117
+ }
118
+ }
119
+ }
110
120
  </style>
@@ -0,0 +1,14 @@
1
+ <svg
2
+ aria-hidden="true"
3
+ focusable="false"
4
+ data-prefix="fas"
5
+ data-icon="times-circle"
6
+ class="svg-inline--fa fa-times-circle fa-w-16"
7
+ role="img"
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ viewBox="0 0 512 512"
10
+ ><path
11
+ fill="currentColor"
12
+ d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"
13
+ ></path></svg
14
+ >
@@ -0,0 +1,49 @@
1
+ %caption {
2
+ font-family: $swr-sans;
3
+ font-size: 0.9rem;
4
+ line-height: 1;
5
+ letter-spacing: 0.0045em;
6
+ }
7
+
8
+ %caption-bold {
9
+ @extend %caption;
10
+ font-weight: 600;
11
+ }
12
+
13
+ %form-label {
14
+ @extend %caption;
15
+ display: block;
16
+ margin-bottom: 0.5em;
17
+ }
18
+
19
+ %copy {
20
+ font-family: $swr-sans;
21
+ font-size: 1.1rem;
22
+ line-height: 1.45;
23
+ letter-spacing: 0.0045em;
24
+ }
25
+
26
+ %copy-bold {
27
+ @extend %copy;
28
+ font-weight: 600;
29
+ }
30
+
31
+ %form-input {
32
+ @extend %copy;
33
+ height: $input-height;
34
+ width: 100%;
35
+ border: 1px solid currentColor;
36
+ border-radius: $border-radius-input;
37
+ background: transparent;
38
+ padding: 0 0.5em;
39
+ padding-top: 0.1em;
40
+ color: currentColor;
41
+ height: $input-height;
42
+ margin: 0;
43
+ display: block;
44
+ width: 100%;
45
+ text-size-adjust: none;
46
+ &:focus-visible {
47
+ outline: 4px solid rgba(white, 0.4);
48
+ }
49
+ }
@@ -0,0 +1,31 @@
1
+ $reanimation-black: #0c0c0c;
2
+ $reanimation-violetblue: #1d0b40;
3
+ $reanimation-violetblue-hover: #2d155d;
4
+ $reanimation-violet: #5920c0;
5
+ $reanimation-blue: #3053d9;
6
+ $reanimation-warmgrey: #dbd5cd;
7
+ $reanimation-activeorange: #ff3300;
8
+ $orange: #ff3300;
9
+
10
+ $border-radius-container: 8px;
11
+ $border-radius-input: 4px;
12
+ $input-height: 2.5rem;
13
+ $app-max-width: 40rem;
14
+
15
+ $swr-sans: 'SWR-VAR-Sans', serif;
16
+ $swr-text: 'SWR-VAR-Text', serif;
17
+
18
+ $transition-fast: 150ms;
19
+
20
+ // Breakpoints
21
+ $break-phone: 510px;
22
+ $break-tablet: 992px;
23
+ $break-desktop-small: 1200px;
24
+ $break-desktop-large: 1400px;
25
+ $break-desktop-xl: 1400px;
26
+
27
+ @mixin bp($point) {
28
+ @media (min-width: $point) {
29
+ @content;
30
+ }
31
+ }
@@ -0,0 +1,8 @@
1
+ @import 'vars';
2
+ @import 'typography';
3
+
4
+ * {
5
+ margin: 0;
6
+ padding: 0;
7
+ box-sizing: border-box;
8
+ }
@@ -1 +0,0 @@
1
- <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="times-circle" class="svg-inline--fa fa-times-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"></path></svg>
@@ -1,77 +0,0 @@
1
- body {
2
- --petrol--1: #00677f;
3
- --eisblau--1: #00dbd7;
4
- --türkisblau--1: #007e8f;
5
- --dunkelblau--1: #0a1e3c;
6
- --orange--1: #ff4e3c;
7
- --purpur--1: #5c267e;
8
- --rosarot--1: #ff003c;
9
- --pink--1: #ff0096;
10
- }
11
-
12
- body[data-stationid="swraktuell"] {
13
- --swrdata-color-primary: var(--petrol--1);
14
- --swrdata-color-highlight: var(--orange--1);
15
- }
16
-
17
- body[data-stationid="swr3"] {
18
- --swrdata-color-primary: var(--rosarot--1);
19
- --swrdata-color-highlight: var(--pink--1);
20
- }
21
-
22
- /* load fonts for swr3 */
23
-
24
- @font-face {
25
- font-family: TheMix;
26
- src:
27
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-3_Light.woff2) format("woff2"),
28
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-3_Light.woff) format("woff");
29
- font-weight: 300;
30
- font-display: swap;
31
- font-style: normal;
32
- }
33
- @font-face {
34
- font-family: TheMix;
35
- src:
36
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-4_SemiLight.woff2) format("woff2"),
37
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-4_SemiLight.woff) format("woff");
38
- font-weight: 400;
39
- font-display: swap;
40
- font-style: normal;
41
- }
42
- @font-face {
43
- font-family: TheMix;
44
- src:
45
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-5_Plain.woff2) format("woff2"),
46
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-5_Plain.woff) format("woff");
47
- font-weight: 500;
48
- font-display: swap;
49
- font-style: normal;
50
- }
51
- @font-face {
52
- font-family: TheMix;
53
- src:
54
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-6_SemiBold.woff2) format("woff2"),
55
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-6_SemiBold.woff) format("woff");
56
- font-weight: 600;
57
- font-display: swap;
58
- font-style: normal;
59
- }
60
- @font-face {
61
- font-family: TheMix;
62
- src:
63
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-7_Bold.woff2) format("woff2"),
64
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-7_Bold.woff) format("woff");
65
- font-weight: 700;
66
- font-display: swap;
67
- font-style: normal;
68
- }
69
- @font-face {
70
- font-family: TheMix;
71
- src:
72
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-8_ExtraBold.woff2) format("woff2"),
73
- url(https://www.swr.de/assets/fonts/transfonter/TheMixC5-8_ExtraBold.woff) format("woff");
74
- font-weight: 800;
75
- font-display: swap;
76
- font-style: normal;
77
- }
@@ -1,87 +0,0 @@
1
- // swr main colors
2
- $petrol--1: #05556a;
3
- $eisblau--1: #00dbd7;
4
- $dunkelblau--1: #0a1e3c;
5
- $orange--1: #ff4e3c;
6
- $purpur--1: #5c267e;
7
- $rosarot--1: #ff003c;
8
-
9
- // impfungen
10
- $erst: #929292;
11
- $voll: rgb(0, 150, 160);
12
- $boost: #05556a;
13
-
14
- // min max
15
- $inzidenz--max: #05556a;
16
- $inzidenz--min: transparentize($inzidenz--max, 0.1);
17
-
18
- // scale with 10 options
19
- $inzidenz--10: rgb(4, 52, 58);
20
- $inzidenz--9: rgb(5, 70, 84);
21
- $inzidenz--8: rgb(5, 92, 112);
22
- $inzidenz--7: rgb(4, 128, 142);
23
- $inzidenz--6: rgb(1, 165, 172);
24
- $inzidenz--5: rgb(1, 203, 203);
25
- $inzidenz--4: rgb(103, 229, 228);
26
- $inzidenz--3: rgb(177, 245, 250);
27
- $inzidenz--2: rgb(203, 245, 250);
28
- $inzidenz--1: rgb(218, 241, 244);
29
-
30
- $inzidenz-1--8: rgb(4, 52, 58);
31
- $inzidenz-1--7: rgb(5, 69, 82);
32
- $inzidenz-1--6: rgb(5, 86, 107);
33
- $inzidenz-1--5: rgb(2, 122, 137);
34
- $inzidenz-1--4: rgb(0, 150, 160);
35
- $inzidenz-1--3: rgb(0, 218, 214);
36
- $inzidenz-1--2: rgb(194, 247, 254);
37
- $inzidenz-1--1: rgb(218, 241, 244);
38
-
39
- // Spritpreise
40
- $diesel-min: #f9ebb7;
41
- $diesel-max: #b7950d;
42
- $e5-min: #d0f0f1;
43
- $e5-max: #05556a;
44
- $e10-min: #ebd9e1;
45
- $e10-max: #7e2d41;
46
-
47
- // extra colors
48
- $hellgrau--1: #b8b8b8;
49
- $hellgrau--2: #929292;
50
- $hellgrau--3: #7b7b7b;
51
- $hellgrau--4: #494949;
52
- $schwarzgrau--1: #383838;
53
- $schwarzgrau--4: #161616;
54
-
55
- $schatten-grau: #eeeeee;
56
- $hintergrund-grau: #f5f5f5;
57
-
58
- body {
59
- --petrol--1: #00677f;
60
- --eisblau--1: #00dbd7;
61
- --türkisblau--1: #007e8f;
62
- --dunkelblau--1: #0a1e3c;
63
- --orange--1: #ff4e3c;
64
- --purpur--1: #5c267e;
65
-
66
- --rosarot--1: #ff003c;
67
- --pink--1: #ff0096;
68
- }
69
-
70
- body[stationid='swraktuell'] {
71
- --swrdata-color-primary: var(--petrol--1);
72
- --swrdata-color-highlight: var(--orange--1);
73
- }
74
-
75
- body[stationid='swr3'] {
76
- --swrdata-color-primary: var(--rosarot--1);
77
- --swrdata-color-highlight: var;
78
- }
79
-
80
- :export {
81
- dieselMin: $diesel-min;
82
- dieselMax: $diesel-max;
83
- e5Min: $e5-min;
84
- e5Max: $e5-max;
85
- e10Min: $e10-min;
86
- e10Max: $e10-max;
87
- }
@@ -1,43 +0,0 @@
1
- $swr-inner-container-width-m: 490px;
2
- $swr-inner-container-width-l: 730px;
3
- $swr-inner-container-width-xl: 976px;
4
- $swr-padding-removal: 20px;
5
- $reanimation-width: 1440px;
6
- $reanimation-max-width: 1440px;
7
- $reanimation-max-text-width: 864px;
8
- $reanimation-ff-text: "SWR-VAR-Text";
9
- $reanimation-ff-sans: "SWR-VAR-Sans";
10
- $reanimation-ff-slab: "SWR-VAR-Slab";
11
- $transition-fast: 150ms;
12
-
13
- // Padding
14
- $reanimation-padding-s: 16px;
15
- $reanimation-padding-m: 32px;
16
- $reanimation-padding-l: 48px;
17
- $reanimation-padding-xl: 64px;
18
- $reanimation-padding-xxl: 96px;
19
- $reanimation-padding-xxxl: 112px;
20
-
21
- // Breakpoints
22
- $break-phone: 510px;
23
- $break-tablet: 992px;
24
- $break-desktop-small: 1200px;
25
- $break-desktop-large: 1400px;
26
- $break-desktop-xl: 1400px;
27
-
28
- // Colors
29
- $reanimation-black: #0c0c0c;
30
- $reanimation-violetblue: #1d0b40;
31
- $reanimation-violetblue-hover: #2d155d;
32
- $reanimation-violet: #5920c0;
33
- $reanimation-blue: #3053d9;
34
- $reanimation-warmgrey: #dbd5cd;
35
- $reanimation-activeorange: #ff3300;
36
-
37
- // Breakout radius
38
- $border-radius-box: 8px;
39
- $border-radius-input: 4px;
40
-
41
- // max container width
42
- $app-max-width: 650px !default;
43
- $input-height: 2.35em;
@@ -1,30 +0,0 @@
1
- @mixin flex-center {
2
- display: flex;
3
- flex-direction: column;
4
- justify-content: center;
5
- align-items: center;
6
- }
7
-
8
- @mixin respond-min($width) {
9
- @media screen and (min-width: $width) {
10
- @content;
11
- }
12
- }
13
-
14
- @mixin respond-max($width) {
15
- @media screen and (max-width: $width) {
16
- @content;
17
- }
18
- }
19
-
20
- @mixin hover {
21
- @media (hover: hover) {
22
- &:hover {
23
- @content;
24
- }
25
- }
26
- &:active {
27
- // &:focus {
28
- @content;
29
- }
30
- }
@@ -1,49 +0,0 @@
1
- @use 'sass:math';
2
-
3
- @font-face {
4
- font-family: 'SWR-VAR-Sans';
5
- font-weight: 400 600 700;
6
- font-display: swap;
7
- src:
8
- local('SWR-VAR-Sans'),
9
- url('https://www.swr.de/assets/fonts/swr_type/SWR_VAR_WEB/SWR-VAR-Sans.woff2') format('woff2');
10
- }
11
- @font-face {
12
- font-family: 'SWR-VAR-Text';
13
- font-weight: 400 600 700;
14
- font-display: swap;
15
- src:
16
- local('SWR-VAR-Text'),
17
- url('https://www.swr.de/assets/fonts/swr_type/SWR_VAR_WEB/SWR-VAR-Text.woff2') format('woff2');
18
- }
19
-
20
- $sans: 'SWR-VAR-Sans', sans-serif;
21
- $text: 'SWR-VAR-Text', sans-serif;
22
-
23
- %caption {
24
- font-size: 0.9rem;
25
- line-height: 1;
26
- letter-spacing: 0.0045em;
27
- }
28
- %caption-bold {
29
- @extend %caption;
30
- font-weight: 700;
31
- }
32
- %copy {
33
- font-family: $text;
34
- font-size: 1.1rem;
35
- line-height: 1.45;
36
- letter-spacing: 0.0045em;
37
- }
38
- %copy-bold {
39
- @extend %copy;
40
- font-weight: 700;
41
- }
42
- %h3 {
43
- @extend %copy;
44
- font-family: $sans;
45
- font-size: 2.2rem;
46
- line-height: 1.15;
47
- font-weight: 600;
48
- letter-spacing: 0.0025em;
49
- }
@@ -1,10 +0,0 @@
1
- @import "constants";
2
- @import "typography";
3
- @import "functions";
4
- @import "colors";
5
-
6
- * {
7
- box-sizing: border-box;
8
- margin: 0;
9
- padding: 0;
10
- }