@manuscripts/body-editor 3.12.67 → 3.13.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 (289) hide show
  1. package/dist/cjs/components/toolbar/type-selector/styles.js +2 -1
  2. package/dist/cjs/versions.js +1 -1
  3. package/dist/es/components/toolbar/type-selector/styles.js +2 -1
  4. package/dist/es/versions.js +1 -1
  5. package/dist/types/components/toolbar/type-selector/styles.d.ts +2 -2
  6. package/dist/types/lib/footnotes.d.ts +4 -2
  7. package/dist/types/lib/utils.d.ts +5 -4
  8. package/dist/types/versions.d.ts +1 -1
  9. package/package.json +37 -36
  10. package/{dist/es/lib/statistics.js → src/__mocks__/styleMock.ts} +2 -14
  11. package/src/assets.ts +20 -0
  12. package/src/classes/collabProvider.ts +38 -0
  13. package/src/clipboard.ts +54 -0
  14. package/src/commands.ts +2109 -0
  15. package/src/components/ChangeHandlingForm.tsx +54 -0
  16. package/src/components/LanguageDropdown/index.tsx +343 -0
  17. package/src/components/affiliations/AffiliationForm.tsx +238 -0
  18. package/src/components/affiliations/AffiliationItem.tsx +151 -0
  19. package/src/components/affiliations/AffiliationList.tsx +71 -0
  20. package/src/components/affiliations/AffiliationsModal.tsx +676 -0
  21. package/src/components/affiliations/AffiliationsPanel.tsx +76 -0
  22. package/src/components/affiliations/CreateAffiliationModal.tsx +135 -0
  23. package/src/components/authors/AuthorDetailsForm.tsx +438 -0
  24. package/src/components/authors/AuthorList.tsx +81 -0
  25. package/src/components/authors/AuthorsModal.tsx +642 -0
  26. package/src/components/authors/AuthorsPanel.tsx +69 -0
  27. package/src/components/authors/CreateAuthorModal.tsx +172 -0
  28. package/src/components/authors/CreditDrawer.tsx +71 -0
  29. package/src/components/authors/DraggableAuthor.tsx +228 -0
  30. package/src/components/authors/useManageAffiliations.tsx +77 -0
  31. package/src/components/authors/useManageCredit.tsx +63 -0
  32. package/src/components/authors-affiliations/AuthorsAndAffiliationsModals.tsx +170 -0
  33. package/src/components/authors-affiliations/GenericPanel.tsx +164 -0
  34. package/src/components/authors-affiliations/ModalTabs.tsx +100 -0
  35. package/src/components/awards/AwardForm.tsx +338 -0
  36. package/src/components/awards/AwardModal.tsx +120 -0
  37. package/src/components/awards/DeleteAwardDiaolog.tsx +52 -0
  38. package/src/components/dialog/ConfirmationDialog.tsx +131 -0
  39. package/src/components/form/CreateModalStyles.tsx +37 -0
  40. package/src/components/form/FormFooter.tsx +54 -0
  41. package/src/components/form/FormPlaceholder.tsx +71 -0
  42. package/src/components/form/ModalFormActions.tsx +88 -0
  43. package/src/components/form/UnsavedLabel.tsx +49 -0
  44. package/src/components/hooks/use-debounce.ts +56 -0
  45. package/src/components/hooks/useAffiliationShowsErrorIndicator.ts +51 -0
  46. package/src/components/hooks/useAuthorShowsErrorIndicator.ts +73 -0
  47. package/src/components/keyboard-shortcuts-modal/FormattedShortcut.tsx +56 -0
  48. package/src/components/keyboard-shortcuts-modal/KeyboardShortcutsModal.tsx +283 -0
  49. package/src/components/keyboard-shortcuts-modal/keyboard-shortcuts.ts +304 -0
  50. package/src/components/keywords/AddKeywordInline.tsx +284 -0
  51. package/src/components/keywords/DeleteKeywordDialog.tsx +52 -0
  52. package/src/components/modal-drawer/GenericDrawer.tsx +65 -0
  53. package/src/components/modal-drawer/GenericDrawerGroup.tsx +125 -0
  54. package/src/components/outline/DraggableTree.tsx +438 -0
  55. package/src/components/outline/ManuscriptOutline.tsx +127 -0
  56. package/src/components/outline/Outline.tsx +141 -0
  57. package/src/components/references/BibliographyItemSource.ts +80 -0
  58. package/src/components/references/CitationEditor.tsx +301 -0
  59. package/src/components/references/CitationViewer.tsx +62 -0
  60. package/src/components/references/ImportBibliographyForm.tsx +232 -0
  61. package/src/components/references/ImportBibliographyModal.tsx +159 -0
  62. package/src/components/references/ReferenceForm/PersonDropDown.tsx +93 -0
  63. package/src/components/references/ReferenceForm/ReferenceForm.tsx +701 -0
  64. package/src/components/references/ReferenceForm/config.ts +133 -0
  65. package/src/components/references/ReferenceForm/styled-components.ts +156 -0
  66. package/src/components/references/ReferenceLine.tsx +43 -0
  67. package/src/components/references/ReferenceSearch.tsx +163 -0
  68. package/src/components/references/ReferenceSearchResults.tsx +113 -0
  69. package/src/components/references/ReferenceSearchResultsPlaceholder.tsx +71 -0
  70. package/src/components/references/ReferenceSearchSection.tsx +124 -0
  71. package/src/components/references/ReferencesEditor.tsx +61 -0
  72. package/src/components/references/ReferencesModal.tsx +352 -0
  73. package/src/components/references/SearchInput.tsx +98 -0
  74. package/src/components/toolbar/InsertEmbedDialog.tsx +222 -0
  75. package/src/components/toolbar/InsertTableDialog.tsx +208 -0
  76. package/src/components/toolbar/ListMenuItem.tsx +203 -0
  77. package/src/components/toolbar/helpers.ts +547 -0
  78. package/src/components/toolbar/type-selector/OptionComponent.tsx +89 -0
  79. package/src/components/toolbar/type-selector/TypeSelector.tsx +157 -0
  80. package/src/components/toolbar/type-selector/styles.ts +79 -0
  81. package/src/components/views/CrossReferenceItems.tsx +199 -0
  82. package/src/components/views/DeleteEmbedDialog.tsx +83 -0
  83. package/src/components/views/DeleteFootnoteDialog.tsx +54 -0
  84. package/src/components/views/FigureDropdown.tsx +423 -0
  85. package/src/components/views/FootnotesSelector.tsx +255 -0
  86. package/src/components/views/InsertSpecialCharacter.tsx +245 -0
  87. package/src/components/views/LinkForm.tsx +220 -0
  88. package/src/components/views/TableCellContextMenu.tsx +241 -0
  89. package/src/configs/ManuscriptsEditor.ts +140 -0
  90. package/src/configs/editor-plugins.ts +119 -0
  91. package/src/configs/editor-views.ts +139 -0
  92. package/src/icons.ts +62 -0
  93. package/src/index.ts +65 -0
  94. package/src/keys/highlight.ts +65 -0
  95. package/src/keys/index.ts +33 -0
  96. package/src/keys/keyword.ts +69 -0
  97. package/src/keys/list.ts +156 -0
  98. package/src/keys/misc.ts +112 -0
  99. package/src/keys/title.ts +221 -0
  100. package/src/lib/__tests__/__fixtures__/doc.json +388 -0
  101. package/src/lib/__tests__/__snapshots__/paste.test.ts.snap +24 -0
  102. package/src/lib/__tests__/authors.test.ts +202 -0
  103. package/src/lib/__tests__/helpers.test.ts +46 -0
  104. package/src/lib/__tests__/paste.test.ts +57 -0
  105. package/src/lib/__tests__/plugins.test.ts +176 -0
  106. package/src/lib/__tests__/url.test.ts +31 -0
  107. package/src/lib/array-reducer.ts +68 -0
  108. package/src/lib/authors-and-affiliations.ts +81 -0
  109. package/src/lib/authors.ts +67 -0
  110. package/src/lib/capabilities.ts +55 -0
  111. package/src/lib/codemirror.ts +37 -0
  112. package/src/lib/comments.ts +123 -0
  113. package/src/lib/context-menu.ts +745 -0
  114. package/src/lib/copy.ts +30 -0
  115. package/src/lib/crossref.ts +90 -0
  116. package/src/lib/dnd.ts +29 -0
  117. package/src/lib/doc.ts +167 -0
  118. package/src/lib/dompurify.ts +28 -0
  119. package/src/lib/files.ts +180 -0
  120. package/src/lib/footnotes.ts +83 -0
  121. package/src/lib/get-media-type.ts +105 -0
  122. package/src/lib/helpers.ts +199 -0
  123. package/src/lib/hierarchy.ts +117 -0
  124. package/src/lib/languages.ts +37 -0
  125. package/src/lib/lists.ts +56 -0
  126. package/src/lib/math.ts +111 -0
  127. package/src/lib/media.ts +334 -0
  128. package/src/lib/navigation-utils.ts +235 -0
  129. package/src/lib/normalize.ts +70 -0
  130. package/src/lib/paste.ts +304 -0
  131. package/src/lib/placeholder.ts +32 -0
  132. package/src/lib/platform.ts +18 -0
  133. package/src/lib/plugins.ts +22 -0
  134. package/src/lib/popper.ts +180 -0
  135. package/src/lib/position-menu.ts +184 -0
  136. package/src/lib/references.ts +94 -0
  137. package/src/lib/template.ts +29 -0
  138. package/src/lib/track-changes-utils.ts +34 -0
  139. package/{dist/types/lib/statistics.d.ts → src/lib/url.ts} +11 -8
  140. package/src/lib/use-do-with-debounce.ts +39 -0
  141. package/src/lib/utils.ts +323 -0
  142. package/src/lib/view.ts +100 -0
  143. package/src/menus.tsx +684 -0
  144. package/src/node-type-icons.tsx +83 -0
  145. package/src/plugins/__tests__/__fixtures__/deleted-footnote.json +140 -0
  146. package/src/plugins/__tests__/__fixtures__/inserted-footnote.json +153 -0
  147. package/src/plugins/__tests__/footnotes.test.ts +67 -0
  148. package/src/plugins/accessibility_element.ts +219 -0
  149. package/src/plugins/add-subtitle.ts +102 -0
  150. package/src/plugins/affiliations.ts +136 -0
  151. package/src/plugins/alt-titles.ts +219 -0
  152. package/src/plugins/bibliography.ts +235 -0
  153. package/src/plugins/comments.ts +328 -0
  154. package/src/plugins/cross-references.ts +70 -0
  155. package/src/plugins/detect-inconsistency/detect-inconsistency-utils.ts +102 -0
  156. package/src/plugins/detect-inconsistency/index.ts +55 -0
  157. package/src/plugins/detect-inconsistency/validators.ts +283 -0
  158. package/src/plugins/doi.ts +66 -0
  159. package/src/plugins/editor-props.ts +39 -0
  160. package/src/plugins/elements.ts +60 -0
  161. package/src/plugins/footnotes.ts +298 -0
  162. package/src/plugins/link.ts +53 -0
  163. package/src/plugins/lock-body.ts +136 -0
  164. package/src/plugins/move-node.ts +55 -0
  165. package/src/plugins/objects.ts +125 -0
  166. package/src/plugins/paragraphs.ts +90 -0
  167. package/src/plugins/persist.ts +64 -0
  168. package/src/plugins/persistent-cursor.ts +66 -0
  169. package/src/plugins/placeholder.ts +219 -0
  170. package/src/plugins/prevent-empty.ts +50 -0
  171. package/src/plugins/search-replace/index.ts +157 -0
  172. package/src/plugins/search-replace/lib.ts +95 -0
  173. package/src/plugins/section_category.ts +212 -0
  174. package/src/plugins/section_title/autocompletion.ts +87 -0
  175. package/src/plugins/section_title/index.ts +105 -0
  176. package/src/plugins/selected-suggestion.ts +243 -0
  177. package/src/plugins/tables-cursor-fix.ts +143 -0
  178. package/src/plugins/translations.ts +263 -0
  179. package/src/rules.ts +60 -0
  180. package/src/selection.ts +112 -0
  181. package/src/testing/default-capabilities.ts +48 -0
  182. package/src/testing/default-editor-data.ts +73 -0
  183. package/src/testing/empty-editor-doc.json +62 -0
  184. package/src/testing/polyfill-dom.ts +43 -0
  185. package/src/testing/section-categories.json +161 -0
  186. package/src/testing/setup-editor.ts +55 -0
  187. package/src/tests.ts +42 -0
  188. package/src/toolbar.tsx +259 -0
  189. package/src/types/@citation-js/core.d.ts +16 -0
  190. package/src/types/@citation-js/index.d.ts +16 -0
  191. package/src/types/@citation-js/plugin-bibtex.d.ts +16 -0
  192. package/src/types/@citation-js/plugin-csl.d.ts +16 -0
  193. package/src/types/@citation-js/plugin-doi.d.ts +16 -0
  194. package/src/types/@citation-js/plugin-enw.d.ts +16 -0
  195. package/src/types/@citation-js/plugin-pubmed.d.ts +16 -0
  196. package/src/types/@citation-js/plugin-ris.d.ts +16 -0
  197. package/src/types/citeproc.d.ts +124 -0
  198. package/src/types/css.d.ts +16 -0
  199. package/src/types/json.d.ts +17 -0
  200. package/src/types/prosemirror-dev-tools.d.ts +16 -0
  201. package/src/types/prosemirror-dropcursor.d.ts +16 -0
  202. package/src/types/styled-components.d.ts +23 -0
  203. package/src/types.ts +49 -0
  204. package/src/useEditor.ts +244 -0
  205. package/src/versions.ts +3 -0
  206. package/src/views/ReactSubView.tsx +145 -0
  207. package/src/views/abstracts.ts +46 -0
  208. package/src/views/accessibility_element.ts +86 -0
  209. package/src/views/affiliations.ts +254 -0
  210. package/src/views/alt_title.ts +85 -0
  211. package/src/views/alt_titles_section.ts +97 -0
  212. package/src/views/attachment.ts +160 -0
  213. package/src/views/attachments.ts +72 -0
  214. package/src/views/author_notes.ts +96 -0
  215. package/src/views/award.ts +194 -0
  216. package/src/views/awards.ts +59 -0
  217. package/src/views/base_node_view.ts +85 -0
  218. package/src/views/bibliography_element.ts +313 -0
  219. package/src/views/block_view.ts +100 -0
  220. package/src/views/blockquote_element.ts +26 -0
  221. package/src/views/blockquote_element_editable.ts +24 -0
  222. package/src/views/box_element.ts +33 -0
  223. package/src/views/caption.ts +37 -0
  224. package/src/views/caption_title.ts +33 -0
  225. package/src/views/citation.ts +67 -0
  226. package/src/views/citation_editable.ts +312 -0
  227. package/src/views/contributors.ts +341 -0
  228. package/src/views/creators.ts +82 -0
  229. package/src/views/cross_reference.ts +74 -0
  230. package/src/views/cross_reference_editable.ts +113 -0
  231. package/src/views/editable_block.ts +141 -0
  232. package/src/views/embed.ts +345 -0
  233. package/src/views/empty.ts +26 -0
  234. package/src/views/equation.ts +47 -0
  235. package/src/views/equation_editable.ts +84 -0
  236. package/src/views/equation_element.ts +29 -0
  237. package/src/views/equation_element_editable.ts +21 -0
  238. package/src/views/figure.ts +84 -0
  239. package/src/views/figure_editable.ts +361 -0
  240. package/src/views/figure_element.ts +197 -0
  241. package/src/views/figure_element_editable.ts +21 -0
  242. package/src/views/footnote.ts +236 -0
  243. package/src/views/footnotes_element.ts +54 -0
  244. package/src/views/general_table_footnote.ts +140 -0
  245. package/src/views/hero_image.ts +76 -0
  246. package/src/views/hero_image_editable.ts +21 -0
  247. package/src/views/image_element.ts +373 -0
  248. package/src/views/image_element_editable.ts +21 -0
  249. package/src/views/inline_equation.ts +47 -0
  250. package/src/views/inline_equation_editable.ts +70 -0
  251. package/src/views/inline_footnote.ts +264 -0
  252. package/src/views/inline_footnote_editable.ts +20 -0
  253. package/src/views/keyword.ts +127 -0
  254. package/src/views/keyword_group.ts +109 -0
  255. package/src/views/link.ts +27 -0
  256. package/src/views/link_editable.ts +169 -0
  257. package/src/views/list.ts +46 -0
  258. package/src/views/list_item.ts +26 -0
  259. package/src/views/paragraph.ts +26 -0
  260. package/src/views/paragraph_editable.ts +21 -0
  261. package/src/views/placeholder.ts +35 -0
  262. package/src/views/placeholder_element.ts +38 -0
  263. package/src/views/placeholder_element_editable.ts +21 -0
  264. package/src/views/pullquote_element.ts +106 -0
  265. package/src/views/pullquote_element_editable.ts +24 -0
  266. package/src/views/quote_image_editable.ts +84 -0
  267. package/src/views/section.ts +64 -0
  268. package/src/views/section_label.ts +20 -0
  269. package/src/views/section_title.ts +87 -0
  270. package/src/views/section_title_editable.ts +21 -0
  271. package/src/views/subtitle.ts +42 -0
  272. package/src/views/subtitle_editable.ts +20 -0
  273. package/src/views/subtitles.ts +34 -0
  274. package/src/views/subtitles_editable.ts +21 -0
  275. package/src/views/supplement.ts +236 -0
  276. package/src/views/supplement_editable.ts +20 -0
  277. package/src/views/supplements.ts +65 -0
  278. package/src/views/supplements_editable.ts +21 -0
  279. package/src/views/table_cell.ts +150 -0
  280. package/src/views/table_element.ts +33 -0
  281. package/src/views/table_element_editable.ts +21 -0
  282. package/src/views/table_element_footer.ts +41 -0
  283. package/src/views/title.ts +46 -0
  284. package/src/views/title_editable.ts +20 -0
  285. package/src/views/trans_graphical_abstract.ts +55 -0
  286. package/src/views/trans_graphical_abstract_editable.ts +21 -0
  287. package/src/views/translated_abstract.ts +53 -0
  288. package/src/views/translated_abstract_editable.ts +21 -0
  289. package/dist/cjs/lib/statistics.js +0 -38
