@mattilsynet/design 3.2.9 → 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.
Files changed (90) hide show
  1. package/mtds/ai/AGENTS.md +892 -0
  2. package/mtds/ai/alert.mdx +63 -0
  3. package/mtds/ai/alert.stories.tsx +128 -0
  4. package/mtds/ai/analytics.mdx +185 -0
  5. package/mtds/ai/app.mdx +60 -0
  6. package/mtds/ai/app.stories.tsx +897 -0
  7. package/mtds/ai/atlas.mdx +82 -0
  8. package/mtds/ai/atlas.stories.tsx +424 -0
  9. package/mtds/ai/avatar.mdx +45 -0
  10. package/mtds/ai/avatar.stories.tsx +109 -0
  11. package/mtds/ai/badge.mdx +70 -0
  12. package/mtds/ai/badge.stories.tsx +122 -0
  13. package/mtds/ai/breadcrumbs.mdx +36 -0
  14. package/mtds/ai/breadcrumbs.stories.tsx +158 -0
  15. package/mtds/ai/button.mdx +179 -0
  16. package/mtds/ai/button.stories.tsx +440 -0
  17. package/mtds/ai/card.mdx +51 -0
  18. package/mtds/ai/card.stories.tsx +469 -0
  19. package/mtds/ai/chart.mdx +67 -0
  20. package/mtds/ai/chart.stories.tsx +519 -0
  21. package/mtds/ai/chip.mdx +71 -0
  22. package/mtds/ai/chip.stories.tsx +211 -0
  23. package/mtds/ai/details.mdx +33 -0
  24. package/mtds/ai/details.stories.tsx +91 -0
  25. package/mtds/ai/dialog.mdx +38 -0
  26. package/mtds/ai/dialog.stories.tsx +373 -0
  27. package/mtds/ai/divider.mdx +19 -0
  28. package/mtds/ai/divider.stories.tsx +50 -0
  29. package/mtds/ai/errorsummary.mdx +26 -0
  30. package/mtds/ai/errorsummary.stories.tsx +137 -0
  31. package/mtds/ai/field.mdx +86 -0
  32. package/mtds/ai/field.stories.tsx +863 -0
  33. package/mtds/ai/fieldset.mdx +126 -0
  34. package/mtds/ai/fieldset.stories.tsx +298 -0
  35. package/mtds/ai/fileupload.mdx +16 -0
  36. package/mtds/ai/fileupload.stories.tsx +126 -0
  37. package/mtds/ai/helptext.mdx +24 -0
  38. package/mtds/ai/helptext.stories.tsx +106 -0
  39. package/mtds/ai/input.mdx +223 -0
  40. package/mtds/ai/input.stories.tsx +352 -0
  41. package/mtds/ai/law.mdx +115 -0
  42. package/mtds/ai/law.stories.tsx +168 -0
  43. package/mtds/ai/layout.mdx +145 -0
  44. package/mtds/ai/layout.stories.tsx +443 -0
  45. package/mtds/ai/link.mdx +45 -0
  46. package/mtds/ai/link.stories.tsx +44 -0
  47. package/mtds/ai/logo.mdx +86 -0
  48. package/mtds/ai/logo.stories.tsx +146 -0
  49. package/mtds/ai/pagination.mdx +136 -0
  50. package/mtds/ai/pagination.stories.tsx +404 -0
  51. package/mtds/ai/popover.mdx +86 -0
  52. package/mtds/ai/popover.stories.tsx +355 -0
  53. package/mtds/ai/print.mdx +96 -0
  54. package/mtds/ai/print.stories.tsx +839 -0
  55. package/mtds/ai/progress.mdx +41 -0
  56. package/mtds/ai/progress.stories.tsx +141 -0
  57. package/mtds/ai/skeleton.mdx +26 -0
  58. package/mtds/ai/skeleton.stories.tsx +131 -0
  59. package/mtds/ai/spinner.mdx +26 -0
  60. package/mtds/ai/spinner.stories.tsx +72 -0
  61. package/mtds/ai/steps.mdx +37 -0
  62. package/mtds/ai/steps.stories.tsx +568 -0
  63. package/mtds/ai/table.mdx +124 -0
  64. package/mtds/ai/table.stories.tsx +1715 -0
  65. package/mtds/ai/tabs.mdx +106 -0
  66. package/mtds/ai/tabs.stories.tsx +159 -0
  67. package/mtds/ai/tag.mdx +49 -0
  68. package/mtds/ai/tag.stories.tsx +111 -0
  69. package/mtds/ai/toast.mdx +67 -0
  70. package/mtds/ai/toast.stories.tsx +215 -0
  71. package/mtds/ai/togglegroup.mdx +75 -0
  72. package/mtds/ai/togglegroup.stories.tsx +96 -0
  73. package/mtds/ai/tooltip.mdx +32 -0
  74. package/mtds/ai/tooltip.stories.tsx +34 -0
  75. package/mtds/ai/typography.mdx +67 -0
  76. package/mtds/ai/typography.stories.tsx +798 -0
  77. package/mtds/ai/validation.mdx +19 -0
  78. package/mtds/ai/validation.stories.tsx +45 -0
  79. package/mtds/atlas/atlas-element.js +1 -1
  80. package/mtds/chart/chart-lines.js +19 -19
  81. package/mtds/chart/chart-lines.js.map +1 -1
  82. package/mtds/chart/chart.css.js +16 -1
  83. package/mtds/chart/chart.css.js.map +1 -1
  84. package/mtds/chart/chart.stories.d.ts +1 -0
  85. package/mtds/index.iife.js +32 -17
  86. package/mtds/package.json.js +1 -1
  87. package/mtds/styles.css +1 -1
  88. package/mtds/table/table-observer.js +26 -15
  89. package/mtds/table/table-observer.js.map +1 -1
  90. package/package.json +4 -2
