fix: prevent asset conflicts between React and Grid.js versions

Add coexistence checks to all enqueue methods to prevent loading
both React and Grid.js assets simultaneously.

Changes:
- ReactAdmin.php: Only enqueue React assets when ?react=1
- Init.php: Skip Grid.js when React active on admin pages
- Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0
- Customer.php, Product.php, License.php: Add coexistence checks

Now the toggle between Classic and React versions works correctly.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-18 17:02:14 +07:00
parent bd9cdac02e
commit e8fbfb14c1
74973 changed files with 6658406 additions and 71 deletions

View File

@@ -0,0 +1,33 @@
import { createElement, Fragment } from "react";
/**
* WordPress dependencies
*/
import { forwardRef } from '@wordpress/element';
/**
* Internal dependencies
*/
import TreeGridItem from './item';
function UnforwardedTreeGridCell({
children,
withoutGridItem = false,
...props
}, ref) {
return createElement("td", {
...props,
role: "gridcell"
}, withoutGridItem ? createElement(Fragment, null, children) : createElement(TreeGridItem, {
ref: ref
}, children));
}
/**
* `TreeGridCell` is used to create a tree hierarchy.
* It is not a visually styled component, but instead helps with adding
* keyboard navigation and roving tab index behaviors to tree grid structures.
*
* @see {@link https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html}
*/
export const TreeGridCell = forwardRef(UnforwardedTreeGridCell);
export default TreeGridCell;
//# sourceMappingURL=cell.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["forwardRef","TreeGridItem","UnforwardedTreeGridCell","children","withoutGridItem","props","ref","createElement","role","Fragment","TreeGridCell"],"sources":["@wordpress/components/src/tree-grid/cell.tsx"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { forwardRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport TreeGridItem from './item';\nimport type { WordPressComponentProps } from '../context';\nimport type { TreeGridCellProps } from './types';\n\nfunction UnforwardedTreeGridCell(\n\t{\n\t\tchildren,\n\t\twithoutGridItem = false,\n\t\t...props\n\t}: WordPressComponentProps< TreeGridCellProps, 'td', false >,\n\tref: React.ForwardedRef< any >\n) {\n\treturn (\n\t\t<td { ...props } role=\"gridcell\">\n\t\t\t{ withoutGridItem ? (\n\t\t\t\t<>{ children }</>\n\t\t\t) : (\n\t\t\t\t<TreeGridItem ref={ ref }>{ children }</TreeGridItem>\n\t\t\t) }\n\t\t</td>\n\t);\n}\n\n/**\n * `TreeGridCell` is used to create a tree hierarchy.\n * It is not a visually styled component, but instead helps with adding\n * keyboard navigation and roving tab index behaviors to tree grid structures.\n *\n * @see {@link https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html}\n */\nexport const TreeGridCell = forwardRef( UnforwardedTreeGridCell );\n\nexport default TreeGridCell;\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,UAAU,QAAQ,oBAAoB;;AAE/C;AACA;AACA;AACA,OAAOC,YAAY,MAAM,QAAQ;AAIjC,SAASC,uBAAuBA,CAC/B;EACCC,QAAQ;EACRC,eAAe,GAAG,KAAK;EACvB,GAAGC;AACuD,CAAC,EAC5DC,GAA8B,EAC7B;EACD,OACCC,aAAA;IAAA,GAASF,KAAK;IAAGG,IAAI,EAAC;EAAU,GAC7BJ,eAAe,GAChBG,aAAA,CAAAE,QAAA,QAAIN,QAAY,CAAC,GAEjBI,aAAA,CAACN,YAAY;IAACK,GAAG,EAAGA;EAAK,GAAGH,QAAwB,CAElD,CAAC;AAEP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMO,YAAY,GAAGV,UAAU,CAAEE,uBAAwB,CAAC;AAEjE,eAAeQ,YAAY"}

View File

