UNPKG

@furystack/shades-common-components

Version:

Common UI components for FuryStack Shades

67 lines 3.39 kB
import { createComponent, Shade } from '@furystack/shades'; import { Button } from '../../button.js'; import { SegmentedControl } from '../../button-group.js'; import { Icon } from '../../icons/icon.js'; import { close as closeIcon, search as searchIcon } from '../../icons/icon-definitions.js'; import { cssVariableTheme } from '../../../services/css-variable-theme.js'; import { filterBaseCss, filterInputCss } from './filter-styles.js'; const operatorLabels = { $eq: '=', $gt: '>', $gte: '>=', $lt: '<', $lte: '<=', }; export const NumberFilter = Shade({ customElementName: 'data-grid-number-filter', css: { ...filterBaseCss, fontFamily: cssVariableTheme.typography.fontFamily, '& input': filterInputCss, }, render: ({ props, useState }) => { const { findOptions } = props; const currentFilter = findOptions.filter?.[props.field]; const currentOperator = currentFilter ? (Object.keys(currentFilter).find((k) => k in operatorLabels) ?? '$eq') : '$eq'; const currentValue = currentFilter?.[currentOperator]; const applyFilter = (operator, value) => { const num = parseFloat(value); const filter = { ...findOptions.filter }; if (isNaN(num)) { delete filter[props.field]; } else { filter[props.field] = { [operator]: num }; } props.onFindOptionsChange({ ...findOptions, filter, skip: 0 }); props.onClose(); }; const clearFilter = () => { const filter = { ...findOptions.filter }; delete filter[props.field]; props.onFindOptionsChange({ ...findOptions, filter, skip: 0 }); props.onClose(); }; const [selectedOperator, setSelectedOperator] = useState('selectedOperator', currentOperator); let inputValue = currentValue !== undefined ? currentValue.toString() : ''; return (createComponent("form", { onsubmit: (ev) => { ev.preventDefault(); applyFilter(selectedOperator, inputValue); } }, createComponent("div", { className: "filter-row" }, createComponent(SegmentedControl, { size: "small", value: selectedOperator, onValueChange: (v) => setSelectedOperator(v), options: Object.keys(operatorLabels).map((op) => ({ value: op, label: operatorLabels[op], })) })), createComponent("div", { className: "filter-row" }, createComponent("input", { "data-testid": "number-filter-value", type: "number", step: "any", placeholder: "Value...", value: inputValue, autofocus: true, oninput: (ev) => { inputValue = ev.target.value; } })), createComponent("div", { className: "filter-actions" }, createComponent(Button, { type: "button", variant: "outlined", size: "small", onclick: clearFilter, startIcon: createComponent(Icon, { icon: closeIcon, size: 14 }) }, "Clear"), createComponent(Button, { type: "submit", variant: "outlined", size: "small", color: "primary", startIcon: createComponent(Icon, { icon: searchIcon, size: 14 }) }, "Apply")))); }, }); //# sourceMappingURL=number-filter.js.map