mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-15 00:56:26 +08:00
init: the first public commit for AFFiNE
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import style9 from 'style9';
|
||||
import {
|
||||
MuiClickAwayListener as ClickAwayListener,
|
||||
MuiGrow as Grow,
|
||||
} from '@toeverything/components/ui';
|
||||
|
||||
import {
|
||||
Virgo,
|
||||
PluginHooks,
|
||||
SelectionInfo,
|
||||
} from '@toeverything/framework/virgo';
|
||||
import { InlineMenuToolbar } from './Toolbar';
|
||||
|
||||
export type InlineMenuContainerProps = {
|
||||
style?: { left: number; top: number };
|
||||
editor: Virgo;
|
||||
hooks: PluginHooks;
|
||||
};
|
||||
|
||||
export const InlineMenuContainer = ({
|
||||
editor,
|
||||
style,
|
||||
hooks,
|
||||
}: InlineMenuContainerProps) => {
|
||||
const [showMenu, setShowMenu] = useState(false);
|
||||
const [containerStyle, setContainerStyle] = useState<{
|
||||
left: number;
|
||||
top: number;
|
||||
}>(null);
|
||||
const [selectionInfo, setSelectionInfo] = useState<SelectionInfo>();
|
||||
|
||||
useEffect(() => {
|
||||
// const unsubscribe = editor.selection.onSelectionChange(info => {
|
||||
const unsubscribe = editor.selection.onSelectEnd(info => {
|
||||
const { type, browserSelection, anchorNode } = info;
|
||||
if (
|
||||
type === 'None' ||
|
||||
!anchorNode ||
|
||||
!browserSelection ||
|
||||
browserSelection?.isCollapsed ||
|
||||
// 👀 inline-toolbar should support more block types except Text
|
||||
// anchorNode.type !== 'text'
|
||||
!editor.blockHelper.getCurrentSelection(anchorNode.id) ||
|
||||
editor.blockHelper.isSelectionCollapsed(anchorNode.id)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rect = browserSelection.getRangeAt(0).getBoundingClientRect();
|
||||
|
||||
setSelectionInfo(info);
|
||||
setShowMenu(true);
|
||||
setContainerStyle({ left: rect.left, top: rect.top - 64 });
|
||||
});
|
||||
|
||||
return unsubscribe;
|
||||
}, [editor]);
|
||||
|
||||
useEffect(() => {
|
||||
const hideInlineMenu = () => {
|
||||
setShowMenu(false);
|
||||
};
|
||||
editor.plugins.observe('hide-inline-menu', hideInlineMenu);
|
||||
|
||||
return () =>
|
||||
editor.plugins.unobserve('hide-inline-menu', hideInlineMenu);
|
||||
}, [editor.plugins]);
|
||||
|
||||
return showMenu && containerStyle ? (
|
||||
<ClickAwayListener onClickAway={() => setShowMenu(false)}>
|
||||
<Grow
|
||||
in={showMenu}
|
||||
style={{ transformOrigin: '0 0 0' }}
|
||||
{...{ timeout: 'auto' }}
|
||||
>
|
||||
<div
|
||||
style={containerStyle}
|
||||
className={styles('toolbarContainer')}
|
||||
onMouseDown={e => {
|
||||
// prevent toolbar from taking focus away from editor
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<InlineMenuToolbar
|
||||
editor={editor}
|
||||
selectionInfo={selectionInfo}
|
||||
setShow={setShowMenu}
|
||||
/>
|
||||
</div>
|
||||
</Grow>
|
||||
</ClickAwayListener>
|
||||
) : null;
|
||||
};
|
||||
|
||||
const styles = style9.create({
|
||||
toolbarContainer: {
|
||||
position: 'fixed',
|
||||
zIndex: 1,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '0 12px',
|
||||
borderRadius: '10px',
|
||||
boxShadow: '0px 1px 10px rgba(152, 172, 189, 0.6)',
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
import { StrictMode } from 'react';
|
||||
import { BasePlugin } from '../../base-plugin';
|
||||
import { PluginRenderRoot } from '../../utils';
|
||||
import { InlineMenuContainer } from './Container';
|
||||
|
||||
const PLUGIN_NAME = 'inline-menu';
|
||||
|
||||
export class InlineMenuPlugin extends BasePlugin {
|
||||
public static override get pluginName(): string {
|
||||
return PLUGIN_NAME;
|
||||
}
|
||||
|
||||
private root: PluginRenderRoot;
|
||||
|
||||
protected override on_render(): void {
|
||||
this.root = new PluginRenderRoot({
|
||||
name: InlineMenuPlugin.pluginName,
|
||||
render: this.editor.reactRenderRoot?.render,
|
||||
});
|
||||
|
||||
this.root.mount();
|
||||
this._renderInlineMenu();
|
||||
}
|
||||
|
||||
private _renderInlineMenu(): void {
|
||||
this.root?.render(
|
||||
<StrictMode>
|
||||
<InlineMenuContainer editor={this.editor} hooks={this.hooks} />
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
public override dispose() {
|
||||
this.root?.unmount();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import { useMemo } from 'react';
|
||||
import { styled } from '@toeverything/components/ui';
|
||||
import { useFlag } from '@toeverything/datasource/feature-flags';
|
||||
|
||||
import type { WithEditorSelectionType } from './types';
|
||||
import { getInlineMenuData } from './utils';
|
||||
import { MenuDropdownItem, MenuIconItem } from './menu-item';
|
||||
import { INLINE_MENU_UI_TYPES } from './config';
|
||||
|
||||
const ToolbarItemSeparator = styled('span')(({ theme }) => ({
|
||||
display: 'inline-flex',
|
||||
marginLeft: theme.affine.spacing.xsSpacing,
|
||||
marginRight: theme.affine.spacing.xsSpacing,
|
||||
color: theme.affine.palette.menuSeparator,
|
||||
}));
|
||||
|
||||
export const InlineMenuToolbar = ({
|
||||
editor,
|
||||
selectionInfo,
|
||||
setShow,
|
||||
}: WithEditorSelectionType) => {
|
||||
// default value is false
|
||||
const enableCommentFeature = useFlag<boolean>('commentDiscussion');
|
||||
|
||||
const inlineMenuData = useMemo(() => {
|
||||
const data = getInlineMenuData({ enableCommentFeature });
|
||||
return data;
|
||||
}, [enableCommentFeature]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{inlineMenuData.map(menu => {
|
||||
const { type, name } = menu;
|
||||
|
||||
if (type === INLINE_MENU_UI_TYPES.dropdown) {
|
||||
return (
|
||||
<MenuDropdownItem
|
||||
{...menu}
|
||||
editor={editor}
|
||||
selectionInfo={selectionInfo}
|
||||
key={name}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (type === INLINE_MENU_UI_TYPES.separator) {
|
||||
return (
|
||||
<ToolbarItemSeparator key={name}>
|
||||
|
|
||||
</ToolbarItemSeparator>
|
||||
);
|
||||
}
|
||||
|
||||
if (type === INLINE_MENU_UI_TYPES.icon) {
|
||||
return (
|
||||
<MenuIconItem
|
||||
{...menu}
|
||||
editor={editor}
|
||||
selectionInfo={selectionInfo}
|
||||
setShow={setShow}
|
||||
key={name}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,102 @@
|
||||
import {
|
||||
fontBgColorPaletteKeys,
|
||||
fontColorPaletteKeys,
|
||||
} from '@toeverything/components/common';
|
||||
import type { InlineMenuNamesType } from './types';
|
||||
import { Protocol } from '@toeverything/datasource/db-service';
|
||||
|
||||
export const INLINE_MENU_UI_TYPES = {
|
||||
icon: 'Icon',
|
||||
dropdown: 'Dropdown',
|
||||
separator: 'Separator',
|
||||
} as const;
|
||||
|
||||
/** inline menu item { key : display-name } */
|
||||
export const inlineMenuShortcuts = {
|
||||
textBold: '⌘+B',
|
||||
textItalic: '⌘+I',
|
||||
textStrikethrough: '⌘+S',
|
||||
link: '⌘+K',
|
||||
[Protocol.Block.Type.code]: '⌘+E',
|
||||
};
|
||||
export const inlineMenuNames = {
|
||||
currentText: 'TEXT SIZE',
|
||||
[Protocol.Block.Type.heading1]: 'Heading 1',
|
||||
[Protocol.Block.Type.heading2]: 'Heading 2',
|
||||
[Protocol.Block.Type.heading3]: 'Heading 3',
|
||||
text: 'Text',
|
||||
currentList: 'CHECK BOX',
|
||||
[Protocol.Block.Type.todo]: 'To do',
|
||||
[Protocol.Block.Type.numbered]: 'Number',
|
||||
[Protocol.Block.Type.bullet]: 'Bullet',
|
||||
comment: 'Comment',
|
||||
textBold: 'Bold',
|
||||
textItalic: 'Italic',
|
||||
textStrikethrough: 'Strikethrough',
|
||||
link: 'Link',
|
||||
[Protocol.Block.Type.code]: 'Code',
|
||||
currentFontColor: 'COLOR',
|
||||
currentFontBackground: 'BACKGROUND COLOR',
|
||||
colorDefault: 'Default',
|
||||
colorGray: 'Gray',
|
||||
colorBrown: 'Brown',
|
||||
colorOrange: 'Orange',
|
||||
colorYellow: 'Yellow',
|
||||
colorGreen: 'Green',
|
||||
colorBlue: 'Blue',
|
||||
colorPurple: 'Purple',
|
||||
colorPink: 'Pink',
|
||||
colorRed: 'Red',
|
||||
bgDefault: 'Default background',
|
||||
bgGray: 'Gray background',
|
||||
bgBrown: 'Brown background',
|
||||
bgOrange: 'Orange background',
|
||||
bgYellow: 'Yellow background',
|
||||
bgGreen: 'Green background',
|
||||
bgBlue: 'Blue background',
|
||||
bgPurple: 'Purple background',
|
||||
bgPink: 'Pink background',
|
||||
bgRed: 'Red background',
|
||||
currentTextAlign: 'TEXT ALIGN',
|
||||
alignLeft: 'Align Left',
|
||||
alignCenter: 'Align Center',
|
||||
alignRight: 'Align Right',
|
||||
turnInto: 'TURN INTO',
|
||||
[Protocol.Block.Type.page]: 'Page',
|
||||
[Protocol.Block.Type.quote]: 'Quote',
|
||||
[Protocol.Block.Type.callout]: 'Callout',
|
||||
// [Protocol.Block.Type.code]: 'Code Block',
|
||||
codeBlock: 'Code Block',
|
||||
[Protocol.Block.Type.image]: 'Image',
|
||||
[Protocol.Block.Type.file]: 'File',
|
||||
backlinks: 'Backlinks',
|
||||
moreActions: 'More Actions',
|
||||
} as const;
|
||||
|
||||
export const inlineMenuNamesKeys = Object.keys(inlineMenuNames).reduce(
|
||||
(aac, curr) => ({ [curr]: curr, ...aac }),
|
||||
{}
|
||||
) as Record<InlineMenuNamesType, InlineMenuNamesType>;
|
||||
|
||||
export const inlineMenuNamesForFontColor = {
|
||||
colorDefault: fontColorPaletteKeys.default,
|
||||
colorGray: fontColorPaletteKeys.affineGray,
|
||||
colorBrown: fontColorPaletteKeys.affineBrown,
|
||||
colorOrange: fontColorPaletteKeys.affineOrange,
|
||||
colorYellow: fontColorPaletteKeys.affineYellow,
|
||||
colorGreen: fontColorPaletteKeys.affineGreen,
|
||||
colorBlue: fontColorPaletteKeys.affineBlue,
|
||||
colorPurple: fontColorPaletteKeys.affinePurple,
|
||||
colorPink: fontColorPaletteKeys.affinePink,
|
||||
colorRed: fontColorPaletteKeys.affineRed,
|
||||
bgDefault: fontBgColorPaletteKeys.default,
|
||||
bgGray: fontBgColorPaletteKeys.affineGray,
|
||||
bgBrown: fontBgColorPaletteKeys.affineBrown,
|
||||
bgOrange: fontBgColorPaletteKeys.affineOrange,
|
||||
bgYellow: fontBgColorPaletteKeys.affineYellow,
|
||||
bgGreen: fontBgColorPaletteKeys.affineGreen,
|
||||
bgBlue: fontBgColorPaletteKeys.affineBlue,
|
||||
bgPurple: fontBgColorPaletteKeys.affinePurple,
|
||||
bgPink: fontBgColorPaletteKeys.affinePink,
|
||||
bgRed: fontBgColorPaletteKeys.affineRed,
|
||||
} as const;
|
||||
@@ -0,0 +1 @@
|
||||
export { InlineMenuPlugin } from './Plugin';
|
||||
@@ -0,0 +1,196 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import style9 from 'style9';
|
||||
import {
|
||||
MuiPopover,
|
||||
styled,
|
||||
type SvgIconProps,
|
||||
Tooltip,
|
||||
} from '@toeverything/components/ui';
|
||||
import {
|
||||
fontBgColorPalette,
|
||||
fontColorPalette,
|
||||
} from '@toeverything/components/common';
|
||||
import { ArrowDropDownIcon } from '@toeverything/components/icons';
|
||||
import type { DropdownItemType, WithEditorSelectionType } from '../types';
|
||||
import {
|
||||
inlineMenuNamesKeys,
|
||||
inlineMenuNamesForFontColor,
|
||||
inlineMenuShortcuts,
|
||||
} from '../config';
|
||||
|
||||
type MenuDropdownItemProps = DropdownItemType & WithEditorSelectionType;
|
||||
|
||||
export const MenuDropdownItem = ({
|
||||
name,
|
||||
nameKey,
|
||||
icon: MenuIcon,
|
||||
children,
|
||||
editor,
|
||||
selectionInfo,
|
||||
}: MenuDropdownItemProps) => {
|
||||
const [anchor_ele, set_anchor_ele] = useState<HTMLButtonElement | null>(
|
||||
null
|
||||
);
|
||||
|
||||
const handle_open_dropdown_menu = useCallback(
|
||||
(event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
set_anchor_ele(event.currentTarget);
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const handle_close_dropdown_menu = useCallback(() => {
|
||||
set_anchor_ele(null);
|
||||
}, []);
|
||||
|
||||
//@ts-ignore
|
||||
const shortcut = inlineMenuShortcuts[nameKey];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip
|
||||
content={
|
||||
<div style={{ padding: '2px 4px' }}>
|
||||
<p>{name}</p>
|
||||
{shortcut && <p>{shortcut}</p>}
|
||||
</div>
|
||||
}
|
||||
placement="bottom"
|
||||
trigger="hover"
|
||||
>
|
||||
<button
|
||||
onClick={handle_open_dropdown_menu}
|
||||
className={styles('currentDropdownButton')}
|
||||
aria-label={name}
|
||||
onMouseDown={e => {
|
||||
// prevent toolbar from taking focus away from editor
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<MenuIcon sx={{ width: 20, height: 20 }} />
|
||||
<ArrowDropDownIcon sx={{ width: 20, height: 20 }} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
<MuiPopover
|
||||
id={anchor_ele ? 'inline-menu-pop' : undefined}
|
||||
open={Boolean(anchor_ele)}
|
||||
anchorEl={anchor_ele}
|
||||
onClose={handle_close_dropdown_menu}
|
||||
anchorOrigin={{
|
||||
horizontal: 'left',
|
||||
vertical: 40,
|
||||
}}
|
||||
>
|
||||
<div className={styles('dropdownContainer')}>
|
||||
{children.map(item => {
|
||||
const {
|
||||
name,
|
||||
icon: ItemIcon,
|
||||
onClick,
|
||||
nameKey: itemNameKey,
|
||||
} = item;
|
||||
|
||||
const StyledIcon = withStylesForIcon(ItemIcon);
|
||||
|
||||
return (
|
||||
<button
|
||||
className={styles('dropdownItem')}
|
||||
key={name}
|
||||
onClick={() => {
|
||||
if (
|
||||
onClick &&
|
||||
selectionInfo?.anchorNode?.id
|
||||
) {
|
||||
onClick({
|
||||
editor,
|
||||
type: itemNameKey,
|
||||
anchorNodeId:
|
||||
selectionInfo?.anchorNode?.id,
|
||||
});
|
||||
}
|
||||
handle_close_dropdown_menu();
|
||||
}}
|
||||
>
|
||||
<StyledIcon
|
||||
fontColor={
|
||||
nameKey ===
|
||||
inlineMenuNamesKeys.currentFontColor
|
||||
? fontColorPalette[
|
||||
inlineMenuNamesForFontColor[
|
||||
itemNameKey as keyof typeof inlineMenuNamesForFontColor
|
||||
]
|
||||
]
|
||||
: nameKey ===
|
||||
inlineMenuNamesKeys.currentFontBackground
|
||||
? fontBgColorPalette[
|
||||
inlineMenuNamesForFontColor[
|
||||
itemNameKey as keyof typeof inlineMenuNamesForFontColor
|
||||
]
|
||||
]
|
||||
: ''
|
||||
}
|
||||
// fontBgColor={
|
||||
// nameKey=== inlineMenuNamesKeys.currentFontBackground ? fontBgColorPalette[
|
||||
// inlineMenuNamesForFontColor[itemNameKey] as keyof typeof fontBgColorPalette
|
||||
// ]:''
|
||||
// }
|
||||
/>
|
||||
{/* <ItemIcon sx={{ width: 20, height: 20 }} /> */}
|
||||
<span className={styles('dropdownItemItext')}>
|
||||
{name}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</MuiPopover>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const withStylesForIcon = (FontIconComponent: React.FC<SvgIconProps>) =>
|
||||
styled(FontIconComponent, {
|
||||
shouldForwardProp: (prop: string) =>
|
||||
!['fontColor', 'fontBgColor'].includes(prop),
|
||||
})<{ fontColor?: string; fontBgColor?: string }>(
|
||||
({ fontColor, fontBgColor }) => {
|
||||
return {
|
||||
width: 20,
|
||||
height: 20,
|
||||
color: fontColor || undefined,
|
||||
backgroundColor: fontBgColor || undefined,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
const styles = style9.create({
|
||||
currentDropdownButton: {
|
||||
display: 'inline-flex',
|
||||
padding: '0',
|
||||
margin: '15px 6px',
|
||||
color: '#98acbd',
|
||||
':hover': { backgroundColor: 'transparent' },
|
||||
},
|
||||
dropdownContainer: {
|
||||
margin: '8px 4px',
|
||||
},
|
||||
dropdownItem: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
// @ts-ignore
|
||||
gap: '12px',
|
||||
// width: '120px',
|
||||
height: '32px',
|
||||
padding: '0px 12px',
|
||||
borderRadius: '5px',
|
||||
color: '#98acbd',
|
||||
':hover': { backgroundColor: '#F5F7F8' },
|
||||
},
|
||||
dropdownItemItext: {
|
||||
color: '#4C6275',
|
||||
fontFamily: 'Helvetica,Arial,"Microsoft Yahei",SimHei,sans-serif',
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import style9 from 'style9';
|
||||
|
||||
import type { IconItemType, WithEditorSelectionType } from '../types';
|
||||
import { inlineMenuNamesKeys, inlineMenuShortcuts } from '../config';
|
||||
import { Tooltip } from '@toeverything/components/ui';
|
||||
type MenuIconItemProps = IconItemType & WithEditorSelectionType;
|
||||
|
||||
export const MenuIconItem = ({
|
||||
name,
|
||||
nameKey,
|
||||
icon: MenuIcon,
|
||||
onClick,
|
||||
editor,
|
||||
selectionInfo,
|
||||
setShow,
|
||||
}: MenuIconItemProps) => {
|
||||
const handleToolbarItemClick = useCallback(
|
||||
(event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
if (onClick && selectionInfo?.anchorNode?.id) {
|
||||
onClick({
|
||||
editor,
|
||||
type: nameKey,
|
||||
anchorNodeId: selectionInfo?.anchorNode?.id,
|
||||
});
|
||||
}
|
||||
if ([inlineMenuNamesKeys.comment].includes(nameKey)) {
|
||||
setShow(false);
|
||||
}
|
||||
if (inlineMenuNamesKeys.comment === nameKey) {
|
||||
editor.plugins.emit('show-add-comment');
|
||||
}
|
||||
},
|
||||
[editor, nameKey, onClick, selectionInfo?.anchorNode?.id, setShow]
|
||||
);
|
||||
|
||||
//@ts-ignore
|
||||
const shortcut = inlineMenuShortcuts[nameKey];
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={
|
||||
<div style={{ padding: '2px 4px' }}>
|
||||
<p>{name}</p>
|
||||
{shortcut && <p>{shortcut}</p>}
|
||||
</div>
|
||||
}
|
||||
placement="bottom"
|
||||
trigger="hover"
|
||||
>
|
||||
<button
|
||||
onClick={handleToolbarItemClick}
|
||||
className={styles('currentIcon')}
|
||||
aria-label={name}
|
||||
>
|
||||
<MenuIcon sx={{ width: 20, height: 20 }} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = style9.create({
|
||||
currentIcon: {
|
||||
display: 'inline-flex',
|
||||
padding: '0',
|
||||
margin: '15px 6px',
|
||||
color: '#98acbd',
|
||||
':hover': { backgroundColor: 'transparent' },
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,2 @@
|
||||
export { MenuIconItem } from './IconItem';
|
||||
export { MenuDropdownItem } from './DropdownItem';
|
||||
@@ -0,0 +1,50 @@
|
||||
import React, { type FC } from 'react';
|
||||
import type { SvgIconProps } from '@toeverything/components/ui';
|
||||
import type { Virgo, SelectionInfo } from '@toeverything/framework/virgo';
|
||||
import { inlineMenuNames, INLINE_MENU_UI_TYPES } from './config';
|
||||
|
||||
export type WithEditorSelectionType = {
|
||||
editor: Virgo;
|
||||
selectionInfo: SelectionInfo;
|
||||
setShow?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
};
|
||||
|
||||
export type InlineMenuNamesType = keyof typeof inlineMenuNames;
|
||||
|
||||
export type ClickItemHandler = ({
|
||||
type,
|
||||
editor,
|
||||
anchorNodeId,
|
||||
}: {
|
||||
type: InlineMenuNamesType;
|
||||
editor: Virgo;
|
||||
anchorNodeId: string;
|
||||
}) => void;
|
||||
|
||||
export type IconItemType = {
|
||||
type: typeof INLINE_MENU_UI_TYPES['icon'];
|
||||
icon: FC<SvgIconProps>;
|
||||
nameKey: InlineMenuNamesType;
|
||||
name: typeof inlineMenuNames[InlineMenuNamesType];
|
||||
onClick?: ClickItemHandler;
|
||||
active?: boolean;
|
||||
};
|
||||
|
||||
export type DropdownItemType = {
|
||||
type: typeof INLINE_MENU_UI_TYPES['dropdown'];
|
||||
icon: FC<SvgIconProps>;
|
||||
nameKey: InlineMenuNamesType;
|
||||
name: typeof inlineMenuNames[InlineMenuNamesType];
|
||||
children: IconItemType[];
|
||||
activeKey?: InlineMenuNamesType;
|
||||
};
|
||||
|
||||
type SeparatorMenuItem = {
|
||||
type: typeof INLINE_MENU_UI_TYPES['separator'];
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type InlineMenuItem =
|
||||
| IconItemType
|
||||
| DropdownItemType
|
||||
| SeparatorMenuItem;
|
||||
@@ -0,0 +1,833 @@
|
||||
/* eslint-disable max-lines */
|
||||
import {
|
||||
HeadingOneIcon,
|
||||
HeadingTwoIcon,
|
||||
HeadingThreeIcon,
|
||||
ToDoIcon,
|
||||
NumberIcon,
|
||||
BulletIcon,
|
||||
FormatBoldEmphasisIcon,
|
||||
FormatItalicIcon,
|
||||
FormatStrikethroughIcon,
|
||||
LinkIcon,
|
||||
CodeIcon,
|
||||
FormatColorTextIcon,
|
||||
FormatBackgroundIcon,
|
||||
AlignLeftIcon,
|
||||
AlignCenterIcon,
|
||||
AlignRightIcon,
|
||||
TurnIntoIcon,
|
||||
BacklinksIcon,
|
||||
MoreIcon,
|
||||
TextFontIcon,
|
||||
QuoteIcon,
|
||||
CalloutIcon,
|
||||
FileIcon,
|
||||
ImageIcon,
|
||||
PagesIcon,
|
||||
CodeBlockIcon,
|
||||
CommentIcon,
|
||||
} from '@toeverything/components/icons';
|
||||
import {
|
||||
fontBgColorPalette,
|
||||
fontColorPalette,
|
||||
type TextAlignOptions,
|
||||
} from '@toeverything/components/common';
|
||||
import { Virgo } from '@toeverything/framework/virgo';
|
||||
import { BlockFlavorKeys, Protocol } from '@toeverything/datasource/db-service';
|
||||
import { ClickItemHandler, InlineMenuItem } from './types';
|
||||
import {
|
||||
inlineMenuNamesKeys,
|
||||
inlineMenuNamesForFontColor,
|
||||
INLINE_MENU_UI_TYPES,
|
||||
inlineMenuNames,
|
||||
} from './config';
|
||||
|
||||
const convert_to_block_type = async ({
|
||||
editor,
|
||||
blockId,
|
||||
blockType,
|
||||
}: {
|
||||
editor: Virgo;
|
||||
blockId: string;
|
||||
blockType: BlockFlavorKeys;
|
||||
}) => {
|
||||
if (Protocol.Block.Type[blockType]) {
|
||||
await editor.commands.blockCommands.convertBlock(blockId, blockType);
|
||||
}
|
||||
};
|
||||
const toggle_text_format = ({
|
||||
editor,
|
||||
nodeId,
|
||||
format,
|
||||
}: {
|
||||
editor: Virgo;
|
||||
nodeId: string;
|
||||
format: 'bold' | 'italic' | 'underline' | 'strikethrough' | 'inlinecode';
|
||||
}) => {
|
||||
editor.blockHelper.toggleTextFormatBySelection(nodeId, format);
|
||||
};
|
||||
const add_link = ({ editor, blockId }: { editor: Virgo; blockId: string }) => {
|
||||
editor.blockHelper.setLinkModalVisible(blockId, true);
|
||||
};
|
||||
const set_paragraph_align = ({
|
||||
editor,
|
||||
nodeId,
|
||||
align,
|
||||
}: {
|
||||
editor: Virgo;
|
||||
nodeId: string;
|
||||
align: TextAlignOptions;
|
||||
}) => {
|
||||
editor.blockHelper.setParagraphAlign(nodeId, align);
|
||||
};
|
||||
const set_font_color = ({
|
||||
editor,
|
||||
nodeId,
|
||||
color,
|
||||
}: {
|
||||
editor: Virgo;
|
||||
nodeId: string;
|
||||
color: keyof typeof fontColorPalette;
|
||||
}) => {
|
||||
editor.blockHelper.setTextFontColor(nodeId, color);
|
||||
};
|
||||
const set_font_bg_color = ({
|
||||
editor,
|
||||
nodeId,
|
||||
bgColor,
|
||||
}: {
|
||||
editor: Virgo;
|
||||
nodeId: string;
|
||||
bgColor: keyof typeof fontBgColorPalette;
|
||||
}) => {
|
||||
editor.blockHelper.setTextFontBgColor(nodeId, bgColor);
|
||||
};
|
||||
const common_handler_for_inline_menu: ClickItemHandler = ({
|
||||
editor,
|
||||
anchorNodeId,
|
||||
type,
|
||||
}) => {
|
||||
switch (type) {
|
||||
case inlineMenuNamesKeys.text:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.text,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.heading1:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.heading1,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.heading2:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.heading2,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.heading3:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.heading3,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bullet:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.bullet,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.todo:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.todo,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.numbered:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.numbered,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.textBold:
|
||||
toggle_text_format({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
format: 'bold',
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.textItalic:
|
||||
toggle_text_format({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
format: 'italic',
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.textStrikethrough:
|
||||
toggle_text_format({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
format: 'strikethrough',
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.link:
|
||||
add_link({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.code:
|
||||
toggle_text_format({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
format: 'inlinecode',
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.alignLeft:
|
||||
set_paragraph_align({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
align: undefined,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.alignCenter:
|
||||
set_paragraph_align({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
align: 'center',
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.alignRight:
|
||||
set_paragraph_align({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
align: 'right',
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.colorDefault:
|
||||
set_font_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
color: inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.colorDefault as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.colorGray:
|
||||
set_font_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
color: inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.colorGray as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.colorBrown:
|
||||
set_font_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
color: inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.colorBrown as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.colorOrange:
|
||||
set_font_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
color: inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.colorOrange as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.colorYellow:
|
||||
set_font_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
color: inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.colorYellow as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.colorGreen:
|
||||
set_font_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
color: inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.colorGreen as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.colorBlue:
|
||||
set_font_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
color: inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.colorBlue as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.colorPurple:
|
||||
set_font_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
color: inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.colorPurple as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.colorPink:
|
||||
set_font_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
color: inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.colorPink as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.colorRed:
|
||||
set_font_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
color: inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.colorRed as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bgDefault:
|
||||
set_font_bg_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
bgColor:
|
||||
inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.bgDefault as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bgGray:
|
||||
set_font_bg_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
bgColor:
|
||||
inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.bgGray as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bgBrown:
|
||||
set_font_bg_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
bgColor:
|
||||
inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.bgBrown as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bgOrange:
|
||||
set_font_bg_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
bgColor:
|
||||
inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.bgOrange as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bgYellow:
|
||||
set_font_bg_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
bgColor:
|
||||
inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.bgYellow as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bgGreen:
|
||||
set_font_bg_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
bgColor:
|
||||
inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.bgGreen as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bgBlue:
|
||||
set_font_bg_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
bgColor:
|
||||
inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.bgBlue as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bgPurple:
|
||||
set_font_bg_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
bgColor:
|
||||
inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.bgPurple as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bgPink:
|
||||
set_font_bg_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
bgColor:
|
||||
inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.bgPink as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.bgRed:
|
||||
set_font_bg_color({
|
||||
editor,
|
||||
nodeId: anchorNodeId,
|
||||
bgColor:
|
||||
inlineMenuNamesForFontColor[
|
||||
inlineMenuNamesKeys.bgRed as keyof typeof inlineMenuNamesForFontColor
|
||||
],
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.quote:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.quote,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.callout:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.callout,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.codeBlock:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.code,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.image:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.image,
|
||||
});
|
||||
break;
|
||||
case inlineMenuNamesKeys.file:
|
||||
convert_to_block_type({
|
||||
editor,
|
||||
blockId: anchorNodeId,
|
||||
blockType: Protocol.Block.Type.file,
|
||||
});
|
||||
break;
|
||||
default: // do nothing
|
||||
}
|
||||
};
|
||||
|
||||
type InlineMenuDataConfigType = {
|
||||
enableCommentFeature: boolean;
|
||||
};
|
||||
|
||||
export const getInlineMenuData = ({
|
||||
enableCommentFeature,
|
||||
}: InlineMenuDataConfigType): InlineMenuItem[] => {
|
||||
const inlineMenuData = [
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.dropdown,
|
||||
icon: HeadingOneIcon,
|
||||
name: inlineMenuNames.currentText,
|
||||
nameKey: inlineMenuNamesKeys.currentText,
|
||||
children: [
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: HeadingOneIcon,
|
||||
name: inlineMenuNames.heading1,
|
||||
nameKey: inlineMenuNamesKeys.heading1,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: HeadingTwoIcon,
|
||||
name: inlineMenuNames.heading2,
|
||||
nameKey: inlineMenuNamesKeys.heading2,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: HeadingThreeIcon,
|
||||
name: inlineMenuNames.heading3,
|
||||
nameKey: inlineMenuNamesKeys.heading3,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: TextFontIcon,
|
||||
name: inlineMenuNames.text,
|
||||
nameKey: inlineMenuNamesKeys.text,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.dropdown,
|
||||
icon: ToDoIcon,
|
||||
name: inlineMenuNames.currentList,
|
||||
nameKey: inlineMenuNamesKeys.currentList,
|
||||
children: [
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: ToDoIcon,
|
||||
name: inlineMenuNames.todo,
|
||||
nameKey: inlineMenuNamesKeys.todo,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: NumberIcon,
|
||||
name: inlineMenuNames.numbered,
|
||||
nameKey: inlineMenuNamesKeys.numbered,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: BulletIcon,
|
||||
name: inlineMenuNames.bullet,
|
||||
nameKey: inlineMenuNamesKeys.bullet,
|
||||
active: false,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.separator,
|
||||
name: 'separator ' + inlineMenuNames.currentList,
|
||||
},
|
||||
enableCommentFeature
|
||||
? {
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: CommentIcon,
|
||||
name: inlineMenuNames.comment,
|
||||
nameKey: inlineMenuNamesKeys.comment,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
}
|
||||
: null,
|
||||
enableCommentFeature
|
||||
? {
|
||||
type: INLINE_MENU_UI_TYPES.separator,
|
||||
name: 'separator ' + inlineMenuNames.comment,
|
||||
}
|
||||
: null,
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBoldEmphasisIcon,
|
||||
name: inlineMenuNames.textBold,
|
||||
nameKey: inlineMenuNamesKeys.textBold,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatItalicIcon,
|
||||
name: inlineMenuNames.textItalic,
|
||||
nameKey: inlineMenuNamesKeys.textItalic,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatStrikethroughIcon,
|
||||
name: inlineMenuNames.textStrikethrough,
|
||||
nameKey: inlineMenuNamesKeys.textStrikethrough,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: LinkIcon,
|
||||
name: inlineMenuNames.link,
|
||||
nameKey: inlineMenuNamesKeys.link,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: CodeIcon,
|
||||
name: inlineMenuNames.code,
|
||||
nameKey: inlineMenuNamesKeys.code,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.separator,
|
||||
name: 'separator ' + inlineMenuNames.code,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.dropdown,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.currentFontColor,
|
||||
nameKey: inlineMenuNamesKeys.currentFontColor,
|
||||
children: [
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.colorDefault,
|
||||
nameKey: inlineMenuNamesKeys.colorDefault,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.colorGray,
|
||||
nameKey: inlineMenuNamesKeys.colorGray,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.colorBrown,
|
||||
nameKey: inlineMenuNamesKeys.colorBrown,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.colorOrange,
|
||||
nameKey: inlineMenuNamesKeys.colorOrange,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.colorYellow,
|
||||
nameKey: inlineMenuNamesKeys.colorYellow,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.colorGreen,
|
||||
nameKey: inlineMenuNamesKeys.colorGreen,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.colorBlue,
|
||||
nameKey: inlineMenuNamesKeys.colorBlue,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.colorPurple,
|
||||
nameKey: inlineMenuNamesKeys.colorPurple,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.colorPink,
|
||||
nameKey: inlineMenuNamesKeys.colorPink,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatColorTextIcon,
|
||||
name: inlineMenuNames.colorRed,
|
||||
nameKey: inlineMenuNamesKeys.colorRed,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.dropdown,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.currentFontBackground,
|
||||
nameKey: inlineMenuNamesKeys.currentFontBackground,
|
||||
children: [
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.bgDefault,
|
||||
nameKey: inlineMenuNamesKeys.bgDefault,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.bgGray,
|
||||
nameKey: inlineMenuNamesKeys.bgGray,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.bgBrown,
|
||||
nameKey: inlineMenuNamesKeys.bgBrown,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.bgOrange,
|
||||
nameKey: inlineMenuNamesKeys.bgOrange,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.bgYellow,
|
||||
nameKey: inlineMenuNamesKeys.bgYellow,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.bgGreen,
|
||||
nameKey: inlineMenuNamesKeys.bgGreen,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.bgBlue,
|
||||
nameKey: inlineMenuNamesKeys.bgBlue,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.bgPurple,
|
||||
nameKey: inlineMenuNamesKeys.bgPurple,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.bgPink,
|
||||
nameKey: inlineMenuNamesKeys.bgPink,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FormatBackgroundIcon,
|
||||
name: inlineMenuNames.bgRed,
|
||||
nameKey: inlineMenuNamesKeys.bgRed,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.dropdown,
|
||||
icon: AlignLeftIcon,
|
||||
name: inlineMenuNames.currentTextAlign,
|
||||
nameKey: inlineMenuNamesKeys.currentTextAlign,
|
||||
children: [
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: AlignLeftIcon,
|
||||
name: inlineMenuNames.alignLeft,
|
||||
nameKey: inlineMenuNamesKeys.alignLeft,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: AlignCenterIcon,
|
||||
name: inlineMenuNames.alignCenter,
|
||||
nameKey: inlineMenuNamesKeys.alignCenter,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: AlignRightIcon,
|
||||
name: inlineMenuNames.alignRight,
|
||||
nameKey: inlineMenuNamesKeys.alignRight,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.separator,
|
||||
name: 'separator ' + inlineMenuNames.alignRight,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.dropdown,
|
||||
icon: TurnIntoIcon,
|
||||
name: inlineMenuNames.turnInto,
|
||||
nameKey: inlineMenuNamesKeys.turnInto,
|
||||
children: [
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: PagesIcon,
|
||||
name: inlineMenuNames.page,
|
||||
nameKey: inlineMenuNamesKeys.page,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: QuoteIcon,
|
||||
name: inlineMenuNames.quote,
|
||||
nameKey: inlineMenuNamesKeys.quote,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: CalloutIcon,
|
||||
name: inlineMenuNames.callout,
|
||||
nameKey: inlineMenuNamesKeys.callout,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: CodeBlockIcon,
|
||||
name: inlineMenuNames.codeBlock,
|
||||
nameKey: inlineMenuNamesKeys.codeBlock,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: ImageIcon,
|
||||
name: inlineMenuNames.image,
|
||||
nameKey: inlineMenuNamesKeys.image,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: FileIcon,
|
||||
name: inlineMenuNames.file,
|
||||
nameKey: inlineMenuNamesKeys.file,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: BacklinksIcon,
|
||||
name: inlineMenuNames.backlinks,
|
||||
nameKey: inlineMenuNamesKeys.backlinks,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
{
|
||||
type: INLINE_MENU_UI_TYPES.icon,
|
||||
icon: MoreIcon,
|
||||
name: inlineMenuNames.moreActions,
|
||||
nameKey: inlineMenuNamesKeys.moreActions,
|
||||
onClick: common_handler_for_inline_menu,
|
||||
},
|
||||
];
|
||||
|
||||
return inlineMenuData.filter(item => Boolean(item));
|
||||
};
|
||||
Reference in New Issue
Block a user