@milkdown/plugin-slash 6.5.4 → 7.0.0-next.0

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.
Files changed (42) hide show
  1. package/lib/index.d.ts +2 -13
  2. package/lib/index.d.ts.map +1 -1
  3. package/lib/index.es.js +80 -382
  4. package/lib/index.es.js.map +1 -1
  5. package/lib/slash-plugin.d.ts +11 -0
  6. package/lib/slash-plugin.d.ts.map +1 -0
  7. package/lib/slash-provider.d.ts +20 -0
  8. package/lib/slash-provider.d.ts.map +1 -0
  9. package/package.json +12 -8
  10. package/src/index.ts +2 -34
  11. package/src/slash-plugin.ts +31 -0
  12. package/src/slash-provider.ts +119 -0
  13. package/lib/config.d.ts +0 -21
  14. package/lib/config.d.ts.map +0 -1
  15. package/lib/item.d.ts +0 -12
  16. package/lib/item.d.ts.map +0 -1
  17. package/lib/prose-plugin/dropdown.d.ts +0 -8
  18. package/lib/prose-plugin/dropdown.d.ts.map +0 -1
  19. package/lib/prose-plugin/index.d.ts +0 -7
  20. package/lib/prose-plugin/index.d.ts.map +0 -1
  21. package/lib/prose-plugin/input.d.ts +0 -14
  22. package/lib/prose-plugin/input.d.ts.map +0 -1
  23. package/lib/prose-plugin/props.d.ts +0 -11
  24. package/lib/prose-plugin/props.d.ts.map +0 -1
  25. package/lib/prose-plugin/status.d.ts +0 -14
  26. package/lib/prose-plugin/status.d.ts.map +0 -1
  27. package/lib/prose-plugin/view.d.ts +0 -13
  28. package/lib/prose-plugin/view.d.ts.map +0 -1
  29. package/lib/style.d.ts +0 -3
  30. package/lib/style.d.ts.map +0 -1
  31. package/lib/utility.d.ts +0 -14
  32. package/lib/utility.d.ts.map +0 -1
  33. package/src/config.ts +0 -142
  34. package/src/item.ts +0 -21
  35. package/src/prose-plugin/dropdown.ts +0 -50
  36. package/src/prose-plugin/index.ts +0 -26
  37. package/src/prose-plugin/input.ts +0 -142
  38. package/src/prose-plugin/props.ts +0 -104
  39. package/src/prose-plugin/status.ts +0 -37
  40. package/src/prose-plugin/view.ts +0 -112
  41. package/src/style.ts +0 -76
  42. package/src/utility.ts +0 -85
@@ -0,0 +1,20 @@
1
+ import type { EditorState } from '@milkdown/prose/state';
2
+ import type { EditorView } from '@milkdown/prose/view';
3
+ import type { Instance, Props } from 'tippy.js';
4
+ export type SlashProviderOptions = {
5
+ content: HTMLElement;
6
+ tippyOptions?: Partial<Props>;
7
+ debounce?: number;
8
+ shouldShow?: (view: EditorView, prevState?: EditorState) => boolean;
9
+ };
10
+ export declare class SlashProvider {
11
+ #private;
12
+ constructor(options: SlashProviderOptions);
13
+ update: (view: EditorView, prevState?: EditorState) => void;
14
+ getContent: (view: EditorView) => string | undefined;
15
+ destroy: () => void;
16
+ show: () => void;
17
+ hide: () => void;
18
+ getInstance: () => Instance<Props> | undefined;
19
+ }
20
+ //# sourceMappingURL=slash-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slash-provider.d.ts","sourceRoot":"","sources":["../src/slash-provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAG/C,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,WAAW,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,KAAK,OAAO,CAAA;CACpE,CAAA;AAED,qBAAa,aAAa;;gBAWZ,OAAO,EAAE,oBAAoB;IAsCzC,MAAM,SAAU,UAAU,cAAc,WAAW,KAAG,IAAI,CAIzD;IAED,UAAU,SAAU,UAAU,KAAG,MAAM,GAAG,SAAS,CAqBlD;IAWD,OAAO,aAEN;IAED,IAAI,aAEH;IAED,IAAI,aAEH;IAED,WAAW,oCAEV;CACF"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@milkdown/plugin-slash",
3
3
  "type": "module",
