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,73 @@
import { createElement } from "react";
/**
* External dependencies
*/
import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { forwardRef } from '@wordpress/element';
import { external } from '@wordpress/icons';
/**
* Internal dependencies
*/
import { VisuallyHidden } from '../visually-hidden';
import { StyledIcon } from './styles/external-link-styles';
function UnforwardedExternalLink(props, ref) {
const {
href,
children,
className,
rel = '',
...additionalProps
} = props;
const optimizedRel = [...new Set([...rel.split(' '), 'external', 'noreferrer', 'noopener'].filter(Boolean))].join(' ');
const classes = classnames('components-external-link', className);
/* Anchor links are perceived as external links.
This constant helps check for on page anchor links,
to prevent them from being opened in the editor. */
const isInternalAnchor = !!href?.startsWith('#');
const onClickHandler = event => {
if (isInternalAnchor) {
event.preventDefault();
}
if (props.onClick) {
props.onClick(event);
}
};
return (/* eslint-disable react/jsx-no-target-blank */
createElement("a", {
...additionalProps,
className: classes,
href: href,
onClick: onClickHandler,
target: "_blank",
rel: optimizedRel,
ref: ref
}, children, createElement(VisuallyHidden, {
as: "span"
}, /* translators: accessibility text */
__('(opens in a new tab)')), createElement(StyledIcon, {
icon: external,
className: "components-external-link__icon"
}))
/* eslint-enable react/jsx-no-target-blank */
);
}
/**
* Link to an external resource.
*
* ```jsx
* import { ExternalLink } from '@wordpress/components';
*
* const MyExternalLink = () => (
* <ExternalLink href="https://wordpress.org">WordPress.org</ExternalLink>
* );
* ```
*/
export const ExternalLink = forwardRef(UnforwardedExternalLink);
export default ExternalLink;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["classnames","__","forwardRef","external","VisuallyHidden","StyledIcon","UnforwardedExternalLink","props","ref","href","children","className","rel","additionalProps","optimizedRel","Set","split","filter","Boolean","join","classes","isInternalAnchor","startsWith","onClickHandler","event","preventDefault","onClick","createElement","target","as","icon","ExternalLink"],"sources":["@wordpress/components/src/external-link/index.tsx"],"sourcesContent":["/**\n * External dependencies\n */\nimport classnames from 'classnames';\nimport type { ForwardedRef } from 'react';\n\n/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { forwardRef } from '@wordpress/element';\nimport { external } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport { VisuallyHidden } from '../visually-hidden';\nimport { StyledIcon } from './styles/external-link-styles';\nimport type { ExternalLinkProps } from './types';\nimport type { WordPressComponentProps } from '../context';\n\nfunction UnforwardedExternalLink(\n\tprops: Omit<\n\t\tWordPressComponentProps< ExternalLinkProps, 'a', false >,\n\t\t'target'\n\t>,\n\tref: ForwardedRef< HTMLAnchorElement >\n) {\n\tconst { href, children, className, rel = '', ...additionalProps } = props;\n\tconst optimizedRel = [\n\t\t...new Set(\n\t\t\t[\n\t\t\t\t...rel.split( ' ' ),\n\t\t\t\t'external',\n\t\t\t\t'noreferrer',\n\t\t\t\t'noopener',\n\t\t\t].filter( Boolean )\n\t\t),\n\t].join( ' ' );\n\tconst classes = classnames( 'components-external-link', className );\n\t/* Anchor links are perceived as external links.\n\tThis constant helps check for on page anchor links,\n\tto prevent them from being opened in the editor. */\n\tconst isInternalAnchor = !! href?.startsWith( '#' );\n\n\tconst onClickHandler = (\n\t\tevent: React.MouseEvent< HTMLAnchorElement, MouseEvent >\n\t) => {\n\t\tif ( isInternalAnchor ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\n\t\tif ( props.onClick ) {\n\t\t\tprops.onClick( event );\n\t\t}\n\t};\n\n\treturn (\n\t\t/* eslint-disable react/jsx-no-target-blank */\n\t\t<a\n\t\t\t{ ...additionalProps }\n\t\t\tclassName={ classes }\n\t\t\thref={ href }\n\t\t\tonClick={ onClickHandler }\n\t\t\ttarget=\"_blank\"\n\t\t\trel={ optimizedRel }\n\t\t\tref={ ref }\n\t\t>\n\t\t\t{ children }\n\t\t\t<VisuallyHidden as=\"span\">\n\t\t\t\t{\n\t\t\t\t\t/* translators: accessibility text */\n\t\t\t\t\t__( '(opens in a new tab)' )\n\t\t\t\t}\n\t\t\t</VisuallyHidden>\n\t\t\t<StyledIcon\n\t\t\t\ticon={ external }\n\t\t\t\tclassName=\"components-external-link__icon\"\n\t\t\t/>\n\t\t</a>\n\t\t/* eslint-enable react/jsx-no-target-blank */\n\t);\n}\n\n/**\n * Link to an external resource.\n *\n * ```jsx\n * import { ExternalLink } from '@wordpress/components';\n *\n * const MyExternalLink = () => (\n * <ExternalLink href=\"https://wordpress.org\">WordPress.org</ExternalLink>\n * );\n * ```\n */\nexport const ExternalLink = forwardRef( UnforwardedExternalLink );\n\nexport default ExternalLink;\n"],"mappings":";AAAA;AACA;AACA;AACA,OAAOA,UAAU,MAAM,YAAY;AAGnC;AACA;AACA;AACA,SAASC,EAAE,QAAQ,iBAAiB;AACpC,SAASC,UAAU,QAAQ,oBAAoB;AAC/C,SAASC,QAAQ,QAAQ,kBAAkB;;AAE3C;AACA;AACA;AACA,SAASC,cAAc,QAAQ,oBAAoB;AACnD,SAASC,UAAU,QAAQ,+BAA+B;AAI1D,SAASC,uBAAuBA,CAC/BC,KAGC,EACDC,GAAsC,EACrC;EACD,MAAM;IAAEC,IAAI;IAAEC,QAAQ;IAAEC,SAAS;IAAEC,GAAG,GAAG,EAAE;IAAE,GAAGC;EAAgB,CAAC,GAAGN,KAAK;EACzE,MAAMO,YAAY,GAAG,CACpB,GAAG,IAAIC,GAAG,CACT,CACC,GAAGH,GAAG,CAACI,KAAK,CAAE,GAAI,CAAC,EACnB,UAAU,EACV,YAAY,EACZ,UAAU,CACV,CAACC,MAAM,CAAEC,OAAQ,CACnB,CAAC,CACD,CAACC,IAAI,CAAE,GAAI,CAAC;EACb,MAAMC,OAAO,GAAGpB,UAAU,CAAE,0BAA0B,EAAEW,SAAU,CAAC;EACnE;AACD;AACA;EACC,MAAMU,gBAAgB,GAAG,CAAC,CAAEZ,IAAI,EAAEa,UAAU,CAAE,GAAI,CAAC;EAEnD,MAAMC,cAAc,GACnBC,KAAwD,IACpD;IACJ,IAAKH,gBAAgB,EAAG;MACvBG,KAAK,CAACC,cAAc,CAAC,CAAC;IACvB;IAEA,IAAKlB,KAAK,CAACmB,OAAO,EAAG;MACpBnB,KAAK,CAACmB,OAAO,CAAEF,KAAM,CAAC;IACvB;EACD,CAAC;EAED,OACC;IACAG,aAAA;MAAA,GACMd,eAAe;MACpBF,SAAS,EAAGS,OAAS;MACrBX,IAAI,EAAGA,IAAM;MACbiB,OAAO,EAAGH,cAAgB;MAC1BK,MAAM,EAAC,QAAQ;MACfhB,GAAG,EAAGE,YAAc;MACpBN,GAAG,EAAGA;IAAK,GAETE,QAAQ,EACViB,aAAA,CAACvB,cAAc;MAACyB,EAAE,EAAC;IAAM,GAEvB;IACA5B,EAAE,CAAE,sBAAuB,CAEb,CAAC,EACjB0B,aAAA,CAACtB,UAAU;MACVyB,IAAI,EAAG3B,QAAU;MACjBQ,SAAS,EAAC;IAAgC,CAC1C,CACC;IACH;EAAA;AAEF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMoB,YAAY,GAAG7B,UAAU,CAAEI,uBAAwB,CAAC;AAEjE,eAAeyB,YAAY"}

View File

@@ -0,0 +1,25 @@
import { createElement } from "react";
/**
* External dependencies
*/
import { TouchableOpacity, Text, Linking } from 'react-native';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { external, Icon } from '@wordpress/icons';
export function ExternalLink({
href,
children
}) {
return createElement(TouchableOpacity, {
onPress: () => Linking.openURL(href),
accessibilityLabel: __('Open link in a browser')
}, createElement(Text, null, children), createElement(Icon, {
icon: external
}));
}
export default ExternalLink;
//# sourceMappingURL=index.native.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["TouchableOpacity","Text","Linking","__","external","Icon","ExternalLink","href","children","createElement","onPress","openURL","accessibilityLabel","icon"],"sources":["@wordpress/components/src/external-link/index.native.js"],"sourcesContent":["/**\n * External dependencies\n */\n\nimport { TouchableOpacity, Text, Linking } from 'react-native';\n\n/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { external, Icon } from '@wordpress/icons';\n\nexport function ExternalLink( { href, children } ) {\n\treturn (\n\t\t<TouchableOpacity\n\t\t\tonPress={ () => Linking.openURL( href ) }\n\t\t\taccessibilityLabel={ __( 'Open link in a browser' ) }\n\t\t>\n\t\t\t<Text>{ children }</Text>\n\t\t\t<Icon icon={ external } />\n\t\t</TouchableOpacity>\n\t);\n}\n\nexport default ExternalLink;\n"],"mappings":";AAAA;AACA;AACA;;AAEA,SAASA,gBAAgB,EAAEC,IAAI,EAAEC,OAAO,QAAQ,cAAc;;AAE9D;AACA;AACA;AACA,SAASC,EAAE,QAAQ,iBAAiB;AACpC,SAASC,QAAQ,EAAEC,IAAI,QAAQ,kBAAkB;AAEjD,OAAO,SAASC,YAAYA,CAAE;EAAEC,IAAI;EAAEC;AAAS,CAAC,EAAG;EAClD,OACCC,aAAA,CAACT,gBAAgB;IAChBU,OAAO,EAAGA,CAAA,KAAMR,OAAO,CAACS,OAAO,CAAEJ,IAAK,CAAG;IACzCK,kBAAkB,EAAGT,EAAE,CAAE,wBAAyB;EAAG,GAErDM,aAAA,CAACR,IAAI,QAAGO,QAAgB,CAAC,EACzBC,aAAA,CAACJ,IAAI;IAACQ,IAAI,EAAGT;EAAU,CAAE,CACR,CAAC;AAErB;AAEA,eAAeE,YAAY"}

