@navikt/ds-react 5.10.0 → 5.10.2

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.
@@ -57,11 +57,7 @@ exports.ExpandableRow = (0, react_1.forwardRef)((_a, ref) => {
57
57
  }
58
58
  e.stopPropagation();
59
59
  };
60
- const onRowClick = (e) => {
61
- if (e.target.nodeName === "TD" || e.target.nodeName === "TH") {
62
- expansionHandler(e);
63
- }
64
- };
60
+ const onRowClick = (e) => !isInteractiveTarget(e.target) && expansionHandler(e);
65
61
  return (react_1.default.createElement(react_1.default.Fragment, null,
66
62
  react_1.default.createElement(Row_1.default, Object.assign({}, rest, { ref: ref, className: (0, clsx_1.default)("navds-table__expandable-row", className, {
67
63
  "navds-table__expandable-row--open": isOpen,
@@ -82,4 +78,13 @@ exports.ExpandableRow = (0, react_1.forwardRef)((_a, ref) => {
82
78
  react_1.default.createElement("td", { colSpan: colSpan, className: "navds-table__expanded-row-cell" },
83
79
  react_1.default.createElement(AnimateHeight_1.default, { className: "navds-table__expanded-row-collapse", innerClassName: "navds-table__expanded-row-content", height: isOpen ? "auto" : 0, duration: 250 }, content)))));
84
80
  });
81
+ function isInteractiveTarget(elm) {
82
+ if (elm.nodeName === "TD" || elm.nodeName === "TH" || !elm.parentElement) {
83
+ return false;
84
+ }
85
+ if (["BUTTON", "DETAILS", "LABEL", "SELECT", "TEXTAREA", "INPUT", "A"].includes(elm.nodeName)) {
86
+ return true;
87
+ }
88
+ return isInteractiveTarget(elm.parentElement);
89
+ }
85
90
  exports.default = exports.ExpandableRow;
@@ -28,11 +28,7 @@ export const ExpandableRow = forwardRef((_a, ref) => {
28
28
  }
29
29
  e.stopPropagation();
30
30
  };
31
- const onRowClick = (e) => {
32
- if (e.target.nodeName === "TD" || e.target.nodeName === "TH") {
33
- expansionHandler(e);
34
- }
35
- };
31
+ const onRowClick = (e) => !isInteractiveTarget(e.target) && expansionHandler(e);
36
32
  return (React.createElement(React.Fragment, null,
37
33
  React.createElement(Row, Object.assign({}, rest, { ref: ref, className: cl("navds-table__expandable-row", className, {
38
34
  "navds-table__expandable-row--open": isOpen,
@@ -53,5 +49,14 @@ export const ExpandableRow = forwardRef((_a, ref) => {
53
49
  React.createElement("td", { colSpan: colSpan, className: "navds-table__expanded-row-cell" },
54
50
  React.createElement(AnimateHeight, { className: "navds-table__expanded-row-collapse", innerClassName: "navds-table__expanded-row-content", height: isOpen ? "auto" : 0, duration: 250 }, content)))));
55
51
  });
52
+ function isInteractiveTarget(elm) {
53
+ if (elm.nodeName === "TD" || elm.nodeName === "TH" || !elm.parentElement) {
54
+ return false;
55
+ }
56
+ if (["BUTTON", "DETAILS", "LABEL", "SELECT", "TEXTAREA", "INPUT", "A"].includes(elm.nodeName)) {
57
+ return true;
58
+ }
59
+ return isInteractiveTarget(elm.parentElement);
60
+ }
56
61
  export default ExpandableRow;
57
62
  //# sourceMappingURL=ExpandableRow.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExpandableRow.js","sourceRoot":"","sources":["../../src/table/ExpandableRow.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ExpandableRow.js","sourceRoot":"","sources":["../../src/table/ExpandableRow.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,MAAM,MAAM,CAAC;AACtB,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,aAAa,MAAM,uBAAuB,CAAC;AAClD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,GAAiB,MAAM,OAAO,CAAC;AAgDtC,MAAM,CAAC,MAAM,aAAa,GAAsB,UAAU,CACxD,CACE,EAYC,EACD,GAAG,EACH,EAAE;QAdF,EACE,SAAS,EACT,QAAQ,EACR,OAAO,EACP,eAAe,GAAG,MAAM,EACxB,WAAW,GAAG,KAAK,EACnB,IAAI,EACJ,YAAY,EACZ,iBAAiB,GAAG,KAAK,EACzB,gBAAgB,GAAG,KAAK,EACxB,OAAO,GAAG,GAAG,OAEd,EADI,IAAI,cAXT,kJAYC,CADQ;IAIT,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAU,WAAW,CAAC,CAAC;IACvE,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,MAAM,GAAG,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,YAAY,CAAC;IAEpC,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE;QAC7B,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,CAAC,MAAM,CAAC,CAAC;QACxB,IAAI,IAAI,KAAK,SAAS,EAAE;YACtB,eAAe,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;SACxC;QACD,CAAC,CAAC,eAAe,EAAE,CAAC;IACtB,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,EAAE,CACvB,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAExD,OAAO,CACL;QACE,oBAAC,GAAG,oBACE,IAAI,IACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,6BAA6B,EAAE,SAAS,EAAE;gBACtD,mCAAmC,EAAE,MAAM;gBAC3C,iDAAiD,EAC/C,iBAAiB;gBACnB,wCAAwC,EAAE,gBAAgB;aAC3D,CAAC,EACF,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;;gBACb,CAAC,iBAAiB,IAAI,gBAAgB,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;gBACxD,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,qDAAG,CAAC,CAAC,CAAC;YACrB,CAAC;YAEA,eAAe,KAAK,OAAO,IAAI,QAAQ;YACxC,oBAAC,QAAQ,IACP,SAAS,EAAE,EAAE,CAAC,iCAAiC,EAAE;oBAC/C,uCAAuC,EAAE,MAAM;iBAChD,CAAC,IAED,CAAC,iBAAiB,IAAI,CACrB,gCACE,SAAS,EAAC,mCAAmC,EAC7C,IAAI,EAAC,QAAQ,mBACE,EAAE,mBACF,MAAM,EACrB,OAAO,EAAE,gBAAgB;gBAEzB,oBAAC,eAAe,IACd,SAAS,EAAC,8BAA8B,EACxC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,GACxC,CACK,CACV,CACQ;YACV,eAAe,KAAK,MAAM,IAAI,QAAQ,CACnC;QACN,4BAAI,SAAS,EAAC,2BAA2B,iBAAc,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE;YACpE,4BAAI,OAAO,EAAE,OAAO,EAAE,SAAS,EAAC,gCAAgC;gBAC9D,oBAAC,aAAa,IACZ,SAAS,EAAC,oCAAoC,EAC9C,cAAc,EAAC,mCAAmC,EAClD,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAC3B,QAAQ,EAAE,GAAG,IAEZ,OAAO,CACM,CACb,CACF,CACJ,CACJ,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,SAAS,mBAAmB,CAAC,GAAgB;IAC3C,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;QACxE,OAAO,KAAK,CAAC;KACd;IACD,IACE,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,QAAQ,CACzE,GAAG,CAAC,QAAQ,CACb,EACD;QACA,OAAO,IAAI,CAAC;KACb;IAED,OAAO,mBAAmB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAChD,CAAC;AAED,eAAe,aAAa,CAAC"}
@@ -1,7 +1,24 @@
1
1
  import React from "react";
2
+ /**
3
+ * This interface represents a component that can be overridden with different props and elements.
4
+ * @template Component The type of the props for the component.
5
+ * @template Element The type of the HTML element that the component renders.
6
+ */
2
7
  export interface OverridableComponent<Component, Element extends HTMLElement> {
8
+ /**
9
+ * This is a function type that takes props and returns a React functional component.
10
+ * @param props The props for the component, which are a combination of the Component type and React.RefAttributes for the Element type.
11
+ * @returns A React functional component.
12
+ */
3
13
  (props: Component & React.RefAttributes<Element>): ReturnType<React.FC>;
14
+ /**
15
+ * This is a function type that takes props and returns a React functional component.
16
+ * It allows for the 'as' prop to override the type of element that the component renders.
17
+ * @template As The type of the element that the component should render as.
18
+ * @param props The props for the component, which are a combination of the Component type, the 'as' prop, and any other props that are not part of the Component type or the 'as' prop.
19
+ * @returns A React functional component.
20
+ */
4
21
  <As extends React.ElementType>(props: {
5
- as: As;
22
+ as?: As;
6
23
  } & Component & Omit<React.ComponentPropsWithRef<As>, keyof Component | "as">): ReturnType<React.FC>;
7
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navikt/ds-react",
3
- "version": "5.10.0",
3
+ "version": "5.10.2",
4
4
  "description": "Aksel react-components for NAV designsystem",
5
5
  "author": "Aksel | NAV designsystem team",
6
6
  "license": "MIT",
@@ -38,8 +38,8 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@floating-ui/react": "0.25.4",
41
- "@navikt/aksel-icons": "^5.10.0",
42
- "@navikt/ds-tokens": "^5.10.0",
41
+ "@navikt/aksel-icons": "^5.10.2",
42
+ "@navikt/ds-tokens": "^5.10.2",
43
43
  "@radix-ui/react-tabs": "1.0.0",
44
44
  "@radix-ui/react-toggle-group": "1.0.0",
45
45
  "clsx": "^1.2.1",
@@ -1,8 +1,8 @@
1
- import React from "react";
2
1
  import type { Meta } from "@storybook/react";
2
+ import React from "react";
3
+ import { Box, HStack, VStack } from "../..";
3
4
  import { BodyLong } from "../../typography";
4
5
  import { Bleed } from "./Bleed";
5
- import { Box, HStack, VStack } from "../..";
6
6
 
7
7
  export default {
8
8
  title: "ds-react/Primitives/Bleed",
@@ -81,11 +81,8 @@ export const ExpandableRow: ExpandableRowType = forwardRef(
81
81
  e.stopPropagation();
82
82
  };
83
83
 
84
- const onRowClick = (e) => {
85
- if (e.target.nodeName === "TD" || e.target.nodeName === "TH") {
86
- expansionHandler(e);
87
- }
88
- };
84
+ const onRowClick = (e) =>
85
+ !isInteractiveTarget(e.target) && expansionHandler(e);
89
86
 
90
87
  return (
91
88
  <>
@@ -143,4 +140,19 @@ export const ExpandableRow: ExpandableRowType = forwardRef(
143
140
  }
144
141
  );
145
142
 
143
+ function isInteractiveTarget(elm: HTMLElement) {
144
+ if (elm.nodeName === "TD" || elm.nodeName === "TH" || !elm.parentElement) {
145
+ return false;
146
+ }
147
+ if (
148
+ ["BUTTON", "DETAILS", "LABEL", "SELECT", "TEXTAREA", "INPUT", "A"].includes(
149
+ elm.nodeName
150
+ )
151
+ ) {
152
+ return true;
153
+ }
154
+
155
+ return isInteractiveTarget(elm.parentElement);
156
+ }
157
+
146
158
  export default ExpandableRow;
@@ -0,0 +1,100 @@
1
+ import { expect, jest } from "@storybook/jest";
2
+ import { userEvent, within } from "@storybook/testing-library";
3
+ import React from "react";
4
+ import { Table } from "../..";
5
+
6
+ export default {
7
+ title: "ds-react/Table/Tests",
8
+ component: Table,
9
+ };
10
+
11
+ export const ClickableRowTest = {
12
+ render: ({ onOpenChange }) => {
13
+ return (
14
+ <>
15
+ <Table zebraStripes>
16
+ <Table.Header>
17
+ <Table.Row>
18
+ <Table.HeaderCell aria-hidden />
19
+ <Table.HeaderCell aria-hidden />
20
+ <Table.HeaderCell aria-hidden />
21
+ <Table.HeaderCell aria-hidden />
22
+ <Table.HeaderCell aria-hidden />
23
+ <Table.HeaderCell aria-hidden />
24
+ </Table.Row>
25
+ </Table.Header>
26
+ <Table.Body>
27
+ <Table.ExpandableRow
28
+ content={<div>placeholder row 2</div>}
29
+ togglePlacement="right"
30
+ data-testid="row1"
31
+ expandOnRowClick
32
+ onOpenChange={onOpenChange}
33
+ >
34
+ <Table.DataCell>
35
+ <div data-testid="cell1">Should be clickable</div>
36
+ </Table.DataCell>
37
+ <Table.DataCell data-testid="cell2">
38
+ Should also be clickable
39
+ </Table.DataCell>
40
+
41
+ <Table.DataCell>
42
+ <button data-testid="cell3">Should not be clickable</button>
43
+ </Table.DataCell>
44
+ <Table.DataCell>
45
+ <div>
46
+ <div>
47
+ <button data-testid="cell4">
48
+ Nested should not be clickable
49
+ </button>
50
+ </div>
51
+ </div>
52
+ </Table.DataCell>
53
+ <Table.DataCell>
54
+ <div>
55
+ <div>
56
+ <button data-testid="cell4">
57
+ <span>2x nested should not be clickable</span>
58
+ </button>
59
+ </div>
60
+ </div>
61
+ </Table.DataCell>
62
+ </Table.ExpandableRow>
63
+ </Table.Body>
64
+ </Table>
65
+ </>
66
+ );
67
+ },
68
+ args: {
69
+ onOpenChange: jest.fn(),
70
+ },
71
+ play: async ({ canvasElement, args }) => {
72
+ args.onOpenChange.mockClear();
73
+ const canvas = within(canvasElement);
74
+
75
+ const cell1 = canvas.getByText("Should be clickable");
76
+ const cell2 = canvas.getByText("Should also be clickable");
77
+ const cell3 = canvas.getByText("Should not be clickable");
78
+ const cell4 = canvas.getByText("Nested should not be clickable");
79
+ const cell5 = canvas.getByText("2x nested should not be clickable");
80
+
81
+ await userEvent.click(cell1);
82
+ expect(args.onOpenChange.mock.calls).toHaveLength(1);
83
+ await userEvent.click(cell1);
84
+ expect(args.onOpenChange.mock.calls).toHaveLength(2);
85
+
86
+ await userEvent.click(cell2);
87
+ expect(args.onOpenChange.mock.calls).toHaveLength(3);
88
+ await userEvent.click(cell2);
89
+ expect(args.onOpenChange.mock.calls).toHaveLength(4);
90
+
91
+ await userEvent.click(cell3);
92
+ expect(args.onOpenChange.mock.calls).toHaveLength(4);
93
+
94
+ await userEvent.click(cell4);
95
+ expect(args.onOpenChange.mock.calls).toHaveLength(4);
96
+
97
+ await userEvent.click(cell5);
98
+ expect(args.onOpenChange.mock.calls).toHaveLength(4);
99
+ },
100
+ };
@@ -1,11 +1,28 @@
1
1
  import React from "react";
2
2
 
3
+ /**
4
+ * This interface represents a component that can be overridden with different props and elements.
5
+ * @template Component The type of the props for the component.
6
+ * @template Element The type of the HTML element that the component renders.
7
+ */
3
8
  export interface OverridableComponent<Component, Element extends HTMLElement> {
9
+ /**
10
+ * This is a function type that takes props and returns a React functional component.
11
+ * @param props The props for the component, which are a combination of the Component type and React.RefAttributes for the Element type.
12
+ * @returns A React functional component.
13
+ */
4
14
  (props: Component & React.RefAttributes<Element>): ReturnType<React.FC>;
5
15
 
16
+ /**
17
+ * This is a function type that takes props and returns a React functional component.
18
+ * It allows for the 'as' prop to override the type of element that the component renders.
19
+ * @template As The type of the element that the component should render as.
20
+ * @param props The props for the component, which are a combination of the Component type, the 'as' prop, and any other props that are not part of the Component type or the 'as' prop.
21
+ * @returns A React functional component.
22
+ */
6
23
  <As extends React.ElementType>(
7
24
  props: {
8
- as: As;
25
+ as?: As;
9
26
  } & Component &
10
27
  Omit<React.ComponentPropsWithRef<As>, keyof Component | "as">
11
28
  ): ReturnType<React.FC>;