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,175 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = require("react");
var _a11y = require("@wordpress/a11y");
var _icons = require("@wordpress/icons");
var _i18n = require("@wordpress/i18n");
var _dropdownMenu = _interopRequireDefault(require("../../dropdown-menu"));
var _menuGroup = _interopRequireDefault(require("../../menu-group"));
var _menuItem = _interopRequireDefault(require("../../menu-item"));
var _hStack = require("../../h-stack");
var _heading = require("../../heading");
var _hook = require("./hook");
var _context = require("../../context");
var _styles = require("../styles");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const DefaultControlsGroup = ({
itemClassName,
items,
toggleItem
}) => {
if (!items.length) {
return null;
}
const resetSuffix = (0, _react.createElement)(_styles.ResetLabel, {
"aria-hidden": true
}, (0, _i18n.__)('Reset'));
return (0, _react.createElement)(_react.Fragment, null, items.map(([label, hasValue]) => {
if (hasValue) {
return (0, _react.createElement)(_menuItem.default, {
key: label,
className: itemClassName,
role: "menuitem",
label: (0, _i18n.sprintf)(
// translators: %s: The name of the control being reset e.g. "Padding".
(0, _i18n.__)('Reset %s'), label),
onClick: () => {
toggleItem(label);
(0, _a11y.speak)((0, _i18n.sprintf)(
// translators: %s: The name of the control being reset e.g. "Padding".
(0, _i18n.__)('%s reset to default'), label), 'assertive');
},
suffix: resetSuffix
}, label);
}
return (0, _react.createElement)(_menuItem.default, {
key: label,
icon: _icons.check,
className: itemClassName,
role: "menuitemcheckbox",
isSelected: true,
"aria-disabled": true
}, label);
}));
};
const OptionalControlsGroup = ({
items,
toggleItem
}) => {
if (!items.length) {
return null;
}
return (0, _react.createElement)(_react.Fragment, null, items.map(([label, isSelected]) => {
const itemLabel = isSelected ? (0, _i18n.sprintf)(
// translators: %s: The name of the control being hidden and reset e.g. "Padding".
(0, _i18n.__)('Hide and reset %s'), label) : (0, _i18n.sprintf)(
// translators: %s: The name of the control to display e.g. "Padding".
(0, _i18n.__)('Show %s'), label);
return (0, _react.createElement)(_menuItem.default, {
key: label,
icon: isSelected ? _icons.check : null,
isSelected: isSelected,
label: itemLabel,
onClick: () => {
if (isSelected) {
(0, _a11y.speak)((0, _i18n.sprintf)(
// translators: %s: The name of the control being reset e.g. "Padding".
(0, _i18n.__)('%s hidden and reset to default'), label), 'assertive');
} else {
(0, _a11y.speak)((0, _i18n.sprintf)(
// translators: %s: The name of the control being reset e.g. "Padding".
(0, _i18n.__)('%s is now visible'), label), 'assertive');
}
toggleItem(label);
},
role: "menuitemcheckbox"
}, label);
}));
};
const ToolsPanelHeader = (props, forwardedRef) => {
const {
areAllOptionalControlsHidden,
defaultControlsItemClassName,
dropdownMenuClassName,
hasMenuItems,
headingClassName,
headingLevel = 2,
label: labelText,
menuItems,
resetAll,
toggleItem,
dropdownMenuProps,
...headerProps
} = (0, _hook.useToolsPanelHeader)(props);
if (!labelText) {
return null;
}
const defaultItems = Object.entries(menuItems?.default || {});
const optionalItems = Object.entries(menuItems?.optional || {});
const dropDownMenuIcon = areAllOptionalControlsHidden ? _icons.plus : _icons.moreVertical;
const dropDownMenuLabelText = (0, _i18n.sprintf)(
// translators: %s: The name of the tool e.g. "Color" or "Typography".
(0, _i18n._x)('%s options', 'Button label to reveal tool panel options'), labelText);
const dropdownMenuDescriptionText = areAllOptionalControlsHidden ? (0, _i18n.__)('All options are currently hidden') : undefined;
const canResetAll = [...defaultItems, ...optionalItems].some(([, isSelected]) => isSelected);
return (0, _react.createElement)(_hStack.HStack, {
...headerProps,
ref: forwardedRef
}, (0, _react.createElement)(_heading.Heading, {
level: headingLevel,
className: headingClassName
}, labelText), hasMenuItems && (0, _react.createElement)(_dropdownMenu.default, {
...dropdownMenuProps,
icon: dropDownMenuIcon,
label: dropDownMenuLabelText,
menuProps: {
className: dropdownMenuClassName
},
toggleProps: {
isSmall: true,
describedBy: dropdownMenuDescriptionText
}
}, () => (0, _react.createElement)(_react.Fragment, null, (0, _react.createElement)(_menuGroup.default, {
label: labelText
}, (0, _react.createElement)(DefaultControlsGroup, {
items: defaultItems,
toggleItem: toggleItem,
itemClassName: defaultControlsItemClassName
}), (0, _react.createElement)(OptionalControlsGroup, {
items: optionalItems,
toggleItem: toggleItem
})), (0, _react.createElement)(_menuGroup.default, null, (0, _react.createElement)(_menuItem.default, {
"aria-disabled": !canResetAll
// @ts-expect-error - TODO: If this "tertiary" style is something we really want to allow on MenuItem,
// we should rename it and explicitly allow it as an official API. All the other Button variants
// don't make sense in a MenuItem context, and should be disallowed.
,
variant: 'tertiary',
onClick: () => {
if (canResetAll) {
resetAll();
(0, _a11y.speak)((0, _i18n.__)('All options reset'), 'assertive');
}
}
}, (0, _i18n.__)('Reset all'))))));
};
const ConnectedToolsPanelHeader = (0, _context.contextConnect)(ToolsPanelHeader, 'ToolsPanelHeader');
var _default = ConnectedToolsPanelHeader;
exports.default = _default;
//# sourceMappingURL=component.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useToolsPanelHeader = useToolsPanelHeader;
var _element = require("@wordpress/element");
var styles = _interopRequireWildcard(require("../styles"));
var _context = require("../context");
var _context2 = require("../../context");
var _useCx = require("../../utils/hooks/use-cx");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function useToolsPanelHeader(props) {
const {
className,
headingLevel = 2,
...otherProps
} = (0, _context2.useContextSystem)(props, 'ToolsPanelHeader');
const cx = (0, _useCx.useCx)();
const classes = (0, _element.useMemo)(() => {
return cx(styles.ToolsPanelHeader, className);
}, [className, cx]);
const dropdownMenuClassName = (0, _element.useMemo)(() => {
return cx(styles.DropdownMenu);
}, [cx]);
const headingClassName = (0, _element.useMemo)(() => {
return cx(styles.ToolsPanelHeading);
}, [cx]);
const defaultControlsItemClassName = (0, _element.useMemo)(() => {
return cx(styles.DefaultControlsItem);
}, [cx]);
const {
menuItems,
hasMenuItems,
areAllOptionalControlsHidden
} = (0, _context.useToolsPanelContext)();
return {
...otherProps,
areAllOptionalControlsHidden,
defaultControlsItemClassName,
dropdownMenuClassName,
hasMenuItems,
headingClassName,
headingLevel,
menuItems,
className: classes
};
}
//# sourceMappingURL=hook.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["_element","require","styles","_interopRequireWildcard","_context","_context2","_useCx","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","useToolsPanelHeader","props","className","headingLevel","otherProps","useContextSystem","cx","useCx","classes","useMemo","ToolsPanelHeader","dropdownMenuClassName","DropdownMenu","headingClassName","ToolsPanelHeading","defaultControlsItemClassName","DefaultControlsItem","menuItems","hasMenuItems","areAllOptionalControlsHidden","useToolsPanelContext"],"sources":["@wordpress/components/src/tools-panel/tools-panel-header/hook.ts"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useMemo } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport * as styles from '../styles';\nimport { useToolsPanelContext } from '../context';\nimport type { WordPressComponentProps } from '../../context';\nimport { useContextSystem } from '../../context';\nimport { useCx } from '../../utils/hooks/use-cx';\nimport type { ToolsPanelHeaderProps } from '../types';\n\nexport function useToolsPanelHeader(\n\tprops: WordPressComponentProps< ToolsPanelHeaderProps, 'h2' >\n) {\n\tconst {\n\t\tclassName,\n\t\theadingLevel = 2,\n\t\t...otherProps\n\t} = useContextSystem( props, 'ToolsPanelHeader' );\n\n\tconst cx = useCx();\n\tconst classes = useMemo( () => {\n\t\treturn cx( styles.ToolsPanelHeader, className );\n\t}, [ className, cx ] );\n\n\tconst dropdownMenuClassName = useMemo( () => {\n\t\treturn cx( styles.DropdownMenu );\n\t}, [ cx ] );\n\n\tconst headingClassName = useMemo( () => {\n\t\treturn cx( styles.ToolsPanelHeading );\n\t}, [ cx ] );\n\n\tconst defaultControlsItemClassName = useMemo( () => {\n\t\treturn cx( styles.DefaultControlsItem );\n\t}, [ cx ] );\n\n\tconst { menuItems, hasMenuItems, areAllOptionalControlsHidden } =\n\t\tuseToolsPanelContext();\n\n\treturn {\n\t\t...otherProps,\n\t\tareAllOptionalControlsHidden,\n\t\tdefaultControlsItemClassName,\n\t\tdropdownMenuClassName,\n\t\thasMenuItems,\n\t\theadingClassName,\n\t\theadingLevel,\n\t\tmenuItems,\n\t\tclassName: classes,\n\t};\n}\n"],"mappings":"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"}

View File

@@ -0,0 +1,14 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function () {
return _component.default;
}
});
var _component = _interopRequireDefault(require("./component"));
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["_component","_interopRequireDefault","require"],"sources":["@wordpress/components/src/tools-panel/tools-panel-header/index.ts"],"sourcesContent":["export { default } from './component';\n"],"mappings":";;;;;;;;;;;;AAAA,IAAAA,UAAA,GAAAC,sBAAA,CAAAC,OAAA"}