Skip to content

Filters and editable panels

Maintenance mode (deprecated)

@ahoo-wang/fetcher-viewer is deprecated and in maintenance mode: existing functionality is maintained, with no new features. Further data-view development belongs to @ahoo-wang/fetcher-view-engine; use View Engine for new projects. This page remains a maintenance reference for existing consumers. The packages use different models and APIs, so migration requires adaptation.

Viewer filters currently produce legacy Wow Condition objects. They do not emit the new FilterExpression format. A FilterValue wraps {condition}, while a FilterState retains the UI operator and raw value even when that value is not a valid query.

Component / type keyOperators / default
TextFilter / textEQ (default), NE, CONTAINS, STARTS_WITH, ENDS_WITH, IN, NOT_IN.
IdFilter / idID (default), IDS; single/array conversion on operator switch.
NumberFilter / numberEQ (default), NE, GT, LT, GTE, LTE, BETWEEN, IN, NOT_IN; switches scalar/range/tag input.
SelectFilter / selectIN (default), NOT_IN; multiple selection, options in value props.
BoolFilter / boolExtendedOperator.UNDEFINED (default), TRUE, FALSE; no value input.
TypedFilter type datetimeBuilt-in date implementation registered under datetime; use this dispatcher because DateTimeFilter and its converters are not root exports.
AssemblyFilterRequired supportedOperators; optional operator.supportedOperators overrides. Empty list throws; valid supplied defaultValue wins, otherwise first operator.

FilterProps requires field {name,label}; optional operator/value supply UI options/defaultValue, conditionOptions passes legacy query options, ref exposes getValue/getState/reset, onChange receives FilterValue or undefined. useFilterState initializes operator/value and does not make them controlled on every prop change. Its setters convert/validate/parse then notify. ExtendedOperator.UNDEFINED yields no condition. Default validation rejects null/undefined/empty strings/empty arrays, accepts EMPTY_VALUE_OPERATORS without a value, and requires exactly two non-null bounds for BETWEEN. NumberFilter uses its own looser numeric-input validation. isValidValue only rejects null/undefined; it is not a finite-number validator. Supply trust-boundary validation separately.

FilterPanel collects each child ref and combines valid conditions with legacy and(...); no valid children produces all(). Search invokes onSearch(condition, conditionMap, stateMap). Reset resets child values without implicitly searching. Enter searches except during IME composition. resetButton defaults visible; false hides it. EditableFilterPanel adds/removes filter definitions, calls onChange(activeFilters), and synchronizes when the filters prop reference changes. AvailableFilterSelect returns newly selected available filters, excluding already active keys. Modal open/close is parent-owned.

The datetime dispatcher uses milliseconds for ordinary dates, before-today local HH:mm:ss text, and integer days for relative-day operators. A midnight range end is expanded to end of day. Invalid/disabled values are omitted rather than sent as an error condition. FallbackFilter displays an unsupported-type message. None of these components fetch data by themselves. For customization see registries.

Definition, input state and emitted query

ValueConsumer and meaning
AvailableFilter / ActiveFilterA catalog entry versus a chosen instance; the instance key lets panels preserve/remove the correct filter.
field.name / field.labelQuery data path / displayed caption; label is not sent as a query path.
operator.defaultValue / value.defaultValueInitial UI choices, not continuously controlled inputs. Use reset/remount intentionally when changing defaults.
FilterStateRaw operator/value needed to restore editing, even if incomplete.
FilterValue.conditionA valid legacy Condition or no emitted value; downstream data loading consumes this query value.
Panel conditionMap / stateMapPer-filter query / UI snapshots alongside the combined condition. Saving only one can lose the other responsibility.

A panel search produces a query, not filtered rows. The application's onLoadData (or FetcherViewer's loader) applies it. Input validation is UI-oriented; remote field authorization and query admission remain server responsibilities.

Complete example

