@navikt/ds-react 7.29.1 → 7.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/cjs/accordion/AccordionContent.js +1 -1
  2. package/cjs/accordion/AccordionContent.js.map +1 -1
  3. package/cjs/accordion/AccordionHeader.js +1 -1
  4. package/cjs/accordion/AccordionHeader.js.map +1 -1
  5. package/cjs/chips/Removable.js +1 -1
  6. package/cjs/chips/Removable.js.map +1 -1
  7. package/cjs/chips/Toggle.js +1 -1
  8. package/cjs/chips/Toggle.js.map +1 -1
  9. package/cjs/copybutton/CopyButton.js +8 -4
  10. package/cjs/copybutton/CopyButton.js.map +1 -1
  11. package/cjs/date/datepicker/parts/DatePicker.WeekNumber.js +1 -1
  12. package/cjs/date/datepicker/parts/DatePicker.WeekNumber.js.map +1 -1
  13. package/cjs/expansion-card/ExpansionCardContent.js +2 -1
  14. package/cjs/expansion-card/ExpansionCardContent.js.map +1 -1
  15. package/cjs/form/checkbox/Checkbox.js +42 -0
  16. package/cjs/form/checkbox/Checkbox.js.map +1 -1
  17. package/cjs/form/checkbox/useCheckbox.d.ts +2 -2
  18. package/cjs/form/checkbox/useCheckbox.js +5 -5
  19. package/cjs/form/checkbox/useCheckbox.js.map +1 -1
  20. package/cjs/form/form-summary/FormSummary.d.ts +11 -17
  21. package/cjs/form/form-summary/FormSummary.js +5 -1
  22. package/cjs/form/form-summary/FormSummary.js.map +1 -1
  23. package/cjs/form/form-summary/FormSummaryEditLink.js +6 -1
  24. package/cjs/form/form-summary/FormSummaryEditLink.js.map +1 -1
  25. package/cjs/form/form-summary/FormSummaryFooter.d.ts +12 -0
  26. package/cjs/form/form-summary/FormSummaryFooter.js +56 -0
  27. package/cjs/form/form-summary/FormSummaryFooter.js.map +1 -0
  28. package/cjs/form/form-summary/FormSummaryHeader.d.ts +1 -1
  29. package/cjs/form/form-summary/FormSummaryHeader.js +3 -1
  30. package/cjs/form/form-summary/FormSummaryHeader.js.map +1 -1
  31. package/cjs/form/form-summary/index.d.ts +1 -0
  32. package/cjs/form/form-summary/index.js +3 -1
  33. package/cjs/form/form-summary/index.js.map +1 -1
  34. package/cjs/form/radio/Radio.js +18 -0
  35. package/cjs/form/radio/Radio.js.map +1 -1
  36. package/cjs/form/radio/useRadio.d.ts +2 -2
  37. package/cjs/form/radio/useRadio.js +5 -5
  38. package/cjs/form/radio/useRadio.js.map +1 -1
  39. package/cjs/form/search/Search.js +1 -1
  40. package/cjs/form/search/Search.js.map +1 -1
  41. package/cjs/guide-panel/GuidePanel.js +3 -3
  42. package/cjs/guide-panel/GuidePanel.js.map +1 -1
  43. package/cjs/help-text/HelpText.js +1 -1
  44. package/cjs/help-text/HelpText.js.map +1 -1
  45. package/cjs/internal-header/InternalHeader.js +1 -1
  46. package/cjs/internal-header/InternalHeader.js.map +1 -1
  47. package/cjs/layout/base/BasePrimitive.js +1 -1
  48. package/cjs/layout/base/BasePrimitive.js.map +1 -1
  49. package/cjs/layout/bleed/Bleed.js +1 -1
  50. package/cjs/layout/bleed/Bleed.js.map +1 -1
  51. package/cjs/layout/box/Box.js +4 -4
  52. package/cjs/layout/box/Box.js.map +1 -1
  53. package/cjs/layout/grid/HGrid.js +1 -1
  54. package/cjs/layout/grid/HGrid.js.map +1 -1
  55. package/cjs/layout/page/Page.js +3 -1
  56. package/cjs/layout/page/Page.js.map +1 -1
  57. package/cjs/layout/stack/Stack.js +1 -1
  58. package/cjs/layout/stack/Stack.js.map +1 -1
  59. package/cjs/link/Link.js +1 -1
  60. package/cjs/link/Link.js.map +1 -1
  61. package/cjs/list/List.js +1 -1
  62. package/cjs/list/List.js.map +1 -1
  63. package/cjs/overlays/action-menu/ActionMenu.js +1 -1
  64. package/cjs/overlays/action-menu/ActionMenu.js.map +1 -1
  65. package/cjs/pagination/PaginationItem.js +1 -1
  66. package/cjs/pagination/PaginationItem.js.map +1 -1
  67. package/cjs/popover/Popover.js +2 -2
  68. package/cjs/popover/Popover.js.map +1 -1
  69. package/cjs/portal/Portal.js +1 -1
  70. package/cjs/portal/Portal.js.map +1 -1
  71. package/cjs/theme/Theme.d.ts +6 -1
  72. package/cjs/theme/Theme.js +10 -2
  73. package/cjs/theme/Theme.js.map +1 -1
  74. package/cjs/timeline/Pin.js +1 -1
  75. package/cjs/timeline/Pin.js.map +1 -1
  76. package/cjs/timeline/period/ClickablePeriod.js +1 -1
  77. package/cjs/timeline/period/ClickablePeriod.js.map +1 -1
  78. package/cjs/timeline/period/index.d.ts +1 -1
  79. package/cjs/timeline/period/index.js.map +1 -1
  80. package/cjs/timeline/utils/timeline.d.ts +7 -6
  81. package/cjs/timeline/utils/timeline.js +39 -62
  82. package/cjs/timeline/utils/timeline.js.map +1 -1
  83. package/cjs/timeline/utils/types.external.d.ts +2 -3
  84. package/cjs/timeline/utils/types.internal.d.ts +1 -1
  85. package/cjs/toggle-group/ToggleGroup.js +1 -1
  86. package/cjs/toggle-group/ToggleGroup.js.map +1 -1
  87. package/cjs/util/composition-warning/CompositionWarning.d.ts +37 -0
  88. package/cjs/util/composition-warning/CompositionWarning.js +71 -0
  89. package/cjs/util/composition-warning/CompositionWarning.js.map +1 -0
  90. package/cjs/util/composition-warning/index.d.ts +1 -0
  91. package/cjs/util/composition-warning/index.js +38 -0
  92. package/cjs/util/composition-warning/index.js.map +1 -0
  93. package/cjs/util/getChildRef.d.ts +1 -0
  94. package/cjs/util/getChildRef.js +8 -0
  95. package/cjs/util/getChildRef.js.map +1 -0
  96. package/cjs/util/renderStoriesForChromatic.d.ts +2 -10
  97. package/cjs/util/renderStoriesForChromatic.js +2 -2
  98. package/cjs/util/renderStoriesForChromatic.js.map +1 -1
  99. package/esm/accordion/AccordionContent.js +1 -1
  100. package/esm/accordion/AccordionContent.js.map +1 -1
  101. package/esm/accordion/AccordionHeader.js +1 -1
  102. package/esm/accordion/AccordionHeader.js.map +1 -1
  103. package/esm/chips/Removable.js +1 -1
  104. package/esm/chips/Removable.js.map +1 -1
  105. package/esm/chips/Toggle.js +1 -1
  106. package/esm/chips/Toggle.js.map +1 -1
  107. package/esm/copybutton/CopyButton.js +8 -4
  108. package/esm/copybutton/CopyButton.js.map +1 -1
  109. package/esm/date/datepicker/parts/DatePicker.WeekNumber.js +1 -1
  110. package/esm/date/datepicker/parts/DatePicker.WeekNumber.js.map +1 -1
  111. package/esm/expansion-card/ExpansionCardContent.js +3 -2
  112. package/esm/expansion-card/ExpansionCardContent.js.map +1 -1
  113. package/esm/form/checkbox/Checkbox.js +44 -2
  114. package/esm/form/checkbox/Checkbox.js.map +1 -1
  115. package/esm/form/checkbox/useCheckbox.d.ts +2 -2
  116. package/esm/form/checkbox/useCheckbox.js +5 -5
  117. package/esm/form/checkbox/useCheckbox.js.map +1 -1
  118. package/esm/form/form-summary/FormSummary.d.ts +11 -17
  119. package/esm/form/form-summary/FormSummary.js +5 -1
  120. package/esm/form/form-summary/FormSummary.js.map +1 -1
  121. package/esm/form/form-summary/FormSummaryEditLink.js +6 -1
  122. package/esm/form/form-summary/FormSummaryEditLink.js.map +1 -1
  123. package/esm/form/form-summary/FormSummaryFooter.d.ts +12 -0
  124. package/esm/form/form-summary/FormSummaryFooter.js +20 -0
  125. package/esm/form/form-summary/FormSummaryFooter.js.map +1 -0
  126. package/esm/form/form-summary/FormSummaryHeader.d.ts +1 -1
  127. package/esm/form/form-summary/FormSummaryHeader.js +3 -1
  128. package/esm/form/form-summary/FormSummaryHeader.js.map +1 -1
  129. package/esm/form/form-summary/index.d.ts +1 -0
  130. package/esm/form/form-summary/index.js +1 -0
  131. package/esm/form/form-summary/index.js.map +1 -1
  132. package/esm/form/radio/Radio.js +17 -2
  133. package/esm/form/radio/Radio.js.map +1 -1
  134. package/esm/form/radio/useRadio.d.ts +2 -2
  135. package/esm/form/radio/useRadio.js +5 -5
  136. package/esm/form/radio/useRadio.js.map +1 -1
  137. package/esm/form/search/Search.js +1 -1
  138. package/esm/form/search/Search.js.map +1 -1
  139. package/esm/guide-panel/GuidePanel.js +3 -3
  140. package/esm/guide-panel/GuidePanel.js.map +1 -1
  141. package/esm/help-text/HelpText.js +1 -1
  142. package/esm/help-text/HelpText.js.map +1 -1
  143. package/esm/internal-header/InternalHeader.js +1 -1
  144. package/esm/internal-header/InternalHeader.js.map +1 -1
  145. package/esm/layout/base/BasePrimitive.js +1 -1
  146. package/esm/layout/base/BasePrimitive.js.map +1 -1
  147. package/esm/layout/bleed/Bleed.js +1 -1
  148. package/esm/layout/bleed/Bleed.js.map +1 -1
  149. package/esm/layout/box/Box.js +4 -4
  150. package/esm/layout/box/Box.js.map +1 -1
  151. package/esm/layout/grid/HGrid.js +1 -1
  152. package/esm/layout/grid/HGrid.js.map +1 -1
  153. package/esm/layout/page/Page.js +3 -1
  154. package/esm/layout/page/Page.js.map +1 -1
  155. package/esm/layout/stack/Stack.js +1 -1
  156. package/esm/layout/stack/Stack.js.map +1 -1
  157. package/esm/link/Link.js +1 -1
  158. package/esm/link/Link.js.map +1 -1
  159. package/esm/list/List.js +1 -1
  160. package/esm/list/List.js.map +1 -1
  161. package/esm/overlays/action-menu/ActionMenu.js +1 -1
  162. package/esm/overlays/action-menu/ActionMenu.js.map +1 -1
  163. package/esm/pagination/PaginationItem.js +1 -1
  164. package/esm/pagination/PaginationItem.js.map +1 -1
  165. package/esm/popover/Popover.js +2 -2
  166. package/esm/popover/Popover.js.map +1 -1
  167. package/esm/portal/Portal.js +1 -1
  168. package/esm/portal/Portal.js.map +1 -1
  169. package/esm/theme/Theme.d.ts +6 -1
  170. package/esm/theme/Theme.js +10 -2
  171. package/esm/theme/Theme.js.map +1 -1
  172. package/esm/timeline/Pin.js +1 -1
  173. package/esm/timeline/Pin.js.map +1 -1
  174. package/esm/timeline/period/ClickablePeriod.js +1 -1
  175. package/esm/timeline/period/ClickablePeriod.js.map +1 -1
  176. package/esm/timeline/period/index.d.ts +1 -1
  177. package/esm/timeline/period/index.js.map +1 -1
  178. package/esm/timeline/utils/timeline.d.ts +7 -6
  179. package/esm/timeline/utils/timeline.js +39 -62
  180. package/esm/timeline/utils/timeline.js.map +1 -1
  181. package/esm/timeline/utils/types.external.d.ts +2 -3
  182. package/esm/timeline/utils/types.internal.d.ts +1 -1
  183. package/esm/toggle-group/ToggleGroup.js +1 -1
  184. package/esm/toggle-group/ToggleGroup.js.map +1 -1
  185. package/esm/util/composition-warning/CompositionWarning.d.ts +37 -0
  186. package/esm/util/composition-warning/CompositionWarning.js +34 -0
  187. package/esm/util/composition-warning/CompositionWarning.js.map +1 -0
  188. package/esm/util/composition-warning/index.d.ts +1 -0
  189. package/esm/util/composition-warning/index.js +2 -0
  190. package/esm/util/composition-warning/index.js.map +1 -0
  191. package/esm/util/getChildRef.d.ts +1 -0
  192. package/esm/util/getChildRef.js +4 -0
  193. package/esm/util/getChildRef.js.map +1 -0
  194. package/esm/util/renderStoriesForChromatic.d.ts +2 -10
  195. package/esm/util/renderStoriesForChromatic.js +2 -2
  196. package/esm/util/renderStoriesForChromatic.js.map +1 -1
  197. package/package.json +3 -3
  198. package/src/accordion/AccordionContent.tsx +1 -1
  199. package/src/accordion/AccordionHeader.tsx +1 -1
  200. package/src/chips/Removable.tsx +1 -1
  201. package/src/chips/Toggle.tsx +1 -1
  202. package/src/copybutton/CopyButton.tsx +8 -4
  203. package/src/date/datepicker/parts/DatePicker.WeekNumber.tsx +3 -1
  204. package/src/expansion-card/ExpansionCardContent.tsx +3 -1
  205. package/src/form/checkbox/Checkbox.tsx +91 -2
  206. package/src/form/checkbox/useCheckbox.ts +5 -5
  207. package/src/form/form-summary/FormSummary.tsx +12 -17
  208. package/src/form/form-summary/FormSummaryEditLink.tsx +16 -7
  209. package/src/form/form-summary/FormSummaryFooter.tsx +33 -0
  210. package/src/form/form-summary/FormSummaryHeader.tsx +12 -9
  211. package/src/form/form-summary/index.ts +4 -0
  212. package/src/form/radio/Radio.tsx +47 -2
  213. package/src/form/radio/useRadio.ts +5 -5
  214. package/src/form/search/Search.tsx +1 -1
  215. package/src/guide-panel/GuidePanel.tsx +3 -3
  216. package/src/help-text/HelpText.tsx +2 -2
  217. package/src/internal-header/InternalHeader.tsx +1 -1
  218. package/src/layout/base/BasePrimitive.tsx +1 -1
  219. package/src/layout/bleed/Bleed.tsx +1 -1
  220. package/src/layout/box/Box.tsx +5 -4
  221. package/src/layout/grid/HGrid.tsx +1 -1
  222. package/src/layout/page/Page.tsx +5 -1
  223. package/src/layout/stack/Stack.tsx +1 -1
  224. package/src/link/Link.tsx +1 -1
  225. package/src/list/List.tsx +1 -1
  226. package/src/overlays/action-menu/ActionMenu.tsx +1 -1
  227. package/src/pagination/PaginationItem.tsx +1 -1
  228. package/src/popover/Popover.tsx +2 -2
  229. package/src/portal/Portal.tsx +1 -1
  230. package/src/theme/Theme.tsx +14 -3
  231. package/src/timeline/Pin.tsx +1 -1
  232. package/src/timeline/period/ClickablePeriod.tsx +1 -1
  233. package/src/timeline/period/index.tsx +3 -1
  234. package/src/timeline/utils/timeline.ts +56 -67
  235. package/src/timeline/utils/types.external.ts +4 -3
  236. package/src/timeline/utils/types.internal.ts +3 -1
  237. package/src/toggle-group/ToggleGroup.tsx +1 -1
  238. package/src/util/composition-warning/CompositionWarning.tsx +67 -0
  239. package/src/util/composition-warning/index.ts +1 -0
  240. package/src/util/getChildRef.ts +6 -0
  241. package/src/util/renderStoriesForChromatic.tsx +12 -9
