diff --git a/core/js/dist/login.js b/core/js/dist/login.js
index fbe5c87c4d7978243a9b73aa3e65742e5e0c2edd..40c80525835845e38370b634cb749537619921f2 100644
Binary files a/core/js/dist/login.js and b/core/js/dist/login.js differ
diff --git a/core/js/dist/login.js.map b/core/js/dist/login.js.map
index 4304a27c2836db19c395f94c8048985e156c485e..9a64101daf2c2051df18f6809ed56cf8ee2664e2 100644
Binary files a/core/js/dist/login.js.map and b/core/js/dist/login.js.map differ
diff --git a/core/js/dist/main.js b/core/js/dist/main.js
index ca40b14d0cf906c957eb0b69f9ee6f673095766f..322e7a9ca0d1583a4072b118ed0bd63e88d99c16 100644
Binary files a/core/js/dist/main.js and b/core/js/dist/main.js differ
diff --git a/core/js/dist/main.js.map b/core/js/dist/main.js.map
index 7245b3261866b86394a071b5efb9814c7f82f4eb..33fe45af7fa5c838e2bc38532fbca55cd2214b8c 100644
Binary files a/core/js/dist/main.js.map and b/core/js/dist/main.js.map differ
diff --git a/core/js/js.js b/core/js/js.js
index b9b46035a95c42ff192215f8e04ce0e9840259a0..c4017b4626729b98905a9bddb37dd034e378c216 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -419,116 +419,6 @@ Object.assign(window.OC, {
 		}
 	},
 
-	/**
-	 * For menu toggling
-	 * @todo Write documentation
-	 *
-	 * @param {jQuery} $toggle
-	 * @param {jQuery} $menuEl
-	 * @param {function|undefined} toggle callback invoked everytime the menu is opened
-	 * @param {boolean} headerMenu is this a top right header menu?
-	 * @returns {undefined}
-	 */
-	registerMenu: function($toggle, $menuEl, toggle, headerMenu) {
-		var self = this;
-		$menuEl.addClass('menu');
-
-		// On link, the enter key trigger a click event
-		// Only use the click to avoid two fired events
-		$toggle.on($toggle.prop('tagName') === 'A'
-			? 'click.menu'
-			: 'click.menu keyup.menu', function(event) {
-			// prevent the link event (append anchor to URL)
-			event.preventDefault();
-
-			// allow enter key as a trigger
-			if (event.key && event.key !== "Enter") {
-				return;
-			}
-
-			if ($menuEl.is(OC._currentMenu)) {
-				self.hideMenus();
-				return;
-			}
-			// another menu was open?
-			else if (OC._currentMenu) {
-				// close it
-				self.hideMenus();
-			}
-
-			if (headerMenu === true) {
-				$menuEl.parent().addClass('openedMenu');
-			}
-
-			// Set menu to expanded
-			$toggle.attr('aria-expanded', true);
-
-			$menuEl.slideToggle(OC.menuSpeed, toggle);
-			OC._currentMenu = $menuEl;
-			OC._currentMenuToggle = $toggle;
-		});
-	},
-
-	/**
-	 *  @todo Write documentation
-	 */
-	unregisterMenu: function($toggle, $menuEl) {
-		// close menu if opened
-		if ($menuEl.is(OC._currentMenu)) {
-			this.hideMenus();
-		}
-		$toggle.off('click.menu').removeClass('menutoggle');
-		$menuEl.removeClass('menu');
-	},
-
-	/**
-	 * Hides any open menus
-	 *
-	 * @param {Function} complete callback when the hiding animation is done
-	 */
-	hideMenus: function(complete) {
-		if (OC._currentMenu) {
-			var lastMenu = OC._currentMenu;
-			OC._currentMenu.trigger(new $.Event('beforeHide'));
-			OC._currentMenu.slideUp(OC.menuSpeed, function() {
-				lastMenu.trigger(new $.Event('afterHide'));
-				if (complete) {
-					complete.apply(this, arguments);
-				}
-			});
-		}
-
-		// Set menu to closed
-		$('.menutoggle').attr('aria-expanded', false);
-
-		$('.openedMenu').removeClass('openedMenu');
-		OC._currentMenu = null;
-		OC._currentMenuToggle = null;
-	},
-
-	/**
-	 * Shows a given element as menu
-	 *
-	 * @param {Object} [$toggle=null] menu toggle
-	 * @param {Object} $menuEl menu element
-	 * @param {Function} complete callback when the showing animation is done
-	 */
-	showMenu: function($toggle, $menuEl, complete) {
-		if ($menuEl.is(OC._currentMenu)) {
-			return;
-		}
-		this.hideMenus();
-		OC._currentMenu = $menuEl;
-		OC._currentMenuToggle = $toggle;
-		$menuEl.trigger(new $.Event('beforeShow'));
-		$menuEl.show();
-		$menuEl.trigger(new $.Event('afterShow'));
-		// no animation
-		if (_.isFunction(complete)) {
-			complete();
-		}
-	},
-
 	/**
 	 * Returns the user's locale as a BCP 47 compliant language tag
 	 *
diff --git a/core/src/OC/index.js b/core/src/OC/index.js
index cf334c5a835798be7cd83d457f9e5d678b73c79b..9ac9be05e60df1aab55f593a0c7cc74afbd78429 100644
--- a/core/src/OC/index.js
+++ b/core/src/OC/index.js
@@ -40,6 +40,12 @@ import ContactsMenu from './contactsmenu'
 import Dialogs from './dialogs'
 import EventSource from './eventsource'
 import {get, set} from './get_set'
+import {
+	hideMenus,
+	registerMenu,
+	showMenu,
+	unregisterMenu,
+} from './menu'
 import {isUserAdmin} from './admin'
 import L10N from './l10n'
 import {
@@ -88,6 +94,15 @@ export default {
 	EventSource,
 	isUserAdmin,
 	L10N,
+
+	/*
+	 * Legacy menu helpers
+	 */
+	hideMenus,
+	registerMenu,
+	showMenu,
+	unregisterMenu,
+
 	msg,
 	Notification,
 	PasswordConfirmation,
