@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.
Files changed (182) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/editor/RichTextEditor.d.ts +11 -4
  3. package/dist/editor/RichTextEditor.d.ts.map +1 -1
  4. package/dist/editor/RichTextEditor.js +124 -60
  5. package/dist/editor/RichTextEditor.js.map +1 -1
  6. package/dist/editor/RichTextView.d.ts +2 -1
  7. package/dist/editor/RichTextView.d.ts.map +1 -1
  8. package/dist/editor/RichTextView.js.map +1 -1
  9. package/dist/editor/core/containers.d.ts +2 -6
  10. package/dist/editor/core/containers.d.ts.map +1 -1
  11. package/dist/editor/core/containers.js +2 -1
  12. package/dist/editor/core/containers.js.map +1 -1
  13. package/dist/editor/core/customTool.d.ts +8 -2
  14. package/dist/editor/core/customTool.d.ts.map +1 -1
  15. package/dist/editor/core/customTool.js.map +1 -1
  16. package/dist/editor/core/customToolEngine.d.ts +9 -1
  17. package/dist/editor/core/customToolEngine.d.ts.map +1 -1
  18. package/dist/editor/core/customToolEngine.js +12 -0
  19. package/dist/editor/core/customToolEngine.js.map +1 -1
  20. package/dist/editor/core/extensions.d.ts.map +1 -1
  21. package/dist/editor/core/extensions.js +1 -1
  22. package/dist/editor/core/extensions.js.map +1 -1
  23. package/dist/editor/core/handle.d.ts +18 -5
  24. package/dist/editor/core/handle.d.ts.map +1 -1
  25. package/dist/editor/core/handle.js +2 -13
  26. package/dist/editor/core/handle.js.map +1 -1
  27. package/dist/editor/core/handleWatchers.d.ts +36 -0
  28. package/dist/editor/core/handleWatchers.d.ts.map +1 -0
  29. package/dist/editor/core/handleWatchers.js +29 -0
  30. package/dist/editor/core/handleWatchers.js.map +1 -0
  31. package/dist/editor/core/nodeNames.d.ts +7 -0
  32. package/dist/editor/core/nodeNames.d.ts.map +1 -0
  33. package/dist/editor/core/nodeNames.js +2 -0
  34. package/dist/editor/core/nodeNames.js.map +1 -0
  35. package/dist/editor/core/schema.d.ts.map +1 -1
  36. package/dist/editor/core/schema.js +4 -2
  37. package/dist/editor/core/schema.js.map +1 -1
  38. package/dist/editor/core/toolCommands.d.ts +78 -0
  39. package/dist/editor/core/toolCommands.d.ts.map +1 -0
  40. package/dist/editor/core/toolCommands.js +2 -0
  41. package/dist/editor/core/toolCommands.js.map +1 -0
  42. package/dist/editor/core/toolDefinition.d.ts +139 -0
  43. package/dist/editor/core/toolDefinition.d.ts.map +1 -0
  44. package/dist/editor/core/toolDefinition.js +28 -0
  45. package/dist/editor/core/toolDefinition.js.map +1 -0
  46. package/dist/editor/core/toolDescriptor.d.ts +71 -2
  47. package/dist/editor/core/toolDescriptor.d.ts.map +1 -1
  48. package/dist/editor/core/toolDescriptor.js +6 -2
  49. package/dist/editor/core/toolDescriptor.js.map +1 -1
  50. package/dist/editor/core/toolOptions.d.ts +157 -0
  51. package/dist/editor/core/toolOptions.d.ts.map +1 -0
  52. package/dist/editor/core/toolOptions.js +21 -0
  53. package/dist/editor/core/toolOptions.js.map +1 -0
  54. package/dist/editor/core/toolState.d.ts +46 -0
  55. package/dist/editor/core/toolState.d.ts.map +1 -0
  56. package/dist/editor/core/toolState.js +2 -0
  57. package/dist/editor/core/toolState.js.map +1 -0
  58. package/dist/editor/core/tools.d.ts +10 -3
  59. package/dist/editor/core/tools.d.ts.map +1 -1
  60. package/dist/editor/core/tools.js +2 -1
  61. package/dist/editor/core/tools.js.map +1 -1
  62. package/dist/editor/core/viewIsland.d.ts.map +1 -1
  63. package/dist/editor/core/viewIsland.js +2 -1
  64. package/dist/editor/core/viewIsland.js.map +1 -1
  65. package/dist/editor/features/builtins.d.ts +9 -4
  66. package/dist/editor/features/builtins.d.ts.map +1 -1
  67. package/dist/editor/features/builtins.js +36 -7
  68. package/dist/editor/features/builtins.js.map +1 -1
  69. package/dist/editor/features/search/SearchPanel.d.ts.map +1 -1
  70. package/dist/editor/features/search/SearchPanel.js +26 -12
  71. package/dist/editor/features/search/SearchPanel.js.map +1 -1
  72. package/dist/editor/features/search/revealMatch.d.ts +16 -0
  73. package/dist/editor/features/search/revealMatch.d.ts.map +1 -1
  74. package/dist/editor/features/search/revealMatch.js +22 -0
  75. package/dist/editor/features/search/revealMatch.js.map +1 -1
  76. package/dist/editor/features/search/searchPlugin.d.ts +8 -3
  77. package/dist/editor/features/search/searchPlugin.d.ts.map +1 -1
  78. package/dist/editor/features/search/searchPlugin.js +17 -6
  79. package/dist/editor/features/search/searchPlugin.js.map +1 -1
  80. package/dist/editor/features/search/searchSnapshot.d.ts +14 -0
  81. package/dist/editor/features/search/searchSnapshot.d.ts.map +1 -0
  82. package/dist/editor/features/search/searchSnapshot.js +17 -0
  83. package/dist/editor/features/search/searchSnapshot.js.map +1 -0
  84. package/dist/editor/features/search/searchTool.d.ts +3 -0
  85. package/dist/editor/features/search/searchTool.d.ts.map +1 -1
  86. package/dist/editor/features/search/searchTool.js +30 -1
  87. package/dist/editor/features/search/searchTool.js.map +1 -1
  88. package/dist/editor/features/toc/RichTextToc.d.ts +91 -0
  89. package/dist/editor/features/toc/RichTextToc.d.ts.map +1 -0
  90. package/dist/editor/features/toc/RichTextToc.js +417 -0
  91. package/dist/editor/features/toc/RichTextToc.js.map +1 -0
  92. package/dist/editor/features/toc/documentHeadings.d.ts +30 -0
  93. package/dist/editor/features/toc/documentHeadings.d.ts.map +1 -0
  94. package/dist/editor/features/toc/documentHeadings.js +20 -0
  95. package/dist/editor/features/toc/documentHeadings.js.map +1 -0
  96. package/dist/editor/features/toc/headings.d.ts +35 -0
  97. package/dist/editor/features/toc/headings.d.ts.map +1 -0
  98. package/dist/editor/features/toc/headings.js +27 -0
  99. package/dist/editor/features/toc/headings.js.map +1 -0
  100. package/dist/editor/features/toc/stickyOffset.d.ts +3 -0
  101. package/dist/editor/features/toc/stickyOffset.d.ts.map +1 -0
  102. package/dist/editor/features/toc/stickyOffset.js +14 -0
  103. package/dist/editor/features/toc/stickyOffset.js.map +1 -0
  104. package/dist/editor/features/toc/tocSnapshot.d.ts +10 -0
  105. package/dist/editor/features/toc/tocSnapshot.d.ts.map +1 -0
  106. package/dist/editor/features/toc/tocSnapshot.js +8 -0
  107. package/dist/editor/features/toc/tocSnapshot.js.map +1 -0
  108. package/dist/editor/features/toc/tocTool.d.ts +6 -0
  109. package/dist/editor/features/toc/tocTool.d.ts.map +1 -0
  110. package/dist/editor/features/toc/tocTool.js +21 -0
  111. package/dist/editor/features/toc/tocTool.js.map +1 -0
  112. package/dist/editor/hooks/useRichTextToolState.d.ts +43 -0
  113. package/dist/editor/hooks/useRichTextToolState.d.ts.map +1 -0
  114. package/dist/editor/hooks/useRichTextToolState.js +77 -0
  115. package/dist/editor/hooks/useRichTextToolState.js.map +1 -0
  116. package/dist/editor/index.d.ts +10 -0
  117. package/dist/editor/index.d.ts.map +1 -1
  118. package/dist/editor/index.js +4 -0
  119. package/dist/editor/index.js.map +1 -1
  120. package/dist/i18n/defaults.d.ts.map +1 -1
  121. package/dist/i18n/defaults.js +1 -0
  122. package/dist/i18n/defaults.js.map +1 -1
  123. package/dist/i18n/messages.d.ts +5 -0
  124. package/dist/i18n/messages.d.ts.map +1 -1
  125. package/dist/locales/ru.d.ts.map +1 -1
  126. package/dist/locales/ru.js +1 -0
  127. package/dist/locales/ru.js.map +1 -1
  128. package/docs/api/editor-extension.en.md +223 -23
  129. package/docs/api/editor-extension.md +224 -22
  130. package/docs/api/messages.en.md +743 -0
  131. package/docs/api/messages.md +1 -0
  132. package/docs/api/migration-notes.en.md +36 -1
  133. package/docs/api/migration-notes.md +35 -0
  134. package/docs/api/utilities.en.md +233 -0
  135. package/docs/components/content/rich-text-toc.en.md +132 -0
  136. package/docs/components/content/rich-text-toc.md +131 -0
  137. package/docs/components/index.en.md +3 -2
  138. package/docs/components/index.md +2 -1
  139. package/docs/components/inputs/rich-text-editor.en.md +277 -43
  140. package/docs/components/inputs/rich-text-editor.md +247 -11
  141. package/docs/conventions.en.md +318 -0
  142. package/docs/getting-started.en.md +7 -7
  143. package/docs/getting-started.md +6 -6
  144. package/docs/glossary.en.md +52 -47
  145. package/docs/glossary.md +51 -46
  146. package/docs/index.en.md +53 -0
  147. package/llms.txt +1 -0
  148. package/package.json +1 -1
  149. package/src/editor/RichTextEditor.tsx +197 -38
  150. package/src/editor/RichTextView.tsx +2 -1
  151. package/src/editor/core/containers.ts +8 -6
  152. package/src/editor/core/customTool.ts +8 -2
  153. package/src/editor/core/customToolEngine.ts +20 -1
  154. package/src/editor/core/extensions.ts +2 -1
  155. package/src/editor/core/handle.ts +26 -23
  156. package/src/editor/core/handleWatchers.ts +72 -0
  157. package/src/editor/core/nodeNames.ts +7 -0
  158. package/src/editor/core/schema.ts +5 -2
  159. package/src/editor/core/toolCommands.ts +85 -0
  160. package/src/editor/core/toolDefinition.ts +208 -0
  161. package/src/editor/core/toolDescriptor.ts +94 -3
  162. package/src/editor/core/toolOptions.ts +211 -0
  163. package/src/editor/core/toolState.ts +56 -0
  164. package/src/editor/core/tools.ts +12 -3
  165. package/src/editor/core/viewIsland.ts +5 -4
  166. package/src/editor/features/builtins.ts +72 -13
  167. package/src/editor/features/search/SearchPanel.tsx +38 -14
  168. package/src/editor/features/search/revealMatch.ts +45 -0
  169. package/src/editor/features/search/searchPlugin.ts +40 -11
  170. package/src/editor/features/search/searchSnapshot.ts +29 -0
  171. package/src/editor/features/search/searchTool.ts +51 -1
  172. package/src/editor/features/toc/RichTextToc.tsx +810 -0
  173. package/src/editor/features/toc/documentHeadings.ts +59 -0
  174. package/src/editor/features/toc/headings.ts +77 -0
  175. package/src/editor/features/toc/stickyOffset.ts +21 -0
  176. package/src/editor/features/toc/tocSnapshot.ts +24 -0
  177. package/src/editor/features/toc/tocTool.ts +41 -0
  178. package/src/editor/hooks/useRichTextToolState.ts +153 -0
  179. package/src/editor/index.ts +21 -0
  180. package/src/i18n/defaults.ts +1 -0
  181. package/src/i18n/messages.ts +5 -0
  182. 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: SearchOptions }
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
- function searchPlugin() {
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, "", EMPTY_OPTIONS, () => -1),
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, "", previous.options, () => -1);
114
+ if (meta?.type === "clear") return build(state, "", flags, () => -1);
96
115
  if (meta?.type === "set") {
97
- return build(state, meta.query, meta.options, (matches) =>
98
- indexFrom(matches, state.selection.from)
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
- setSearch: (query: string, options: SearchOptions) => ReturnType;
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: () => [searchPlugin()],
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
- engine: (context) => [SearchExtension.configure({ open: context.openSearch ?? (() => false) })],
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
  {