@@ -0,0 +1,313 @@
import { createElement } from "react";
/**
* WordPress dependencies
*/
import { focus } from '@wordpress/dom';
import { forwardRef, useCallback } from '@wordpress/element';
import { UP, DOWN, LEFT, RIGHT, HOME, END } from '@wordpress/keycodes';
/**
* Internal dependencies
*/
import RovingTabIndexContainer from './roving-tab-index';
/**
* Return focusables in a row element, excluding those from other branches
* nested within the row.
*
* @param rowElement The DOM element representing the row.
*
* @return The array of focusables in the row.
*/
function getRowFocusables(rowElement) {
const focusablesInRow = focus.focusable.find(rowElement, {
sequential: true
});
return focusablesInRow.filter(focusable => {
return focusable.closest('[role="row"]') === rowElement;
});
}
/**
* Renders both a table and tbody element, used to create a tree hierarchy.
*
*/
function UnforwardedTreeGrid({
children,
onExpandRow = () => {},
onCollapseRow = () => {},
onFocusRow = () => {},
applicationAriaLabel,
...props
}, /** A ref to the underlying DOM table element. */
ref) {
const onKeyDown = useCallback(event => {
const {
keyCode,
metaKey,
ctrlKey,
altKey
} = event;
// The shift key is intentionally absent from the following list,
// to enable shift + up/down to select items from the list.
const hasModifierKeyPressed = metaKey || ctrlKey || altKey;
if (hasModifierKeyPressed || ![UP, DOWN, LEFT, RIGHT, HOME, END].includes(keyCode)) {
return;
}
// The event will be handled, stop propagation.
event.stopPropagation();
const {
activeElement
} = document;
const {
currentTarget: treeGridElement
} = event;
if (!activeElement || !treeGridElement.contains(activeElement)) {
return;
}
// Calculate the columnIndex of the active element.
const activeRow = activeElement.closest('[role="row"]');
if (!activeRow) {
return;
}
const focusablesInRow = getRowFocusables(activeRow);
const currentColumnIndex = focusablesInRow.indexOf(activeElement);
const canExpandCollapse = 0 === currentColumnIndex;
const cannotFocusNextColumn = canExpandCollapse && (activeRow.getAttribute('data-expanded') === 'false' || activeRow.getAttribute('aria-expanded') === 'false') && keyCode === RIGHT;
if ([LEFT, RIGHT].includes(keyCode)) {
// Calculate to the next element.
let nextIndex;
if (keyCode === LEFT) {
nextIndex = Math.max(0, currentColumnIndex - 1);
} else {
nextIndex = Math.min(currentColumnIndex + 1, focusablesInRow.length - 1);
}
// Focus is at the left most column.
if (canExpandCollapse) {
if (keyCode === LEFT) {
var _activeRow$getAttribu;
// Left:
// If a row is focused, and it is expanded, collapses the current row.
if (activeRow.getAttribute('data-expanded') === 'true' || activeRow.getAttribute('aria-expanded') === 'true') {
onCollapseRow(activeRow);
event.preventDefault();
return;
}
// If a row is focused, and it is collapsed, moves to the parent row (if there is one).
const level = Math.max(parseInt((_activeRow$getAttribu = activeRow?.getAttribute('aria-level')) !== null && _activeRow$getAttribu !== void 0 ? _activeRow$getAttribu : '1', 10) - 1, 1);
const rows = Array.from(treeGridElement.querySelectorAll('[role="row"]'));
let parentRow = activeRow;
const currentRowIndex = rows.indexOf(activeRow);
for (let i = currentRowIndex; i >= 0; i--) {
const ariaLevel = rows[i].getAttribute('aria-level');
if (ariaLevel !== null && parseInt(ariaLevel, 10) === level) {
parentRow = rows[i];
break;
}
}
getRowFocusables(parentRow)?.[0]?.focus();
}
if (keyCode === RIGHT) {
// Right:
// If a row is focused, and it is collapsed, expands the current row.
if (activeRow.getAttribute('data-expanded') === 'false' || activeRow.getAttribute('aria-expanded') === 'false') {
onExpandRow(activeRow);
event.preventDefault();
return;
}
// If a row is focused, and it is expanded, focuses the next cell in the row.
const focusableItems = getRowFocusables(activeRow);
if (focusableItems.length > 0) {
focusableItems[nextIndex]?.focus();
}
}
// Prevent key use for anything else. For example, Voiceover
// will start reading text on continued use of left/right arrow
// keys.
event.preventDefault();
return;
}
// Focus the next element. If at most left column and row is collapsed, moving right is not allowed as this will expand. However, if row is collapsed, moving left is allowed.
if (cannotFocusNextColumn) {
return;
}
focusablesInRow[nextIndex].focus();
// Prevent key use for anything else. This ensures Voiceover
// doesn't try to handle key navigation.
event.preventDefault();
} else if ([UP, DOWN].includes(keyCode)) {
// Calculate the rowIndex of the next row.
const rows = Array.from(treeGridElement.querySelectorAll('[role="row"]'));
const currentRowIndex = rows.indexOf(activeRow);
let nextRowIndex;
if (keyCode === UP) {
nextRowIndex = Math.max(0, currentRowIndex - 1);
} else {
nextRowIndex = Math.min(currentRowIndex + 1, rows.length - 1);
}
// Focus is either at the top or bottom edge of the grid. Do nothing.
if (nextRowIndex === currentRowIndex) {
// Prevent key use for anything else. For example, Voiceover
// will start navigating horizontally when reaching the vertical
// bounds of a table.
event.preventDefault();
return;
}
// Get the focusables in the next row.
const focusablesInNextRow = getRowFocusables(rows[nextRowIndex]);
// If for some reason there are no focusables in the next row, do nothing.
if (!focusablesInNextRow || !focusablesInNextRow.length) {
// Prevent key use for anything else. For example, Voiceover
// will still focus text when using arrow keys, while this
// component should limit navigation to focusables.
event.preventDefault();
return;
}
// Try to focus the element in the next row that's at a similar column to the activeElement.
const nextIndex = Math.min(currentColumnIndex, focusablesInNextRow.length - 1);
focusablesInNextRow[nextIndex].focus();
// Let consumers know the row that was originally focused,
// and the row that is now in focus.
onFocusRow(event, activeRow, rows[nextRowIndex]);
// Prevent key use for anything else. This ensures Voiceover
// doesn't try to handle key navigation.
event.preventDefault();
} else if ([HOME, END].includes(keyCode)) {
// Calculate the rowIndex of the next row.
const rows = Array.from(treeGridElement.querySelectorAll('[role="row"]'));
const currentRowIndex = rows.indexOf(activeRow);
let nextRowIndex;
if (keyCode === HOME) {
nextRowIndex = 0;
} else {
nextRowIndex = rows.length - 1;
}
// Focus is either at the top or bottom edge of the grid. Do nothing.
if (nextRowIndex === currentRowIndex) {
// Prevent key use for anything else. For example, Voiceover
// will start navigating horizontally when reaching the vertical
// bounds of a table.
event.preventDefault();
return;
}
// Get the focusables in the next row.
const focusablesInNextRow = getRowFocusables(rows[nextRowIndex]);
// If for some reason there are no focusables in the next row, do nothing.
if (!focusablesInNextRow || !focusablesInNextRow.length) {
// Prevent key use for anything else. For example, Voiceover
// will still focus text when using arrow keys, while this
// component should limit navigation to focusables.
event.preventDefault();
return;
}
// Try to focus the element in the next row that's at a similar column to the activeElement.
const nextIndex = Math.min(currentColumnIndex, focusablesInNextRow.length - 1);
focusablesInNextRow[nextIndex].focus();
// Let consumers know the row that was originally focused,
// and the row that is now in focus.
onFocusRow(event, activeRow, rows[nextRowIndex]);
// Prevent key use for anything else. This ensures Voiceover
// doesn't try to handle key navigation.
event.preventDefault();
}
}, [onExpandRow, onCollapseRow, onFocusRow]);
/* Disable reason: A treegrid is implemented using a table element. */
/* eslint-disable jsx-a11y/no-noninteractive-element-to-interactive-role */
return createElement(RovingTabIndexContainer, null, createElement("div", {
role: "application",
"aria-label": applicationAriaLabel
}, createElement("table", {
...props,
role: "treegrid",
onKeyDown: onKeyDown,
ref: ref
}, createElement("tbody", null, children))));
/* eslint-enable jsx-a11y/no-noninteractive-element-to-interactive-role */
}
/**
* `TreeGrid` is used to create a tree hierarchy.
* It is not a visually styled component, but instead helps with adding
* keyboard navigation and roving tab index behaviors to tree grid structures.
*
* A tree grid is a hierarchical 2 dimensional UI component, for example it could be
* used to implement a file system browser.
*
* A tree grid allows the user to navigate using arrow keys.
* Up/down to navigate vertically across rows, and left/right to navigate horizontally
* between focusables in a row.
*
* The `TreeGrid` renders both a `table` and `tbody` element, and is intended to be used
* with `TreeGridRow` (`tr`) and `TreeGridCell` (`td`) to build out a grid.
*
* ```jsx
* function TreeMenu() {
* return (
* <TreeGrid>
* <TreeGridRow level={ 1 } positionInSet={ 1 } setSize={ 2 }>
* <TreeGridCell>
* { ( props ) => (
* <Button onClick={ onSelect } { ...props }>Select</Button>
* ) }
* </TreeGridCell>
* <TreeGridCell>
* { ( props ) => (
* <Button onClick={ onMove } { ...props }>Move</Button>
* ) }
* </TreeGridCell>
* </TreeGridRow>
* <TreeGridRow level={ 1 } positionInSet={ 2 } setSize={ 2 }>
* <TreeGridCell>
* { ( props ) => (
* <Button onClick={ onSelect } { ...props }>Select</Button>
* ) }
* </TreeGridCell>
* <TreeGridCell>
* { ( props ) => (
* <Button onClick={ onMove } { ...props }>Move</Button>
* ) }
* </TreeGridCell>
* </TreeGridRow>
* <TreeGridRow level={ 2 } positionInSet={ 1 } setSize={ 1 }>
* <TreeGridCell>
* { ( props ) => (
* <Button onClick={ onSelect } { ...props }>Select</Button>
* ) }
* </TreeGridCell>
* <TreeGridCell>
* { ( props ) => (
* <Button onClick={ onMove } { ...props }>Move</Button>
* ) }
* </TreeGridCell>
* </TreeGridRow>
* </TreeGrid>
* );
* }
* ```
*
* @see {@link https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html}
*/
export const TreeGrid = forwardRef(UnforwardedTreeGrid);
export default TreeGrid;
export { default as TreeGridRow } from './row';
export { default as TreeGridCell } from './cell';
export { default as TreeGridItem } from './item';
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,30 @@
import { createElement } from "react";
/**
* WordPress dependencies
*/
import { forwardRef } from '@wordpress/element';
/**
* Internal dependencies
*/
import RovingTabIndexItem from './roving-tab-index-item';
function UnforwardedTreeGridItem({
children,
...props
}, ref) {
return createElement(RovingTabIndexItem, {
ref: ref,
...props
}, children);
}
/**
* `TreeGridItem` is used to create a tree hierarchy.
* It is not a visually styled component, but instead helps with adding
* keyboard navigation and roving tab index behaviors to tree grid structures.
*
* @see {@link https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html}
*/
export const TreeGridItem = forwardRef(UnforwardedTreeGridItem);
export default TreeGridItem;
//# sourceMappingURL=item.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["forwardRef","RovingTabIndexItem","UnforwardedTreeGridItem","children","props","ref","createElement","TreeGridItem"],"sources":["@wordpress/components/src/tree-grid/item.tsx"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { forwardRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport RovingTabIndexItem from './roving-tab-index-item';\nimport type { RovingTabIndexItemProps } from './types';\n\nfunction UnforwardedTreeGridItem(\n\t{ children, ...props }: RovingTabIndexItemProps,\n\tref: React.ForwardedRef< any >\n) {\n\treturn (\n\t\t<RovingTabIndexItem ref={ ref } { ...props }>\n\t\t\t{ children }\n\t\t</RovingTabIndexItem>\n\t);\n}\n\n/**\n * `TreeGridItem` is used to create a tree hierarchy.\n * It is not a visually styled component, but instead helps with adding\n * keyboard navigation and roving tab index behaviors to tree grid structures.\n *\n * @see {@link https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html}\n */\nexport const TreeGridItem = forwardRef( UnforwardedTreeGridItem );\n\nexport default TreeGridItem;\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,UAAU,QAAQ,oBAAoB;;AAE/C;AACA;AACA;AACA,OAAOC,kBAAkB,MAAM,yBAAyB;AAGxD,SAASC,uBAAuBA,CAC/B;EAAEC,QAAQ;EAAE,GAAGC;AAA+B,CAAC,EAC/CC,GAA8B,EAC7B;EACD,OACCC,aAAA,CAACL,kBAAkB;IAACI,GAAG,EAAGA,GAAK;IAAA,GAAMD;EAAK,GACvCD,QACiB,CAAC;AAEvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMI,YAAY,GAAGP,UAAU,CAAEE,uBAAwB,CAAC;AAEjE,eAAeK,YAAY"}

