@navikt/ds-react 7.23.2 → 7.24.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.
Files changed (55) hide show
  1. package/cjs/form/switch/Switch.js +23 -2
  2. package/cjs/form/switch/Switch.js.map +1 -1
  3. package/cjs/index.d.ts +1 -0
  4. package/cjs/index.js +3 -1
  5. package/cjs/index.js.map +1 -1
  6. package/cjs/link-card/LinkCard.d.ts +126 -0
  7. package/cjs/link-card/LinkCard.js +141 -0
  8. package/cjs/link-card/LinkCard.js.map +1 -0
  9. package/cjs/link-card/index.d.ts +2 -0
  10. package/cjs/link-card/index.js +13 -0
  11. package/cjs/link-card/index.js.map +1 -0
  12. package/cjs/link-panel/LinkPanel.d.ts +3 -11
  13. package/cjs/link-panel/LinkPanel.js +3 -11
  14. package/cjs/link-panel/LinkPanel.js.map +1 -1
  15. package/cjs/table/Table.d.ts +5 -0
  16. package/cjs/table/Table.js +2 -1
  17. package/cjs/table/Table.js.map +1 -1
  18. package/cjs/util/link-anchor/LinkAnchor.d.ts +26 -0
  19. package/cjs/util/link-anchor/LinkAnchor.js +110 -0
  20. package/cjs/util/link-anchor/LinkAnchor.js.map +1 -0
  21. package/cjs/util/link-anchor/index.d.ts +2 -0
  22. package/cjs/util/link-anchor/index.js +9 -0
  23. package/cjs/util/link-anchor/index.js.map +1 -0
  24. package/esm/form/switch/Switch.js +23 -2
  25. package/esm/form/switch/Switch.js.map +1 -1
  26. package/esm/index.d.ts +1 -0
  27. package/esm/index.js +1 -0
  28. package/esm/index.js.map +1 -1
  29. package/esm/link-card/LinkCard.d.ts +126 -0
  30. package/esm/link-card/LinkCard.js +105 -0
  31. package/esm/link-card/LinkCard.js.map +1 -0
  32. package/esm/link-card/index.d.ts +2 -0
  33. package/esm/link-card/index.js +3 -0
  34. package/esm/link-card/index.js.map +1 -0
  35. package/esm/link-panel/LinkPanel.d.ts +3 -11
  36. package/esm/link-panel/LinkPanel.js +3 -11
  37. package/esm/link-panel/LinkPanel.js.map +1 -1
  38. package/esm/table/Table.d.ts +5 -0
  39. package/esm/table/Table.js +2 -1
  40. package/esm/table/Table.js.map +1 -1
  41. package/esm/util/link-anchor/LinkAnchor.d.ts +26 -0
  42. package/esm/util/link-anchor/LinkAnchor.js +72 -0
  43. package/esm/util/link-anchor/LinkAnchor.js.map +1 -0
  44. package/esm/util/link-anchor/index.d.ts +2 -0
  45. package/esm/util/link-anchor/index.js +3 -0
  46. package/esm/util/link-anchor/index.js.map +1 -0
  47. package/package.json +13 -3
  48. package/src/form/switch/Switch.tsx +79 -26
  49. package/src/index.ts +10 -0
  50. package/src/link-card/LinkCard.tsx +317 -0
  51. package/src/link-card/index.tsx +20 -0
  52. package/src/link-panel/LinkPanel.tsx +3 -11
  53. package/src/table/Table.tsx +7 -0
  54. package/src/util/link-anchor/LinkAnchor.tsx +153 -0
  55. package/src/util/link-anchor/index.tsx +7 -0
@@ -0,0 +1,72 @@
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 React, { forwardRef, useRef, } from "react";
13
+ import { ArrowRightIcon } from "@navikt/aksel-icons";
14
+ import { Slot } from "../../slot/Slot.js";
15
+ import { useRenameCSS } from "../../theme/Theme.js";
16
+ import { composeEventHandlers } from "../composeEventHandlers.js";
17
+ import { createContext } from "../create-context.js";
18
+ import { useMergeRefs } from "../hooks/useMergeRefs.js";
19
+ const [LinkAnchorContextProvider, useLinkAnchorContext] = createContext({
20
+ name: "LinkAnchorOverlayContext",
21
+ });
22
+ const LinkAnchorOverlay = forwardRef((_a, forwardedRef) => {
23
+ var { children, asChild, className, onClick } = _a, restProps = __rest(_a, ["children", "asChild", "className", "onClick"]);
24
+ const { cn } = useRenameCSS();
25
+ const anchorRef = useRef(null);
26
+ const Component = asChild ? Slot : "div";
27
+ return (React.createElement(LinkAnchorContextProvider, { anchorRef: anchorRef },
28
+ React.createElement(Component, Object.assign({ ref: forwardedRef }, restProps, { className: cn("navds-link-anchor__overlay", className), onClick: composeEventHandlers(onClick, (e) => {
29
+ var _a;
30
+ if (e.target === anchorRef.current || isTextSelected()) {
31
+ return;
32
+ }
33
+ const event = new MouseEvent("click", {
34
+ bubbles: true,
35
+ cancelable: true,
36
+ view: window,
37
+ ctrlKey: e.ctrlKey,
38
+ shiftKey: e.shiftKey,
39
+ altKey: e.altKey,
40
+ metaKey: e.metaKey,
41
+ button: e.button,
42
+ screenX: e.screenX,
43
+ screenY: e.screenY,
44
+ clientX: e.clientX,
45
+ clientY: e.clientY,
46
+ });
47
+ (_a = anchorRef.current) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
48
+ }) }), children)));
49
+ });
50
+ const LinkAnchor = forwardRef((_a, forwardedRef) => {
51
+ var { children, asChild, className } = _a, restProps = __rest(_a, ["children", "asChild", "className"]);
52
+ const { cn } = useRenameCSS();
53
+ const context = useLinkAnchorContext(false);
54
+ const mergedRefs = useMergeRefs(forwardedRef, context === null || context === void 0 ? void 0 : context.anchorRef);
55
+ const Component = asChild ? Slot : "a";
56
+ return (React.createElement(Component, Object.assign({ ref: mergedRefs }, restProps, { className: cn("navds-link-anchor", className) }), children));
57
+ });
58
+ const LinkAnchorArrow = forwardRef((_a, forwardedRef) => {
59
+ var { className } = _a, restProps = __rest(_a, ["className"]);
60
+ const { cn } = useRenameCSS();
61
+ return (React.createElement(ArrowRightIcon, Object.assign({ ref: forwardedRef, "aria-hidden": true, className: cn("navds-link-anchor__arrow", className) }, restProps)));
62
+ });
63
+ /* -------------------------- LinkAnchor Utilities -------------------------- */
64
+ function isTextSelected() {
65
+ var _a;
66
+ if (typeof window === "undefined") {
67
+ return false;
68
+ }
69
+ return !!((_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.toString());
70
+ }
71
+ export { LinkAnchor, LinkAnchorArrow, LinkAnchorOverlay };
72
+ //# sourceMappingURL=LinkAnchor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkAnchor.js","sourceRoot":"","sources":["../../../src/util/link-anchor/LinkAnchor.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { LinkAnchor, LinkAnchorOverlay, LinkAnchorArrow } from "./LinkAnchor.js";
2
+ export type { LinkAnchorProps, LinkAnchorOverlayProps, LinkAnchorArrowProps, } from "./LinkAnchor.js";
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ export { LinkAnchor, LinkAnchorOverlay, LinkAnchorArrow } from "./LinkAnchor.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/util/link-anchor/index.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navikt/ds-react",
3
- "version": "7.23.2",
3
+ "version": "7.24.0",
4
4
  "description": "React components from the Norwegian Labour and Welfare Administration.",
5
5
  "author": "Aksel, a team part of the Norwegian Labour and Welfare Administration.",
6
6
  "license": "MIT",
@@ -264,6 +264,16 @@
264
264
  "default": "./cjs/link/index.js"
265
265
  }
266
266
  },
267
+ "./LinkCard": {
268
+ "import": {
269
+ "types": "./esm/link-card/index.d.ts",
270
+ "default": "./esm/link-card/index.js"
271
+ },
272
+ "require": {
273
+ "types": "./cjs/link-card/index.d.ts",
274
+ "default": "./cjs/link-card/index.js"
275
+ }
276
+ },
267
277
  "./LinkPanel": {
268
278
  "import": {
269
279
  "types": "./esm/link-panel/index.d.ts",
@@ -630,8 +640,8 @@
630
640
  "dependencies": {
631
641
  "@floating-ui/react": "0.27.8",
632
642
  "@floating-ui/react-dom": "^2.0.9",
633
- "@navikt/aksel-icons": "^7.23.2",
634
- "@navikt/ds-tokens": "^7.23.2",
643
+ "@navikt/aksel-icons": "^7.24.0",
644
+ "@navikt/ds-tokens": "^7.24.0",
635
645
  "clsx": "^2.1.0",
636
646
  "date-fns": "^4.0.0",
637
647
  "react-day-picker": "9.7.0"
@@ -117,32 +117,7 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
117
117
  />
118
118
  <span className={cn("navds-switch__track")}>
119
119
  <span className={cn("navds-switch__thumb")}>
120
- {loading ? (
121
- <Loader
122
- size="xsmall"
123
- aria-live="polite"
124
- variant={checked ? "interaction" : "inverted"}
125
- />
126
- ) : (
127
- <svg
128
- width="12"
129
- height="10"
130
- viewBox="0 0 12 10"
131
- fill="none"
132
- xmlns="http://www.w3.org/2000/svg"
133
- focusable={false}
134
- role="img"
135
- aria-hidden
136
- className={cn("navds-switch__checkmark")}
137
- >
138
- <path
139
- fillRule="evenodd"
140
- clipRule="evenodd"
141
- d="M11.2674 0.647802C11.8762 1.20971 11.9141 2.1587 11.3522 2.76743L5.35221 9.26743C5.07531 9.56739 4.68813 9.74155 4.27998 9.74971C3.87184 9.75787 3.478 9.59933 3.18934 9.31067L0.68934 6.81067C0.103553 6.22488 0.103553 5.27513 0.68934 4.68935C1.27513 4.10356 2.22487 4.10356 2.81066 4.68935L4.20673 6.08541L9.14779 0.732587C9.7097 0.123856 10.6587 0.0858967 11.2674 0.647802Z"
142
- fill="currentColor"
143
- />
144
- </svg>
145
- )}
120
+ <SwitchIcon size={size} checked={checked} loading={loading} />
146
121
  </span>
147
122
  </span>
148
123
  <label
@@ -181,4 +156,82 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
181
156
  },
182
157
  );
183
158
 
159
+ const SwitchIcon = ({
160
+ size,
161
+ checked,
162
+ loading,
163
+ }: {
164
+ size: SwitchProps["size"];
165
+ checked: SwitchProps["checked"];
166
+ loading: SwitchProps["loading"];
167
+ }) => {
168
+ if (loading) {
169
+ let baseSize = 16;
170
+
171
+ if (size === "small") {
172
+ baseSize = 12;
173
+ }
174
+
175
+ if (checked) {
176
+ baseSize += 2;
177
+ }
178
+
179
+ return (
180
+ <Loader
181
+ size="small"
182
+ aria-live="polite"
183
+ variant={checked ? "interaction" : "inverted"}
184
+ width={`${baseSize / 16}rem`}
185
+ height={`${baseSize / 16}rem`}
186
+ />
187
+ );
188
+ }
189
+
190
+ if (!checked) {
191
+ return null;
192
+ }
193
+
194
+ if (size === "small") {
195
+ return (
196
+ <svg
197
+ width="11"
198
+ height="8"
199
+ viewBox="0 0 11 8"
200
+ fill="none"
201
+ xmlns="http://www.w3.org/2000/svg"
202
+ focusable={false}
203
+ role="img"
204
+ aria-hidden
205
+ >
206
+ <path
207
+ fillRule="evenodd"
208
+ clipRule="evenodd"
209
+ d="M9.62013 0.530226C10.1194 0.952686 10.1817 1.6999 9.7592 2.19917L5.4171 7.33075C5.20318 7.58356 4.89318 7.73525 4.5623 7.74901C4.23142 7.76277 3.90989 7.63735 3.67572 7.40318L1.3073 5.03476C0.844833 4.5723 0.844833 3.8225 1.3073 3.36003C1.76976 2.89757 2.51956 2.89757 2.98202 3.36003L4.4404 4.81841L7.95118 0.669304C8.37364 0.170033 9.12085 0.107765 9.62013 0.530226Z"
210
+ fill="currentColor"
211
+ />
212
+ </svg>
213
+ );
214
+ }
215
+
216
+ return (
217
+ <svg
218
+ width="12"
219
+ height="10"
220
+ viewBox="0 0 12 10"
221
+ fill="none"
222
+ xmlns="http://www.w3.org/2000/svg"
223
+ focusable={false}
224
+ role="img"
225
+ aria-hidden
226
+ >
227
+ <path
228
+ fillRule="evenodd"
229
+ clipRule="evenodd"
230
+ d="M11.2674 0.647802C11.8762 1.20971 11.9141 2.1587 11.3522 2.76743L5.35221 9.26743C5.07531 9.56739 4.68813 9.74155 4.27998 9.74971C3.87184 9.75787 3.478 9.59933 3.18934 9.31067L0.68934 6.81067C0.103553 6.22488 0.103553 5.27513 0.68934 4.68935C1.27513 4.10356 2.22487 4.10356 2.81066 4.68935L4.20673 6.08541L9.14779 0.732587C9.7097 0.123856 10.6587 0.0858967 11.2674 0.647802Z"
231
+ fill="currentColor"
232
+ />
233
+ </svg>
234
+ );
235
+ };
236
+
184
237
  export default Switch;
package/src/index.ts CHANGED
@@ -150,6 +150,16 @@ export { Select, type SelectProps } from "./form/select";
150
150
  export { Switch, type SwitchProps } from "./form/switch";
151
151
  export { Textarea, type TextareaProps } from "./form/textarea";
152
152
  export { TextField, type TextFieldProps } from "./form/textfield";
153
+ export {
154
+ LinkCard,
155
+ type LinkCardProps,
156
+ type LinkCardTitleProps,
157
+ type LinkCardDescriptionProps,
158
+ type LinkCardFooterProps,
159
+ type LinkCardAnchorProps,
160
+ type LinkCardIconProps,
161
+ type LinkCardImageProps,
162
+ } from "./link-card";
153
163
 
154
164
  /**
155
165
  * Theming
@@ -0,0 +1,317 @@
1
+ import React, { HTMLAttributes, forwardRef } from "react";
2
+ import { useRenameCSS } from "../theme/Theme";
3
+ import { BodyLong, Heading } from "../typography";
4
+ import { createContext } from "../util/create-context";
5
+ import {
6
+ LinkAnchor,
7
+ LinkAnchorArrow,
8
+ LinkAnchorOverlay,
9
+ LinkAnchorProps,
10
+ } from "../util/link-anchor";
11
+
12
+ /* ------------------------------ LinkCard Root ----------------------------- */
13
+ interface LinkCardProps extends HTMLAttributes<HTMLDivElement> {
14
+ /**
15
+ * @default true
16
+ */
17
+ arrow?: boolean;
18
+ /**
19
+ * Changes padding and typo sizes.
20
+ * @default "medium"
21
+ */
22
+ size?: "small" | "medium";
23
+ }
24
+
25
+ type LinkCardContextProps = {
26
+ size: LinkCardProps["size"];
27
+ arrow: LinkCardProps["arrow"];
28
+ };
29
+
30
+ const [LinkCardContextProvider, useLinkCardContext] =
31
+ createContext<LinkCardContextProps>({
32
+ name: "LinkCardContextProvider",
33
+ });
34
+
35
+ interface LinkCardComponent
36
+ extends React.ForwardRefExoticComponent<
37
+ LinkCardProps & React.RefAttributes<HTMLDivElement>
38
+ > {
39
+ /**
40
+ * @see 🏷️ {@link LinkCardTitleProps}
41
+ */
42
+ Title: typeof LinkCardTitle;
43
+ /**
44
+ * @see 🏷️ {@link LinkCardAnchorProps}
45
+ */
46
+ Anchor: typeof LinkCardAnchor;
47
+ /**
48
+ * @see 🏷️ {@link LinkCardDescriptionProps}
49
+ */
50
+ Description: typeof LinkCardDescription;
51
+ /**
52
+ * @see 🏷️ {@link LinkCardFooterProps}
53
+ */
54
+ Footer: typeof LinkCardFooter;
55
+ /**
56
+ * @see 🏷️ {@link LinkCardIconProps}
57
+ */
58
+ Icon: typeof LinkCardIcon;
59
+ /**
60
+ * @see 🏷️ {@link LinkCardImageProps}
61
+ */
62
+ Image: typeof LinkCardImage;
63
+ }
64
+
65
+ /**
66
+ * Accessible clickable card as a link.
67
+ *
68
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/core/linkcard)
69
+ * @see 🏷️ {@link LinkCardProps}
70
+ *
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * <LinkCard>
75
+ * <LinkCard.Icon>
76
+ * <IconOrPictogram />
77
+ * </LinkCard.Icon>
78
+ * <LinkCard.Title>
79
+ * <LinkCard.Anchor href="/href">
80
+ * LinkCard title
81
+ * </LinkCard.Anchor>
82
+ * </LinkCard.Title>
83
+ * <LinkCard.Description>
84
+ * This is a description of the link card.
85
+ * </LinkCard.Description>
86
+ * <LinkCard.Footer>Footer content</LinkCard.Footer>
87
+ * </LinkCard>
88
+ * ```
89
+ */
90
+ export const LinkCard = forwardRef<HTMLDivElement, LinkCardProps>(
91
+ (
92
+ {
93
+ children,
94
+ className,
95
+ arrow = true,
96
+ size = "medium",
97
+ ...restProps
98
+ }: LinkCardProps,
99
+ forwardedRef,
100
+ ) => {
101
+ const { cn } = useRenameCSS();
102
+
103
+ return (
104
+ <LinkCardContextProvider size={size} arrow={arrow}>
105
+ <LinkAnchorOverlay asChild>
106
+ <BodyLong
107
+ as="div"
108
+ size={size}
109
+ ref={forwardedRef}
110
+ data-color="neutral"
111
+ className={cn(
112
+ "navds-link-card",
113
+ className,
114
+ `navds-link-card--${size}`,
115
+ )}
116
+ {...restProps}
117
+ >
118
+ {children}
119
+ </BodyLong>
120
+ </LinkAnchorOverlay>
121
+ </LinkCardContextProvider>
122
+ );
123
+ },
124
+ ) as LinkCardComponent;
125
+
126
+ /* ---------------------------- LinkCard Title ---------------------------- */
127
+ type LinkCardTitleProps = HTMLAttributes<HTMLHeadingElement> & {
128
+ children: React.ReactNode;
129
+ /**
130
+ * Heading tag. Use "span" if you want a non header defining card
131
+ * (eg. you have a lot of them all at once, such as in a grid)
132
+ * @default "span"
133
+ */
134
+ as?: "span" | "h2" | "h3" | "h4" | "h5" | "h6";
135
+ };
136
+
137
+ /**
138
+ * @see 🏷️ {@link LinkCardTitleProps}
139
+ */
140
+ export const LinkCardTitle = forwardRef<HTMLHeadingElement, LinkCardTitleProps>(
141
+ (
142
+ { children, as = "span", className, ...restProps }: LinkCardTitleProps,
143
+ forwardedRef,
144
+ ) => {
145
+ const { cn } = useRenameCSS();
146
+
147
+ const context = useLinkCardContext();
148
+
149
+ return (
150
+ <Heading
151
+ ref={forwardedRef}
152
+ as={as}
153
+ size={context.size === "medium" ? "small" : "xsmall"}
154
+ className={cn("navds-link-card__title", className)}
155
+ {...restProps}
156
+ >
157
+ {children}
158
+ {context.arrow && (
159
+ <LinkAnchorArrow
160
+ fontSize={context.size === "medium" ? "1.75rem" : "1.5rem"}
161
+ />
162
+ )}
163
+ </Heading>
164
+ );
165
+ },
166
+ );
167
+
168
+ /* ---------------------------- LinkCard Anchor ---------------------------- */
169
+ type LinkCardAnchorProps = LinkAnchorProps;
170
+
171
+ /**
172
+ * @see 🏷️ {@link LinkCardAnchorProps}
173
+ */
174
+ export const LinkCardAnchor = LinkAnchor;
175
+
176
+ /* ---------------------------- LinkCard Description ---------------------------- */
177
+ interface LinkCardDescriptionProps extends HTMLAttributes<HTMLDivElement> {
178
+ children: React.ReactNode;
179
+ }
180
+
181
+ /**
182
+ * @see 🏷️ {@link LinkCardDescriptionProps}
183
+ */
184
+ export const LinkCardDescription = forwardRef<
185
+ HTMLDivElement,
186
+ LinkCardDescriptionProps
187
+ >(
188
+ (
189
+ { children, className, ...restProps }: LinkCardDescriptionProps,
190
+ forwardedRef,
191
+ ) => {
192
+ const { cn } = useRenameCSS();
193
+
194
+ return (
195
+ <div
196
+ ref={forwardedRef}
197
+ className={cn("navds-link-card__description", className)}
198
+ {...restProps}
199
+ >
200
+ {children}
201
+ </div>
202
+ );
203
+ },
204
+ );
205
+
206
+ /* ---------------------------- LinkCard Footer ---------------------------- */
207
+ interface LinkCardFooterProps extends HTMLAttributes<HTMLDivElement> {
208
+ children: React.ReactNode;
209
+ }
210
+
211
+ /**
212
+ * @see 🏷️ {@link LinkCardFooterProps}
213
+ */
214
+ export const LinkCardFooter = forwardRef<HTMLDivElement, LinkCardFooterProps>(
215
+ (
216
+ { children, className, ...restProps }: LinkCardFooterProps,
217
+ forwardedRef,
218
+ ) => {
219
+ const { cn } = useRenameCSS();
220
+
221
+ return (
222
+ <div
223
+ ref={forwardedRef}
224
+ className={cn("navds-link-card__footer", className)}
225
+ {...restProps}
226
+ >
227
+ {children}
228
+ </div>
229
+ );
230
+ },
231
+ );
232
+
233
+ /* ---------------------------- LinkCard Icon ---------------------------- */
234
+ interface LinkCardIconProps extends HTMLAttributes<HTMLDivElement> {
235
+ children: React.ReactNode;
236
+ }
237
+
238
+ /**
239
+ * @see 🏷️ {@link LinkCardIconProps}
240
+ */
241
+ export const LinkCardIcon = forwardRef<HTMLDivElement, LinkCardIconProps>(
242
+ ({ children, className, ...restProps }: LinkCardIconProps, forwardedRef) => {
243
+ const { cn } = useRenameCSS();
244
+
245
+ return (
246
+ <div
247
+ ref={forwardedRef}
248
+ aria-hidden
249
+ className={cn("navds-link-card__icon", className)}
250
+ {...restProps}
251
+ >
252
+ {children}
253
+ </div>
254
+ );
255
+ },
256
+ );
257
+
258
+ /* ---------------------------- LinkCard Image ---------------------------- */
259
+ type ImageAspectRatio = "1/1" | "16/9" | "16/10" | "4/3" | (string & {});
260
+
261
+ interface LinkCardImageProps extends HTMLAttributes<HTMLDivElement> {
262
+ children: React.ReactNode;
263
+ /**
264
+ * The aspect-ratio CSS property allows you to define the desired width-to-height ratio of an element's box.
265
+ * This means that even if the parent container or viewport size changes, the browser will adjust the element's dimensions to maintain the specified width-to-height ratio.
266
+ */
267
+ aspectRatio?: ImageAspectRatio;
268
+ }
269
+
270
+ /**
271
+ * @see 🏷️ {@link LinkCardImageProps}
272
+ */
273
+ export const LinkCardImage = forwardRef<HTMLDivElement, LinkCardImageProps>(
274
+ (
275
+ {
276
+ children,
277
+ className,
278
+ aspectRatio,
279
+ style,
280
+ ...restProps
281
+ }: LinkCardImageProps,
282
+ forwardedRef,
283
+ ) => {
284
+ const { cn } = useRenameCSS();
285
+
286
+ return (
287
+ <div
288
+ ref={forwardedRef}
289
+ className={cn("navds-link-card__image-container", className)}
290
+ style={{
291
+ ...style,
292
+ aspectRatio,
293
+ }}
294
+ {...restProps}
295
+ >
296
+ {children}
297
+ </div>
298
+ );
299
+ },
300
+ );
301
+
302
+ LinkCard.Title = LinkCardTitle;
303
+ LinkCard.Anchor = LinkCardAnchor;
304
+ LinkCard.Description = LinkCardDescription;
305
+ LinkCard.Footer = LinkCardFooter;
306
+ LinkCard.Icon = LinkCardIcon;
307
+ LinkCard.Image = LinkCardImage;
308
+
309
+ export type {
310
+ LinkCardAnchorProps,
311
+ LinkCardDescriptionProps,
312
+ LinkCardFooterProps,
313
+ LinkCardIconProps,
314
+ LinkCardImageProps,
315
+ LinkCardProps,
316
+ LinkCardTitleProps,
317
+ };
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ export {
3
+ LinkCard,
4
+ LinkCardTitle,
5
+ LinkCardDescription,
6
+ LinkCardFooter,
7
+ LinkCardAnchor,
8
+ LinkCardIcon,
9
+ LinkCardImage,
10
+ } from "./LinkCard";
11
+
12
+ export type {
13
+ LinkCardProps,
14
+ LinkCardTitleProps,
15
+ LinkCardDescriptionProps,
16
+ LinkCardFooterProps,
17
+ LinkCardAnchorProps,
18
+ LinkCardIconProps,
19
+ LinkCardImageProps,
20
+ } from "./LinkCard";
@@ -38,21 +38,13 @@ interface LinkPanelComponentType
38
38
  }
39
39
 
40
40
  /**
41
- * A component that displays a link panel.
41
+ * @deprecated Use `LinkCard` instead. Migrations should be straightforward as the API is similar.
42
+ * @see [📝 LinkCard documentation](https://aksel.nav.no/komponenter/core/linkcard)
42
43
  *
43
- * @see [📝 Documentation](https://aksel.nav.no/komponenter/core/linkpanel)
44
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/legacy/linkpanel)
44
45
  * @see 🏷️ {@link LinkPanelProps}
45
46
  * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
46
47
  *
47
- * @example
48
- * ```jsx
49
- * <LinkPanel href="#" border>
50
- * <LinkPanel.Title>Arbeidssøker eller permittert</LinkPanel.Title>
51
- * <LinkPanel.Description>
52
- * Om jobb, registrering, CV, dagpenger og feriepenger av dagpenger
53
- * </LinkPanel.Description>
54
- * </LinkPanel>
55
- * ```
56
48
  */
57
49
  export const LinkPanelComponent: OverridableComponent<
58
50
  LinkPanelProps,
@@ -22,6 +22,11 @@ export interface TableProps
22
22
  * @default false
23
23
  */
24
24
  zebraStripes?: boolean;
25
+ /**
26
+ * Makes the header sticky
27
+ * @default false
28
+ */
29
+ stickyHeader?: boolean;
25
30
  /**
26
31
  * Sort state
27
32
  */
@@ -85,6 +90,7 @@ export const Table = forwardRef(
85
90
  size = "medium",
86
91
  onSortChange,
87
92
  sort,
93
+ stickyHeader = false,
88
94
  ...rest
89
95
  },
90
96
  ref,
@@ -97,6 +103,7 @@ export const Table = forwardRef(
97
103
  ref={ref}
98
104
  className={cn("navds-table", `navds-table--${size}`, className, {
99
105
  "navds-table--zebra-stripes": zebraStripes,
106
+ "navds-table--sticky-header": stickyHeader,
100
107
  })}
101
108
  />
102
109
  </TableContext.Provider>