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,87 @@
import { createElement } from "react";
/**
* External dependencies
*/
import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { useInstanceId } from '@wordpress/compose';
/**
* Internal dependencies
*/
import BaseControl from '../base-control';
import { VStack } from '../v-stack';
/**
* Render a user interface to select the user type using radio inputs.
*
* ```jsx
* import { RadioControl } from '@wordpress/components';
* import { useState } from '@wordpress/element';
*
* const MyRadioControl = () => {
* const [ option, setOption ] = useState( 'a' );
*
* return (
* <RadioControl
* label="User type"
* help="The type of the current user"
* selected={ option }
* options={ [
* { label: 'Author', value: 'a' },
* { label: 'Editor', value: 'e' },
* ] }
* onChange={ ( value ) => setOption( value ) }
* />
* );
* };
* ```
*/
export function RadioControl(props) {
const {
label,
className,
selected,
help,
onChange,
hideLabelFromVision,
options = [],
...additionalProps
} = props;
const instanceId = useInstanceId(RadioControl);
const id = `inspector-radio-control-${instanceId}`;
const onChangeValue = event => onChange(event.target.value);
if (!options?.length) {
return null;
}
return createElement(BaseControl, {
__nextHasNoMarginBottom: true,
label: label,
id: id,
hideLabelFromVision: hideLabelFromVision,
help: help,
className: classnames(className, 'components-radio-control')
}, createElement(VStack, {
spacing: 1
}, options.map((option, index) => createElement("div", {
key: `${id}-${index}`,
className: "components-radio-control__option"
}, createElement("input", {
id: `${id}-${index}`,
className: "components-radio-control__input",
type: "radio",
name: id,
value: option.value,
onChange: onChangeValue,
checked: option.value === selected,
"aria-describedby": !!help ? `${id}__help` : undefined,
...additionalProps
}), createElement("label", {
className: "components-radio-control__label",
htmlFor: `${id}-${index}`
}, option.label)))));
}
export default RadioControl;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["classnames","useInstanceId","BaseControl","VStack","RadioControl","props","label","className","selected","help","onChange","hideLabelFromVision","options","additionalProps","instanceId","id","onChangeValue","event","target","value","length","createElement","__nextHasNoMarginBottom","spacing","map","option","index","key","type","name","checked","undefined","htmlFor"],"sources":["@wordpress/components/src/radio-control/index.tsx"],"sourcesContent":["/**\n * External dependencies\n */\nimport classnames from 'classnames';\nimport type { ChangeEvent } from 'react';\n\n/**\n * WordPress dependencies\n */\nimport { useInstanceId } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport BaseControl from '../base-control';\nimport type { WordPressComponentProps } from '../context';\nimport type { RadioControlProps } from './types';\nimport { VStack } from '../v-stack';\n\n/**\n * Render a user interface to select the user type using radio inputs.\n *\n * ```jsx\n * import { RadioControl } from '@wordpress/components';\n * import { useState } from '@wordpress/element';\n *\n * const MyRadioControl = () => {\n * const [ option, setOption ] = useState( 'a' );\n *\n * return (\n * <RadioControl\n * label=\"User type\"\n * help=\"The type of the current user\"\n * selected={ option }\n * options={ [\n * { label: 'Author', value: 'a' },\n * { label: 'Editor', value: 'e' },\n * ] }\n * onChange={ ( value ) => setOption( value ) }\n * />\n * );\n * };\n * ```\n */\nexport function RadioControl(\n\tprops: WordPressComponentProps< RadioControlProps, 'input', false >\n) {\n\tconst {\n\t\tlabel,\n\t\tclassName,\n\t\tselected,\n\t\thelp,\n\t\tonChange,\n\t\thideLabelFromVision,\n\t\toptions = [],\n\t\t...additionalProps\n\t} = props;\n\tconst instanceId = useInstanceId( RadioControl );\n\tconst id = `inspector-radio-control-${ instanceId }`;\n\tconst onChangeValue = ( event: ChangeEvent< HTMLInputElement > ) =>\n\t\tonChange( event.target.value );\n\n\tif ( ! options?.length ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<BaseControl\n\t\t\t__nextHasNoMarginBottom\n\t\t\tlabel={ label }\n\t\t\tid={ id }\n\t\t\thideLabelFromVision={ hideLabelFromVision }\n\t\t\thelp={ help }\n\t\t\tclassName={ classnames( className, 'components-radio-control' ) }\n\t\t>\n\t\t\t<VStack spacing={ 1 }>\n\t\t\t\t{ options.map( ( option, index ) => (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={ `${ id }-${ index }` }\n\t\t\t\t\t\tclassName=\"components-radio-control__option\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tid={ `${ id }-${ index }` }\n\t\t\t\t\t\t\tclassName=\"components-radio-control__input\"\n\t\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t\tname={ id }\n\t\t\t\t\t\t\tvalue={ option.value }\n\t\t\t\t\t\t\tonChange={ onChangeValue }\n\t\t\t\t\t\t\tchecked={ option.value === selected }\n\t\t\t\t\t\t\taria-describedby={\n\t\t\t\t\t\t\t\t!! help ? `${ id }__help` : undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{ ...additionalProps }\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<label\n\t\t\t\t\t\t\tclassName=\"components-radio-control__label\"\n\t\t\t\t\t\t\thtmlFor={ `${ id }-${ index }` }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ option.label }\n\t\t\t\t\t\t</label>\n\t\t\t\t\t</div>\n\t\t\t\t) ) }\n\t\t\t</VStack>\n\t\t</BaseControl>\n\t);\n}\n\nexport default RadioControl;\n"],"mappings":";AAAA;AACA;AACA;AACA,OAAOA,UAAU,MAAM,YAAY;AAGnC;AACA;AACA;AACA,SAASC,aAAa,QAAQ,oBAAoB;;AAElD;AACA;AACA;AACA,OAAOC,WAAW,MAAM,iBAAiB;AAGzC,SAASC,MAAM,QAAQ,YAAY;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAC3BC,KAAmE,EAClE;EACD,MAAM;IACLC,KAAK;IACLC,SAAS;IACTC,QAAQ;IACRC,IAAI;IACJC,QAAQ;IACRC,mBAAmB;IACnBC,OAAO,GAAG,EAAE;IACZ,GAAGC;EACJ,CAAC,GAAGR,KAAK;EACT,MAAMS,UAAU,GAAGb,aAAa,CAAEG,YAAa,CAAC;EAChD,MAAMW,EAAE,GAAI,2BAA2BD,UAAY,EAAC;EACpD,MAAME,aAAa,GAAKC,KAAsC,IAC7DP,QAAQ,CAAEO,KAAK,CAACC,MAAM,CAACC,KAAM,CAAC;EAE/B,IAAK,CAAEP,OAAO,EAAEQ,MAAM,EAAG;IACxB,OAAO,IAAI;EACZ;EAEA,OACCC,aAAA,CAACnB,WAAW;IACXoB,uBAAuB;IACvBhB,KAAK,EAAGA,KAAO;IACfS,EAAE,EAAGA,EAAI;IACTJ,mBAAmB,EAAGA,mBAAqB;IAC3CF,IAAI,EAAGA,IAAM;IACbF,SAAS,EAAGP,UAAU,CAAEO,SAAS,EAAE,0BAA2B;EAAG,GAEjEc,aAAA,CAAClB,MAAM;IAACoB,OAAO,EAAG;EAAG,GAClBX,OAAO,CAACY,GAAG,CAAE,CAAEC,MAAM,EAAEC,KAAK,KAC7BL,aAAA;IACCM,GAAG,EAAI,GAAGZ,EAAI,IAAIW,KAAO,EAAG;IAC5BnB,SAAS,EAAC;EAAkC,GAE5Cc,aAAA;IACCN,EAAE,EAAI,GAAGA,EAAI,IAAIW,KAAO,EAAG;IAC3BnB,SAAS,EAAC,iCAAiC;IAC3CqB,IAAI,EAAC,OAAO;IACZC,IAAI,EAAGd,EAAI;IACXI,KAAK,EAAGM,MAAM,CAACN,KAAO;IACtBT,QAAQ,EAAGM,aAAe;IAC1Bc,OAAO,EAAGL,MAAM,CAACN,KAAK,KAAKX,QAAU;IACrC,oBACC,CAAC,CAAEC,IAAI,GAAI,GAAGM,EAAI,QAAO,GAAGgB,SAC5B;IAAA,GACIlB;EAAe,CACpB,CAAC,EACFQ,aAAA;IACCd,SAAS,EAAC,iCAAiC;IAC3CyB,OAAO,EAAI,GAAGjB,EAAI,IAAIW,KAAO;EAAG,GAE9BD,MAAM,CAACnB,KACH,CACH,CACJ,CACK,CACI,CAAC;AAEhB;AAEA,eAAeF,YAAY"}