View File

@@ -0,0 +1,8 @@
/**
* WordPress dependencies
*/
import { createContext, useContext } from '@wordpress/element';
const RovingTabIndexContext = createContext(undefined);
export const useRovingTabIndexContext = () => useContext(RovingTabIndexContext);
export const RovingTabIndexProvider = RovingTabIndexContext.Provider;
//# sourceMappingURL=roving-tab-index-context.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["createContext","useContext","RovingTabIndexContext","undefined","useRovingTabIndexContext","RovingTabIndexProvider","Provider"],"sources":["@wordpress/components/src/tree-grid/roving-tab-index-context.ts"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { createContext, useContext } from '@wordpress/element';\n\nconst RovingTabIndexContext = createContext<\n\t| {\n\t\t\tlastFocusedElement: HTMLElement | undefined;\n\t\t\tsetLastFocusedElement: React.Dispatch<\n\t\t\t\tReact.SetStateAction< HTMLElement | undefined >\n\t\t\t>;\n\t }\n\t| undefined\n>( undefined );\nexport const useRovingTabIndexContext = () =>\n\tuseContext( RovingTabIndexContext );\nexport const RovingTabIndexProvider = RovingTabIndexContext.Provider;\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,aAAa,EAAEC,UAAU,QAAQ,oBAAoB;AAE9D,MAAMC,qBAAqB,GAAGF,aAAa,CAQxCG,SAAU,CAAC;AACd,OAAO,MAAMC,wBAAwB,GAAGA,CAAA,KACvCH,UAAU,CAAEC,qBAAsB,CAAC;AACpC,OAAO,MAAMG,sBAAsB,GAAGH,qBAAqB,CAACI,QAAQ"}