4
- "version": "6.5.4",
4
+ "version": "7.0.0-next.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -20,19 +20,23 @@
20
20
  "src"
21
21
  ],
22
22
  "peerDependencies": {
23
- "@milkdown/core": "^6.0.1",
24
- "@milkdown/prose": "^6.0.1"
23
+ "@milkdown/core": "^7.0.0-next.0",
24
+ "@milkdown/ctx": "^7.0.0-next.0",
25
+ "@milkdown/prose": "^7.0.0-next.0"
25
26
  },
26
27
  "dependencies": {
28
+ "@types/lodash.debounce": "^4.0.7",
29
+ "lodash.debounce": "^4.0.8",
27
30
  "smooth-scroll-into-view-if-needed": "^1.1.32",
31
+ "tippy.js": "^6.3.7",
28
32
  "tslib": "^2.4.0",
29
- "@milkdown/exception": "6.5.4",
30
- "@milkdown/utils": "6.5.4"
33
+ "@milkdown/exception": "7.0.0-next.0",
34
+ "@milkdown/utils": "7.0.0-next.0"
31
35
  },
32
36
  "devDependencies": {
33
- "@milkdown/core": "6.5.4",
34
- "@milkdown/design-system": "6.5.4",
35
- "@milkdown/prose": "6.5.4"
37
+ "@milkdown/core": "7.0.0-next.0",
38
+ "@milkdown/ctx": "7.0.0-next.0",
39
+ "@milkdown/prose": "7.0.0-next.0"
36
40
  },
