@coveord/plasma-mantine
Version:
A Plasma flavoured Mantine theme
186 lines (185 loc) • 8.63 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { IconSearch } from '@coveord/plasma-react-icons';
import { Box, CloseButton, Combobox, Divider, factory, Group, Text, TextInput, Title, useCombobox, useProps } from '@mantine/core';
import { useUncontrolled } from '@mantine/hooks';
import { clsx } from 'clsx';
import { useEffect } from 'react';
import { groupOptions } from '../../utils/groupOptions.js';
import { DefaultFacetItem } from './DefaultFacetItem.js';
import classes from './Facet.module.css';
import { FacetScrollArea } from './FacetScrollArea.js';
const defaultProps = {
searchPlaceholder: 'Search',
nothingFound: 'No matching items',
placeholder: 'No items',
height: 200,
limit: Infinity,
itemComponent: DefaultFacetItem,
listComponent: FacetScrollArea,
removable: false
};
export const Facet = factory((_props, ref)=>{
const props = useProps('Facet', defaultProps, _props);
const { className, data, onChange, onRemove, initialSelection = [], removable, selection, itemComponent: ItemComponent, listComponent: ListComponent, itemCountFormatter, searchPlaceholder, query, hideSearch = data.length <= 7, onSearch, filter = defaultFilter, nothingFound, placeholder, title, height, radius, __staticSelector, classNames, styles, limit, unstyled, ...others } = props;
const combobox = useCombobox();
const [search, handleSearch] = useUncontrolled({
value: query,
defaultValue: '',
finalValue: '',
onChange: onSearch
});
const [_selection, handleSelection] = useUncontrolled({
value: selection,
defaultValue: initialSelection,
finalValue: [],
onChange
});
const unGroupedItems = [];
const groupedItems = [];
const filteredData = data.filter((item)=>filter(search, item)).slice(0, limit);
const sortedData = groupOptions({
data: filteredData
});
const handleValueSelect = (val)=>handleSelection(_selection.includes(val) ? _selection.filter((v)=>v !== val) : [
..._selection,
val
]);
let groupName = null;
useEffect(()=>{
combobox.openDropdown();
}, []);
sortedData.forEach((item)=>{
const isSelected = _selection.includes(item.value);
const itemComponent = /*#__PURE__*/ _jsx(Combobox.Option, {
"aria-selected": isSelected ? true : false,
value: item.value,
onMouseEnter: ()=>combobox.resetSelectedOption(),
className: clsx(classes.facetItem),
children: /*#__PURE__*/ _jsx(ItemComponent, {
data: item,
selected: isSelected,
countFormatter: itemCountFormatter
})
}, item.value);
if (!item.group) {
unGroupedItems.push(itemComponent);
} else {
if (groupName !== item.group) {
groupName = item.group;
groupedItems.push(/*#__PURE__*/ _jsx("div", {
className: classes.separator,
children: /*#__PURE__*/ _jsx(Divider, {
classNames: {
label: classes.separatorLabel
},
label: groupName
})
}, groupName));
}
groupedItems.push(itemComponent);
}
});
if (groupedItems.length > 0 && unGroupedItems.length > 0) {
unGroupedItems.unshift(/*#__PURE__*/ _jsx("div", {
className: classes.separator,
children: /*#__PURE__*/ _jsx(Divider, {
unstyled: unstyled,
classNames: {
label: classes.separatorLabel
}
})
}, "ungrouped-separator"));
}
return /*#__PURE__*/ _jsx(Box, {
className: clsx(classes.facet, className),
...others,
ref: ref,
children: /*#__PURE__*/ _jsxs(Combobox, {
store: combobox,
onOptionSubmit: handleValueSelect,
children: [
/*#__PURE__*/ _jsx(Combobox.EventsTarget, {
children: /*#__PURE__*/ _jsxs(Box, {
className: classes.facetHeader,
children: [
/*#__PURE__*/ _jsxs(Group, {
wrap: "nowrap",
justify: "space-between",
className: classes.facetTitleRow,
children: [
title ? /*#__PURE__*/ _jsx(Title, {
order: 5,
className: classes.facetTitle,
children: title
}) : null,
removable ? /*#__PURE__*/ _jsx(CloseButton, {
onClick: onRemove,
className: classes.facetRemoveButton,
"aria-label": "remove facet"
}) : null
]
}),
/*#__PURE__*/ _jsx(TextInput, {
unstyled: unstyled,
value: search,
onChange: (event)=>{
handleSearch(event.currentTarget.value);
combobox.updateSelectedOptionIndex();
},
placeholder: searchPlaceholder,
"aria-hidden": hideSearch,
tabIndex: hideSearch ? -1 : undefined,
className: clsx(classes.facetSearch, {
[classes.hiddenSearch]: hideSearch
}),
rightSection: search ? /*#__PURE__*/ _jsx(CloseButton, {
"aria-label": "clear search",
onClick: ()=>{
handleSearch('');
}
}) : /*#__PURE__*/ _jsx(IconSearch, {
height: 16
})
})
]
})
}),
/*#__PURE__*/ _jsx("div", {
className: classes.facetBody,
children: /*#__PURE__*/ _jsx(Combobox.EventsTarget, {
children: /*#__PURE__*/ _jsx(ListComponent, {
className: classes.facetItems,
mah: height,
style: {
overflow: 'auto',
position: 'relative'
},
tabIndex: hideSearch ? 0 : undefined,
children: /*#__PURE__*/ _jsx(Combobox.Options, {
"aria-multiselectable": "true",
children: groupedItems.length > 0 || unGroupedItems.length > 0 ? /*#__PURE__*/ _jsxs(_Fragment, {
children: [
groupedItems,
unGroupedItems
]
}) : /*#__PURE__*/ _jsx(Combobox.Empty, {
children: /*#__PURE__*/ _jsx(Text, {
c: "dimmed",
unstyled: unstyled,
size: "sm",
ta: "center",
my: "sm",
children: !search && placeholder ? placeholder : nothingFound
})
})
})
})
})
})
]
})
});
});
Facet.displayName = 'Facet';
const defaultFilter = (query, item)=>item.label.toLowerCase().trim().includes(query.toLowerCase().trim()) || item.value.toLowerCase().trim().includes(query.toLowerCase().trim());
//# sourceMappingURL=Facet.js.map