diff --git a/browser/css/jsdialogs.css b/browser/css/jsdialogs.css
index 6e7446987a79..6ac848a8f631 100644
--- a/browser/css/jsdialogs.css
+++ b/browser/css/jsdialogs.css
@@ -161,10 +161,6 @@ div#autoFillPreviewTooltip .lokdialog.ui-dialog-content.ui-widget-content {
vertical-align: middle;
}
-.jsdialog.vertical:not(.sidebar):not(.ui-separator) {
- width: 100%;
-}
-
th.jsdialog:not(:first-child) {
padding-inline-end: 24px;
}
diff --git a/browser/css/toolbar.css b/browser/css/toolbar.css
index 14551d0aa387..d1f1453f9468 100644
--- a/browser/css/toolbar.css
+++ b/browser/css/toolbar.css
@@ -60,6 +60,22 @@
margin: 0px;
}
+/* overflow menu */
+.menu-overflow-wrapper {
+ position: absolute;
+ height: var(--header-height);
+ top: var(--header-height);
+ display: flex;
+ background-color: var(--color-background-lighter);
+ border: 1px solid var(--color-toolbar-border);
+ align-items: center;
+ border-radius: 4px;
+ padding: 0 4px;
+ box-shadow: 0 2px 6px 2px rgba(60, 64, 67, .15);
+ opacity: 0;
+ pointer-events: none;
+}
+
/* status bar / mobile bottom bar */
#toolbar-down .ui-badge {
diff --git a/browser/images/dark/lc_menuoverflow.svg b/browser/images/dark/lc_menuoverflow.svg
new file mode 100644
index 000000000000..1b5ba0a22f6e
--- /dev/null
+++ b/browser/images/dark/lc_menuoverflow.svg
@@ -0,0 +1,70 @@
+
+
diff --git a/browser/images/lc_menuoverflow.svg b/browser/images/lc_menuoverflow.svg
new file mode 100644
index 000000000000..d4b90d9e6d17
--- /dev/null
+++ b/browser/images/lc_menuoverflow.svg
@@ -0,0 +1,70 @@
+
+
diff --git a/browser/src/control/Control.TopToolbar.js b/browser/src/control/Control.TopToolbar.js
index 5101b0e41bab..a499d3f001b8 100644
--- a/browser/src/control/Control.TopToolbar.js
+++ b/browser/src/control/Control.TopToolbar.js
@@ -190,6 +190,7 @@ class TopToolbar extends JSDialog.Toolbar {
{type: 'customtoolitem', id: 'insertannotation', text: _UNO('.uno:InsertAnnotation', '', true), visible: false, lockUno: '.uno:InsertAnnotation'},
{type: 'customtoolitem', id: 'inserthyperlink', command: 'inserthyperlink', text: _UNO('.uno:HyperlinkDialog', '', true), lockUno: '.uno:HyperlinkDialog'},
{type: 'toolitem', id: 'insertsymbol', text: _UNO('.uno:InsertSymbol', '', true), command: '.uno:InsertSymbol'},
+ {type: 'customtoolitem', id: 'menuoverflow', text: _('More'), desktop: true, mobile: false, visible: true},
{type: 'spacer', id: 'topspacer'},
{type: 'separator', orientation: 'vertical', id: 'breaksidebar', visible: false},
{type: 'toolitem', id: 'sidebar', text: _UNO('.uno:Sidebar', '', true), command: '.uno:SidebarDeck.PropertyDeck', visible: false},
@@ -228,14 +229,123 @@ class TopToolbar extends JSDialog.Toolbar {
}
}
+ createOverflowMenu() {
+ const topBarMenu = this.parentContainer.querySelector(
+ '.root-container .vertical',
+ );
+
+ const overflowMenu = L.DomUtil.create(
+ 'div',
+ 'menu-overflow-wrapper',
+ this.parentContainer,
+ );
+
+ const overflowMenuButton =
+ this.parentContainer.querySelector('#menuoverflow');
+
+ const showOverflowMenu = () => {
+ overflowMenu.style.opacity = 1;
+ overflowMenu.style.pointerEvents = 'revert';
+ L.DomUtil.addClass(overflowMenuButton, 'selected');
+ };
+
+ const hideOverflowMenu = () => {
+ overflowMenu.style.opacity = 0;
+ overflowMenu.style.pointerEvents = 'none';
+ L.DomUtil.removeClass(overflowMenuButton, 'selected');
+ };
+
+ overflowMenuButton.addEventListener('click', () => {
+ if (
+ overflowMenu.style.opacity === '0' ||
+ overflowMenu.style.opacity === ''
+ ) {
+ showOverflowMenu();
+ } else {
+ hideOverflowMenu();
+ }
+ });
+
+ const breakSidebar = this.parentContainer.querySelector('#breaksidebar');
+ const foldButton = this.parentContainer.querySelector('#fold');
+
+ const getMenuWidth = () => {
+ const splitPosition =
+ foldButton.offsetLeft +
+ foldButton.offsetWidth * 2 -
+ breakSidebar.offsetLeft;
+ return window.innerWidth - splitPosition;
+ };
+
+ let overflowMenuDebounced = 0;
+ const originalTopbar = topBarMenu.querySelectorAll('.jsdialog');
+
+ const overflowMenuHandler = () => {
+ overflowMenuDebounced && clearTimeout(overflowMenuDebounced);
+
+ hideOverflowMenu();
+
+ overflowMenuDebounced = setTimeout(() => {
+ topBarMenu.replaceChildren(...originalTopbar);
+
+ const topBarButtons = topBarMenu.querySelectorAll('.jsdialog:not(.hidden)');
+ const menuWidth = getMenuWidth();
+
+ const overflowMenuOffscreen = document.createElement('div');
+ overflowMenuOffscreen.className = 'menu-overfow-vertical';
+
+ let section = [];
+ let overflow = false;
+
+ const appendSection = () => {
+ for (const element of section) {
+ overflowMenuOffscreen.appendChild(element);
+ }
+ section.length = 0;
+ };
+
+ for (const button of topBarButtons) {
+ if (button.id === 'topspacer' || button.id === 'menuoverflow') {
+ break;
+ }
+
+ if (button.offsetLeft > menuWidth || overflow) {
+ overflow = true;
+ appendSection();
+ overflowMenuOffscreen.appendChild(button);
+ } else if (button.className.includes('vertical')) {
+ section = [button];
+ } else {
+ section.push(button);
+ }
+ }
+
+ overflowMenu.replaceChildren(overflowMenuOffscreen);
+
+ if (overflowMenuOffscreen.children.length <= 0) {
+ overflowMenuButton.style.display = 'none';
+ } else {
+ overflowMenuButton.style.display = 'revert';
+ }
+
+ overflowMenu.style.left =
+ overflowMenuButton.offsetLeft -
+ overflowMenu.clientWidth +
+ overflowMenuButton.offsetWidth +
+ 'px';
+ }, 250);
+ };
+
+ window.addEventListener('resize', overflowMenuHandler);
+ }
+
create() {
this.reset();
var items = this.getToolItems();
this.builder.build(this.parentContainer, items);
- JSDialog.MakeScrollable(this.parentContainer, this.parentContainer.querySelector('div'));
- JSDialog.RefreshScrollables();
+ this.createOverflowMenu();
if (this.map.isRestrictedUser()) {
for (var i = 0; i < items.length; i++) {
@@ -260,7 +370,7 @@ class TopToolbar extends JSDialog.Toolbar {
this.onDocLayerInit();
// if app opens direct in compact mode then we need to set the saveState first
- this.map.saveState = new app.definitions.saveState(this.map);
+ this.map.saveState = new app.definitions.saveState(this.map);
}
onDocLayerInit() {