@manuscripts/body-editor 1.6.9 → 1.6.10

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.
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.DeleteKeywordDialog = void 0;
27
+ const style_guide_1 = require("@manuscripts/style-guide");
28
+ const react_1 = __importStar(require("react"));
29
+ const DeleteKeywordDialog = ({ keyword, handleDelete, }) => {
30
+ const [isOpen, setOpen] = (0, react_1.useState)(true);
31
+ return (react_1.default.createElement(style_guide_1.Dialog, { isOpen: isOpen, actions: {
32
+ primary: {
33
+ action: () => setOpen(false),
34
+ title: 'Cancel',
35
+ },
36
+ secondary: {
37
+ action: () => {
38
+ setOpen(false);
39
+ handleDelete();
40
+ },
41
+ title: 'Delete',
42
+ },
43
+ }, category: style_guide_1.Category.confirmation, header: 'Delete Keyword', message: `Are you sure you want to delete "${keyword}" keyword?
44
+ ` }));
45
+ };
46
+ exports.DeleteKeywordDialog = DeleteKeywordDialog;
@@ -30,7 +30,6 @@ const comment_annotation_1 = __importDefault(require("../plugins/comment_annotat
30
30
  const elements_1 = __importDefault(require("../plugins/elements"));
31
31
  const footnotes_1 = __importDefault(require("../plugins/footnotes"));
32
32
  const highlight_1 = __importDefault(require("../plugins/highlight"));
33
- const keywords_1 = __importDefault(require("../plugins/keywords"));
34
33
  const objects_1 = __importDefault(require("../plugins/objects"));
35
34
  const paragraphs_1 = __importDefault(require("../plugins/paragraphs"));
36
35
  const persist_1 = __importDefault(require("../plugins/persist"));
@@ -54,7 +53,6 @@ exports.default = (props) => {
54
53
  (0, persist_1.default)(),
55
54
  (0, sections_1.default)(),
56
55
  (0, toc_1.default)(props),
57
- (0, keywords_1.default)(props),
58
56
  (0, bibliography_1.default)(props),
59
57
  (0, objects_1.default)(props),
60
58
  (0, comment_annotation_1.default)(props),
@@ -34,7 +34,7 @@ const footnotes_element_1 = __importDefault(require("../views/footnotes_element"
34
34
  const inline_equation_editable_1 = __importDefault(require("../views/inline_equation_editable"));
35
35
  const inline_footnote_editable_1 = __importDefault(require("../views/inline_footnote_editable"));
36
36
  const keyword_1 = __importDefault(require("../views/keyword"));
37
- const keywords_element_1 = __importDefault(require("../views/keywords_element"));
37
+ const keyword_group_1 = __importDefault(require("../views/keyword_group"));
38
38
  const link_editable_1 = __importDefault(require("../views/link_editable"));
39
39
  const listing_editable_1 = __importDefault(require("../views/listing_editable"));
40
40
  const listing_element_editable_1 = __importDefault(require("../views/listing_element_editable"));
@@ -65,8 +65,8 @@ exports.default = (props, dispatch) => {
65
65
  footnotes_element: (0, footnotes_element_1.default)(props),
66
66
  inline_equation: (0, inline_equation_editable_1.default)(props),
67
67
  inline_footnote: (0, inline_footnote_editable_1.default)(props),
68
- keyword: (0, keyword_1.default)(props),
69
- keywords_element: (0, keywords_element_1.default)(props, dispatch),
68
+ keyword: (0, keyword_1.default)(props, dispatch),
69
+ keyword_group: (0, keyword_group_1.default)(props, dispatch),
70
70
  link: (0, link_editable_1.default)(props),
71
71
  listing: (0, listing_editable_1.default)(props),
72
72
  listing_element: (0, listing_element_editable_1.default)(props),
package/dist/cjs/index.js CHANGED
@@ -56,6 +56,5 @@ var comment_annotation_1 = require("./plugins/comment_annotation");
56
56
  Object.defineProperty(exports, "commentScroll", { enumerable: true, get: function () { return comment_annotation_1.commentScroll; } });
57
57
  Object.defineProperty(exports, "isThereSelector", { enumerable: true, get: function () { return comment_annotation_1.isThereSelector; } });
58
58
  Object.defineProperty(exports, "isHighlightComment", { enumerable: true, get: function () { return comment_annotation_1.isHighlightComment; } });
59
- __exportStar(require("./plugins/keywords"), exports);
60
59
  __exportStar(require("./lib/utils"), exports);
61
60
  __exportStar(require("./useEditor"), exports);
@@ -14,15 +14,71 @@
14
14
  * See the License for the specific language governing permissions and
15
15
  * limitations under the License.
16
16
  */
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };
17
20
  Object.defineProperty(exports, "__esModule", { value: true });
18
21
  exports.KeywordView = void 0;
22
+ const DeleteKeywordDialog_1 = require("../components/keywords/DeleteKeywordDialog");
23
+ const track_changes_utils_1 = require("../lib/track-changes-utils");
19
24
  const base_node_view_1 = require("./base_node_view");
20
25
  const creators_1 = require("./creators");
26
+ const ReactSubView_1 = __importDefault(require("./ReactSubView"));
27
+ const deleteIcon = '<svg width="8px" height="8px" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg">\n' +
28
+ ' <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n' +
29
+ ' <g fill="#6E6E6E">\n' +
30
+ ' <rect id="Rectangle-23-Copy" transform="translate(13.000000, 13.000000) rotate(-45.000000) translate(-13.000000, -13.000000) " x="-3" y="11" width="32" height="4" rx="2"></rect>\n' +
31
+ ' <rect id="Rectangle-23-Copy-2" transform="translate(13.000000, 13.000000) scale(1, -1) rotate(-45.000000) translate(-13.000000, -13.000000) " x="-3" y="11" width="32" height="4" rx="2"></rect>\n' +
32
+ ' </g>\n' +
33
+ ' </g>\n' +
34
+ '</svg>';
21
35
  class KeywordView extends base_node_view_1.BaseNodeView {
22
36
  constructor() {
23
37
  super(...arguments);
24
- this.stopEvent = () => true;
25
- this.ignoreMutation = () => true;
38
+ this.initialise = () => {
39
+ this.createDOM();
40
+ this.updateContents();
41
+ };
42
+ this.createDOM = () => {
43
+ this.dom = document.createElement('span');
44
+ this.contentDOM = document.createElement('span');
45
+ };
46
+ this.updateContents = () => {
47
+ const keyword = document.createElement('span');
48
+ const classes = ['keyword', ...(0, track_changes_utils_1.getChangeClasses)(this.node)];
49
+ keyword.classList.add(...classes);
50
+ keyword.appendChild(this.contentDOM);
51
+ const can = this.props.getCapabilities();
52
+ if (can.editArticle) {
53
+ const svg = new DOMParser()
54
+ .parseFromString(deleteIcon, 'image/svg+xml')
55
+ .querySelector('svg');
56
+ svg.classList.add('delete-keyword');
57
+ svg.addEventListener('click', this.showConfirmationDialog);
58
+ keyword.appendChild(svg);
59
+ }
60
+ this.dom.innerHTML = '';
61
+ this.dom.appendChild(keyword);
62
+ };
63
+ this.showConfirmationDialog = () => {
64
+ var _a;
65
+ (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.remove();
66
+ const keyword = this.node;
67
+ const pos = this.getPos();
68
+ const handleDelete = () => {
69
+ const tr = this.view.state.tr;
70
+ tr.delete(pos, pos + keyword.nodeSize);
71
+ this.view.dispatch(tr);
72
+ };
73
+ const componentProps = {
74
+ keyword: keyword.textContent,
75
+ handleDelete: handleDelete,
76
+ };
77
+ this.dialog = (0, ReactSubView_1.default)(this.props, DeleteKeywordDialog_1.DeleteKeywordDialog, componentProps, this.node, this.getPos, this.view, 'keywords-delete');
78
+ if (this.dialog) {
79
+ this.dom.appendChild(this.dialog);
80
+ }
81
+ };
26
82
  }
27
83
  }
28
84
  exports.KeywordView = KeywordView;
@@ -18,36 +18,33 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
18
18
  return (mod && mod.__esModule) ? mod : { "default": mod };
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.KeywordsElementView = void 0;
21
+ exports.KeywordGroupView = void 0;
22
22
  const AddKeywordInline_1 = require("../components/keywords/AddKeywordInline");
23
- const DeleteKeyword_1 = require("../components/keywords/DeleteKeyword");
24
23
  const block_view_1 = __importDefault(require("./block_view"));
25
24
  const creators_1 = require("./creators");
26
25
  const ReactSubView_1 = __importDefault(require("./ReactSubView"));
27
- class KeywordsElementView extends block_view_1.default {
26
+ class KeywordGroupView extends block_view_1.default {
28
27
  constructor() {
29
28
  super(...arguments);
30
29
  this.ignoreMutation = () => true;
31
30
  this.stopEvent = () => true;
32
31
  this.createElement = () => {
33
32
  this.element = document.createElement('div');
34
- this.element.classList.add('block');
33
+ this.element.classList.add('block', 'keyword-group-container');
35
34
  this.dom.appendChild(this.element);
36
35
  this.contentDOM = document.createElement('div');
37
- this.contentDOM.classList.add('keywords-list');
36
+ this.contentDOM.classList.add('keyword-group');
38
37
  this.contentDOM.setAttribute('id', this.node.attrs.id);
39
38
  this.contentDOM.setAttribute('contenteditable', 'false');
40
39
  this.element.appendChild(this.contentDOM);
41
- this.addingTools = (0, ReactSubView_1.default)(this.props, AddKeywordInline_1.AddKeywordInline, { getUpdatedNode: () => this.node }, this.node, this.getPos, this.view, 'keywords-editor');
42
- if (this.addingTools && this.props.getCapabilities().editArticle) {
43
- this.element.appendChild(this.addingTools);
40
+ if (this.props.getCapabilities().editArticle) {
41
+ this.addingTools = (0, ReactSubView_1.default)(this.props, AddKeywordInline_1.AddKeywordInline, { getUpdatedNode: () => this.node }, this.node, this.getPos, this.view, 'keywords-editor');
44
42
  }
45
- this.deleteTools = (0, ReactSubView_1.default)(this.props, DeleteKeyword_1.DeleteKeyword, { getUpdatedNode: () => this.node }, this.node, this.getPos, this.view, 'keywords-delete');
46
- if (this.deleteTools) {
47
- this.element.appendChild(this.deleteTools);
43
+ if (this.addingTools) {
44
+ this.element.appendChild(this.addingTools);
48
45
  }
49
46
  };
50
47
  }
51
48
  }
52
- exports.KeywordsElementView = KeywordsElementView;
53
- exports.default = (0, creators_1.createNodeView)(KeywordsElementView);
49
+ exports.KeywordGroupView = KeywordGroupView;
50
+ exports.default = (0, creators_1.createNodeView)(KeywordGroupView);
@@ -0,0 +1,19 @@
1
+ import { Category, Dialog } from '@manuscripts/style-guide';
2
+ import React, { useState } from 'react';
3
+ export const DeleteKeywordDialog = ({ keyword, handleDelete, }) => {
4
+ const [isOpen, setOpen] = useState(true);
5
+ return (React.createElement(Dialog, { isOpen: isOpen, actions: {
6
+ primary: {
7
+ action: () => setOpen(false),
8
+ title: 'Cancel',
9
+ },
10
+ secondary: {
11
+ action: () => {
12
+ setOpen(false);
13
+ handleDelete();
14
+ },
15
+ title: 'Delete',
16
+ },
17
+ }, category: Category.confirmation, header: 'Delete Keyword', message: `Are you sure you want to delete "${keyword}" keyword?
18
+ ` }));
19
+ };
@@ -25,7 +25,6 @@ import comment_annotation from '../plugins/comment_annotation';
25
25
  import elements from '../plugins/elements';
26
26
  import footnotes from '../plugins/footnotes';
27
27
  import highlights from '../plugins/highlight';
28
- import keywords from '../plugins/keywords';
29
28
  import objects from '../plugins/objects';
30
29
  import paragraphs from '../plugins/paragraphs';
31
30
  import persist from '../plugins/persist';
@@ -49,7 +48,6 @@ export default (props) => {
49
48
  persist(),
50
49
  sections(),
51
50
  toc(props),
52
- keywords(props),
53
51
  bibliography(props),
54
52
  objects(props),
55
53
  comment_annotation(props),
@@ -29,7 +29,7 @@ import footnotesElement from '../views/footnotes_element';
29
29
  import inlineEquation from '../views/inline_equation_editable';
30
30
  import inlineFootnote from '../views/inline_footnote_editable';
31
31
  import keyword from '../views/keyword';
32
- import keywordsElement from '../views/keywords_element';
32
+ import keywordGroup from '../views/keyword_group';
33
33
  import link from '../views/link_editable';
34
34
  import listing from '../views/listing_editable';
35
35
  import listingElement from '../views/listing_element_editable';
@@ -60,8 +60,8 @@ export default (props, dispatch) => {
60
60
  footnotes_element: footnotesElement(props),
61
61
  inline_equation: inlineEquation(props),
62
62
  inline_footnote: inlineFootnote(props),
63
- keyword: keyword(props),
64
- keywords_element: keywordsElement(props, dispatch),
63
+ keyword: keyword(props, dispatch),
64
+ keyword_group: keywordGroup(props, dispatch),
65
65
  link: link(props),
66
66
  listing: listing(props),
67
67
  listing_element: listingElement(props),
package/dist/es/index.js CHANGED
@@ -27,6 +27,5 @@ export { PopperManager } from './lib/popper';
27
27
  export { toolbar } from './toolbar';
28
28
  export * from './plugins/highlight';
29
29
  export { commentScroll, isThereSelector, isHighlightComment, } from './plugins/comment_annotation';
30
- export * from './plugins/keywords';
31
30
  export * from './lib/utils';
32
31
  export * from './useEditor';
@@ -13,13 +13,66 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { DeleteKeywordDialog, } from '../components/keywords/DeleteKeywordDialog';
17
+ import { getChangeClasses } from '../lib/track-changes-utils';
16
18
  import { BaseNodeView } from './base_node_view';
17
19
  import { createNodeView } from './creators';
20
+ import ReactSubView from './ReactSubView';
21
+ const deleteIcon = '<svg width="8px" height="8px" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg">\n' +
22
+ ' <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n' +
23
+ ' <g fill="#6E6E6E">\n' +
24
+ ' <rect id="Rectangle-23-Copy" transform="translate(13.000000, 13.000000) rotate(-45.000000) translate(-13.000000, -13.000000) " x="-3" y="11" width="32" height="4" rx="2"></rect>\n' +
25
+ ' <rect id="Rectangle-23-Copy-2" transform="translate(13.000000, 13.000000) scale(1, -1) rotate(-45.000000) translate(-13.000000, -13.000000) " x="-3" y="11" width="32" height="4" rx="2"></rect>\n' +
26
+ ' </g>\n' +
27
+ ' </g>\n' +
28
+ '</svg>';
18
29
  export class KeywordView extends BaseNodeView {
19
30
  constructor() {
20
31
  super(...arguments);
21
- this.stopEvent = () => true;
22
- this.ignoreMutation = () => true;
32
+ this.initialise = () => {
33
+ this.createDOM();
34
+ this.updateContents();
35
+ };
36
+ this.createDOM = () => {
37
+ this.dom = document.createElement('span');
38
+ this.contentDOM = document.createElement('span');
39
+ };
40
+ this.updateContents = () => {
41
+ const keyword = document.createElement('span');
42
+ const classes = ['keyword', ...getChangeClasses(this.node)];
43
+ keyword.classList.add(...classes);
44
+ keyword.appendChild(this.contentDOM);
45
+ const can = this.props.getCapabilities();
46
+ if (can.editArticle) {
47
+ const svg = new DOMParser()
48
+ .parseFromString(deleteIcon, 'image/svg+xml')
49
+ .querySelector('svg');
50
+ svg.classList.add('delete-keyword');
51
+ svg.addEventListener('click', this.showConfirmationDialog);
52
+ keyword.appendChild(svg);
53
+ }
54
+ this.dom.innerHTML = '';
55
+ this.dom.appendChild(keyword);
56
+ };
57
+ this.showConfirmationDialog = () => {
58
+ var _a;
59
+ (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.remove();
60
+ const keyword = this.node;
61
+ const pos = this.getPos();
62
+ const handleDelete = () => {
63
+ const tr = this.view.state.tr;
64
+ tr.delete(pos, pos + keyword.nodeSize);
65
+ this.view.dispatch(tr);
66
+ };
67
+ const componentProps = {
68
+ keyword: keyword.textContent,
69
+ handleDelete: handleDelete,
70
+ };
71
+ this.dialog = ReactSubView(this.props, DeleteKeywordDialog, componentProps, this.node, this.getPos, this.view, 'keywords-delete');
72
+ if (this.dialog) {
73
+ this.dom.appendChild(this.dialog);
74
+ }
75
+ };
23
76
  }
24
77
  }
25
78
  export default createNodeView(KeywordView);
@@ -14,33 +14,30 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { AddKeywordInline } from '../components/keywords/AddKeywordInline';
17
- import { DeleteKeyword } from '../components/keywords/DeleteKeyword';
18
17
  import BlockView from './block_view';
19
18
  import { createNodeView } from './creators';
20
19
  import ReactSubView from './ReactSubView';
21
- export class KeywordsElementView extends BlockView {
20
+ export class KeywordGroupView extends BlockView {
22
21
  constructor() {
23
22
  super(...arguments);
24
23
  this.ignoreMutation = () => true;
25
24
  this.stopEvent = () => true;
26
25
  this.createElement = () => {
27
26
  this.element = document.createElement('div');
28
- this.element.classList.add('block');
27
+ this.element.classList.add('block', 'keyword-group-container');
29
28
  this.dom.appendChild(this.element);
30
29
  this.contentDOM = document.createElement('div');
31
- this.contentDOM.classList.add('keywords-list');
30
+ this.contentDOM.classList.add('keyword-group');
32
31
  this.contentDOM.setAttribute('id', this.node.attrs.id);
33
32
  this.contentDOM.setAttribute('contenteditable', 'false');
34
33
  this.element.appendChild(this.contentDOM);
35
- this.addingTools = ReactSubView(this.props, AddKeywordInline, { getUpdatedNode: () => this.node }, this.node, this.getPos, this.view, 'keywords-editor');
36
- if (this.addingTools && this.props.getCapabilities().editArticle) {
37
- this.element.appendChild(this.addingTools);
34
+ if (this.props.getCapabilities().editArticle) {
35
+ this.addingTools = ReactSubView(this.props, AddKeywordInline, { getUpdatedNode: () => this.node }, this.node, this.getPos, this.view, 'keywords-editor');
38
36
  }
39
- this.deleteTools = ReactSubView(this.props, DeleteKeyword, { getUpdatedNode: () => this.node }, this.node, this.getPos, this.view, 'keywords-delete');
40
- if (this.deleteTools) {
41
- this.element.appendChild(this.deleteTools);
37
+ if (this.addingTools) {
38
+ this.element.appendChild(this.addingTools);
42
39
  }
43
40
  };
44
41
  }
45
42
  }
46
- export default createNodeView(KeywordsElementView);
43
+ export default createNodeView(KeywordGroupView);
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export interface DeleteKeywordDialogProps {
3
+ keyword: string;
4
+ handleDelete: () => void;
5
+ }
6
+ export declare const DeleteKeywordDialog: React.FC<DeleteKeywordDialogProps>;
@@ -18,7 +18,7 @@ import { Dispatch } from '../commands';
18
18
  import { CitationViewProps } from '../views/citation';
19
19
  import { EditableBlockProps } from '../views/editable_block';
20
20
  import { FigureProps } from '../views/figure_editable';
21
- import { KeywordsElementProps } from '../views/keywords_element';
21
+ import { KeywordsElementProps } from '../views/keyword_group';
22
22
  type EditorProps = EditableBlockProps & CitationViewProps & FigureProps & KeywordsElementProps & {
23
23
  theme: DefaultTheme;
24
24
  };
@@ -260,8 +260,8 @@ declare const _default: (props: EditorProps, dispatch: Dispatch) => {
260
260
  footnotes_element: import("../types").NodeViewCreator<import("../views/footnotes_element").FootnotesElementView<any>>;
261
261
  inline_equation: import("../types").NodeViewCreator<import("../views/inline_equation_editable").InlineEquationEditableView>;
262
262
  inline_footnote: import("../types").NodeViewCreator<import("../views/inline_footnote").InlineFootnoteView<any>>;
263
- keyword: import("../types").NodeViewCreator<import("../views/keyword").KeywordView<any>>;
264
- keywords_element: import("../types").NodeViewCreator<import("../views/keywords_element").KeywordsElementView>;
263
+ keyword: import("../types").NodeViewCreator<import("../views/keyword").KeywordView>;
264
+ keyword_group: import("../types").NodeViewCreator<import("../views/keyword_group").KeywordGroupView>;
265
265
  link: import("../types").NodeViewCreator<import("../views/link_editable").LinkEditableView>;
266
266
  listing: import("../types").NodeViewCreator<import("../views/listing_editable").ListingEditableView>;
267
267
  listing_element: import("../types").NodeViewCreator<{
@@ -28,6 +28,5 @@ export { PopperManager } from './lib/popper';
28
28
  export { toolbar } from './toolbar';
29
29
  export * from './plugins/highlight';
30
30
  export { commentScroll, isThereSelector, isHighlightComment, } from './plugins/comment_annotation';
31
- export * from './plugins/keywords';
32
31
  export * from './lib/utils';
33
32
  export * from './useEditor';
@@ -13,15 +13,15 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Capabilities } from '@manuscripts/style-guide';
17
16
  import { ManuscriptNodeView } from '@manuscripts/transform';
18
- import { BaseNodeProps, BaseNodeView } from './base_node_view';
19
- export interface Props extends BaseNodeProps {
20
- getCapabilities: () => Capabilities;
17
+ import { BaseNodeView } from './base_node_view';
18
+ import { EditableBlockProps } from './editable_block';
19
+ export declare class KeywordView extends BaseNodeView<EditableBlockProps> implements ManuscriptNodeView {
20
+ private dialog;
21
+ initialise: () => void;
22
+ createDOM: () => void;
23
+ updateContents: () => void;
24
+ private showConfirmationDialog;
21
25
  }
22
- export declare class KeywordView<PropsType extends Props> extends BaseNodeView<PropsType> implements ManuscriptNodeView {
23
- stopEvent: () => boolean;
24
- ignoreMutation: () => boolean;
25
- }
26
- declare const _default: (props: BaseNodeProps, dispatch?: import("..").Dispatch | undefined) => import("../types").NodeViewCreator<KeywordView<any>>;
26
+ declare const _default: (props: import("./base_node_view").BaseNodeProps, dispatch?: import("..").Dispatch | undefined) => import("../types").NodeViewCreator<KeywordView>;
27
27
  export default _default;
@@ -27,13 +27,12 @@ export interface KeywordsElementProps {
27
27
  retrySync: (componentIDs: string[]) => Promise<void>;
28
28
  saveModel: <T extends Model>(model: T | Build<T> | Partial<T>) => Promise<T>;
29
29
  }
30
- export declare class KeywordsElementView extends BlockView<BaseNodeProps & KeywordsElementProps> {
30
+ export declare class KeywordGroupView extends BlockView<BaseNodeProps & KeywordsElementProps> {
31
31
  private element;
32
- addingTools: HTMLDivElement;
33
- deleteTools: HTMLDivElement;
32
+ private addingTools;
34
33
  ignoreMutation: () => boolean;
35
34
  stopEvent: () => boolean;
36
35
  createElement: () => void;
37
36
  }
38
- declare const _default: (props: BaseNodeProps, dispatch?: Dispatch | undefined) => import("../types").NodeViewCreator<KeywordsElementView>;
37
+ declare const _default: (props: BaseNodeProps, dispatch?: Dispatch | undefined) => import("../types").NodeViewCreator<KeywordGroupView>;
39
38
  export default _default;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@manuscripts/body-editor",
3
3
  "description": "Prosemirror components for editing and viewing manuscripts",
4
- "version": "1.6.9",
4
+ "version": "1.6.10",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -545,10 +545,6 @@ Next levels are shifted 'up' by 1
545
545
  border-radius: 0 0 32px 32px;
546
546
  }
547
547
 
548
- .keywords {
549
- margin: 0 0 36px;
550
- }
551
-
552
548
  .ProseMirror > .keywords > .block-section_title > h1 {
553
549
  color: #353535 !important;
554
550
  font-size: 12px !important;
@@ -558,76 +554,76 @@ Next levels are shifted 'up' by 1
558
554
  margin-top: 4px !important;
559
555
  }
560
556
 
561
- .keywords-list {
562
- margin: 0;
563
- display: inline;
564
- }
565
-
566
- .keywords-list span.keyword {
557
+ .keywords .keyword {
567
558
  display: inline-block;
568
559
  color: #353535;
569
560
  background-color: #f2f2f2;
570
- font-family: Lato, sans-serif;
561
+ font-family: Lato,sans-serif;
571
562
  font-size: 14px;
572
563
  line-height: 16px;
573
564
  margin-right: 4px;
574
565
  margin-bottom: 4px;
575
- border: 1px solid #f2f2f2;
566
+ border: 1px solid transparent;
576
567
  border-radius: 6px;
577
568
  position: relative;
578
569
  cursor: default;
570
+ padding: 4px 8px
579
571
  }
580
572
 
581
- .keywords-list span.keyword.no-tracking {
582
- padding: 4px 8px;
583
- }
584
-
585
- .keywords-list span.keyword ins,
586
- .keywords-list span.keyword del {
587
- display: inline-block;
588
- padding: 4px 8px;
589
- border-radius: 6px;
573
+ .keywords .keyword ins, .keywords .keyword del {
574
+ background-color: inherit !important
590
575
  }
591
576
 
592
- .keywords-list span.keyword:hover,
593
- .keywords-list span.keyword:hover ins,
594
- .keywords-list span.keyword:hover del {
595
- background-color: #f2fbfc;
596
- border-color: #f2fbfc;
577
+ .keywords .keyword:hover {
578
+ background-color:#f2fbfc !important;
597
579
  }
598
580
 
599
- .keywords-list span.keyword.selected {
581
+ .keywords .keyword.selected {
600
582
  background-color: #f2fbfc;
601
583
  border-color: #bce7f6;
602
584
  }
603
585
 
604
- .keywords-list .keyword.deleted.pending,
605
- .keywords-list .keyword.deleted.accepted {
586
+ .keywords .keyword.deleted.pending,.keywords .keyword.deleted.accepted {
606
587
  text-decoration: line-through;
607
588
  }
608
- .keywords-list .keyword .track-changes--control {
589
+
590
+ .keywords .keyword .track-changes--control {
609
591
  top: 0;
610
592
  }
611
593
 
612
- .keywords-list span.delete-keyword {
594
+ .keywords .delete-keyword {
613
595
  cursor: pointer;
614
596
  margin: 0 0 0 8px;
615
597
  opacity: 0.5;
616
598
  }
617
599
 
618
- .keywords-list span.delete-keyword:hover {
600
+ .keywords .delete-keyword:hover {
619
601
  opacity: 1;
620
602
  }
621
603
 
622
- .keywords-list .deleted.accepted span.delete-keyword {
604
+ .keywords .deleted .delete-keyword {
605
+ display: none;
606
+ }
607
+
608
+ .keywords .deleted.rejected .delete-keyword {
609
+ display: inline;
610
+ }
611
+
612
+ .keywords .inserted.pending .delete-keyword {
623
613
  display: none;
624
614
  }
625
615
 
626
- .keywords-list > div {
616
+ .keywords .keyword-group-container {
617
+ position: relative;
618
+ margin: 0 0 36px !important;
619
+
620
+ }
621
+
622
+ .keywords .keyword-group {
627
623
  display: inline;
628
624
  }
629
625
 
630
- .keywords-editor {
626
+ .keywords .keywords-editor {
631
627
  position: static;
632
628
  display: inline-block;
633
629
  width: auto;
@@ -643,6 +639,15 @@ Next levels are shifted 'up' by 1
643
639
  align-items: center;
644
640
  }
645
641
 
642
+ .keywords .block-comment-button {
643
+ position: absolute;
644
+ right: 0;
645
+ top: 0;
646
+ }
647
+
648
+ .keywords .block-comment-button .comment-icon {
649
+ top: 8px;
650
+ }
646
651
 
647
652
  .attrs-popper-button-active,
648
653
  .attrs-track-mark:hover .attrs-popper-button {
@@ -1,92 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.DeleteKeyword = void 0;
27
- const style_guide_1 = require("@manuscripts/style-guide");
28
- const react_1 = __importStar(require("react"));
29
- const DeleteKeyword = ({ viewProps }) => {
30
- const [isDeletingKeyword, setIsDeletingKeyword] = (0, react_1.useState)(false);
31
- const [keywordToDelete, setKeywordToDelete] = (0, react_1.useState)('');
32
- const [keywordToDeleteId, setKeywordToDeleteId] = (0, react_1.useState)('');
33
- const { getPos, view, node } = viewProps;
34
- const getKeywords = () => {
35
- let position = 0, elementSize = 0;
36
- node.descendants((node, pos) => {
37
- if (node.attrs.id === keywordToDeleteId) {
38
- position = pos + getPos();
39
- elementSize = node.nodeSize;
40
- return false;
41
- }
42
- });
43
- return { pos: position, to: position + elementSize + 1 };
44
- };
45
- const handleClick = (event) => {
46
- var _a, _b;
47
- const clickTarget = event.target;
48
- const deleteIcon = clickTarget.closest('.delete-keyword');
49
- if (deleteIcon) {
50
- const keywordId = ((_a = deleteIcon.closest('.keyword')) === null || _a === void 0 ? void 0 : _a.getAttribute('id')) || '';
51
- const keywordContent = ((_b = deleteIcon.closest('.keyword')) === null || _b === void 0 ? void 0 : _b.textContent) || '';
52
- setKeywordToDeleteId(keywordId);
53
- setKeywordToDelete(keywordContent);
54
- setIsDeletingKeyword(true);
55
- }
56
- };
57
- const handleCancel = () => {
58
- resetState();
59
- };
60
- const handleDelete = () => {
61
- if (keywordToDeleteId) {
62
- const { pos, to } = getKeywords();
63
- if (view.dispatch) {
64
- view.dispatch(view.state.tr.delete(pos, to).setMeta('keywordsUpdated', true));
65
- }
66
- resetState();
67
- }
68
- };
69
- const resetState = () => {
70
- setIsDeletingKeyword(false);
71
- setKeywordToDeleteId('');
72
- };
73
- (0, react_1.useEffect)(() => {
74
- document.addEventListener('mousedown', handleClick);
75
- return () => {
76
- document.removeEventListener('mousedown', handleClick);
77
- };
78
- }, []);
79
- const actions = {
80
- primary: {
81
- action: handleCancel,
82
- title: 'Cancel',
83
- },
84
- secondary: {
85
- action: handleDelete,
86
- title: 'Delete',
87
- },
88
- };
89
- return (react_1.default.createElement(style_guide_1.Dialog, { isOpen: isDeletingKeyword, actions: actions, category: style_guide_1.Category.confirmation, header: 'Delete Keyword', message: `Are you sure you want to delete "${keywordToDelete}" keyword?
90
- ` }));
91
- };
92
- exports.DeleteKeyword = DeleteKeyword;
@@ -1,121 +0,0 @@
1
- "use strict";
2
- /*!
3
- * © 2019 Atypon Systems LLC
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
- var __importDefault = (this && this.__importDefault) || function (mod) {
18
- return (mod && mod.__esModule) ? mod : { "default": mod };
19
- };
20
- Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.keywordsKey = void 0;
22
- const CloseIconDark_1 = __importDefault(require("@manuscripts/assets/react/CloseIconDark"));
23
- const json_schema_1 = require("@manuscripts/json-schema");
24
- const transform_1 = require("@manuscripts/transform");
25
- const prosemirror_state_1 = require("prosemirror-state");
26
- const prosemirror_view_1 = require("prosemirror-view");
27
- const react_1 = require("react");
28
- const react_dom_1 = __importDefault(require("react-dom"));
29
- const track_changes_utils_1 = require("../lib/track-changes-utils");
30
- exports.keywordsKey = new prosemirror_state_1.PluginKey('keywords');
31
- const isKeywordNode = (node) => node.type === node.type.schema.nodes.keyword;
32
- const buildKeywordNodes = (doc) => {
33
- const keywordNodes = [];
34
- doc.descendants((node, pos) => {
35
- if (isKeywordNode(node)) {
36
- keywordNodes.push([node, pos]);
37
- }
38
- });
39
- return keywordNodes;
40
- };
41
- const keywordsUpdated = (transactions) => transactions.some((tr) => {
42
- const metaDeleted = tr.getMeta('keywordsUpdated');
43
- return metaDeleted;
44
- });
45
- const buildDecorations = (keywordNodes, getCapabilities) => {
46
- const decorations = [];
47
- for (const [node, pos] of keywordNodes) {
48
- const nodeClasses = [...(0, track_changes_utils_1.getChangeClasses)(node)];
49
- if (!(0, track_changes_utils_1.isTracked)(node)) {
50
- nodeClasses.push('no-tracking');
51
- }
52
- const classesDecoration = prosemirror_view_1.Decoration.node(pos, pos + node.nodeSize, {
53
- class: nodeClasses.join(' '),
54
- });
55
- decorations.push(classesDecoration);
56
- if (!(0, track_changes_utils_1.isPending)(node) && !(0, track_changes_utils_1.isDeleted)(node) && getCapabilities().editArticle) {
57
- const removeIconDecoration = prosemirror_view_1.Decoration.widget(pos + node.nodeSize - 1, () => {
58
- const closeIconWrapper = document.createElement('span');
59
- closeIconWrapper.classList.add('delete-keyword');
60
- react_dom_1.default.render((0, react_1.createElement)(CloseIconDark_1.default, {
61
- height: 8,
62
- width: 8,
63
- color: '#353535',
64
- }), closeIconWrapper);
65
- return closeIconWrapper;
66
- }, { side: -1 });
67
- decorations.push(removeIconDecoration);
68
- }
69
- }
70
- return decorations;
71
- };
72
- exports.default = (props) => {
73
- return new prosemirror_state_1.Plugin({
74
- key: exports.keywordsKey,
75
- state: {
76
- init(config, instance) {
77
- const keywordNodes = buildKeywordNodes(instance.doc);
78
- return {
79
- keywordNodes,
80
- };
81
- },
82
- apply(tr, value, oldState, newState) {
83
- const keywordNodes = buildKeywordNodes(newState.doc);
84
- return {
85
- keywordNodes,
86
- };
87
- },
88
- },
89
- appendTransaction(transactions, oldState, newState) {
90
- if (!keywordsUpdated(transactions)) {
91
- return;
92
- }
93
- const keywordsElements = [];
94
- const { tr } = newState;
95
- tr.doc.descendants((node, pos) => {
96
- if (node.type === node.type.schema.nodes.keywords_element) {
97
- keywordsElements.push({
98
- node,
99
- pos,
100
- });
101
- }
102
- });
103
- if (keywordsElements.length) {
104
- for (const { node, pos } of keywordsElements) {
105
- tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { id: node.attrs.id || (0, transform_1.generateID)(json_schema_1.ObjectTypes.KeywordsElement) }));
106
- }
107
- if (tr.selection instanceof prosemirror_state_1.NodeSelection) {
108
- tr.setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, tr.selection.from));
109
- }
110
- tr.setMeta('origin', exports.keywordsKey);
111
- return tr;
112
- }
113
- },
114
- props: {
115
- decorations(state) {
116
- const { keywordNodes } = exports.keywordsKey.getState(state);
117
- return prosemirror_view_1.DecorationSet.create(state.doc, buildDecorations(keywordNodes, props.getCapabilities));
118
- },
119
- },
120
- });
121
- };
@@ -1,65 +0,0 @@
1
- import { Category, Dialog } from '@manuscripts/style-guide';
2
- import React, { useEffect, useState } from 'react';
3
- export const DeleteKeyword = ({ viewProps }) => {
4
- const [isDeletingKeyword, setIsDeletingKeyword] = useState(false);
5
- const [keywordToDelete, setKeywordToDelete] = useState('');
6
- const [keywordToDeleteId, setKeywordToDeleteId] = useState('');
7
- const { getPos, view, node } = viewProps;
8
- const getKeywords = () => {
9
- let position = 0, elementSize = 0;
10
- node.descendants((node, pos) => {
11
- if (node.attrs.id === keywordToDeleteId) {
12
- position = pos + getPos();
13
- elementSize = node.nodeSize;
14
- return false;
15
- }
16
- });
17
- return { pos: position, to: position + elementSize + 1 };
18
- };
19
- const handleClick = (event) => {
20
- var _a, _b;
21
- const clickTarget = event.target;
22
- const deleteIcon = clickTarget.closest('.delete-keyword');
23
- if (deleteIcon) {
24
- const keywordId = ((_a = deleteIcon.closest('.keyword')) === null || _a === void 0 ? void 0 : _a.getAttribute('id')) || '';
25
- const keywordContent = ((_b = deleteIcon.closest('.keyword')) === null || _b === void 0 ? void 0 : _b.textContent) || '';
26
- setKeywordToDeleteId(keywordId);
27
- setKeywordToDelete(keywordContent);
28
- setIsDeletingKeyword(true);
29
- }
30
- };
31
- const handleCancel = () => {
32
- resetState();
33
- };
34
- const handleDelete = () => {
35
- if (keywordToDeleteId) {
36
- const { pos, to } = getKeywords();
37
- if (view.dispatch) {
38
- view.dispatch(view.state.tr.delete(pos, to).setMeta('keywordsUpdated', true));
39
- }
40
- resetState();
41
- }
42
- };
43
- const resetState = () => {
44
- setIsDeletingKeyword(false);
45
- setKeywordToDeleteId('');
46
- };
47
- useEffect(() => {
48
- document.addEventListener('mousedown', handleClick);
49
- return () => {
50
- document.removeEventListener('mousedown', handleClick);
51
- };
52
- }, []);
53
- const actions = {
54
- primary: {
55
- action: handleCancel,
56
- title: 'Cancel',
57
- },
58
- secondary: {
59
- action: handleDelete,
60
- title: 'Delete',
61
- },
62
- };
63
- return (React.createElement(Dialog, { isOpen: isDeletingKeyword, actions: actions, category: Category.confirmation, header: 'Delete Keyword', message: `Are you sure you want to delete "${keywordToDelete}" keyword?
64
- ` }));
65
- };
@@ -1,115 +0,0 @@
1
- /*!
2
- * © 2019 Atypon Systems LLC
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import CloseIconDark from '@manuscripts/assets/react/CloseIconDark';
17
- import { ObjectTypes } from '@manuscripts/json-schema';
18
- import { generateID } from '@manuscripts/transform';
19
- import { NodeSelection, Plugin, PluginKey, } from 'prosemirror-state';
20
- import { Decoration, DecorationSet } from 'prosemirror-view';
21
- import { createElement } from 'react';
22
- import ReactDOM from 'react-dom';
23
- import { getChangeClasses, isDeleted, isPending, isTracked, } from '../lib/track-changes-utils';
24
- export const keywordsKey = new PluginKey('keywords');
25
- const isKeywordNode = (node) => node.type === node.type.schema.nodes.keyword;
26
- const buildKeywordNodes = (doc) => {
27
- const keywordNodes = [];
28
- doc.descendants((node, pos) => {
29
- if (isKeywordNode(node)) {
30
- keywordNodes.push([node, pos]);
31
- }
32
- });
33
- return keywordNodes;
34
- };
35
- const keywordsUpdated = (transactions) => transactions.some((tr) => {
36
- const metaDeleted = tr.getMeta('keywordsUpdated');
37
- return metaDeleted;
38
- });
39
- const buildDecorations = (keywordNodes, getCapabilities) => {
40
- const decorations = [];
41
- for (const [node, pos] of keywordNodes) {
42
- const nodeClasses = [...getChangeClasses(node)];
43
- if (!isTracked(node)) {
44
- nodeClasses.push('no-tracking');
45
- }
46
- const classesDecoration = Decoration.node(pos, pos + node.nodeSize, {
47
- class: nodeClasses.join(' '),
48
- });
49
- decorations.push(classesDecoration);
50
- if (!isPending(node) && !isDeleted(node) && getCapabilities().editArticle) {
51
- const removeIconDecoration = Decoration.widget(pos + node.nodeSize - 1, () => {
52
- const closeIconWrapper = document.createElement('span');
53
- closeIconWrapper.classList.add('delete-keyword');
54
- ReactDOM.render(createElement(CloseIconDark, {
55
- height: 8,
56
- width: 8,
57
- color: '#353535',
58
- }), closeIconWrapper);
59
- return closeIconWrapper;
60
- }, { side: -1 });
61
- decorations.push(removeIconDecoration);
62
- }
63
- }
64
- return decorations;
65
- };
66
- export default (props) => {
67
- return new Plugin({
68
- key: keywordsKey,
69
- state: {
70
- init(config, instance) {
71
- const keywordNodes = buildKeywordNodes(instance.doc);
72
- return {
73
- keywordNodes,
74
- };
75
- },
76
- apply(tr, value, oldState, newState) {
77
- const keywordNodes = buildKeywordNodes(newState.doc);
78
- return {
79
- keywordNodes,
80
- };
81
- },
82
- },
83
- appendTransaction(transactions, oldState, newState) {
84
- if (!keywordsUpdated(transactions)) {
85
- return;
86
- }
87
- const keywordsElements = [];
88
- const { tr } = newState;
89
- tr.doc.descendants((node, pos) => {
90
- if (node.type === node.type.schema.nodes.keywords_element) {
91
- keywordsElements.push({
92
- node,
93
- pos,
94
- });
95
- }
96
- });
97
- if (keywordsElements.length) {
98
- for (const { node, pos } of keywordsElements) {
99
- tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { id: node.attrs.id || generateID(ObjectTypes.KeywordsElement) }));
100
- }
101
- if (tr.selection instanceof NodeSelection) {
102
- tr.setSelection(NodeSelection.create(tr.doc, tr.selection.from));
103
- }
104
- tr.setMeta('origin', keywordsKey);
105
- return tr;
106
- }
107
- },
108
- props: {
109
- decorations(state) {
110
- const { keywordNodes } = keywordsKey.getState(state);
111
- return DecorationSet.create(state.doc, buildDecorations(keywordNodes, props.getCapabilities));
112
- },
113
- },
114
- });
115
- };
@@ -1,10 +0,0 @@
1
- import { ManuscriptEditorView, ManuscriptNode } from '@manuscripts/transform';
2
- import React from 'react';
3
- export declare const DeleteKeyword: React.FC<{
4
- viewProps: {
5
- view: ManuscriptEditorView;
6
- getPos: () => number;
7
- node: ManuscriptNode;
8
- };
9
- getUpdatedNode: () => ManuscriptNode;
10
- }>;
@@ -1,28 +0,0 @@
1
- /*!
2
- * © 2019 Atypon Systems LLC
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { Capabilities } from '@manuscripts/style-guide';
17
- import type { KeywordNode } from '@manuscripts/transform';
18
- import { Plugin, PluginKey } from 'prosemirror-state';
19
- export declare const keywordsKey: PluginKey<any>;
20
- interface PluginState {
21
- keywordNodes: KeywordNodes;
22
- }
23
- interface KeywordsProps {
24
- getCapabilities: () => Capabilities;
25
- }
26
- type KeywordNodes = Array<[KeywordNode, number]>;
27
- declare const _default: (props: KeywordsProps) => Plugin<PluginState>;
28
- export default _default;