@manuscripts/body-editor 3.12.33 → 3.12.35

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 (70) hide show
  1. package/dist/cjs/components/ChangeHandlingForm.js +3 -2
  2. package/dist/cjs/components/affiliations/AffiliationForm.js +77 -44
  3. package/dist/cjs/components/affiliations/AffiliationsModal.js +69 -58
  4. package/dist/cjs/components/affiliations/AffiliationsPanel.js +1 -1
  5. package/dist/cjs/components/affiliations/CreateAffiliationModal.js +96 -0
  6. package/dist/cjs/components/authors/AuthorDetailsForm.js +110 -54
  7. package/dist/cjs/components/authors/AuthorsModal.js +71 -48
  8. package/dist/cjs/components/authors/AuthorsPanel.js +2 -2
  9. package/dist/cjs/components/authors/CreateAuthorModal.js +121 -0
  10. package/dist/cjs/components/authors/CreditDrawer.js +14 -12
  11. package/dist/cjs/components/authors-affiliations/AuthorsAndAffiliationsModals.js +8 -24
  12. package/dist/cjs/components/authors-affiliations/GenericPanel.js +2 -2
  13. package/dist/cjs/components/authors-affiliations/ModalTabs.js +80 -0
  14. package/dist/cjs/components/dialog/ConfirmationDialog.js +3 -2
  15. package/dist/cjs/components/form/CreateModalStyles.js +24 -0
  16. package/dist/cjs/components/form/FormFooter.js +8 -3
  17. package/dist/cjs/components/form/ModalFormActions.js +19 -42
  18. package/dist/cjs/components/form/UnsavedLabel.js +25 -0
  19. package/dist/cjs/components/hooks/useAffiliationShowsErrorIndicator.js +27 -0
  20. package/dist/cjs/components/hooks/useAuthorShowsErrorIndicator.js +40 -0
  21. package/dist/cjs/lib/authors-and-affiliations.js +51 -0
  22. package/dist/cjs/lib/helpers.js +28 -1
  23. package/dist/cjs/lib/normalize.js +17 -5
  24. package/dist/cjs/useEditor.js +7 -4
  25. package/dist/cjs/versions.js +1 -1
  26. package/dist/es/components/ChangeHandlingForm.js +3 -2
  27. package/dist/es/components/affiliations/AffiliationForm.js +75 -46
  28. package/dist/es/components/affiliations/AffiliationsModal.js +71 -60
  29. package/dist/es/components/affiliations/AffiliationsPanel.js +2 -2
  30. package/dist/es/components/affiliations/CreateAffiliationModal.js +56 -0
  31. package/dist/es/components/authors/AuthorDetailsForm.js +111 -56
  32. package/dist/es/components/authors/AuthorsModal.js +74 -51
  33. package/dist/es/components/authors/AuthorsPanel.js +3 -3
  34. package/dist/es/components/authors/CreateAuthorModal.js +81 -0
  35. package/dist/es/components/authors/CreditDrawer.js +13 -11
  36. package/dist/es/components/authors-affiliations/AuthorsAndAffiliationsModals.js +8 -24
  37. package/dist/es/components/authors-affiliations/GenericPanel.js +2 -2
  38. package/dist/es/components/authors-affiliations/ModalTabs.js +73 -0
  39. package/dist/es/components/dialog/ConfirmationDialog.js +3 -2
  40. package/dist/es/components/form/CreateModalStyles.js +18 -0
  41. package/dist/es/components/form/FormFooter.js +9 -4
  42. package/dist/es/components/form/ModalFormActions.js +18 -42
  43. package/dist/es/components/form/UnsavedLabel.js +18 -0
  44. package/dist/es/components/hooks/useAffiliationShowsErrorIndicator.js +21 -0
  45. package/dist/es/components/hooks/useAuthorShowsErrorIndicator.js +34 -0
  46. package/dist/es/lib/authors-and-affiliations.js +48 -0
  47. package/dist/es/lib/helpers.js +27 -1
  48. package/dist/es/lib/normalize.js +15 -4
  49. package/dist/es/useEditor.js +8 -5
  50. package/dist/es/versions.js +1 -1
  51. package/dist/es/views/affiliations.js +1 -1
  52. package/dist/types/components/affiliations/AffiliationForm.d.ts +6 -2
  53. package/dist/types/components/affiliations/AffiliationsModal.d.ts +1 -1
  54. package/dist/types/components/affiliations/CreateAffiliationModal.d.ts +8 -0
  55. package/dist/types/components/authors/AuthorDetailsForm.d.ts +11 -1
  56. package/dist/types/components/authors/AuthorsPanel.d.ts +1 -1
  57. package/dist/types/components/authors/CreateAuthorModal.d.ts +9 -0
  58. package/dist/types/components/authors/CreditDrawer.d.ts +2 -4
  59. package/dist/types/components/authors-affiliations/ModalTabs.d.ts +22 -0
  60. package/dist/types/components/form/CreateModalStyles.d.ts +4 -0
  61. package/dist/types/components/form/FormFooter.d.ts +2 -1
  62. package/dist/types/components/form/ModalFormActions.d.ts +12 -6
  63. package/dist/types/components/form/UnsavedLabel.d.ts +10 -0
  64. package/dist/types/components/hooks/useAffiliationShowsErrorIndicator.d.ts +5 -0
  65. package/dist/types/components/hooks/useAuthorShowsErrorIndicator.d.ts +5 -0
  66. package/dist/types/lib/authors-and-affiliations.d.ts +19 -0
  67. package/dist/types/lib/helpers.d.ts +2 -0
  68. package/dist/types/lib/normalize.d.ts +2 -1
  69. package/dist/types/versions.d.ts +1 -1
  70. package/package.json +2 -2
@@ -54,30 +54,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
54
54
  exports.openAuthorsAndAffiliationsModals = exports.AuthorsAndAffiliationsModals = void 0;
55
55
  const transform_1 = require("@manuscripts/transform");
56
56
  const react_1 = __importStar(require("react"));
57
+ const authors_and_affiliations_1 = require("../../lib/authors-and-affiliations");
57
58
  const editor_props_1 = require("../../plugins/editor-props");
58
59
  const ReactSubView_1 = __importDefault(require("../../views/ReactSubView"));
59
60
  const view_1 = require("../../lib/view");
60
61
  const AffiliationsModal_1 = require("../affiliations/AffiliationsModal");
62
+ const CreateAffiliationModal_1 = require("../affiliations/CreateAffiliationModal");
61
63
  const AuthorsModal_1 = require("../authors/AuthorsModal");
62
- function insertNode(parentType, childType) {
63
- return (view, attrs) => {
64
- const parent = (0, view_1.findChildByType)(view, parentType);
65
- if (parent) {
66
- view.dispatch(view.state.tr.insert(parent.pos + 1, childType.create(attrs)));
67
- }
68
- };
69
- }
70
- function upsertNode(nodeType, insertFn) {
71
- return (view, attrs) => {
72
- if (!(0, view_1.updateNodeAttrs)(view, nodeType, attrs)) {
73
- insertFn(view, attrs);
74
- }
75
- };
76
- }
77
- const insertAuthorNode = insertNode(transform_1.schema.nodes.contributors, transform_1.schema.nodes.contributor);
78
- const insertAffiliationNode = insertNode(transform_1.schema.nodes.affiliations, transform_1.schema.nodes.affiliation);
79
- const upsertAuthor = upsertNode(transform_1.schema.nodes.contributor, insertAuthorNode);
80
- const upsertAffiliation = upsertNode(transform_1.schema.nodes.affiliation, insertAffiliationNode);
64
+ const CreateAuthorModal_1 = require("../authors/CreateAuthorModal");
81
65
  const AuthorsAndAffiliationsModals = ({ initialModal, view, author, affiliation, addNewAuthor, addNewAffiliation, }) => {
82
66
  const [showOverlay, setShowOverlay] = (0, react_1.useState)(false);
83
67
  const [authors, setAuthors] = (0, react_1.useState)(() => (0, view_1.findChildrenAttrsByType)(view, transform_1.schema.nodes.contributor));
@@ -93,7 +77,7 @@ const AuthorsAndAffiliationsModals = ({ initialModal, view, author, affiliation,
93
77
  authors,
94
78
  affiliations,
95
79
  addNewAuthor,
96
- onSaveAuthor: (a) => upsertAuthor(view, a),
80
+ onSaveAuthor: (a) => (0, authors_and_affiliations_1.upsertAuthor)(view, a),
97
81
  onDeleteAuthor: (a) => (0, view_1.deleteNode)(view, a.id),
98
82
  };
99
83
  const affiliationsProps = {
@@ -101,18 +85,18 @@ const AuthorsAndAffiliationsModals = ({ initialModal, view, author, affiliation,
101
85
  authors,
102
86
  affiliations,
103
87
  addNewAffiliation,
104
- onSaveAffiliation: (a) => upsertAffiliation(view, a),
88
+ onSaveAffiliation: (a) => (0, authors_and_affiliations_1.upsertAffiliation)(view, a),
105
89
  onDeleteAffiliation: (a) => (0, view_1.deleteNode)(view, a.id),
106
90
  onUpdateAuthors: (updated) => updated.forEach((a) => (0, view_1.updateNodeAttrs)(view, transform_1.schema.nodes.contributor, a)),
107
91
  };
108
92
  if (initialModal === 'authors') {
109
93
  return (react_1.default.createElement(react_1.default.Fragment, null,
110
94
  react_1.default.createElement(AuthorsModal_1.AuthorsModal, { ...authorsProps, onOpenAffiliationsModal: handleOpenOverlay }),
111
- showOverlay && (react_1.default.createElement(AffiliationsModal_1.AffiliationsModal, { ...affiliationsProps, addNewAffiliation: true, onClose: handleOverlayClose }))));
95
+ showOverlay && (react_1.default.createElement(CreateAffiliationModal_1.CreateAffiliationModal, { affiliationsCount: affiliations.length, onSave: (a) => (0, authors_and_affiliations_1.upsertAffiliation)(view, a), onClose: handleOverlayClose }))));
112
96
  }
113
97
  return (react_1.default.createElement(react_1.default.Fragment, null,
114
- react_1.default.createElement(AffiliationsModal_1.AffiliationsModal, { ...affiliationsProps, onOpenAuthorsModal: handleOpenOverlay }),
115
- showOverlay && (react_1.default.createElement(AuthorsModal_1.AuthorsModal, { ...authorsProps, addNewAuthor: true, onClose: handleOverlayClose }))));
98
+ react_1.default.createElement(AffiliationsModal_1.AffiliationsModal, { ...affiliationsProps, openAuthorsModal: handleOpenOverlay }),
99
+ showOverlay && (react_1.default.createElement(CreateAuthorModal_1.CreateAuthorModal, { authorsCount: authors.length, affiliations: affiliations, onSave: (a) => (0, authors_and_affiliations_1.upsertAuthor)(view, a), onClose: handleOverlayClose }))));
116
100
  };
117
101
  exports.AuthorsAndAffiliationsModals = AuthorsAndAffiliationsModals;
118
102
  const openAuthorsAndAffiliationsModals = (pos, view, initialModal) => {
@@ -97,8 +97,8 @@ const PanelEmpty = styled_components_1.default.div `
97
97
  ${(props) => props.theme.grid.unit * 4}px;
98
98
  `;
99
99
  const PanelEmptyIcon = styled_components_1.default.div `
100
- width: 120px;
101
- height: 120px;
100
+ width: 80px;
101
+ height: 80px;
102
102
  flex-shrink: 0;
103
103
  display: flex;
104
104
  align-items: center;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /*!
3
+ * © 2026 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.ModalTabs = void 0;
22
+ const style_guide_1 = require("@manuscripts/style-guide");
23
+ const react_1 = __importDefault(require("react"));
24
+ const styled_components_1 = __importDefault(require("styled-components"));
25
+ const ModalTabs = ({ tabLabels, tabErrorIndicators, tabWarningIndicators, }) => (react_1.default.createElement(StyledTabList, null, tabLabels.map((label, i) => {
26
+ const hasError = tabErrorIndicators?.[i];
27
+ const showWarning = tabWarningIndicators?.[i] && !hasError;
28
+ return (react_1.default.createElement(StyledTab, { key: label },
29
+ label,
30
+ (showWarning || hasError) && (react_1.default.createElement(TabIndicatorGroup, { role: "presentation" },
31
+ showWarning ? react_1.default.createElement(TabWarningDot, { "aria-hidden": true }) : null,
32
+ hasError ? react_1.default.createElement(TabErrorDot, { "aria-hidden": true }) : null))));
33
+ })));
34
+ exports.ModalTabs = ModalTabs;
35
+ const TabIndicatorGroup = styled_components_1.default.span `
36
+ display: inline-flex;
37
+ align-items: center;
38
+ gap: 6px;
39
+ margin-left: 6px;
40
+ flex-shrink: 0;
41
+ `;
42
+ const TabErrorDot = styled_components_1.default.span `
43
+ display: inline-block;
44
+ width: 8px;
45
+ height: 8px;
46
+ border-radius: 50%;
47
+ background: #cf1322;
48
+ flex-shrink: 0;
49
+ vertical-align: middle;
50
+ `;
51
+ const TabWarningDot = styled_components_1.default.span `
52
+ display: inline-block;
53
+ width: 8px;
54
+ height: 8px;
55
+ border-radius: 50%;
56
+ background: ${(props) => props.theme.colors.text.warning};
57
+ flex-shrink: 0;
58
+ vertical-align: middle;
59
+ `;
60
+ const StyledTab = (0, styled_components_1.default)(style_guide_1.InspectorTab) `
61
+ border-radius: 14px;
62
+ flex: 1;
63
+ display: inline-flex;
64
+ align-items: center;
65
+ justify-content: center;
66
+
67
+ &[aria-selected='true'] {
68
+ background: ${(props) => props.theme.colors.background.primary};
69
+ border: unset;
70
+ color: ${(props) => props.theme.colors.text.primary} !important;
71
+ font-weight: 700;
72
+ }
73
+ `;
74
+ const StyledTabList = (0, styled_components_1.default)(style_guide_1.InspectorTabList) `
75
+ display: flex;
76
+ justify-content: space-evenly;
77
+ border-radius: 14px;
78
+ background: #e2e2e2 !important;
79
+ padding: 2px;
80
+ `;
@@ -31,8 +31,8 @@ const getDialogConfig = (dialogType, entityType) => {
31
31
  secondary: 'Would you like to save or discard your changes?',
32
32
  },
33
33
  buttons: {
34
- primary: 'Save',
35
- secondary: 'Discard',
34
+ primary: 'Continue editing',
35
+ secondary: 'Discard changes',
36
36
  },
37
37
  },
38
38
  [DialogType.DELETE]: {
@@ -80,6 +80,7 @@ const ConfirmationDialog = ({ isOpen, type, entityType, onPrimary, onSecondary,
80
80
  secondary: {
81
81
  action: onSecondary,
82
82
  title: config.buttons.secondary,
83
+ variant: type === DialogType.DELETE ? 'default' : 'textDanger',
83
84
  },
84
85
  } }));
85
86
  };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.StyledScrollableModalContent = exports.FormTitle = exports.StyledModalBody = exports.MODAL_ON_CLOSE_NOTIFY_DELAY_MS = void 0;
7
+ const style_guide_1 = require("@manuscripts/style-guide");
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ exports.MODAL_ON_CLOSE_NOTIFY_DELAY_MS = 220;
10
+ exports.StyledModalBody = (0, styled_components_1.default)(style_guide_1.ModalBody) `
11
+ position: relative;
12
+ height: calc(90vh - 250px);
13
+ `;
14
+ exports.FormTitle = styled_components_1.default.h2 `
15
+ margin: 0 0 ${(props) => props.theme.grid.unit * 3}px;
16
+ font-family: ${(props) => props.theme.font.family.sans};
17
+ font-size: ${(props) => props.theme.font.size.large};
18
+ font-weight: ${(props) => props.theme.font.weight.semibold};
19
+ line-height: ${(props) => props.theme.font.lineHeight.large};
20
+ color: ${(props) => props.theme.colors.text.primary};
21
+ `;
22
+ exports.StyledScrollableModalContent = (0, styled_components_1.default)(style_guide_1.ScrollableModalContent) `
23
+ padding: 45px 16px 16px;
24
+ `;
@@ -10,15 +10,20 @@ const Footer = styled_components_1.default.div `
10
10
  display: flex;
11
11
  justify-content: flex-end;
12
12
  align-items: center;
13
+ gap: ${(props) => props.theme.grid.unit * 6}px;
13
14
  padding: 16px 32px;
14
- height: 40px;
15
+ min-height: 40px;
15
16
  box-shadow: 0px -2px 12px 0px rgba(216, 216, 216, 0.26);
16
17
  border-radius: 0px 0px 8px 8px;
17
18
  position: relative;
18
19
  z-index: 3;
19
20
  `;
20
- const FormFooter = ({ onCancel }) => {
21
+ const StyledIconTextButton = (0, styled_components_1.default)(style_guide_1.IconTextButton) `
22
+ color: ${(props) => props.theme.colors.brand.default};
23
+ `;
24
+ const FormFooter = ({ onCancel, primaryAction, }) => {
21
25
  return (react_1.default.createElement(Footer, null,
22
- react_1.default.createElement(style_guide_1.PrimaryButton, { onClick: onCancel }, "Close")));
26
+ react_1.default.createElement(StyledIconTextButton, { color: "secondary", onClick: onCancel }, "Close"),
27
+ primaryAction));
23
28
  };
24
29
  exports.default = FormFooter;
@@ -3,53 +3,30 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ModalFormActions = void 0;
6
+ exports.ModalFormActions = exports.ModalFormSaveButton = void 0;
7
7
  const style_guide_1 = require("@manuscripts/style-guide");
8
8
  const react_1 = __importDefault(require("react"));
9
- const styled_components_1 = __importDefault(require("styled-components"));
10
9
  const ConfirmationDialog_1 = require("../dialog/ConfirmationDialog");
11
- const ActionsContainer = styled_components_1.default.div `
12
- display: flex;
13
- position: absolute;
14
- top: 5px;
15
- right: 5px;
16
- `;
17
- const StyledButtonGroup = (0, styled_components_1.default)(style_guide_1.ButtonGroup) `
18
- flex: 1;
19
- `;
20
- const StyledIconButton = (0, styled_components_1.default)(style_guide_1.IconButton) `
21
- color: #0d79d0;
22
- text-align: center;
23
- font-size: 14px;
24
- font-style: normal;
25
- font-weight: 400;
26
- line-height: 1;
27
- width: auto;
28
- height: 24px;
29
- &:disabled {
30
- color: #c9c9c9 !important;
31
- background-color: unset !important;
32
- border: unset;
33
- }
34
- svg {
35
- margin-right: 4px;
36
- }
37
- `;
38
- const ModalFormActions = ({ type, form, onDelete, showingDeleteDialog, showDeleteDialog, newEntity, isDisableSave, onSubmitForm, }) => {
39
- const saveButton = onSubmitForm ? (react_1.default.createElement(StyledIconButton, { disabled: isDisableSave, type: "button", onClick: () => {
10
+ const styled_components_1 = __importDefault(require("styled-components"));
11
+ const ModalFormSaveButton = ({ form, newEntity, isDisableSave, onSubmitForm, createLabel, updateLabel, }) => {
12
+ const label = newEntity
13
+ ? (createLabel ?? 'Save Changes')
14
+ : (updateLabel ?? 'Update Changes');
15
+ const saveButton = onSubmitForm ? (react_1.default.createElement(StylePrimaryButton, { disabled: isDisableSave, type: "button", onClick: () => {
40
16
  if (!isDisableSave) {
41
17
  void onSubmitForm();
42
18
  }
43
- } },
44
- react_1.default.createElement(style_guide_1.PlusIcon, null),
45
- newEntity ? 'Save Details' : 'Update Details')) : (react_1.default.createElement(StyledIconButton, { disabled: isDisableSave, type: "submit", form: form },
46
- react_1.default.createElement(style_guide_1.PlusIcon, null),
47
- newEntity ? 'Save Details' : 'Update Details'));
48
- return (react_1.default.createElement(ActionsContainer, { "data-cy": `${type}-action` },
49
- react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showingDeleteDialog, onPrimary: () => {
50
- onDelete();
51
- showDeleteDialog();
52
- }, onSecondary: showDeleteDialog, type: ConfirmationDialog_1.DialogType.DELETE, entityType: type }),
53
- react_1.default.createElement(StyledButtonGroup, null, saveButton)));
19
+ } }, label)) : (react_1.default.createElement(StylePrimaryButton, { disabled: isDisableSave, type: "submit", form: form }, label));
20
+ return saveButton;
21
+ };
22
+ exports.ModalFormSaveButton = ModalFormSaveButton;
23
+ const ModalFormActions = ({ type, onDelete, showingDeleteDialog, showDeleteDialog, }) => {
24
+ return (react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showingDeleteDialog, onPrimary: () => {
25
+ onDelete();
26
+ showDeleteDialog();
27
+ }, onSecondary: showDeleteDialog, type: ConfirmationDialog_1.DialogType.DELETE, entityType: type }));
54
28
  };
55
29
  exports.ModalFormActions = ModalFormActions;
30
+ const StylePrimaryButton = (0, styled_components_1.default)(style_guide_1.PrimaryButton) `
31
+ min-width: 145px;
32
+ `;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FieldUnsavedDot = exports.UnsavedLabelRow = exports.UnsavedLabel = void 0;
7
+ const style_guide_1 = require("@manuscripts/style-guide");
8
+ const react_1 = __importDefault(require("react"));
9
+ const styled_components_1 = __importDefault(require("styled-components"));
10
+ const UnsavedLabel = ({ htmlFor, showDot, children, }) => (react_1.default.createElement(exports.UnsavedLabelRow, null,
11
+ showDot ? react_1.default.createElement(exports.FieldUnsavedDot, { "aria-hidden": true }) : null,
12
+ react_1.default.createElement(style_guide_1.Label, { htmlFor: htmlFor }, children)));
13
+ exports.UnsavedLabel = UnsavedLabel;
14
+ exports.UnsavedLabelRow = styled_components_1.default.div `
15
+ display: inline-flex;
16
+ align-items: center;
17
+ gap: 6px;
18
+ `;
19
+ exports.FieldUnsavedDot = styled_components_1.default.span `
20
+ width: 8px;
21
+ height: 8px;
22
+ border-radius: 50%;
23
+ background: ${(props) => props.theme.colors.text.warning};
24
+ flex-shrink: 0;
25
+ `;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useAffiliationShowsErrorIndicator = void 0;
4
+ exports.isInstitutionError = isInstitutionError;
5
+ exports.affiliationShowsErrorIndicator = affiliationShowsErrorIndicator;
6
+ const formik_1 = require("formik");
7
+ const react_1 = require("react");
8
+ function isInstitutionError(formik, newEntity) {
9
+ if (!(0, formik_1.getIn)(formik.errors, 'institution')) {
10
+ return false;
11
+ }
12
+ if (newEntity) {
13
+ return Boolean(formik.touched.institution || formik.dirty);
14
+ }
15
+ return Boolean(formik.touched.institution);
16
+ }
17
+ function affiliationShowsErrorIndicator(formik, newEntity) {
18
+ return isInstitutionError(formik, newEntity);
19
+ }
20
+ const useAffiliationShowsErrorIndicator = (newEntity, onChange) => {
21
+ const formik = (0, formik_1.useFormikContext)();
22
+ const hasError = affiliationShowsErrorIndicator(formik, newEntity);
23
+ (0, react_1.useEffect)(() => {
24
+ onChange?.(hasError);
25
+ }, [hasError, onChange]);
26
+ };
27
+ exports.useAffiliationShowsErrorIndicator = useAffiliationShowsErrorIndicator;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useAuthorShowsErrorIndicator = void 0;
4
+ exports.isNamePairError = isNamePairError;
5
+ exports.authorShowsErrorIndicator = authorShowsErrorIndicator;
6
+ const formik_1 = require("formik");
7
+ const react_1 = require("react");
8
+ function isNamePairError(formik, newEntity, requiredContinueActive = false) {
9
+ if (!(0, formik_1.getIn)(formik.errors, 'given')) {
10
+ return false;
11
+ }
12
+ if (requiredContinueActive) {
13
+ return true;
14
+ }
15
+ if (newEntity) {
16
+ return Boolean(formik.touched.given || formik.touched.family);
17
+ }
18
+ return Boolean(formik.touched.given || formik.touched.family || formik.dirty);
19
+ }
20
+ function authorShowsErrorIndicator(formik, newEntity, requiredContinueActive = false) {
21
+ if (isNamePairError(formik, newEntity, requiredContinueActive)) {
22
+ return true;
23
+ }
24
+ if (((0, formik_1.getIn)(formik.touched, 'email') || requiredContinueActive) &&
25
+ (0, formik_1.getIn)(formik.errors, 'email')) {
26
+ return true;
27
+ }
28
+ if ((0, formik_1.getIn)(formik.touched, 'ORCID') && (0, formik_1.getIn)(formik.errors, 'ORCID')) {
29
+ return true;
30
+ }
31
+ return false;
32
+ }
33
+ const useAuthorShowsErrorIndicator = (newEntity, requiredContinueActive, onChange) => {
34
+ const formik = (0, formik_1.useFormikContext)();
35
+ const hasError = authorShowsErrorIndicator(formik, newEntity, requiredContinueActive);
36
+ (0, react_1.useEffect)(() => {
37
+ onChange?.(hasError);
38
+ }, [hasError, onChange]);
39
+ };
40
+ exports.useAuthorShowsErrorIndicator = useAuthorShowsErrorIndicator;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /*!
3
+ * © 2026 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
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.upsertAffiliation = exports.upsertAuthor = void 0;
19
+ const transform_1 = require("@manuscripts/transform");
20
+ const utils_1 = require("./utils");
21
+ const view_1 = require("./view");
22
+ function insertNode(parentType, childType) {
23
+ return (view, attrs) => {
24
+ const parent = (0, view_1.findChildByType)(view, parentType);
25
+ let tr = view.state.tr;
26
+ if (parent) {
27
+ tr = tr.insert(parent.pos + 1, childType.create(attrs));
28
+ }
29
+ else {
30
+ const insertPos = (0, utils_1.findInsertionPosition)(parentType, view.state.doc);
31
+ const wrapper = parentType.create({
32
+ id: (0, transform_1.generateNodeID)(parentType),
33
+ });
34
+ tr = tr
35
+ .insert(insertPos, wrapper)
36
+ .insert(insertPos + 1, childType.create(attrs));
37
+ }
38
+ view.dispatch(tr);
39
+ };
40
+ }
41
+ function upsertNode(nodeType, insertFn) {
42
+ return (view, attrs) => {
43
+ if (!(0, view_1.updateNodeAttrs)(view, nodeType, attrs)) {
44
+ insertFn(view, attrs);
45
+ }
46
+ };
47
+ }
48
+ const insertAuthorNode = insertNode(transform_1.schema.nodes.contributors, transform_1.schema.nodes.contributor);
49
+ const insertAffiliationNode = insertNode(transform_1.schema.nodes.affiliations, transform_1.schema.nodes.affiliation);
50
+ exports.upsertAuthor = upsertNode(transform_1.schema.nodes.contributor, insertAuthorNode);
51
+ exports.upsertAffiliation = upsertNode(transform_1.schema.nodes.affiliation, insertAffiliationNode);
@@ -15,8 +15,9 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.findWordBoundaries = exports.handleScrollToSelectedTarget = exports.mergeSimilarItems = exports.nearestAncestor = exports.isNodeOfType = void 0;
18
+ exports.findWordBoundaries = exports.handleScrollToSelectedTarget = exports.selectionForOutlineNavigation = exports.mergeSimilarItems = exports.nearestAncestor = exports.isNodeOfType = void 0;
19
19
  const transform_1 = require("@manuscripts/transform");
20
+ const prosemirror_state_1 = require("prosemirror-state");
20
21
  const isNodeOfType = (...type) => (node) => {
21
22
  const [head, ...tail] = type;
22
23
  if (node.type === node.type.schema.nodes[head]) {
@@ -51,6 +52,32 @@ const mergeSimilarItems = (compareFunc, mergeFunc) => (items) => {
51
52
  }, []);
52
53
  };
53
54
  exports.mergeSimilarItems = mergeSimilarItems;
55
+ const selectionForOutlineNavigation = (doc, pos) => {
56
+ const node = doc.nodeAt(pos);
57
+ if (!node || (0, transform_1.isExecutableNodeType)(node.type)) {
58
+ return prosemirror_state_1.NodeSelection.create(doc, pos);
59
+ }
60
+ if (node.isTextblock) {
61
+ return prosemirror_state_1.TextSelection.create(doc, pos + 1);
62
+ }
63
+ if (node.type === transform_1.schema.nodes.section) {
64
+ let textPos = null;
65
+ node.forEach((child, offset) => {
66
+ if (textPos !== null) {
67
+ return;
68
+ }
69
+ if (child.type === transform_1.schema.nodes.section_title ||
70
+ child.type === transform_1.schema.nodes.section_title_plain) {
71
+ textPos = pos + 1 + offset + 1;
72
+ }
73
+ });
74
+ if (textPos !== null) {
75
+ return prosemirror_state_1.TextSelection.create(doc, textPos);
76
+ }
77
+ }
78
+ return prosemirror_state_1.NodeSelection.create(doc, pos);
79
+ };
80
+ exports.selectionForOutlineNavigation = selectionForOutlineNavigation;
54
81
  const handleScrollToSelectedTarget = (view) => {
55
82
  const selection = view.state.selection;
56
83
  if (selection.empty) {
@@ -15,9 +15,23 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.checkID = exports.normalizeAuthor = void 0;
18
+ exports.checkID = exports.normalizeAuthor = exports.normalizeAffiliation = void 0;
19
19
  const transform_1 = require("@manuscripts/transform");
20
20
  const trim = (value) => (value ?? '').trim();
21
+ const normalizeAffiliation = (a) => ({
22
+ ...a,
23
+ institution: trim(a.institution),
24
+ department: trim(a.department),
25
+ addressLine1: trim(a.addressLine1),
26
+ addressLine2: trim(a.addressLine2),
27
+ addressLine3: trim(a.addressLine3),
28
+ postCode: trim(a.postCode),
29
+ country: trim(a.country),
30
+ county: trim(a.county),
31
+ city: trim(a.city),
32
+ email: a.email ?? { href: '', text: '' },
33
+ });
34
+ exports.normalizeAffiliation = normalizeAffiliation;
21
35
  const normalizeAuthor = (author) => {
22
36
  const basic = {
23
37
  id: author.id,
@@ -31,15 +45,13 @@ const normalizeAuthor = (author) => {
31
45
  isAuthenticated: author.isAuthenticated || false,
32
46
  priority: author.priority,
33
47
  isJointContributor: author.isJointContributor || false,
34
- degrees: author.degrees || [],
48
+ degrees: Array.isArray(author.degrees) ? author.degrees : [],
35
49
  footnoteIDs: author.footnoteIDs || [],
36
50
  correspIDs: author.correspIDs || [],
37
51
  prefix: trim(author.prefix),
38
52
  suffix: trim(author.suffix),
53
+ creditRoles: Array.isArray(author.creditRoles) ? author.creditRoles : [],
39
54
  };
40
- if (author.creditRoles && Array.isArray(author.creditRoles)) {
41
- basic.creditRoles = author.creditRoles;
42
- }
43
55
  return basic;
44
56
  };
45
57
  exports.normalizeAuthor = normalizeAuthor;
@@ -24,6 +24,7 @@ const react_router_dom_1 = require("react-router-dom");
24
24
  const ManuscriptsEditor_1 = require("./configs/ManuscriptsEditor");
25
25
  const popper_1 = require("./lib/popper");
26
26
  const use_do_with_debounce_1 = require("./lib/use-do-with-debounce");
27
+ const helpers_1 = require("./lib/helpers");
27
28
  const search_replace_1 = require("./plugins/search-replace");
28
29
  const useEditor = (externalProps) => {
29
30
  const view = (0, react_1.useRef)(undefined);
@@ -109,12 +110,14 @@ const useEditor = (externalProps) => {
109
110
  if (!id || !currentView || !state) {
110
111
  return;
111
112
  }
112
- state.doc.descendants((node, pos) => {
113
+ const viewState = currentView.state;
114
+ viewState.doc.descendants((node, pos) => {
113
115
  if (node.attrs.id === id) {
114
116
  currentView.focus();
115
- const selection = prosemirror_state_1.NodeSelection.create(state.tr.doc, pos);
116
- currentView.dispatch(state.tr.setSelection(selection));
117
- const dom = currentView.domAtPos(pos + 1);
117
+ const selection = (0, helpers_1.selectionForOutlineNavigation)(viewState.doc, pos);
118
+ currentView.dispatch(viewState.tr.setSelection(selection));
119
+ const scrollPos = selection instanceof prosemirror_state_1.TextSelection ? selection.from : pos + 1;
120
+ const dom = currentView.domAtPos(scrollPos);
118
121
  if (dom.node instanceof Element) {
119
122
  dom.node.scrollIntoView({
120
123
  behavior: 'smooth',
@@ -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.12.33';
4
+ exports.VERSION = '3.12.35';
5
5
  exports.MATHJAX_VERSION = '3.2.2';
@@ -10,8 +10,9 @@ export const ChangeHandlingForm = (props) => {
10
10
  return (React.createElement(FlexForm, { id: id, ref: formRef, ...formProps }, children));
11
11
  };
12
12
  export const FlexForm = styled(Form) `
13
- height: 100%;
14
13
  display: flex;
15
14
  flex-direction: column;
16
- overflow: hidden;
15
+ min-height: 0;
16
+ width: 100%;
17
+ box-sizing: border-box;
17
18
  `;