37
41
  "nx": {
38
42
  "targets": {
package/src/index.ts CHANGED
@@ -1,35 +1,3 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { AtomList, createPlugin } from '@milkdown/utils'
3
-
4
- import type { Config } from './config'
5
- import { defaultConfig } from './config'
6
- import { createSlashPlugin } from './prose-plugin'
7
- import type { CalcPosition } from './prose-plugin/view'
8
- import { defaultCalcPosition } from './prose-plugin/view'
9
-
10
- export type { Config, StatusConfig, StatusConfigBuilder, StatusConfigBuilderParams } from './config'
11
- export { defaultActions, defaultConfig } from './config'
12
- export type { Action, WrappedAction } from './item'
13
- export { createDropdownItem } from './utility'
14
-
15
- export interface Options {
16
- config: Config
17
- calcPosition: CalcPosition
18
- }
19
-
20
- export const slashPlugin = createPlugin<string, Options>((utils, options) => {
21
- const slashConfig = options?.config ?? defaultConfig
22
- const calcPosition = options?.calcPosition ?? defaultCalcPosition
23
-
24
- return {
25
- prosePlugins: (_, ctx) => {
26
- const config = slashConfig(ctx)
27
-
28
- const plugin = createSlashPlugin(utils, config, 'slash-dropdown', calcPosition)
29
-
30
- return [plugin]
31
- },
32
- }
33
- })
34
-
35
- export const slash = AtomList.create([slashPlugin()])
2
+ export * from './slash-plugin'
3
+ export * from './slash-provider'
@@ -0,0 +1,31 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+ import type { SliceType } from '@milkdown/ctx'
3
+ import type { PluginSpec } from '@milkdown/prose/state'
4
+ import { Plugin, PluginKey } from '@milkdown/prose/state'
5
+ import type { $Ctx, $Prose } from '@milkdown/utils'
6
+ import { $ctx, $prose } from '@milkdown/utils'
7
+
8
+ export type SlashPluginSpecId<Id extends string> = `${Id}_SLASH_SPEC`
9
+
10
+ export type SlashPlugin<Id extends string, State = any> = [$Ctx<PluginSpec<State>, SlashPluginSpecId<Id>>, $Prose] & {
11
+ key: SliceType<PluginSpec<State>, SlashPluginSpecId<Id>>
12
+ pluginKey: $Prose['key']
13
+ }
14
+
15
+ export const slashFactory = <Id extends string, State = any>(id: Id) => {
16
+ const slashSpec = $ctx<PluginSpec<State>, SlashPluginSpecId<Id>>({}, `${id}_SLASH_SPEC`)
17
+ const slashPlugin = $prose((ctx) => {
18
+ const spec = ctx.get(slashSpec.key)
19
+ return new Plugin({
20
+ key: new PluginKey(`${id}_SLASH`),
21
+ ...spec,
22
+ })
23
+ })
24
+ const result = [slashSpec, slashPlugin] as SlashPlugin<Id>
25
+ result.key = slashSpec.key
26
+ result.pluginKey = slashPlugin.key
27
+
28
+ return result
29
+ }
30
+
31
+ export const slash = slashFactory('MILKDOWN')
@@ -0,0 +1,119 @@
1
+ /* Copyright 2021, Milkdown by Mirone. */
2
+ import { findParentNode, posToDOMRect } from '@milkdown/prose'
3
+ import type { EditorState } from '@milkdown/prose/state'
4
+ import { TextSelection } from '@milkdown/prose/state'
5
+ import type { EditorView } from '@milkdown/prose/view'
6
+ import debounce from 'lodash.debounce'
7
+ import type { Instance, Props } from 'tippy.js'
8
+ import tippy from 'tippy.js'
9
+
10
+ export type SlashProviderOptions = {
11
+ content: HTMLElement
12
+ tippyOptions?: Partial<Props>
13
+ debounce?: number
14
+ shouldShow?: (view: EditorView, prevState?: EditorState) => boolean
15
+ }
16
+
17
+ export class SlashProvider {
18
+ #tippy: Instance | undefined
19
+
20
+ #element: HTMLElement
21
+
22
+ #tippyOptions: Partial<Props>
23
+
24
+ #debounce: number
25
+
26
+ #shouldShow: (view: EditorView, prevState?: EditorState) => boolean
27
+
28
+ constructor(options: SlashProviderOptions) {
29
+ this.#element = options.content
30
+ this.#tippyOptions = options.tippyOptions ?? {}
31
+ this.#debounce = options.debounce ?? 200
32
+ this.#shouldShow = options.shouldShow ?? this.#_shouldShow
33
+ }
34
+
35
+ #onUpdate = (view: EditorView, prevState?: EditorState): void => {
36
+ const { state, composing } = view
37
+ const { selection, doc } = state
38
+ const { ranges } = selection
39
+ const from = Math.min(...ranges.map(range => range.$from.pos))
40
+ const to = Math.max(...ranges.map(range => range.$to.pos))
41
+ const isSame = prevState && prevState.doc.eq(doc) && prevState.selection.eq(selection)
42
+
43
+ this.#tippy ??= tippy(view.dom, {
44
+ trigger: 'manual',
45
+ placement: 'bottom-start',
46
+ interactive: true,
47
+ ...this.#tippyOptions,
48
+ content: this.#element,
49
+ })
50
+
51
+ if (composing || isSame)
52
+ return
53
+
54
+ if (!this.#shouldShow(view, prevState)) {
55
+ this.hide()
56
+ return
57
+ }
58
+
59
+ this.#tippy.setProps({
60
+ getReferenceClientRect: () => posToDOMRect(view, from, to),
61
+ })
62
+
63
+ this.show()
64
+ }
65
+
66
+ update = (view: EditorView, prevState?: EditorState): void => {
67
+ const updater = debounce(this.#onUpdate, this.#debounce)
68
+
69
+ updater(view, prevState)
70
+ }
71
+
72
+ getContent = (view: EditorView): string | undefined => {
73
+ const { selection } = view.state
74
+ const { empty } = selection
75
+ const isTextBlock = view.state.selection instanceof TextSelection
76
+
77
+ const isSlashChildren = this.#element.contains(document.activeElement)
78
+
79
+ const notHasFocus = !view.hasFocus() && !isSlashChildren
80
+
81
+ const isReadonly = !view.editable
82
+
83
+ const paragraph = findParentNode(({ type }) => type.name === 'paragraph')(view.state.selection)
84
+
85
+ const isNotInParagraph = !paragraph
86
+
87
+ if (notHasFocus || isReadonly || !empty || !isTextBlock || isNotInParagraph)
88
+ return
89
+
90
+ const currentTextBlockContent = paragraph.node.textContent
91
+
92
+ return currentTextBlockContent
93
+ }
94
+
95
+ #_shouldShow(view: EditorView): boolean {
96
+ const currentTextBlockContent = this.getContent(view)
97
+
98
+ if (!currentTextBlockContent)
99
+ return false
100
+
101
+ return currentTextBlockContent.at(-1) === '/'
102
+ }
103
+
104
+ destroy = () => {
105
+ this.#tippy?.destroy()
106
+ }
107
+
108
+ show = () => {
109
+ this.#tippy?.show()
110
+ }
111
+
112
+ hide = () => {
113
+ this.#tippy?.hide()
114
+ }
115
+
116
+ getInstance = () => {
117
+ return this.#tippy
118
+ }
119
+ }
package/lib/config.d.ts DELETED
@@ -1,21 +0,0 @@
1
- import type { Ctx } from '@milkdown/core';
2
- import type { Node } from '@milkdown/prose/model';
3
- import type { EditorState } from '@milkdown/prose/state';
4
- import type { WrappedAction } from './item';
5
- type Nullable<T> = T | null | undefined;
6
- export interface StatusConfig {
7
- placeholder?: Nullable<string>;
8
- actions?: Nullable<WrappedAction[]>;
9
- }
10
- export interface StatusConfigBuilderParams {
11
- content: string;
12
- isTopLevel: boolean;
13
- parentNode: Node;
14
- state: EditorState;
15
- }
16
- export type StatusConfigBuilder = (params: StatusConfigBuilderParams) => Nullable<StatusConfig>;
17
- export type Config = (ctx: Ctx) => StatusConfigBuilder;
18
- export declare const defaultActions: (ctx: Ctx, input?: string) => WrappedAction[];
19
- export declare const defaultConfig: Config;
20
- export {};
21
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAG3C,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;AAEvC,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC9B,OAAO,CAAC,EAAE,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,IAAI,CAAA;IAChB,KAAK,EAAE,WAAW,CAAA;CACnB;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,yBAAyB,KAAK,QAAQ,CAAC,YAAY,CAAC,CAAA;AAE/F,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,mBAAmB,CAAA;AAEtD,eAAO,MAAM,cAAc,QAAS,GAAG,qBAAgB,aAAa,EAuFnE,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,MAyB3B,CAAA"}
package/lib/item.d.ts DELETED
@@ -1,12 +0,0 @@
1
- import type { Command } from '@milkdown/prose/state';
2
- export interface Action {
3
- id: string;
4
- $: HTMLElement;
5
- command: Command;
6
- }
7
- export type WrappedAction = Pick<Action, 'id'> & {
8
- command: () => void;
9
- dom: HTMLElement;
10
- };
11
- export declare const transformAction: (action: WrappedAction) => Action;
12
- //# sourceMappingURL=item.d.ts.map
package/lib/item.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../src/item.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAIpD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,CAAC,EAAE,WAAW,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG;IAC/C,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,GAAG,EAAE,WAAW,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,eAAe,WAAY,aAAa,KAAG,MAItD,CAAA"}
@@ -1,8 +0,0 @@
1
- import type { Status } from './status';
2
- interface Listeners {
3
- mouseEnter: EventListener;
4
- mouseLeave: EventListener;
5
- }
6
- export declare const renderDropdown: (status: Status, dropdownElement: HTMLElement, listeners: Listeners) => boolean;
7
- export {};
8
- //# sourceMappingURL=dropdown.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dropdown.d.ts","sourceRoot":"","sources":["../../src/prose-plugin/dropdown.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC,UAAU,SAAS;IACjB,UAAU,EAAE,aAAa,CAAA;IACzB,UAAU,EAAE,aAAa,CAAA;CAC1B;AAED,eAAO,MAAM,cAAc,WAAY,MAAM,mBAAmB,WAAW,aAAa,SAAS,KAAG,OAuCnG,CAAA"}
@@ -1,7 +0,0 @@
1
- import { Plugin } from '@milkdown/prose/state';
2
- import type { ThemeUtils } from '@milkdown/utils';
3
- import type { StatusConfigBuilder } from '..';
4
- import type { CalcPosition } from './view';
5
- export declare const key = "MILKDOWN_SLASH";
6
- export declare const createSlashPlugin: (utils: ThemeUtils, builder: StatusConfigBuilder, className: string, calcPosition: CalcPosition) => Plugin<any>;
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prose-plugin/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAa,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,IAAI,CAAA;AAG7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAG1C,eAAO,MAAM,GAAG,mBAAmB,CAAA;AAEnC,eAAO,MAAM,iBAAiB,UACrB,UAAU,WACR,mBAAmB,aACjB,MAAM,gBACH,YAAY,gBAS3B,CAAA"}
@@ -1,14 +0,0 @@
1
- import type { EditorView } from '@milkdown/prose/view';
2
- import type { Status } from './status';
3
- export declare const createMouseManager: () => {
4
- isLock: () => boolean;
5
- lock: () => void;
6
- unlock: () => void;
7
- };
8
- export type MouseManager = ReturnType<typeof createMouseManager>;
9
- export declare const handleMouseMove: (mouseManager: MouseManager) => () => void;
10
- export declare const handleMouseEnter: (status: Status, mouseManager: MouseManager) => (e: MouseEvent) => void;
11
- export declare const handleMouseLeave: () => (e: MouseEvent) => void;
12
- export declare const handleClick: (status: Status, view: EditorView, dropdownElement: HTMLElement) => (e: Event) => void;
13
- export declare const handleKeydown: (status: Status, view: EditorView, dropdownElement: HTMLElement, mouseManager: MouseManager) => (e: Event) => void;
14
- //# sourceMappingURL=input.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/prose-plugin/input.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAGtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC,eAAO,MAAM,kBAAkB;;;;CAY9B,CAAA;AACD,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAEhE,eAAO,MAAM,eAAe,iBAAkB,YAAY,eAEzD,CAAA;AAED,eAAO,MAAM,gBAAgB,WAAY,MAAM,gBAAgB,YAAY,SAAS,UAAU,SAa7F,CAAA;AAED,eAAO,MAAM,gBAAgB,YAAa,UAAU,SAKnD,CAAA;AAED,eAAO,MAAM,WAAW,WACT,MAAM,QAAQ,UAAU,mBAAmB,WAAW,SAC3D,KAAK,KAAG,IA4BX,CAAA;AAEP,eAAO,MAAM,aAAa,WACX,MAAM,QAAQ,UAAU,mBAAmB,WAAW,gBAAgB,YAAY,SAAS,KAAK,SA4D1G,CAAA"}
@@ -1,11 +0,0 @@
1
- import type { EditorState } from '@milkdown/prose/state';
2
- import type { EditorView } from '@milkdown/prose/view';
3
- import { DecorationSet } from '@milkdown/prose/view';
4
- import type { ThemeUtils } from '@milkdown/utils';
5
- import type { Status } from './status';
6
- export type Props = ReturnType<typeof createProps>;
7
- export declare const createProps: (status: Status, utils: ThemeUtils) => {
8
- handleKeyDown: (_: EditorView, event: Event) => boolean;
9
- decorations: (state: EditorState) => DecorationSet | null;
10
- };
11
- //# sourceMappingURL=props.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/prose-plugin/props.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAc,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC,MAAM,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAA;AA4BlD,eAAO,MAAM,WAAW,WAAY,MAAM,SAAS,UAAU;uBAEtC,UAAU,SAAS,KAAK;yBAYtB,WAAW;CAkDnC,CAAA"}
@@ -1,14 +0,0 @@
1
- import type { StatusConfigBuilder, StatusConfigBuilderParams } from '..';
2
- import type { Action } from '../item';
3
- export interface StatusCtx {
4
- placeholder: string | null;
5
- actions: Action[];
6
- }
7
- export type Status = ReturnType<typeof createStatus>;
8
- export declare const createStatus: (builder: StatusConfigBuilder) => {
9
- get: () => StatusCtx;
10
- clear: () => void;
11
- update: (builderParams: StatusConfigBuilderParams) => StatusCtx;
12
- isEmpty: () => boolean;
13
- };
14
- //# sourceMappingURL=status.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/prose-plugin/status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,IAAI,CAAA;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAGrC,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AASD,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;AAEpD,eAAO,MAAM,YAAY,YAAa,mBAAmB;;;4BAS7B,yBAAyB;;CAQpD,CAAA"}
@@ -1,13 +0,0 @@
1
- import type { EditorView } from '@milkdown/prose/view';
2
- import type { ThemeUtils } from '@milkdown/utils';
3
- import type { Status } from './status';
4
- export declare const defaultCalcPosition: (view: EditorView, dropdownElement: HTMLElement) => void;
5
- export type CalcPosition = (view: EditorView, dropdownElement: HTMLElement) => void;
6
- export declare const createView: (status: Status, view: EditorView, utils: ThemeUtils, className: string, calcPosition: CalcPosition) => {
7
- update?: undefined;
8
- destroy?: undefined;
9
- } | {
10
- update: (view: EditorView) => void;
11
- destroy: () => void;
12
- };
13
- //# sourceMappingURL=view.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/prose-plugin/view.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAYjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC,eAAO,MAAM,mBAAmB,SAAU,UAAU,mBAAmB,WAAW,SA4CjF,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,KAAK,IAAI,CAAA;AAEnF,eAAO,MAAM,UAAU,WACb,MAAM,QACR,UAAU,SACT,UAAU,aACN,MAAM,gBACH,YAAY;;;;mBAqBT,UAAU;;CAmB5B,CAAA"}
package/lib/style.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import type { Emotion, ThemeManager } from '@milkdown/core';
2
- export declare const injectStyle: (themeManager: ThemeManager, emotion: Emotion) => string;
3
- //# sourceMappingURL=style.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../src/style.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,OAAO,EACP,YAAY,EACb,MAAM,gBAAgB,CAAA;AAgDvB,eAAO,MAAM,WAAW,iBAAkB,YAAY,WAAW,OAAO,WAsBvE,CAAA"}
package/lib/utility.d.ts DELETED
@@ -1,14 +0,0 @@
1
- import type { ThemeManager } from '@milkdown/core';
2
- import type { Icon } from '@milkdown/design-system';
3
- import type { Node } from '@milkdown/prose/model';
4
- import type { Command } from '@milkdown/prose/state';
5
- import type { ThemeUtils } from '@milkdown/utils';
6
- export declare const createDropdown: (utils: ThemeUtils, className: string) => HTMLDivElement;
7
- interface ItemOptions {
8
- textClassName: string;
9
- }
10
- export declare const createDropdownItem: (themeManager: ThemeManager, text: string, icon: Icon, options?: Partial<ItemOptions>) => HTMLDivElement;
11
- export declare const getDepth: (node: Node) => number;
12
- export declare const cleanUpAndCreateNode: (createCommand: () => void) => Command;
13
- export {};
14
- //# sourceMappingURL=utility.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utility.d.ts","sourceRoot":"","sources":["../src/utility.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAElD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAA;AAEnD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAIjD,eAAO,MAAM,cAAc,UAAW,UAAU,aAAa,MAAM,mBAclE,CAAA;AAED,UAAU,WAAW;IACnB,aAAa,EAAE,MAAM,CAAA;CACtB;AACD,eAAO,MAAM,kBAAkB,iBACf,YAAY,QACpB,MAAM,QACN,IAAI,YACA,QAAQ,WAAW,CAAC,mBAqB/B,CAAA;AAED,eAAO,MAAM,QAAQ,SAAU,IAAI,WASlC,CAAA;AAUD,eAAO,MAAM,oBAAoB,kBACX,MAAM,IAAI,KAAG,OAO5B,CAAA"}
package/src/config.ts DELETED
@@ -1,142 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import type { Ctx } from '@milkdown/core'
3
- import { commandsCtx, editorViewCtx, schemaCtx, themeManagerCtx } from '@milkdown/core'
4
- import type { Node } from '@milkdown/prose/model'
5
- import type { EditorState } from '@milkdown/prose/state'
6
-
7
- import type { WrappedAction } from './item'
8
- import { createDropdownItem } from './utility'
9
-
10
- type Nullable<T> = T | null | undefined
11
-
12
- export interface StatusConfig {
13
- placeholder?: Nullable<string>
14
- actions?: Nullable<WrappedAction[]>
15
- }
16
-
17
- export interface StatusConfigBuilderParams {
18
- content: string
19
- isTopLevel: boolean
20
- parentNode: Node
21
- state: EditorState
22
- }
23
-
24
- export type StatusConfigBuilder = (params: StatusConfigBuilderParams) => Nullable<StatusConfig>
25
-
26
- export type Config = (ctx: Ctx) => StatusConfigBuilder
27
-
28
- export const defaultActions = (ctx: Ctx, input = '/'): WrappedAction[] => {
29
- const { nodes } = ctx.get(schemaCtx)
30
- const actions: Array<WrappedAction & { keyword: string[]; typeName: string }> = [
31
- {
32
- id: 'h1',
33
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Large Heading', 'h1'),
34
- command: () => ctx.get(commandsCtx).call('TurnIntoHeading', 1),
35
- keyword: ['h1', 'large heading'],
36
- typeName: 'heading',
37
- },
38
- {
39
- id: 'h2',
40
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Medium Heading', 'h2'),
41
- command: () => ctx.get(commandsCtx).call('TurnIntoHeading', 2),
42
- keyword: ['h2', 'medium heading'],
43
- typeName: 'heading',
44
- },
45
- {
46
- id: 'h3',
47
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Small Heading', 'h3'),
48
- command: () => ctx.get(commandsCtx).call('TurnIntoHeading', 3),
49
- keyword: ['h3', 'small heading'],
50
- typeName: 'heading',
51
- },
52
- {
53
- id: 'bulletList',
54
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Bullet List', 'bulletList'),
55
- command: () => ctx.get(commandsCtx).call('WrapInBulletList'),
56
- keyword: ['bullet list', 'ul'],
57
- typeName: 'bullet_list',
58
- },
59
- {
60
- id: 'orderedList',
61
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Ordered List', 'orderedList'),
62
- command: () => ctx.get(commandsCtx).call('WrapInOrderedList'),
63
- keyword: ['ordered list', 'ol'],
64
- typeName: 'ordered_list',
65
- },
66
- {
67
- id: 'taskList',
68
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Task List', 'taskList'),
69
- command: () => ctx.get(commandsCtx).call('TurnIntoTaskList'),
70
- keyword: ['task list', 'task'],
71
- typeName: 'task_list_item',
72
- },
73
- {
74
- id: 'image',
75
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Image', 'image'),
76
- command: () => ctx.get(commandsCtx).call('InsertImage'),
77
- keyword: ['image'],
78
- typeName: 'image',
79
- },
80
- {
81
- id: 'blockquote',
82
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Quote', 'quote'),
83
- command: () => ctx.get(commandsCtx).call('WrapInBlockquote'),
84
- keyword: ['quote', 'blockquote'],
85
- typeName: 'blockquote',
86
- },
87
- {
88
- id: 'table',
89
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Table', 'table'),
90
- command: () => ctx.get(commandsCtx).call('InsertTable'),
91
- keyword: ['table'],
92
- typeName: 'table',
93
- },
94
- {
95
- id: 'code',
96
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Code Fence', 'code'),
97
- command: () => ctx.get(commandsCtx).call('TurnIntoCodeFence'),
98
- keyword: ['code'],
99
- typeName: 'fence',
100
- },
101
- {
102
- id: 'divider',
103
- dom: createDropdownItem(ctx.get(themeManagerCtx), 'Divide Line', 'divider'),
104
- command: () => ctx.get(commandsCtx).call('InsertHr'),
105
- keyword: ['divider', 'hr'],
106
- typeName: 'hr',
107
- },
108
- ]
109
-
110
- const userInput = input.slice(1).toLocaleLowerCase()
111
-
112
- return actions
113
- .filter(action => !!nodes[action.typeName] && action.keyword.some(keyword => keyword.includes(userInput)))
114
- .map(({ keyword, typeName, ...action }) => action)
115
- }
116
-
117
- export const defaultConfig: Config = (ctx) => {
118
- return ({ content, isTopLevel }) => {
119
- if (!isTopLevel)
120
- return null
121
-
122
- const view = ctx.get(editorViewCtx)
123
- if (!view?.editable)
124
- return null
125
-
126
- if (!content)
127
- return { placeholder: 'Type / to use the slash commands...' }
128
-
129
- if (content.startsWith('/')) {
130
- return content === '/'
131
- ? {
132
- placeholder: 'Type to filter...',
133
- actions: defaultActions(ctx),
134
- }
135
- : {
136
- actions: defaultActions(ctx, content),
137
- }
138
- }
139
-
140
- return null
141
- }
142
- }
package/src/item.ts DELETED
@@ -1,21 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import type { Command } from '@milkdown/prose/state'
3
-
4
- import { cleanUpAndCreateNode } from './utility'
5
-
6
- export interface Action {
7
- id: string
8
- $: HTMLElement
9
- command: Command
10
- }
11
-
12
- export type WrappedAction = Pick<Action, 'id'> & {
13
- command: () => void
14
- dom: HTMLElement
15
- }
16
-
17
- export const transformAction = (action: WrappedAction): Action => ({
18
- id: action.id,
19
- $: action.dom,
20
- command: cleanUpAndCreateNode(action.command),
21
- })
@@ -1,50 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import scrollIntoView from 'smooth-scroll-into-view-if-needed'
3
-
4
- import type { Status } from './status'
5
-
6
- interface Listeners {
7
- mouseEnter: EventListener
8
- mouseLeave: EventListener
9
- }
10
-
11
- export const renderDropdown = (status: Status, dropdownElement: HTMLElement, listeners: Listeners): boolean => {
12
- const { actions } = status.get()
13
-
14
- if (!actions.length) {
15
- dropdownElement.classList.add('hide')
16
- return false
17
- }
18
-
19
- dropdownElement.childNodes.forEach((child) => {
20
- child.removeEventListener('mouseenter', listeners.mouseEnter)
21
- child.removeEventListener('mouseleave', listeners.mouseLeave)
22
- })
23
-
24
- while (dropdownElement.firstChild)
25
- dropdownElement.firstChild.remove()
26
-
27
- actions.forEach(({ $ }) => {
28
- $.classList.remove('active')
29
- $.addEventListener('mouseenter', listeners.mouseEnter)
30
- $.addEventListener('mouseleave', listeners.mouseLeave)
31
- dropdownElement.appendChild($)
32
- })
33
-
34
- dropdownElement.style.maxHeight = ''
35
- dropdownElement.classList.remove('hide')
36
-
37
- const first$ = actions[0]
38
- if (first$) {
39
- first$.$.classList.add('active')
40
- requestAnimationFrame(() => {
41
- scrollIntoView(first$.$, {
42
- scrollMode: 'if-needed',
43
- block: 'nearest',
44
- inline: 'nearest',
45
- })
46
- })
47
- }
48
-
49
- return true
50
- }