@manuscripts/body-editor 3.7.29 → 3.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/cjs/components/affiliations/AffiliationItem.js +2 -3
  2. package/dist/cjs/components/authors/DraggableAuthor.js +2 -3
  3. package/dist/cjs/components/references/ImportBibliographyModal.js +6 -20
  4. package/dist/cjs/components/references/ReferenceForm/ReferenceForm.js +2 -3
  5. package/dist/cjs/components/references/ReferencesModal.js +2 -3
  6. package/dist/cjs/configs/editor-plugins.js +1 -1
  7. package/dist/cjs/lib/popper.js +2 -1
  8. package/dist/cjs/menus.js +1 -2
  9. package/dist/cjs/plugins/{section-category/section-category-utils.js → section_category.js} +49 -47
  10. package/dist/cjs/versions.js +1 -1
  11. package/dist/es/components/affiliations/AffiliationItem.js +3 -4
  12. package/dist/es/components/authors/DraggableAuthor.js +3 -4
  13. package/dist/es/components/references/ImportBibliographyModal.js +6 -20
  14. package/dist/es/components/references/ReferenceForm/ReferenceForm.js +3 -4
  15. package/dist/es/components/references/ReferencesModal.js +3 -4
  16. package/dist/es/configs/editor-plugins.js +1 -1
  17. package/dist/es/lib/popper.js +2 -1
  18. package/dist/es/menus.js +1 -2
  19. package/dist/es/plugins/{section-category/section-category-utils.js → section_category.js} +48 -46
  20. package/dist/es/versions.js +1 -1
  21. package/dist/types/plugins/{section-category/index.d.ts → section_category.d.ts} +1 -1
  22. package/dist/types/versions.d.ts +1 -1
  23. package/package.json +2 -2
  24. package/dist/cjs/plugins/section-category/index.js +0 -17
  25. package/dist/es/plugins/section-category/index.js +0 -14
  26. package/dist/types/plugins/section-category/section-category-utils.d.ts +0 -4
@@ -114,8 +114,7 @@ const AffiliationItem = ({ affiliation, isSelected, onClick, onDelete, showSucce
114
114
  affiliation.country ? ', ' : '')),
115
115
  affiliation.country && react_1.default.createElement(react_1.default.Fragment, null, affiliation.country))),
116
116
  showSuccessIcon && (react_1.default.createElement(style_guide_1.CrclTickAnimation, { size: 36, style: { position: 'absolute', left: '10px' } })),
117
- isSelected && (react_1.default.createElement(RemoveButton, { onClick: () => onDelete(), "data-tooltip-id": 'delete-button-tooltip' },
118
- react_1.default.createElement(style_guide_1.DeleteIcon, { fill: '#6E6E6E' }),
119
- react_1.default.createElement(style_guide_1.Tooltip, { id: 'delete-button-tooltip', place: "bottom" }, 'Delete')))));
117
+ isSelected && (react_1.default.createElement(RemoveButton, { onClick: () => onDelete(), "data-tooltip-content": "Delete" },
118
+ react_1.default.createElement(style_guide_1.DeleteIcon, { fill: '#6E6E6E' })))));
120
119
  };
121
120
  exports.AffiliationItem = AffiliationItem;
@@ -201,7 +201,6 @@ exports.DraggableAuthor = react_1.default.memo(({ author, isSelected, onClick, o
201
201
  react_1.default.createElement(AuthorNotes, { "data-cy": "author-notes" }, author.isCorresponding && (react_1.default.createElement(AuthorBadge, null,
202
202
  react_1.default.createElement(style_guide_1.CorrespondingAuthorIcon, null))))),
203
203
  react_1.default.createElement(AuthorName, { "data-cy": "author-name" }, (0, authors_1.authorLabel)(author)),
204
- isSelected && (react_1.default.createElement(RemoveButton, { onClick: () => onDelete(), "data-tooltip-id": 'delete-button-tooltip' },
205
- react_1.default.createElement(style_guide_1.DeleteIcon, { fill: '#6E6E6E' }),
206
- react_1.default.createElement(style_guide_1.Tooltip, { id: 'delete-button-tooltip', place: "bottom" }, 'Delete')))));
204
+ isSelected && (react_1.default.createElement(RemoveButton, { onClick: () => onDelete(), "data-tooltip-content": "Delete" },
205
+ react_1.default.createElement(style_guide_1.DeleteIcon, { fill: '#6E6E6E' })))));
207
206
  });
@@ -97,38 +97,24 @@ const ImportBibliographyModal = ({ onCancel, onSave }) => {
97
97
  react_1.default.createElement(ModalBody, null,
98
98
  react_1.default.createElement(ModalTitle, null, "Import Bibliography"),
99
99
  react_1.default.createElement("p", null,
100
- react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "example_bibtex" }, "BibTex"),
100
+ react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "import-example-tooltip", "data-tooltip-content": exampleBibtex, "data-tool": true }, "BibTex"),
101
101
  ",",
102
102
  ' ',
103
- react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "example_pubmed" }, "PubMed"),
103
+ react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "import-example-tooltip", "data-tooltip-content": examplePubmed }, "PubMed"),
104
104
  ",",
105
105
  ' ',
106
- react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "example_ris" }, "RIS"),
106
+ react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "import-example-tooltip", "data-tooltip-content": exampleRis }, "RIS"),
107
107
  ",",
108
108
  ' ',
