Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/@react-aria/focus/src/useFocusable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface FocusableProviderProps extends DOMAttributes {
}

interface FocusableContextValue extends FocusableProviderProps {
ref?: MutableRefObject<FocusableElement>
ref?: MutableRefObject<FocusableElement | null>
}

let FocusableContext = React.createContext<FocusableContextValue | null>(null);
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-aria/interactions/src/DOMPropsContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface DOMPropsResponderProps extends DOMAttributes {

interface IDOMPropsResponderContext extends DOMAttributes {
register(): void,
ref?: MutableRefObject<Element>
ref?: MutableRefObject<Element | null>
}

export const DOMPropsResponderContext = React.createContext<IDOMPropsResponderContext | null>(null);
Expand Down
10 changes: 5 additions & 5 deletions packages/@react-aria/utils/src/focusWithoutScrolling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ export function focusWithoutScrolling(element: FocusableElement) {
}
}

let supportsPreventScrollCached: boolean = null;
let supportsPreventScrollCached: boolean | null = null;
function supportsPreventScroll() {
if (supportsPreventScrollCached == null) {
supportsPreventScrollCached = false;
try {
var focusElem = document.createElement('div');
let focusElem = document.createElement('div');
focusElem.focus({
get preventScroll() {
supportsPreventScrollCached = true;
Expand All @@ -59,9 +59,9 @@ function supportsPreventScroll() {
}

function getScrollableElements(element: FocusableElement): ScrollableElement[] {
var parent = element.parentNode;
var scrollableElements: ScrollableElement[] = [];
var rootScrollingElement = document.scrollingElement || document.documentElement;
let parent = element.parentNode;
let scrollableElements: ScrollableElement[] = [];
let rootScrollingElement = document.scrollingElement || document.documentElement;

while (parent instanceof HTMLElement && parent !== rootScrollingElement) {
if (
Expand Down
11 changes: 6 additions & 5 deletions packages/@react-aria/utils/src/getScrollParent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
*/

export function getScrollParent(node: Element, checkForOverflow?: boolean): Element {
if (isScrollable(node, checkForOverflow)) {
node = node.parentElement;
let scrollableNode: Element | null = node;
if (isScrollable(scrollableNode, checkForOverflow)) {
scrollableNode = scrollableNode.parentElement;
}

while (node && !isScrollable(node, checkForOverflow)) {
node = node.parentElement;
while (scrollableNode && !isScrollable(scrollableNode, checkForOverflow)) {
scrollableNode = scrollableNode.parentElement;
}

return node || document.scrollingElement || document.documentElement;
return scrollableNode || document.scrollingElement || document.documentElement;
}

export function isScrollable(node: Element, checkForOverflow?: boolean): boolean {
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-aria/utils/src/mergeRefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function mergeRefs<T>(...refs: ForwardedRef<T>[]): ForwardedRef<T> {
return refs[0];
}

return (value: T) => {
return (value: T | null) => {
for (let ref of refs) {
if (typeof ref === 'function') {
ref(value);
Expand Down
12 changes: 6 additions & 6 deletions packages/@react-aria/utils/src/openLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,21 +116,21 @@ function getSyntheticLink(target: Element, open: (link: HTMLAnchorElement) => vo
open(target);
} else if (target.hasAttribute('data-href')) {
let link = document.createElement('a');
link.href = target.getAttribute('data-href');
link.href = target.getAttribute('data-href')!;
if (target.hasAttribute('data-target')) {
link.target = target.getAttribute('data-target');
link.target = target.getAttribute('data-target')!;
}
if (target.hasAttribute('data-rel')) {
link.rel = target.getAttribute('data-rel');
link.rel = target.getAttribute('data-rel')!;
}
if (target.hasAttribute('data-download')) {
link.download = target.getAttribute('data-download');
link.download = target.getAttribute('data-download')!;
}
if (target.hasAttribute('data-ping')) {
link.ping = target.getAttribute('data-ping');
link.ping = target.getAttribute('data-ping')!;
}
if (target.hasAttribute('data-referrer-policy')) {
link.referrerPolicy = target.getAttribute('data-referrer-policy');
link.referrerPolicy = target.getAttribute('data-referrer-policy')!;
}
target.appendChild(link);
open(link);
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-aria/utils/src/useDeepMemo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {useRef} from 'react';
export function useDeepMemo<T>(value: T, isEqual: (a: T, b: T) => boolean): T {
// Using a ref during render is ok here because it's only an optimization – both values are equivalent.
// If a render is thrown away, it'll still work the same no matter if the next render is the same or not.
let lastValue = useRef(null);
let lastValue = useRef<T | null>(null);
if (value && lastValue.current && isEqual(value, lastValue.current)) {
value = lastValue.current;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/@react-aria/utils/src/useDescription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ let descriptionId = 0;
const descriptionNodes = new Map<string, {refCount: number, element: Element}>();

export function useDescription(description?: string): AriaLabelingProps {
let [id, setId] = useState(undefined);
let [id, setId] = useState<string | undefined>();

useLayoutEffect(() => {
if (!description) {
Expand All @@ -43,7 +43,7 @@ export function useDescription(description?: string): AriaLabelingProps {

desc.refCount++;
return () => {
if (--desc.refCount === 0) {
if (desc && --desc.refCount === 0) {
desc.element.remove();
descriptionNodes.delete(description);
}
Expand Down
6 changes: 3 additions & 3 deletions packages/@react-aria/utils/src/useEffectEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
import {useCallback, useRef} from 'react';
import {useLayoutEffect} from './useLayoutEffect';

export function useEffectEvent<T extends Function>(fn: T): T {
const ref = useRef<T | null>(null);
export function useEffectEvent<T extends Function>(fn?: T): T {
const ref = useRef<T | null | undefined>(null);
useLayoutEffect(() => {
ref.current = fn;
}, [fn]);
// @ts-ignore
return useCallback<T>((...args) => {
const f = ref.current!;
return f(...args);
return f?.(...args);
}, []);
}
6 changes: 3 additions & 3 deletions packages/@react-aria/utils/src/useEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ export function useEvent<K extends keyof GlobalEventHandlersEventMap>(
let isDisabled = handler == null;

useEffect(() => {
if (isDisabled) {
if (isDisabled || !ref.current) {
return;
}

let element = ref.current;
element.addEventListener(event, handleEvent, options);
element.addEventListener(event, handleEvent as EventListener, options);
return () => {
element.removeEventListener(event, handleEvent, options);
element.removeEventListener(event, handleEvent as EventListener, options);
};
}, [ref, event, options, isDisabled, handleEvent]);
}
4 changes: 2 additions & 2 deletions packages/@react-aria/utils/src/useObjectRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import {MutableRefObject, useMemo, useRef} from 'react';
* @returns An object ref that updates the given ref.
* @see https://reactjs.org/docs/forwarding-refs.html
*/
export function useObjectRef<T>(forwardedRef?: ((instance: T | null) => void) | MutableRefObject<T | null> | null): MutableRefObject<T> {
const objRef = useRef<T>();
export function useObjectRef<T>(forwardedRef?: ((instance: T | null) => void) | MutableRefObject<T | null> | null): MutableRefObject<T | null> {
const objRef: MutableRefObject<T | null> = useRef<T>(null);
return useMemo(() => ({
get current() {
return objRef.current;
Expand Down
6 changes: 4 additions & 2 deletions packages/@react-aria/utils/src/useSyncRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {MutableRefObject, RefObject} from 'react';
import {useLayoutEffect} from './';

interface ContextValue<T> {
ref?: MutableRefObject<T>
ref?: MutableRefObject<T | null>
}

// Syncs ref from context with ref passed to hook
Expand All @@ -23,7 +23,9 @@ export function useSyncRef<T>(context?: ContextValue<T> | null, ref?: RefObject<
if (context && context.ref && ref) {
context.ref.current = ref.current;
return () => {
context.ref.current = null;
if (context.ref) {
context.ref.current = null;
}
};
}
});
Expand Down
7 changes: 5 additions & 2 deletions packages/@react-aria/utils/src/useValueEffect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/

import {Dispatch, useRef, useState} from 'react';
import {Dispatch, MutableRefObject, useRef, useState} from 'react';
import {useEffectEvent, useLayoutEffect} from './';

type SetValueAction<S> = (prev: S) => Generator<any, void, unknown>;
Expand All @@ -21,11 +21,14 @@ type SetValueAction<S> = (prev: S) => Generator<any, void, unknown>;
// written linearly.
export function useValueEffect<S>(defaultValue: S | (() => S)): [S, Dispatch<SetValueAction<S>>] {
let [value, setValue] = useState(defaultValue);
let effect = useRef(null);
let effect: MutableRefObject<Generator<S> | null> = useRef<Generator<S> | null>(null);

// Store the function in a ref so we can always access the current version
// which has the proper `value` in scope.
let nextRef = useEffectEvent(() => {
if (!effect.current) {
return;
}
// Run the generator to the next yield.
let newValue = effect.current.next();

Expand Down
4 changes: 2 additions & 2 deletions packages/@react-aria/utils/src/useViewportSize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function useViewportSize(): ViewportSize {

function getViewportSize(): ViewportSize {
return {
width: visualViewport?.width || window.innerWidth,
height: visualViewport?.height || window.innerHeight
width: (visualViewport && visualViewport?.width) || window.innerWidth,
height: (visualViewport && visualViewport?.height) || window.innerHeight
};
}
2 changes: 1 addition & 1 deletion packages/@react-aria/utils/test/useObjectRef.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('useObjectRef', () => {

expect(result.current).toBeDefined();
expect(result.current).not.toBeNull();
expect(result.current.current).toBeUndefined();
expect(result.current.current).toBeNull();
});

it('should support React.forwardRef for an object ref', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-aria-components/src/FileTrigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function FileTrigger(props: FileTriggerProps, ref: ForwardedRef<HTMLInputElement
<>
<PressResponder
onPress={() => {
if (inputRef.current.value) {
if (inputRef.current?.value) {
inputRef.current.value = '';
}
inputRef.current?.click();
Expand Down
7 changes: 5 additions & 2 deletions packages/react-aria-components/src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,12 @@ function ResizableTableContainer(props: ResizableTableContainerProps, ref: Forwa
useResizeObserver({
ref: objectRef,
onResize() {
setWidth(objectRef.current?.clientWidth);
setWidth(objectRef.current?.clientWidth ?? 0);
}
});

useLayoutEffect(() => {
setWidth(objectRef.current?.clientWidth);
setWidth(objectRef.current?.clientWidth ?? 0);
}, [objectRef]);

let ctx = useMemo(() => ({
Expand Down Expand Up @@ -940,6 +940,9 @@ function ColumnResizer(props: ColumnResizerProps, ref: ForwardedRef<HTMLDivEleme
let objectRef = useObjectRef(ref);
let [cursor, setCursor] = useState('');
useEffect(() => {
if (!objectRef.current) {
return;
}
let style = window.getComputedStyle(objectRef.current);
setCursor(style.cursor);
}, [objectRef, resizableDirection]);
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"./packages/@react-aria/tabs",
"./packages/@react-aria/tag",
"./packages/@react-aria/toggle",
"./packages/@react-aria/u",
"./packages/@react-aria/visually-hidden",
"./packages/@react-aria/w",
"./packages/@react-aria/x",
Expand Down