mt-flowbite-react
Version:
Official React components built for Flowbite and Tailwind CSS
103 lines (102 loc) • 5.75 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Dropdown = exports.DropdownContext = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("@floating-ui/react");
const react_2 = require("react");
const hi_1 = require("react-icons/hi");
const __1 = require("../../");
const merge_deep_1 = require("../../helpers/merge-deep");
const DropdownDivider_1 = require("./DropdownDivider");
const DropdownHeader_1 = require("./DropdownHeader");
const DropdownItem_1 = require("./DropdownItem");
const tailwind_merge_1 = require("tailwind-merge");
const use_floating_1 = require("../../helpers/use-floating");
const icons = {
top: hi_1.HiOutlineChevronUp,
right: hi_1.HiOutlineChevronRight,
bottom: hi_1.HiOutlineChevronDown,
left: hi_1.HiOutlineChevronLeft,
};
const Trigger = ({ refs, children, inline, theme, disabled, setButtonWidth, getReferenceProps, renderTrigger, ...buttonProps }) => {
const ref = refs.reference;
const a11yProps = getReferenceProps();
(0, react_2.useEffect)(() => {
if (ref.current) {
setButtonWidth?.(ref.current.clientWidth);
}
}, [ref, setButtonWidth]);
if (renderTrigger) {
const triggerElement = renderTrigger(theme);
return (0, react_2.cloneElement)(triggerElement, { ref: refs.setReference, disabled, ...a11yProps, ...triggerElement.props });
}
return inline ? ((0, jsx_runtime_1.jsx)("button", { type: "button", ref: refs.setReference, className: theme?.inlineWrapper, disabled: disabled, ...a11yProps, children: children })) : ((0, jsx_runtime_1.jsx)(__1.Button, { ...buttonProps, disabled: disabled, type: "button", ref: refs.setReference, ...a11yProps, children: children }));
};
exports.DropdownContext = (0, react_2.createContext)({});
const DropdownComponent = ({ children, className, dismissOnClick = true, theme: customTheme = {}, renderTrigger, ...props }) => {
const [open, setOpen] = (0, react_2.useState)(false);
const [activeIndex, setActiveIndex] = (0, react_2.useState)(null);
const [selectedIndex, setSelectedIndex] = (0, react_2.useState)(null);
const [buttonWidth, setButtonWidth] = (0, react_2.useState)(undefined);
const elementsRef = (0, react_2.useRef)([]);
const labelsRef = (0, react_2.useRef)([]);
const theme = (0, merge_deep_1.mergeDeep)((0, __1.useTheme)().theme.dropdown, customTheme);
const theirProps = props;
const dataTestId = props['data-testid'] || 'flowbite-dropdown-target';
const { placement = props.inline ? 'bottom-start' : 'bottom', trigger = 'click', label, inline, arrowIcon = true, ...buttonProps } = theirProps;
const handleSelect = (0, react_2.useCallback)((index) => {
setSelectedIndex(index);
setOpen(false);
}, []);
const handleTypeaheadMatch = (0, react_2.useCallback)((index) => {
if (open) {
setActiveIndex(index);
}
else {
handleSelect(index);
}
}, [open, handleSelect]);
const { context, floatingStyles, refs } = (0, use_floating_1.useBaseFLoating)({
open,
setOpen,
placement,
});
const listNav = (0, react_1.useListNavigation)(context, {
listRef: elementsRef,
activeIndex,
selectedIndex,
onNavigate: setActiveIndex,
});
const typeahead = (0, react_1.useTypeahead)(context, {
listRef: labelsRef,
activeIndex,
selectedIndex,
onMatch: handleTypeaheadMatch,
});
const { getReferenceProps, getFloatingProps, getItemProps } = (0, use_floating_1.useFloatingInteractions)({
context,
role: 'menu',
trigger,
interactions: [listNav, typeahead],
});
const Icon = (0, react_2.useMemo)(() => {
const [p] = placement.split('-');
return icons[p] ?? hi_1.HiOutlineChevronDown;
}, [placement]);
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(Trigger, { ...buttonProps, refs: refs, inline: inline, theme: theme, "data-testid": dataTestId, className: (0, tailwind_merge_1.twMerge)(theme.floating.target, buttonProps.className), setButtonWidth: setButtonWidth, getReferenceProps: getReferenceProps, renderTrigger: renderTrigger, children: [label, arrowIcon && (0, jsx_runtime_1.jsx)(Icon, { className: theme.arrowIcon })] }), (0, jsx_runtime_1.jsx)(exports.DropdownContext.Provider, { value: {
activeIndex,
dismissOnClick,
getItemProps,
handleSelect,
}, children: open && ((0, jsx_runtime_1.jsx)(react_1.FloatingFocusManager, { context: context, modal: false, children: (0, jsx_runtime_1.jsx)("div", { ref: refs.setFloating, style: { ...floatingStyles, minWidth: buttonWidth }, "data-testid": "flowbite-dropdown", "aria-expanded": open, ...getFloatingProps({
className: (0, tailwind_merge_1.twMerge)(theme.floating.base, theme.floating.animation, 'duration-100', !open && theme.floating.hidden, theme.floating.style.auto, className),
}), children: (0, jsx_runtime_1.jsx)(react_1.FloatingList, { elementsRef: elementsRef, labelsRef: labelsRef, children: (0, jsx_runtime_1.jsx)("ul", { className: theme.content, tabIndex: -1, children: children }) }) }) })) })] }));
};
DropdownComponent.displayName = 'Dropdown';
DropdownHeader_1.DropdownHeader.displayName = 'Dropdown.Header';
DropdownDivider_1.DropdownDivider.displayName = 'Dropdown.Divider';
exports.Dropdown = Object.assign(DropdownComponent, {
Item: DropdownItem_1.DropdownItem,
Header: DropdownHeader_1.DropdownHeader,
Divider: DropdownDivider_1.DropdownDivider,
});