tsx
import { FilterPanel } from '@ahoo-wang/fetcher-viewer';
import type { ActiveFilter } from '@ahoo-wang/fetcher-viewer';
import { Operator } from '@ahoo-wang/fetcher-wow';
const filters: ActiveFilter[] = [
  {
    key: 'name',
    type: 'text',
    field: { name: 'state.name', label: 'Name' },
    operator: { defaultValue: Operator.CONTAINS },
    value: { defaultValue: 'Ada' },
  },
];
export function SearchPanel() {
  return (
    <FilterPanel
      filters={filters}
      onSearch={condition => console.log(condition)}
    />
  );
}

Public signatures and types

These signatures follow declarations reachable from the current root entry. ? marks optional input; generics/interfaces only constrain compile-time types. Locate inherited and related types through the symbol index. Runtime defaults and failure behavior are described above.

OPERATOR_zh_CN

ts
declare const OPERATOR_zh_CN: SelectOperatorLocale;

packages/viewer/src/filter/operator/locale/operator.zh_CN.ts:16

ExtendedOperator

ts
export enum ExtendedOperator {
  UNDEFINED = 'UNDEFINED',
}

packages/viewer/src/filter/operator/types.ts:16

SelectOperator

ts
export type SelectOperator = ExtendedOperator | Operator;

packages/viewer/src/filter/operator/types.ts:20

SelectOperatorLocale

ts
export type SelectOperatorLocale = {
  [K in Operator]: string;
} & {
  [K in ExtendedOperator]: string;
};

packages/viewer/src/filter/operator/types.ts:22

AvailableFilterSelect

ts
export function AvailableFilterSelect(
  props: AvailableFilterSelectProps,
): import('react').JSX.Element;

packages/viewer/src/filter/panel/AvailableFilterSelect.tsx:57

AvailableFilter

ts
export interface AvailableFilter extends AttributesCapable {
  key: Key;
  field: FilterField;
  component: FilterType;
  value?: FilterValueProps;
  operator?: FilterOperatorProps;
  conditionOptions?: ConditionOptions;
}

packages/viewer/src/filter/panel/AvailableFilterSelect.tsx:31

AvailableFilterGroup

ts
export interface AvailableFilterGroup {
  label: string;
  filters: AvailableFilter[];
}

packages/viewer/src/filter/panel/AvailableFilterSelect.tsx:40

AvailableFilterSelectRef

ts
export interface AvailableFilterSelectRef {
  getValue(): AvailableFilter[];
}

packages/viewer/src/filter/panel/AvailableFilterSelect.tsx:45

AvailableFilterSelectProps

ts
export interface AvailableFilterSelectProps
  extends StyleCapable, RefAttributes<AvailableFilterSelectRef> {
  filters: AvailableFilterGroup[];
  activeFilters?: ActiveFilter[];
}

packages/viewer/src/filter/panel/AvailableFilterSelect.tsx:49

AvailableFilterSelectModal

ts
export function AvailableFilterSelectModal(
  props: AvailableFiltersModalProps,
): React.JSX.Element;

packages/viewer/src/filter/panel/AvailableFilterSelectModal.tsx:29

AvailableFiltersModalProps

ts
export interface AvailableFiltersModalProps extends Omit<ModalProps, 'onOk'> {
  availableFilters: Omit<AvailableFilterSelectProps, 'ref'>;
  onSave?: (filters: AvailableFilter[]) => void;
}

packages/viewer/src/filter/panel/AvailableFilterSelectModal.tsx:24

EditableFilterPanel

ts
export function EditableFilterPanel(
  props: EditableFilterPanelProps,
): React.JSX.Element;

packages/viewer/src/filter/panel/EditableFilterPanel.tsx:35

EditableFilterPanelProps

ts
export interface EditableFilterPanelProps extends Omit<
  FilterPanelProps,
  'actions'
> {
  availableFilters: AvailableFilterGroup[];
  onChange?: (filters: ActiveFilter[]) => void;
}

