@react-aria/utils 3.33.1 → 3.34.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 (262) hide show
  1. package/dist/import.mjs +47 -43
  2. package/dist/main.js +120 -115
  3. package/dist/main.js.map +1 -1
  4. package/dist/module.js +47 -43
  5. package/dist/module.js.map +1 -1
  6. package/dist/types/src/index.d.ts +45 -0
  7. package/package.json +15 -15
  8. package/src/index.ts +45 -43
  9. package/dist/DOMFunctions.main.js +0 -57
  10. package/dist/DOMFunctions.main.js.map +0 -1
  11. package/dist/DOMFunctions.mjs +0 -49
  12. package/dist/DOMFunctions.module.js +0 -49
  13. package/dist/DOMFunctions.module.js.map +0 -1
  14. package/dist/ShadowTreeWalker.main.js +0 -200
  15. package/dist/ShadowTreeWalker.main.js.map +0 -1
  16. package/dist/ShadowTreeWalker.mjs +0 -194
  17. package/dist/ShadowTreeWalker.module.js +0 -194
  18. package/dist/ShadowTreeWalker.module.js.map +0 -1
  19. package/dist/animation.main.js +0 -97
  20. package/dist/animation.main.js.map +0 -1
  21. package/dist/animation.mjs +0 -91
  22. package/dist/animation.module.js +0 -91
  23. package/dist/animation.module.js.map +0 -1
  24. package/dist/chain.main.js +0 -26
  25. package/dist/chain.main.js.map +0 -1
  26. package/dist/chain.mjs +0 -21
  27. package/dist/chain.module.js +0 -21
  28. package/dist/chain.module.js.map +0 -1
  29. package/dist/constants.main.js +0 -23
  30. package/dist/constants.main.js.map +0 -1
  31. package/dist/constants.mjs +0 -17
  32. package/dist/constants.module.js +0 -17
  33. package/dist/constants.module.js.map +0 -1
  34. package/dist/domHelpers.main.js +0 -28
  35. package/dist/domHelpers.main.js.map +0 -1
  36. package/dist/domHelpers.mjs +0 -21
  37. package/dist/domHelpers.module.js +0 -21
  38. package/dist/domHelpers.module.js.map +0 -1
  39. package/dist/filterDOMProps.main.js +0 -88
  40. package/dist/filterDOMProps.main.js.map +0 -1
  41. package/dist/filterDOMProps.mjs +0 -83
  42. package/dist/filterDOMProps.module.js +0 -83
  43. package/dist/filterDOMProps.module.js.map +0 -1
  44. package/dist/focusWithoutScrolling.main.js +0 -72
  45. package/dist/focusWithoutScrolling.main.js.map +0 -1
  46. package/dist/focusWithoutScrolling.mjs +0 -67
  47. package/dist/focusWithoutScrolling.module.js +0 -67
  48. package/dist/focusWithoutScrolling.module.js.map +0 -1
  49. package/dist/getOffset.main.js +0 -24
  50. package/dist/getOffset.main.js.map +0 -1
  51. package/dist/getOffset.mjs +0 -19
  52. package/dist/getOffset.module.js +0 -19
  53. package/dist/getOffset.module.js.map +0 -1
  54. package/dist/getScrollParent.main.js +0 -28
  55. package/dist/getScrollParent.main.js.map +0 -1
  56. package/dist/getScrollParent.mjs +0 -23
  57. package/dist/getScrollParent.module.js +0 -23
  58. package/dist/getScrollParent.module.js.map +0 -1
  59. package/dist/getScrollParents.main.js +0 -31
  60. package/dist/getScrollParents.main.js.map +0 -1
  61. package/dist/getScrollParents.mjs +0 -26
  62. package/dist/getScrollParents.module.js +0 -26
  63. package/dist/getScrollParents.module.js.map +0 -1
  64. package/dist/inertValue.main.js +0 -19
  65. package/dist/inertValue.main.js.map +0 -1
  66. package/dist/inertValue.mjs +0 -14
  67. package/dist/inertValue.module.js +0 -14
  68. package/dist/inertValue.module.js.map +0 -1
  69. package/dist/isElementVisible.main.js +0 -45
  70. package/dist/isElementVisible.main.js.map +0 -1
  71. package/dist/isElementVisible.mjs +0 -40
  72. package/dist/isElementVisible.module.js +0 -40
  73. package/dist/isElementVisible.module.js.map +0 -1
  74. package/dist/isFocusable.main.js +0 -56
  75. package/dist/isFocusable.main.js.map +0 -1
  76. package/dist/isFocusable.mjs +0 -50
  77. package/dist/isFocusable.module.js +0 -50
  78. package/dist/isFocusable.module.js.map +0 -1
  79. package/dist/isScrollable.main.js +0 -29
  80. package/dist/isScrollable.main.js.map +0 -1
  81. package/dist/isScrollable.mjs +0 -24
  82. package/dist/isScrollable.module.js +0 -24
  83. package/dist/isScrollable.module.js.map +0 -1
  84. package/dist/isVirtualEvent.main.js +0 -41
  85. package/dist/isVirtualEvent.main.js.map +0 -1
  86. package/dist/isVirtualEvent.mjs +0 -35
  87. package/dist/isVirtualEvent.module.js +0 -35
  88. package/dist/isVirtualEvent.module.js.map +0 -1
  89. package/dist/keyboard.main.js +0 -42
  90. package/dist/keyboard.main.js.map +0 -1
  91. package/dist/keyboard.mjs +0 -36
  92. package/dist/keyboard.module.js +0 -36
  93. package/dist/keyboard.module.js.map +0 -1
  94. package/dist/mergeProps.main.js +0 -54
  95. package/dist/mergeProps.main.js.map +0 -1
  96. package/dist/mergeProps.mjs +0 -45
  97. package/dist/mergeProps.module.js +0 -45
  98. package/dist/mergeProps.module.js.map +0 -1
  99. package/dist/mergeRefs.main.js +0 -40
  100. package/dist/mergeRefs.main.js.map +0 -1
  101. package/dist/mergeRefs.mjs +0 -35
  102. package/dist/mergeRefs.module.js +0 -35
  103. package/dist/mergeRefs.module.js.map +0 -1
  104. package/dist/openLink.main.js +0 -169
  105. package/dist/openLink.main.js.map +0 -1
  106. package/dist/openLink.mjs +0 -153
  107. package/dist/openLink.module.js +0 -153
  108. package/dist/openLink.module.js.map +0 -1
  109. package/dist/platform.main.js +0 -73
  110. package/dist/platform.main.js.map +0 -1
  111. package/dist/platform.mjs +0 -60
  112. package/dist/platform.module.js +0 -60
  113. package/dist/platform.module.js.map +0 -1
  114. package/dist/runAfterTransition.main.js +0 -97
  115. package/dist/runAfterTransition.main.js.map +0 -1
  116. package/dist/runAfterTransition.mjs +0 -92
  117. package/dist/runAfterTransition.module.js +0 -92
  118. package/dist/runAfterTransition.module.js.map +0 -1
  119. package/dist/scrollIntoView.main.js +0 -138
  120. package/dist/scrollIntoView.main.js.map +0 -1
  121. package/dist/scrollIntoView.mjs +0 -132
  122. package/dist/scrollIntoView.module.js +0 -132
  123. package/dist/scrollIntoView.module.js.map +0 -1
  124. package/dist/types.d.ts +0 -299
  125. package/dist/types.d.ts.map +0 -1
  126. package/dist/useDeepMemo.main.js +0 -30
  127. package/dist/useDeepMemo.main.js.map +0 -1
  128. package/dist/useDeepMemo.mjs +0 -25
  129. package/dist/useDeepMemo.module.js +0 -25
  130. package/dist/useDeepMemo.module.js.map +0 -1
  131. package/dist/useDescription.main.js +0 -59
  132. package/dist/useDescription.main.js.map +0 -1
  133. package/dist/useDescription.mjs +0 -54
  134. package/dist/useDescription.module.js +0 -54
  135. package/dist/useDescription.module.js.map +0 -1
  136. package/dist/useDrag1D.main.js +0 -141
  137. package/dist/useDrag1D.main.js.map +0 -1
  138. package/dist/useDrag1D.mjs +0 -136
  139. package/dist/useDrag1D.module.js +0 -136
  140. package/dist/useDrag1D.module.js.map +0 -1
  141. package/dist/useEffectEvent.main.js +0 -45
  142. package/dist/useEffectEvent.main.js.map +0 -1
  143. package/dist/useEffectEvent.mjs +0 -36
  144. package/dist/useEffectEvent.module.js +0 -36
  145. package/dist/useEffectEvent.module.js.map +0 -1
  146. package/dist/useEvent.main.js +0 -41
  147. package/dist/useEvent.main.js.map +0 -1
  148. package/dist/useEvent.mjs +0 -36
  149. package/dist/useEvent.module.js +0 -36
  150. package/dist/useEvent.module.js.map +0 -1
  151. package/dist/useFormReset.main.js +0 -39
  152. package/dist/useFormReset.main.js.map +0 -1
  153. package/dist/useFormReset.mjs +0 -34
  154. package/dist/useFormReset.module.js +0 -34
  155. package/dist/useFormReset.module.js.map +0 -1
  156. package/dist/useGlobalListeners.main.js +0 -62
  157. package/dist/useGlobalListeners.main.js.map +0 -1
  158. package/dist/useGlobalListeners.mjs +0 -57
  159. package/dist/useGlobalListeners.module.js +0 -57
  160. package/dist/useGlobalListeners.module.js.map +0 -1
  161. package/dist/useId.main.js +0 -108
  162. package/dist/useId.main.js.map +0 -1
  163. package/dist/useId.mjs +0 -101
  164. package/dist/useId.module.js +0 -101
  165. package/dist/useId.module.js.map +0 -1
  166. package/dist/useLabels.main.js +0 -44
  167. package/dist/useLabels.main.js.map +0 -1
  168. package/dist/useLabels.mjs +0 -39
  169. package/dist/useLabels.module.js +0 -39
  170. package/dist/useLabels.module.js.map +0 -1
  171. package/dist/useLayoutEffect.main.js +0 -27
  172. package/dist/useLayoutEffect.main.js.map +0 -1
  173. package/dist/useLayoutEffect.mjs +0 -18
  174. package/dist/useLayoutEffect.module.js +0 -18
  175. package/dist/useLayoutEffect.module.js.map +0 -1
  176. package/dist/useLoadMore.main.js +0 -73
  177. package/dist/useLoadMore.main.js.map +0 -1
  178. package/dist/useLoadMore.mjs +0 -68
  179. package/dist/useLoadMore.module.js +0 -68
  180. package/dist/useLoadMore.module.js.map +0 -1
  181. package/dist/useLoadMoreSentinel.main.js +0 -58
  182. package/dist/useLoadMoreSentinel.main.js.map +0 -1
  183. package/dist/useLoadMoreSentinel.mjs +0 -53
  184. package/dist/useLoadMoreSentinel.module.js +0 -53
  185. package/dist/useLoadMoreSentinel.module.js.map +0 -1
  186. package/dist/useObjectRef.main.js +0 -58
  187. package/dist/useObjectRef.main.js.map +0 -1
  188. package/dist/useObjectRef.mjs +0 -53
  189. package/dist/useObjectRef.module.js +0 -53
  190. package/dist/useObjectRef.module.js.map +0 -1
  191. package/dist/useResizeObserver.main.js +0 -47
  192. package/dist/useResizeObserver.main.js.map +0 -1
  193. package/dist/useResizeObserver.mjs +0 -42
  194. package/dist/useResizeObserver.module.js +0 -42
  195. package/dist/useResizeObserver.module.js.map +0 -1
  196. package/dist/useSyncRef.main.js +0 -32
  197. package/dist/useSyncRef.main.js.map +0 -1
  198. package/dist/useSyncRef.mjs +0 -27
  199. package/dist/useSyncRef.module.js +0 -27
  200. package/dist/useSyncRef.module.js.map +0 -1
  201. package/dist/useUpdateEffect.main.js +0 -42
  202. package/dist/useUpdateEffect.main.js.map +0 -1
  203. package/dist/useUpdateEffect.mjs +0 -37
  204. package/dist/useUpdateEffect.module.js +0 -37
  205. package/dist/useUpdateEffect.module.js.map +0 -1
  206. package/dist/useUpdateLayoutEffect.main.js +0 -40
  207. package/dist/useUpdateLayoutEffect.main.js.map +0 -1
  208. package/dist/useUpdateLayoutEffect.mjs +0 -35
  209. package/dist/useUpdateLayoutEffect.module.js +0 -35
  210. package/dist/useUpdateLayoutEffect.module.js.map +0 -1
  211. package/dist/useValueEffect.main.js +0 -63
  212. package/dist/useValueEffect.main.js.map +0 -1
  213. package/dist/useValueEffect.mjs +0 -58
  214. package/dist/useValueEffect.module.js +0 -58
  215. package/dist/useValueEffect.module.js.map +0 -1
  216. package/dist/useViewportSize.main.js +0 -84
  217. package/dist/useViewportSize.main.js.map +0 -1
  218. package/dist/useViewportSize.mjs +0 -79
  219. package/dist/useViewportSize.module.js +0 -79
  220. package/dist/useViewportSize.module.js.map +0 -1
  221. package/src/animation.ts +0 -103
  222. package/src/chain.ts +0 -24
  223. package/src/constants.ts +0 -15
  224. package/src/domHelpers.ts +0 -33
  225. package/src/filterDOMProps.ts +0 -127
  226. package/src/focusWithoutScrolling.ts +0 -96
  227. package/src/getOffset.ts +0 -21
  228. package/src/getScrollParent.ts +0 -27
  229. package/src/getScrollParents.ts +0 -27
  230. package/src/inertValue.ts +0 -11
  231. package/src/isElementVisible.ts +0 -75
  232. package/src/isFocusable.ts +0 -56
  233. package/src/isScrollable.ts +0 -31
  234. package/src/isVirtualEvent.ts +0 -58
  235. package/src/keyboard.tsx +0 -48
  236. package/src/mergeProps.ts +0 -77
  237. package/src/mergeRefs.ts +0 -52
  238. package/src/openLink.tsx +0 -201
  239. package/src/platform.ts +0 -78
  240. package/src/runAfterTransition.ts +0 -124
  241. package/src/scrollIntoView.ts +0 -168
  242. package/src/shadowdom/DOMFunctions.ts +0 -100
  243. package/src/shadowdom/ShadowTreeWalker.ts +0 -319
  244. package/src/useDeepMemo.ts +0 -27
  245. package/src/useDescription.ts +0 -56
  246. package/src/useDrag1D.ts +0 -191
  247. package/src/useEffectEvent.ts +0 -30
  248. package/src/useEvent.ts +0 -37
  249. package/src/useFormReset.ts +0 -36
  250. package/src/useGlobalListeners.ts +0 -52
  251. package/src/useId.ts +0 -129
  252. package/src/useLabels.ts +0 -48
  253. package/src/useLayoutEffect.ts +0 -20
  254. package/src/useLoadMore.ts +0 -82
  255. package/src/useLoadMoreSentinel.ts +0 -63
  256. package/src/useObjectRef.ts +0 -69
  257. package/src/useResizeObserver.ts +0 -52
  258. package/src/useSyncRef.ts +0 -33
  259. package/src/useUpdateEffect.ts +0 -39
  260. package/src/useUpdateLayoutEffect.ts +0 -37
  261. package/src/useValueEffect.ts +0 -68
  262. package/src/useViewportSize.ts +0 -103
package/src/mergeRefs.ts DELETED
@@ -1,52 +0,0 @@
1
- /*
2
- * Copyright 2020 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
-
13
- import {MutableRefObject, Ref} from 'react';
14
-
15
- /**
16
- * Merges multiple refs into one. Works with either callback or object refs.
17
- */
18
- export function mergeRefs<T>(...refs: Array<Ref<T> | MutableRefObject<T> | null | undefined>): Ref<T> {
19
- if (refs.length === 1 && refs[0]) {
20
- return refs[0];
21
- }
22
-
23
- return (value: T | null) => {
24
- let hasCleanup = false;
25
-
26
- const cleanups = refs.map(ref => {
27
- const cleanup = setRef(ref, value);
28
- hasCleanup ||= typeof cleanup == 'function';
29
- return cleanup;
30
- });
31
-
32
- if (hasCleanup) {
33
- return () => {
34
- cleanups.forEach((cleanup, i) => {
35
- if (typeof cleanup === 'function') {
36
- cleanup();
37
- } else {
38
- setRef(refs[i], null);
39
- }
40
- });
41
- };
42
- }
43
- };
44
- }
45
-
46
- function setRef<T>(ref: Ref<T> | MutableRefObject<T> | null | undefined, value: T) {
47
- if (typeof ref === 'function') {
48
- return ref(value);
49
- } else if (ref != null) {
50
- ref.current = value;
51
- }
52
- }
package/src/openLink.tsx DELETED
@@ -1,201 +0,0 @@
1
- /*
2
- * Copyright 2023 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
-
13
- import {focusWithoutScrolling, isMac, isWebKit} from './index';
14
- import {Href, LinkDOMProps, RouterOptions} from '@react-types/shared';
15
- import {isFirefox, isIPad} from './platform';
16
- import React, {createContext, DOMAttributes, JSX, MouseEvent as ReactMouseEvent, ReactNode, useContext, useMemo} from 'react';
17
-
18
- interface Router {
19
- isNative: boolean,
20
- open: (target: Element, modifiers: Modifiers, href: Href, routerOptions: RouterOptions | undefined) => void,
21
- useHref: (href: Href) => string
22
- }
23
-
24
- const RouterContext = createContext<Router>({
25
- isNative: true,
26
- open: openSyntheticLink,
27
- useHref: (href) => href
28
- });
29
-
30
- interface RouterProviderProps {
31
- navigate: (path: Href, routerOptions: RouterOptions | undefined) => void,
32
- useHref?: (href: Href) => string,
33
- children: ReactNode
34
- }
35
-
36
- /**
37
- * A RouterProvider accepts a `navigate` function from a framework or client side router,
38
- * and provides it to all nested React Aria links to enable client side navigation.
39
- */
40
- export function RouterProvider(props: RouterProviderProps): JSX.Element {
41
- let {children, navigate, useHref} = props;
42
-
43
- let ctx = useMemo(() => ({
44
- isNative: false,
45
- open: (target: Element, modifiers: Modifiers, href: Href, routerOptions: RouterOptions | undefined) => {
46
- getSyntheticLink(target, link => {
47
- if (shouldClientNavigate(link, modifiers)) {
48
- navigate(href, routerOptions);
49
- } else {
50
- openLink(link, modifiers);
51
- }
52
- });
53
- },
54
- useHref: useHref || ((href) => href)
55
- }), [navigate, useHref]);
56
-
57
- return (
58
- <RouterContext.Provider value={ctx}>
59
- {children}
60
- </RouterContext.Provider>
61
- );
62
- }
63
-
64
- export function useRouter(): Router {
65
- return useContext(RouterContext);
66
- }
67
-
68
- interface Modifiers {
69
- metaKey?: boolean,
70
- ctrlKey?: boolean,
71
- altKey?: boolean,
72
- shiftKey?: boolean
73
- }
74
-
75
- export function shouldClientNavigate(link: HTMLAnchorElement, modifiers: Modifiers): boolean {
76
- // Use getAttribute here instead of link.target. Firefox will default link.target to "_parent" when inside an iframe.
77
- let target = link.getAttribute('target');
78
- return (
79
- (!target || target === '_self') &&
80
- link.origin === location.origin &&
81
- !link.hasAttribute('download') &&
82
- !modifiers.metaKey && // open in new tab (mac)
83
- !modifiers.ctrlKey && // open in new tab (windows)
84
- !modifiers.altKey && // download
85
- !modifiers.shiftKey
86
- );
87
- }
88
-
89
- export function openLink(target: HTMLAnchorElement, modifiers: Modifiers, setOpening = true): void {
90
- let {metaKey, ctrlKey, altKey, shiftKey} = modifiers;
91
-
92
- // Firefox does not recognize keyboard events as a user action by default, and the popup blocker
93
- // will prevent links with target="_blank" from opening. However, it does allow the event if the
94
- // Command/Control key is held, which opens the link in a background tab. This seems like the best we can do.
95
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=257870 and https://bugzilla.mozilla.org/show_bug.cgi?id=746640.
96
- if (isFirefox() && window.event?.type?.startsWith('key') && target.target === '_blank') {
97
- if (isMac()) {
98
- metaKey = true;
99
- } else {
100
- ctrlKey = true;
101
- }
102
- }
103
-
104
- // WebKit does not support firing click events with modifier keys, but does support keyboard events.
105
- // https://github.com/WebKit/WebKit/blob/c03d0ac6e6db178f90923a0a63080b5ca210d25f/Source/WebCore/html/HTMLAnchorElement.cpp#L184
106
- let event = isWebKit() && isMac() && !isIPad() && process.env.NODE_ENV !== 'test'
107
- // @ts-ignore - keyIdentifier is a non-standard property, but it's what webkit expects
108
- ? new KeyboardEvent('keydown', {keyIdentifier: 'Enter', metaKey, ctrlKey, altKey, shiftKey})
109
- : new MouseEvent('click', {metaKey, ctrlKey, altKey, shiftKey, detail: 1, bubbles: true, cancelable: true});
110
- (openLink as any).isOpening = setOpening;
111
- focusWithoutScrolling(target);
112
- target.dispatchEvent(event);
113
- (openLink as any).isOpening = false;
114
- }
115
- // https://github.com/parcel-bundler/parcel/issues/8724
116
- (openLink as any).isOpening = false;
117
-
118
- function getSyntheticLink(target: Element, open: (link: HTMLAnchorElement) => void) {
119
- if (target instanceof HTMLAnchorElement) {
120
- open(target);
121
- } else if (target.hasAttribute('data-href')) {
122
- let link = document.createElement('a');
123
- link.href = target.getAttribute('data-href')!;
124
- if (target.hasAttribute('data-target')) {
125
- link.target = target.getAttribute('data-target')!;
126
- }
127
- if (target.hasAttribute('data-rel')) {
128
- link.rel = target.getAttribute('data-rel')!;
129
- }
130
- if (target.hasAttribute('data-download')) {
131
- link.download = target.getAttribute('data-download')!;
132
- }
133
- if (target.hasAttribute('data-ping')) {
134
- link.ping = target.getAttribute('data-ping')!;
135
- }
136
- if (target.hasAttribute('data-referrer-policy')) {
137
- link.referrerPolicy = target.getAttribute('data-referrer-policy')!;
138
- }
139
- target.appendChild(link);
140
- open(link);
141
- target.removeChild(link);
142
- }
143
- }
144
-
145
- function openSyntheticLink(target: Element, modifiers: Modifiers) {
146
- getSyntheticLink(target, link => openLink(link, modifiers));
147
- }
148
-
149
- export function useSyntheticLinkProps(props: LinkDOMProps): DOMAttributes<HTMLElement> {
150
- let router = useRouter();
151
- const href = router.useHref(props.href ?? '');
152
- return {
153
- 'data-href': props.href ? href : undefined,
154
- 'data-target': props.target,
155
- 'data-rel': props.rel,
156
- 'data-download': props.download,
157
- 'data-ping': props.ping,
158
- 'data-referrer-policy': props.referrerPolicy
159
- } as DOMAttributes<HTMLElement>;
160
- }
161
-
162
- /** @deprecated - For backward compatibility. */
163
- export function getSyntheticLinkProps(props: LinkDOMProps): DOMAttributes<HTMLElement> {
164
- return {
165
- 'data-href': props.href,
166
- 'data-target': props.target,
167
- 'data-rel': props.rel,
168
- 'data-download': props.download,
169
- 'data-ping': props.ping,
170
- 'data-referrer-policy': props.referrerPolicy
171
- } as DOMAttributes<HTMLElement>;
172
- }
173
-
174
- export function useLinkProps(props?: LinkDOMProps): LinkDOMProps {
175
- let router = useRouter();
176
- const href = router.useHref(props?.href ?? '');
177
- return {
178
- href: props?.href ? href : undefined,
179
- target: props?.target,
180
- rel: props?.rel,
181
- download: props?.download,
182
- ping: props?.ping,
183
- referrerPolicy: props?.referrerPolicy
184
- };
185
- }
186
-
187
- export function handleLinkClick(e: ReactMouseEvent, router: Router, href: Href | undefined, routerOptions: RouterOptions | undefined): void {
188
- // If a custom router is provided, prevent default and forward if this link should client navigate.
189
- if (
190
- !router.isNative &&
191
- e.currentTarget instanceof HTMLAnchorElement &&
192
- e.currentTarget.href &&
193
- // If props are applied to a router Link component, it may have already prevented default.
194
- !e.isDefaultPrevented() &&
195
- shouldClientNavigate(e.currentTarget, e) &&
196
- href
197
- ) {
198
- e.preventDefault();
199
- router.open(e.currentTarget, e, href, routerOptions);
200
- }
201
- }
package/src/platform.ts DELETED
@@ -1,78 +0,0 @@
1
- /*
2
- * Copyright 2020 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
-
13
- function testUserAgent(re: RegExp) {
14
- if (typeof window === 'undefined' || window.navigator == null) {
15
- return false;
16
- }
17
- let brands = window.navigator['userAgentData']?.brands;
18
- return Array.isArray(brands) && brands.some((brand: {brand: string, version: string}) => re.test(brand.brand)) ||
19
- re.test(window.navigator.userAgent);
20
- }
21
-
22
- function testPlatform(re: RegExp) {
23
- return typeof window !== 'undefined' && window.navigator != null
24
- ? re.test(window.navigator['userAgentData']?.platform || window.navigator.platform)
25
- : false;
26
- }
27
-
28
- function cached(fn: () => boolean) {
29
- if (process.env.NODE_ENV === 'test') {
30
- return fn;
31
- }
32
-
33
- let res: boolean | null = null;
34
- return () => {
35
- if (res == null) {
36
- res = fn();
37
- }
38
- return res;
39
- };
40
- }
41
-
42
- export const isMac: () => boolean = cached(function () {
43
- return testPlatform(/^Mac/i);
44
- });
45
-
46
- export const isIPhone: () => boolean = cached(function () {
47
- return testPlatform(/^iPhone/i);
48
- });
49
-
50
- export const isIPad: () => boolean = cached(function () {
51
- return testPlatform(/^iPad/i) ||
52
- // iPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support.
53
- (isMac() && navigator.maxTouchPoints > 1);
54
- });
55
-
56
- export const isIOS: () => boolean = cached(function () {
57
- return isIPhone() || isIPad();
58
- });
59
-
60
- export const isAppleDevice: () => boolean = cached(function () {
61
- return isMac() || isIOS();
62
- });
63
-
64
- export const isWebKit: () => boolean = cached(function () {
65
- return testUserAgent(/AppleWebKit/i) && !isChrome();
66
- });
67
-
68
- export const isChrome: () => boolean = cached(function () {
69
- return testUserAgent(/Chrome/i);
70
- });
71
-
72
- export const isAndroid: () => boolean = cached(function () {
73
- return testUserAgent(/Android/i);
74
- });
75
-
76
- export const isFirefox: () => boolean = cached(function () {
77
- return testUserAgent(/Firefox/i);
78
- });
@@ -1,124 +0,0 @@
1
- /*
2
- * Copyright 2020 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
-
13
- // We store a global list of elements that are currently transitioning,
14
- // mapped to a set of CSS properties that are transitioning for that element.
15
- // This is necessary rather than a simple count of transitions because of browser
16
- // bugs, e.g. Chrome sometimes fires both transitionend and transitioncancel rather
17
- // than one or the other. So we need to track what's actually transitioning so that
18
- // we can ignore these duplicate events.
19
- import {getEventTarget} from './shadowdom/DOMFunctions';
20
- let transitionsByElement = new Map<EventTarget, Set<string>>();
21
-
22
- // A list of callbacks to call once there are no transitioning elements.
23
- let transitionCallbacks = new Set<() => void>();
24
-
25
- function setupGlobalEvents() {
26
- if (typeof window === 'undefined') {
27
- return;
28
- }
29
-
30
- function isTransitionEvent(event: Event): event is TransitionEvent {
31
- return 'propertyName' in event;
32
- }
33
-
34
- let onTransitionStart = (e: Event) => {
35
- let eventTarget = getEventTarget(e);
36
- if (!isTransitionEvent(e) || !eventTarget) {
37
- return;
38
- }
39
- // Add the transitioning property to the list for this element.
40
- let transitions = transitionsByElement.get(eventTarget);
41
- if (!transitions) {
42
- transitions = new Set();
43
- transitionsByElement.set(eventTarget, transitions);
44
-
45
- // The transitioncancel event must be registered on the element itself, rather than as a global
46
- // event. This enables us to handle when the node is deleted from the document while it is transitioning.
47
- // In that case, the cancel event would have nowhere to bubble to so we need to handle it directly.
48
- eventTarget.addEventListener('transitioncancel', onTransitionEnd, {
49
- once: true
50
- });
51
- }
52
-
53
- transitions.add(e.propertyName);
54
- };
55
-
56
- let onTransitionEnd = (e: Event) => {
57
- let eventTarget = getEventTarget(e);
58
- if (!isTransitionEvent(e) || !eventTarget) {
59
- return;
60
- }
61
- // Remove property from list of transitioning properties.
62
- let properties = transitionsByElement.get(eventTarget);
63
- if (!properties) {
64
- return;
65
- }
66
-
67
- properties.delete(e.propertyName);
68
-
69
- // If empty, remove transitioncancel event, and remove the element from the list of transitioning elements.
70
- if (properties.size === 0) {
71
- eventTarget.removeEventListener('transitioncancel', onTransitionEnd);
72
- transitionsByElement.delete(eventTarget);
73
- }
74
-
75
- // If no transitioning elements, call all of the queued callbacks.
76
- if (transitionsByElement.size === 0) {
77
- for (let cb of transitionCallbacks) {
78
- cb();
79
- }
80
-
81
- transitionCallbacks.clear();
82
- }
83
- };
84
-
85
- document.body.addEventListener('transitionrun', onTransitionStart);
86
- document.body.addEventListener('transitionend', onTransitionEnd);
87
- }
88
-
89
- if (typeof document !== 'undefined') {
90
- if (document.readyState !== 'loading') {
91
- setupGlobalEvents();
92
- } else {
93
- document.addEventListener('DOMContentLoaded', setupGlobalEvents);
94
- }
95
- }
96
-
97
- /**
98
- * Cleans up any elements that are no longer in the document.
99
- * This is necessary because we can't rely on transitionend events to fire
100
- * for elements that are removed from the document while transitioning.
101
- */
102
- function cleanupDetachedElements() {
103
- for (const [eventTarget] of transitionsByElement) {
104
- // Similar to `eventTarget instanceof Element && !eventTarget.isConnected`, but avoids
105
- // the explicit instanceof check, since it may be different in different contexts.
106
- if ('isConnected' in eventTarget && !eventTarget.isConnected) {
107
- transitionsByElement.delete(eventTarget);
108
- }
109
- }
110
- }
111
-
112
- export function runAfterTransition(fn: () => void): void {
113
- // Wait one frame to see if an animation starts, e.g. a transition on mount.
114
- requestAnimationFrame(() => {
115
- cleanupDetachedElements();
116
- // If no transitions are running, call the function immediately.
117
- // Otherwise, add it to a list of callbacks to run at the end of the animation.
118
- if (transitionsByElement.size === 0) {
119
- fn();
120
- } else {
121
- transitionCallbacks.add(fn);
122
- }
123
- });
124
- }
@@ -1,168 +0,0 @@
1
- /*
2
- * Copyright 2020 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
-
13
- import {getScrollParents} from './getScrollParents';
14
- import {isChrome, isIOS} from './platform';
15
-
16
- interface ScrollIntoViewOpts {
17
- /** The position to align items along the block axis in. */
18
- block?: ScrollLogicalPosition,
19
- /** The position to align items along the inline axis in. */
20
- inline?: ScrollLogicalPosition
21
- }
22
-
23
-
24
- interface ScrollIntoViewportOpts {
25
- /** The optional containing element of the target to be centered in the viewport. */
26
- containingElement?: Element | null
27
- }
28
-
29
- /**
30
- * Scrolls `scrollView` so that `element` is visible.
31
- * Similar to `element.scrollIntoView({block: 'nearest'})` (not supported in Edge),
32
- * but doesn't affect parents above `scrollView`.
33
- */
34
- export function scrollIntoView(scrollView: HTMLElement, element: HTMLElement, opts: ScrollIntoViewOpts = {}): void {
35
- let {block = 'nearest', inline = 'nearest'} = opts;
36
-
37
- if (scrollView === element) { return; }
38
-
39
- let y = scrollView.scrollTop;
40
- let x = scrollView.scrollLeft;
41
-
42
- let target = element.getBoundingClientRect();
43
- let view = scrollView.getBoundingClientRect();
44
- let itemStyle = window.getComputedStyle(element);
45
- let viewStyle = window.getComputedStyle(scrollView);
46
- let root = document.scrollingElement || document.documentElement;
47
-
48
- let viewTop = scrollView === root ? 0 : view.top;
49
- let viewBottom = scrollView === root ? scrollView.clientHeight : view.bottom;
50
- let viewLeft = scrollView === root ? 0 : view.left;
51
- let viewRight = scrollView === root ? scrollView.clientWidth : view.right;
52
-
53
- let scrollMarginTop = parseInt(itemStyle.scrollMarginTop, 10) || 0;
54
- let scrollMarginBottom = parseInt(itemStyle.scrollMarginBottom, 10) || 0;
55
- let scrollMarginLeft = parseInt(itemStyle.scrollMarginLeft, 10) || 0;
56
- let scrollMarginRight = parseInt(itemStyle.scrollMarginRight, 10) || 0;
57
-
58
- let scrollPaddingTop = parseInt(viewStyle.scrollPaddingTop, 10) || 0;
59
- let scrollPaddingBottom = parseInt(viewStyle.scrollPaddingBottom, 10) || 0;
60
- let scrollPaddingLeft = parseInt(viewStyle.scrollPaddingLeft, 10) || 0;
61
- let scrollPaddingRight = parseInt(viewStyle.scrollPaddingRight, 10) || 0;
62
-
63
- let borderTopWidth = parseInt(viewStyle.borderTopWidth, 10) || 0;
64
- let borderBottomWidth = parseInt(viewStyle.borderBottomWidth, 10) || 0;
65
- let borderLeftWidth = parseInt(viewStyle.borderLeftWidth, 10) || 0;
66
- let borderRightWidth = parseInt(viewStyle.borderRightWidth, 10) || 0;
67
-
68
- let scrollAreaTop = target.top - scrollMarginTop;
69
- let scrollAreaBottom = target.bottom + scrollMarginBottom;
70
- let scrollAreaLeft = target.left - scrollMarginLeft;
71
- let scrollAreaRight = target.right + scrollMarginRight;
72
-
73
- let scrollBarOffsetX = scrollView === root ? 0 : borderLeftWidth + borderRightWidth;
74
- let scrollBarOffsetY = scrollView === root ? 0 : borderTopWidth + borderBottomWidth;
75
- let scrollBarWidth = scrollView.offsetWidth - scrollView.clientWidth - scrollBarOffsetX;
76
- let scrollBarHeight = scrollView.offsetHeight - scrollView.clientHeight - scrollBarOffsetY;
77
-
78
- let scrollPortTop = viewTop + borderTopWidth + scrollPaddingTop;
79
- let scrollPortBottom = viewBottom - borderBottomWidth - scrollPaddingBottom - scrollBarHeight;
80
- let scrollPortLeft = viewLeft + borderLeftWidth + scrollPaddingLeft;
81
- let scrollPortRight = viewRight - borderRightWidth - scrollPaddingRight;
82
-
83
- // IOS always positions the scrollbar on the right ¯\_(ツ)_/¯
84
- if (viewStyle.direction === 'rtl' && !isIOS()) {
85
- scrollPortLeft += scrollBarWidth;
86
- } else {
87
- scrollPortRight -= scrollBarWidth;
88
- }
89
-
90
- let shouldScrollBlock = scrollAreaTop < scrollPortTop || scrollAreaBottom > scrollPortBottom;
91
- let shouldScrollInline = scrollAreaLeft < scrollPortLeft || scrollAreaRight > scrollPortRight;
92
-
93
- if (shouldScrollBlock && block === 'start') {
94
- y += scrollAreaTop - scrollPortTop;
95
- } else if (shouldScrollBlock && block === 'center') {
96
- y += (scrollAreaTop + scrollAreaBottom) / 2 - (scrollPortTop + scrollPortBottom) / 2;
97
- } else if (shouldScrollBlock && block === 'end') {
98
- y += scrollAreaBottom - scrollPortBottom;
99
- } else if (shouldScrollBlock && block === 'nearest') {
100
- let start = scrollAreaTop - scrollPortTop;
101
- let end = scrollAreaBottom - scrollPortBottom;
102
- y += Math.abs(start) <= Math.abs(end) ? start : end;
103
- }
104
-
105
- if (shouldScrollInline && inline === 'start') {
106
- x += scrollAreaLeft - scrollPortLeft;
107
- } else if (shouldScrollInline && inline === 'center') {
108
- x += (scrollAreaLeft + scrollAreaRight) / 2 - (scrollPortLeft + scrollPortRight) / 2;
109
- } else if (shouldScrollInline && inline === 'end') {
110
- x += scrollAreaRight - scrollPortRight;
111
- } else if (shouldScrollInline && inline === 'nearest') {
112
- let start = scrollAreaLeft - scrollPortLeft;
113
- let end = scrollAreaRight - scrollPortRight;
114
- x += Math.abs(start) <= Math.abs(end) ? start : end;
115
- }
116
-
117
- if (process.env.NODE_ENV === 'test') {
118
- scrollView.scrollLeft = x;
119
- scrollView.scrollTop = y;
120
- return;
121
- }
122
-
123
- scrollView.scrollTo({left: x, top: y});
124
- }
125
-
126
- /**
127
- * Scrolls the `targetElement` so it is visible in the viewport. Accepts an optional `opts.containingElement`
128
- * that will be centered in the viewport prior to scrolling the targetElement into view. If scrolling is prevented on
129
- * the body (e.g. targetElement is in a popover), this will only scroll the scroll parents of the targetElement up to but not including the body itself.
130
- */
131
- export function scrollIntoViewport(targetElement: Element | null, opts: ScrollIntoViewportOpts = {}): void {
132
- let {containingElement} = opts;
133
- if (targetElement && targetElement.isConnected) {
134
- let root = document.scrollingElement || document.documentElement;
135
- let isScrollPrevented = window.getComputedStyle(root).overflow === 'hidden';
136
- // If scrolling is not currently prevented then we aren't in a overlay nor is a overlay open, just use element.scrollIntoView to bring the element into view
137
- // Also ignore in chrome because of this bug: https://issues.chromium.org/issues/40074749
138
- if (!isScrollPrevented && !isChrome()) {
139
- let {left: originalLeft, top: originalTop} = targetElement.getBoundingClientRect();
140
-
141
- // use scrollIntoView({block: 'nearest'}) instead of .focus to check if the element is fully in view or not since .focus()
142
- // won't cause a scroll if the element is already focused and doesn't behave consistently when an element is partially out of view horizontally vs vertically
143
- targetElement?.scrollIntoView?.({block: 'nearest'});
144
- let {left: newLeft, top: newTop} = targetElement.getBoundingClientRect();
145
- // Account for sub pixel differences from rounding
146
- if ((Math.abs(originalLeft - newLeft) > 1) || (Math.abs(originalTop - newTop) > 1)) {
147
- containingElement?.scrollIntoView?.({block: 'center', inline: 'center'});
148
- targetElement.scrollIntoView?.({block: 'nearest'});
149
- }
150
- } else {
151
- let {left: originalLeft, top: originalTop} = targetElement.getBoundingClientRect();
152
-
153
- // If scrolling is prevented, we don't want to scroll the body since it might move the overlay partially offscreen and the user can't scroll it back into view.
154
- let scrollParents = getScrollParents(targetElement, true);
155
- for (let scrollParent of scrollParents) {
156
- scrollIntoView(scrollParent as HTMLElement, targetElement as HTMLElement);
157
- }
158
- let {left: newLeft, top: newTop} = targetElement.getBoundingClientRect();
159
- // Account for sub pixel differences from rounding
160
- if ((Math.abs(originalLeft - newLeft) > 1) || (Math.abs(originalTop - newTop) > 1)) {
161
- scrollParents = containingElement ? getScrollParents(containingElement, true) : [];
162
- for (let scrollParent of scrollParents) {
163
- scrollIntoView(scrollParent as HTMLElement, containingElement as HTMLElement, {block: 'center', inline: 'center'});
164
- }
165
- }
166
- }
167
- }
168
- }