@navikt/ds-react 5.9.1 → 5.10.0

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 CHANGED
@@ -17323,6 +17323,151 @@
17323
17323
  }
17324
17324
  }
17325
17325
  },
17326
+ {
17327
+ "filePath": "src/layout/page/Page.tsx",
17328
+ "displayName": "PageComponent",
17329
+ "props": {
17330
+ "as": {
17331
+ "defaultValue": {
17332
+ "value": "\"div\""
17333
+ },
17334
+ "description": "Overrides html-tag",
17335
+ "name": "as",
17336
+ "parent": {
17337
+ "fileName": "src/layout/page/Page.tsx",
17338
+ "name": "PageProps"
17339
+ },
17340
+ "declarations": [
17341
+ {
17342
+ "fileName": "src/layout/page/Page.tsx",
17343
+ "name": "PageProps"
17344
+ }
17345
+ ],
17346
+ "required": false,
17347
+ "type": {
17348
+ "name": "\"div\" | \"body\""
17349
+ }
17350
+ },
17351
+ "background": {
17352
+ "defaultValue": {
17353
+ "value": "bg-default"
17354
+ },
17355
+ "description": "Background color. Accepts a color token.",
17356
+ "name": "background",
17357
+ "parent": {
17358
+ "fileName": "src/layout/page/Page.tsx",
17359
+ "name": "PageProps"
17360
+ },
17361
+ "declarations": [
17362
+ {
17363
+ "fileName": "src/layout/page/Page.tsx",
17364
+ "name": "PageProps"
17365
+ }
17366
+ ],
17367
+ "required": false,
17368
+ "type": {
17369
+ "name": "\"bg-default\" | \"bg-subtle\""
17370
+ }
17371
+ },
17372
+ "footer": {
17373
+ "defaultValue": null,
17374
+ "description": "Allows better positioning of footer",
17375
+ "name": "footer",
17376
+ "parent": {
17377
+ "fileName": "src/layout/page/Page.tsx",
17378
+ "name": "PageProps"
17379
+ },
17380
+ "declarations": [
17381
+ {
17382
+ "fileName": "src/layout/page/Page.tsx",
17383
+ "name": "PageProps"
17384
+ }
17385
+ ],
17386
+ "required": false,
17387
+ "type": {
17388
+ "name": "ReactNode"
17389
+ }
17390
+ },
17391
+ "footerPosition": {
17392
+ "defaultValue": null,
17393
+ "description": "Places footer below page-fold",
17394
+ "name": "footerPosition",
17395
+ "parent": {
17396
+ "fileName": "src/layout/page/Page.tsx",
17397
+ "name": "PageProps"
17398
+ },
17399
+ "declarations": [
17400
+ {
17401
+ "fileName": "src/layout/page/Page.tsx",
17402
+ "name": "PageProps"
17403
+ }
17404
+ ],
17405
+ "required": false,
17406
+ "type": {
17407
+ "name": "\"belowFold\""
17408
+ }
17409
+ },
17410
+ "contentBlockPadding": {
17411
+ "defaultValue": {
17412
+ "value": "end"
17413
+ },
17414
+ "description": "Adds a standardised padding of 4rem between content and footer",
17415
+ "name": "contentBlockPadding",
17416
+ "parent": {
17417
+ "fileName": "src/layout/page/Page.tsx",
17418
+ "name": "PageProps"
17419
+ },
17420
+ "declarations": [
17421
+ {
17422
+ "fileName": "src/layout/page/Page.tsx",
17423
+ "name": "PageProps"
17424
+ }
17425
+ ],
17426
+ "required": false,
17427
+ "type": {
17428
+ "name": "\"end\" | \"none\""
17429
+ }
17430
+ },
17431
+ "className": {
17432
+ "defaultValue": null,
17433
+ "description": "",
17434
+ "name": "className",
17435
+ "parent": {
17436
+ "fileName": "aksel/node_modules/@types/react/index.d.ts",
17437
+ "name": "HTMLAttributes"
17438
+ },
17439
+ "declarations": [
17440
+ {
17441
+ "fileName": "aksel/node_modules/@types/react/index.d.ts",
17442
+ "name": "HTMLAttributes"
17443
+ }
17444
+ ],
17445
+ "required": false,
17446
+ "type": {
17447
+ "name": "string"
17448
+ }
17449
+ },
17450
+ "ref": {
17451
+ "defaultValue": null,
17452
+ "description": "Allows getting a ref to the component instance.\nOnce the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref).\n@see https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom",
17453
+ "name": "ref",
17454
+ "parent": {
17455
+ "fileName": "aksel/node_modules/@types/react/index.d.ts",
17456
+ "name": "RefAttributes"
17457
+ },
17458
+ "declarations": [
17459
+ {
17460
+ "fileName": "aksel/node_modules/@types/react/index.d.ts",
17461
+ "name": "RefAttributes"
17462
+ }
17463
+ ],
17464
+ "required": false,
17465
+ "type": {
17466
+ "name": "Ref<HTMLElement>"
17467
+ }
17468
+ }
17469
+ }
17470
+ },
17326
17471
  {
17327
17472
  "filePath": "src/layout/responsive/Responsive.tsx",
17328
17473
  "displayName": "Hide",
@@ -19162,6 +19307,92 @@
19162
19307
  }
