@mattilsynet/design 3.2.8 → 3.3.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/mtds/ai/AGENTS.md +892 -0
- package/mtds/ai/alert.mdx +63 -0
- package/mtds/ai/alert.stories.tsx +128 -0
- package/mtds/ai/analytics.mdx +185 -0
- package/mtds/ai/app.mdx +60 -0
- package/mtds/ai/app.stories.tsx +897 -0
- package/mtds/ai/atlas.mdx +82 -0
- package/mtds/ai/atlas.stories.tsx +424 -0
- package/mtds/ai/avatar.mdx +45 -0
- package/mtds/ai/avatar.stories.tsx +109 -0
- package/mtds/ai/badge.mdx +70 -0
- package/mtds/ai/badge.stories.tsx +122 -0
- package/mtds/ai/breadcrumbs.mdx +36 -0
- package/mtds/ai/breadcrumbs.stories.tsx +158 -0
- package/mtds/ai/button.mdx +179 -0
- package/mtds/ai/button.stories.tsx +440 -0
- package/mtds/ai/card.mdx +51 -0
- package/mtds/ai/card.stories.tsx +469 -0
- package/mtds/ai/chart.mdx +67 -0
- package/mtds/ai/chart.stories.tsx +519 -0
- package/mtds/ai/chip.mdx +71 -0
- package/mtds/ai/chip.stories.tsx +211 -0
- package/mtds/ai/details.mdx +33 -0
- package/mtds/ai/details.stories.tsx +91 -0
- package/mtds/ai/dialog.mdx +38 -0
- package/mtds/ai/dialog.stories.tsx +373 -0
- package/mtds/ai/divider.mdx +19 -0
- package/mtds/ai/divider.stories.tsx +50 -0
- package/mtds/ai/errorsummary.mdx +26 -0
- package/mtds/ai/errorsummary.stories.tsx +137 -0
- package/mtds/ai/field.mdx +86 -0
- package/mtds/ai/field.stories.tsx +863 -0
- package/mtds/ai/fieldset.mdx +126 -0
- package/mtds/ai/fieldset.stories.tsx +298 -0
- package/mtds/ai/fileupload.mdx +16 -0
- package/mtds/ai/fileupload.stories.tsx +126 -0
- package/mtds/ai/helptext.mdx +24 -0
- package/mtds/ai/helptext.stories.tsx +106 -0
- package/mtds/ai/input.mdx +223 -0
- package/mtds/ai/input.stories.tsx +352 -0
- package/mtds/ai/law.mdx +115 -0
- package/mtds/ai/law.stories.tsx +168 -0
- package/mtds/ai/layout.mdx +145 -0
- package/mtds/ai/layout.stories.tsx +443 -0
- package/mtds/ai/link.mdx +45 -0
- package/mtds/ai/link.stories.tsx +44 -0
- package/mtds/ai/logo.mdx +86 -0
- package/mtds/ai/logo.stories.tsx +146 -0
- package/mtds/ai/pagination.mdx +136 -0
- package/mtds/ai/pagination.stories.tsx +404 -0
- package/mtds/ai/popover.mdx +86 -0
- package/mtds/ai/popover.stories.tsx +355 -0
- package/mtds/ai/print.mdx +96 -0
- package/mtds/ai/print.stories.tsx +839 -0
- package/mtds/ai/progress.mdx +41 -0
- package/mtds/ai/progress.stories.tsx +141 -0
- package/mtds/ai/skeleton.mdx +26 -0
- package/mtds/ai/skeleton.stories.tsx +131 -0
- package/mtds/ai/spinner.mdx +26 -0
- package/mtds/ai/spinner.stories.tsx +72 -0
- package/mtds/ai/steps.mdx +37 -0
- package/mtds/ai/steps.stories.tsx +568 -0
- package/mtds/ai/table.mdx +124 -0
- package/mtds/ai/table.stories.tsx +1715 -0
- package/mtds/ai/tabs.mdx +106 -0
- package/mtds/ai/tabs.stories.tsx +159 -0
- package/mtds/ai/tag.mdx +49 -0
- package/mtds/ai/tag.stories.tsx +111 -0
- package/mtds/ai/toast.mdx +67 -0
- package/mtds/ai/toast.stories.tsx +215 -0
- package/mtds/ai/togglegroup.mdx +75 -0
- package/mtds/ai/togglegroup.stories.tsx +96 -0
- package/mtds/ai/tooltip.mdx +32 -0
- package/mtds/ai/tooltip.stories.tsx +34 -0
- package/mtds/ai/typography.mdx +67 -0
- package/mtds/ai/typography.stories.tsx +798 -0
- package/mtds/ai/validation.mdx +19 -0
- package/mtds/ai/validation.stories.tsx +45 -0
- package/mtds/app/app-observer.js +1 -1
- package/mtds/app/app-toggle.js +26 -10
- package/mtds/app/app-toggle.js.map +1 -1
- package/mtds/app/app-toggle2.js +10 -26
- package/mtds/app/app-toggle2.js.map +1 -1
- package/mtds/app/app.js +1 -1
- package/mtds/atlas/atlas-element.js +1 -1
- package/mtds/breadcrumbs/breadcrumbs.d.ts +1 -1
- package/mtds/breadcrumbs/breadcrumbs.js.map +1 -1
- package/mtds/chart/chart-lines.js +19 -19
- package/mtds/chart/chart-lines.js.map +1 -1
- package/mtds/chart/chart.css.js +16 -1
- package/mtds/chart/chart.css.js.map +1 -1
- package/mtds/chart/chart.stories.d.ts +1 -0
- package/mtds/deprecations.js +6 -5
- package/mtds/deprecations.js.map +1 -1
- package/mtds/errorsummary/errorsummary.d.ts +1 -1
- package/mtds/errorsummary/errorsummary.js.map +1 -1
- package/mtds/field/field.d.ts +1 -1
- package/mtds/field/field.js.map +1 -1
- package/mtds/index.d.ts +1 -2
- package/mtds/index.iife.js +29 -18
- package/mtds/index.js +32 -37
- package/mtds/index.js.map +1 -1
- package/mtds/package.json.js +1 -1
- package/mtds/pagination/pagination.d.ts +1 -1
- package/mtds/pagination/pagination.js +9 -8
- package/mtds/pagination/pagination.js.map +1 -1
- package/mtds/styles.css +1 -1
- package/mtds/styles.json +23 -23
- package/mtds/styles.module.css.js +33 -33
- package/mtds/table/table-observer.js +26 -15
- package/mtds/table/table-observer.js.map +1 -1
- package/mtds/tabs/tabs.d.ts +1 -1
- package/mtds/tabs/tabs.js.map +1 -1
- package/mtds/tailwind.css +0 -1
- package/mtds/tooltip/tooltip-element.js +7 -6
- package/mtds/tooltip/tooltip-element.js.map +1 -1
- package/package.json +8 -6
- package/mtds/external/@u-elements/u-datalist/dist/u-datalist.js +0 -238
- package/mtds/external/@u-elements/u-datalist/dist/u-datalist.js.map +0 -1
- package/mtds/external/@u-elements/u-details/dist/u-details.js +0 -101
- package/mtds/external/@u-elements/u-details/dist/u-details.js.map +0 -1
- package/mtds/external/@u-elements/u-tabs/dist/u-tabs.js +0 -235
- package/mtds/external/@u-elements/u-tabs/dist/u-tabs.js.map +0 -1
|
@@ -0,0 +1,863 @@
|
|
|
1
|
+
import { PintGlassIcon, WindIcon } from "@phosphor-icons/react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
3
|
+
import { useRef, useState } from "react";
|
|
4
|
+
import type { DSSuggestionElement } from "../";
|
|
5
|
+
import type { FieldSuggestionSelected } from "../react";
|
|
6
|
+
import { Field, Flex, Input } from "../react";
|
|
7
|
+
import styles from "../styles.module.css";
|
|
8
|
+
|
|
9
|
+
const meta = {
|
|
10
|
+
title: "Designsystem/Field",
|
|
11
|
+
argTypes: {
|
|
12
|
+
as: {
|
|
13
|
+
description: "Element type",
|
|
14
|
+
table: {
|
|
15
|
+
defaultValue: { summary: "input" },
|
|
16
|
+
type: { summary: "input | textarea | select" },
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
type: {
|
|
20
|
+
description: "Input type",
|
|
21
|
+
table: {
|
|
22
|
+
type: { summary: "text | checkbox | radio | ..." },
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
label: {
|
|
26
|
+
description: "Label text",
|
|
27
|
+
table: {
|
|
28
|
+
type: { summary: "React.ReactNode" },
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
description: {
|
|
32
|
+
description: "Description text",
|
|
33
|
+
table: {
|
|
34
|
+
type: { summary: "React.ReactNode" },
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
value: {
|
|
38
|
+
description: "Value",
|
|
39
|
+
table: {
|
|
40
|
+
type: { summary: "string" },
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
checked: {
|
|
44
|
+
description: 'If `type="checkbox"` or `type="radio"`',
|
|
45
|
+
table: {
|
|
46
|
+
type: { summary: "boolean" },
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
validation: {
|
|
50
|
+
description: "Validation message",
|
|
51
|
+
table: {
|
|
52
|
+
type: { summary: "React.ReactNode" },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
count: {
|
|
56
|
+
description: "Character count",
|
|
57
|
+
table: {
|
|
58
|
+
type: { summary: "number" },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
options: {
|
|
62
|
+
description: 'If `as="select"` or `as={Field.Suggestion}`',
|
|
63
|
+
table: {
|
|
64
|
+
type: {
|
|
65
|
+
summary:
|
|
66
|
+
"string[] | { label: string; value: string; children?: React.ReactNode }[]",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
prefix: {
|
|
71
|
+
description: "Prefix",
|
|
72
|
+
table: {
|
|
73
|
+
type: { summary: "string" },
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
suffix: {
|
|
77
|
+
description: "Suffix",
|
|
78
|
+
table: {
|
|
79
|
+
type: { summary: "string" },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
helpText: {
|
|
83
|
+
description: "What to display in HelpText",
|
|
84
|
+
table: {
|
|
85
|
+
type: { summary: "React.ReactNode" },
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
helpTextLabel: {
|
|
89
|
+
description: "Label of HelpText button",
|
|
90
|
+
table: {
|
|
91
|
+
type: { summary: "string" },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
"data-nofilter": {
|
|
95
|
+
description: "If `as={Field.Suggestion}`",
|
|
96
|
+
table: {
|
|
97
|
+
type: { summary: "boolean" },
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
selected: {
|
|
101
|
+
description: "If `as={Field.Suggestion}`",
|
|
102
|
+
table: {
|
|
103
|
+
type: {
|
|
104
|
+
summary:
|
|
105
|
+
"{ label: string; value: string; children?: React.ReactNode }[]",
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
onSelectedChange: {
|
|
110
|
+
description: "If `as={Field.Suggestion}`",
|
|
111
|
+
table: {
|
|
112
|
+
type: { summary: "(selected) => void" },
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
decorators: [
|
|
117
|
+
(Story) => (
|
|
118
|
+
<div className={styles.grid}>
|
|
119
|
+
<Story />
|
|
120
|
+
</div>
|
|
121
|
+
),
|
|
122
|
+
],
|
|
123
|
+
} satisfies Meta;
|
|
124
|
+
|
|
125
|
+
export default meta;
|
|
126
|
+
type Story = StoryObj<typeof meta>;
|
|
127
|
+
|
|
128
|
+
export const Default: Story = {
|
|
129
|
+
render: () => (
|
|
130
|
+
<ds-field className={styles.field}>
|
|
131
|
+
<label>Ledetekst</label>
|
|
132
|
+
<p data-field="description">Beskrivelse</p>
|
|
133
|
+
<input type="text" className={styles.input} />
|
|
134
|
+
</ds-field>
|
|
135
|
+
),
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const React: Story = {
|
|
139
|
+
render: () => (
|
|
140
|
+
<>
|
|
141
|
+
<h2>
|
|
142
|
+
Field uten <code>as</code> attributt lar deg bygge opp av bestanddeler:
|
|
143
|
+
</h2>
|
|
144
|
+
<Field>
|
|
145
|
+
<Field.Label>Ledetekst</Field.Label>
|
|
146
|
+
<Field.Description>Beskrivelse</Field.Description>
|
|
147
|
+
<Input />
|
|
148
|
+
</Field>
|
|
149
|
+
<br />
|
|
150
|
+
<h2>
|
|
151
|
+
Field med <code>as="input"</code> gir deg en komplett field med
|
|
152
|
+
<small></small>
|
|
153
|
+
<br />
|
|
154
|
+
<code>label</code> + <code>description</code> + <code>input</code> +{" "}
|
|
155
|
+
<code>error</code> + <code>prefix</code> + <code>suffix</code>:
|
|
156
|
+
</h2>
|
|
157
|
+
<Field
|
|
158
|
+
as="input"
|
|
159
|
+
label="Ledetekst"
|
|
160
|
+
helpText="Hjelpetekst"
|
|
161
|
+
helpTextLabel="Vis hjelpetekst"
|
|
162
|
+
description="Beskrivelse"
|
|
163
|
+
validation="Feilmelding"
|
|
164
|
+
prefix="Før"
|
|
165
|
+
suffix="Etter"
|
|
166
|
+
/>
|
|
167
|
+
<br />
|
|
168
|
+
<h2>
|
|
169
|
+
Field med <code>as="input"</code> og <code>type="checkbox"</code>:
|
|
170
|
+
</h2>
|
|
171
|
+
<Field as="input" type="checkbox" label="Ledetekst" />
|
|
172
|
+
<br />
|
|
173
|
+
<h2>
|
|
174
|
+
Field med <code>as="textarea"</code> og{" "}
|
|
175
|
+
<code>count={15}</code>:
|
|
176
|
+
</h2>
|
|
177
|
+
<Field
|
|
178
|
+
as="textarea"
|
|
179
|
+
label="Ledetekst"
|
|
180
|
+
description="Beskrivelse"
|
|
181
|
+
count={15}
|
|
182
|
+
/>
|
|
183
|
+
<br />
|
|
184
|
+
<h2>
|
|
185
|
+
Field med <code>as="select"</code>:
|
|
186
|
+
</h2>
|
|
187
|
+
<Field as="select" label="Ledetekst" options={["Option 1", "Option 2"]} />
|
|
188
|
+
</>
|
|
189
|
+
),
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
export const Required: Story = {
|
|
193
|
+
parameters: { showInOverview: true },
|
|
194
|
+
render: () => (
|
|
195
|
+
<ds-field className={styles.field}>
|
|
196
|
+
<label>Ledetekst</label>
|
|
197
|
+
<p data-field="description">Beskrivelse</p>
|
|
198
|
+
<input type="text" required className={styles.input} />
|
|
199
|
+
</ds-field>
|
|
200
|
+
),
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
export const Indeterminate: Story = {
|
|
204
|
+
render: function Render() {
|
|
205
|
+
const [checked, setChecked] = useState(["1", "2"]);
|
|
206
|
+
const all = ["1", "2", "3"];
|
|
207
|
+
const isAll = checked.length === all.length;
|
|
208
|
+
|
|
209
|
+
const onChange = ({ target }: React.ChangeEvent<HTMLInputElement>) =>
|
|
210
|
+
setChecked(
|
|
211
|
+
checked.includes(target.value)
|
|
212
|
+
? checked.filter((v) => v !== target.value)
|
|
213
|
+
: [...checked, target.value],
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
<fieldset className={styles.fieldset}>
|
|
218
|
+
<legend>Velg alternativer</legend>
|
|
219
|
+
<ds-field className={styles.field}>
|
|
220
|
+
<label>Velg alle</label>
|
|
221
|
+
<input
|
|
222
|
+
checked={isAll}
|
|
223
|
+
className={styles.input}
|
|
224
|
+
data-indeterminate={!isAll && !!checked.length}
|
|
225
|
+
onChange={() => setChecked(isAll ? [] : all)}
|
|
226
|
+
type="checkbox"
|
|
227
|
+
/>
|
|
228
|
+
</ds-field>
|
|
229
|
+
<div className={styles.grid} style={{ paddingLeft: "var(--mtds-8)" }}>
|
|
230
|
+
{all.map((value) => (
|
|
231
|
+
<ds-field className={styles.field} key={value}>
|
|
232
|
+
<label>Alternativ 1</label>
|
|
233
|
+
<input
|
|
234
|
+
checked={checked.includes(value)}
|
|
235
|
+
className={styles.input}
|
|
236
|
+
onChange={onChange}
|
|
237
|
+
type="checkbox"
|
|
238
|
+
value={value}
|
|
239
|
+
/>
|
|
240
|
+
</ds-field>
|
|
241
|
+
))}
|
|
242
|
+
</div>
|
|
243
|
+
</fieldset>
|
|
244
|
+
);
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export const Toggles: Story = {
|
|
249
|
+
render: () => (
|
|
250
|
+
<>
|
|
251
|
+
<fieldset className={styles.fieldset} aria-label="Velg alternativ">
|
|
252
|
+
<ds-field className={styles.field}>
|
|
253
|
+
<label>Radio 1</label>
|
|
254
|
+
<input
|
|
255
|
+
type="radio"
|
|
256
|
+
className={styles.input}
|
|
257
|
+
name="my-radio"
|
|
258
|
+
defaultChecked
|
|
259
|
+
/>
|
|
260
|
+
</ds-field>
|
|
261
|
+
<ds-field className={styles.field}>
|
|
262
|
+
<label>Radio 2</label>
|
|
263
|
+
<p data-field="description">Beskrivelse</p>
|
|
264
|
+
<input type="radio" className={styles.input} name="my-radio" />
|
|
265
|
+
</ds-field>
|
|
266
|
+
</fieldset>
|
|
267
|
+
<ds-field className={styles.field}>
|
|
268
|
+
<label>Check</label>
|
|
269
|
+
<input type="checkbox" className={styles.input} />
|
|
270
|
+
</ds-field>
|
|
271
|
+
<ds-field className={styles.field}>
|
|
272
|
+
<label>Switch</label>
|
|
273
|
+
<input type="checkbox" className={styles.input} role="switch" />
|
|
274
|
+
</ds-field>
|
|
275
|
+
</>
|
|
276
|
+
),
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export const WithValidation: Story = {
|
|
280
|
+
parameters: { showInOverview: true },
|
|
281
|
+
render: () => (
|
|
282
|
+
<ds-field className={styles.field}>
|
|
283
|
+
<label>Ledetekst</label>
|
|
284
|
+
<p data-field="description">Beskrivelse</p>
|
|
285
|
+
<input type="text" className={styles.input} />
|
|
286
|
+
<div className={styles.validation} data-field="validation">
|
|
287
|
+
Validation
|
|
288
|
+
</div>
|
|
289
|
+
</ds-field>
|
|
290
|
+
),
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
export const WithValidationForm: Story = {
|
|
294
|
+
parameters: { layout: "padded" },
|
|
295
|
+
name: "With Validation Form",
|
|
296
|
+
render: () => {
|
|
297
|
+
const [selected, setSelected] = useState<FieldSuggestionSelected>([]);
|
|
298
|
+
|
|
299
|
+
return (
|
|
300
|
+
<form action="#" className={styles.prose} data-validation="form">
|
|
301
|
+
<ds-field className={styles.field}>
|
|
302
|
+
<label>E-post</label>
|
|
303
|
+
<p data-field="description">Beskrivelse</p>
|
|
304
|
+
<input type="email" className={styles.input} required />
|
|
305
|
+
<div className={styles.validation} data-field="validation">
|
|
306
|
+
Må inneholde en gyldig e-postadresse
|
|
307
|
+
</div>
|
|
308
|
+
</ds-field>
|
|
309
|
+
<ds-field className={styles.field}>
|
|
310
|
+
<label>Tekst</label>
|
|
311
|
+
<p data-field="description">Beskrivelse</p>
|
|
312
|
+
<input type="text" className={styles.input} required />
|
|
313
|
+
<div className={styles.validation} data-field="validation">
|
|
314
|
+
Må fylles ut
|
|
315
|
+
</div>
|
|
316
|
+
</ds-field>
|
|
317
|
+
<ds-field className={styles.field}>
|
|
318
|
+
<label>Suggestion</label>
|
|
319
|
+
<ds-suggestion className={styles.suggestion}>
|
|
320
|
+
<select hidden></select>
|
|
321
|
+
<input type="text" className={styles.input} aria-required="true" />
|
|
322
|
+
<del role="img" aria-label="Fjern tekst"></del>
|
|
323
|
+
<u-datalist>
|
|
324
|
+
<u-option value="Sogndal">Sogndal</u-option>
|
|
325
|
+
<u-option value="Oslo">Oslo</u-option>
|
|
326
|
+
<u-option value="Brønnøysund">Brønnøysund</u-option>
|
|
327
|
+
<u-option value="Stavanger">Stavanger</u-option>
|
|
328
|
+
<u-option value="Trondheim">Trondheim</u-option>
|
|
329
|
+
<u-option value="Bergen">Bergen</u-option>
|
|
330
|
+
<u-option value="Lillestrøm">Lillestrøm</u-option>
|
|
331
|
+
</u-datalist>
|
|
332
|
+
</ds-suggestion>
|
|
333
|
+
<div className={styles.validation} data-field="validation">
|
|
334
|
+
Må fylles ut
|
|
335
|
+
</div>
|
|
336
|
+
</ds-field>
|
|
337
|
+
<Field
|
|
338
|
+
as="input"
|
|
339
|
+
validation="Må fylles ut"
|
|
340
|
+
label="React input"
|
|
341
|
+
required
|
|
342
|
+
/>
|
|
343
|
+
<Field
|
|
344
|
+
aria-required="true"
|
|
345
|
+
as={Field.Suggestion}
|
|
346
|
+
label="React Suggestion"
|
|
347
|
+
onSelectedChange={setSelected}
|
|
348
|
+
selected={selected}
|
|
349
|
+
validation="Må fylles ut"
|
|
350
|
+
options={[
|
|
351
|
+
{ value: "Sogndal", label: "Sogndal" },
|
|
352
|
+
{ value: "Oslo", label: "Oslo" },
|
|
353
|
+
{ value: "Bergen", label: "Bergen" },
|
|
354
|
+
]}
|
|
355
|
+
/>
|
|
356
|
+
<button type="submit" className={styles.button} data-variant="primary">
|
|
357
|
+
Send inn
|
|
358
|
+
</button>
|
|
359
|
+
</form>
|
|
360
|
+
);
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
export const WithAffixes: Story = {
|
|
365
|
+
parameters: {
|
|
366
|
+
showInOverview: true,
|
|
367
|
+
},
|
|
368
|
+
render: () => (
|
|
369
|
+
<ds-field className={styles.field}>
|
|
370
|
+
<label>Pris i NOK per måned</label>
|
|
371
|
+
<div className={styles.affixes}>
|
|
372
|
+
<span>NOK</span>
|
|
373
|
+
<input type="text" className={styles.input} />
|
|
374
|
+
<span>pr. mnd.</span>
|
|
375
|
+
</div>
|
|
376
|
+
</ds-field>
|
|
377
|
+
),
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
export const WithCharacterCount: Story = {
|
|
381
|
+
parameters: {
|
|
382
|
+
layout: "padded",
|
|
383
|
+
showInOverview: true,
|
|
384
|
+
},
|
|
385
|
+
render: () => (
|
|
386
|
+
<ds-field className={styles.field}>
|
|
387
|
+
<label>Ledetekst</label>
|
|
388
|
+
<p data-field="description">Beskrivelse</p>
|
|
389
|
+
<textarea className={styles.input} defaultValue="Noe innhold" />
|
|
390
|
+
<p data-field="counter" data-limit="20" />
|
|
391
|
+
</ds-field>
|
|
392
|
+
),
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
export const WithCustomDescriptionTag: Story = {
|
|
396
|
+
parameters: { layout: "padded" },
|
|
397
|
+
render: () => (
|
|
398
|
+
<ds-field className={styles.field}>
|
|
399
|
+
<label>Ledetekst</label>
|
|
400
|
+
<div data-field="description" className={styles.prose}>
|
|
401
|
+
<p data-field="description">
|
|
402
|
+
Beskrivelse i en <code>data-field="description"</code> som virker med
|
|
403
|
+
og uten <code><p></code>
|
|
404
|
+
</p>
|
|
405
|
+
</div>
|
|
406
|
+
<textarea className={styles.input} defaultValue="Noe innhold" />
|
|
407
|
+
<p className={styles.validation} data-field="counter" data-limit="20" />
|
|
408
|
+
</ds-field>
|
|
409
|
+
),
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
export const WithSuggestion: Story = {
|
|
413
|
+
parameters: {
|
|
414
|
+
layout: "padded",
|
|
415
|
+
},
|
|
416
|
+
render: () => (
|
|
417
|
+
<ds-field className={styles.field}>
|
|
418
|
+
<label>Med forslag</label>
|
|
419
|
+
<ds-suggestion className={styles.suggestion}>
|
|
420
|
+
<input type="text" className={styles.input} />
|
|
421
|
+
<del role="img" aria-label="Fjern tekst"></del>
|
|
422
|
+
<u-datalist>
|
|
423
|
+
<u-option value="Sogndal">Sogndal</u-option>
|
|
424
|
+
<u-option value="Oslo">Oslo</u-option>
|
|
425
|
+
<u-option value="Brønnøysund">Brønnøysund</u-option>
|
|
426
|
+
<u-option value="Stavanger">Stavanger</u-option>
|
|
427
|
+
<u-option value="Trondheim">Trondheim</u-option>
|
|
428
|
+
<u-option value="Bergen">Bergen</u-option>
|
|
429
|
+
<u-option value="Lillestrøm">Lillestrøm</u-option>
|
|
430
|
+
</u-datalist>
|
|
431
|
+
</ds-suggestion>
|
|
432
|
+
<select name="form-data" hidden></select>
|
|
433
|
+
</ds-field>
|
|
434
|
+
),
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
export const WithSuggestionMultiple: Story = {
|
|
438
|
+
parameters: {
|
|
439
|
+
layout: "padded",
|
|
440
|
+
},
|
|
441
|
+
render: () => (
|
|
442
|
+
<ds-field className={styles.field}>
|
|
443
|
+
<label>Med forslag flervalg</label>
|
|
444
|
+
<ds-suggestion className={styles.suggestion} data-multiple>
|
|
445
|
+
<data value="Sogndal">Sogndal</data>
|
|
446
|
+
<input type="text" className={styles.input} />
|
|
447
|
+
<del role="img" aria-label="Fjern tekst"></del>
|
|
448
|
+
<u-datalist>
|
|
449
|
+
<u-option value="Sogndal">Sogndal</u-option>
|
|
450
|
+
<u-option value="Oslo">Oslo</u-option>
|
|
451
|
+
<u-option value="Brønnøysund">Brønnøysund</u-option>
|
|
452
|
+
<u-option value="Stavanger">Stavanger</u-option>
|
|
453
|
+
<u-option value="Trondheim">Trondheim</u-option>
|
|
454
|
+
<u-option value="Bergen">Bergen</u-option>
|
|
455
|
+
<u-option value="Lillestrøm">Lillestrøm</u-option>
|
|
456
|
+
</u-datalist>
|
|
457
|
+
</ds-suggestion>
|
|
458
|
+
</ds-field>
|
|
459
|
+
),
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
export const WithSuggestionMultipleInside: Story = {
|
|
463
|
+
parameters: {
|
|
464
|
+
layout: "padded",
|
|
465
|
+
},
|
|
466
|
+
render: () => (
|
|
467
|
+
<ds-field className={styles.field}>
|
|
468
|
+
<label>Med forslag flervalg inni</label>
|
|
469
|
+
<ds-suggestion
|
|
470
|
+
className={styles.suggestion}
|
|
471
|
+
data-multiple
|
|
472
|
+
data-variant="inside"
|
|
473
|
+
>
|
|
474
|
+
<data value="Sogndal">Sogndal</data>
|
|
475
|
+
<input type="text" className={styles.input} />
|
|
476
|
+
<del role="img" aria-label="Fjern tekst"></del>
|
|
477
|
+
<u-datalist>
|
|
478
|
+
<u-option value="Sogndal">Sogndal</u-option>
|
|
479
|
+
<u-option value="Oslo">Oslo</u-option>
|
|
480
|
+
<u-option value="Brønnøysund">Brønnøysund</u-option>
|
|
481
|
+
<u-option value="Stavanger">Stavanger</u-option>
|
|
482
|
+
<u-option value="Trondheim">Trondheim</u-option>
|
|
483
|
+
<u-option value="Bergen">Bergen</u-option>
|
|
484
|
+
<u-option value="Lillestrøm">Lillestrøm</u-option>
|
|
485
|
+
</u-datalist>
|
|
486
|
+
</ds-suggestion>
|
|
487
|
+
</ds-field>
|
|
488
|
+
),
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
export const WithSuggestionCreatable: Story = {
|
|
492
|
+
parameters: {
|
|
493
|
+
layout: "padded",
|
|
494
|
+
},
|
|
495
|
+
render: () => (
|
|
496
|
+
<ds-field className={styles.field}>
|
|
497
|
+
<label>Skriv noe som ikke finnes i listen og trykk Enter:</label>
|
|
498
|
+
<ds-suggestion className={styles.suggestion} data-multiple data-creatable>
|
|
499
|
+
<data value="Sogndal">Sogndal</data>
|
|
500
|
+
<input type="text" className={styles.input} />
|
|
501
|
+
<del role="img" aria-label="Fjern tekst"></del>
|
|
502
|
+
<u-datalist>
|
|
503
|
+
<u-option value="Sogndal">Sogndal</u-option>
|
|
504
|
+
<u-option value="Oslo">Oslo</u-option>
|
|
505
|
+
<u-option value="Brønnøysund">Brønnøysund</u-option>
|
|
506
|
+
<u-option value="Stavanger">Stavanger</u-option>
|
|
507
|
+
<u-option value="Trondheim">Trondheim</u-option>
|
|
508
|
+
<u-option value="Bergen">Bergen</u-option>
|
|
509
|
+
<u-option value="Lillestrøm">Lillestrøm</u-option>
|
|
510
|
+
</u-datalist>
|
|
511
|
+
</ds-suggestion>
|
|
512
|
+
</ds-field>
|
|
513
|
+
),
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
export const WithSuggestionAPI: Story = {
|
|
517
|
+
parameters: {
|
|
518
|
+
layout: "padded",
|
|
519
|
+
},
|
|
520
|
+
render: () => {
|
|
521
|
+
const [options, setOptions] = useState<string[] | string>("Name a country"); // Store results
|
|
522
|
+
const timer = useRef<ReturnType<typeof setTimeout> | number>(0);
|
|
523
|
+
|
|
524
|
+
const getCountries = async (value: string) => {
|
|
525
|
+
if (!value) return setOptions("Name a country");
|
|
526
|
+
const api = `https://restcountries.com/v2/name/${value}?fields=name`;
|
|
527
|
+
const countries = await (await fetch(api)).json();
|
|
528
|
+
|
|
529
|
+
setOptions(
|
|
530
|
+
Array.isArray(countries)
|
|
531
|
+
? countries.map(({ name }) => name)
|
|
532
|
+
: "No results",
|
|
533
|
+
);
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
const handleInput = (event: React.InputEvent<HTMLInputElement>) => {
|
|
537
|
+
const value = encodeURIComponent(event.currentTarget.value.trim());
|
|
538
|
+
|
|
539
|
+
setOptions(value ? "Loading..." : "Name a country");
|
|
540
|
+
clearTimeout(timer.current);
|
|
541
|
+
timer.current = setTimeout(getCountries, 500, value); // Debounce API call
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
return (
|
|
545
|
+
<ds-field className={styles.field}>
|
|
546
|
+
<label>Med henting av resultater fra API</label>
|
|
547
|
+
<ds-suggestion className={styles.suggestion}>
|
|
548
|
+
<input
|
|
549
|
+
type="search"
|
|
550
|
+
className={styles.input}
|
|
551
|
+
onInput={handleInput} // Note: using onInput, not onChange
|
|
552
|
+
/>
|
|
553
|
+
<del role="img" aria-label="Fjern tekst"></del>
|
|
554
|
+
<u-datalist data-nofilter>
|
|
555
|
+
{Array.isArray(options) ? (
|
|
556
|
+
options.map((option) => (
|
|
557
|
+
<u-option key={option}>{option}</u-option>
|
|
558
|
+
))
|
|
559
|
+
) : (
|
|
560
|
+
<u-option value="">{options}</u-option>
|
|
561
|
+
)}
|
|
562
|
+
</u-datalist>
|
|
563
|
+
</ds-suggestion>
|
|
564
|
+
</ds-field>
|
|
565
|
+
);
|
|
566
|
+
},
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
export const WithSuggestionCustomFilter: Story = {
|
|
570
|
+
parameters: {
|
|
571
|
+
layout: "padded",
|
|
572
|
+
},
|
|
573
|
+
render: () => {
|
|
574
|
+
const ref = useRef<DSSuggestionElement>(null);
|
|
575
|
+
const [value, setValue] = useState("");
|
|
576
|
+
const options = [
|
|
577
|
+
"Sogndal",
|
|
578
|
+
"Oslo",
|
|
579
|
+
"Brønnøysund",
|
|
580
|
+
"Stavanger",
|
|
581
|
+
"Trondheim",
|
|
582
|
+
"Bergen",
|
|
583
|
+
"Lillestrøm",
|
|
584
|
+
];
|
|
585
|
+
|
|
586
|
+
return (
|
|
587
|
+
<ds-field className={styles.field}>
|
|
588
|
+
<label>Eget filter - gir kun treff fra starten av ordet</label>
|
|
589
|
+
<ds-suggestion className={styles.suggestion} ref={ref}>
|
|
590
|
+
<input
|
|
591
|
+
className={styles.input}
|
|
592
|
+
onInput={({ currentTarget }) => setValue(currentTarget.value)}
|
|
593
|
+
/>
|
|
594
|
+
<del role="img" aria-label="Fjern tekst"></del>
|
|
595
|
+
<u-datalist data-nofilter>
|
|
596
|
+
{options
|
|
597
|
+
.filter((option) =>
|
|
598
|
+
option.toLowerCase().startsWith(value.toLowerCase()),
|
|
599
|
+
)
|
|
600
|
+
.map((option) => (
|
|
601
|
+
<u-option key={option} value={option}>
|
|
602
|
+
{option}
|
|
603
|
+
</u-option>
|
|
604
|
+
))}
|
|
605
|
+
</u-datalist>
|
|
606
|
+
</ds-suggestion>
|
|
607
|
+
</ds-field>
|
|
608
|
+
);
|
|
609
|
+
},
|
|
610
|
+
};
|
|
611
|
+
|
|
612
|
+
export const ReactWithSuggestion: Story = {
|
|
613
|
+
parameters: {
|
|
614
|
+
layout: "padded",
|
|
615
|
+
},
|
|
616
|
+
render: function Render() {
|
|
617
|
+
// IMPORTANT:
|
|
618
|
+
// Using Field.Suggestion requires
|
|
619
|
+
// "use client" if doing server-side rendering
|
|
620
|
+
const [selected, setSelected] = useState<FieldSuggestionSelected>([
|
|
621
|
+
{ value: "saft", label: "Saft" },
|
|
622
|
+
]);
|
|
623
|
+
|
|
624
|
+
return (
|
|
625
|
+
<Field
|
|
626
|
+
as={Field.Suggestion}
|
|
627
|
+
label="React med forslag"
|
|
628
|
+
description="Beskrivelse"
|
|
629
|
+
selected={selected}
|
|
630
|
+
onSelectedChange={setSelected}
|
|
631
|
+
options={[
|
|
632
|
+
{ value: "saft", label: "Saft" },
|
|
633
|
+
{
|
|
634
|
+
value: "suse",
|
|
635
|
+
label: "Suse",
|
|
636
|
+
children: (
|
|
637
|
+
<Flex data-align="center">
|
|
638
|
+
<WindIcon /> Suse
|
|
639
|
+
</Flex>
|
|
640
|
+
),
|
|
641
|
+
},
|
|
642
|
+
]}
|
|
643
|
+
/>
|
|
644
|
+
);
|
|
645
|
+
},
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
export const ReactWithSuggestionWithChildren: Story = {
|
|
649
|
+
parameters: {
|
|
650
|
+
layout: "padded",
|
|
651
|
+
},
|
|
652
|
+
render: function Render() {
|
|
653
|
+
const multiple = true;
|
|
654
|
+
const [selected, setSelected] = useState<FieldSuggestionSelected>([]);
|
|
655
|
+
|
|
656
|
+
return (
|
|
657
|
+
<Field>
|
|
658
|
+
<Field.Label>React med Field.Suggestion med barn</Field.Label>
|
|
659
|
+
<Field.Description>
|
|
660
|
+
Hvis Field.Suggestion har barn, tegner den ikke input selv.
|
|
661
|
+
</Field.Description>
|
|
662
|
+
<Field.Suggestion
|
|
663
|
+
data-multiple={multiple}
|
|
664
|
+
selected={selected}
|
|
665
|
+
onSelectedChange={setSelected}
|
|
666
|
+
>
|
|
667
|
+
<Input />
|
|
668
|
+
<del role="img" aria-label="Fjern tekst"></del>
|
|
669
|
+
<Field.Datalist>
|
|
670
|
+
<Field.Option value="saft" label="Saft">
|
|
671
|
+
<Flex data-align="center">
|
|
672
|
+
<PintGlassIcon /> Saft
|
|
673
|
+
</Flex>
|
|
674
|
+
</Field.Option>
|
|
675
|
+
<Field.Option value="suse" label="Suse">
|
|
676
|
+
<Flex data-align="center">
|
|
677
|
+
<WindIcon /> Suse
|
|
678
|
+
</Flex>
|
|
679
|
+
</Field.Option>
|
|
680
|
+
</Field.Datalist>
|
|
681
|
+
</Field.Suggestion>
|
|
682
|
+
</Field>
|
|
683
|
+
);
|
|
684
|
+
},
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
export const ReactWithSuggestionMultiple: Story = {
|
|
688
|
+
parameters: {
|
|
689
|
+
layout: "padded",
|
|
690
|
+
},
|
|
691
|
+
render: function Render() {
|
|
692
|
+
// IMPORTANT:
|
|
693
|
+
// Using Field.Suggestion requires
|
|
694
|
+
// "use client" if doing server-side rendering
|
|
695
|
+
const [selected, setSelected] = useState<FieldSuggestionSelected>([
|
|
696
|
+
{ value: "saft", label: "Saft" },
|
|
697
|
+
]);
|
|
698
|
+
|
|
699
|
+
return (
|
|
700
|
+
<Field
|
|
701
|
+
as={Field.Suggestion}
|
|
702
|
+
data-multiple
|
|
703
|
+
label="React med forslag flervalg"
|
|
704
|
+
selected={selected}
|
|
705
|
+
onSelectedChange={setSelected}
|
|
706
|
+
options={[
|
|
707
|
+
{ value: "saft", label: "Saft" },
|
|
708
|
+
{ value: "suse", label: "Suse" },
|
|
709
|
+
]}
|
|
710
|
+
/>
|
|
711
|
+
);
|
|
712
|
+
},
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
export const ReactWithSuggestionMultipleInside: Story = {
|
|
716
|
+
parameters: {
|
|
717
|
+
layout: "padded",
|
|
718
|
+
},
|
|
719
|
+
render: function Render() {
|
|
720
|
+
// IMPORTANT:
|
|
721
|
+
// Using Field.Suggestion requires
|
|
722
|
+
// "use client" if doing server-side rendering
|
|
723
|
+
const [selected, setSelected] = useState<FieldSuggestionSelected>([
|
|
724
|
+
{ value: "saft", label: "Saft" },
|
|
725
|
+
]);
|
|
726
|
+
|
|
727
|
+
return (
|
|
728
|
+
<Field
|
|
729
|
+
as={Field.Suggestion}
|
|
730
|
+
data-multiple
|
|
731
|
+
data-variant="inside"
|
|
732
|
+
label="React med forslag flervalg"
|
|
733
|
+
selected={selected}
|
|
734
|
+
onSelectedChange={setSelected}
|
|
735
|
+
options={[
|
|
736
|
+
{ value: "saft", label: "Saft" },
|
|
737
|
+
{ value: "suse", label: "Suse" },
|
|
738
|
+
]}
|
|
739
|
+
/>
|
|
740
|
+
);
|
|
741
|
+
},
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
export const ReactWithSuggestionCreatable: Story = {
|
|
745
|
+
parameters: {
|
|
746
|
+
layout: "padded",
|
|
747
|
+
},
|
|
748
|
+
render: function Render() {
|
|
749
|
+
// IMPORTANT:
|
|
750
|
+
// Using Field.Suggestion requires
|
|
751
|
+
// "use client" if doing server-side rendering
|
|
752
|
+
const [selected, setSelected] = useState<FieldSuggestionSelected>([
|
|
753
|
+
{ value: "saft", label: "Saft" },
|
|
754
|
+
]);
|
|
755
|
+
|
|
756
|
+
return (
|
|
757
|
+
<Field
|
|
758
|
+
as={Field.Suggestion}
|
|
759
|
+
data-multiple
|
|
760
|
+
data-creatable
|
|
761
|
+
label="React med forslag flervalg"
|
|
762
|
+
selected={selected}
|
|
763
|
+
onSelectedChange={setSelected}
|
|
764
|
+
options={[
|
|
765
|
+
{ value: "saft", label: "Saft" },
|
|
766
|
+
{ value: "suse", label: "Suse" },
|
|
767
|
+
]}
|
|
768
|
+
/>
|
|
769
|
+
);
|
|
770
|
+
},
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
export const ReactWithSuggestionLong: Story = {
|
|
774
|
+
parameters: {
|
|
775
|
+
layout: "padded",
|
|
776
|
+
},
|
|
777
|
+
render: () => {
|
|
778
|
+
// IMPORTANT:
|
|
779
|
+
// Using Field.Suggestion requires
|
|
780
|
+
// "use client" if doing server-side rendering
|
|
781
|
+
const [selected, setSelected] = useState<FieldSuggestionSelected>([]);
|
|
782
|
+
|
|
783
|
+
return (
|
|
784
|
+
<>
|
|
785
|
+
<div style={{ height: 400 }} />
|
|
786
|
+
<Field>
|
|
787
|
+
<Field.Label>React med lange og mange</Field.Label>
|
|
788
|
+
<Field.Description>Beskrivelse</Field.Description>
|
|
789
|
+
<Field.Suggestion selected={selected} onSelectedChange={setSelected}>
|
|
790
|
+
<Input />
|
|
791
|
+
<del role="img" aria-label="Fjern tekst"></del>
|
|
792
|
+
<Field.Datalist data-nofilter data-placement="top">
|
|
793
|
+
<Field.Option>
|
|
794
|
+
Thunder Thunder Thunder Thunder Thunder Thunder Thunder Thunder
|
|
795
|
+
Thunder Thunder Thunder Thunder Thunder
|
|
796
|
+
</Field.Option>
|
|
797
|
+
<Field.Option>Whisper</Field.Option>
|
|
798
|
+
<Field.Option>Galaxy</Field.Option>
|
|
799
|
+
<Field.Option>Melody</Field.Option>
|
|
800
|
+
<Field.Option>Crystal</Field.Option>
|
|
801
|
+
<Field.Option>Sunset</Field.Option>
|
|
802
|
+
<Field.Option>Journey</Field.Option>
|
|
803
|
+
<Field.Option>Phoenix</Field.Option>
|
|
804
|
+
<Field.Option>Harmony</Field.Option>
|
|
805
|
+
<Field.Option>Neptune</Field.Option>
|
|
806
|
+
<Field.Option>Cascade</Field.Option>
|
|
807
|
+
<Field.Option>Velvet</Field.Option>
|
|
808
|
+
<Field.Option>Rhythm</Field.Option>
|
|
809
|
+
<Field.Option>Compass</Field.Option>
|
|
810
|
+
<Field.Option>Prism</Field.Option>
|
|
811
|
+
<Field.Option>Breeze</Field.Option>
|
|
812
|
+
<Field.Option>Eclipse</Field.Option>
|
|
813
|
+
<Field.Option>Sterling</Field.Option>
|
|
814
|
+
<Field.Option>Canvas</Field.Option>
|
|
815
|
+
<Field.Option>Zenith</Field.Option>
|
|
816
|
+
</Field.Datalist>
|
|
817
|
+
</Field.Suggestion>
|
|
818
|
+
</Field>
|
|
819
|
+
<div style={{ height: 800 }} />
|
|
820
|
+
</>
|
|
821
|
+
);
|
|
822
|
+
},
|
|
823
|
+
};
|
|
824
|
+
|
|
825
|
+
export const ReactWithSuggestionCustomFilter: Story = {
|
|
826
|
+
parameters: {
|
|
827
|
+
layout: "padded",
|
|
828
|
+
},
|
|
829
|
+
render: function Render() {
|
|
830
|
+
const [value, setValue] = useState("");
|
|
831
|
+
const [selected, setSelected] = useState<FieldSuggestionSelected>([]);
|
|
832
|
+
const options = [
|
|
833
|
+
"Sogndal",
|
|
834
|
+
"Oslo",
|
|
835
|
+
"Brønnøysund",
|
|
836
|
+
"Stavanger",
|
|
837
|
+
"Trondheim",
|
|
838
|
+
"Bergen",
|
|
839
|
+
"Lillestrøm",
|
|
840
|
+
];
|
|
841
|
+
|
|
842
|
+
return (
|
|
843
|
+
<Field>
|
|
844
|
+
<Field.Label>Filterer på starten av ordet</Field.Label>
|
|
845
|
+
<Field.Suggestion
|
|
846
|
+
data-nofilter
|
|
847
|
+
data-multiple
|
|
848
|
+
selected={selected}
|
|
849
|
+
onSelectedChange={setSelected}
|
|
850
|
+
options={options
|
|
851
|
+
.filter((opt) => opt.toLowerCase().startsWith(value.toLowerCase()))
|
|
852
|
+
.map((value) => ({ label: value, value }))}
|
|
853
|
+
>
|
|
854
|
+
<Input
|
|
855
|
+
value={value}
|
|
856
|
+
onInput={({ currentTarget }) => setValue(currentTarget.value)}
|
|
857
|
+
/>
|
|
858
|
+
<del role="img" aria-label="Fjern tekst"></del>
|
|
859
|
+
</Field.Suggestion>
|
|
860
|
+
</Field>
|
|
861
|
+
);
|
|
862
|
+
},
|
|
863
|
+
};
|