@medway-ui/notes-core 0.1.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/README.md +127 -0
- package/dist/document/normalize.d.ts +61 -0
- package/dist/document/normalize.d.ts.map +1 -0
- package/dist/document/normalize.js +373 -0
- package/dist/document/normalize.js.map +1 -0
- package/dist/document/types.d.ts +47 -0
- package/dist/document/types.d.ts.map +1 -0
- package/dist/document/types.js +9 -0
- package/dist/document/types.js.map +1 -0
- package/dist/editor/handle.d.ts +28 -0
- package/dist/editor/handle.d.ts.map +1 -0
- package/dist/editor/handle.js +34 -0
- package/dist/editor/handle.js.map +1 -0
- package/dist/editor/slashCommands.d.ts +21 -0
- package/dist/editor/slashCommands.d.ts.map +1 -0
- package/dist/editor/slashCommands.js +98 -0
- package/dist/editor/slashCommands.js.map +1 -0
- package/dist/editor/vocabulary.d.ts +110 -0
- package/dist/editor/vocabulary.d.ts.map +1 -0
- package/dist/editor/vocabulary.js +11 -0
- package/dist/editor/vocabulary.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/schema/contract.d.ts +14 -0
- package/dist/schema/contract.d.ts.map +1 -0
- package/dist/schema/contract.js +51 -0
- package/dist/schema/contract.js.map +1 -0
- package/dist/schema/extensions.d.ts +23 -0
- package/dist/schema/extensions.d.ts.map +1 -0
- package/dist/schema/extensions.js +81 -0
- package/dist/schema/extensions.js.map +1 -0
- package/dist/schema/image.d.ts +14 -0
- package/dist/schema/image.d.ts.map +1 -0
- package/dist/schema/image.js +28 -0
- package/dist/schema/image.js.map +1 -0
- package/dist/schema/index.d.ts +17 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +18 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/slashCommand.d.ts +19 -0
- package/dist/schema/slashCommand.d.ts.map +1 -0
- package/dist/schema/slashCommand.js +146 -0
- package/dist/schema/slashCommand.js.map +1 -0
- package/package.json +134 -0
- package/src/document/normalize.ts +456 -0
- package/src/document/types.ts +74 -0
- package/src/editor/handle.ts +65 -0
- package/src/editor/slashCommands.ts +120 -0
- package/src/editor/vocabulary.ts +126 -0
- package/src/index.ts +52 -0
- package/src/schema/contract.ts +76 -0
- package/src/schema/extensions.ts +120 -0
- package/src/schema/image.ts +44 -0
- package/src/schema/index.ts +29 -0
- package/src/schema/slashCommand.ts +181 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { EditorDocument } from '../document/types.js';
|
|
2
|
+
import type { EditorCommand, EditorSelectionState, SlashCommandId, SlashMenuState } from './vocabulary.js';
|
|
3
|
+
/**
|
|
4
|
+
* What every host exposes once it has an editor running — a WebView plus
|
|
5
|
+
* message bridge on React Native, an in-process Tiptap `Editor` on web.
|
|
6
|
+
* Neither the WebView nor the `Editor` may leak past this interface.
|
|
7
|
+
*/
|
|
8
|
+
export type NoteEditorHandle = {
|
|
9
|
+
/** `false` until the editor is mounted and ready to accept commands. */
|
|
10
|
+
isReady: boolean;
|
|
11
|
+
state: EditorSelectionState;
|
|
12
|
+
slash: SlashMenuState;
|
|
13
|
+
/**
|
|
14
|
+
* Pulls the current document. Asynchronous because on React Native it is a
|
|
15
|
+
* round trip across the bridge — the document is serialized on demand, never
|
|
16
|
+
* pushed on every keystroke.
|
|
17
|
+
*/
|
|
18
|
+
requestDocument: () => Promise<EditorDocument>;
|
|
19
|
+
runCommand: (command: EditorCommand) => void;
|
|
20
|
+
runSlashCommand: (commandId: SlashCommandId) => void;
|
|
21
|
+
dismissSlash: () => void;
|
|
22
|
+
focus: (position?: 'start' | 'end') => void;
|
|
23
|
+
blur: () => void;
|
|
24
|
+
};
|
|
25
|
+
/** The state a host starts from, before the editor has reported anything. */
|
|
26
|
+
export declare const INITIAL_EDITOR_STATE: EditorSelectionState;
|
|
27
|
+
export declare const EMPTY_SLASH_STATE: SlashMenuState;
|
|
28
|
+
//# sourceMappingURL=handle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handle.d.ts","sourceRoot":"","sources":["../../src/editor/handle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,cAAc,EACf,MAAM,iBAAiB,CAAC;AAEzB;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,oBAAoB,CAAC;IAC5B,KAAK,EAAE,cAAc,CAAC;IACtB;;;;OAIG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;IAC/C,UAAU,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,eAAe,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IACrD,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC;IAC5C,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,EAAE,oBAyBlC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,cAK/B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** The state a host starts from, before the editor has reported anything. */
|
|
2
|
+
export const INITIAL_EDITOR_STATE = {
|
|
3
|
+
isFocused: false,
|
|
4
|
+
isEmpty: true,
|
|
5
|
+
canUndo: false,
|
|
6
|
+
canRedo: false,
|
|
7
|
+
canIndent: false,
|
|
8
|
+
canOutdent: false,
|
|
9
|
+
active: {
|
|
10
|
+
bold: false,
|
|
11
|
+
italic: false,
|
|
12
|
+
underline: false,
|
|
13
|
+
strike: false,
|
|
14
|
+
code: false,
|
|
15
|
+
link: false,
|
|
16
|
+
paragraph: true,
|
|
17
|
+
heading1: false,
|
|
18
|
+
heading2: false,
|
|
19
|
+
heading3: false,
|
|
20
|
+
bulletList: false,
|
|
21
|
+
orderedList: false,
|
|
22
|
+
taskList: false,
|
|
23
|
+
blockquote: false,
|
|
24
|
+
codeBlock: false,
|
|
25
|
+
},
|
|
26
|
+
linkHref: null,
|
|
27
|
+
};
|
|
28
|
+
export const EMPTY_SLASH_STATE = {
|
|
29
|
+
active: false,
|
|
30
|
+
query: '',
|
|
31
|
+
commandIds: [],
|
|
32
|
+
caret: null,
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=handle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handle.js","sourceRoot":"","sources":["../../src/editor/handle.ts"],"names":[],"mappings":"AA+BA,6EAA6E;AAC7E,MAAM,CAAC,MAAM,oBAAoB,GAAyB;IACxD,SAAS,EAAE,KAAK;IAChB,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,KAAK;IAChB,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE;QACN,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,KAAK;QACX,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,KAAK;QACf,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,KAAK;QACf,UAAU,EAAE,KAAK;QACjB,SAAS,EAAE,KAAK;KACjB;IACD,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAmB;IAC/C,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,EAAE;IACT,UAAU,EAAE,EAAE;IACd,KAAK,EAAE,IAAI;CACZ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catalog behind the `/` menu. The editor filters ids by `keywords` as the
|
|
3
|
+
* student types; the host renders the labels and icons — natively on mobile, in
|
|
4
|
+
* the DOM on the web. Keeping one list is what stops the ends from disagreeing
|
|
5
|
+
* about which commands exist.
|
|
6
|
+
*
|
|
7
|
+
* Dependency-free on purpose: both the editor and every host read this list.
|
|
8
|
+
*/
|
|
9
|
+
import type { SlashCommandId } from './vocabulary.js';
|
|
10
|
+
export type SlashCommandDefinition = {
|
|
11
|
+
id: SlashCommandId;
|
|
12
|
+
label: string;
|
|
13
|
+
description: string;
|
|
14
|
+
/** Lowercase, unaccented terms matched against the typed query. */
|
|
15
|
+
keywords: string[];
|
|
16
|
+
};
|
|
17
|
+
export declare const SLASH_COMMANDS: readonly SlashCommandDefinition[];
|
|
18
|
+
/** Filters the catalog by the text typed after `/`. Empty query lists all. */
|
|
19
|
+
export declare const filterSlashCommands: (query: string) => SlashCommandId[];
|
|
20
|
+
export declare const getSlashCommand: (id: SlashCommandId) => SlashCommandDefinition | undefined;
|
|
21
|
+
//# sourceMappingURL=slashCommands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slashCommands.d.ts","sourceRoot":"","sources":["../../src/editor/slashCommands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,cAAc,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,SAAS,sBAAsB,EAmE3D,CAAC;AAiBF,8EAA8E;AAC9E,eAAO,MAAM,mBAAmB,GAAI,OAAO,MAAM,KAAG,cAAc,EAUjE,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,IAAI,cAAc,KACjB,sBAAsB,GAAG,SACyB,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catalog behind the `/` menu. The editor filters ids by `keywords` as the
|
|
3
|
+
* student types; the host renders the labels and icons — natively on mobile, in
|
|
4
|
+
* the DOM on the web. Keeping one list is what stops the ends from disagreeing
|
|
5
|
+
* about which commands exist.
|
|
6
|
+
*
|
|
7
|
+
* Dependency-free on purpose: both the editor and every host read this list.
|
|
8
|
+
*/
|
|
9
|
+
export const SLASH_COMMANDS = [
|
|
10
|
+
{
|
|
11
|
+
id: 'paragraph',
|
|
12
|
+
label: 'Texto',
|
|
13
|
+
description: 'Parágrafo simples',
|
|
14
|
+
keywords: ['texto', 'paragrafo', 'text', 'p'],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: 'heading1',
|
|
18
|
+
label: 'Título 1',
|
|
19
|
+
description: 'Título de seção grande',
|
|
20
|
+
keywords: ['titulo1', 'titulo', 'h1', 'heading'],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: 'heading2',
|
|
24
|
+
label: 'Título 2',
|
|
25
|
+
description: 'Título de seção médio',
|
|
26
|
+
keywords: ['titulo2', 'titulo', 'h2', 'heading'],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'heading3',
|
|
30
|
+
label: 'Título 3',
|
|
31
|
+
description: 'Título de seção pequeno',
|
|
32
|
+
keywords: ['titulo3', 'titulo', 'h3', 'heading'],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'bulletList',
|
|
36
|
+
label: 'Lista',
|
|
37
|
+
description: 'Lista com marcadores',
|
|
38
|
+
keywords: ['lista', 'bullet', 'marcador', 'ul'],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 'orderedList',
|
|
42
|
+
label: 'Lista numerada',
|
|
43
|
+
description: 'Lista ordenada',
|
|
44
|
+
keywords: ['lista', 'numerada', 'ordenada', 'ol', 'numero'],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'taskList',
|
|
48
|
+
label: 'Checklist',
|
|
49
|
+
description: 'Lista de tarefas',
|
|
50
|
+
keywords: ['checklist', 'tarefa', 'todo', 'check', 'caixa'],
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: 'blockquote',
|
|
54
|
+
label: 'Citação',
|
|
55
|
+
description: 'Bloco de citação',
|
|
56
|
+
keywords: ['citacao', 'quote', 'aspas'],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 'codeBlock',
|
|
60
|
+
label: 'Código',
|
|
61
|
+
description: 'Bloco de código',
|
|
62
|
+
keywords: ['codigo', 'code', 'bloco'],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'horizontalRule',
|
|
66
|
+
label: 'Divisor',
|
|
67
|
+
description: 'Linha divisória',
|
|
68
|
+
keywords: ['divisor', 'linha', 'separador', 'hr'],
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'image',
|
|
72
|
+
label: 'Imagem',
|
|
73
|
+
description: 'Insere uma imagem',
|
|
74
|
+
keywords: ['imagem', 'foto', 'image', 'picture', 'upload'],
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
const ACCENTS = 'áàâãäéèêëíìîïóòôõöúùûüçñ';
|
|
78
|
+
const PLAIN = 'aaaaaeeeeiiiiooooouuuucn';
|
|
79
|
+
/** Lowercases and strips accents so "citacao" matches "citação". */
|
|
80
|
+
const normalizeTerm = (term) => term
|
|
81
|
+
.toLowerCase()
|
|
82
|
+
.trim()
|
|
83
|
+
.split('')
|
|
84
|
+
.map((char) => {
|
|
85
|
+
const accentIndex = ACCENTS.indexOf(char);
|
|
86
|
+
return accentIndex === -1 ? char : PLAIN[accentIndex];
|
|
87
|
+
})
|
|
88
|
+
.join('');
|
|
89
|
+
/** Filters the catalog by the text typed after `/`. Empty query lists all. */
|
|
90
|
+
export const filterSlashCommands = (query) => {
|
|
91
|
+
const term = normalizeTerm(query);
|
|
92
|
+
if (!term) {
|
|
93
|
+
return SLASH_COMMANDS.map((command) => command.id);
|
|
94
|
+
}
|
|
95
|
+
return SLASH_COMMANDS.filter((command) => command.keywords.some((keyword) => normalizeTerm(keyword).startsWith(term))).map((command) => command.id);
|
|
96
|
+
};
|
|
97
|
+
export const getSlashCommand = (id) => SLASH_COMMANDS.find((command) => command.id === id);
|
|
98
|
+
//# sourceMappingURL=slashCommands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slashCommands.js","sourceRoot":"","sources":["../../src/editor/slashCommands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH,MAAM,CAAC,MAAM,cAAc,GAAsC;IAC/D;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,OAAO;QACd,WAAW,EAAE,mBAAmB;QAChC,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC;KAC9C;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,wBAAwB;QACrC,QAAQ,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC;KACjD;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,uBAAuB;QACpC,QAAQ,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC;KACjD;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,yBAAyB;QACtC,QAAQ,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC;KACjD;IACD;QACE,EAAE,EAAE,YAAY;QAChB,KAAK,EAAE,OAAO;QACd,WAAW,EAAE,sBAAsB;QACnC,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC;KAChD;IACD;QACE,EAAE,EAAE,aAAa;QACjB,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,gBAAgB;QAC7B,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC;KAC5D;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,WAAW;QAClB,WAAW,EAAE,kBAAkB;QAC/B,QAAQ,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC;KAC5D;IACD;QACE,EAAE,EAAE,YAAY;QAChB,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,kBAAkB;QAC/B,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC;KACxC;IACD;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,iBAAiB;QAC9B,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC;KACtC;IACD;QACE,EAAE,EAAE,gBAAgB;QACpB,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,iBAAiB;QAC9B,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC;KAClD;IACD;QACE,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,mBAAmB;QAChC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;KAC3D;CACF,CAAC;AAEF,MAAM,OAAO,GAAG,0BAA0B,CAAC;AAC3C,MAAM,KAAK,GAAG,0BAA0B,CAAC;AAEzC,oEAAoE;AACpE,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,EAAE,CACrC,IAAI;KACD,WAAW,EAAE;KACb,IAAI,EAAE;KACN,KAAK,CAAC,EAAE,CAAC;KACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;IACZ,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACxD,CAAC,CAAC;KACD,IAAI,CAAC,EAAE,CAAC,CAAC;AAEd,8EAA8E;AAC9E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAAoB,EAAE;IACrE,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAElC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAC5E,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,EAAkB,EACkB,EAAE,CACtC,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The vocabulary a note editor speaks, independent of how it is hosted: what
|
|
3
|
+
* can be asked of an editor and what it reports back is identical on mobile
|
|
4
|
+
* (WebView + bridge) and web (in-process), so a toolbar written against these
|
|
5
|
+
* types works either way.
|
|
6
|
+
*
|
|
7
|
+
* The transport (envelopes, protocol version, injected global) must not land
|
|
8
|
+
* here: it only exists on React Native.
|
|
9
|
+
*/
|
|
10
|
+
export type EditorMarkFlag = 'bold' | 'italic' | 'underline' | 'strike' | 'code' | 'link';
|
|
11
|
+
export type EditorBlockFlag = 'paragraph' | 'heading1' | 'heading2' | 'heading3' | 'bulletList' | 'orderedList' | 'taskList' | 'blockquote' | 'codeBlock';
|
|
12
|
+
export type EditorActiveFlags = Record<EditorMarkFlag | EditorBlockFlag, boolean>;
|
|
13
|
+
/** Small payload published on every selection change to drive the toolbar. */
|
|
14
|
+
export type EditorSelectionState = {
|
|
15
|
+
isFocused: boolean;
|
|
16
|
+
isEmpty: boolean;
|
|
17
|
+
canUndo: boolean;
|
|
18
|
+
canRedo: boolean;
|
|
19
|
+
canIndent: boolean;
|
|
20
|
+
canOutdent: boolean;
|
|
21
|
+
active: EditorActiveFlags;
|
|
22
|
+
/** `href` of the link under the cursor, when there is one. */
|
|
23
|
+
linkHref: string | null;
|
|
24
|
+
};
|
|
25
|
+
export type SlashCommandId = 'paragraph' | 'heading1' | 'heading2' | 'heading3' | 'bulletList' | 'orderedList' | 'taskList' | 'blockquote' | 'codeBlock' | 'horizontalRule' | 'image';
|
|
26
|
+
/**
|
|
27
|
+
* Caret rectangle in CSS pixels, relative to the editor's own viewport. The
|
|
28
|
+
* host places its menu from this — natively on mobile, in the DOM on the web.
|
|
29
|
+
*/
|
|
30
|
+
export type EditorCaretRect = {
|
|
31
|
+
x: number;
|
|
32
|
+
y: number;
|
|
33
|
+
width: number;
|
|
34
|
+
height: number;
|
|
35
|
+
};
|
|
36
|
+
export type SlashMenuState = {
|
|
37
|
+
active: boolean;
|
|
38
|
+
query: string;
|
|
39
|
+
/** Ids matching `query`, in display order. Empty means "no match". */
|
|
40
|
+
commandIds: SlashCommandId[];
|
|
41
|
+
caret: EditorCaretRect | null;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Resolved design-system values handed to the editor surface. The editor never
|
|
45
|
+
* picks its own colors — the host resolves them (Restyle on mobile, CSS custom
|
|
46
|
+
* properties on web) so the document follows light/dark mode and the student's
|
|
47
|
+
* font-size preference.
|
|
48
|
+
*/
|
|
49
|
+
export type EditorTheme = {
|
|
50
|
+
colorScheme: 'light' | 'dark';
|
|
51
|
+
background: string;
|
|
52
|
+
text: string;
|
|
53
|
+
heading: string;
|
|
54
|
+
muted: string;
|
|
55
|
+
placeholder: string;
|
|
56
|
+
border: string;
|
|
57
|
+
accent: string;
|
|
58
|
+
caret: string;
|
|
59
|
+
selection: string;
|
|
60
|
+
codeBackground: string;
|
|
61
|
+
codeText: string;
|
|
62
|
+
fontSize: number;
|
|
63
|
+
lineHeight: number;
|
|
64
|
+
paddingHorizontal: number;
|
|
65
|
+
paddingTop: number;
|
|
66
|
+
paddingBottom: number;
|
|
67
|
+
};
|
|
68
|
+
/** Everything a host may ask the editor to do. */
|
|
69
|
+
export type EditorCommand = {
|
|
70
|
+
name: 'toggleBold';
|
|
71
|
+
} | {
|
|
72
|
+
name: 'toggleItalic';
|
|
73
|
+
} | {
|
|
74
|
+
name: 'toggleUnderline';
|
|
75
|
+
} | {
|
|
76
|
+
name: 'toggleStrike';
|
|
77
|
+
} | {
|
|
78
|
+
name: 'toggleCode';
|
|
79
|
+
} | {
|
|
80
|
+
name: 'setParagraph';
|
|
81
|
+
} | {
|
|
82
|
+
name: 'toggleHeading';
|
|
83
|
+
level: 1 | 2 | 3;
|
|
84
|
+
} | {
|
|
85
|
+
name: 'toggleBulletList';
|
|
86
|
+
} | {
|
|
87
|
+
name: 'toggleOrderedList';
|
|
88
|
+
} | {
|
|
89
|
+
name: 'toggleTaskList';
|
|
90
|
+
} | {
|
|
91
|
+
name: 'toggleBlockquote';
|
|
92
|
+
} | {
|
|
93
|
+
name: 'toggleCodeBlock';
|
|
94
|
+
} | {
|
|
95
|
+
name: 'setHorizontalRule';
|
|
96
|
+
} | {
|
|
97
|
+
name: 'setLink';
|
|
98
|
+
href: string;
|
|
99
|
+
} | {
|
|
100
|
+
name: 'unsetLink';
|
|
101
|
+
} | {
|
|
102
|
+
name: 'indent';
|
|
103
|
+
} | {
|
|
104
|
+
name: 'outdent';
|
|
105
|
+
} | {
|
|
106
|
+
name: 'undo';
|
|
107
|
+
} | {
|
|
108
|
+
name: 'redo';
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=vocabulary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vocabulary.d.ts","sourceRoot":"","sources":["../../src/editor/vocabulary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The vocabulary a note editor speaks, independent of how it is hosted: what
|
|
3
|
+
* can be asked of an editor and what it reports back is identical on mobile
|
|
4
|
+
* (WebView + bridge) and web (in-process), so a toolbar written against these
|
|
5
|
+
* types works either way.
|
|
6
|
+
*
|
|
7
|
+
* The transport (envelopes, protocol version, injected global) must not land
|
|
8
|
+
* here: it only exists on React Native.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=vocabulary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vocabulary.js","sourceRoot":"","sources":["../../src/editor/vocabulary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@medway-ui/notes-core` — the note editor's domain layer: the document model,
|
|
3
|
+
* its whitelist, and the vocabulary hosts drive an editor with.
|
|
4
|
+
*
|
|
5
|
+
* Hard constraint: this entry point is free of Tiptap, React, React Native and
|
|
6
|
+
* the DOM. Anything touching Tiptap lives behind the `/schema` subpath.
|
|
7
|
+
*/
|
|
8
|
+
export type { EditorAttributes, EditorDocument, EditorImageNode, EditorLinkMark, EditorMark, EditorMarkType, EditorNode, EditorNodeType, } from './document/types.js';
|
|
9
|
+
export { EMPTY_DOCUMENT, documentToPlainText, documentsAreEqual, isEditorDocument, isEmptyDocument, normalizeDocument, sanitizeImageSrc, sanitizeLinkHref, toEditorContent, } from './document/normalize.js';
|
|
10
|
+
export type { EditorActiveFlags, EditorBlockFlag, EditorCaretRect, EditorCommand, EditorMarkFlag, EditorSelectionState, EditorTheme, SlashCommandId, SlashMenuState, } from './editor/vocabulary.js';
|
|
11
|
+
export type { NoteEditorHandle } from './editor/handle.js';
|
|
12
|
+
export { EMPTY_SLASH_STATE, INITIAL_EDITOR_STATE } from './editor/handle.js';
|
|
13
|
+
export type { SlashCommandDefinition } from './editor/slashCommands.js';
|
|
14
|
+
export { SLASH_COMMANDS, filterSlashCommands, getSlashCommand, } from './editor/slashCommands.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,cAAc,EACd,UAAU,EACV,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,WAAW,EACX,cAAc,EACd,cAAc,GACf,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,YAAY,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,eAAe,GAChB,MAAM,2BAA2B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@medway-ui/notes-core` — the note editor's domain layer: the document model,
|
|
3
|
+
* its whitelist, and the vocabulary hosts drive an editor with.
|
|
4
|
+
*
|
|
5
|
+
* Hard constraint: this entry point is free of Tiptap, React, React Native and
|
|
6
|
+
* the DOM. Anything touching Tiptap lives behind the `/schema` subpath.
|
|
7
|
+
*/
|
|
8
|
+
export { EMPTY_DOCUMENT, documentToPlainText, documentsAreEqual, isEditorDocument, isEmptyDocument, normalizeDocument, sanitizeImageSrc, sanitizeLinkHref, toEditorContent, } from './document/normalize.js';
|
|
9
|
+
export { EMPTY_SLASH_STATE, INITIAL_EDITOR_STATE } from './editor/handle.js';
|
|
10
|
+
export { SLASH_COMMANDS, filterSlashCommands, getSlashCommand, } from './editor/slashCommands.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAejC,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG7E,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,eAAe,GAChB,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Schema } from '@tiptap/pm/model';
|
|
2
|
+
import type { EditorMarkType, EditorNodeType } from '../document/types.js';
|
|
3
|
+
export declare const NODE_TYPES: EditorNodeType[];
|
|
4
|
+
export declare const MARK_TYPES: EditorMarkType[];
|
|
5
|
+
/**
|
|
6
|
+
* Returns every disagreement between the model and the built schema, in both
|
|
7
|
+
* directions: declared but missing (`node:`/`mark:`), and present in the schema
|
|
8
|
+
* but not the model (`extra-node:`/`extra-mark:`, which is how `extra` in
|
|
9
|
+
* `buildExtensions` can smuggle a type past this file). Either direction means
|
|
10
|
+
* one client can write JSON another client's `normalizeDocument` silently
|
|
11
|
+
* drops — treat any result as fatal in dev, not just log it.
|
|
12
|
+
*/
|
|
13
|
+
export declare const assertSchemaContract: (schema: Schema) => string[];
|
|
14
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/schema/contract.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EACf,MAAM,sBAAsB,CAAC;AAuC9B,eAAO,MAAM,UAAU,EAAiC,cAAc,EAAE,CAAC;AAEzE,eAAO,MAAM,UAAU,EAAiC,cAAc,EAAE,CAAC;AAEzE;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,KAAG,MAAM,EAiB3D,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const assignableToTiptap = true;
|
|
2
|
+
// `Record<Union, true>` instead of an array: adding a member without listing it
|
|
3
|
+
// here stops compiling.
|
|
4
|
+
const NODE_TYPE_MAP = {
|
|
5
|
+
doc: true,
|
|
6
|
+
paragraph: true,
|
|
7
|
+
text: true,
|
|
8
|
+
hardBreak: true,
|
|
9
|
+
heading: true,
|
|
10
|
+
bulletList: true,
|
|
11
|
+
orderedList: true,
|
|
12
|
+
listItem: true,
|
|
13
|
+
taskList: true,
|
|
14
|
+
taskItem: true,
|
|
15
|
+
blockquote: true,
|
|
16
|
+
codeBlock: true,
|
|
17
|
+
horizontalRule: true,
|
|
18
|
+
image: true,
|
|
19
|
+
};
|
|
20
|
+
const MARK_TYPE_MAP = {
|
|
21
|
+
bold: true,
|
|
22
|
+
italic: true,
|
|
23
|
+
underline: true,
|
|
24
|
+
strike: true,
|
|
25
|
+
code: true,
|
|
26
|
+
link: true,
|
|
27
|
+
};
|
|
28
|
+
export const NODE_TYPES = Object.keys(NODE_TYPE_MAP);
|
|
29
|
+
export const MARK_TYPES = Object.keys(MARK_TYPE_MAP);
|
|
30
|
+
/**
|
|
31
|
+
* Returns every disagreement between the model and the built schema, in both
|
|
32
|
+
* directions: declared but missing (`node:`/`mark:`), and present in the schema
|
|
33
|
+
* but not the model (`extra-node:`/`extra-mark:`, which is how `extra` in
|
|
34
|
+
* `buildExtensions` can smuggle a type past this file). Either direction means
|
|
35
|
+
* one client can write JSON another client's `normalizeDocument` silently
|
|
36
|
+
* drops — treat any result as fatal in dev, not just log it.
|
|
37
|
+
*/
|
|
38
|
+
export const assertSchemaContract = (schema) => {
|
|
39
|
+
void assignableToTiptap;
|
|
40
|
+
return [
|
|
41
|
+
...NODE_TYPES.filter((name) => !(name in schema.nodes)).map((name) => `node:${name}`),
|
|
42
|
+
...MARK_TYPES.filter((name) => !(name in schema.marks)).map((name) => `mark:${name}`),
|
|
43
|
+
...Object.keys(schema.nodes)
|
|
44
|
+
.filter((name) => !(name in NODE_TYPE_MAP))
|
|
45
|
+
.map((name) => `extra-node:${name}`),
|
|
46
|
+
...Object.keys(schema.marks)
|
|
47
|
+
.filter((name) => !(name in MARK_TYPE_MAP))
|
|
48
|
+
.map((name) => `extra-mark:${name}`),
|
|
49
|
+
];
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/schema/contract.ts"],"names":[],"mappings":"AAgBA,MAAM,kBAAkB,GAAuB,IAAI,CAAC;AAEpD,gFAAgF;AAChF,wBAAwB;AACxB,MAAM,aAAa,GAAiC;IAClD,GAAG,EAAE,IAAI;IACT,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,IAAI;IACV,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,WAAW,EAAE,IAAI;IACjB,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,UAAU,EAAE,IAAI;IAChB,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,IAAI;IACpB,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF,MAAM,aAAa,GAAiC;IAClD,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,IAAI;IACZ,SAAS,EAAE,IAAI;IACf,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;CACX,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAqB,CAAC;AAEzE,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAqB,CAAC;AAEzE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAc,EAAY,EAAE;IAC/D,KAAK,kBAAkB,CAAC;IAExB,OAAO;QACL,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CACzD,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,IAAI,EAAE,CACzB;QACD,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CACzD,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,IAAI,EAAE,CACzB;QACD,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aACzB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,aAAa,CAAC,CAAC;aAC1C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,IAAI,EAAE,CAAC;QACtC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aACzB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,aAAa,CAAC,CAAC;aAC1C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,IAAI,EAAE,CAAC;KACvC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AnyExtension } from '@tiptap/core';
|
|
2
|
+
export type BuildExtensionsOptions = {
|
|
3
|
+
/** Shown while the whole note is blank. */
|
|
4
|
+
placeholder?: string;
|
|
5
|
+
/** Shown on whichever empty paragraph currently holds the caret. */
|
|
6
|
+
caretHint?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Appended after the schema — the slash-command extension from
|
|
9
|
+
* `createSlashCommand`, and anything else a host adds. Nothing here may
|
|
10
|
+
* introduce a node or a mark: the schema is what this file declares, and
|
|
11
|
+
* `assertSchemaContract` checks that claim.
|
|
12
|
+
*/
|
|
13
|
+
extra?: AnyExtension[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The document schema, and the single place where it is declared: a second
|
|
17
|
+
* declaration would let two clients write documents the other reads wrong.
|
|
18
|
+
*
|
|
19
|
+
* Node and mark names end up in the persisted JSON and must stay in sync with
|
|
20
|
+
* `EditorNodeType` / `EditorMarkType` in `../document/types`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const buildExtensions: ({ placeholder, caretHint, extra, }?: BuildExtensionsOptions) => AnyExtension[];
|
|
23
|
+
//# sourceMappingURL=extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/schema/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAsCjD,MAAM,MAAM,sBAAsB,GAAG;IACnC,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;CACxB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,qCAI7B,sBAA2B,KAAG,YAAY,EAwD5C,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import Blockquote from '@tiptap/extension-blockquote';
|
|
2
|
+
import Bold from '@tiptap/extension-bold';
|
|
3
|
+
import Code from '@tiptap/extension-code';
|
|
4
|
+
import CodeBlock from '@tiptap/extension-code-block';
|
|
5
|
+
import Document from '@tiptap/extension-document';
|
|
6
|
+
import HardBreak from '@tiptap/extension-hard-break';
|
|
7
|
+
import Heading from '@tiptap/extension-heading';
|
|
8
|
+
import HorizontalRule from '@tiptap/extension-horizontal-rule';
|
|
9
|
+
import Italic from '@tiptap/extension-italic';
|
|
10
|
+
import Link from '@tiptap/extension-link';
|
|
11
|
+
import Paragraph from '@tiptap/extension-paragraph';
|
|
12
|
+
import Strike from '@tiptap/extension-strike';
|
|
13
|
+
import Text from '@tiptap/extension-text';
|
|
14
|
+
import Underline from '@tiptap/extension-underline';
|
|
15
|
+
import { BulletList, ListItem, ListKeymap, OrderedList, TaskItem, TaskList, } from '@tiptap/extension-list';
|
|
16
|
+
import { Dropcursor, Gapcursor, Placeholder, Selection, TrailingNode, UndoRedo, } from '@tiptap/extensions';
|
|
17
|
+
import { Image } from './image.js';
|
|
18
|
+
const DEFAULT_PLACEHOLDER = 'Comece a escrever ou digite "/" para comandos';
|
|
19
|
+
const DEFAULT_CARET_HINT = 'Digite "/" para comandos';
|
|
20
|
+
/**
|
|
21
|
+
* The document schema, and the single place where it is declared: a second
|
|
22
|
+
* declaration would let two clients write documents the other reads wrong.
|
|
23
|
+
*
|
|
24
|
+
* Node and mark names end up in the persisted JSON and must stay in sync with
|
|
25
|
+
* `EditorNodeType` / `EditorMarkType` in `../document/types`.
|
|
26
|
+
*/
|
|
27
|
+
export const buildExtensions = ({ placeholder = DEFAULT_PLACEHOLDER, caretHint = DEFAULT_CARET_HINT, extra = [], } = {}) => [
|
|
28
|
+
Document,
|
|
29
|
+
Paragraph,
|
|
30
|
+
Text,
|
|
31
|
+
HardBreak,
|
|
32
|
+
Heading.configure({ levels: [1, 2, 3] }),
|
|
33
|
+
BulletList,
|
|
34
|
+
OrderedList,
|
|
35
|
+
ListItem,
|
|
36
|
+
TaskList,
|
|
37
|
+
TaskItem.configure({ nested: true }),
|
|
38
|
+
Blockquote,
|
|
39
|
+
CodeBlock,
|
|
40
|
+
HorizontalRule,
|
|
41
|
+
Image,
|
|
42
|
+
Bold,
|
|
43
|
+
Italic,
|
|
44
|
+
Underline,
|
|
45
|
+
Strike,
|
|
46
|
+
Code,
|
|
47
|
+
Link.configure({
|
|
48
|
+
// Clicks are reported to the host, which decides what to open. The editor
|
|
49
|
+
// surface must never navigate away from the document it is editing.
|
|
50
|
+
openOnClick: false,
|
|
51
|
+
autolink: true,
|
|
52
|
+
linkOnPaste: true,
|
|
53
|
+
protocols: ['http', 'https', 'mailto'],
|
|
54
|
+
HTMLAttributes: { rel: 'noopener noreferrer nofollow', target: '_blank' },
|
|
55
|
+
}),
|
|
56
|
+
UndoRedo,
|
|
57
|
+
ListKeymap,
|
|
58
|
+
Dropcursor,
|
|
59
|
+
Gapcursor,
|
|
60
|
+
// Keeps the selection visible while the toolbar holds focus instead of the
|
|
61
|
+
// editor — the normal case on mobile.
|
|
62
|
+
Selection,
|
|
63
|
+
// Always an empty paragraph to tap at the end of the note.
|
|
64
|
+
TrailingNode,
|
|
65
|
+
Placeholder.configure({
|
|
66
|
+
placeholder: ({ editor, node, pos, hasAnchor }) => {
|
|
67
|
+
if (node.type.name !== 'paragraph')
|
|
68
|
+
return '';
|
|
69
|
+
// `pos === 0` is required: a blank note stays `isEmpty` after Enter adds
|
|
70
|
+
// a second paragraph, so without it both paragraphs show the note-level
|
|
71
|
+
// hint at once and it reads as duplicated/stuck placeholder text.
|
|
72
|
+
if (editor.isEmpty && pos === 0)
|
|
73
|
+
return placeholder;
|
|
74
|
+
return hasAnchor ? caretHint : '';
|
|
75
|
+
},
|
|
76
|
+
showOnlyCurrent: false,
|
|
77
|
+
includeChildren: false,
|
|
78
|
+
}),
|
|
79
|
+
...extra,
|
|
80
|
+
];
|
|
81
|
+
//# sourceMappingURL=extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../src/schema/extensions.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,8BAA8B,CAAC;AACtD,OAAO,IAAI,MAAM,wBAAwB,CAAC;AAC1C,OAAO,IAAI,MAAM,wBAAwB,CAAC;AAC1C,OAAO,SAAS,MAAM,8BAA8B,CAAC;AACrD,OAAO,QAAQ,MAAM,4BAA4B,CAAC;AAClD,OAAO,SAAS,MAAM,8BAA8B,CAAC;AACrD,OAAO,OAAO,MAAM,2BAA2B,CAAC;AAChD,OAAO,cAAc,MAAM,mCAAmC,CAAC;AAC/D,OAAO,MAAM,MAAM,0BAA0B,CAAC;AAC9C,OAAO,IAAI,MAAM,wBAAwB,CAAC;AAC1C,OAAO,SAAS,MAAM,6BAA6B,CAAC;AACpD,OAAO,MAAM,MAAM,0BAA0B,CAAC;AAC9C,OAAO,IAAI,MAAM,wBAAwB,CAAC;AAC1C,OAAO,SAAS,MAAM,6BAA6B,CAAC;AACpD,OAAO,EACL,UAAU,EACV,QAAQ,EACR,UAAU,EACV,WAAW,EACX,QAAQ,EACR,QAAQ,GACT,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,YAAY,EACZ,QAAQ,GACT,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,mBAAmB,GACvB,+CAA+C,CAAC;AAClD,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAgBtD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAC9B,WAAW,GAAG,mBAAmB,EACjC,SAAS,GAAG,kBAAkB,EAC9B,KAAK,GAAG,EAAE,MACgB,EAAE,EAAkB,EAAE,CAAC;IACjD,QAAQ;IACR,SAAS;IACT,IAAI;IACJ,SAAS;IACT,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACxC,UAAU;IACV,WAAW;IACX,QAAQ;IACR,QAAQ;IACR,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACpC,UAAU;IACV,SAAS;IACT,cAAc;IACd,KAAK;IAEL,IAAI;IACJ,MAAM;IACN,SAAS;IACT,MAAM;IACN,IAAI;IACJ,IAAI,CAAC,SAAS,CAAC;QACb,0EAA0E;QAC1E,oEAAoE;QACpE,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC;QACtC,cAAc,EAAE,EAAE,GAAG,EAAE,8BAA8B,EAAE,MAAM,EAAE,QAAQ,EAAE;KAC1E,CAAC;IAEF,QAAQ;IACR,UAAU;IACV,UAAU;IACV,SAAS;IACT,2EAA2E;IAC3E,sCAAsC;IACtC,SAAS;IACT,2DAA2D;IAC3D,YAAY;IACZ,WAAW,CAAC,SAAS,CAAC;QACpB,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE;YAChD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO,EAAE,CAAC;YAE9C,yEAAyE;YACzE,wEAAwE;YACxE,kEAAkE;YAClE,IAAI,MAAM,CAAC,OAAO,IAAI,GAAG,KAAK,CAAC;gBAAE,OAAO,WAAW,CAAC;YAEpD,OAAO,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QACpC,CAAC;QACD,eAAe,EAAE,KAAK;QACtB,eAAe,EAAE,KAAK;KACvB,CAAC;IAEF,GAAG,KAAK;CACT,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Node } from '@tiptap/core';
|
|
2
|
+
export declare const Image: Node<any, any>;
|
|
3
|
+
declare module '@tiptap/core' {
|
|
4
|
+
interface Commands<ReturnType> {
|
|
5
|
+
image: {
|
|
6
|
+
/** Inserts an image node at the current selection. */
|
|
7
|
+
setImage: (attrs: {
|
|
8
|
+
src: string;
|
|
9
|
+
alt?: string | null;
|
|
10
|
+
}) => ReturnType;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/schema/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AAIrD,eAAO,MAAM,KAAK,gBA8BhB,CAAC;AAEH,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,QAAQ,CAAC,UAAU;QAC3B,KAAK,EAAE;YACL,sDAAsD;YACtD,QAAQ,EAAE,CAAC,KAAK,EAAE;gBAAE,GAAG,EAAE,MAAM,CAAC;gBAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;aAAE,KAAK,UAAU,CAAC;SACvE,CAAC;KACH;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Node, mergeAttributes } from '@tiptap/core';
|
|
2
|
+
// Reimplements the minimum of `@tiptap/extension-image` (not a dependency of
|
|
3
|
+
// this package); getting a `src` is host UI.
|
|
4
|
+
export const Image = Node.create({
|
|
5
|
+
name: 'image',
|
|
6
|
+
group: 'block',
|
|
7
|
+
atom: true,
|
|
8
|
+
selectable: true,
|
|
9
|
+
draggable: true,
|
|
10
|
+
addAttributes() {
|
|
11
|
+
return {
|
|
12
|
+
src: { default: null },
|
|
13
|
+
alt: { default: null },
|
|
14
|
+
};
|
|
15
|
+
},
|
|
16
|
+
parseHTML() {
|
|
17
|
+
return [{ tag: 'img[src]' }];
|
|
18
|
+
},
|
|
19
|
+
renderHTML({ HTMLAttributes }) {
|
|
20
|
+
return ['img', mergeAttributes(HTMLAttributes)];
|
|
21
|
+
},
|
|
22
|
+
addCommands() {
|
|
23
|
+
return {
|
|
24
|
+
setImage: (attrs) => ({ commands }) => commands.insertContent({ type: this.name, attrs }),
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/schema/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErD,6EAA6E;AAC7E,6CAA6C;AAC7C,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,IAAI;IAChB,SAAS,EAAE,IAAI;IAEf,aAAa;QACX,OAAO;YACL,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;YACtB,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;SACvB,CAAC;IACJ,CAAC;IAED,SAAS;QACP,OAAO,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,UAAU,CAAC,EAAE,cAAc,EAAE;QAC3B,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,WAAW;QACT,OAAO;YACL,QAAQ,EACN,CAAC,KAA2C,EAAE,EAAE,CAChD,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CACf,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;SACvD,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@medway-ui/notes-core/schema` — the Tiptap half, behind its own subpath so
|
|
3
|
+
* that importing the document model never pulls Tiptap in.
|
|
4
|
+
*
|
|
5
|
+
* `Editor`, `generateHTML` and `generateJSON` are re-exported to guarantee a
|
|
6
|
+
* single ProseMirror copy, and must always be passed the exact array
|
|
7
|
+
* `buildExtensions()` returns.
|
|
8
|
+
*/
|
|
9
|
+
export { Editor, generateHTML, generateJSON } from '@tiptap/core';
|
|
10
|
+
export type { AnyExtension, JSONContent } from '@tiptap/core';
|
|
11
|
+
export type { BuildExtensionsOptions } from './extensions.js';
|
|
12
|
+
export { buildExtensions } from './extensions.js';
|
|
13
|
+
export { Image } from './image.js';
|
|
14
|
+
export type { SlashCommandController } from './slashCommand.js';
|
|
15
|
+
export { createSlashCommand } from './slashCommand.js';
|
|
16
|
+
export { MARK_TYPES, NODE_TYPES, assertSchemaContract, } from './contract.js';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAClE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAMlD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,GACrB,MAAM,eAAe,CAAC"}
|