@navikt/ds-react 0.16.8 → 0.16.12

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/cjs/index.js CHANGED
@@ -22,6 +22,7 @@ __exportStar(require("./link-panel"), exports);
22
22
  __exportStar(require("./loader"), exports);
23
23
  __exportStar(require("./menu"), exports);
24
24
  __exportStar(require("./modal"), exports);
25
+ __exportStar(require("./pagination"), exports);
25
26
  __exportStar(require("./panel"), exports);
26
27
  __exportStar(require("./popover"), exports);
27
28
  __exportStar(require("./speech-bubble"), exports);
@@ -0,0 +1,71 @@
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.getSteps = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const classnames_1 = __importDefault(require("classnames"));
9
+ const ds_icons_1 = require("@navikt/ds-icons");
10
+ const __1 = require("..");
11
+ const getSteps = ({ page, count, boundaryCount = 1, siblingCount = 1, }) => {
12
+ var _a, _b;
13
+ const range = (start, end) => Array.from({ length: end - start + 1 }, (_, i) => start + i);
14
+ if (count <= (boundaryCount + siblingCount) * 2 + 3)
15
+ return range(1, count);
16
+ const startPages = range(1, boundaryCount);
17
+ const endPages = range(count - boundaryCount + 1, count);
18
+ const siblingsStart = Math.max(Math.min(page - siblingCount, count - boundaryCount - siblingCount * 2 - 1), boundaryCount + 2);
19
+ const siblingsEnd = siblingsStart + siblingCount * 2;
20
+ return [
21
+ ...startPages,
22
+ siblingsStart - ((_a = startPages[startPages.length - 1]) !== null && _a !== void 0 ? _a : 0) === 2
23
+ ? siblingsStart - 1
24
+ : "ellipsis",
25
+ ...range(siblingsStart, siblingsEnd),
26
+ ((_b = endPages[0]) !== null && _b !== void 0 ? _b : count + 1) - siblingsEnd === 2
27
+ ? siblingsEnd + 1
28
+ : "ellipsis",
29
+ ...endPages,
30
+ ];
31
+ };
32
+ exports.getSteps = getSteps;
33
+ const Pagination = ({ page, onPageChange, count, boundaryCount = 1, siblingCount = 1, className, size = "medium", prevNextTexts = false, }) => {
34
+ if (page < 1) {
35
+ console.error("page cannot be less than 1");
36
+ return null;
37
+ }
38
+ if (count < 1) {
39
+ console.error("count cannot be less than 1");
40
+ return null;
41
+ }
42
+ if (boundaryCount < 0) {
43
+ console.error("boundaryCount cannot be less than 0");
44
+ return null;
45
+ }
46
+ if (siblingCount < 0) {
47
+ console.error("siblingCount cannot be less than 0");
48
+ return null;
49
+ }
50
+ return (react_1.default.createElement("nav", { className: (0, classnames_1.default)("navds-pagination", `navds-pagination--${size}`, className) },
51
+ prevNextTexts && (react_1.default.createElement("button", { className: "navds-pagination__prev-next", disabled: page === 1, onClick: () => onPageChange(page - 1) },
52
+ react_1.default.createElement(ds_icons_1.Back, { className: "navds-pagination__prev-next-icon", role: "presentation" }),
53
+ react_1.default.createElement(__1.BodyShort, { size: size, className: "navds-pagination__prev-text" }, "Tilbake"))),
54
+ react_1.default.createElement("ul", { className: "navds-pagination__list" },
55
+ !prevNextTexts && (react_1.default.createElement("li", null,
56
+ react_1.default.createElement("button", { className: "navds-pagination__prev-next", disabled: page === 1, onClick: () => onPageChange(page - 1) },
57
+ react_1.default.createElement(ds_icons_1.Back, { className: "navds-pagination__prev-next-icon", title: "Tilbake" })))),
58
+ (0, exports.getSteps)({ page, count, siblingCount, boundaryCount }).map((step, i) => {
59
+ const n = Number(step);
60
+ return isNaN(n) ? (react_1.default.createElement("li", { className: "navds-pagination__ellipsis", key: `${step}${i}` },
61
+ react_1.default.createElement(__1.BodyShort, { size: size }, "..."))) : (react_1.default.createElement("li", { key: step },
62
+ react_1.default.createElement(__1.BodyShort, { size: size, as: "button", className: "navds-pagination__item", onClick: () => onPageChange(n), "aria-current": page === n ? true : undefined }, n)));
63
+ }),
64
+ !prevNextTexts && (react_1.default.createElement("li", null,
65
+ react_1.default.createElement("button", { className: "navds-pagination__prev-next", disabled: page === count, onClick: () => onPageChange(page + 1) },
66
+ react_1.default.createElement(ds_icons_1.Next, { className: "navds-pagination__prev-next-icon", title: "Neste" }))))),
67
+ prevNextTexts && (react_1.default.createElement("button", { className: "navds-pagination__prev-next", disabled: page === count, onClick: () => onPageChange(page + 1) },
68
+ react_1.default.createElement(__1.BodyShort, { size: size, className: "navds-pagination__next-text" }, "Neste"),
69
+ react_1.default.createElement(ds_icons_1.Next, { className: "navds-pagination__prev-next-icon", role: "presentation" })))));
70
+ };
71
+ exports.default = Pagination;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ var __importDefault = (this && this.__importDefault) || function (mod) {
13
+ return (mod && mod.__esModule) ? mod : { "default": mod };
14
+ };
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.Pagination = void 0;
17
+ var Pagination_1 = require("./Pagination");
18
+ Object.defineProperty(exports, "Pagination", { enumerable: true, get: function () { return __importDefault(Pagination_1).default; } });
19
+ __exportStar(require("./Pagination"), exports);
@@ -0,0 +1,6 @@
1
+ {
2
+ "sideEffects": false,
3
+ "main": "./index.js",
4
+ "module": "../../esm/pagination/index.js",
5
+ "types": "../../esm/pagination/index.d.ts"
6
+ }
@@ -57,12 +57,15 @@ const ToggleGroup = (0, react_1.forwardRef)((_a, ref) => {
57
57
  [desc !== null && desc !== void 0 ? desc : ""]: !!desc,
58
58
  [labelId]: !!label,
59
59
  });
