Skip to content

DatePickerInput's pt type declares a pcInputText slot the runtime never emits, so the attributes are dropped and tsc stays green #150

Description

@woksin

What happens

@cratis/components' DatePickerInput types its pass-through prop as pt?: DatePickerRootProps['pt']
(dist/esm/Common/DatePickerInput.d.ts), re-exporting PrimeReact's DatePickerRootPassThrough wholesale. That
type declares a slot the runtime never emits:

// @primereact/types/primitive/datepicker/DatePickerRoot.types.d.ts:29
/**
 * Used to pass attributes to the input's DOM element.
 */
pcInputText?: DatePickerRootPassThroughType<React.HTMLAttributes<HTMLInputElement>>;

Nothing is emitted under that key at runtime; the input element carries data-part="input". A consumer writing
pt={{ pcInputText: { id, 'aria-label': …, disabled } }} therefore compiles, renders, and drops every one of
those attributes with no warning.

The root cause is in @primereact/types, not in this package — we are filing it here because
DatePickerInput is the surface a Components consumer writes against, and because the mapping between "what
this wrapper composes" and "which pt keys therefore exist" is only knowable by reading the wrapper's source.

Evidence

@cratis/components 3.4.0, primereact 11.1.0, @primereact/types as shipped with it.

We shipped exactly this mistake during our PrimeReact 11 migration. The rendered element:

<input data-scope="datepicker" data-part="input" class="p-inputtext p-component p-datepicker-input">

with aria-label null. The sibling data-part="trigger" element — written through the correctly-named
trigger key in the same pt object — had its label. Switching the key from pcInputText to input fixed it.

It fails silently and type-checks clean, which is the worst combination: no error, no warning, no console
output, and a green tsc.

DatePickerInput composes DatePicker.Input as={InputText} (dist/esm/Common/DatePickerInput.js), which is
what makes input the real key.

What it costs a consumer

When it bites, the date field loses its accessible name, its id (so an external <label for> cannot
associate), its aria-describedby, and its disabled state. It is an accessibility and a functional
regression, delivered by a type that says it is fine.

Suggested fix — the seam

Either of these closes it:

  • Narrow or redeclare the pt type on DatePickerInput to the slots this wrapper's composition actually
    emits, so pcInputText stops type-checking and input is discoverable from the type.
  • Or escalate to PrimeTek to emit the pcInputText slot, or rename the declared key to input.

A type that names a non-existent slot is worse than no type. This is the concrete, per-component case of the
verification surface asked for in #122 — a consumer cannot tell a live slot from a dead one without reading
the wrapper's source.

What is explicitly not being asked for

Not asking Components to fork or vendor PrimeReact's pass-through types, and not asking for a Components-owned
pt dialect. Naming the emitted slots for the components Components itself composes would be enough.

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