109
- react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "example_enw" }, "ENW"),
109
+ react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "import-example-tooltip", "data-tooltip-content": exampleEnw }, "ENW"),
110
110
  ' ',
111
111
  "and",
112
112
  ' ',
113
- react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "example_doi" }, "DOI"),
113
+ react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "import-example-tooltip", "data-tooltip-content": exampleDoi }, "DOI"),
114
114
  ' ',
115
115
  "formats are supported"),
116
116
  react_1.default.createElement(ImportBibliographyForm_1.ImportBibliographyForm, { onCancel: handleCancel, onSave: handleSave }),
117
- react_1.default.createElement(Example, { id: "example_bibtex", place: "bottom" },
118
- react_1.default.createElement("div", null,
119
- react_1.default.createElement("pre", null, exampleBibtex))),
120
- react_1.default.createElement(Example, { id: "example_pubmed", place: "bottom" },
121
- react_1.default.createElement("div", null,
122
- react_1.default.createElement("pre", null, examplePubmed))),
123
- react_1.default.createElement(Example, { id: "example_ris", place: "bottom" },
124
- react_1.default.createElement("div", null,
125
- react_1.default.createElement("pre", null, exampleRis))),
126
- react_1.default.createElement(Example, { id: "example_enw", place: "bottom" },
127
- react_1.default.createElement("div", null,
128
- react_1.default.createElement("pre", null, exampleEnw))),
129
- react_1.default.createElement(Example, { id: "example_doi", place: "bottom" },
130
- react_1.default.createElement("div", null,
131
- react_1.default.createElement("pre", null, exampleDoi)))))));
117
+ react_1.default.createElement(Example, { id: "import-example-tooltip", place: "bottom", render: (s) => (react_1.default.createElement("pre", null, s.content)) })))));
132
118
  };
133
119
  exports.ImportBibliographyModal = ImportBibliographyModal;
134
120
  const ModalBody = styled_components_1.default.div `
@@ -112,9 +112,8 @@ const ReferenceForm = ({ values, showDelete, onChange, onDelete, onCancel, onSav
112
112
  react_1.default.createElement(style_guide_1.ButtonGroup, null,
113
113
  react_1.default.createElement(style_guide_1.IconButton, { as: "a", href: `https://doi.org/${formik.values.DOI}`, target: '_blank' },
114
114
  react_1.default.createElement(style_guide_1.LinkIcon, null)),
115
- react_1.default.createElement(styled_components_1.DeleteButton, { defaultColor: true, disabled: !showDelete, "data-tooltip-id": showDelete ? '' : 'delete-button-tooltip', onClick: () => setShowDeleteDialog(true) },
116
- react_1.default.createElement(style_guide_1.DeleteIcon, null)),
117
- react_1.default.createElement(style_guide_1.Tooltip, { id: "delete-button-tooltip", place: "bottom" }, "Unable to delete because the item is used in the document")),
115
+ react_1.default.createElement(styled_components_1.DeleteButton, { defaultColor: true, disabled: !showDelete, "data-tooltip-content": "Unable to delete because the item is used in the document", "data-tooltip-hidden": showDelete, onClick: () => setShowDeleteDialog(true) },
116
+ react_1.default.createElement(style_guide_1.DeleteIcon, null))),
118
117
  react_1.default.createElement(style_guide_1.ButtonGroup, null,
119
118
  react_1.default.createElement(style_guide_1.SecondaryButton, { onClick: onCancel }, "Cancel"),
120
119
  react_1.default.createElement(style_guide_1.PrimaryButton, { type: "submit", disabled: !formik.isValid || !formik.dirty }, "Save"))),
@@ -247,9 +247,8 @@ const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts, onSave
247
247
  react_1.default.createElement(ReferencesInnerWrapper, null, items.slice(startIndex, endIndex + 1).map((item) => (react_1.default.createElement(ReferenceButton, { key: item.id, id: item.id, className: isSelected(item) ? 'selected' : '', onClick: () => handleItemClick(item), ref: isSelected(item) ? selectionRef : null },
248
248
  react_1.default.createElement(IconContainer, null,
249
249
  react_1.default.createElement(style_guide_1.CitationCountIcon, null),
250
- (citationCounts.get(item.id) || 0) > 0 ? (react_1.default.createElement(CitationCount, { "data-tooltip-id": "citation-count-tooltip" }, citationCounts.get(item.id))) : (react_1.default.createElement(CitationCount, { className: "unused" }, "0"))),
251
- react_1.default.createElement(ReferenceLine_1.ReferenceLine, { item: item }))))),
252
- react_1.default.createElement(style_guide_1.Tooltip, { id: "citation-count-tooltip", place: "bottom" }, "Number of times used in the document"))),
250
+ (citationCounts.get(item.id) || 0) > 0 ? (react_1.default.createElement(CitationCount, { "data-tooltip-content": "Number of times used in the document" }, citationCounts.get(item.id))) : (react_1.default.createElement(CitationCount, { className: "unused" }, "0"))),
251
+ react_1.default.createElement(ReferenceLine_1.ReferenceLine, { item: item }))))))),
253
252
  react_1.default.createElement(style_guide_1.ScrollableModalContent, null, selection && (react_1.default.createElement(ReferenceForm_1.ReferenceForm, { values: normalize(selection), showDelete: !citationCounts.get(selection.id) &&
254
253
  isNewItem(selection, ['id', 'type']), onChange: handleChange, onCancel: onCancel, onDelete: handleDelete, onSave: handleSave, actionsRef: actionsRef })))))));
