@navikt/ds-react 5.9.2 → 5.10.1

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.
@@ -0,0 +1,48 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import cl from "clsx";
13
+ import React, { forwardRef } from "react";
14
+ export const widths = ["lg", "xl", "2xl"];
15
+ /**
16
+ * Acts as a top-level container for defining max-width, gutters and horizontal centering
17
+ *
18
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/primitives/page)
19
+ * @see 🏷️ {@link PageBlockProps}
20
+ * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
21
+ *
22
+ * @example
23
+ * ```jsx
24
+ * <Page
25
+ * footer={<Page.Block width="xl" gutters />}
26
+ * >
27
+ * <Page.Block width="xl" gutters />// Header
28
+ * <Page.Block width="xl" gutters />// Content
29
+ * </Page>
30
+ * ```
31
+ * @example
32
+ * With background bleed
33
+ * Wrapping `Page.Block` with `Box` allows the background-color to use full screen-width
34
+ * ```jsx
35
+ * <Page
36
+ * footer={<Box background="..."><Page.Block width="xl" gutters /></Box>}
37
+ * footerPosition="belowFold"
38
+ * >
39
+ * <Box background="..."><Page.Block width="xl" gutters /></Box>//Header
40
+ * <Box background="..."><Page.Block width="xl" gutters /></Box>//Content
41
+ * </Page>
42
+ * ```
43
+ */
44
+ export const PageBlock = forwardRef((_a, ref) => {
45
+ var { as: Component = "div", gutters, className, width } = _a, rest = __rest(_a, ["as", "gutters", "className", "width"]);
46
+ return (React.createElement(Component, Object.assign({}, rest, { className: cl("navds-pageblock", `navds-pageblock--${width}`, className, { "navds-pageblock--gutters": gutters }), ref: ref })));
47
+ });
48
+ //# sourceMappingURL=PageBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageBlock.js","sourceRoot":"","sources":["../../../../src/layout/page/parts/PageBlock.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,MAAM,CAAC;AACtB,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAG1C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAU,CAAC;AAsBnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,SAAS,GACpB,UAAU,CACR,CAAC,EAA6D,EAAE,GAAG,EAAE,EAAE;QAAtE,EAAE,EAAE,EAAE,SAAS,GAAG,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,OAAW,EAAN,IAAI,cAA3D,uCAA6D,CAAF;IAC1D,OAAO,CACL,oBAAC,SAAS,oBACJ,IAAI,IACR,SAAS,EAAE,EAAE,CACX,iBAAiB,EACjB,oBAAoB,KAAK,EAAE,EAC3B,SAAS,EACT,EAAE,0BAA0B,EAAE,OAAO,EAAE,CACxC,EACD,GAAG,EAAE,GAAG,IACR,CACH,CAAC;AACJ,CAAC,CACF,CAAC"}
@@ -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":";;;;;;;;;;;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;QACvB,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE;YAC5D,gBAAgB,CAAC,CAAC,CAAC,CAAC;SACrB;IACH,CAAC,CAAC;IAEF,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,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"ExpandableRow.js","sourceRoot":"","sources":["../../src/table/ExpandableRow.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navikt/ds-react",
3
- "version": "5.9.2",
3
+ "version": "5.10.1",
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.9.2",
42
- "@navikt/ds-tokens": "^5.9.2",
41
+ "@navikt/aksel-icons": "^5.10.1",
42
+ "@navikt/ds-tokens": "^5.10.1",
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",
package/src/index.ts CHANGED
@@ -38,3 +38,4 @@ export * from "./layout/stack";
38
38
  export * from "./layout/grid";
39
39
  export * from "./layout/content-container";
40
40
  export * from "./layout/responsive";
41
+ export * from "./layout/page";
@@ -0,0 +1,271 @@
1
+ import bgColors from "@navikt/ds-tokens/src/colors-bg.json";
2
+ import type { Meta, StoryFn } from "@storybook/react";
3
+ import React, { useEffect } from "react";
4
+ import { Box } from "../box";
5
+ import { HGrid } from "../grid";
6
+ import Page from "./Page";
7
+ import { widths } from "./parts/PageBlock";
8
+
9
+ const meta: Meta = {
10
+ title: "ds-react/Primitives/Page",
11
+ component: Page,
12
+ parameters: {
13
+ layout: "fullscreen",
14
+ },
15
+ };
16
+
17
+ export default meta;
18
+
19
+ export const Default: StoryFn = ({
20
+ belowFold,
21
+ background,
22
+ width,
23
+ gutters,
24
+ contentBlockPadding,
25
+ }) => (
26
+ <Page
27
+ footer={<Footer width={width} gutters={gutters} />}
28
+ footerPosition={belowFold ? "belowFold" : undefined}
29
+ background={background}
30
+ contentBlockPadding={contentBlockPadding}
31
+ >
32
+ <Header width={width} gutters={gutters} />
33
+ <Content width={width} gutters={gutters} />
34
+ </Page>
35
+ );
36
+
37
+ Default.argTypes = {
38
+ width: {
39
+ control: "radio",
40
+ options: widths,
41
+ },
42
+ background: {
43
+ control: "radio",
44
+ options: Object.keys(bgColors.a),
45
+ },
46
+ belowFold: {
47
+ control: "boolean",
48
+ },
49
+ gutters: {
50
+ control: "boolean",
51
+ },
52
+ contentBlockPadding: {
53
+ control: "radio",
54
+ options: ["end", "none"],
55
+ },
56
+ };
57
+
58
+ Default.args = {
59
+ belowFold: false,
60
+ gutters: false,
61
+ contentBlockPadding: "end",
62
+ };
63
+
64
+ export const BelowFold: StoryFn = () => (
65
+ <Page
66
+ footer={<Footer />}
67
+ footerPosition="belowFold"
68
+ contentBlockPadding="end"
69
+ >
70
+ <Header />
71
+ <Content />
72
+ </Page>
73
+ );
74
+
75
+ export const Background: StoryFn = () => (
76
+ <HGrid columns={2} gap="4">
77
+ <Page
78
+ background="bg-default"
79
+ footer={<div>footer</div>}
80
+ contentBlockPadding="end"
81
+ >
82
+ <div>header</div>
83
+ <div>content</div>
84
+ </Page>
85
+ <Page
86
+ background="bg-subtle"
87
+ footer={<div>footer</div>}
88
+ contentBlockPadding="end"
89
+ >
90
+ <div>header</div>
91
+ <div>content</div>
92
+ </Page>
93
+ </HGrid>
94
+ );
95
+
96
+ export const ContentBlockPadding: StoryFn = () => (
97
+ <HGrid columns={2} gap="6" align="start">
98
+ <Page
99
+ footer={<Footer width="lg" gutters />}
100
+ contentBlockPadding="end"
101
+ background="bg-subtle"
102
+ >
103
+ <Header width="lg" gutters />
104
+ <Page.Block width="lg" gutters as="main">
105
+ <Box background="surface-alt-3-subtle" style={{ height: "80vh" }}>
106
+ Main
107
+ </Box>
108
+ </Page.Block>
109
+ </Page>
110
+ <Page
111
+ footer={<Footer width="lg" gutters />}
112
+ contentBlockPadding="none"
113
+ background="bg-subtle"
114
+ >
115
+ <Header width="lg" gutters />
116
+ <Page.Block width="lg" gutters as="main">
117
+ <Box background="surface-alt-3-subtle" style={{ height: "80vh" }}>
118
+ Main
119
+ </Box>
120
+ </Page.Block>
121
+ </Page>
122
+ </HGrid>
123
+ );
124
+
125
+ export const Gutters: StoryFn = () => (
126
+ <HGrid columns={2} gap="6" align="start">
127
+ <Page footer={<Footer width="lg" gutters />} background="bg-subtle">
128
+ <Header width="lg" gutters />
129
+ <Page.Block width="lg" gutters as="main">
130
+ <Box background="surface-alt-3-subtle" style={{ height: "80vh" }}>
131
+ Main
132
+ </Box>
133
+ </Page.Block>
134
+ </Page>
135
+ <Page footer={<Footer width="lg" />} background="bg-subtle">
136
+ <Header width="lg" />
137
+ <Page.Block width="lg" as="main">
138
+ <Box background="surface-alt-3-subtle" style={{ height: "80vh" }}>
139
+ Main
140
+ </Box>
141
+ </Page.Block>
142
+ </Page>
143
+ </HGrid>
144
+ );
145
+
146
+ Gutters.parameters = {
147
+ chromatic: {
148
+ modes: {
149
+ mobile_portrait: {
150
+ viewport: {
151
+ width: 400,
152
+ height: 850,
153
+ },
154
+ },
155
+ desktop: {
156
+ viewport: {
157
+ width: 1280,
158
+ height: 960,
159
+ },
160
+ },
161
+ },
162
+ },
163
+ };
164
+
165
+ const MILJO_URL = "https://www.nav.no/dekoratoren";
166
+
167
+ export const WithDecorator: StoryFn = () => {
168
+ return (
169
+ <Page
170
+ contentBlockPadding="end"
171
+ footerPosition="belowFold"
172
+ footer={<div id="decorator-footer"></div>}
173
+ >
174
+ <div id="decorator-header"></div>
175
+ <Content width="lg" gutters />
176
+ <div
177
+ id="decorator-env"
178
+ data-src={`${MILJO_URL}/env?context=privatperson`}
179
+ ></div>
180
+ </Page>
181
+ );
182
+ };
183
+
184
+ WithDecorator.decorators = [
185
+ (Story) => {
186
+ useEffect(() => {
187
+ const script = document.createElement("script");
188
+ script.src = `${MILJO_URL}/client.js`;
189
+ script.async = true;
190
+ document.body.appendChild(script);
191
+
192
+ const styles = document.createElement("link");
193
+ styles.href = `${MILJO_URL}/css/client.css`;
194
+ styles.rel = "stylesheet";
195
+ document.head.appendChild(styles);
196
+
197
+ return () => {
198
+ document.body.removeChild(script);
199
+ document.head.removeChild(styles);
200
+ };
201
+ }, []);
202
+
203
+ return <Story />;
204
+ },
205
+ ];
206
+
207
+ WithDecorator.parameters = {
208
+ chromatic: {
209
+ disable: true,
210
+ },
211
+ };
212
+
213
+ export const OutsideBackground = () => {
214
+ return (
215
+ <Page
216
+ contentBlockPadding="end"
217
+ footer={
218
+ <Box
219
+ background="surface-alt-3-subtle"
220
+ style={{ height: 100 }}
221
+ as="footer"
222
+ >
223
+ <Page.Block width="lg" gutters>
224
+ Footer
225
+ </Page.Block>
226
+ </Box>
227
+ }
228
+ >
229
+ <Box background="surface-alt-1-subtle" style={{ height: 64 }} as="header">
230
+ <Page.Block width="lg" gutters>
231
+ Header
232
+ </Page.Block>
233
+ </Box>
234
+ <Box background="surface-alt-2-subtle" style={{ height: 300 }} as="main">
235
+ <Page.Block width="lg" gutters>
236
+ main
237
+ </Page.Block>
238
+ </Box>
239
+ </Page>
240
+ );
241
+ };
242
+
243
+ function Header({ width = "lg", gutters = false }: any) {
244
+ return (
245
+ <Page.Block as="header" width={width} gutters={gutters}>
246
+ <Box background="surface-alt-3-subtle" style={{ height: 64 }}>
247
+ Header
248
+ </Box>
249
+ </Page.Block>
250
+ );
251
+ }
252
+
253
+ function Content({ width = "lg", gutters = false }: any) {
254
+ return (
255
+ <Page.Block width={width} gutters={gutters} as="main">
256
+ <Box background="surface-alt-3-subtle" style={{ height: 300 }}>
257
+ Main
258
+ </Box>
259
+ </Page.Block>
260
+ );
261
+ }
262
+
263
+ function Footer({ width = "lg", gutters = false }: any) {
264
+ return (
265
+ <Page.Block width={width} gutters={gutters} as="footer">
266
+ <Box background="surface-alt-3-subtle" style={{ height: 100 }}>
267
+ Footer
268
+ </Box>
269
+ </Page.Block>
270
+ );
271
+ }
@@ -0,0 +1,115 @@
1
+ import bgColors from "@navikt/ds-tokens/src/colors-bg.json";
2
+ import cl from "clsx";
3
+ import React, { forwardRef } from "react";
4
+ import { OverridableComponent } from "../../util";
5
+ import { PageBlock } from "./parts/PageBlock";
6
+
7
+ export interface PageProps extends React.HTMLAttributes<HTMLElement> {
8
+ /**
9
+ * Overrides html-tag
10
+ * @default "div"
11
+ */
12
+ as?: "div" | "body";
13
+ /**
14
+ * Background color. Accepts a color token.
15
+ * @default bg-default
16
+ */
17
+ background?: keyof typeof bgColors.a;
18
+ /**
19
+ * Allows better positioning of footer
20
+ */
21
+ footer?: React.ReactNode;
22
+ /**
23
+ * Places footer below page-fold
24
+ */
25
+ footerPosition?: "belowFold";
26
+ /**
27
+ * Adds a standardised padding of 4rem between content and footer
28
+ * @default block-end
29
+ */
30
+ contentBlockPadding?: "end" | "none";
31
+ }
32
+
33
+ interface PageComponentType
34
+ extends OverridableComponent<PageProps, HTMLElement> {
35
+ Block: typeof PageBlock;
36
+ }
37
+
38
+ export const PageComponent: OverridableComponent<PageProps, HTMLElement> =
39
+ forwardRef(
40
+ (
41
+ {
42
+ as: Component = "div",
43
+ className,
44
+ style: _style,
45
+ footer,
46
+ children,
47
+ footerPosition,
48
+ background = "bg-default",
49
+ contentBlockPadding = "end",
50
+ ...rest
51
+ },
52
+ ref
53
+ ) => {
54
+ const style: React.CSSProperties = {
55
+ ..._style,
56
+ "--__ac-page-background": `var(--a-${background})`,
57
+ };
58
+
59
+ const belowFold = footerPosition === "belowFold";
60
+
61
+ return (
62
+ <Component
63
+ {...rest}
64
+ className={cl("navds-page", className)}
65
+ ref={ref}
66
+ style={style}
67
+ >
68
+ <div
69
+ className={cl({
70
+ "navds-page__content--fullheight": belowFold,
71
+ "navds-page__content--grow": !belowFold,
72
+ "navds-page__content--padding": contentBlockPadding === "end",
73
+ })}
74
+ >
75
+ {children}
76
+ </div>
77
+ {footer}
78
+ </Component>
79
+ );
80
+ }
81
+ );
82
+
83
+ /**
84
+ * Page helps with establishing a top-level layout for your page
85
+ *
86
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/primitives/page)
87
+ * @see 🏷️ {@link PageProps}
88
+ * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
89
+ *
90
+ * @example
91
+ * ```jsx
92
+ * <Page
93
+ * footer={<Page.Block width="xl" gutters />}
94
+ * >
95
+ * <Page.Block width="xl" gutters />// Header
96
+ * <Page.Block width="xl" gutters />// Content
97
+ * </Page>
98
+ * ```
99
+ * @example
100
+ * Footer placed below page-fold
101
+ * ```jsx
102
+ * <Page
103
+ * footer={<Page.Block width="xl" gutters />}
104
+ * footerPosition="belowFold"
105
+ * >
106
+ * <Page.Block width="xl" gutters />// Header
107
+ * <Page.Block width="xl" gutters />// Content
108
+ * </Page>
109
+ * ```
110
+ */
111
+ const Page = PageComponent as PageComponentType;
112
+
113
+ Page.Block = PageBlock;
114
+
115
+ export default Page;
@@ -0,0 +1,2 @@
1
+ export { default as Page, type PageProps } from "./Page";
2
+ export { type PageBlockProps } from "./parts/PageBlock";
@@ -0,0 +1,72 @@
1
+ import cl from "clsx";
2
+ import React, { forwardRef } from "react";
3
+ import { OverridableComponent } from "../../../util/OverridableComponent";
4
+
5
+ export const widths = ["lg", "xl", "2xl"] as const;
6
+
7
+ export interface PageBlockProps extends React.HTMLAttributes<HTMLDivElement> {
8
+ /**
9
+ * Predefined max-width
10
+ * @example
11
+ * lg: 1024px
12
+ * xl: 1280px
13
+ * 2xl: 1440px
14
+ * @default max-width: 100%;
15
+ */
16
+ width?: (typeof widths)[number];
17
+ /**
18
+ * Adds a standardised responsive padding-inline
19
+ * @example
20
+ * 3rem on > md
21
+ * 1rem on < md
22
+ * @default false
23
+ */
24
+ gutters?: boolean;
25
+ }
26
+
27
+ /**
28
+ * Acts as a top-level container for defining max-width, gutters and horizontal centering
29
+ *
30
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/primitives/page)
31
+ * @see 🏷️ {@link PageBlockProps}
32
+ * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
33
+ *
34
+ * @example
35
+ * ```jsx
36
+ * <Page
37
+ * footer={<Page.Block width="xl" gutters />}
38
+ * >
39
+ * <Page.Block width="xl" gutters />// Header
40
+ * <Page.Block width="xl" gutters />// Content
41
+ * </Page>
42
+ * ```
43
+ * @example
44
+ * With background bleed
45
+ * Wrapping `Page.Block` with `Box` allows the background-color to use full screen-width
46
+ * ```jsx
47
+ * <Page
48
+ * footer={<Box background="..."><Page.Block width="xl" gutters /></Box>}
49
+ * footerPosition="belowFold"
50
+ * >
51
+ * <Box background="..."><Page.Block width="xl" gutters /></Box>//Header
52
+ * <Box background="..."><Page.Block width="xl" gutters /></Box>//Content
53
+ * </Page>
54
+ * ```
55
+ */
56
+ export const PageBlock: OverridableComponent<PageBlockProps, HTMLDivElement> =
57
+ forwardRef(
58
+ ({ as: Component = "div", gutters, className, width, ...rest }, ref) => {
59
+ return (
60
+ <Component
61
+ {...rest}
62
+ className={cl(
63
+ "navds-pageblock",
64
+ `navds-pageblock--${width}`,
65
+ className,
66
+ { "navds-pageblock--gutters": gutters }
67
+ )}
68
+ ref={ref}
69
+ />
70
+ );
71
+ }
72
+ );
@@ -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;