@seorii/tiptap 0.3.0-next.9 → 0.4.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.
- package/dist/i18n/index.d.ts +106 -6
- package/dist/i18n/index.js +56 -11
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/plugin/command/emoji.d.ts +3 -17
- package/dist/plugin/command/emoji.js +51 -24
- package/dist/plugin/command/stores.svelte.d.ts +52 -0
- package/dist/plugin/command/stores.svelte.js +69 -0
- package/dist/plugin/command/suggest.d.ts +6 -19
- package/dist/plugin/command/suggest.js +149 -49
- package/dist/plugin/embed.d.ts +2 -2
- package/dist/plugin/embed.js +6 -2
- package/dist/plugin/iframe.js +1 -1
- package/dist/plugin/image/dragdrop.d.ts +2 -0
- package/dist/plugin/image/dragdrop.js +126 -15
- package/dist/plugin/image/index.js +4 -3
- package/dist/plugin/indent.js +0 -1
- package/dist/plugin/orderedlist/index.d.ts +1 -1
- package/dist/plugin/orderedlist/index.js +1 -1
- package/dist/plugin/orderedlist/{korean.scss → korean.css} +2 -2
- package/dist/plugin/resize/index.d.ts +8 -0
- package/dist/plugin/resize/index.js +454 -0
- package/dist/plugin/table/index.d.ts +1 -1
- package/dist/plugin/table/index.js +19 -11
- package/dist/plugin/table/style/{cell.scss → cell.css} +6 -5
- package/dist/plugin/table/style/{grip.scss → grip.css} +14 -19
- package/dist/plugin/table/style/resize.css +28 -0
- package/dist/plugin/table/style/{table.scss → table.css} +15 -17
- package/dist/plugin/table/style.css +4 -0
- package/dist/plugin/table/tableCell/index.js +2 -4
- package/dist/plugin/table/tableHeader/index.js +1 -2
- package/dist/plugin/upload/skeleton/UploadSkeleton.svelte +97 -0
- package/dist/plugin/upload/skeleton/UploadSkeleton.svelte.d.ts +5 -0
- package/dist/plugin/upload/skeleton/index.d.ts +30 -0
- package/dist/plugin/upload/skeleton/index.js +147 -0
- package/dist/plugin/youtube.js +1 -1
- package/dist/tiptap/Bubble.svelte +231 -92
- package/dist/tiptap/Bubble.svelte.d.ts +9 -6
- package/dist/tiptap/Command.svelte +160 -158
- package/dist/tiptap/Command.svelte.d.ts +2 -3
- package/dist/tiptap/Floating.svelte +51 -24
- package/dist/tiptap/Floating.svelte.d.ts +1 -0
- package/dist/tiptap/TipTap.svelte +302 -140
- package/dist/tiptap/TipTap.svelte.d.ts +10 -3
- package/dist/tiptap/ToolbarButton.svelte +30 -10
- package/dist/tiptap/ToolbarButton.svelte.d.ts +10 -6
- package/dist/tiptap/setMath.d.ts +2 -1
- package/dist/tiptap/setMath.js +74 -12
- package/dist/tiptap/tiptap.d.ts +9 -1
- package/dist/tiptap/tiptap.js +172 -16
- package/package.json +63 -57
- package/dist/plugin/command/stores.d.ts +0 -13
- package/dist/plugin/command/stores.js +0 -7
- package/dist/plugin/table/style/resize.scss +0 -26
- package/dist/plugin/table/style.scss +0 -4
package/dist/i18n/index.d.ts
CHANGED
|
@@ -1,7 +1,107 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
declare const locales: readonly [{
|
|
2
|
+
target: string[];
|
|
3
|
+
lang: string;
|
|
4
|
+
country: string;
|
|
5
|
+
text: string;
|
|
6
|
+
block: string;
|
|
7
|
+
loading: string;
|
|
8
|
+
delete: string;
|
|
9
|
+
close: string;
|
|
10
|
+
cancel: string;
|
|
11
|
+
insert: string;
|
|
12
|
+
noResult: string;
|
|
13
|
+
default: string;
|
|
14
|
+
auto: string;
|
|
15
|
+
title: string;
|
|
16
|
+
paragraph: string;
|
|
17
|
+
link: string;
|
|
18
|
+
alignLeft: string;
|
|
19
|
+
alignCenter: string;
|
|
20
|
+
alignRight: string;
|
|
21
|
+
alignJustify: string;
|
|
22
|
+
unorderedList: string;
|
|
23
|
+
numberList: string;
|
|
24
|
+
codeBlock: string;
|
|
25
|
+
mathBlock: string;
|
|
26
|
+
table: string;
|
|
27
|
+
image: string;
|
|
28
|
+
iframe: string;
|
|
29
|
+
youtube: string;
|
|
30
|
+
blockquote: string;
|
|
31
|
+
title1Info: string;
|
|
32
|
+
title2Info: string;
|
|
33
|
+
title3Info: string;
|
|
34
|
+
unorderedListInfo: string;
|
|
35
|
+
numberListInfo: string;
|
|
36
|
+
codeBlockInfo: string;
|
|
37
|
+
mathBlockInfo: string;
|
|
38
|
+
tableInfo: string;
|
|
39
|
+
imageInfo: string;
|
|
40
|
+
iframeInfo: string;
|
|
41
|
+
youtubeInfo: string;
|
|
42
|
+
blockquoteInfo: string;
|
|
43
|
+
newLineInfo: string;
|
|
44
|
+
placeholder: string;
|
|
45
|
+
insertCode: string;
|
|
46
|
+
}, {
|
|
47
|
+
target: string[];
|
|
48
|
+
lang: string;
|
|
49
|
+
country: string;
|
|
50
|
+
text: string;
|
|
51
|
+
block: string;
|
|
52
|
+
loading: string;
|
|
53
|
+
delete: string;
|
|
54
|
+
close: string;
|
|
55
|
+
cancel: string;
|
|
56
|
+
insert: string;
|
|
57
|
+
noResult: string;
|
|
58
|
+
default: string;
|
|
59
|
+
auto: string;
|
|
60
|
+
title: string;
|
|
61
|
+
paragraph: string;
|
|
62
|
+
link: string;
|
|
63
|
+
alignLeft: string;
|
|
64
|
+
alignCenter: string;
|
|
65
|
+
alignRight: string;
|
|
66
|
+
alignJustify: string;
|
|
67
|
+
unorderedList: string;
|
|
68
|
+
numberList: string;
|
|
69
|
+
codeBlock: string;
|
|
70
|
+
mathBlock: string;
|
|
71
|
+
table: string;
|
|
72
|
+
image: string;
|
|
73
|
+
iframe: string;
|
|
74
|
+
youtube: string;
|
|
75
|
+
blockquote: string;
|
|
76
|
+
title1Info: string;
|
|
77
|
+
title2Info: string;
|
|
78
|
+
title3Info: string;
|
|
79
|
+
unorderedListInfo: string;
|
|
80
|
+
numberListInfo: string;
|
|
81
|
+
codeBlockInfo: string;
|
|
82
|
+
mathBlockInfo: string;
|
|
83
|
+
tableInfo: string;
|
|
84
|
+
imageInfo: string;
|
|
85
|
+
iframeInfo: string;
|
|
86
|
+
youtubeInfo: string;
|
|
87
|
+
blockquoteInfo: string;
|
|
88
|
+
newLineInfo: string;
|
|
89
|
+
placeholder: string;
|
|
90
|
+
insertCode: string;
|
|
91
|
+
}];
|
|
92
|
+
type Locale = (typeof locales)[number];
|
|
93
|
+
export type LocaleInput = string | Locale | null | undefined;
|
|
94
|
+
export type I18nTranslate = (...args: string[]) => string;
|
|
95
|
+
export declare const I18N_CONTEXT: unique symbol;
|
|
96
|
+
export declare function getLocale(localeList?: readonly Locale[], language?: string | null): Locale;
|
|
97
|
+
export declare function translateWithLocale(input: LocaleInput, ...args: string[]): string;
|
|
98
|
+
type I18n = ((...args: string[]) => string) & {
|
|
99
|
+
locale: Locale;
|
|
100
|
+
localeLangCountry: string;
|
|
101
|
+
locales: readonly Locale[];
|
|
102
|
+
setLocale: (input?: LocaleInput) => Locale;
|
|
103
|
+
getLocale: () => Locale;
|
|
104
|
+
};
|
|
105
|
+
declare const i18n: I18n;
|
|
106
|
+
export declare function setLocale(input?: LocaleInput): Locale;
|
|
7
107
|
export default i18n;
|
package/dist/i18n/index.js
CHANGED
|
@@ -1,21 +1,66 @@
|
|
|
1
1
|
import enUs from './en-us/index';
|
|
2
2
|
import koKr from './ko-kr/index';
|
|
3
3
|
const locales = [enUs, koKr];
|
|
4
|
-
export
|
|
4
|
+
export const I18N_CONTEXT = Symbol('tiptap-i18n');
|
|
5
|
+
const normalizeLocaleCode = (value) => (value ?? '').trim().replace(/_/g, '-').toLowerCase();
|
|
6
|
+
const findLocale = (localeList, language) => {
|
|
7
|
+
const normalized = normalizeLocaleCode(language);
|
|
8
|
+
if (!normalized)
|
|
9
|
+
return null;
|
|
10
|
+
const exact = localeList.find((item) => item.target.some((target) => normalizeLocaleCode(target) === normalized));
|
|
11
|
+
if (exact)
|
|
12
|
+
return exact;
|
|
13
|
+
const primary = normalized.split('-')[0];
|
|
14
|
+
if (!primary)
|
|
15
|
+
return null;
|
|
16
|
+
return (localeList.find((item) => normalizeLocaleCode(item.lang) === primary) ??
|
|
17
|
+
localeList.find((item) => item.target.some((target) => normalizeLocaleCode(target).split('-')[0] === primary)) ??
|
|
18
|
+
null);
|
|
19
|
+
};
|
|
20
|
+
export function getLocale(localeList = locales, language) {
|
|
21
|
+
if (language)
|
|
22
|
+
return findLocale(localeList, language) ?? enUs;
|
|
5
23
|
if (typeof navigator === 'undefined')
|
|
6
24
|
return enUs;
|
|
7
|
-
|
|
8
|
-
const locale = locales.find((item) => item.target.includes(language));
|
|
9
|
-
return locale || enUs;
|
|
25
|
+
return findLocale(localeList, navigator.language) ?? enUs;
|
|
10
26
|
}
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
27
|
+
const resolveLocale = (input) => {
|
|
28
|
+
if (!input || (typeof input === 'string' && normalizeLocaleCode(input) === 'auto'))
|
|
29
|
+
return getLocale();
|
|
30
|
+
if (typeof input === 'string')
|
|
31
|
+
return getLocale(locales, input);
|
|
32
|
+
return input;
|
|
33
|
+
};
|
|
34
|
+
const translate = (locale, args) => {
|
|
35
|
+
let value = locale;
|
|
36
|
+
for (const key of args) {
|
|
37
|
+
if (value && typeof value === 'object' && key in value) {
|
|
38
|
+
value = value[key];
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
value = '';
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
return typeof value === 'string' ? value : '';
|
|
45
|
+
};
|
|
46
|
+
export function translateWithLocale(input, ...args) {
|
|
47
|
+
return translate(resolveLocale(input), args);
|
|
16
48
|
}
|
|
17
|
-
|
|
18
|
-
i18n
|
|
49
|
+
let currentLocale = getLocale();
|
|
50
|
+
const i18n = ((...args) => {
|
|
51
|
+
return translate(currentLocale, args);
|
|
52
|
+
});
|
|
53
|
+
export function setLocale(input) {
|
|
54
|
+
currentLocale = resolveLocale(input);
|
|
55
|
+
i18n.locale = currentLocale;
|
|
56
|
+
i18n.localeLangCountry = `${i18n('lang')}-${i18n('country')}`;
|
|
57
|
+
return currentLocale;
|
|
58
|
+
}
|
|
59
|
+
i18n.locales = locales;
|
|
60
|
+
i18n.getLocale = () => currentLocale;
|
|
61
|
+
i18n.setLocale = setLocale;
|
|
62
|
+
setLocale(currentLocale);
|
|
63
|
+
export default i18n;
|
|
19
64
|
//@ts-ignore
|
|
20
65
|
if (typeof window !== 'undefined')
|
|
21
66
|
window.__me_i18n = i18n;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Reexport your entry components here
|
|
2
2
|
import TipTap from './tiptap/index.js';
|
|
3
3
|
import { getDetail } from './plugin/command/suggest.js';
|
|
4
|
+
import { insertUploadSkeleton } from './plugin/upload/skeleton/index.js';
|
|
4
5
|
|
|
5
6
|
export default TipTap;
|
|
6
|
-
export { getDetail };
|
|
7
|
+
export { getDetail, insertUploadSkeleton };
|
|
@@ -1,20 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type SlashItem } from './stores.svelte';
|
|
2
|
+
import { type SuggestionOptions } from '@tiptap/suggestion';
|
|
2
3
|
import type { Editor } from '@tiptap/core';
|
|
3
|
-
export declare const emoji:
|
|
4
|
-
pluginKey: PluginKey<any>;
|
|
5
|
-
char: string;
|
|
6
|
-
items: ({ query }: {
|
|
7
|
-
query: any;
|
|
8
|
-
}) => {
|
|
9
|
-
title: string;
|
|
10
|
-
command: {};
|
|
11
|
-
}[];
|
|
12
|
-
render: () => {
|
|
13
|
-
onStart: (props: any) => void;
|
|
14
|
-
onUpdate(props: any): void;
|
|
15
|
-
onKeyDown(props: any): true | undefined;
|
|
16
|
-
onExit(): void;
|
|
17
|
-
};
|
|
18
|
-
};
|
|
4
|
+
export declare const emoji: Omit<SuggestionOptions<SlashItem>, 'editor'>;
|
|
19
5
|
declare const _default: (editor: Editor) => import("prosemirror-state").Plugin<any>;
|
|
20
6
|
export default _default;
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { PluginKey } from '
|
|
3
|
-
import Suggestion from '@tiptap/suggestion';
|
|
4
|
-
|
|
1
|
+
import { closeSlash, moveSlashSelection, runSlashItemAt, setSlashItems, setSlashLocation, setSlashProps, slashState } from './stores.svelte';
|
|
2
|
+
import { PluginKey } from '@tiptap/pm/state';
|
|
3
|
+
import Suggestion, {} from '@tiptap/suggestion';
|
|
4
|
+
// @ts-ignore
|
|
5
5
|
import emojis from 'emojis-list';
|
|
6
|
-
|
|
6
|
+
// @ts-ignore
|
|
7
7
|
import tags from 'emojis-keywords';
|
|
8
8
|
const max = 10;
|
|
9
|
-
function fixRange(editor,
|
|
10
|
-
const
|
|
9
|
+
function fixRange(editor, rawRange, split = '/') {
|
|
10
|
+
const range = { ...rawRange };
|
|
11
|
+
const { state } = editor.view;
|
|
12
|
+
const { selection, doc } = state;
|
|
11
13
|
if (selection.$to.nodeBefore?.text?.includes?.(split)) {
|
|
12
14
|
range.from = range.to;
|
|
13
15
|
while (range.from > 0 && doc.textBetween(range.from - 1, range.from) !== split) {
|
|
14
16
|
try {
|
|
15
17
|
range.from -= 1;
|
|
16
18
|
}
|
|
17
|
-
catch
|
|
19
|
+
catch {
|
|
18
20
|
range.from += 2;
|
|
19
21
|
break;
|
|
20
22
|
}
|
|
@@ -25,7 +27,7 @@ function fixRange(editor, range, split = '/') {
|
|
|
25
27
|
try {
|
|
26
28
|
range.to += 1;
|
|
27
29
|
}
|
|
28
|
-
catch
|
|
30
|
+
catch {
|
|
29
31
|
range.to -= 1;
|
|
30
32
|
break;
|
|
31
33
|
}
|
|
@@ -36,20 +38,22 @@ export const emoji = {
|
|
|
36
38
|
pluginKey: new PluginKey('slash-emoji'),
|
|
37
39
|
char: ':',
|
|
38
40
|
items: ({ query }) => {
|
|
39
|
-
|
|
41
|
+
const normalizedQuery = `:${query.toLowerCase()}`;
|
|
40
42
|
const filtered = [];
|
|
41
43
|
for (let i = 0; i < emojis.length; i++) {
|
|
42
|
-
if (tags[i]?.includes?.(
|
|
44
|
+
if (tags[i]?.includes?.(normalizedQuery)) {
|
|
45
|
+
const emojiValue = emojis[i];
|
|
43
46
|
filtered.push({
|
|
44
|
-
title:
|
|
47
|
+
title: `${emojiValue} ${tags[i]}`,
|
|
45
48
|
command: ({ editor, range }) => {
|
|
46
49
|
editor
|
|
47
50
|
.chain()
|
|
48
51
|
.deleteRange(fixRange(editor, range, ':'))
|
|
49
|
-
.insertContent(
|
|
52
|
+
.insertContent(`${emojiValue} `)
|
|
50
53
|
.run();
|
|
51
54
|
}
|
|
52
55
|
});
|
|
56
|
+
}
|
|
53
57
|
if (filtered.length >= max)
|
|
54
58
|
break;
|
|
55
59
|
}
|
|
@@ -58,26 +62,49 @@ export const emoji = {
|
|
|
58
62
|
render: () => {
|
|
59
63
|
return {
|
|
60
64
|
onStart: (props) => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
const { editor, range } = props;
|
|
66
|
+
setSlashProps({ editor, range });
|
|
67
|
+
slashState.visible = true;
|
|
68
|
+
slashState.selectedIndex = 0;
|
|
69
|
+
setSlashItems(props.items);
|
|
70
|
+
slashState.detail = 'emoji';
|
|
71
|
+
const location = props.clientRect?.();
|
|
72
|
+
if (location) {
|
|
73
|
+
setSlashLocation({ x: location.x, y: location.y, height: location.height });
|
|
74
|
+
}
|
|
69
75
|
},
|
|
70
76
|
onUpdate(props) {
|
|
71
|
-
|
|
77
|
+
setSlashProps({ editor: props.editor, range: props.range });
|
|
78
|
+
setSlashItems(props.items);
|
|
72
79
|
},
|
|
73
80
|
onKeyDown(props) {
|
|
81
|
+
if (props.event.key === 'ArrowUp') {
|
|
82
|
+
props.event.preventDefault();
|
|
83
|
+
moveSlashSelection(-1);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
if (props.event.key === 'ArrowDown') {
|
|
87
|
+
props.event.preventDefault();
|
|
88
|
+
moveSlashSelection(1);
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
if (props.event.key === 'Tab') {
|
|
92
|
+
props.event.preventDefault();
|
|
93
|
+
moveSlashSelection(props.event.shiftKey ? -1 : 1);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
if (props.event.key === 'Enter') {
|
|
97
|
+
props.event.preventDefault();
|
|
98
|
+
return runSlashItemAt(slashState.selectedIndex);
|
|
99
|
+
}
|
|
74
100
|
if (props.event.key === 'Escape') {
|
|
75
|
-
|
|
101
|
+
closeSlash();
|
|
76
102
|
return true;
|
|
77
103
|
}
|
|
104
|
+
return false;
|
|
78
105
|
},
|
|
79
106
|
onExit() {
|
|
80
|
-
|
|
107
|
+
closeSlash();
|
|
81
108
|
}
|
|
82
109
|
};
|
|
83
110
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Editor, Range } from '@tiptap/core';
|
|
2
|
+
export type SlashCommandContext = {
|
|
3
|
+
editor: Editor;
|
|
4
|
+
range: Range;
|
|
5
|
+
};
|
|
6
|
+
export type SlashItem = {
|
|
7
|
+
title: string;
|
|
8
|
+
subtitle?: string;
|
|
9
|
+
icon?: string;
|
|
10
|
+
keywords?: string[];
|
|
11
|
+
command: (context: SlashCommandContext) => void;
|
|
12
|
+
};
|
|
13
|
+
export type SlashGroup = {
|
|
14
|
+
section: string;
|
|
15
|
+
list: SlashItem[];
|
|
16
|
+
};
|
|
17
|
+
export type SlashDetail = null | 'emoji' | {
|
|
18
|
+
title: string;
|
|
19
|
+
placeholder: string;
|
|
20
|
+
handler: (input: string) => void;
|
|
21
|
+
};
|
|
22
|
+
export type SlashLocation = {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
height: number;
|
|
26
|
+
};
|
|
27
|
+
export type SlashProps = {
|
|
28
|
+
editor: Editor | null;
|
|
29
|
+
range: Range | null;
|
|
30
|
+
};
|
|
31
|
+
export type SlashEntry = SlashItem | SlashGroup;
|
|
32
|
+
export declare const slashState: {
|
|
33
|
+
visible: boolean;
|
|
34
|
+
items: SlashEntry[];
|
|
35
|
+
location: SlashLocation;
|
|
36
|
+
props: SlashProps;
|
|
37
|
+
detail: SlashDetail;
|
|
38
|
+
selection: (() => void) | null;
|
|
39
|
+
selectedIndex: number;
|
|
40
|
+
};
|
|
41
|
+
export declare const slashLocaltion: SlashLocation;
|
|
42
|
+
export declare function isSlashGroup(item: SlashEntry): item is SlashGroup;
|
|
43
|
+
export declare function isSlashItem(item: SlashEntry): item is SlashItem;
|
|
44
|
+
export declare function flattenSlashItems(items?: SlashEntry[]): SlashItem[];
|
|
45
|
+
export declare function countSlashItems(items?: SlashEntry[]): number;
|
|
46
|
+
export declare function moveSlashSelection(delta: number): void;
|
|
47
|
+
export declare function normalizeSlashIndex(): void;
|
|
48
|
+
export declare function setSlashItems(items: SlashEntry[]): void;
|
|
49
|
+
export declare function setSlashProps(props: SlashProps): void;
|
|
50
|
+
export declare function setSlashLocation(location: SlashLocation): void;
|
|
51
|
+
export declare function runSlashItemAt(index: number): boolean;
|
|
52
|
+
export declare function closeSlash(): void;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export const slashState = $state({
|
|
2
|
+
visible: false,
|
|
3
|
+
items: [],
|
|
4
|
+
location: { x: 0, y: 0, height: 0 },
|
|
5
|
+
props: { editor: null, range: null },
|
|
6
|
+
detail: null,
|
|
7
|
+
selection: null,
|
|
8
|
+
selectedIndex: 0
|
|
9
|
+
});
|
|
10
|
+
// keep typo alias for backward compatibility
|
|
11
|
+
export const slashLocaltion = slashState.location;
|
|
12
|
+
export function isSlashGroup(item) {
|
|
13
|
+
return 'list' in item;
|
|
14
|
+
}
|
|
15
|
+
export function isSlashItem(item) {
|
|
16
|
+
return 'command' in item;
|
|
17
|
+
}
|
|
18
|
+
export function flattenSlashItems(items = slashState.items) {
|
|
19
|
+
if (!items.length)
|
|
20
|
+
return [];
|
|
21
|
+
if (isSlashGroup(items[0])) {
|
|
22
|
+
return items.flatMap((item) => (isSlashGroup(item) ? item.list : []));
|
|
23
|
+
}
|
|
24
|
+
return items.filter(isSlashItem);
|
|
25
|
+
}
|
|
26
|
+
export function countSlashItems(items = slashState.items) {
|
|
27
|
+
return flattenSlashItems(items).length;
|
|
28
|
+
}
|
|
29
|
+
export function moveSlashSelection(delta) {
|
|
30
|
+
const count = countSlashItems();
|
|
31
|
+
if (count === 0) {
|
|
32
|
+
slashState.selectedIndex = 0;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
slashState.selectedIndex += delta;
|
|
36
|
+
normalizeSlashIndex();
|
|
37
|
+
}
|
|
38
|
+
export function normalizeSlashIndex() {
|
|
39
|
+
const count = countSlashItems();
|
|
40
|
+
if (count === 0) {
|
|
41
|
+
slashState.selectedIndex = 0;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
slashState.selectedIndex = ((slashState.selectedIndex % count) + count) % count;
|
|
45
|
+
}
|
|
46
|
+
export function setSlashItems(items) {
|
|
47
|
+
slashState.items = items;
|
|
48
|
+
normalizeSlashIndex();
|
|
49
|
+
}
|
|
50
|
+
export function setSlashProps(props) {
|
|
51
|
+
slashState.props = props;
|
|
52
|
+
}
|
|
53
|
+
export function setSlashLocation(location) {
|
|
54
|
+
slashState.location.x = location.x;
|
|
55
|
+
slashState.location.y = location.y;
|
|
56
|
+
slashState.location.height = location.height;
|
|
57
|
+
}
|
|
58
|
+
export function runSlashItemAt(index) {
|
|
59
|
+
const item = flattenSlashItems()[index];
|
|
60
|
+
const { editor, range } = slashState.props;
|
|
61
|
+
if (!item || !editor || !range)
|
|
62
|
+
return false;
|
|
63
|
+
item.command({ editor, range });
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
export function closeSlash() {
|
|
67
|
+
slashState.visible = false;
|
|
68
|
+
slashState.selectedIndex = 0;
|
|
69
|
+
}
|
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Editor } from '@tiptap/core';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
items: ({ query }: {
|
|
8
|
-
query: any;
|
|
9
|
-
}) => {
|
|
10
|
-
section: any;
|
|
11
|
-
list: any[];
|
|
12
|
-
}[];
|
|
13
|
-
render: () => {
|
|
14
|
-
onStart: (props: any) => void;
|
|
15
|
-
onUpdate(props: any): void;
|
|
16
|
-
onKeyDown(props: any): true | undefined;
|
|
17
|
-
onExit(): void;
|
|
18
|
-
};
|
|
19
|
-
};
|
|
1
|
+
import { type SlashDetail, type SlashGroup } from './stores.svelte';
|
|
2
|
+
import type { Editor, Range } from '@tiptap/core';
|
|
3
|
+
import { type SuggestionOptions } from '@tiptap/suggestion';
|
|
4
|
+
type DetailInput = Exclude<SlashDetail, null | 'emoji'>;
|
|
5
|
+
export declare function getDetail(editor: Editor, range: Range, option: DetailInput): void;
|
|
6
|
+
export declare const suggest: Omit<SuggestionOptions<SlashGroup>, 'editor'>;
|
|
20
7
|
declare const _default: (editor: Editor) => import("prosemirror-state").Plugin<any>;
|
|
21
8
|
export default _default;
|