255
254
  };
@@ -48,7 +48,7 @@ const placeholder_1 = __importDefault(require("../plugins/placeholder"));
48
48
  const prevent_empty_1 = __importDefault(require("../plugins/prevent-empty"));
49
49
  const search_replace_1 = __importDefault(require("../plugins/search-replace"));
50
50
  const section_title_1 = __importDefault(require("../plugins/section_title"));
51
- const section_category_1 = __importDefault(require("../plugins/section-category"));
51
+ const section_category_1 = __importDefault(require("../plugins/section_category"));
52
52
  const selected_suggestion_1 = __importDefault(require("../plugins/selected-suggestion"));
53
53
  const tables_cursor_fix_1 = __importDefault(require("../plugins/tables-cursor-fix"));
54
54
  const rules_1 = __importDefault(require("../rules"));
@@ -64,7 +64,8 @@ class PopperManager {
64
64
  this.destroy();
65
65
  }
66
66
  };
67
- if (contents.classList.contains('context-menu')) {
67
+ if (contents.classList.contains('context-menu') ||
68
+ contents.classList.contains('section-category')) {
68
69
  window.addEventListener('click', this.handleDocumentClick);
69
70
  }
70
71
  });
package/dist/cjs/menus.js CHANGED
@@ -200,8 +200,7 @@ const getEditorMenus = (editor) => {
200
200
  label: 'Author Notes',
201
201
  isEnabled: true,
202
202
  submenu: categories.map(insertBackmatterSectionMenu),
203
- isHidden: !(0, template_1.templateAllows)(state, transform_1.schema.nodes.author_notes) ||
204
- !categories.length,
203
+ isHidden: !categories.length,
205
204
  },
206
205
  {
207
206
  id: 'insert-section',
@@ -1,49 +1,64 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildPluginState = buildPluginState;
3
+ exports.sectionCategoryKey = void 0;
4
4
  const transform_1 = require("@manuscripts/transform");
5
+ const prosemirror_state_1 = require("prosemirror-state");
5
6
  const prosemirror_utils_1 = require("prosemirror-utils");
6
7
  const prosemirror_view_1 = require("prosemirror-view");
7
- const icons_1 = require("../../icons");
8
- const popper_1 = require("../../lib/popper");
9
- const popper = new popper_1.PopperManager();
10
- function createMenuItem(contents, handler, isDisabled = false, isSelected = false) {
8
+ const icons_1 = require("../icons");
9
+ exports.sectionCategoryKey = new prosemirror_state_1.PluginKey('section-category');
10
+ exports.default = (props) => new prosemirror_state_1.Plugin({
11
+ key: exports.sectionCategoryKey,
12
+ state: {
13
+ init: (_, state) => buildPluginState(state, props),
14
+ apply: (tr, value, oldState, newState) => {
15
+ if (!tr.docChanged) {
16
+ return value;
17
+ }
18
+ return buildPluginState(newState, props);
19
+ }
20
+ },
21
+ props: {
22
+ decorations: (state) => exports.sectionCategoryKey.getState(state)?.decorations || prosemirror_view_1.DecorationSet.empty,
23
+ },
24
+ });
25
+ const createMenuItem = (props, contents, handler, isDisabled, isSelected) => {
11
26
  const item = document.createElement('div');
12
- item.className = `menu-item ${isDisabled ? 'disabled' : ''} ${isSelected ? 'selected' : ''}`;
27
+ item.classList.add('menu-item');
28
+ if (isSelected) {
29
+ item.classList.add('selected');
30
+ }
31
+ if (isDisabled) {
32
+ item.classList.add('disabled');
33
+ }
13
34
  item.textContent = contents;
14
35
  item.addEventListener('mousedown', (event) => {
15
36
  handler(event);
16
- popper.destroy();
37
+ props.popper.destroy();
17
38
  });
18
39
  return item;
19
- }
20
- function createMenu(currentCategory, categories, usedCategoryIDs, onSelect) {
40
+ };
41
+ const createMenu = (props, currentCategory, categories, usedCategoryIDs, onSelect) => {
21
42
  const menu = document.createElement('div');
22
43
  menu.className = 'section-category menu';
23
44
  categories.forEach((category) => {
24
- const item = createMenuItem(category.titles[0], () => onSelect(category), category.isUnique && usedCategoryIDs.has(category.id), currentCategory === category);
45
+ const item = createMenuItem(props, category.titles[0], () => onSelect(category), category.isUnique && usedCategoryIDs.has(category.id), currentCategory === category);
25
46
  menu.appendChild(item);
26
47
  });
27
- document.addEventListener('mousedown', (event) => {
28
- if (!menu.contains(event.target)) {
29
- popper.destroy();
30
- }
31
- });
32
48
  return menu;
33
- }
34
- function createButton(view, pos, currentCategory, categories, usedCategoryIDs, canEdit = true, disabled) {
49
+ };
50
+ const createButton = (props, view, pos, currentCategory, categories, usedCategoryIDs, canEdit = true, disabled) => {
35
51
  const handleSelect = (category) => {
36
52
  const tr = view.state.tr;
37
53
  tr.setNodeAttribute(pos, 'category', category.id);
38
54
  view.dispatch(tr);
39
55
  };
40
- const arrow = document.createElement('div');
41
- arrow.className = 'section-category popper-arrow';
42
56
  const button = document.createElement('button');
43
57
  button.innerHTML = icons_1.sectionCategoryIcon;
44
58
  button.classList.add('section-category-button');
45
59
  button.setAttribute('aria-label', 'Section categories menu');
46
60
  if (currentCategory) {
61
+ button.setAttribute('data-tooltip-content', currentCategory.titles[0]);
47
62
  button.classList.add('assigned');
48
63
  }
49
64
  if (disabled) {
@@ -51,38 +66,18 @@ function createButton(view, pos, currentCategory, categories, usedCategoryIDs, c
51
66
  }
52
67
  else if (canEdit) {
53
68
  button.addEventListener('mousedown', () => {
54
- popper.destroy();
55
- const menu = createMenu(currentCategory, categories, usedCategoryIDs, handleSelect);
56
- popper.show(button, menu, 'bottom-end', false, [
57
- { name: 'offset', options: { offset: [0, -10] } },
58
- ]);
59
- });
60
- }
61
- else {
62
- button.addEventListener('mouseenter', () => {
63
- const tooltip = document.createElement('div');
64
- tooltip.className = 'section-category tooltip';
65
- tooltip.textContent = 'Category:';
66
- const span = document.createElement('span');
67
- span.textContent = currentCategory?.titles[0] || '';
68
- tooltip.appendChild(span);
69
- tooltip.appendChild(arrow);
70
- popper.show(button, tooltip, 'left', false, [
71
- { name: 'offset', options: { offset: [0, 10] } },
72
- { name: 'arrow', options: { element: arrow } },
73
- ]);
74
- });
75
- button.addEventListener('mouseleave', () => {
76
- popper.destroy();
69
+ const menu = createMenu(props, currentCategory, categories, usedCategoryIDs, handleSelect);
70
+ props.popper.show(button, menu, 'bottom-end', false);
77
71
  });
78
72
  }
79
73
  return button;
80
- }
81
- function buildPluginState(state, props) {
74
+ };
75
+ const buildPluginState = (state, props) => {
82
76
  const decorations = [];
83
77
  const can = props.getCapabilities();
84
78
  const categories = props.sectionCategories;
85
79
  const usedCategoryIDs = getUsedSectionCategoryIDs(state);
80
+ const canEdit = !!can?.editArticle;
86
81
  state.doc.descendants((node, pos) => {
87
82
  if (node.type === transform_1.schema.nodes.box_element) {
88
83
  return false;
@@ -93,17 +88,24 @@ function buildPluginState(state, props) {
93
88
  const $pos = state.doc.resolve(pos);
94
89
  const group = getGroup($pos);
95
90
  const groupCategories = (0, transform_1.getGroupCategories)(categories, group);
96
- decorations.push(prosemirror_view_1.Decoration.widget(pos + 1, (view) => createButton(view, pos, category, groupCategories, usedCategoryIDs, can?.editArticle, categories.size === 0)));
91
+ const numOptions = groupCategories.length;
92
+ const shouldShow = !!category || (canEdit && numOptions >= 2);
93
+ if (shouldShow) {
94
+ const isEditable = canEdit && numOptions >= 2;
95
+ decorations.push(prosemirror_view_1.Decoration.widget(pos + 1, (view) => createButton(props, view, pos, category, groupCategories, usedCategoryIDs, isEditable, categories.size === 0)));
96
+ }
97
97
  return false;
98
98
  }
99
99
  });
100
100
  return { decorations: prosemirror_view_1.DecorationSet.create(state.doc, decorations) };
101
- }
101
+ };
102
102
  const getUsedSectionCategoryIDs = (state) => {
103
103
  const sections = (0, prosemirror_utils_1.findChildrenByType)(state.doc, transform_1.schema.nodes.section);
104
104
  const used = new Set();
105
105
  sections.forEach(({ node }) => {
106
- node.attrs.category && used.add(node.attrs.category);
106
+ if (node.attrs.category) {
107
+ used.add(node.attrs.category);
108
+ }
107
109
  });
108
110
  return used;
109
111
  };
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MATHJAX_VERSION = exports.VERSION = void 0;
4
- exports.VERSION = '3.7.29';
4
+ exports.VERSION = '3.8.1';
5
5
  exports.MATHJAX_VERSION = '3.2.2';
@@ -1,4 +1,4 @@
1
- import { AffiliationIcon, CrclTickAnimation, DeleteIcon, Tooltip, } from '@manuscripts/style-guide';
1
+ import { AffiliationIcon, CrclTickAnimation, DeleteIcon, } from '@manuscripts/style-guide';
2
2
  import React, { useRef } from 'react';
3
3
  import styled from 'styled-components';
4
4
  const AffiliationContainer = styled.div `
@@ -75,7 +75,6 @@ export const AffiliationItem = ({ affiliation, isSelected, onClick, onDelete, sh
75
75
  affiliation.country ? ', ' : '')),
76
76
  affiliation.country && React.createElement(React.Fragment, null, affiliation.country))),
77
77
  showSuccessIcon && (React.createElement(CrclTickAnimation, { size: 36, style: { position: 'absolute', left: '10px' } })),
78
- isSelected && (React.createElement(RemoveButton, { onClick: () => onDelete(), "data-tooltip-id": 'delete-button-tooltip' },
79
- React.createElement(DeleteIcon, { fill: '#6E6E6E' }),
80
- React.createElement(Tooltip, { id: 'delete-button-tooltip', place: "bottom" }, 'Delete')))));
78
+ isSelected && (React.createElement(RemoveButton, { onClick: () => onDelete(), "data-tooltip-content": "Delete" },
79
+ React.createElement(DeleteIcon, { fill: '#6E6E6E' })))));
81
80
  };
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Avatar, CorrespondingAuthorIcon, CrclTickAnimation, DeleteIcon, DraggableIcon, Tooltip, } from '@manuscripts/style-guide';
16
+ import { Avatar, CorrespondingAuthorIcon, CrclTickAnimation, DeleteIcon, DraggableIcon, } from '@manuscripts/style-guide';
17
17
  import React, { useRef, useState } from 'react';
18
18
  import { useDrag, useDrop } from 'react-dnd';
19
19
  import styled from 'styled-components';
@@ -162,7 +162,6 @@ export const DraggableAuthor = React.memo(({ author, isSelected, onClick, onDele
162
162
  React.createElement(AuthorNotes, { "data-cy": "author-notes" }, author.isCorresponding && (React.createElement(AuthorBadge, null,
163
163
  React.createElement(CorrespondingAuthorIcon, null))))),
164
164
  React.createElement(AuthorName, { "data-cy": "author-name" }, authorLabel(author)),
165
- isSelected && (React.createElement(RemoveButton, { onClick: () => onDelete(), "data-tooltip-id": 'delete-button-tooltip' },
166
- React.createElement(DeleteIcon, { fill: '#6E6E6E' }),
167
- React.createElement(Tooltip, { id: 'delete-button-tooltip', place: "bottom" }, 'Delete')))));
165
+ isSelected && (React.createElement(RemoveButton, { onClick: () => onDelete(), "data-tooltip-content": "Delete" },
166
+ React.createElement(DeleteIcon, { fill: '#6E6E6E' })))));
168
167
  });
@@ -58,38 +58,24 @@ export const ImportBibliographyModal = ({ onCancel, onSave }) => {
58
58
  React.createElement(ModalBody, null,
59
59
  React.createElement(ModalTitle, null, "Import Bibliography"),
60
60
  React.createElement("p", null,
61
- React.createElement(SpanWithExample, { "data-tooltip-id": "example_bibtex" }, "BibTex"),
61
+ React.createElement(SpanWithExample, { "data-tooltip-id": "import-example-tooltip", "data-tooltip-content": exampleBibtex, "data-tool": true }, "BibTex"),
62
62
  ",",
63
63
  ' ',
64
- React.createElement(SpanWithExample, { "data-tooltip-id": "example_pubmed" }, "PubMed"),
64
+ React.createElement(SpanWithExample, { "data-tooltip-id": "import-example-tooltip", "data-tooltip-content": examplePubmed }, "PubMed"),
65
65
  ",",
66
66
  ' ',
67
- React.createElement(SpanWithExample, { "data-tooltip-id": "example_ris" }, "RIS"),
67
+ React.createElement(SpanWithExample, { "data-tooltip-id": "import-example-tooltip", "data-tooltip-content": exampleRis }, "RIS"),
68
68
  ",",
69
69
  ' ',
70
- React.createElement(SpanWithExample, { "data-tooltip-id": "example_enw" }, "ENW"),
70
+ React.createElement(SpanWithExample, { "data-tooltip-id": "import-example-tooltip", "data-tooltip-content": exampleEnw }, "ENW"),
71
71
  ' ',
72
72
  "and",
73
73
  ' ',
74
- React.createElement(SpanWithExample, { "data-tooltip-id": "example_doi" }, "DOI"),
74
+ React.createElement(SpanWithExample, { "data-tooltip-id": "import-example-tooltip", "data-tooltip-content": exampleDoi }, "DOI"),
75
75
  ' ',
76
76
  "formats are supported"),
77
77
  React.createElement(ImportBibliographyForm, { onCancel: handleCancel, onSave: handleSave }),
78
- React.createElement(Example, { id: "example_bibtex", place: "bottom" },
79
- React.createElement("div", null,
80
- React.createElement("pre", null, exampleBibtex))),
81
- React.createElement(Example, { id: "example_pubmed", place: "bottom" },
82
- React.createElement("div", null,
83
- React.createElement("pre", null, examplePubmed))),
84
- React.createElement(Example, { id: "example_ris", place: "bottom" },
85
- React.createElement("div", null,
86
- React.createElement("pre", null, exampleRis))),
87
- React.createElement(Example, { id: "example_enw", place: "bottom" },
88
- React.createElement("div", null,
89
- React.createElement("pre", null, exampleEnw))),
90
- React.createElement(Example, { id: "example_doi", place: "bottom" },
91
- React.createElement("div", null,
92
- React.createElement("pre", null, exampleDoi)))))));
78
+ React.createElement(Example, { id: "import-example-tooltip", place: "bottom", render: (s) => (React.createElement("pre", null, s.content)) })))));
93
79
  };
94
80
  const ModalBody = styled.div `
95
81
  box-sizing: border-box;
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { AddAuthorIcon, ButtonGroup, Category, DeleteIcon, Dialog, IconButton, LinkIcon, PrimaryButton, SecondaryButton, SelectField, Tooltip, } from '@manuscripts/style-guide';
16
+ import { AddAuthorIcon, ButtonGroup, Category, DeleteIcon, Dialog, IconButton, LinkIcon, PrimaryButton, SecondaryButton, SelectField, } from '@manuscripts/style-guide';
17
17
  import { Field, FieldArray, Formik } from 'formik';
18
18
  import React, { useEffect, useRef, useState } from 'react';
19
19
  import { bibliographyItemTypes } from '../../../lib/references';
@@ -76,9 +76,8 @@ export const ReferenceForm = ({ values, showDelete, onChange, onDelete, onCancel
76
76
  React.createElement(ButtonGroup, null,
77
77
  React.createElement(IconButton, { as: "a", href: `https://doi.org/${formik.values.DOI}`, target: '_blank' },
78
78
  React.createElement(LinkIcon, null)),
79
- React.createElement(DeleteButton, { defaultColor: true, disabled: !showDelete, "data-tooltip-id": showDelete ? '' : 'delete-button-tooltip', onClick: () => setShowDeleteDialog(true) },
80
- React.createElement(DeleteIcon, null)),
81
- React.createElement(Tooltip, { id: "delete-button-tooltip", place: "bottom" }, "Unable to delete because the item is used in the document")),
79
+ React.createElement(DeleteButton, { defaultColor: true, disabled: !showDelete, "data-tooltip-content": "Unable to delete because the item is used in the document", "data-tooltip-hidden": showDelete, onClick: () => setShowDeleteDialog(true) },
80
+ React.createElement(DeleteIcon, null))),
82
81
  React.createElement(ButtonGroup, null,
83
82
  React.createElement(SecondaryButton, { onClick: onCancel }, "Cancel"),
84
83
  React.createElement(PrimaryButton, { type: "submit", disabled: !formik.isValid || !formik.dirty }, "Save"))),
@@ -1,4 +1,4 @@
1
- import { Category, CitationCountIcon, CloseButton, Dialog, ModalBody, ModalContainer, ModalHeader, ModalSidebar, ModalSidebarHeader, ModalSidebarTitle, ScrollableModalContent, SidebarContent, StyledModal, Tooltip, useScrollDetection, } from '@manuscripts/style-guide';
1
+ import { Category, CitationCountIcon, CloseButton, Dialog, ModalBody, ModalContainer, ModalHeader, ModalSidebar, ModalSidebarHeader, ModalSidebarTitle, ScrollableModalContent, SidebarContent, StyledModal, useScrollDetection, } from '@manuscripts/style-guide';
2
2
  import { isEqual } from 'lodash';
3
3
  import React, { useEffect, useRef, useState } from 'react';
4
4
  import styled from 'styled-components';
@@ -208,9 +208,8 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
208
208
  React.createElement(ReferencesInnerWrapper, null, items.slice(startIndex, endIndex + 1).map((item) => (React.createElement(ReferenceButton, { key: item.id, id: item.id, className: isSelected(item) ? 'selected' : '', onClick: () => handleItemClick(item), ref: isSelected(item) ? selectionRef : null },
209
209
  React.createElement(IconContainer, null,
210
210
  React.createElement(CitationCountIcon, null),
211
- (citationCounts.get(item.id) || 0) > 0 ? (React.createElement(CitationCount, { "data-tooltip-id": "citation-count-tooltip" }, citationCounts.get(item.id))) : (React.createElement(CitationCount, { className: "unused" }, "0"))),
212
- React.createElement(ReferenceLine, { item: item }))))),
213
- React.createElement(Tooltip, { id: "citation-count-tooltip", place: "bottom" }, "Number of times used in the document"))),
211
+ (citationCounts.get(item.id) || 0) > 0 ? (React.createElement(CitationCount, { "data-tooltip-content": "Number of times used in the document" }, citationCounts.get(item.id))) : (React.createElement(CitationCount, { className: "unused" }, "0"))),
212
+ React.createElement(ReferenceLine, { item: item }))))))),
214
213
  React.createElement(ScrollableModalContent, null, selection && (React.createElement(ReferenceForm, { values: normalize(selection), showDelete: !citationCounts.get(selection.id) &&
215
214
  isNewItem(selection, ['id', 'type']), onChange: handleChange, onCancel: onCancel, onDelete: handleDelete, onSave: handleSave, actionsRef: actionsRef })))))));
216
215
  };
@@ -43,7 +43,7 @@ import placeholder from '../plugins/placeholder';
43
43
  import prevent_empty from '../plugins/prevent-empty';
44
44
  import search_replace from '../plugins/search-replace';
45
45
  import section_title from '../plugins/section_title';
46
- import section_category from '../plugins/section-category';
46
+ import section_category from '../plugins/section_category';
47
47
  import selected_suggestion from '../plugins/selected-suggestion';
48
48
  import table_editing_fix from '../plugins/tables-cursor-fix';
49
49
  import rules from '../rules';
@@ -61,7 +61,8 @@ export class PopperManager {
61
61
  this.destroy();
62
62
  }
63
63
  };
64
- if (contents.classList.contains('context-menu')) {
64
+ if (contents.classList.contains('context-menu') ||
65
+ contents.classList.contains('section-category')) {
65
66
  window.addEventListener('click', this.handleDocumentClick);
66
67
  }
67
68
  });
package/dist/es/menus.js CHANGED
@@ -197,8 +197,7 @@ export const getEditorMenus = (editor) => {
197
197
  label: 'Author Notes',
198
198
  isEnabled: true,
199
199
  submenu: categories.map(insertBackmatterSectionMenu),
200
- isHidden: !templateAllows(state, schema.nodes.author_notes) ||
201
- !categories.length,
200
+ isHidden: !categories.length,
202
201
  },
