Skip to content

fix: InlineTextField renders empty for nullish values#1664

Open
shiminshen wants to merge 1 commit into
puckeditor:mainfrom
shiminshen:fix/inline-text-field-nullish-render
Open

fix: InlineTextField renders empty for nullish values#1664
shiminshen wants to merge 1 commit into
puckeditor:mainfrom
shiminshen:fix/inline-text-field-nullish-render

Conversation

@shiminshen
Copy link
Copy Markdown

Closes #1639

Description

InlineTextField was rendering the literal text "null" (or "undefined") in the contentEditable canvas whenever a text or textarea field with contentEditable: true received a nullish value. The cause is Node.replaceChildren(...nodes) coercing each non-Node argument via String(...)String(null) === "null" and String(undefined) === "undefined" — so a defaultProp of subtitle: null, or a server response returning null for an unfilled optional field, persistently surfaced as null text in the editor until the user manually selected-all and deleted.

The richtext field type is unaffected because TipTap handles nullish content; this is specific to InlineTextField only.

Changes made

  • Coerce value ?? "" before calling replaceChildren, in the same effect that syncs the contentEditable span's text.
  • Widen the value prop type from string to string | null | undefined so the type matches what the text / textarea field transforms actually pass in (the data model allows nullish props).
  • Add jest tests covering value={null}, value={undefined}, and value="Hello world".

How to test

Minimal repro from the issue:

const config = {
  components: {
    MyBlock: {
      fields: {
        subtitle: { type: 'textarea', contentEditable: true },
      },
      defaultProps: { subtitle: null },
      render: ({ subtitle }) => <p>{subtitle}</p>,
    },
  },
};

Insert MyBlock in the editor. Before: the canvas shows the text null where the subtitle would be. After: empty, like an empty string.

Or run yarn test --testPathPattern=InlineTextField from packages/core — 3 new tests cover the null / undefined / string cases.

Node.replaceChildren coerces non-Node arguments via String(), so a nullish
value materialised as a literal "null" / "undefined" text node in the
contentEditable canvas. defaultProps with subtitle: null (or server data
returning a null optional field) persistently rendered "null" until the
user manually selected-all and deleted.

Coerce nullish to "" before replaceChildren, and widen the prop type to
string | null | undefined to reflect the runtime reality at the text /
textarea field transform call sites.

Closes puckeditor#1639
@vercel
Copy link
Copy Markdown

vercel Bot commented May 13, 2026

@shiminshen is attempting to deploy a commit to the Puck Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

InlineTextField renders literal "null" when value is null/undefined

1 participant