Skip to content

The richtext type is spelled three ways across four layout/column sets, and the spec spells it none of them #4250

Description

@yinlianghui

Found during the spelling-sensitivity sweep for #4219 (the autonumber / auto_number gap in TEXTUAL_REF_FALLBACK_TYPES); filed unassigned per Prime Directive #10. Same defect shape, different type family — reported rather than fixed inside #4219 because it spans three packages and carries an adjacent design call.

The spelling

@objectstack/spec's FieldType enum spells it richtext — one word, no separator. The alias table agrees and knows no other spelling:

packages/fields/src/field-type-alias.ts:72
  richtext: 'field:richtext', // WYSIWYG rich-text editor

There is no rich_text and no rich-text anywhere in the alias table or the spec enum, so neither is a spelling any producer emits.

The sets that miss it

Each of these is matched by RAW spelling, so a member nothing emits is a dead entry AND a missing live one — the set silently does nothing for the type it names:

where member effect on a spec-spelled richtext field
packages/plugin-detail/src/RelatedList.tsx:979SKIP_TYPES rich_text not skipped: the field is auto-derived into a related-list column, so raw markup renders in a table cell. The set's own comment says "Only types with no useful tabular rendering stay excluded"
packages/plugin-detail/src/autoLayout.ts:38WIDE_FIELD_TYPES rich-text, field:rich-text never spans full width in a multi-column detail section, unlike markdown / html beside it
packages/plugin-form/src/autoLayout.ts:45WIDE_FIELD_TYPES rich-text same, on the form
packages/app-shell/src/views/RecordDetailView.tsx:136SECONDARY_FIELD_TYPES rich-text not treated as a secondary field

The convention that already exists, one file away from two of them, is to carry every spelling:

packages/plugin-form/src/deriveMasterDetail.ts:339
  'textarea', 'richtext', 'html', 'markdown', 'rich-text',

Why the pin does not catch it

packages/plugin-form/src/__tests__/autoLayout.test.ts:30
  expect(isWideFieldType('rich-text')).toBe(true);

That assertion is green because the set contains the string it asks about — not because any field ever reaches it with that type. It is the shape #4219's sweep was looking for: a pin whose fixture spells something the schema never emits, so it keeps passing while the rule is dead for every real field.

Design call attached (why this is not a one-word patch)

Two decisions belong to whoever picks this up, and both change the diff:

  1. Does markdown belong in RelatedList's SKIP_TYPES? It is absent entirely, and the stated rationale ("no useful tabular rendering") applies to it exactly as it does to html. Adding richtext without deciding this leaves the same class of gap one type over.
  2. Drop the dead spellings or keep them? deriveMasterDetail keeps both, which is defensive and honest about legacy metadata; the alternative is to spell only what the spec spells and let the alias table be the single place aliases live. Whichever is chosen should be applied to all four sets at once — fixing only the two in plugin-detail would make the detail page and the form disagree about the same field, which is worse than a uniform gap.

Acceptance criteria

  • A field typed richtext (the spec spelling) is excluded from auto-derived related-list columns, spans full width in both autoLayout implementations, and is treated as secondary in RecordDetailView.
  • Each fix carries a pin that fails when the spelling is removed — asserted through the behavior (a rendered column set / a resolved span), not only through isWideFieldType('...') on a string the set already holds.
  • The markdown question above is answered explicitly, in the code or in the PR body.

Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions