UNPKG

@wordpress/components

Version:
168 lines (166 loc) 4.95 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // packages/components/src/navigable-container/container.tsx var container_exports = {}; __export(container_exports, { default: () => container_default }); module.exports = __toCommonJS(container_exports); var import_element = require("@wordpress/element"); var import_dom = require("@wordpress/dom"); var import_jsx_runtime = require("react/jsx-runtime"); var noop = () => { }; var MENU_ITEM_ROLES = ["menuitem", "menuitemradio", "menuitemcheckbox"]; function cycleValue(value, total, offset) { const nextValue = value + offset; if (nextValue < 0) { return total + nextValue; } else if (nextValue >= total) { return nextValue - total; } return nextValue; } var NavigableContainer = class extends import_element.Component { constructor(args) { super(args); this.onKeyDown = this.onKeyDown.bind(this); this.bindContainer = this.bindContainer.bind(this); this.getFocusableContext = this.getFocusableContext.bind(this); this.getFocusableIndex = this.getFocusableIndex.bind(this); } componentDidMount() { if (!this.container) { return; } this.container.addEventListener("keydown", this.onKeyDown); } componentWillUnmount() { if (!this.container) { return; } this.container.removeEventListener("keydown", this.onKeyDown); } bindContainer(ref) { const { forwardedRef } = this.props; this.container = ref; if (typeof forwardedRef === "function") { forwardedRef(ref); } else if (forwardedRef && "current" in forwardedRef) { forwardedRef.current = ref; } } getFocusableContext(target) { if (!this.container) { return null; } const { onlyBrowserTabstops } = this.props; const finder = onlyBrowserTabstops ? import_dom.focus.tabbable : import_dom.focus.focusable; const focusables = finder.find(this.container); const index = this.getFocusableIndex(focusables, target); if (index > -1 && target) { return { index, target, focusables }; } return null; } getFocusableIndex(focusables, target) { return focusables.indexOf(target); } onKeyDown(event) { if (this.props.onKeyDown) { this.props.onKeyDown(event); } const { getFocusableContext } = this; const { cycle = true, eventToOffset, onNavigate = noop, stopNavigationEvents } = this.props; const offset = eventToOffset(event); if (offset !== void 0 && stopNavigationEvents) { event.stopImmediatePropagation(); const targetRole = event.target?.getAttribute("role"); const targetHasMenuItemRole = !!targetRole && MENU_ITEM_ROLES.includes(targetRole); if (targetHasMenuItemRole) { event.preventDefault(); } } if (!offset) { return; } const activeElement = event.target?.ownerDocument?.activeElement; if (!activeElement) { return; } const context = getFocusableContext(activeElement); if (!context) { return; } const { index, focusables } = context; const nextIndex = cycle ? cycleValue(index, focusables.length, offset) : index + offset; if (nextIndex >= 0 && nextIndex < focusables.length) { focusables[nextIndex].focus(); onNavigate(nextIndex, focusables[nextIndex]); if (event.code === "Tab") { event.preventDefault(); } } } render() { const { children, stopNavigationEvents, eventToOffset, onNavigate, onKeyDown, cycle, onlyBrowserTabstops, forwardedRef, ...restProps } = this.props; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: this.bindContainer, ...restProps, children }); } }; var forwardedNavigableContainer = (props, ref) => { return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigableContainer, { ...props, forwardedRef: ref }); }; forwardedNavigableContainer.displayName = "NavigableContainer"; var container_default = (0, import_element.forwardRef)(forwardedNavigableContainer); //# sourceMappingURL=container.js.map