Add column enum filter.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
71b10a3c89
commit
267afa68dd
2 changed files with 83 additions and 1 deletions
69
src/Smartable/Filters/EnumFilter.tsx
Normal file
69
src/Smartable/Filters/EnumFilter.tsx
Normal file
|
@ -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<OptionKey extends keyof any, Option>(options: Record<OptionKey, Option>): ColumnFilter<OptionKey[], EnumFilterState<OptionKey>>
|
||||
{
|
||||
return (
|
||||
{
|
||||
filter: (data: OptionKey|OptionKey[], filterState: EnumFilterState<OptionKey>) => {
|
||||
// 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: <EnumFilterComponent options={options} />
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumeration filter state.
|
||||
*/
|
||||
export interface EnumFilterState<OptionKey extends keyof any>
|
||||
{
|
||||
/**
|
||||
* Filter value.
|
||||
*/
|
||||
value: OptionKey[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum filter component.
|
||||
*/
|
||||
export function EnumFilterComponent<OptionKey extends keyof any, Option>({options}: {
|
||||
/**
|
||||
* Enum options.
|
||||
*/
|
||||
options: Record<OptionKey, Option>;
|
||||
})
|
||||
{
|
||||
// Initialize enum filter state.
|
||||
const [enumFilterState, setEnumFilterState] =
|
||||
useFilterState<EnumFilterState<OptionKey>>({ value: [] });
|
||||
|
||||
// Handle filter input change.
|
||||
const handleChange = useCallback((filter: OptionKey[]) => {
|
||||
// Save the current filter value.
|
||||
setEnumFilterState({
|
||||
value: filter,
|
||||
})
|
||||
}, [setEnumFilterState]);
|
||||
|
||||
return (
|
||||
<Select<OptionKey, Option> options={options} multiple={true} size={1}
|
||||
className={!enumFilterState.value?.length ? "empty" : undefined}
|
||||
value={enumFilterState.value} onChange={handleChange} />
|
||||
)
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue