@navikt/ds-react 0.16.17 → 0.16.20

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 (45) hide show
  1. package/cjs/button/Button.js +3 -3
  2. package/cjs/modal/Modal.js +2 -2
  3. package/cjs/table/ColumnHeader.js +58 -0
  4. package/cjs/table/DataCell.js +4 -2
  5. package/cjs/table/HeaderCell.js +4 -2
  6. package/cjs/table/Table.js +4 -2
  7. package/cjs/toggle-group/ToggleGroup.js +1 -1
  8. package/esm/button/Button.d.ts +1 -1
  9. package/esm/button/Button.js +3 -3
  10. package/esm/button/Button.js.map +1 -1
  11. package/esm/menu/Menu.js.map +1 -1
  12. package/esm/modal/Modal.d.ts +5 -0
  13. package/esm/modal/Modal.js +2 -2
  14. package/esm/modal/Modal.js.map +1 -1
  15. package/esm/table/ColumnHeader.d.ts +17 -0
  16. package/esm/table/ColumnHeader.js +35 -0
  17. package/esm/table/ColumnHeader.js.map +1 -0
  18. package/esm/table/DataCell.d.ts +5 -0
  19. package/esm/table/DataCell.js +4 -2
  20. package/esm/table/DataCell.js.map +1 -1
  21. package/esm/table/HeaderCell.d.ts +6 -1
  22. package/esm/table/HeaderCell.js +4 -2
  23. package/esm/table/HeaderCell.js.map +1 -1
  24. package/esm/table/Table.d.ts +16 -0
  25. package/esm/table/Table.js +4 -2
  26. package/esm/table/Table.js.map +1 -1
  27. package/esm/toggle-group/ToggleGroup.js +1 -1
  28. package/esm/toggle-group/ToggleGroup.js.map +1 -1
  29. package/package.json +4 -3
  30. package/src/button/Button.tsx +7 -3
  31. package/src/button/button.stories.tsx +8 -0
  32. package/src/menu/Menu.tsx +9 -9
  33. package/src/modal/Modal.tsx +7 -0
  34. package/src/modal/{stories/modal.stories.tsx → modal.stories.tsx} +9 -5
  35. package/src/table/ColumnHeader.tsx +70 -0
  36. package/src/table/DataCell.tsx +11 -3
  37. package/src/table/HeaderCell.tsx +11 -3
  38. package/src/table/Table.tsx +30 -2
  39. package/src/table/stories/people.json +822 -0
  40. package/src/table/stories/table-async.stories.tsx +169 -0
  41. package/src/table/stories/table-hot.stories.tsx +376 -0
  42. package/src/table/stories/table.stories.tsx +35 -2
  43. package/src/toggle-group/ToggleGroup.stories.tsx +11 -0
  44. package/src/toggle-group/ToggleGroup.tsx +1 -1
  45. package/src/modal/stories/modal.stories.mdx +0 -32
@@ -36,6 +36,11 @@ export interface ModalProps {
36
36
  "aria-labelledby"?: string;
37
37
  "aria-describedby"?: string;
38
38
  "aria-modal"?: boolean;
39
+ /**
40
+ * Sets aria-label on modal
41
+ * @warning This should be set if not using 'aria-labelledby' or 'aria-describedby'
42
+ */
43
+ "aria-label"?: string;
39
44
  }
40
45
 
41
46
  interface ModalComponent
@@ -62,6 +67,7 @@ const Modal = forwardRef<ReactModal, ModalProps>(
62
67
  "aria-describedby": ariaDescribedBy,
63
68
  "aria-labelledby": ariaLabelledBy,
64
69
  "aria-modal": ariaModal,
70
+ "aria-label": contentLabel,
65
71
  ...rest
66
72
  },
67
73
  ref
@@ -92,6 +98,7 @@ const Modal = forwardRef<ReactModal, ModalProps>(
92
98
  labelledby: ariaLabelledBy,
93
99
  modal: ariaModal,
94
100
  }}
101
+ contentLabel={contentLabel}
95
102
  >
96
103
  {children}
97
104
  {closeButton && (
@@ -16,9 +16,13 @@ export const All = () => {
16
16
  return (
17
17
  <>
18
18
  <button onClick={() => setOpen(true)}>Open modal</button>
19
- <Modal open={open} onClose={() => setOpen(false)}>
19
+ <Modal
20
+ open={open}
21
+ onClose={() => setOpen(false)}
22
+ aria-labelledby="header123"
23
+ >
20
24
  <Modal.Content>
21
- <h1>Header</h1>
25
+ <h1 id="header123">Header</h1>
22
26
  <h2>subheader</h2>
23
27
  <p>Cupidatat irure ipsum veniam ad in esse.</p>
24
28
  <p>Cillum tempor pariatur amet ut laborum Lorem enim enim.</p>
@@ -32,9 +36,10 @@ export const All = () => {
32
36
  shouldCloseOnOverlayClick={false}
33
37
  open={openTwo}
34
38
  onClose={() => setOpenTwo(false)}
39
+ aria-labelledby="header123"
35
40
  >
36
41
  <Modal.Content>
37
- <h1>Header</h1>
42
+ <h1 id="header123">Header</h1>
38
43
  <h2>subheader</h2>
39
44
  <p>
40
45
  Cupidatat irure ipsum veniam ad in esse. Voluptate do nulla amet
@@ -54,10 +59,9 @@ export const All = () => {
54
59
  open={openThree}
55
60
  closeButton={false}
56
61
  onClose={() => setOpenThree(false)}
62
+ aria-label="Min modal"
57
63
  >
58
64
  <Modal.Content>
59
- <h1>Header</h1>
60
- <h2>subheader</h2>
61
65
  <p>Cupidatat irure ipsum veniam ad in esse.</p>
62
66
  <p>Cillum tempor pariatur amet ut laborum Lorem enim enim.</p>
63
67
  </Modal.Content>
@@ -0,0 +1,70 @@
1
+ import React, { forwardRef, useContext } from "react";
2
+ import { Down, Up } from "@navikt/ds-icons";
3
+ import { TableContext } from "..";
4
+ import HeaderCell, { HeaderCellProps } from "./HeaderCell";
5
+
6
+ interface ColumnHeaderProps extends HeaderCellProps {
7
+ /**
8
+ * Key to sort by
9
+ */
10
+ sortKey?: string;
11
+ /**
12
+ * Column is sortable
13
+ * @default false
14
+ */
15
+ sortable?: boolean;
16
+ }
17
+
18
+ export interface ColumnHeaderType
19
+ extends React.ForwardRefExoticComponent<
20
+ ColumnHeaderProps & React.RefAttributes<HTMLTableCellElement>
21
+ > {}
22
+
23
+ const ColumnHeader: ColumnHeaderType = forwardRef(
24
+ ({ className, children, sortable = false, sortKey, ...rest }, ref) => {
25
+ const context = useContext(TableContext);
26
+
27
+ if (sortable && !sortKey) {
28
+ console.warn("ColumnHeader with `sortable=true` must have a sortKey.");
29
+ }
30
+
31
+ return (
32
+ <HeaderCell
33
+ scope="col"
34
+ ref={ref}
35
+ className={className}
36
+ aria-sort={
37
+ sortable
38
+ ? context?.sort?.orderBy === sortKey
39
+ ? context?.sort?.direction
40
+ : "none"
41
+ : undefined
42
+ }
43
+ {...rest}
44
+ >
45
+ {sortable ? (
46
+ <button
47
+ className="navds-table__sort-button"
48
+ onClick={
49
+ sortable && sortKey
50
+ ? () => context?.onSortChange?.(sortKey)
51
+ : undefined
52
+ }
53
+ >
54
+ {children}
55
+ {context?.sort?.orderBy === sortKey &&
56
+ context?.sort?.direction === "descending" ? (
57
+ <Down aria-label="sorter synkende" />
58
+ ) : (
59
+ <Up aria-label="sorter stigende" />
60
+ )}
61
+ </button>
62
+ ) : (
63
+ children
64
+ )}
65
+ </HeaderCell>
66
+ );
67
+ }
68
+ );
69
+
70
+ export default ColumnHeader;
@@ -3,7 +3,13 @@ import cl from "classnames";
3
3
  import { BodyShort } from "..";
4
4
  import { TableContext } from ".";
5
5
 
6
- interface DataCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {}
6
+ interface DataCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {
7
+ /**
8
+ * Content alignment
9
+ * @default "left"
10
+ */
11
+ align?: "left" | "center" | "right";
12
+ }
7
13
 
8
14
  export interface DataCellType
9
15
  extends React.ForwardRefExoticComponent<
@@ -11,14 +17,16 @@ export interface DataCellType
11
17
  > {}
12
18
 
13
19
  const DataCell: DataCellType = forwardRef(
14
- ({ className, children = "", ...rest }, ref) => {
20
+ ({ className, children = "", align, ...rest }, ref) => {
15
21
  const context = useContext(TableContext);
16
22
 
17
23
  return (
18
24
  <BodyShort
19
25
  as="td"
20
26
  ref={ref}
21
- className={cl("navds-table__data-cell", className)}
27
+ className={cl("navds-table__data-cell", className, {
28
+ [`navds-table__data-cell--align-${align}`]: align,
29
+ })}
22
30
  size={context?.size}
23
31
  {...rest}
24
32
  >
@@ -2,8 +2,14 @@ import React, { forwardRef, useContext } from "react";
2
2
  import cl from "classnames";
3
3
  import { Label, TableContext } from "..";
4
4
 
5
- interface HeaderCellProps extends React.ThHTMLAttributes<HTMLTableCellElement> {
5
+ export interface HeaderCellProps
6
+ extends React.ThHTMLAttributes<HTMLTableCellElement> {
6
7
  scope?: string;
8
+ /**
9
+ * Content alignment
10
+ * @default "left"
11
+ */
12
+ align?: "left" | "center" | "right";
7
13
  }
8
14
 
9
15
  export interface HeaderCellType
@@ -12,14 +18,16 @@ export interface HeaderCellType
12
18
  > {}
13
19
 
14
20
  const HeaderCell: HeaderCellType = forwardRef(
15
- ({ className, children, ...rest }, ref) => {
21
+ ({ className, children, align, ...rest }, ref) => {
16
22
  const context = useContext(TableContext);
17
23
 
18
24
  return (
19
25
  <Label
20
26
  as="th"
21
27
  ref={ref}
22
- className={cl("navds-table__header-cell", className)}
28
+ className={cl("navds-table__header-cell", className, {
29
+ [`navds-table__header-cell--align-${align}`]: align,
30
+ })}
23
31
  size={context?.size}
24
32
  {...rest}
25
33
  >
@@ -3,9 +3,15 @@ import cl from "classnames";
3
3
  import Header, { HeaderType } from "./Header";
4
4
  import Body, { BodyType } from "./Body";
5
5
  import Row, { RowType } from "./Row";
6
+ import ColumnHeader, { ColumnHeaderType } from "./ColumnHeader";
6
7
  import HeaderCell, { HeaderCellType } from "./HeaderCell";
7
8
  import DataCell, { DataCellType } from "./DataCell";
8
9
 
10
+ export interface SortState {
11
+ orderBy: string;
12
+ direction: "ascending" | "descending";
13
+ }
14
+
9
15
  export interface TableProps
10
16
  extends React.TableHTMLAttributes<HTMLTableElement> {
11
17
  /**
@@ -18,6 +24,14 @@ export interface TableProps
18
24
  * @default false
19
25
  */
20
26
  zebraStripes?: boolean;
27
+ /**
28
+ * Sort state
29
+ */
30
+ sort?: SortState;
31
+ /**
32
+ * Callback whens sort state changes
33
+ */
34
+ onSortChange?: (sortKey?: string) => void;
21
35
  }
22
36
 
23
37
  export interface TableType
@@ -29,17 +43,30 @@ export interface TableType
29
43
  Row: RowType;
30
44
  DataCell: DataCellType;
31
45
  HeaderCell: HeaderCellType;
46
+ ColumnHeader: ColumnHeaderType;
32
47
  }
33
48
 
34
49
  export interface TableContextProps {
35
50
  size: "medium" | "small";
51
+ onSortChange?: (sortKey: string) => void;
52
+ sort?: SortState;
36
53
  }
37
54
 
38
55
  export const TableContext = createContext<TableContextProps | null>(null);
39
56
 
40
57
  const Table = forwardRef(
41
- ({ className, zebraStripes = false, size = "medium", ...rest }, ref) => (
42
- <TableContext.Provider value={{ size }}>
58
+ (
59
+ {
60
+ className,
61
+ zebraStripes = false,
62
+ size = "medium",
63
+ onSortChange,
64
+ sort,
65
+ ...rest
66
+ },
67
+ ref
68
+ ) => (
69
+ <TableContext.Provider value={{ size, onSortChange, sort }}>
43
70
  <table
44
71
  {...rest}
45
72
  ref={ref}
@@ -54,6 +81,7 @@ const Table = forwardRef(
54
81
  Table.Header = Header;
55
82
  Table.Body = Body;
56
83
  Table.Row = Row;
84
+ Table.ColumnHeader = ColumnHeader;
57
85
  Table.HeaderCell = HeaderCell;
58
86
  Table.DataCell = DataCell;
59
87