Homepage teaser: rich text editor #51

Merged
whitlocktech merged 1 commits from feature/homepage-teaser-rte into main 2026-07-11 16:09:53 +00:00
Member

Closes #48.

The homepage teaser under Settings was a plain textarea. This gives it the shared rich-text editor and renders the teaser as sanitized HTML on the portal.

Changes

  • SettingsAdmin — the homepage_teaser field now uses the shared RichTextEditor (lazy-loaded so TipTap stays code-split, matching PostEditor). Rich fields render in a <div> wrapper rather than a <label> so the editor's toolbar buttons / contenteditable aren't nested inside a label.
  • HeroElement — text-block lines flagged html render sanitized HTML (DOMPurify) instead of plain text; others are unchanged.
  • heroLayout — the default-layout teaser line is now an HTML line (tag: 'div', html: true). The teaser only appears in the portal's fallback hero (shown when no custom hero layout is published).
  • admin.controllerhomepage_teaser is sanitized against the same allowlist as post/wiki bodies (cleanBody) on save; the client re-sanitizes on render as defense in depth.
  • theme.css.hero-rich collapses the editor's outer block margins so hero spacing stays driven by the line's own marginTop.

Verification

  • client production build succeeds; RichTextEditor splits back into its own chunk (main bundle no longer bloated).
  • server test suite: 142/142 pass.
  • Existing plain-text teaser values render unchanged through the HTML path.

🤖 Generated with Claude Code

Closes #48. The homepage teaser under Settings was a plain textarea. This gives it the shared rich-text editor and renders the teaser as sanitized HTML on the portal. ## Changes - **SettingsAdmin** — the `homepage_teaser` field now uses the shared `RichTextEditor` (lazy-loaded so TipTap stays code-split, matching `PostEditor`). Rich fields render in a `<div>` wrapper rather than a `<label>` so the editor's toolbar buttons / contenteditable aren't nested inside a label. - **HeroElement** — text-block lines flagged `html` render sanitized HTML (`DOMPurify`) instead of plain text; others are unchanged. - **heroLayout** — the default-layout teaser line is now an HTML line (`tag: 'div'`, `html: true`). The teaser only appears in the portal's fallback hero (shown when no custom hero layout is published). - **admin.controller** — `homepage_teaser` is sanitized against the same allowlist as post/wiki bodies (`cleanBody`) on save; the client re-sanitizes on render as defense in depth. - **theme.css** — `.hero-rich` collapses the editor's outer block margins so hero spacing stays driven by the line's own `marginTop`. ## Verification - `client` production build succeeds; `RichTextEditor` splits back into its own chunk (main bundle no longer bloated). - `server` test suite: 142/142 pass. - Existing plain-text teaser values render unchanged through the HTML path. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
wtclaude added 1 commit 2026-07-11 16:07:31 +00:00
Replace the plain textarea for the homepage_teaser setting with the shared
TipTap rich-text editor, and render the teaser as sanitized HTML in the
portal hero's default layout.

- SettingsAdmin: teaser field now uses RichTextEditor (lazy-loaded, code-split
  like PostEditor); rich fields render in a <div> wrapper instead of <label>.
- HeroElement: text-block lines flagged `html` render sanitized HTML.
- heroLayout: the default-layout teaser line is now an HTML line.
- admin.controller: sanitize homepage_teaser against the body allowlist on save.
- theme.css: collapse the teaser's nested block margins in the hero.

Closes #48

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
whitlocktech approved these changes 2026-07-11 16:09:44 +00:00
whitlocktech merged commit 350433635b into main 2026-07-11 16:09:53 +00:00
whitlocktech deleted branch feature/homepage-teaser-rte 2026-07-11 16:09:54 +00:00
Sign in to join this conversation.
No description provided.