60
+ if (!value && !defaultValue) {
61
+ console.error("ToggleGroup needs either a value or defaultValue");
62
+ }
60
63
  return (react_1.default.createElement(exports.ToggleGroupContext.Provider, { value: {
61
64
  size,
62
65
  } },
63
66
  react_1.default.createElement("div", null,
64
67
  label && (react_1.default.createElement(__1.Label, { size: size, className: "navds-toggle-group__label", id: labelId }, label)),
65
- react_1.default.createElement(RadixToggleGroup.Root, Object.assign({}, rest, { onValueChange: handleValueChange, value: value !== null && value !== void 0 ? value : groupValue, defaultValue: defaultValue, ref: ref, className: (0, classnames_1.default)("navds-toggle-group", className, `navds-toggle-group--${size}`) }, (describeBy && { "aria-describedby": describeBy }), { type: "single" }), children))));
68
+ react_1.default.createElement(RadixToggleGroup.Root, Object.assign({}, rest, { onValueChange: handleValueChange, value: value !== null && value !== void 0 ? value : groupValue, defaultValue: defaultValue, ref: ref, className: (0, classnames_1.default)("navds-toggle-group", className, `navds-toggle-group--${size}`) }, (describeBy && { "aria-describedby": describeBy }), { role: "toolbar", type: "single" }), children))));
66
69
  });
67
70
  ToggleGroup.Item = ToggleItem_1.default;
68
71
  exports.default = ToggleGroup;
@@ -37,9 +37,10 @@ const react_1 = __importStar(require("react"));
37
37
  const classnames_1 = __importDefault(require("classnames"));
38
38
  const __1 = require("..");
39
39
  const RadixToggleGroup = __importStar(require("@radix-ui/react-toggle-group"));
40
+ const ToggleGroup_1 = require("./ToggleGroup");
40
41
  const ToggleItem = (0, react_1.forwardRef)((_a, ref) => {
41
42
  var { className, children } = _a, rest = __rest(_a, ["className", "children"]);
42
- const context = (0, react_1.useContext)(__1.ToggleGroupContext);
43
+ const context = (0, react_1.useContext)(ToggleGroup_1.ToggleGroupContext);
43
44
  return (react_1.default.createElement(RadixToggleGroup.Item, Object.assign({}, rest, { ref: ref, className: (0, classnames_1.default)("navds-toggle-group__button", className) }),
44
45
  react_1.default.createElement(__1.Label, { as: "span", className: "navds-toggle-group__button-inner", size: context === null || context === void 0 ? void 0 : context.size }, children)));
45
46
  });
@@ -1,14 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
- };
12
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
13
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
14
4
  };
@@ -16,4 +6,3 @@ Object.defineProperty(exports, "__esModule", { value: true });
16
6
  exports.ToggleGroup = void 0;
17
7
  var ToggleGroup_1 = require("./ToggleGroup");
18
8
  Object.defineProperty(exports, "ToggleGroup", { enumerable: true, get: function () { return __importDefault(ToggleGroup_1).default; } });
19
- __exportStar(require("./ToggleGroup"), exports);
package/esm/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export * from "./link-panel";
10
10
  export * from "./loader";
11
11
  export * from "./menu";
12
12
  export * from "./modal";
13
+ export * from "./pagination";
13
14
  export * from "./panel";
14
15
  export * from "./popover";
15
16
  export * from "./speech-bubble";
package/esm/index.js CHANGED
@@ -10,6 +10,7 @@ export * from "./link-panel";
10
10
  export * from "./loader";
11
11
  export * from "./menu";
12
12
  export * from "./modal";
13
+ export * from "./pagination";
13
14
  export * from "./panel";
14
15
  export * from "./popover";
15
16
  export * from "./speech-bubble";
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,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,OAAO,CAAC;AACtB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AAEvB,6BAA6B;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,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,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,OAAO,CAAC;AACtB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AAEvB,6BAA6B;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import ReactModal from "react-modal";
3
3
  import { ModalContentType } from "./ModalContent";
4
- export interface ModalProps extends ReactModal {
4
+ export interface ModalProps {
5
5
  /**
6
6
  * Modal content
7
7
  */
@@ -0,0 +1,43 @@
1
+ import React from "react";
2
+ interface PaginationProps extends React.HTMLAttributes<HTMLElement> {
3
+ /**
4
+ * Current page
5
+ */
6
+ page: number;
7
+ /**
8
+ * Number of always visible pages before and after the current page.
9
+ * @default 1
10
+ */
11
+ siblingCount?: number;
12
+ /**
13
+ * Number of always visible pages at the beginning and end.
14
+ * @default 1
15
+ */
16
+ boundaryCount?: number;
17
+ /**
18
+ * Callback when current page changes
19
+ */
20
+ onPageChange: (page: number) => void;
21
+ /**
22
+ * Total number of pages
23
+ */
24
+ count: number;
25
+ /**
26
+ * Changes padding, height and font-size
27
+ * @default "medium"
28
+ */
29
+ size?: "medium" | "small";
30
+ /**
31
+ * Display text alongside "previous" and "next" icons
32
+ * @default false
33
+ */
34
+ prevNextTexts?: boolean;
35
+ }
36
+ export declare const getSteps: ({ page, count, boundaryCount, siblingCount, }: {
37
+ page: any;
38
+ count: any;
39
+ boundaryCount?: number | undefined;
40
+ siblingCount?: number | undefined;
41
+ }) => (string | number)[];
42
+ declare const Pagination: ({ page, onPageChange, count, boundaryCount, siblingCount, className, size, prevNextTexts, }: PaginationProps) => JSX.Element | null;
43
+ export default Pagination;
@@ -0,0 +1,65 @@
1
+ import React from "react";
2
+ import cl from "classnames";
3
+ import { Back, Next } from "@navikt/ds-icons";
4
+ import { BodyShort } from "..";
5
+ export const getSteps = ({ page, count, boundaryCount = 1, siblingCount = 1, }) => {
6
+ var _a, _b;
7
+ const range = (start, end) => Array.from({ length: end - start + 1 }, (_, i) => start + i);
8
+ if (count <= (boundaryCount + siblingCount) * 2 + 3)
9
+ return range(1, count);
10
+ const startPages = range(1, boundaryCount);
11
+ const endPages = range(count - boundaryCount + 1, count);
12
+ const siblingsStart = Math.max(Math.min(page - siblingCount, count - boundaryCount - siblingCount * 2 - 1), boundaryCount + 2);
13
+ const siblingsEnd = siblingsStart + siblingCount * 2;
14
+ return [
15
+ ...startPages,
16
+ siblingsStart - ((_a = startPages[startPages.length - 1]) !== null && _a !== void 0 ? _a : 0) === 2
17
+ ? siblingsStart - 1
18
+ : "ellipsis",
19
+ ...range(siblingsStart, siblingsEnd),
20
+ ((_b = endPages[0]) !== null && _b !== void 0 ? _b : count + 1) - siblingsEnd === 2
21
+ ? siblingsEnd + 1
22
+ : "ellipsis",
23
+ ...endPages,
24
+ ];
25
+ };
26
+ const Pagination = ({ page, onPageChange, count, boundaryCount = 1, siblingCount = 1, className, size = "medium", prevNextTexts = false, }) => {
27
+ if (page < 1) {
28
+ console.error("page cannot be less than 1");
29
+ return null;
30
+ }
31
+ if (count < 1) {
32
+ console.error("count cannot be less than 1");
33
+ return null;
34
+ }
35
+ if (boundaryCount < 0) {
36
+ console.error("boundaryCount cannot be less than 0");
37
+ return null;
38
+ }
39
+ if (siblingCount < 0) {
40
+ console.error("siblingCount cannot be less than 0");
41
+ return null;
42
+ }
43
+ return (React.createElement("nav", { className: cl("navds-pagination", `navds-pagination--${size}`, className) },
44
+ prevNextTexts && (React.createElement("button", { className: "navds-pagination__prev-next", disabled: page === 1, onClick: () => onPageChange(page - 1) },
45
+ React.createElement(Back, { className: "navds-pagination__prev-next-icon", role: "presentation" }),
46
+ React.createElement(BodyShort, { size: size, className: "navds-pagination__prev-text" }, "Tilbake"))),
47
+ React.createElement("ul", { className: "navds-pagination__list" },
48
+ !prevNextTexts && (React.createElement("li", null,
49
+ React.createElement("button", { className: "navds-pagination__prev-next", disabled: page === 1, onClick: () => onPageChange(page - 1) },
50
+ React.createElement(Back, { className: "navds-pagination__prev-next-icon", title: "Tilbake" })))),
51
+ getSteps({ page, count, siblingCount, boundaryCount }).map((step, i) => {
52
+ const n = Number(step);
53
+ return isNaN(n) ? (React.createElement("li", { className: "navds-pagination__ellipsis", key: `${step}${i}` },
54
+ React.createElement(BodyShort, { size: size }, "..."))) : (React.createElement("li", { key: step },
55
+ React.createElement(BodyShort, { size: size, as: "button", className: "navds-pagination__item", onClick: () => onPageChange(n), "aria-current": page === n ? true : undefined }, n)));
56
+ }),
57
+ !prevNextTexts && (React.createElement("li", null,
58
+ React.createElement("button", { className: "navds-pagination__prev-next", disabled: page === count, onClick: () => onPageChange(page + 1) },
59
+ React.createElement(Next, { className: "navds-pagination__prev-next-icon", title: "Neste" }))))),
60
+ prevNextTexts && (React.createElement("button", { className: "navds-pagination__prev-next", disabled: page === count, onClick: () => onPageChange(page + 1) },
61
+ React.createElement(BodyShort, { size: size, className: "navds-pagination__next-text" }, "Neste"),
62
+ React.createElement(Next, { className: "navds-pagination__prev-next-icon", role: "presentation" })))));
63
+ };
64
+ export default Pagination;
65
+ //# sourceMappingURL=Pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination.js","sourceRoot":"","sources":["../../src/pagination/Pagination.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { default as Pagination } from "./Pagination";
2
+ export * from "./Pagination";
@@ -0,0 +1,3 @@
1
+ export { default as Pagination } from "./Pagination";
2
+ export * from "./Pagination";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pagination/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,cAAc,cAAc,CAAC"}
@@ -32,12 +32,15 @@ const ToggleGroup = forwardRef((_a, ref) => {
32
32
  [desc !== null && desc !== void 0 ? desc : ""]: !!desc,
33
33
  [labelId]: !!label,
34
34
  });
35
+ if (!value && !defaultValue) {
36
+ console.error("ToggleGroup needs either a value or defaultValue");
37
+ }
35
38
  return (React.createElement(ToggleGroupContext.Provider, { value: {
36
39
  size,
37
40
  } },
38
41
  React.createElement("div", null,
39
42
  label && (React.createElement(Label, { size: size, className: "navds-toggle-group__label", id: labelId }, label)),
40
- React.createElement(RadixToggleGroup.Root, Object.assign({}, rest, { onValueChange: handleValueChange, value: value !== null && value !== void 0 ? value : groupValue, defaultValue: defaultValue, ref: ref, className: cl("navds-toggle-group", className, `navds-toggle-group--${size}`) }, (describeBy && { "aria-describedby": describeBy }), { type: "single" }), children))));
43
+ React.createElement(RadixToggleGroup.Root, Object.assign({}, rest, { onValueChange: handleValueChange, value: value !== null && value !== void 0 ? value : groupValue, defaultValue: defaultValue, ref: ref, className: cl("navds-toggle-group", className, `navds-toggle-group--${size}`) }, (describeBy && { "aria-describedby": describeBy }), { role: "toolbar", type: "single" }), children))));
41
44
  });
