@ks-digital/designsystem-angular 0.0.1-alpha.25 → 0.0.1-alpha.27
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/fesm2022/ks-digital-designsystem-angular.mjs +1100 -0
- package/fesm2022/ks-digital-designsystem-angular.mjs.map +1 -0
- package/index.d.ts +333 -0
- package/package.json +15 -20
- package/.storybook/customTheme.ts +0 -15
- package/.storybook/default-args.ts +0 -18
- package/.storybook/main.ts +0 -27
- package/.storybook/manager.ts +0 -10
- package/.storybook/preview-head.html +0 -16
- package/.storybook/preview.ts +0 -70
- package/.storybook/themes.ts +0 -9
- package/.storybook/tsconfig.json +0 -16
- package/.storybook/vite.config.mts +0 -5
- package/eslint.config.mjs +0 -28
- package/ng-package.json +0 -9
- package/project.json +0 -81
- package/src/components/alert/alert.mdx +0 -46
- package/src/components/alert/alert.spec.ts +0 -33
- package/src/components/alert/alert.stories.ts +0 -138
- package/src/components/alert/alert.ts +0 -46
- package/src/components/alert/index.ts +0 -1
- package/src/components/button/button.mdx +0 -40
- package/src/components/button/button.spec.ts +0 -86
- package/src/components/button/button.stories.ts +0 -123
- package/src/components/button/button.ts +0 -60
- package/src/components/button/index.ts +0 -1
- package/src/components/card/card-block.ts +0 -10
- package/src/components/card/card.mdx +0 -100
- package/src/components/card/card.spec.ts +0 -70
- package/src/components/card/card.stories.ts +0 -101
- package/src/components/card/card.ts +0 -44
- package/src/components/card/index.ts +0 -2
- package/src/components/checkbox/README.md +0 -13
- package/src/components/checkbox/checkbox.mdx +0 -50
- package/src/components/checkbox/checkbox.spec.ts +0 -21
- package/src/components/checkbox/checkbox.stories.ts +0 -182
- package/src/components/checkbox/index.ts +0 -0
- package/src/components/colors.ts +0 -36
- package/src/components/common-inputs.ts +0 -30
- package/src/components/details/controlled-details.ts +0 -63
- package/src/components/details/details-content.ts +0 -7
- package/src/components/details/details-summary.ts +0 -7
- package/src/components/details/details.mdx +0 -89
- package/src/components/details/details.spec.ts +0 -56
- package/src/components/details/details.stories.ts +0 -129
- package/src/components/details/details.ts +0 -69
- package/src/components/details/index.ts +0 -3
- package/src/components/field/field-counter.ts +0 -56
- package/src/components/field/field-description.ts +0 -10
- package/src/components/field/field-error.ts +0 -13
- package/src/components/field/field-observer.ts +0 -121
- package/src/components/field/field-state.ts +0 -21
- package/src/components/field/field.mdx +0 -40
- package/src/components/field/field.spec.ts +0 -131
- package/src/components/field/field.stories.ts +0 -98
- package/src/components/field/field.ts +0 -70
- package/src/components/field/index.ts +0 -3
- package/src/components/fieldset/fieldset-description.ts +0 -8
- package/src/components/fieldset/fieldset-legend.ts +0 -11
- package/src/components/fieldset/fieldset.spec.ts +0 -80
- package/src/components/fieldset/fieldset.ts +0 -11
- package/src/components/fieldset/index.ts +0 -3
- package/src/components/input/index.ts +0 -1
- package/src/components/input/input.mdx +0 -11
- package/src/components/input/input.spec.ts +0 -25
- package/src/components/input/input.stories.ts +0 -72
- package/src/components/input/input.ts +0 -67
- package/src/components/label/index.ts +0 -1
- package/src/components/label/label.ts +0 -17
- package/src/components/paragraph/index.ts +0 -1
- package/src/components/paragraph/paragraph.ts +0 -10
- package/src/components/popover/controlled-popover.ts +0 -62
- package/src/components/popover/index.ts +0 -1
- package/src/components/popover/popover.mdx +0 -81
- package/src/components/popover/popover.spec.ts +0 -143
- package/src/components/popover/popover.stories.ts +0 -63
- package/src/components/popover/popover.ts +0 -186
- package/src/components/radio/radio.mdx +0 -117
- package/src/components/radio/radio.stories.ts +0 -226
- package/src/components/search/index.ts +0 -4
- package/src/components/search/search-button.ts +0 -35
- package/src/components/search/search-clear.ts +0 -57
- package/src/components/search/search-input.ts +0 -18
- package/src/components/search/search.mdx +0 -56
- package/src/components/search/search.spec.ts +0 -48
- package/src/components/search/search.stories.ts +0 -205
- package/src/components/search/search.ts +0 -50
- package/src/components/spinner/index.ts +0 -1
- package/src/components/spinner/spinner.mdx +0 -24
- package/src/components/spinner/spinner.spec.ts +0 -13
- package/src/components/spinner/spinner.stories.ts +0 -54
- package/src/components/spinner/spinner.ts +0 -62
- package/src/components/switch/switch.mdx +0 -82
- package/src/components/switch/switch.stories.ts +0 -94
- package/src/components/textarea/textarea.mdx +0 -14
- package/src/components/textarea/textarea.stories.ts +0 -52
- package/src/components/validation-message/index.ts +0 -1
- package/src/components/validation-message/validation-message.ts +0 -11
- package/src/index.ts +0 -14
- package/src/test-setup.ts +0 -12
- package/src/utils/log-if-devmode.ts +0 -13
- package/src/utils/random-id.ts +0 -3
- package/tsconfig.json +0 -34
- package/tsconfig.lib.json +0 -28
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -30
- package/vite.config.mts +0 -35
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Meta,
|
|
3
|
-
Primary,
|
|
4
|
-
Controls,
|
|
5
|
-
Story,
|
|
6
|
-
Canvas,
|
|
7
|
-
} from '@storybook/addon-docs/blocks'
|
|
8
|
-
|
|
9
|
-
import * as SearchStories from './search.stories'
|
|
10
|
-
|
|
11
|
-
<Meta of={SearchStories} />
|
|
12
|
-
|
|
13
|
-
# Search
|
|
14
|
-
|
|
15
|
-
Search lar brukere raskt finne relevant innhold på et nettsted i en applikasjon. Komponenten består av et søkefelt, med eller uten en søkeknapp
|
|
16
|
-
|
|
17
|
-
<Primary />
|
|
18
|
-
<Controls />
|
|
19
|
-
|
|
20
|
-
## Bruk
|
|
21
|
-
|
|
22
|
-
```tsx
|
|
23
|
-
import {
|
|
24
|
-
Search,
|
|
25
|
-
SearchInput,
|
|
26
|
-
SearchClear,
|
|
27
|
-
SearchButton,
|
|
28
|
-
} from '@ks-digital/designsystem-angular'
|
|
29
|
-
;<ksd-search>
|
|
30
|
-
<input ksd-search-input />
|
|
31
|
-
<button ksd-search-clear></button>
|
|
32
|
-
<button ksd-search-button></button>
|
|
33
|
-
</ksd-search>
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Kontrollert
|
|
37
|
-
|
|
38
|
-
<Canvas of={SearchStories.Controlled} />
|
|
39
|
-
|
|
40
|
-
## Variants
|
|
41
|
-
|
|
42
|
-
Du kan endre variant på Button for å tilpasse visningen. Alternativt kan du fjerne knappen for å bruke et søkefelt med ikon. Eksemplene nedenfor viser varianter som inkluderer ikon, primær- og sekundærknapp.
|
|
43
|
-
|
|
44
|
-
<Canvas of={SearchStories.Variants} />
|
|
45
|
-
|
|
46
|
-
## Med Label
|
|
47
|
-
|
|
48
|
-
Dersom du vil ha label på søkefeltet, må du legge til en Label komponent som du kobler sammen med SearchInput. I eksempelet har vi brukt Field for å få oppkobling mellom Label og SearchInput.
|
|
49
|
-
|
|
50
|
-
<Canvas of={SearchStories.WithLabel} />
|
|
51
|
-
|
|
52
|
-
## Skjema
|
|
53
|
-
|
|
54
|
-
Søkeknappen har typen "submit" og vil dermed automatisk sende inn skjema.
|
|
55
|
-
|
|
56
|
-
<Canvas of={SearchStories.Form} />
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/angular'
|
|
2
|
-
import userEvent from '@testing-library/user-event'
|
|
3
|
-
import { Input } from '../input'
|
|
4
|
-
import { Search } from './search'
|
|
5
|
-
import { SearchButton } from './search-button'
|
|
6
|
-
import { SearchClear } from './search-clear'
|
|
7
|
-
import { SearchInput } from './search-input'
|
|
8
|
-
|
|
9
|
-
test('should render minimal search component', async () => {
|
|
10
|
-
await render(
|
|
11
|
-
`
|
|
12
|
-
<ksd-search>
|
|
13
|
-
<input ksd-search-input role="searchbox" />
|
|
14
|
-
</ksd-search>
|
|
15
|
-
`,
|
|
16
|
-
{ imports: [SearchInput, Search, Input] },
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
const searchElement = screen.getByRole('searchbox').parentElement
|
|
20
|
-
expect(searchElement).toBeInTheDocument()
|
|
21
|
-
expect(searchElement).toHaveClass('ds-search')
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
test('should clear the input when the clear button is clicked', async () => {
|
|
25
|
-
await render(
|
|
26
|
-
`
|
|
27
|
-
<ksd-search>
|
|
28
|
-
<input ksd-search-input role="searchbox" />
|
|
29
|
-
<button ksd-search-clear role="button"></button>
|
|
30
|
-
<button ksd-search-button></button>
|
|
31
|
-
</ksd-search>
|
|
32
|
-
`,
|
|
33
|
-
{
|
|
34
|
-
imports: [SearchInput, SearchClear, SearchButton, Search],
|
|
35
|
-
},
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
const searchInput = screen.getByRole('searchbox') as HTMLInputElement
|
|
39
|
-
const clearButton = screen.getByRole('button', {
|
|
40
|
-
name: /tøm/i,
|
|
41
|
-
}) as HTMLButtonElement
|
|
42
|
-
|
|
43
|
-
await userEvent.type(searchInput, 'test')
|
|
44
|
-
expect(searchInput.value).toBe('test')
|
|
45
|
-
|
|
46
|
-
await userEvent.click(clearButton)
|
|
47
|
-
expect(searchInput.value).toBe('')
|
|
48
|
-
})
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { moduleMetadata, type Meta } from '@storybook/angular'
|
|
2
|
-
import { CommonArgs, commonArgTypes } from '../../../.storybook/default-args'
|
|
3
|
-
import { Button } from '../button'
|
|
4
|
-
import { Field } from '../field/field'
|
|
5
|
-
import { Input } from '../input'
|
|
6
|
-
import { Label } from '../label/label'
|
|
7
|
-
import { Search } from './search'
|
|
8
|
-
import { SearchButton } from './search-button'
|
|
9
|
-
import { SearchClear } from './search-clear'
|
|
10
|
-
import { SearchInput } from './search-input'
|
|
11
|
-
|
|
12
|
-
type SearchArgs = CommonArgs & {
|
|
13
|
-
variant?: 'primary' | 'secondary'
|
|
14
|
-
buttonLabel?: string
|
|
15
|
-
clearButtonLabel?: string
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const meta: Meta<SearchArgs> = {
|
|
19
|
-
component: Search,
|
|
20
|
-
title: 'Komponenter/Search',
|
|
21
|
-
argTypes: {
|
|
22
|
-
...commonArgTypes,
|
|
23
|
-
variant: {
|
|
24
|
-
options: ['primary', 'secondary'],
|
|
25
|
-
control: { type: 'radio' },
|
|
26
|
-
description: 'Velg variant for søkeknappen',
|
|
27
|
-
},
|
|
28
|
-
buttonLabel: {
|
|
29
|
-
control: { type: 'text' },
|
|
30
|
-
description: 'Label for søkeknappen',
|
|
31
|
-
},
|
|
32
|
-
clearButtonLabel: {
|
|
33
|
-
control: { type: 'text' },
|
|
34
|
-
description: 'Label for tøm-knappen',
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
decorators: [
|
|
38
|
-
moduleMetadata({
|
|
39
|
-
imports: [
|
|
40
|
-
Search,
|
|
41
|
-
SearchClear,
|
|
42
|
-
SearchButton,
|
|
43
|
-
SearchInput,
|
|
44
|
-
Button,
|
|
45
|
-
Input,
|
|
46
|
-
Field,
|
|
47
|
-
Label,
|
|
48
|
-
],
|
|
49
|
-
}),
|
|
50
|
-
],
|
|
51
|
-
}
|
|
52
|
-
export default meta
|
|
53
|
-
type Story = Meta<Search>
|
|
54
|
-
|
|
55
|
-
export const Preview: Story = {
|
|
56
|
-
args: {
|
|
57
|
-
variant: 'primary',
|
|
58
|
-
buttonLabel: 'Søk',
|
|
59
|
-
clearButtonLabel: 'Tøm',
|
|
60
|
-
'data-size': '',
|
|
61
|
-
'data-color': '',
|
|
62
|
-
},
|
|
63
|
-
render: (args) => ({
|
|
64
|
-
props: {
|
|
65
|
-
...args,
|
|
66
|
-
dataSize: (args as SearchArgs)['data-size'],
|
|
67
|
-
dataColor: (args as SearchArgs)['data-color'],
|
|
68
|
-
},
|
|
69
|
-
template: `
|
|
70
|
-
<ksd-search role="search" [attr.data-size]="dataSize" [attr.data-color]="dataColor">
|
|
71
|
-
<input ksd-search-input role="searchbox" aria-label="Søkefelt" />
|
|
72
|
-
<button ksd-search-clear [aria-label]="clearButtonLabel"></button>
|
|
73
|
-
<button ksd-search-button [variant]="variant" [aria-label]="buttonLabel"></button>
|
|
74
|
-
</ksd-search>
|
|
75
|
-
`,
|
|
76
|
-
}),
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export const Controlled: Story = {
|
|
80
|
-
render: () => {
|
|
81
|
-
const state = {
|
|
82
|
-
value: '',
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
props: {
|
|
86
|
-
state,
|
|
87
|
-
|
|
88
|
-
setInput: (value: string) => {
|
|
89
|
-
state.value = value
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
setValue: (event: KeyboardEvent) => {
|
|
93
|
-
const input = event.target as HTMLInputElement
|
|
94
|
-
state.value = input.value
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
clearValue: () => {
|
|
98
|
-
state.value = ''
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
template: `
|
|
102
|
-
<ksd-search>
|
|
103
|
-
<input ksd-search-input role="searchbox" [value]="state.value" (keyup)="setValue($event)"/>
|
|
104
|
-
<button ksd-search-clear (clearInput)="clearValue()" ></button>
|
|
105
|
-
<button ksd-search-button></button>
|
|
106
|
-
</ksd-search>
|
|
107
|
-
|
|
108
|
-
<div>
|
|
109
|
-
<span>Current search value: "{{ state.value }}"</span>
|
|
110
|
-
|
|
111
|
-
<button ksd-button (click)="setInput('Calzone')">
|
|
112
|
-
Set input value to "Calzone"
|
|
113
|
-
</button>
|
|
114
|
-
|
|
115
|
-
<p>The clear button has an output <em>(clearInput)</em> that is emitted when clicked.</p>
|
|
116
|
-
</div>
|
|
117
|
-
`,
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export const Variants: Story = {
|
|
123
|
-
args: {},
|
|
124
|
-
render: (args) => ({
|
|
125
|
-
props: args,
|
|
126
|
-
template: `
|
|
127
|
-
<div>
|
|
128
|
-
<p>Primary variant (default)</p>
|
|
129
|
-
<ksd-search>
|
|
130
|
-
<input ksd-search-input role="searchbox" />
|
|
131
|
-
<button ksd-search-clear></button>
|
|
132
|
-
<button ksd-search-button></button>
|
|
133
|
-
</ksd-search>
|
|
134
|
-
</div>
|
|
135
|
-
|
|
136
|
-
<div>
|
|
137
|
-
<p>Secondary variant</p>
|
|
138
|
-
<ksd-search>
|
|
139
|
-
<input ksd-search-input role="searchbox" />
|
|
140
|
-
<button ksd-search-clear></button>
|
|
141
|
-
<button ksd-search-button variant="secondary"></button>
|
|
142
|
-
</ksd-search>
|
|
143
|
-
</div>
|
|
144
|
-
|
|
145
|
-
<div>
|
|
146
|
-
<p>Search with icon</p>
|
|
147
|
-
<ksd-search>
|
|
148
|
-
<input ksd-search-input role="searchbox" />
|
|
149
|
-
<button ksd-search-clear></button>
|
|
150
|
-
</ksd-search>
|
|
151
|
-
</div>
|
|
152
|
-
`,
|
|
153
|
-
}),
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export const WithLabel: Story = {
|
|
157
|
-
args: {},
|
|
158
|
-
render: (args) => ({
|
|
159
|
-
props: args,
|
|
160
|
-
template: `
|
|
161
|
-
<ksd-field>
|
|
162
|
-
<ksd-label>Søk etter hunder:</ksd-label>
|
|
163
|
-
<ksd-search>
|
|
164
|
-
<input ksd-search-input role="searchbox" name="dog-search" />
|
|
165
|
-
<button ksd-search-clear></button>
|
|
166
|
-
<button ksd-search-button></button>
|
|
167
|
-
</ksd-search>
|
|
168
|
-
</ksd-field>
|
|
169
|
-
`,
|
|
170
|
-
}),
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export const Form: Story = {
|
|
174
|
-
render: () => {
|
|
175
|
-
const state = { value: '' }
|
|
176
|
-
return {
|
|
177
|
-
props: {
|
|
178
|
-
state,
|
|
179
|
-
onSubmit: (event: Event) => {
|
|
180
|
-
event.preventDefault()
|
|
181
|
-
const form = event.target as HTMLFormElement
|
|
182
|
-
const formData = new FormData(form)
|
|
183
|
-
state.value = formData.get('search') as string
|
|
184
|
-
},
|
|
185
|
-
onClear: () => {
|
|
186
|
-
state.value = ''
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
template: `
|
|
190
|
-
<form role="search" (submit)="onSubmit($event)">
|
|
191
|
-
<ksd-search>
|
|
192
|
-
<input ksd-search-input role="searchbox" name="search" />
|
|
193
|
-
<button ksd-search-clear (clearInput)="onClear()"></button>
|
|
194
|
-
<button ksd-search-button></button>
|
|
195
|
-
</ksd-search>
|
|
196
|
-
</form>
|
|
197
|
-
|
|
198
|
-
<p>Submitted value: "{{ state.value }}"</p>
|
|
199
|
-
`,
|
|
200
|
-
}
|
|
201
|
-
},
|
|
202
|
-
// play: async ({ canvas }) => {
|
|
203
|
-
// await expect(canvas.getByRole('search')).toBeTruthy()
|
|
204
|
-
// },
|
|
205
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { afterNextRender, Component, contentChild } from '@angular/core'
|
|
2
|
-
import { logIfDevMode } from '../../utils/log-if-devmode'
|
|
3
|
-
import { CommonInputs } from '../common-inputs'
|
|
4
|
-
import { SearchInput } from './search-input'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Search Component
|
|
8
|
-
*
|
|
9
|
-
* Use to contain the search input and buttons.
|
|
10
|
-
* Only `SearchInput` is required, while `SearchClear` and `SearchButton` are optional.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* <div ksd-search>
|
|
14
|
-
* <input ksd-search-input />
|
|
15
|
-
* <button ksd-search-clear></button>
|
|
16
|
-
* <button ksd-search-button></button>
|
|
17
|
-
* </div>
|
|
18
|
-
*/
|
|
19
|
-
@Component({
|
|
20
|
-
selector: 'ksd-search',
|
|
21
|
-
template: `
|
|
22
|
-
<ng-content select="[ksd-search-input]" />
|
|
23
|
-
<ng-content select="[ksd-search-clear]" />
|
|
24
|
-
<ng-content select="[ksd-search-button]" />
|
|
25
|
-
`,
|
|
26
|
-
host: {
|
|
27
|
-
class: 'ds-search',
|
|
28
|
-
},
|
|
29
|
-
hostDirectives: [
|
|
30
|
-
{
|
|
31
|
-
directive: CommonInputs,
|
|
32
|
-
inputs: ['data-size', 'data-color'],
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
})
|
|
36
|
-
export class Search {
|
|
37
|
-
private readonly input = contentChild(SearchInput)
|
|
38
|
-
|
|
39
|
-
constructor() {
|
|
40
|
-
afterNextRender(() => {
|
|
41
|
-
if (!this.input()) {
|
|
42
|
-
logIfDevMode({
|
|
43
|
-
component: 'Search',
|
|
44
|
-
message:
|
|
45
|
-
'Missing required elements: ksd-search-input must be provided as child. Check imports and markup.',
|
|
46
|
-
})
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Spinner } from './spinner'
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Meta, Primary, Controls, Canvas } from '@storybook/addon-docs/blocks'
|
|
2
|
-
|
|
3
|
-
import * as SpinnerStories from './spinner.stories'
|
|
4
|
-
|
|
5
|
-
<Meta of={SpinnerStories} />
|
|
6
|
-
|
|
7
|
-
# Spinner
|
|
8
|
-
|
|
9
|
-
`Spinner` brukes for å indikere at en handling pågår. Dette kan være når vi venter på at et skjema skal sendes inn.
|
|
10
|
-
|
|
11
|
-
<Primary />
|
|
12
|
-
<Controls />
|
|
13
|
-
|
|
14
|
-
## Størrelser
|
|
15
|
-
|
|
16
|
-
Du kan justere størrelsen på `Spinner` etter hvor den skal plasseres.
|
|
17
|
-
Størrelsen vil være mindre i knapper, men større dersom den er ved et skjemafelt.
|
|
18
|
-
|
|
19
|
-
<Canvas of={SpinnerStories.Sizes} />
|
|
20
|
-
|
|
21
|
-
## Tilgjengelighet
|
|
22
|
-
|
|
23
|
-
Når brukeren har `prefers-reduced-motion` satt til `reduce` vil spinneren ha en animasjon på 6 sekunder.
|
|
24
|
-
Animasjonen er ikke dekorativ, og vi skrur den derfor ikke av.
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/angular'
|
|
2
|
-
import { Spinner } from './spinner'
|
|
3
|
-
|
|
4
|
-
it('should render a spinner with title "loading"', async () => {
|
|
5
|
-
await render(
|
|
6
|
-
`
|
|
7
|
-
<ksd-spinner aria-label="Loading">
|
|
8
|
-
`,
|
|
9
|
-
{ imports: [Spinner] },
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
expect(screen.getByLabelText('Loading')).toBeInTheDocument()
|
|
13
|
-
})
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
argsToTemplate,
|
|
3
|
-
moduleMetadata,
|
|
4
|
-
type Meta,
|
|
5
|
-
type StoryObj,
|
|
6
|
-
} from '@storybook/angular'
|
|
7
|
-
import { CommonArgs } from '../../../.storybook/default-args'
|
|
8
|
-
import { Spinner } from './spinner'
|
|
9
|
-
|
|
10
|
-
type SpinnerArgs = CommonArgs
|
|
11
|
-
|
|
12
|
-
const meta: Meta<SpinnerArgs> = {
|
|
13
|
-
component: Spinner,
|
|
14
|
-
title: 'Komponenter/Loaders/Spinner',
|
|
15
|
-
decorators: [
|
|
16
|
-
moduleMetadata({
|
|
17
|
-
imports: [Spinner],
|
|
18
|
-
}),
|
|
19
|
-
],
|
|
20
|
-
}
|
|
21
|
-
export default meta
|
|
22
|
-
type Story = StoryObj<SpinnerArgs>
|
|
23
|
-
|
|
24
|
-
export const Preview: Story = {
|
|
25
|
-
args: {
|
|
26
|
-
'data-size': 'md',
|
|
27
|
-
'data-color': undefined,
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
render: (args) => ({
|
|
31
|
-
props: args,
|
|
32
|
-
template: `
|
|
33
|
-
<ksd-spinner ${argsToTemplate(args)} data-size="xl" />
|
|
34
|
-
`,
|
|
35
|
-
}),
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export const Sizes: Story = {
|
|
39
|
-
args: {
|
|
40
|
-
...Preview.args,
|
|
41
|
-
'data-size': undefined,
|
|
42
|
-
},
|
|
43
|
-
render: (args) => ({
|
|
44
|
-
props: args,
|
|
45
|
-
template: `
|
|
46
|
-
<ksd-spinner aria-label="Laster" ${argsToTemplate(args)} data-size="2xs" />
|
|
47
|
-
<ksd-spinner aria-label="Laster" ${argsToTemplate(args)} data-size="xs" />
|
|
48
|
-
<ksd-spinner aria-label="Laster" ${argsToTemplate(args)} data-size="sm" />
|
|
49
|
-
<ksd-spinner aria-label="Laster" ${argsToTemplate(args)} data-size="md" />
|
|
50
|
-
<ksd-spinner aria-label="Laster" ${argsToTemplate(args)} data-size="lg" />
|
|
51
|
-
<ksd-spinner aria-label="Laster" ${argsToTemplate(args)} data-size="xl" />
|
|
52
|
-
`,
|
|
53
|
-
}),
|
|
54
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @angular-eslint/no-input-rename */
|
|
2
|
-
import { booleanAttribute, Component, input } from '@angular/core'
|
|
3
|
-
import { Size } from '../common-inputs'
|
|
4
|
-
|
|
5
|
-
@Component({
|
|
6
|
-
selector: 'ksd-spinner',
|
|
7
|
-
styles: `
|
|
8
|
-
:host {
|
|
9
|
-
display: contents;
|
|
10
|
-
}
|
|
11
|
-
`,
|
|
12
|
-
template: `
|
|
13
|
-
<svg
|
|
14
|
-
class="ds-spinner"
|
|
15
|
-
role="img"
|
|
16
|
-
viewBox="0 0 50 50"
|
|
17
|
-
[attr.data-size]="dataSize()"
|
|
18
|
-
[attr.data-color]="dataColor()"
|
|
19
|
-
>
|
|
20
|
-
<circle
|
|
21
|
-
class="ds-spinner__background"
|
|
22
|
-
cx="25"
|
|
23
|
-
cy="25"
|
|
24
|
-
r="20"
|
|
25
|
-
fill="none"
|
|
26
|
-
stroke-width="5"
|
|
27
|
-
/>
|
|
28
|
-
<circle
|
|
29
|
-
class="ds-spinner__circle"
|
|
30
|
-
cx="25"
|
|
31
|
-
cy="25"
|
|
32
|
-
r="20"
|
|
33
|
-
fill="none"
|
|
34
|
-
stroke-width="5"
|
|
35
|
-
/>
|
|
36
|
-
</svg>
|
|
37
|
-
`,
|
|
38
|
-
})
|
|
39
|
-
export class Spinner {
|
|
40
|
-
/**
|
|
41
|
-
* Aria-label for the spinner
|
|
42
|
-
*/
|
|
43
|
-
readonly ariaLabel = input<string>(undefined, { alias: 'aria-label' })
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Aria-label for the spinner
|
|
47
|
-
*/
|
|
48
|
-
readonly dataSize = input<Size>(undefined, { alias: 'data-size' })
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Aria-label for the spinner
|
|
52
|
-
*/
|
|
53
|
-
readonly dataColor = input<Size>(undefined, { alias: 'data-color' })
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Aria-hidden for the spinner
|
|
57
|
-
*/
|
|
58
|
-
readonly ariaHidden = input(undefined, {
|
|
59
|
-
transform: booleanAttribute,
|
|
60
|
-
alias: 'aria-hidden',
|
|
61
|
-
})
|
|
62
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { Meta, Primary, Controls, Canvas } from '@storybook/addon-docs/blocks'
|
|
2
|
-
|
|
3
|
-
import * as SwitchStories from './switch.stories'
|
|
4
|
-
|
|
5
|
-
<Meta of={SwitchStories} />
|
|
6
|
-
|
|
7
|
-
# Switch
|
|
8
|
-
|
|
9
|
-
`Switch` brukes til å gi brukeren et valg mellom to alternativer. Bryteren kan enten slås av eller på og skal alltid være innstilt med et standardvalg
|
|
10
|
-
|
|
11
|
-
<Primary />
|
|
12
|
-
<Controls />
|
|
13
|
-
|
|
14
|
-
## Bruk
|
|
15
|
-
|
|
16
|
-
```html
|
|
17
|
-
<ksd-field>
|
|
18
|
-
<ksd-label>Min switch</ksd-label>
|
|
19
|
-
<input ksd-input type="checkbox" role="switch" />
|
|
20
|
-
</ksd-field>
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Kodeeksempler
|
|
24
|
-
|
|
25
|
-
**Gruppering**
|
|
26
|
-
|
|
27
|
-
Bruk `Fieldset`for å gruppere fler `Switch`-komponenter sammen
|
|
28
|
-
|
|
29
|
-
<Canvas of={SwitchStories.Grouped} />
|
|
30
|
-
|
|
31
|
-
**Høyre justering**
|
|
32
|
-
|
|
33
|
-
Plasser `label` etter `input` for å plassere `Switch` til høyre side av ledeteksten hvis du trenger det.
|
|
34
|
-
|
|
35
|
-
<Canvas of={SwitchStories.RightAligned} />
|
|
36
|
-
|
|
37
|
-
## Retningslinjer
|
|
38
|
-
|
|
39
|
-
`Switch`skal være et valg mellom to alternativer. Vi bruker `Switch` til innstillinger, ikke i skjema.
|
|
40
|
-
|
|
41
|
-
**Passer til:**
|
|
42
|
-
|
|
43
|
-
- aktivere eller deaktivere funksjoner/tilstander med en gang
|
|
44
|
-
- slå varsler av og på
|
|
45
|
-
|
|
46
|
-
**Passer ikke til:**
|
|
47
|
-
|
|
48
|
-
- å bruke i stedet for `Checkbox` eller `Radio` i et skjema
|
|
49
|
-
- situasjoner der brukerne må lagre informasjon før en endring får effekt
|
|
50
|
-
- endre visning av innhold mellom to kategorier
|
|
51
|
-
|
|
52
|
-
**Bruk heller**
|
|
53
|
-
|
|
54
|
-
- `Checkbox` hvis du skal tilby brukerne flere valg, der de skal velge ett eller flere alternativer
|
|
55
|
-
- `Radio` hvis brukerne skal få flere valg, men bare skal velge ett
|
|
56
|
-
- `Chip til å filtrere innhold
|
|
57
|
-
|
|
58
|
-
## Tekst
|
|
59
|
-
|
|
60
|
-
Teksten til en `Switch` må være kort og presis, ofte betyr det bare ett eller to ord. Det skal gi mening når du sier ledeteksten høyt og legger til av/på etterpå. Unngå tekst med flere ord og mellomrom.
|
|
61
|
-
|
|
62
|
-
Hvis du har flere `Switch` i en gruppe, må du passe på at du er konsekvent med hvordan du formulerer tekstene til hver av dem også, ikke formulerer dem forskjellig.
|
|
63
|
-
|
|
64
|
-
Teksten skal beskrive hva funksjonen gjelder, ikke om den er på eller av. Hvis statusen skrives inn i labelen, kan det bli forvirrende og vanskelig å vite hvilken tilstand switchen faktisk er i.
|
|
65
|
-
|
|
66
|
-
**Eksempel 1**
|
|
67
|
-
|
|
68
|
-
- Riktig: Varsle på epost (Av/på)
|
|
69
|
-
- Feil: Skru av varsel på epost (Av/på)
|
|
70
|
-
|
|
71
|
-
**Eksempel 2**
|
|
72
|
-
|
|
73
|
-
- Riktig: Flymodus (Av/på)
|
|
74
|
-
- Feil: Skru på flymodus (Av/på)
|
|
75
|
-
|
|
76
|
-
**Plassering av tekst**
|
|
77
|
-
|
|
78
|
-
Som regel er det høyre som er den beste plasseringen for tekst, unntaket er når `Switch er fast plassert på høyre side i grensesnittet er det best at teksten er på venstre side. Slik at alle knappene blir justert etter samme vertikale
|
|
79
|
-
|
|
80
|
-
## Tilgjengelighet
|
|
81
|
-
|
|
82
|
-
Vi bruker `role="switch"` for å fortelle skjermlesere at dette er en vippebryter. Dette gjør at skjermlesere kan gi brukeren informasjon om at dette er en vippebryter og at den kan skrus av og på. Det er ikke lagt på `aria-checked` siden dette er ikke nødvendig når bryteren er en input med `type="checkbox".
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
argsToTemplate,
|
|
3
|
-
moduleMetadata,
|
|
4
|
-
type Meta,
|
|
5
|
-
type StoryObj,
|
|
6
|
-
} from '@storybook/angular'
|
|
7
|
-
import { CommonArgs } from '../../../.storybook/default-args'
|
|
8
|
-
import { Field } from '../field/field'
|
|
9
|
-
import { FieldDescription } from '../field/field-description'
|
|
10
|
-
import { Fieldset } from '../fieldset/fieldset'
|
|
11
|
-
import { FieldsetDescription } from '../fieldset/fieldset-description'
|
|
12
|
-
import { FieldsetLegend } from '../fieldset/fieldset-legend'
|
|
13
|
-
import { Input } from '../input/input'
|
|
14
|
-
import { Label } from '../label/label'
|
|
15
|
-
import { ValidationMessage } from '../validation-message'
|
|
16
|
-
|
|
17
|
-
type SwitchArgs = CommonArgs & {
|
|
18
|
-
readonly: boolean
|
|
19
|
-
disabled: boolean
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const meta: Meta<SwitchArgs> = {
|
|
23
|
-
component: Input,
|
|
24
|
-
title: 'Komponenter/Switch',
|
|
25
|
-
decorators: [
|
|
26
|
-
moduleMetadata({
|
|
27
|
-
imports: [
|
|
28
|
-
Label,
|
|
29
|
-
Field,
|
|
30
|
-
Input,
|
|
31
|
-
FieldDescription,
|
|
32
|
-
Fieldset,
|
|
33
|
-
FieldsetLegend,
|
|
34
|
-
FieldsetDescription,
|
|
35
|
-
ValidationMessage,
|
|
36
|
-
],
|
|
37
|
-
}),
|
|
38
|
-
],
|
|
39
|
-
}
|
|
40
|
-
export default meta
|
|
41
|
-
type Story = StoryObj<SwitchArgs>
|
|
42
|
-
|
|
43
|
-
export const Preview: Story = {
|
|
44
|
-
args: {
|
|
45
|
-
readonly: false,
|
|
46
|
-
disabled: false,
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
render: (args) => ({
|
|
50
|
-
props: args,
|
|
51
|
-
template: `
|
|
52
|
-
<ksd-field>
|
|
53
|
-
<ksd-label>Min switch</ksd-label>
|
|
54
|
-
<input ksd-input role="switch" type="checkbox" ${argsToTemplate(args)} role="switch"/>
|
|
55
|
-
</ksd-field>
|
|
56
|
-
`,
|
|
57
|
-
}),
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export const Grouped: Story = {
|
|
61
|
-
render: () => ({
|
|
62
|
-
template: `
|
|
63
|
-
<fieldset ksd-fieldset>
|
|
64
|
-
<legend ksd-fieldset-legend> Skru av/på lys </legend>
|
|
65
|
-
<ksd-field>
|
|
66
|
-
<ksd-label>Stue</ksd-label>
|
|
67
|
-
<input ksd-input type="checkbox" role="switch" checked=${true} />
|
|
68
|
-
</ksd-field>
|
|
69
|
-
<ksd-field>
|
|
70
|
-
<ksd-label>Kjøkken</ksd-label>
|
|
71
|
-
<input ksd-input type="checkbox" role="switch"/>
|
|
72
|
-
</ksd-field>
|
|
73
|
-
<ksd-field>
|
|
74
|
-
<ksd-label>Bad</ksd-label>
|
|
75
|
-
<input ksd-input type="checkbox" role="switch"/>
|
|
76
|
-
</ksd-field>
|
|
77
|
-
<ksd-field>
|
|
78
|
-
<ksd-label>Soverom</ksd-label>
|
|
79
|
-
<input ksd-input type="checkbox" role="switch" />
|
|
80
|
-
</ksd-field>
|
|
81
|
-
</fieldset>`,
|
|
82
|
-
}),
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export const RightAligned: Story = {
|
|
86
|
-
render: () => ({
|
|
87
|
-
template: `
|
|
88
|
-
<ksd-field>
|
|
89
|
-
<input ksd-input role="switch" type="checkbox" role="switch"/>
|
|
90
|
-
<ksd-label>Min switch</ksd-label>
|
|
91
|
-
</ksd-field>
|
|
92
|
-
`,
|
|
93
|
-
}),
|
|
94
|
-
}
|