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>
142 lines
4.4 KiB
JavaScript
142 lines
4.4 KiB
JavaScript
import { createElement } from "react";
|
|
/**
|
|
* External dependencies
|
|
*/
|
|
import classnames from 'classnames';
|
|
/**
|
|
* WordPress dependencies
|
|
*/
|
|
import { useRef, useState } from '@wordpress/element';
|
|
import { useMergeRefs } from '@wordpress/compose';
|
|
import deprecated from '@wordpress/deprecated';
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import { contextConnect, useContextSystem } from '../context';
|
|
import { useControlledValue } from '../utils/hooks';
|
|
import Popover from '../popover';
|
|
const UnconnectedDropdown = (props, forwardedRef) => {
|
|
const {
|
|
renderContent,
|
|
renderToggle,
|
|
className,
|
|
contentClassName,
|
|
expandOnMobile,
|
|
headerTitle,
|
|
focusOnMount,
|
|
popoverProps,
|
|
onClose,
|
|
onToggle,
|
|
style,
|
|
open,
|
|
defaultOpen,
|
|
// Deprecated props
|
|
position,
|
|
// From context system
|
|
variant
|
|
} = useContextSystem(props, 'Dropdown');
|
|
if (position !== undefined) {
|
|
deprecated('`position` prop in wp.components.Dropdown', {
|
|
since: '6.2',
|
|
alternative: '`popoverProps.placement` prop',
|
|
hint: 'Note that the `position` prop will override any values passed through the `popoverProps.placement` prop.'
|
|
});
|
|
}
|
|
|
|
// Use internal state instead of a ref to make sure that the component
|
|
// re-renders when the popover's anchor updates.
|
|
const [fallbackPopoverAnchor, setFallbackPopoverAnchor] = useState(null);
|
|
const containerRef = useRef();
|
|
const [isOpen, setIsOpen] = useControlledValue({
|
|
defaultValue: defaultOpen,
|
|
value: open,
|
|
onChange: onToggle
|
|
});
|
|
|
|
/**
|
|
* Closes the popover when focus leaves it unless the toggle was pressed or
|
|
* focus has moved to a separate dialog. The former is to let the toggle
|
|
* handle closing the popover and the latter is to preserve presence in
|
|
* case a dialog has opened, allowing focus to return when it's dismissed.
|
|
*/
|
|
function closeIfFocusOutside() {
|
|
if (!containerRef.current) {
|
|
return;
|
|
}
|
|
const {
|
|
ownerDocument
|
|
} = containerRef.current;
|
|
const dialog = ownerDocument?.activeElement?.closest('[role="dialog"]');
|
|
if (!containerRef.current.contains(ownerDocument.activeElement) && (!dialog || dialog.contains(containerRef.current))) {
|
|
close();
|
|
}
|
|
}
|
|
function close() {
|
|
onClose?.();
|
|
setIsOpen(false);
|
|
}
|
|
const args = {
|
|
isOpen: !!isOpen,
|
|
onToggle: () => setIsOpen(!isOpen),
|
|
onClose: close
|
|
};
|
|
const popoverPropsHaveAnchor = !!popoverProps?.anchor ||
|
|
// Note: `anchorRef`, `getAnchorRect` and `anchorRect` are deprecated and
|
|
// be removed from `Popover` from WordPress 6.3
|
|
!!popoverProps?.anchorRef || !!popoverProps?.getAnchorRect || !!popoverProps?.anchorRect;
|
|
return createElement("div", {
|
|
className: className,
|
|
ref: useMergeRefs([containerRef, forwardedRef, setFallbackPopoverAnchor])
|
|
// Some UAs focus the closest focusable parent when the toggle is
|
|
// clicked. Making this div focusable ensures such UAs will focus
|
|
// it and `closeIfFocusOutside` can tell if the toggle was clicked.
|
|
,
|
|
tabIndex: -1,
|
|
style: style
|
|
}, renderToggle(args), isOpen && createElement(Popover, {
|
|
position: position,
|
|
onClose: close,
|
|
onFocusOutside: closeIfFocusOutside,
|
|
expandOnMobile: expandOnMobile,
|
|
headerTitle: headerTitle,
|
|
focusOnMount: focusOnMount
|
|
// This value is used to ensure that the dropdowns
|
|
// align with the editor header by default.
|
|
,
|
|
offset: 13,
|
|
anchor: !popoverPropsHaveAnchor ? fallbackPopoverAnchor : undefined,
|
|
variant: variant,
|
|
...popoverProps,
|
|
className: classnames('components-dropdown__content', popoverProps?.className, contentClassName)
|
|
}, renderContent(args)));
|
|
};
|
|
|
|
/**
|
|
* Renders a button that opens a floating content modal when clicked.
|
|
*
|
|
* ```jsx
|
|
* import { Button, Dropdown } from '@wordpress/components';
|
|
*
|
|
* const MyDropdown = () => (
|
|
* <Dropdown
|
|
* className="my-container-class-name"
|
|
* contentClassName="my-dropdown-content-classname"
|
|
* popoverProps={ { placement: 'bottom-start' } }
|
|
* renderToggle={ ( { isOpen, onToggle } ) => (
|
|
* <Button
|
|
* variant="primary"
|
|
* onClick={ onToggle }
|
|
* aria-expanded={ isOpen }
|
|
* >
|
|
* Toggle Dropdown!
|
|
* </Button>
|
|
* ) }
|
|
* renderContent={ () => <div>This is the content of the dropdown.</div> }
|
|
* />
|
|
* );
|
|
* ```
|
|
*/
|
|
export const Dropdown = contextConnect(UnconnectedDropdown, 'Dropdown');
|
|
export default Dropdown;
|
|
//# sourceMappingURL=index.js.map
|