Skip to content

clientFiltering is declared on DataTableForQuery, DataTableForObservableQuery and DataPage, forwarded by DataPage, and never read by any implementation #159

Description

@woksin

What happens

clientFiltering?: boolean is a declared, public member of three prop types — DataTableForQueryProps,
DataTableForObservableQueryProps and DataPageProps — and DataPage forwards it into whichever table it
mounts. No implementation ever reads it. The identifier does not occur in either table's compiled module,
and DataTableCore — the component both tables actually render — has no clientFiltering member at all, so
there is nowhere for the value to be honored even in principle.

Passing it is silently a no-op. Nothing in a type-check, a lint run or a unit test flags it, because the prop
is genuinely declared.

Evidence

Read from the published package as installed — @cratis/components 3.4.0, primereact 11.1.0.

Every occurrence of the identifier in the whole shipped package:

$ grep -rn "clientFiltering" node_modules/@cratis/components/dist
dist/esm/DataPage/DataPage.d.ts:43:                     clientFiltering?: boolean;
dist/esm/DataTables/DataTableForQuery.d.ts:18:          clientFiltering?: boolean;
dist/esm/DataTables/DataTableForObservableQuery.d.ts:18: clientFiltering?: boolean;
dist/esm/DataPage/DataPage.js:79:  jsx(DataTableForQuery,           { ...context, …, clientFiltering: context.clientFiltering, … })
dist/esm/DataPage/DataPage.js:80:  jsx(DataTableForObservableQuery, { ...context, …, clientFiltering: context.clientFiltering, … })

Three declarations and two forwards. Zero occurrences in DataTableForQuery.js or
DataTableForObservableQuery.js
— the two modules that receive it.

Following the value to its terminus rather than trusting the grep: both tables render DataTableCore, and
DataTableCoreProps (dist/esm/DataTables/DataTableCore.d.ts) declares data, children, dataKey,
emptyMessage, selectionMode, selectionAriaLabel, selection, onSelectionChange, onRowClick,
rowClassName, globalFilterFields, globalSearchPlaceholder, defaultFilters, onFilter, scrollable,
scrollHeight, className, style, pt, ptOptions, unstyled — and no filtering-mode member. The
declared destructuring parameter list on the exported DataTableCore const matches that set exactly, so the
chain ends there.

This is a static read of the shipped artifact, not a browser measurement. It is offered as decisive for the
narrow claim "the prop is never read" — an identifier absent from the compiled implementation cannot be
consulted at runtime — and for nothing wider. What the intended semantic was is not something we can
recover from the outside, which is why the fix below is offered as a choice rather than a specification.

What it costs a consumer

Small, but of the kind that is expensive to diagnose. A representative consumer passed clientFiltering
on an application table and in a component example. Nothing broke — the table rendered and paged correctly —
but the call sites implied that a filtering mode was configured when it was not. That wrong belief can survive
every mechanical gate until someone reads the shipped source.

There is a second-order cost: a dead prop contaminates other investigations. Report
#149 bisected DataPage's defaultFilters behavior and used
a clientFiltering-only configuration as one of its control rows. That row was sound — it simply measured
nothing about filtering, which was not apparent from the public contract.

Suggested fix — the seam

Either direction closes it, and we have no preference between them:

  1. Implement it — have both tables consult clientFiltering and pass a corresponding mode down to
    DataTableCore, which would need a member to receive it; or
  2. Remove it from DataTableForQueryProps, DataTableForObservableQueryProps and DataPageProps. A
    compile error at every call site is strictly better than a silent no-op, and the removal is trivially
    verifiable.

If it is kept as a declared prop, a line of TSDoc saying what mode it selects would prevent the same wrong
belief forming again.

What is explicitly not being asked for

  • Not asking for any particular filtering semantic, or for client-side filtering to exist at all.
  • Not asking for a change to defaultFilters, globalFilterFields, the column filter menus, or anything else
    in the filtering surface — this is only about a prop that is declared and not read.
  • Not claiming this causes the behavior in DataPage renders an empty table when given defaultFilters (any value, including {}) #149. Those are separate findings that happen to touch adjacent
    props.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions