UNPKG

6.29 kBJavaScriptView Raw
1"use strict";
2/**
3 * @reach/dialog v0.18.0
4 *
5 * Copyright (c) 2018-2022, React Training LLC
6 *
7 * This source code is licensed under the MIT license found in the
8 * LICENSE.md file in the root directory of this source tree.
9 *
10 * @license MIT
11 */
12
13
14// src/reach-dialog.tsx
15import * as React from "react";
16import { Portal } from "@reach/portal";
17import {
18 composeEventHandlers,
19 createContext,
20 getOwnerDocument,
21 noop,
22 useComposedRefs
23} from "@reach/utils";
24import FocusLock from "react-focus-lock";
25import { RemoveScroll } from "react-remove-scroll";
26var [DialogContextProvider, useDialogContext] = createContext("DialogContext", {
27 isOpen: false
28});
29function DialogWrapper({
30 isOpen = true,
31 children,
32 ...props
33}) {
34 React.useEffect(() => {
35 if (isOpen) {
36 window.__REACH_DISABLE_TOOLTIPS = true;
37 } else {
38 window.requestAnimationFrame(() => {
39 window.__REACH_DISABLE_TOOLTIPS = false;
40 });
41 }
42 }, [isOpen]);
43 return /* @__PURE__ */ React.createElement(Portal, {
44 "data-reach-dialog-wrapper": "",
45 "data-state": isOpen ? "open" /* Open */ : "closed" /* Closed */,
46 ...props
47 }, /* @__PURE__ */ React.createElement(DialogContextProvider, {
48 isOpen
49 }, children));
50}
51DialogWrapper.displayName = "unstable_DialogWrapper";
52var DialogInner = React.forwardRef(function DialogInner2({
53 allowPinchZoom,
54 as: Comp = "div",
55 dangerouslyBypassFocusLock,
56 dangerouslyBypassScrollLock,
57 initialFocusRef,
58 onClick,
59 onDismiss = noop,
60 onKeyDown,
61 onMouseDown,
62 unstable_lockFocusAcrossFrames,
63 ...props
64}, forwardedRef) {
65 let { isOpen } = useDialogContext("DialogInner");
66 let lockFocusAcrossFramesIsDefined = unstable_lockFocusAcrossFrames !== void 0;
67 if (true) {
68 React.useEffect(() => {
69 if (lockFocusAcrossFramesIsDefined) {
70 console.warn(`The unstable_lockFocusAcrossFrames in @reach/dialog is deprecated. It will be removed in the next minor release.`);
71 }
72 }, [lockFocusAcrossFramesIsDefined]);
73 }
74 const mouseDownTarget = React.useRef(null);
75 const overlayNode = React.useRef(null);
76 const ref = useComposedRefs(overlayNode, forwardedRef);
77 const activateFocusLock = React.useCallback(() => {
78 if (initialFocusRef && initialFocusRef.current) {
79 initialFocusRef.current.focus();
80 }
81 }, [initialFocusRef]);
82 function handleClick(event) {
83 if (mouseDownTarget.current === event.target) {
84 event.stopPropagation();
85 onDismiss(event);
86 }
87 }
88 function handleKeyDown(event) {
89 if (event.key === "Escape") {
90 event.stopPropagation();
91 onDismiss(event);
92 }
93 }
94 function handleMouseDown(event) {
95 mouseDownTarget.current = event.target;
96 }
97 React.useEffect(() => {
98 return overlayNode.current ? createAriaHider(overlayNode.current) : void 0;
99 }, []);
100 return /* @__PURE__ */ React.createElement(FocusLock, {
101 autoFocus: true,
102 returnFocus: true,
103 onActivation: activateFocusLock,
104 disabled: dangerouslyBypassFocusLock != null ? dangerouslyBypassFocusLock : !isOpen,
105 crossFrame: unstable_lockFocusAcrossFrames ?? true
106 }, /* @__PURE__ */ React.createElement(RemoveScroll, {
107 allowPinchZoom,
108 enabled: dangerouslyBypassScrollLock != null ? !dangerouslyBypassScrollLock : isOpen
109 }, /* @__PURE__ */ React.createElement(Comp, {
110 ...props,
111 ref,
112 "data-reach-dialog-inner": "",
113 "data-state": isOpen ? "open" /* Open */ : "closed" /* Closed */,
114 onClick: composeEventHandlers(onClick, handleClick),
115 onKeyDown: composeEventHandlers(onKeyDown, handleKeyDown),
116 onMouseDown: composeEventHandlers(onMouseDown, handleMouseDown)
117 })));
118});
119DialogInner.displayName = "DialogInner";
120var DialogOverlay = React.forwardRef(function DialogOverlay2({ as: Comp = "div", isOpen = true, ...props }, forwardedRef) {
121 return isOpen ? /* @__PURE__ */ React.createElement(DialogWrapper, {
122 isOpen
123 }, /* @__PURE__ */ React.createElement(DialogInner, {
124 "data-reach-dialog-overlay": "",
125 ref: forwardedRef,
126 as: Comp,
127 ...props
128 })) : null;
129});
130DialogOverlay.displayName = "DialogOverlay";
131var DialogContent = React.forwardRef(function DialogContent2({ as: Comp = "div", onClick, onKeyDown, ...props }, forwardedRef) {
132 let { isOpen } = useDialogContext("DialogContent");
133 return /* @__PURE__ */ React.createElement(Comp, {
134 "aria-modal": "true",
135 role: "dialog",
136 tabIndex: -1,
137 ...props,
138 ref: forwardedRef,
139 "data-reach-dialog-content": "",
140 "data-state": isOpen ? "open" /* Open */ : "closed" /* Closed */,
141 onClick: composeEventHandlers(onClick, (event) => {
142 event.stopPropagation();
143 })
144 });
145});
146DialogContent.displayName = "DialogContent";
147var Dialog = React.forwardRef(function Dialog2({
148 allowPinchZoom = false,
149 initialFocusRef,
150 isOpen,
151 onDismiss = noop,
152 ...props
153}, forwardedRef) {
154 return /* @__PURE__ */ React.createElement(DialogOverlay, {
155 allowPinchZoom,
156 initialFocusRef,
157 isOpen,
158 onDismiss
159 }, /* @__PURE__ */ React.createElement(DialogContent, {
160 ref: forwardedRef,
161 ...props
162 }));
163});
164Dialog.displayName = "Dialog";
165function createAriaHider(dialogNode) {
166 let originalValues = [];
167 let rootNodes = [];
168 let ownerDocument = getOwnerDocument(dialogNode);
169 if (!dialogNode) {
170 if (true) {
171 console.warn("A ref has not yet been attached to a dialog node when attempting to call `createAriaHider`.");
172 }
173 return noop;
174 }
175 Array.prototype.forEach.call(ownerDocument.querySelectorAll("body > *"), (node) => {
176 const portalNode = dialogNode.parentNode?.parentNode?.parentNode;
177 if (node === portalNode) {
178 return;
179 }
180 let attr = node.getAttribute("aria-hidden");
181 let alreadyHidden = attr !== null && attr !== "false";
182 if (alreadyHidden) {
183 return;
184 }
185 originalValues.push(attr);
186 rootNodes.push(node);
187 node.setAttribute("aria-hidden", "true");
188 });
189 return () => {
190 rootNodes.forEach((node, index) => {
191 let originalValue = originalValues[index];
192 if (originalValue === null) {
193 node.removeAttribute("aria-hidden");
194 } else {
195 node.setAttribute("aria-hidden", originalValue);
196 }
197 });
198 };
199}
200export {
201 Dialog,
202 DialogContent,
203 DialogInner,
204 DialogOverlay,
205 DialogWrapper as unstable_DialogWrapper
206};