fix(inline-toolbar): appearing logic improved

This commit is contained in:
Peter Savchenko 2023-12-06 19:13:13 +03:00
parent 531ab06f63
commit 4d70d45449
No known key found for this signature in database
GPG key ID: E68306B1AB0F727C
2 changed files with 52 additions and 93 deletions

View file

@ -138,7 +138,7 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
* Avoid to use it just for closing IT, better call .close() clearly.
* @param [needToShowConversionToolbar] - pass false to not to show Conversion Toolbar
*/
public tryToShow(needToClose = false, needToShowConversionToolbar = true): void {
public async tryToShow(needToClose = false, needToShowConversionToolbar = true): Promise<void> {
if (!this.allowedToShow()) {
if (needToClose) {
this.close();
@ -147,6 +147,7 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
return;
}
await this.addToolsFiltered(needToShowConversionToolbar);
this.move();
this.open(needToShowConversionToolbar);
this.Editor.Toolbar.close();
@ -187,51 +188,6 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
this.Editor.ConversionToolbar.close();
}
/**
* Shows Inline Toolbar
*
* @param [needToShowConversionToolbar] - pass false to not to show Conversion Toolbar
*/
public open(needToShowConversionToolbar = true): void {
if (this.opened) {
return;
}
/**
* Filter inline-tools and show only allowed by Block's Tool
*/
this.addToolsFiltered();
/**
* Show Inline Toolbar
*/
this.nodes.wrapper.classList.add(this.CSS.inlineToolbarShowed);
this.buttonsList = this.nodes.buttons.querySelectorAll(`.${this.CSS.inlineToolButton}`);
this.opened = true;
if (needToShowConversionToolbar && this.Editor.ConversionToolbar.hasTools()) {
/**
* Change Conversion Dropdown content for current tool
*/
this.setConversionTogglerContent();
} else {
/**
* hide Conversion Dropdown with there are no tools
*/
this.nodes.conversionToggler.hidden = true;
}
/**
* Get currently visible buttons to pass it to the Flipper
*/
let visibleTools = Array.from(this.buttonsList);
visibleTools.unshift(this.nodes.conversionToggler);
visibleTools = visibleTools.filter((tool) => !(tool as HTMLElement).hidden);
this.flipper.activate(visibleTools as HTMLElement[]);
}
/**
* Check if node is contained by Inline Toolbar
*
@ -327,6 +283,33 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
this.enableFlipper();
}
/**
* Shows Inline Toolbar
*/
private open(): void {
if (this.opened) {
return;
}
/**
* Show Inline Toolbar
*/
this.nodes.wrapper.classList.add(this.CSS.inlineToolbarShowed);
this.buttonsList = this.nodes.buttons.querySelectorAll(`.${this.CSS.inlineToolButton}`);
this.opened = true;
/**
* Get currently visible buttons to pass it to the Flipper
*/
let visibleTools = Array.from(this.buttonsList);
visibleTools.unshift(this.nodes.conversionToggler);
visibleTools = visibleTools.filter((tool) => !(tool as HTMLElement).hidden);
this.flipper.activate(visibleTools as HTMLElement[]);
}
/**
* Move Toolbar to the selected text
*/
@ -334,7 +317,7 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
const selectionRect = SelectionUtils.rect as DOMRect;
const wrapperOffset = this.Editor.UI.nodes.wrapper.getBoundingClientRect();
const newCoords = {
x: selectionRect.x - wrapperOffset.left,
x: selectionRect.x - wrapperOffset.x,
y: selectionRect.y +
selectionRect.height -
// + window.scrollY
@ -342,34 +325,15 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
this.toolbarVerticalMargin,
};
const realRightCoord = newCoords.x + this.width + wrapperOffset.x;
/**
* If we know selections width, place InlineToolbar to center
* Prevent InlineToolbar from overflowing the content zone on the right side
*/
if (selectionRect.width) {
newCoords.x += Math.floor(selectionRect.width / 2);
if (realRightCoord > this.Editor.UI.contentRect.right) {
newCoords.x = this.Editor.UI.contentRect.right - this.width - wrapperOffset.x;
}
/**
* Inline Toolbar has -50% translateX, so we need to check real coords to prevent overflowing
*/
const realLeftCoord = newCoords.x - this.width / 2;
const realRightCoord = newCoords.x + this.width / 2;
/**
* By default, Inline Toolbar has top-corner at the center
* We are adding a modifiers for to move corner to the left or right
*/
this.nodes.wrapper.classList.toggle(
this.CSS.inlineToolbarLeftOriented,
realLeftCoord < this.Editor.UI.contentRect.left
);
this.nodes.wrapper.classList.toggle(
this.CSS.inlineToolbarRightOriented,
realRightCoord > this.Editor.UI.contentRect.right
);
this.nodes.wrapper.style.left = Math.floor(newCoords.x) + 'px';
this.nodes.wrapper.style.top = Math.floor(newCoords.y) + 'px';
}
@ -529,8 +493,10 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
/**
* Append only allowed Tools
*
* @param {boolean} needToShowConversionToolbar - pass false to not to show Conversion Toolbar (e.g. for Footnotes-like tools)
*/
private addToolsFiltered(): void {
private async addToolsFiltered(needToShowConversionToolbar = true): Promise<void> {
const currentSelection = SelectionUtils.get();
const currentBlock = this.Editor.BlockManager.getBlock(currentSelection.anchorNode as HTMLElement);
@ -545,6 +511,18 @@ export default class InlineToolbar extends Module<InlineToolbarNodes> {
this.addTool(tool);
});
if (needToShowConversionToolbar && this.Editor.ConversionToolbar.hasTools()) {
/**
* Change Conversion Dropdown content for current tool
*/
await this.setConversionTogglerContent();
} else {
/**
* hide Conversion Dropdown with there are no tools
*/
this.nodes.conversionToggler.hidden = true;
}
/**
* Recalculate width because some buttons can be hidden
*/

View file

@ -2,11 +2,10 @@
--y-offset: 8px;
@apply --overlay-pane;
transform: translateX(-50%) translateY(8px) scale(0.94);
opacity: 0;
visibility: hidden;
transition: transform 150ms ease, opacity 250ms ease;
will-change: transform, opacity;
transition: opacity 250ms ease;
will-change: opacity, left, top;
top: 0;
left: 0;
z-index: 3;
@ -14,24 +13,6 @@
&--showed {
opacity: 1;
visibility: visible;
transform: translateX(-50%)
}
&--left-oriented {
transform: translateX(-23px) translateY(8px) scale(0.94);
}
&--left-oriented&--showed {
transform: translateX(-23px);
}
&--right-oriented {
transform: translateX(-100%) translateY(8px) scale(0.94);
margin-left: 23px;
}
&--right-oriented&--showed {
transform: translateX(-100%);
}
[hidden] {