Skip to content

Commit

Permalink
hamburger menu if there are too many languages
Browse files Browse the repository at this point in the history
  • Loading branch information
kongulov committed Dec 27, 2022
1 parent 23f43ab commit cb4c071
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 15 deletions.
2 changes: 1 addition & 1 deletion dist/css/field.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/js/field.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions dist/js/field.js.LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* @license MIT
*/

/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */

/**
* @license
* Lodash <https://lodash.com/>
Expand Down
27 changes: 24 additions & 3 deletions resources/js/components/DetailField.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
<template>
<div id="nova-tab-translatable" class="details w-full">
<div class="tab-items px-8">
<span class="tab-item" v-for="lang in field.languages"
<div class="tab-items px-8" ref="tabItems">
<span class="tab-item"
v-for="lang in lineMenu"
ref="tabItem"
:data-langfor="lang"
:class="{'active':selectedLang === lang}" @click="switchLanguage(lang)">
:class="{'active':selectedLang === lang}"
@click="switchLanguage(lang)"
>
{{ lang }}
</span>

<div id="hamburger-menu" v-show="hamburgerMenu.length">
<div class="hamburger-icon" @click="menuIsOpen = !menuIsOpen" :data-hiddencount="hamburgerMenu.length" :class="{'fs14':hamburgerMenu.length < 100}">
<span></span>
</div>
<div class="hamburger-content tab-items" v-show="menuIsOpen">
<span class="tab-item"
v-for="lang in reversedHamburgerMenu"
ref="tabItem"
:data-langfor="lang"
:class="{'active':selectedLang === lang}"
@click="switchLanguage(lang)"
>
{{ lang }}
</span>
</div>
</div>
</div>
<div class="tab-contents">
<div v-for="(component, index) in field.fields"
Expand Down
25 changes: 22 additions & 3 deletions resources/js/components/FormField.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
<template>
<div id="nova-tab-translatable" class="w-full">
<div class="tab-items px-8">
<div class="tab-items px-8" ref="tabItems">
<span class="tab-item"
v-for="lang in field.languages"
v-for="lang in lineMenu"
ref="tabItem"
:data-langfor="lang"
:class="{'active':selectedLang === lang, 'has-error':checkError(lang)}"
@click="switchLanguage(lang)"
>
{{ lang }}
<span class="text-danger text-sm">{{ field.requiredLocales[lang] !== undefined && field.requiredLocales[lang] == true ? '*' : '' }}</span>
</span>

<div id="hamburger-menu" v-show="hamburgerMenu.length">
<div class="hamburger-icon" @click="menuIsOpen = !menuIsOpen" :data-hiddencount="hamburgerMenu.length" :class="{'fs14':hamburgerMenu.length < 100}">
<span></span>
</div>
<div class="hamburger-content tab-items" v-show="menuIsOpen">
<span class="tab-item"
v-for="lang in reversedHamburgerMenu"
ref="tabItem"
:data-langfor="lang"
:class="{'active':selectedLang === lang, 'has-error':checkError(lang)}"
@click="switchLanguage(lang)"
>
{{ lang }}
<span class="text-danger text-sm">{{ field.requiredLocales[lang] !== undefined && field.requiredLocales[lang] == true ? '*' : '' }}</span>
</span>
</div>
</div>
</div>
<div class="tab-contents">
<div class="tab-content"
<div class="tab-content"
v-for="(component, index) in field.fields"
v-show="selectedLang === component.locale && checkVisibility(component)"
:data-lang="component.locale">
Expand Down
30 changes: 25 additions & 5 deletions resources/js/components/IndexField.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
<template>
<div class="nova-tab-translatable-index w-full">
<div class="tab-items px-8">
<span class="tab-item" v-for="lang in field.languages"
<div class="tab-items px-8" ref="tabItems">
<span class="tab-item"
v-for="lang in lineMenu"
ref="tabItem"
:data-langfor="lang"
:class="{'active':selectedLang === lang}" @click.stop="switchLanguage(lang)">
:class="{'active':selectedLang === lang}"
@click.stop="switchLanguage(lang)">
{{ lang }}
</span>

<div id="hamburger-menu" v-show="hamburgerMenu.length">
<div class="hamburger-icon" @click.stop="menuIsOpen = !menuIsOpen" :data-hiddencount="hamburgerMenu.length" :class="{'fs14':hamburgerMenu.length < 100}">
<span></span>
</div>
<div class="hamburger-content tab-items" v-show="menuIsOpen">
<span class="tab-item"
v-for="lang in reversedHamburgerMenu"
ref="tabItem"
:data-langfor="lang"
:class="{'active':selectedLang === lang}"
@click.stop="switchLanguage(lang)"
>
{{ lang }}
</span>
</div>
</div>
</div>
<div class="tab-contents">
<div class="tab-content" style="display: flex"
<div class="tab-content" style="display: flex"
v-for="(component, index) in field.fields"
v-show="selectedLang === component.locale && component.showOnIndex"
:data-lang="component.locale">
<span style="margin-right: 5px;">{{ componentName(component) }}:</span>
<span style="margin-right: 5px;">{{ componentName(component) }} [{{ component.locale}}]:</span>
<component
:key="index"
:class="{'remove-bottom-border ': (index + 1) % field.originalFieldsCount !== 0}"
Expand Down
46 changes: 46 additions & 0 deletions resources/js/mixins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,60 @@ export default {
data() {
return {
selectedLang: '',

menuIsOpen:false,
totalSpace: 0,
lineMenu: [],
hamburgerMenu: [],
breakWidths: [],
}
},
mounted() {
this.selectedLang = this.getSelectedLang();
this.lineMenu = this.field.languages;

window.addEventListener("resize", this.calculateMenu);

this.$nextTick(() => {
this.$refs.tabItem.forEach(col => {
this.totalSpace += col.clientWidth;
this.breakWidths.push(this.totalSpace);
})

this.calculateMenu();
})
},
destroyed() {
window.removeEventListener("resize", this.calculateMenu);
},
computed: {
reversedHamburgerMenu(){
return this.hamburgerMenu.slice().reverse();
}
},
methods: {
calculateMenu(){
let tabItems = this.$refs.tabItems;
let availableSpace = tabItems.clientWidth - ( 24 * 2 ) - 40; // 24*2=padding, 15=?, 40=hamburgerMenu
let numOfVisibleItems = this.lineMenu.length;
let requiredSpace = this.breakWidths[numOfVisibleItems - 1];

if (requiredSpace > availableSpace) {
this.hamburgerMenu.push(this.lineMenu[this.lineMenu.length - 1]);
this.lineMenu.pop();
numOfVisibleItems -= 1;
this.calculateMenu();
// There is more than enough space
} else if (availableSpace > this.breakWidths[numOfVisibleItems]) {
this.lineMenu.push(this.hamburgerMenu[this.hamburgerMenu.length - 1]);
this.hamburgerMenu.pop();
numOfVisibleItems += 1;
this.calculateMenu();
}
},
switchLanguage(lang){
this.selectedLang = lang;
this.menuIsOpen = false;

localStorage.setItem(this.getStorageName()+'lastSelectedLang', lang);
},
Expand Down
109 changes: 107 additions & 2 deletions resources/sass/field.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#nova-tab-translatable {
position: relative;

&.details{
margin-top: 8px;
}
Expand All @@ -15,12 +17,13 @@

.tab-item {
display: block;
white-space: nowrap;
color: #7c858e;
text-decoration: none;
background-color: transparent;
padding: .5rem 1rem;
margin-bottom: -1px;
border: 1px solid transparent;
border: 0;
border-top-left-radius: .25rem;
border-top-right-radius: .25rem;
cursor: pointer;
Expand Down Expand Up @@ -89,11 +92,12 @@

.tab-item {
display: block;
white-space: nowrap;
color: #4099de;
text-decoration: none;
background-color: transparent;
margin-bottom: -1px;
border: 1px solid transparent;
border: 0;
border-top-left-radius: .25rem;
border-top-right-radius: .25rem;
cursor: pointer;
Expand All @@ -116,6 +120,94 @@
}
}

#hamburger-menu{
padding: 0 0.5rem;

.hamburger-icon{
cursor: pointer;
position: relative;
width: 38px;
height: 38px;
display: inline-block;
padding: 5px;

&:after{
content: attr(data-hiddencount);
position: absolute;
right: -5px;
top: -5px;
background: #7c858e;
color: #ffffff;
border-radius: 50%;
width: 22px;
height: 22px;
display: flex;
justify-content: center;
align-items: center;
font: 11px Arial, sans-serif;
}
&.fs14{
&:after {
font: 14px Arial, sans-serif;
}
}

span{
position: relative;
display: inline-block;
width: 28px;
height: 3px;
background: #7c858e;
margin: auto;

&:before{
content: '';
position: absolute;
left: 0;
top: -8px;
width: 28px;
height: 3px;
background: #7c858e;
}

&:after {
content: '';
position: absolute;
left: 0;
bottom: -8px;
width: 28px;
height: 3px;
background: #7c858e;
}
}
}

.hamburger-content{
position: absolute;
background-color: #eef1f4;
flex-direction: column;
z-index: 1;
right: 0;
max-height: 300px;
overflow: auto;
margin-top: unset;
margin-bottom: unset;
border: 0;

box-shadow: 0 0 #0000, 0 0 #0000, 0 0 #0000, 0 0 #0000, 0 1px 3px 0 rgba(0,0,0,.1), 0 1px 2px -1px rgba(0,0,0,.1);

.tab-item{
margin-bottom: unset;
}
}
}

.nova-tab-translatable-index{
#hamburger-menu{
position: relative;
}
}

html.dark {
#nova-tab-translatable,
.nova-tab-translatable-index,{
Expand Down Expand Up @@ -160,5 +252,18 @@ html.dark {
}
}
}

#hamburger-menu{
.hamburger-icon{
&:after{
background: #1e293b;
color: unset;
}
}

.hamburger-content{
background-color: #344155;
}
}
}

0 comments on commit cb4c071

Please sign in to comment.