the description is rich text

It is the one piece of writing about a collection, a piece or a collab — the
paragraph the template draws under the name — so it wants the headings, emphasis,
links and alignment the page's own text blocks have, not a plain textarea.

Prose on the site already renders HTML when it finds any and falls back to
paragraphs when it does not, so everything stored as plain text goes on working
untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-05 14:59:09 +01:00
co-authored by Claude Opus 5
parent 76a749d8f9
commit d6fdf936cf
+14 -3
View File
@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
import { useClient } from 'hooks/useClient';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { RichText } from '../RichText';
import { useAutosave } from '../useAutosave';
import type { SubjectRecord, SubjectSection } from './subjects';
@@ -67,12 +68,22 @@ export const SubjectFields = <T extends SubjectRecord>({
</p>
</div>
{/*
Rich text, not a textarea.
It is the paragraph the template draws under the name — the one piece of writing about this
thing — so it wants the same headings, emphasis, links and alignment the page's own text
blocks have. `Prose` on the site already renders HTML when it finds any and falls back to
paragraphs when it does not, so what is already stored as plain text goes on working.
Sanitised on the way in by the API, against the same allowlist the page components use.
*/}
<div className="space-y-1.5">
<label className="text-xs text-muted-foreground">Description</label>
<Textarea
rows={4}
<RichText
value={value('description')}
onChange={(event) => set('description')(event.target.value)}
onChange={(html) => set('description')(html)}
placeholder="What this is."
/>
</div>