Files
formipay/node_modules/@wordpress/components/src/query-controls/index.tsx
dwindown e8fbfb14c1 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>
2026-04-18 17:02:14 +07:00

201 lines
5.4 KiB
TypeScript

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import AuthorSelect from './author-select';
import CategorySelect from './category-select';
import FormTokenField from '../form-token-field';
import RangeControl from '../range-control';
import SelectControl from '../select-control';
import { VStack } from '../v-stack';
import type {
QueryControlsProps,
QueryControlsWithMultipleCategorySelectionProps,
QueryControlsWithSingleCategorySelectionProps,
} from './types';
const DEFAULT_MIN_ITEMS = 1;
const DEFAULT_MAX_ITEMS = 100;
const MAX_CATEGORIES_SUGGESTIONS = 20;
function isSingleCategorySelection(
props: QueryControlsProps
): props is QueryControlsWithSingleCategorySelectionProps {
return 'categoriesList' in props;
}
function isMultipleCategorySelection(
props: QueryControlsProps
): props is QueryControlsWithMultipleCategorySelectionProps {
return 'categorySuggestions' in props;
}
/**
* Controls to query for posts.
*
* ```jsx
* const MyQueryControls = () => (
* <QueryControls
* { ...{ maxItems, minItems, numberOfItems, order, orderBy } }
* onOrderByChange={ ( newOrderBy ) => {
* updateQuery( { orderBy: newOrderBy } )
* }
* onOrderChange={ ( newOrder ) => {
* updateQuery( { order: newOrder } )
* }
* categoriesList={ categories }
* selectedCategoryId={ category }
* onCategoryChange={ ( newCategory ) => {
* updateQuery( { category: newCategory } )
* }
* onNumberOfItemsChange={ ( newNumberOfItems ) => {
* updateQuery( { numberOfItems: newNumberOfItems } )
* } }
* />
* );
* ```
*/
export function QueryControls( {
__next40pxDefaultSize = false,
authorList,
selectedAuthorId,
numberOfItems,
order,
orderBy,
maxItems = DEFAULT_MAX_ITEMS,
minItems = DEFAULT_MIN_ITEMS,
onAuthorChange,
onNumberOfItemsChange,
onOrderChange,
onOrderByChange,
// Props for single OR multiple category selection are not destructured here,
// but instead are destructured inline where necessary.
...props
}: QueryControlsProps ) {
return (
<VStack spacing="4" className="components-query-controls">
{ [
onOrderChange && onOrderByChange && (
<SelectControl
__nextHasNoMarginBottom
__next40pxDefaultSize={ __next40pxDefaultSize }
key="query-controls-order-select"
label={ __( 'Order by' ) }
value={ `${ orderBy }/${ order }` }
options={ [
{
label: __( 'Newest to oldest' ),
value: 'date/desc',
},
{
label: __( 'Oldest to newest' ),
value: 'date/asc',
},
{
/* translators: label for ordering posts by title in ascending order */
label: __( 'A → Z' ),
value: 'title/asc',
},
{
/* translators: label for ordering posts by title in descending order */
label: __( 'Z → A' ),
value: 'title/desc',
},
] }
onChange={ ( value ) => {
if ( typeof value !== 'string' ) {
return;
}
const [ newOrderBy, newOrder ] = value.split( '/' );
if ( newOrder !== order ) {
onOrderChange(
newOrder as NonNullable<
QueryControlsProps[ 'order' ]
>
);
}
if ( newOrderBy !== orderBy ) {
onOrderByChange(
newOrderBy as NonNullable<
QueryControlsProps[ 'orderBy' ]
>
);
}
} }
/>
),
isSingleCategorySelection( props ) &&
props.categoriesList &&
props.onCategoryChange && (
<CategorySelect
__next40pxDefaultSize={ __next40pxDefaultSize }
key="query-controls-category-select"
categoriesList={ props.categoriesList }
label={ __( 'Category' ) }
noOptionLabel={ __( 'All' ) }
selectedCategoryId={ props.selectedCategoryId }
onChange={ props.onCategoryChange }
/>
),
isMultipleCategorySelection( props ) &&
props.categorySuggestions &&
props.onCategoryChange && (
<FormTokenField
__next40pxDefaultSize={ __next40pxDefaultSize }
__nextHasNoMarginBottom
key="query-controls-categories-select"
label={ __( 'Categories' ) }
value={
props.selectedCategories &&
props.selectedCategories.map( ( item ) => ( {
id: item.id,
// Keeping the fallback to `item.value` for legacy reasons,
// even if items of `selectedCategories` should not have a
// `value` property.
// @ts-expect-error
value: item.name || item.value,
} ) )
}
suggestions={ Object.keys(
props.categorySuggestions
) }
onChange={ props.onCategoryChange }
maxSuggestions={ MAX_CATEGORIES_SUGGESTIONS }
/>
),
onAuthorChange && (
<AuthorSelect
__next40pxDefaultSize={ __next40pxDefaultSize }
key="query-controls-author-select"
authorList={ authorList }
label={ __( 'Author' ) }
noOptionLabel={ __( 'All' ) }
selectedAuthorId={ selectedAuthorId }
onChange={ onAuthorChange }
/>
),
onNumberOfItemsChange && (
<RangeControl
__nextHasNoMarginBottom
__next40pxDefaultSize={ __next40pxDefaultSize }
key="query-controls-range-control"
label={ __( 'Number of items' ) }
value={ numberOfItems }
onChange={ onNumberOfItemsChange }
min={ minItems }
max={ maxItems }
required
/>
),
] }
</VStack>
);
}
export default QueryControls;