Skip to content

Feature: first-class multi-line text props — @multiline sugar + lint unknown @pattern values #221

Description

@drubot

Context

Drupal Canvas decides storability and translatability of a string prop structurally from its JSON schema shape. Multi-line plain text is recognized only as the exact literal shape { "type": "string", "pattern": "(.|\r?\n)*" } (Canvas PropShape::isPlainOrRichProse(), extended for translatability in canvas!1327, shipped in Canvas 1.8+). The pattern is a marker, not validation — it matches everything.

nuxt-component-preview currently passes @pattern through verbatim (detectPatternTag() in generateComponentIndex.ts) and documents it as "JSON Schema regex". That invites a silent failure mode: an author who uses @pattern for actual validation (e.g. ^[a-z-]+$) produces a prop shape Canvas cannot map to any field type — the prop becomes non-storable and non-translatable, with no feedback at authoring time and a hard-to-trace failure at Canvas registration.

Proposal

  1. @multiline JSDoc tag as first-class sugar: emits exactly pattern: (.|\r?\n)* into the component index, so authors never type the magic literal. (Keep @pattern working for the literal for backwards compatibility.)
  2. Lint at index generation: when @pattern carries any value other than the recognized literal, emit a build-time warning (or error behind a strict flag): "pattern X is not a Canvas-storable prop shape — the prop will be neither storable nor translatable; use @Multiline for multi-line text, an enum for constrained values, or runtime validation."
  3. Docs: document the multi-line convention and the storable-shape constraint in the module docs / component-previews guide.

Why here

The authoring chain is JSDoc → nuxt-component-preview → component-index → Canvas discovery; this module is the only place that sees the author's intent early enough to warn before Drupal is involved.


Filed via Claude Code (drunomics session; context: MCD-1149/Canvas 1.9 verification).

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