UNPKG

2.41 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 {FocusEvent, HTMLAttributes} from 'react';
19import {FocusEvents} from '@react-types/shared';
20import {useSyntheticBlurEvent} from './utils';
21
22interface FocusProps extends FocusEvents {
23 /** Whether the focus events should be disabled. */
24 isDisabled?: boolean
25}
26
27interface FocusResult {
28 /** Props to spread onto the target element. */
29 focusProps: HTMLAttributes<HTMLElement>
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 onBlur: FocusProps['onBlur'];
38 if (!props.isDisabled && (props.onBlur || props.onFocusChange)) {
39 onBlur = (e: FocusEvent) => {
40 if (e.target === e.currentTarget) {
41 if (props.onBlur) {
42 props.onBlur(e);
43 }
44
45 if (props.onFocusChange) {
46 props.onFocusChange(false);
47 }
48
49 return true;
50 }
51 };
52 } else {
53 onBlur = null;
54 }
55
56 let onSyntheticFocus = useSyntheticBlurEvent(onBlur);
57
58 let onFocus: FocusProps['onFocus'];
59 if (!props.isDisabled && (props.onFocus || props.onFocusChange || props.onBlur)) {
60 onFocus = (e: FocusEvent) => {
61 if (e.target === e.currentTarget) {
62 if (props.onFocus) {
63 props.onFocus(e);
64 }
65
66 if (props.onFocusChange) {
67 props.onFocusChange(true);
68 }
69
70 onSyntheticFocus(e);
71 }
72 };
73 }
74
75 return {
76 focusProps: {
77 onFocus,
78 onBlur
79 }
80 };
81}