fix a few more node

This commit is contained in:
Nate Kelley 2025-07-28 23:23:25 -06:00
parent c5794a2593
commit 9c08da8fad
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
4 changed files with 75 additions and 18 deletions

View File

@ -16,7 +16,7 @@ const editorContainerVariants = cva('relative cursor-text h-full p-4', {
comment: 'bg-background/50'
},
readonly: {
true: 'cursor-not-allowed'
true: 'cursor-text'
}
},
defaultVariants: {

View File

@ -4,8 +4,8 @@ import * as React from 'react';
import { DndPlugin, useDraggable, useDropLine } from '@platejs/dnd';
import { BlockSelectionPlugin } from '@platejs/selection/react';
import { GripDotsVertical } from '@/components/ui/icons';
import { getPluginByType, isType, KEYS, type TElement } from 'platejs';
import { GripDotsVertical, Plus } from '@/components/ui/icons';
import { getPluginByType, isType, KEYS, type SlateRenderNodeProps, type TElement } from 'platejs';
import {
type PlateEditor,
type PlateElementProps,
@ -109,23 +109,27 @@ function Draggable(props: PlateElementProps) {
<div className={cn('slate-blockToolbarWrapper', 'flex h-[1.5em]', isInColumn && 'h-4')}>
<div
className={cn(
'slate-blockToolbar relative w-4.5',
'pointer-events-auto mr-1 flex items-center',
'slate-blockToolbar pointer-events-auto relative mr-1 flex w-12 items-center',
isInColumn && 'mr-1.5'
)}>
<AddNewBlockButton
style={{ top: `${dragButtonTop + 3}px` }}
className="absolute left-0"
/>
<Button
ref={handleRef}
variant="ghost"
className="absolute -left-0 h-6 w-full p-0"
className="absolute right-0"
style={{ top: `${dragButtonTop + 3}px` }}
data-plate-prevent-deselect>
<DragHandle
isDragging={isDragging}
previewRef={previewRef}
resetPreview={resetPreview}
setPreviewTop={setPreviewTop}
/>
</Button>
data-plate-prevent-deselect
prefix={
<DragHandle
isDragging={isDragging}
previewRef={previewRef}
resetPreview={resetPreview}
setPreviewTop={setPreviewTop}
/>
}></Button>
</div>
</div>
</Gutter>
@ -148,6 +152,59 @@ function Draggable(props: PlateElementProps) {
</div>
);
}
function AddNewBlockButton({
style,
className
}: {
style: React.CSSProperties;
className: string;
}) {
const editor = useEditorRef();
const path = usePath();
const handleClick = (event: React.MouseEvent) => {
// build the insertion point based on modifier key
const parentPath = path.slice(0, -1);
const currentIndex = path[path.length - 1];
// Option/Alt key adds before, regular click adds after
const insertIndex = event.altKey ? currentIndex : currentIndex + 1;
editor.tf.insertNodes(
{ type: 'p', children: [{ text: '' }] },
{ at: [...parentPath, insertIndex] }
);
setTimeout(() => {
// Calculate the path to the start of the new paragraph's text
const newNodePath = [...parentPath, insertIndex];
const textPath = [...newNodePath, 0]; // Path to the first text node
// Set the selection to the start of the new paragraph
editor.tf.select({
anchor: { path: textPath, offset: 0 },
focus: { path: textPath, offset: 0 }
});
// Ensure the editor is focused
editor.tf.focus();
}, 25);
};
return (
<Tooltip title="Add new block">
<Button
onClick={handleClick}
variant="ghost"
className={cn(className)}
prefix={<Plus />}
style={style}
/>
</Tooltip>
);
}
function Gutter({ children, className, ...props }: React.ComponentProps<'div'>) {
const editor = useEditorRef();
const element = useElement();

View File

@ -29,7 +29,7 @@ export function CalloutElement({
return (
<PlateElement
className={cn('bg-muted my-1 flex rounded-sm p-4 pl-3', attributes.className)}
className={cn('bg-muted flex rounded-sm p-4 pl-3', attributes.className)}
style={{
...attributes.style,
backgroundColor: props.element.backgroundColor
@ -57,7 +57,7 @@ export function CalloutElement({
}>
<EmojiPicker {...emojiPickerState} {...calloutProps} />
</EmojiPopover>
<div className="w-full">{children}</div>
<div className="mt-1.5 w-full">{children}</div>
</div>
</PlateElement>
);

View File

@ -33,9 +33,9 @@ export function CodeBlockElement(props: PlateElementProps<TCodeBlockElement>) {
return (
<PlateElement
className="py-1 **:[.hljs-addition]:bg-[#f0fff4] **:[.hljs-addition]:text-[#22863a] dark:**:[.hljs-addition]:bg-[#3c5743] dark:**:[.hljs-addition]:text-[#ceead5] **:[.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] dark:**:[.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable]:text-[#6596cf] **:[.hljs-built\\\\_in,.hljs-symbol]:text-[#e36209] dark:**:[.hljs-built\\\\_in,.hljs-symbol]:text-[#c3854e] **:[.hljs-bullet]:text-[#735c0f] **:[.hljs-comment,.hljs-code,.hljs-formula]:text-[#6a737d] dark:**:[.hljs-comment,.hljs-code,.hljs-formula]:text-[#6a737d] **:[.hljs-deletion]:bg-[#ffeef0] **:[.hljs-deletion]:text-[#b31d28] dark:**:[.hljs-deletion]:bg-[#473235] dark:**:[.hljs-deletion]:text-[#e7c7cb] **:[.hljs-emphasis]:italic **:[.hljs-keyword,.hljs-doctag,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language\\\\_]:text-[#d73a49] dark:**:[.hljs-keyword,.hljs-doctag,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language\\\\_]:text-[#ee6960] **:[.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo]:text-[#22863a] dark:**:[.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo]:text-[#36a84f] **:[.hljs-regexp,.hljs-string,.hljs-meta_.hljs-string]:text-[#032f62] dark:**:[.hljs-regexp,.hljs-string,.hljs-meta_.hljs-string]:text-[#3593ff] **:[.hljs-section]:font-bold **:[.hljs-section]:text-[#005cc5] dark:**:[.hljs-section]:text-[#61a5f2] **:[.hljs-strong]:font-bold **:[.hljs-title,.hljs-title.class\\\\_,.hljs-title.class\\\\_.inherited\\\\_\\\\_,.hljs-title.function\\\\_]:text-[#6f42c1] dark:**:[.hljs-title,.hljs-title.class\\\\_,.hljs-title.class\\\\_.inherited\\\\_\\\\_,.hljs-title.function\\\\_]:text-[#a77bfa]"
className="bg-transparent p-1 **:[.hljs-addition]:bg-[#f0fff4] **:[.hljs-addition]:text-[#22863a] dark:**:[.hljs-addition]:bg-[#3c5743] dark:**:[.hljs-addition]:text-[#ceead5] **:[.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] dark:**:[.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable]:text-[#6596cf] **:[.hljs-built\\\\_in,.hljs-symbol]:text-[#e36209] dark:**:[.hljs-built\\\\_in,.hljs-symbol]:text-[#c3854e] **:[.hljs-bullet]:text-[#735c0f] **:[.hljs-comment,.hljs-code,.hljs-formula]:text-[#6a737d] dark:**:[.hljs-comment,.hljs-code,.hljs-formula]:text-[#6a737d] **:[.hljs-deletion]:bg-[#ffeef0] **:[.hljs-deletion]:text-[#b31d28] dark:**:[.hljs-deletion]:bg-[#473235] dark:**:[.hljs-deletion]:text-[#e7c7cb] **:[.hljs-emphasis]:italic **:[.hljs-keyword,.hljs-doctag,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language\\\\_]:text-[#d73a49] dark:**:[.hljs-keyword,.hljs-doctag,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language\\\\_]:text-[#ee6960] **:[.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo]:text-[#22863a] dark:**:[.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo]:text-[#36a84f] **:[.hljs-regexp,.hljs-string,.hljs-meta_.hljs-string]:text-[#032f62] dark:**:[.hljs-regexp,.hljs-string,.hljs-meta_.hljs-string]:text-[#3593ff] **:[.hljs-section]:font-bold **:[.hljs-section]:text-[#005cc5] dark:**:[.hljs-section]:text-[#61a5f2] **:[.hljs-strong]:font-bold **:[.hljs-title,.hljs-title.class\\\\_,.hljs-title.class\\\\_.inherited\\\\_\\\\_,.hljs-title.function\\\\_]:text-[#6f42c1] dark:**:[.hljs-title,.hljs-title.class\\\\_,.hljs-title.class\\\\_.inherited\\\\_\\\\_,.hljs-title.function\\\\_]:text-[#a77bfa]"
{...props}>
<div className="bg-muted/50 relative rounded-md">
<div className="bg-muted/50 relative rounded-md py-1">
<pre className="overflow-x-auto p-8 pr-4 font-mono text-sm leading-[normal] [tab-size:2] print:break-inside-avoid">
<code>{props.children}</code>
</pre>