19163
19308
  }
19164
19309
  },
19310
+ {
19311
+ "filePath": "src/layout/page/parts/PageBlock.tsx",
19312
+ "displayName": "PageBlock",
19313
+ "props": {
19314
+ "width": {
19315
+ "defaultValue": {
19316
+ "value": "max-width: 100%;"
19317
+ },
19318
+ "description": "Predefined max-width\n@example lg: 1024px\nxl: 1280px\n2xl: 1440px",
19319
+ "name": "width",
19320
+ "parent": {
19321
+ "fileName": "src/layout/page/parts/PageBlock.tsx",
19322
+ "name": "PageBlockProps"
19323
+ },
19324
+ "declarations": [
19325
+ {
19326
+ "fileName": "src/layout/page/parts/PageBlock.tsx",
19327
+ "name": "PageBlockProps"
19328
+ }
19329
+ ],
19330
+ "required": false,
19331
+ "type": {
19332
+ "name": "\"lg\" | \"xl\" | \"2xl\""
19333
+ }
19334
+ },
19335
+ "gutters": {
19336
+ "defaultValue": {
19337
+ "value": "false"
19338
+ },
19339
+ "description": "Adds a standardised responsive padding-inline\n@example 3rem on > md\n1rem on < md",
19340
+ "name": "gutters",
19341
+ "parent": {
19342
+ "fileName": "src/layout/page/parts/PageBlock.tsx",
19343
+ "name": "PageBlockProps"
19344
+ },
19345
+ "declarations": [
19346
+ {
19347
+ "fileName": "src/layout/page/parts/PageBlock.tsx",
19348
+ "name": "PageBlockProps"
19349
+ }
19350
+ ],
19351
+ "required": false,
19352
+ "type": {
19353
+ "name": "boolean"
19354
+ }
19355
+ },
19356
+ "className": {
19357
+ "defaultValue": null,
19358
+ "description": "",
19359
+ "name": "className",
19360
+ "parent": {
19361
+ "fileName": "aksel/node_modules/@types/react/index.d.ts",
19362
+ "name": "HTMLAttributes"
19363
+ },
19364
+ "declarations": [
19365
+ {
19366
+ "fileName": "aksel/node_modules/@types/react/index.d.ts",
19367
+ "name": "HTMLAttributes"
19368
+ }
19369
+ ],
19370
+ "required": false,
19371
+ "type": {
19372
+ "name": "string"
19373
+ }
19374
+ },
19375
+ "ref": {
19376
+ "defaultValue": null,
19377
+ "description": "Allows getting a ref to the component instance.\nOnce the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref).\n@see https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom",
19378
+ "name": "ref",
19379
+ "parent": {
19380
+ "fileName": "aksel/node_modules/@types/react/index.d.ts",
19381
+ "name": "RefAttributes"
19382
+ },
19383
+ "declarations": [
19384
+ {
19385
+ "fileName": "aksel/node_modules/@types/react/index.d.ts",
19386
+ "name": "RefAttributes"
19387
+ }
19388
+ ],
19389
+ "required": false,
19390
+ "type": {
19391
+ "name": "Ref<HTMLDivElement>"
19392
+ }
19393
+ }
19394
+ }
19395
+ },
19165
19396
  {
19166
19397
  "filePath": "src/layout/sidemal-test/content-box/ContentBox.tsx",
19167
19398
  "displayName": "ContentBox",
@@ -44,7 +44,10 @@ const DateWrapper = ({ open, children, onClose, anchor, locale, variant, popover
44
44
  "navds-date": variant === "month",
45
45
  }), flip: false }, popoverProps), children));
