@manuscripts/body-editor 3.16.2 → 3.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/cjs/lib/context-menu.js +28 -11
  2. package/dist/cjs/lib/popper.js +15 -1
  3. package/dist/cjs/lib/position-menu.js +175 -100
  4. package/dist/cjs/plugins/detect-inconsistency/index.js +6 -4
  5. package/dist/cjs/plugins/persist.js +3 -0
  6. package/dist/cjs/versions.js +1 -1
  7. package/dist/cjs/views/box_element.js +23 -1
  8. package/dist/cjs/views/caption_title.js +1 -1
  9. package/dist/cjs/views/equation.js +2 -0
  10. package/dist/cjs/views/equation_editable.js +2 -0
  11. package/dist/cjs/views/image_element.js +7 -62
  12. package/dist/cjs/views/inline_equation.js +2 -0
  13. package/dist/cjs/views/inline_equation_editable.js +2 -0
  14. package/dist/cjs/views/pullquote_element.js +23 -1
  15. package/dist/cjs/views/table_element.js +23 -1
  16. package/dist/es/lib/context-menu.js +29 -12
  17. package/dist/es/lib/popper.js +15 -1
  18. package/dist/es/lib/position-menu.js +173 -91
  19. package/dist/es/plugins/detect-inconsistency/index.js +6 -4
  20. package/dist/es/plugins/persist.js +3 -0
  21. package/dist/es/versions.js +1 -1
  22. package/dist/es/views/box_element.js +23 -1
  23. package/dist/es/views/caption_title.js +1 -1
  24. package/dist/es/views/equation.js +2 -0
  25. package/dist/es/views/equation_editable.js +2 -0
  26. package/dist/es/views/image_element.js +7 -62
  27. package/dist/es/views/inline_equation.js +2 -0
  28. package/dist/es/views/inline_equation_editable.js +2 -0
  29. package/dist/es/views/pullquote_element.js +23 -1
  30. package/dist/es/views/table_element.js +23 -1
  31. package/dist/types/lib/popper.d.ts +4 -2
  32. package/dist/types/lib/position-menu.d.ts +36 -11
  33. package/dist/types/versions.d.ts +1 -1
  34. package/dist/types/views/box_element.d.ts +6 -0
  35. package/dist/types/views/image_element.d.ts +2 -9
  36. package/dist/types/views/pullquote_element.d.ts +6 -0
  37. package/dist/types/views/table_element.d.ts +6 -0
  38. package/package.json +1 -1
  39. package/src/lib/context-menu.ts +42 -21
  40. package/src/lib/popper.ts +18 -1
  41. package/src/lib/position-menu.ts +242 -137
  42. package/src/plugins/detect-inconsistency/index.ts +6 -4
  43. package/src/plugins/persist.ts +3 -0
  44. package/src/versions.ts +1 -1
  45. package/src/views/box_element.ts +34 -1
  46. package/src/views/caption_title.ts +1 -1
  47. package/src/views/equation.ts +5 -0
  48. package/src/views/equation_editable.ts +3 -0
  49. package/src/views/image_element.ts +12 -89
  50. package/src/views/inline_equation.ts +5 -0
  51. package/src/views/inline_equation_editable.ts +3 -0
  52. package/src/views/pullquote_element.ts +33 -1
  53. package/src/views/table_element.ts +34 -1
  54. package/styles/AdvancedEditor.css +5 -8
  55. package/styles/Editor.css +11 -6
@@ -13,21 +13,13 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { ContextMenu } from '@manuscripts/style-guide';
17
16
  import { schema } from '@manuscripts/transform';
18
17
  import { deleteIcon, linkIcon } from '../icons';
19
18
  import { addInteractionHandlers, createMediaPlaceholder, MediaType, } from '../lib/media';
20
19
  import { handleEnterKey } from '../lib/navigation-utils';
