@stack-spot/portal-components 2.27.1 → 2.27.3

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 (247) hide show
  1. package/CHANGELOG.md +642 -628
  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 +7 -3
  40. package/dist/components/Placeholder.d.ts.map +1 -1
  41. package/dist/components/Placeholder.js +3 -3
  42. package/dist/components/Placeholder.js.map +1 -1
  43. package/dist/components/ScrollView.js +16 -16
  44. package/dist/components/Select/BadgeItem.d.ts +1 -1
  45. package/dist/components/Select/BadgeItem.js +1 -1
  46. package/dist/components/Select/ClearInput.d.ts +1 -1
  47. package/dist/components/Select/ClearInput.js +1 -1
  48. package/dist/components/Select/CloseItem.d.ts +1 -1
  49. package/dist/components/Select/CloseItem.js +1 -1
  50. package/dist/components/Select/CreatableSelect.js +1 -1
  51. package/dist/components/Select/CustomMenu.d.ts +1 -1
  52. package/dist/components/Select/CustomMenu.js +1 -1
  53. package/dist/components/Select/LabelItem.d.ts +1 -1
  54. package/dist/components/Select/LabelItem.js +1 -1
  55. package/dist/components/Select/MultiValue.d.ts +1 -1
  56. package/dist/components/Select/MultiValue.js +1 -1
  57. package/dist/components/Select/SelectInfiniteScroll.d.ts +1 -1
  58. package/dist/components/Select/SelectInfiniteScroll.js +1 -1
  59. package/dist/components/Select/SelectSearch.d.ts +1 -1
  60. package/dist/components/Select/SelectSearch.js +1 -1
  61. package/dist/components/SelectionList.d.ts +1 -1
  62. package/dist/components/SelectionList.js +62 -62
  63. package/dist/components/SelectionList.js.map +1 -1
  64. package/dist/components/StatusCircle.d.ts +1 -1
  65. package/dist/components/StatusCircle.js +6 -6
  66. package/dist/components/Stepper/Navigation.js +4 -4
  67. package/dist/components/Stepper/Step.js +3 -3
  68. package/dist/components/Stepper/Stepper.js +6 -6
  69. package/dist/components/Stepper/headers.js +22 -22
  70. package/dist/components/Table/HeaderItem.js +1 -1
  71. package/dist/components/Table/SettingsVerticalMenu.d.ts +1 -1
  72. package/dist/components/Table/SettingsVerticalMenu.js +1 -1
  73. package/dist/components/Table/StyledLinkTable.d.ts +1 -1
  74. package/dist/components/Table/StyledLinkTable.js +5 -5
  75. package/dist/components/Table/TableData.d.ts +1 -1
  76. package/dist/components/Table/TableData.js +25 -25
  77. package/dist/components/TimelineSection.d.ts +1 -1
  78. package/dist/components/TimelineSection.js +14 -14
  79. package/dist/components/error/ErrorFeedback.d.ts +1 -1
  80. package/dist/components/error/ErrorFeedback.js +35 -35
  81. package/dist/components/error/NotFound.d.ts +1 -1
  82. package/dist/components/error/NotFound.js +1 -1
  83. package/dist/components/error/UnderMaintenance.d.ts +1 -1
  84. package/dist/components/error/UnderMaintenance.js +1 -1
  85. package/dist/components/form/Form/Form.d.ts +1 -1
  86. package/dist/components/form/Form/Form.js +1 -1
  87. package/dist/components/form/Form/FormGroup.d.ts +2 -2
  88. package/dist/components/form/Form/FormGroup.js +1 -1
  89. package/dist/components/form/SearchInput.d.ts +1 -1
  90. package/dist/components/form/SearchInput.js +1 -1
  91. package/dist/components/form/Select/CustomSelect.d.ts +1 -1
  92. package/dist/components/form/Select/CustomSelect.js +1 -1
  93. package/dist/components/form/Select/DetailedSelect.d.ts +1 -1
  94. package/dist/components/form/Select/DetailedSelect.js +1 -1
  95. package/dist/components/form/Select/Select.d.ts +1 -1
  96. package/dist/components/form/Select/Select.js +1 -1
  97. package/dist/components/form/Select/styled.js +161 -161
  98. package/dist/components/form/Select/utils.js +1 -1
  99. package/dist/components/notification/NotificationComponent.d.ts +1 -1
  100. package/dist/components/notification/NotificationComponent.js +54 -54
  101. package/dist/components/notification/NotificationItem.d.ts +1 -1
  102. package/dist/components/notification/NotificationItem.d.ts.map +1 -1
  103. package/dist/components/notification/NotificationItem.js +8 -2
  104. package/dist/components/notification/NotificationItem.js.map +1 -1
  105. package/dist/components/notification/NotificationList.d.ts +1 -1
  106. package/dist/components/notification/NotificationList.d.ts.map +1 -1
  107. package/dist/components/notification/NotificationList.js +44 -44
  108. package/dist/components/notification/NotificationList.js.map +1 -1
  109. package/dist/components/notification/NotificationPlaceholder.d.ts +1 -1
  110. package/dist/components/notification/NotificationPlaceholder.d.ts.map +1 -1
  111. package/dist/components/notification/NotificationPlaceholder.js +2 -2
  112. package/dist/components/notification/NotificationPlaceholder.js.map +1 -1
  113. package/dist/containers/NotificationsPage.d.ts +1 -1
  114. package/dist/containers/NotificationsPage.js +10 -10
  115. package/dist/context/anchor.d.ts +1 -1
  116. package/dist/context/anchor.js +1 -1
  117. package/dist/context/loading.d.ts +1 -1
  118. package/dist/context/loading.js +1 -1
  119. package/dist/context/notification/context.d.ts +1 -1
  120. package/dist/context/notification/context.js +1 -1
  121. package/dist/hooks/date.js +1 -1
  122. package/dist/hooks/service-now.js +28 -28
  123. package/dist/svg/AI.d.ts +1 -1
  124. package/dist/svg/AI.js +1 -1
  125. package/dist/svg/CS.d.ts +1 -1
  126. package/dist/svg/CS.js +1 -1
  127. package/dist/svg/EDP.d.ts +1 -1
  128. package/dist/svg/EDP.js +1 -1
  129. package/dist/svg/Forbidden.d.ts +1 -1
  130. package/dist/svg/Forbidden.js +1 -1
  131. package/dist/svg/GenericPlaceholder.d.ts +4 -2
  132. package/dist/svg/GenericPlaceholder.d.ts.map +1 -1
  133. package/dist/svg/GenericPlaceholder.js +2 -2
  134. package/dist/svg/GenericPlaceholder.js.map +1 -1
  135. package/dist/svg/HUB.d.ts +1 -1
  136. package/dist/svg/HUB.js +1 -1
  137. package/dist/svg/Logo.d.ts +1 -1
  138. package/dist/svg/Logo.js +1 -1
  139. package/dist/svg/MiniLogo.d.ts +1 -1
  140. package/dist/svg/MiniLogo.js +1 -1
  141. package/dist/svg/NotFound.d.ts +1 -1
  142. package/dist/svg/NotFound.js +1 -1
  143. package/dist/svg/ServerError.d.ts +1 -1
  144. package/dist/svg/ServerError.js +1 -1
  145. package/dist/svg/Unauthenticated.d.ts +1 -1
  146. package/dist/svg/Unauthenticated.js +1 -1
  147. package/package.json +80 -80
  148. package/readme.md +66 -66
  149. package/src/components/AnimatedHeight.tsx +174 -174
  150. package/src/components/AsyncContent.tsx +78 -78
  151. package/src/components/BannerWarning.tsx +91 -91
  152. package/src/components/Breadcrumb/index.tsx +76 -76
  153. package/src/components/Breadcrumb/styled.ts +37 -37
  154. package/src/components/ButtonLoading.tsx +29 -29
  155. package/src/components/ChatBot.tsx +82 -82
  156. package/src/components/ContentValidateFilter.tsx +15 -15
  157. package/src/components/FadingOverflow.tsx +265 -265
  158. package/src/components/FileTreeView/More.tsx +114 -114
  159. package/src/components/FileTreeView/index.tsx +186 -186
  160. package/src/components/InfiniteScroll.tsx +24 -24
  161. package/src/components/InfoMaintenanceBanner.tsx +29 -29
  162. package/src/components/LazyMarkdown/BlockquoteMd.tsx +107 -107
  163. package/src/components/LazyMarkdown/CodeViewer.tsx +161 -161
  164. package/src/components/LazyMarkdown/Markdown.tsx +122 -122
  165. package/src/components/LazyMarkdown/MarkdownButton.tsx +24 -24
  166. package/src/components/LazyMarkdown/Video.tsx +13 -13
  167. package/src/components/LazyMarkdown/index.tsx +21 -21
  168. package/src/components/Placeholder.tsx +123 -118
  169. package/src/components/ScrollView.tsx +57 -57
  170. package/src/components/Select/BadgeItem.tsx +58 -58
  171. package/src/components/Select/ClearInput.tsx +24 -24
  172. package/src/components/Select/CloseItem.tsx +38 -38
  173. package/src/components/Select/CreatableSelect.tsx +155 -155
  174. package/src/components/Select/CustomMenu.tsx +16 -16
  175. package/src/components/Select/LabelItem.tsx +8 -8
  176. package/src/components/Select/MultiValue.tsx +49 -49
  177. package/src/components/Select/SelectInfiniteScroll.tsx +82 -82
  178. package/src/components/Select/SelectSearch.tsx +195 -195
  179. package/src/components/Select/index.tsx +7 -7
  180. package/src/components/Select/types.ts +8 -8
  181. package/src/components/SelectionList.tsx +427 -427
  182. package/src/components/StatusCircle.tsx +67 -67
  183. package/src/components/Stepper/Navigation.tsx +97 -97
  184. package/src/components/Stepper/Step.tsx +30 -30
  185. package/src/components/Stepper/Stepper.tsx +113 -113
  186. package/src/components/Stepper/headers.tsx +64 -64
  187. package/src/components/Stepper/index.ts +3 -3
  188. package/src/components/Table/HeaderItem.tsx +52 -52
  189. package/src/components/Table/SettingsVerticalMenu.tsx +50 -50
  190. package/src/components/Table/StyledLinkTable.tsx +22 -22
  191. package/src/components/Table/TableData.tsx +251 -251
  192. package/src/components/Table/index.tsx +2 -2
  193. package/src/components/TimelineSection.tsx +66 -66
  194. package/src/components/error/ErrorFeedback.tsx +217 -217
  195. package/src/components/error/NotFound.tsx +24 -24
  196. package/src/components/error/UnderMaintenance.tsx +30 -30
  197. package/src/components/error/index.ts +4 -4
  198. package/src/components/form/Form/Form.tsx +101 -101
  199. package/src/components/form/Form/FormGroup.tsx +221 -221
  200. package/src/components/form/Form/index.ts +2 -2
  201. package/src/components/form/SearchInput.tsx +69 -69
  202. package/src/components/form/Select/CustomSelect.tsx +232 -232
  203. package/src/components/form/Select/DetailedSelect.tsx +85 -85
  204. package/src/components/form/Select/Select.tsx +67 -67
  205. package/src/components/form/Select/index.ts +4 -4
  206. package/src/components/form/Select/styled.ts +165 -165
  207. package/src/components/form/Select/types.ts +112 -112
  208. package/src/components/form/Select/utils.tsx +28 -28
  209. package/src/components/notification/NotificationComponent.tsx +340 -340
  210. package/src/components/notification/NotificationItem.tsx +345 -337
  211. package/src/components/notification/NotificationList.tsx +179 -178
  212. package/src/components/notification/NotificationPlaceholder.tsx +44 -43
  213. package/src/components/notification/types.ts +72 -72
  214. package/src/containers/NotificationsPage.tsx +119 -119
  215. package/src/context/anchor.tsx +37 -37
  216. package/src/context/loading.tsx +36 -36
  217. package/src/context/notification/LazyNotificationList.ts +103 -103
  218. package/src/context/notification/NotificationController.ts +104 -104
  219. package/src/context/notification/context.tsx +23 -23
  220. package/src/context/notification/hooks.ts +98 -98
  221. package/src/context/notification/types.ts +66 -66
  222. package/src/hooks/date.ts +31 -31
  223. package/src/hooks/keyboard.tsx +128 -128
  224. package/src/hooks/manual-render.tsx +10 -10
  225. package/src/hooks/service-now.tsx +233 -233
  226. package/src/hooks/text.tsx +30 -30
  227. package/src/hooks/title.tsx +28 -28
  228. package/src/hooks/use-effect-once.tsx +43 -43
  229. package/src/index.ts +19 -19
  230. package/src/notifications.ts +11 -11
  231. package/src/svg/AI.tsx +41 -41
  232. package/src/svg/CS.tsx +48 -48
  233. package/src/svg/EDP.tsx +31 -31
  234. package/src/svg/Forbidden.tsx +22 -22
  235. package/src/svg/GenericPlaceholder.tsx +20 -20
  236. package/src/svg/HUB.tsx +48 -48
  237. package/src/svg/Logo.tsx +16 -16
  238. package/src/svg/MiniLogo.tsx +12 -12
  239. package/src/svg/NotFound.tsx +16 -16
  240. package/src/svg/ServerError.tsx +33 -33
  241. package/src/svg/Unauthenticated.tsx +16 -16
  242. package/src/svg/index.ts +11 -11
  243. package/src/utils/accessibility.ts +135 -135
  244. package/src/utils/cookie.ts +73 -73
  245. package/src/utils/promise.ts +5 -5
  246. package/src/utils/read-file.ts +16 -16
  247. 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
+ }