42
45
  ToggleGroup.Item = ToggleItem;
43
46
  export default ToggleGroup;
@@ -1 +1 @@
1
- {"version":3,"file":"ToggleGroup.js","sourceRoot":"","sources":["../../src/toggle-group/ToggleGroup.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,EACZ,aAAa,EACb,UAAU,EAEV,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,UAA8B,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,gBAAgB,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC;AA0ClC,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAC7C,IAAI,CACL,CAAC;AAEF,MAAM,WAAW,GAAG,UAAU,CAC5B,CACE,EAWC,EACD,GAAG,EACH,EAAE;QAbF,EACE,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,IAAI,GAAG,QAAQ,EACf,KAAK,EACL,KAAK,EACL,YAAY,EACZ,EAAE,EACF,kBAAkB,EAAE,IAAI,OAEzB,EADI,IAAI,cAVT,yGAWC,CADQ;IAIT,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,sBAAsB,KAAK,EAAE,EAAE,CAAC;IAEhD,MAAM,iBAAiB,GAAG,CAAC,CAAS,EAAE,EAAE;QACtC,IAAI,CAAC,KAAK,EAAE,EAAE;YACZ,aAAa,CAAC,CAAC,CAAC,CAAC;YACjB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,CAAC,CAAC,CAAC;SACf;IACH,CAAC,CAAC;IAEF,IAAI,CAAC,KAAK,IAAI,CAAC,YAAY,EAAE;QAC3B,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;KACxE;IAED,MAAM,UAAU,GAAG,EAAE,CAAC;QACpB,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI;QACpB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK;KACnB,CAAC,CAAC;IAEH,OAAO,CACL,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;YACL,IAAI;SACL;QAED;YACG,KAAK,IAAI,CACR,oBAAC,KAAK,IACJ,IAAI,EAAE,IAAI,EACV,SAAS,EAAC,2BAA2B,EACrC,EAAE,EAAE,OAAO,IAEV,KAAK,CACA,CACT;YACD,oBAAC,gBAAgB,CAAC,IAAI,oBAChB,IAAI,IACR,aAAa,EAAE,iBAAiB,EAChC,KAAK,EAAE,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,UAAU,EAC1B,YAAY,EAAE,YAAY,EAC1B,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,oBAAoB,EACpB,SAAS,EACT,uBAAuB,IAAI,EAAE,CAC9B,IACG,CAAC,UAAU,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,CAAC,IACtD,IAAI,EAAC,QAAQ,KAEZ,QAAQ,CACa,CACpB,CACsB,CAC/B,CAAC;AACJ,CAAC,CACsB,CAAC;AAE1B,WAAW,CAAC,IAAI,GAAG,UAAU,CAAC;AAE9B,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ToggleGroup.js","sourceRoot":"","sources":["../../src/toggle-group/ToggleGroup.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,EACZ,aAAa,EACb,UAAU,EAEV,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,UAA8B,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,gBAAgB,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC;AA0ClC,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAC7C,IAAI,CACL,CAAC;AAEF,MAAM,WAAW,GAAG,UAAU,CAC5B,CACE,EAWC,EACD,GAAG,EACH,EAAE;QAbF,EACE,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,IAAI,GAAG,QAAQ,EACf,KAAK,EACL,KAAK,EACL,YAAY,EACZ,EAAE,EACF,kBAAkB,EAAE,IAAI,OAEzB,EADI,IAAI,cAVT,yGAWC,CADQ;IAIT,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,sBAAsB,KAAK,EAAE,EAAE,CAAC;IAEhD,MAAM,iBAAiB,GAAG,CAAC,CAAS,EAAE,EAAE;QACtC,IAAI,CAAC,KAAK,EAAE,EAAE;YACZ,aAAa,CAAC,CAAC,CAAC,CAAC;YACjB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,CAAC,CAAC,CAAC;SACf;IACH,CAAC,CAAC;IAEF,IAAI,CAAC,KAAK,IAAI,CAAC,YAAY,EAAE;QAC3B,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;KACxE;IAED,MAAM,UAAU,GAAG,EAAE,CAAC;QACpB,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI;QACpB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK;KACnB,CAAC,CAAC;IAEH,IAAI,CAAC,KAAK,IAAI,CAAC,YAAY,EAAE;QAC3B,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;KACnE;IAED,OAAO,CACL,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;YACL,IAAI;SACL;QAED;YACG,KAAK,IAAI,CACR,oBAAC,KAAK,IACJ,IAAI,EAAE,IAAI,EACV,SAAS,EAAC,2BAA2B,EACrC,EAAE,EAAE,OAAO,IAEV,KAAK,CACA,CACT;YACD,oBAAC,gBAAgB,CAAC,IAAI,oBAChB,IAAI,IACR,aAAa,EAAE,iBAAiB,EAChC,KAAK,EAAE,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,UAAU,EAC1B,YAAY,EAAE,YAAY,EAC1B,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,oBAAoB,EACpB,SAAS,EACT,uBAAuB,IAAI,EAAE,CAC9B,IACG,CAAC,UAAU,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,CAAC,IACtD,IAAI,EAAC,SAAS,EACd,IAAI,EAAC,QAAQ,KAEZ,QAAQ,CACa,CACpB,CACsB,CAC/B,CAAC;AACJ,CAAC,CACsB,CAAC;AAE1B,WAAW,CAAC,IAAI,GAAG,UAAU,CAAC;AAE9B,eAAe,WAAW,CAAC"}
@@ -11,8 +11,9 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import React, { forwardRef, useContext } from "react";
13
13
  import cl from "classnames";
14
- import { Label, ToggleGroupContext } from "..";
14
+ import { Label } from "..";
15
15
  import * as RadixToggleGroup from "@radix-ui/react-toggle-group";
16
+ import { ToggleGroupContext } from "./ToggleGroup";
16
17
  const ToggleItem = forwardRef((_a, ref) => {
17
18
  var { className, children } = _a, rest = __rest(_a, ["className", "children"]);
18
19
  const context = useContext(ToggleGroupContext);
@@ -1 +1 @@
1
- {"version":3,"file":"ToggleItem.js","sourceRoot":"","sources":["../../src/toggle-group/ToggleItem.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,KAAK,gBAAgB,MAAM,8BAA8B,CAAC;AAkBjE,MAAM,UAAU,GAAG,UAAU,CAC3B,CAAC,EAAgC,EAAE,GAAG,EAAE,EAAE;QAAzC,EAAE,SAAS,EAAE,QAAQ,OAAW,EAAN,IAAI,cAA9B,yBAAgC,CAAF;IAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAE/C,OAAO,CACL,oBAAC,gBAAgB,CAAC,IAAI,oBAChB,IAAI,IACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,4BAA4B,EAAE,SAAS,CAAC;QAEtD,oBAAC,KAAK,IACJ,EAAE,EAAC,MAAM,EACT,SAAS,EAAC,kCAAkC,EAC5C,IAAI,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,IAElB,QAAQ,CACH,CACc,CACzB,CAAC;AACJ,CAAC,CACgB,CAAC;AAEpB,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ToggleItem.js","sourceRoot":"","sources":["../../src/toggle-group/ToggleItem.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC;AAC3B,OAAO,KAAK,gBAAgB,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAkBnD,MAAM,UAAU,GAAG,UAAU,CAC3B,CAAC,EAAgC,EAAE,GAAG,EAAE,EAAE;QAAzC,EAAE,SAAS,EAAE,QAAQ,OAAW,EAAN,IAAI,cAA9B,yBAAgC,CAAF;IAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAE/C,OAAO,CACL,oBAAC,gBAAgB,CAAC,IAAI,oBAChB,IAAI,IACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,4BAA4B,EAAE,SAAS,CAAC;QAEtD,oBAAC,KAAK,IACJ,EAAE,EAAC,MAAM,EACT,SAAS,EAAC,kCAAkC,EAC5C,IAAI,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,IAElB,QAAQ,CACH,CACc,CACzB,CAAC;AACJ,CAAC,CACgB,CAAC;AAEpB,eAAe,UAAU,CAAC"}
@@ -1,2 +1,2 @@
1
1
  export { default as ToggleGroup } from "./ToggleGroup";
2
- export * from "./ToggleGroup";
2
+ export { ToggleGroupProps } from "./ToggleGroup";
@@ -1,3 +1,2 @@
1
1
  export { default as ToggleGroup } from "./ToggleGroup";
2
- export * from "./ToggleGroup";
3
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/toggle-group/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/toggle-group/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navikt/ds-react",
3
- "version": "0.16.8",
3
+ "version": "0.16.12",
4
4
  "private": false,
5
5
  "description": "NAV designsystem react components",
6
6
  "author": "NAV Designsystem team",
@@ -65,5 +65,5 @@
65
65
  "@types/react": "^17.0.30",
66
66
  "react": "^17.0.0"
67
67
  },
68
- "gitHead": "cb429868c15db40ba7d29a639de2de3cd6ba72ce"
68
+ "gitHead": "8f99813590a93d55b4f06f6c1129da169a72fa58"
69
69
  }
package/src/index.ts CHANGED
@@ -10,6 +10,7 @@ export * from "./link-panel";
10
10
  export * from "./loader";
11
11
  export * from "./menu";
12
12
  export * from "./modal";
13
+ export * from "./pagination";
13
14
  export * from "./panel";
14
15
  export * from "./popover";
15
16
  export * from "./speech-bubble";
@@ -6,7 +6,7 @@ import { Close } from "@navikt/ds-icons";
6
6
  import { Button } from "..";
7
7
  import ModalContent, { ModalContentType } from "./ModalContent";
8
8
 
9
- export interface ModalProps extends ReactModal {
9
+ export interface ModalProps {
10
10
  /**
11
11
  * Modal content
12
12
  */
@@ -0,0 +1,191 @@
1
+ import React from "react";
2
+ import cl from "classnames";
3
+ import { Back, Next } from "@navikt/ds-icons";
4
+ import { BodyShort } from "..";
5
+
6
+ interface PaginationProps extends React.HTMLAttributes<HTMLElement> {
7
+ /**
8
+ * Current page
9
+ */
10
+ page: number;
11
+ /**
12
+ * Number of always visible pages before and after the current page.
13
+ * @default 1
14
+ */
15
+ siblingCount?: number;
16
+ /**
17
+ * Number of always visible pages at the beginning and end.
18
+ * @default 1
19
+ */
20
+ boundaryCount?: number;
21
+ /**
22
+ * Callback when current page changes
23
+ */
24
+ onPageChange: (page: number) => void;
25
+ /**
26
+ * Total number of pages
27
+ */
28
+ count: number;
29
+ /**
30
+ * Changes padding, height and font-size
31
+ * @default "medium"
32
+ */
33
+ size?: "medium" | "small";
34
+ /**
35
+ * Display text alongside "previous" and "next" icons
36
+ * @default false
37
+ */
38
+ prevNextTexts?: boolean;
39
+ }
40
+
41
+ export const getSteps = ({
42
+ page,
43
+ count,
44
+ boundaryCount = 1,
45
+ siblingCount = 1,
46
+ }) => {
47
+ const range = (start: number, end: number) =>
48
+ Array.from({ length: end - start + 1 }, (_, i) => start + i);
49
+
50
+ if (count <= (boundaryCount + siblingCount) * 2 + 3) return range(1, count);
51
+
52
+ const startPages = range(1, boundaryCount);
53
+ const endPages = range(count - boundaryCount + 1, count);
54
+
55
+ const siblingsStart = Math.max(
56
+ Math.min(page - siblingCount, count - boundaryCount - siblingCount * 2 - 1),
57
+ boundaryCount + 2
58
+ );
59
+ const siblingsEnd = siblingsStart + siblingCount * 2;
60
+
61
+ return [
62
+ ...startPages,
63
+ siblingsStart - (startPages[startPages.length - 1] ?? 0) === 2
64
+ ? siblingsStart - 1
65
+ : "ellipsis",
66
+ ...range(siblingsStart, siblingsEnd),
67
+ (endPages[0] ?? count + 1) - siblingsEnd === 2
68
+ ? siblingsEnd + 1
69
+ : "ellipsis",
70
+ ...endPages,
71
+ ];
72
+ };
73
+
74
+ const Pagination = ({
75
+ page,
76
+ onPageChange,
77
+ count,
78
+ boundaryCount = 1,
79
+ siblingCount = 1,
80
+ className,
81
+ size = "medium",
82
+ prevNextTexts = false,
83
+ }: PaginationProps) => {
84
+ if (page < 1) {
85
+ console.error("page cannot be less than 1");
86
+ return null;
87
+ }
88
+ if (count < 1) {
89
+ console.error("count cannot be less than 1");
90
+ return null;
91
+ }
92
+ if (boundaryCount < 0) {
93
+ console.error("boundaryCount cannot be less than 0");
94
+ return null;
95
+ }
96
+ if (siblingCount < 0) {
97
+ console.error("siblingCount cannot be less than 0");
98
+ return null;
99
+ }
100
+
101
+ return (
102
+ <nav
103
+ className={cl("navds-pagination", `navds-pagination--${size}`, className)}
104
+ >
105
+ {prevNextTexts && (
106
+ <button
107
+ className="navds-pagination__prev-next"
108
+ disabled={page === 1}
109
+ onClick={() => onPageChange(page - 1)}
110
+ >
111
+ <Back
112
+ className="navds-pagination__prev-next-icon"
113
+ role="presentation"
114
+ />
115
+ <BodyShort size={size} className="navds-pagination__prev-text">
116
+ Tilbake
117
+ </BodyShort>
118
+ </button>
119
+ )}
120
+ <ul className="navds-pagination__list">
121
+ {!prevNextTexts && (
122
+ <li>
123
+ <button
124
+ className="navds-pagination__prev-next"
125
+ disabled={page === 1}
126
+ onClick={() => onPageChange(page - 1)}
127
+ >
128
+ <Back
129
+ className="navds-pagination__prev-next-icon"
130
+ title="Tilbake"
131
+ />
132
+ </button>
133
+ </li>
134
+ )}
135
+ {getSteps({ page, count, siblingCount, boundaryCount }).map(
136
+ (step, i) => {
137
+ const n = Number(step);
138
+ return isNaN(n) ? (
139
+ <li className="navds-pagination__ellipsis" key={`${step}${i}`}>
140
+ <BodyShort size={size}>...</BodyShort>
141
+ </li>
142
+ ) : (
143
+ <li key={step}>
144
+ <BodyShort
145
+ size={size}
146
+ as="button"
147
+ className="navds-pagination__item"
148
+ onClick={() => onPageChange(n)}
149
+ aria-current={page === n ? true : undefined}
150
+ >
151
+ {n}
152
+ </BodyShort>
153
+ </li>
154
+ );
155
+ }
156
+ )}
157
+ {!prevNextTexts && (
158
+ <li>
159
+ <button
160
+ className="navds-pagination__prev-next"
161
+ disabled={page === count}
162
+ onClick={() => onPageChange(page + 1)}
163
+ >
164
+ <Next
165
+ className="navds-pagination__prev-next-icon"
166
+ title="Neste"
167
+ />
168
+ </button>
169
+ </li>
170
+ )}
171
+ </ul>
172
+ {prevNextTexts && (
173
+ <button
174
+ className="navds-pagination__prev-next"
175
+ disabled={page === count}
176
+ onClick={() => onPageChange(page + 1)}
177
+ >
178
+ <BodyShort size={size} className="navds-pagination__next-text">
179
+ Neste
180
+ </BodyShort>
181
+ <Next
182
+ className="navds-pagination__prev-next-icon"
183
+ role="presentation"
184
+ />
185
+ </button>
186
+ )}
187
+ </nav>
188
+ );
189
+ };
190
+
191
+ export default Pagination;
@@ -0,0 +1,2 @@
1
+ export { default as Pagination } from "./Pagination";
2
+ export * from "./Pagination";
@@ -0,0 +1,37 @@
1
+ import React, { useState } from "react";
2
+ import Pagination from "./Pagination";
3
+
4
+ export default {
5
+ title: "ds-react/pagination",
6
+ component: Pagination,
7
+ };
8
+
9
+ export const All = (props) => {
10
+ const [page, setPage] = useState(props.page);
11
+ return (
12
+ <div>
13
+ <h2>Pagination</h2>
14
+ <Pagination {...props} page={page} onPageChange={setPage} />
15
+
16
+ <h2>Small</h2>
17
+ <Pagination size="small" {...props} page={page} onPageChange={setPage} />
18
+
19
+ <h2>prevNextTexts</h2>
20
+ <Pagination prevNextTexts {...props} page={page} onPageChange={setPage} />
21
+ <h3>prevNextTexts small</h3>
22
+ <Pagination
23
+ prevNextTexts
24
+ size="small"
25
+ {...props}
26
+ page={page}
27
+ onPageChange={setPage}
28
+ />
29
+ </div>
30
+ );
31
+ };
32
+ All.args = {
33
+ page: 1,
34
+ count: 8,
35
+ siblingCount: 1,
36
+ boundaryCount: 1,
37
+ };
@@ -0,0 +1,120 @@
1
+ import faker from "faker";
2
+ import { getSteps } from "./Pagination";
3
+
4
+ describe("getSteps", () => {
5
+ it("lists all pages when count is <= 7", () => {
6
+ const count = faker.datatype.number({ min: 1, max: 7 });
7
+ expect(getSteps({ page: 1, count })).toEqual(
8
+ Array.from({ length: count }, (_, i) => i + 1)
9
+ );
10
+ });
11
+
12
+ it("has an end ellipsis when count >= 8", () => {
13
+ const count = faker.datatype.number({ min: 8 });
14
+ const page = faker.datatype.number({ min: 1, max: 4 });
15
+ expect(
16
+ getSteps({
17
+ page,
18
+ count,
19
+ })
20
+ ).toEqual([1, 2, 3, 4, 5, "ellipsis", count]);
21
+ });
22
+
23
+ it("has a start ellipsis when count - page >= 3", () => {
24
+ const count = faker.datatype.number({ min: 8 });
25
+ const page = faker.datatype.number({ min: count - 3, max: count });
26
+ expect(
27
+ getSteps({
28
+ page,
29
+ count,
30
+ })
31
+ ).toEqual([
32
+ 1,
33
+ "ellipsis",
34
+ count - 4,
35
+ count - 3,
36
+ count - 2,
37
+ count - 1,
38
+ count,
39
+ ]);
40
+ });
41
+
42
+ it("has start & end ellipsis when count is high", () => {
43
+ const count = faker.datatype.number({ min: 9 });
44
+ const page = faker.datatype.number({ min: 5, max: count - 4 });
45
+ expect(
46
+ getSteps({
47
+ page,
48
+ count,
49
+ })
50
+ ).toEqual([1, "ellipsis", page - 1, page, page + 1, "ellipsis", count]);
51
+ });
52
+
53
+ it("can have a reduced siblingCount", () => {
54
+ const count = faker.datatype.number({ min: 7 });
55
+ const page = faker.datatype.number({ min: 4, max: count - 3 });
56
+ expect(
57
+ getSteps({
58
+ page,
59
+ count,
60
+ siblingCount: 0,
61
+ })
62
+ ).toEqual([1, "ellipsis", page, "ellipsis", count]);
63
+ });
64
+
65
+ it("can have an increased siblingCount", () => {
66
+ const count = faker.datatype.number({ min: 11 });
67
+ const page = faker.datatype.number({ min: 6, max: count - 5 });
68
+ expect(
69
+ getSteps({
70
+ page,
71
+ count,
72
+ siblingCount: 2,
73
+ })
74
+ ).toEqual([
75
+ 1,
76
+ "ellipsis",
77
+ page - 2,
78
+ page - 1,
79
+ page,
80
+ page + 1,
81
+ page + 2,
82
+ "ellipsis",
83
+ count,
84
+ ]);
85
+ });
86
+
87
+ it("can have an reduced boundaryCount", () => {
88
+ const count = faker.datatype.number({ min: 7 });
89
+ const page = faker.datatype.number({ min: 4, max: count - 3 });
90
+ expect(
91
+ getSteps({
92
+ page,
93
+ count,
94
+ boundaryCount: 0,
95
+ })
96
+ ).toEqual(["ellipsis", page - 1, page, page + 1, "ellipsis"]);
97
+ });
98
+
99
+ it("can have an increased boundaryCount", () => {
100
+ const count = faker.datatype.number({ min: 11 });
101
+ const page = faker.datatype.number({ min: 6, max: count - 5 });
102
+ expect(
103
+ getSteps({
104
+ page,
105
+ count,
106
+ boundaryCount: 2,
107
+ })
108
+ ).toEqual([
109
+ 1,
110
+ 2,
111
+ "ellipsis",
112
+ page - 1,
113
+ page,
114
+ page + 1,
115
+ "ellipsis",
116
+ count - 1,
117
+ count,
118
+ ]);
119
+ });
120
+ });
@@ -10,19 +10,43 @@ export default {
10
10
  },
11
11
  } as Meta;
12
12
 
13
- const Items = (icon?: boolean) => (
13
+ const Items = (icon?: boolean, both?: boolean) => (
14
14
  <>
15
15
  <ToggleGroup.Item value="first">
16
- {icon ? <Hamburger /> : "First"}
16
+ {both ? (
17
+ <>
18
+ <Hamburger /> First
19
+ </>
20
+ ) : (
21
+ <>{icon ? <Hamburger /> : "First"}</>
22
+ )}
17
23
  </ToggleGroup.Item>
18
24
  <ToggleGroup.Item value="second">
19
- {icon ? <Star /> : "Second more txt"}
25
+ {both ? (
26
+ <>
27
+ <Star /> Second more txt
28
+ </>
29
+ ) : (
30
+ <>{icon ? <Star /> : "Second more txt"}</>
31
+ )}
20
32
  </ToggleGroup.Item>
21
33
  <ToggleGroup.Item value="third">
22
- {icon ? <Attachment /> : "Third"}
34
+ {both ? (
35
+ <>
36
+ <Attachment /> Thrid
37
+ </>
38
+ ) : (
39
+ <>{icon ? <Attachment /> : "Third"}</>
40
+ )}
23
41
  </ToggleGroup.Item>
24
42
  <ToggleGroup.Item value="fourth">
25
- {icon ? <System /> : "Fourth"}
43
+ {both ? (
44
+ <>
45
+ <System /> Fourth
46
+ </>
47
+ ) : (
48
+ <>{icon ? <System /> : "Fourth"}</>
49
+ )}
26
50
  </ToggleGroup.Item>
27
51
  </>
28
52
  );
@@ -41,6 +65,9 @@ export const All = () => {
41
65
  <ToggleGroup value={activeValue} onChange={setActiveValue}>
42
66
  {Items(true)}
43
67
  </ToggleGroup>
68
+ <ToggleGroup value={activeValue} onChange={setActiveValue}>
69
+ {Items(true, true)}
70
+ </ToggleGroup>
44
71
  </div>
45
72
  <h2>ToggleGroup Small</h2>
46
73
  <h3>{activeValue}</h3>
@@ -51,6 +78,9 @@ export const All = () => {
51
78
  <ToggleGroup size="small" value={activeValue} onChange={setActiveValue}>
52
79
  {Items(true)}
53
80
  </ToggleGroup>
81
+ <ToggleGroup size="small" value={activeValue} onChange={setActiveValue}>
82
+ {Items(true, true)}
83
+ </ToggleGroup>
54
84
  </div>
55
85
  <h2>ToggleGroup label</h2>
56
86
  <div style={{ display: "flex", flexDirection: "column", gap: "0.5rem" }}>
@@ -88,6 +88,10 @@ const ToggleGroup = forwardRef<HTMLDivElement, ToggleGroupProps>(
88
88
  [labelId]: !!label,
89
89
  });
90
90
 
91
+ if (!value && !defaultValue) {
92
+ console.error("ToggleGroup needs either a value or defaultValue");
93
+ }
94
+
91
95
  return (
92
96
  <ToggleGroupContext.Provider
93
97
  value={{
@@ -116,6 +120,7 @@ const ToggleGroup = forwardRef<HTMLDivElement, ToggleGroupProps>(
116
120
  `navds-toggle-group--${size}`
117
121
  )}
118
122
  {...(describeBy && { "aria-describedby": describeBy })}
123
+ role="toolbar"
119
124
  type="single"
120
125
  >
121
126
  {children}
@@ -1,7 +1,8 @@
1
1
  import React, { forwardRef, useContext } from "react";
2
2
  import cl from "classnames";
3
- import { Label, ToggleGroupContext } from "..";
3
+ import { Label } from "..";
4
4
  import * as RadixToggleGroup from "@radix-ui/react-toggle-group";
5
+ import { ToggleGroupContext } from "./ToggleGroup";
5
6
 
6
7
  export interface ToggleItemProps
7
8
  extends React.HTMLAttributes<HTMLButtonElement> {
@@ -1,2 +1,2 @@
1
1
  export { default as ToggleGroup } from "./ToggleGroup";
2
- export * from "./ToggleGroup";
2
+ export { ToggleGroupProps } from "./ToggleGroup";