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>
237 lines
8.1 KiB
JavaScript
237 lines
8.1 KiB
JavaScript
import { createElement, Fragment } from "react";
|
|
/**
|
|
* External dependencies
|
|
*/
|
|
// eslint-disable-next-line no-restricted-imports
|
|
import * as Ariakit from '@ariakit/react';
|
|
|
|
/**
|
|
* WordPress dependencies
|
|
*/
|
|
import { forwardRef, createContext, useContext, useMemo, cloneElement, isValidElement, useCallback } from '@wordpress/element';
|
|
import { isRTL } from '@wordpress/i18n';
|
|
import { check, chevronRightSmall } from '@wordpress/icons';
|
|
import { SVG, Circle } from '@wordpress/primitives';
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import { useContextSystem, contextConnect } from '../context';
|
|
import Icon from '../icon';
|
|
import * as Styled from './styles';
|
|
export const DropdownMenuContext = createContext(undefined);
|
|
export const DropdownMenuItem = forwardRef(function DropdownMenuItem({
|
|
prefix,
|
|
suffix,
|
|
children,
|
|
hideOnClick = true,
|
|
...props
|
|
}, ref) {
|
|
const dropdownMenuContext = useContext(DropdownMenuContext);
|
|
return createElement(Styled.DropdownMenuItem, {
|
|
ref: ref,
|
|
...props,
|
|
accessibleWhenDisabled: true,
|
|
hideOnClick: hideOnClick,
|
|
store: dropdownMenuContext?.store
|
|
}, createElement(Styled.ItemPrefixWrapper, null, prefix), createElement(Styled.DropdownMenuItemContentWrapper, null, createElement(Styled.DropdownMenuItemChildrenWrapper, null, children), suffix && createElement(Styled.ItemSuffixWrapper, null, suffix)));
|
|
});
|
|
export const DropdownMenuCheckboxItem = forwardRef(function DropdownMenuCheckboxItem({
|
|
suffix,
|
|
children,
|
|
hideOnClick = false,
|
|
...props
|
|
}, ref) {
|
|
const dropdownMenuContext = useContext(DropdownMenuContext);
|
|
return createElement(Styled.DropdownMenuCheckboxItem, {
|
|
ref: ref,
|
|
...props,
|
|
accessibleWhenDisabled: true,
|
|
hideOnClick: hideOnClick,
|
|
store: dropdownMenuContext?.store
|
|
}, createElement(Ariakit.MenuItemCheck, {
|
|
store: dropdownMenuContext?.store,
|
|
render: createElement(Styled.ItemPrefixWrapper, null)
|
|
// Override some ariakit inline styles
|
|
,
|
|
style: {
|
|
width: 'auto',
|
|
height: 'auto'
|
|
}
|
|
}, createElement(Icon, {
|
|
icon: check,
|
|
size: 24
|
|
})), createElement(Styled.DropdownMenuItemContentWrapper, null, createElement(Styled.DropdownMenuItemChildrenWrapper, null, children), suffix && createElement(Styled.ItemSuffixWrapper, null, suffix)));
|
|
});
|
|
const radioCheck = createElement(SVG, {
|
|
xmlns: "http://www.w3.org/2000/svg",
|
|
viewBox: "0 0 24 24"
|
|
}, createElement(Circle, {
|
|
cx: 12,
|
|
cy: 12,
|
|
r: 3
|
|
}));
|
|
export const DropdownMenuRadioItem = forwardRef(function DropdownMenuRadioItem({
|
|
suffix,
|
|
children,
|
|
hideOnClick = false,
|
|
...props
|
|
}, ref) {
|
|
const dropdownMenuContext = useContext(DropdownMenuContext);
|
|
return createElement(Styled.DropdownMenuRadioItem, {
|
|
ref: ref,
|
|
...props,
|
|
accessibleWhenDisabled: true,
|
|
hideOnClick: hideOnClick,
|
|
store: dropdownMenuContext?.store
|
|
}, createElement(Ariakit.MenuItemCheck, {
|
|
store: dropdownMenuContext?.store,
|
|
render: createElement(Styled.ItemPrefixWrapper, null)
|
|
// Override some ariakit inline styles
|
|
,
|
|
style: {
|
|
width: 'auto',
|
|
height: 'auto'
|
|
}
|
|
}, createElement(Icon, {
|
|
icon: radioCheck,
|
|
size: 24
|
|
})), createElement(Styled.DropdownMenuItemContentWrapper, null, createElement(Styled.DropdownMenuItemChildrenWrapper, null, children), suffix && createElement(Styled.ItemSuffixWrapper, null, suffix)));
|
|
});
|
|
export const DropdownMenuGroup = forwardRef(function DropdownMenuGroup(props, ref) {
|
|
const dropdownMenuContext = useContext(DropdownMenuContext);
|
|
return createElement(Styled.DropdownMenuGroup, {
|
|
ref: ref,
|
|
...props,
|
|
store: dropdownMenuContext?.store
|
|
});
|
|
});
|
|
const UnconnectedDropdownMenu = (props, ref) => {
|
|
var _props$placement;
|
|
const {
|
|
// Store props
|
|
open,
|
|
defaultOpen = false,
|
|
onOpenChange,
|
|
placement,
|
|
// Menu trigger props
|
|
trigger,
|
|
// Menu props
|
|
gutter,
|
|
children,
|
|
shift,
|
|
modal = true,
|
|
// From internal components context
|
|
variant,
|
|
// Rest
|
|
...otherProps
|
|
} = useContextSystem(props, 'DropdownMenu');
|
|
const parentContext = useContext(DropdownMenuContext);
|
|
const computedDirection = isRTL() ? 'rtl' : 'ltr';
|
|
|
|
// If an explicit value for the `placement` prop is not passed,
|
|
// apply a default placement of `bottom-start` for the root dropdown,
|
|
// and of `right-start` for nested dropdowns.
|
|
let computedPlacement = (_props$placement = props.placement) !== null && _props$placement !== void 0 ? _props$placement : parentContext?.store ? 'right-start' : 'bottom-start';
|
|
// Swap left/right in case of RTL direction
|
|
if (computedDirection === 'rtl') {
|
|
if (/right/.test(computedPlacement)) {
|
|
computedPlacement = computedPlacement.replace('right', 'left');
|
|
} else if (/left/.test(computedPlacement)) {
|
|
computedPlacement = computedPlacement.replace('left', 'right');
|
|
}
|
|
}
|
|
const dropdownMenuStore = Ariakit.useMenuStore({
|
|
parent: parentContext?.store,
|
|
open,
|
|
defaultOpen,
|
|
placement: computedPlacement,
|
|
focusLoop: true,
|
|
setOpen(willBeOpen) {
|
|
onOpenChange?.(willBeOpen);
|
|
},
|
|
rtl: computedDirection === 'rtl'
|
|
});
|
|
const contextValue = useMemo(() => ({
|
|
store: dropdownMenuStore,
|
|
variant
|
|
}), [dropdownMenuStore, variant]);
|
|
|
|
// Extract the side from the applied placement — useful for animations.
|
|
const appliedPlacementSide = dropdownMenuStore.useState('placement').split('-')[0];
|
|
if (dropdownMenuStore.parent && !(isValidElement(trigger) && DropdownMenuItem === trigger.type)) {
|
|
// eslint-disable-next-line no-console
|
|
console.warn('For nested DropdownMenus, the `trigger` should always be a `DropdownMenuItem`.');
|
|
}
|
|
const hideOnEscape = useCallback(event => {
|
|
// Pressing Escape can cause unexpected consequences (ie. exiting
|
|
// full screen mode on MacOs, close parent modals...).
|
|
event.preventDefault();
|
|
// Returning `true` causes the menu to hide.
|
|
return true;
|
|
}, []);
|
|
const wrapperProps = useMemo(() => ({
|
|
dir: computedDirection,
|
|
style: {
|
|
direction: computedDirection
|
|
}
|
|
}), [computedDirection]);
|
|
return createElement(Fragment, null, createElement(Ariakit.MenuButton, {
|
|
ref: ref,
|
|
store: dropdownMenuStore,
|
|
render: dropdownMenuStore.parent ? cloneElement(trigger, {
|
|
// Add submenu arrow, unless a `suffix` is explicitly specified
|
|
suffix: createElement(Fragment, null, trigger.props.suffix, createElement(Styled.SubmenuChevronIcon, {
|
|
"aria-hidden": "true",
|
|
icon: chevronRightSmall,
|
|
size: 24,
|
|
preserveAspectRatio: "xMidYMid slice"
|
|
}))
|
|
}) : trigger
|
|
}), createElement(Styled.DropdownMenu, {
|
|
...otherProps,
|
|
modal: modal,
|
|
store: dropdownMenuStore
|
|
// Root menu has an 8px distance from its trigger,
|
|
// otherwise 0 (which causes the submenu to slightly overlap)
|
|
,
|
|
gutter: gutter !== null && gutter !== void 0 ? gutter : dropdownMenuStore.parent ? 0 : 8
|
|
// Align nested menu by the same (but opposite) amount
|
|
// as the menu container's padding.
|
|
,
|
|
shift: shift !== null && shift !== void 0 ? shift : dropdownMenuStore.parent ? -4 : 0,
|
|
hideOnHoverOutside: false,
|
|
"data-side": appliedPlacementSide,
|
|
variant: variant,
|
|
wrapperProps: wrapperProps,
|
|
hideOnEscape: hideOnEscape,
|
|
unmountOnHide: true
|
|
}, createElement(DropdownMenuContext.Provider, {
|
|
value: contextValue
|
|
}, children)));
|
|
};
|
|
export const DropdownMenu = contextConnect(UnconnectedDropdownMenu, 'DropdownMenu');
|
|
export const DropdownMenuSeparator = forwardRef(function DropdownMenuSeparator(props, ref) {
|
|
const dropdownMenuContext = useContext(DropdownMenuContext);
|
|
return createElement(Styled.DropdownMenuSeparator, {
|
|
ref: ref,
|
|
...props,
|
|
store: dropdownMenuContext?.store,
|
|
variant: dropdownMenuContext?.variant
|
|
});
|
|
});
|
|
export const DropdownMenuItemLabel = forwardRef(function DropdownMenuItemLabel(props, ref) {
|
|
return createElement(Styled.DropdownMenuItemLabel, {
|
|
numberOfLines: 1,
|
|
ref: ref,
|
|
...props
|
|
});
|
|
});
|
|
export const DropdownMenuItemHelpText = forwardRef(function DropdownMenuItemHelpText(props, ref) {
|
|
return createElement(Styled.DropdownMenuItemHelpText, {
|
|
numberOfLines: 2,
|
|
ref: ref,
|
|
...props
|
|
});
|
|
});
|
|
//# sourceMappingURL=index.js.map
|