refactore of menus: classes and scss

This commit is contained in:
Simon Vieille 2025-04-14 20:16:54 +02:00
commit c32d1fffec
Signed by: deblan
GPG key ID: 579388D585F70417
19 changed files with 338 additions and 333 deletions

View file

@ -15,7 +15,7 @@ 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/>.
-->
<template>
<div class="side-menu-search">
<div class="cm-search">
<input
v-model="model"
type="text"

View file

@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<button
class="side-menu-opener side-menu-closer"
class="cm-opener cm-closer"
:arial-label="t('side_menu', 'Close the menu')"
@click="$emit('click')"
>

View file

@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<button
class="side-menu-opener"
class="cm-opener"
:arial-label="label"
@click="$emit('click')"
>

View file

@ -15,9 +15,9 @@ 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/>.
-->
<template>
<div id="side-menu-loader">
<div class="cm-loader">
<div
id="side-menu-loader-bar"
class="cm-loader-bar"
:style="createStyle(width)"
></div>
</div>

View file

@ -15,7 +15,7 @@ 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/>.
-->
<template>
<div class="side-menu-settings">
<div class="cm-setting">
<a :href="href">
<!--
{{ label }}

View file

@ -22,11 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
:title="label"
>
<img
class="side-menu-app-icon"
class="cm-app-icon"
:src="icon"
:alt="label"
/>
<span class="side-menu-app-text">{{ label }}</span>
<span class="cm-app-text">{{ label }}</span>
</a>
</li>
</template>

View file

@ -22,11 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
:title="label"
>
<img
class="side-menu-app-icon"
class="cm-app-icon"
:src="icon"
:alt="label"
/>
<span class="side-menu-app-text">{{ label }}</span>
<span class="cm-app-text">{{ label }}</span>
</a>
</li>
</template>

View file

@ -16,8 +16,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<FormSelect
class="cm-settings-form-opener"
v-model="model"
class="cm-settings-form-opener"
:options="options"
/>
</template>

View file

@ -17,8 +17,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<template>
<div class="cm-settings-form-range">
<em
class="cm-settings-form-range-prepend"
v-if="prepend"
class="cm-settings-form-range-prepend"
>{{ t('side_menu', prepend) }}</em
>

View file

@ -16,8 +16,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<FormSelect
class="cm-settings-form-size"
v-model="model"
class="cm-settings-form-size"
:options="options"
/>
</template>

View file

@ -16,8 +16,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<NcCheckboxRadioSwitch
class="cm-settings-form-yesno"
v-model="model"
class="cm-settings-form-yesno"
type="switch"
/>
</template>

View file

@ -19,17 +19,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<PageLoader v-if="hasPageLoader" />
<TopWideMenu
v-if="display === 'big-menu'"
id="side-menu"
:open="isOpen"
class="cm"
@close="closeMenu"
/>
<SideMenuWithCategories
v-else-if="display === 'side-with-categories'"
id="side-menu"
:open="isOpen"
class="cm"
@close="closeMenu"
/>
<SimpleSideMenu
v-else-if="display === 'simple-side-menu'"
id="side-menu"
:open="isOpen"
class="cm"
@close="closeMenu"
@open="openMenu"
@toggle="toggleMenu(!isOpen)"
@ -83,7 +89,7 @@ const createOpener = () => {
}
const opener = createElement('button', {
class: 'side-menu-opener',
class: 'cm-opener',
'arial-label': t('side_menu', 'Toggle the menu'),
html: `<span>${t('side_menu', 'Toggle the menu')}</span>`,
})

View file

@ -16,12 +16,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<div
id="side-menu"
ref="menu"
class="side-menu-with-categories"
class="cm--sidemenuwithcategories"
:class="{ open: open }"
>
<div class="side-menu-header">
<div class="cm-header">
<SettingsButton
v-if="settings"
:href="settings.href"
@ -35,31 +34,32 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/>
</div>
<div class="side-menu-categories-wrapper">
<div class="side-menu-categories">
<div class="cm-categories-wrapper">
<div class="cm-categories">
<template
v-for="(category, key) in items"
:key="key"
>
<div
v-if="containsAppsMatchingSearch(category.apps, search)"
class="side-menu-category"
class="cm-category"
>
<h2
v-if="category.name != ''"
class="side-menu-category-title"
class="cm-category-title"
>
{{ category.name }}
</h2>
<ul class="side-menu-apps-list">
<ul class="cm-apps">
<template
v-for="(app, appId) in category.apps"
:key="appId"
>
<SideMenuBigApp
v-if="isAppMatchingSearch(app, search)"
:classes="{ 'side-menu-app': true, active: activeApp === appId }"
class="cm-app"
:classes="{ active: activeApp === appId }"
:icon="app.icon"
:label="app.name"
:href="app.href"

