init: the first public commit for AFFiNE

This commit is contained in:
DarkSky
2022-07-22 15:49:21 +08:00
commit e3e3741393
1451 changed files with 108124 additions and 0 deletions
@@ -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));
};