diff --git a/core/src/OC/menu.js b/core/src/OC/menu.js
new file mode 100644
index 0000000000000000000000000000000000000000..a0ecd2a5f4fe5c25e76a31be40e17e1eaaf8a53a
--- /dev/null
+++ b/core/src/OC/menu.js
@@ -0,0 +1,135 @@
+/*
+ * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import _ from 'underscore'
+import $ from 'jquery'
+
+import {menuSpeed} from './constants'
+
+let currentMenu = null
+let currentMenuToggle = null
+
+/**
+ * For menu toggling
+ *
+ * @param {jQuery} $toggle
+ * @param {jQuery} $menuEl
+ * @param {function|undefined} toggle callback invoked everytime the menu is opened
+ * @param {boolean} headerMenu is this a top right header menu?
+ * @returns {undefined}
+ */
+export const registerMenu = ($toggle, $menuEl, toggle, headerMenu) => {
+	$menuEl.addClass('menu')
+
+	// On link, the enter key trigger a click event
+	// Only use the click to avoid two fired events
+	$toggle.on($toggle.prop('tagName') === 'A'
+		? 'click.menu'
+		: 'click.menu keyup.menu', function (event) {
+		// prevent the link event (append anchor to URL)
+		event.preventDefault()
+
+		// allow enter key as a trigger
+		if (event.key && event.key !== "Enter") {
+			return
+		}
+
+		if ($menuEl.is(currentMenu)) {
+			hideMenus()
+			return
+		} else if (currentMenu) {
+			// another menu was open?
+			// close it
+			hideMenus()
+		}
+
+		if (headerMenu === true) {
+			$menuEl.parent().addClass('openedMenu')
+		}
+
+		// Set menu to expanded
+		$toggle.attr('aria-expanded', true)
+
+		$menuEl.slideToggle(menuSpeed, toggle)
+		currentMenu = $menuEl
+		currentMenuToggle = $toggle
+	})
+}
+
+/**
+ *  @todo Write documentation
+ */
+export const unregisterMenu = ($toggle, $menuEl) => {
+	// close menu if opened
+	if ($menuEl.is(currentMenu)) {
+		hideMenus()
+	}
+	$toggle.off('click.menu').removeClass('menutoggle')
+	$menuEl.removeClass('menu')
+}
+
+/**
+ * Hides any open menus
+ *
+ * @param {Function} complete callback when the hiding animation is done
+ */
+export const hideMenus = function(complete) {
+	if (currentMenu) {
+		const lastMenu = currentMenu
+		currentMenu.trigger(new $.Event('beforeHide'))
+		currentMenu.slideUp(menuSpeed, function () {
+			lastMenu.trigger(new $.Event('afterHide'))
+			if (complete) {
+				complete.apply(this, arguments)
+			}
+		})
+	}
+
+	// Set menu to closed
+	$('.menutoggle').attr('aria-expanded', false)
+
+	$('.openedMenu').removeClass('openedMenu')
+	currentMenu = null
+	currentMenuToggle = null
+}
+
+/**
+ * Shows a given element as menu
+ *
+ * @param {Object} [$toggle=null] menu toggle
+ * @param {Object} $menuEl menu element
+ * @param {Function} complete callback when the showing animation is done
+ */
+export const showMenu = ($toggle, $menuEl, complete) => {
+	if ($menuEl.is(currentMenu)) {
+		return
+	}
+	hideMenus()
+	currentMenu = $menuEl
+	currentMenuToggle = $toggle
+	$menuEl.trigger(new $.Event('beforeShow'))
+	$menuEl.show()
+	$menuEl.trigger(new $.Event('afterShow'))
+	// no animation
+	if (_.isFunction(complete)) {
+		complete()
+	}
+}