@@ -1,7 +1,8 @@
1
+ import cl from "clsx";
1
2
  import React, { forwardRef } from "react";
2
- import { useRenameCSS } from "../../theme/Theme";
3
+ import { useRenameCSS, useThemeInternal } from "../../theme/Theme";
3
4
  import { BodyShort } from "../../typography";
4
- import { omit } from "../../util";
5
+ import { omit, useId } from "../../util";
5
6
  import { ReadOnlyIconWithTitle } from "../ReadOnlyIcon";
6
7
  import { CheckboxProps } from "./types";
7
8
  import useCheckbox from "./useCheckbox";
@@ -10,6 +11,94 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
10
11
  (props, ref) => {
11
12
  const { cn } = useRenameCSS();
12
13
  const { inputProps, hasError, size, readOnly, nested } = useCheckbox(props);
14
+ const descriptionId = useId();
15
+ const themeContext = useThemeInternal(false);
16
+
17
+ if (themeContext?.isDarkside) {
18
+ return (
19
+ <div
20
+ className={cn(
21
+ props.className,
22
+ "navds-checkbox",
23
+ `navds-checkbox--${size}`,
24
+ {
25
+ "navds-checkbox--error": hasError,
26
+ "navds-checkbox--disabled": inputProps.disabled,
27
+ "navds-checkbox--readonly": readOnly,
28
+ },
29
+ )}
30
+ data-color={hasError ? "danger" : props["data-color"]}
31
+ >
32
+ <div className={cn("navds-checkbox__input-wrapper")}>
33
+ <input
34
+ {...omit(props, [
35
+ "children",
36
+ "size",
37
+ "error",
38
+ "description",
39
+ "hideLabel",
40
+ "indeterminate",
41
+ "errorId",
42
+ "readOnly",
43
+ ])}
44
+ {...omit(inputProps, ["aria-invalid", "aria-describedby"])}
45
+ aria-describedby={cl(inputProps["aria-describedby"], {
46
+ [descriptionId]: props.description,
47
+ })}
48
+ type="checkbox"
49
+ className={cn("navds-checkbox__input")}
50
+ ref={(el) => {
51
+ if (el) {
52
+ el.indeterminate = props.indeterminate ?? false;
53
+ }
54
+
55
+ if (typeof ref === "function") {
56
+ ref(el);
57
+ } else if (ref != null) {
58
+ ref.current = el;
59
+ }
60
+ }}
61
+ />
62
+ <svg
63
+ xmlns="http://www.w3.org/2000/svg"
64
+ viewBox="0 0 13 10"
65
+ fill="none"
66
+ focusable={false}
67
+ role="img"
68
+ aria-hidden
69
+ className={cn("navds-checkbox__icon")}
70
+ >
71
+ <path
72
+ d="M4.03524 6.41478L10.4752 0.404669C11.0792 -0.160351 12.029 -0.130672 12.5955 0.47478C13.162 1.08027 13.1296 2.03007 12.5245 2.59621L5.02111 9.59934C4.74099 9.85904 4.37559 10 4.00025 10C3.60651 10 3.22717 9.84621 2.93914 9.56111L0.439143 7.06111C-0.146381 6.47558 -0.146381 5.52542 0.439143 4.93989C1.02467 4.35437 1.97483 4.35437 2.56036 4.93989L4.03524 6.41478Z"
73
+ fill="currentColor"
74
+ />
75
+ </svg>
76
+ </div>
77
+ <BodyShort
78
+ as="label"
79
+ htmlFor={inputProps.id}
80
+ size={size}
81
+ className={cn("navds-checkbox__label", {
82
+ "navds-sr-only": props.hideLabel,
83
+ })}
84
+ >
85
+ {!nested && readOnly && <ReadOnlyIconWithTitle />}
86
+ {props.children}
87
+ </BodyShort>
88
+ {props.description && (
89
+ <BodyShort
90
+ id={descriptionId}
91
+ size={size}
92
+ className={cn(
93
+ "navds-form-field__subdescription navds-checkbox__description",
94
+ )}
95
+ >
96
+ {props.description}
97
+ </BodyShort>
98
+ )}
99
+ </div>
100
+ );
101
+ }
13
102
 
14
103
  return (
15
104
  <div
@@ -40,19 +40,19 @@ const useCheckbox = (props: CheckboxProps) => {
40
40
  defaultChecked: checkboxGroup?.defaultValue
41
41
  ? checkboxGroup.defaultValue.includes(props.value)
42
42
  : props.defaultChecked,
43
- onChange: (e) => {
43
+ onChange: (event: React.ChangeEvent<HTMLInputElement>) => {
44
44
  if (readOnly) {
45
45
  return;
46
46
  }
47
- props.onChange?.(e);
47
+ props.onChange?.(event);
48
48
  checkboxGroup?.toggleValue(props.value);
49
49
  },
50
- onClick: (e) => {
50
+ onClick: (event: React.MouseEvent<HTMLInputElement>) => {
51
51
  if (readOnly) {
52
- e.preventDefault();
52
+ event.preventDefault();
53
53
  return;
54
54
  }
55
- props?.onClick?.(e);
55
+ props?.onClick?.(event);
56
56
  },
57
57
  },
58
58
  };
@@ -3,6 +3,7 @@ import { useRenameCSS } from "../../theme/Theme";
3
3
  import FormSummaryAnswer from "./FormSummaryAnswer";
4
4
  import FormSummaryAnswers from "./FormSummaryAnswers";
5
5
  import FormSummaryEditLink from "./FormSummaryEditLink";
6
+ import FormSummaryFooter from "./FormSummaryFooter";
6
7
  import FormSummaryHeader from "./FormSummaryHeader";
7
8
  import FormSummaryHeading from "./FormSummaryHeading";
8
9
  import FormSummaryLabel from "./FormSummaryLabel";
@@ -13,7 +14,7 @@ interface FormSummaryComponent
13
14
  FormSummaryProps & React.RefAttributes<HTMLDivElement>
14
15
  > {
15
16
  /**
16
- * Must include `<FormSummary.Heading>` and optionally `<FormSummary.EditLink>`.
17
+ * Must include `<FormSummary.Heading>`.
17
18
  */
18
19
  Header: typeof FormSummaryHeader;
19
20
  /**
@@ -21,7 +22,7 @@ interface FormSummaryComponent
21
22
  */
22
23
  Heading: typeof FormSummaryHeading;
23
24
  /**
24
- * Link to edit the answers to use in the `FormSummary.Header` component. Should link to the relevant part of the form.
25
+ * Link to edit the answers to use in the `FormSummary.Footer` component. Should link to the relevant part of the form.
25
26
  */
26
27
  EditLink: typeof FormSummaryEditLink;
27
28
  /**
@@ -40,6 +41,10 @@ interface FormSummaryComponent
40
41
  * Corresponds to the answer in the form. To be used in the `FormSummary.Answer` component.
41
42
  */
42
43
  Value: typeof FormSummaryValue;
44
+ /**
45
+ * Footer component for the form summary, if applicable this is a good place for `<FormSummary.EditLink>`.
46
+ */
47
+ Footer: typeof FormSummaryFooter;
43
48
  }
44
49
 
45
50
  export interface FormSummaryProps extends HTMLAttributes<HTMLDivElement> {
@@ -48,20 +53,7 @@ export interface FormSummaryProps extends HTMLAttributes<HTMLDivElement> {
48
53
  *
49
54
  * - `<FormSummary.Header>`
50
55
  * - `<FormSummary.Answers>`
51
- *
52
- * @example
53
- * <FormSummary>
54
- * <FormSummary.Header>
55
- * <FormSummary.Heading level="2">HeadingTekst</FormSummary.Heading>
56
- * <FormSummary.EditLink href="#" />
57
- * </FormSummary.Header>
58
- * <FormSummary.Answers>
59
- * <FormSummary.Answer>
60
- * <FormSummary.Label>Navn</FormSummary.Label>
61
- * <FormSummary.Value>Ola Nordmann</FormSummary.Value>
62
- * </FormSummary.Answer>
63
- * </FormSummary.Answers>
64
- * </FormSummary>
56
+ * - `<FormSummary.Footer>` (optional)
65
57
  */
66
58
  children: React.ReactNode;
67
59
  }
@@ -75,7 +67,6 @@ export interface FormSummaryProps extends HTMLAttributes<HTMLDivElement> {
75
67
  * <FormSummary>
76
68
  * <FormSummary.Header>
77
69
  * <FormSummary.Heading level="2">HeadingTekst</FormSummary.Heading>
78
- * <FormSummary.EditLink href="#" />
79
70
  * </FormSummary.Header>
80
71
  * <FormSummary.Answers>
81
72
  * <FormSummary.Answer>
@@ -83,6 +74,9 @@ export interface FormSummaryProps extends HTMLAttributes<HTMLDivElement> {
83
74
  * <FormSummary.Value>Ola Nordmann</FormSummary.Value>
84
75
  * </FormSummary.Answer>
85
76
  * </FormSummary.Answers>
77
+ * <FormSummary.Footer>
78
+ * <FormSummary.EditLink href="#" />
79
+ * </FormSummary.Footer>
86
80
  * </FormSummary>
87
81
  */
88
82
  export const FormSummary = forwardRef<HTMLDivElement, FormSummaryProps>(
@@ -104,5 +98,6 @@ FormSummary.Answers = FormSummaryAnswers;
104
98
  FormSummary.Answer = FormSummaryAnswer;
105
99
  FormSummary.Label = FormSummaryLabel;
106
100
  FormSummary.Value = FormSummaryValue;
101
+ FormSummary.Footer = FormSummaryFooter;
107
102
 
108
103
  export default FormSummary;
@@ -1,6 +1,8 @@
1
1
  import React, { forwardRef } from "react";
2
+ import { PencilIcon } from "@navikt/aksel-icons";
2
3
  import { Link } from "../../link";
3
4
  import { useRenameCSS } from "../../theme/Theme";
5
+ import { CompositionWarning } from "../../util/composition-warning";
4
6
  import { useI18n } from "../../util/i18n/i18n.hooks";
5
7
  import { OverridableComponent } from "../../util/types";
6
8
 
@@ -24,17 +26,24 @@ export const FormSummaryEditLink: OverridableComponent<
24
26
  HTMLAnchorElement
25
27
  > = forwardRef(({ children, className, as = "a", ...rest }, ref) => {
26
28
  const { cn } = useRenameCSS();
29
+
27
30
  const translate = useI18n("FormSummary");
28
31
 
29
32
  return (
30
- <Link
31
- ref={ref}
32
- as={as}
33
- {...rest}
34
- className={cn("navds-form-summary__edit", className)}
33
+ <CompositionWarning.Forbidden
34
+ name="FormSummary.Header"
35
+ message="<FormSummary.EditLink> should not be placed in <FormSummary.Header> anymore. See https://aksel.nav.no/komponenter/core/formsummary"
35
36
  >
36
- {children || translate("editAnswer")}
37
- </Link>
37
+ <Link
38
+ ref={ref}
39
+ as={as}
40
+ {...rest}
41
+ className={cn("navds-form-summary__edit", className)}
42
+ >
43
+ <PencilIcon aria-hidden fontSize="1.5rem" />
44
+ {children || translate("editAnswer")}
45
+ </Link>
46
+ </CompositionWarning.Forbidden>
38
47
  );
39
48
  });
40
49
 
@@ -0,0 +1,33 @@
1
+ import React, { forwardRef } from "react";
2
+ import { useRenameCSS } from "../../theme/Theme";
3
+
4
+ /**
5
+ * Footer slot for actions in `FormSummary`.
6
+ */
7
+ export interface FormSummaryFooterProps
8
+ extends React.HTMLAttributes<HTMLDivElement> {
9
+ /**
10
+ * Should include `<FormSummary.EditLink>`.
11
+ */
12
+ children: React.ReactNode;
13
+ }
14
+
15
+ export const FormSummaryFooter = forwardRef<
16
+ HTMLDivElement,
17
+ FormSummaryFooterProps
18
+ >(({ children, className, ...rest }, ref) => {
19
+ const { cn } = useRenameCSS();
20
+
21
+ return (
22
+ <div
23
+ ref={ref}
24
+ data-color="info"
25
+ {...rest}
26
+ className={cn("navds-form-summary__footer", className)}
27
+ >
28
+ {children}
29
+ </div>
30
+ );
31
+ });
32
+
33
+ export default FormSummaryFooter;
@@ -1,10 +1,11 @@
1
1
  import React, { forwardRef } from "react";
2
2
  import { useRenameCSS } from "../../theme/Theme";
3
+ import { CompositionWarning } from "../../util/composition-warning";
3
4
 
4
5
  export interface FormSummaryHeaderProps
5
6
  extends React.HTMLAttributes<HTMLDivElement> {
6
7
  /**
7
- * Must include `<FormSummary.Heading>` and optionally `<FormSummary.EditLink>`.
8
+ * Must include `<FormSummary.Heading>`.
8
9
  */
9
10
  children: React.ReactNode;
10
11
  }
@@ -12,17 +13,19 @@ export interface FormSummaryHeaderProps
12
13
  export const FormSummaryHeader = forwardRef<
13
14
  HTMLDivElement,
14
15
  FormSummaryHeaderProps
15
- >(({ children, className, ...rest }, ref) => {
16
+ >(({ children, className, ...rest }: FormSummaryHeaderProps, ref) => {
16
17
  const { cn } = useRenameCSS();
17
18
 
18
19
  return (
19
- <header
20
- ref={ref}
21
- {...rest}
22
- className={cn("navds-form-summary__header", className)}
23
- >
24
- {children}
25
- </header>
20
+ <CompositionWarning.Root name="FormSummary.Header">
21
+ <div
22
+ ref={ref}
23
+ {...rest}
24
+ className={cn("navds-form-summary__header", className)}
25
+ >
26
+ {children}
27
+ </div>
28
+ </CompositionWarning.Root>
26
29
  );
27
30
  });
28
31
 
@@ -12,6 +12,10 @@ export {
12
12
  default as FormSummaryEditLink,
13
13
  type FormSummaryEditProps,
14
14
  } from "./FormSummaryEditLink";
15
+ export {
16
+ default as FormSummaryFooter,
17
+ type FormSummaryFooterProps,
18
+ } from "./FormSummaryFooter";
15
19
  export {
16
20
  default as FormSummaryHeader,
17
21
  type FormSummaryHeaderProps,
@@ -1,13 +1,58 @@
1
+ import cl from "clsx";
1
2
  import React, { forwardRef } from "react";
2
- import { useRenameCSS } from "../../theme/Theme";
3
+ import { useRenameCSS, useThemeInternal } from "../../theme/Theme";
3
4
  import { BodyShort } from "../../typography";
4
- import { omit } from "../../util";
5
+ import { omit, useId } from "../../util";
5
6
  import { RadioProps } from "./types";
6
7
  import { useRadio } from "./useRadio";
7
8
 
8
9
  export const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {
9
10
  const { cn } = useRenameCSS();
10
11
  const { inputProps, size, hasError, readOnly } = useRadio(props);
12
+ const descriptionId = useId();
13
+ const themeContext = useThemeInternal(false);
14
+
15
+ if (themeContext?.isDarkside) {
16
+ return (
17
+ <div
18
+ className={cn(props.className, "navds-radio", `navds-radio--${size}`, {
19
+ "navds-radio--error": hasError,
20
+ "navds-radio--disabled": inputProps.disabled,
21
+ "navds-radio--readonly": readOnly,
22
+ })}
23
+ data-color={hasError ? "danger" : props["data-color"]}
24
+ >
25
+ <input
26
+ {...omit(props, ["children", "size", "description", "readOnly"])}
27
+ {...omit(inputProps, ["aria-invalid", "aria-describedby"])}
28
+ aria-describedby={cl(inputProps["aria-describedby"], {
29
+ [descriptionId]: props.description,
30
+ })}
31
+ className={cn("navds-radio__input")}
32
+ ref={ref}
33
+ />
34
+ <BodyShort
35
+ as="label"
36
+ htmlFor={inputProps.id}
37
+ className={cn("navds-radio__label")}
38
+ size={size}
39
+ >
40
+ {props.children}
41
+ </BodyShort>
42
+ {props.description && (
43
+ <BodyShort
44
+ id={descriptionId}
45
+ size={size}
46
+ className={cn(
47
+ "navds-form-field__subdescription navds-radio__description",
48
+ )}
49
+ >
50
+ {props.description}
51
+ </BodyShort>
52
+ )}
53
+ </div>
54
+ );
55
+ }
11
56
 
12
57
  return (
13
58
  <div
@@ -37,19 +37,19 @@ export const useRadio = (props: RadioProps) => {
37
37
  radioGroup?.value === undefined
38
38
  ? undefined
39
39
  : radioGroup?.value === props.value,
40
- onChange: (e) => {
40
+ onChange: (event: React.ChangeEvent<HTMLInputElement>) => {
41
41
  if (readOnly) {
42
42
  return;
43
43
  }
44
- props.onChange?.(e);
44
+ props.onChange?.(event);
45
45
  radioGroup?.onChange?.(props.value);
46
46
  },
47
- onClick: (e) => {
47
+ onClick: (event: React.MouseEvent<HTMLInputElement>) => {
48
48
  if (readOnly) {
49
- e.preventDefault();
49
+ event.preventDefault();
50
50
  return;
51
51
  }
52
- props?.onClick?.(e);
52
+ props?.onClick?.(event);
53
53
  },
54
54
  required: radioGroup?.required,
55
55
  type: "radio",
@@ -271,7 +271,7 @@ function ClearButton({
271
271
  const themeContext = useThemeInternal(false);
272
272
  const translate = useI18n("Search");
273
273
 
274
- return themeContext ? (
274
+ return themeContext?.isDarkside ? (
275
275
  <Button
276
276
  className={cn("navds-search__button-clear")}
277
277
  variant="tertiary"
@@ -64,14 +64,14 @@ export const GuidePanel = forwardRef<HTMLDivElement, GuidePanelProps>(
64
64
  >
65
65
  <div className={cn("navds-guide")}>
66
66
  {illustration ??
67
- (themeContext ? (
67
+ (themeContext?.isDarkside ? (
68
68
  <DarksideGudiepanelIllustration />
69
69
  ) : (
70
70
  <DefaultIllustration />
71
71
  ))}
72
72
  </div>
73
73
  <div className={cn("navds-guide-panel__content")}>
74
- {themeContext && (
74
+ {themeContext?.isDarkside && (
75
75
  <svg
76
76
  viewBox="0 0 33 22"
77
77
  width="33"
@@ -96,7 +96,7 @@ export const GuidePanel = forwardRef<HTMLDivElement, GuidePanelProps>(
96
96
  />
97
97
  </svg>
98
98
  )}
99
- {themeContext ? (
99
+ {themeContext?.isDarkside ? (
100
100
  <div className={cn("navds-guide-panel__content-inner")}>
101
101
  {children}
102
102
  </div>
@@ -81,8 +81,8 @@ export const HelpText = forwardRef<HTMLButtonElement, HelpTextProps>(
81
81
  anchorEl={buttonRef.current}
82
82
  placement={placement}
83
83
  strategy={strategy}
84
- offset={themeContext ? 8 : 12}
85
- arrow={!themeContext}
84
+ offset={themeContext?.isDarkside ? 8 : 12}
85
+ arrow={!themeContext?.isDarkside}
86
86
  >
87
87
  <Popover.Content className={cn("navds-body-short")}>
88
88
  {children}
@@ -84,7 +84,7 @@ export const InternalHeader = forwardRef(({ className, ...rest }, ref) => {
84
84
  /*
85
85
  * Component is always in "dark" mode, so we manually override global theme.
86
86
  */
87
- if (themeContext) {
87
+ if (themeContext?.isDarkside) {
88
88
  return (
89
89
  <Theme theme="dark" asChild hasBackground={false}>
90
90
  <header
@@ -253,7 +253,7 @@ export const BasePrimitive = ({
253
253
  }: BasePrimitiveProps) => {
254
254
  const themeContext = useThemeInternal(false);
255
255
  const { cn } = useRenameCSS();
256
- const prefix = themeContext ? "ax" : "a";
256
+ const prefix = themeContext?.isDarkside ? "ax" : "a";
257
257
 
258
258
  const style: React.CSSProperties = {
259
259
  /* Padding */
@@ -82,7 +82,7 @@ export const Bleed = forwardRef<HTMLDivElement, BleedProps>(
82
82
  ) => {
83
83
  const themeContext = useThemeInternal(false);
84
84
  const { cn } = useRenameCSS();
85
- const prefix = themeContext ? "ax" : "a";
85
+ const prefix = themeContext?.isDarkside ? "ax" : "a";
86
86
 
87
87
  let style: React.CSSProperties = {
88
88
  ..._style,
@@ -113,7 +113,7 @@ export const BoxComponent: OverridableComponent<BoxProps, HTMLDivElement> =
113
113
 
114
114
  if (
115
115
  process.env.NODE_ENV !== "production" &&
116
- themeContext &&
116
+ themeContext?.isDarkside &&
117
117
  (background || borderColor || shadow)
118
118
  ) {
119
119
  let errorText = ``;
@@ -131,7 +131,7 @@ export const BoxComponent: OverridableComponent<BoxProps, HTMLDivElement> =
131
131
  );
132
132
  }
133
133
 
134
- const prefix = themeContext ? "ax" : "a";
134
+ const prefix = themeContext?.isDarkside ? "ax" : "a";
135
135
 
136
136
  const style: React.CSSProperties = {
137
137
  ..._style,
@@ -173,8 +173,9 @@ export const BoxComponent: OverridableComponent<BoxProps, HTMLDivElement> =
173
173
  "navds-box-bg": background,
174
174
  "navds-box-border-color": borderColor,
175
175
  "navds-box-border-width": borderWidth,
176
- "navds-box-border-radius": borderRadius && !themeContext,
177
- "navds-box-radius": borderRadius && themeContext,
176
+ "navds-box-border-radius":
177
+ borderRadius && !themeContext?.isDarkside,
178
+ "navds-box-radius": borderRadius && themeContext?.isDarkside,
178
179
  "navds-box-shadow": shadow,
179
180
  })}
180
181
  >
@@ -78,7 +78,7 @@ export const HGrid: OverridableComponent<HGridProps, HTMLDivElement> =
78
78
  ref,
79
79
  ) => {
80
80
  const themeContext = useThemeInternal(false);
81
- const prefix = themeContext ? "ax" : "a";
81
+ const prefix = themeContext?.isDarkside ? "ax" : "a";
82
82
  const { cn } = useRenameCSS();
83
83
 
84
84
  const styles: React.CSSProperties = {
@@ -56,7 +56,11 @@ export const PageComponent: OverridableComponent<PageProps, HTMLElement> =
56
56
  const themeContext = useThemeInternal(false);
57
57
  const { cn } = useRenameCSS();
58
58
 
59
- if (process.env.NODE_ENV !== "production" && themeContext && background) {
59
+ if (
60
+ process.env.NODE_ENV !== "production" &&
61
+ themeContext?.isDarkside &&
62
+ background
63
+ ) {
60
64
  console.warn(
61
65
  `Prop \`background\` is deprecated and cannot be used with theme-support. Instead wrap component with \`<Box asChild background>\``,
62
66
  );
@@ -84,7 +84,7 @@ export const Stack: OverridableComponent<StackProps, HTMLDivElement> =
84
84
  ref,
85
85
  ) => {
86
86
  const themeContext = useThemeInternal(false);
87
- const prefix = themeContext ? "ax" : "a";
87
+ const prefix = themeContext?.isDarkside ? "ax" : "a";
88
88
  const { cn } = useRenameCSS();
89
89
 
90
90
  const style: React.CSSProperties = {
package/src/link/Link.tsx CHANGED
@@ -72,7 +72,7 @@ export const Link: OverridableComponent<LinkProps, HTMLAnchorElement> =
72
72
  */
73
73
  let localVariant: LinkProps["variant"];
74
74
 
75
- if (themeContext) {
75
+ if (themeContext?.isDarkside) {
76
76
  localVariant = variant;
77
77
  } else {
78
78
  localVariant = variant ?? "action";
package/src/list/List.tsx CHANGED
@@ -63,7 +63,7 @@ export const List = forwardRef<HTMLDivElement, ListProps>(
63
63
 
64
64
  const listSize = size ?? contextSize;
65
65
 
66
- if (themeContext) {
66
+ if (themeContext?.isDarkside) {
67
67
  if (
68
68
  process.env.NODE_ENV !== "production" &&
69
69
  (title || description || headingTag)
@@ -802,7 +802,7 @@ export const ActionMenuRadioItem = forwardRef<
802
802
  fill="var(--ax-bg-default, var(--a-surface-default))"
803
803
  />
804
804
  </g>
805
- {themeContext ? (
805
+ {themeContext?.isDarkside ? (
806
806
  <g className={cn("navds-action-menu__indicator-icon--checked")}>
807
807
  <rect
808
808
  width="24"
@@ -46,7 +46,7 @@ export const Item: PaginationItemType = forwardRef(
46
46
  return (
47
47
  <Button
48
48
  as={Component}
49
- variant={themeContext ? "tertiary-neutral" : "tertiary"}
49
+ variant={themeContext?.isDarkside ? "tertiary-neutral" : "tertiary"}
50
50
  data-color={color}
51
51
  aria-current={selected}
52
52
  data-pressed={selected}
@@ -138,7 +138,7 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
138
138
  placement,
139
139
  open,
140
140
  middleware: [
141
- flOffset(offset ?? (themeContext ? 8 : arrow ? 16 : 4)),
141
+ flOffset(offset ?? (themeContext?.isDarkside ? 8 : arrow ? 16 : 4)),
142
142
  chosenFlip &&
143
143
  flip({ padding: 5, fallbackPlacements: ["bottom", "top"] }),
144
144
  shift({ padding: 12 }),
@@ -191,7 +191,7 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
191
191
  >
192
192
  {children}
193
193
  {/* Hide arrow in new design, prop will be removed in breaking change update */}
194
- {arrow && !themeContext && (
194
+ {arrow && !themeContext?.isDarkside && (
195
195
  <div
196
196
  ref={(node) => {
197
197
  arrowRef.current = node;
@@ -26,7 +26,7 @@ export const Portal = forwardRef<HTMLDivElement, PortalProps>(
26
26
  * Portal can be mounted outside of theme-classNames.
27
27
  * If a theme is present, we want to make sure that theme cascades to portaled element.
28
28
  */
29
- if (themeContext) {
29
+ if (themeContext?.isDarkside) {
30
30
  return root
31
31
  ? ReactDOM.createPortal(
32
32
  <Theme