View File

@@ -0,0 +1,48 @@
import { createElement } from "react";
/**
* WordPress dependencies
*/
import { useRef, forwardRef } from '@wordpress/element';
/**
* Internal dependencies
*/
import { useRovingTabIndexContext } from './roving-tab-index-context';
export const RovingTabIndexItem = forwardRef(function UnforwardedRovingTabIndexItem({
children,
as: Component,
...props
}, forwardedRef) {
const localRef = useRef();
const ref = forwardedRef || localRef;
// @ts-expect-error - We actually want to throw an error if this is undefined.
const {
lastFocusedElement,
setLastFocusedElement
} = useRovingTabIndexContext();
let tabIndex;
if (lastFocusedElement) {
tabIndex = lastFocusedElement === (
// TODO: The original implementation simply used `ref.current` here, assuming
// that a forwarded ref would always be an object, which is not necessarily true.
// This workaround maintains the original runtime behavior in a type-safe way,
// but should be revisited.
'current' in ref ? ref.current : undefined) ? 0 : -1;
}
const onFocus = event => setLastFocusedElement?.(event.target);
const allProps = {
ref,
tabIndex,
onFocus,
...props
};
if (typeof children === 'function') {
return children(allProps);
}
if (!Component) return null;
return createElement(Component, {
...allProps
}, children);
});
export default RovingTabIndexItem;
//# sourceMappingURL=roving-tab-index-item.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useRef","forwardRef","useRovingTabIndexContext","RovingTabIndexItem","UnforwardedRovingTabIndexItem","children","as","Component","props","forwardedRef","localRef","ref","lastFocusedElement","setLastFocusedElement","tabIndex","current","undefined","onFocus","event","target","allProps","createElement"],"sources":["@wordpress/components/src/tree-grid/roving-tab-index-item.tsx"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useRef, forwardRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { useRovingTabIndexContext } from './roving-tab-index-context';\nimport type { RovingTabIndexItemProps } from './types';\n\nexport const RovingTabIndexItem = forwardRef(\n\tfunction UnforwardedRovingTabIndexItem(\n\t\t{ children, as: Component, ...props }: RovingTabIndexItemProps,\n\t\tforwardedRef: React.ForwardedRef< any >\n\t) {\n\t\tconst localRef = useRef< any >();\n\t\tconst ref = forwardedRef || localRef;\n\t\t// @ts-expect-error - We actually want to throw an error if this is undefined.\n\t\tconst { lastFocusedElement, setLastFocusedElement } =\n\t\t\tuseRovingTabIndexContext();\n\t\tlet tabIndex;\n\n\t\tif ( lastFocusedElement ) {\n\t\t\ttabIndex =\n\t\t\t\tlastFocusedElement ===\n\t\t\t\t// TODO: The original implementation simply used `ref.current` here, assuming\n\t\t\t\t// that a forwarded ref would always be an object, which is not necessarily true.\n\t\t\t\t// This workaround maintains the original runtime behavior in a type-safe way,\n\t\t\t\t// but should be revisited.\n\t\t\t\t( 'current' in ref ? ref.current : undefined )\n\t\t\t\t\t? 0\n\t\t\t\t\t: -1;\n\t\t}\n\n\t\tconst onFocus: React.FocusEventHandler< HTMLElement > = ( event ) =>\n\t\t\tsetLastFocusedElement?.( event.target );\n\t\tconst allProps = { ref, tabIndex, onFocus, ...props };\n\n\t\tif ( typeof children === 'function' ) {\n\t\t\treturn children( allProps );\n\t\t}\n\n\t\tif ( ! Component ) return null;\n\n\t\treturn <Component { ...allProps }>{ children }</Component>;\n\t}\n);\n\nexport default RovingTabIndexItem;\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,MAAM,EAAEC,UAAU,QAAQ,oBAAoB;;AAEvD;AACA;AACA;AACA,SAASC,wBAAwB,QAAQ,4BAA4B;AAGrE,OAAO,MAAMC,kBAAkB,GAAGF,UAAU,CAC3C,SAASG,6BAA6BA,CACrC;EAAEC,QAAQ;EAAEC,EAAE,EAAEC,SAAS;EAAE,GAAGC;AAA+B,CAAC,EAC9DC,YAAuC,EACtC;EACD,MAAMC,QAAQ,GAAGV,MAAM,CAAQ,CAAC;EAChC,MAAMW,GAAG,GAAGF,YAAY,IAAIC,QAAQ;EACpC;EACA,MAAM;IAAEE,kBAAkB;IAAEC;EAAsB,CAAC,GAClDX,wBAAwB,CAAC,CAAC;EAC3B,IAAIY,QAAQ;EAEZ,IAAKF,kBAAkB,EAAG;IACzBE,QAAQ,GACPF,kBAAkB;IAClB;IACA;IACA;IACA;IACE,SAAS,IAAID,GAAG,GAAGA,GAAG,CAACI,OAAO,GAAGC,SAAS,CAAE,GAC3C,CAAC,GACD,CAAC,CAAC;EACP;EAEA,MAAMC,OAA+C,GAAKC,KAAK,IAC9DL,qBAAqB,GAAIK,KAAK,CAACC,MAAO,CAAC;EACxC,MAAMC,QAAQ,GAAG;IAAET,GAAG;IAAEG,QAAQ;IAAEG,OAAO;IAAE,GAAGT;EAAM,CAAC;EAErD,IAAK,OAAOH,QAAQ,KAAK,UAAU,EAAG;IACrC,OAAOA,QAAQ,CAAEe,QAAS,CAAC;EAC5B;EAEA,IAAK,CAAEb,SAAS,EAAG,OAAO,IAAI;EAE9B,OAAOc,aAAA,CAACd,SAAS;IAAA,GAAMa;EAAQ,GAAKf,QAAqB,CAAC;AAC3D,CACD,CAAC;AAED,eAAeF,kBAAkB"}

