@stack-spot/portal-components 2.26.0 → 2.27.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 (237) hide show
  1. package/CHANGELOG.md +621 -614
  2. package/dist/components/AnimatedHeight.d.ts +1 -1
  3. package/dist/components/AnimatedHeight.js +26 -26
  4. package/dist/components/AsyncContent.d.ts +1 -1
  5. package/dist/components/AsyncContent.js +1 -1
  6. package/dist/components/BannerWarning.d.ts +1 -1
  7. package/dist/components/BannerWarning.js +1 -1
  8. package/dist/components/Breadcrumb/index.d.ts +2 -2
  9. package/dist/components/Breadcrumb/index.js +1 -1
  10. package/dist/components/Breadcrumb/styled.js +31 -31
  11. package/dist/components/ButtonLoading.d.ts +1 -1
  12. package/dist/components/ButtonLoading.js +1 -1
  13. package/dist/components/ChatBot.d.ts +1 -1
  14. package/dist/components/ChatBot.js +1 -1
  15. package/dist/components/ContentValidateFilter.d.ts +1 -1
  16. package/dist/components/ContentValidateFilter.js +1 -1
  17. package/dist/components/FadingOverflow.d.ts +1 -1
  18. package/dist/components/FadingOverflow.js +69 -69
  19. package/dist/components/FileTreeView/More.d.ts +1 -1
  20. package/dist/components/FileTreeView/More.js +1 -1
  21. package/dist/components/FileTreeView/index.d.ts +1 -1
  22. package/dist/components/FileTreeView/index.js +1 -1
  23. package/dist/components/InfiniteScroll.d.ts +1 -1
  24. package/dist/components/InfiniteScroll.js +1 -1
  25. package/dist/components/InfoMaintenanceBanner.d.ts +1 -1
  26. package/dist/components/InfoMaintenanceBanner.js +2 -2
  27. package/dist/components/LazyMarkdown/BlockquoteMd.d.ts +1 -1
  28. package/dist/components/LazyMarkdown/BlockquoteMd.js +1 -1
  29. package/dist/components/LazyMarkdown/CodeViewer.d.ts +1 -1
  30. package/dist/components/LazyMarkdown/CodeViewer.js +76 -76
  31. package/dist/components/LazyMarkdown/Markdown.d.ts +1 -1
  32. package/dist/components/LazyMarkdown/Markdown.js +1 -1
  33. package/dist/components/LazyMarkdown/MarkdownButton.d.ts +1 -1
  34. package/dist/components/LazyMarkdown/MarkdownButton.js +1 -1
  35. package/dist/components/LazyMarkdown/Video.d.ts +1 -1
  36. package/dist/components/LazyMarkdown/Video.js +1 -1
  37. package/dist/components/LazyMarkdown/index.d.ts +1 -1
  38. package/dist/components/LazyMarkdown/index.js +1 -1
  39. package/dist/components/Placeholder.d.ts +3 -3
  40. package/dist/components/Placeholder.js +1 -1
  41. package/dist/components/ScrollView.js +16 -16
  42. package/dist/components/Select/BadgeItem.d.ts +1 -1
  43. package/dist/components/Select/BadgeItem.js +1 -1
  44. package/dist/components/Select/ClearInput.d.ts +1 -1
  45. package/dist/components/Select/ClearInput.js +1 -1
  46. package/dist/components/Select/CloseItem.d.ts +1 -1
  47. package/dist/components/Select/CloseItem.js +1 -1
  48. package/dist/components/Select/CreatableSelect.js +1 -1
  49. package/dist/components/Select/CustomMenu.d.ts +1 -1
  50. package/dist/components/Select/CustomMenu.js +1 -1
  51. package/dist/components/Select/LabelItem.d.ts +1 -1
  52. package/dist/components/Select/LabelItem.js +1 -1
  53. package/dist/components/Select/MultiValue.d.ts +1 -1
  54. package/dist/components/Select/MultiValue.js +1 -1
  55. package/dist/components/Select/SelectInfiniteScroll.d.ts +1 -1
  56. package/dist/components/Select/SelectInfiniteScroll.js +1 -1
  57. package/dist/components/Select/SelectSearch.d.ts +1 -1
  58. package/dist/components/Select/SelectSearch.js +1 -1
  59. package/dist/components/SelectionList.d.ts +1 -1
  60. package/dist/components/SelectionList.js +61 -61
  61. package/dist/components/StatusCircle.d.ts +1 -1
  62. package/dist/components/StatusCircle.js +6 -6
  63. package/dist/components/Stepper/Navigation.js +4 -4
  64. package/dist/components/Stepper/Step.js +3 -3
  65. package/dist/components/Stepper/Stepper.js +6 -6
  66. package/dist/components/Stepper/headers.js +22 -22
  67. package/dist/components/Table/HeaderItem.js +1 -1
  68. package/dist/components/Table/SettingsVerticalMenu.d.ts +1 -1
  69. package/dist/components/Table/SettingsVerticalMenu.js +1 -1
  70. package/dist/components/Table/StyledLinkTable.d.ts +1 -1
  71. package/dist/components/Table/StyledLinkTable.js +5 -5
  72. package/dist/components/Table/TableData.d.ts +1 -1
  73. package/dist/components/Table/TableData.js +25 -25
  74. package/dist/components/TimelineSection.d.ts +1 -1
  75. package/dist/components/TimelineSection.js +14 -14
  76. package/dist/components/error/ErrorFeedback.d.ts +1 -1
  77. package/dist/components/error/ErrorFeedback.js +35 -35
  78. package/dist/components/error/NotFound.d.ts +1 -1
  79. package/dist/components/error/NotFound.js +1 -1
  80. package/dist/components/error/UnderMaintenance.d.ts +1 -1
  81. package/dist/components/error/UnderMaintenance.js +1 -1
  82. package/dist/components/form/Form/Form.d.ts +1 -1
  83. package/dist/components/form/Form/Form.js +1 -1
  84. package/dist/components/form/Form/FormGroup.d.ts +2 -2
  85. package/dist/components/form/Form/FormGroup.js +1 -1
  86. package/dist/components/form/SearchInput.d.ts +1 -1
  87. package/dist/components/form/SearchInput.js +1 -1
  88. package/dist/components/form/Select/CustomSelect.d.ts +1 -1
  89. package/dist/components/form/Select/CustomSelect.js +1 -1
  90. package/dist/components/form/Select/DetailedSelect.d.ts +1 -1
  91. package/dist/components/form/Select/DetailedSelect.js +1 -1
  92. package/dist/components/form/Select/Select.d.ts +1 -1
  93. package/dist/components/form/Select/Select.js +1 -1
  94. package/dist/components/form/Select/styled.js +161 -161
  95. package/dist/components/form/Select/utils.js +1 -1
  96. package/dist/components/notification/NotificationComponent.d.ts +1 -1
  97. package/dist/components/notification/NotificationComponent.js +54 -54
  98. package/dist/components/notification/NotificationItem.d.ts +1 -1
  99. package/dist/components/notification/NotificationItem.js +1 -1
  100. package/dist/components/notification/NotificationList.d.ts +1 -1
  101. package/dist/components/notification/NotificationList.js +43 -43
  102. package/dist/components/notification/NotificationPlaceholder.d.ts +1 -1
  103. package/dist/components/notification/NotificationPlaceholder.js +9 -9
  104. package/dist/components/notification/NotificationPlaceholder.js.map +1 -1
  105. package/dist/containers/NotificationsPage.d.ts +1 -1
  106. package/dist/containers/NotificationsPage.js +10 -10
  107. package/dist/context/anchor.d.ts +1 -1
  108. package/dist/context/anchor.js +1 -1
  109. package/dist/context/loading.d.ts +1 -1
  110. package/dist/context/loading.js +1 -1
  111. package/dist/context/notification/context.d.ts +1 -1
  112. package/dist/context/notification/context.js +1 -1
  113. package/dist/hooks/date.js +1 -1
  114. package/dist/hooks/service-now.js +28 -28
  115. package/dist/svg/AI.d.ts +1 -1
  116. package/dist/svg/AI.js +1 -1
  117. package/dist/svg/CS.d.ts +1 -1
  118. package/dist/svg/CS.js +1 -1
  119. package/dist/svg/EDP.d.ts +1 -1
  120. package/dist/svg/EDP.js +1 -1
  121. package/dist/svg/Forbidden.d.ts +1 -1
  122. package/dist/svg/Forbidden.js +1 -1
  123. package/dist/svg/GenericPlaceholder.d.ts +1 -1
  124. package/dist/svg/GenericPlaceholder.js +1 -1
  125. package/dist/svg/HUB.d.ts +1 -1
  126. package/dist/svg/HUB.js +1 -1
  127. package/dist/svg/Logo.d.ts +1 -1
  128. package/dist/svg/Logo.js +1 -1
  129. package/dist/svg/MiniLogo.d.ts +1 -1
  130. package/dist/svg/MiniLogo.js +1 -1
  131. package/dist/svg/NotFound.d.ts +1 -1
  132. package/dist/svg/NotFound.js +1 -1
  133. package/dist/svg/ServerError.d.ts +1 -1
  134. package/dist/svg/ServerError.js +1 -1
  135. package/dist/svg/Unauthenticated.d.ts +1 -1
  136. package/dist/svg/Unauthenticated.js +1 -1
  137. package/package.json +6 -6
  138. package/readme.md +66 -66
  139. package/src/components/AnimatedHeight.tsx +174 -174
  140. package/src/components/AsyncContent.tsx +78 -78
  141. package/src/components/BannerWarning.tsx +91 -91
  142. package/src/components/Breadcrumb/index.tsx +76 -76
  143. package/src/components/Breadcrumb/styled.ts +37 -37
  144. package/src/components/ButtonLoading.tsx +29 -29
  145. package/src/components/ChatBot.tsx +82 -82
  146. package/src/components/ContentValidateFilter.tsx +15 -15
  147. package/src/components/FadingOverflow.tsx +265 -265
  148. package/src/components/FileTreeView/More.tsx +114 -114
  149. package/src/components/FileTreeView/index.tsx +186 -186
  150. package/src/components/InfiniteScroll.tsx +24 -24
  151. package/src/components/InfoMaintenanceBanner.tsx +29 -29
  152. package/src/components/LazyMarkdown/BlockquoteMd.tsx +107 -107
  153. package/src/components/LazyMarkdown/CodeViewer.tsx +161 -161
  154. package/src/components/LazyMarkdown/Markdown.tsx +122 -122
  155. package/src/components/LazyMarkdown/MarkdownButton.tsx +24 -24
  156. package/src/components/LazyMarkdown/Video.tsx +13 -13
  157. package/src/components/LazyMarkdown/index.tsx +21 -21
  158. package/src/components/Placeholder.tsx +118 -118
  159. package/src/components/ScrollView.tsx +57 -57
  160. package/src/components/Select/BadgeItem.tsx +58 -58
  161. package/src/components/Select/ClearInput.tsx +24 -24
  162. package/src/components/Select/CloseItem.tsx +38 -38
  163. package/src/components/Select/CreatableSelect.tsx +155 -155
  164. package/src/components/Select/CustomMenu.tsx +16 -16
  165. package/src/components/Select/LabelItem.tsx +8 -8
  166. package/src/components/Select/MultiValue.tsx +49 -49
  167. package/src/components/Select/SelectInfiniteScroll.tsx +82 -82
  168. package/src/components/Select/SelectSearch.tsx +195 -195
  169. package/src/components/Select/index.tsx +7 -7
  170. package/src/components/Select/types.ts +8 -8
  171. package/src/components/SelectionList.tsx +427 -427
  172. package/src/components/StatusCircle.tsx +67 -67
  173. package/src/components/Stepper/Navigation.tsx +97 -97
  174. package/src/components/Stepper/Step.tsx +30 -30
  175. package/src/components/Stepper/Stepper.tsx +113 -113
  176. package/src/components/Stepper/headers.tsx +64 -64
  177. package/src/components/Stepper/index.ts +3 -3
  178. package/src/components/Table/HeaderItem.tsx +52 -52
  179. package/src/components/Table/SettingsVerticalMenu.tsx +50 -50
  180. package/src/components/Table/StyledLinkTable.tsx +22 -22
  181. package/src/components/Table/TableData.tsx +251 -251
  182. package/src/components/Table/index.tsx +2 -2
  183. package/src/components/TimelineSection.tsx +66 -66
  184. package/src/components/error/ErrorFeedback.tsx +217 -217
  185. package/src/components/error/NotFound.tsx +24 -24
  186. package/src/components/error/UnderMaintenance.tsx +30 -30
  187. package/src/components/error/index.ts +4 -4
  188. package/src/components/form/Form/Form.tsx +101 -101
  189. package/src/components/form/Form/FormGroup.tsx +221 -221
  190. package/src/components/form/Form/index.ts +2 -2
  191. package/src/components/form/SearchInput.tsx +69 -69
  192. package/src/components/form/Select/CustomSelect.tsx +232 -232
  193. package/src/components/form/Select/DetailedSelect.tsx +85 -85
  194. package/src/components/form/Select/Select.tsx +67 -67
  195. package/src/components/form/Select/index.ts +4 -4
  196. package/src/components/form/Select/styled.ts +165 -165
  197. package/src/components/form/Select/types.ts +112 -112
  198. package/src/components/form/Select/utils.tsx +28 -28
  199. package/src/components/notification/NotificationComponent.tsx +340 -340
  200. package/src/components/notification/NotificationItem.tsx +336 -336
  201. package/src/components/notification/NotificationList.tsx +178 -178
  202. package/src/components/notification/NotificationPlaceholder.tsx +43 -43
  203. package/src/components/notification/types.ts +72 -72
  204. package/src/containers/NotificationsPage.tsx +98 -98
  205. package/src/context/anchor.tsx +37 -37
  206. package/src/context/loading.tsx +36 -36
  207. package/src/context/notification/LazyNotificationList.ts +103 -103
  208. package/src/context/notification/NotificationController.ts +104 -104
  209. package/src/context/notification/context.tsx +23 -23
  210. package/src/context/notification/hooks.ts +98 -98
  211. package/src/context/notification/types.ts +65 -65
  212. package/src/hooks/date.ts +31 -31
  213. package/src/hooks/keyboard.tsx +128 -128
  214. package/src/hooks/manual-render.tsx +10 -10
  215. package/src/hooks/service-now.tsx +233 -233
  216. package/src/hooks/text.tsx +30 -30
  217. package/src/hooks/title.tsx +28 -28
  218. package/src/hooks/use-effect-once.tsx +43 -43
  219. package/src/index.ts +19 -19
  220. package/src/notifications.ts +11 -11
  221. package/src/svg/AI.tsx +41 -41
  222. package/src/svg/CS.tsx +48 -48
  223. package/src/svg/EDP.tsx +31 -31
  224. package/src/svg/Forbidden.tsx +22 -22
  225. package/src/svg/GenericPlaceholder.tsx +20 -20
  226. package/src/svg/HUB.tsx +48 -48
  227. package/src/svg/Logo.tsx +16 -16
  228. package/src/svg/MiniLogo.tsx +12 -12
  229. package/src/svg/NotFound.tsx +16 -16
  230. package/src/svg/ServerError.tsx +33 -33
  231. package/src/svg/Unauthenticated.tsx +16 -16
  232. package/src/svg/index.ts +11 -11
  233. package/src/utils/accessibility.ts +135 -135
  234. package/src/utils/cookie.ts +73 -73
  235. package/src/utils/promise.ts +5 -5
  236. package/src/utils/read-file.ts +16 -16
  237. package/tsconfig.json +10 -10
