@standardnotes/markdown-visual 1.3.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/asset-manifest.json +83 -0
- package/build/index.html +1 -0
- package/build/static/css/main.ea19efe4.css +3 -0
- package/build/static/css/main.ea19efe4.css.map +1 -0
- package/build/static/js/main.js +3 -0
- package/build/static/js/main.js.LICENSE.txt +59 -0
- package/build/static/js/main.js.map +1 -0
- package/build/static/media/KaTeX_AMS-Regular..ttf +0 -0
- package/build/static/media/KaTeX_AMS-Regular..woff +0 -0
- package/build/static/media/KaTeX_AMS-Regular..woff2 +0 -0
- package/build/static/media/KaTeX_Caligraphic-Bold..ttf +0 -0
- package/build/static/media/KaTeX_Caligraphic-Bold..woff +0 -0
- package/build/static/media/KaTeX_Caligraphic-Bold..woff2 +0 -0
- package/build/static/media/KaTeX_Caligraphic-Regular..ttf +0 -0
- package/build/static/media/KaTeX_Caligraphic-Regular..woff +0 -0
- package/build/static/media/KaTeX_Caligraphic-Regular..woff2 +0 -0
- package/build/static/media/KaTeX_Fraktur-Bold..ttf +0 -0
- package/build/static/media/KaTeX_Fraktur-Bold..woff +0 -0
- package/build/static/media/KaTeX_Fraktur-Bold..woff2 +0 -0
- package/build/static/media/KaTeX_Fraktur-Regular..ttf +0 -0
- package/build/static/media/KaTeX_Fraktur-Regular..woff +0 -0
- package/build/static/media/KaTeX_Fraktur-Regular..woff2 +0 -0
- package/build/static/media/KaTeX_Main-Bold..ttf +0 -0
- package/build/static/media/KaTeX_Main-Bold..woff +0 -0
- package/build/static/media/KaTeX_Main-Bold..woff2 +0 -0
- package/build/static/media/KaTeX_Main-BoldItalic..ttf +0 -0
- package/build/static/media/KaTeX_Main-BoldItalic..woff +0 -0
- package/build/static/media/KaTeX_Main-BoldItalic..woff2 +0 -0
- package/build/static/media/KaTeX_Main-Italic..ttf +0 -0
- package/build/static/media/KaTeX_Main-Italic..woff +0 -0
- package/build/static/media/KaTeX_Main-Italic..woff2 +0 -0
- package/build/static/media/KaTeX_Main-Regular..ttf +0 -0
- package/build/static/media/KaTeX_Main-Regular..woff +0 -0
- package/build/static/media/KaTeX_Main-Regular..woff2 +0 -0
- package/build/static/media/KaTeX_Math-BoldItalic..ttf +0 -0
- package/build/static/media/KaTeX_Math-BoldItalic..woff +0 -0
- package/build/static/media/KaTeX_Math-BoldItalic..woff2 +0 -0
- package/build/static/media/KaTeX_Math-Italic..ttf +0 -0
- package/build/static/media/KaTeX_Math-Italic..woff +0 -0
- package/build/static/media/KaTeX_Math-Italic..woff2 +0 -0
- package/build/static/media/KaTeX_SansSerif-Bold..ttf +0 -0
- package/build/static/media/KaTeX_SansSerif-Bold..woff +0 -0
- package/build/static/media/KaTeX_SansSerif-Bold..woff2 +0 -0
- package/build/static/media/KaTeX_SansSerif-Italic..ttf +0 -0
- package/build/static/media/KaTeX_SansSerif-Italic..woff +0 -0
- package/build/static/media/KaTeX_SansSerif-Italic..woff2 +0 -0
- package/build/static/media/KaTeX_SansSerif-Regular..ttf +0 -0
- package/build/static/media/KaTeX_SansSerif-Regular..woff +0 -0
- package/build/static/media/KaTeX_SansSerif-Regular..woff2 +0 -0
- package/build/static/media/KaTeX_Script-Regular..ttf +0 -0
- package/build/static/media/KaTeX_Script-Regular..woff +0 -0
- package/build/static/media/KaTeX_Script-Regular..woff2 +0 -0
- package/build/static/media/KaTeX_Size1-Regular..ttf +0 -0
- package/build/static/media/KaTeX_Size1-Regular..woff +0 -0
- package/build/static/media/KaTeX_Size1-Regular..woff2 +0 -0
- package/build/static/media/KaTeX_Size2-Regular..ttf +0 -0
- package/build/static/media/KaTeX_Size2-Regular..woff +0 -0
- package/build/static/media/KaTeX_Size2-Regular..woff2 +0 -0
- package/build/static/media/KaTeX_Size3-Regular..ttf +0 -0
- package/build/static/media/KaTeX_Size3-Regular..woff +0 -0
- package/build/static/media/KaTeX_Size3-Regular..woff2 +0 -0
- package/build/static/media/KaTeX_Size4-Regular..ttf +0 -0
- package/build/static/media/KaTeX_Size4-Regular..woff +0 -0
- package/build/static/media/KaTeX_Size4-Regular..woff2 +0 -0
- package/build/static/media/KaTeX_Typewriter-Regular..ttf +0 -0
- package/build/static/media/KaTeX_Typewriter-Regular..woff +0 -0
- package/build/static/media/KaTeX_Typewriter-Regular..woff2 +0 -0
- package/build/static/media/material-icons-outlined..woff +0 -0
- package/build/static/media/material-icons-outlined..woff2 +0 -0
- package/build/static/media/material-icons-round..woff +0 -0
- package/build/static/media/material-icons-round..woff2 +0 -0
- package/build/static/media/material-icons-sharp..woff +0 -0
- package/build/static/media/material-icons-sharp..woff2 +0 -0
- package/build/static/media/material-icons-two-tone..woff +0 -0
- package/build/static/media/material-icons-two-tone..woff2 +0 -0
- package/build/static/media/material-icons..woff +0 -0
- package/build/static/media/material-icons..woff2 +0 -0
- package/package.json +6 -2
- package/CHANGELOG.md +0 -108
- package/config-overrides.js +0 -2
- package/public/index.html +0 -31
- package/src/components/CodeMirror/index.tsx +0 -94
- package/src/components/CodeMirror/styles.scss +0 -55
- package/src/components/Milkdown/editor.ts +0 -62
- package/src/components/Milkdown/index.tsx +0 -77
- package/src/components/Milkdown/plugins/advanced-menu/README.md +0 -3
- package/src/components/Milkdown/plugins/advanced-menu/button.ts +0 -102
- package/src/components/Milkdown/plugins/advanced-menu/config.ts +0 -94
- package/src/components/Milkdown/plugins/advanced-menu/divider.ts +0 -37
- package/src/components/Milkdown/plugins/advanced-menu/index.ts +0 -64
- package/src/components/Milkdown/plugins/advanced-menu/manager.ts +0 -122
- package/src/components/Milkdown/plugins/advanced-menu/menuBar.ts +0 -108
- package/src/components/Milkdown/plugins/advanced-menu/select.ts +0 -163
- package/src/components/Milkdown/styles.scss +0 -209
- package/src/components/SplitView/index.tsx +0 -42
- package/src/components/SplitView/styles.scss +0 -51
- package/src/index.tsx +0 -215
- package/src/react-app-env.d.ts +0 -1
- package/src/setupTests.ts +0 -5
- package/src/stylesheets/main.scss +0 -45
- package/src/stylesheets/prism/material-light.css +0 -207
- package/tsconfig.json +0 -21
- /package/{public → build}/favicon.ico +0 -0
- /package/{public → build}/logo192.png +0 -0
- /package/{public → build}/logo512.png +0 -0
- /package/{public → build}/manifest.json +0 -0
- /package/{public → build}/robots.txt +0 -0
- /package/{public → build}/sample.ext.json +0 -0
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
|
|
3
|
-
import { css } from '@emotion/css'
|
|
4
|
-
import { CmdKey, commandsCtx, Ctx } from '@milkdown/core'
|
|
5
|
-
import type { Icon } from '@milkdown/design-system'
|
|
6
|
-
import type { EditorView } from '@milkdown/prose'
|
|
7
|
-
import type { Utils } from '@milkdown/utils'
|
|
8
|
-
|
|
9
|
-
import type { MenuCommonConfig } from './config'
|
|
10
|
-
|
|
11
|
-
type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> &
|
|
12
|
-
{
|
|
13
|
-
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>
|
|
14
|
-
}[Keys]
|
|
15
|
-
|
|
16
|
-
type Config<T = any> = {
|
|
17
|
-
type: 'button'
|
|
18
|
-
icon: Icon
|
|
19
|
-
key?: CmdKey<T>
|
|
20
|
-
callback?: () => void
|
|
21
|
-
options?: T
|
|
22
|
-
active?: (view?: EditorView) => boolean
|
|
23
|
-
alwaysVisible: boolean
|
|
24
|
-
} & MenuCommonConfig
|
|
25
|
-
|
|
26
|
-
export type ButtonConfig = RequireAtLeastOne<Config, 'key' | 'callback'>
|
|
27
|
-
|
|
28
|
-
export const button = (utils: Utils, config: Config, ctx: Ctx, view: EditorView) => {
|
|
29
|
-
const buttonStyle = utils.getStyle((themeTool) => {
|
|
30
|
-
return css`
|
|
31
|
-
border: 0;
|
|
32
|
-
box-sizing: unset;
|
|
33
|
-
width: 1.5rem;
|
|
34
|
-
height: 1.5rem;
|
|
35
|
-
padding: 0.25rem;
|
|
36
|
-
margin: 0.5rem;
|
|
37
|
-
flex-shrink: 0;
|
|
38
|
-
display: flex;
|
|
39
|
-
justify-content: center;
|
|
40
|
-
align-items: center;
|
|
41
|
-
background-color: ${themeTool.palette('surface')};
|
|
42
|
-
color: ${themeTool.palette('solid')};
|
|
43
|
-
transition: all 0.4s ease-in-out;
|
|
44
|
-
cursor: pointer;
|
|
45
|
-
&.active,
|
|
46
|
-
&:hover {
|
|
47
|
-
background-color: ${themeTool.palette('secondary', 0.12)};
|
|
48
|
-
color: ${themeTool.palette('primary')};
|
|
49
|
-
}
|
|
50
|
-
&:disabled {
|
|
51
|
-
display: none;
|
|
52
|
-
}
|
|
53
|
-
`
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
const $button = document.createElement('button')
|
|
57
|
-
$button.setAttribute('type', 'button')
|
|
58
|
-
$button.classList.add('button')
|
|
59
|
-
|
|
60
|
-
if (buttonStyle) {
|
|
61
|
-
$button.classList.add(buttonStyle)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const $label = utils.themeTool.slots.label(config.icon)
|
|
65
|
-
if ($label) {
|
|
66
|
-
$button.setAttribute('aria-label', $label)
|
|
67
|
-
$button.setAttribute('title', $label)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const $icon = utils.themeTool.slots.icon(config.icon)
|
|
71
|
-
$button.appendChild($icon)
|
|
72
|
-
$button.addEventListener('click', (e) => {
|
|
73
|
-
e.preventDefault()
|
|
74
|
-
e.stopPropagation()
|
|
75
|
-
|
|
76
|
-
config.callback && config.callback()
|
|
77
|
-
config.key && ctx.get(commandsCtx).call(config.key, config.options)
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
if (config.active) {
|
|
81
|
-
const active = config.active()
|
|
82
|
-
if (active) {
|
|
83
|
-
$button.classList.add('active')
|
|
84
|
-
} else {
|
|
85
|
-
$button.classList.remove('active')
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (config.alwaysVisible) {
|
|
90
|
-
$button.removeAttribute('disabled')
|
|
91
|
-
return $button
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const disabled = !view.editable || (config.disabled && config.disabled(view))
|
|
95
|
-
if (disabled) {
|
|
96
|
-
$button.setAttribute('disabled', 'true')
|
|
97
|
-
} else {
|
|
98
|
-
$button.removeAttribute('disabled')
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return $button
|
|
102
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
InsertHr,
|
|
3
|
-
InsertImage,
|
|
4
|
-
LiftListItem,
|
|
5
|
-
SinkListItem,
|
|
6
|
-
WrapInBlockquote,
|
|
7
|
-
WrapInBulletList,
|
|
8
|
-
WrapInOrderedList,
|
|
9
|
-
} from '@milkdown/preset-commonmark'
|
|
10
|
-
import { InsertTable, TurnIntoTaskList } from '@milkdown/preset-gfm'
|
|
11
|
-
import { EditorView, liftListItem, sinkListItem, wrapIn } from '@milkdown/prose'
|
|
12
|
-
import { ButtonConfig } from './button'
|
|
13
|
-
import { SelectConfig } from './select'
|
|
14
|
-
|
|
15
|
-
export type MenuCommonConfig = {
|
|
16
|
-
disabled?: (view: EditorView) => boolean
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type MenuConfigItem = SelectConfig | ButtonConfig
|
|
20
|
-
export type MenuConfig = Array<Array<MenuConfigItem>>
|
|
21
|
-
|
|
22
|
-
export const menuConfig: any = [
|
|
23
|
-
[
|
|
24
|
-
{
|
|
25
|
-
type: 'button',
|
|
26
|
-
icon: 'bulletList',
|
|
27
|
-
key: WrapInBulletList,
|
|
28
|
-
disabled: (view: EditorView) => {
|
|
29
|
-
const { state } = view
|
|
30
|
-
return !wrapIn(state.schema.nodes.bullet_list)(state)
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
type: 'button',
|
|
35
|
-
icon: 'orderedList',
|
|
36
|
-
key: WrapInOrderedList,
|
|
37
|
-
disabled: (view: EditorView) => {
|
|
38
|
-
const { state } = view
|
|
39
|
-
return !wrapIn(state.schema.nodes.ordered_list)(state)
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
type: 'button',
|
|
44
|
-
icon: 'taskList',
|
|
45
|
-
key: TurnIntoTaskList,
|
|
46
|
-
disabled: (view: EditorView) => {
|
|
47
|
-
const { state } = view
|
|
48
|
-
return !wrapIn(state.schema.nodes.task_list_item)(state)
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
type: 'button',
|
|
53
|
-
icon: 'liftList',
|
|
54
|
-
key: LiftListItem,
|
|
55
|
-
disabled: (view: EditorView) => {
|
|
56
|
-
const { state } = view
|
|
57
|
-
return !liftListItem(state.schema.nodes.list_item)(state)
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
type: 'button',
|
|
62
|
-
icon: 'sinkList',
|
|
63
|
-
key: SinkListItem,
|
|
64
|
-
disabled: (view: EditorView) => {
|
|
65
|
-
const { state } = view
|
|
66
|
-
return !sinkListItem(state.schema.nodes.list_item)(state)
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
[
|
|
71
|
-
{
|
|
72
|
-
type: 'button',
|
|
73
|
-
icon: 'image',
|
|
74
|
-
key: InsertImage,
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
type: 'button',
|
|
78
|
-
icon: 'table',
|
|
79
|
-
key: InsertTable,
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
[
|
|
83
|
-
{
|
|
84
|
-
type: 'button',
|
|
85
|
-
icon: 'quote',
|
|
86
|
-
key: WrapInBlockquote,
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
type: 'button',
|
|
90
|
-
icon: 'divider',
|
|
91
|
-
key: InsertHr,
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
|
-
]
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
|
|
3
|
-
import { css } from '@emotion/css'
|
|
4
|
-
import { Utils } from '@milkdown/utils'
|
|
5
|
-
|
|
6
|
-
export type DividerConfig = {
|
|
7
|
-
type: 'divider'
|
|
8
|
-
group: HTMLElement[]
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const divider = (utils: Utils, config: DividerConfig) => {
|
|
12
|
-
const dividerStyle = utils.getStyle((themeTool) => {
|
|
13
|
-
return css`
|
|
14
|
-
flex-shrink: 0;
|
|
15
|
-
width: ${themeTool.size.lineWidth};
|
|
16
|
-
background-color: ${themeTool.palette('line')};
|
|
17
|
-
margin: 0.75rem 1rem;
|
|
18
|
-
`
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
const $divider = document.createElement('div')
|
|
22
|
-
$divider.classList.add('divider')
|
|
23
|
-
|
|
24
|
-
if (dividerStyle) {
|
|
25
|
-
$divider.classList.add(dividerStyle)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const disabled = config.group.every((x) => x.getAttribute('disabled') || x.classList.contains('disabled'))
|
|
29
|
-
|
|
30
|
-
if (disabled) {
|
|
31
|
-
$divider.classList.add('disabled')
|
|
32
|
-
} else {
|
|
33
|
-
$divider.classList.remove('disabled')
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return $divider
|
|
37
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
|
|
3
|
-
import { createCmd, createCmdKey, Ctx } from '@milkdown/core'
|
|
4
|
-
import { EditorView, Plugin, PluginKey, selectParentNode } from '@milkdown/prose'
|
|
5
|
-
import { createPlugin } from '@milkdown/utils'
|
|
6
|
-
|
|
7
|
-
import { MenuConfig, menuConfig } from './config'
|
|
8
|
-
import { Manager } from './manager'
|
|
9
|
-
import { HandleDOM, MenuBar } from './menuBar'
|
|
10
|
-
|
|
11
|
-
export type Options = {
|
|
12
|
-
config: MenuConfig
|
|
13
|
-
domHandler: HandleDOM
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { menuConfig } from './config'
|
|
17
|
-
|
|
18
|
-
export const menu = createPlugin<string, Options>((utils, options) => {
|
|
19
|
-
const config = options?.config ?? menuConfig
|
|
20
|
-
const domHandler = options?.domHandler
|
|
21
|
-
|
|
22
|
-
let restoreDOM: (() => void) | null = null
|
|
23
|
-
let menu: HTMLDivElement | null = null
|
|
24
|
-
let manager: Manager | null = null
|
|
25
|
-
|
|
26
|
-
const SelectParent = createCmdKey()
|
|
27
|
-
|
|
28
|
-
const initIfNecessary = (ctx: Ctx, editorView: EditorView) => {
|
|
29
|
-
if (!menu) {
|
|
30
|
-
const [_menu, _restoreDOM] = MenuBar(utils, editorView, ctx, domHandler)
|
|
31
|
-
menu = _menu
|
|
32
|
-
restoreDOM = () => {
|
|
33
|
-
_restoreDOM()
|
|
34
|
-
menu = null
|
|
35
|
-
manager = null
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!manager) {
|
|
40
|
-
manager = new Manager(config, utils, ctx, menu, editorView)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
commands: () => [createCmd(SelectParent, () => selectParentNode)],
|
|
46
|
-
prosePlugins: (_, ctx) => {
|
|
47
|
-
const plugin = new Plugin({
|
|
48
|
-
key: new PluginKey('milkdown-advanced-menu'),
|
|
49
|
-
view: (editorView) => {
|
|
50
|
-
initIfNecessary(ctx, editorView)
|
|
51
|
-
if (editorView.editable) {
|
|
52
|
-
manager?.update(editorView)
|
|
53
|
-
}
|
|
54
|
-
return {
|
|
55
|
-
update: (view) => manager?.update(view),
|
|
56
|
-
destroy: () => restoreDOM?.(),
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
return [plugin]
|
|
62
|
-
},
|
|
63
|
-
}
|
|
64
|
-
})
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
|
|
3
|
-
import { Ctx } from '@milkdown/core'
|
|
4
|
-
import { EditorView } from '@milkdown/prose'
|
|
5
|
-
import { Utils } from '@milkdown/utils'
|
|
6
|
-
|
|
7
|
-
import { button, ButtonConfig } from './button'
|
|
8
|
-
import { MenuConfig, MenuConfigItem } from './config'
|
|
9
|
-
import { divider, DividerConfig } from './divider'
|
|
10
|
-
import { select, SelectConfig } from './select'
|
|
11
|
-
|
|
12
|
-
type InnerConfig = (MenuConfigItem | DividerConfig) & { $: HTMLElement }
|
|
13
|
-
|
|
14
|
-
export class Manager {
|
|
15
|
-
private config: InnerConfig[]
|
|
16
|
-
|
|
17
|
-
constructor(originalConfig: MenuConfig, private utils: Utils, private ctx: Ctx, menu: HTMLElement, view: EditorView) {
|
|
18
|
-
this.config = originalConfig
|
|
19
|
-
.map((xs) =>
|
|
20
|
-
xs.map((x) => ({
|
|
21
|
-
...x,
|
|
22
|
-
$: this.$create(x, view),
|
|
23
|
-
})),
|
|
24
|
-
)
|
|
25
|
-
.map((xs, i): Array<InnerConfig> => {
|
|
26
|
-
if (i === originalConfig.length - 1) {
|
|
27
|
-
return xs
|
|
28
|
-
}
|
|
29
|
-
const dividerConfig: DividerConfig = {
|
|
30
|
-
type: 'divider',
|
|
31
|
-
group: xs.map((x) => x.$),
|
|
32
|
-
}
|
|
33
|
-
return [
|
|
34
|
-
...xs,
|
|
35
|
-
{
|
|
36
|
-
...dividerConfig,
|
|
37
|
-
$: this.$create(dividerConfig, view),
|
|
38
|
-
},
|
|
39
|
-
]
|
|
40
|
-
})
|
|
41
|
-
.flat()
|
|
42
|
-
|
|
43
|
-
this.config.forEach((x) => menu.appendChild(x.$))
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public update(view: EditorView) {
|
|
47
|
-
const enabled = view.editable
|
|
48
|
-
|
|
49
|
-
this.config.forEach((config) => {
|
|
50
|
-
switch (config.type) {
|
|
51
|
-
case 'button': {
|
|
52
|
-
if (config.active) {
|
|
53
|
-
const active = config.active(view)
|
|
54
|
-
if (active) {
|
|
55
|
-
config.$.classList.add('active')
|
|
56
|
-
} else {
|
|
57
|
-
config.$.classList.remove('active')
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (config.alwaysVisible) {
|
|
62
|
-
config.$.removeAttribute('disabled')
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const disabled = !enabled || (config.disabled && config.disabled(view))
|
|
67
|
-
if (disabled) {
|
|
68
|
-
config.$.setAttribute('disabled', 'true')
|
|
69
|
-
} else {
|
|
70
|
-
config.$.removeAttribute('disabled')
|
|
71
|
-
}
|
|
72
|
-
break
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
case 'select': {
|
|
76
|
-
if (config.alwaysVisible) {
|
|
77
|
-
config.$.removeAttribute('disabled')
|
|
78
|
-
return
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const disabled = !enabled || (config.disabled && config.disabled(view))
|
|
82
|
-
if (disabled) {
|
|
83
|
-
config.$.classList.add('disabled')
|
|
84
|
-
config.$.children[0].setAttribute('disabled', 'true')
|
|
85
|
-
} else {
|
|
86
|
-
config.$.classList.remove('disabled')
|
|
87
|
-
config.$.children[0].removeAttribute('disabled')
|
|
88
|
-
}
|
|
89
|
-
break
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
case 'divider': {
|
|
93
|
-
const disabled = config.group.every((x) => x.getAttribute('disabled') || x.classList.contains('disabled'))
|
|
94
|
-
if (disabled) {
|
|
95
|
-
config.$.classList.add('disabled')
|
|
96
|
-
} else {
|
|
97
|
-
config.$.classList.remove('disabled')
|
|
98
|
-
}
|
|
99
|
-
break
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
private $create(item: ButtonConfig | DividerConfig | SelectConfig, view: EditorView): HTMLElement {
|
|
106
|
-
const { utils, ctx } = this
|
|
107
|
-
|
|
108
|
-
switch (item.type) {
|
|
109
|
-
case 'button': {
|
|
110
|
-
return button(utils, item, ctx, view)
|
|
111
|
-
}
|
|
112
|
-
case 'select': {
|
|
113
|
-
return select(utils, item, ctx, view)
|
|
114
|
-
}
|
|
115
|
-
case 'divider': {
|
|
116
|
-
return divider(utils, item)
|
|
117
|
-
}
|
|
118
|
-
default:
|
|
119
|
-
throw new Error()
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
|
|
3
|
-
import { css } from '@emotion/css'
|
|
4
|
-
import { Ctx, rootCtx } from '@milkdown/core'
|
|
5
|
-
import { EditorView } from '@milkdown/prose'
|
|
6
|
-
import { Utils } from '@milkdown/utils'
|
|
7
|
-
|
|
8
|
-
export const MenuBar = (utils: Utils, view: EditorView, ctx: Ctx, domHandler: HandleDOM = defaultDOMHandler) => {
|
|
9
|
-
const menuWrapper = document.createElement('div')
|
|
10
|
-
menuWrapper.classList.add('milkdown-menu-wrapper')
|
|
11
|
-
const menu = document.createElement('div')
|
|
12
|
-
menu.classList.add('milkdown-menu')
|
|
13
|
-
|
|
14
|
-
const editorDOM = view.dom as HTMLDivElement
|
|
15
|
-
|
|
16
|
-
const editorWrapperStyle = utils.getStyle((themeTool) => {
|
|
17
|
-
return themeTool.mixin.scrollbar('y')
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
if (editorWrapperStyle) {
|
|
21
|
-
editorDOM.classList.add(editorWrapperStyle)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const menuStyle = utils.getStyle((themeTool) => {
|
|
25
|
-
const border = themeTool.mixin.border()
|
|
26
|
-
const scrollbar = themeTool.mixin.scrollbar('x')
|
|
27
|
-
const style = css`
|
|
28
|
-
box-sizing: border-box;
|
|
29
|
-
width: 100%;
|
|
30
|
-
display: flex;
|
|
31
|
-
flex-wrap: nowrap;
|
|
32
|
-
overflow-x: auto;
|
|
33
|
-
${border};
|
|
34
|
-
${scrollbar};
|
|
35
|
-
background: ${themeTool.palette('surface')};
|
|
36
|
-
-webkit-overflow-scrolling: auto;
|
|
37
|
-
.disabled {
|
|
38
|
-
display: none;
|
|
39
|
-
}
|
|
40
|
-
`
|
|
41
|
-
return style
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
if (menuStyle) {
|
|
45
|
-
menuStyle.split(' ').forEach((x) => menu.classList.add(x))
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const root = ctx.get(rootCtx)
|
|
49
|
-
|
|
50
|
-
const editorRoot = getRoot(root) as HTMLElement
|
|
51
|
-
const milkdownDOM = editorDOM.parentElement
|
|
52
|
-
|
|
53
|
-
if (!milkdownDOM) {
|
|
54
|
-
throw new Error('No parent node found')
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
domHandler({
|
|
58
|
-
menu,
|
|
59
|
-
menuWrapper,
|
|
60
|
-
editorDOM,
|
|
61
|
-
editorRoot,
|
|
62
|
-
milkdownDOM,
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
const restoreDOM = () => {
|
|
66
|
-
restore({
|
|
67
|
-
menu,
|
|
68
|
-
menuWrapper,
|
|
69
|
-
editorDOM,
|
|
70
|
-
editorRoot,
|
|
71
|
-
milkdownDOM,
|
|
72
|
-
})
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return [menu, restoreDOM] as const
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export type HandleDOMParams = {
|
|
79
|
-
menu: HTMLDivElement
|
|
80
|
-
menuWrapper: HTMLDivElement
|
|
81
|
-
editorRoot: HTMLElement
|
|
82
|
-
milkdownDOM: HTMLElement
|
|
83
|
-
editorDOM: HTMLDivElement
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export type HandleDOM = (params: HandleDOMParams) => void
|
|
87
|
-
|
|
88
|
-
const restore: HandleDOM = ({ milkdownDOM, editorRoot, menu, menuWrapper }) => {
|
|
89
|
-
editorRoot.appendChild(milkdownDOM)
|
|
90
|
-
menuWrapper.remove()
|
|
91
|
-
menu.remove()
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const defaultDOMHandler: HandleDOM = ({ menu, menuWrapper, editorRoot, milkdownDOM }) => {
|
|
95
|
-
menuWrapper.appendChild(menu)
|
|
96
|
-
editorRoot.replaceChild(menuWrapper, milkdownDOM)
|
|
97
|
-
menuWrapper.appendChild(milkdownDOM)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const getRoot = (root: string | Node | null | undefined) => {
|
|
101
|
-
if (!root) return document.body
|
|
102
|
-
if (typeof root === 'string') {
|
|
103
|
-
const el = document.querySelector(root)
|
|
104
|
-
if (el) return el
|
|
105
|
-
return document.body
|
|
106
|
-
}
|
|
107
|
-
return root
|
|
108
|
-
}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
|
|
3
|
-
import { css } from '@emotion/css'
|
|
4
|
-
import { CmdKey, commandsCtx, Ctx } from '@milkdown/core'
|
|
5
|
-
import { EditorView } from '@milkdown/prose'
|
|
6
|
-
import { Utils } from '@milkdown/utils'
|
|
7
|
-
|
|
8
|
-
import type { MenuCommonConfig } from './config'
|
|
9
|
-
|
|
10
|
-
type SelectOptions = {
|
|
11
|
-
id: string
|
|
12
|
-
text: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type SelectConfig<T = any> = {
|
|
16
|
-
type: 'select'
|
|
17
|
-
text: string
|
|
18
|
-
options: SelectOptions[]
|
|
19
|
-
active?: (view: EditorView) => string
|
|
20
|
-
onSelect: (id: string, view: EditorView) => [key: CmdKey<T>, info?: T]
|
|
21
|
-
alwaysVisible: boolean
|
|
22
|
-
} & MenuCommonConfig
|
|
23
|
-
|
|
24
|
-
export const select = (utils: Utils, config: SelectConfig, ctx: Ctx, view: EditorView) => {
|
|
25
|
-
const selectStyle = utils.getStyle((themeTool) => {
|
|
26
|
-
return css`
|
|
27
|
-
flex-shrink: 0;
|
|
28
|
-
font-weight: 500;
|
|
29
|
-
font-size: 0.875rem;
|
|
30
|
-
${themeTool.mixin.border('right')};
|
|
31
|
-
${themeTool.mixin.border('left')};
|
|
32
|
-
.menu-selector {
|
|
33
|
-
border: 0;
|
|
34
|
-
box-sizing: unset;
|
|
35
|
-
cursor: pointer;
|
|
36
|
-
font: inherit;
|
|
37
|
-
text-align: left;
|
|
38
|
-
justify-content: space-between;
|
|
39
|
-
align-items: center;
|
|
40
|
-
color: ${themeTool.palette('neutral', 0.87)};
|
|
41
|
-
display: flex;
|
|
42
|
-
padding: 0.25rem 0.5rem;
|
|
43
|
-
margin: 0.5rem;
|
|
44
|
-
background: ${themeTool.palette('secondary', 0.12)};
|
|
45
|
-
width: 10.375rem;
|
|
46
|
-
&:disabled {
|
|
47
|
-
display: none;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
.menu-selector-value {
|
|
51
|
-
flex: 1;
|
|
52
|
-
white-space: nowrap;
|
|
53
|
-
text-overflow: ellipsis;
|
|
54
|
-
}
|
|
55
|
-
.menu-selector-list {
|
|
56
|
-
width: calc(12.375rem);
|
|
57
|
-
position: absolute;
|
|
58
|
-
top: 3rem;
|
|
59
|
-
background: ${themeTool.palette('surface')};
|
|
60
|
-
${themeTool.mixin.border()};
|
|
61
|
-
${themeTool.mixin.shadow()};
|
|
62
|
-
border-bottom-left-radius: ${themeTool.size.radius};
|
|
63
|
-
border-bottom-right-radius: ${themeTool.size.radius};
|
|
64
|
-
z-index: 3;
|
|
65
|
-
}
|
|
66
|
-
.menu-selector-list-item {
|
|
67
|
-
background-color: transparent;
|
|
68
|
-
border: 0;
|
|
69
|
-
cursor: pointer;
|
|
70
|
-
display: block;
|
|
71
|
-
font: inherit;
|
|
72
|
-
text-align: left;
|
|
73
|
-
padding: 0.75rem 1rem;
|
|
74
|
-
line-height: 1.5rem;
|
|
75
|
-
width: 100%;
|
|
76
|
-
color: ${themeTool.palette('neutral', 0.87)};
|
|
77
|
-
&:hover {
|
|
78
|
-
background: ${themeTool.palette('secondary', 0.12)};
|
|
79
|
-
color: ${themeTool.palette('primary')};
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
&.fold {
|
|
83
|
-
border-color: transparent;
|
|
84
|
-
.menu-selector {
|
|
85
|
-
background: unset;
|
|
86
|
-
}
|
|
87
|
-
.menu-selector-list {
|
|
88
|
-
display: none;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
`
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
const selectorWrapper = document.createElement('div')
|
|
95
|
-
selectorWrapper.classList.add('menu-selector-wrapper', 'fold')
|
|
96
|
-
|
|
97
|
-
const selector = document.createElement('button')
|
|
98
|
-
selector.setAttribute('type', 'button')
|
|
99
|
-
selector.classList.add('menu-selector', 'fold')
|
|
100
|
-
selector.addEventListener('mousedown', (e) => {
|
|
101
|
-
e.preventDefault()
|
|
102
|
-
e.stopPropagation()
|
|
103
|
-
selectorWrapper.classList.toggle('fold')
|
|
104
|
-
selectorList.style.left = `${
|
|
105
|
-
selectorWrapper.getBoundingClientRect().left - view.dom.getBoundingClientRect().left
|
|
106
|
-
}px`
|
|
107
|
-
})
|
|
108
|
-
view.dom.addEventListener('click', () => {
|
|
109
|
-
selectorWrapper.classList.add('fold')
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
const selectorValue = document.createElement('span')
|
|
113
|
-
selectorValue.classList.add('menu-selector-value')
|
|
114
|
-
selectorValue.textContent = config.text
|
|
115
|
-
|
|
116
|
-
const selectorButton = utils.themeTool.slots.icon('downArrow')
|
|
117
|
-
selectorButton.setAttribute('aria-hidden', 'true')
|
|
118
|
-
|
|
119
|
-
selectorWrapper.appendChild(selector)
|
|
120
|
-
selector.appendChild(selectorValue)
|
|
121
|
-
selector.appendChild(selectorButton)
|
|
122
|
-
|
|
123
|
-
const selectorList = document.createElement('div')
|
|
124
|
-
selectorList.classList.add('menu-selector-list')
|
|
125
|
-
config.options.forEach((option) => {
|
|
126
|
-
const selectorListItem = document.createElement('button')
|
|
127
|
-
selectorListItem.setAttribute('type', 'button')
|
|
128
|
-
selectorListItem.dataset.id = option.id
|
|
129
|
-
selectorListItem.textContent = option.text
|
|
130
|
-
selectorListItem.classList.add('menu-selector-list-item')
|
|
131
|
-
selectorList.appendChild(selectorListItem)
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
selectorList.addEventListener('mousedown', (e) => {
|
|
135
|
-
const { target } = e
|
|
136
|
-
if (target instanceof HTMLButtonElement && target.dataset.id) {
|
|
137
|
-
ctx.get(commandsCtx).call(...config.onSelect(target.dataset.id, view))
|
|
138
|
-
selectorWrapper.classList.add('fold')
|
|
139
|
-
}
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
selectorWrapper.appendChild(selectorList)
|
|
143
|
-
|
|
144
|
-
if (selectStyle) {
|
|
145
|
-
selectorWrapper.classList.add(selectStyle)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (config.alwaysVisible) {
|
|
149
|
-
selector.removeAttribute('disabled')
|
|
150
|
-
return selectorWrapper
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const disabled = !view.editable || (config.disabled && config.disabled(view))
|
|
154
|
-
if (disabled) {
|
|
155
|
-
selector.classList.add('disabled')
|
|
156
|
-
selector.children[0].setAttribute('disabled', 'true')
|
|
157
|
-
} else {
|
|
158
|
-
selector.classList.remove('disabled')
|
|
159
|
-
selector.children[0].removeAttribute('disabled')
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return selectorWrapper
|
|
163
|
-
}
|