@@ -0,0 +1,223 @@
1
+ import { Meta, Canvas } from '@storybook/addon-docs/blocks';
2
+ import { JumpTo, Example, CssVariables } from '../../.storybook/blocks';
3
+ import * as stories from './input.stories';
4
+ import { Flex, Prose } from '../react';
5
+ import styles from '../styles.module.css';
6
+
7
+ <Meta of={stories} />
8
+
9
+ # Input
10
+ >Input er et skjemaelement for å samle inn brukerdata. Det tilbyr grunnleggende funksjonalitet og er ideell når du trenger full kontroll over komponentens oppsett og validering, noe som gjør det ideelt for bygging av spesialtilpassede elementer.
11
+
12
+ <JumpTo />
13
+
14
+ ## Kode
15
+ - Legg klassen `input` på `<input>`, `<select>` eller `<textarea>`
16
+ - Input `type="radio"`, `type="checkbox"` og `role="switch"` er også støttet
17
+ - Bruk [field](?path=/docs/designsystem-field--docs) for automatisk kobling mot `<label>` eller `aria-label` på `input` for skjult label
18
+ <Canvas of={stories.Default} />
19
+
20
+ ## Skikk og bruk
21
+ ### Tekstfelt
22
+ <Flex data-items="350">
23
+ {/* Viser tekstfelt som ligger over hverandre */}
24
+ <Example data-color="success" data-variant="false" text="Plasser tekstfelt over hverandre, slik at det er lettere å navigere mellom komponentene og skanne innholdet." zoom="100%">
25
+ <div className={styles.prose} data-items="auto">
26
+ <ds-field className={styles.field}>
27
+ <label>Fornavn</label>
28
+ <input className={styles.input} />
29
+ </ds-field>
30
+
31
+ <ds-field className={styles.field}>
32
+ <label>Etternavn</label>
33
+ <input className={styles.input} />
34
+ </ds-field>
35
+
36
+ <ds-field className={styles.field}>
37
+ <label>E-post</label>
38
+ <input className={styles.input} />
39
+ </ds-field>
40
+
41
+ <ds-field className={styles.field}>
42
+ <label>Telefon</label>
43
+ <input className={styles.input} />
44
+ </ds-field>
45
+ </div>
46
+
47
+ </Example>
48
+ <Example data-color="danger" data-variant="false" text="Unngå plassering av tekstfelt ved siden av hverandre. Skannbarheten blir dårligere." zoom="100%">
49
+ <div className={styles.grid} data-items="150" data-gap="6">
50
+ <ds-field className={styles.field}>
51
+ <label>Fornavn</label>
52
+ <input className={styles.input} type="number" />
53
+ </ds-field>
54
+
55
+ <ds-field className={styles.field}>
56
+ <label>Etternavn</label>
57
+ <input className={styles.input} type="text" inputMode="numeric" />
58
+ </ds-field>
59
+ <ds-field className={styles.field}>
60
+ <label>E-post</label>
61
+ <input className={styles.input} type="number" />
62
+ </ds-field>
63
+
64
+ <ds-field className={styles.field}>
65
+ <label>Telefon</label>
66
+ <input className={styles.input} type="text" inputMode="numeric" />
67
+ </ds-field>
68
+ </div>
69
+ </Example>
70
+ </Flex>
71
+
72
+ ### Switch
73
+ <Flex data-items="350">
74
+ {/* Viser tekstfelt som ligger over hverandre */}
75
+ <Example data-color="success" data-variant="false" text="Bruk tydelig og beskrivende labeltekst. Status vises i selve komponenten." zoom="100%">
76
+ <ds-field className={styles.field}>
77
+ <label>Varsle via e-post</label>
78
+ <input type="checkbox" role="switch" className={styles.input} />
79
+ </ds-field>
80
+ </Example>
81
+ <Example data-color="danger" data-variant="false" text="Unngå beskrivelse av status i labelteksten, da dette kan forvirre brukeren." zoom="100%">
82
+ <ds-field className={styles.field}>
83
+ <label>Slå på e-postvarsling</label>
84
+ <input type="checkbox" role="switch" className={styles.input} />
85
+ </ds-field>
86
+ </Example>
87
+ </Flex>
88
+
89
+ ### Radio
90
+ <Flex data-items="350">
91
+ <Example data-color="success" data-variant="false" text="Det er anbefalt å bruke radio hvis du har færre enn 5-7 alternativer." zoom="100%">
92
+ <fieldset className={styles.fieldset}>
93
+ <legend>Skal du reise med hund?</legend>
94
+ <ds-field className={styles.field}>
95
+ <input type="radio" className={styles.input} name="do-radio"/>
96
+ <label>Ja</label>
97
+ </ds-field>
98
+ <ds-field className={styles.field}>
99
+ <input type="radio" className={styles.input} name="do-radio"/>
100
+ <label>Nei</label>
101
+ </ds-field>
102
+ </fieldset>
103
+ </Example>
104
+ <Example data-color="danger" data-variant="false" text="Bruk av radio med mange alternativer gjør det mer tungvindt for bruker å ta et raskt valg." zoom="100%">
105
+ <fieldset className={styles.fieldset}>
106
+ <legend>Hvilken hunderase skal du reise med?</legend>
107
+ <ds-field className={styles.field}>
108
+ <input type="radio" className={styles.input} name="dont-radio"/>
109
+ <label>Golden retriever</label>
110
+ </ds-field>
111
+ <ds-field className={styles.field}>
112
+ <input type="radio" className={styles.input} name="dont-radio"/>
113
+ <label>Fuglehund</label>
114
+ </ds-field>
115
+ <ds-field className={styles.field}>
116
+ <input type="radio" className={styles.input} name="dont-radio"/>
117
+ <label>Cocker spaniel</label>
118
+ </ds-field>
119
+ <ds-field className={styles.field}>
120
+ <input type="radio" className={styles.input} name="dont-radio"/>
121
+ <label>Terrier</label>
122
+ </ds-field>
123
+ <ds-field className={styles.field}>
124
+ <input type="radio" className={styles.input} name="dont-radio"/>
125
+ <label>Beagle</label>
126
+ </ds-field>
127
+ <ds-field className={styles.field}>
128
+ <input type="radio" className={styles.input} name="dont-radio"/>
129
+ <label>Chihuahua</label>
130
+ </ds-field>
131
+ <ds-field className={styles.field}>
132
+ <input type="radio" className={styles.input} name="dont-radio"/>
133
+ <label>Puddel</label>
134
+ </ds-field>
135
+ <ds-field className={styles.field}>
136
+ <input type="radio" className={styles.input} name="dont-radio"/>
137
+ <label>Setter</label>
138
+ </ds-field>
139
+ <ds-field className={styles.field}>
140
+ <input type="radio" className={styles.input} name="dont-radio"/>
141
+ <label>Spisshund</label>
142
+ </ds-field>
143
+ </fieldset>
144
+ </Example>
145
+ </Flex>
146
+
147
+ ### Select
148
+ <Flex data-items="350">
149
+ <Example data-color="success" data-variant="false" text="Bruk select når det er mange alternativer." zoom="100%">
150
+ <ds-field className={styles.field}>
151
+ <label>Hvor skal du reise med hund?</label>
152
+ <select className={styles.input}>
153
+ <option>Albania</option>
154
+ <option>Bahamas</option>
155
+ <option>Canada</option>
156
+ <option>Danmark</option>
157
+ <option>Estland</option>
158
+ <option>Finland</option>
159
+ <option>Georgia</option>
160
+ <option>Hellas</option>
161
+ <option>India</option>
162
+ <option>Japan</option>
163
+ <option>Kroatia</option>
164
+ <option>Latvia</option>
165
+ <option>Maldivene</option>
166
+ </select>
167
+ </ds-field>
168
+ </Example>
169
+ <Example data-color="danger" data-variant="false" text="Ikke bruk select når det er få alternativer." zoom="100%">
170
+ <ds-field className={styles.field}>
171
+ <label>Har hunden noen kjente sykdommer?</label>
172
+ <select className={styles.input}>
173
+ <option>Ja</option>
174
+ <option>Nei</option>
175
+ </select>
176
+ </ds-field>
177
+ </Example>
178
+ </Flex>
179
+
180
+ ## Typer
181
+ - Bruk `<select>`, `<textarea>` eller `<input type="text | checkbox | radio | email | number | password | radio | search | tel | url">`
182
+ - Kombiner `type="checkbox" role="switch"` for å få bryter-design
183
+ <Canvas of={stories.Types} />
184
+
185
+ ## Størrelser
186
+ - Bruk `data-size="sm | md | lg"`
187
+ - Bruk `size="number"` for å sette en bredde som indikere antall tegn
188
+ <Canvas of={stories.Sizes} />
189
+
190
+ ## Read only
191
+ - Legg på attributt `readonly`
192
+ - Husk også `disabled` dersom du legger `readonly` på `type="checkbox"` eller `type="radio"`, siden disse ikke stoppes automatisk av nettleseren
193
+ - **Merk:** `readonly disabled` felter ikke sendes inn som skjemadata i verken `<form>` eller `FormData`
194
+ <Canvas of={stories.ReadOnly} />
195
+
196
+ ## Disabled
197
+ - Legg på attributt `disabled`
198
+ <Canvas of={stories.Disabled} />
199
+
200
+ ## Indeterminate
201
+ - Legg på attributt `data-indeterminate` på `type="checkbox"` for å indikere en tilstand som er verken av eller på, f.eks
202
+ <Canvas of={stories.Indeterminate} />
203
+
204
+ ## Søk
205
+ - Bruk `type="search"`
206
+ - Bruk `data-icon="none"` dersom du ønsker å skjule forstørrelsesglass-ikonet
207
+ <Canvas of={stories.TypeSearch} />
208
+
209
+ ## Datovelger
210
+ - Bruk `type="date"`
211
+ <Canvas of={stories.TypeDate} />
212
+
213
+ ## Tall
214
+ - Øker taller inkrementelt (f.eks. et antall av noe)? Bruk `type="number"`
215
+ - Skal tallet ikke øke (f.eks. referansenummer, fødselsnummer, etc.)? Bruk `type="text" inputmode="numeric"`
216
+ - Nysgjerrig? [Les mer om input og tall på GOV.uk](https://technology.blog.gov.uk/2020/02/24/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers/)
217
+ <Canvas of={stories.TypeNumber} />
218
+
219
+ ## Variant Inline (Eksperimentell)
220
+ - Bruk `data-variant="inline"` på `input`, `select` eller `textarea` for subtil fremtoning
221
+ <Canvas of={stories.VariantInline} />
222
+
223
+ <CssVariables component="input" />
@@ -0,0 +1,352 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { Field, Input } from "../react";
3
+ import styles from "../styles.module.css";
4
+
5
+ const meta = {
6
+ title: "Designsystem/Input",
7
+ decorators: [
8
+ (Story) => (
9
+ <div className={styles.grid}>
10
+ <Story />
11
+ </div>
12
+ ),
13
+ ],
14
+ } satisfies Meta;
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof meta>;
18
+
19
+ export const Default: Story = {
20
+ render: () => (
21
+ <ds-field className={styles.field}>
22
+ <label>Ledetekst</label>
23
+ <input className={styles.input} />
24
+ </ds-field>
25
+ ),
26
+ };
27
+
28
+ export const React: Story = {
29
+ render: () => (
30
+ <Field>
31
+ <Field.Label>Ledetekst</Field.Label>
32
+ <Input />
33
+ </Field>
34
+ ),
35
+ };
36
+
37
+ export const Types: Story = {
38
+ render: () => (
39
+ <>
40
+ <ds-field className={styles.field}>
41
+ <label>Text</label>
42
+ <input type="text" className={styles.input} />
43
+ </ds-field>
44
+
45
+ <ds-field className={styles.field}>
46
+ <label>Select</label>
47
+ <select className={styles.input}>
48
+ <option>Option 1</option>
49
+ <option>Option 2</option>
50
+ <option>Option 3</option>
51
+ <option>Option 4</option>
52
+ <option>Option 5</option>
53
+ </select>
54
+ </ds-field>
55
+
56
+ <ds-field className={styles.field}>
57
+ <label>Checkbox</label>
58
+ <input type="checkbox" className={styles.input} />
59
+ </ds-field>
60
+
61
+ <ds-field className={styles.field}>
62
+ <label>Radio 1</label>
63
+ <input
64
+ type="radio"
65
+ className={styles.input}
66
+ name="my-radio"
67
+ defaultChecked
68
+ />
69
+ </ds-field>
70
+
71
+ <ds-field className={styles.field}>
72
+ <label>Radio 2</label>
73
+ <input type="radio" className={styles.input} name="my-radio" />
74
+ </ds-field>
75
+
76
+ <ds-field className={styles.field}>
77
+ <label>Switch</label>
78
+ <input type="checkbox" role="switch" className={styles.input} />
79
+ </ds-field>
80
+
81
+ <ds-field className={styles.field}>
82
+ <label>Textarea</label>
83
+ <textarea className={styles.input} />
84
+ </ds-field>
85
+ </>
86
+ ),
87
+ };
88
+
89
+ export const Select: Story = {
90
+ parameters: {
91
+ showInOverview: true,
92
+ },
93
+ render: () => (
94
+ <ds-field className={styles.field}>
95
+ <label>Select</label>
96
+ <select className={styles.input}>
97
+ <option>Option 1</option>
98
+ <option>Option 2</option>
99
+ <option>Option 3</option>
100
+ <option>Option 4</option>
101
+ <option>Option 5</option>
102
+ </select>
103
+ </ds-field>
104
+ ),
105
+ };
106
+
107
+ export const Textarea: Story = {
108
+ parameters: {
109
+ showInOverview: true,
110
+ },
111
+ render: () => (
112
+ <ds-field className={styles.field}>
113
+ <label>Textarea</label>
114
+ <textarea className={styles.input}></textarea>
115
+ </ds-field>
116
+ ),
117
+ };
118
+
119
+ export const Checkbox: Story = {
120
+ render: () => (
121
+ <ds-field className={styles.field}>
122
+ <label>Checkbox</label>
123
+ <input type="checkbox" className={styles.input} />
124
+ </ds-field>
125
+ ),
126
+ };
127
+
128
+ export const Radio: Story = {
129
+ render: () => (
130
+ <ds-field className={styles.field}>
131
+ <label>Radio</label>
132
+ <input type="radio" className={styles.input} />
133
+ </ds-field>
134
+ ),
135
+ };
136
+
137
+ export const Switch: Story = {
138
+ parameters: {
139
+ showInOverview: true,
140
+ },
141
+ render: () => (
142
+ <ds-field className={styles.field}>
143
+ <label>Switch</label>
144
+ <input type="checkbox" role="switch" className={styles.input} />
145
+ </ds-field>
146
+ ),
147
+ };
148
+
149
+ export const Sizes: Story = {
150
+ render: () => (
151
+ <>
152
+ <input
153
+ aria-label="small"
154
+ className={styles.input}
155
+ data-size="sm"
156
+ defaultValue="Small"
157
+ />
158
+ <input
159
+ aria-label="medium"
160
+ className={styles.input}
161
+ data-size="md"
162
+ defaultValue="Medium"
163
+ />
164
+ <input
165
+ aria-label="large"
166
+ className={styles.input}
167
+ data-size="lg"
168
+ defaultValue="Large"
169
+ />
170
+ <input
171
+ aria-label="size=20"
172
+ className={styles.input}
173
+ size={20}
174
+ defaultValue="size=20"
175
+ />
176
+ </>
177
+ ),
178
+ };
179
+
180
+ export const ReadOnly: Story = {
181
+ render: () => (
182
+ <>
183
+ <ds-field className={styles.field}>
184
+ <label>Read only text</label>
185
+ <input className={styles.input} readOnly value="Value" />
186
+ </ds-field>
187
+ <ds-field className={styles.field}>
188
+ <label>Read only checkbox</label>
189
+ <input type="checkbox" className={styles.input} readOnly disabled />
190
+ </ds-field>
191
+ <ds-field className={styles.field}>
192
+ <label>Read only radio</label>
193
+ <input type="radio" className={styles.input} readOnly disabled />
194
+ </ds-field>
195
+ <ds-field className={styles.field}>
196
+ <label>Read only switch</label>
197
+ <input
198
+ type="checkbox"
199
+ role="switch"
200
+ className={styles.input}
201
+ readOnly
202
+ disabled
203
+ />
204
+ </ds-field>
205
+ </>
206
+ ),
207
+ };
208
+
209
+ export const Disabled: Story = {
210
+ render: () => (
211
+ <>
212
+ <ds-field className={styles.field}>
213
+ <label>Disabled text</label>
214
+ <input className={styles.input} disabled />
215
+ </ds-field>
216
+ <ds-field className={styles.field}>
217
+ <label>Disabled checkbox</label>
218
+ <input type="checkbox" className={styles.input} disabled />
219
+ </ds-field>
220
+ <ds-field className={styles.field}>
221
+ <label>Disabled radio</label>
222
+ <input type="radio" className={styles.input} disabled />
223
+ </ds-field>
224
+ <ds-field className={styles.field}>
225
+ <label>Disabled switch</label>
226
+ <input
227
+ type="checkbox"
228
+ role="switch"
229
+ className={styles.input}
230
+ disabled
231
+ />
232
+ </ds-field>
233
+ </>
234
+ ),
235
+ };
236
+
237
+ export const Indeterminate: Story = {
238
+ render: () => (
239
+ <>
240
+ <ds-field className={styles.field}>
241
+ <label>Disabled text</label>
242
+ <input className={styles.input} type="checkbox" data-indeterminate />
243
+ </ds-field>
244
+ </>
245
+ ),
246
+ };
247
+
248
+ export const TypeSearch: Story = {
249
+ parameters: {
250
+ showInOverview: true,
251
+ },
252
+ render: () => (
253
+ <>
254
+ <ds-field className={styles.field}>
255
+ <label>Søkefelt</label>
256
+ <input
257
+ className={styles.input}
258
+ type="search"
259
+ placeholder="Skriv for å søke"
260
+ />
261
+ </ds-field>
262
+ <ds-field className={styles.field}>
263
+ <label>Søkefelt data-icon="none"</label>
264
+ <input className={styles.input} type="search" data-icon="none" />
265
+ </ds-field>
266
+ </>
267
+ ),
268
+ };
269
+
270
+ export const TypeDate: Story = {
271
+ parameters: {
272
+ showInOverview: true,
273
+ },
274
+ render: () => (
275
+ <ds-field className={styles.field}>
276
+ <label>Datovelger</label>
277
+ <input className={styles.input} type="date" />
278
+ </ds-field>
279
+ ),
280
+ };
281
+
282
+ export const TypeNumber: Story = {
283
+ render: () => (
284
+ <div className={styles.grid} data-items="auto">
285
+ <ds-field className={styles.field}>
286
+ <label>Antall dyr</label>
287
+ <input className={styles.input} type="number" />
288
+ </ds-field>
289
+ <ds-field className={styles.field}>
290
+ <label>Referansenummer</label>
291
+ <input className={styles.input} type="text" inputMode="numeric" />
292
+ </ds-field>
293
+ </div>
294
+ ),
295
+ };
296
+
297
+ export const VariantInline: Story = {
298
+ name: "Variant Inline (Eksperimentell)",
299
+ render: () => (
300
+ <>
301
+ <ds-field className={styles.field}>
302
+ <label>Text</label>
303
+ <input
304
+ type="text"
305
+ defaultValue="Content"
306
+ className={styles.input}
307
+ data-variant="inline"
308
+ />
309
+ </ds-field>
310
+
311
+ <ds-field className={styles.field}>
312
+ <label>Select</label>
313
+ <select
314
+ className={styles.input}
315
+ data-variant="inline"
316
+ defaultValue="Option 1"
317
+ >
318
+ <option>Option 1</option>
319
+ <option>Option 2</option>
320
+ <option>Option 3</option>
321
+ <option>Option 4</option>
322
+ <option>Option 5</option>
323
+ </select>
324
+ </ds-field>
325
+
326
+ <ds-field className={styles.field}>
327
+ <label>Textarea</label>
328
+ <textarea
329
+ className={styles.input}
330
+ data-variant="inline"
331
+ defaultValue="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum euismod dui lacus, eget lacinia metus ullamcorper a. Nam id erat eu odio dignissim ornare ac eu erat. Maecenas bibendum cursus risus, sed tincidunt ipsum auctor id. Aliquam erat volutpat. Pellentesque mi sapien, ornare a iaculis ac, blandit in lectus. "
332
+ />
333
+ </ds-field>
334
+ </>
335
+ ),
336
+ };
337
+
338
+ // <Field
339
+ // as="input"
340
+ // label="Dato"
341
+ // onFocus={() =>
342
+ // document
343
+ // .querySelector<HTMLInputElement>('input[type="date"]')
344
+ // ?.showPicker()
345
+ // }
346
+ // />
347
+ // <Input
348
+ // type="date"
349
+ // aria-hidden="true"
350
+ // tabIndex={-1}
351
+ // style={{ marginTop: -60, opacity: 0, pointerEvents: "none" }}
352
+ // />
@@ -0,0 +1,115 @@
1
+ import { Meta, Canvas } from '@storybook/addon-docs/blocks';
2
+ import { HeartIcon } from '@phosphor-icons/react';
3
+ import * as stories from './law.stories';
4
+ import { Alert, Table, Prose, Popover } from '../react';
5
+
6
+
7
+ <Meta of={stories} />
8
+
9
+ # Law (Eksperimentell)
10
+ > Law gir visning og valg av lover og forskrifter fra Lovdata.
11
+
12
+ <Alert data-color="warning">
13
+ På grunn av pågådende kartlegging av bruk og behov, er Law foreløpig først og fremst et sett med hjelpefunksjoner og CSS.
14
+ Vi setter stor pris på [tilbakemeldinger](https://mattilsynet-hq.slack.com/archives/C03FAJ7N1EU) <HeartIcon style={{ verticalAlign: -3 }} />
15
+ </Alert>
16
+
17
+ ## Kode
18
+
19
+ - Legg klassen `law` på en `<div>` og fyll med HTML generert av `fixLawHtml()`
20
+ - Bruk `data-variant="view"` eller `data-variant="readonly"` dersom du ikke ønsker valg-knapper
21
+ - Du må selv hente [HTML via Lovdatas API](https://api.lovdata.no/), mens valg og parsing løses av hjelpefunksjonene `fixLawHtml`, `parseLawIds`, `setLawChecked`, `getLawChecked` og `toggleLawChecked` (støtter strukturer fra både Lovdatas betalte og gratis API). <button data-popover="inline" popoverTarget='pop-filenameHTML'>Vær obs på feil i feltet filenameHTML</button>
22
+ <Popover id='pop-filenameHTML' style={{ maxWidth: 700 }}><Prose>
23
+ Lovdatas felt `filenameHTML` slutter noen ganger på `.html`, og noen ganger ikke. Sørg for at kall til `https://api.lovdata.no/v1/structuredRules/get/` alltid slutter på `.html`. Eksempel:
24
+ ```js
25
+ const fix = `${filenameHTML.replace('.html', '')}.html`;
26
+ const url = `https://api.lovdata.no/v1/structuredRules/get/${fix}`;
27
+ ```
28
+ <style>{`[popover] .docblock-source { margin: 0 }`}</style>
29
+ </Prose></Popover>
30
+
31
+
32
+ <Table data-fixed>
33
+ <thead>
34
+ <tr>
35
+ <th style={{ width: 450 }}>Funksjon</th>
36
+ <th>Beskrivelse</th>
37
+ </tr>
38
+ </thead>
39
+ <tbody>
40
+ <tr>
41
+ <td>
42
+ ```ts
43
+ fixLawHtml(html: string)
44
+ // Returns:
45
+ string
46
+ ```
47
+ </td>
48
+ <td>
49
+ - Parser, renser og legger på valg-knapper i HTML fra Lovdata
50
+ - **Kan kjøre på:** Server og nettleser
51
+ - **React?** Bruk `useMemo`
52
+ </td>
53
+ </tr>
54
+ <tr>
55
+ <td>
56
+ ```ts
57
+ parseLawIds(ids: string[], html: string)
58
+ // Returns:
59
+ {
60
+ id: string; // Element ID
61
+ className: string; // From Lovdata
62
+ html: string; // Outer HTML
63
+ label: string; // Juridisk henvisning
64
+ path: []; // Parent elements
65
+ url: string; // Closest lovdata url
66
+ guideUrl: string; // URL for mattilsynet.no-veiledning
67
+ }
68
+ ```
69
+ </td>
70
+ <td>
71
+ - Parser en liste med IDer til et strukturert objekt, som blant annet inneholder juridisk henvisningstekst til bruk i vedtaksbrev osv.
72
+ - **Kan kjøre på:** Server og nettleser
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td>
77
+ ```ts
78
+ setLawChecked(ids: string[], element: HTMLElement)
79
+ // Returns:
80
+ void
81
+ ```
82
+ </td>
83
+ <td>
84
+ - Markerer valgte deler av regelverk i et `Law` element.
85
+ - **Kan kjøre på:** Kun nettleser
86
+ </td>
87
+ </tr>
88
+ <tr>
89
+ <td>
90
+ ```ts
91
+ getLawChecked(element: HTMLElement)
92
+ // Returns:
93
+ string[]
94
+ ```
95
+ </td>
96
+ <td>
97
+ - Hente valgte IDer.
98
+ - **Kan kjøre på:** Kun nettleser
99
+ </td>
100
+ </tr>
101
+ <tr>
102
+ <td>
103
+ ```ts
104
+ toggleLawChecked(ids: string[], element: HTMLElement)
105
+ // Returns:
106
+ string[]
107
+ ```
108
+ </td>
109
+ <td>
110
+ - Hente valgte IDer.
111
+ - **Kan kjøre på:** Kun nettleser
112
+ </td>
113
+ </tr>
114
+ </tbody>
115
+ </Table>