@navikt/ds-react 0.16.16 → 0.16.19

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 (38) hide show
  1. package/cjs/button/Button.js +3 -3
  2. package/cjs/table/ColumnHeader.js +58 -0
  3. package/cjs/table/DataCell.js +4 -2
  4. package/cjs/table/HeaderCell.js +4 -2
  5. package/cjs/table/Table.js +4 -2
  6. package/cjs/toggle-group/ToggleGroup.js +1 -1
  7. package/esm/button/Button.d.ts +1 -1
  8. package/esm/button/Button.js +3 -3
  9. package/esm/button/Button.js.map +1 -1
  10. package/esm/menu/Menu.js.map +1 -1
  11. package/esm/table/ColumnHeader.d.ts +17 -0
  12. package/esm/table/ColumnHeader.js +35 -0
  13. package/esm/table/ColumnHeader.js.map +1 -0
  14. package/esm/table/DataCell.d.ts +5 -0
  15. package/esm/table/DataCell.js +4 -2
  16. package/esm/table/DataCell.js.map +1 -1
  17. package/esm/table/HeaderCell.d.ts +6 -1
  18. package/esm/table/HeaderCell.js +4 -2
  19. package/esm/table/HeaderCell.js.map +1 -1
  20. package/esm/table/Table.d.ts +16 -0
  21. package/esm/table/Table.js +4 -2
  22. package/esm/table/Table.js.map +1 -1
  23. package/esm/toggle-group/ToggleGroup.js +1 -1
  24. package/esm/toggle-group/ToggleGroup.js.map +1 -1
  25. package/package.json +4 -3
  26. package/src/button/Button.tsx +7 -3
  27. package/src/button/button.stories.tsx +8 -0
  28. package/src/menu/Menu.tsx +9 -9
  29. package/src/table/ColumnHeader.tsx +70 -0
  30. package/src/table/DataCell.tsx +11 -3
  31. package/src/table/HeaderCell.tsx +11 -3
  32. package/src/table/Table.tsx +30 -2
  33. package/src/table/stories/people.json +822 -0
  34. package/src/table/stories/table-async.stories.tsx +169 -0
  35. package/src/table/stories/table-hot.stories.tsx +376 -0
  36. package/src/table/stories/table.stories.tsx +35 -2
  37. package/src/toggle-group/ToggleGroup.stories.tsx +11 -0
  38. package/src/toggle-group/ToggleGroup.tsx +1 -1
@@ -0,0 +1,169 @@
1
+ import React, { useState } from "react";
2
+ import { rest } from "msw";
3
+ import useSWR from "swr";
4
+ import people from "./people.json";
5
+ import { Table } from "../index";
6
+ import { Loader, Pagination, SortState } from "../..";
7
+
8
+ export default {
9
+ title: "ds-react/table",
10
+ component: Table,
11
+ parameters: {
12
+ chromatic: { delay: 500 },
13
+ },
14
+ };
15
+
16
+ const rowsPerPage = 10;
17
+
18
+ const queryString = (obj) =>
19
+ Object.keys(obj)
20
+ .filter((key) => obj[key] !== undefined)
21
+ .map((key) => key + "=" + obj[key])
22
+ .join("&");
23
+
24
+ export const Async = () => {
25
+ const [page, setPage] = useState(1);
26
+ const [sort, setSort] = useState<SortState>();
27
+
28
+ const { data } = useSWR(
29
+ `/people?${queryString({
30
+ page,
31
+ sort: sort ? `${sort.orderBy}:${sort.direction}` : undefined,
32
+ })}`,
33
+ (url) => fetch(url).then((res) => res.json())
34
+ );
35
+
36
+ if (!data) {
37
+ return <Loader size="2xlarge" />;
38
+ }
39
+
40
+ const { results: people, count } = data;
41
+
42
+ const columns = [
43
+ { key: "name", name: "Name", width: 154 },
44
+ { key: "height", name: "Height", width: 108 },
45
+ { key: "mass", name: "Mass", width: 95 },
46
+ {
47
+ key: "birth_year",
48
+ name: "Birth year",
49
+ value: (person) =>
50
+ person.birth_year !== null ? `${person.birth_year}BBY` : undefined,
51
+ width: 133,
52
+ },
53
+ { key: "eye_color", name: "Eye color", width: 127 },
54
+ { key: "gender", name: "Gender", width: 113, sortable: false },
55
+ { key: "hair_color", name: "Hair color", width: 132 },
56
+ { key: "skin_color", name: "Skin color", width: 133 },
57
+ ];
58
+
59
+ return (
60
+ <div
61
+ style={{
62
+ display: "flex",
63
+ flexDirection: "column",
64
+ gap: 16,
65
+ }}
66
+ >
67
+ <div style={{ overflow: "auto" }}>
68
+ <Table
69
+ style={{ width: "initial" }}
70
+ sort={sort}
71
+ onSortChange={(sortKey) =>
72
+ setSort(
73
+ sort?.orderBy === sortKey && sort.direction === "descending"
74
+ ? undefined
75
+ : {
76
+ orderBy: sortKey,
77
+ direction:
78
+ sort?.direction === "ascending"
79
+ ? "descending"
80
+ : "ascending",
81
+ }
82
+ )
83
+ }
84
+ >
85
+ <Table.Header>
86
+ <Table.Row>
87
+ {columns.map(({ key, name, width, sortable = true }) => (
88
+ <Table.ColumnHeader
89
+ style={{ width, minWidth: width, maxWidth: width }}
90
+ key={key}
91
+ sortable={sortable}
92
+ sortKey={key}
93
+ >
94
+ {name}
95
+ </Table.ColumnHeader>
96
+ ))}
97
+ </Table.Row>
98
+ </Table.Header>
99
+ <Table.Body>
100
+ {people.map((person) => (
101
+ <Table.Row key={person.name}>
102
+ {columns.map(({ key, width, value }) => (
103
+ <Table.DataCell
104
+ style={{
105
+ width,
106
+ minWidth: width,
107
+ maxWidth: width,
108
+ overflow: "hidden",
109
+ whiteSpace: "nowrap",
110
+ textOverflow: "ellipsis",
111
+ }}
112
+ title={person[key]}
113
+ key={key}
114
+ >
115
+ {value ? value(person) : person[key]}
116
+ </Table.DataCell>
117
+ ))}
118
+ </Table.Row>
119
+ ))}
120
+ </Table.Body>
121
+ </Table>
122
+ </div>
123
+ <Pagination
124
+ page={page}
125
+ onPageChange={setPage}
126
+ count={Math.ceil(count / rowsPerPage)}
127
+ />
128
+ </div>
129
+ );
130
+ };
131
+
132
+ Async.parameters = {
133
+ msw: {
134
+ handlers: [
135
+ rest.get("/people", (req, res, ctx) => {
136
+ const comparator = (a, b, orderBy) => {
137
+ if (b[orderBy] < a[orderBy]) {
138
+ return -1;
139
+ }
140
+ if (b[orderBy] > a[orderBy]) {
141
+ return 1;
142
+ }
143
+ return 0;
144
+ };
145
+
146
+ const page = Number(req.url.searchParams.get("page"));
147
+ const sort = req.url.searchParams.get("sort");
148
+ return res(
149
+ //ctx.delay(),
150
+ ctx.json({
151
+ count: people.length,
152
+ results: people
153
+ .slice()
154
+ .sort((a, b) => {
155
+ if (sort) {
156
+ const [orderBy, direction] = sort.split(":");
157
+ return direction === "ascending"
158
+ ? comparator(b, a, orderBy)
159
+ : comparator(a, b, orderBy);
160
+ }
161
+ return 1;
162
+ })
163
+ .slice((page - 1) * rowsPerPage, page * rowsPerPage),
164
+ })
165
+ );
166
+ }),
167
+ ],
168
+ },
169
+ };
@@ -0,0 +1,376 @@
1
+ import React, { useState } from "react";
2
+ import { capitalize } from "@material-ui/core";
3
+ import { Table } from "../";
4
+ import { Button } from "../..";
5
+ import { SortState } from "../..";
6
+
7
+ export default {
8
+ title: "ds-react/table",
9
+ component: Table,
10
+ };
11
+
12
+ interface Column {
13
+ key: string;
14
+ name?: string;
15
+ sortable?: boolean;
16
+ render?: (value: any) => React.ReactElement<any, any> | null;
17
+ value?: (oppgave: any) => any;
18
+ width?: number;
19
+ align?: "left" | "center" | "right";
20
+ }
21
+
22
+ export const Hot = () => {
23
+ const [sort, setSort] = useState<SortState>();
24
+
25
+ const columns: Column[] = [
26
+ {
27
+ key: "eier",
28
+ name: "Eier",
29
+ render: (value) =>
30
+ value ?? (
31
+ <Button
32
+ size="xsmall"
33
+ style={{ marginTop: -2, marginBottom: -2, marginLeft: -6 }}
34
+ variant="tertiary"
35
+ >
36
+ Start saken
37
+ </Button>
38
+ ),
39
+ value: (oppgave) => oppgave.saksbehandler?.navn,
40
+ width: 152,
41
+ },
42
+ {
43
+ key: "status",
44
+ name: "Status",
45
+ value: (oppgave) =>
46
+ ({
47
+ ALLE: "Alle",
48
+ VEDTAK_FATTET: "Innvilget",
49
+ AVVENTER_SAKSBEHANDLER: "Mottatt",
50
+ SENDT_GOSYS: "Sendt GOSYS",
51
+ TILDELT_SAKSBEHANDLER: "Under behandling",
52
+ }[oppgave.status]),
53
+ width: 154,
54
+ },
55
+ {
56
+ key: "område",
57
+ name: "Område",
58
+ value: (oppgave) =>
59
+ capitalize(oppgave.personinformasjon.funksjonsnedsettelse[0]),
60
+ width: 152,
61
+ },
62
+ {
63
+ key: "søknadOm",
64
+ name: "Søknad om",
65
+ width: 192,
66
+ },
67
+ {
68
+ key: "hjelpemiddelbruker",
69
+ name: "Hjelpemiddelbruker",
70
+ value: (oppgave) =>
71
+ `${oppgave.personinformasjon.etternavn}, ${oppgave.personinformasjon.fornavn}`,
72
+ width: 188,
73
+ },
74
+ {
75
+ key: "fødselsnr",
76
+ name: "Fødselsnr.",
77
+ value: (oppgave) =>
78
+ `${oppgave.personinformasjon.fnr.slice(
79
+ 0,
80
+ 6
81
+ )} ${oppgave.personinformasjon.fnr.slice(6)}`,
82
+ width: 124,
83
+ align: "right",
84
+ },
85
+ {
86
+ key: "bosted",
87
+ name: "Bosted",
88
+ value: (oppgave) => oppgave.personinformasjon.bosted,
89
+ width: 144,
90
+ },
91
+ {
92
+ key: "formidlerNavn",
93
+ name: "Formidler",
94
+ width: 164,
95
+ },
96
+ {
97
+ key: "mottattDato",
98
+ name: "Mottatt dato",
99
+ width: 124,
100
+ },
101
+ {
102
+ key: "menu",
103
+ sortable: false,
104
+ render: (value) => (
105
+ <span style={{ display: "flex", marginBlock: -2 }}></span>
106
+ ),
107
+ value: (oppgave) => oppgave.saksbehandler,
108
+ },
109
+ ];
110
+
111
+ return (
112
+ <div
113
+ style={{
114
+ display: "flex",
115
+ flexDirection: "column",
116
+ gap: 16,
117
+ }}
118
+ >
119
+ <div style={{ overflow: "auto" }}>
120
+ <Table
121
+ size="small"
122
+ style={{ width: "initial" }}
123
+ sort={sort}
124
+ onSortChange={(sortKey) =>
125
+ setSort({
126
+ orderBy: sortKey,
127
+ direction:
128
+ sort?.direction === "ascending" ? "descending" : "ascending",
129
+ })
130
+ }
131
+ >
132
+ <Table.Header>
133
+ <Table.Row>
134
+ {columns.map(({ key, name, width, sortable = true, align }) => (
135
+ <Table.ColumnHeader
136
+ style={{
137
+ width,
138
+ minWidth: width,
139
+ maxWidth: width,
140
+ }}
141
+ key={key}
142
+ sortable={sortable}
143
+ sortKey={key}
144
+ align={align}
145
+ >
146
+ <div
147
+ style={{
148
+ overflow: "hidden",
149
+ whiteSpace: "nowrap",
150
+ textOverflow: "ellipsis",
151
+ }}
152
+ >
153
+ {name}
154
+ </div>
155
+ </Table.ColumnHeader>
156
+ ))}
157
+ </Table.Row>
158
+ </Table.Header>
159
+ <Table.Body>
160
+ {data
161
+ .slice()
162
+ .sort((a, b) => {
163
+ if (sort) {
164
+ const comparator = (a, b, orderBy) => {
165
+ const lookup = (oppgave) => {
166
+ const column = columns.find(({ key }) => key === orderBy);
167
+
168
+ return column.value
169
+ ? column.value(oppgave)
170
+ : oppgave[orderBy];
171
+ };
172
+
173
+ if (lookup(b) < lookup(a) || lookup(b) === undefined) {
174
+ return -1;
175
+ }
176
+ if (lookup(b) > lookup(a)) {
177
+ return 1;
178
+ }
179
+ return 0;
180
+ };
181
+
182
+ return sort.direction === "ascending"
183
+ ? comparator(b, a, sort.orderBy)
184
+ : comparator(a, b, sort.orderBy);
185
+ }
186
+ return 1;
187
+ })
188
+ .map((oppgave) => (
189
+ <Table.Row key={oppgave.saksid}>
190
+ {columns.map(
191
+ ({
192
+ key,
193
+ value,
194
+ width,
195
+ render = (value) => value,
196
+ align,
197
+ }) => (
198
+ <Table.DataCell
199
+ style={{
200
+ width,
201
+ minWidth: width,
202
+ maxWidth: width,
203
+ overflow: "hidden",
204
+ whiteSpace: "nowrap",
205
+ textOverflow: "ellipsis",
206
+ }}
207
+ title={oppgave[key]}
208
+ key={key}
209
+ align={align}
210
+ >
211
+ {render(value ? value(oppgave) : oppgave[key])}
212
+ </Table.DataCell>
213
+ )
214
+ )}
215
+ </Table.Row>
216
+ ))}
217
+ </Table.Body>
218
+ </Table>
219
+ </div>
220
+ </div>
221
+ );
222
+ };
223
+
224
+ const data = [
225
+ {
226
+ saksid: "111111",
227
+ søknadOm:
228
+ "Søknad om: Toalettforhøyer; kalender-/minnesystem; støttehåndtak; tidsur; komfyr-/elvakt",
229
+ mottattDato: "2021-09-19T13:55:45",
230
+ formidlerNavn: "Kari Johansen",
231
+ personinformasjon: {
232
+ fnr: "19044238651",
233
+ funksjonsnedsettelse: ["bevegelse"],
234
+ fornavn: "Petter Andreas",
235
+ etternavn: "Hansen",
236
+ poststed: "Trondheim",
237
+ bosted: "TRONDHEIM",
238
+ },
239
+ saksbehandler: null,
240
+ status: "AVVENTER_SAKSBEHANDLER",
241
+ enhet: [
242
+ {
243
+ enhetsnummer: "6969",
244
+ enhetsnavn: "Enhetsnavn",
245
+ },
246
+ ],
247
+ },
248
+ {
249
+ saksid: "222222",
250
+ søknadOm: "Hjelpemidler",
251
+ mottattDato: "2021-09-24T13:55:45",
252
+ formidlerNavn: "Kari Johansen",
253
+ personinformasjon: {
254
+ fnr: "13044238651",
255
+ funksjonsnedsettelse: ["bevegelse"],
256
+ fornavn: "Mia Cathrine",
257
+ etternavn: "Svendsen",
258
+ poststed: "Trondheim",
259
+ bosted: "TRONDHEIM",
260
+ },
261
+ saksbehandler: null,
262
+ status: "AVVENTER_SAKSBEHANDLER",
263
+ enhet: [
264
+ {
265
+ enhetsnummer: "6969",
266
+ enhetsnavn: "Enhetsnavn",
267
+ },
268
+ ],
269
+ },
270
+
271
+ {
272
+ saksid: "5878444",
273
+ søknadOm: "Hjelpemidler",
274
+ mottattDato: "2021-09-20T13:55:45",
275
+ formidlerNavn: "Kari Johansen",
276
+ personinformasjon: {
277
+ fnr: "130441386551",
278
+ funksjonsnedsettelse: ["bevegelse"],
279
+ fornavn: "Per Bjørkli",
280
+ etternavn: "Hansen",
281
+ poststed: "Trondheim",
282
+ bosted: "TRONDHEIM",
283
+ },
284
+ saksbehandler: {
285
+ epost: "a.b@nav.no",
286
+ objectId: "23ea7485-1324-4b25-a763-6969",
287
+ navn: "Geir Markusen",
288
+ },
289
+ status: "SENDT_GOSYS",
290
+ enhet: [
291
+ {
292
+ enhetsnummer: "6969",
293
+ enhetsnavn: "Enhetsnavn",
294
+ },
295
+ ],
296
+ },
297
+
298
+ {
299
+ saksid: "1234567",
300
+ søknadOm: "Hjelpemidler",
301
+ mottattDato: "2021-06-25T13:55:45",
302
+ formidlerNavn: "Kari Johansen",
303
+ personinformasjon: {
304
+ fnr: "06115559891",
305
+ funksjonsnedsettelse: ["kognisjon"],
306
+ fornavn: "Iver",
307
+ etternavn: "Slettan",
308
+ poststed: "Lade",
309
+ bosted: "TRONDHEIM",
310
+ },
311
+ saksbehandler: {
312
+ epost: "a.b@nav.no",
313
+ objectId: "23ea7485-1324-4b25-a763-assdfdfa",
314
+ navn: "Silje Saksbehandler",
315
+ },
316
+ status: "TILDELT_SAKSBEHANDLER",
317
+ enhet: [
318
+ {
319
+ enhetsnummer: "6969",
320
+ enhetsnavn: "Enhetsnavn",
321
+ },
322
+ ],
323
+ },
324
+ {
325
+ saksid: "999999",
326
+ søknadOm: "Hjelpemidler",
327
+ mottattDato: "2021-06-25T16:55:45",
328
+ formidlerNavn: "Kari Johansen",
329
+ personinformasjon: {
330
+ fnr: "16120101181",
331
+ funksjonsnedsettelse: ["bevegelse"],
332
+ fornavn: "Sondre",
333
+ etternavn: "Hansen",
334
+ poststed: "Lade",
335
+ bosted: "TRONDHEIM",
336
+ },
337
+ saksbehandler: {
338
+ epost: "a.b@nav.no",
339
+ objectId: "23ea7485-1324-4b25-a763-6969",
340
+ navn: "Geir Markusen",
341
+ },
342
+ status: "TILDELT_SAKSBEHANDLER",
343
+ enhet: [
344
+ {
345
+ enhetsnummer: "6969",
346
+ enhetsnavn: "Enhetsnavn",
347
+ },
348
+ ],
349
+ },
350
+ {
351
+ saksid: "888888",
352
+ søknadOm: "Hjelpemidler",
353
+ mottattDato: "2021-09-19T13:55:45",
354
+ formidlerNavn: "Kari Johansen",
355
+ personinformasjon: {
356
+ fnr: "19044238651",
357
+ funksjonsnedsettelse: ["bevegelse"],
358
+ fornavn: "Geir",
359
+ etternavn: "Dalby",
360
+ poststed: "Trondheim",
361
+ bosted: "TRONDHEIM",
362
+ },
363
+ saksbehandler: {
364
+ epost: "a.b@nav.no",
365
+ objectId: "23ea7485-1324-4b25-a763-assdfdfa",
366
+ navn: "Silje Saksbehandler",
367
+ },
368
+ status: "VEDTAK_FATTET",
369
+ enhet: [
370
+ {
371
+ enhetsnummer: "6969",
372
+ enhetsnavn: "Enhetsnavn",
373
+ },
374
+ ],
375
+ },
376
+ ];
@@ -1,6 +1,6 @@
1
1
  import React, { useState } from "react";
2
- import { Table } from "../index";
3
- import { Alert, Checkbox, Link } from "@navikt/ds-react";
2
+ import { Table } from "../";
3
+ import { Alert, Button, Checkbox, Link } from "../..";
4
4
 
5
5
  export default {
6
6
  title: "ds-react/table",
@@ -12,6 +12,7 @@ export const All = () => {
12
12
  <Table {...props}>
13
13
  <Table.Header>
14
14
  <Table.Row>
15
+ {props.button && <Table.HeaderCell>Action</Table.HeaderCell>}
15
16
  <Table.HeaderCell>ID</Table.HeaderCell>
16
17
  <Table.HeaderCell>Fornavn</Table.HeaderCell>
17
18
  <Table.HeaderCell>Etternavn</Table.HeaderCell>
@@ -20,18 +21,48 @@ export const All = () => {
20
21
  </Table.Header>
21
22
  <Table.Body>
22
23
  <Table.Row>
24
+ {props.button && (
25
+ <Table.DataCell
26
+ style={{
27
+ paddingTop: 6,
28
+ paddingBottom: 6,
29
+ }}
30
+ >
31
+ <Button size="xsmall">Click me!</Button>
32
+ </Table.DataCell>
33
+ )}
23
34
  <Table.HeaderCell>1</Table.HeaderCell>
24
35
  <Table.DataCell>Jean-Luc</Table.DataCell>
25
36
  <Table.DataCell>Picard</Table.DataCell>
26
37
  <Table.DataCell>Kaptein</Table.DataCell>
27
38
  </Table.Row>
28
39
  <Table.Row>
40
+ {props.button && (
41
+ <Table.DataCell
42
+ style={{
43
+ paddingTop: 6,
44
+ paddingBottom: 6,
45
+ }}
46
+ >
47
+ <Button size="xsmall">Click me!</Button>
48
+ </Table.DataCell>
49
+ )}
29
50
  <Table.HeaderCell>2</Table.HeaderCell>
30
51
  <Table.DataCell>William</Table.DataCell>
31
52
  <Table.DataCell>Riker</Table.DataCell>
32
53
  <Table.DataCell>Kommandør</Table.DataCell>
33
54
  </Table.Row>
34
55
  <Table.Row>
56
+ {props.button && (
57
+ <Table.DataCell
58
+ style={{
59
+ paddingTop: 6,
60
+ paddingBottom: 6,
61
+ }}
62
+ >
63
+ <Button size="xsmall">Click me!</Button>
64
+ </Table.DataCell>
65
+ )}
35
66
  <Table.HeaderCell>3</Table.HeaderCell>
36
67
  <Table.DataCell>Geordi</Table.DataCell>
37
68
  <Table.DataCell>La Forge</Table.DataCell>
@@ -48,6 +79,8 @@ export const All = () => {
48
79
  <TableComponent zebraStripes />
49
80
  <h2>Small Table</h2>
50
81
  <TableComponent size="small" />
82
+ <h2>Small Table with buttons</h2>
83
+ <TableComponent size="small" button />
51
84
  <h2>Table with divs</h2>
52
85
  <Alert variant="warning">
53
86
  Obs! Hvis man skal bygge tabeller uten å bruke vanlig {"<tabell> "}
@@ -51,6 +51,17 @@ const Items = (icon?: boolean, both?: boolean) => (
51
51
  </>
52
52
  );
53
53
 
54
+ export const UUDemo = () => {
55
+ const [activeValue, setActiveValue] = useState("ulest");
56
+ return (
57
+ <ToggleGroup value={activeValue} onChange={setActiveValue}>
58
+ <ToggleGroup.Item value="ulest">Ulest</ToggleGroup.Item>
59
+ <ToggleGroup.Item value="lest">Leste</ToggleGroup.Item>
60
+ <ToggleGroup.Item value="sendt">Sendte</ToggleGroup.Item>
61
+ </ToggleGroup>
62
+ );
63
+ };
64
+
54
65
  export const All = () => {
55
66
  const [activeValue, setActiveValue] = useState("first");
56
67
 
@@ -120,7 +120,7 @@ const ToggleGroup = forwardRef<HTMLDivElement, ToggleGroupProps>(
120
120
  `navds-toggle-group--${size}`
121
121
  )}
122
122
  {...(describeBy && { "aria-describedby": describeBy })}
123
- role="toolbar"
123
+ role="radiogroup"
124
124
  type="single"
125
125
  >
126
126
  {children}