View File

@@ -0,0 +1,33 @@
import { createElement } from "react";
/**
* WordPress dependencies
*/
import { useState, useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
import { RovingTabIndexProvider } from './roving-tab-index-context';
/**
* Provider for adding roving tab index behaviors to tree grid structures.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/components/src/tree-grid/README.md
*/
export default function RovingTabIndex({
children
}) {
const [lastFocusedElement, setLastFocusedElement] = useState();
// Use `useMemo` to avoid creation of a new object for the providerValue
// on every render. Only create a new object when the `lastFocusedElement`
// value changes.
const providerValue = useMemo(() => ({
lastFocusedElement,
setLastFocusedElement
}), [lastFocusedElement]);
return createElement(RovingTabIndexProvider, {
value: providerValue
}, children);
}
//# sourceMappingURL=roving-tab-index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useState","useMemo","RovingTabIndexProvider","RovingTabIndex","children","lastFocusedElement","setLastFocusedElement","providerValue","createElement","value"],"sources":["@wordpress/components/src/tree-grid/roving-tab-index.tsx"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useState, useMemo } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { RovingTabIndexProvider } from './roving-tab-index-context';\n\n/**\n * Provider for adding roving tab index behaviors to tree grid structures.\n *\n * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/components/src/tree-grid/README.md\n */\nexport default function RovingTabIndex( {\n\tchildren,\n}: {\n\tchildren: React.ReactNode;\n} ) {\n\tconst [ lastFocusedElement, setLastFocusedElement ] =\n\t\tuseState< HTMLElement >();\n\n\t// Use `useMemo` to avoid creation of a new object for the providerValue\n\t// on every render. Only create a new object when the `lastFocusedElement`\n\t// value changes.\n\tconst providerValue = useMemo(\n\t\t() => ( { lastFocusedElement, setLastFocusedElement } ),\n\t\t[ lastFocusedElement ]\n\t);\n\n\treturn (\n\t\t<RovingTabIndexProvider value={ providerValue }>\n\t\t\t{ children }\n\t\t</RovingTabIndexProvider>\n\t);\n}\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,QAAQ,EAAEC,OAAO,QAAQ,oBAAoB;;AAEtD;AACA;AACA;AACA,SAASC,sBAAsB,QAAQ,4BAA4B;;AAEnE;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,cAAcA,CAAE;EACvCC;AAGD,CAAC,EAAG;EACH,MAAM,CAAEC,kBAAkB,EAAEC,qBAAqB,CAAE,GAClDN,QAAQ,CAAgB,CAAC;;EAE1B;EACA;EACA;EACA,MAAMO,aAAa,GAAGN,OAAO,CAC5B,OAAQ;IAAEI,kBAAkB;IAAEC;EAAsB,CAAC,CAAE,EACvD,CAAED,kBAAkB,CACrB,CAAC;EAED,OACCG,aAAA,CAACN,sBAAsB;IAACO,KAAK,EAAGF;EAAe,GAC5CH,QACqB,CAAC;AAE3B"}

View File

@@ -0,0 +1,39 @@
import { createElement } from "react";
/**
* WordPress dependencies
*/
import { forwardRef } from '@wordpress/element';
/**
* Internal dependencies
*/
function UnforwardedTreeGridRow({
children,
level,
positionInSet,
setSize,
isExpanded,
...props
}, ref) {
return createElement("tr", {
...props,
ref: ref,
role: "row",
"aria-level": level,
"aria-posinset": positionInSet,
"aria-setsize": setSize,
"aria-expanded": isExpanded
}, children);
}
/**
* `TreeGridRow` is used to create a tree hierarchy.
* It is not a visually styled component, but instead helps with adding
* keyboard navigation and roving tab index behaviors to tree grid structures.
*
* @see {@link https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html}
*/
export const TreeGridRow = forwardRef(UnforwardedTreeGridRow);
export default TreeGridRow;
//# sourceMappingURL=row.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["forwardRef","UnforwardedTreeGridRow","children","level","positionInSet","setSize","isExpanded","props","ref","createElement","role","TreeGridRow"],"sources":["@wordpress/components/src/tree-grid/row.tsx"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { forwardRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport type { WordPressComponentProps } from '../context';\nimport type { TreeGridRowProps } from './types';\n\nfunction UnforwardedTreeGridRow(\n\t{\n\t\tchildren,\n\t\tlevel,\n\t\tpositionInSet,\n\t\tsetSize,\n\t\tisExpanded,\n\t\t...props\n\t}: WordPressComponentProps< TreeGridRowProps, 'tr', false >,\n\tref: React.ForwardedRef< HTMLTableRowElement >\n) {\n\treturn (\n\t\t<tr\n\t\t\t{ ...props }\n\t\t\tref={ ref }\n\t\t\trole=\"row\"\n\t\t\taria-level={ level }\n\t\t\taria-posinset={ positionInSet }\n\t\t\taria-setsize={ setSize }\n\t\t\taria-expanded={ isExpanded }\n\t\t>\n\t\t\t{ children }\n\t\t</tr>\n\t);\n}\n\n/**\n * `TreeGridRow` is used to create a tree hierarchy.\n * It is not a visually styled component, but instead helps with adding\n * keyboard navigation and roving tab index behaviors to tree grid structures.\n *\n * @see {@link https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html}\n */\nexport const TreeGridRow = forwardRef( UnforwardedTreeGridRow );\n\nexport default TreeGridRow;\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,UAAU,QAAQ,oBAAoB;;AAE/C;AACA;AACA;;AAIA,SAASC,sBAAsBA,CAC9B;EACCC,QAAQ;EACRC,KAAK;EACLC,aAAa;EACbC,OAAO;EACPC,UAAU;EACV,GAAGC;AACsD,CAAC,EAC3DC,GAA8C,EAC7C;EACD,OACCC,aAAA;IAAA,GACMF,KAAK;IACVC,GAAG,EAAGA,GAAK;IACXE,IAAI,EAAC,KAAK;IACV,cAAaP,KAAO;IACpB,iBAAgBC,aAAe;IAC/B,gBAAeC,OAAS;IACxB,iBAAgBC;EAAY,GAE1BJ,QACC,CAAC;AAEP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMS,WAAW,GAAGX,UAAU,CAAEC,sBAAuB,CAAC;AAE/D,eAAeU,WAAW"}

View File

@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sources":["@wordpress/components/src/tree-grid/types.ts"],"sourcesContent":["export type TreeGridRowProps = {\n\t/**\n\t * The children to be rendered in the row.\n\t */\n\tchildren: React.ReactNode;\n\t/**\n\t * An integer value designating the level in the hierarchical tree structure.\n\t * Counting starts at 1. A value of `1` indicates the root level of the structure.\n\t */\n\tlevel: NonNullable< React.AriaAttributes[ 'aria-level' ] >;\n\t/**\n\t * An integer value that represents the position in the set.\n\t * A set is the count of elements at a specific level. Counting starts at 1.\n\t */\n\tpositionInSet: NonNullable< React.AriaAttributes[ 'aria-posinset' ] >;\n\t/**\n\t * An integer value that represents the total number of items in the set,\n\t * at this specific level of the hierarchy.\n\t */\n\tsetSize: NonNullable< React.AriaAttributes[ 'aria-setsize' ] >;\n\t/**\n\t * An optional value that designates whether a row is expanded or collapsed.\n\t * Currently this value only sets the correct aria-expanded property on a row,\n\t * it has no other built-in behavior.\n\t *\n\t * If there is a need to implement `aria-expanded` elsewhere in the row, cell,\n\t * or element within a cell, you may pass `isExpanded={ undefined }`.\n\t * In order for keyboard navigation to continue working, add the\n\t * `data-expanded` attribute with either `true`/`false`. This allows the\n\t * `TreeGrid` component to still manage keyboard interactions while allowing\n\t * the `aria-expanded` attribute to be placed elsewhere.\n\t */\n\tisExpanded?: boolean;\n};\n\ntype RovingTabIndexItemPassThruProps = {\n\tref: React.ForwardedRef< any >;\n\ttabIndex?: number;\n\tonFocus: React.FocusEventHandler< any >;\n\t[ key: string ]: any;\n};\n\nexport type RovingTabIndexItemProps = {\n\t/**\n\t * A render function that receives the props necessary to make it participate in the\n\t * roving tabindex. Any extra props will also be passed through to this function.\n\t *\n\t * Props passed as an argument to the render prop must be passed to the child\n\t * focusable component/element within the cell. If a component is used, it must\n\t * correctly handle the `onFocus`, `tabIndex`, and `ref` props, passing these to the\n\t * element it renders. These props are used to handle the roving tabindex functionality\n\t * of the tree grid.\n\t *\n\t * ```jsx\n\t * <TreeGridCell>\n\t * \t{ ( props ) => (\n\t * \t\t<Button onClick={ doSomething } { ...props }>\n\t * \t\t\tDo something\n\t * \t\t</Button>\n\t * \t) }\n\t * </TreeGridCell>\n\t * ```\n\t */\n\tchildren?: ( props: RovingTabIndexItemPassThruProps ) => JSX.Element;\n\t/**\n\t * If `children` is not a function, this component will be used instead.\n\t */\n\tas?: React.ComponentType< RovingTabIndexItemPassThruProps >;\n\t[ key: string ]: any;\n};\n\nexport type TreeGridCellProps =\n\t| ( {\n\t\t\t/**\n\t\t\t * Render `children` without wrapping it in a `TreeGridItem` component.\n\t\t\t * This means that `children` will not participate in the roving tabindex.\n\t\t\t *\n\t\t\t * @default false\n\t\t\t */\n\t\t\twithoutGridItem?: false;\n\t } & NonNullable< Pick< RovingTabIndexItemProps, 'children' > > )\n\t| {\n\t\t\tchildren: React.ReactNode;\n\t\t\twithoutGridItem: true;\n\t };\n\nexport type TreeGridProps = {\n\t/**\n\t * Label to use for the element with the `application` role.\n\t */\n\tapplicationAriaLabel?: string;\n\t/**\n\t * The children to be rendered in the tree grid.\n\t */\n\tchildren: React.ReactNode;\n\t/**\n\t * Callback to fire when row is expanded.\n\t *\n\t * @default noop\n\t */\n\tonExpandRow?: ( row: HTMLElement ) => void;\n\t/**\n\t * Callback to fire when row is collapsed.\n\t *\n\t * @default noop\n\t */\n\tonCollapseRow?: ( row: HTMLElement ) => void;\n\t/**\n\t * Callback that fires when focus is shifted from one row to another via\n\t * the Up and Down keys. Callback is also fired on Home and End keys which\n\t * move focus from the beginning row to the end row.\n\t *\n\t * The callback is passed the event, the start row element that the focus was on\n\t * originally, and the destination row element after the focus has moved.\n\t *\n\t * @default noop\n\t */\n\tonFocusRow?: (\n\t\tevent: React.KeyboardEvent< HTMLTableElement >,\n\t\tstartRow: HTMLElement,\n\t\tdestinationRow: HTMLElement\n\t) => void;\n};\n"],"mappings":""}