Line data Source code
1 : /*
2 : * Copyright (C) 2024 Red Hat, Inc.
3 : * SPDX-License-Identifier: LGPL-2.1-or-later
4 : */
5 :
6 53 : import React, { useState } from 'react';
7 :
8 : import { MenuToggle } from "@patternfly/react-core/dist/esm/components/MenuToggle";
9 : import { Dropdown, DropdownList, DropdownPopperProps } from "@patternfly/react-core/dist/esm/components/Dropdown";
10 :
11 : import { EllipsisVIcon } from '@patternfly/react-icons';
12 :
13 : /*
14 : * A dropdown with a Kebab button, commonly used in Cockpit pages provided as
15 : * component so not all pages have to re-invent the wheel.
16 : *
17 : * isOpen/setIsOpen are optional -- you need to handle the state externally if you render the KebabDropdown in an
18 : * "unstable" environment such as a dynamic list. When not given, the dropdown will manage its own state.
19 : *
20 : * This component expects a list of (non-deprecated!) DropdownItem's, if you
21 : * require a separator between DropdownItem's use PatternFly's Divivder
22 : * component.
23 : */
24 35 : export const KebabDropdown = ({ dropdownItems, position = "end", isDisabled = false, toggleButtonId, isOpen, setIsOpen } : {
25 : dropdownItems: React.ReactNode,
26 : position?: DropdownPopperProps['position'],
27 : isDisabled?: boolean,
28 : toggleButtonId?: string;
29 : isOpen?: boolean, setIsOpen?: React.Dispatch<React.SetStateAction<boolean>>,
30 35 : }) => {
31 35 : const [isKebabOpenInternal, setKebabOpenInternal] = useState(false);
32 35 : const isKebabOpen = isOpen ?? isKebabOpenInternal;
33 35 : const setKebabOpen = setIsOpen ?? setKebabOpenInternal;
34 :
35 35 : return (
36 35 : <Dropdown
37 1 : onOpenChange={isOpen => setKebabOpen(isOpen)}
38 11 : onSelect={() => setKebabOpen(false)}
39 35 : toggle={(toggleRef) => (
40 35 : <MenuToggle
41 35 : id={toggleButtonId}
42 35 : isDisabled={isDisabled}
43 35 : ref={toggleRef}
44 35 : variant="plain"
45 13 : onClick={() => setKebabOpen(!isKebabOpen)}
46 35 : isExpanded={isKebabOpen}
47 : >
48 35 : <EllipsisVIcon />
49 35 : </MenuToggle>
50 : )}
51 35 : isOpen={isKebabOpen}
52 35 : popperProps={{ position }}
53 : >
54 35 : <DropdownList>
55 35 : {dropdownItems}
56 35 : </DropdownList>
57 35 : </Dropdown>
58 : );
59 35 : };
|