View file

@ -16,13 +16,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<div
id="side-menu"
ref="menu"
:class="{ open: open }"
>
<div
v-if="settings || displayLogo || open || !openerHover"
class="side-menu-header"
class="cm-header"
>
<SettingsButton
v-if="settings && open"
@ -40,14 +39,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/>
<MenuLogo
v-if="displayLogo"
:classes="{ 'side-menu-logo': true, avatardiv: false }"
class="cm-logo"
:classes="{ avatardiv: false }"
:image="useAvatarAsLogo ? avatar : logo"
:link="logoLink"
/>
</div>
<ul
class="side-menu-apps-list"
class="cm-apps"
:class="{ 'side-menu-apps-list--with-logo': displayLogo }"
>
<template
@ -56,7 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
>
<SideMenuApp
v-if="isAppMatchingSearch(app, search)"
:classes="{ 'side-menu-app': true, active: app.id === activeApp }"
class="cm-app"
:classes="{ active: app.id === activeApp }"
:icon="app.icon"
:label="app.name"
:href="app.href"
@ -108,7 +109,7 @@ const menu = useTemplateRef('menu')
const isTouchDevice = window.matchMedia('(pointer: coarse)').matches
watch(apps, (val) => {
document.querySelector('html').classList.toggle('side-menu-always-displayed', alwaysDisplayed.value && val.length)
document.querySelector('html').classList.toggle('cm-always-displayed', alwaysDisplayed.value && val.length)
})
watch(

View file

@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<nav
class="app-menu show"
class="cm--standardmenu app-menu show"
:aria-label="t('core', 'Applications menu')"
>
<ul

View file

@ -16,12 +16,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<div
id="side-menu"
ref="menu"
class="side-menu-big"
class="cm--topwidemenu"
:class="{ open: open }"
>
<div class="side-menu-header">
<div class="cm-header">
<CloserButton
v-if="!openerHover"
@click="$emit('close')"
@ -39,31 +38,32 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/>
</div>
<div class="side-menu-categories-wrapper">
<div class="side-menu-categories">
<div class="cm-categories-wrapper">
<div class="cm-categories">
<template
v-for="(category, key) in items"
:key="key"
>
<div
v-if="containsAppsMatchingSearch(category.apps, search)"
class="side-menu-category"
class="cm-category"
>
<h2
v-if="category.name != ''"
class="side-menu-category-title"
class="cm-category-title"
>
{{ category.name }}
</h2>
<ul class="side-menu-apps-list">
<ul class="cm-apps">
<template
v-for="(app, appId) in category.apps"
:key="appId"
>
<SideMenuBigApp
v-if="isAppMatchingSearch(app, search)"
:classes="{ 'side-menu-app': true, active: activeApp === appId }"
class="cm-app"
:classes="{ active: activeApp === appId }"
:icon="app.icon"
:label="app.name"
:href="app.href"

View file

@ -535,8 +535,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<NcModal
v-if="showConfig"
@close="showConfig = false"
class="cm-settings-config-modal"
@close="showConfig = false"
>
<div class="modal__content">
<p style="margin-bottom: 5px">{{ trans('Configuration:') }}</p>

View file

@ -15,18 +15,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
.__debug {
background: red;
padding: 5px;
color: #fff;
width: 50vw;
bottom: 0;
right: 0;
z-index: 3000;
position: fixed;
#header {
.cm-opener {
margin-left: 0px;
margin-top: 0px;
}
}
#side-menu {
.cm {
position: fixed;
top: 0;
left: 0;
@ -41,258 +37,261 @@
rgba(0, 0, 0, 0.18) 0px 4.8px 14.4px 0px;
display: none;
&-opener {
background: var(--side-menu-opener, url('../../img/side-menu-opener.svg'));
background-color: transparent !important;
height: 40px !important;
width: 40px !important;
border-radius: 0 !important;
border: 0 !important;
padding-right: 12px !important;
padding-left: 12px !important;
margin-top: 1px !important;
margin-left: 5px !important;
margin-left: 3px !important;
overflow: hidden;
span {
position: relative;
left: 50px;
display: block;
width: 1px;
height: 1px;
overflow: hidden;
}
&:active,
&:focus {
background-color: var(--side-menu-current-app-background-color, #444) !important;
}
}
&-closer {
background: url('../../img/side-menu-opener-closer.svg');
display: none;
}
a {
transition: 0.2s;
}
&-categories-wrapper {
padding-bottom: 70px;
}
&-search {
float: right;
input {
background: none;
border: 0;
border-radius: 0;
color: var(--side-menu-text-color);
&::placeholder {
color: var(--side-menu-text-color);
}
}
}
&-categories {
max-height: calc(100vh - 55px);
overflow: auto;
position: relative;
display: flex;
flex-wrap: wrap;
justify-content: center;
padding: 0 10% 0 10%;
}
&-category {
padding: 10px 20px;
flex: 1 1 auto;
&-title {
padding-left: 10px;
color: var(--side-menu-text-color, #fff);
font-weight: bold;
font-size: 20px;
margin-bottom: 12px;
line-height: 30px;
margin-top: 0;
}
}
&-header {
width: 100%;
z-index: 2300;
max-width: 290px;
padding-top: 2px;
top: 0;
&::after {
content: ' ';
display: block;
clear: both;
}
}
&-loader {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 3001;
&-bar {
height: 4px;
background: var(--side-menu-loader-color, #0e75ac);
width: 0;
transition-property: width;
}
}
&-apps {
height: calc(100vh - 49px);
top: 49px;
z-index: 2200;
position: fixed;
width: 100%;
max-width: 290px;
overflow: auto;
&.side-menu-apps-list--with-logo {
height: calc(100vh - 160px);
top: 160px;
}
}
&-app {
a {
line-height: 30px;
color: var(--side-menu-text-color, #fff);
display: block;
padding: 7px 0 5px 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
a:hover,
a:focus,
&:active,
&.active {
background: var(--side-menu-current-app-background-color, #444);
}
&-icon {
width: 20px;
vertical-align: middle;
margin-top: -4px;
margin-right: 10px;
filter: invert(var(--side-menu-icon-invert-filter, 0%));
opacity: var(--side-menu-icon-opacity, 1);
}
}
&-setting {
margin-right: 9px;
margin-top: 2px;
float: right;
line-height: 34px;
height: 42px;
display: none;
a {
color: var(--side-menu-text-color, #fff);
display: block;
padding: 4px 7px;
}
&:hover a,
a:active,
a:focus {
background: var(--side-menu-current-app-background-color, #444);
}
img {
vertical-align: bottom;
margin-left: 3px;
width: 32px;
height: 32px;
}
}
&.open {
display: block;
.side-menu-settings {
.cm-setting {
display: block;
}
}
.side-menu-opener {
margin-top: 1px !important;
&-logo {
text-align: center;
clear: both;
img {
max-width: 60%;
max-height: 100px;
}
}
&.side-menu-big {
&--topwidemenu {
max-width: 100%;
height: auto;
}
&.side-menu-with-categories {
&--sidemenuwithcategories {
max-width: 290px;
height: 100vh;
.side-menu-categories {
.cm-categories {
display: block;
padding: 0;
width: 100%;
}
.side-menu-category {
.cm-category {
padding: 10px 0;
}
}
}
#header {
.side-menu-opener {
margin-left: 0px;
margin-top: 0px;
}
}
.side-menu-settings {
margin-right: 9px;
margin-top: 2px;
float: right;
line-height: 34px;
height: 42px;
display: none;
a {
color: var(--side-menu-text-color, #fff);
display: block;
padding: 4px 7px;
}
&:hover a,
a:active,
a:focus {
background: var(--side-menu-current-app-background-color, #444);
}
img {
vertical-align: bottom;
margin-left: 3px;
width: 32px;
height: 32px;
}
}
.side-menu-opener {
background: var(--side-menu-opener, url('../../img/side-menu-opener.svg'));
background-color: transparent !important;
height: 40px !important;
width: 40px !important;
border-radius: 0 !important;
border: 0 !important;
padding-right: 12px !important;
padding-left: 12px !important;
margin-left: 5px !important;
margin-left: 3px !important;
overflow: hidden;
span {
position: relative;
left: 50px;
display: block;
width: 1px;
height: 1px;
overflow: hidden;
}
&:active,
&:focus {
background-color: var(--side-menu-current-app-background-color, #444) !important;
}
}
.side-menu-closer {
background: url('../../img/side-menu-opener-closer.svg');
display: none;
}
.side-menu-apps-list {
height: calc(100vh - 49px);
top: 49px;
z-index: 2200;
position: fixed;
width: 100%;
max-width: 290px;
overflow: auto;
&.side-menu-apps-list--with-logo {
height: calc(100vh - 160px);
top: 160px;
}
}
.side-menu-app-icon {
width: 20px;
vertical-align: middle;
margin-top: -4px;
margin-right: 10px;
filter: invert(var(--side-menu-icon-invert-filter, 0%));
opacity: var(--side-menu-icon-opacity, 1);
}
.side-menu-app {
a {
line-height: 30px;
color: var(--side-menu-text-color, #fff);
display: block;
padding: 7px 0 5px 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
a:hover,
a:focus,
&:active,
&.active {
background: var(--side-menu-current-app-background-color, #444);
}
}
.side-menu-logo {
text-align: center;
clear: both;
img {
max-width: 60%;
max-height: 100px;
}
}
.side-menu-header {
width: 100%;
z-index: 2300;
max-width: 290px;
padding-top: 2px;
top: 0;
&::after {
content: ' ';
display: block;
clear: both;
}
}
#side-menu.side-menu-with-categories .side-menu-header {
max-width: 295px;
}
#side-menu-loader {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 3001;
#side-menu-loader-bar {
height: 4px;
background: var(--side-menu-loader-color, #0e75ac);
width: 0;
transition-property: width;
}
}
.side-menu-big,
.side-menu-with-categories {
.side-menu-apps-list {
height: auto;
position: static;
max-width: 100vw;
overflow: auto;
}
.side-menu-app {
a {
padding: 7px 0 7px 7px;
.cm-header {
max-width: 295px;
}
}
.side-menu-app-icon {
vertical-align: middle;
margin-top: -2px;
&.cm--topwidemenu,
&.cm--sidemenuwithcategories {
.cm-apps {
height: auto !important;
position: static !important;
max-width: 100vw !important;
overflow: auto !important;
}
.cm-app {
a {
padding: 7px 0 7px 7px;
}
&-icon {
vertical-align: middle;
margin-top: -2px;
}
}
}
&.cm--standardmenu {
visibility: hidden;
&.show {
visibility: visible;
}
}
}
.side-menu-categories-wrapper {
padding-bottom: 70px;
}
.side-menu-categories {
max-height: calc(100vh - 55px);
overflow: auto;
position: relative;
display: flex;
flex-wrap: wrap;
justify-content: center;
padding: 0 10% 0 10%;
}
.side-menu-category {
padding: 10px 20px;
flex: 1 1 auto;
}
.side-menu-category-title {
padding-left: 10px;
color: var(--side-menu-text-color, #fff);
font-weight: bold;
font-size: 20px;
margin-bottom: 12px;
line-height: 30px;
margin-top: 0;
}
.side-menu-loader {
text-align: center;
}
.side-menu-loader svg {
width: 45px;
margin: auto;
stroke: var(--side-menu-text-color, #fff);
}
.side-menu-always-displayed {
.cm-always-displayed {
body {
width: calc(100% - 50px) !important;
position: absolute;
@ -301,45 +300,59 @@
#header {
position: absolute !important;
.cm-opener {
display: none;
}
}
#side-menu {
.cm {
display: block;
}
.side-menu-apps-list {
height: calc(100vh - 49px);
top: 49px;
}
.side-menu-apps-list:hover {
overflow: auto;
}
#side-menu,
.side-menu-header,
.side-menu-apps-list {
width: 50px;
}
#side-menu .side-menu-app-text,
#header .side-menu-opener,
.side-menu-logo {
display: none;
}
&-apps {
height: calc(100vh - 49px);
width: 50px;
top: 49px;
#side-menu .side-menu-header {
height: 49px;
}
&:hover {
overflow: auto;
}
}
#side-menu.open,
#side-menu.open .side-menu-apps-list,
#side-menu.open .side-menu-header {
width: 100%;
}
&-header {
height: 49px;
width: 50px;
}
#side-menu.open .side-menu-app-text {
display: inline;
&-logo {
display: none;
}
&-app {
&-text {
display: none;
}
}
&.open {
width: 100%;
max-width: 290px;
.cm-apps {
width: 100%;
}
.cm-app {
&-text {
display: inline;
}
}
.cm-header {
width: 100%;
}
}
}
.app-navigation-toggle-wrapper {
@ -348,55 +361,40 @@
}
}
.app-menu {
visibility: hidden;
}
@media screen and (max-width: 1024px) {
.cm {
&--topwidemenu {
max-width: 290px;
height: 100vh;
.app-menu.show {
visibility: visible;
}
.cm-header {
max-width: 100%;
}
}
.side-menu-search {
float: right;
}
&-categories {
display: block;
padding: 0;
}
.side-menu-search {
input {
background: none;
border: 0;
border-radius: 0;
color: var(--side-menu-text-color);
&::placeholder {
color: var(--side-menu-text-color);
&-category {
padding: 10px 0;
}
}
}
@media screen and (max-width: 1024px) {
#side-menu.side-menu-big {
max-width: 290px;
height: 100vh;
}
.side-menu-categories {
display: block;
padding: 0;
}
.side-menu-category {
padding: 10px 0;
}
}
@media screen and (min-width: 1024px) {
.side-menu-closer {
display: block;
float: right;
margin-right: 9px;
}
.cm {
&--topwidemenu {
.cm-header {
max-width: 100%;
}
}
.side-menu-big .side-menu-header {
max-width: 100%;
&-closer {
display: block;
float: right;
margin-right: 9px;
}
}
}

View file

@ -15,7 +15,7 @@
<?php endif; ?>
<?php if ($_['size-text'] === 'hidden'): ?>
#side-menu, .side-menu-apps-list {
.cm-apps {
<?php if ($_['size-icon'] === 'big'): ?>
width: 55px;
<?php else: ?>
@ -23,7 +23,7 @@
<?php endif; ?>
}
#side-menu .side-menu-opener {
.cm .cm-opener {
<?php if ($_['size-icon'] === 'big'): ?>
margin-left: 1px;
<?php else: ?>
@ -33,51 +33,51 @@
<?php endif; ?>
<?php if ($_['size-icon'] === 'hidden'): ?>
.side-menu-app-icon {
.cm-app-icon {
display: none;
}
<?php elseif ($_['size-icon'] === 'small'): ?>
.side-menu-app-icon svg {
.cm-app-icon svg {
width: 15px;
height: 15px;
}
img.side-menu-app-icon {
img.cm-app-icon {
width: 15px;
height: 15px;
}
<?php elseif ($_['size-icon'] === 'normal'): ?>
.side-menu-app-icon svg {
.cm-app-icon svg {
width: 20px;
height: 20px;
}
img.side-menu-app-icon {
img.cm-app-icon {
width: 20px;
height: 20px;
}
<?php elseif ($_['size-icon'] === 'big'): ?>
.side-menu-app-icon svg {
.cm-app-icon svg {
width: 23px;
height: 23px;
}
img.side-menu-app-icon {
img.cm-app-icon {
width: 23px;
height: 23px;
}
<?php endif; ?>
<?php if ($_['size-text'] === 'hidden'): ?>
.side-menu-app-text {
.cm-app-text {
display: none;
}
<?php elseif ($_['size-text'] === 'small'): ?>
.side-menu-app-text {
.cm-app-text {
font-size: 12px;
}
<?php elseif ($_['size-text'] === 'big'): ?>
.side-menu-app-text {
.cm-app-text {
font-size: 16px;
}
<?php endif; ?>