Skip to content

View and Viewer composition

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.

Choose View for a filter/table/pagination surface with supplied rows. Choose Viewer to add saved-view selection and a top toolbar. Choose FetcherViewer only when the service implements the package's remote definition/view endpoints.

ComponentRequired props / ownership
View<RecordType>fields, availableFilters, dataSource {total,list}, showFilter, filterMode, defaultColumns, defaultPageSize, defaultTableSize, pagination and enableRowSelection.
Viewer<RecordType>defaultViews/defaultView, definition, dataSource and pagination; row selection defaults true. It manages editable active-view state.
ViewRefclearSelectedRowKeys, updateTableSize, reset, getCondition; ref is a React 19 prop.
ViewerRefclearSelectedRowKeys, getActiveView, getCondition.

View's filterMode is none/normal/editable. showFilter controls visibility, while filterMode chooses whether a panel exists. pagination false hides pagination; it does not truncate dataSource. Normal page controls use the dataSource total and call the state change callback. onChange(condition,index,size,sorter?) / Viewer onLoadData delegate actual fetching to you. Filters and sorter changes reset page to 1; table selection updates onSelectedDataChange and count. External state props and callbacks must be paired as described in state ownership.

Viewer receives onCreateView, onUpdateView, onDeleteView with optional success callbacks. It forwards actions to the application and only updates its local collection through those completion callbacks; it has no built-in local-storage persistence for view definitions. onSwitchView reports selected saved state. DataMonitor configuration uses definition.countUrl and current condition; the monitoring service has its own polling lifecycle. Wrap context-dependent toolbar fullscreen actions in React FullscreenProvider; the exported Fullscreen component is a standalone button, not a provider.

A reset restores view defaults, remounts filters/table and clears selected rows. Merely replacing dataSource does not automatically clear selection; call the ref when your refresh requires it. Fields' render callbacks and application callbacks may throw; this component is not an error boundary. Browser-dependent toolbar features require window/document. The example renders supplied local data only; it makes no service request.

Props and ref responsibilities

Input / actionViewViewer
dataSourceRequired {list,total} is already the desired pageSame; loading is an optional presentation input
paginationRequired false or options; total comes from dataSourceSame; the component owns onChange/onShowSizeChange wiring
Initial arrangementRequired defaultColumns/defaultPageSize/defaultTableSize, plus optional default stateRequired defaultViews/defaultView and definition; these initialize local state
Filter controlsRequired showFilter/filterMode; editable mode allows adding/removing filtersActive-view state supplies the filter panel and visibility
Controlled dimensionPair an external* value and matching externalUpdate* callbackUse View directly for this level of external state control
Load rowsonChange(condition,index,size,sorter?)onLoadData with the same arguments
Ref readgetCondition() reads filter-panel conditionAdds getActiveView(), undefined when no saved views remain
Ref mutationclearSelectedRowKeys, updateTableSize, resetclearSelectedRowKeys; data reload/persistence remain callbacks

Pass ref as a React 19 prop. Read refs after mount and tolerate undefined conditions before a filter panel exists. Clearing selected keys does not issue a query. Reset restores defaults and requests the corresponding data through the change callback; it is not a backend rollback. A controlled value without its update callback can appear frozen because mutations then write unused internal state.

Complete example

tsx
import { View } from '@ahoo-wang/fetcher-viewer';
import type { FieldDefinition, ViewColumn } from '@ahoo-wang/fetcher-viewer';
interface User {
  id: string;
  name: string;
}
const fields: FieldDefinition[] = [
  { name: 'id', label: 'ID', type: 'text', primaryKey: true },
  { name: 'name', label: 'Name', type: 'text', primaryKey: false },
];
const columns: ViewColumn[] = fields.map(field => ({
  name: field.name,
  key: field.name,
  fixed: false,
  hidden: false,
}));
export function Users() {
  return (
    <View<User>
      fields={fields}
      availableFilters={[]}
      dataSource={{ list: [{ id: '1', name: 'Ada' }], total: 1 }}
      showFilter={false}
      filterMode="none"
      defaultColumns={columns}
      defaultPageSize={10}
      defaultTableSize="middle"
      pagination={false}
      enableRowSelection={false}
    />
  );
}

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.

View

ts
export function View<RecordType>(
  options: ViewProps<RecordType>,
): React.JSX.Element;

packages/viewer/src/view/View.tsx:212

ViewRef

ts
export interface ViewRef extends ViewTableRef, FilterPanelConditionCapableRef {
  updateTableSize: (size: SizeType) => void;
  reset: () => void;
}

packages/viewer/src/view/View.tsx:47

FilterMode

ts
export type FilterMode = 'none' | 'normal' | 'editable';

packages/viewer/src/view/View.tsx:66

ViewProps

Expand all fields and members
ts
export interface ViewProps<RecordType>
  extends
    PrimaryKeyClickHandlerCapable<RecordType>,
    ViewTableSettingCapable,
    RefAttributes<ViewRef> {
  fields: FieldDefinition[];
  availableFilters: AvailableFilterGroup[];
  dataSource: PagedList<RecordType>;
  showFilter: boolean;
  filterMode: FilterMode;
  defaultActiveFilters?: ActiveFilter[];
  externalActiveFilters?: ActiveFilter[];
  externalUpdateActiveFilters?: (filters: ActiveFilter[]) => void;
  defaultColumns: ViewColumn[];
  externalColumns?: ViewColumn[];
  externalUpdateColumns?: (columns: ViewColumn[]) => void;
  defaultPage?: number;
  externalPage?: number;
  externalUpdatePage?: (page: number) => void;
  defaultPageSize: number;
  externalPageSize?: number;
  externalUpdatePageSize?: (pageSize: number) => void;
  defaultTableSize: SizeType;
  externalTableSize?: SizeType;
  externalUpdateTableSize?: (size: SizeType) => void;
  defaultSorter?: FieldSort[];
  externalSorter?: FieldSort[];
  externalUpdateSorter?: (sorter: FieldSort[]) => void;
  defaultCondition?: Condition;
  externalCondition?: Condition;
  externalUpdateCondition?: (
    finalCondition: Condition,
    activeFilterValues: Map<Key, Condition>,
    filterStates: Map<Key, FilterState>,
    resetFilters?: ActiveFilter[],
  ) => void;
  actionColumn?: ViewTableActionColumn<RecordType>;
  pagination:
    false | Omit<PaginationProps, 'onChange' | 'onShowSizeChange' | 'total'>;
  enableRowSelection: boolean;
  loading?: boolean;
  onChange?: ViewChangeAction;
  onSelectedDataChange?: (data: RecordType[]) => void;
}

packages/viewer/src/view/View.tsx:106

Viewer

ts
export function Viewer<RecordType = any>(
  options: ViewerProps<RecordType>,
): React.JSX.Element;

packages/viewer/src/viewer/Viewer.tsx:74

ViewerRef

ts
export interface ViewerRef extends FilterPanelConditionCapableRef {
  clearSelectedRowKeys: () => void;
  getActiveView: () => ViewState | undefined;
}

packages/viewer/src/viewer/Viewer.tsx:36

ViewerProps

Expand all fields and members
ts
export interface ViewerProps<RecordType>
  extends
    ViewTableSettingCapable,
    GetRecordCountActionCapable,
    ViewMutationActionsCapable,
    RefAttributes<ViewerRef>,
    TopbarActionsCapable<RecordType> {
  defaultViews: ViewState[];
  defaultView: ViewState;
  definition: ViewDefinition;
  dataSource: PagedList<RecordType>;
  pagination:
    false | Omit<PaginationProps, 'onChange' | 'onShowSizeChange' | 'total'>;
  actionColumn?: ViewTableActionColumn<RecordType>;
  onClickPrimaryKey?: (id: any, record: RecordType) => void;
  enableRowSelection?: boolean;
  loading?: boolean;
  onLoadData?: ViewChangeAction;
  onSwitchView?: (view: ViewState) => void;
  fullscreenTarget?: React.RefObject<HTMLElement | null>;
}

packages/viewer/src/viewer/Viewer.tsx:41

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

Released under the Apache License 2.0.