@@ -1,128 +1,128 @@
1
- import { useCallback, useEffect, useRef } from 'react'
2
-
3
- interface Options<T extends HTMLElement = HTMLDivElement> {
4
- /**
5
- * A query selector that returns every html element that must be navigable through the keyboard.
6
- */
7
- querySelectors: string,
8
- /**
9
- * Function to call when ESC is pressed. or when TAB is pressed at the last item in the list of items returned by the query selector.
10
- */
11
- onPressEscape?: () => void,
12
- /**
13
- * Function to call when TAB is pressed at the last item in the list of items returned by the query selector. Will be the same as
14
- * onPressEscape if not specified.
15
- *
16
- * Attention: has no effect if `disableTabBehavior` is true.
17
- */
18
- onPressLastTab?: () => void,
19
- /**
20
- * Pass this function if you want any behavior when the user presses the arrow left.
21
- */
22
- onPressArrowLeft?: () => void,
23
- /**
24
- * Pass this function if you want any behavior when the user presses the arrow right.
25
- */
26
- onPressArrowRight?: () => void,
27
- /**
28
- * Disables any alteration to the tab key.
29
- * @default false
30
- */
31
- disableTabBehavior?: boolean,
32
- /**
33
- * If you already have a ref to the element you want to attach the events to, you can pass it in this prop.
34
- *
35
- * If you pass a ref. The events won't be attached to the document, instead, they will be attached to the element referred by the ref.
36
- */
37
- ref?: React.RefObject<T>,
38
- }
39
-
40
- /**
41
- * Creates listeners for controlling a Menu UI through the keyboard.
42
- * - Arrow down: next element in the iterator returned by the query selectors. First element, if the current element is the last.
43
- * - Arrow up: previous element in the iterator returned by the query selectors. Last element, if the current element is the first.
44
- * - Tab: same as Arrow down, but has a different behavior if the element is the last (see onPressLastTab).
45
- * - Esc: determined by onPressEscape.
46
- * @param props {@link Options}.
47
- * @returns an object with the element controlled by the keyboard (useRef); a function to attach the keyboard events and a function to
48
- * detach the keyboard events.
49
- */
50
- export function useKeyboardControls<T extends HTMLElement = HTMLDivElement>(
51
- /**
52
- * Options for the keyboard controls.
53
- */
54
- {
55
- querySelectors, onPressEscape, onPressLastTab = onPressEscape, onPressArrowLeft, onPressArrowRight, disableTabBehavior, ref,
56
- }: Options<T>,
57
- /**
58
- * Calls `attachKeyboardListeners` (mount) and `detachKeyboardListeners` (unmount) whenever the deps passed as parameter changes.
59
- *
60
- * If deps are undefined, this component doesn't automatically add these listeners and you have to use the functions returned in the
61
- * result.
62
- */
63
- deps?: any[],
64
- ) {
65
- const localRef = useRef<T>(null)
66
- const keyboardControlledElement = ref ?? localRef
67
- const listeners = useRef<Pick<Options, 'onPressEscape' | 'onPressLastTab'>>({})
68
- listeners.current = { onPressEscape, onPressLastTab }
69
-
70
- const keyboardControls = useCallback((event: Event) => {
71
- const eventKey = (event as KeyboardEvent).key
72
- const target = event?.target as HTMLElement | null
73
-
74
- function getSelectableAnchors() {
75
- return keyboardControlledElement.current?.querySelectorAll(querySelectors) ?? []
76
- }
77
-
78
- function handleArrows(key = eventKey) {
79
- const anchors = getSelectableAnchors()
80
- let i = 0
81
- while (i < anchors.length && document.activeElement !== anchors[i]) i++
82
- const next: any = key === 'ArrowDown' ? (anchors[i + 1] ?? anchors[0]) : (anchors[i - 1] ?? anchors[anchors.length - 1])
83
- next?.focus?.()
84
- }
85
-
86
- const handlers: Record<string, (() => void) | undefined> = {
87
- Escape: () => {
88
- listeners.current.onPressEscape?.()
89
- event.stopPropagation()
90
- event.preventDefault()
91
- },
92
- Enter: () => {
93
- target?.click()
94
- },
95
- Tab: () => {
96
- if (disableTabBehavior) return
97
- const anchors = getSelectableAnchors()
98
- if (document.activeElement === anchors[anchors.length - 1]) listeners.current.onPressLastTab?.()
99
- else handleArrows('ArrowDown')
100
- event.preventDefault()
101
- },
102
- ArrowUp: handleArrows,
103
- ArrowDown: handleArrows,
104
- ArrowLeft: onPressArrowLeft,
105
- ArrowRight: onPressArrowRight,
106
- }
107
-
108
- handlers[eventKey]?.()
109
- }, [])
110
-
111
- const attachKeyboardListeners = useCallback(() => {
112
- const element = ref?.current ?? document
113
- element.addEventListener('keydown', keyboardControls)
114
- }, [])
115
-
116
- const detachKeyboardListeners = useCallback(() => {
117
- const element = ref?.current ?? document
118
- element.removeEventListener('keydown', keyboardControls)
119
- }, [])
120
-
121
- useEffect(() => {
122
- if (!deps) return
123
- attachKeyboardListeners()
124
- return detachKeyboardListeners
125
- }, deps)
126
-
127
- return { keyboardControlledElement, attachKeyboardListeners, detachKeyboardListeners }
128
- }
1
+ import { useCallback, useEffect, useRef } from 'react'
2
+
3
+ interface Options<T extends HTMLElement = HTMLDivElement> {
4
+ /**
5
+ * A query selector that returns every html element that must be navigable through the keyboard.
6
+ */
7
+ querySelectors: string,
8
+ /**
9
+ * Function to call when ESC is pressed. or when TAB is pressed at the last item in the list of items returned by the query selector.
10
+ */
11
+ onPressEscape?: () => void,
12
+ /**
13
+ * Function to call when TAB is pressed at the last item in the list of items returned by the query selector. Will be the same as
14
+ * onPressEscape if not specified.
15
+ *
16
+ * Attention: has no effect if `disableTabBehavior` is true.
17
+ */
18
+ onPressLastTab?: () => void,
19
+ /**
20
+ * Pass this function if you want any behavior when the user presses the arrow left.
21
+ */
22
+ onPressArrowLeft?: () => void,
23
+ /**
24
+ * Pass this function if you want any behavior when the user presses the arrow right.
25
+ */
26
+ onPressArrowRight?: () => void,
27
+ /**
28
+ * Disables any alteration to the tab key.
29
+ * @default false
30
+ */
31
+ disableTabBehavior?: boolean,
32
+ /**
33
+ * If you already have a ref to the element you want to attach the events to, you can pass it in this prop.
34
+ *
35
+ * If you pass a ref. The events won't be attached to the document, instead, they will be attached to the element referred by the ref.
36
+ */
37
+ ref?: React.RefObject<T>,
38
+ }
39
+
40
+ /**
41
+ * Creates listeners for controlling a Menu UI through the keyboard.
42
+ * - Arrow down: next element in the iterator returned by the query selectors. First element, if the current element is the last.
43
+ * - Arrow up: previous element in the iterator returned by the query selectors. Last element, if the current element is the first.
44
+ * - Tab: same as Arrow down, but has a different behavior if the element is the last (see onPressLastTab).
45
+ * - Esc: determined by onPressEscape.
46
+ * @param props {@link Options}.
47
+ * @returns an object with the element controlled by the keyboard (useRef); a function to attach the keyboard events and a function to
48
+ * detach the keyboard events.
49
+ */
50
+ export function useKeyboardControls<T extends HTMLElement = HTMLDivElement>(
51
+ /**
52
+ * Options for the keyboard controls.
53
+ */
54
+ {
55
+ querySelectors, onPressEscape, onPressLastTab = onPressEscape, onPressArrowLeft, onPressArrowRight, disableTabBehavior, ref,
56
+ }: Options<T>,
57
+ /**
58
+ * Calls `attachKeyboardListeners` (mount) and `detachKeyboardListeners` (unmount) whenever the deps passed as parameter changes.
59
+ *
60
+ * If deps are undefined, this component doesn't automatically add these listeners and you have to use the functions returned in the
61
+ * result.
62
+ */
63
+ deps?: any[],
64
+ ) {
65
+ const localRef = useRef<T>(null)
66
+ const keyboardControlledElement = ref ?? localRef
67
+ const listeners = useRef<Pick<Options, 'onPressEscape' | 'onPressLastTab'>>({})
68
+ listeners.current = { onPressEscape, onPressLastTab }
69
+
70
+ const keyboardControls = useCallback((event: Event) => {
71
+ const eventKey = (event as KeyboardEvent).key
72
+ const target = event?.target as HTMLElement | null
73
+
74
+ function getSelectableAnchors() {
75
+ return keyboardControlledElement.current?.querySelectorAll(querySelectors) ?? []
76
+ }
77
+
78
+ function handleArrows(key = eventKey) {
79
+ const anchors = getSelectableAnchors()
80
+ let i = 0
81
+ while (i < anchors.length && document.activeElement !== anchors[i]) i++
82
+ const next: any = key === 'ArrowDown' ? (anchors[i + 1] ?? anchors[0]) : (anchors[i - 1] ?? anchors[anchors.length - 1])
83
+ next?.focus?.()
84
+ }
85
+
86
+ const handlers: Record<string, (() => void) | undefined> = {
87
+ Escape: () => {
88
+ listeners.current.onPressEscape?.()
89
+ event.stopPropagation()
90
+ event.preventDefault()
91
+ },
92
+ Enter: () => {
93
+ target?.click()
94
+ },
95
+ Tab: () => {
96
+ if (disableTabBehavior) return
97
+ const anchors = getSelectableAnchors()
98
+ if (document.activeElement === anchors[anchors.length - 1]) listeners.current.onPressLastTab?.()
99
+ else handleArrows('ArrowDown')
100
+ event.preventDefault()
101
+ },
102
+ ArrowUp: handleArrows,
103
+ ArrowDown: handleArrows,
104
+ ArrowLeft: onPressArrowLeft,
105
+ ArrowRight: onPressArrowRight,
106
+ }
107
+
108
+ handlers[eventKey]?.()
109
+ }, [])
110
+
111
+ const attachKeyboardListeners = useCallback(() => {
112
+ const element = ref?.current ?? document
113
+ element.addEventListener('keydown', keyboardControls)
114
+ }, [])
115
+
116
+ const detachKeyboardListeners = useCallback(() => {
117
+ const element = ref?.current ?? document
118
+ element.removeEventListener('keydown', keyboardControls)
119
+ }, [])
120
+
121
+ useEffect(() => {
122
+ if (!deps) return
123
+ attachKeyboardListeners()
124
+ return detachKeyboardListeners
125
+ }, deps)
126
+
127
+ return { keyboardControlledElement, attachKeyboardListeners, detachKeyboardListeners }
128
+ }
@@ -1,10 +1,10 @@
1
- import { useCallback, useState } from 'react'
2
-
3
- /**
4
- * Use this hook to manually trigger a re-render from React.
5
- * @returns an object with a function to re-render the component.
6
- */
7
- export function useManualRender() {
8
- const [, setCount] = useState(0)
9
- return { repaint: useCallback(() => setCount(v => v + 1), []) }
10
- }
1
+ import { useCallback, useState } from 'react'
2
+
3
+ /**
4
+ * Use this hook to manually trigger a re-render from React.
5
+ * @returns an object with a function to re-render the component.
6
+ */
7
+ export function useManualRender() {
8
+ const [, setCount] = useState(0)
9
+ return { repaint: useCallback(() => setCount(v => v + 1), []) }
10
+ }