diff --git a/src/Smartable/Filters/EnumFilter.tsx b/src/Smartable/Filters/EnumFilter.tsx new file mode 100644 index 0000000..d875272 --- /dev/null +++ b/src/Smartable/Filters/EnumFilter.tsx @@ -0,0 +1,69 @@ +import React, {useCallback} from "react"; +import {ColumnFilter, useFilterState} from "../Columns/ColumnFilter"; +import {Select} from "@kernelui/core"; + +/** + * String column filter. + */ +export function EnumFilter(options: Record): ColumnFilter> +{ + return ( + { + filter: (data: OptionKey|OptionKey[], filterState: EnumFilterState) => { + // Normalized data array. + const dataArray = Array.isArray(data) ? data : [data]; + + // Nothing in filter value, allow everything. + if (!filterState?.value?.length) return true; + + // Get current filter result. + return filterState?.value?.some( + // Keep the row if any element in data match the current filter value. + (optionKey) => dataArray.includes(optionKey) + ); + }, + + element: + } + ); +} + +/** + * Enumeration filter state. + */ +export interface EnumFilterState +{ + /** + * Filter value. + */ + value: OptionKey[]; +} + +/** + * Enum filter component. + */ +export function EnumFilterComponent({options}: { + /** + * Enum options. + */ + options: Record; +}) +{ + // Initialize enum filter state. + const [enumFilterState, setEnumFilterState] = + useFilterState>({ value: [] }); + + // Handle filter input change. + const handleChange = useCallback((filter: OptionKey[]) => { + // Save the current filter value. + setEnumFilterState({ + value: filter, + }) + }, [setEnumFilterState]); + + return ( + options={options} multiple={true} size={1} + className={!enumFilterState.value?.length ? "empty" : undefined} + value={enumFilterState.value} onChange={handleChange} /> + ) +} diff --git a/src/styles/_filters.less b/src/styles/_filters.less index 7372b72..b5adbee 100644 --- a/src/styles/_filters.less +++ b/src/styles/_filters.less @@ -9,9 +9,22 @@ tr.filters padding-left: 0.25em; } - input + input, .select { + margin: 0; width: 100%; } + + .select + { + ul.selected + { + margin: 0 0 0.25em 0; + } + &.empty ul.selected + { + margin: 0; + } + } } }