hoda-react
Version:
<div align="center"> <h1>:construction: flowbite-react (unreleased) :construction:</h1> <p> <a href="https://flowbite-react.com"> <img alt="Flowbite - Tailwind CSS components" width="350" src=".github/assets/flowbite-react-github.png"> <
58 lines (57 loc) • 3.04 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { Children, useMemo, useState } from 'react';
import { HiOutlineChevronDown, HiOutlineChevronLeft, HiOutlineChevronRight, HiOutlineChevronUp } from 'react-icons/hi';
import { uuid } from '../../helpers/uuid';
import { Button } from '../Button';
import { Floating } from '../Floating';
import { useTheme } from '../Flowbite/ThemeContext';
import { DropdownDivider } from './DropdownDivider';
import { DropdownHeader } from './DropdownHeader';
import { DropdownItem } from './DropdownItem';
const icons = {
top: HiOutlineChevronUp,
right: HiOutlineChevronRight,
bottom: HiOutlineChevronDown,
left: HiOutlineChevronLeft,
};
const DropdownComponent = ({ children, className, dismissOnClick = true, ...props }) => {
const theme = useTheme().theme.dropdown;
const theirProps = props;
const { placement = props.inline ? 'bottom-start' : 'bottom', trigger = 'click', label, inline, floatingArrow = false, arrowIcon = true, ...buttonProps } = theirProps;
const Icon = useMemo(() => {
const [p] = placement.split('-');
return icons[p] ?? HiOutlineChevronDown;
}, [placement]);
const [closeRequestKey, setCloseRequestKey] = useState(undefined);
// Extends DropdownItem's onClick to trigger a close request to the Floating component
const attachCloseListener = (node) => {
if (!React.isValidElement(node))
return node;
if (node.type === DropdownItem)
return React.cloneElement(node, {
onClick: () => {
node.props.onClick?.();
dismissOnClick && setCloseRequestKey(uuid());
},
});
if (node.props.children && typeof node.props.children === 'object') {
return React.cloneElement(node, {
// @ts-ignore
children: Children.map(node.props.children, attachCloseListener),
});
}
return node;
};
const content = useMemo(() => _jsx("ul", { className: theme.content, children: Children.map(children, attachCloseListener) }), [children, theme]);
const TriggerWrapper = ({ children }) => inline ? _jsx("button", { className: theme.inlineWrapper, children: children }) : _jsx(Button, { ...buttonProps, children: children });
return (_jsx(Floating, { content: content, style: "auto", animation: "duration-100", placement: placement, arrow: floatingArrow, trigger: trigger, theme: theme.floating, closeRequestKey: closeRequestKey, className: className, children: _jsxs(TriggerWrapper, { children: [label, arrowIcon && _jsx(Icon, { className: theme.arrowIcon })] }) }));
};
DropdownComponent.displayName = 'Dropdown';
DropdownItem.displayName = 'Dropdown.Item';
DropdownHeader.displayName = 'Dropdown.Header';
DropdownDivider.displayName = 'Dropdown.Divider';
export const Dropdown = Object.assign(DropdownComponent, {
Item: DropdownItem,
Header: DropdownHeader,
Divider: DropdownDivider,
});