packages/viewer/src/filter/panel/EditableFilterPanel.tsx:27

FilterPanel

ts
export function FilterPanel(props: FilterPanelProps): React.JSX.Element;

packages/viewer/src/filter/panel/FilterPanel.tsx:92

ActiveFilter

ts
export interface ActiveFilter extends Omit<
  TypedFilterProps,
  'onChange' | 'ref'
> {
  key: Key;
  onRemove?: () => void;
}

packages/viewer/src/filter/panel/FilterPanel.tsx:29

FilterPanelConditionCapableRef

ts
export interface FilterPanelConditionCapableRef {
  getCondition(): Condition | undefined;
}

packages/viewer/src/filter/panel/FilterPanel.tsx:37

FilterPanelRef

ts
export interface FilterPanelRef extends FilterPanelConditionCapableRef {
  search(): void;
  reset(): void;
}

packages/viewer/src/filter/panel/FilterPanel.tsx:47

FilterPanelProps

ts
export interface FilterPanelProps extends RefAttributes<FilterPanelRef> {
  row?: RowProps;
  col?: ColProps;
  actionsCol?: ColProps;
  filters: ActiveFilter[];
  actions?: React.ReactNode;
  onSearch?: (
    finalCondition: Condition,
    activeFilterValues: Map<Key, Condition>,
    filterStates: Map<Key, FilterState>,
  ) => void;
  resetButton?: boolean | Omit<ButtonProps, 'onClick'>;
  searchButton?: Omit<ButtonProps, 'onClick'>;
}

packages/viewer/src/filter/panel/FilterPanel.tsx:61

RemovableTypedFilter

ts
export function RemovableTypedFilter(
  props: RemovableTypedFilterProps,
): React.JSX.Element;

packages/viewer/src/filter/panel/RemovableTypedFilter.tsx:26

RemovableTypedFilterProps

ts
export interface RemovableTypedFilterProps extends TypedFilterProps {
  onRemove?: () => void;
}

packages/viewer/src/filter/panel/RemovableTypedFilter.tsx:22

AssemblyFilter

ts
export function AssemblyFilter(
  options: AssemblyFilterProps,
): import('react').JSX.Element;

packages/viewer/src/filter/AssemblyFilter.tsx:45

ValueInputRender

ts
export type ValueInputRender = (
  filterState: UseFilterStateReturn,
) => ReactNode | null;

packages/viewer/src/filter/AssemblyFilter.tsx:30

AssemblyFilterProps

ts
export interface AssemblyFilterProps<
  ValuePropsType extends FilterValueProps = FilterValueProps,
> extends FilterProps<ValuePropsType> {
  supportedOperators: SelectOperator[];
  onOperatorChangeValueConverter?: OnOperatorChangeValueConverter;
  validate?: ValidateValue;
  conditionValueParser?: ConditionValueParser;
  filterValueConverter?: FilterValueConverter;
  valueInputRender?: ValueInputRender;
}

packages/viewer/src/filter/AssemblyFilter.tsx:34

BoolFilter

ts
export function BoolFilter(props: FilterProps): import('react').JSX.Element;

packages/viewer/src/filter/BoolFilter.tsx:28

ts
BoolFilter;

packages/viewer/src/filter/BoolFilter.tsx:42

BOOL_FILTER

ts
declare const BOOL_FILTER: 'bool';

packages/viewer/src/filter/BoolFilter.tsx:22

FallbackFilter

ts
export function FallbackFilter(options: TypedFilterProps): React.JSX.Element;

packages/viewer/src/filter/FallbackFilter.tsx:20

ts
FallbackFilter;

packages/viewer/src/filter/FallbackFilter.tsx:44

filterRegistry

ts
declare const filterRegistry: TypedComponentRegistry<
  string,
  FilterProps<import('./types').FilterValueProps>
>;

packages/viewer/src/filter/filterRegistry.ts:73

IdFilter

ts
export function IdFilter(props: FilterProps): import('react').JSX.Element;

