From e14e6d6bf5044447f10feab109244021be8f366d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A2=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BD=D1=86=D0=B5=D0=B2?= Date: Tue, 28 Nov 2023 14:07:30 +0100 Subject: [PATCH] chore: added toolbar to playground --- demo/Playground.scss | 1 + demo/Playground.tsx | 12 +- src/i18n/hints/en.json | 4 + src/i18n/hints/index.ts | 8 + src/i18n/hints/ru.json | 4 + src/i18n/menubar/en.json | 36 +++ src/i18n/menubar/index.ts | 8 + src/i18n/menubar/ru.json | 36 +++ src/icons/Mono.tsx | 20 ++ src/icons/Tabs.tsx | 20 ++ src/icons/index.ts | 133 ++++++++++ src/shortcuts/chars.ts | 16 ++ src/shortcuts/const.ts | 52 ++++ src/shortcuts/default.ts | 40 +++ src/shortcuts/formatter.ts | 44 ++++ src/shortcuts/index.ts | 4 + src/shortcuts/types.ts | 8 + src/toolbar/ToolbarListButton.scss | 5 +- src/toolbar/config/action-names.ts | 40 +++ src/toolbar/config/index.ts | 1 + src/toolbar/config/wysiwyg.ts | 386 +++++++++++++++++++++++++++++ src/toolbar/index.ts | 1 + 22 files changed, 875 insertions(+), 4 deletions(-) create mode 100644 src/i18n/hints/en.json create mode 100644 src/i18n/hints/index.ts create mode 100644 src/i18n/hints/ru.json create mode 100644 src/i18n/menubar/en.json create mode 100644 src/i18n/menubar/index.ts create mode 100644 src/i18n/menubar/ru.json create mode 100644 src/icons/Mono.tsx create mode 100644 src/icons/Tabs.tsx create mode 100644 src/icons/index.ts create mode 100644 src/shortcuts/chars.ts create mode 100644 src/shortcuts/const.ts create mode 100644 src/shortcuts/default.ts create mode 100644 src/shortcuts/formatter.ts create mode 100644 src/shortcuts/index.ts create mode 100644 src/shortcuts/types.ts create mode 100644 src/toolbar/config/action-names.ts create mode 100644 src/toolbar/config/index.ts create mode 100644 src/toolbar/config/wysiwyg.ts diff --git a/demo/Playground.scss b/demo/Playground.scss index e570f8c1..e4474c1e 100644 --- a/demo/Playground.scss +++ b/demo/Playground.scss @@ -38,6 +38,7 @@ &__editor-view { min-height: 100px; margin: 20px 0; + padding-left: 4px; } &__pm-selection { diff --git a/demo/Playground.tsx b/demo/Playground.tsx index a9739055..4ca651a3 100644 --- a/demo/Playground.tsx +++ b/demo/Playground.tsx @@ -16,7 +16,10 @@ import { Extension, ReactRenderStorage, ReactRendererComponent, + FlexToolbar, } from '../src'; +import {wHiddenData, wToolbarConfig} from '../src/toolbar/config/wysiwyg'; + import {PlaygroundHtmlPreview} from './HtmlPreview'; import {ProseMirrorDevTools} from './ProseMirrorDevTools'; import {PMSelection} from './PMSelection'; @@ -172,7 +175,14 @@ const Playground = React.memo((props) => {
- + editor.focus()} + data={wToolbarConfig} + hiddenActions={wHiddenData} + /> + diff --git a/src/i18n/hints/en.json b/src/i18n/hints/en.json new file mode 100644 index 00000000..16d4c1c1 --- /dev/null +++ b/src/i18n/hints/en.json @@ -0,0 +1,4 @@ +{ + "math_hint": "Math uses", + "math_hint_katex": "Katex syntax" +} diff --git a/src/i18n/hints/index.ts b/src/i18n/hints/index.ts new file mode 100644 index 00000000..46bc0d6a --- /dev/null +++ b/src/i18n/hints/index.ts @@ -0,0 +1,8 @@ +import {registerKeyset} from '../i18n'; + +import en from './en.json'; +import ru from './ru.json'; + +const KEYSET = 'hints'; + +export const i18n = registerKeyset(KEYSET, {en, ru}); diff --git a/src/i18n/hints/ru.json b/src/i18n/hints/ru.json new file mode 100644 index 00000000..ec9ea821 --- /dev/null +++ b/src/i18n/hints/ru.json @@ -0,0 +1,4 @@ +{ + "math_hint": "При создании формул используется", + "math_hint_katex": "синтаксис Katex" +} diff --git a/src/i18n/menubar/en.json b/src/i18n/menubar/en.json new file mode 100644 index 00000000..53507984 --- /dev/null +++ b/src/i18n/menubar/en.json @@ -0,0 +1,36 @@ +{ + "undo": "Undo", + "redo": "Redo", + "bold": "Bold", + "italic": "Italic", + "underline": "Underline", + "strike": "Strikethrough", + "mono": "Monospace", + "mark": "Marked", + "heading": "Heading", + "heading1": "Heading 1", + "heading2": "Heading 2", + "heading3": "Heading 3", + "heading4": "Heading 4", + "heading5": "Heading 5", + "heading6": "Heading 6", + "list": "List", + "ulist": "Bullet list", + "olist": "Ordered list", + "list__action_sink": "Sink item", + "list__action_lift": "Lift item", + "checkbox": "Checkbox", + "quote": "Quote", + "cut": "Cut", + "note": "Note", + "table": "Table", + "code": "Code", + "code_inline": "Inline code", + "codeblock": "Code block", + "hrule": "Separator", + "math": "Math", + "math_inline": "Inline math", + "math_block": "Math block", + "more_action": "More action", + "tabs": "Tabs" +} diff --git a/src/i18n/menubar/index.ts b/src/i18n/menubar/index.ts new file mode 100644 index 00000000..99096ab2 --- /dev/null +++ b/src/i18n/menubar/index.ts @@ -0,0 +1,8 @@ +import {registerKeyset} from '../i18n'; + +import en from './en.json'; +import ru from './ru.json'; + +const KEYSET = 'menubar'; + +export const i18n = registerKeyset(KEYSET, {en, ru}); diff --git a/src/i18n/menubar/ru.json b/src/i18n/menubar/ru.json new file mode 100644 index 00000000..7fcbf3c3 --- /dev/null +++ b/src/i18n/menubar/ru.json @@ -0,0 +1,36 @@ +{ + "undo": "Отменить", + "redo": "Повторить", + "bold": "Жирный", + "italic": "Курсив", + "mono": "Моноширинный", + "mark": "Выделенный", + "underline": "Подчеркивание", + "strike": "Зачеркивание", + "heading": "Заголовок", + "heading1": "Заголовок 1", + "heading2": "Заголовок 2", + "heading3": "Заголовок 3", + "heading4": "Заголовок 4", + "heading5": "Заголовок 5", + "heading6": "Заголовок 6", + "list": "Список", + "ulist": "Маркированный список", + "olist": "Нумерованный список", + "list__action_sink": "Увеличить отступ", + "list__action_lift": "Уменьшить отступ", + "checkbox": "Контрольный список", + "quote": "Цитата", + "cut": "Кат", + "note": "Примечание", + "table": "Таблица", + "code": "Код", + "code_inline": "Код в тексте", + "codeblock": "Блок кода", + "hrule": "Разделитель", + "math": "Формула", + "math_inline": "Формула в тексте", + "math_block": "Блок с формулой", + "more_action": "Другие действия", + "tabs": "Табы" +} diff --git a/src/icons/Mono.tsx b/src/icons/Mono.tsx new file mode 100644 index 00000000..82eb09f8 --- /dev/null +++ b/src/icons/Mono.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; +import {SVGProps} from 'react'; +const Mono = (props: SVGProps) => ( + + + +); +export default Mono; diff --git a/src/icons/Tabs.tsx b/src/icons/Tabs.tsx new file mode 100644 index 00000000..9873e470 --- /dev/null +++ b/src/icons/Tabs.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; +import {SVGProps} from 'react'; +const Tabs = (props: SVGProps) => ( + + + +); +export default Tabs; diff --git a/src/icons/index.ts b/src/icons/index.ts new file mode 100644 index 00000000..081b8f40 --- /dev/null +++ b/src/icons/index.ts @@ -0,0 +1,133 @@ +import TabsIcon from './Tabs'; +import MonoIcon from './Mono'; +import { + ArrowUturnCcwLeft as UndoIcon, + ArrowUturnCwRight as RedoIcon, + // + Bold as BoldIcon, + Italic as ItalicIcon, + Underline as UnderlineIcon, + Strikethrough as StrikethroughIcon, + FontCursor as MarkIcon, + // + Heading as HeadingIcon, + Heading1 as Heading1Icon, + Heading2 as Heading2Icon, + Heading3 as Heading3Icon, + Heading4 as Heading4Icon, + Heading5 as Heading5Icon, + Heading6 as Heading6Icon, + // + ListUl as ListBlIcon, + ListOl as ListOlIcon, + // + TextOutdent as LiftIcon, + TextIndent as SinkIcon, + // + Font as TextColorIcon, + // + Link as LinkIcon, + QuoteClose as QuoteIcon, + Scissors as CutIcon, + Sticker as NoteIcon, + Minus as HRuleIcon, + // + LayoutList as TableIcon, + // + ChevronsExpandHorizontal as IframeIcon, + SquareCheck as CheckListIcon, + Picture as ImageIcon, + // + Code as CodeInlineIcon, + FileCode as CodeBlockIcon, + // + Function as FunctionInlineIcon, + CurlyBracketsFunction as FunctionBlockIcon, +} from '@gravity-ui/icons'; +import {ToolbarIconData} from '../toolbar'; + +type Icon = + | 'undo' + | 'redo' + | 'bold' + | 'italic' + | 'underline' + | 'strikethrough' + | 'mono' + | 'mark' + | 'textColor' + | 'headline' + | 'h1' + | 'h2' + | 'h3' + | 'h4' + | 'h5' + | 'h6' + | 'bulletList' + | 'orderedList' + | 'sink' + | 'lift' + | 'cut' + | 'note' + | 'code' + | 'codeBlock' + | 'link' + | 'image' + | 'iframe' + | 'table' + | 'quote' + | 'checklist' + | 'horizontalRule' + | 'functionInline' + | 'functionBlock' + | 'tabs'; + +type Icons = Record; + +export const icons: Icons = { + undo: {data: UndoIcon}, + redo: {data: RedoIcon}, + + bold: {data: BoldIcon}, + italic: {data: ItalicIcon}, + underline: {data: UnderlineIcon}, + strikethrough: {data: StrikethroughIcon}, + mono: {data: MonoIcon}, + mark: {data: MarkIcon}, + + textColor: {data: TextColorIcon}, + + headline: {data: HeadingIcon}, + h1: {data: Heading1Icon}, + h2: {data: Heading2Icon}, + h3: {data: Heading3Icon}, + h4: {data: Heading4Icon}, + h5: {data: Heading5Icon}, + h6: {data: Heading6Icon}, + + bulletList: {data: ListBlIcon}, + orderedList: {data: ListOlIcon}, + + sink: {data: SinkIcon}, + lift: {data: LiftIcon}, + + cut: {data: CutIcon}, + note: {data: NoteIcon}, + + code: {data: CodeInlineIcon}, + codeBlock: {data: CodeBlockIcon}, + + link: {data: LinkIcon}, + image: {data: ImageIcon}, + iframe: {data: IframeIcon}, + + table: {data: TableIcon}, + quote: {data: QuoteIcon}, + checklist: {data: CheckListIcon}, + horizontalRule: {data: HRuleIcon}, + + functionInline: {data: FunctionInlineIcon}, + functionBlock: {data: FunctionBlockIcon}, + + tabs: {data: TabsIcon}, +}; diff --git a/src/shortcuts/chars.ts b/src/shortcuts/chars.ts new file mode 100644 index 00000000..55e3fc01 --- /dev/null +++ b/src/shortcuts/chars.ts @@ -0,0 +1,16 @@ +import {isMac} from '../utils/platform'; +import {ModKey as MK, Key as K} from './const'; +import {Chars} from './types'; + +const cmMac = { + [MK.Mod]: 'cmd', +}; + +const cmPC = { + [MK.Mod]: 'ctrl', +}; + +export const cmChars: Chars = { + [K.Esc]: 'Esc', + ...(isMac() ? cmMac : cmPC), +}; diff --git a/src/shortcuts/const.ts b/src/shortcuts/const.ts new file mode 100644 index 00000000..1b4ffa79 --- /dev/null +++ b/src/shortcuts/const.ts @@ -0,0 +1,52 @@ +export enum ModKey { + Mod = 'mod', + Alt = 'alt', + Option = 'alt', + Cmd = 'cmd', + Ctrl = 'ctrl', + Control = 'ctrl', + Shift = 'shift', + Tab = 'tab', +} + +export enum Key { + Enter = 'Enter', + Esc = 'Escape', +} + +export enum Action { + __debug = '__debug__', + + Cancel = 'cancel', + Submit = 'submit', + + Undo = 'undo', + Redo = 'redo', + + Bold = 'bold', + Italic = 'italic', + Underline = 'underline', + Strike = 'strike', + Code = 'code', + Link = 'link', + + Text = 'text', + Heading1 = 'h1', + Heading2 = 'h2', + Heading3 = 'h3', + Heading4 = 'h4', + Heading5 = 'h5', + Heading6 = 'h6', + + BulletList = 'ulist', + OrderedList = 'olist', + + LiftListItem = 'list__action_lift', + SinkListItem = 'list__action_sink', + + Quote = 'quote', + CodeBlock = 'codeblock', + + Cut = 'cut', + Note = 'note', +} diff --git a/src/shortcuts/default.ts b/src/shortcuts/default.ts new file mode 100644 index 00000000..e7083806 --- /dev/null +++ b/src/shortcuts/default.ts @@ -0,0 +1,40 @@ +import {Action as A, ModKey as MK, Key as K} from './const'; +import {formatter} from './formatter'; + +/* eslint-disable */ +formatter + .set(A.__debug, [MK.Mod, MK.Option, ']']) + + .set(A.Cancel, [K.Esc]) + .set(A.Submit, [MK.Mod, K.Enter]) + + .set(A.Undo, [MK.Mod, 'z']) + .set(A.Redo, [MK.Mod, MK.Shift, 'z']) + + .set(A.Bold, [MK.Mod, 'b']) + .set(A.Italic, [MK.Mod, 'i']) + .set(A.Underline, [MK.Mod, 'u']) + .set(A.Strike, [MK.Mod, MK.Shift, 's']) + .set(A.Code, [MK.Mod, 'e']) + .set(A.Link, [MK.Mod, 'k']) + + .set(A.Text, {pc: [MK.Ctrl, MK.Shift, '0'], mac: [MK.Cmd, MK.Option, '0']}) + .set(A.Heading1, {pc: [MK.Ctrl, MK.Shift, '1'], mac: [MK.Cmd, MK.Option, '1']}) + .set(A.Heading2, {pc: [MK.Ctrl, MK.Shift, '2'], mac: [MK.Cmd, MK.Option, '2']}) + .set(A.Heading3, {pc: [MK.Ctrl, MK.Shift, '3'], mac: [MK.Cmd, MK.Option, '3']}) + .set(A.Heading4, {pc: [MK.Ctrl, MK.Shift, '4'], mac: [MK.Cmd, MK.Option, '4']}) + .set(A.Heading5, {pc: [MK.Ctrl, MK.Shift, '5'], mac: [MK.Cmd, MK.Option, '5']}) + .set(A.Heading6, {pc: [MK.Ctrl, MK.Shift, '6'], mac: [MK.Cmd, MK.Option, '6']}) + + .set(A.BulletList, [MK.Mod, MK.Shift, 'l']) + .set(A.OrderedList, [MK.Mod, MK.Shift, 'm']) + + .set(A.SinkListItem, [MK.Tab]) + .set(A.LiftListItem, [MK.Shift, MK.Tab]) + + .set(A.Quote, [MK.Mod, MK.Shift, '.']) + .set(A.CodeBlock, {pc: [MK.Ctrl, MK.Shift, 'e'], mac: [MK.Cmd, MK.Option, 'e']}) + + .set(A.Cut, {pc: [MK.Ctrl, MK.Shift, '7'], mac: [MK.Cmd, MK.Option, '7']}) + .set(A.Note, {pc: [MK.Ctrl, MK.Shift, '8'], mac: [MK.Cmd, MK.Option, '8']}); +/* eslint-enable */ diff --git a/src/shortcuts/formatter.ts b/src/shortcuts/formatter.ts new file mode 100644 index 00000000..52e30f11 --- /dev/null +++ b/src/shortcuts/formatter.ts @@ -0,0 +1,44 @@ +import {ModKey as MK} from './const'; +import {cmChars} from './chars'; +import {Defs, PlatfrormDefs} from './types'; +import {isMac} from '../utils/platform'; +import {capitalize} from 'lodash'; + +class ShortCutFormatter { + #map = new Map(); + + set(name: string, defs: Defs | PlatfrormDefs) { + if (Array.isArray(defs)) { + this.#map.set(name, defs); + } else { + const platformedDefs = defs[isMac() ? 'mac' : 'pc']; + if (platformedDefs) { + this.#map.set(name, platformedDefs); + } + } + return this; + } + + toPM(name: string): string | null { + const defs = this.#map.get(name); + if (!defs) return null; + return defs.join('-'); + } + + toCM(name: string): string | null { + const defs = this.#map.get(name); + if (!defs) return null; + return defs + .map((str) => cmChars[str] ?? str) + .sort((a) => (a === MK.Shift ? -1 : 0)) + .map(capitalize) + .join('-'); + } + + toView(name: string): string | undefined { + const defs = this.#map.get(name); + return defs?.join('+'); + } +} + +export const formatter = new ShortCutFormatter(); diff --git a/src/shortcuts/index.ts b/src/shortcuts/index.ts new file mode 100644 index 00000000..e24cb06b --- /dev/null +++ b/src/shortcuts/index.ts @@ -0,0 +1,4 @@ +import './default'; + +export * from './const'; +export * from './formatter'; diff --git a/src/shortcuts/types.ts b/src/shortcuts/types.ts new file mode 100644 index 00000000..04004221 --- /dev/null +++ b/src/shortcuts/types.ts @@ -0,0 +1,8 @@ +export type Chars = Partial>; + +export type Defs = string[]; + +export type PlatfrormDefs = { + pc?: Defs; + mac?: Defs; +}; diff --git a/src/toolbar/ToolbarListButton.scss b/src/toolbar/ToolbarListButton.scss index 42f1b7ae..9dca69d1 100644 --- a/src/toolbar/ToolbarListButton.scss +++ b/src/toolbar/ToolbarListButton.scss @@ -1,8 +1,7 @@ .ye-toolbar-list-button { - // TODO: FIXME - // button with 2 icons - // 42px width &_arrow { + width: 42px; + .yc-button__text.yc-button__text.yc-button__text { margin: 0px 21px; } diff --git a/src/toolbar/config/action-names.ts b/src/toolbar/config/action-names.ts new file mode 100644 index 00000000..42543eb7 --- /dev/null +++ b/src/toolbar/config/action-names.ts @@ -0,0 +1,40 @@ +const names = [ + 'undo', + 'redo', + 'bold', + 'italic', + 'underline', + 'strike', + 'mono', + 'mark', + 'heading1', + 'heading2', + 'heading3', + 'heading4', + 'heading5', + 'heading6', + 'bulletList', + 'orderedList', + 'liftListItem', + 'sinkListItem', + 'checkbox', + 'quote', + 'yfm_cut', + 'yfm_note', + 'table', + 'code_inline', + 'code_block', + 'horizontalrule', + 'math_inline', + 'math_block', + 'tabs', +] as const; + +type ItemsType = L extends readonly (infer T)[] ? T : never; + +const namesObj = names.reduce, string>>((obj, val) => { + obj[val] = val; + return obj; +}, {} as Record, string>); + +export const ActionName: Readonly = namesObj; diff --git a/src/toolbar/config/index.ts b/src/toolbar/config/index.ts new file mode 100644 index 00000000..a9d73ae4 --- /dev/null +++ b/src/toolbar/config/index.ts @@ -0,0 +1 @@ +export * from './wysiwyg'; diff --git a/src/toolbar/config/wysiwyg.ts b/src/toolbar/config/wysiwyg.ts new file mode 100644 index 00000000..c4c73e81 --- /dev/null +++ b/src/toolbar/config/wysiwyg.ts @@ -0,0 +1,386 @@ +import {i18n} from '../../i18n/menubar'; +import {i18n as i18nHint} from '../../i18n/hints'; +import type {ActionStorage} from '../../core'; +import type {ToolbarData} from '../Toolbar'; +import type {ToolbarGroupData} from '../ToolbarGroup'; +import type {ToolbarListButtonData} from '../ToolbarListButton'; +import { + ToolbarDataType, + type ToolbarGroupItemData, + type ToolbarItemData, + type ToolbarSingleItemData, +} from '../types'; +import {Action as A, formatter as f} from '../../shortcuts'; + +import {icons} from '../../icons'; +import {ActionName} from './action-names'; + +export type WToolbarData = ToolbarData; +export type WToolbarItemData = ToolbarItemData; +export type WToolbarSingleItemData = ToolbarSingleItemData; +export type WToolbarGroupData = ToolbarGroupData; +export type WToolbarGroupItemData = ToolbarGroupItemData; +export type WToolbarListButtonData = ToolbarListButtonData; + +export const wHistoryGroupConfig: WToolbarGroupData = [ + { + id: ActionName.undo, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'undo'), + icon: icons.undo, + hotkey: f.toView(A.Undo), + disabledPopoverVisible: true, + exec: (e) => e.actions.undo.run(), + isActive: (e) => e.actions.undo.isActive(), + isEnable: (e) => e.actions.undo.isEnable(), + }, + { + id: ActionName.redo, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'redo'), + icon: icons.redo, + hotkey: f.toView(A.Redo), + disabledPopoverVisible: true, + exec: (e) => e.actions.redo.run(), + isActive: (e) => e.actions.redo.isActive(), + isEnable: (e) => e.actions.redo.isEnable(), + }, +]; + +/** Bold, Italic, Underline, Strike buttons group */ + +export const wBoldItemData: WToolbarSingleItemData = { + id: ActionName.bold, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'bold'), + icon: icons.bold, + hotkey: f.toView(A.Bold), + exec: (e) => e.actions.bold.run(), + isActive: (e) => e.actions.bold.isActive(), + isEnable: (e) => e.actions.bold.isEnable(), +}; + +export const wItalicItemData: WToolbarSingleItemData = { + id: ActionName.italic, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'italic'), + icon: icons.italic, + hotkey: f.toView(A.Italic), + exec: (e) => e.actions.italic.run(), + isActive: (e) => e.actions.italic.isActive(), + isEnable: (e) => e.actions.italic.isEnable(), +}; + +export const wBiusGroupConfig: WToolbarGroupData = [ + wBoldItemData, + wItalicItemData, + { + id: ActionName.underline, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'underline'), + icon: icons.underline, + hotkey: f.toView(A.Underline), + exec: (e) => e.actions.underline.run(), + isActive: (e) => e.actions.underline.isActive(), + isEnable: (e) => e.actions.underline.isEnable(), + }, + { + id: ActionName.strike, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'strike'), + icon: icons.strikethrough, + hotkey: f.toView(A.Strike), + exec: (e) => e.actions.strike.run(), + isActive: (e) => e.actions.strike.isActive(), + isEnable: (e) => e.actions.strike.isEnable(), + }, + { + id: ActionName.mono, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'mono'), + icon: icons.mono, + exec: (e) => e.actions.mono.run(), + isActive: (e) => e.actions.mono.isActive(), + isEnable: (e) => e.actions.mono.isEnable(), + }, + { + id: ActionName.mark, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'mark'), + icon: icons.mark, + exec: (e) => e.actions.mark.run(), + isActive: (e) => e.actions.mark.isActive(), + isEnable: (e) => e.actions.mark.isEnable(), + }, +]; + +export const wHeadingListConfig: WToolbarListButtonData = { + icon: icons.headline, + withArrow: true, + title: i18n.bind(null, 'heading'), + data: [ + { + id: ActionName.heading1, + title: i18n.bind(null, 'heading1'), + icon: icons.h1, + hotkey: f.toView(A.Heading1), + exec: (e) => e.actions.toH1.run(), + isActive: (e) => e.actions.toH1.isActive(), + isEnable: (e) => e.actions.toH1.isEnable(), + }, + { + id: ActionName.heading2, + title: i18n.bind(null, 'heading2'), + icon: icons.h2, + hotkey: f.toView(A.Heading2), + exec: (e) => e.actions.toH2.run(), + isActive: (e) => e.actions.toH2.isActive(), + isEnable: (e) => e.actions.toH2.isEnable(), + }, + { + id: ActionName.heading3, + title: i18n.bind(null, 'heading3'), + icon: icons.h3, + hotkey: f.toView(A.Heading3), + exec: (e) => e.actions.toH3.run(), + isActive: (e) => e.actions.toH3.isActive(), + isEnable: (e) => e.actions.toH3.isEnable(), + }, + { + id: ActionName.heading4, + title: i18n.bind(null, 'heading4'), + icon: icons.h4, + hotkey: f.toView(A.Heading4), + exec: (e) => e.actions.toH4.run(), + isActive: (e) => e.actions.toH4.isActive(), + isEnable: (e) => e.actions.toH4.isEnable(), + }, + { + id: ActionName.heading5, + title: i18n.bind(null, 'heading5'), + icon: icons.h5, + hotkey: f.toView(A.Heading5), + exec: (e) => e.actions.toH5.run(), + isActive: (e) => e.actions.toH5.isActive(), + isEnable: (e) => e.actions.toH5.isEnable(), + }, + { + id: ActionName.heading6, + title: i18n.bind(null, 'heading6'), + icon: icons.h6, + hotkey: f.toView(A.Heading6), + exec: (e) => e.actions.toH6.run(), + isActive: (e) => e.actions.toH6.isActive(), + isEnable: (e) => e.actions.toH6.isEnable(), + }, + ], +}; + +export const wListsListConfig: WToolbarListButtonData = { + icon: icons.bulletList, + withArrow: true, + title: i18n.bind(null, 'list'), + data: [ + { + id: ActionName.bulletList, + title: i18n.bind(null, 'ulist'), + icon: icons.bulletList, + hotkey: f.toView(A.BulletList), + exec: (e) => e.actions.toBulletList.run(), + isActive: (e) => e.actions.toBulletList.isActive(), + isEnable: (e) => e.actions.toBulletList.isEnable(), + }, + { + id: ActionName.orderedList, + title: i18n.bind(null, 'olist'), + icon: icons.orderedList, + hotkey: f.toView(A.OrderedList), + exec: (e) => e.actions.toOrderedList.run(), + isActive: (e) => e.actions.toOrderedList.isActive(), + isEnable: (e) => e.actions.toOrderedList.isEnable(), + }, + { + id: ActionName.sinkListItem, + title: i18n.bind(null, 'list__action_sink'), + icon: icons.sink, + hotkey: f.toView(A.SinkListItem), + disabledPopoverVisible: true, + exec: (e) => e.actions.sinkListItem.run(), + isActive: (e) => e.actions.sinkListItem.isActive(), + isEnable: (e) => e.actions.sinkListItem.isEnable(), + }, + { + id: ActionName.liftListItem, + title: i18n.bind(null, 'list__action_lift'), + icon: icons.lift, + hotkey: f.toView(A.LiftListItem), + disabledPopoverVisible: true, + exec: (e) => e.actions.liftListItem.run(), + isActive: (e) => e.actions.liftListItem.isActive(), + isEnable: (e) => e.actions.liftListItem.isEnable(), + }, + ], +}; + +export const wCheckboxItemData: WToolbarSingleItemData = { + id: ActionName.checkbox, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'checkbox'), + icon: icons.checklist, + exec: (e) => e.actions.addCheckbox.run(), + isActive: (e) => e.actions.addCheckbox.isActive(), + isEnable: (e) => e.actions.addCheckbox.isEnable(), +}; + +export const wQuoteItemData: WToolbarSingleItemData = { + id: ActionName.quote, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'quote'), + icon: icons.quote, + hotkey: f.toView(A.Quote), + exec: (e) => e.actions.quote.run(), + isActive: (e) => e.actions.quote.isActive(), + isEnable: (e) => e.actions.quote.isEnable(), +}; + +export const wCutItemData: WToolbarSingleItemData = { + id: ActionName.yfm_cut, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'cut'), + icon: icons.cut, + hotkey: f.toView(A.Cut), + exec: (e) => e.actions.toYfmCut.run(), + isActive: (e) => e.actions.toYfmCut.isActive(), + isEnable: (e) => e.actions.toYfmCut.isEnable(), +}; + +export const wNoteItemData: WToolbarSingleItemData = { + id: ActionName.yfm_note, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'note'), + icon: icons.note, + hotkey: f.toView(A.Note), + exec: (e) => e.actions.toYfmNote.run(), + isActive: (e) => e.actions.toYfmNote.isActive(), + isEnable: (e) => e.actions.toYfmNote.isEnable(), +}; + +export const wTableItemData: WToolbarSingleItemData = { + id: ActionName.table, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'table'), + icon: icons.table, + exec: (e) => e.actions.createYfmTable.run(), + isActive: (e) => e.actions.createYfmTable.isActive(), + isEnable: (e) => e.actions.createYfmTable.isEnable(), +}; + +export const wCodeItemData: WToolbarSingleItemData = { + id: ActionName.code_inline, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'code_inline'), + icon: icons.code, + hotkey: f.toView(A.Code), + exec: (e) => e.actions.code.run(), + isActive: (e) => e.actions.code.isActive(), + isEnable: (e) => e.actions.code.isEnable(), +}; + +export const wCodeBlockItemData: WToolbarItemData = { + id: ActionName.code_block, + title: i18n.bind(null, 'codeblock'), + icon: icons.codeBlock, + hotkey: f.toView(A.CodeBlock), + exec: (e) => e.actions.toCodeBlock.run(), + isActive: (e) => e.actions.toCodeBlock.isActive(), + isEnable: (e) => e.actions.toCodeBlock.isEnable(), +}; + +export const wCodeListConfig: WToolbarListButtonData = { + icon: icons.code, + withArrow: true, + title: i18n.bind(null, 'code'), + data: [wCodeItemData, wCodeBlockItemData], +}; + +export const wHruleItemData: WToolbarItemData = { + id: ActionName.horizontalrule, + title: i18n.bind(null, 'hrule'), + icon: icons.horizontalRule, + exec: (e) => e.actions.hRule.run(), + isActive: (e) => e.actions.hRule.isActive(), + isEnable: (e) => e.actions.hRule.isEnable(), +}; + +export const wMathInlineItemData: WToolbarSingleItemData = { + id: ActionName.math_inline, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'math_inline'), + icon: icons.functionInline, + hint: () => `${i18nHint.bind(null, 'math_hint')()} ${i18nHint.bind(null, 'math_hint_katex')()}`, + exec: (e) => e.actions.addMathInline.run(), + isActive: (e) => e.actions.addMathInline.isActive(), + isEnable: (e) => e.actions.addMathInline.isEnable(), +}; + +export const wTabsItemData: WToolbarSingleItemData = { + id: ActionName.tabs, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'tabs'), + icon: icons.tabs, + exec: (e) => e.actions.toYfmTabs.run(), + isActive: (e) => e.actions.toYfmTabs.isActive(), + isEnable: (e) => e.actions.toYfmTabs.isEnable(), +}; + +export const wMathBlockItemData: WToolbarSingleItemData = { + id: ActionName.math_block, + type: ToolbarDataType.SingleButton, + title: i18n.bind(null, 'math_block'), + icon: icons.functionBlock, + hint: () => `${i18nHint.bind(null, 'math_hint')()} ${i18nHint.bind(null, 'math_hint_katex')()}`, + exec: (e) => e.actions.toMathBlock.run(), + isActive: (e) => e.actions.toMathBlock.isActive(), + isEnable: (e) => e.actions.toMathBlock.isEnable(), +}; + +export const wMathListConfig: WToolbarListButtonData = { + icon: icons.functionInline, + withArrow: true, + title: i18n.bind(null, 'math'), + data: [wMathInlineItemData, wMathBlockItemData], +}; + +export const wHiddenData = [wHruleItemData, wTabsItemData]; + +/** prepared wysiwyg toolbar config */ +export const wToolbarConfig: WToolbarData = [ + wHistoryGroupConfig, + wBiusGroupConfig, + [ + { + id: 'heading', + type: ToolbarDataType.ListButton, + ...wHeadingListConfig, + }, + { + id: 'list', + type: ToolbarDataType.ListButton, + ...wListsListConfig, + }, + wNoteItemData, + wCutItemData, + wQuoteItemData, + { + id: 'code', + type: ToolbarDataType.ListButton, + ...wCodeListConfig, + }, + { + id: 'math', + type: ToolbarDataType.ListButton, + ...wMathListConfig, + }, + ], + [wTableItemData, wCheckboxItemData], +]; diff --git a/src/toolbar/index.ts b/src/toolbar/index.ts index 4c2fe879..cb0534b4 100644 --- a/src/toolbar/index.ts +++ b/src/toolbar/index.ts @@ -5,3 +5,4 @@ export * from './ToolbarButton'; export * from './ToolbarGroup'; export * from './ToolbarListButton'; export * from './FlexToolbar'; +export * from './config';