@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.
- package/_docs.json +231 -0
- package/cjs/index.js +1 -0
- package/cjs/layout/page/Page.js +86 -0
- package/cjs/layout/page/index.js +8 -0
- package/cjs/layout/page/package.json +6 -0
- package/cjs/layout/page/parts/PageBlock.js +76 -0
- package/cjs/table/ExpandableRow.js +10 -5
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/esm/layout/page/Page.d.ts +63 -0
- package/esm/layout/page/Page.js +58 -0
- package/esm/layout/page/Page.js.map +1 -0
- package/esm/layout/page/index.d.ts +2 -0
- package/esm/layout/page/index.js +2 -0
- package/esm/layout/page/index.js.map +1 -0
- package/esm/layout/page/parts/PageBlock.d.ts +52 -0
- package/esm/layout/page/parts/PageBlock.js +48 -0
- package/esm/layout/page/parts/PageBlock.js.map +1 -0
- package/esm/table/ExpandableRow.js +10 -5
- package/esm/table/ExpandableRow.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +1 -0
- package/src/layout/page/Page.stories.tsx +271 -0
- package/src/layout/page/Page.tsx +115 -0
- package/src/layout/page/index.ts +2 -0
- package/src/layout/page/parts/PageBlock.tsx +72 -0
- package/src/table/ExpandableRow.tsx +17 -5
- package/src/table/stories/tests/table.stories.tsx +100 -0
|
@@ -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
|
|
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.
|
|
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.
|
|
42
|
-
"@navikt/ds-tokens": "^5.
|
|
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
|
@@ -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,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
|
-
|
|
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;
|