@ariakit/react
Version:
Toolkit for building accessible web apps with React
297 lines (270 loc) • 11 kB
JavaScript
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
var _LZ6L3ECGcjs = require('./LZ6L3ECG.cjs');
// ../ariakit-react-components/dist/focusable/focusable-context.js
var _react = require('react');
var FocusableContext = _react.createContext.call(void 0, true);
// ../ariakit-react-components/dist/focusable/focusable.js
var TagName = "div";
var accessibleWhenDisabledSymbol = /* @__PURE__ */ Symbol("accessibleWhenDisabled");
var isSafariBrowser = _LZ6L3ECGcjs.isSafari.call(void 0, );
var alwaysFocusVisibleInputTypes = [
"text",
"search",
"url",
"tel",
"email",
"password",
"number",
"date",
"month",
"week",
"time",
"datetime",
"datetime-local"
];
function isAlwaysFocusVisible(element) {
const { tagName, readOnly, type } = element;
if (tagName === "TEXTAREA" && !readOnly) return true;
if (tagName === "SELECT" && !readOnly) return true;
if (tagName === "INPUT" && !readOnly) return alwaysFocusVisibleInputTypes.includes(type);
if (element.isContentEditable) return true;
if (element.getAttribute("role") === "combobox" && element.dataset.name) return true;
return false;
}
function isNativeTabbable(tagName) {
if (!tagName) return true;
return tagName === "button" || tagName === "summary" || tagName === "input" || tagName === "select" || tagName === "textarea" || tagName === "a";
}
function supportsDisabledAttribute(tagName) {
if (!tagName) return true;
return tagName === "button" || tagName === "input" || tagName === "select" || tagName === "textarea";
}
function isNativeSubmitControl(element) {
if (element.tagName === "BUTTON") {
const { type } = element;
return type === "submit";
}
if (element.tagName === "INPUT") {
const { type } = element;
return type === "submit" || type === "image";
}
return false;
}
function getTabIndex({ focusable, trulyDisabled, nativeTabbable, supportsDisabled, safariTabIndex, tabIndexProp }) {
if (!focusable) return tabIndexProp;
if (trulyDisabled) {
if (nativeTabbable && !supportsDisabled) return -1;
return;
}
if (nativeTabbable) {
if (safariTabIndex && tabIndexProp == null) return 0;
return tabIndexProp;
}
return tabIndexProp != null ? tabIndexProp : 0;
}
function useDisableEvent(onEvent, disabled) {
return _LZ6L3ECGcjs.useEvent.call(void 0, (event) => {
onEvent == null ? void 0 : onEvent(event);
if (event.defaultPrevented) return;
if (disabled) {
event.stopPropagation();
event.preventDefault();
}
});
}
var hasInstalledGlobalEventListeners = false;
var isKeyboardModality = true;
function onGlobalMouseDown(event) {
const target = event.target;
if (_LZ6L3ECGcjs.isElement.call(void 0, target) && !target.hasAttribute("data-focus-visible")) isKeyboardModality = false;
}
function onGlobalKeyDown(event) {
if (event.metaKey) return;
if (event.ctrlKey) return;
if (event.altKey) return;
isKeyboardModality = true;
}
var useFocusable = _LZ6L3ECGcjs.createHook.call(void 0, function useFocusable2({ focusable = true, accessibleWhenDisabled, autoFocus, onFocusVisible, ...props }) {
const ref = _react.useRef.call(void 0, null);
const [parentAccessibleWhenDisabled, metadataProps] = _LZ6L3ECGcjs.useMetadataProps.call(void 0, props, accessibleWhenDisabledSymbol, accessibleWhenDisabled);
accessibleWhenDisabled != null ? accessibleWhenDisabled : accessibleWhenDisabled = parentAccessibleWhenDisabled;
_react.useEffect.call(void 0, () => {
if (!focusable) return;
if (hasInstalledGlobalEventListeners) return;
_LZ6L3ECGcjs.addGlobalEventListener.call(void 0, "mousedown", onGlobalMouseDown, true);
_LZ6L3ECGcjs.addGlobalEventListener.call(void 0, "keydown", onGlobalKeyDown, true);
hasInstalledGlobalEventListeners = true;
}, [focusable]);
const disabled = focusable && _LZ6L3ECGcjs.disabledFromProps.call(void 0, props);
const trulyDisabled = disabled && !accessibleWhenDisabled;
const [focusVisible, setFocusVisible] = _react.useState.call(void 0, false);
const focusVisibleRef = _react.useRef.call(void 0, false);
const nativeSubmitObserverCleanupRef = _react.useRef.call(void 0, null);
const cleanupFocusVisible = _LZ6L3ECGcjs.useEvent.call(void 0, (element) => {
var _a;
(_a = nativeSubmitObserverCleanupRef.current) == null ? void 0 : _a.call(nativeSubmitObserverCleanupRef);
nativeSubmitObserverCleanupRef.current = null;
focusVisibleRef.current = false;
element == null ? void 0 : element.removeAttribute("data-focus-visible");
});
_react.useEffect.call(void 0, () => {
if (!focusable) return;
if (!trulyDisabled) return;
cleanupFocusVisible(ref.current);
if (focusVisible) setFocusVisible(false);
}, [
focusable,
trulyDisabled,
focusVisible,
cleanupFocusVisible
]);
_react.useEffect.call(void 0, () => {
if (!focusable) return;
if (!focusVisible) return;
const element = ref.current;
if (!element) return;
if (typeof IntersectionObserver === "undefined") return;
const observer = new IntersectionObserver(() => {
if (!_LZ6L3ECGcjs.isFocusable.call(void 0, element)) {
focusVisibleRef.current = false;
setFocusVisible(false);
}
});
observer.observe(element);
return () => observer.disconnect();
}, [focusable, focusVisible]);
_react.useEffect.call(void 0, () => {
return () => {
var _a;
return (_a = nativeSubmitObserverCleanupRef.current) == null ? void 0 : _a.call(nativeSubmitObserverCleanupRef);
};
}, []);
const onKeyPressCapture = useDisableEvent(props.onKeyPressCapture, disabled);
const onMouseDownCapture = useDisableEvent(props.onMouseDownCapture, disabled);
const onClickCapture = useDisableEvent(props.onClickCapture, disabled);
const handleFocusVisible = (event, currentTarget) => {
var _a;
if (currentTarget) event.currentTarget = currentTarget;
if (!focusable) return;
const element = event.currentTarget;
if (!element) return;
if (!_LZ6L3ECGcjs.hasFocus.call(void 0, element)) return;
onFocusVisible == null ? void 0 : onFocusVisible(event);
if (event.defaultPrevented) return;
element.dataset.focusVisible = "true";
focusVisibleRef.current = true;
if (isNativeSubmitControl(element)) {
(_a = nativeSubmitObserverCleanupRef.current) == null ? void 0 : _a.call(nativeSubmitObserverCleanupRef);
nativeSubmitObserverCleanupRef.current = null;
if (typeof IntersectionObserver !== "undefined") {
const observer = new IntersectionObserver(() => {
if (_LZ6L3ECGcjs.isFocusable.call(void 0, element)) return;
cleanupFocusVisible(element);
});
observer.observe(element);
nativeSubmitObserverCleanupRef.current = () => observer.disconnect();
}
return;
}
setFocusVisible(true);
};
const onKeyDownCaptureProp = props.onKeyDownCapture;
const onKeyDownCapture = _LZ6L3ECGcjs.useEvent.call(void 0, (event) => {
onKeyDownCaptureProp == null ? void 0 : onKeyDownCaptureProp(event);
if (event.defaultPrevented) return;
if (!focusable) return;
if (focusVisible) return;
if (focusVisibleRef.current) return;
if (event.metaKey) return;
if (event.altKey) return;
if (event.ctrlKey) return;
if (!_LZ6L3ECGcjs.isSelfTarget.call(void 0, event)) return;
const element = event.currentTarget;
const applyFocusVisible = () => handleFocusVisible(event, element);
_LZ6L3ECGcjs.queueBeforeEvent.call(void 0, element, "focusout", applyFocusVisible);
});
const onFocusCaptureProp = props.onFocusCapture;
const onFocusCapture = _LZ6L3ECGcjs.useEvent.call(void 0, (event) => {
onFocusCaptureProp == null ? void 0 : onFocusCaptureProp(event);
if (event.defaultPrevented) return;
if (!focusable) return;
if (!_LZ6L3ECGcjs.isSelfTarget.call(void 0, event)) {
setFocusVisible(false);
return;
}
const element = event.currentTarget;
const applyFocusVisible = () => handleFocusVisible(event, element);
if (isKeyboardModality || isAlwaysFocusVisible(event.target)) _LZ6L3ECGcjs.queueBeforeEvent.call(void 0, event.target, "focusout", applyFocusVisible);
else setFocusVisible(false);
});
const onBlurProp = props.onBlur;
const onBlur = _LZ6L3ECGcjs.useEvent.call(void 0, (event) => {
onBlurProp == null ? void 0 : onBlurProp(event);
if (!focusable) return;
if (!_LZ6L3ECGcjs.isFocusEventOutside.call(void 0, event)) return;
cleanupFocusVisible(event.currentTarget);
setFocusVisible(false);
});
const autoFocusOnShow = _react.useContext.call(void 0, FocusableContext);
const autoFocusRef = _LZ6L3ECGcjs.useEvent.call(void 0, (element) => {
if (!focusable) return;
if (!autoFocus) return;
if (!element) return;
if (!autoFocusOnShow) return;
queueMicrotask(() => {
if (_LZ6L3ECGcjs.hasFocus.call(void 0, element)) return;
if (!_LZ6L3ECGcjs.isFocusable.call(void 0, element)) return;
element.focus();
});
});
const tagName = _LZ6L3ECGcjs.useTagName.call(void 0, ref);
const nativeTabbable = focusable && isNativeTabbable(tagName);
const supportsDisabled = focusable && supportsDisabledAttribute(tagName);
const [safariTabIndex, setSafariTabIndex] = _react.useState.call(void 0, false);
if (isSafariBrowser) _react.useEffect.call(void 0, () => {
if (!focusable) return;
const element = ref.current;
if (!element) return;
const { type } = element;
const isNativeCheckboxOrRadio = element.tagName === "INPUT" && (type === "checkbox" || type === "radio");
setSafariTabIndex(_LZ6L3ECGcjs.isButton.call(void 0, element) || isNativeCheckboxOrRadio);
}, [focusable]);
const styleProp = props.style;
const style = _react.useMemo.call(void 0, () => {
if (trulyDisabled) return {
pointerEvents: "none",
...styleProp
};
return styleProp;
}, [trulyDisabled, styleProp]);
props = {
"data-focus-visible": focusable && focusVisible || void 0,
"data-autofocus": autoFocus || void 0,
"aria-disabled": disabled || void 0,
...props,
...metadataProps,
ref: _LZ6L3ECGcjs.useMergeRefs.call(void 0, ref, autoFocusRef, props.ref),
style,
tabIndex: getTabIndex({
focusable,
trulyDisabled,
nativeTabbable,
supportsDisabled,
safariTabIndex,
tabIndexProp: props.tabIndex
}),
disabled: supportsDisabled && trulyDisabled ? true : void 0,
contentEditable: disabled ? void 0 : props.contentEditable,
onKeyPressCapture,
onClickCapture,
onMouseDownCapture,
onKeyDownCapture,
onFocusCapture,
onBlur
};
return _LZ6L3ECGcjs.removeUndefinedValues.call(void 0, props);
});
var Focusable = _LZ6L3ECGcjs.forwardRef.call(void 0, function Focusable2(props) {
return _LZ6L3ECGcjs.createElement.call(void 0, TagName, useFocusable(props));
});
exports.FocusableContext = FocusableContext; exports.useFocusable = useFocusable; exports.Focusable = Focusable;