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,101 @@
/**
* External dependencies
*/
import { colord, extend } from 'colord';
import a11yPlugin from 'colord/plugins/a11y';
import namesPlugin from 'colord/plugins/names';
/**
* WordPress dependencies
*/
import warning from '@wordpress/warning';
/**
* Internal dependencies
*/
import { COLORS } from '../utils';
extend([namesPlugin, a11yPlugin]);
export function generateThemeVariables(inputs) {
validateInputs(inputs);
const generatedColors = {
...generateAccentDependentColors(inputs.accent),
...generateBackgroundDependentColors(inputs.background)
};
warnContrastIssues(checkContrasts(inputs, generatedColors));
return {
colors: generatedColors
};
}
function validateInputs(inputs) {
for (const [key, value] of Object.entries(inputs)) {
if (typeof value !== 'undefined' && !colord(value).isValid()) {
typeof SCRIPT_DEBUG !== "undefined" && SCRIPT_DEBUG === true ? warning(`wp.components.Theme: "${value}" is not a valid color value for the '${key}' prop.`) : void 0;
}
}
}
export function checkContrasts(inputs, outputs) {
const background = inputs.background || COLORS.white;
const accent = inputs.accent || '#3858e9';
const foreground = outputs.foreground || COLORS.gray[900];
const gray = outputs.gray || COLORS.gray;
return {
accent: colord(background).isReadable(accent) ? undefined : `The background color ("${background}") does not have sufficient contrast against the accent color ("${accent}").`,
foreground: colord(background).isReadable(foreground) ? undefined : `The background color provided ("${background}") does not have sufficient contrast against the standard foreground colors.`,
grays: colord(background).contrast(gray[600]) >= 3 && colord(background).contrast(gray[700]) >= 4.5 ? undefined : `The background color provided ("${background}") cannot generate a set of grayscale foreground colors with sufficient contrast. Try adjusting the color to be lighter or darker.`
};
}
function warnContrastIssues(issues) {
for (const error of Object.values(issues)) {
if (error) {
typeof SCRIPT_DEBUG !== "undefined" && SCRIPT_DEBUG === true ? warning('wp.components.Theme: ' + error) : void 0;
}
}
}
function generateAccentDependentColors(accent) {
if (!accent) return {};
return {
accent,
accentDarker10: colord(accent).darken(0.1).toHex(),
accentDarker20: colord(accent).darken(0.2).toHex(),
accentInverted: getForegroundForColor(accent)
};
}
function generateBackgroundDependentColors(background) {
if (!background) return {};
const foreground = getForegroundForColor(background);
return {
background,
foreground,
foregroundInverted: getForegroundForColor(foreground),
gray: generateShades(background, foreground)
};
}
function getForegroundForColor(color) {
return colord(color).isDark() ? COLORS.white : COLORS.gray[900];
}
export function generateShades(background, foreground) {
// How much darkness you need to add to #fff to get the COLORS.gray[n] color
const SHADES = {
100: 0.06,
200: 0.121,
300: 0.132,
400: 0.2,
600: 0.42,
700: 0.543,
800: 0.821
};
// Darkness of COLORS.gray[ 900 ], relative to #fff
const limit = 0.884;
const direction = colord(background).isDark() ? 'lighten' : 'darken';
// Lightness delta between the background and foreground colors
const range = Math.abs(colord(background).toHsl().l - colord(foreground).toHsl().l) / 100;
const result = {};
Object.entries(SHADES).forEach(([key, value]) => {
result[parseInt(key)] = colord(background)[direction](value / limit * range).toHex();
});
return result;
}
//# sourceMappingURL=color-algorithms.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,51 @@
import { createElement } from "react";
/**
* WordPress dependencies
*/
import { useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
import { colorVariables, Wrapper } from './styles';
import { generateThemeVariables } from './color-algorithms';
import { useCx } from '../utils';
/**
* `Theme` allows defining theme variables for components in the `@wordpress/components` package.
*
* Multiple `Theme` components can be nested in order to override specific theme variables.
*
*
* ```jsx
* const Example = () => {
* return (
* <Theme accent="red">
* <Button variant="primary">I'm red</Button>
* <Theme accent="blue">
* <Button variant="primary">I'm blue</Button>
* </Theme>
* </Theme>
* );
* };
* ```
*/
function Theme({
accent,
background,
className,
...props
}) {
const cx = useCx();
const classes = useMemo(() => cx(...colorVariables(generateThemeVariables({
accent,
background
})), className), [accent, background, className, cx]);
return createElement(Wrapper, {
className: classes,
...props
});
}
export default Theme;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useMemo","colorVariables","Wrapper","generateThemeVariables","useCx","Theme","accent","background","className","props","cx","classes","createElement"],"sources":["@wordpress/components/src/theme/index.tsx"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useMemo } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport type { ThemeProps } from './types';\nimport type { WordPressComponentProps } from '../context';\nimport { colorVariables, Wrapper } from './styles';\nimport { generateThemeVariables } from './color-algorithms';\nimport { useCx } from '../utils';\n\n/**\n * `Theme` allows defining theme variables for components in the `@wordpress/components` package.\n *\n * Multiple `Theme` components can be nested in order to override specific theme variables.\n *\n *\n * ```jsx\n * const Example = () => {\n * return (\n * <Theme accent=\"red\">\n * <Button variant=\"primary\">I'm red</Button>\n * <Theme accent=\"blue\">\n * <Button variant=\"primary\">I'm blue</Button>\n * </Theme>\n * </Theme>\n * );\n * };\n * ```\n */\nfunction Theme( {\n\taccent,\n\tbackground,\n\tclassName,\n\t...props\n}: WordPressComponentProps< ThemeProps, 'div', true > ) {\n\tconst cx = useCx();\n\tconst classes = useMemo(\n\t\t() =>\n\t\t\tcx(\n\t\t\t\t...colorVariables(\n\t\t\t\t\tgenerateThemeVariables( { accent, background } )\n\t\t\t\t),\n\t\t\t\tclassName\n\t\t\t),\n\t\t[ accent, background, className, cx ]\n\t);\n\n\treturn <Wrapper className={ classes } { ...props } />;\n}\n\nexport default Theme;\n"],"mappings":";AAAA;AACA;AACA;AACA,SAASA,OAAO,QAAQ,oBAAoB;;AAE5C;AACA;AACA;;AAGA,SAASC,cAAc,EAAEC,OAAO,QAAQ,UAAU;AAClD,SAASC,sBAAsB,QAAQ,oBAAoB;AAC3D,SAASC,KAAK,QAAQ,UAAU;;AAEhC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,KAAKA,CAAE;EACfC,MAAM;EACNC,UAAU;EACVC,SAAS;EACT,GAAGC;AACgD,CAAC,EAAG;EACvD,MAAMC,EAAE,GAAGN,KAAK,CAAC,CAAC;EAClB,MAAMO,OAAO,GAAGX,OAAO,CACtB,MACCU,EAAE,CACD,GAAGT,cAAc,CAChBE,sBAAsB,CAAE;IAAEG,MAAM;IAAEC;EAAW,CAAE,CAChD,CAAC,EACDC,SACD,CAAC,EACF,CAAEF,MAAM,EAAEC,UAAU,EAAEC,SAAS,EAAEE,EAAE,CACpC,CAAC;EAED,OAAOE,aAAA,CAACV,OAAO;IAACM,SAAS,EAAGG,OAAS;IAAA,GAAMF;EAAK,CAAI,CAAC;AACtD;AAEA,eAAeJ,KAAK"}

