Skip to content

Reuse a shared BlockProps record instead of inlining the full Block CSS surface (~95 fields) per component #82

Description

@jagguji

Summary

When a component's props extend the Block primitive (Omit<BlockProps, 'children'>), bindgen inlines the entire BlockProps CSS surface (~95 fields) into the generated record, and repeats it for every such component. This is faithful but very verbose and duplicative — it would be much cleaner to reuse a single shared blockProps record (the same way bindgen already reuses JsxDOM.domProps for HTML attributes).

Observed with @juspay/blend-design-system@0.0.37-beta.5 / @juspay/rescript-bindgen@1.2.4.

Example

Tags/types.d.ts:

export type TagProps = Omit<BlockProps, 'children'> & {
    text: string;
    variant?: TagVariant;
    color?: TagColor;
    leftSlot?: ReactNode;
    rightSlot?: ReactNode;
    ...
};

BlockProps (Primitives/Block/Block.d.ts) is a large CSS record — color, position, inset, top/right/bottom/left, zIndex, opacity, padding(+Top/Bottom/Left/Right/X/Y), margin(+...), display, flex*(×8), gap(+row/column), borderRadius(×5), _hover/_focus/_active/... etc.

Generated tagsPrimaryTagConfig ends up with 95 fields, the vast majority of which are the inlined Block CSS surface. The same surface is duplicated across ~14 generated component records here (Tag, and other Block-extending components).

Impact

  • Generated *Types.res records are bloated and noisy; the component-specific fields (text, color, …) are buried among dozens of CSS props.
  • Heavy duplication across every Block-extending component.
  • Harder to read/diff the generated output.

Suggestion

Emit a single shared record (e.g. CommonTypes.blockProps or Primitives.blockProps) for Omit<BlockProps, 'children'> and reference/spread it in each consumer, instead of inlining the full field list per component — analogous to how JsxDOM.domProps is already reused for HTML attribute spreads.

Priority

Low — this is an ergonomics / DRY improvement, not a correctness bug. (The fields themselves are correct; a Tag does accept all Block styling 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