caption update

This commit is contained in:
Nate Kelley 2025-09-09 22:39:41 -06:00 committed by Wells Bunker
parent 598f74fa2b
commit 2c39af58ad
No known key found for this signature in database
GPG Key ID: DB16D6F2679B78FC
4 changed files with 51 additions and 15 deletions

View File

@ -322,11 +322,16 @@ export const NodeTypeLabels = {
keyboard: undefined,
keywords: [],
},
caption: {
addCaption: {
label: 'Add caption',
keyboard: undefined,
keywords: [],
},
removeCaption: {
label: 'Remove caption',
keyboard: undefined,
keywords: [],
},
pasteEmbedLink: {
label: 'Paste the embed link...',
keyboard: undefined,

View File

@ -1,18 +1,18 @@
import {
CaptionPlugin,
Caption as CaptionPrimitive,
CaptionTextarea as CaptionTextareaPrimitive,
useCaptionButton,
useCaptionButtonState,
} from '@platejs/caption/react';
import { createPrimitiveComponent } from '@udecode/cn';
import type { VariantProps } from 'class-variance-authority';
import { cva } from 'class-variance-authority';
import type { Editor, TElement } from 'platejs';
import type * as React from 'react';
import { Button } from '@/components/ui/buttons';
import { cn } from '@/lib/utils';
import { NodeTypeLabels } from '../config/labels';
const captionVariants = cva('max-w-full', {
const captionVariants = cva('max-w-full text-[13px] text-gray-dark', {
defaultVariants: {
align: 'center',
},
@ -47,7 +47,38 @@ export function CaptionTextarea(props: React.ComponentProps<typeof CaptionTextar
);
}
export const CaptionButton = createPrimitiveComponent(Button)({
propsHook: useCaptionButton,
stateHook: useCaptionButtonState,
});
export const CaptionButton = (props: React.ComponentProps<typeof Button>) => {
const captionButtonState = useCaptionButtonState();
const hasCaption = (captionButtonState.element?.caption as TElement[])?.length > 0;
const text = hasCaption ? NodeTypeLabels.removeCaption.label : NodeTypeLabels.addCaption.label;
const editor = captionButtonState.editor;
const element = captionButtonState.element;
const addCaption = () => {
const path = editor.api.findPath(element);
editor.setOption(CaptionPlugin, 'visibleId', element.id as string);
setTimeout(() => {
path && editor.setOption(CaptionPlugin, 'focusEndPath', path);
}, 0);
};
const removeCaption = () => {
editor.tf.unsetNodes('caption', { at: element });
editor.setOption(CaptionPlugin, 'visibleId', null);
};
const onClick = () => {
if (hasCaption) {
removeCaption();
} else {
addCaption();
}
};
return (
<Button variant={'default'} {...props} {...captionButtonState} onClick={onClick}>
{text}
</Button>
);
};

View File

@ -82,11 +82,11 @@ export function MediaToolbar({
{NodeTypeLabels.editLink.label}
</FloatingMediaPrimitive.EditButton>
<CaptionButton variant="ghost">{NodeTypeLabels.caption.label}</CaptionButton>
<CaptionButton />
<Separator orientation="vertical" className="mx-1 h-6" />
<Button prefix={<NodeTypeIcons.trash />} variant="ghost" {...buttonProps}></Button>
<Button prefix={<NodeTypeIcons.trash />} {...buttonProps}></Button>
</div>
)}
</PopoverContent>

View File

@ -67,16 +67,16 @@ export function MetricToolbar({
<PopoverAnchor>{children}</PopoverAnchor>
<PopoverContent className="w-auto p-2" onOpenAutoFocus={(e) => e.preventDefault()}>
<div className="box-content flex items-center space-x-1">
<div className="box-content flex items-center space-x-2">
{/* <Button onClick={onOpenEdit} variant="ghost">
{NodeTypeLabels.editMetric?.label}
</Button> */}
<CaptionButton variant="ghost">{NodeTypeLabels.caption.label}</CaptionButton>
<CaptionButton />
{/* <Separator orientation="vertical" className="mx-1 h-6" /> */}
<Separator orientation="vertical" className=" h-6" />
<Button prefix={<NodeTypeIcons.trash />} variant="ghost" {...removeButtonProps}>
<Button prefix={<NodeTypeIcons.trash />} {...removeButtonProps}>
Delete
</Button>
</div>