mirror of https://github.com/buster-so/buster.git
Merge pull request #660 from buster-so/big-nate-bus-1603-finalize-context-menu-options
block context menu updates
This commit is contained in:
commit
efbe35cd39
|
@ -207,7 +207,7 @@ const value: ReportElements = [
|
|||
children: [
|
||||
{
|
||||
text: 'This is a todo list',
|
||||
subscript: true
|
||||
subscript: false
|
||||
}
|
||||
],
|
||||
indent: 1,
|
||||
|
|
|
@ -203,6 +203,7 @@ export const NodeTypeIcons = {
|
|||
indent: IndentIncrease,
|
||||
outdent: IndentDecrease,
|
||||
download: Download,
|
||||
turnInto: Pilcrow,
|
||||
|
||||
// Tools
|
||||
equation: Equation,
|
||||
|
|
|
@ -124,6 +124,21 @@ export const NodeTypeLabels = {
|
|||
keyboard: '⌘+⇧+Z',
|
||||
keywords: []
|
||||
},
|
||||
delete: {
|
||||
label: 'Delete',
|
||||
keyboard: '⌘+⌫',
|
||||
keywords: []
|
||||
},
|
||||
duplicate: {
|
||||
label: 'Duplicate',
|
||||
keyboard: undefined,
|
||||
keywords: []
|
||||
},
|
||||
askAI: {
|
||||
label: 'Ask AI',
|
||||
keyboard: undefined,
|
||||
keywords: []
|
||||
},
|
||||
link: {
|
||||
label: 'Link',
|
||||
keyboard: '⌘+K',
|
||||
|
@ -161,13 +176,18 @@ export const NodeTypeLabels = {
|
|||
keyboard: undefined,
|
||||
keywords: []
|
||||
},
|
||||
insert: {
|
||||
label: 'Insert',
|
||||
align: {
|
||||
label: 'Align',
|
||||
keyboard: undefined,
|
||||
keywords: []
|
||||
},
|
||||
align: {
|
||||
label: 'Align',
|
||||
indentation: {
|
||||
label: 'Indentation',
|
||||
keyboard: undefined,
|
||||
keywords: ['indent', 'outdent']
|
||||
},
|
||||
insert: {
|
||||
label: 'Insert',
|
||||
keyboard: undefined,
|
||||
keywords: []
|
||||
},
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
} from '@/components/ui/dropdown-menu';
|
||||
|
||||
import { ToolbarButton } from '@/components/ui/toolbar/Toolbar';
|
||||
import { Tooltip } from '../../tooltip';
|
||||
|
||||
const items = [
|
||||
{
|
||||
|
@ -69,13 +70,15 @@ export function AlignToolbarButton(props: DropdownMenuProps) {
|
|||
tf.textAlign.setNodes(value as Alignment);
|
||||
editor.tf.focus();
|
||||
}}>
|
||||
{items.map(({ icon: Icon, value: itemValue }) => (
|
||||
<DropdownMenuRadioItem
|
||||
key={itemValue}
|
||||
className="data-[state=checked]:bg-accent pl-2 *:first:[span]:hidden"
|
||||
value={itemValue}>
|
||||
<Icon />
|
||||
</DropdownMenuRadioItem>
|
||||
{items.map(({ icon: Icon, label, value: itemValue }) => (
|
||||
<Tooltip key={itemValue} title={label} side="left">
|
||||
<DropdownMenuRadioItem
|
||||
key={itemValue}
|
||||
className="data-[state=checked]:bg-accent pl-2 *:first:[span]:hidden"
|
||||
value={itemValue}>
|
||||
<Icon />
|
||||
</DropdownMenuRadioItem>
|
||||
</Tooltip>
|
||||
))}
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
ContextMenuContent,
|
||||
ContextMenuGroup,
|
||||
ContextMenuItem,
|
||||
ContextMenuShortcut,
|
||||
ContextMenuSub,
|
||||
ContextMenuSubContent,
|
||||
ContextMenuSubTrigger,
|
||||
|
@ -23,10 +24,33 @@ import {
|
|||
} from '@/components/ui/context-menu';
|
||||
import { useIsTouchDevice } from '@/hooks/useIsTouchDevice';
|
||||
import { THEME_RESET_STYLE } from '@/styles/theme-reset';
|
||||
import { NodeTypeIcons } from '../config/icons';
|
||||
import { NodeTypeLabels } from '../config/labels';
|
||||
|
||||
// Helper function to render menu item content
|
||||
const MenuItemContent = ({
|
||||
icon,
|
||||
labelKey
|
||||
}: {
|
||||
icon: React.ComponentType;
|
||||
labelKey: keyof typeof NodeTypeLabels;
|
||||
}) => {
|
||||
const label = NodeTypeLabels[labelKey];
|
||||
const Icon = icon;
|
||||
return (
|
||||
<>
|
||||
<div className="text-icon-color text-md size-4">
|
||||
<Icon />
|
||||
</div>
|
||||
{label.label}
|
||||
{label.keyboard && <ContextMenuShortcut>{label.keyboard}</ContextMenuShortcut>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
type Value = 'askAI' | null;
|
||||
|
||||
export function BlockContextMenu({ children }: { children: React.ReactNode }) {
|
||||
function BlockContextMenuComponent({ children }: { children: React.ReactNode }) {
|
||||
const { api, editor } = useEditorPlugin(BlockMenuPlugin);
|
||||
const [value, setValue] = React.useState<Value>(null);
|
||||
const isTouch = useIsTouchDevice();
|
||||
|
@ -88,7 +112,7 @@ export function BlockContextMenu({ children }: { children: React.ReactNode }) {
|
|||
y: event.clientY
|
||||
});
|
||||
}}>
|
||||
<div className="w-full">{children}</div>
|
||||
<div className="block-context-menu-trigger">{children}</div>
|
||||
</ContextMenuTrigger>
|
||||
<ContextMenuContent
|
||||
className="w-64"
|
||||
|
@ -104,56 +128,84 @@ export function BlockContextMenu({ children }: { children: React.ReactNode }) {
|
|||
setValue(null);
|
||||
}}>
|
||||
<ContextMenuGroup>
|
||||
<ContextMenuItem
|
||||
{/* <ContextMenuItem
|
||||
onClick={() => {
|
||||
setValue('askAI');
|
||||
}}>
|
||||
Ask AI
|
||||
</ContextMenuItem>
|
||||
<MenuItemContent icon={NodeTypeIcons.ai} labelKey="askAI" />
|
||||
</ContextMenuItem> */}
|
||||
<ContextMenuItem
|
||||
onClick={() => {
|
||||
editor.getTransforms(BlockSelectionPlugin).blockSelection.removeNodes();
|
||||
editor.tf.focus();
|
||||
}}>
|
||||
Delete
|
||||
<MenuItemContent icon={NodeTypeIcons.trash} labelKey="delete" />
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem
|
||||
onClick={() => {
|
||||
editor.getTransforms(BlockSelectionPlugin).blockSelection.duplicate();
|
||||
}}>
|
||||
Duplicate
|
||||
{/* <ContextMenuShortcut>⌘ + D</ContextMenuShortcut> */}
|
||||
<MenuItemContent icon={NodeTypeIcons.copy} labelKey="duplicate" />
|
||||
</ContextMenuItem>
|
||||
<ContextMenuSub>
|
||||
<ContextMenuSubTrigger>Turn into</ContextMenuSubTrigger>
|
||||
<ContextMenuSubTrigger>
|
||||
<MenuItemContent icon={NodeTypeIcons.turnInto} labelKey="turnInto" />
|
||||
</ContextMenuSubTrigger>
|
||||
<ContextMenuSubContent className="w-48">
|
||||
<ContextMenuItem onClick={() => handleTurnInto(KEYS.p)}>Paragraph</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleTurnInto(KEYS.p)}>
|
||||
<MenuItemContent icon={NodeTypeIcons.paragraph} labelKey="paragraph" />
|
||||
</ContextMenuItem>
|
||||
|
||||
<ContextMenuItem onClick={() => handleTurnInto(KEYS.h1)}>Heading 1</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleTurnInto(KEYS.h2)}>Heading 2</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleTurnInto(KEYS.h3)}>Heading 3</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleTurnInto(KEYS.h1)}>
|
||||
<MenuItemContent icon={NodeTypeIcons.h1} labelKey="h1" />
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleTurnInto(KEYS.h2)}>
|
||||
<MenuItemContent icon={NodeTypeIcons.h2} labelKey="h2" />
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleTurnInto(KEYS.h3)}>
|
||||
<MenuItemContent icon={NodeTypeIcons.h3} labelKey="h3" />
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleTurnInto(KEYS.blockquote)}>
|
||||
Blockquote
|
||||
<MenuItemContent icon={NodeTypeIcons.quote} labelKey="blockquote" />
|
||||
</ContextMenuItem>
|
||||
</ContextMenuSubContent>
|
||||
</ContextMenuSub>
|
||||
</ContextMenuGroup>
|
||||
|
||||
<ContextMenuGroup>
|
||||
<ContextMenuItem
|
||||
onClick={() => editor.getTransforms(BlockSelectionPlugin).blockSelection.setIndent(1)}>
|
||||
Indent
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem
|
||||
onClick={() => editor.getTransforms(BlockSelectionPlugin).blockSelection.setIndent(-1)}>
|
||||
Outdent
|
||||
</ContextMenuItem>
|
||||
<ContextMenuSub>
|
||||
<ContextMenuSubTrigger>Align</ContextMenuSubTrigger>
|
||||
<ContextMenuSubTrigger>
|
||||
<MenuItemContent icon={NodeTypeIcons.indent} labelKey="indentation" />
|
||||
</ContextMenuSubTrigger>
|
||||
<ContextMenuSubContent className="w-48">
|
||||
<ContextMenuItem onClick={() => handleAlign('left')}>Left</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleAlign('center')}>Center</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleAlign('right')}>Right</ContextMenuItem>
|
||||
<ContextMenuItem
|
||||
onClick={() =>
|
||||
editor.getTransforms(BlockSelectionPlugin).blockSelection.setIndent(1)
|
||||
}>
|
||||
<MenuItemContent icon={NodeTypeIcons.indent} labelKey="indent" />
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem
|
||||
onClick={() =>
|
||||
editor.getTransforms(BlockSelectionPlugin).blockSelection.setIndent(-1)
|
||||
}>
|
||||
<MenuItemContent icon={NodeTypeIcons.outdent} labelKey="outdent" />
|
||||
</ContextMenuItem>
|
||||
</ContextMenuSubContent>
|
||||
</ContextMenuSub>
|
||||
<ContextMenuSub>
|
||||
<ContextMenuSubTrigger>
|
||||
<MenuItemContent icon={NodeTypeIcons.alignLeft} labelKey="align" />
|
||||
</ContextMenuSubTrigger>
|
||||
<ContextMenuSubContent className="w-48">
|
||||
<ContextMenuItem onClick={() => handleAlign('left')}>
|
||||
<MenuItemContent icon={NodeTypeIcons.alignLeft} labelKey="alignLeft" />
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleAlign('center')}>
|
||||
<MenuItemContent icon={NodeTypeIcons.alignCenter} labelKey="alignCenter" />
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem onClick={() => handleAlign('right')}>
|
||||
<MenuItemContent icon={NodeTypeIcons.alignRight} labelKey="alignRight" />
|
||||
</ContextMenuItem>
|
||||
</ContextMenuSubContent>
|
||||
</ContextMenuSub>
|
||||
</ContextMenuGroup>
|
||||
|
@ -161,3 +213,5 @@ export function BlockContextMenu({ children }: { children: React.ReactNode }) {
|
|||
</ContextMenu>
|
||||
);
|
||||
}
|
||||
|
||||
export const BlockContextMenu = React.memo(BlockContextMenuComponent);
|
||||
|
|
Loading…
Reference in New Issue