-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
copy m3 design to playground/m3.html
- Loading branch information
Showing
20 changed files
with
2,224 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
<script> | ||
const appFloatMenu = { | ||
all: { | ||
data() { | ||
return { | ||
selected: null, | ||
submenu: null, | ||
show: false, | ||
showSubMenu: false, | ||
init() { | ||
this.$nextTick(() => { | ||
this.show = true; | ||
}); | ||
}, | ||
openMenuControl(menu) { | ||
if (menu.children && menu.children.length > 0) { | ||
this.selected = menu.name; | ||
this.$nextTick(() => { | ||
this.showSubMenu = true; | ||
}); | ||
} | ||
}, | ||
back() { | ||
if (this.selected) { | ||
this.showSubMenu = false; | ||
this.$nextTick(() => { | ||
setTimeout(() => this.selected = null, 300); | ||
}); | ||
} else { | ||
this.show = false; | ||
setTimeout(() => this.$dispatch('close-sub-menu'), 300); | ||
} | ||
} | ||
} | ||
}, | ||
}, | ||
float: { | ||
data() { | ||
return { | ||
show: false, | ||
init() { | ||
this.$nextTick(() => { | ||
this.show = true; | ||
}) | ||
} | ||
} | ||
}, | ||
}, | ||
menu: { | ||
data() { | ||
return { | ||
selected: null, | ||
opens: [], | ||
openSubMenuControl(submenu) { | ||
const index = this.opens.indexOf(submenu.path); | ||
if (index === -1) { | ||
this.opens = [...this.opens, submenu.path] | ||
} else { | ||
this.opens = [...this.opens.slice(0, index), ...this.opens.slice(index + 1)] | ||
} | ||
}, | ||
init() { | ||
if (this.$route.path.startsWith('/')) { | ||
const ps = this.$route.path.split('/'); | ||
ps.pop(); | ||
this.opens = [ps.join('/')]; | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
getSubmenu(menus, name) { | ||
if (!name) return null; | ||
const menu = menus.find(m => m.name === name) || { name: '' }; | ||
return menu; | ||
}, | ||
} | ||
</script> | ||
|
||
<template x-component:app="float-menu-all" x-data="appFloatMenu.all.data"> | ||
<div class="absolute top-0 left-0 w-full h-full bg-zinc-800/70 border" style="z-index:0;" | ||
@click="show=false;setTimeout(() => $dispatch('close-sub-menu'), 300);"></div> | ||
<div :class="`shadow-md grid absolute top-0 left-0 h-full bg-${$store.page.color}-100 font-medium text-${$store.page.color}-600 dark:text-white dark:bg-${$store.page.color}-700 border-l border-l-${$store.page.color}-500 overflow-hidden`" | ||
:style="`${show ? 'width:308px;' : 'width:0px;'} transition: width 0.3s; z-index:1;grid-template-rows: 50px auto 78px;`"> | ||
<div class="px-2 py-2"> | ||
<button :class="`hover:bg-${$store.page.color}-200 dark:hover:bg-${$store.page.color}-600 rounded-full p-3`" | ||
@click="back"> | ||
<i class="uil uil-left-indent text-2xl"></i> | ||
</button> | ||
</div> | ||
<div> | ||
<template x-if="Boolean(selected) === false"> | ||
<template x-for="(menu, index) in $prop('menus', [])"> | ||
<div :class="`${index===0 ? 'pt-0' : ''} px-2`"> | ||
<template x-if="!Boolean(menu.children) || menu.children.length === 0"> | ||
<div | ||
:class="`px-3 flex w-full justify-between items-center hover:bg-${$store.page.color}-200 dark:hover:bg-${$store.page.color}-600 rounded-full cursor-pointer ${selected === menu.name ? 'bg-sky-200 dark:bg-sky-800' : ''}`"> | ||
|
||
<a :href="`#${menu.path}`" class="flex items-center"> | ||
<i :class="`uil uil-${menu.icon} text-2xl`"></i> | ||
<button class="px-4 py-3 text-sm whitespace-nowrap text-2xl font-semibold" | ||
x-text="menu.name"></button> | ||
</a> | ||
</div> | ||
</template> | ||
|
||
<template x-if="Boolean(menu.children) && menu.children.length > 0"> | ||
<div @click="openMenuControl(menu)" | ||
:class="`px-3 flex w-full justify-between items-center hover:bg-${$store.page.color}-200 dark:hover:bg-${$store.page.color}-600 rounded-full cursor-pointer ${selected === menu.name ? 'bg-sky-200 dark:bg-sky-800' : ''}`"> | ||
<div class="flex items-center"> | ||
<i :class="`uil uil-${menu.icon} text-2xl`"></i> | ||
<button class="px-4 py-3 text-sm whitespace-nowrap text-2xl font-semibold" | ||
x-text="menu.name"></button> | ||
</div> | ||
<i class="uil uil-arrow-right text-2xl"></i> | ||
</div> | ||
</template> | ||
</div> | ||
</template> | ||
</template> | ||
<template x-if="Boolean(selected)"> | ||
<div x-data="{menu:appFloatMenu.getSubmenu($prop('menus', []), selected)}"> | ||
<fin-topbar-float-menu :menu="menu" :show="showSubMenu"></fin-topbar-float-menu> | ||
</div> | ||
</template> | ||
</div> | ||
<div class="flex justify-center items-center"> | ||
<template x-if="Boolean(selected) === false"> | ||
<div :class="`hover:bg-${$store.page.color}-200 dark:hover:bg-${$store.page.color}-600 rounded-full px-5 py-3 flex gap-3 cursor-pointer whitespace-nowrap border`" | ||
x-on:click="$store.persist.changeTheme()"> | ||
<i :class="`uil uil-${$store.persist.theme==='dark'?'brightness':'moon'} text-2xl`"></i> | ||
<div x-text="`Switch to ${$store.persist.theme === 'dark' ? 'light': 'dark'} mode`"></div> | ||
</div> | ||
</template> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<template x-component:app="side-float-menu" x-data="appFloatMenu.float.data"> | ||
<div :class="`shadow-md hover:shadow-lg absolute top-0 h-screen bg-${$store.page.color}-100 font-medium text-${$store.page.color}-600 dark:text-white dark:bg-${$store.page.color}-700 border-l border-l-${$store.page.color}-500 overflow-x-hidden overflow-y-auto`" | ||
:style="`left:88px;${show ? 'width:240px;' : 'width:0px;'} transition: width 0.3s; z-index:1;`" | ||
@mouseleave.debounce="if(!$prop('menu') || !Boolean($prop('menu').children) || $prop('menu').children.length === 0) { show=false; }setTimeout(() => $dispatch('close-sub-menu', $prop('menu')), 300);"> | ||
|
||
<div x-data="{menu:$prop('menu')}"> | ||
<fin-float-menu :menu="menu"></fin-float-menu> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<template x-component:fin="topbar-float-menu"> | ||
<div :class="`absolute top-0 h-screen bg-${$store.page.color}-100 font-medium text-${$store.page.color}-600 dark:text-white dark:bg-${$store.page.color}-700 border-l border-l-${$store.page.color}-500 overflow-x-hidden overflow-y-auto`" | ||
:style="`left:64px;${$prop('show') ? 'width:240px;' : 'width:0px;'} transition: width 0.3s; z-index:1;`"> | ||
|
||
<div x-data="{menu:$prop('menu')}"> | ||
<fin-float-menu :menu="menu"></fin-float-menu> | ||
</div> | ||
|
||
</div> | ||
</template> | ||
|
||
<template x-component:fin="float-menu" x-data="appFloatMenu.menu.data"> | ||
<template x-for="(submenu,index) in $prop('menu',{children:[]}).children"> | ||
<div :class="`${index===0 ? 'pt-4' : ''} px-2`"> | ||
|
||
<template x-if="!Boolean(submenu.children) || submenu.children.length === 0"> | ||
<a :href="`#${submenu.path}`" | ||
:class="`mb-1 px-2 flex w-full justify-between hover:bg-${$store.page.color}-300 dark:hover:bg-${$store.page.color}-600 rounded-full cursor-pointer ${$route.path.startsWith(submenu.path || 'abc') ? `bg-${$store.page.color}-300 dark:bg-${$store.page.color}-800` : ''}`"> | ||
<button class="flex justify-center px-4 py-3 text-sm whitespace-nowrap" | ||
x-text="submenu.name"></button> | ||
<template x-if="Boolean(submenu.children) && submenu.children.length > 0"> | ||
<button class="px-4"><i class="uil uil-angle-down text-2xl"></i></button> | ||
</template> | ||
</a> | ||
</template> | ||
|
||
<template x-if="Boolean(submenu.children) && submenu.children.length > 0"> | ||
<div @click="openSubMenuControl(submenu)" | ||
:class="`mb-1 px-2 flex w-full justify-between hover:bg-${$store.page.color}-300 dark:hover:bg-${$store.page.color}-600 rounded-full cursor-pointer ${$route.path.startsWith(submenu.path || 'abc') ? `bg-${$store.page.color}-300 dark:bg-${$store.page.color}-900` : ''}`"> | ||
<button class="flex justify-center px-4 py-3 text-sm whitespace-nowrap" | ||
x-text="submenu.name"></button> | ||
<button class="px-4"><i class="uil uil-angle-down text-2xl"></i></button> | ||
</div> | ||
</template> | ||
|
||
<template x-if="Boolean(submenu.children) && submenu.children.length > 0"> | ||
<div class="pl-4 overflow-hidden" | ||
:style="`${opens.indexOf(submenu.path) !== -1 ? `height:${submenu.children.length * 48}px;` : 'height:0px;'} transition: height 0.6s;`"> | ||
<template x-for="childmenu in submenu.children"> | ||
<a :href="`#${childmenu.path}`" | ||
:class="`mb-1 px-2 flex w-full justify-between hover:bg-${$store.page.color}-300 dark:hover:bg-${$store.page.color}-600 rounded-full cursor-pointer ${$route.path === childmenu.path ? `bg-${$store.page.color}-200 dark:bg-${$store.page.color}-800` : ''}`"> | ||
<button class="flex justify-center px-4 py-3 text-sm whitespace-nowrap" | ||
x-text="childmenu.name"></button> | ||
</a> | ||
</template> | ||
</div> | ||
</template> | ||
</div> | ||
</template> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<template x-component:app="footer"> | ||
<div class="mt-24 mb-16 w-full relative" style="height:8px;"> | ||
<svg aria-hidden="true" width="100%" height="8" fill="none" xmlns="http:https://www.w3.org/2000/svg"> | ||
<pattern id="a" width="91" height="8" patternUnits="userSpaceOnUse"> | ||
<g clip-path="url(#clip0_2426_11367)"> | ||
<path | ||
d="M114 4c-5.067 4.667-10.133 4.667-15.2 0S88.667-.667 83.6 4 73.467 8.667 68.4 4 58.267-.667 53.2 4 43.067 8.667 38 4 27.867-.667 22.8 4 12.667 8.667 7.6 4-2.533-.667-7.6 4s-10.133 4.667-15.2 0S-32.933-.667-38 4s-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0-10.133-4.667-15.2 0-10.133 4.667-15.2 0" | ||
stroke="#E1E3E1" stroke-linecap="square"></path> | ||
</g> | ||
</pattern> | ||
<rect width="100%" height="100%" fill="url(#a)"></rect> | ||
</svg> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<script> | ||
const onThisPage = { | ||
data() { | ||
return { | ||
top: 500, | ||
list: [], | ||
init() { | ||
this.$nextTick(() => { | ||
this.top = this.$prop('top', 500); | ||
this.list = this.$prop('list', []); | ||
}) | ||
}, | ||
onSelect(index) { | ||
if (this.list[index].hrefid) { | ||
this.$dispatch('on-select', this.list[index].hrefid); | ||
} | ||
} | ||
} | ||
}, | ||
scroll(e) { | ||
const onThisPage = document.getElementById('onThisPage'); | ||
const top = +onThisPage.style.top.replace('px', ''); | ||
if (e.target.scrollTop <= (top - 60)) { | ||
onThisPage.style.marginTop = `${-1 * e.target.scrollTop}px`; | ||
} | ||
}, | ||
}; | ||
</script> | ||
<template x-component:app="on-this-page" x-data="onThisPage.data"> | ||
<div id="onThisPage" class="absolute bg-gray-100 dark:bg-neutral-700 dark:text-gray-300 p-4 rounded-lg" :style="`width: 200px; right: 20px; top:${top}px;`"> | ||
<div class="px-6 font-xs font-light">On this page</div> | ||
<template x-for="(item,index) in list"> | ||
<div :class="`px-6 py-1 font-normal rounded-full cursor-pointer ${$prop('selected',0) === index ? `font-semibold border` : ``}`" | ||
x-text="item.text" @click="onSelect(index)"></div> | ||
</template> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<script> | ||
const pageContainer = { | ||
data() { | ||
return { | ||
init() { | ||
setTimeout(() => { | ||
this.$nextTick(() => { | ||
const mainPageContainer = document.getElementById('mainPageContainer'); | ||
this.$store.page.mainSize.width = mainPageContainer.getBoundingClientRect().width; | ||
}) | ||
}, 600) | ||
} | ||
} | ||
} | ||
} | ||
</script> | ||
|
||
<template x-component:app="page-container" id="mainPageContainer" | ||
:class="`bg-transparent w-full text-black dark:text-slate-300 dark:bg-neutral-800 p-2 overflow-y-auto ${$prop('class', '')}`" | ||
:style="`height:${$store.page.size.height - ($store.page.showTopbar ? 60 : 0)}px; ${$prop('style', '')}`" | ||
x-data="pageContainer.data" x-on:scroll="$prop('scroll', () => { })"> | ||
<slot></slot> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<script> | ||
function appSideMenuData() { | ||
return { | ||
selected: this.$route.path, | ||
isSelected(menu) { | ||
const start = menu.path.startsWith('/') ? `/${menu.path.split('/')[1]}` : 'abc'; | ||
return this.selected.startsWith(start); | ||
} | ||
} | ||
}; | ||
</script> | ||
<template x-component:app="side-menu" x-data="appSideMenuData"> | ||
<div :class="`bg-${$store.page.color}-100 font-medium text-${$store.page.color}-600 dark:text-${$store.page.color}-200 dark:bg-${$store.page.color}-700 py-4 h-full grid shadow`" | ||
style="grid-template-rows: auto 60px;"> | ||
<div> | ||
<template x-for="menu in $prop('menus',[])"> | ||
<div class="mb-6"> | ||
<a class="font-medium text-${$store.page.color}-600" :href="`#${menu.path}`"> | ||
<button x-on:click="selected = menu.path" | ||
@mouseenter.debounce="$dispatch('open-sub-menu', menu)" | ||
:class="`m-auto flex justify-center px-4 py-1 hover:bg-${$store.page.color}-200 dark:hover:bg-${$store.page.color}-600 rounded-full cursor-pointer ${isSelected(menu) ? `bg-${$store.page.color}-200 dark:bg-${$store.page.color}-800` : ''}`"> | ||
<i :class="`uil uil-${menu.icon} text-2xl`"></i> | ||
</button> | ||
<div :class="`flex justify-center pt-1 text-xs ${isSelected(menu) ? 'font-bold dark:text-sky-200' : ''}`" | ||
x-text="menu.name"></div> | ||
</a> | ||
</div> | ||
</template> | ||
</div> | ||
<button x-on:click="$store.persist.changeTheme()" | ||
:class="`m-auto flex justify-center p-3 dark:hover:bg-${$store.page.color}-600 rounded-full cursor-pointer border`"> | ||
<i :class="`uil uil-${$store.persist.theme==='dark'?'brightness':'moon'} text-2xl`"></i> | ||
</button> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<script> | ||
const appTabList = { | ||
data() { | ||
return { | ||
list: [], | ||
init() { | ||
this.$nextTick(() => { | ||
this.list = this.$prop('list', []); | ||
}) | ||
}, | ||
onSelect(index) { | ||
this.$dispatch('on-select', index); | ||
} | ||
} | ||
}, | ||
scroll(e) { | ||
const topContainer = document.getElementById('topContainer'); | ||
const tabListContainer = document.getElementById('tabListContainer'); | ||
const tabListInnerContainer = document.getElementById('tabListInnerContainer'); | ||
if (e.target.scrollTop >= topContainer.getBoundingClientRect().height) { | ||
tabListContainer.classList.add('absolute'); | ||
tabListContainer.classList.add('top-0'); | ||
tabListContainer.classList.add('text-xl'); | ||
tabListContainer.classList.add('scale-70'); | ||
|
||
tabListInnerContainer.classList.add('shadow-md'); | ||
|
||
} else { | ||
tabListContainer.classList.remove('absolute'); | ||
tabListContainer.classList.remove('top-0'); | ||
tabListContainer.classList.remove('text-xl'); | ||
tabListContainer.classList.remove('scale-70'); | ||
|
||
tabListInnerContainer.classList.remove('shadow-md'); | ||
} | ||
}, | ||
}; | ||
</script> | ||
<template x-component:app="tab-list" x-data="appTabList.data"> | ||
<div id="tabListContainer" class="h-20 flex justify-center transition-transform delay-100 ease-in-in" | ||
:style="`width:${$store.page.mainSize.width - 32}px`"> | ||
<div id="tabListInnerContainer" | ||
:class="`bg-gray-100 font-medium text-dark dark:text-neutral-200 dark:bg-neutral-700 flex justify-between rounded-full w-full h-full`"> | ||
<template x-for="(item,index) in list"> | ||
<div :class="`h-full rounded-full flex grow justify-center items-center cursor-pointer ${$prop('selected',0) === index ? `font-semibold bg-${$store.page.color}-200 hover:bg-${$store.page.color}-300 dark:bg-${$store.page.color}-400 dark:hover:bg-${$store.page.color}-500` : `bg-transparent hover:bg-gray-300 dark:bg-transparent dark:hover:bg-neutral-700`}`" | ||
x-text="item" @click="onSelect(index)"></div> | ||
</template> | ||
</div> | ||
</div> | ||
</template> |
Oops, something went wrong.