View File

@@ -0,0 +1,33 @@
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
*/
import { css } from '@emotion/react';
/**
* Internal dependencies
*/
export const colorVariables = ({
colors
}) => {
const shades = Object.entries(colors.gray || {}).map(([k, v]) => `--wp-components-color-gray-${k}: ${v};`).join('');
return [/*#__PURE__*/css("--wp-components-color-accent:", colors.accent, ";--wp-components-color-accent-darker-10:", colors.accentDarker10, ";--wp-components-color-accent-darker-20:", colors.accentDarker20, ";--wp-components-color-accent-inverted:", colors.accentInverted, ";--wp-components-color-background:", colors.background, ";--wp-components-color-foreground:", colors.foreground, ";--wp-components-color-foreground-inverted:", colors.foregroundInverted, ";", shades, ";" + (process.env.NODE_ENV === "production" ? "" : ";label:colorVariables;"), process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkB3b3JkcHJlc3MvY29tcG9uZW50cy9zcmMvdGhlbWUvc3R5bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWlCSyIsImZpbGUiOiJAd29yZHByZXNzL2NvbXBvbmVudHMvc3JjL3RoZW1lL3N0eWxlcy50cyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRXh0ZXJuYWwgZGVwZW5kZW5jaWVzXG4gKi9cbmltcG9ydCBzdHlsZWQgZnJvbSAnQGVtb3Rpb24vc3R5bGVkJztcbmltcG9ydCB7IGNzcyB9IGZyb20gJ0BlbW90aW9uL3JlYWN0JztcblxuLyoqXG4gKiBJbnRlcm5hbCBkZXBlbmRlbmNpZXNcbiAqL1xuaW1wb3J0IHR5cGUgeyBUaGVtZU91dHB1dFZhbHVlcyB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgY29sb3JWYXJpYWJsZXMgPSAoIHsgY29sb3JzIH06IFRoZW1lT3V0cHV0VmFsdWVzICkgPT4ge1xuXHRjb25zdCBzaGFkZXMgPSBPYmplY3QuZW50cmllcyggY29sb3JzLmdyYXkgfHwge30gKVxuXHRcdC5tYXAoICggWyBrLCB2IF0gKSA9PiBgLS13cC1jb21wb25lbnRzLWNvbG9yLWdyYXktJHsgayB9OiAkeyB2IH07YCApXG5cdFx0LmpvaW4oICcnICk7XG5cblx0cmV0dXJuIFtcblx0XHRjc3NgXG5cdFx0XHQtLXdwLWNvbXBvbmVudHMtY29sb3ItYWNjZW50OiAkeyBjb2xvcnMuYWNjZW50IH07XG5cdFx0XHQtLXdwLWNvbXBvbmVudHMtY29sb3ItYWNjZW50LWRhcmtlci0xMDogJHsgY29sb3JzLmFjY2VudERhcmtlcjEwIH07XG5cdFx0XHQtLXdwLWNvbXBvbmVudHMtY29sb3ItYWNjZW50LWRhcmtlci0yMDogJHsgY29sb3JzLmFjY2VudERhcmtlcjIwIH07XG5cdFx0XHQtLXdwLWNvbXBvbmVudHMtY29sb3ItYWNjZW50LWludmVydGVkOiAkeyBjb2xvcnMuYWNjZW50SW52ZXJ0ZWQgfTtcblxuXHRcdFx0LS13cC1jb21wb25lbnRzLWNvbG9yLWJhY2tncm91bmQ6ICR7IGNvbG9ycy5iYWNrZ3JvdW5kIH07XG5cdFx0XHQtLXdwLWNvbXBvbmVudHMtY29sb3ItZm9yZWdyb3VuZDogJHsgY29sb3JzLmZvcmVncm91bmQgfTtcblx0XHRcdC0td3AtY29tcG9uZW50cy1jb2xvci1mb3JlZ3JvdW5kLWludmVydGVkOiAkeyBjb2xvcnMuZm9yZWdyb3VuZEludmVydGVkIH07XG5cblx0XHRcdCR7IHNoYWRlcyB9XG5cdFx0YCxcblx0XTtcbn07XG5cbmV4cG9ydCBjb25zdCBXcmFwcGVyID0gc3R5bGVkLmRpdmBcblx0Y29sb3I6IHZhciggLS13cC1jb21wb25lbnRzLWNvbG9yLWZvcmVncm91bmQsIGN1cnJlbnRDb2xvciApO1xuYDtcbiJdfQ== */")];
};
export const Wrapper = _styled("div", process.env.NODE_ENV === "production" ? {
target: "e1krjpvb0"
} : {
target: "e1krjpvb0",
label: "Wrapper"
})(process.env.NODE_ENV === "production" ? {
name: "1a3idx0",
styles: "color:var( --wp-components-color-foreground, currentColor )"
} : {
name: "1a3idx0",
styles: "color:var( --wp-components-color-foreground, currentColor )",
map: "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkB3b3JkcHJlc3MvY29tcG9uZW50cy9zcmMvdGhlbWUvc3R5bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWdDaUMiLCJmaWxlIjoiQHdvcmRwcmVzcy9jb21wb25lbnRzL3NyYy90aGVtZS9zdHlsZXMudHMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEV4dGVybmFsIGRlcGVuZGVuY2llc1xuICovXG5pbXBvcnQgc3R5bGVkIGZyb20gJ0BlbW90aW9uL3N0eWxlZCc7XG5pbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCc7XG5cbi8qKlxuICogSW50ZXJuYWwgZGVwZW5kZW5jaWVzXG4gKi9cbmltcG9ydCB0eXBlIHsgVGhlbWVPdXRwdXRWYWx1ZXMgfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGNvbG9yVmFyaWFibGVzID0gKCB7IGNvbG9ycyB9OiBUaGVtZU91dHB1dFZhbHVlcyApID0+IHtcblx0Y29uc3Qgc2hhZGVzID0gT2JqZWN0LmVudHJpZXMoIGNvbG9ycy5ncmF5IHx8IHt9IClcblx0XHQubWFwKCAoIFsgaywgdiBdICkgPT4gYC0td3AtY29tcG9uZW50cy1jb2xvci1ncmF5LSR7IGsgfTogJHsgdiB9O2AgKVxuXHRcdC5qb2luKCAnJyApO1xuXG5cdHJldHVybiBbXG5cdFx0Y3NzYFxuXHRcdFx0LS13cC1jb21wb25lbnRzLWNvbG9yLWFjY2VudDogJHsgY29sb3JzLmFjY2VudCB9O1xuXHRcdFx0LS13cC1jb21wb25lbnRzLWNvbG9yLWFjY2VudC1kYXJrZXItMTA6ICR7IGNvbG9ycy5hY2NlbnREYXJrZXIxMCB9O1xuXHRcdFx0LS13cC1jb21wb25lbnRzLWNvbG9yLWFjY2VudC1kYXJrZXItMjA6ICR7IGNvbG9ycy5hY2NlbnREYXJrZXIyMCB9O1xuXHRcdFx0LS13cC1jb21wb25lbnRzLWNvbG9yLWFjY2VudC1pbnZlcnRlZDogJHsgY29sb3JzLmFjY2VudEludmVydGVkIH07XG5cblx0XHRcdC0td3AtY29tcG9uZW50cy1jb2xvci1iYWNrZ3JvdW5kOiAkeyBjb2xvcnMuYmFja2dyb3VuZCB9O1xuXHRcdFx0LS13cC1jb21wb25lbnRzLWNvbG9yLWZvcmVncm91bmQ6ICR7IGNvbG9ycy5mb3JlZ3JvdW5kIH07XG5cdFx0XHQtLXdwLWNvbXBvbmVudHMtY29sb3ItZm9yZWdyb3VuZC1pbnZlcnRlZDogJHsgY29sb3JzLmZvcmVncm91bmRJbnZlcnRlZCB9O1xuXG5cdFx0XHQkeyBzaGFkZXMgfVxuXHRcdGAsXG5cdF07XG59O1xuXG5leHBvcnQgY29uc3QgV3JhcHBlciA9IHN0eWxlZC5kaXZgXG5cdGNvbG9yOiB2YXIoIC0td3AtY29tcG9uZW50cy1jb2xvci1mb3JlZ3JvdW5kLCBjdXJyZW50Q29sb3IgKTtcbmA7XG4iXX0= */",
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
});
//# sourceMappingURL=styles.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["css","colorVariables","colors","shades","Object","entries","gray","map","k","v","join","accent","accentDarker10","accentDarker20","accentInverted","background","foreground","foregroundInverted","process","env","NODE_ENV","Wrapper","_styled","target","label","name","styles","toString","_EMOTION_STRINGIFIED_CSS_ERROR__"],"sources":["@wordpress/components/src/theme/styles.ts"],"sourcesContent":["/**\n * External dependencies\n */\nimport styled from '@emotion/styled';\nimport { css } from '@emotion/react';\n\n/**\n * Internal dependencies\n */\nimport type { ThemeOutputValues } from './types';\n\nexport const colorVariables = ( { colors }: ThemeOutputValues ) => {\n\tconst shades = Object.entries( colors.gray || {} )\n\t\t.map( ( [ k, v ] ) => `--wp-components-color-gray-${ k }: ${ v };` )\n\t\t.join( '' );\n\n\treturn [\n\t\tcss`\n\t\t\t--wp-components-color-accent: ${ colors.accent };\n\t\t\t--wp-components-color-accent-darker-10: ${ colors.accentDarker10 };\n\t\t\t--wp-components-color-accent-darker-20: ${ colors.accentDarker20 };\n\t\t\t--wp-components-color-accent-inverted: ${ colors.accentInverted };\n\n\t\t\t--wp-components-color-background: ${ colors.background };\n\t\t\t--wp-components-color-foreground: ${ colors.foreground };\n\t\t\t--wp-components-color-foreground-inverted: ${ colors.foregroundInverted };\n\n\t\t\t${ shades }\n\t\t`,\n\t];\n};\n\nexport const Wrapper = styled.div`\n\tcolor: var( --wp-components-color-foreground, currentColor );\n`;\n"],"mappings":";;AAAA;AACA;AACA;;AAEA,SAASA,GAAG,QAAQ,gBAAgB;;AAEpC;AACA;AACA;;AAGA,OAAO,MAAMC,cAAc,GAAGA,CAAE;EAAEC;AAA0B,CAAC,KAAM;EAClE,MAAMC,MAAM,GAAGC,MAAM,CAACC,OAAO,CAAEH,MAAM,CAACI,IAAI,IAAI,CAAC,CAAE,CAAC,CAChDC,GAAG,CAAE,CAAE,CAAEC,CAAC,EAAEC,CAAC,CAAE,KAAO,8BAA8BD,CAAG,KAAKC,CAAG,GAAG,CAAC,CACnEC,IAAI,CAAE,EAAG,CAAC;EAEZ,OAAO,cACNV,GAAG,kCAC+BE,MAAM,CAACS,MAAM,8CACHT,MAAM,CAACU,cAAc,8CACrBV,MAAM,CAACW,cAAc,6CACtBX,MAAM,CAACY,cAAc,wCAE1BZ,MAAM,CAACa,UAAU,wCACjBb,MAAM,CAACc,UAAU,iDACRd,MAAM,CAACe,kBAAkB,OAEpEd,MAAM,SAAAe,OAAA,CAAAC,GAAA,CAAAC,QAAA,oDAAAF,OAAA,CAAAC,GAAA,CAAAC,QAAA,gvDAEV;AACF,CAAC;AAED,OAAO,MAAMC,OAAO,GAAAC,OAAA,QAAAJ,OAAA,CAAAC,GAAA,CAAAC,QAAA;EAAAG,MAAA;AAAA;EAAAA,MAAA;EAAAC,KAAA;AAAA,GAAAN,OAAA,CAAAC,GAAA,CAAAC,QAAA;EAAAK,IAAA;EAAAC,MAAA;AAAA;EAAAD,IAAA;EAAAC,MAAA;EAAAnB,GAAA;EAAAoB,QAAA,EAAAC;AAAA,EAEnB"}

View File

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

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sources":["@wordpress/components/src/theme/types.ts"],"sourcesContent":["/**\n * External dependencies\n */\nimport type { ReactNode } from 'react';\n\nexport type ThemeInputValues = {\n\t/**\n\t * The accent color (used by components as the primary color).\n\t *\n\t * If an accent color is not defined, the default fallback value is the original\n\t * WP Admin main theme color. Not all valid CSS color syntaxes are supported —\n\t * in particular, keywords (like `'currentcolor'`, `'inherit'`, `'initial'`,\n\t * `'revert'`, `'unset'`...) and CSS custom properties (e.g.\n\t * `var(--my-custom-property)`) are _not_ supported values for this property.\n\t */\n\taccent?: string;\n\t/**\n\t * The background color.\n\t *\n\t * If a component explicitly has a background, it will be this color.\n\t * Otherwise, this color will simply be used to determine what the foreground colors should be.\n\t * The actual background color will need to be set on the component's container element.\n\t *\n\t * If a background color is not defined, the default fallback value is #fff.\n\t * Not all valid CSS color syntaxes are supported —\n\t * in particular, keywords (like `'currentcolor'`, `'inherit'`, `'initial'`,\n\t * `'revert'`, `'unset'`...) and CSS custom properties (e.g.\n\t * `var(--my-custom-property)`) are _not_ supported values for this property.\n\t */\n\tbackground?: string;\n};\n\nexport type ThemeOutputValues = {\n\tcolors: Partial< {\n\t\taccent: string;\n\t\taccentDarker10: string;\n\t\taccentDarker20: string;\n\t\t/** Foreground color to use when accent color is the background. */\n\t\taccentInverted: string;\n\t\tbackground: string;\n\t\tforeground: string;\n\t\t/** Foreground color to use when foreground color is the background. */\n\t\tforegroundInverted: string;\n\t\tgray: {\n\t\t\t100: string;\n\t\t\t200: string;\n\t\t\t300: string;\n\t\t\t400: string;\n\t\t\t600: string;\n\t\t\t700: string;\n\t\t\t800: string;\n\t\t};\n\t} >;\n};\n\nexport type ThemeProps = ThemeInputValues & {\n\t/**\n\t * The children elements.\n\t */\n\tchildren?: ReactNode;\n};\n"],"mappings":""}