packages/viewer/src/filter/IdFilter.tsx:48

ts
IdFilter;

packages/viewer/src/filter/IdFilter.tsx:73

ID_FILTER

ts
declare const ID_FILTER: 'id';

packages/viewer/src/filter/IdFilter.tsx:25

IdOnOperatorChangeValueConverter

ts
declare const IdOnOperatorChangeValueConverter: OnOperatorChangeValueConverter;

packages/viewer/src/filter/IdFilter.tsx:27

NumberFilter

ts
export function NumberFilter(props: FilterProps): import('react').JSX.Element;

packages/viewer/src/filter/NumberFilter.tsx:67

ts
NumberFilter;

packages/viewer/src/filter/NumberFilter.tsx:141

NUMBER_FILTER

ts
declare const NUMBER_FILTER: 'number';

packages/viewer/src/filter/NumberFilter.tsx:26

NumberOnOperatorChangeValueConverter

ts
declare const NumberOnOperatorChangeValueConverter: OnOperatorChangeValueConverter;

packages/viewer/src/filter/NumberFilter.tsx:49

SelectFilter

ts
export function SelectFilter(
  props: FilterProps<SelectFilterValueProps>,
): import('react').JSX.Element;

packages/viewer/src/filter/SelectFilter.tsx:48

ts
SelectFilter;

packages/viewer/src/filter/SelectFilter.tsx:69

SELECT_FILTER

ts
declare const SELECT_FILTER: 'select';

packages/viewer/src/filter/SelectFilter.tsx:25

SelectFilterValueProps

ts
export interface SelectFilterValueProps
  extends
    FilterValueProps,
    Omit<
      SelectProps,
      | 'defaultValue'
      | 'mode'
      | 'value'
      | 'allowClear'
      | 'onChange'
      | 'placeholder'
    > {}

packages/viewer/src/filter/SelectFilter.tsx:27

SelectOnOperatorChangeValueConverter

ts
declare const SelectOnOperatorChangeValueConverter: OnOperatorChangeValueConverter;

packages/viewer/src/filter/SelectFilter.tsx:40

TextFilter

ts
export function TextFilter(props: FilterProps): import('react').JSX.Element;

packages/viewer/src/filter/TextFilter.tsx:53

ts
TextFilter;

packages/viewer/src/filter/TextFilter.tsx:97

TEXT_FILTER

ts
declare const TEXT_FILTER: 'text';

packages/viewer/src/filter/TextFilter.tsx:25

TextOnOperatorChangeValueConverter

ts
declare const TextOnOperatorChangeValueConverter: OnOperatorChangeValueConverter;

packages/viewer/src/filter/TextFilter.tsx:27

TypedFilter

ts
export function TypedFilter(
  props: TypedFilterProps,
): React.FunctionComponentElement<TypedFilterProps>;

packages/viewer/src/filter/TypedFilter.tsx:30

ts
TypedFilter;

packages/viewer/src/filter/TypedFilter.tsx:45

FilterType

ts
export type FilterType = string;

packages/viewer/src/filter/TypedFilter.tsx:20

TypedFilterProps

ts
export interface TypedFilterProps
  extends FilterProps, TypeCapable<FilterType> {}

packages/viewer/src/filter/TypedFilter.tsx:22

FilterField

ts
export interface FilterField extends NamedCapable {
  label: string;
  type?: string;
  format?: string;
}

packages/viewer/src/filter/types.ts:28

FilterRef

ts
export interface FilterRef {
  getValue(): FilterValue | undefined;
  getState(): FilterState;
  reset(): void;
}

packages/viewer/src/filter/types.ts:34

FilterState

ts
export interface FilterState {
  operator: SelectOperator;
  value: Optional;
}

packages/viewer/src/filter/types.ts:42

FilterLabelProps

ts
export interface FilterLabelProps extends StyleCapable {}

packages/viewer/src/filter/types.ts:47

FilterOperatorProps

