@codinglane/dropdown
Version:
An easy-to-use react dropdown
57 lines (56 loc) • 2.75 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import React from 'react';
import * as Contracts from '../../../../contracts';
import { Group } from './group';
const DEFAULT_FAVORITE = 'Favorite';
const DEFAULT_NON_FAVORITE = 'Standard';
export const Grouped = React.forwardRef(({ id, options, onOptionClick, onFilteredChange, current, filter, onFavorize, favoriteGroupName, nonFavoriteGroupName, grouping, favorize, anchor, ...props }, ref) => {
const favorites = options.filter((opt) => opt.favorite).length;
const favoritesName = favoriteGroupName ?? DEFAULT_FAVORITE;
const nonFavoritesName = nonFavoriteGroupName ?? DEFAULT_NON_FAVORITE;
const top = React.useMemo(() => {
if (anchor?.direction === 'DOWN')
return anchor.at;
}, [anchor]);
const bottom = React.useMemo(() => {
if (anchor?.direction === 'UP')
return anchor.at;
}, [anchor]);
const grouped = React.useMemo(() => {
if (favorize && !grouping)
return Contracts.mapToFavoriteGroup(options, { favorite: favoritesName, nonFavorite: nonFavoritesName }, filter);
if (!favorize)
return Contracts.mapToGroups(options, filter);
return Contracts.mapToGroupsWithFavorites(options, { favorite: favoritesName, nonFavorite: nonFavoritesName }, filter);
}, [options, filter, favorize, favorites]);
const selected = React.useMemo(() => grouped
.reduce((prev, curr) => {
if (!curr.isParent)
return prev.concat(curr.options);
return prev.concat(curr.options.reduce((prv, crr) => {
if (!crr.isParent)
return prv.concat(crr.options);
return [];
}, []));
}, [])
.filter((option) => option.value === current)
.pop(), [options, current]);
React.useEffect(() => {
onFilteredChange(grouped
.reduce((prev, curr) => {
if (!curr.isParent)
return prev.concat(curr.options);
return curr.options.reduce((prv, crr) => {
if (!crr.isParent)
return prv.concat(crr.options);
return [];
}, []);
}, [])
.map((fltr) => fltr.value));
}, [grouped]);
return (_jsx("div", { className: 'dropdown-content dropdown-grouped', ref: ref, style: {
top,
bottom,
maxHeight: Contracts.MENU_MAX_HEIGHT,
}, ...props, children: _jsx(Group, { onOptionClick: onOptionClick, id: id?.concat('option'), selected: selected, favorize: favorize, onFavorize: onFavorize, grouped: grouped, "data-testid": props['data-testid']?.concat('-group') }) }));
});