diff --git a/packages/react-core/src/components/Dropdown/examples/Dropdown.md b/packages/react-core/src/components/Dropdown/examples/Dropdown.md index 831bd97a5cf..4e0cf97fe46 100644 --- a/packages/react-core/src/components/Dropdown/examples/Dropdown.md +++ b/packages/react-core/src/components/Dropdown/examples/Dropdown.md @@ -16,7 +16,7 @@ propComponents: ] --- -import { useState } from 'react'; +import { useState, useRef } from 'react'; import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; ## Examples @@ -63,3 +63,15 @@ To provide users with more context about a ``, pass a short messag ```ts file="./DropdownWithDescriptions.tsx" ``` + +### Split toggle with checkbox + +To combine a checkbox or other control with a dropdown menu, use a split button. + +A `` can be rendered as a split button via `splitButtonItems`. Elements to be displayed before the dropdown toggle button (like the ``) must be included in the `splitButtonItems`. + +If the dropdown menu closes upon selection, you will need to manually shift focus back to the toggle element after a user selects an item from the menu. + +```ts file="./DropdownWithSplit.tsx" + +``` diff --git a/packages/react-core/src/components/Dropdown/examples/DropdownWithSplit.tsx b/packages/react-core/src/components/Dropdown/examples/DropdownWithSplit.tsx new file mode 100644 index 00000000000..140a99510cd --- /dev/null +++ b/packages/react-core/src/components/Dropdown/examples/DropdownWithSplit.tsx @@ -0,0 +1,97 @@ +import { + Dropdown, + MenuToggle, + MenuToggleCheckbox, + DropdownItem, + DropdownList, + Divider, + MenuToggleElement +} from '@patternfly/react-core'; +import { useRef, useState } from 'react'; + +export const DropdownSplitButtonText: React.FunctionComponent = () => { + const [isOpen, setIsOpen] = useState(false); + const toggleRef = useRef(null); + + const onFocus = () => { + if (!toggleRef.current) { + return; + } + + const toggleButton = toggleRef.current.querySelector('button[aria-expanded]'); + toggleButton?.focus(); + }; + + const onSelect = () => { + setIsOpen(false); + onFocus(); + }; + + const onToggleClick = () => { + setIsOpen(!isOpen); + }; + + return ( + setIsOpen(isOpen)} + toggle={(toggleRefCallback: React.Ref) => ( + { + // Handle both callback ref and useRef + if (typeof toggleRefCallback === 'function') { + toggleRefCallback(node); + } else if (toggleRefCallback) { + (toggleRefCallback as React.MutableRefObject).current = node; + } + (toggleRef as React.MutableRefObject).current = node; + }} + splitButtonItems={[ + + ]} + aria-label="Dropdown with checkbox split button" + onClick={onToggleClick} + isExpanded={isOpen} + /> + )} + isOpen={isOpen} + > + + + Action + + ev.preventDefault()} + > + Link + + + Disabled Action + + + Disabled Link + + + Aria-disabled Link + + + + Separated Action + + ev.preventDefault()}> + Separated Link + + + + ); +};