Line data Source code
1 : /*
2 : * Copyright (C) 2024 Red Hat, Inc.
3 : * SPDX-License-Identifier: LGPL-2.1-or-later
4 : */
5 :
6 101 : 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 45 : 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 45 : }) => {
31 45 : const [isKebabOpenInternal, setKebabOpenInternal] = useState(false);
32 45 : const isKebabOpen = isOpen ?? isKebabOpenInternal;
33 45 : const setKebabOpen = setIsOpen ?? setKebabOpenInternal;
34 :
35 45 : return (
36 45 : <Dropdown
37 1 : onOpenChange={isOpen => setKebabOpen(isOpen)}
38 17 : onSelect={() => setKebabOpen(false)}
39 45 : toggle={(toggleRef) => (
40 45 : <MenuToggle
41 45 : id={toggleButtonId}
42 45 : isDisabled={isDisabled}
43 45 : ref={toggleRef}
44 45 : variant="plain"
45 19 : onClick={() => setKebabOpen(!isKebabOpen)}
46 45 : isExpanded={isKebabOpen}
47 : >
48 45 : <EllipsisVIcon />
49 45 : </MenuToggle>
50 : )}
51 45 : isOpen={isKebabOpen}
52 45 : popperProps={{ position }}
53 : >
54 45 : <DropdownList>
55 45 : {dropdownItems}
56 45 : </DropdownList>
57 45 : </Dropdown>
58 : );
59 45 : };
|