Changelog
@fn-sphere/filter
1.0.0
Major Changes
-
15f2755
Thanks @lawvs! - ## Migrate to Zod 4- Upgrade all filtering utilities to Zod 4, adopting the new
z.function({ input, output })
factory. - Update tests, docs, and playground examples to reflect the revised function schema API.
- Surface tuple-based parameter metadata so filter UIs can materialise runtime validators without accessing private internals.
- Prepare downstream apps for the breaking changes required when upgrading filter definitions to Zod 4.
Migration guide
- Make sure your project is already on Zod 4 before consuming this release. Review the upstream changes at https://zod.dev/v4/changelog to plan any schema updates.
- Replace every
z.function().args(...).returns(...)
with the new factory signature.
const equals = defineTypedFn({name: "equals",define: z.function().args(z.string(), z.string()).returns(z.boolean()),define: z.function({ input: [z.string(), z.string()], output: z.boolean() }),implement: (value, target) => value === target,});getParametersExceptFirst
now returns a$ZodTuple
rather than a plain array. Usetuple._zod.def.items
when you need to inspect or parse arguments at runtime.DataInputViewProps
/DataInputViewSpec
consume tuple schemas instead of loose arrays:
// Beforetype DataInputViewProps = {rule: SingleFilter;requiredDataSchema: [] | [z.ZodTypeAny, ...z.ZodTypeAny[]];updateInput: (...input: unknown[]) => void;};type DataInputViewSpec = {name: string;match:| []| [z.ZodTypeAny, ...z.ZodTypeAny[]]| ((parameterSchemas: [] | [z.ZodTypeAny, ...z.ZodTypeAny[]],fieldSchema?: z.ZodTypeAny,) => boolean);view: ComponentType<DataInputViewProps>;};// Aftertype DataInputViewProps = {rule: SingleFilter;requiredDataSchema: $ZodTuple;updateInput: (...input: unknown[]) => void;};type DataInputViewSpec = {name: string;match:| []| [$ZodType, ...$ZodType[]]| $ZodTuple| ((parameterSchemas: $ZodTuple, fieldSchema?: $ZodType) => boolean);view: ComponentType<DataInputViewProps>;};- Update all usages of
DataInputViewSpec.match
to handle the new tuple schema.
const literalUnionView: DataInputViewSpec = {name: "literal union",match: (parameterSchemas) => {if (parameterSchemas.length !== 1) {if (parameterSchemas._zod.def.items.length !== 1) {return false;}const [item] = parameterSchemas;const isUnion = item instanceof z.ZodUnion;const theOnlyItem = parameterSchemas._zod.def.items.at(0);const schemaDef = (theOnlyItem as $ZodTypes)._zod.def;const isUnion = schemaDef.type === "union";if (!isUnion) {return false;}return item.options.every((option: unknown) => option instanceof z.ZodLiteral,return schemaDef.options.every((option) => option._zod.def.type === "literal",);},view: function View({ requiredDataSchema, rule, updateInput }) {const { Select } = useView("components");const { getLocaleText } = useRootRule();const options = useMemo(() => {const unionSchema = requiredDataSchema[0] as z.ZodUnion<[z.ZodLiteral<z.Primitive>]>;const unionSchema = requiredDataSchema._zod.def.items[0] as $ZodUnion<$ZodLiteral[]>;return unionSchema.options.map((item: z.ZodLiteral<z.Primitive>) => ({return unionSchema._zod.def.options.map((item) => {const value = item._zod.def.values[0];const meta = z.globalRegistry.get(item);const metaDesc =meta && meta.description ? meta.description : undefined;return {label: getLocaleText(metaDesc ?? String(value)),value,};});}, [getLocaleText, requiredDataSchema]);return (<Selectoptions={options}value={rule.args[0]}onChange={(value) => {updateInput(value);}}/>);},} - Upgrade all filtering utilities to Zod 4, adopting the new
Patch Changes
- Updated dependencies [
15f2755
]:- @fn-sphere/[email protected]
0.8.0
Minor Changes
-
a915a9a
Thanks @lawvs! - feat(filter)!: retain args by default when filter changes via tryRetainArgs- BREAKING: FieldSelect and FilterSelect now default
tryRetainArgs
(andtryRetainFilter
for fields) totrue
. Previously, leaving these props undefined defaulted to resettingargs
. To restore the old behavior, explicitly passtryRetainArgs={false}
(and/ortryRetainFilter={false}
). - When switching filters within the same field, if the new filter’s parameter schema is compatible, existing
args
are preserved. - Data input “literal union” options are memoized for stability.
This change improves UX by avoiding unnecessary argument resets when changing a filter, while still allowing users to opt out.
- BREAKING: FieldSelect and FilterSelect now default
Patch Changes
-
Updated dependencies [
82696fa
]:- @fn-sphere/[email protected]
0.7.2
Patch Changes
- #105
941d4a9
Thanks @Garfield550! - Fix the incorrect version of @types/react in peer dependencies.
0.7.1
Patch Changes
0.7.0
Minor Changes
0.6.0
Minor Changes
-
ef470f1
Thanks @lawvs! - Breaking Changes- Now the first field and the first filter will be selected by default when creating a new rule.
- Updated
useFilterSphere
to usecreateDefaultRule
for default rule creation. - Updated
useFilterGroup
anduseFilterRule
to usecreateDefaultRule
when no input is provided.
- Updated
- Now the first field and the first filter will be selected by default when creating a new rule.
-
62aeaf0
Thanks @lawvs! - ExportfilterableFields
inuseRootRule
hook. RemovefilterableFields
fromuseFilterRule
hook.BREAKING CHANGE: The
filterableFields
is now exported in theuseRootRule
hook instead of theuseFilterRule
hook.Migration:
const { filterableFields } = useRootRule();const { filterableFields } = useFilterRule(rule); -
#51
a8b07f2
Thanks @lawvs! - Add locale supportsBREAKING CHANGE
- All name of filter has been changed.
- The
booleanFilter
has been removed.
-
9badd88
Thanks @lawvs! - Breaking Changes- Renamed
filterGroup
prop torule
in FilterGroupContainer. - Modified
filterTheme
in theme-mui-material to userule
instead offilterGroup
.
- Renamed
Patch Changes
-
5f4d54f
Thanks @lawvs! - RenameupdateRootRule
tosetRootRule
inuseRootRule
hookMigration:
const { updateRootRule } = useRootRule();const { setRootRule } = useRootRule(); -
200e5a1
Thanks @lawvs! - DeprecatedgetRootRule
in favor ofrootRule
inuseRootRule
hook.Migration:
const { rootRule } = useRootRule();const { getRootRule } = useRootRule(); -
479f048
Thanks @lawvs! - Fix logical error intoggleGroupOp
function within theuseFilterGroup
hook -
8337984
Thanks @lawvs! - Support custom style for components -
Updated dependencies [
a8b07f2
,020bdb1
,a8b07f2
,01369a8
]:- @fn-sphere/[email protected]
0.5.0
Minor Changes
-
ab1a0c6: - Deprecated
onPredicateChange
inuseFilterSphere
-
⚠️ BREAKING CHANGES
- The
onRuleChange
callback inuseFilterSphere
now receives an object with bothfilterRule
andpredicate
properties, instead of just thefilterRule
. - The
onPredicateChange
callback has been removed. Use thepredicate
property in theonRuleChange
callback instead.
export interface FilterSphereInput<Data>extends BasicFilterSphereInput<Data> {onRuleChange?: (data: {filterRule: FilterGroup;predicate: (data: Data) => boolean;}) => void;}const { context } = useFilterSphere({schema: YOUR_DATA_SCHEMA,onRuleChange: ({ predicate }) => {const filteredData = YOUR_DATA.filter(predicate);console.log(filteredData);},}); - The
-
Migration Guide
const { context } = useFilterSphere({schema: YOUR_DATA_SCHEMA,onRuleChange: (filterRule) => {console.log(filterRule);},onPredicateChange: (predicate) => {const filteredData = YOUR_DATA.filter(predicate);console.log(filteredData);},onRuleChange: ({ filterRule, predicate }) => {const filteredData = YOUR_DATA.filter(predicate);console.log(filterRule, filteredData);},}); -
-
87acc5e: - BREAKING CHANGES
updateInput
inDataInputViewProps
now use spread parameter to accept new values.
updateInput([newValue]);updateInput(newValue); -
70565bc: - BREAKING CHANGES
- Increased spacing in templates
- Enhanced
SingleFilterContainer
styling:- Improved vertical alignment of child elements
- Remove
isValid
flag fromFilterRule
- Move
Add Condition
andAdd Group
buttons to theFilterGroupContainer
Patch Changes
- 4a6e88a: Support multiple select for literal union
- 03624b8: Add multiple select
- f03f6e2: Remove unnecessary ref prop from data input views
- Updated dependencies [f5eae65]
- Updated dependencies [2b17977]
- @fn-sphere/[email protected]
0.4.0
Minor Changes
-
55b7fb1: - In
useFilterSelect
:- The
updateField
function has been deprecated and replaced withsetField
for clarity and consistency. - The
updateFilter
function has been deprecated and replaced withsetFilter
. - In
useFilterRule
:- The
updateRule
function has been renamed tosetRule
- Added a new
duplicateRule
function to duplicate a rule. - Added a new
invertRule
function.
- The
- In
useFilterGroup
anduseFilterRule
:- The parameter
SingleFilter
has been changed toSingleFilterInput
for simplicity. - The parameter
FilterGroup
has been changed toFilterGroupInput
for simplicity.
- The parameter
- The
-
e05bcbe: Removed inline theme merging logic from
FilterSphereProvider
.Introduced
createFilterTheme
for theme merging.Migration guide:
<FilterSphereProvider theme={customTheme}>const theme = createFilterTheme(customTheme);<FilterSphereProvider theme={theme}>
Patch Changes
-
0ce4129: Add
tryRetainArgs
to allow retainingargs
when filter is changed -
d4c6a7d: - Update
useFilterSphere
hook to usepredicate
instead ofgetPredicate
:import { useFilterSphere } from "@fn-sphere/filter";const { rule, predicate, context } = useFilterSphere({const { rule, getPredicate, context } = useFilterSphere({schema: YOUR_DATA_SCHEMA,});const filteredData = YOUR_DATA.filter(getPredicate());const filteredData = YOUR_DATA.filter(predicate);- Update
countTotalRules()
toget totalRuleCount
inuseFilterSphere
hook - Add
validRuleCount
touseFilterSphere
hook to get the count of valid rules
- Update
-
c5ad41a: Add
countValidRules
function touseFilterSphere
hookconst { countValidRules } = useFilterSphere();const validRulesCount = countValidRules(); -
311f306: - Added the ability to retain the current filter and arguments when the field is changed in the
useFilterSelect
hook.- Introduced the
UpdateFieldOptions
type to specify the behavior when updating the field. - Updated the
FieldSelect
component to pass theupdateFieldOptions
to theupdateField
function.
export type UpdateFieldOptions = {/*** Try to continue using the current filter when the field is changed.** @default true*/tryRetainFilter?: boolean;/*** Automatically select the first filter when the field is changed and the filter is not retained.** @default true*/autoSelectFirstFilter?: boolean;/*** Try to continue using the current args when the field is changed.** @default true*/tryRetainArgs?: boolean;};<FieldSelectrule={rule}tryRetainFilterautoSelectFirstFiltertryRetainArgs/>; - Introduced the
-
Updated dependencies [e0f5632]
-
Updated dependencies [744b13e]
-
Updated dependencies [b042713]
- @fn-sphere/[email protected]
0.3.8
Patch Changes
- 19e8e38: Update preset templates
- @fn-sphere/[email protected]
0.3.7
Patch Changes
- 715e792: Add
getLocaleText
API- @fn-sphere/[email protected]
0.3.6
Patch Changes
-
b272f24: Export
FnSchema
,StandardFnSchema
andGenericFnSchema
type from core package.Export
defineGenericFn
anddefineTypedFn
from core package.- @fn-sphere/[email protected]
0.3.5
Patch Changes
-
98b38de: Add field schema to the match function in the
DataInputViewSpec
. -
75feec4: Update data input view to handle empty values
If input value is empty string, the input view will update the rule args to
[]
instead of[""]
. This is to prevent the rule from running with an empty string as an argument.- @fn-sphere/[email protected]
0.3.4
Patch Changes
- 51abfaa: Export
FilterField
- @fn-sphere/[email protected]
0.3.3
Patch Changes
-
caeeb9c: Move
createFilterGroup
andcreateSingleFilter
to core package.Add
getFilterRule
method tocreateFilterSphere
. -
79abaa0: Update readme
-
Updated dependencies [caeeb9c]
-
Updated dependencies [79abaa0]
- @fn-sphere/[email protected]
0.3.2
Patch Changes
- 2a8d304: Add new
reset
method touseFilterSphere
hook - 3ccf45a: Update styles for default templates
- @fn-sphere/[email protected]
0.3.1
Patch Changes
-
aef8fbc: Fix
numberOfRules
should only count the SingleRule and not the RuleGroup.Return
countTotalRules
function touseFilterSphere
hook.- @fn-sphere/[email protected]
0.3.0
Minor Changes
-
49df2cd: Add new
FilterSphereProvider
component to provide filter context to children components.Add
useFilterSphere
hook to access filter predicate.The
FilterBuilder
component no longer adds a provider to its child components.const { filterRule, schema, predicate } = useFilterSphere<YourData>();const filteredData = data.filter(predicate); -
c66db35: Redesign
useFilterSphere
hook to return agetPredicate
function and acontext
object.import { useFilterSphere } from "@fn-sphere/filter";const { getPredicate, context } = useFilterSphere<YourData>({schema: yourDataSchema,});const predicate = getPredicate();const filteredData = data.filter(predicate);
Patch Changes
-
1c4bfae: Rename
BasicFilterBuilderProps
toBasicFilterSphereInput
and update type definitions.Export new type
BasicFilterSphereProps
.export interface BasicFilterSphereInput<Data = unknown> {filterRule: FilterGroup;schema: ZodType<Data>;filterFnList?: FnSchema[];fieldDeepLimit?: number;mapFieldName?: (field: FilterField) => string;mapFilterName?: (filterSchema: StandardFnSchema,field: FilterField,) => string;onRuleChange?: (rule: FilterGroup) => void;}export type BasicFilterSphereProps<Data = unknown> = Required<BasicFilterSphereInput<Data>>; -
1ac1c43: Rename
createEmptyFilter
tocreateEmptySingleFilter
andcreateEmptyFilterGroup
tocreateFilterGroup
. -
1ac1c43: Add
SingleFilterContainer
to template. -
991d8e7: Export
useRootRule
anduseFilterSelect
hooks. -
b31b201: Rename
filterList
tofilterFnList
-
Updated dependencies [b31b201]
- @fn-sphere/[email protected]
0.2.0
Minor Changes
- 742c3af: Refactor API
Patch Changes
- @fn-sphere/[email protected]
0.1.3
Patch Changes
- 1670687: Export presetFilter
0.1.2
Patch Changes
-
b9d3b0a: chore: add type export for filter specs
-
b9d3b0a: Rename and export
FilterRule
interface SingleFilter {type: "Filter";/*** Field path** If it's a empty array, it means the root object.* If not provided, it means user didn't select a field.*/path?: FilterPath;/*** Filter name** If not provided, it means user didn't select a filter.*/name?: string;/*** Arguments for the filter function*/args: unknown[];invert?: boolean;}interface SingleFilter extends SingleFilterInput {/*** Unique id, used for tracking changes or resorting*/id: FilterId;}export interface FilterGroupInput {type: "FilterGroup";op: "and" | "or";conditions: (SingleFilter | FilterGroup)[];invert?: boolean;}export interface FilterGroup extends FilterGroupInput {/*** Unique id, used for tracking changes or resorting*/id: FilterId;}export type FilterRule = SingleFilter | FilterGroup; -
Updated dependencies [336fe84]
-
Updated dependencies [b9d3b0a]
- @fn-sphere/[email protected]
0.1.1
Patch Changes
- d7460ba: export UiSpec
0.1.0
Minor Changes
- 5c84d94: first publish
Patch Changes
- Updated dependencies [5c84d94]
- @fn-sphere/[email protected]