@react-aria/utils 3.23.0 → 3.23.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.
- package/dist/import.mjs +25 -16
- package/dist/main.js +25 -16
- package/dist/main.js.map +1 -1
- package/dist/module.js +25 -16
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +4 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/focusWithoutScrolling.ts +5 -5
- package/src/getScrollParent.ts +6 -5
- package/src/mergeRefs.ts +1 -1
- package/src/openLink.tsx +6 -6
- package/src/runAfterTransition.ts +15 -3
- package/src/useDeepMemo.ts +1 -1
- package/src/useDescription.ts +2 -2
- package/src/useEffectEvent.ts +3 -3
- package/src/useEvent.ts +3 -3
- package/src/useObjectRef.ts +3 -3
- package/src/useSyncRef.ts +4 -2
- package/src/useValueEffect.ts +5 -2
- package/src/useViewportSize.ts +2 -2
package/src/getScrollParent.ts
CHANGED
|
@@ -11,15 +11,16 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
export function getScrollParent(node: Element, checkForOverflow?: boolean): Element {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
let scrollableNode: Element | null = node;
|
|
15
|
+
if (isScrollable(scrollableNode, checkForOverflow)) {
|
|
16
|
+
scrollableNode = scrollableNode.parentElement;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
while (
|
|
19
|
-
|
|
19
|
+
while (scrollableNode && !isScrollable(scrollableNode, checkForOverflow)) {
|
|
20
|
+
scrollableNode = scrollableNode.parentElement;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
return
|
|
23
|
+
return scrollableNode || document.scrollingElement || document.documentElement;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export function isScrollable(node: Element, checkForOverflow?: boolean): boolean {
|
package/src/mergeRefs.ts
CHANGED
package/src/openLink.tsx
CHANGED
|
@@ -116,21 +116,21 @@ function getSyntheticLink(target: Element, open: (link: HTMLAnchorElement) => vo
|
|
|
116
116
|
open(target);
|
|
117
117
|
} else if (target.hasAttribute('data-href')) {
|
|
118
118
|
let link = document.createElement('a');
|
|
119
|
-
link.href = target.getAttribute('data-href')
|
|
119
|
+
link.href = target.getAttribute('data-href')!;
|
|
120
120
|
if (target.hasAttribute('data-target')) {
|
|
121
|
-
link.target = target.getAttribute('data-target')
|
|
121
|
+
link.target = target.getAttribute('data-target')!;
|
|
122
122
|
}
|
|
123
123
|
if (target.hasAttribute('data-rel')) {
|
|
124
|
-
link.rel = target.getAttribute('data-rel')
|
|
124
|
+
link.rel = target.getAttribute('data-rel')!;
|
|
125
125
|
}
|
|
126
126
|
if (target.hasAttribute('data-download')) {
|
|
127
|
-
link.download = target.getAttribute('data-download')
|
|
127
|
+
link.download = target.getAttribute('data-download')!;
|
|
128
128
|
}
|
|
129
129
|
if (target.hasAttribute('data-ping')) {
|
|
130
|
-
link.ping = target.getAttribute('data-ping')
|
|
130
|
+
link.ping = target.getAttribute('data-ping')!;
|
|
131
131
|
}
|
|
132
132
|
if (target.hasAttribute('data-referrer-policy')) {
|
|
133
|
-
link.referrerPolicy = target.getAttribute('data-referrer-policy')
|
|
133
|
+
link.referrerPolicy = target.getAttribute('data-referrer-policy')!;
|
|
134
134
|
}
|
|
135
135
|
target.appendChild(link);
|
|
136
136
|
open(link);
|
|
@@ -26,7 +26,14 @@ function setupGlobalEvents() {
|
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
function isTransitionEvent(event: Event): event is TransitionEvent {
|
|
30
|
+
return 'propertyName' in event;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let onTransitionStart = (e: Event) => {
|
|
34
|
+
if (!isTransitionEvent(e) || !e.target) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
30
37
|
// Add the transitioning property to the list for this element.
|
|
31
38
|
let transitions = transitionsByElement.get(e.target);
|
|
32
39
|
if (!transitions) {
|
|
@@ -36,13 +43,18 @@ function setupGlobalEvents() {
|
|
|
36
43
|
// The transitioncancel event must be registered on the element itself, rather than as a global
|
|
37
44
|
// event. This enables us to handle when the node is deleted from the document while it is transitioning.
|
|
38
45
|
// In that case, the cancel event would have nowhere to bubble to so we need to handle it directly.
|
|
39
|
-
e.target.addEventListener('transitioncancel', onTransitionEnd
|
|
46
|
+
e.target.addEventListener('transitioncancel', onTransitionEnd, {
|
|
47
|
+
once: true
|
|
48
|
+
});
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
transitions.add(e.propertyName);
|
|
43
52
|
};
|
|
44
53
|
|
|
45
|
-
let onTransitionEnd = (e:
|
|
54
|
+
let onTransitionEnd = (e: Event) => {
|
|
55
|
+
if (!isTransitionEvent(e) || !e.target) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
46
58
|
// Remove property from list of transitioning properties.
|
|
47
59
|
let properties = transitionsByElement.get(e.target);
|
|
48
60
|
if (!properties) {
|
package/src/useDeepMemo.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {useRef} from 'react';
|
|
|
17
17
|
export function useDeepMemo<T>(value: T, isEqual: (a: T, b: T) => boolean): T {
|
|
18
18
|
// Using a ref during render is ok here because it's only an optimization – both values are equivalent.
|
|
19
19
|
// If a render is thrown away, it'll still work the same no matter if the next render is the same or not.
|
|
20
|
-
let lastValue = useRef(null);
|
|
20
|
+
let lastValue = useRef<T | null>(null);
|
|
21
21
|
if (value && lastValue.current && isEqual(value, lastValue.current)) {
|
|
22
22
|
value = lastValue.current;
|
|
23
23
|
}
|
package/src/useDescription.ts
CHANGED
|
@@ -18,7 +18,7 @@ let descriptionId = 0;
|
|
|
18
18
|
const descriptionNodes = new Map<string, {refCount: number, element: Element}>();
|
|
19
19
|
|
|
20
20
|
export function useDescription(description?: string): AriaLabelingProps {
|
|
21
|
-
let [id, setId] = useState(
|
|
21
|
+
let [id, setId] = useState<string | undefined>();
|
|
22
22
|
|
|
23
23
|
useLayoutEffect(() => {
|
|
24
24
|
if (!description) {
|
|
@@ -43,7 +43,7 @@ export function useDescription(description?: string): AriaLabelingProps {
|
|
|
43
43
|
|
|
44
44
|
desc.refCount++;
|
|
45
45
|
return () => {
|
|
46
|
-
if (--desc.refCount === 0) {
|
|
46
|
+
if (desc && --desc.refCount === 0) {
|
|
47
47
|
desc.element.remove();
|
|
48
48
|
descriptionNodes.delete(description);
|
|
49
49
|
}
|
package/src/useEffectEvent.ts
CHANGED
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
import {useCallback, useRef} from 'react';
|
|
14
14
|
import {useLayoutEffect} from './useLayoutEffect';
|
|
15
15
|
|
|
16
|
-
export function useEffectEvent<T extends Function>(fn
|
|
17
|
-
const ref = useRef<T | null>(null);
|
|
16
|
+
export function useEffectEvent<T extends Function>(fn?: T): T {
|
|
17
|
+
const ref = useRef<T | null | undefined>(null);
|
|
18
18
|
useLayoutEffect(() => {
|
|
19
19
|
ref.current = fn;
|
|
20
20
|
}, [fn]);
|
|
21
21
|
// @ts-ignore
|
|
22
22
|
return useCallback<T>((...args) => {
|
|
23
23
|
const f = ref.current!;
|
|
24
|
-
return f(...args);
|
|
24
|
+
return f?.(...args);
|
|
25
25
|
}, []);
|
|
26
26
|
}
|
package/src/useEvent.ts
CHANGED
|
@@ -23,14 +23,14 @@ export function useEvent<K extends keyof GlobalEventHandlersEventMap>(
|
|
|
23
23
|
let isDisabled = handler == null;
|
|
24
24
|
|
|
25
25
|
useEffect(() => {
|
|
26
|
-
if (isDisabled) {
|
|
26
|
+
if (isDisabled || !ref.current) {
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
let element = ref.current;
|
|
31
|
-
element.addEventListener(event, handleEvent, options);
|
|
31
|
+
element.addEventListener(event, handleEvent as EventListener, options);
|
|
32
32
|
return () => {
|
|
33
|
-
element.removeEventListener(event, handleEvent, options);
|
|
33
|
+
element.removeEventListener(event, handleEvent as EventListener, options);
|
|
34
34
|
};
|
|
35
35
|
}, [ref, event, options, isDisabled, handleEvent]);
|
|
36
36
|
}
|
package/src/useObjectRef.ts
CHANGED
|
@@ -15,14 +15,14 @@ import {MutableRefObject, useMemo, useRef} from 'react';
|
|
|
15
15
|
/**
|
|
16
16
|
* Offers an object ref for a given callback ref or an object ref. Especially
|
|
17
17
|
* helfpul when passing forwarded refs (created using `React.forwardRef`) to
|
|
18
|
-
* React Aria
|
|
18
|
+
* React Aria hooks.
|
|
19
19
|
*
|
|
20
20
|
* @param forwardedRef The original ref intended to be used.
|
|
21
21
|
* @returns An object ref that updates the given ref.
|
|
22
22
|
* @see https://reactjs.org/docs/forwarding-refs.html
|
|
23
23
|
*/
|
|
24
|
-
export function useObjectRef<T>(forwardedRef?: ((instance: T | null) => void) | MutableRefObject<T | null> | null): MutableRefObject<T> {
|
|
25
|
-
const objRef = useRef<T>();
|
|
24
|
+
export function useObjectRef<T>(forwardedRef?: ((instance: T | null) => void) | MutableRefObject<T | null> | null): MutableRefObject<T | null> {
|
|
25
|
+
const objRef: MutableRefObject<T | null> = useRef<T>(null);
|
|
26
26
|
return useMemo(() => ({
|
|
27
27
|
get current() {
|
|
28
28
|
return objRef.current;
|
package/src/useSyncRef.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {MutableRefObject, RefObject} from 'react';
|
|
|
14
14
|
import {useLayoutEffect} from './';
|
|
15
15
|
|
|
16
16
|
interface ContextValue<T> {
|
|
17
|
-
ref?: MutableRefObject<T>
|
|
17
|
+
ref?: MutableRefObject<T | null>
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// Syncs ref from context with ref passed to hook
|
|
@@ -23,7 +23,9 @@ export function useSyncRef<T>(context?: ContextValue<T> | null, ref?: RefObject<
|
|
|
23
23
|
if (context && context.ref && ref) {
|
|
24
24
|
context.ref.current = ref.current;
|
|
25
25
|
return () => {
|
|
26
|
-
context.ref
|
|
26
|
+
if (context.ref) {
|
|
27
|
+
context.ref.current = null;
|
|
28
|
+
}
|
|
27
29
|
};
|
|
28
30
|
}
|
|
29
31
|
});
|
package/src/useValueEffect.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {Dispatch, useRef, useState} from 'react';
|
|
13
|
+
import {Dispatch, MutableRefObject, useRef, useState} from 'react';
|
|
14
14
|
import {useEffectEvent, useLayoutEffect} from './';
|
|
15
15
|
|
|
16
16
|
type SetValueAction<S> = (prev: S) => Generator<any, void, unknown>;
|
|
@@ -21,11 +21,14 @@ type SetValueAction<S> = (prev: S) => Generator<any, void, unknown>;
|
|
|
21
21
|
// written linearly.
|
|
22
22
|
export function useValueEffect<S>(defaultValue: S | (() => S)): [S, Dispatch<SetValueAction<S>>] {
|
|
23
23
|
let [value, setValue] = useState(defaultValue);
|
|
24
|
-
let effect = useRef(null);
|
|
24
|
+
let effect: MutableRefObject<Generator<S> | null> = useRef<Generator<S> | null>(null);
|
|
25
25
|
|
|
26
26
|
// Store the function in a ref so we can always access the current version
|
|
27
27
|
// which has the proper `value` in scope.
|
|
28
28
|
let nextRef = useEffectEvent(() => {
|
|
29
|
+
if (!effect.current) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
29
32
|
// Run the generator to the next yield.
|
|
30
33
|
let newValue = effect.current.next();
|
|
31
34
|
|
package/src/useViewportSize.ts
CHANGED
|
@@ -57,7 +57,7 @@ export function useViewportSize(): ViewportSize {
|
|
|
57
57
|
|
|
58
58
|
function getViewportSize(): ViewportSize {
|
|
59
59
|
return {
|
|
60
|
-
width: visualViewport?.width || window.innerWidth,
|
|
61
|
-
height: visualViewport?.height || window.innerHeight
|
|
60
|
+
width: (visualViewport && visualViewport?.width) || window.innerWidth,
|
|
61
|
+
height: (visualViewport && visualViewport?.height) || window.innerHeight
|
|
62
62
|
};
|
|
63
63
|
}
|