@react-md/core 6.2.1 → 6.3.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 (345) hide show
  1. package/dist/_base.scss +1 -1
  2. package/dist/app-bar/styles.d.ts +0 -2
  3. package/dist/app-bar/styles.js.map +1 -1
  4. package/dist/autocomplete/types.d.ts +12 -0
  5. package/dist/autocomplete/types.js.map +1 -1
  6. package/dist/avatar/Avatar.d.ts +0 -10
  7. package/dist/avatar/Avatar.js.map +1 -1
  8. package/dist/avatar/styles.d.ts +10 -0
  9. package/dist/avatar/styles.js.map +1 -1
  10. package/dist/badge/Badge.d.ts +11 -0
  11. package/dist/badge/Badge.js.map +1 -1
  12. package/dist/badge/styles.d.ts +0 -8
  13. package/dist/badge/styles.js.map +1 -1
  14. package/dist/box/_box.scss +8 -8
  15. package/dist/box/styles.d.ts +9 -0
  16. package/dist/box/styles.js.map +1 -1
  17. package/dist/button/_button.scss +4 -0
  18. package/dist/button/styles.d.ts +5 -1
  19. package/dist/button/styles.js.map +1 -1
  20. package/dist/card/Card.d.ts +0 -7
  21. package/dist/card/Card.js.map +1 -1
  22. package/dist/card/styles.d.ts +6 -0
  23. package/dist/card/styles.js +8 -8
  24. package/dist/card/styles.js.map +1 -1
  25. package/dist/chip/Chip.d.ts +6 -13
  26. package/dist/chip/Chip.js.map +1 -1
  27. package/dist/chip/styles.d.ts +26 -1
  28. package/dist/chip/styles.js.map +1 -1
  29. package/dist/datetime/NativeDateField.d.ts +24 -0
  30. package/dist/datetime/NativeDateField.js +63 -0
  31. package/dist/datetime/NativeDateField.js.map +1 -0
  32. package/dist/datetime/NativeTimeField.d.ts +26 -0
  33. package/dist/datetime/NativeTimeField.js +63 -0
  34. package/dist/datetime/NativeTimeField.js.map +1 -0
  35. package/dist/datetime/useDateField.d.ts +120 -0
  36. package/dist/datetime/useDateField.js +35 -0
  37. package/dist/datetime/useDateField.js.map +1 -0
  38. package/dist/datetime/useTimeField.d.ts +124 -0
  39. package/dist/datetime/useTimeField.js +65 -0
  40. package/dist/datetime/useTimeField.js.map +1 -0
  41. package/dist/datetime/utils.d.ts +34 -0
  42. package/dist/datetime/utils.js +27 -0
  43. package/dist/datetime/utils.js.map +1 -0
  44. package/dist/dialog/styles.d.ts +5 -2
  45. package/dist/dialog/styles.js.map +1 -1
  46. package/dist/divider/styles.d.ts +1 -1
  47. package/dist/divider/styles.js.map +1 -1
  48. package/dist/draggable/utils.d.ts +3 -6
  49. package/dist/draggable/utils.js.map +1 -1
  50. package/dist/error-boundary/ErrorBoundary.js.map +1 -1
  51. package/dist/expansion-panel/ExpansionList.js +1 -1
  52. package/dist/expansion-panel/ExpansionList.js.map +1 -1
  53. package/dist/expansion-panel/useExpansionList.d.ts +2 -7
  54. package/dist/expansion-panel/useExpansionList.js.map +1 -1
  55. package/dist/files/validation.js.map +1 -1
  56. package/dist/form/FormMessage.js +3 -1
  57. package/dist/form/FormMessage.js.map +1 -1
  58. package/dist/form/FormMessageContainer.d.ts +2 -1
  59. package/dist/form/FormMessageContainer.js +3 -2
  60. package/dist/form/FormMessageContainer.js.map +1 -1
  61. package/dist/form/FormMessageCounter.d.ts +3 -2
  62. package/dist/form/FormMessageCounter.js +5 -2
  63. package/dist/form/FormMessageCounter.js.map +1 -1
  64. package/dist/form/InputToggle.js.map +1 -1
  65. package/dist/form/Label.d.ts +0 -10
  66. package/dist/form/Label.js.map +1 -1
  67. package/dist/form/Listbox.d.ts +3 -10
  68. package/dist/form/Listbox.js +8 -27
  69. package/dist/form/Listbox.js.map +1 -1
  70. package/dist/form/ListboxProvider.d.ts +17 -0
  71. package/dist/form/ListboxProvider.js +33 -1
  72. package/dist/form/ListboxProvider.js.map +1 -1
  73. package/dist/form/NativeSelect.js +1 -0
  74. package/dist/form/NativeSelect.js.map +1 -1
  75. package/dist/form/Slider.d.ts +4 -0
  76. package/dist/form/Slider.js.map +1 -1
  77. package/dist/form/Switch.js.map +1 -1
  78. package/dist/form/TextArea.js +1 -0
  79. package/dist/form/TextArea.js.map +1 -1
  80. package/dist/form/TextField.js +1 -0
  81. package/dist/form/TextField.js.map +1 -1
  82. package/dist/form/TextFieldContainer.d.ts +0 -13
  83. package/dist/form/TextFieldContainer.js.map +1 -1
  84. package/dist/form/_form-message.scss +13 -0
  85. package/dist/form/_select.scss +5 -1
  86. package/dist/form/_text-area.scss +2 -1
  87. package/dist/form/_text-field.scss +13 -3
  88. package/dist/form/formMessageContainerStyles.d.ts +7 -0
  89. package/dist/form/formMessageContainerStyles.js +4 -2
  90. package/dist/form/formMessageContainerStyles.js.map +1 -1
  91. package/dist/form/sliderUtils.d.ts +3 -7
  92. package/dist/form/sliderUtils.js.map +1 -1
  93. package/dist/form/types.d.ts +33 -0
  94. package/dist/form/types.js.map +1 -1
  95. package/dist/form/useCombobox.d.ts +6 -2
  96. package/dist/form/useCombobox.js +8 -9
  97. package/dist/form/useCombobox.js.map +1 -1
  98. package/dist/form/useFormReset.d.ts +4 -1
  99. package/dist/form/useFormReset.js +9 -4
  100. package/dist/form/useFormReset.js.map +1 -1
  101. package/dist/form/useNumberField.d.ts +5 -5
  102. package/dist/form/useNumberField.js +10 -2
  103. package/dist/form/useNumberField.js.map +1 -1
  104. package/dist/form/useSelectCombobox.js +2 -2
  105. package/dist/form/useSelectCombobox.js.map +1 -1
  106. package/dist/form/useTextField.d.ts +76 -59
  107. package/dist/form/useTextField.js +7 -1
  108. package/dist/form/useTextField.js.map +1 -1
  109. package/dist/interaction/types.d.ts +5 -1
  110. package/dist/interaction/types.js.map +1 -1
  111. package/dist/interaction/utils.d.ts +14 -0
  112. package/dist/interaction/utils.js +23 -12
  113. package/dist/interaction/utils.js.map +1 -1
  114. package/dist/link/Link.d.ts +0 -7
  115. package/dist/link/Link.js.map +1 -1
  116. package/dist/link/styles.d.ts +7 -0
  117. package/dist/link/styles.js.map +1 -1
  118. package/dist/list/List.d.ts +5 -20
  119. package/dist/list/List.js.map +1 -1
  120. package/dist/list/ListItem.d.ts +4 -38
  121. package/dist/list/ListItem.js.map +1 -1
  122. package/dist/list/listItemStyles.d.ts +24 -2
  123. package/dist/list/listItemStyles.js.map +1 -1
  124. package/dist/list/listStyles.d.ts +17 -2
  125. package/dist/list/listStyles.js.map +1 -1
  126. package/dist/menu/Menu.js.map +1 -1
  127. package/dist/menu/MenuBar.js +1 -1
  128. package/dist/menu/MenuBar.js.map +1 -1
  129. package/dist/menu/MenuItemTextField.d.ts +1 -2
  130. package/dist/menu/MenuItemTextField.js.map +1 -1
  131. package/dist/menu/MenuWidget.js +3 -2
  132. package/dist/menu/MenuWidget.js.map +1 -1
  133. package/dist/movement/constants.d.ts +10 -0
  134. package/dist/movement/constants.js +20 -4
  135. package/dist/movement/constants.js.map +1 -1
  136. package/dist/movement/types.d.ts +59 -10
  137. package/dist/movement/types.js.map +1 -1
  138. package/dist/movement/useKeyboardMovementProvider.d.ts +5 -1
  139. package/dist/movement/useKeyboardMovementProvider.js +171 -73
  140. package/dist/movement/useKeyboardMovementProvider.js.map +1 -1
  141. package/dist/navigation/NavItem.d.ts +4 -1
  142. package/dist/navigation/NavItem.js.map +1 -1
  143. package/dist/navigation/navItemStyles.d.ts +7 -0
  144. package/dist/navigation/navItemStyles.js.map +1 -1
  145. package/dist/overlay/Overlay.d.ts +4 -23
  146. package/dist/overlay/Overlay.js.map +1 -1
  147. package/dist/overlay/styles.d.ts +26 -8
  148. package/dist/overlay/styles.js.map +1 -1
  149. package/dist/progress/LinearProgress.d.ts +4 -9
  150. package/dist/progress/LinearProgress.js.map +1 -1
  151. package/dist/progress/circularProgressStyles.d.ts +6 -0
  152. package/dist/progress/circularProgressStyles.js.map +1 -1
  153. package/dist/progress/linearProgressStyles.d.ts +20 -5
  154. package/dist/progress/linearProgressStyles.js.map +1 -1
  155. package/dist/progress/types.d.ts +0 -9
  156. package/dist/progress/types.js.map +1 -1
  157. package/dist/segmented-button/SegmentedButton.d.ts +7 -12
  158. package/dist/segmented-button/SegmentedButton.js.map +1 -1
  159. package/dist/segmented-button/segmentedButtonStyles.d.ts +26 -3
  160. package/dist/segmented-button/segmentedButtonStyles.js.map +1 -1
  161. package/dist/sheet/Sheet.d.ts +0 -12
  162. package/dist/sheet/Sheet.js.map +1 -1
  163. package/dist/sheet/styles.d.ts +12 -0
  164. package/dist/sheet/styles.js.map +1 -1
  165. package/dist/snackbar/Toast.d.ts +2 -13
  166. package/dist/snackbar/Toast.js.map +1 -1
  167. package/dist/snackbar/ToastManager.js.map +1 -1
  168. package/dist/snackbar/toastStyles.d.ts +17 -2
  169. package/dist/snackbar/toastStyles.js.map +1 -1
  170. package/dist/tabs/Tab.d.ts +2 -41
  171. package/dist/tabs/Tab.js.map +1 -1
  172. package/dist/tabs/tabStyles.d.ts +45 -4
  173. package/dist/tabs/tabStyles.js.map +1 -1
  174. package/dist/tabs/useTabList.js +1 -1
  175. package/dist/tabs/useTabList.js.map +1 -1
  176. package/dist/test-utils/drag.d.ts +6 -9
  177. package/dist/test-utils/mocks/IntersectionObserver.js.map +1 -1
  178. package/dist/test-utils/mocks/ResizeObserver.js.map +1 -1
  179. package/dist/test-utils/utils/createFileList.js.map +1 -1
  180. package/dist/theme/_theme.scss +0 -1
  181. package/dist/theme/getDerivedTheme.d.ts +0 -24
  182. package/dist/theme/getDerivedTheme.js.map +1 -1
  183. package/dist/theme/types.d.ts +25 -0
  184. package/dist/theme/types.js.map +1 -1
  185. package/dist/tooltip/Tooltip.d.ts +4 -32
  186. package/dist/tooltip/Tooltip.js.map +1 -1
  187. package/dist/tooltip/styles.d.ts +38 -1
  188. package/dist/tooltip/styles.js +1 -1
  189. package/dist/tooltip/styles.js.map +1 -1
  190. package/dist/transition/SkeletonPlaceholder.d.ts +0 -7
  191. package/dist/transition/SkeletonPlaceholder.js.map +1 -1
  192. package/dist/transition/Slide.js.map +1 -1
  193. package/dist/transition/skeletonPlaceholderUtils.d.ts +7 -0
  194. package/dist/transition/skeletonPlaceholderUtils.js.map +1 -1
  195. package/dist/transition/useCarousel.d.ts +2 -2
  196. package/dist/transition/useCarousel.js.map +1 -1
  197. package/dist/transition/useMaxWidthTransition.d.ts +14 -2
  198. package/dist/transition/useMaxWidthTransition.js.map +1 -1
  199. package/dist/transition/useSlideTransition.d.ts +5 -0
  200. package/dist/transition/useSlideTransition.js.map +1 -1
  201. package/dist/tree/Tree.d.ts +5 -9
  202. package/dist/tree/Tree.js +1 -1
  203. package/dist/tree/Tree.js.map +1 -1
  204. package/dist/tree/styles.d.ts +9 -1
  205. package/dist/tree/styles.js.map +1 -1
  206. package/dist/tree/useTreeMovement.d.ts +2 -1
  207. package/dist/tree/useTreeMovement.js +2 -1
  208. package/dist/tree/useTreeMovement.js.map +1 -1
  209. package/dist/types.d.ts +14 -0
  210. package/dist/types.js.map +1 -1
  211. package/dist/typography/Mark.d.ts +4 -1
  212. package/dist/typography/Mark.js.map +1 -1
  213. package/dist/typography/TextContainer.d.ts +0 -6
  214. package/dist/typography/TextContainer.js.map +1 -1
  215. package/dist/typography/markStyles.d.ts +5 -0
  216. package/dist/typography/markStyles.js.map +1 -1
  217. package/dist/typography/textContainerStyles.d.ts +6 -0
  218. package/dist/typography/textContainerStyles.js.map +1 -1
  219. package/dist/typography/typographyStyles.d.ts +9 -0
  220. package/dist/typography/typographyStyles.js.map +1 -1
  221. package/dist/useResizeObserver.js.map +1 -1
  222. package/dist/utils/getMiddleOfRange.d.ts +2 -3
  223. package/dist/utils/getMiddleOfRange.js.map +1 -1
  224. package/dist/utils/getPercentage.d.ts +2 -9
  225. package/dist/utils/getPercentage.js +1 -1
  226. package/dist/utils/getPercentage.js.map +1 -1
  227. package/dist/utils/getRangeSteps.d.ts +2 -3
  228. package/dist/utils/getRangeSteps.js +0 -3
  229. package/dist/utils/getRangeSteps.js.map +1 -1
  230. package/dist/utils/nearest.d.ts +2 -3
  231. package/dist/utils/nearest.js +0 -3
  232. package/dist/utils/nearest.js.map +1 -1
  233. package/dist/utils/trigonometry.d.ts +31 -0
  234. package/dist/utils/trigonometry.js +25 -0
  235. package/dist/utils/trigonometry.js.map +1 -0
  236. package/dist/window-splitter/WindowSplitter.d.ts +5 -19
  237. package/dist/window-splitter/WindowSplitter.js.map +1 -1
  238. package/dist/window-splitter/styles.d.ts +27 -3
  239. package/dist/window-splitter/styles.js.map +1 -1
  240. package/dist/window-splitter/useWindowSplitter.d.ts +1 -1
  241. package/dist/window-splitter/useWindowSplitter.js.map +1 -1
  242. package/package.json +8 -8
  243. package/src/app-bar/styles.ts +0 -2
  244. package/src/autocomplete/types.ts +17 -0
  245. package/src/avatar/Avatar.tsx +0 -11
  246. package/src/avatar/styles.ts +11 -0
  247. package/src/badge/Badge.tsx +12 -0
  248. package/src/badge/styles.ts +0 -9
  249. package/src/box/styles.ts +9 -0
  250. package/src/button/styles.ts +5 -1
  251. package/src/card/Card.tsx +0 -8
  252. package/src/card/styles.ts +15 -8
  253. package/src/chip/Chip.tsx +9 -15
  254. package/src/chip/styles.ts +29 -1
  255. package/src/datetime/NativeDateField.tsx +92 -0
  256. package/src/datetime/NativeTimeField.tsx +94 -0
  257. package/src/datetime/useDateField.ts +193 -0
  258. package/src/datetime/useTimeField.ts +233 -0
  259. package/src/datetime/utils.ts +48 -0
  260. package/src/dialog/styles.ts +5 -2
  261. package/src/divider/styles.ts +1 -1
  262. package/src/draggable/utils.ts +3 -6
  263. package/src/expansion-panel/ExpansionList.tsx +2 -1
  264. package/src/expansion-panel/useExpansionList.ts +6 -12
  265. package/src/form/FormMessage.tsx +4 -0
  266. package/src/form/FormMessageContainer.tsx +8 -4
  267. package/src/form/FormMessageCounter.tsx +17 -6
  268. package/src/form/InputToggle.tsx +2 -0
  269. package/src/form/Label.tsx +0 -11
  270. package/src/form/Listbox.tsx +18 -46
  271. package/src/form/ListboxProvider.ts +61 -1
  272. package/src/form/NativeSelect.tsx +1 -0
  273. package/src/form/Slider.tsx +6 -0
  274. package/src/form/Switch.tsx +2 -0
  275. package/src/form/TextArea.tsx +3 -0
  276. package/src/form/TextField.tsx +1 -0
  277. package/src/form/TextFieldContainer.tsx +0 -14
  278. package/src/form/formMessageContainerStyles.ts +10 -2
  279. package/src/form/sliderUtils.ts +3 -7
  280. package/src/form/types.ts +44 -0
  281. package/src/form/useCombobox.ts +15 -10
  282. package/src/form/useFormReset.ts +12 -5
  283. package/src/form/useNumberField.ts +17 -14
  284. package/src/form/useSelectCombobox.ts +2 -2
  285. package/src/form/useTextField.ts +102 -69
  286. package/src/interaction/types.ts +5 -1
  287. package/src/interaction/utils.ts +18 -20
  288. package/src/link/Link.tsx +0 -8
  289. package/src/link/styles.ts +8 -0
  290. package/src/list/List.tsx +7 -24
  291. package/src/list/ListItem.tsx +7 -43
  292. package/src/list/listItemStyles.ts +26 -2
  293. package/src/list/listStyles.ts +18 -2
  294. package/src/menu/Menu.tsx +2 -0
  295. package/src/menu/MenuBar.tsx +1 -1
  296. package/src/menu/MenuItemTextField.tsx +1 -3
  297. package/src/menu/MenuWidget.tsx +4 -2
  298. package/src/movement/constants.ts +26 -4
  299. package/src/movement/types.ts +84 -19
  300. package/src/movement/useKeyboardMovementProvider.ts +209 -95
  301. package/src/navigation/NavItem.tsx +6 -2
  302. package/src/navigation/navItemStyles.ts +8 -0
  303. package/src/overlay/Overlay.tsx +4 -26
  304. package/src/overlay/styles.ts +29 -10
  305. package/src/progress/LinearProgress.tsx +8 -10
  306. package/src/progress/circularProgressStyles.ts +7 -0
  307. package/src/progress/linearProgressStyles.ts +22 -5
  308. package/src/progress/types.ts +0 -10
  309. package/src/segmented-button/SegmentedButton.tsx +14 -15
  310. package/src/segmented-button/segmentedButtonStyles.ts +28 -3
  311. package/src/sheet/Sheet.tsx +0 -13
  312. package/src/sheet/styles.ts +13 -0
  313. package/src/snackbar/Toast.tsx +2 -15
  314. package/src/snackbar/toastStyles.ts +20 -2
  315. package/src/tabs/Tab.tsx +4 -49
  316. package/src/tabs/tabStyles.ts +52 -4
  317. package/src/tabs/useTabList.ts +1 -1
  318. package/src/test-utils/drag.ts +8 -12
  319. package/src/theme/getDerivedTheme.ts +0 -26
  320. package/src/theme/types.ts +26 -0
  321. package/src/tooltip/Tooltip.tsx +4 -36
  322. package/src/tooltip/styles.ts +43 -2
  323. package/src/transition/SkeletonPlaceholder.tsx +0 -8
  324. package/src/transition/Slide.tsx +2 -0
  325. package/src/transition/skeletonPlaceholderUtils.ts +8 -0
  326. package/src/transition/useCarousel.ts +2 -2
  327. package/src/transition/useMaxWidthTransition.ts +17 -2
  328. package/src/transition/useSlideTransition.ts +8 -0
  329. package/src/tree/Tree.tsx +6 -11
  330. package/src/tree/styles.ts +10 -1
  331. package/src/tree/useTreeMovement.ts +4 -0
  332. package/src/types.ts +16 -0
  333. package/src/typography/Mark.tsx +6 -2
  334. package/src/typography/TextContainer.tsx +0 -7
  335. package/src/typography/markStyles.ts +6 -0
  336. package/src/typography/textContainerStyles.ts +7 -0
  337. package/src/typography/typographyStyles.ts +10 -0
  338. package/src/utils/getMiddleOfRange.ts +2 -3
  339. package/src/utils/getPercentage.ts +3 -11
  340. package/src/utils/getRangeSteps.ts +3 -3
  341. package/src/utils/nearest.ts +3 -3
  342. package/src/utils/trigonometry.ts +46 -0
  343. package/src/window-splitter/WindowSplitter.tsx +9 -22
  344. package/src/window-splitter/styles.ts +31 -3
  345. package/src/window-splitter/useWindowSplitter.ts +3 -2
@@ -13,24 +13,46 @@ export const DEFAULT_KEYBOARD_MOVEMENT: Readonly<KeyboardMovementConfig> = {
13
13
  jumpToLastKeys: ["End"],
14
14
  };
15
15
 
16
+ /**
17
+ * @since 6.3.0
18
+ * @internal
19
+ */
20
+ export const DEFAULT_LTR_KEYBOARD_MOVEMENT_WITHOUT_JUMP: Readonly<KeyboardMovementConfig> =
21
+ {
22
+ incrementKeys: ["ArrowRight"],
23
+ decrementKeys: ["ArrowLeft"],
24
+ jumpToFirstKeys: [],
25
+ jumpToLastKeys: [],
26
+ };
27
+
16
28
  /**
17
29
  * @since 5.1.2
18
30
  * @internal
19
31
  */
20
32
  export const DEFAULT_LTR_KEYBOARD_MOVEMENT: Readonly<KeyboardMovementConfig> = {
21
- incrementKeys: ["ArrowRight"],
22
- decrementKeys: ["ArrowLeft"],
33
+ ...DEFAULT_LTR_KEYBOARD_MOVEMENT_WITHOUT_JUMP,
23
34
  jumpToFirstKeys: ["Home"],
24
35
  jumpToLastKeys: ["End"],
25
36
  };
