UNPKG

@uifabric/utilities

Version:

Fluent UI React utilities for building components.

1 lines 5.42 kB
{"version":3,"file":"useFocusRects.js","sourceRoot":"../src/","sources":["useFocusRects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;GAGG;AACH,IAAI,aAAa,GAAG,IAAI,OAAO,EAAkB,CAAC;AAElD,SAAS,gBAAgB,CAAC,GAAW,EAAE,KAAa;IAClD,IAAI,QAAQ,CAAC;IACb,IAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,SAAS,EAAE;QACb,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;KAC9B;SAAM;QACL,QAAQ,GAAG,CAAC,CAAC;KACd;IAED,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACjC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAID;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,aAAa,CAAC,OAAsC;IAClE,KAAK,CAAC,SAAS,CAAC;;QACd,IAAM,GAAG,GAAG,SAAS,OAAC,OAAO,0CAAE,OAAO,CAAc,CAAC;QAErD,IAAI,CAAC,GAAG,IAAI,OAAA,GAAG,CAAC,YAAY,0CAAE,iBAAiB,MAAK,IAAI,EAAE;YACxD,OAAO,SAAS,CAAC;SAClB;QAED,IAAI,KAAK,GAAG,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrC,IAAI,KAAK,IAAI,CAAC,EAAE;YACd,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;YACtD,GAAG,CAAC,gBAAgB,CAAC,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;YAC1D,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;SACnD;QAED,OAAO;;YACL,IAAI,CAAC,GAAG,IAAI,OAAA,GAAG,CAAC,YAAY,0CAAE,iBAAiB,MAAK,IAAI,EAAE;gBACxD,OAAO;aACR;YAED,KAAK,GAAG,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,KAAK,KAAK,CAAC,EAAE;gBACf,GAAG,CAAC,mBAAmB,CAAC,WAAW,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;gBACzD,GAAG,CAAC,mBAAmB,CAAC,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;gBAC7D,GAAG,CAAC,mBAAmB,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;aACtD;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,IAAM,UAAU,GAAwE,UAAA,KAAK;IAClG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,SAAS,YAAY,CAAC,EAAc;IAClC,kBAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,MAAiB,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CAAC,EAAgB;IACtC,IAAI,EAAE,CAAC,WAAW,KAAK,OAAO,EAAE;QAC9B,kBAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,MAAiB,CAAC,CAAC;KACjD;AACH,CAAC;AAED,SAAS,UAAU,CAAC,EAAiB;IACnC,mDAAmD;IACnD,IAAI,oBAAoB,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;QAClC,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC,MAAiB,CAAC,CAAC;KAChD;AACH,CAAC","sourcesContent":["import * as React from 'react';\nimport { getWindow } from './dom/getWindow';\nimport { isDirectionalKeyCode } from './keyboard';\nimport { setFocusVisibility } from './setFocusVisibility';\n\n/**\n * Counter for mounted component that uses focus rectangle.\n * We want to cleanup the listners before last component that uses focus rectangle unmounts.\n */\nlet mountCounters = new WeakMap<Window, number>();\n\nfunction setMountCounters(key: Window, delta: number): number {\n let newValue;\n const currValue = mountCounters.get(key);\n if (currValue) {\n newValue = currValue + delta;\n } else {\n newValue = 1;\n }\n\n mountCounters.set(key, newValue);\n return newValue;\n}\n\ntype AppWindow = (Window & { FabricConfig?: { disableFocusRects?: boolean } }) | undefined;\n\n/**\n * Initializes the logic which:\n *\n * 1. Subscribes keydown and mousedown events. (It will only do it once per window,\n * so it's safe to call this method multiple times.)\n * 2. When the user presses directional keyboard keys, adds the 'ms-Fabric--isFocusVisible' classname\n * to the document body, removes the 'ms-Fabric-isFocusHidden' classname.\n * 3. When the user clicks a mouse button, adds the 'ms-Fabric-isFocusHidden' classname to the\n * document body, removes the 'ms-Fabric--isFocusVisible' classname.\n *\n * This logic allows components on the page to conditionally render focus treatments based on\n * the existence of global classnames, which simplifies logic overall.\n *\n * @param rootRef - A Ref object. Focus rectangle can be applied on itself and all its children.\n */\nexport function useFocusRects(rootRef?: React.RefObject<HTMLElement>): void {\n React.useEffect(() => {\n const win = getWindow(rootRef?.current) as AppWindow;\n\n if (!win || win.FabricConfig?.disableFocusRects === true) {\n return undefined;\n }\n\n let count = setMountCounters(win, 1);\n if (count <= 1) {\n win.addEventListener('mousedown', _onMouseDown, true);\n win.addEventListener('pointerdown', _onPointerDown, true);\n win.addEventListener('keydown', _onKeyDown, true);\n }\n\n return () => {\n if (!win || win.FabricConfig?.disableFocusRects === true) {\n return;\n }\n\n count = setMountCounters(win, -1);\n if (count === 0) {\n win.removeEventListener('mousedown', _onMouseDown, true);\n win.removeEventListener('pointerdown', _onPointerDown, true);\n win.removeEventListener('keydown', _onKeyDown, true);\n }\n };\n }, [rootRef]);\n}\n\n/**\n * Function Component wrapper which enables calling `useFocusRects` hook.\n * Renders nothing.\n */\nexport const FocusRects: React.FunctionComponent<{ rootRef?: React.RefObject<HTMLElement> }> = props => {\n useFocusRects(props.rootRef);\n return null;\n};\n\nfunction _onMouseDown(ev: MouseEvent): void {\n setFocusVisibility(false, ev.target as Element);\n}\n\nfunction _onPointerDown(ev: PointerEvent): void {\n if (ev.pointerType !== 'mouse') {\n setFocusVisibility(false, ev.target as Element);\n }\n}\n\nfunction _onKeyDown(ev: KeyboardEvent): void {\n // eslint-disable-next-line deprecation/deprecation\n if (isDirectionalKeyCode(ev.which)) {\n setFocusVisibility(true, ev.target as Element);\n }\n}\n"]}