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,18 @@
import { createElement } from "react";
/**
* WordPress dependencies
*/
import { chevronDown, Icon } from '@wordpress/icons';
/**
* Internal dependencies
*/
import { chevronIconSize, DownArrowWrapper, InputControlSuffixWrapperWithClickThrough } from './styles/select-control-styles';
const SelectControlChevronDown = () => {
return createElement(InputControlSuffixWrapperWithClickThrough, null, createElement(DownArrowWrapper, null, createElement(Icon, {
icon: chevronDown,
size: chevronIconSize
})));
};
export default SelectControlChevronDown;
//# sourceMappingURL=chevron-down.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["chevronDown","Icon","chevronIconSize","DownArrowWrapper","InputControlSuffixWrapperWithClickThrough","SelectControlChevronDown","createElement","icon","size"],"sources":["@wordpress/components/src/select-control/chevron-down.tsx"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { chevronDown, Icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport {\n\tchevronIconSize,\n\tDownArrowWrapper,\n\tInputControlSuffixWrapperWithClickThrough,\n} from './styles/select-control-styles';\n\nconst SelectControlChevronDown = () => {\n\treturn (\n\t\t<InputControlSuffixWrapperWithClickThrough>\n\t\t\t<DownArrowWrapper>\n\t\t\t\t<Icon icon={ chevronDown } size={ chevronIconSize } />\n\t\t\t</DownArrowWrapper>\n\t\t</InputControlSuffixWrapperWithClickThrough>\n\t);\n};\n\nexport default SelectControlChevronDown;\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,WAAW,EAAEC,IAAI,QAAQ,kBAAkB;;AAEpD;AACA;AACA;AACA,SACCC,eAAe,EACfC,gBAAgB,EAChBC,yCAAyC,QACnC,gCAAgC;AAEvC,MAAMC,wBAAwB,GAAGA,CAAA,KAAM;EACtC,OACCC,aAAA,CAACF,yCAAyC,QACzCE,aAAA,CAACH,gBAAgB,QAChBG,aAAA,CAACL,IAAI;IAACM,IAAI,EAAGP,WAAa;IAACQ,IAAI,EAAGN;EAAiB,CAAE,CACpC,CACwB,CAAC;AAE9C,CAAC;AAED,eAAeG,wBAAwB"}

View File

