@olddevs/ui 4.3.0 → 4.5.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/CHANGELOG.md +36 -0
- package/dist/editor/RichTextEditor.d.ts +11 -4
- package/dist/editor/RichTextEditor.d.ts.map +1 -1
- package/dist/editor/RichTextEditor.js +124 -60
- package/dist/editor/RichTextEditor.js.map +1 -1
- package/dist/editor/RichTextView.d.ts +2 -1
- package/dist/editor/RichTextView.d.ts.map +1 -1
- package/dist/editor/RichTextView.js.map +1 -1
- package/dist/editor/core/containers.d.ts +2 -6
- package/dist/editor/core/containers.d.ts.map +1 -1
- package/dist/editor/core/containers.js +2 -1
- package/dist/editor/core/containers.js.map +1 -1
- package/dist/editor/core/customTool.d.ts +8 -2
- package/dist/editor/core/customTool.d.ts.map +1 -1
- package/dist/editor/core/customTool.js.map +1 -1
- package/dist/editor/core/customToolEngine.d.ts +9 -1
- package/dist/editor/core/customToolEngine.d.ts.map +1 -1
- package/dist/editor/core/customToolEngine.js +12 -0
- package/dist/editor/core/customToolEngine.js.map +1 -1
- package/dist/editor/core/extensions.d.ts.map +1 -1
- package/dist/editor/core/extensions.js +1 -1
- package/dist/editor/core/extensions.js.map +1 -1
- package/dist/editor/core/handle.d.ts +18 -5
- package/dist/editor/core/handle.d.ts.map +1 -1
- package/dist/editor/core/handle.js +2 -13
- package/dist/editor/core/handle.js.map +1 -1
- package/dist/editor/core/handleWatchers.d.ts +36 -0
- package/dist/editor/core/handleWatchers.d.ts.map +1 -0
- package/dist/editor/core/handleWatchers.js +29 -0
- package/dist/editor/core/handleWatchers.js.map +1 -0
- package/dist/editor/core/nodeNames.d.ts +7 -0
- package/dist/editor/core/nodeNames.d.ts.map +1 -0
- package/dist/editor/core/nodeNames.js +2 -0
- package/dist/editor/core/nodeNames.js.map +1 -0
- package/dist/editor/core/schema.d.ts.map +1 -1
- package/dist/editor/core/schema.js +4 -2
- package/dist/editor/core/schema.js.map +1 -1
- package/dist/editor/core/toolCommands.d.ts +78 -0
- package/dist/editor/core/toolCommands.d.ts.map +1 -0
- package/dist/editor/core/toolCommands.js +2 -0
- package/dist/editor/core/toolCommands.js.map +1 -0
- package/dist/editor/core/toolDefinition.d.ts +139 -0
- package/dist/editor/core/toolDefinition.d.ts.map +1 -0
- package/dist/editor/core/toolDefinition.js +28 -0
- package/dist/editor/core/toolDefinition.js.map +1 -0
- package/dist/editor/core/toolDescriptor.d.ts +71 -2
- package/dist/editor/core/toolDescriptor.d.ts.map +1 -1
- package/dist/editor/core/toolDescriptor.js +6 -2
- package/dist/editor/core/toolDescriptor.js.map +1 -1
- package/dist/editor/core/toolOptions.d.ts +157 -0
- package/dist/editor/core/toolOptions.d.ts.map +1 -0
- package/dist/editor/core/toolOptions.js +21 -0
- package/dist/editor/core/toolOptions.js.map +1 -0
- package/dist/editor/core/toolState.d.ts +46 -0
- package/dist/editor/core/toolState.d.ts.map +1 -0
- package/dist/editor/core/toolState.js +2 -0
- package/dist/editor/core/toolState.js.map +1 -0
- package/dist/editor/core/tools.d.ts +10 -3
- package/dist/editor/core/tools.d.ts.map +1 -1
- package/dist/editor/core/tools.js +2 -1
- package/dist/editor/core/tools.js.map +1 -1
- package/dist/editor/core/viewIsland.d.ts.map +1 -1
- package/dist/editor/core/viewIsland.js +2 -1
- package/dist/editor/core/viewIsland.js.map +1 -1
- package/dist/editor/features/builtins.d.ts +9 -4
- package/dist/editor/features/builtins.d.ts.map +1 -1
- package/dist/editor/features/builtins.js +36 -7
- package/dist/editor/features/builtins.js.map +1 -1
- package/dist/editor/features/search/SearchPanel.d.ts.map +1 -1
- package/dist/editor/features/search/SearchPanel.js +26 -12
- package/dist/editor/features/search/SearchPanel.js.map +1 -1
- package/dist/editor/features/search/revealMatch.d.ts +16 -0
- package/dist/editor/features/search/revealMatch.d.ts.map +1 -1
- package/dist/editor/features/search/revealMatch.js +22 -0
- package/dist/editor/features/search/revealMatch.js.map +1 -1
- package/dist/editor/features/search/searchPlugin.d.ts +8 -3
- package/dist/editor/features/search/searchPlugin.d.ts.map +1 -1
- package/dist/editor/features/search/searchPlugin.js +17 -6
- package/dist/editor/features/search/searchPlugin.js.map +1 -1
- package/dist/editor/features/search/searchSnapshot.d.ts +14 -0
- package/dist/editor/features/search/searchSnapshot.d.ts.map +1 -0
- package/dist/editor/features/search/searchSnapshot.js +17 -0
- package/dist/editor/features/search/searchSnapshot.js.map +1 -0
- package/dist/editor/features/search/searchTool.d.ts +3 -0
- package/dist/editor/features/search/searchTool.d.ts.map +1 -1
- package/dist/editor/features/search/searchTool.js +30 -1
- package/dist/editor/features/search/searchTool.js.map +1 -1
- package/dist/editor/features/toc/RichTextToc.d.ts +91 -0
- package/dist/editor/features/toc/RichTextToc.d.ts.map +1 -0
- package/dist/editor/features/toc/RichTextToc.js +417 -0
- package/dist/editor/features/toc/RichTextToc.js.map +1 -0
- package/dist/editor/features/toc/documentHeadings.d.ts +30 -0
- package/dist/editor/features/toc/documentHeadings.d.ts.map +1 -0
- package/dist/editor/features/toc/documentHeadings.js +20 -0
- package/dist/editor/features/toc/documentHeadings.js.map +1 -0
- package/dist/editor/features/toc/headings.d.ts +35 -0
- package/dist/editor/features/toc/headings.d.ts.map +1 -0
- package/dist/editor/features/toc/headings.js +27 -0
- package/dist/editor/features/toc/headings.js.map +1 -0
- package/dist/editor/features/toc/stickyOffset.d.ts +3 -0
- package/dist/editor/features/toc/stickyOffset.d.ts.map +1 -0
- package/dist/editor/features/toc/stickyOffset.js +14 -0
- package/dist/editor/features/toc/stickyOffset.js.map +1 -0
- package/dist/editor/features/toc/tocSnapshot.d.ts +10 -0
- package/dist/editor/features/toc/tocSnapshot.d.ts.map +1 -0
- package/dist/editor/features/toc/tocSnapshot.js +8 -0
- package/dist/editor/features/toc/tocSnapshot.js.map +1 -0
- package/dist/editor/features/toc/tocTool.d.ts +6 -0
- package/dist/editor/features/toc/tocTool.d.ts.map +1 -0
- package/dist/editor/features/toc/tocTool.js +21 -0
- package/dist/editor/features/toc/tocTool.js.map +1 -0
- package/dist/editor/hooks/useRichTextToolState.d.ts +43 -0
- package/dist/editor/hooks/useRichTextToolState.d.ts.map +1 -0
- package/dist/editor/hooks/useRichTextToolState.js +77 -0
- package/dist/editor/hooks/useRichTextToolState.js.map +1 -0
- package/dist/editor/index.d.ts +10 -0
- package/dist/editor/index.d.ts.map +1 -1
- package/dist/editor/index.js +4 -0
- package/dist/editor/index.js.map +1 -1
- package/dist/i18n/defaults.d.ts.map +1 -1
- package/dist/i18n/defaults.js +1 -0
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/messages.d.ts +5 -0
- package/dist/i18n/messages.d.ts.map +1 -1
- package/dist/locales/ru.d.ts.map +1 -1
- package/dist/locales/ru.js +1 -0
- package/dist/locales/ru.js.map +1 -1
- package/docs/api/editor-extension.en.md +223 -23
- package/docs/api/editor-extension.md +224 -22
- package/docs/api/messages.en.md +743 -0
- package/docs/api/messages.md +1 -0
- package/docs/api/migration-notes.en.md +36 -1
- package/docs/api/migration-notes.md +35 -0
- package/docs/api/utilities.en.md +233 -0
- package/docs/components/content/rich-text-toc.en.md +132 -0
- package/docs/components/content/rich-text-toc.md +131 -0
- package/docs/components/index.en.md +3 -2
- package/docs/components/index.md +2 -1
- package/docs/components/inputs/rich-text-editor.en.md +277 -43
- package/docs/components/inputs/rich-text-editor.md +247 -11
- package/docs/conventions.en.md +318 -0
- package/docs/getting-started.en.md +7 -7
- package/docs/getting-started.md +6 -6
- package/docs/glossary.en.md +52 -47
- package/docs/glossary.md +51 -46
- package/docs/index.en.md +53 -0
- package/llms.txt +1 -0
- package/package.json +1 -1
- package/src/editor/RichTextEditor.tsx +197 -38
- package/src/editor/RichTextView.tsx +2 -1
- package/src/editor/core/containers.ts +8 -6
- package/src/editor/core/customTool.ts +8 -2
- package/src/editor/core/customToolEngine.ts +20 -1
- package/src/editor/core/extensions.ts +2 -1
- package/src/editor/core/handle.ts +26 -23
- package/src/editor/core/handleWatchers.ts +72 -0
- package/src/editor/core/nodeNames.ts +7 -0
- package/src/editor/core/schema.ts +5 -2
- package/src/editor/core/toolCommands.ts +85 -0
- package/src/editor/core/toolDefinition.ts +208 -0
- package/src/editor/core/toolDescriptor.ts +94 -3
- package/src/editor/core/toolOptions.ts +211 -0
- package/src/editor/core/toolState.ts +56 -0
- package/src/editor/core/tools.ts +12 -3
- package/src/editor/core/viewIsland.ts +5 -4
- package/src/editor/features/builtins.ts +72 -13
- package/src/editor/features/search/SearchPanel.tsx +38 -14
- package/src/editor/features/search/revealMatch.ts +45 -0
- package/src/editor/features/search/searchPlugin.ts +40 -11
- package/src/editor/features/search/searchSnapshot.ts +29 -0
- package/src/editor/features/search/searchTool.ts +51 -1
- package/src/editor/features/toc/RichTextToc.tsx +810 -0
- package/src/editor/features/toc/documentHeadings.ts +59 -0
- package/src/editor/features/toc/headings.ts +77 -0
- package/src/editor/features/toc/stickyOffset.ts +21 -0
- package/src/editor/features/toc/tocSnapshot.ts +24 -0
- package/src/editor/features/toc/tocTool.ts +41 -0
- package/src/editor/hooks/useRichTextToolState.ts +153 -0
- package/src/editor/index.ts +21 -0
- package/src/i18n/defaults.ts +1 -0
- package/src/i18n/messages.ts +5 -0
- package/src/locales/ru.ts +1 -0
|
@@ -23,7 +23,7 @@ interface SearchPluginState {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
type SearchMeta =
|
|
26
|
-
| { type: "set"; query: string; options
|
|
26
|
+
| { type: "set"; query: string; options?: Partial<SearchOptions> }
|
|
27
27
|
| { type: "select"; index: number }
|
|
28
28
|
| { type: "clear" };
|
|
29
29
|
|
|
@@ -85,17 +85,39 @@ function build(
|
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Флажки после `setSearch`: названные в `named` заменяют прежние, остальные
|
|
90
|
+
* остаются. Ключ со значением `undefined` — не названный: обычное слияние
|
|
91
|
+
* `{ ...a, ...b }` стёрло бы им флажок, а вызов `setQuery(q, { matchCase: value })`
|
|
92
|
+
* с необязательным значением экрана не просит ничего менять.
|
|
93
|
+
*/
|
|
94
|
+
function withNamedFlags(current: SearchOptions, named: Partial<SearchOptions> = {}): SearchOptions {
|
|
95
|
+
const next = { ...current };
|
|
96
|
+
for (const key of Object.keys(named) as (keyof SearchOptions)[]) {
|
|
97
|
+
const value = named[key];
|
|
98
|
+
if (value !== undefined) next[key] = value;
|
|
99
|
+
}
|
|
100
|
+
return next;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @param flags флажки без запроса: до первого `setSearch` и после `clearSearch`
|
|
105
|
+
* (Опции Инструмента). Поиск, который идёт, держит свои.
|
|
106
|
+
*/
|
|
107
|
+
function searchPlugin(flags: SearchOptions) {
|
|
89
108
|
return new Plugin<SearchPluginState>({
|
|
90
109
|
key: SEARCH_KEY,
|
|
91
110
|
state: {
|
|
92
|
-
init: (_, state) => build(state, "",
|
|
111
|
+
init: (_, state) => build(state, "", flags, () => -1),
|
|
93
112
|
apply(tr: Transaction, previous, _old, state) {
|
|
94
113
|
const meta = tr.getMeta(SEARCH_KEY) as SearchMeta | undefined;
|
|
95
|
-
if (meta?.type === "clear") return build(state, "",
|
|
114
|
+
if (meta?.type === "clear") return build(state, "", flags, () => -1);
|
|
96
115
|
if (meta?.type === "set") {
|
|
97
|
-
return build(
|
|
98
|
-
|
|
116
|
+
return build(
|
|
117
|
+
state,
|
|
118
|
+
meta.query,
|
|
119
|
+
withNamedFlags(previous.options, meta.options),
|
|
120
|
+
(matches) => indexFrom(matches, state.selection.from)
|
|
99
121
|
);
|
|
100
122
|
}
|
|
101
123
|
if (meta?.type === "select") {
|
|
@@ -151,8 +173,11 @@ function replaceRange(tr: Transaction, { from, to }: SearchMatch, text: string)
|
|
|
151
173
|
declare module "@tiptap/core" {
|
|
152
174
|
interface Commands<ReturnType> {
|
|
153
175
|
search: {
|
|
154
|
-
/**
|
|
155
|
-
|
|
176
|
+
/**
|
|
177
|
+
* Новый запрос или флажки: совпадения пересчитываются, текущее — первое после
|
|
178
|
+
* каретки. Не названные флажки остаются как были.
|
|
179
|
+
*/
|
|
180
|
+
setSearch: (query: string, options?: Partial<SearchOptions>) => ReturnType;
|
|
156
181
|
/**
|
|
157
182
|
* Следующее (`1`) или предыдущее (`-1`) совпадение по кругу; выделяет его.
|
|
158
183
|
* Прокрутка ProseMirror срабатывает, только когда фокус в Документе; из
|
|
@@ -163,13 +188,15 @@ declare module "@tiptap/core" {
|
|
|
163
188
|
replaceMatch: (replacement: string) => ReturnType;
|
|
164
189
|
/** Заменить все совпадения — одна транзакция, одна отмена. */
|
|
165
190
|
replaceAllMatches: (replacement: string) => ReturnType;
|
|
166
|
-
/** Убрать запрос и
|
|
191
|
+
/** Убрать запрос и подсветку; флажки вернутся к Опциям Инструмента. */
|
|
167
192
|
clearSearch: () => ReturnType;
|
|
168
193
|
};
|
|
169
194
|
}
|
|
170
195
|
}
|
|
171
196
|
|
|
172
197
|
export interface SearchExtensionOptions {
|
|
198
|
+
/** Флажки, с которых стартует поиск и к которым он возвращается: Опции Инструмента. */
|
|
199
|
+
flags: SearchOptions;
|
|
173
200
|
/**
|
|
174
201
|
* Открыть панель поиска (`replace` — с фокусом в поле замены). Панель держит
|
|
175
202
|
* `RichTextEditor`; `false` — панели нет, и `Mod+F` уходит браузеру.
|
|
@@ -186,8 +213,10 @@ export interface SearchExtensionOptions {
|
|
|
186
213
|
*/
|
|
187
214
|
export const SearchExtension = Extension.create<SearchExtensionOptions>({
|
|
188
215
|
name: "search",
|
|
189
|
-
addOptions: () => ({ open: () => false }),
|
|
190
|
-
addProseMirrorPlugins
|
|
216
|
+
addOptions: () => ({ open: () => false, flags: EMPTY_OPTIONS }),
|
|
217
|
+
addProseMirrorPlugins() {
|
|
218
|
+
return [searchPlugin(this.options.flags)];
|
|
219
|
+
},
|
|
191
220
|
addKeyboardShortcuts() {
|
|
192
221
|
return {
|
|
193
222
|
"Mod-f": () => this.options.open(false),
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { Editor } from "@tiptap/core";
|
|
4
|
+
import type { SearchToolState } from "../../core/toolState.js";
|
|
5
|
+
import { searchState } from "./searchPlugin.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Снимок Состояния `search` для `useRichTextToolState`: открытые поля
|
|
9
|
+
* `searchState` плагина плюс открытость панели, без позиций совпадений. Лежит
|
|
10
|
+
* отдельно от `searchPlugin.ts`: вычисление нужно только хуку и не должно
|
|
11
|
+
* попадать в статический граф Редактора.
|
|
12
|
+
*
|
|
13
|
+
* Флажки — из плагина и при закрытой панели: их держит движок, а не панель.
|
|
14
|
+
* Закрытие возвращает их к стартовым из Опций, а `setQuery` без панели ставит
|
|
15
|
+
* свои. `null` — плагина нет (Инструмент `search` не вошёл в движок).
|
|
16
|
+
*/
|
|
17
|
+
export function searchSnapshot(editor: Editor, open: boolean): SearchToolState | null {
|
|
18
|
+
const state = searchState(editor.state);
|
|
19
|
+
if (!state) return null;
|
|
20
|
+
const { matchCase, wholeWord, regex } = state.options;
|
|
21
|
+
return {
|
|
22
|
+
open,
|
|
23
|
+
query: state.query,
|
|
24
|
+
flags: { matchCase, wholeWord, regex },
|
|
25
|
+
total: state.total,
|
|
26
|
+
current: state.current,
|
|
27
|
+
error: state.error ?? null,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import type { Editor } from "@tiptap/core";
|
|
3
4
|
import type { ToolDescriptor } from "../../core/toolDescriptor.js";
|
|
5
|
+
import type { SearchToolCommands } from "../../core/toolCommands.js";
|
|
6
|
+
import type { SearchToolOptions } from "../../core/toolOptions.js";
|
|
4
7
|
import { SearchExtension } from "./searchPlugin.js";
|
|
5
8
|
|
|
6
9
|
/**
|
|
@@ -14,9 +17,56 @@ import { SearchExtension } from "./searchPlugin.js";
|
|
|
14
17
|
/** Сочетание кнопки «Поиск»: строка справочника и подсказка кнопки — из одной записи. */
|
|
15
18
|
export const SEARCH_KEYS = ["mod", "F"] as const;
|
|
16
19
|
|
|
20
|
+
/** Стартовые флажки панели: все выключены. */
|
|
21
|
+
export const SEARCH_DEFAULTS: SearchToolOptions = {
|
|
22
|
+
matchCase: false,
|
|
23
|
+
wholeWord: false,
|
|
24
|
+
regex: false,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const isFlag = (value: unknown) => typeof value === "boolean";
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
Показать текущее совпадение после команды. ProseMirror прокручивает только
|
|
31
|
+
при фокусе в Документе, а команды зовут и с кнопки экрана. Код прокрутки
|
|
32
|
+
(`revealMatch.ts`) лежит в ленивом куске панели и в старт не входит:
|
|
33
|
+
грузится при первом вызове, поэтому прокрутка приходит на микрозадачу и кадр
|
|
34
|
+
позже. Открытая панель уже подгрузила его, и её переходы сливаются с этим
|
|
35
|
+
вызовом в одну прокрутку.
|
|
36
|
+
*/
|
|
37
|
+
const reveal = (editor: Editor, done: boolean) => {
|
|
38
|
+
if (done) void import("./revealMatch.js").then((module) => module.scheduleRevealMatch(editor));
|
|
39
|
+
return done;
|
|
40
|
+
};
|
|
41
|
+
|
|
17
42
|
export const SEARCH_TOOL: ToolDescriptor = {
|
|
18
43
|
name: "search",
|
|
19
|
-
|
|
44
|
+
defaults: SEARCH_DEFAULTS,
|
|
45
|
+
checks: { matchCase: isFlag, wholeWord: isFlag, regex: isFlag },
|
|
46
|
+
/*
|
|
47
|
+
Запрос, переходы и замена — команды движка, как у панели; панель и HTML-режим
|
|
48
|
+
знает мост. `editor.commands` читается при каждом вызове, а не один раз:
|
|
49
|
+
Tiptap собирает его вместе с транзакцией, и сохранённый набор отправил бы
|
|
50
|
+
устаревшую.
|
|
51
|
+
*/
|
|
52
|
+
commands: ({ editor, bridge }): SearchToolCommands => ({
|
|
53
|
+
open: (options) => bridge.openSearch(options?.replace === true, options?.query),
|
|
54
|
+
close: bridge.closeSearch,
|
|
55
|
+
setQuery: (query, flags) =>
|
|
56
|
+
!bridge.sourceOpen() &&
|
|
57
|
+
editor.commands.setSearch(query, flags) &&
|
|
58
|
+
(reveal(editor, query !== ""), true),
|
|
59
|
+
next: () => reveal(editor, editor.commands.searchStep(1)),
|
|
60
|
+
previous: () => reveal(editor, editor.commands.searchStep(-1)),
|
|
61
|
+
replace: (text) => editor.commands.replaceMatch(text),
|
|
62
|
+
replaceAll: (text) => editor.commands.replaceAllMatches(text),
|
|
63
|
+
}),
|
|
64
|
+
engine: (context, options) => [
|
|
65
|
+
SearchExtension.configure({
|
|
66
|
+
open: context.openSearch ?? (() => false),
|
|
67
|
+
flags: options as SearchToolOptions,
|
|
68
|
+
}),
|
|
69
|
+
],
|
|
20
70
|
shortcuts: [
|
|
21
71
|
{ id: "search", group: "search", tool: "search", keys: SEARCH_KEYS, label: (m) => m.search },
|
|
22
72
|
{
|