Skip to content

Commit 578c0c6

Browse files
committed
Extend shadcn/ui Typeset to the live Plate editor
Wrap the editing surface in .typeset (editor content variants) and strip the prose typography from the live *-node.tsx components, mirroring the read-only static nodes, so Typeset owns typography/rhythm/colour in edit mode too. Import typeset.css into the cmsui style bundle and make typeset.css UNLAYERED: the cmsui editor bundles Tailwind preflight (h1-h6 { font-size: inherit }) into the 'cmsui' cascade layer, declared last, which would beat an @layer components variant. Unlayered rules win over every layer, so Typeset applies in both the read-only renderer and the live editor.
1 parent e79b369 commit 578c0c6

11 files changed

Lines changed: 479 additions & 494 deletions

File tree

packages/plate/components/ui/block-list.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,7 @@ function List(props: PlateElementProps) {
4242
const List = isOrderedList(props.element) ? 'ol' : 'ul';
4343

4444
return (
45-
<List
46-
className="relative m-0 p-0"
47-
style={{ listStyleType }}
48-
start={listStart}
49-
>
45+
<List className="relative" style={{ listStyleType }} start={listStart}>
5046
{Marker && <Marker {...props} />}
5147
{Li ? <Li {...props} /> : <li>{props.children}</li>}
5248
</List>

packages/plate/components/ui/blockquote-node.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ import { type PlateElementProps, PlateElement } from 'platejs/react';
22

33
import { BlockInnerContainer } from './block-inner-container';
44

5+
// Blockquote styling (border, padding, colour) is owned by shadcn/ui Typeset.
56
export function BlockquoteElement(props: PlateElementProps) {
67
return (
78
<PlateElement as="blockquote" {...props}>
8-
<BlockInnerContainer className="my-1 border-l-2 pl-6 italic">
9-
{props.children}
10-
</BlockInnerContainer>
9+
<BlockInnerContainer>{props.children}</BlockInnerContainer>
1110
</PlateElement>
1211
);
1312
}

packages/plate/components/ui/code-block-node.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ export function CodeBlockElement(props: PlateElementProps<TCodeBlockElement>) {
3030
return (
3131
<PlateElement
3232
className={`
33-
py-1
3433
**:[.hljs-addition]:bg-[#f0fff4] **:[.hljs-addition]:text-[#22863a]
3534
dark:**:[.hljs-addition]:bg-[#3c5743] dark:**:[.hljs-addition]:text-[#ceead5]
3635
**:[.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable]:text-[#005cc5]
@@ -57,10 +56,12 @@ export function CodeBlockElement(props: PlateElementProps<TCodeBlockElement>) {
5756
{...props}
5857
>
5958
<BlockInnerContainer>
60-
<div className="relative rounded-md bg-muted/50">
59+
{/* The `pre` panel (background, padding, radius, mono font) is owned by
60+
shadcn/ui Typeset. `relative` stays to anchor the edit-mode toolbar;
61+
hljs token colours live on the PlateElement above. */}
62+
<div className="relative">
6163
<pre
6264
className={`
63-
overflow-x-auto p-8 pr-4 font-mono text-sm leading-[normal]
6465
[tab-size:2]
6566
print:break-inside-avoid
6667
`}

packages/plate/components/ui/code-node.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@ import type { PlateLeafProps } from 'platejs/react';
22

33
import { PlateLeaf } from 'platejs/react';
44

5+
// Inline code styling is owned by shadcn/ui Typeset (`.typeset :not(pre) > code`).
56
export function CodeLeaf(props: PlateLeafProps) {
67
return (
7-
<PlateLeaf
8-
{...props}
9-
as="code"
10-
className="rounded-md bg-muted px-[0.3em] py-[0.2em] font-mono text-sm whitespace-pre-wrap"
11-
>
8+
<PlateLeaf {...props} as="code">
129
{props.children}
1310
</PlateLeaf>
1411
);

packages/plate/components/ui/editor.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,18 +106,18 @@ export const editorVariants = cva(
106106
`,
107107
comment: cn('rounded-none border-none bg-transparent text-sm'),
108108
default: `
109-
size-full px-16 pt-4 pb-72 text-base
109+
typeset size-full px-16 pt-4 pb-72 text-base
110110
sm:px-[max(64px,calc(50%-350px))]
111111
`,
112112
demo: `
113-
size-full px-16 pt-4 pb-72 text-base
113+
typeset size-full px-16 pt-4 pb-72 text-base
114114
sm:px-[max(64px,calc(50%-350px))]
115115
`,
116116
fullWidth: `
117-
size-full px-16 pt-4 pb-72 text-base
117+
typeset size-full px-16 pt-4 pb-72 text-base
118118
sm:px-24
119119
`,
120-
block: 'px-6',
120+
block: 'typeset px-6',
121121
none: '',
122122
select: `
123123
px-3 py-2 text-base

packages/plate/components/ui/heading-node.tsx

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,19 @@
11
import type { PlateElementProps } from 'platejs/react';
22

3-
import { type VariantProps, cva } from 'class-variance-authority';
43
import { PlateElement } from 'platejs/react';
54

65
import { BlockInnerContainer } from './block-inner-container';
76

8-
const headingVariants = cva('relative mb-1', {
9-
variants: {
10-
variant: {
11-
h1: 'font-heading mt-[1.6em] pb-1 text-4xl font-bold',
12-
h2: 'font-heading mt-[1.4em] pb-px text-2xl font-semibold tracking-tight',
13-
h3: 'font-heading mt-[1em] pb-px text-xl font-semibold tracking-tight',
14-
h4: 'font-heading mt-[0.75em] text-lg font-semibold tracking-tight',
15-
h5: 'mt-[0.75em] text-lg font-semibold tracking-tight',
16-
h6: 'mt-[0.75em] text-base font-semibold tracking-tight',
17-
},
18-
},
19-
});
7+
type HeadingVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
208

9+
// Heading typography (size, weight, rhythm) is owned by shadcn/ui Typeset —
10+
// see `styles/typeset.css`. The component only selects the semantic tag.
2111
export function HeadingElement({
2212
variant = 'h1',
2313
...props
24-
}: PlateElementProps & VariantProps<typeof headingVariants>) {
14+
}: PlateElementProps & { variant?: HeadingVariant }) {
2515
return (
26-
<PlateElement
27-
as={variant!}
28-
className={headingVariants({ variant })}
29-
{...props}
30-
>
16+
<PlateElement as={variant} {...props}>
3117
<BlockInnerContainer>{props.children}</BlockInnerContainer>
3218
</PlateElement>
3319
);

packages/plate/components/ui/hr-node.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ export function HrElement(props: PlateElementProps) {
1616

1717
return (
1818
<PlateElement {...props}>
19-
<div className="py-6" contentEditable={false}>
19+
<div contentEditable={false}>
20+
{/* Divider visual (border, spacing) is owned by shadcn/ui Typeset;
21+
only the edit-mode selection/cursor affordances remain here. */}
2022
<hr
2123
className={cn(
22-
'h-0.5 rounded-sm border-none bg-muted bg-clip-content',
2324
selected && focused && 'ring-2 ring-ring ring-offset-2',
2425
!readOnly && 'cursor-pointer',
2526
)}

packages/plate/components/ui/link-node.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ export function LinkElement(props: PlateElementProps<TLinkElement>) {
1818
<PlateElement
1919
{...props}
2020
as="span"
21+
// Link appearance (colour, underline) is owned by shadcn/ui Typeset;
22+
// only the suggestion (track-changes) affordances remain here.
2123
className={cn(
22-
'font-medium text-primary underline decoration-primary underline-offset-4',
2324
suggestionData?.type === 'remove' && 'bg-red-100 text-red-700',
2425
suggestionData?.type === 'insert' && 'bg-emerald-100 text-emerald-700',
2526
)}

packages/plate/components/ui/paragraph-node.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import type { PlateElementProps } from 'platejs/react';
33
import { PlateElement } from 'platejs/react';
44

55
import { BlockInnerContainer } from './block-inner-container';
6-
import { cn } from '../../lib/utils';
76

7+
// Prose styling (spacing, colour) is owned by shadcn/ui Typeset — see
8+
// `styles/typeset.css` and the `.typeset` wrapper on the editor surface.
89
export function ParagraphElement(props: PlateElementProps) {
910
return (
10-
<PlateElement {...props} className={cn('m-0 px-0 py-1')}>
11+
<PlateElement {...props}>
1112
<BlockInnerContainer>{props.children}</BlockInnerContainer>
1213
</PlateElement>
1314
);

packages/plate/styles/cmsui.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
/* Do not remove, it's necessary for the registry to detect Tailwind and load
22
the styles for @plone/plate in the cmsui */
33

4+
/* shadcn/ui Typeset — styles the live editor content (the .typeset wrapper on
5+
the editing surface). */
6+
@import './typeset.css';
7+
48
.block-inner-container {
59
display: block;
610
width: 100%;

0 commit comments

Comments
 (0)