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,113 @@
# VStack
<div class="callout callout-alert">
This feature is still experimental. “Experimental” means this is an early implementation subject to drastic and breaking changes.
</div>
`VStack` (or Vertical Stack) is a layout component that arranges child elements in a vertical line.
## Usage
`VStack` can render anything inside.
```jsx
import {
__experimentalText as Text,
__experimentalVStack as VStack,
} from '@wordpress/components';
function Example() {
return (
<VStack>
<Text>Code</Text>
<Text>is</Text>
<Text>Poetry</Text>
</VStack>
);
}
```
## Props
##### `alignment`: `HStackAlignment | CSSProperties['alignItems']`
Determines how the child elements are aligned.
- `top`: Aligns content to the top.
- `topLeft`: Aligns content to the top/left.
- `topRight`: Aligns content to the top/right.
- `left`: Aligns content to the left.
- `center`: Aligns content to the center.
- `right`: Aligns content to the right.
- `bottom`: Aligns content to the bottom.
- `bottomLeft`: Aligns content to the bottom/left.
- `bottomRight`: Aligns content to the bottom/right.
- `edge`: Justifies content to be evenly spread out up to the main axis edges of the container.
- `stretch`: Stretches content to the cross axis edges of the container.
##### `direction`: `FlexDirection`
The direction flow of the children content can be adjusted with `direction`. `column` will align children vertically and `row` will align children horizontally.
##### `expanded`: `boolean`
Expands to the maximum available width (if horizontal) or height (if vertical).
##### `justify`: `CSSProperties['justifyContent']`
Horizontally aligns content if the `direction` is `row`, or vertically aligns content if the `direction` is `column`.
In the example below, `flex-start` will align the children content to the left.
##### `spacing`: `CSSProperties['width']`
The amount of space between each child element. Spacing in between each child can be adjusted by using `spacing`.
The value of `spacing` works as a multiplier to the library's grid system (base of `4px`).
##### `wrap`: `boolean`
Determines if children should wrap.
## Spacer
When a `Spacer` is used within an `VStack`, the `Spacer` adaptively expands to take up the remaining space.
```jsx
import {
__experimentalSpacer as Spacer,
__experimentalText as Text,
__experimentalVStack as VStack,
} from '@wordpress/components';
function Example() {
return (
<VStack>
<Text>Code</Text>
<Spacer>
<Text>is</Text>
</Spacer>
<Text>Poetry</Text>
</VStack>
);
}
```
`Spacer` can also be used in-between items to push them apart.
```jsx
import {
__experimentalSpacer as Spacer,
__experimentalText as Text,
__experimentalVStack as VStack,
} from '@wordpress/components';
function Example() {
return (
<VStack>
<Text>Code</Text>
<Spacer />
<Text>is</Text>
<Text>Poetry</Text>
</VStack>
);
}
```

View File

@@ -0,0 +1,49 @@
/**
* External dependencies
*/
import type { ForwardedRef } from 'react';
/**
* Internal dependencies
*/
import type { WordPressComponentProps } from '../context';
import { contextConnect } from '../context';
import { View } from '../view';
import { useVStack } from './hook';
import type { VStackProps } from './types';
function UnconnectedVStack(
props: WordPressComponentProps< VStackProps, 'div' >,
forwardedRef: ForwardedRef< any >
) {
const vStackProps = useVStack( props );
return <View { ...vStackProps } ref={ forwardedRef } />;
}
/**
* `VStack` (or Vertical Stack) is a layout component that arranges child
* elements in a vertical line.
*
* `VStack` can render anything inside.
*
* ```jsx
* import {
* __experimentalText as Text,
* __experimentalVStack as VStack,
* } from `@wordpress/components`;
*
* function Example() {
* return (
* <VStack>
* <Text>Code</Text>
* <Text>is</Text>
* <Text>Poetry</Text>
* </VStack>
* );
* }
* ```
*/
export const VStack = contextConnect( UnconnectedVStack, 'VStack' );
export default VStack;

26
node_modules/@wordpress/components/src/v-stack/hook.ts generated vendored Normal file
View File

@@ -0,0 +1,26 @@
/**
* Internal dependencies
*/
import type { WordPressComponentProps } from '../context';
import { useContextSystem } from '../context';
import { useHStack } from '../h-stack';
import type { VStackProps } from './types';
export function useVStack(
props: WordPressComponentProps< VStackProps, 'div' >
) {
const {
expanded = false,
alignment = 'stretch',
...otherProps
} = useContextSystem( props, 'VStack' );
const hStackProps = useHStack( {
direction: 'column',
expanded,
alignment,
...otherProps,
} );
return hStackProps;
}

View File

@@ -0,0 +1,2 @@
export { default as VStack } from './component';
export { useVStack } from './hook';

View File

@@ -0,0 +1,36 @@
/**
* External dependencies
*/
import type { StoryFn, Meta } from '@storybook/react';
/**
* Internal dependencies
*/
import { View } from '../../../view';
import { VStack } from '../..';
const meta: Meta< typeof VStack > = {
component: VStack,
title: 'Components (Experimental)/VStack',
};
export default meta;
const Template: StoryFn< typeof VStack > = ( props ) => {
return (
<VStack
{ ...props }
style={ { background: '#eee', minHeight: '3rem' } }
>
{ [ 'One', 'Two', 'Three', 'Four', 'Five' ].map( ( text ) => (
<View key={ text } style={ { background: '#b9f9ff' } }>
{ text }
</View>
) ) }
</VStack>
);
};
export const Default: StoryFn< typeof VStack > = Template.bind( {} );
Default.args = {
spacing: 3,
};

