UNPKG

2.46 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports.default = useFocusManager;
5
6var _react = require("react");
7
8var _useEventCallback = _interopRequireDefault(require("./useEventCallback"));
9
10var _useMounted = _interopRequireDefault(require("./useMounted"));
11
12function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
14/**
15 * useFocusManager provides a way to track and manage focus as it moves around
16 * a container element. An `onChange` is fired when focus enters or leaves the
17 * element, but not when it moves around inside the element, similar to
18 * `pointerenter` and `pointerleave` DOM events.
19 *
20 * ```tsx
21 * const [focused, setFocusState] = useState(false)
22 *
23 * const { onBlur, onFocus } = useFocusManager({
24 * onChange: nextFocused => setFocusState(nextFocused)
25 * })
26 *
27 * return (
28 * <div tabIndex="-1" onFocus={onFocus} onBlur={onBlur}>
29 * {String(focused)}
30 * <input />
31 * <input />
32 *
33 * <button>A button</button>
34 * </div>
35 * ```
36 *
37 */
38function useFocusManager(opts) {
39 var isMounted = (0, _useMounted.default)();
40 var lastFocused = (0, _react.useRef)();
41 var handle = (0, _react.useRef)();
42 var willHandle = (0, _useEventCallback.default)(opts.willHandle);
43 var didHandle = (0, _useEventCallback.default)(opts.didHandle);
44 var onChange = (0, _useEventCallback.default)(opts.onChange);
45 var isDisabled = (0, _useEventCallback.default)(opts.isDisabled);
46 var handleFocusChange = (0, _react.useCallback)(function (focused, event) {
47 if (event && event.persist) event.persist();
48 if (willHandle && willHandle(focused, event) === false) return;
49 clearTimeout(handle.current);
50 handle.current = setTimeout(function () {
51 if (focused !== lastFocused.current) {
52 if (didHandle) didHandle(focused, event); // only fire a change when unmounted if its a blur
53
54 if (isMounted() || !focused) {
55 lastFocused.current = focused;
56 onChange && onChange(focused, event);
57 }
58 }
59 });
60 }, [isMounted, willHandle, didHandle, onChange, lastFocused]);
61 var handleBlur = (0, _react.useCallback)(function (event) {
62 if (!isDisabled()) handleFocusChange(false, event);
63 }, [handleFocusChange, isDisabled]);
64 var handleFocus = (0, _react.useCallback)(function (event) {
65 if (!isDisabled()) handleFocusChange(true, event);
66 }, [handleFocusChange, isDisabled]);
67 return {
68 onBlur: handleBlur,
69 onFocus: handleFocus
70 };
71}
\No newline at end of file