ts
export interface FilterOperatorProps extends Omit<
  SelectProps<SelectOperator>,
  'value' | 'options' | 'mode'
> {
  locale?: SelectOperatorLocale;
  supportedOperators?: SelectOperator[];
}

packages/viewer/src/filter/types.ts:49

FilterValueProps

ts
export interface FilterValueProps extends StyleCapable {
  defaultValue?: any;
  placeholder?: string;
  [key: string]: any;
}

packages/viewer/src/filter/types.ts:57

FilterValue

ts
export interface FilterValue extends ConditionCapable {}

packages/viewer/src/filter/types.ts:64

FilterProps

ts
export interface FilterProps<
  ValuePropsType extends FilterValueProps = FilterValueProps,
>
  extends AttributesCapable, RefAttributes<FilterRef>, StyleCapable {
  field: FilterField;
  label?: FilterLabelProps;
  operator?: FilterOperatorProps | null;
  value?: ValuePropsType | null;
  onChange?: (value?: FilterValue) => void;
  conditionOptions?: ConditionOptions;
}

packages/viewer/src/filter/types.ts:66

FilterComponent

ts
export type FilterComponent = React.FunctionComponent<FilterProps>;

packages/viewer/src/filter/types.ts:78

useFilterState

ts
export function useFilterState(
  options: UseFilterStateOptions,
): UseFilterStateReturn;

packages/viewer/src/filter/useFilterState.ts:101

OnOperatorChangeValueConverter

ts
export type OnOperatorChangeValueConverter = (
  beforeOperator: SelectOperator,
  afterOperator: SelectOperator,
  value: Optional,
) => Optional;

packages/viewer/src/filter/useFilterState.ts:24

OnChange

ts
export type OnChange = (condition: Optional<FilterValue>) => void;

packages/viewer/src/filter/useFilterState.ts:29

ValidateValue

ts
export type ValidateValue = (operator: Operator, value: Optional) => boolean;

packages/viewer/src/filter/useFilterState.ts:30

ConditionValueParser

ts
export type ConditionValueParser = (
  operator: Operator,
  value: Optional,
) => Optional;

packages/viewer/src/filter/useFilterState.ts:31

FilterValueConverter

ts
export type FilterValueConverter = (
  filterValue: FilterValue,
) => Optional<FilterValue>;

packages/viewer/src/filter/useFilterState.ts:35

TrueValidateValue

ts
declare const TrueValidateValue: ValidateValue;

packages/viewer/src/filter/useFilterState.ts:38

UseFilterStateOptions

ts
export interface UseFilterStateOptions extends RefAttributes<FilterRef> {
  field?: string;
  operator: SelectOperator;
  value: Optional;
  conditionOptions?: ConditionOptions;
  onOperatorChangeValueConverter?: OnOperatorChangeValueConverter;
  validate?: ValidateValue;
  conditionValueParser?: ConditionValueParser;
  filterValueConverter?: FilterValueConverter;
  onChange?: OnChange;
}

packages/viewer/src/filter/useFilterState.ts:42

UseFilterStateReturn

ts
export interface UseFilterStateReturn {
  operator: SelectOperator;
  value: Optional;
  setOperator: (operator: SelectOperator) => void;
  setValue: (value: Optional) => void;
  reset: () => void;
}

packages/viewer/src/filter/useFilterState.ts:54

isValidBetweenValue

ts
export function isValidBetweenValue(value: any): boolean;

packages/viewer/src/filter/utils.ts:29

isValidValue

ts
export function isValidValue(value: any): boolean;

packages/viewer/src/filter/utils.ts:57

currentTimeZone

ts
export function currentTimeZone(): string;

packages/viewer/src/filter/utils.ts:78

Models and state ownership · View and Viewer composition · Saved-view panels and persistence callbacks · FetcherViewer remote integration · Tables, columns and cells · Registries, inputs and fullscreen button · Toolbar, refresh and locale

Released under the Apache License 2.0.