UNPKG

2.5 kBPlain TextView Raw
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// Portions of the code in this file are based on code from react.
14// Original licensing for the following can be found in the
15// NOTICE file in the root directory of this source tree.
16// See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions
17
18import {DOMAttributes, FocusEvents} from '@react-types/shared';
19import {FocusEvent, useCallback} from 'react';
20import {useSyntheticBlurEvent} from './utils';
21
22export interface FocusProps extends FocusEvents {
23 /** Whether the focus events should be disabled. */
24 isDisabled?: boolean
25}
26
27export interface FocusResult {
28 /** Props to spread onto the target element. */
29 focusProps: DOMAttributes
30}
31
32/**
33 * Handles focus events for the immediate target.
34 * Focus events on child elements will be ignored.
35 */
36export function useFocus(props: FocusProps): FocusResult {
37 let {
38 isDisabled,
39 onFocus: onFocusProp,
40 onBlur: onBlurProp,
41 onFocusChange
42 } = props;
43
44 const onBlur: FocusProps['onBlur'] = useCallback((e: FocusEvent) => {
45 if (e.target === e.currentTarget) {
46 if (onBlurProp) {
47 onBlurProp(e);
48 }
49
50 if (onFocusChange) {
51 onFocusChange(false);
52 }
53
54 return true;
55 }
56 }, [onBlurProp, onFocusChange]);
57
58
59 const onSyntheticFocus = useSyntheticBlurEvent(onBlur);
60
61 const onFocus: FocusProps['onFocus'] = useCallback((e: FocusEvent) => {
62 if (e.target === e.currentTarget) {
63 if (onFocusProp) {
64 onFocusProp(e);
65 }
66
67 if (onFocusChange) {
68 onFocusChange(true);
69 }
70
71 onSyntheticFocus(e);
72 }
73 }, [onFocusChange, onFocusProp, onSyntheticFocus]);
74
75 return {
76 focusProps: {
77 onFocus: (!isDisabled && (onFocusProp || onFocusChange || onBlurProp)) ? onFocus : undefined,
78 onBlur: (!isDisabled && (onBlurProp || onFocusChange)) ? onBlur : null
79 }
80 };
81}