View File

@@ -0,0 +1,23 @@
import { createElement, Fragment } from "react";
/**
* Internal dependencies
*/
import RadioCell from '../mobile/bottom-sheet/radio-cell';
function RadioControl({
onChange,
selected,
options = [],
...props
}) {
return createElement(Fragment, null, options.map((option, index) => {
return createElement(RadioCell, {
label: option.label,
onPress: () => onChange(option.value),
selected: option.value === selected,
key: `${option.value}-${index}`,
...props
});
}));
}
export default RadioControl;
//# sourceMappingURL=index.native.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["RadioCell","RadioControl","onChange","selected","options","props","createElement","Fragment","map","option","index","label","onPress","value","key"],"sources":["@wordpress/components/src/radio-control/index.native.js"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport RadioCell from '../mobile/bottom-sheet/radio-cell';\n\nfunction RadioControl( { onChange, selected, options = [], ...props } ) {\n\treturn (\n\t\t<>\n\t\t\t{ options.map( ( option, index ) => {\n\t\t\t\treturn (\n\t\t\t\t\t<RadioCell\n\t\t\t\t\t\tlabel={ option.label }\n\t\t\t\t\t\tonPress={ () => onChange( option.value ) }\n\t\t\t\t\t\tselected={ option.value === selected }\n\t\t\t\t\t\tkey={ `${ option.value }-${ index }` }\n\t\t\t\t\t\t{ ...props }\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\t} ) }\n\t\t</>\n\t);\n}\n\nexport default RadioControl;\n"],"mappings":";AAAA;AACA;AACA;AACA,OAAOA,SAAS,MAAM,mCAAmC;AAEzD,SAASC,YAAYA,CAAE;EAAEC,QAAQ;EAAEC,QAAQ;EAAEC,OAAO,GAAG,EAAE;EAAE,GAAGC;AAAM,CAAC,EAAG;EACvE,OACCC,aAAA,CAAAC,QAAA,QACGH,OAAO,CAACI,GAAG,CAAE,CAAEC,MAAM,EAAEC,KAAK,KAAM;IACnC,OACCJ,aAAA,CAACN,SAAS;MACTW,KAAK,EAAGF,MAAM,CAACE,KAAO;MACtBC,OAAO,EAAGA,CAAA,KAAMV,QAAQ,CAAEO,MAAM,CAACI,KAAM,CAAG;MAC1CV,QAAQ,EAAGM,MAAM,CAACI,KAAK,KAAKV,QAAU;MACtCW,GAAG,EAAI,GAAGL,MAAM,CAACI,KAAO,IAAIH,KAAO,EAAG;MAAA,GACjCL;IAAK,CACV,CAAC;EAEJ,CAAE,CACD,CAAC;AAEL;AAEA,eAAeJ,YAAY"}

View File

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

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sources":["@wordpress/components/src/radio-control/types.ts"],"sourcesContent":["/**\n * Internal dependencies\n */\nimport type { BaseControlProps } from '../base-control/types';\n\nexport type RadioControlProps = Pick<\n\tBaseControlProps,\n\t'label' | 'help' | 'hideLabelFromVision'\n> & {\n\t/**\n\t * A function that receives the value of the new option that is being\n\t * selected as input.\n\t */\n\tonChange: ( value: string ) => void;\n\t/**\n\t * An array of objects containing the value and label of the options.\n\t */\n\toptions?: {\n\t\t/**\n\t\t * The label to be shown to the user\n\t\t */\n\t\tlabel: string;\n\t\t/**\n\t\t * The internal value compared against select and passed to onChange\n\t\t */\n\t\tvalue: string;\n\t}[];\n\t/**\n\t * The value property of the currently selected option.\n\t */\n\tselected?: string;\n};\n"],"mappings":""}