UNPKG

3.42 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var React = require("react");
4var getWindow_1 = require("./dom/getWindow");
5var keyboard_1 = require("./keyboard");
6var setFocusVisibility_1 = require("./setFocusVisibility");
7/**
8 * Counter for mounted component that uses focus rectangle.
9 * We want to cleanup the listners before last component that uses focus rectangle unmounts.
10 */
11var mountCounters = new WeakMap();
12function setMountCounters(key, delta) {
13 var newValue;
14 var currValue = mountCounters.get(key);
15 if (currValue) {
16 newValue = currValue + delta;
17 }
18 else {
19 newValue = 1;
20 }
21 mountCounters.set(key, newValue);
22 return newValue;
23}
24/**
25 * Initializes the logic which:
26 *
27 * 1. Subscribes keydown and mousedown events. (It will only do it once per window,
28 * so it's safe to call this method multiple times.)
29 * 2. When the user presses directional keyboard keys, adds the 'ms-Fabric--isFocusVisible' classname
30 * to the document body, removes the 'ms-Fabric-isFocusHidden' classname.
31 * 3. When the user clicks a mouse button, adds the 'ms-Fabric-isFocusHidden' classname to the
32 * document body, removes the 'ms-Fabric--isFocusVisible' classname.
33 *
34 * This logic allows components on the page to conditionally render focus treatments based on
35 * the existence of global classnames, which simplifies logic overall.
36 *
37 * @param rootRef - A Ref object. Focus rectangle can be applied on itself and all its children.
38 */
39function useFocusRects(rootRef) {
40 React.useEffect(function () {
41 var _a, _b;
42 var win = getWindow_1.getWindow((_a = rootRef) === null || _a === void 0 ? void 0 : _a.current);
43 if (!win || ((_b = win.FabricConfig) === null || _b === void 0 ? void 0 : _b.disableFocusRects) === true) {
44 return undefined;
45 }
46 var count = setMountCounters(win, 1);
47 if (count <= 1) {
48 win.addEventListener('mousedown', _onMouseDown, true);
49 win.addEventListener('pointerdown', _onPointerDown, true);
50 win.addEventListener('keydown', _onKeyDown, true);
51 }
52 return function () {
53 var _a;
54 if (!win || ((_a = win.FabricConfig) === null || _a === void 0 ? void 0 : _a.disableFocusRects) === true) {
55 return;
56 }
57 count = setMountCounters(win, -1);
58 if (count === 0) {
59 win.removeEventListener('mousedown', _onMouseDown, true);
60 win.removeEventListener('pointerdown', _onPointerDown, true);
61 win.removeEventListener('keydown', _onKeyDown, true);
62 }
63 };
64 }, [rootRef]);
65}
66exports.useFocusRects = useFocusRects;
67/**
68 * Function Component wrapper which enables calling `useFocusRects` hook.
69 * Renders nothing.
70 */
71exports.FocusRects = function (props) {
72 useFocusRects(props.rootRef);
73 return null;
74};
75function _onMouseDown(ev) {
76 setFocusVisibility_1.setFocusVisibility(false, ev.target);
77}
78function _onPointerDown(ev) {
79 if (ev.pointerType !== 'mouse') {
80 setFocusVisibility_1.setFocusVisibility(false, ev.target);
81 }
82}
83function _onKeyDown(ev) {
84 // eslint-disable-next-line deprecation/deprecation
85 if (keyboard_1.isDirectionalKeyCode(ev.which)) {
86 setFocusVisibility_1.setFocusVisibility(true, ev.target);
87 }
88}
89//# sourceMappingURL=useFocusRects.js.map
\No newline at end of file