203
202
  {
204
203
  id: 'insert-section',
@@ -1,46 +1,61 @@
1
1
  import { getGroupCategories, isSectionNode, schema, } from '@manuscripts/transform';
2
+ import { Plugin, PluginKey } from 'prosemirror-state';
2
3
  import { findChildrenByType, findParentNodeOfTypeClosestToPos, } from 'prosemirror-utils';
3
4
  import { Decoration, DecorationSet } from 'prosemirror-view';
4
- import { sectionCategoryIcon } from '../../icons';
5
- import { PopperManager } from '../../lib/popper';
6
- const popper = new PopperManager();
7
- function createMenuItem(contents, handler, isDisabled = false, isSelected = false) {
5
+ import { sectionCategoryIcon } from '../icons';
6
+ export const sectionCategoryKey = new PluginKey('section-category');
7
+ export default (props) => new Plugin({
8
+ key: sectionCategoryKey,
9
+ state: {
10
+ init: (_, state) => buildPluginState(state, props),
11
+ apply: (tr, value, oldState, newState) => {
12
+ if (!tr.docChanged) {
13
+ return value;
14
+ }
15
+ return buildPluginState(newState, props);
16
+ }
17
+ },
18
+ props: {
19
+ decorations: (state) => sectionCategoryKey.getState(state)?.decorations || DecorationSet.empty,
20
+ },
21
+ });
22
+ const createMenuItem = (props, contents, handler, isDisabled, isSelected) => {
8
23
  const item = document.createElement('div');
9
- item.className = `menu-item ${isDisabled ? 'disabled' : ''} ${isSelected ? 'selected' : ''}`;
24
+ item.classList.add('menu-item');
25
+ if (isSelected) {
26
+ item.classList.add('selected');
27
+ }
28
+ if (isDisabled) {
29
+ item.classList.add('disabled');
30
+ }
10
31
  item.textContent = contents;
11
32
  item.addEventListener('mousedown', (event) => {
12
33
  handler(event);
13
- popper.destroy();
34
+ props.popper.destroy();
14
35
  });
15
36
  return item;
16
- }
17
- function createMenu(currentCategory, categories, usedCategoryIDs, onSelect) {
37
+ };
38
+ const createMenu = (props, currentCategory, categories, usedCategoryIDs, onSelect) => {
18
39
  const menu = document.createElement('div');
19
40
  menu.className = 'section-category menu';
20
41
  categories.forEach((category) => {
21
- const item = createMenuItem(category.titles[0], () => onSelect(category), category.isUnique && usedCategoryIDs.has(category.id), currentCategory === category);
42
+ const item = createMenuItem(props, category.titles[0], () => onSelect(category), category.isUnique && usedCategoryIDs.has(category.id), currentCategory === category);
22
43
  menu.appendChild(item);
23
44
  });
24
- document.addEventListener('mousedown', (event) => {
25
- if (!menu.contains(event.target)) {
26
- popper.destroy();
27
- }
28
- });
29
45
  return menu;
30
- }
31
- function createButton(view, pos, currentCategory, categories, usedCategoryIDs, canEdit = true, disabled) {
46
+ };
47
+ const createButton = (props, view, pos, currentCategory, categories, usedCategoryIDs, canEdit = true, disabled) => {
32
48
  const handleSelect = (category) => {
33
49
  const tr = view.state.tr;
34
50
  tr.setNodeAttribute(pos, 'category', category.id);
35
51
  view.dispatch(tr);
36
52
  };
37
- const arrow = document.createElement('div');
38
- arrow.className = 'section-category popper-arrow';
39
53
  const button = document.createElement('button');
40
54
  button.innerHTML = sectionCategoryIcon;
41
55
  button.classList.add('section-category-button');
42
56
  button.setAttribute('aria-label', 'Section categories menu');
43
57
  if (currentCategory) {
58
+ button.setAttribute('data-tooltip-content', currentCategory.titles[0]);
44
59
  button.classList.add('assigned');
45
60
  }
46
61
  if (disabled) {
@@ -48,38 +63,18 @@ function createButton(view, pos, currentCategory, categories, usedCategoryIDs, c
48
63
  }
49
64
  else if (canEdit) {
50
65
  button.addEventListener('mousedown', () => {
51
- popper.destroy();
52
- const menu = createMenu(currentCategory, categories, usedCategoryIDs, handleSelect);
53
- popper.show(button, menu, 'bottom-end', false, [
54
- { name: 'offset', options: { offset: [0, -10] } },
55
- ]);
56
- });
57
- }
58
- else {
59
- button.addEventListener('mouseenter', () => {
60
- const tooltip = document.createElement('div');
61
- tooltip.className = 'section-category tooltip';
62
- tooltip.textContent = 'Category:';
63
- const span = document.createElement('span');
64
- span.textContent = currentCategory?.titles[0] || '';
65
- tooltip.appendChild(span);
66
- tooltip.appendChild(arrow);
67
- popper.show(button, tooltip, 'left', false, [
68
- { name: 'offset', options: { offset: [0, 10] } },
69
- { name: 'arrow', options: { element: arrow } },
70
- ]);
71
- });
72
- button.addEventListener('mouseleave', () => {
73
- popper.destroy();
66
+ const menu = createMenu(props, currentCategory, categories, usedCategoryIDs, handleSelect);
67
+ props.popper.show(button, menu, 'bottom-end', false);
74
68
  });
75
69
  }
76
70
  return button;
77
- }
78
- export function buildPluginState(state, props) {
71
+ };
72
+ const buildPluginState = (state, props) => {
79
73
  const decorations = [];
80
74
  const can = props.getCapabilities();
81
75
  const categories = props.sectionCategories;
82
76
  const usedCategoryIDs = getUsedSectionCategoryIDs(state);
77
+ const canEdit = !!can?.editArticle;
83
78
  state.doc.descendants((node, pos) => {
84
79
  if (node.type === schema.nodes.box_element) {
85
80
  return false;
@@ -90,17 +85,24 @@ export function buildPluginState(state, props) {
90
85
  const $pos = state.doc.resolve(pos);
91
86
  const group = getGroup($pos);
92
87
  const groupCategories = getGroupCategories(categories, group);
93
- decorations.push(Decoration.widget(pos + 1, (view) => createButton(view, pos, category, groupCategories, usedCategoryIDs, can?.editArticle, categories.size === 0)));
88
+ const numOptions = groupCategories.length;
89
+ const shouldShow = !!category || (canEdit && numOptions >= 2);
90
+ if (shouldShow) {
91
+ const isEditable = canEdit && numOptions >= 2;
92
+ decorations.push(Decoration.widget(pos + 1, (view) => createButton(props, view, pos, category, groupCategories, usedCategoryIDs, isEditable, categories.size === 0)));
93
+ }
94
94
  return false;
95
95
  }
96
96
  });
97
97
  return { decorations: DecorationSet.create(state.doc, decorations) };
98
- }
98
+ };
99
99
  const getUsedSectionCategoryIDs = (state) => {
100
100
  const sections = findChildrenByType(state.doc, schema.nodes.section);
101
101
  const used = new Set();
102
102
  sections.forEach(({ node }) => {
103
- node.attrs.category && used.add(node.attrs.category);
103
+ if (node.attrs.category) {
104
+ used.add(node.attrs.category);
105
+ }
104
106
  });
105
107
  return used;
106
108
  };
@@ -1,2 +1,2 @@
1
- export const VERSION = '3.7.29';
1
+ export const VERSION = '3.8.1';
2
2
  export const MATHJAX_VERSION = '3.2.2';
@@ -1,6 +1,6 @@
1
1
  import { Plugin, PluginKey } from 'prosemirror-state';
2
2
  import { DecorationSet } from 'prosemirror-view';
3
- import { EditorProps } from '../../configs/ManuscriptsEditor';
3
+ import { EditorProps } from '../configs/ManuscriptsEditor';
4
4
  export declare const sectionCategoryKey: PluginKey<PluginState>;
5
5
  export interface PluginState {
6
6
  decorations: DecorationSet;
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "3.7.29";
1
+ export declare const VERSION = "3.8.1";
2
2
  export declare const MATHJAX_VERSION = "3.2.2";
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": "3.7.29",
4
+ "version": "3.8.1",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -38,7 +38,7 @@
38
38
  "@citation-js/plugin-ris": "0.7.18",
39
39
  "@iarna/word-count": "1.1.2",
40
40
  "@manuscripts/json-schema": "2.2.12",
41
- "@manuscripts/style-guide": "3.3.15",
41
+ "@manuscripts/style-guide": "3.4.0",
42
42
  "@manuscripts/track-changes-plugin": "2.2.3",
43
43
  "@manuscripts/transform": "4.3.14",
44
44
  "@popperjs/core": "2.11.8",
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sectionCategoryKey = void 0;
4
- const prosemirror_state_1 = require("prosemirror-state");
5
- const prosemirror_view_1 = require("prosemirror-view");
6
- const section_category_utils_1 = require("./section-category-utils");
7
- exports.sectionCategoryKey = new prosemirror_state_1.PluginKey('section-category');
8
- exports.default = (props) => new prosemirror_state_1.Plugin({
9
- key: exports.sectionCategoryKey,
10
- state: {
11
- init: (_, state) => (0, section_category_utils_1.buildPluginState)(state, props),
12
- apply: (tr, value, oldState, newState) => (0, section_category_utils_1.buildPluginState)(newState, props),
13
- },
14
- props: {
15
- decorations: (state) => exports.sectionCategoryKey.getState(state)?.decorations || prosemirror_view_1.DecorationSet.empty,
16
- },
17
- });
@@ -1,14 +0,0 @@
1
- import { Plugin, PluginKey } from 'prosemirror-state';
2
- import { DecorationSet } from 'prosemirror-view';
3
- import { buildPluginState } from './section-category-utils';
4
- export const sectionCategoryKey = new PluginKey('section-category');
5
- export default (props) => new Plugin({
6
- key: sectionCategoryKey,
7
- state: {
8
- init: (_, state) => buildPluginState(state, props),
9
- apply: (tr, value, oldState, newState) => buildPluginState(newState, props),
10
- },
11
- props: {
12
- decorations: (state) => sectionCategoryKey.getState(state)?.decorations || DecorationSet.empty,
13
- },
14
- });
@@ -1,4 +0,0 @@
1
- import { EditorState } from 'prosemirror-state';
2
- import { EditorProps } from '../../configs/ManuscriptsEditor';
3
- import { PluginState } from './index';
4
- export declare function buildPluginState(state: EditorState, props: EditorProps): PluginState;