26
37
 
38
+ /**
39
+ * @since 6.3.0
40
+ * @internal
41
+ */
42
+ export const DEFAULT_RTL_KEYBOARD_MOVEMENT_WITHOUT_JUMP: Readonly<KeyboardMovementConfig> =
43
+ {
44
+ incrementKeys: ["ArrowLeft"],
45
+ decrementKeys: ["ArrowRight"],
46
+ jumpToFirstKeys: [],
47
+ jumpToLastKeys: [],
48
+ };
49
+
27
50
  /**
28
51
  * @since 5.1.2
29
52
  * @internal
30
53
  */
31
54
  export const DEFAULT_RTL_KEYBOARD_MOVEMENT: Readonly<KeyboardMovementConfig> = {
32
- incrementKeys: ["ArrowLeft"],
33
- decrementKeys: ["ArrowRight"],
55
+ ...DEFAULT_RTL_KEYBOARD_MOVEMENT_WITHOUT_JUMP,
34
56
  jumpToFirstKeys: ["Home"],
35
57
  jumpToLastKeys: ["End"],
36
58
  };
@@ -1,16 +1,15 @@
1
- import type {
2
- FocusEvent,
3
- FocusEventHandler,
4
- KeyboardEvent,
5
- KeyboardEventHandler,
6
- MouseEvent,
7
- MouseEventHandler,
1
+ import {
2
+ type HTMLAttributes,
3
+ type KeyboardEvent,
4
+ type Ref,
5
+ type RefCallback,
6
+ type RefObject,
8
7
  } from "react";
9
8
 
10
- import type {
11
- NonNullMutableRef,
12
- NonNullRef,
13
- UseStateSetter,
9
+ import {
10
+ type NonNullMutableRef,
11
+ type NonNullRef,
12
+ type UseStateSetter,
14
13
  } from "../types.js";
15
14
 
16
15
  /**
@@ -136,6 +135,23 @@ export interface KeyboardMovementBehavior {
136
135
  horizontal?: boolean;
137
136
  }
138
137
 
138
+ /**
139
+ * @since 6.3.0
140
+ */
141
+ export interface KeyboardFocusFromKeyOptions {
142
+ key: string;
143
+ /** @defaultValue `false` */
144
+ reversed?: boolean;
145
+
146
+ /** @defaultValue `getFocusableElementsFromRef()` */
147
+ focusables?: readonly HTMLElement[];
148
+ }
149
+
150
+ /**
151
+ * @since 6.3.0
152
+ */
153
+ export type KeyboardFocusAction = (focusables?: readonly HTMLElement[]) => void;
154
+
139
155
  /**
140
156
  * @since 5.0.0
141
157
  * @since 6.0.0 Removed `attach`, `detach` and `watching`
@@ -154,6 +170,31 @@ export interface KeyboardMovementContext
154
170
  * has been set to `"roving"` or `"virtual"`.
155
171
  */
156
172
  activeDescendantId: string;
173
+
174
+ /**
175
+ * @since 6.3.0
176
+ */
177
+ focusFirst: KeyboardFocusAction;
178
+
179
+ /**
180
+ * @since 6.3.0
181
+ */
182
+ focusLast: KeyboardFocusAction;
183
+
184
+ /**
185
+ * @since 6.3.0
186
+ */
187
+ focusNext: KeyboardFocusAction;
188
+
189
+ /**
190
+ * @since 6.3.0
191
+ */
192
+ focusPrevious: KeyboardFocusAction;
193
+
194
+ /**
195
+ * @since 6.3.0
196
+ */
197
+ focusFromKey: (options: KeyboardFocusFromKeyOptions) => void;
157
198
  }
158
199
 
159
200
  /**
@@ -208,20 +249,33 @@ export interface KeyboardMovementExtensionData<E extends HTMLElement>
208
249
  setActiveDescendantId: (id: string) => void;
209
250
  }
210
251
 
252
+ /**
253
+ * @since 6.3.0
254
+ */
255
+ export type KeyboardMovementEventHandlers<E extends HTMLElement> = Pick<
256
+ HTMLAttributes<E>,
257
+ "onClick" | "onFocus" | "onKeyDown"
258
+ >;
259
+
260
+ /**
261
+ * @since 6.3.0
262
+ */
263
+ export interface SimpleKeyboardMovementWrapperOptions<E extends HTMLElement>
264
+ extends KeyboardMovementEventHandlers<E> {
265
+ ref?: Ref<E>;
266
+ }
267
+
211
268
  /**
212
269
  * @since 6.0.0
213
270
  * @internal
214
271
  */
215
272
  export interface KeyboardMovementProviderOptions<E extends HTMLElement>
216
273
  extends KeyboardMovementBehavior,
274
+ SimpleKeyboardMovementWrapperOptions<E>,
217
275
  KeyboardMovementConfiguration {
218
276
  /** @see {@link TabIndexBehavior} */
219
277
  tabIndexBehavior?: TabIndexBehavior;
220
278
 
221
- onClick?: (event: MouseEvent<E>) => void;
222
- onFocus?: (event: FocusEvent<E>) => void;
223
- onKeyDown?: (event: KeyboardEvent<E>) => void;
224
-
225
279
  /** @defaultValue `false` */
226
280
  disabled?: boolean;
227
281
 
@@ -262,13 +316,24 @@ export interface KeyboardMovementProviderOptions<E extends HTMLElement>
262
316
  * @defaultValue `false`
263
317
  */
264
318
  isNegativeOneAllowed?: boolean;
319
+
320
+ /**
321
+ * This was added to support spinbutton groups so the user can either use the
322
+ * ArrowLeft, ArrowRight, or Tab keys to move. Without this, switching
323
+ * between tab and the arrow keys would have the wrong tab index.
324
+ *
325
+ * @since 6.3.0
326
+ * @defaultValue `false`
327
+ */
328
+ trackTabKeys?: boolean;
265
329
  }
266
330
 
267
331
  /**
268
332
  * @since 6.0.0
269
333
  * @internal
270
334
  */
271
- export interface KeyboardMovementProps<E extends HTMLElement> {
335
+ export interface KeyboardMovementProps<E extends HTMLElement>
336
+ extends Required<KeyboardMovementEventHandlers<E>> {
272
337
  /**
273
338
  * This will only be provided if the {@link KeyboardMovementContext.tabIndexBehavior}
274
339
  * is set to `"virtual"`.
@@ -285,9 +350,8 @@ export interface KeyboardMovementProps<E extends HTMLElement> {
285
350
  * - a child element **should** have a `tabIndex={0}` instead
286
351
  */
287
352
  tabIndex?: number;
288
- onClick: MouseEventHandler<E>;
289
- onFocus: FocusEventHandler<E>;
290
- onKeyDown: KeyboardEventHandler<E>;
353
+
354
+ ref: RefCallback<E>;
291
355
  }
292
356
 
293
357
  /**
@@ -295,6 +359,7 @@ export interface KeyboardMovementProps<E extends HTMLElement> {
295
359
  * @internal
296
360
  */
297
361
  export interface KeyboardMovementProviderImplementation<E extends HTMLElement> {
362
+ nodeRef: RefObject<E>;
298
363
  movementProps: Readonly<KeyboardMovementProps<E>>;
299
364
  movementContext: Readonly<KeyboardMovementContext>;
300
365
  currentFocusIndex: NonNullMutableRef<number>;
@@ -2,6 +2,7 @@
2
2
 
3
3
  import {
4
4
  createContext,
5
+ useCallback,
5
6
  useContext,
6
7
  useEffect,
7
8
  useMemo,
@@ -12,6 +13,7 @@ import {
12
13
  import { getFocusableElements as defaultGetFocusableElements } from "../focus/utils.js";
13
14
  import { useUserInteractionMode } from "../interaction/UserInteractionModeProvider.js";
14
15
  import { useDir } from "../typography/WritingDirectionProvider.js";
16
+ import { useEnsuredRef } from "../useEnsuredRef.js";
15
17
  import { useIsomorphicLayoutEffect } from "../useIsomorphicLayoutEffect.js";
16
18
  import {
17
19
  DEFAULT_KEYBOARD_MOVEMENT,
@@ -19,12 +21,13 @@ import {
19
21
  DEFAULT_RTL_KEYBOARD_MOVEMENT,
20
22
  } from "./constants.js";
21
23
  import { findMatchIndex } from "./findMatchIndex.js";
22
- import type {
23
- KeyboardMovementConfig,
24
- KeyboardMovementConfiguration,
25
- KeyboardMovementContext,
26
- KeyboardMovementProviderImplementation,
27
- KeyboardMovementProviderOptions,
24
+ import {
25
+ type KeyboardFocusFromKeyOptions,
26
+ type KeyboardMovementConfig,
27
+ type KeyboardMovementConfiguration,
28
+ type KeyboardMovementContext,
29
+ type KeyboardMovementProviderImplementation,
30
+ type KeyboardMovementProviderOptions,
28
31
  } from "./types.js";
29
32
  import {
30
33
  getFirstFocusableIndex,
@@ -38,19 +41,36 @@ import {
38
41
  recalculateFocusIndex,
39
42
  } from "./utils.js";
40
43
 
44
+ const noop = (): void => {
45
+ // do nothing
46
+ };
47
+
48
+ /**
49
+ * @since 6.3.0
50
+ */
51
+ export const DEFAULT_KEYBOARD_MOVEMENT_CONTEXT: Readonly<KeyboardMovementContext> =
52
+ {
53
+ config: { current: DEFAULT_KEYBOARD_MOVEMENT },
54
+ loopable: false,
55
+ searchable: false,
56
+ horizontal: false,
57
+ includeDisabled: false,
58
+ tabIndexBehavior: undefined,
59
+ activeDescendantId: "",
60
+ focusFirst: noop,
61
+ focusLast: noop,
62
+ focusNext: noop,
63
+ focusPrevious: noop,
64
+ focusFromKey: noop,
65
+ };
66
+
41
67
  /**
42
68
  * @since 5.0.0
43
69
  * @internal
44
70
  */
45
- const context = createContext<KeyboardMovementContext>({
46
- config: { current: DEFAULT_KEYBOARD_MOVEMENT },
47
- loopable: false,
48
- searchable: false,
49
- horizontal: false,
50
- includeDisabled: false,
51
- tabIndexBehavior: undefined,
52
- activeDescendantId: "",
53
- });
71
+ const context = createContext<KeyboardMovementContext>(
72
+ DEFAULT_KEYBOARD_MOVEMENT_CONTEXT
73
+ );
54
74
  context.displayName = "KeyboardMovement";
55
75
  export const { Provider: KeyboardMovementProvider } = context;
56
76
 
@@ -62,10 +82,6 @@ export function useKeyboardMovementContext(): Readonly<KeyboardMovementContext>
62
82
  return useContext(context);
63
83
  }
64
84
 
65
- const noop = (): void => {
66
- // do nothing
67
- };
68
-
69
85
  const returnNegative1 = (): number => -1;
70
86
 
71
87
  /**
@@ -193,6 +209,7 @@ export function useKeyboardMovementProvider<E extends HTMLElement>(
193
209
  options: KeyboardMovementProviderOptions<E> = {}
194
210
  ): KeyboardMovementProviderImplementation<E> {
195
211
  const {
212
+ ref: propRef,
196
213
  onClick = noop,
197
214
  onFocus = noop,
198
215
  onKeyDown = noop,
@@ -200,6 +217,7 @@ export function useKeyboardMovementProvider<E extends HTMLElement>(
200
217
  disabled,
201
218
  searchable = false,
202
219
  horizontal = false,
220
+ trackTabKeys = false,
203
221
  includeDisabled = false,
204
222
  tabIndexBehavior,
205
223
  extendKeyDown = noop,
@@ -214,6 +232,8 @@ export function useKeyboardMovementProvider<E extends HTMLElement>(
214
232
  isNegativeOneAllowed = false,
215
233
  } = options;
216
234
 
235
+ const [nodeRef, nodeRefCallback] = useEnsuredRef(propRef);
236
+
217
237
  const isRTL = useDir().dir === "rtl";
218
238
  let defaults: Readonly<Required<KeyboardMovementConfiguration>>;
219
239
  if (horizontal) {
@@ -240,29 +260,10 @@ export function useKeyboardMovementProvider<E extends HTMLElement>(
240
260
  config.current = configuration;
241
261
  });
242
262
 
243
- const [activeDescendantId, setActiveDescendantId] = useState("");
244
- const movementContext = useMemo<KeyboardMovementContext>(
245
- () => ({
246
- config,
247
- loopable,
248
- searchable,
249
- horizontal,
250
- includeDisabled,
251
- tabIndexBehavior,
252
- activeDescendantId,
253
- }),
254
- [
255
- activeDescendantId,
256
- horizontal,
257
- includeDisabled,
258
- loopable,
259
- searchable,
260
- tabIndexBehavior,
261
- ]
262
- );
263
- const currentFocusIndex = useRef(-1);
264
263
  const mode = useUserInteractionMode();
265
264
  const refocus = useRef(false);
265
+ const currentFocusIndex = useRef(-1);
266
+ const [activeDescendantId, setActiveDescendantId] = useState("");
266
267
 
267
268
  if (process.env.NODE_ENV !== "production") {
268
269
  // this fixes issues during hot reloading and using the `useId()` hook
@@ -282,10 +283,155 @@ export function useKeyboardMovementProvider<E extends HTMLElement>(
282
283
  : 0;
283
284
  }
284
285
 
286
+ const getFocusableElementsFromRef = useCallback(() => {
287
+ const container = nodeRef.current;
288
+ if (!container) {
289
+ return [];
290
+ }
291
+
292
+ return getFocusableElements(container, programmatic);
293
+ }, [getFocusableElements, nodeRef, programmatic]);
294
+ const updateFocusIndex = useCallback(
295
+ (index: number, focusables = getFocusableElementsFromRef()) => {
296
+ if (currentFocusIndex.current === index || index === -1) {
297
+ return;
298
+ }
299
+
300
+ currentFocusIndex.current = index;
301
+ const focused = focusables[index];
302
+ if (tabIndexBehavior) {
303
+ focused.scrollIntoView({
304
+ block: "nearest",
305
+ inline: "nearest",
306
+ });
307
+ setActiveDescendantId(focused.id);
308
+ }
309
+
310
+ if (tabIndexBehavior !== "virtual") {
311
+ focused.focus();
312
+ }
313
+
314
+ onFocusChange({
315
+ index,
316
+ element: focused,
317
+ });
318
+ },
319
+ [getFocusableElementsFromRef, onFocusChange, tabIndexBehavior]
320
+ );
321
+
322
+ const focusNext = useCallback(
323
+ (focusables = getFocusableElementsFromRef()) => {
324
+ updateFocusIndex(
325
+ getNextFocusableIndex({
326
+ loopable,
327
+ increment: true,
328
+ focusables,
329
+ includeDisabled: true,
330
+ currentFocusIndex: currentFocusIndex.current,
331
+ }),
332
+ focusables
333
+ );
334
+ },
335
+ [getFocusableElementsFromRef, loopable, updateFocusIndex]
336
+ );
337
+ const focusPrevious = useCallback(
338
+ (focusables = getFocusableElementsFromRef()) => {
339
+ updateFocusIndex(
340
+ getNextFocusableIndex({
341
+ loopable,
342
+ increment: false,
343
+ focusables,
344
+ includeDisabled: true,
345
+ currentFocusIndex: currentFocusIndex.current,
346
+ }),
347
+ focusables
348
+ );
349
+ },
350
+ [getFocusableElementsFromRef, loopable, updateFocusIndex]
351
+ );
352
+ const focusFirst = useCallback(
353
+ (focusables = getFocusableElementsFromRef()) => {
354
+ updateFocusIndex(
355
+ getFirstFocusableIndex({
356
+ focusables,
357
+ includeDisabled,
358
+ }),
359
+ focusables
360
+ );
361
+ },
362
+ [getFocusableElementsFromRef, includeDisabled, updateFocusIndex]
363
+ );
364
+ const focusLast = useCallback(
365
+ (focusables = getFocusableElementsFromRef()) => {
366
+ updateFocusIndex(
367
+ getLastFocusableIndex({
368
+ focusables,
369
+ includeDisabled,
370
+ }),
371
+ focusables
372
+ );
373
+ },
374
+ [getFocusableElementsFromRef, includeDisabled, updateFocusIndex]
375
+ );
376
+ const focusFromKey = useCallback(
377
+ (options: KeyboardFocusFromKeyOptions) => {
378
+ const {
379
+ key,
380
+ reversed,
381
+ focusables = getFocusableElementsFromRef(),
382
+ } = options;
383
+ if (!searchable) {
384
+ return;
385
+ }
386
+
387
+ const index = findMatchIndex({
388
+ value: key,
389
+ values: focusables.map((element) =>
390
+ getSearchText(element, !isNotFocusable(element, includeDisabled))
391
+ ),
392
+ startIndex: reversed ? -1 : currentFocusIndex.current,
393
+ });
394
+ updateFocusIndex(index, focusables);
395
+ },
396
+ [getFocusableElementsFromRef, includeDisabled, searchable, updateFocusIndex]
397
+ );
398
+
399
+ const movementContext = useMemo<KeyboardMovementContext>(
400
+ () => ({
401
+ config,
402
+ loopable,
403
+ searchable,
404
+ horizontal,
405
+ focusFirst,
406
+ focusLast,
407
+ focusNext,
408
+ focusPrevious,
409
+ focusFromKey,
410
+ includeDisabled,
411
+ tabIndexBehavior,
412
+ activeDescendantId,
413
+ }),
414
+ [
415
+ activeDescendantId,
416
+ focusFirst,
417
+ focusFromKey,
418
+ focusLast,
419
+ focusNext,
420
+ focusPrevious,
421
+ horizontal,
422
+ includeDisabled,
423
+ loopable,
424
+ searchable,
425
+ tabIndexBehavior,
426
+ ]
427
+ );
428
+
285
429
  return {
430
+ nodeRef,
286
431
  movementProps: {
287
432
  "aria-activedescendant":
288
433
  tabIndexBehavior === "virtual" ? activeDescendantId : undefined,
434
+ ref: nodeRefCallback,
289
435
  tabIndex,
290
436
 
291
437
  // Note: This used to be on the `onFocus` event, but this causes issues in
@@ -411,28 +557,7 @@ export function useKeyboardMovementProvider<E extends HTMLElement>(
411
557
  ): void => {
412
558
  event.preventDefault();
413
559
  event.stopPropagation();
414
- if (currentFocusIndex.current === index || index === -1) {
415
- return;
416
- }
417
-
418
- currentFocusIndex.current = index;
419
- const focused = focusables[index];
420
- if (tabIndexBehavior) {
421
- focused.scrollIntoView({
422
- block: "nearest",
423
- inline: "nearest",
424
- });
425
- setActiveDescendantId(focused.id);
426
- }
427
-
428
- if (tabIndexBehavior !== "virtual") {
429
- focused.focus();
430
- }
431
-
432
- onFocusChange({
433
- index,
434
- element: focused,
435
- });
560
+ updateFocusIndex(index, focusables);
436
561
  };
437
562
 
438
563
  extendKeyDown({
@@ -487,15 +612,14 @@ export function useKeyboardMovementProvider<E extends HTMLElement>(
487
612
  } = config.current;
488
613
 
489
614
  if (searchable && isSearchableEvent(event)) {
490
- const focusables = getFocusableElements(currentTarget, programmatic);
491
- const index = findMatchIndex({
492
- value: key,
493
- values: focusables.map((element) =>
494
- getSearchText(element, !isNotFocusable(element, includeDisabled))
495
- ),
496
- startIndex: shiftKey ? -1 : currentFocusIndex.current,
497
- });
498
- setFocusIndex(index, focusables);
615
+ event.preventDefault();
616
+ event.stopPropagation();
617
+ focusFromKey({ key, reversed: shiftKey });
618
+ return;
619
+ }
620
+
621
+ if (trackTabKeys && key === "Tab") {
622
+ currentFocusIndex.current += event.shiftKey ? -1 : 1;
499
623
  return;
500
624
  }
501
625
 
@@ -509,33 +633,23 @@ export function useKeyboardMovementProvider<E extends HTMLElement>(
509
633
  !increment &&
510
634
  decrementKeys.includes(key);
511
635
 
512
- if (!jumpToFirst && !jumpToLast && !increment && !decrement) {
513
- return;
514
- }
515
- const focusables = getFocusableElements(currentTarget, programmatic);
516
-
517
- let index: number;
518
636
  if (jumpToFirst) {
519
- index = getFirstFocusableIndex({
520
- focusables,
521
- includeDisabled,
522
- });
637
+ event.preventDefault();
638
+ event.stopPropagation();
639
+ focusFirst();
523
640
  } else if (jumpToLast) {
524
- index = getLastFocusableIndex({
525
- focusables,
526
- includeDisabled,
527
- });
528
- } else {
529
- index = getNextFocusableIndex({
530
- loopable,
531
- increment,
532
- focusables,
533
- includeDisabled,
534
- currentFocusIndex: currentFocusIndex.current,
535
- });
641
+ event.preventDefault();
642
+ event.stopPropagation();
643
+ focusLast();
644
+ } else if (increment) {
645
+ event.preventDefault();
646
+ event.stopPropagation();
647
+ focusNext();
648
+ } else if (decrement) {
649
+ event.preventDefault();
650
+ event.stopPropagation();
651
+ focusPrevious();
536
652
  }
537
-
538
- setFocusIndex(index, focusables);
539
653
  },
540
654
  },
541
655
  movementContext,
@@ -1,11 +1,15 @@
1
1
  import { type LiHTMLAttributes, type ReactNode, forwardRef } from "react";
2
2
 
3
- import { navItem } from "./navItemStyles.js";
3
+ import { type NavItemClassNameOptions, navItem } from "./navItemStyles.js";
4
4
 
5
5
  /**
6
6
  * @since 6.0.0
7
+ * @since 6.3.1 Extends NavItemClassNameOptions to allow for CSS properties
8
+ * augmentation.
7
9
  */
8
- export interface NavItemProps extends LiHTMLAttributes<HTMLLIElement> {
10
+ export interface NavItemProps
11
+ extends LiHTMLAttributes<HTMLLIElement>,
12
+ NavItemClassNameOptions {
9
13
  children: ReactNode;
10
14
  }
11
15
 
@@ -6,6 +6,14 @@ import { bem } from "../utils/bem.js";
6
6
 
7
7
  const styles = bem("rmd-nav-item");
8
8
 
9
+ declare module "react" {
10
+ interface CSSProperties {
11
+ "--rmd-navigation-border-radius"?: string | number;
12
+ "--rmd-navigation-horizontal-padding"?: string | number;
13
+ "--rmd-navigation-padding-incrementor"?: string | number;
14
+ }
15
+ }
16
+
9
17
  /**
10
18
  * @since 6.0.0
11
19
  */
@@ -3,7 +3,6 @@
3
3
  import { type HTMLAttributes, forwardRef } from "react";
4
4
 
5
5
  import { useSsr } from "../SsrProvider.js";
6
- import { type BoxAlignItems, type BoxJustifyContent } from "../box/styles.js";
7
6
  import { Portal } from "../portal/Portal.js";
8
7
  import {
9
8
  type CSSTransitionComponentProps,
@@ -11,44 +10,23 @@ import {
11
10
  } from "../transition/types.js";
12
11
  import { useCSSTransition } from "../transition/useCSSTransition.js";
13
12
  import {
13
+ type BaseOverlayClassNameOptions,
14
14
  DEFAULT_OVERLAY_CLASSNAMES,
15
15
  DEFAULT_OVERLAY_TIMEOUT,
16
16
  overlay,
17
17
  } from "./styles.js";
18
18
 
19
- declare module "react" {
20
- interface CSSProperties {
21
- "--rmd-overlay-background-color"?: string;
22
- "--rmd-overlay-z-index"?: number;
23
- }
24
- }
25
-
26
19
  /**
27
20
  * @since 6.0.0 Added `align` and `justify` props.
28
21
  * @since 6.0.0 Renamed `hidden` to `noOpacity`.
22
+ * @since 6.3.1 Extends BaseOverlayClassNameOptions for CSSProperties module
23
+ * augmentation.
29
24
  */
30
25
  export interface OverlayProps
31
26
  extends HTMLAttributes<HTMLSpanElement>,
27
+ BaseOverlayClassNameOptions,
32
28
  CSSTransitionComponentProps,
33
29
  TransitionActions {
34
- /**
35
- * @defaultValue `"center"`
36
- * @since 6.0.0
37
- */
38
- align?: BoxAlignItems;
39
-
40
- /**
41
- * @defaultValue `"center"`
42
- * @since 6.0.0
43
- */
44
- justify?: BoxJustifyContent;
45
-
46
- /**
47
- * Set this to `true` for when the overlay should be visible. Toggling this
48
- * value will trigger the enter/exit animation.
49
- */
50
- visible: boolean;
51
-
52
30
  /**
53
31
  * Set this to `true` if the overlay should be rendered with an `opacity: 0`
54
32
  * and disabling the animation. This is useful if you'd like a "close on