@navikt/ds-react 7.30.0 → 7.31.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 (238) 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/expansion-card/ExpansionCardContent.js +2 -1
  12. package/cjs/expansion-card/ExpansionCardContent.js.map +1 -1
  13. package/cjs/form/checkbox/Checkbox.js +42 -0
  14. package/cjs/form/checkbox/Checkbox.js.map +1 -1
  15. package/cjs/form/checkbox/useCheckbox.d.ts +2 -2
  16. package/cjs/form/checkbox/useCheckbox.js +5 -5
  17. package/cjs/form/checkbox/useCheckbox.js.map +1 -1
  18. package/cjs/form/combobox/Combobox.js +15 -13
  19. package/cjs/form/combobox/Combobox.js.map +1 -1
  20. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js +53 -3
  21. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
  22. package/cjs/form/combobox/FilteredOptions/useVirtualFocus.js.map +1 -1
  23. package/cjs/form/combobox/Input/InputController.js +15 -14
  24. package/cjs/form/combobox/Input/InputController.js.map +1 -1
  25. package/cjs/form/radio/Radio.js +18 -0
  26. package/cjs/form/radio/Radio.js.map +1 -1
  27. package/cjs/form/radio/useRadio.d.ts +2 -2
  28. package/cjs/form/radio/useRadio.js +5 -5
  29. package/cjs/form/radio/useRadio.js.map +1 -1
  30. package/cjs/form/search/Search.js +1 -1
  31. package/cjs/form/search/Search.js.map +1 -1
  32. package/cjs/guide-panel/GuidePanel.js +3 -3
  33. package/cjs/guide-panel/GuidePanel.js.map +1 -1
  34. package/cjs/help-text/HelpText.js +1 -1
  35. package/cjs/help-text/HelpText.js.map +1 -1
  36. package/cjs/internal-header/InternalHeader.js +1 -1
  37. package/cjs/internal-header/InternalHeader.js.map +1 -1
  38. package/cjs/layout/base/BasePrimitive.js +1 -1
  39. package/cjs/layout/base/BasePrimitive.js.map +1 -1
  40. package/cjs/layout/bleed/Bleed.js +1 -1
  41. package/cjs/layout/bleed/Bleed.js.map +1 -1
  42. package/cjs/layout/box/Box.js +4 -4
  43. package/cjs/layout/box/Box.js.map +1 -1
  44. package/cjs/layout/grid/HGrid.js +1 -1
  45. package/cjs/layout/grid/HGrid.js.map +1 -1
  46. package/cjs/layout/page/Page.js +3 -1
  47. package/cjs/layout/page/Page.js.map +1 -1
  48. package/cjs/layout/stack/Stack.js +1 -1
  49. package/cjs/layout/stack/Stack.js.map +1 -1
  50. package/cjs/link/Link.js +1 -1
  51. package/cjs/link/Link.js.map +1 -1
  52. package/cjs/list/List.js +1 -1
  53. package/cjs/list/List.js.map +1 -1
  54. package/cjs/overlays/action-menu/ActionMenu.js +1 -1
  55. package/cjs/overlays/action-menu/ActionMenu.js.map +1 -1
  56. package/cjs/overlays/floating/Floating.d.ts +11 -0
  57. package/cjs/overlays/floating/Floating.js +32 -8
  58. package/cjs/overlays/floating/Floating.js.map +1 -1
  59. package/cjs/overlays/overlay/hooks/useAnimationsFinished.d.ts +27 -0
  60. package/cjs/overlays/overlay/hooks/useAnimationsFinished.js +138 -0
  61. package/cjs/overlays/overlay/hooks/useAnimationsFinished.js.map +1 -0
  62. package/cjs/overlays/overlay/hooks/useEventCallback.d.ts +6 -0
  63. package/cjs/overlays/overlay/hooks/useEventCallback.js +89 -0
  64. package/cjs/overlays/overlay/hooks/useEventCallback.js.map +1 -0
  65. package/cjs/overlays/overlay/hooks/useLatestRef.d.ts +5 -0
  66. package/cjs/overlays/overlay/hooks/useLatestRef.js +23 -0
  67. package/cjs/overlays/overlay/hooks/useLatestRef.js.map +1 -0
  68. package/cjs/overlays/overlay/hooks/useOpenChangeComplete.d.ts +31 -0
  69. package/cjs/overlays/overlay/hooks/useOpenChangeComplete.js +35 -0
  70. package/cjs/overlays/overlay/hooks/useOpenChangeComplete.js.map +1 -0
  71. package/cjs/overlays/overlay/hooks/useRefWithInit.d.ts +7 -0
  72. package/cjs/overlays/overlay/hooks/useRefWithInit.js +14 -0
  73. package/cjs/overlays/overlay/hooks/useRefWithInit.js.map +1 -0
  74. package/cjs/pagination/PaginationItem.js +1 -1
  75. package/cjs/pagination/PaginationItem.js.map +1 -1
  76. package/cjs/popover/Popover.js +2 -2
  77. package/cjs/popover/Popover.js.map +1 -1
  78. package/cjs/portal/Portal.js +1 -1
  79. package/cjs/portal/Portal.js.map +1 -1
  80. package/cjs/table/ExpandableRow.d.ts +1 -1
  81. package/cjs/table/ExpandableRow.js +2 -10
  82. package/cjs/table/ExpandableRow.js.map +1 -1
  83. package/cjs/table/Row.d.ts +7 -0
  84. package/cjs/table/Row.js +13 -2
  85. package/cjs/table/Row.js.map +1 -1
  86. package/cjs/table/Table.utils.d.ts +9 -0
  87. package/cjs/table/Table.utils.js +57 -0
  88. package/cjs/table/Table.utils.js.map +1 -0
  89. package/cjs/theme/Theme.d.ts +6 -1
  90. package/cjs/theme/Theme.js +10 -2
  91. package/cjs/theme/Theme.js.map +1 -1
  92. package/cjs/timeline/Pin.js +1 -1
  93. package/cjs/timeline/Pin.js.map +1 -1
  94. package/cjs/timeline/period/ClickablePeriod.js +1 -1
  95. package/cjs/timeline/period/ClickablePeriod.js.map +1 -1
  96. package/cjs/toggle-group/ToggleGroup.js +1 -1
  97. package/cjs/toggle-group/ToggleGroup.js.map +1 -1
  98. package/esm/accordion/AccordionContent.js +1 -1
  99. package/esm/accordion/AccordionContent.js.map +1 -1
  100. package/esm/accordion/AccordionHeader.js +1 -1
  101. package/esm/accordion/AccordionHeader.js.map +1 -1
  102. package/esm/chips/Removable.js +1 -1
  103. package/esm/chips/Removable.js.map +1 -1
  104. package/esm/chips/Toggle.js +1 -1
  105. package/esm/chips/Toggle.js.map +1 -1
  106. package/esm/copybutton/CopyButton.js +8 -4
  107. package/esm/copybutton/CopyButton.js.map +1 -1
  108. package/esm/expansion-card/ExpansionCardContent.js +3 -2
  109. package/esm/expansion-card/ExpansionCardContent.js.map +1 -1
  110. package/esm/form/checkbox/Checkbox.js +44 -2
  111. package/esm/form/checkbox/Checkbox.js.map +1 -1
  112. package/esm/form/checkbox/useCheckbox.d.ts +2 -2
  113. package/esm/form/checkbox/useCheckbox.js +5 -5
  114. package/esm/form/checkbox/useCheckbox.js.map +1 -1
  115. package/esm/form/combobox/Combobox.js +15 -13
  116. package/esm/form/combobox/Combobox.js.map +1 -1
  117. package/esm/form/combobox/FilteredOptions/FilteredOptions.js +21 -4
  118. package/esm/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
  119. package/esm/form/combobox/FilteredOptions/useVirtualFocus.js.map +1 -1
  120. package/esm/form/combobox/Input/InputController.js +15 -14
  121. package/esm/form/combobox/Input/InputController.js.map +1 -1
  122. package/esm/form/radio/Radio.js +17 -2
  123. package/esm/form/radio/Radio.js.map +1 -1
  124. package/esm/form/radio/useRadio.d.ts +2 -2
  125. package/esm/form/radio/useRadio.js +5 -5
  126. package/esm/form/radio/useRadio.js.map +1 -1
  127. package/esm/form/search/Search.js +1 -1
  128. package/esm/form/search/Search.js.map +1 -1
  129. package/esm/guide-panel/GuidePanel.js +3 -3
  130. package/esm/guide-panel/GuidePanel.js.map +1 -1
  131. package/esm/help-text/HelpText.js +1 -1
  132. package/esm/help-text/HelpText.js.map +1 -1
  133. package/esm/internal-header/InternalHeader.js +1 -1
  134. package/esm/internal-header/InternalHeader.js.map +1 -1
  135. package/esm/layout/base/BasePrimitive.js +1 -1
  136. package/esm/layout/base/BasePrimitive.js.map +1 -1
  137. package/esm/layout/bleed/Bleed.js +1 -1
  138. package/esm/layout/bleed/Bleed.js.map +1 -1
  139. package/esm/layout/box/Box.js +4 -4
  140. package/esm/layout/box/Box.js.map +1 -1
  141. package/esm/layout/grid/HGrid.js +1 -1
  142. package/esm/layout/grid/HGrid.js.map +1 -1
  143. package/esm/layout/page/Page.js +3 -1
  144. package/esm/layout/page/Page.js.map +1 -1
  145. package/esm/layout/stack/Stack.js +1 -1
  146. package/esm/layout/stack/Stack.js.map +1 -1
  147. package/esm/link/Link.js +1 -1
  148. package/esm/link/Link.js.map +1 -1
  149. package/esm/list/List.js +1 -1
  150. package/esm/list/List.js.map +1 -1
  151. package/esm/overlays/action-menu/ActionMenu.js +1 -1
  152. package/esm/overlays/action-menu/ActionMenu.js.map +1 -1
  153. package/esm/overlays/floating/Floating.d.ts +11 -0
  154. package/esm/overlays/floating/Floating.js +32 -8
  155. package/esm/overlays/floating/Floating.js.map +1 -1
  156. package/esm/overlays/overlay/hooks/useAnimationsFinished.d.ts +27 -0
  157. package/esm/overlays/overlay/hooks/useAnimationsFinished.js +99 -0
  158. package/esm/overlays/overlay/hooks/useAnimationsFinished.js.map +1 -0
  159. package/esm/overlays/overlay/hooks/useEventCallback.d.ts +6 -0
  160. package/esm/overlays/overlay/hooks/useEventCallback.js +53 -0
  161. package/esm/overlays/overlay/hooks/useEventCallback.js.map +1 -0
  162. package/esm/overlays/overlay/hooks/useLatestRef.d.ts +5 -0
  163. package/esm/overlays/overlay/hooks/useLatestRef.js +20 -0
  164. package/esm/overlays/overlay/hooks/useLatestRef.js.map +1 -0
  165. package/esm/overlays/overlay/hooks/useOpenChangeComplete.d.ts +31 -0
  166. package/esm/overlays/overlay/hooks/useOpenChangeComplete.js +32 -0
  167. package/esm/overlays/overlay/hooks/useOpenChangeComplete.js.map +1 -0
  168. package/esm/overlays/overlay/hooks/useRefWithInit.d.ts +7 -0
  169. package/esm/overlays/overlay/hooks/useRefWithInit.js +12 -0
  170. package/esm/overlays/overlay/hooks/useRefWithInit.js.map +1 -0
  171. package/esm/pagination/PaginationItem.js +1 -1
  172. package/esm/pagination/PaginationItem.js.map +1 -1
  173. package/esm/popover/Popover.js +2 -2
  174. package/esm/popover/Popover.js.map +1 -1
  175. package/esm/portal/Portal.js +1 -1
  176. package/esm/portal/Portal.js.map +1 -1
  177. package/esm/table/ExpandableRow.d.ts +1 -1
  178. package/esm/table/ExpandableRow.js +2 -10
  179. package/esm/table/ExpandableRow.js.map +1 -1
  180. package/esm/table/Row.d.ts +7 -0
  181. package/esm/table/Row.js +13 -2
  182. package/esm/table/Row.js.map +1 -1
  183. package/esm/table/Table.utils.d.ts +9 -0
  184. package/esm/table/Table.utils.js +55 -0
  185. package/esm/table/Table.utils.js.map +1 -0
  186. package/esm/theme/Theme.d.ts +6 -1
  187. package/esm/theme/Theme.js +10 -2
  188. package/esm/theme/Theme.js.map +1 -1
  189. package/esm/timeline/Pin.js +1 -1
  190. package/esm/timeline/Pin.js.map +1 -1
  191. package/esm/timeline/period/ClickablePeriod.js +1 -1
  192. package/esm/timeline/period/ClickablePeriod.js.map +1 -1
  193. package/esm/toggle-group/ToggleGroup.js +1 -1
  194. package/esm/toggle-group/ToggleGroup.js.map +1 -1
  195. package/package.json +3 -3
  196. package/src/accordion/AccordionContent.tsx +1 -1
  197. package/src/accordion/AccordionHeader.tsx +1 -1
  198. package/src/chips/Removable.tsx +1 -1
  199. package/src/chips/Toggle.tsx +1 -1
  200. package/src/copybutton/CopyButton.tsx +8 -4
  201. package/src/expansion-card/ExpansionCardContent.tsx +3 -1
  202. package/src/form/checkbox/Checkbox.tsx +93 -2
  203. package/src/form/checkbox/useCheckbox.ts +5 -5
  204. package/src/form/combobox/Combobox.tsx +44 -41
  205. package/src/form/combobox/FilteredOptions/FilteredOptions.tsx +29 -4
  206. package/src/form/combobox/FilteredOptions/useVirtualFocus.ts +1 -0
  207. package/src/form/combobox/Input/InputController.tsx +33 -29
  208. package/src/form/radio/Radio.tsx +49 -2
  209. package/src/form/radio/useRadio.ts +5 -5
  210. package/src/form/search/Search.tsx +1 -1
  211. package/src/guide-panel/GuidePanel.tsx +3 -3
  212. package/src/help-text/HelpText.tsx +2 -2
  213. package/src/internal-header/InternalHeader.tsx +1 -1
  214. package/src/layout/base/BasePrimitive.tsx +1 -1
  215. package/src/layout/bleed/Bleed.tsx +1 -1
  216. package/src/layout/box/Box.tsx +5 -4
  217. package/src/layout/grid/HGrid.tsx +1 -1
  218. package/src/layout/page/Page.tsx +5 -1
  219. package/src/layout/stack/Stack.tsx +1 -1
  220. package/src/link/Link.tsx +1 -1
  221. package/src/list/List.tsx +1 -1
  222. package/src/overlays/action-menu/ActionMenu.tsx +1 -1
  223. package/src/overlays/floating/Floating.tsx +110 -59
  224. package/src/overlays/overlay/hooks/useAnimationsFinished.ts +117 -0
  225. package/src/overlays/overlay/hooks/useEventCallback.ts +73 -0
  226. package/src/overlays/overlay/hooks/useLatestRef.ts +25 -0
  227. package/src/overlays/overlay/hooks/useOpenChangeComplete.ts +66 -0
  228. package/src/overlays/overlay/hooks/useRefWithInit.ts +25 -0
  229. package/src/pagination/PaginationItem.tsx +1 -1
  230. package/src/popover/Popover.tsx +2 -2
  231. package/src/portal/Portal.tsx +1 -1
  232. package/src/table/ExpandableRow.tsx +4 -17
  233. package/src/table/Row.tsx +33 -1
  234. package/src/table/Table.utils.ts +65 -0
  235. package/src/theme/Theme.tsx +14 -3
  236. package/src/timeline/Pin.tsx +1 -1
  237. package/src/timeline/period/ClickablePeriod.tsx +1 -1
  238. package/src/toggle-group/ToggleGroup.tsx +1 -1
@@ -1,4 +1,5 @@
1
1
  import React, { forwardRef } from "react";
2
+ import { Floating } from "../../overlays/floating/Floating";
2
3
  import { useRenameCSS } from "../../theme/Theme";
3
4
  import { BodyShort, ErrorMessage, Label } from "../../typography";
4
5
  import { ReadOnlyIconWithTitle } from "../ReadOnlyIcon";
@@ -34,52 +35,54 @@ export const Combobox = forwardRef<
34
35
  } = useInputContext();
35
36
 
36
37
  return (
37
- <ComboboxWrapper
38
- className={className}
39
- hasError={hasError}
40
- inputProps={inputProps}
41
- inputSize={size}
42
- toggleIsListOpen={toggleIsListOpen}
43
- >
44
- <Label
45
- htmlFor={inputProps.id}
46
- size={size}
47
- className={cn("navds-form-field__label", {
48
- "navds-sr-only": hideLabel,
49
- })}
38
+ <Floating>
39
+ <ComboboxWrapper
40
+ className={className}
41
+ hasError={hasError}
42
+ inputProps={inputProps}
43
+ inputSize={size}
44
+ toggleIsListOpen={toggleIsListOpen}
50
45
  >
51
- {readOnly && <ReadOnlyIconWithTitle />}
52
- {label}
53
- </Label>
54
- {!!description && (
55
- <BodyShort
56
- as="div"
57
- className={cn("navds-form-field__description", {
46
+ <Label
47
+ htmlFor={inputProps.id}
48
+ size={size}
49
+ className={cn("navds-form-field__label", {
58
50
  "navds-sr-only": hideLabel,
59
51
  })}
60
- id={inputDescriptionId}
61
- size={size}
62
52
  >
63
- {description}
64
- </BodyShort>
65
- )}
66
- <div className={cn("navds-combobox__wrapper")}>
67
- <InputController ref={ref} {...rest} />
68
- <FilteredOptions />
69
- </div>
70
- <div
71
- className={cn("navds-form-field__error")}
72
- id={errorId}
73
- aria-relevant="additions removals"
74
- aria-live="polite"
75
- >
76
- {showErrorMsg && (
77
- <ErrorMessage size={size} showIcon>
78
- {error}
79
- </ErrorMessage>
53
+ {readOnly && <ReadOnlyIconWithTitle />}
54
+ {label}
55
+ </Label>
56
+ {!!description && (
57
+ <BodyShort
58
+ as="div"
59
+ className={cn("navds-form-field__description", {
60
+ "navds-sr-only": hideLabel,
61
+ })}
62
+ id={inputDescriptionId}
63
+ size={size}
64
+ >
65
+ {description}
66
+ </BodyShort>
80
67
  )}
81
- </div>
82
- </ComboboxWrapper>
68
+ <div className={cn("navds-combobox__wrapper")}>
69
+ <InputController ref={ref} {...rest} />
70
+ <FilteredOptions />
71
+ </div>
72
+ <div
73
+ className={cn("navds-form-field__error")}
74
+ id={errorId}
75
+ aria-relevant="additions removals"
76
+ aria-live="polite"
77
+ >
78
+ {showErrorMsg && (
79
+ <ErrorMessage size={size} showIcon>
80
+ {error}
81
+ </ErrorMessage>
82
+ )}
83
+ </div>
84
+ </ComboboxWrapper>
85
+ </Floating>
83
86
  );
84
87
  });
85
88
 
@@ -1,5 +1,7 @@
1
- import React from "react";
2
- import { useRenameCSS } from "../../../theme/Theme";
1
+ import React, { useState } from "react";
2
+ import { Floating } from "../../../overlays/floating/Floating";
3
+ import { useRenameCSS, useThemeInternal } from "../../../theme/Theme";
4
+ import { useClientLayoutEffect } from "../../../util";
3
5
  import { useInputContext } from "../Input/Input.context";
4
6
  import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
5
7
  import AddNewOption from "./AddNewOption";
@@ -12,6 +14,7 @@ import { useFilteredOptionsContext } from "./filteredOptionsContext";
12
14
 
13
15
  const FilteredOptions = () => {
14
16
  const { cn } = useRenameCSS();
17
+ const themeContext = useThemeInternal(false);
15
18
  const {
16
19
  inputProps: { id },
17
20
  } = useInputContext();
@@ -25,6 +28,16 @@ const FilteredOptions = () => {
25
28
  isMouseLastUsedInputDevice,
26
29
  isValueNew,
27
30
  } = useFilteredOptionsContext();
31
+ const [localOpen, setLocalOpen] = useState(isListOpen);
32
+
33
+ /**
34
+ * This is a dirty hack to make the positioning-logic in Floating base the "flip" on the static 290px max-height,
35
+ * instead of the dynamic one based on available space. Without this, the list won't flip to top when there's
36
+ * not enough space below the input.
37
+ */
38
+ useClientLayoutEffect(() => {
39
+ queueMicrotask(() => setLocalOpen(isListOpen));
40
+ }, [isListOpen]);
28
41
 
29
42
  const { maxSelected, isMultiSelect } = useSelectedOptionsContext();
30
43
 
@@ -37,14 +50,26 @@ const FilteredOptions = () => {
37
50
  (allowNewValues && isValueNew && !maxSelected.isLimitReached) || // Render add new option
38
51
  filteredOptions.length > 0; // Render filtered options
39
52
 
53
+ const height = themeContext?.isDarkside ? "316px" : "290px";
54
+
40
55
  return (
41
- <div
56
+ <Floating.Content
42
57
  className={cn("navds-combobox__list", {
43
58
  "navds-combobox__list--closed": !isListOpen,
44
59
  "navds-combobox__list--with-hover": isMouseLastUsedInputDevice,
45
60
  })}
46
61
  id={filteredOptionsUtil.getFilteredOptionsId(id)}
47
62
  tabIndex={-1}
63
+ sideOffset={8}
64
+ side="bottom"
65
+ fallbackPlacements={["top"]}
66
+ enabled={isListOpen}
67
+ style={{
68
+ maxHeight: localOpen
69
+ ? `min(${height}, var(--ac-floating-available-height))`
70
+ : `${height}`,
71
+ }}
72
+ autoUpdateWhileMounted={false}
48
73
  >
49
74
  {shouldRenderNonSelectables && (
50
75
  <div
@@ -74,7 +99,7 @@ const FilteredOptions = () => {
74
99
  ))}
75
100
  </ul>
76
101
  )}
77
- </div>
102
+ </Floating.Content>
78
103
  );
79
104
  };
80
105
 
@@ -64,6 +64,7 @@ const useVirtualFocus = (
64
64
 
65
65
  const moveFocusDown = () => {
66
66
  const elementsAbleToReceiveFocus = getElementsAbleToReceiveFocus();
67
+
67
68
  if (!activeElement) {
68
69
  setActiveAndScrollToElement(elementsAbleToReceiveFocus[0]);
69
70
  return;
@@ -1,5 +1,8 @@
1
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
2
+
1
3
  /* eslint-disable jsx-a11y/no-static-element-interactions */
2
4
  import React, { forwardRef } from "react";
5
+ import { Floating } from "../../../overlays/floating/Floating";
3
6
  import { useRenameCSS } from "../../../theme/Theme";
4
7
  import { useMergeRefs } from "../../../util/hooks";
5
8
  import { useFilteredOptionsContext } from "../FilteredOptions/filteredOptionsContext";
@@ -54,42 +57,43 @@ export const InputController = forwardRef<
54
57
  const mergedInputRef = useMergeRefs(inputRef, ref);
55
58
 
56
59
  return (
57
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events
58
- <div
59
- className={cn("navds-combobox__wrapper-inner navds-text-field__input", {
60
- "navds-combobox__wrapper-inner--virtually-unfocused":
61
- activeDecendantId !== undefined,
62
- })}
63
- onClick={() => {
64
- if (inputProps.disabled || readOnly) {
65
- return;
66
- }
60
+ <Floating.Anchor asChild>
61
+ <div
62
+ className={cn("navds-combobox__wrapper-inner navds-text-field__input", {
63
+ "navds-combobox__wrapper-inner--virtually-unfocused":
64
+ activeDecendantId !== undefined,
65
+ })}
66
+ onClick={() => {
67
+ if (inputProps.disabled || readOnly) {
68
+ return;
69
+ }
67
70
 
68
- toggleIsListOpen(true);
69
- focusInput();
70
- }}
71
- >
72
- {!shouldShowSelectedOptions ? (
73
- <Input
74
- id={inputProps.id}
75
- ref={mergedInputRef}
76
- inputClassName={inputClassName}
77
- readOnly={readOnly}
78
- {...rest}
79
- />
80
- ) : (
81
- <SelectedOptions selectedOptions={selectedOptions} size={size}>
71
+ toggleIsListOpen(true);
72
+ focusInput();
73
+ }}
74
+ >
75
+ {!shouldShowSelectedOptions ? (
82
76
  <Input
83
77
  id={inputProps.id}
84
78
  ref={mergedInputRef}
85
79
  inputClassName={inputClassName}
86
- shouldShowSelectedOptions={shouldShowSelectedOptions}
87
80
  readOnly={readOnly}
88
81
  {...rest}
89
82
  />
90
- </SelectedOptions>
91
- )}
92
- {toggleListButton && <ToggleListButton ref={toggleOpenButtonRef} />}
93
- </div>
83
+ ) : (
84
+ <SelectedOptions selectedOptions={selectedOptions} size={size}>
85
+ <Input
86
+ id={inputProps.id}
87
+ ref={mergedInputRef}
88
+ inputClassName={inputClassName}
89
+ shouldShowSelectedOptions={shouldShowSelectedOptions}
90
+ readOnly={readOnly}
91
+ {...rest}
92
+ />
93
+ </SelectedOptions>
94
+ )}
95
+ {toggleListButton && <ToggleListButton ref={toggleOpenButtonRef} />}
96
+ </div>
97
+ </Floating.Anchor>
94
98
  );
95
99
  });
@@ -1,13 +1,60 @@
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={
29
+ cl(inputProps["aria-describedby"], {
30
+ [descriptionId]: props.description,
31
+ }) || undefined
32
+ }
33
+ className={cn("navds-radio__input")}
34
+ ref={ref}
35
+ />
36
+ <BodyShort
37
+ as="label"
38
+ htmlFor={inputProps.id}
39
+ className={cn("navds-radio__label")}
40
+ size={size}
41
+ >
42
+ {props.children}
43
+ </BodyShort>
44
+ {props.description && (
45
+ <BodyShort
46
+ id={descriptionId}
47
+ size={size}
48
+ className={cn(
49
+ "navds-form-field__subdescription navds-radio__description",
50
+ )}
51
+ >
52
+ {props.description}
53
+ </BodyShort>
54
+ )}
55
+ </div>
56
+ );
57
+ }
11
58
 
12
59
  return (
13
60
  <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"