View File

@@ -0,0 +1,25 @@
import _styled from "@emotion/styled/base";
function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
import { Icon } from '@wordpress/icons';
export const StyledIcon = /*#__PURE__*/_styled(Icon, process.env.NODE_ENV === "production" ? {
target: "esh4a730"
} : {
target: "esh4a730",
label: "StyledIcon"
})(process.env.NODE_ENV === "production" ? {
name: "rvs7bx",
styles: "width:1em;height:1em;margin:0;vertical-align:middle;fill:currentColor"
} : {
name: "rvs7bx",
styles: "width:1em;height:1em;margin:0;vertical-align:middle;fill:currentColor",
map: "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkB3b3JkcHJlc3MvY29tcG9uZW50cy9zcmMvZXh0ZXJuYWwtbGluay9zdHlsZXMvZXh0ZXJuYWwtbGluay1zdHlsZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBVXdDIiwiZmlsZSI6IkB3b3JkcHJlc3MvY29tcG9uZW50cy9zcmMvZXh0ZXJuYWwtbGluay9zdHlsZXMvZXh0ZXJuYWwtbGluay1zdHlsZXMudHMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEV4dGVybmFsIGRlcGVuZGVuY2llc1xuICovXG5pbXBvcnQgc3R5bGVkIGZyb20gJ0BlbW90aW9uL3N0eWxlZCc7XG5cbi8qKlxuICogV29yZFByZXNzIGRlcGVuZGVuY2llc1xuICovXG5pbXBvcnQgeyBJY29uIH0gZnJvbSAnQHdvcmRwcmVzcy9pY29ucyc7XG5cbmV4cG9ydCBjb25zdCBTdHlsZWRJY29uID0gc3R5bGVkKCBJY29uIClgXG5cdHdpZHRoOiAxZW07XG5cdGhlaWdodDogMWVtO1xuXHRtYXJnaW46IDA7XG5cdHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG5cdGZpbGw6IGN1cnJlbnRDb2xvcjtcbmA7XG4iXX0= */",
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
});
//# sourceMappingURL=external-link-styles.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["Icon","StyledIcon","_styled","process","env","NODE_ENV","target","label","name","styles","map","toString","_EMOTION_STRINGIFIED_CSS_ERROR__"],"sources":["@wordpress/components/src/external-link/styles/external-link-styles.ts"],"sourcesContent":["/**\n * External dependencies\n */\nimport styled from '@emotion/styled';\n\n/**\n * WordPress dependencies\n */\nimport { Icon } from '@wordpress/icons';\n\nexport const StyledIcon = styled( Icon )`\n\twidth: 1em;\n\theight: 1em;\n\tmargin: 0;\n\tvertical-align: middle;\n\tfill: currentColor;\n`;\n"],"mappings":";;AAAA;AACA;AACA;;AAGA;AACA;AACA;AACA,SAASA,IAAI,QAAQ,kBAAkB;AAEvC,OAAO,MAAMC,UAAU,GAAG,aAAAC,OAAA,CAAQF,IAAI,EAAAG,OAAA,CAAAC,GAAA,CAAAC,QAAA;EAAAC,MAAA;AAAA;EAAAA,MAAA;EAAAC,KAAA;AAAA,CAAC,CAAC,CAAAJ,OAAA,CAAAC,GAAA,CAAAC,QAAA;EAAAG,IAAA;EAAAC,MAAA;AAAA;EAAAD,IAAA;EAAAC,MAAA;EAAAC,GAAA;EAAAC,QAAA,EAAAC;AAAA,EAMvC"}

View File

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

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sources":["@wordpress/components/src/external-link/types.ts"],"sourcesContent":["/**\n * External dependencies\n */\nimport type { ReactNode } from 'react';\n\nexport type ExternalLinkProps = {\n\t/**\n\t * The content to be displayed within the link.\n\t */\n\tchildren: ReactNode;\n\t/**\n\t * The URL of the external resource.\n\t */\n\thref: string;\n};\n"],"mappings":""}