View File

@@ -0,0 +1,62 @@
/**
* External dependencies
*/
import type { Meta, StoryFn } from '@storybook/react';
/**
* Internal dependencies
*/
import { View } from '../../view';
import { VStack } from '..';
const ALIGNMENTS = {
top: 'top',
topLeft: 'topLeft',
topRight: 'topRight',
left: 'left',
center: 'center',
right: 'right',
bottom: 'bottom',
bottomLeft: 'bottomLeft',
bottomRight: 'bottomRight',
edge: 'edge',
stretch: 'stretch',
};
const meta: Meta< typeof VStack > = {
component: VStack,
title: 'Components (Experimental)/VStack',
argTypes: {
alignment: {
control: { type: 'select' },
options: Object.keys( ALIGNMENTS ),
mapping: ALIGNMENTS,
},
as: { control: { type: 'text' } },
direction: { control: { type: 'text' } },
justify: { control: { type: 'text' } },
spacing: { control: { type: 'text' } },
},
parameters: {
controls: { expanded: true },
docs: { canvas: { sourceState: 'shown' } },
},
};
export default meta;
const Template: StoryFn< typeof VStack > = ( props ) => {
return (
<VStack
{ ...props }
style={ { background: '#eee', minHeight: '200px' } }
>
{ [ 'One', 'Two', 'Three', 'Four', 'Five' ].map( ( text ) => (
<View key={ text } style={ { background: '#b9f9ff' } }>
{ text }
</View>
) ) }
</VStack>
);
};
export const Default = Template.bind( {} );

View File

@@ -0,0 +1,121 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`props should render alignment 1`] = `
.emotion-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: calc(4px * 2);
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
.emotion-0>* {
min-height: 0;
}
<div>
<div
class="components-flex components-h-stack components-v-stack emotion-0 emotion-1"
data-wp-c16t="true"
data-wp-component="VStack"
>
<div
class="emotion-2 emotion-1"
/>
<div
class="emotion-2 emotion-1"
/>
</div>
</div>
`;
exports[`props should render correctly 1`] = `
.emotion-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: stretch;
-webkit-box-align: stretch;
-ms-flex-align: stretch;
align-items: stretch;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: calc(4px * 2);
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
.emotion-0>* {
min-height: 0;
}
<div>
<div
class="components-flex components-h-stack components-v-stack emotion-0 emotion-1"
data-wp-c16t="true"
data-wp-component="VStack"
>
<div
class="emotion-2 emotion-1"
/>
<div
class="emotion-2 emotion-1"
/>
</div>
</div>
`;
exports[`props should render spacing 1`] = `
.emotion-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: stretch;
-webkit-box-align: stretch;
-ms-flex-align: stretch;
align-items: stretch;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: calc(4px * 5);
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
.emotion-0>* {
min-height: 0;
}
<div>
<div
class="components-flex components-h-stack components-v-stack emotion-0 emotion-1"
data-wp-c16t="true"
data-wp-component="VStack"
>
<div
class="emotion-2 emotion-1"
/>
<div
class="emotion-2 emotion-1"
/>
</div>
</div>
`;

View File

@@ -0,0 +1,42 @@
/**
* External dependencies
*/
import { render } from '@testing-library/react';
/**
* Internal dependencies
*/
import { View } from '../../view';
import { VStack } from '..';
describe( 'props', () => {
test( 'should render correctly', () => {
const { container } = render(
<VStack>
<View />
<View />
</VStack>
);
expect( container ).toMatchSnapshot();
} );
test( 'should render alignment', () => {
const { container } = render(
<VStack alignment="center">
<View />
<View />
</VStack>
);
expect( container ).toMatchSnapshot();
} );
test( 'should render spacing', () => {
const { container } = render(
<VStack spacing={ 5 }>
<View />
<View />
</VStack>
);
expect( container ).toMatchSnapshot();
} );
} );

View File

@@ -0,0 +1,36 @@
/**
* External dependencies
*/
import type { CSSProperties } from 'react';
/**
* Internal dependencies
*/
import type { HStackAlignment, Props as HStackProps } from '../h-stack/types';
export type VStackProps = Omit< HStackProps, 'alignment' | 'spacing' > & {
/**
* Determines how the child elements are aligned.
*
* - `top`: Aligns content to the top.
* - `topLeft`: Aligns content to the top/left.
* - `topRight`: Aligns content to the top/right.
* - `left`: Aligns content to the left.
* - `center`: Aligns content to the center.
* - `right`: Aligns content to the right.
* - `bottom`: Aligns content to the bottom.
* - `bottomLeft`: Aligns content to the bottom/left.
* - `bottomRight`: Aligns content to the bottom/right.
* - `edge`: Justifies content to be evenly spread out up to the main axis edges of the container.
* - `stretch`: Stretches content to the cross axis edges of the container.
*
* @default 'stretch'
*/
alignment?: HStackAlignment | CSSProperties[ 'alignItems' ];
/**
* The amount of space between each child element. Spacing in between each
* child can be adjusted by using `spacing`. The value of `spacing` works as
* a multiplier to the library's grid system (base of `4px`).
*/
spacing?: CSSProperties[ 'width' ];
};