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.
| Component | Required 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. |
| ViewRef | clearSelectedRowKeys, updateTableSize, reset, getCondition; ref is a React 19 prop. |
| ViewerRef | clearSelectedRowKeys, 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 / action | View | Viewer |
|---|---|---|
dataSource | Required {list,total} is already the desired page | Same; loading is an optional presentation input |
pagination | Required false or options; total comes from dataSource | Same; the component owns onChange/onShowSizeChange wiring |
| Initial arrangement | Required defaultColumns/defaultPageSize/defaultTableSize, plus optional default state | Required defaultViews/defaultView and definition; these initialize local state |
| Filter controls | Required showFilter/filterMode; editable mode allows adding/removing filters | Active-view state supplies the filter panel and visibility |
| Controlled dimension | Pair an external* value and matching externalUpdate* callback | Use View directly for this level of external state control |
| Load rows | onChange(condition,index,size,sorter?) | onLoadData with the same arguments |
| Ref read | getCondition() reads filter-panel condition | Adds getActiveView(), undefined when no saved views remain |
| Ref mutation | clearSelectedRowKeys, updateTableSize, reset | clearSelectedRowKeys; 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
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
export function View<RecordType>(
options: ViewProps<RecordType>,
): React.JSX.Element;packages/viewer/src/view/View.tsx:212
ViewRef
export interface ViewRef extends ViewTableRef, FilterPanelConditionCapableRef {
updateTableSize: (size: SizeType) => void;
reset: () => void;
}packages/viewer/src/view/View.tsx:47
FilterMode
export type FilterMode = 'none' | 'normal' | 'editable';packages/viewer/src/view/View.tsx:66
ViewProps
Expand all fields and members
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
export function Viewer<RecordType = any>(
options: ViewerProps<RecordType>,
): React.JSX.Element;packages/viewer/src/viewer/Viewer.tsx:74
ViewerRef
export interface ViewerRef extends FilterPanelConditionCapableRef {
clearSelectedRowKeys: () => void;
getActiveView: () => ViewState | undefined;
}packages/viewer/src/viewer/Viewer.tsx:36
ViewerProps
Expand all fields and members
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
Related topics
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