@@ -0,0 +1,151 @@
import { createElement } from "react";
/**
* External dependencies
*/
import classNames from 'classnames';
/**
* WordPress dependencies
*/
import { useInstanceId } from '@wordpress/compose';
import { useState, forwardRef } from '@wordpress/element';
/**
* Internal dependencies
*/
import BaseControl from '../base-control';
import InputBase from '../input-control/input-base';
import { Select } from './styles/select-control-styles';
import SelectControlChevronDown from './chevron-down';
import { useDeprecated36pxDefaultSizeProp } from '../utils/use-deprecated-props';
const noop = () => {};
function useUniqueId(idProp) {
const instanceId = useInstanceId(SelectControl);
const id = `inspector-select-control-${instanceId}`;
return idProp || id;
}
function UnforwardedSelectControl(props, ref) {
const {
className,
disabled = false,
help,
hideLabelFromVision,
id: idProp,
label,
multiple = false,
onBlur = noop,
onChange,
onFocus = noop,
options = [],
size = 'default',
value: valueProp,
labelPosition = 'top',
children,
prefix,
suffix,
__next40pxDefaultSize = false,
__nextHasNoMarginBottom = false,
...restProps
} = useDeprecated36pxDefaultSizeProp(props, 'wp.components.SelectControl', '6.4');
const [isFocused, setIsFocused] = useState(false);
const id = useUniqueId(idProp);
const helpId = help ? `${id}__help` : undefined;
// Disable reason: A select with an onchange throws a warning.
if (!options?.length && !children) return null;
const handleOnBlur = event => {
onBlur(event);
setIsFocused(false);
};
const handleOnFocus = event => {
onFocus(event);
setIsFocused(true);
};
const handleOnChange = event => {
if (props.multiple) {
const selectedOptions = Array.from(event.target.options).filter(({
selected
}) => selected);
const newValues = selectedOptions.map(({
value
}) => value);
props.onChange?.(newValues, {
event
});
return;
}
props.onChange?.(event.target.value, {
event
});
};
const classes = classNames('components-select-control', className);
return createElement(BaseControl, {
help: help,
id: id,
__nextHasNoMarginBottom: __nextHasNoMarginBottom
}, createElement(InputBase, {
className: classes,
disabled: disabled,
hideLabelFromVision: hideLabelFromVision,
id: id,
isFocused: isFocused,
label: label,
size: size,
suffix: suffix || !multiple && createElement(SelectControlChevronDown, null),
prefix: prefix,
labelPosition: labelPosition,
__next40pxDefaultSize: __next40pxDefaultSize
}, createElement(Select, {
...restProps,
__next40pxDefaultSize: __next40pxDefaultSize,
"aria-describedby": helpId,
className: "components-select-control__input",
disabled: disabled,
id: id,
multiple: multiple,
onBlur: handleOnBlur,
onChange: handleOnChange,
onFocus: handleOnFocus,
ref: ref,
selectSize: size,
value: valueProp
}, children || options.map((option, index) => {
const key = option.id || `${option.label}-${option.value}-${index}`;
return createElement("option", {
key: key,
value: option.value,
disabled: option.disabled,
hidden: option.hidden
}, option.label);
}))));
}
/**
* `SelectControl` allows users to select from a single or multiple option menu.
* It functions as a wrapper around the browser's native `<select>` element.
*
* ```jsx
* import { SelectControl } from '@wordpress/components';
* import { useState } from '@wordpress/element';
*
* const MySelectControl = () => {
* const [ size, setSize ] = useState( '50%' );
*
* return (
* <SelectControl
* label="Size"
* value={ size }
* options={ [
* { label: 'Big', value: '100%' },
* { label: 'Medium', value: '50%' },
* { label: 'Small', value: '25%' },
* ] }
* onChange={ setSize }
* />
* );
* };
* ```
*/
export const SelectControl = forwardRef(UnforwardedSelectControl);
export default SelectControl;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,36 @@
import { createElement } from "react";
/**
* WordPress dependencies
*/
import { memo } from '@wordpress/element';
/**
* Internal dependencies
*/
import PickerCell from '../mobile/bottom-sheet/picker-cell';
export const SelectControl = memo(({
help,
instanceId,
label,
multiple = false,
onChange,
options = [],
className,
hideLabelFromVision,
...props
}) => {
const id = `inspector-select-control-${instanceId}`;
return createElement(PickerCell, {
label: label,
hideLabelFromVision: hideLabelFromVision,
id: id,
help: help,
className: className,
onChangeValue: onChange,
"aria-describedby": !!help ? `${id}__help` : undefined,
multiple: multiple,
options: options,
...props
});
});
export default SelectControl;
//# sourceMappingURL=index.native.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["memo","PickerCell","SelectControl","help","instanceId","label","multiple","onChange","options","className","hideLabelFromVision","props","id","createElement","onChangeValue","undefined"],"sources":["@wordpress/components/src/select-control/index.native.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { memo } from '@wordpress/element';\n/**\n * Internal dependencies\n */\nimport PickerCell from '../mobile/bottom-sheet/picker-cell';\n\nexport const SelectControl = memo(\n\t( {\n\t\thelp,\n\t\tinstanceId,\n\t\tlabel,\n\t\tmultiple = false,\n\t\tonChange,\n\t\toptions = [],\n\t\tclassName,\n\t\thideLabelFromVision,\n\t\t...props\n\t} ) => {\n\t\tconst id = `inspector-select-control-${ instanceId }`;\n\n\t\treturn (\n\t\t\t<PickerCell\n\t\t\t\tlabel={ label }\n\t\t\t\thideLabelFromVision={ hideLabelFromVision }\n\t\t\t\tid={ id }\n\t\t\t\thelp={ help }\n\t\t\t\tclassName={ className }\n\t\t\t\tonChangeValue={ onChange }\n\t\t\t\taria-describedby={ !! help ? `${ id }__help` : undefined }\n\t\t\t\tmultiple={ multiple }\n\t\t\t\toptions={ options }\n\t\t\t\t{ ...props }\n\t\t\t/>\n\t\t);\n\t}\n);\n\nexport default SelectControl;\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,IAAI,QAAQ,oBAAoB;AACzC;AACA;AACA;AACA,OAAOC,UAAU,MAAM,oCAAoC;AAE3D,OAAO,MAAMC,aAAa,GAAGF,IAAI,CAChC,CAAE;EACDG,IAAI;EACJC,UAAU;EACVC,KAAK;EACLC,QAAQ,GAAG,KAAK;EAChBC,QAAQ;EACRC,OAAO,GAAG,EAAE;EACZC,SAAS;EACTC,mBAAmB;EACnB,GAAGC;AACJ,CAAC,KAAM;EACN,MAAMC,EAAE,GAAI,4BAA4BR,UAAY,EAAC;EAErD,OACCS,aAAA,CAACZ,UAAU;IACVI,KAAK,EAAGA,KAAO;IACfK,mBAAmB,EAAGA,mBAAqB;IAC3CE,EAAE,EAAGA,EAAI;IACTT,IAAI,EAAGA,IAAM;IACbM,SAAS,EAAGA,SAAW;IACvBK,aAAa,EAAGP,QAAU;IAC1B,oBAAmB,CAAC,CAAEJ,IAAI,GAAI,GAAGS,EAAI,QAAO,GAAGG,SAAW;IAC1DT,QAAQ,EAAGA,QAAU;IACrBE,OAAO,EAAGA,OAAS;IAAA,GACdG;EAAK,CACV,CAAC;AAEJ,CACD,CAAC;AAED,eAAeT,aAAa"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

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

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sources":["@wordpress/components/src/select-control/types.ts"],"sourcesContent":["/**\n * External dependencies\n */\nimport type { ChangeEvent, FocusEvent, ReactNode } from 'react';\n\n/**\n * Internal dependencies\n */\nimport type { InputBaseProps } from '../input-control/types';\nimport type { BaseControlProps } from '../base-control/types';\n\ntype SelectControlBaseProps = Pick<\n\tInputBaseProps,\n\t| '__next36pxDefaultSize'\n\t| '__next40pxDefaultSize'\n\t| 'disabled'\n\t| 'hideLabelFromVision'\n\t| 'label'\n\t| 'labelPosition'\n\t| 'prefix'\n\t| 'size'\n\t| 'suffix'\n> &\n\tPick< BaseControlProps, 'help' | '__nextHasNoMarginBottom' > & {\n\t\tonBlur?: ( event: FocusEvent< HTMLSelectElement > ) => void;\n\t\tonFocus?: ( event: FocusEvent< HTMLSelectElement > ) => void;\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * The label to be shown to the user.\n\t\t\t */\n\t\t\tlabel: string;\n\t\t\t/**\n\t\t\t * The internal value used to choose the selected value.\n\t\t\t * This is also the value passed to `onChange` when the option is selected.\n\t\t\t */\n\t\t\tvalue: string;\n\t\t\tid?: string;\n\t\t\t/**\n\t\t\t * Whether or not the option should have the disabled attribute.\n\t\t\t *\n\t\t\t * @default false\n\t\t\t */\n\t\t\tdisabled?: boolean;\n\t\t\t/**\n\t\t\t * Whether or not the option should be hidden.\n\t\t\t *\n\t\t\t * @default false\n\t\t\t */\n\t\t\thidden?: boolean;\n\t\t}[];\n\t\t/**\n\t\t * As an alternative to the `options` prop, `optgroup`s and `options` can be\n\t\t * passed in as `children` for more customizability.\n\t\t */\n\t\tchildren?: ReactNode;\n\t};\n\nexport type SelectControlSingleSelectionProps = SelectControlBaseProps & {\n\t/**\n\t * If this property is added, multiple values can be selected. The `value` passed should be an array.\n\t *\n\t * In most cases, it is preferable to use the `FormTokenField` or `CheckboxControl` components instead.\n\t *\n\t * @default false\n\t */\n\tmultiple?: false;\n\tvalue?: string;\n\t/**\n\t * A function that receives the value of the new option that is being selected as input.\n\t *\n\t * If `multiple` is `true`, the value received is an array of the selected value.\n\t * Otherwise, the value received is a single value with the new selected value.\n\t */\n\tonChange?: (\n\t\tvalue: string,\n\t\textra?: { event?: ChangeEvent< HTMLSelectElement > }\n\t) => void;\n};\n\nexport type SelectControlMultipleSelectionProps = SelectControlBaseProps & {\n\t/**\n\t * If this property is added, multiple values can be selected. The `value` passed should be an array.\n\t *\n\t * In most cases, it is preferable to use the `FormTokenField` or `CheckboxControl` components instead.\n\t *\n\t * @default false\n\t */\n\tmultiple: true;\n\tvalue?: string[];\n\t/**\n\t * A function that receives the value of the new option that is being selected as input.\n\t *\n\t * If `multiple` is `true`, the value received is an array of the selected value.\n\t * Otherwise, the value received is a single value with the new selected value.\n\t */\n\tonChange?: (\n\t\tvalue: string[],\n\t\textra?: { event?: ChangeEvent< HTMLSelectElement > }\n\t) => void;\n};\n\nexport type SelectControlProps =\n\t| SelectControlSingleSelectionProps\n\t| SelectControlMultipleSelectionProps;\n"],"mappings":""}