46
46
  }
47
- return (react_1.default.createElement(modal_1.Modal, { ref: modalRef, open: open, onClose: onClose, "aria-label": (0, labels_1.modalLabel)(locale, variant), className: (0, clsx_1.default)("navds-date__modal", {
47
+ return (react_1.default.createElement(modal_1.Modal, { ref: modalRef, open: open, onClose: (event) => {
48
+ event.stopPropagation();
49
+ onClose();
50
+ }, "aria-label": (0, labels_1.modalLabel)(locale, variant), className: (0, clsx_1.default)("navds-date__modal", {
48
51
  "navds-date__nested-modal": isInModal,
49
52
  "navds-date": variant === "month",
50
53
  }), closeOnBackdropClick: true },
package/cjs/index.js CHANGED
@@ -54,3 +54,4 @@ __exportStar(require("./layout/stack"), exports);
54
54
  __exportStar(require("./layout/grid"), exports);
55
55
  __exportStar(require("./layout/content-container"), exports);
56
56
  __exportStar(require("./layout/responsive"), exports);
57
+ __exportStar(require("./layout/page"), exports);
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __rest = (this && this.__rest) || function (s, e) {
26
+ var t = {};
27
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
28
+ t[p] = s[p];
29
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
30
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
32
+ t[p[i]] = s[p[i]];
33
+ }
34
+ return t;
35
+ };
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.PageComponent = void 0;
41
+ const clsx_1 = __importDefault(require("clsx"));
42
+ const react_1 = __importStar(require("react"));
43
+ const PageBlock_1 = require("./parts/PageBlock");
44
+ exports.PageComponent = (0, react_1.forwardRef)((_a, ref) => {
45
+ var { as: Component = "div", className, style: _style, footer, children, footerPosition, background = "bg-default", contentBlockPadding = "end" } = _a, rest = __rest(_a, ["as", "className", "style", "footer", "children", "footerPosition", "background", "contentBlockPadding"]);
46
+ const style = Object.assign(Object.assign({}, _style), { "--__ac-page-background": `var(--a-${background})` });
47
+ const belowFold = footerPosition === "belowFold";
48
+ return (react_1.default.createElement(Component, Object.assign({}, rest, { className: (0, clsx_1.default)("navds-page", className), ref: ref, style: style }),
49
+ react_1.default.createElement("div", { className: (0, clsx_1.default)({
50
+ "navds-page__content--fullheight": belowFold,
51
+ "navds-page__content--grow": !belowFold,
52
+ "navds-page__content--padding": contentBlockPadding === "end",
53
+ }) }, children),
54
+ footer));
55
+ });
56
+ /**
57
+ * Page helps with establishing a top-level layout for your page
58
+ *
59
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/primitives/page)
60
+ * @see 🏷️ {@link PageProps}
61
+ * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
62
+ *
63
+ * @example
64
+ * ```jsx
65
+ * <Page
66
+ * footer={<Page.Block width="xl" gutters />}
67
+ * >
68
+ * <Page.Block width="xl" gutters />// Header
69
+ * <Page.Block width="xl" gutters />// Content
70
+ * </Page>
71
+ * ```
72
+ * @example
73
+ * Footer placed below page-fold
74
+ * ```jsx
75
+ * <Page
76
+ * footer={<Page.Block width="xl" gutters />}
77
+ * footerPosition="belowFold"
78
+ * >
79
+ * <Page.Block width="xl" gutters />// Header
80
+ * <Page.Block width="xl" gutters />// Content
81
+ * </Page>
82
+ * ```
83
+ */
84
+ const Page = exports.PageComponent;
85
+ Page.Block = PageBlock_1.PageBlock;
86
+ exports.default = Page;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Page = void 0;
7
+ var Page_1 = require("./Page");
8
+ Object.defineProperty(exports, "Page", { enumerable: true, get: function () { return __importDefault(Page_1).default; } });
@@ -0,0 +1,6 @@
1
+ {
2
+ "sideEffects": false,
3
+ "main": "./index.js",
4
+ "module": "../../../esm/layout/page/index.js",
5
+ "types": "../../../esm/layout/page/index.d.ts"
6
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __rest = (this && this.__rest) || function (s, e) {
26
+ var t = {};
27
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
28
+ t[p] = s[p];
29
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
30
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
32
+ t[p[i]] = s[p[i]];
33
+ }
34
+ return t;
35
+ };
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.PageBlock = exports.widths = void 0;
41
+ const clsx_1 = __importDefault(require("clsx"));
42
+ const react_1 = __importStar(require("react"));
43
+ exports.widths = ["lg", "xl", "2xl"];
44
+ /**
45
+ * Acts as a top-level container for defining max-width, gutters and horizontal centering
46
+ *
47
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/primitives/page)
48
+ * @see 🏷️ {@link PageBlockProps}
49
+ * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
50
+ *
51
+ * @example
52
+ * ```jsx
53
+ * <Page
54
+ * footer={<Page.Block width="xl" gutters />}
55
+ * >
56
+ * <Page.Block width="xl" gutters />// Header
57
+ * <Page.Block width="xl" gutters />// Content
58
+ * </Page>
59
+ * ```
60
+ * @example
61
+ * With background bleed
62
+ * Wrapping `Page.Block` with `Box` allows the background-color to use full screen-width
63
+ * ```jsx
64
+ * <Page
65
+ * footer={<Box background="..."><Page.Block width="xl" gutters /></Box>}
66
+ * footerPosition="belowFold"
67
+ * >
68
+ * <Box background="..."><Page.Block width="xl" gutters /></Box>//Header
69
+ * <Box background="..."><Page.Block width="xl" gutters /></Box>//Content
70
+ * </Page>
71
+ * ```
72
+ */
73
+ exports.PageBlock = (0, react_1.forwardRef)((_a, ref) => {
74
+ var { as: Component = "div", gutters, className, width } = _a, rest = __rest(_a, ["as", "gutters", "className", "width"]);
75
+ return (react_1.default.createElement(Component, Object.assign({}, rest, { className: (0, clsx_1.default)("navds-pageblock", `navds-pageblock--${width}`, className, { "navds-pageblock--gutters": gutters }), ref: ref })));
76
+ });
@@ -15,7 +15,10 @@ export const DateWrapper = ({ open, children, onClose, anchor, locale, variant,
15
15
  "navds-date": variant === "month",
16
16
  }), flip: false }, popoverProps), children));
17
17
  }
18
- return (React.createElement(Modal, { ref: modalRef, open: open, onClose: onClose, "aria-label": modalLabel(locale, variant), className: cl("navds-date__modal", {
18
+ return (React.createElement(Modal, { ref: modalRef, open: open, onClose: (event) => {
19
+ event.stopPropagation();
20
+ onClose();
21
+ }, "aria-label": modalLabel(locale, variant), className: cl("navds-date__modal", {
19
22
  "navds-date__nested-modal": isInModal,
20
23
  "navds-date": variant === "month",
21
24
  }), closeOnBackdropClick: true },
@@ -1 +1 @@
1
- {"version":3,"file":"DateWrapper.js","sourceRoot":"","sources":["../../../src/date/parts/DateWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,MAAM,CAAC;AACtB,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAepE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,MAAM,EACN,MAAM,EACN,OAAO,EACP,YAAY,GACK,EAAE,EAAE;IACrB,MAAM,QAAQ,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACpD,MAAM,SAAS,GACb,QAAQ,CAAC,+BAA+B,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;IAEhE,IAAI,SAAS,EAAE;QACb,OAAO,CACL,oBAAC,OAAO,kBACN,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,SAAS,EAAC,cAAc,EACxB,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,EAAE,CAAC,qBAAqB,EAAE;gBACnC,YAAY,EAAE,OAAO,KAAK,OAAO;aAClC,CAAC,EACF,IAAI,EAAE,KAAK,IACP,YAAY,GAEf,QAAQ,CACD,CACX,CAAC;KACH;IACD,OAAO,CACL,oBAAC,KAAK,IACJ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,gBACJ,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,SAAS,EAAE,EAAE,CAAC,mBAAmB,EAAE;YACjC,0BAA0B,EAAE,SAAS;YACrC,YAAY,EAAE,OAAO,KAAK,OAAO;SAClC,CAAC,EACF,oBAAoB;QAEpB,6BAAK,SAAS,EAAC,wBAAwB;YACpC,QAAQ;YACT,oBAAC,MAAM,IACL,OAAO,EAAC,UAAU,EAClB,OAAO,EAAE,GAAG,EAAE,WAAC,OAAA,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,0CAAE,KAAK,EAAE,CAAA,EAAA,EACzC,IAAI,EAAC,OAAO,IAEX,qBAAqB,CAAC,MAAM,CAAC,CACvB,CACL,CACA,CACT,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"DateWrapper.js","sourceRoot":"","sources":["../../../src/date/parts/DateWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,MAAM,CAAC;AACtB,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAepE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,MAAM,EACN,MAAM,EACN,OAAO,EACP,YAAY,GACK,EAAE,EAAE;IACrB,MAAM,QAAQ,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACpD,MAAM,SAAS,GACb,QAAQ,CAAC,+BAA+B,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;IAEhE,IAAI,SAAS,EAAE;QACb,OAAO,CACL,oBAAC,OAAO,kBACN,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,SAAS,EAAC,cAAc,EACxB,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,EAAE,CAAC,qBAAqB,EAAE;gBACnC,YAAY,EAAE,OAAO,KAAK,OAAO;aAClC,CAAC,EACF,IAAI,EAAE,KAAK,IACP,YAAY,GAEf,QAAQ,CACD,CACX,CAAC;KACH;IACD,OAAO,CACL,oBAAC,KAAK,IACJ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,OAAO,EAAE,CAAC;QACZ,CAAC,gBACW,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,SAAS,EAAE,EAAE,CAAC,mBAAmB,EAAE;YACjC,0BAA0B,EAAE,SAAS;YACrC,YAAY,EAAE,OAAO,KAAK,OAAO;SAClC,CAAC,EACF,oBAAoB;QAEpB,6BAAK,SAAS,EAAC,wBAAwB;YACpC,QAAQ;YACT,oBAAC,MAAM,IACL,OAAO,EAAC,UAAU,EAClB,OAAO,EAAE,GAAG,EAAE,WAAC,OAAA,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,0CAAE,KAAK,EAAE,CAAA,EAAA,EACzC,IAAI,EAAC,OAAO,IAEX,qBAAqB,CAAC,MAAM,CAAC,CACvB,CACL,CACA,CACT,CAAC;AACJ,CAAC,CAAC"}
package/esm/index.d.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";
package/esm/index.js CHANGED
@@ -38,4 +38,5 @@ 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";
41
42
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC"}
@@ -0,0 +1,63 @@
1
+ import bgColors from "@navikt/ds-tokens/src/colors-bg.json";
2
+ import React from "react";
3
+ import { OverridableComponent } from "../../util";
4
+ import { PageBlock } from "./parts/PageBlock";
5
+ export interface PageProps extends React.HTMLAttributes<HTMLElement> {
6
+ /**
7
+ * Overrides html-tag
8
+ * @default "div"
9
+ */
10
+ as?: "div" | "body";
11
+ /**
12
+ * Background color. Accepts a color token.
13
+ * @default bg-default
14
+ */
15
+ background?: keyof typeof bgColors.a;
16
+ /**
17
+ * Allows better positioning of footer
18
+ */
19
+ footer?: React.ReactNode;
20
+ /**
21
+ * Places footer below page-fold
22
+ */
23
+ footerPosition?: "belowFold";
24
+ /**
25
+ * Adds a standardised padding of 4rem between content and footer
26
+ * @default block-end
27
+ */
28
+ contentBlockPadding?: "end" | "none";
29
+ }
30
+ interface PageComponentType extends OverridableComponent<PageProps, HTMLElement> {
31
+ Block: typeof PageBlock;
32
+ }
33
+ export declare const PageComponent: OverridableComponent<PageProps, HTMLElement>;
34
+ /**
35
+ * Page helps with establishing a top-level layout for your page
36
+ *
37
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/primitives/page)
38
+ * @see 🏷️ {@link PageProps}
39
+ * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
40
+ *
41
+ * @example
42
+ * ```jsx
43
+ * <Page
44
+ * footer={<Page.Block width="xl" gutters />}
45
+ * >
46
+ * <Page.Block width="xl" gutters />// Header
47
+ * <Page.Block width="xl" gutters />// Content
48
+ * </Page>
49
+ * ```
50
+ * @example
51
+ * Footer placed below page-fold
52
+ * ```jsx
53
+ * <Page
54
+ * footer={<Page.Block width="xl" gutters />}
55
+ * footerPosition="belowFold"
56
+ * >
57
+ * <Page.Block width="xl" gutters />// Header
58
+ * <Page.Block width="xl" gutters />// Content
59
+ * </Page>
60
+ * ```
61
+ */
62
+ declare const Page: PageComponentType;
63
+ export default Page;
@@ -0,0 +1,58 @@
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
+ import { PageBlock } from "./parts/PageBlock";
15
+ export const PageComponent = forwardRef((_a, ref) => {
16
+ var { as: Component = "div", className, style: _style, footer, children, footerPosition, background = "bg-default", contentBlockPadding = "end" } = _a, rest = __rest(_a, ["as", "className", "style", "footer", "children", "footerPosition", "background", "contentBlockPadding"]);
17
+ const style = Object.assign(Object.assign({}, _style), { "--__ac-page-background": `var(--a-${background})` });
18
+ const belowFold = footerPosition === "belowFold";
19
+ return (React.createElement(Component, Object.assign({}, rest, { className: cl("navds-page", className), ref: ref, style: style }),
20
+ React.createElement("div", { className: cl({
21
+ "navds-page__content--fullheight": belowFold,
22
+ "navds-page__content--grow": !belowFold,
23
+ "navds-page__content--padding": contentBlockPadding === "end",
24
+ }) }, children),
25
+ footer));
26
+ });
27
+ /**
28
+ * Page helps with establishing a top-level layout for your page
29
+ *
30
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/primitives/page)
31
+ * @see 🏷️ {@link PageProps}
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
+ * Footer placed below page-fold
45
+ * ```jsx
46
+ * <Page
47
+ * footer={<Page.Block width="xl" gutters />}
48
+ * footerPosition="belowFold"
49
+ * >
50
+ * <Page.Block width="xl" gutters />// Header
51
+ * <Page.Block width="xl" gutters />// Content
52
+ * </Page>
53
+ * ```
54
+ */
55
+ const Page = PageComponent;
56
+ Page.Block = PageBlock;
57
+ export default Page;
58
+ //# sourceMappingURL=Page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Page.js","sourceRoot":"","sources":["../../../src/layout/page/Page.tsx"],"names":[],"mappings":";;;;;;;;;;;AACA,OAAO,EAAE,MAAM,MAAM,CAAC;AACtB,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAiC9C,MAAM,CAAC,MAAM,aAAa,GACxB,UAAU,CACR,CACE,EAUC,EACD,GAAG,EACH,EAAE;QAZF,EACE,EAAE,EAAE,SAAS,GAAG,KAAK,EACrB,SAAS,EACT,KAAK,EAAE,MAAM,EACb,MAAM,EACN,QAAQ,EACR,cAAc,EACd,UAAU,GAAG,YAAY,EACzB,mBAAmB,GAAG,KAAK,OAE5B,EADI,IAAI,cATT,yGAUC,CADQ;IAIT,MAAM,KAAK,mCACN,MAAM,KACT,wBAAwB,EAAE,WAAW,UAAU,GAAG,GACnD,CAAC;IAEF,MAAM,SAAS,GAAG,cAAc,KAAK,WAAW,CAAC;IAEjD,OAAO,CACL,oBAAC,SAAS,oBACJ,IAAI,IACR,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,EACtC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK;QAEZ,6BACE,SAAS,EAAE,EAAE,CAAC;gBACZ,iCAAiC,EAAE,SAAS;gBAC5C,2BAA2B,EAAE,CAAC,SAAS;gBACvC,8BAA8B,EAAE,mBAAmB,KAAK,KAAK;aAC9D,CAAC,IAED,QAAQ,CACL;QACL,MAAM,CACG,CACb,CAAC;AACJ,CAAC,CACF,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,IAAI,GAAG,aAAkC,CAAC;AAEhD,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;AAEvB,eAAe,IAAI,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as Page, type PageProps } from "./Page";
2
+ export { type PageBlockProps } from "./parts/PageBlock";
@@ -0,0 +1,2 @@
1
+ export { default as Page } from "./Page";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/layout/page/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAkB,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,52 @@
1
+ import React from "react";
2
+ import { OverridableComponent } from "../../../util/OverridableComponent";
3
+ export declare const widths: readonly ["lg", "xl", "2xl"];
4
+ export interface PageBlockProps extends React.HTMLAttributes<HTMLDivElement> {
5
+ /**
6
+ * Predefined max-width
7
+ * @example
8
+ * lg: 1024px
9
+ * xl: 1280px
10
+ * 2xl: 1440px
11
+ * @default max-width: 100%;
12
+ */
13
+ width?: (typeof widths)[number];
14
+ /**
15
+ * Adds a standardised responsive padding-inline
16
+ * @example
17
+ * 3rem on > md
18
+ * 1rem on < md
19
+ * @default false
20
+ */
21
+ gutters?: boolean;
22
+ }
23
+ /**
24
+ * Acts as a top-level container for defining max-width, gutters and horizontal centering
25
+ *
26
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/primitives/page)
27
+ * @see 🏷️ {@link PageBlockProps}
28
+ * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
29
+ *
30
+ * @example
31
+ * ```jsx
32
+ * <Page
33
+ * footer={<Page.Block width="xl" gutters />}
34
+ * >
35
+ * <Page.Block width="xl" gutters />// Header
36
+ * <Page.Block width="xl" gutters />// Content
37
+ * </Page>
38
+ * ```
39
+ * @example
40
+ * With background bleed
41
+ * Wrapping `Page.Block` with `Box` allows the background-color to use full screen-width
42
+ * ```jsx
43
+ * <Page
44
+ * footer={<Box background="..."><Page.Block width="xl" gutters /></Box>}
45
+ * footerPosition="belowFold"
46
+ * >
47
+ * <Box background="..."><Page.Block width="xl" gutters /></Box>//Header
48
+ * <Box background="..."><Page.Block width="xl" gutters /></Box>//Content
49
+ * </Page>
50
+ * ```
51
+ */
52
+ export declare const PageBlock: OverridableComponent<PageBlockProps, HTMLDivElement>;
@@ -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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navikt/ds-react",
3
- "version": "5.9.1",
3
+ "version": "5.10.0",
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.1",
42
- "@navikt/ds-tokens": "^5.9.1",
41
+ "@navikt/aksel-icons": "^5.10.0",
42
+ "@navikt/ds-tokens": "^5.10.0",
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",
@@ -437,28 +437,36 @@ export const ModalDemo = () => {
437
437
  toDate: new Date("Feb 23 2024"),
438
438
  onDateChange: console.log,
439
439
  });
440
+ const [open, setOpen] = useState(true);
440
441
 
441
442
  return (
442
- <Modal open header={{ heading: "Modal-demo" }}>
443
- <Modal.Body style={{ position: "relative" }}>
444
- <BodyLong spacing>
445
- Lorem ipsum dolor sit, amet consectetur adipisicing elit.
446
- </BodyLong>
447
-
448
- <DatePicker {...datepickerProps} dropdownCaption>
449
- <DatePicker.Input
450
- {...inputProps}
451
- label="Velg dato"
452
- description="Format: dd.mm.yyyy"
453
- />
454
- </DatePicker>
455
- </Modal.Body>
456
- <Modal.Footer>
457
- <Button>Neste</Button>
458
- <Button variant="secondary">Tilbake</Button>
459
- <Button variant="tertiary">Avbryt</Button>
460
- </Modal.Footer>
461
- </Modal>
443
+ <>
444
+ <Button onClick={() => setOpen(!open)}>Open modal</Button>
445
+ <Modal
446
+ open={open}
447
+ onClose={() => setOpen(false)}
448
+ header={{ heading: "Modal-demo" }}
449
+ >
450
+ <Modal.Body style={{ position: "relative" }}>
451
+ <BodyLong spacing>
452
+ Lorem ipsum dolor sit, amet consectetur adipisicing elit.
453
+ </BodyLong>
454
+
455
+ <DatePicker {...datepickerProps} dropdownCaption>
456
+ <DatePicker.Input
457
+ {...inputProps}
458
+ label="Velg dato"
459
+ description="Format: dd.mm.yyyy"
460
+ />
461
+ </DatePicker>
462
+ </Modal.Body>
463
+ <Modal.Footer>
464
+ <Button>Neste</Button>
465
+ <Button variant="secondary">Tilbake</Button>
466
+ <Button variant="tertiary">Avbryt</Button>
467
+ </Modal.Footer>
468
+ </Modal>
469
+ </>
462
470
  );
463
471
  };
464
472
  ModalDemo.parameters = { chromatic: { pauseAnimationAtEnd: true } };
@@ -57,7 +57,10 @@ export const DateWrapper = ({
57
57
  <Modal
58
58
  ref={modalRef}
59
59
  open={open}
60
- onClose={onClose}
60
+ onClose={(event) => {
61
+ event.stopPropagation();
62
+ onClose();
63
+ }}
61
64
  aria-label={modalLabel(locale, variant)}
62
65
  className={cl("navds-date__modal", {
63
66
  "navds-date__nested-modal": isInModal,
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
+ );