@verbb/plugin-kit-tiptap-core 2.0.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 +11 -0
- package/LICENSE.md +21 -0
- package/README.md +36 -0
- package/dist/extensions/create-extensions.d.ts +13 -0
- package/dist/extensions/create-extensions.d.ts.map +1 -0
- package/dist/extensions/create-extensions.js +92 -0
- package/dist/extensions/create-extensions.js.map +1 -0
- package/dist/extensions/index.d.ts +6 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +4 -0
- package/dist/extensions/one-liner-document.d.ts +2 -0
- package/dist/extensions/one-liner-document.d.ts.map +1 -0
- package/dist/extensions/one-liner-document.js +7 -0
- package/dist/extensions/one-liner-document.js.map +1 -0
- package/dist/extensions/variable-tag.d.ts +7 -0
- package/dist/extensions/variable-tag.d.ts.map +1 -0
- package/dist/extensions/variable-tag.js +156 -0
- package/dist/extensions/variable-tag.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/links/commands.d.ts +9 -0
- package/dist/links/commands.d.ts.map +1 -0
- package/dist/links/commands.js +63 -0
- package/dist/links/commands.js.map +1 -0
- package/dist/links/craft-element.d.ts +28 -0
- package/dist/links/craft-element.d.ts.map +1 -0
- package/dist/links/craft-element.js +80 -0
- package/dist/links/craft-element.js.map +1 -0
- package/dist/links/extension.d.ts +3 -0
- package/dist/links/extension.d.ts.map +1 -0
- package/dist/links/extension.js +17 -0
- package/dist/links/extension.js.map +1 -0
- package/dist/links/index.d.ts +5 -0
- package/dist/links/index.d.ts.map +1 -0
- package/dist/links/index.js +4 -0
- package/dist/links/types.d.ts +62 -0
- package/dist/links/types.d.ts.map +1 -0
- package/dist/links/types.js +0 -0
- package/dist/serialization/editor.d.ts +9 -0
- package/dist/serialization/editor.d.ts.map +1 -0
- package/dist/serialization/editor.js +112 -0
- package/dist/serialization/editor.js.map +1 -0
- package/dist/serialization/input.d.ts +55 -0
- package/dist/serialization/input.d.ts.map +1 -0
- package/dist/serialization/input.js +293 -0
- package/dist/serialization/input.js.map +1 -0
- package/dist/toolbar/button-registry.d.ts +14 -0
- package/dist/toolbar/button-registry.d.ts.map +1 -0
- package/dist/toolbar/button-registry.js +114 -0
- package/dist/toolbar/button-registry.js.map +1 -0
- package/dist/toolbar/index.d.ts +3 -0
- package/dist/toolbar/index.d.ts.map +1 -0
- package/dist/toolbar/index.js +3 -0
- package/dist/toolbar/toolbar-schema.d.ts +66 -0
- package/dist/toolbar/toolbar-schema.d.ts.map +1 -0
- package/dist/toolbar/toolbar-schema.js +340 -0
- package/dist/toolbar/toolbar-schema.js.map +1 -0
- package/dist/types/variable-option.d.ts +10 -0
- package/dist/types/variable-option.d.ts.map +1 -0
- package/dist/types/variable-option.js +0 -0
- package/package.json +99 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 2.0.0 - 2026-07-19
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Initial public release of `@verbb/plugin-kit-tiptap-core` — shared TipTap schema, extensions, and serialization for Plugin Kit rich-text surfaces.
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Package versions lockstep with `@verbb/plugin-kit-web` and related `@verbb/plugin-kit-*` packages at `2.0.0`.
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Verbb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# `@verbb/plugin-kit-tiptap-core`
|
|
2
|
+
|
|
3
|
+
Shared TipTap schema, extensions, toolbar helpers, and serialization for Plugin Kit rich-text surfaces.
|
|
4
|
+
|
|
5
|
+
You normally consume TipTap through UI packages (`pk-tiptap-*` / React/Vue facades). Use this package when you need the headless helpers without mounting an editor.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @verbb/plugin-kit-tiptap-core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
TipTap packages are dependencies of this package.
|
|
14
|
+
|
|
15
|
+
## What you get
|
|
16
|
+
|
|
17
|
+
| Area | Examples |
|
|
18
|
+
|------|----------|
|
|
19
|
+
| Extensions | `createTiptapExtensions`, `createTiptapInputExtensions`, variable-tag extension |
|
|
20
|
+
| Serialization | `valueToContent`, `contentToValue`, normalize / empty checks |
|
|
21
|
+
| Toolbar | presets, group menus, `runToolbarButton`, active-state helpers |
|
|
22
|
+
| Links | Craft element / URL link helpers |
|
|
23
|
+
|
|
24
|
+
Subpath exports: `./extensions`, `./toolbar`, `./links`, `./serialization/editor`, `./serialization/input`.
|
|
25
|
+
|
|
26
|
+
## UI entry points
|
|
27
|
+
|
|
28
|
+
| Surface | Import |
|
|
29
|
+
|---------|--------|
|
|
30
|
+
| Web | `@verbb/plugin-kit-web/components/tiptap-editor.js` (also `tiptap-input`, `tiptap-content`) |
|
|
31
|
+
| React | `TiptapEditor`, `TiptapInput`, `TiptapContent` from `@verbb/plugin-kit-react/components` |
|
|
32
|
+
| Vue | same names from `@verbb/plugin-kit-vue/components` |
|
|
33
|
+
|
|
34
|
+
## Docs
|
|
35
|
+
|
|
36
|
+
Component pages under [Web](https://docs.verbb.io/plugin-kit/web/components/tiptap-editor) / [React](https://docs.verbb.io/plugin-kit/react/components/tiptap-editor) / [Vue](https://docs.verbb.io/plugin-kit/vue/components/tiptap-editor).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { NodeViewRenderer } from '@tiptap/core';
|
|
2
|
+
export type CreateTiptapExtensionsOptions = {
|
|
3
|
+
trailingCursorText?: string;
|
|
4
|
+
variableTagNodeView?: NodeViewRenderer;
|
|
5
|
+
includeVariableTag?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare const createTiptapExtensions: ({ trailingCursorText, variableTagNodeView, includeVariableTag, }?: CreateTiptapExtensionsOptions) => (import('@tiptap/core').Mark<import('@tiptap/extension-link').LinkOptions, any> | import('@tiptap/core').Node<any, any> | import('@tiptap/core').Extension<import('@tiptap/extensions').DropcursorOptions, any> | import('@tiptap/core').Extension<any, any> | import('@tiptap/core').Node<import('@tiptap/extension-paragraph').ParagraphOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-hard-break').HardBreakOptions, any> | import('@tiptap/core').Mark<import('@tiptap/extension-bold').BoldOptions, any> | import('@tiptap/core').Mark<import('@tiptap/extension-highlight').HighlightOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-list').BulletListOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-code-block').CodeBlockOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-heading').HeadingOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-horizontal-rule').HorizontalRuleOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-list').ListItemOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-table').TableOptions, any> | import('@tiptap/core').Extension<import('@tiptap/extensions').UndoRedoOptions, any> | import('@tiptap/core').Extension<import('@tiptap/extension-text-align').TextAlignOptions, any>)[];
|
|
8
|
+
export type CreateTiptapInputExtensionsOptions = {
|
|
9
|
+
trailingCursorText?: string;
|
|
10
|
+
variableTagNodeView?: NodeViewRenderer;
|
|
11
|
+
};
|
|
12
|
+
export declare const createTiptapInputExtensions: ({ trailingCursorText, variableTagNodeView, }?: CreateTiptapInputExtensionsOptions) => import('@tiptap/core').Node<any, any>[];
|
|
13
|
+
//# sourceMappingURL=create-extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-extensions.d.ts","sourceRoot":"","sources":["../../src/extensions/create-extensions.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMrD,MAAM,MAAM,6BAA6B,GAAG;IACxC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,gBAAgB,CAAC;IACvC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,mEAIpC,6BAAkC,szCA2CpC,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC7C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,gBAAgB,CAAC;CAC1C,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAI,+CAGzC,kCAAuC,4CASzC,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createLinkExtension } from "../links/extension.js";
|
|
2
|
+
import { createVariableTagExtension } from "./variable-tag.js";
|
|
3
|
+
import { OneLinerDocument } from "./one-liner-document.js";
|
|
4
|
+
import Bold from "@tiptap/extension-bold";
|
|
5
|
+
import Code from "@tiptap/extension-code";
|
|
6
|
+
import Highlight from "@tiptap/extension-highlight";
|
|
7
|
+
import Italic from "@tiptap/extension-italic";
|
|
8
|
+
import Strike from "@tiptap/extension-strike";
|
|
9
|
+
import Subscript from "@tiptap/extension-subscript";
|
|
10
|
+
import Superscript from "@tiptap/extension-superscript";
|
|
11
|
+
import Underline from "@tiptap/extension-underline";
|
|
12
|
+
import Blockquote from "@tiptap/extension-blockquote";
|
|
13
|
+
import BulletList from "@tiptap/extension-bullet-list";
|
|
14
|
+
import CodeBlock from "@tiptap/extension-code-block";
|
|
15
|
+
import Document from "@tiptap/extension-document";
|
|
16
|
+
import HardBreak from "@tiptap/extension-hard-break";
|
|
17
|
+
import Heading from "@tiptap/extension-heading";
|
|
18
|
+
import HorizontalRule from "@tiptap/extension-horizontal-rule";
|
|
19
|
+
import ListItem from "@tiptap/extension-list-item";
|
|
20
|
+
import OrderedList from "@tiptap/extension-ordered-list";
|
|
21
|
+
import Paragraph from "@tiptap/extension-paragraph";
|
|
22
|
+
import { Table } from "@tiptap/extension-table";
|
|
23
|
+
import TableCell from "@tiptap/extension-table-cell";
|
|
24
|
+
import TableHeader from "@tiptap/extension-table-header";
|
|
25
|
+
import TableRow from "@tiptap/extension-table-row";
|
|
26
|
+
import Text from "@tiptap/extension-text";
|
|
27
|
+
import Dropcursor from "@tiptap/extension-dropcursor";
|
|
28
|
+
import Gapcursor from "@tiptap/extension-gapcursor";
|
|
29
|
+
import History from "@tiptap/extension-history";
|
|
30
|
+
import TextAlign from "@tiptap/extension-text-align";
|
|
31
|
+
//#region src/extensions/create-extensions.ts
|
|
32
|
+
var createTiptapExtensions = ({ trailingCursorText = "", variableTagNodeView, includeVariableTag = true } = {}) => {
|
|
33
|
+
const extensions = [
|
|
34
|
+
Document,
|
|
35
|
+
Dropcursor,
|
|
36
|
+
Gapcursor,
|
|
37
|
+
Paragraph,
|
|
38
|
+
Text,
|
|
39
|
+
HardBreak,
|
|
40
|
+
Bold,
|
|
41
|
+
Code,
|
|
42
|
+
Highlight,
|
|
43
|
+
Italic,
|
|
44
|
+
Strike,
|
|
45
|
+
Subscript,
|
|
46
|
+
Superscript,
|
|
47
|
+
Underline,
|
|
48
|
+
Blockquote,
|
|
49
|
+
BulletList,
|
|
50
|
+
CodeBlock,
|
|
51
|
+
Heading.configure({ levels: [
|
|
52
|
+
1,
|
|
53
|
+
2,
|
|
54
|
+
3,
|
|
55
|
+
4,
|
|
56
|
+
5,
|
|
57
|
+
6
|
|
58
|
+
] }),
|
|
59
|
+
HorizontalRule,
|
|
60
|
+
ListItem,
|
|
61
|
+
OrderedList,
|
|
62
|
+
Table.configure({ resizable: true }),
|
|
63
|
+
TableRow,
|
|
64
|
+
TableHeader,
|
|
65
|
+
TableCell,
|
|
66
|
+
History,
|
|
67
|
+
createLinkExtension(),
|
|
68
|
+
TextAlign.configure({
|
|
69
|
+
types: ["heading", "paragraph"],
|
|
70
|
+
defaultAlignment: "start"
|
|
71
|
+
})
|
|
72
|
+
];
|
|
73
|
+
if (includeVariableTag) extensions.push(createVariableTagExtension({
|
|
74
|
+
trailingCursorText,
|
|
75
|
+
addNodeView: variableTagNodeView
|
|
76
|
+
}));
|
|
77
|
+
return extensions;
|
|
78
|
+
};
|
|
79
|
+
var createTiptapInputExtensions = ({ trailingCursorText = "", variableTagNodeView } = {}) => {
|
|
80
|
+
return [
|
|
81
|
+
OneLinerDocument,
|
|
82
|
+
Text,
|
|
83
|
+
createVariableTagExtension({
|
|
84
|
+
trailingCursorText,
|
|
85
|
+
addNodeView: variableTagNodeView
|
|
86
|
+
})
|
|
87
|
+
];
|
|
88
|
+
};
|
|
89
|
+
//#endregion
|
|
90
|
+
export { createTiptapExtensions, createTiptapInputExtensions };
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=create-extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-extensions.js","names":[],"sources":["../../src/extensions/create-extensions.ts"],"sourcesContent":["import Bold from '@tiptap/extension-bold';\nimport Code from '@tiptap/extension-code';\nimport Highlight from '@tiptap/extension-highlight';\nimport Italic from '@tiptap/extension-italic';\nimport Strike from '@tiptap/extension-strike';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport Underline from '@tiptap/extension-underline';\n\nimport Blockquote from '@tiptap/extension-blockquote';\nimport BulletList from '@tiptap/extension-bullet-list';\nimport CodeBlock from '@tiptap/extension-code-block';\nimport Document from '@tiptap/extension-document';\nimport HardBreak from '@tiptap/extension-hard-break';\nimport Heading from '@tiptap/extension-heading';\nimport HorizontalRule from '@tiptap/extension-horizontal-rule';\nimport ListItem from '@tiptap/extension-list-item';\nimport OrderedList from '@tiptap/extension-ordered-list';\nimport Paragraph from '@tiptap/extension-paragraph';\nimport { Table } from '@tiptap/extension-table';\nimport TableCell from '@tiptap/extension-table-cell';\nimport TableHeader from '@tiptap/extension-table-header';\nimport TableRow from '@tiptap/extension-table-row';\nimport Text from '@tiptap/extension-text';\n\nimport Dropcursor from '@tiptap/extension-dropcursor';\nimport Gapcursor from '@tiptap/extension-gapcursor';\nimport History from '@tiptap/extension-history';\nimport TextAlign from '@tiptap/extension-text-align';\nimport type { NodeViewRenderer } from '@tiptap/core';\n\nimport { createLinkExtension } from '../links/extension.js';\nimport { createVariableTagExtension } from './variable-tag.js';\nimport { OneLinerDocument } from './one-liner-document.js';\n\nexport type CreateTiptapExtensionsOptions = {\n trailingCursorText?: string;\n variableTagNodeView?: NodeViewRenderer;\n includeVariableTag?: boolean;\n};\n\nexport const createTiptapExtensions = ({\n trailingCursorText = '\\u200B',\n variableTagNodeView,\n includeVariableTag = true,\n}: CreateTiptapExtensionsOptions = {}) => {\n const extensions = [\n Document,\n Dropcursor,\n Gapcursor,\n Paragraph,\n Text,\n HardBreak,\n\n Bold,\n Code,\n Highlight,\n Italic,\n Strike,\n Subscript,\n Superscript,\n Underline,\n\n Blockquote,\n BulletList,\n CodeBlock,\n Heading.configure({ levels: [1, 2, 3, 4, 5, 6] }),\n HorizontalRule,\n ListItem,\n OrderedList,\n Table.configure({ resizable: true }),\n TableRow,\n TableHeader,\n TableCell,\n\n History,\n createLinkExtension(),\n TextAlign.configure({ types: ['heading', 'paragraph'], defaultAlignment: 'start' }),\n ];\n\n if (includeVariableTag) {\n extensions.push(createVariableTagExtension({\n trailingCursorText,\n addNodeView: variableTagNodeView,\n }));\n }\n\n return extensions;\n};\n\nexport type CreateTiptapInputExtensionsOptions = {\n trailingCursorText?: string;\n variableTagNodeView?: NodeViewRenderer;\n};\n\nexport const createTiptapInputExtensions = ({\n trailingCursorText = '\\u200B',\n variableTagNodeView,\n}: CreateTiptapInputExtensionsOptions = {}) => {\n return [\n OneLinerDocument,\n Text,\n createVariableTagExtension({\n trailingCursorText,\n addNodeView: variableTagNodeView,\n }),\n ];\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,IAAa,0BAA0B,EACnC,qBAAqB,KACrB,qBACA,qBAAqB,SACU,EAAE,KAAK;CACtC,MAAM,aAAa;EACf;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA,QAAQ,UAAU,EAAE,QAAQ;GAAC;GAAG;GAAG;GAAG;GAAG;GAAG;GAAE,EAAE,CAAC;EACjD;EACA;EACA;EACA,MAAM,UAAU,EAAE,WAAW,MAAM,CAAC;EACpC;EACA;EACA;EAEA;EACA,qBAAqB;EACrB,UAAU,UAAU;GAAE,OAAO,CAAC,WAAW,YAAY;GAAE,kBAAkB;GAAS,CAAC;EACtF;AAED,KAAI,mBACA,YAAW,KAAK,2BAA2B;EACvC;EACA,aAAa;EAChB,CAAC,CAAC;AAGP,QAAO;;AAQX,IAAa,+BAA+B,EACxC,qBAAqB,KACrB,wBACoC,EAAE,KAAK;AAC3C,QAAO;EACH;EACA;EACA,2BAA2B;GACvB;GACA,aAAa;GAChB,CAAC;EACL"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './create-extensions.js';
|
|
2
|
+
export type { CreateTiptapExtensionsOptions, CreateTiptapInputExtensionsOptions } from './create-extensions.js';
|
|
3
|
+
export * from './one-liner-document.js';
|
|
4
|
+
export * from './variable-tag.js';
|
|
5
|
+
export type { VariableTagExtensionOptions } from './variable-tag.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extensions/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,YAAY,EAAE,6BAA6B,EAAE,kCAAkC,EAAE,MAAM,wBAAwB,CAAC;AAChH,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,YAAY,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { createVariableTagExtension } from "./variable-tag.js";
|
|
2
|
+
import { OneLinerDocument } from "./one-liner-document.js";
|
|
3
|
+
import { createTiptapExtensions, createTiptapInputExtensions } from "./create-extensions.js";
|
|
4
|
+
export { OneLinerDocument, createTiptapExtensions, createTiptapInputExtensions, createVariableTagExtension };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"one-liner-document.d.ts","sourceRoot":"","sources":["../../src/extensions/one-liner-document.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB,uCAE3B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"one-liner-document.js","names":[],"sources":["../../src/extensions/one-liner-document.ts"],"sourcesContent":["import Document from '@tiptap/extension-document';\n\nexport const OneLinerDocument = Document.extend({\n content: 'inline*',\n});\n"],"mappings":";;AAEA,IAAa,mBAAmB,SAAS,OAAO,EAC5C,SAAS,WACZ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Node, NodeViewRenderer } from '@tiptap/core';
|
|
2
|
+
export type VariableTagExtensionOptions = {
|
|
3
|
+
trailingCursorText?: string;
|
|
4
|
+
addNodeView?: NodeViewRenderer;
|
|
5
|
+
};
|
|
6
|
+
export declare function createVariableTagExtension({ trailingCursorText, addNodeView, }?: VariableTagExtensionOptions): Node<any, any>;
|
|
7
|
+
//# sourceMappingURL=variable-tag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variable-tag.d.ts","sourceRoot":"","sources":["../../src/extensions/variable-tag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,KAAK,EAAgB,gBAAgB,EAAe,MAAM,cAAc,CAAC;AAKhF,MAAM,MAAM,2BAA2B,GAAG;IACtC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAClC,CAAC;AAMF,wBAAgB,0BAA0B,CAAC,EACvC,kBAA6B,EAC7B,WAAW,GACd,GAAE,2BAAgC,kBA8LlC"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Node } from "@tiptap/core";
|
|
2
|
+
import { NodeSelection, Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
|
|
3
|
+
//#region src/extensions/variable-tag.ts
|
|
4
|
+
var isCursorPlaceholder = (node) => {
|
|
5
|
+
return node && node.isText && (node.text === "" || node.text === "");
|
|
6
|
+
};
|
|
7
|
+
function createVariableTagExtension({ trailingCursorText = "", addNodeView } = {}) {
|
|
8
|
+
return Node.create({
|
|
9
|
+
name: "variableTag",
|
|
10
|
+
group: "inline",
|
|
11
|
+
inline: true,
|
|
12
|
+
selectable: true,
|
|
13
|
+
draggable: true,
|
|
14
|
+
atom: true,
|
|
15
|
+
addOptions() {
|
|
16
|
+
return { trailingCursorText };
|
|
17
|
+
},
|
|
18
|
+
addAttributes() {
|
|
19
|
+
return {
|
|
20
|
+
label: { default: null },
|
|
21
|
+
value: { default: null },
|
|
22
|
+
openOnInsert: { default: false },
|
|
23
|
+
default: { default: null },
|
|
24
|
+
transformerId: { default: null },
|
|
25
|
+
transformerParams: { default: null },
|
|
26
|
+
unresolved: { default: false }
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
parseHTML() {
|
|
30
|
+
return [{
|
|
31
|
+
tag: "variable-tag",
|
|
32
|
+
getAttrs: (dom) => {
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(dom.innerHTML);
|
|
35
|
+
} catch {
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}];
|
|
40
|
+
},
|
|
41
|
+
renderHTML({ HTMLAttributes }) {
|
|
42
|
+
return ["variable-tag", JSON.stringify(HTMLAttributes)];
|
|
43
|
+
},
|
|
44
|
+
addCommands() {
|
|
45
|
+
return { setVariableTag: (options) => {
|
|
46
|
+
return ({ dispatch, state }) => {
|
|
47
|
+
if (!dispatch) return false;
|
|
48
|
+
const { selection } = state;
|
|
49
|
+
const textSelection = selection;
|
|
50
|
+
const position = textSelection.$cursor ? textSelection.$cursor.pos : textSelection.$to.pos;
|
|
51
|
+
const node = this.type.create(options);
|
|
52
|
+
const transaction = state.tr.insert(position, node);
|
|
53
|
+
const insertPos = position + node.nodeSize;
|
|
54
|
+
const cursorText = this.options.trailingCursorText;
|
|
55
|
+
if (cursorText) {
|
|
56
|
+
transaction.insert(insertPos, state.schema.text(cursorText));
|
|
57
|
+
transaction.setSelection(TextSelection.create(transaction.doc, insertPos + cursorText.length));
|
|
58
|
+
} else transaction.setSelection(TextSelection.create(transaction.doc, insertPos));
|
|
59
|
+
dispatch(transaction);
|
|
60
|
+
return true;
|
|
61
|
+
};
|
|
62
|
+
} };
|
|
63
|
+
},
|
|
64
|
+
addNodeView() {
|
|
65
|
+
return addNodeView ?? null;
|
|
66
|
+
},
|
|
67
|
+
addProseMirrorPlugins() {
|
|
68
|
+
return [new Plugin({
|
|
69
|
+
key: new PluginKey("variableTagProtection"),
|
|
70
|
+
props: {
|
|
71
|
+
handleKeyDown: (view, event) => {
|
|
72
|
+
const { state } = view;
|
|
73
|
+
const { selection, doc } = state;
|
|
74
|
+
if (event.key === "ArrowLeft" && selection.empty) {
|
|
75
|
+
const { $from } = selection;
|
|
76
|
+
const { pos } = $from;
|
|
77
|
+
if (pos > 0) {
|
|
78
|
+
const before = $from.nodeBefore;
|
|
79
|
+
if (isCursorPlaceholder(before)) {
|
|
80
|
+
const posBeforePlaceholder = pos - before.nodeSize;
|
|
81
|
+
const variableTagNode = doc.resolve(posBeforePlaceholder).nodeBefore;
|
|
82
|
+
if (variableTagNode && variableTagNode.type.name === "variableTag") {
|
|
83
|
+
const tagStart = posBeforePlaceholder - variableTagNode.nodeSize;
|
|
84
|
+
event.preventDefault();
|
|
85
|
+
view.dispatch(state.tr.setSelection(NodeSelection.create(doc, tagStart)));
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (event.key === "ArrowRight" && selection.empty) {
|
|
92
|
+
const { $from } = selection;
|
|
93
|
+
const { pos } = $from;
|
|
94
|
+
const after = $from.nodeAfter;
|
|
95
|
+
if (isCursorPlaceholder(after)) {
|
|
96
|
+
const before = $from.nodeBefore;
|
|
97
|
+
if (before && before.type.name === "variableTag") {
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
view.dispatch(state.tr.setSelection(TextSelection.create(doc, pos + after.nodeSize)));
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (event.key === "Backspace" && selection.empty) {
|
|
105
|
+
const { $from } = selection;
|
|
106
|
+
const { pos } = $from;
|
|
107
|
+
if (pos > 0) {
|
|
108
|
+
const before = $from.nodeBefore;
|
|
109
|
+
if (isCursorPlaceholder(before)) {
|
|
110
|
+
const posBeforePlaceholder = pos - before.nodeSize;
|
|
111
|
+
const variableTagNode = doc.resolve(posBeforePlaceholder).nodeBefore;
|
|
112
|
+
if (variableTagNode && variableTagNode.type.name === "variableTag") {
|
|
113
|
+
const deleteFrom = posBeforePlaceholder - variableTagNode.nodeSize;
|
|
114
|
+
event.preventDefault();
|
|
115
|
+
const tr = state.tr.delete(deleteFrom, pos);
|
|
116
|
+
tr.setSelection(TextSelection.create(tr.doc, Math.max(0, deleteFrom)));
|
|
117
|
+
view.dispatch(tr);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (selection instanceof NodeSelection && selection.node.type.name === "variableTag") {
|
|
124
|
+
if ([
|
|
125
|
+
"ArrowLeft",
|
|
126
|
+
"ArrowRight",
|
|
127
|
+
"ArrowUp",
|
|
128
|
+
"ArrowDown",
|
|
129
|
+
"Home",
|
|
130
|
+
"End"
|
|
131
|
+
].includes(event.key)) return false;
|
|
132
|
+
if (["Delete", "Backspace"].includes(event.key)) return false;
|
|
133
|
+
if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) return false;
|
|
134
|
+
if (event.key.length === 1 || event.key === "Enter") return true;
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
},
|
|
138
|
+
handlePaste: (view) => {
|
|
139
|
+
const { selection } = view.state;
|
|
140
|
+
if (selection instanceof NodeSelection && selection.node.type.name === "variableTag") return true;
|
|
141
|
+
return false;
|
|
142
|
+
},
|
|
143
|
+
handleDrop: (view) => {
|
|
144
|
+
const { selection } = view.state;
|
|
145
|
+
if (selection instanceof NodeSelection && selection.node.type.name === "variableTag" && !view.dragging) return true;
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
})];
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
//#endregion
|
|
154
|
+
export { createVariableTagExtension };
|
|
155
|
+
|
|
156
|
+
//# sourceMappingURL=variable-tag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variable-tag.js","names":[],"sources":["../../src/extensions/variable-tag.ts"],"sourcesContent":["import { Node } from '@tiptap/core';\nimport type { CommandProps, NodeViewRenderer, RawCommands } from '@tiptap/core';\nimport {\n Plugin, PluginKey, NodeSelection, TextSelection,\n} from '@tiptap/pm/state';\n\nexport type VariableTagExtensionOptions = {\n trailingCursorText?: string;\n addNodeView?: NodeViewRenderer;\n};\n\nconst isCursorPlaceholder = (node: { isText?: boolean; text?: string } | null | undefined) => {\n return node && node.isText && (node.text === '\\u200B' || node.text === '\\u2060');\n};\n\nexport function createVariableTagExtension({\n trailingCursorText = '\\u200B',\n addNodeView,\n}: VariableTagExtensionOptions = {}) {\n return Node.create({\n name: 'variableTag',\n group: 'inline',\n inline: true,\n selectable: true,\n draggable: true,\n atom: true,\n\n addOptions() {\n return {\n trailingCursorText,\n };\n },\n\n addAttributes() {\n return {\n label: { default: null },\n value: { default: null },\n openOnInsert: { default: false },\n default: { default: null },\n transformerId: { default: null },\n transformerParams: { default: null },\n // Display-only: token did not match a known variable option.\n unresolved: { default: false },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'variable-tag',\n getAttrs: (dom) => {\n try {\n return JSON.parse((dom as HTMLElement).innerHTML);\n } catch {\n return {};\n }\n },\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['variable-tag', JSON.stringify(HTMLAttributes)];\n },\n\n addCommands() {\n return {\n setVariableTag: (options: Record<string, unknown>) => {\n return ({ dispatch, state }: CommandProps) => {\n if (!dispatch) {\n return false;\n }\n\n const { selection } = state;\n const textSelection = selection as TextSelection;\n const position = textSelection.$cursor ? textSelection.$cursor.pos : textSelection.$to.pos;\n const node = this.type.create(options);\n const transaction = state.tr.insert(position, node);\n const insertPos = position + node.nodeSize;\n const cursorText = this.options.trailingCursorText;\n\n if (cursorText) {\n transaction.insert(insertPos, state.schema.text(cursorText));\n transaction.setSelection(TextSelection.create(transaction.doc, insertPos + cursorText.length));\n } else {\n transaction.setSelection(TextSelection.create(transaction.doc, insertPos));\n }\n\n dispatch(transaction);\n return true;\n };\n },\n } as Partial<RawCommands>;\n },\n\n addNodeView() {\n return addNodeView ?? null;\n },\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: new PluginKey('variableTagProtection'),\n\n props: {\n handleKeyDown: (view, event) => {\n const { state } = view;\n const { selection, doc } = state;\n\n if (event.key === 'ArrowLeft' && selection.empty) {\n const { $from } = selection;\n const { pos } = $from;\n if (pos > 0) {\n const before = $from.nodeBefore;\n if (isCursorPlaceholder(before)) {\n const posBeforePlaceholder = pos - before!.nodeSize;\n const $beforePlaceholder = doc.resolve(posBeforePlaceholder);\n const variableTagNode = $beforePlaceholder.nodeBefore;\n if (variableTagNode && variableTagNode.type.name === 'variableTag') {\n const tagStart = posBeforePlaceholder - variableTagNode.nodeSize;\n event.preventDefault();\n view.dispatch(state.tr.setSelection(NodeSelection.create(doc, tagStart)));\n return true;\n }\n }\n }\n }\n\n if (event.key === 'ArrowRight' && selection.empty) {\n const { $from } = selection;\n const { pos } = $from;\n const after = $from.nodeAfter;\n if (isCursorPlaceholder(after)) {\n const before = $from.nodeBefore;\n if (before && before.type.name === 'variableTag') {\n event.preventDefault();\n view.dispatch(state.tr.setSelection(TextSelection.create(doc, pos + after!.nodeSize)));\n return true;\n }\n }\n }\n\n if (event.key === 'Backspace' && selection.empty) {\n const { $from } = selection;\n const { pos } = $from;\n if (pos > 0) {\n const before = $from.nodeBefore;\n if (isCursorPlaceholder(before)) {\n const posBeforePlaceholder = pos - before!.nodeSize;\n const $beforePlaceholder = doc.resolve(posBeforePlaceholder);\n const variableTagNode = $beforePlaceholder.nodeBefore;\n if (variableTagNode && variableTagNode.type.name === 'variableTag') {\n const deleteFrom = posBeforePlaceholder - variableTagNode.nodeSize;\n event.preventDefault();\n const tr = state.tr.delete(deleteFrom, pos);\n tr.setSelection(TextSelection.create(tr.doc, Math.max(0, deleteFrom)));\n view.dispatch(tr);\n return true;\n }\n }\n }\n }\n\n if (selection instanceof NodeSelection && selection.node.type.name === 'variableTag') {\n if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) {\n return false;\n }\n\n if (['Delete', 'Backspace'].includes(event.key)) {\n return false;\n }\n\n if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) {\n return false;\n }\n\n if (event.key.length === 1 || event.key === 'Enter') {\n return true;\n }\n }\n\n return false;\n },\n\n handlePaste: (view) => {\n const { selection } = view.state;\n\n if (selection instanceof NodeSelection && selection.node.type.name === 'variableTag') {\n return true;\n }\n\n return false;\n },\n\n handleDrop: (view) => {\n const { selection } = view.state;\n\n if (selection instanceof NodeSelection && selection.node.type.name === 'variableTag' && !view.dragging) {\n return true;\n }\n\n return false;\n },\n },\n }),\n ];\n },\n });\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type { VariableOption, VariableCategories } from './types/variable-option.js';
|
|
2
|
+
export { createTiptapExtensions, createTiptapInputExtensions, createVariableTagExtension, OneLinerDocument, } from './extensions/index.js';
|
|
3
|
+
export type { CreateTiptapExtensionsOptions, CreateTiptapInputExtensionsOptions, VariableTagExtensionOptions, } from './extensions/index.js';
|
|
4
|
+
export { normalizeContentArray, valueToContent, getFatalTiptapContentError, } from './serialization/editor.js';
|
|
5
|
+
export type { VariableTagAttrs } from './serialization/input.js';
|
|
6
|
+
export { buildVariableTagAttrs, contentToValue, dedupeVariableOptions, flattenVariableOptions, getReferenceBaseToken, parseTokenWithDefault, replaceTokenWithVariable, resolveVariableTagByValue, resolveVariableTagLabel, valueToContent as inputValueToContent, } from './serialization/input.js';
|
|
7
|
+
export * from './links/index.js';
|
|
8
|
+
export { isTiptapButtonActive, isTiptapButtonName, runTiptapButton, } from './toolbar/index.js';
|
|
9
|
+
export type { RunTiptapButtonOptions, TiptapButtonName, TiptapTableInsertOptions, } from './toolbar/index.js';
|
|
10
|
+
export { expandPresetItems, flattenToolbarButtonNames, getToolbarGroupDefaultIcon, getToolbarGroupItems, getToolbarGroupMenuItems, getToolbarGroupTriggerState, isFormattingToolbarPreset, isHeadingsOnlyToolbarPreset, isToolbarButtonActive, isToolbarSeparatorToken, normalizeToolbarNodes, parseToolbarConfig, runToolbarButton, toolbarIncludesButton, } from './toolbar/index.js';
|
|
11
|
+
export type { ToolbarButtonNode, ToolbarFormattingPreset, ToolbarGroup, ToolbarGroupItemDefinition, ToolbarGroupMenuButton, ToolbarGroupMenuEntry, ToolbarGroupNode, ToolbarGroupPreset, ToolbarGroupTriggerState, ToolbarHeadingsPreset, ToolbarHeadingLevel, ToolbarIconName, ToolbarNode, ToolbarSeparatorNode, ToolbarSeparatorToken, } from './toolbar/index.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErF,OAAO,EACH,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,gBAAgB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACR,6BAA6B,EAC7B,kCAAkC,EAClC,2BAA2B,GAC9B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACH,qBAAqB,EACrB,cAAc,EACd,0BAA0B,GAC7B,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EACH,qBAAqB,EACrB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,yBAAyB,EACzB,uBAAuB,EACvB,cAAc,IAAI,mBAAmB,GACxC,MAAM,0BAA0B,CAAC;AAElC,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EACH,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,GAClB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACR,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACH,iBAAiB,EACjB,yBAAyB,EACzB,0BAA0B,EAC1B,oBAAoB,EACpB,wBAAwB,EACxB,2BAA2B,EAC3B,yBAAyB,EACzB,2BAA2B,EAC3B,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACR,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,0BAA0B,EAC1B,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,qBAAqB,GACxB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createLinkExtension } from "./links/extension.js";
|
|
2
|
+
import { createVariableTagExtension } from "./extensions/variable-tag.js";
|
|
3
|
+
import { OneLinerDocument } from "./extensions/one-liner-document.js";
|
|
4
|
+
import { createTiptapExtensions, createTiptapInputExtensions } from "./extensions/create-extensions.js";
|
|
5
|
+
import "./extensions/index.js";
|
|
6
|
+
import { getFatalTiptapContentError, normalizeContentArray, valueToContent as valueToContent$1 } from "./serialization/editor.js";
|
|
7
|
+
import { buildVariableTagAttrs, contentToValue, dedupeVariableOptions, flattenVariableOptions, getReferenceBaseToken, parseTokenWithDefault, replaceTokenWithVariable, resolveVariableTagByValue, resolveVariableTagLabel, valueToContent } from "./serialization/input.js";
|
|
8
|
+
import { buildCraftElementLinkUrl, buildCraftElementSelectorStorageKey, getCraftLinkOptions, getLinkOptionsElementSiteId, hasCraftLinkOptions, isCraftElementLink, isLinkOptionsArray, openCraftElementLinkSelector, parseCraftElementLink } from "./links/craft-element.js";
|
|
9
|
+
import { applyLinkToEditor, buildLinkMarkAttributes, getLinkEditState, getLinkOpenInNewTab, getSelectedText, unsetLinkFromEditor } from "./links/commands.js";
|
|
10
|
+
import "./links/index.js";
|
|
11
|
+
import { isTiptapButtonActive, isTiptapButtonName, runTiptapButton } from "./toolbar/button-registry.js";
|
|
12
|
+
import { expandPresetItems, flattenToolbarButtonNames, getToolbarGroupDefaultIcon, getToolbarGroupItems, getToolbarGroupMenuItems, getToolbarGroupTriggerState, isFormattingToolbarPreset, isHeadingsOnlyToolbarPreset, isToolbarButtonActive, isToolbarSeparatorToken, normalizeToolbarNodes, parseToolbarConfig, runToolbarButton, toolbarIncludesButton } from "./toolbar/toolbar-schema.js";
|
|
13
|
+
export { OneLinerDocument, applyLinkToEditor, buildCraftElementLinkUrl, buildCraftElementSelectorStorageKey, buildLinkMarkAttributes, buildVariableTagAttrs, contentToValue, createLinkExtension, createTiptapExtensions, createTiptapInputExtensions, createVariableTagExtension, dedupeVariableOptions, expandPresetItems, flattenToolbarButtonNames, flattenVariableOptions, getCraftLinkOptions, getFatalTiptapContentError, getLinkEditState, getLinkOpenInNewTab, getLinkOptionsElementSiteId, getReferenceBaseToken, getSelectedText, getToolbarGroupDefaultIcon, getToolbarGroupItems, getToolbarGroupMenuItems, getToolbarGroupTriggerState, hasCraftLinkOptions, valueToContent as inputValueToContent, isCraftElementLink, isFormattingToolbarPreset, isHeadingsOnlyToolbarPreset, isLinkOptionsArray, isTiptapButtonActive, isTiptapButtonName, isToolbarButtonActive, isToolbarSeparatorToken, normalizeContentArray, normalizeToolbarNodes, openCraftElementLinkSelector, parseCraftElementLink, parseTokenWithDefault, parseToolbarConfig, replaceTokenWithVariable, resolveVariableTagByValue, resolveVariableTagLabel, runTiptapButton, runToolbarButton, toolbarIncludesButton, unsetLinkFromEditor, valueToContent$1 as valueToContent };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Editor } from '@tiptap/core';
|
|
2
|
+
import { InsertLinkParams, LinkEditState, LinkMarkAttributes } from './types.js';
|
|
3
|
+
export declare function buildLinkMarkAttributes(url: string, openInNewTab: boolean): LinkMarkAttributes;
|
|
4
|
+
export declare function getSelectedText(editor: Editor): string;
|
|
5
|
+
export declare function getLinkOpenInNewTab(editor: Editor): boolean;
|
|
6
|
+
export declare function getLinkEditState(editor: Editor): LinkEditState;
|
|
7
|
+
export declare function applyLinkToEditor(editor: Editor, params: InsertLinkParams): void;
|
|
8
|
+
export declare function unsetLinkFromEditor(editor: Editor): void;
|
|
9
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/links/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,KAAK,EACR,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EACrB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,kBAAkB,CAQ9F;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAgB9D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA+BhF;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAExD"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { getMarkRange } from "@tiptap/core";
|
|
2
|
+
//#region src/links/commands.ts
|
|
3
|
+
function buildLinkMarkAttributes(url, openInNewTab) {
|
|
4
|
+
const linkAttrs = { href: url };
|
|
5
|
+
if (openInNewTab) linkAttrs.target = "_blank";
|
|
6
|
+
return linkAttrs;
|
|
7
|
+
}
|
|
8
|
+
function getSelectedText(editor) {
|
|
9
|
+
const { from, to } = editor.state.selection;
|
|
10
|
+
return editor.state.doc.textBetween(from, to, " ");
|
|
11
|
+
}
|
|
12
|
+
function getLinkOpenInNewTab(editor) {
|
|
13
|
+
return editor.isActive("link") && editor.getAttributes("link").target === "_blank";
|
|
14
|
+
}
|
|
15
|
+
function getLinkEditState(editor) {
|
|
16
|
+
const { href } = editor.getAttributes("link");
|
|
17
|
+
const { state } = editor;
|
|
18
|
+
const linkType = state.schema.marks.link;
|
|
19
|
+
const range = getMarkRange(state.selection.$from, linkType);
|
|
20
|
+
const from = range?.from ?? state.selection.from;
|
|
21
|
+
const to = range?.to ?? state.selection.to;
|
|
22
|
+
const text = editor.state.doc.textBetween(from, to, " ");
|
|
23
|
+
return {
|
|
24
|
+
from,
|
|
25
|
+
to,
|
|
26
|
+
href: href ?? "",
|
|
27
|
+
text,
|
|
28
|
+
openInNewTab: getLinkOpenInNewTab(editor)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function applyLinkToEditor(editor, params) {
|
|
32
|
+
const { url, text, openInNewTab, from: fromParam, to: toParam } = params;
|
|
33
|
+
const chain = editor.chain().focus();
|
|
34
|
+
const linkAttrs = buildLinkMarkAttributes(url, openInNewTab);
|
|
35
|
+
const content = {
|
|
36
|
+
type: "text",
|
|
37
|
+
text: text.trim() || url,
|
|
38
|
+
marks: [{
|
|
39
|
+
type: "link",
|
|
40
|
+
attrs: linkAttrs
|
|
41
|
+
}]
|
|
42
|
+
};
|
|
43
|
+
if (typeof fromParam === "number" && typeof toParam === "number" && fromParam !== toParam) {
|
|
44
|
+
chain.insertContentAt({
|
|
45
|
+
from: fromParam,
|
|
46
|
+
to: toParam
|
|
47
|
+
}, [content]).run();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const { from, to } = editor.state.selection;
|
|
51
|
+
if (editor.state.doc.textBetween(from, to, " ")) {
|
|
52
|
+
chain.extendMarkRange("link").setLink(linkAttrs).run();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
chain.insertContent([content]).run();
|
|
56
|
+
}
|
|
57
|
+
function unsetLinkFromEditor(editor) {
|
|
58
|
+
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { applyLinkToEditor, buildLinkMarkAttributes, getLinkEditState, getLinkOpenInNewTab, getSelectedText, unsetLinkFromEditor };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","names":[],"sources":["../../src/links/commands.ts"],"sourcesContent":["import { getMarkRange, type Editor } from '@tiptap/core';\n\nimport type {\n InsertLinkParams,\n LinkEditState,\n LinkMarkAttributes,\n} from './types.js';\n\nexport function buildLinkMarkAttributes(url: string, openInNewTab: boolean): LinkMarkAttributes {\n const linkAttrs: LinkMarkAttributes = { href: url };\n\n if (openInNewTab) {\n linkAttrs.target = '_blank';\n }\n\n return linkAttrs;\n}\n\nexport function getSelectedText(editor: Editor): string {\n const { from, to } = editor.state.selection;\n return editor.state.doc.textBetween(from, to, ' ');\n}\n\nexport function getLinkOpenInNewTab(editor: Editor): boolean {\n return editor.isActive('link') && editor.getAttributes('link').target === '_blank';\n}\n\nexport function getLinkEditState(editor: Editor): LinkEditState {\n const { href } = editor.getAttributes('link');\n const { state } = editor;\n const linkType = state.schema.marks.link;\n const range = getMarkRange(state.selection.$from, linkType);\n const from = range?.from ?? state.selection.from;\n const to = range?.to ?? state.selection.to;\n const text = editor.state.doc.textBetween(from, to, ' ');\n\n return {\n from,\n to,\n href: href ?? '',\n text,\n openInNewTab: getLinkOpenInNewTab(editor),\n };\n}\n\nexport function applyLinkToEditor(editor: Editor, params: InsertLinkParams): void {\n const {\n url,\n text,\n openInNewTab,\n from: fromParam,\n to: toParam,\n } = params;\n\n const chain = editor.chain().focus();\n const linkAttrs = buildLinkMarkAttributes(url, openInNewTab);\n const content = {\n type: 'text',\n text: text.trim() || url,\n marks: [{ type: 'link', attrs: linkAttrs }],\n };\n\n if (typeof fromParam === 'number' && typeof toParam === 'number' && fromParam !== toParam) {\n chain.insertContentAt({ from: fromParam, to: toParam }, [content]).run();\n return;\n }\n\n const { from, to } = editor.state.selection;\n const selectedText = editor.state.doc.textBetween(from, to, ' ');\n\n if (selectedText) {\n chain.extendMarkRange('link').setLink(linkAttrs).run();\n return;\n }\n\n chain.insertContent([content]).run();\n}\n\nexport function unsetLinkFromEditor(editor: Editor): void {\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\n}\n"],"mappings":";;AAQA,SAAgB,wBAAwB,KAAa,cAA2C;CAC5F,MAAM,YAAgC,EAAE,MAAM,KAAK;AAEnD,KAAI,aACA,WAAU,SAAS;AAGvB,QAAO;;AAGX,SAAgB,gBAAgB,QAAwB;CACpD,MAAM,EAAE,MAAM,OAAO,OAAO,MAAM;AAClC,QAAO,OAAO,MAAM,IAAI,YAAY,MAAM,IAAI,IAAI;;AAGtD,SAAgB,oBAAoB,QAAyB;AACzD,QAAO,OAAO,SAAS,OAAO,IAAI,OAAO,cAAc,OAAO,CAAC,WAAW;;AAG9E,SAAgB,iBAAiB,QAA+B;CAC5D,MAAM,EAAE,SAAS,OAAO,cAAc,OAAO;CAC7C,MAAM,EAAE,UAAU;CAClB,MAAM,WAAW,MAAM,OAAO,MAAM;CACpC,MAAM,QAAQ,aAAa,MAAM,UAAU,OAAO,SAAS;CAC3D,MAAM,OAAO,OAAO,QAAQ,MAAM,UAAU;CAC5C,MAAM,KAAK,OAAO,MAAM,MAAM,UAAU;CACxC,MAAM,OAAO,OAAO,MAAM,IAAI,YAAY,MAAM,IAAI,IAAI;AAExD,QAAO;EACH;EACA;EACA,MAAM,QAAQ;EACd;EACA,cAAc,oBAAoB,OAAO;EAC5C;;AAGL,SAAgB,kBAAkB,QAAgB,QAAgC;CAC9E,MAAM,EACF,KACA,MACA,cACA,MAAM,WACN,IAAI,YACJ;CAEJ,MAAM,QAAQ,OAAO,OAAO,CAAC,OAAO;CACpC,MAAM,YAAY,wBAAwB,KAAK,aAAa;CAC5D,MAAM,UAAU;EACZ,MAAM;EACN,MAAM,KAAK,MAAM,IAAI;EACrB,OAAO,CAAC;GAAE,MAAM;GAAQ,OAAO;GAAW,CAAC;EAC9C;AAED,KAAI,OAAO,cAAc,YAAY,OAAO,YAAY,YAAY,cAAc,SAAS;AACvF,QAAM,gBAAgB;GAAE,MAAM;GAAW,IAAI;GAAS,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAK;AACxE;;CAGJ,MAAM,EAAE,MAAM,OAAO,OAAO,MAAM;AAGlC,KAFqB,OAAO,MAAM,IAAI,YAAY,MAAM,IAAI,IAExD,EAAc;AACd,QAAM,gBAAgB,OAAO,CAAC,QAAQ,UAAU,CAAC,KAAK;AACtD;;AAGJ,OAAM,cAAc,CAAC,QAAQ,CAAC,CAAC,KAAK;;AAGxC,SAAgB,oBAAoB,QAAsB;AACtD,QAAO,OAAO,CAAC,OAAO,CAAC,gBAAgB,OAAO,CAAC,WAAW,CAAC,KAAK"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CraftSelectedElement, ElementSelectorHost, LinkElementConfig, LinkOptionSchemaItem, LinkOptionsInput, ParsedCraftElementLink } from './types.js';
|
|
2
|
+
export declare function isLinkOptionsArray(value: LinkOptionsInput | undefined): value is LinkOptionSchemaItem[];
|
|
3
|
+
export declare function getCraftLinkOptions(linkOptions: LinkOptionsInput | undefined): LinkOptionSchemaItem[];
|
|
4
|
+
export declare function getLinkOptionsElementSiteId(linkOptions: LinkOptionsInput | undefined): number | undefined;
|
|
5
|
+
export declare function hasCraftLinkOptions(linkOptions: LinkOptionsInput | undefined): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Build a Craft element link URL with the standard ref fragment:
|
|
8
|
+
* `https://example.com/page#refHandle:123@1`
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildCraftElementLinkUrl(element: CraftSelectedElement, refHandle: string): string;
|
|
11
|
+
/** Parse a Craft element link URL back into its parts. */
|
|
12
|
+
export declare function parseCraftElementLink(href: string): ParsedCraftElementLink | null;
|
|
13
|
+
export declare function isCraftElementLink(href: string): boolean;
|
|
14
|
+
export declare function buildCraftElementSelectorStorageKey(linkSelectorStorageKeyPrefix: string, elementType: string): string;
|
|
15
|
+
export type OpenCraftElementLinkSelectorParams = {
|
|
16
|
+
config: LinkElementConfig;
|
|
17
|
+
elementSiteId?: number;
|
|
18
|
+
linkSelectorStorageKeyPrefix?: string;
|
|
19
|
+
getSelectedText: () => string;
|
|
20
|
+
onSelect: (result: {
|
|
21
|
+
url: string;
|
|
22
|
+
text: string;
|
|
23
|
+
}) => void;
|
|
24
|
+
host: ElementSelectorHost;
|
|
25
|
+
};
|
|
26
|
+
/** Open Craft's element selector modal and return a Plugin Kit link URL on selection. */
|
|
27
|
+
export declare function openCraftElementLinkSelector({ config, elementSiteId, linkSelectorStorageKeyPrefix, getSelectedText, onSelect, host, }: OpenCraftElementLinkSelectorParams): void;
|
|
28
|
+
//# sourceMappingURL=craft-element.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"craft-element.d.ts","sourceRoot":"","sources":["../../src/links/craft-element.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACzB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,GAAG,KAAK,IAAI,oBAAoB,EAAE,CAEvG;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,gBAAgB,GAAG,SAAS,GAAG,oBAAoB,EAAE,CAwBrG;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,gBAAgB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAMzG;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,gBAAgB,GAAG,SAAS,GAAG,OAAO,CAEtF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACpC,OAAO,EAAE,oBAAoB,EAC7B,SAAS,EAAE,MAAM,GAClB,MAAM,CAER;AAED,0DAA0D;AAC1D,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAqBjF;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,mCAAmC,CAC/C,4BAA4B,EAAE,MAAM,EACpC,WAAW,EAAE,MAAM,GACpB,MAAM,CAER;AAED,MAAM,MAAM,kCAAkC,GAAG;IAC7C,MAAM,EAAE,iBAAiB,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,eAAe,EAAE,MAAM,MAAM,CAAC;IAC9B,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC1D,IAAI,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF,yFAAyF;AACzF,wBAAgB,4BAA4B,CAAC,EACzC,MAAM,EACN,aAAa,EACb,4BAA4B,EAC5B,eAAe,EACf,QAAQ,EACR,IAAI,GACP,EAAE,kCAAkC,GAAG,IAAI,CAwB3C"}
|