21
- import { createPositionMenuWrapper } from '../lib/position-menu';
20
+ import { HorizontalPositionMenu } from '../lib/position-menu';
22
21
  import BlockView from './block_view';
23
22
  import { createNodeView } from './creators';
24
- import ReactSubView from './ReactSubView';
25
- export var figurePositions;
26
- (function (figurePositions) {
27
- figurePositions["left"] = "half-left";
28
- figurePositions["right"] = "half-right";
29
- figurePositions["default"] = "";
30
- })(figurePositions || (figurePositions = {}));
31
23
  export class ImageElementView extends BlockView {
32
24
  constructor() {
33
25
  super(...arguments);
@@ -42,46 +34,6 @@ export class ImageElementView extends BlockView {
42
34
  this.setExtLink({ extLink: result.id });
43
35
  this.updateContents();
44
36
  };
45
- this.showPositionMenu = () => {
46
- const firstFigure = this.getFirstFigure();
47
- if (!firstFigure) {
48
- return;
49
- }
50
- this.props.popper.destroy();
51
- const options = [
52
- {
53
- label: 'Left',
54
- action: () => {
55
- this.props.popper.destroy();
56
- this.updateAllFiguresPosition(figurePositions.left);
57
- },
58
- icon: 'ImageLeft',
59
- selected: this.figurePosition === figurePositions.left,
60
- },
61
- {
62
- label: 'Default',
63
- action: () => {
64
- this.props.popper.destroy();
65
- this.updateAllFiguresPosition(figurePositions.default);
66
- },
67
- icon: 'ImageDefault',
68
- selected: !this.figurePosition,
69
- },
70
- {
71
- label: 'Right',
72
- action: () => {
73
- this.props.popper.destroy();
74
- this.updateAllFiguresPosition(figurePositions.right);
75
- },
76
- icon: 'ImageRight',
77
- selected: this.figurePosition === figurePositions.right,
78
- },
79
- ];
80
- const componentProps = {
81
- actions: options,
82
- };
83
- this.props.popper.show(this.positionMenuWrapper, ReactSubView(this.props, ContextMenu, componentProps, this.node, this.getPos, this.view, ['context-menu', 'position-menu']), 'left', false);
84
- };
85
37
  this.removeExtLink = () => {
86
38
  this.setExtLink({ extLink: '' });
87
39
  };
@@ -127,18 +79,6 @@ export class ImageElementView extends BlockView {
127
79
  addTools() {
128
80
  this.addPositionMenu();
129
81
  }
130
- addPositionMenu() {
131
- if (this.props.getCapabilities()?.editArticle) {
132
- const existingMenu = this.container.querySelector('.position-menu');
133
- if (existingMenu) {
134
- existingMenu.remove();
135
- }
136
- const firstFigure = this.getFirstFigure();
137
- this.figurePosition = firstFigure?.attrs.type || figurePositions.default;
138
- this.positionMenuWrapper = createPositionMenuWrapper(this.figurePosition, this.showPositionMenu, this.props);
139
- this.container.prepend(this.positionMenuWrapper);
140
- }
141
- }
142
82
  getFirstFigure() {
143
83
  if (this.node.type === schema.nodes.image_element) {
144
84
  const figureNode = this.node.firstChild;
@@ -176,6 +116,12 @@ export class ImageElementView extends BlockView {
176
116
  }
177
117
  return figures;
178
118
  }
119
+ addPositionMenu() {
120
+ if (!this.positionMenu) {
121
+ this.positionMenu = new HorizontalPositionMenu(this, this.updateAllFiguresPosition.bind(this), this.container, () => this.getFirstFigure());
122
+ }
123
+ this.positionMenu.create();
124
+ }
179
125
  updateAllFiguresPosition(position) {
180
126
  const figures = this.getAllFigures();
181
127
  const { tr } = this.view.state;
@@ -186,7 +132,6 @@ export class ImageElementView extends BlockView {
186
132
  });
187
133
  });
188
134
  this.view.dispatch(tr);
189
- this.figurePosition = position;
190
135
  }
191
136
  createDnDPlaceholder() {
192
137
  const can = this.props.getCapabilities();
@@ -16,6 +16,7 @@
16
16
  import { renderMath } from '../lib/math';
17
17
  import { BaseNodeView } from './base_node_view';
18
18
  import { createNodeView } from './creators';
19
+ import { handleEnterKey } from '../lib/navigation-utils';
19
20
  export class InlineEquationView extends BaseNodeView {
20
21
  constructor() {
21
22
  super(...arguments);
@@ -24,6 +25,7 @@ export class InlineEquationView extends BaseNodeView {
24
25
  initialise() {
25
26
  this.createDOM();
26
27
  this.updateContents();
28
+ this.dom.addEventListener('keydown', handleEnterKey(() => this.selectNode()));
27
29
  }
28
30
  updateContents() {
29
31
  super.updateContents();
@@ -34,6 +34,8 @@ export class InlineEquationEditableView extends InlineEquationView {
34
34
  Esc: () => {
35
35
  this.props.popper.destroy();
36
36
  this.view.focus();
37
+ const tabbableView = this.dom.querySelector('[tabindex="0"]');
38
+ tabbableView?.focus();
37
39
  },
38
40
  },
39
41
  });
@@ -21,6 +21,7 @@ import { setCommentSelection } from '../plugins/comments';
21
21
  import BlockView from './block_view';
22
22
  import { createNodeOrElementView } from './creators';
23
23
  import ReactSubView from './ReactSubView';
24
+ import { HorizontalPositionMenu } from '../lib/position-menu';
24
25
  export class PullquoteElementView extends BlockView {
25
26
  constructor() {
26
27
  super(...arguments);
@@ -43,7 +44,10 @@ export class PullquoteElementView extends BlockView {
43
44
  this.contentDOM = document.createElement(this.elementType);
44
45
  this.contentDOM.className = 'block';
45
46
  this.contentDOM.classList.add('pullquote');
46
- this.dom.appendChild(this.contentDOM);
47
+ this.container = document.createElement('div');
48
+ this.container.classList.add('container');
49
+ this.container.appendChild(this.contentDOM);
50
+ this.dom.appendChild(this.container);
47
51
  this.dom.addEventListener('click', this.handleClick);
48
52
  };
49
53
  this.actionGutterButtons = () => {
@@ -78,5 +82,23 @@ export class PullquoteElementView extends BlockView {
78
82
  tr.insert(this.getPos() + 1, schema.nodes.quote_image.create());
79
83
  this.view.dispatch(tr);
80
84
  }
85
+ updateContents() {
86
+ super.updateContents();
87
+ this.addTools();
88
+ }
89
+ addTools() {
90
+ this.addPositionMenu();
91
+ }
92
+ addPositionMenu() {
93
+ if (!this.positionMenu) {
94
+ this.positionMenu = new HorizontalPositionMenu(this, this.updateHorizontalPosition, this.container);
95
+ }
96
+ this.positionMenu.create();
97
+ }
98
+ updateHorizontalPosition(horizontalPosition) {
99
+ const tr = this.view.state.tr;
100
+ tr.setNodeAttribute(this.getPos(), 'type', horizontalPosition);
101
+ this.view.dispatch(tr);
102
+ }
81
103
  }
82
104
  export default createNodeOrElementView(PullquoteElementView, 'aside');
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import BlockView from './block_view';
17
17
  import { createNodeView } from './creators';
18
+ import { HorizontalPositionMenu } from '../lib/position-menu';
18
19
  export class TableElementView extends BlockView {
19
20
  constructor() {
20
21
  super(...arguments);
@@ -23,8 +24,29 @@ export class TableElementView extends BlockView {
23
24
  this.contentDOM = document.createElement('figure');
24
25
  this.contentDOM.classList.add('block');
25
26
  this.contentDOM.setAttribute('id', this.node.attrs.id);
26
- this.dom.appendChild(this.contentDOM);
27
+ this.container = document.createElement('div');
28
+ this.container.classList.add('container');
29
+ this.container.appendChild(this.contentDOM);
30
+ this.dom.appendChild(this.container);
27
31
  };
28
32
  }
33
+ updateContents() {
34
+ super.updateContents();
35
+ this.addTools();
36
+ }
37
+ addTools() {
38
+ this.addPositionMenu();
39
+ }
40
+ addPositionMenu() {
41
+ if (!this.positionMenu) {
42
+ this.positionMenu = new HorizontalPositionMenu(this, this.updateHorizontalPosition, this.container);
43
+ }
44
+ this.positionMenu.create();
45
+ }
46
+ updateHorizontalPosition(horizontalPosition) {
47
+ const tr = this.view.state.tr;
48
+ tr.setNodeAttribute(this.getPos(), 'type', horizontalPosition);
49
+ this.view.dispatch(tr);
50
+ }
29
51
  }
30
52
  export default createNodeView(TableElementView);
@@ -13,16 +13,18 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Placement, StrictModifiers } from '@popperjs/core';
16
+ import { Instance, Placement, StrictModifiers } from '@popperjs/core';
17
17
  export declare class PopperManager {
18
18
  private activePopper?;
19
19
  private handleDocumentClick?;
20
20
  private triggerElement?;
21
21
  private container?;
22
- show(target: Element, contents: HTMLElement, placement?: Placement, showArrow?: boolean, modifiers?: Array<Partial<StrictModifiers>>, autoFocus?: boolean): void;
22
+ private destructionListener?;
23
+ show(target: Element, contents: HTMLElement, placement?: Placement, showArrow?: boolean, modifiers?: Array<Partial<StrictModifiers>>, autoFocus?: boolean, onDestroy?: ((i: Instance) => void) | undefined): void;
23
24
  destroy(): void;
24
25
  getContainer(): HTMLElement | undefined;
25
26
  update(): void;
27
+ replaceContent(newContent: HTMLElement): void;
26
28
  isActive: () => boolean;
27
29
  private focusInput;
28
30
  private addContainerClass;
@@ -15,20 +15,45 @@
15
15
  */
16
16
  import { ManuscriptEditorView, ManuscriptNode, ManuscriptNodeType } from '@manuscripts/transform';
17
17
  import { EditorProps } from '../configs/ManuscriptsEditor';
18
+ import BlockView from '../views/block_view';
19
+ export declare enum HorizontalPositions {
20
+ left = "half-left",
21
+ right = "half-right",
22
+ default = ""
23
+ }
18
24
  export interface PopperMenuPositionOption {
19
25
  label: string;
20
26
  action: () => void;
21
27
  icon: string;
22
28
  selected: boolean;
23
29
  }
24
- export declare const createPositionOptions: <T extends ManuscriptNode>(nodeType: ManuscriptNodeType, node: T, currentPosition: string, view: ManuscriptEditorView, onComplete?: () => void) => {
25
- title: string;
26
- action: () => void;
27
- IconComponent: string;
28
- iconName: string;
29
- selected: boolean;
30
- }[];
31
- export declare const createPopperMenuPositionOptions: <T extends ManuscriptNode>(nodeType: ManuscriptNodeType, node: T, currentPosition: string, view: ManuscriptEditorView, onComplete?: () => void) => PopperMenuPositionOption[];
32
- export declare const showPositionMenu: <T extends ManuscriptNode>(nodeType: ManuscriptNodeType, node: T, currentPosition: string, positionMenuWrapper: HTMLElement, view: ManuscriptEditorView, getPos: () => number, props: EditorProps) => void;
33
- export declare const setElementPositionAlignment: (element: HTMLElement, position: string) => void;
34
- export declare const createPositionMenuWrapper: (currentPosition: string, onClick: () => void, props: EditorProps) => HTMLDivElement;
30
+ export declare class HorizontalPositionMenu {
31
+ private parent;
32
+ menuOpen: boolean;
33
+ posMenuSelector: string;
34
+ onChange: (newPos: HorizontalPositions) => void;
35
+ positionMenuWrapper: HTMLDivElement;
36
+ location: HTMLElement;
37
+ getPositionSource?: () => ManuscriptNode | null;
38
+ constructor(parent: BlockView<ManuscriptNode>, onChange: (newPos: HorizontalPositions) => void, location?: HTMLElement, getPositionSource?: () => ManuscriptNode | null);
39
+ static createPositionOptions<T extends ManuscriptNode>(nodeType: ManuscriptNodeType, node: T, currentPosition: string, view: ManuscriptEditorView, onComplete?: () => void): {
40
+ title: string;
41
+ action: () => void;
42
+ IconComponent: string;
43
+ iconName: string;
44
+ selected: boolean;
45
+ }[];
46
+ createPopperMenuPositionOptions<T extends ManuscriptNode>(nodeType: ManuscriptNodeType, node: T, currentPosition: string, view: ManuscriptEditorView, onComplete?: () => void): PopperMenuPositionOption[];
47
+ buttonClass: string;
48
+ createPositionMenuWrapper(currentPosition: string, props: EditorProps): void;
49
+ getHorizontalPositionOptions(current: string, onPick: (newPos: HorizontalPositions) => void, destroy: () => void): {
50
+ actions: {
51
+ label: string;
52
+ action: () => void;
53
+ icon: string;
54
+ selected: boolean;
55
+ }[];
56
+ };
57
+ showPositionMenu(force?: boolean): void;
58
+ create(): void;
59
+ }
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "3.16.2";
1
+ export declare const VERSION = "3.17.0";
2
2
  export declare const MATHJAX_VERSION = "3.2.2";
@@ -17,7 +17,13 @@ import { BoxElementNode } from '@manuscripts/transform';
17
17
  import BlockView from './block_view';
18
18
  export declare class BoxElementView extends BlockView<BoxElementNode> {
19
19
  elementType: string;
20
+ container: HTMLDivElement;
20
21
  createElement: () => void;
22
+ updateContents(): void;
23
+ protected addTools(): void;
24
+ private positionMenu;
25
+ protected addPositionMenu(): void;
26
+ private updateHorizontalPosition;
21
27
  }
22
28
  declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps, dispatch?: import("..").Dispatch) => import("../types").NodeViewCreator<BoxElementView>;
23
29
  export default _default;
@@ -16,17 +16,11 @@
16
16
  import { ImageElementNode } from '@manuscripts/transform';
17
17
  import { Trackable } from '../types';
18
18
  import BlockView from './block_view';
19
- export declare enum figurePositions {
20
- left = "half-left",
21
- right = "half-right",
22
- default = ""
23
- }
24
19
  export declare class ImageElementView extends BlockView<Trackable<ImageElementNode>> {
25
20
  container: HTMLElement;
26
21
  subcontainer: HTMLElement;
27
22
  extLinkEditorContainer: HTMLDivElement;
28
- private positionMenuWrapper;
29
- private figurePosition;
23
+ private positionMenu;
30
24
  private isEditingExtLink;
31
25
  ignoreMutation: () => boolean;
32
26
  upload: (file: File) => Promise<void>;
@@ -35,10 +29,9 @@ export declare class ImageElementView extends BlockView<Trackable<ImageElementNo
35
29
  createElement(): void;
36
30
  updateContents(): void;
37
31
  protected addTools(): void;
38
- protected addPositionMenu(): void;
39
32
  private getFirstFigure;
40
33
  private getAllFigures;
41
- private showPositionMenu;
34
+ protected addPositionMenu(): void;
42
35
  private updateAllFiguresPosition;
43
36
  private removeExtLink;
44
37
  private setExtLink;
@@ -18,6 +18,8 @@ import BlockView from './block_view';
18
18
  export declare class PullquoteElementView extends BlockView<PullquoteElementNode> {
19
19
  elementType: string;
20
20
  contextMenu: HTMLElement;
21
+ container: HTMLDivElement;
22
+ private positionMenu;
21
23
  ignoreMutation: () => boolean;
22
24
  stopEvent: () => boolean;
23
25
  private handleClick;
@@ -25,7 +27,11 @@ export declare class PullquoteElementView extends BlockView<PullquoteElementNode
25
27
  handleAddFigure(): void;
26
28
  actionGutterButtons: () => HTMLElement[];
27
29
  addFigureContextMenu: () => HTMLElement | undefined;
30
+ updateContents(): void;
28
31
  destroy: () => void;
32
+ protected addTools(): void;
33
+ protected addPositionMenu(): void;
34
+ private updateHorizontalPosition;
29
35
  }
30
36
  declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps) => import("../types").NodeViewCreator<PullquoteElementView>;
31
37
  export default _default;
@@ -17,7 +17,13 @@ import { TableElementNode } from '@manuscripts/transform';
17
17
  import BlockView from './block_view';
18
18
  export declare class TableElementView extends BlockView<TableElementNode> {
19
19
  elementType: string;
20
+ container: HTMLDivElement;
21
+ private positionMenu;
20
22
  createElement: () => void;
23
+ updateContents(): void;
24
+ protected addTools(): void;
25
+ protected addPositionMenu(): void;
26
+ private updateHorizontalPosition;
21
27
  }
22
28
  declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps, dispatch?: import("..").Dispatch) => import("../types").NodeViewCreator<TableElementView>;
23
29
  export default _default;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@manuscripts/body-editor",
3
3
  "description": "Prosemirror components for editing and viewing manuscripts",
4
- "version": "3.16.2",
4
+ "version": "3.17.0",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -42,7 +42,7 @@ import {
42
42
  insertInlineTableFootnote,
43
43
  } from '../commands'
44
44
  import { PopperManager } from './popper'
45
- import { createPositionOptions } from './position-menu'
45
+ import { HorizontalPositionMenu } from './position-menu'
46
46
  import { templateAllows } from './template'
47
47
  import {
48
48
  getMatchingChild,
@@ -59,9 +59,18 @@ const readonlyTypes = [
59
59
  schema.nodes.footnotes_section,
60
60
  ]
61
61
 
62
- const isBoxElementSectionTitle = ($pos: ResolvedPos, node: ManuscriptNode) =>
63
- isSectionTitleNode(node) &&
64
- $pos.node($pos.depth - 1).type === schema.nodes.box_element
62
+ const getBoxElementOfSectionTitle = (
63
+ $pos: ResolvedPos,
64
+ node: ManuscriptNode
65
+ ) => {
66
+ if (isSectionTitleNode(node)) {
67
+ const parent = $pos.node($pos.depth - 1)
68
+ if (parent.type === schema.nodes.box_element) {
69
+ return parent
70
+ }
71
+ }
72
+ return null
73
+ }
65
74
 
66
75
  export const sectionLevel = (depth: number) => {
67
76
  switch (depth) {
@@ -245,31 +254,43 @@ export class ContextMenu {
245
254
  menu.className = 'menu'
246
255
 
247
256
  const $pos = this.resolvePos()
248
- const isBox = isBoxElementSectionTitle($pos, this.node)
249
- const type = isBox ? schema.nodes.box_element : this.node.type
257
+ const boxParent = getBoxElementOfSectionTitle($pos, this.node)
258
+ const type = boxParent ? schema.nodes.box_element : this.node.type
250
259
 
251
- if (
252
- type === schema.nodes.figure_element ||
253
- type === schema.nodes.image_element
254
- ) {
260
+ const positionableTypes = [
261
+ schema.nodes.figure_element,
262
+ schema.nodes.image_element,
263
+ schema.nodes.box_element,
264
+ schema.nodes.pullquote_element,
265
+ schema.nodes.table_element,
266
+ ]
267
+
268
+ let nodeBase = this.node
269
+
270
+ if (positionableTypes.includes(type)) {
255
271
  const figure = getMatchingChild(
256
272
  this.node,
257
273
  (node) => node.type === schema.nodes.figure
258
274
  )
259
275
 
260
276
  if (figure) {
261
- const attrType = figure.attrs.type
262
- const submenuOptions = createPositionOptions(
263
- schema.nodes.figure,
264
- figure,
265
- attrType,
266
- this.view,
267
- () => popper.destroy()
268
- )
269
- const submenuLabel = 'Position'
270
- const submenu = this.createSubmenu(submenuLabel, submenuOptions)
271
- menu.appendChild(submenu)
277
+ nodeBase = figure
278
+ }
279
+
280
+ if (boxParent) {
281
+ nodeBase = boxParent
272
282
  }
283
+
284
+ const submenuOptions = HorizontalPositionMenu.createPositionOptions(
285
+ schema.nodes[nodeBase.type.name],
286
+ nodeBase,
287
+ nodeBase.attrs.type,
288
+ this.view,
289
+ () => popper.destroy()
290
+ )
291
+ const submenuLabel = 'Position'
292
+ const submenu = this.createSubmenu(submenuLabel, submenuOptions)
293
+ menu.appendChild(submenu)
273
294
  }
274
295
 
275
296
  if (type === schema.nodes.list) {
package/src/lib/popper.ts CHANGED
@@ -27,6 +27,7 @@ export class PopperManager {
27
27
  private handleDocumentClick?: (e: Event) => void
28
28
  private triggerElement?: Element
29
29
  private container?: HTMLElement
30
+ private destructionListener?: (i: Instance) => void
30
31
 
31
32
  public show(
32
33
  target: Element,
@@ -34,7 +35,8 @@ export class PopperManager {
34
35
  placement: Placement = 'bottom',
35
36
  showArrow = true,
36
37
  modifiers: Array<Partial<StrictModifiers>> = [],
37
- autoFocus = true
38
+ autoFocus = true,
39
+ onDestroy: ((i: Instance) => void) | undefined = undefined
38
40
  ) {
39
41
  // destroy any existing popper first
40
42
  // checking activePopper is in destroy() method
@@ -42,6 +44,7 @@ export class PopperManager {
42
44
 
43
45
  // Store the trigger element to return focus later
44
46
  this.triggerElement = target
47
+ this.destructionListener = onDestroy
45
48
 
46
49
  window.requestAnimationFrame(() => {
47
50
  const container = document.createElement('div')
@@ -125,6 +128,8 @@ export class PopperManager {
125
128
  this.removeContainerClass(
126
129
  this.activePopper.state.elements.reference as Element
127
130
  )
131
+ this.destructionListener?.(this.activePopper)
132
+ this.destructionListener = undefined
128
133
  this.activePopper.destroy()
129
134
  this.activePopper.state.elements.popper.remove()
130
135
  if (this.handleDocumentClick) {
@@ -146,6 +151,18 @@ export class PopperManager {
146
151
  }
147
152
  }
148
153
 
154
+ public replaceContent(newContent: HTMLElement) {
155
+ if (this.container && this.activePopper) {
156
+ const arrow = this.container.querySelector('.popper-arrow')
157
+ this.container.innerHTML = ''
158
+ if (arrow) {
159
+ this.container.appendChild(arrow)
160
+ }
161
+ this.container.appendChild(newContent)
162
+ this.activePopper.update()
163
+ }
164
+ }
165
+
149
166
  public isActive = () => !!this.activePopper
150
167
 
151
168
  private focusInput(container: HTMLDivElement, autoFocus = true) {