@@ -0,0 +1,170 @@
1
+ /*!
2
+ * © 2026 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
+
17
+ /**
18
+ * Coordinates the authors and affiliations modals, including opening one from
19
+ * the other via an overlay (e.g. affiliations from the authors modal and vice versa).
20
+ */
21
+ import { ManuscriptEditorView, schema } from '@manuscripts/transform'
22
+ import { EditorView } from 'prosemirror-view'
23
+ import React, { useState } from 'react'
24
+
25
+ import { AffiliationAttrs, ContributorAttrs } from '../../lib/authors'
26
+ import {
27
+ upsertAuthor,
28
+ upsertAffiliation,
29
+ } from '../../lib/authors-and-affiliations'
30
+ import { getEditorProps } from '../../plugins/editor-props'
31
+ import ReactSubView from '../../views/ReactSubView'
32
+ import {
33
+ deleteNode,
34
+ findChildrenAttrsByType,
35
+ updateNodeAttrs,
36
+ } from '../../lib/view'
37
+ import {
38
+ AffiliationsModal,
39
+ AffiliationsModalProps,
40
+ } from '../affiliations/AffiliationsModal'
41
+ import { CreateAffiliationModal } from '../affiliations/CreateAffiliationModal'
42
+ import { AuthorsModal, AuthorsModalProps } from '../authors/AuthorsModal'
43
+ import { CreateAuthorModal } from '../authors/CreateAuthorModal'
44
+
45
+ export interface AuthorsAndAffiliationsModalsProps {
46
+ initialModal: 'authors' | 'affiliations'
47
+ view: ManuscriptEditorView
48
+ author?: ContributorAttrs
49
+ affiliation?: AffiliationAttrs
50
+ addNewAuthor?: boolean
51
+ addNewAffiliation?: boolean
52
+ }
53
+
54
+ export const AuthorsAndAffiliationsModals: React.FC<
55
+ AuthorsAndAffiliationsModalsProps
56
+ > = ({
57
+ initialModal,
58
+ view,
59
+ author,
60
+ affiliation,
61
+ addNewAuthor,
62
+ addNewAffiliation,
63
+ }) => {
64
+ const [showOverlay, setShowOverlay] = useState(false)
65
+ const [authors, setAuthors] = useState(() =>
66
+ findChildrenAttrsByType<ContributorAttrs>(view, schema.nodes.contributor)
67
+ )
68
+ const [affiliations, setAffiliations] = useState(() =>
69
+ findChildrenAttrsByType<AffiliationAttrs>(view, schema.nodes.affiliation)
70
+ )
71
+
72
+ const handleOpenOverlay = () => setShowOverlay(true)
73
+
74
+ const handleOverlayClose = () => {
75
+ setShowOverlay(false)
76
+ setAuthors(
77
+ findChildrenAttrsByType<ContributorAttrs>(view, schema.nodes.contributor)
78
+ )
79
+ setAffiliations(
80
+ findChildrenAttrsByType<AffiliationAttrs>(view, schema.nodes.affiliation)
81
+ )
82
+ }
83
+
84
+ const authorsProps: AuthorsModalProps = {
85
+ author,
86
+ authors,
87
+ affiliations,
88
+ addNewAuthor,
89
+ onSaveAuthor: (a) => upsertAuthor(view, a),
90
+ onDeleteAuthor: (a) => deleteNode(view, a.id),
91
+ }
92
+
93
+ const affiliationsProps: AffiliationsModalProps = {
94
+ affiliation,
95
+ authors,
96
+ affiliations,
97
+ addNewAffiliation,
98
+ onSaveAffiliation: (a) => upsertAffiliation(view, a),
99
+ onDeleteAffiliation: (a) => deleteNode(view, a.id),
100
+ onUpdateAuthors: (updated) =>
101
+ updated.forEach((a) =>
102
+ updateNodeAttrs(view, schema.nodes.contributor, a)
103
+ ),
104
+ }
105
+
106
+ if (initialModal === 'authors') {
107
+ return (
108
+ <>
109
+ <AuthorsModal
110
+ {...authorsProps}
111
+ onOpenAffiliationsModal={handleOpenOverlay}
112
+ />
113
+ {showOverlay && (
114
+ <CreateAffiliationModal
115
+ affiliationsCount={affiliations.length}
116
+ onSave={(a) => upsertAffiliation(view, a)}
117
+ onClose={handleOverlayClose}
118
+ />
119
+ )}
120
+ </>
121
+ )
122
+ }
123
+
124
+ return (
125
+ <>
126
+ <AffiliationsModal
127
+ {...affiliationsProps}
128
+ openAuthorsModal={handleOpenOverlay}
129
+ />
130
+ {showOverlay && (
131
+ <CreateAuthorModal
132
+ authorsCount={authors.length}
133
+ affiliations={affiliations}
134
+ onSave={(a) => upsertAuthor(view, a)}
135
+ onClose={handleOverlayClose}
136
+ />
137
+ )}
138
+ </>
139
+ )
140
+ }
141
+
142
+ export const openAuthorsAndAffiliationsModals = (
143
+ pos: number,
144
+ view: ManuscriptEditorView | EditorView | undefined,
145
+ initialModal: 'authors' | 'affiliations'
146
+ ) => {
147
+ if (!view) {
148
+ return
149
+ }
150
+
151
+ const { state } = view
152
+ const props = getEditorProps(state)
153
+ const componentProps: AuthorsAndAffiliationsModalsProps = {
154
+ initialModal,
155
+ view: view as ManuscriptEditorView,
156
+ addNewAuthor: initialModal === 'authors',
157
+ addNewAffiliation: initialModal === 'affiliations',
158
+ }
159
+
160
+ const dialog = ReactSubView(
161
+ props,
162
+ AuthorsAndAffiliationsModals,
163
+ componentProps,
164
+ state.doc,
165
+ () => pos,
166
+ view
167
+ )
168
+ view.focus()
169
+ document.body.appendChild(dialog)
170
+ }
@@ -0,0 +1,164 @@
1
+ /*!
2
+ * © 2026 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
+
17
+ import {
18
+ AddedIcon,
19
+ AddIcon,
20
+ DrawerIcon,
21
+ DrawerItemLabel,
22
+ DrawerItemMeta,
23
+ DrawerItemsList,
24
+ DrawerLabelContainer,
25
+ DrawerListItem,
26
+ IconButton,
27
+ PlusIcon,
28
+ } from '@manuscripts/style-guide'
29
+ import React, { useMemo } from 'react'
30
+ import styled from 'styled-components'
31
+
32
+ export const ListItems = DrawerItemsList
33
+
34
+ const Panel = styled.div`
35
+ display: flex;
36
+ flex-direction: column;
37
+ `
38
+
39
+ const PanelHeader = styled.div`
40
+ display: flex;
41
+ align-items: flex-start;
42
+ padding: ${(props) => props.theme.grid.unit * 2}px
43
+ ${(props) => props.theme.grid.unit * 4}px;
44
+ `
45
+
46
+ const PanelCreateButton = styled(IconButton)`
47
+ color: #0d79d0;
48
+ font-size: 14px;
49
+ font-weight: 400;
50
+ font-style: normal;
51
+ line-height: 1;
52
+ width: auto;
53
+ height: 24px;
54
+ margin-left: auto;
55
+ svg {
56
+ margin-right: 4px;
57
+ }
58
+ `
59
+
60
+ const PanelEmpty = styled.div`
61
+ display: flex;
62
+ flex-direction: column;
63
+ align-items: center;
64
+ justify-content: center;
65
+ gap: 16px;
66
+ padding: ${(props) => props.theme.grid.unit * 20}px
67
+ ${(props) => props.theme.grid.unit * 4}px;
68
+ `
69
+
70
+ const PanelEmptyIcon = styled.div`
71
+ width: 80px;
72
+ height: 80px;
73
+ flex-shrink: 0;
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: center;
77
+ svg {
78
+ width: 100%;
79
+ height: 100%;
80
+ }
81
+ `
82
+
83
+ const PanelEmptyText = styled.p`
84
+ margin: 0;
85
+ font-size: 18px;
86
+ line-height: 24px;
87
+ text-align: center;
88
+ letter-spacing: -0.369px;
89
+ `
90
+
91
+ export interface GenericPanelProps {
92
+ createLabel: string
93
+ onCreate: () => void
94
+ createDataCy: string
95
+ emptyDataCy: string
96
+ isEmpty: boolean
97
+ emptyIcon: React.ReactNode
98
+ emptyMessage: React.ReactNode
99
+ children: React.ReactNode
100
+ }
101
+
102
+ export const GenericPanel: React.FC<GenericPanelProps> = ({
103
+ createLabel,
104
+ onCreate,
105
+ createDataCy,
106
+ emptyDataCy,
107
+ isEmpty,
108
+ emptyIcon,
109
+ emptyMessage,
110
+ children,
111
+ }) => (
112
+ <Panel>
113
+ <PanelHeader>
114
+ <PanelCreateButton onClick={onCreate} data-cy={createDataCy}>
115
+ <PlusIcon />
116
+ {createLabel}
117
+ </PanelCreateButton>
118
+ </PanelHeader>
119
+ {isEmpty ? (
120
+ <PanelEmpty data-cy={emptyDataCy}>
121
+ <PanelEmptyIcon aria-hidden>{emptyIcon}</PanelEmptyIcon>
122
+ <PanelEmptyText>{emptyMessage}</PanelEmptyText>
123
+ </PanelEmpty>
124
+ ) : (
125
+ children
126
+ )}
127
+ </Panel>
128
+ )
129
+
130
+ export interface ListItemProps {
131
+ selected: boolean
132
+ onClick: () => void
133
+ primary: React.ReactNode
134
+ secondary?: React.ReactNode
135
+ }
136
+
137
+ export const ListItem: React.FC<ListItemProps> = ({
138
+ selected,
139
+ onClick,
140
+ primary,
141
+ secondary,
142
+ }) => (
143
+ <DrawerListItem data-cy="item" selected={selected} onClick={onClick}>
144
+ <DrawerIcon>
145
+ {selected ? (
146
+ <AddedIcon width={22} height={22} />
147
+ ) : (
148
+ <AddIcon width={22} height={22} />
149
+ )}
150
+ </DrawerIcon>
151
+ <DrawerLabelContainer>
152
+ <DrawerItemLabel>{primary}</DrawerItemLabel>
153
+ {secondary != null && secondary !== '' ? (
154
+ <DrawerItemMeta>{secondary}</DrawerItemMeta>
155
+ ) : null}
156
+ </DrawerLabelContainer>
157
+ </DrawerListItem>
158
+ )
159
+
160
+ export function useListSelectedIds(
161
+ selectedItems: { id: string }[]
162
+ ): Set<string> {
163
+ return useMemo(() => new Set(selectedItems.map((x) => x.id)), [selectedItems])
164
+ }
@@ -0,0 +1,100 @@
1
+ /*!
2
+ * © 2026 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
+
17
+ import { InspectorTab, InspectorTabList } from '@manuscripts/style-guide'
18
+ import React from 'react'
19
+ import styled from 'styled-components'
20
+
21
+ export interface ModalTabsProps {
22
+ tabLabels: string[]
23
+ tabErrorIndicators?: boolean[]
24
+ tabWarningIndicators?: boolean[]
25
+ }
26
+
27
+ export const ModalTabs: React.FC<ModalTabsProps> = ({
28
+ tabLabels,
29
+ tabErrorIndicators,
30
+ tabWarningIndicators,
31
+ }) => (
32
+ <StyledTabList data-cy="ModalTabs">
33
+ {tabLabels.map((label, i) => {
34
+ const hasError = tabErrorIndicators?.[i]
35
+ const showWarning = tabWarningIndicators?.[i] && !hasError
36
+ return (
37
+ <StyledTab key={label} data-cy="ModalTab">
38
+ {label}
39
+ {(showWarning || hasError) && (
40
+ <TabIndicatorGroup role="presentation">
41
+ {showWarning ? <TabWarningDot aria-hidden /> : null}
42
+ {hasError ? <TabErrorDot aria-hidden /> : null}
43
+ </TabIndicatorGroup>
44
+ )}
45
+ </StyledTab>
46
+ )
47
+ })}
48
+ </StyledTabList>
49
+ )
50
+
51
+ const TabIndicatorGroup = styled.span`
52
+ display: inline-flex;
53
+ align-items: center;
54
+ gap: 6px;
55
+ margin-left: 6px;
56
+ flex-shrink: 0;
57
+ `
58
+
59
+ const TabErrorDot = styled.span`
60
+ display: inline-block;
61
+ width: 8px;
62
+ height: 8px;
63
+ border-radius: 50%;
64
+ background: #cf1322;
65
+ flex-shrink: 0;
66
+ vertical-align: middle;
67
+ `
68
+
69
+ const TabWarningDot = styled.span`
70
+ display: inline-block;
71
+ width: 8px;
72
+ height: 8px;
73
+ border-radius: 50%;
74
+ background: ${(props) => props.theme.colors.text.warning};
75
+ flex-shrink: 0;
76
+ vertical-align: middle;
77
+ `
78
+
79
+ const StyledTab = styled(InspectorTab)`
80
+ border-radius: 14px;
81
+ flex: 1;
82
+ display: inline-flex;
83
+ align-items: center;
84
+ justify-content: center;
85
+
86
+ &[aria-selected='true'] {
87
+ background: ${(props) => props.theme.colors.background.primary};
88
+ border: unset;
89
+ color: ${(props) => props.theme.colors.text.primary} !important;
90
+ font-weight: 700;
91
+ }
92
+ `
93
+
94
+ const StyledTabList = styled(InspectorTabList)`
95
+ display: flex;
96
+ justify-content: space-evenly;
97
+ border-radius: 14px;
98
+ background: #e2e2e2 !important;
99
+ padding: 2px;
100
+ `