Mobile first layout with sidebar in bottom of screen.
This commit is contained in:
parent
06ad60e917
commit
865a070826
7 changed files with 155 additions and 82 deletions
66
src/App.vue
66
src/App.vue
|
|
@ -1,22 +1,70 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RouterView } from 'vue-router'
|
import { RouterView } from 'vue-router'
|
||||||
|
import Footer from "@/components/Footer.vue";
|
||||||
import Sidebar from "@/components/Sidebar.vue";
|
import Sidebar from "@/components/Sidebar.vue";
|
||||||
import TopBar from "@/components/TopBar.vue";
|
import TopBar from "@/components/TopBar.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="min-h-screen flex relative lg:static bg-surface-50 dark:bg-surface-950">
|
<div class="act-layout">
|
||||||
<Sidebar></Sidebar>
|
<TopBar class="act-header"></TopBar>
|
||||||
<main class="min-h-screen flex flex-col relative flex-auto">
|
<div class="act-sidebar">
|
||||||
<TopBar></TopBar>
|
<Sidebar></Sidebar>
|
||||||
<div class="p-0 sm:p-4">
|
</div>
|
||||||
<div class="border-2 border-dashed border-surface rounded-border bg-surface-0 dark:bg-surface-950 flex-auto">
|
<div class="act-content">
|
||||||
<RouterView />
|
<main class="">
|
||||||
</div>
|
<RouterView />
|
||||||
|
</main>
|
||||||
|
<div class="act-footer">
|
||||||
|
<Footer></Footer>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
$header-height: 60px !default;
|
||||||
|
$footer-height: 90px !default;
|
||||||
|
$footer-width: 100px !default;
|
||||||
|
|
||||||
|
.act-layout {
|
||||||
|
// To scroll only in the middle, see https://jsfiddle.net/VNVqs/
|
||||||
|
margin-bottom: $footer-height; // for scrolling
|
||||||
|
margin-top: $header-height; // for scrolling
|
||||||
|
.act-footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.act-sidebar {
|
||||||
|
bottom: 0;
|
||||||
|
height: $footer-height;
|
||||||
|
left: 0;
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
.act-header {
|
||||||
|
height: $header-height;
|
||||||
|
left: 0;
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
@media (screen(sm)) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-left: $footer-width;
|
||||||
|
.act-footer {
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
.act-sidebar {
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
position: fixed;
|
||||||
|
width: $footer-width;
|
||||||
|
}
|
||||||
|
.act-header {
|
||||||
|
left: $footer-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,7 @@
|
||||||
@import './base.css';
|
@import './base.css';
|
||||||
@import 'primeicons/primeicons.css';
|
@import 'primeicons/primeicons.css';
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: #111;
|
||||||
|
background-color: #F2F2F2;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
.nav-item {
|
.nav-item {
|
||||||
@apply flex flex-row lg:flex-col items-center cursor-pointer p-4 lg:justify-center hover:bg-surface-800 rounded-border text-surface-300 hover:text-white duration-150 transition-colors;
|
@apply flex flex-col items-center p-4 lg:justify-center hover:bg-surface-800 rounded-border text-surface-300 hover:text-white duration-150 transition-colors;
|
||||||
span {
|
span {
|
||||||
@apply font-medium inline text-base lg:text-xs lg:block;
|
@apply font-medium inline text-base lg:text-xs lg:block;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
src/components/Footer.vue
Normal file
22
src/components/Footer.vue
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<footer>
|
||||||
|
footer
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
@import "@/assets/nav-items.css";
|
||||||
|
footer {
|
||||||
|
background-color: #E0E0E0;
|
||||||
|
color: #777;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
@media (screen(sm)) {
|
||||||
|
aside {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,46 +1,47 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<nav class="mt-4">
|
<nav>
|
||||||
<ul class="list-none p-4 m-0">
|
<RouterLink
|
||||||
<li>
|
class="nav-item"
|
||||||
<RouterLink
|
to="/">
|
||||||
class="nav-item"
|
<i class="pi pi-home nav-icon" />
|
||||||
to="/">
|
<span>Home</span>
|
||||||
<i class="pi pi-home nav-icon" />
|
</RouterLink>
|
||||||
<span>Home</span>
|
<RouterLink class="nav-item" to="/sticker">
|
||||||
</RouterLink>
|
<i class="pi pi-image nav-icon" />
|
||||||
</li>
|
<span>Sticker</span>
|
||||||
<li>
|
</RouterLink>
|
||||||
<RouterLink class="nav-item" to="/sticker">
|
<a class="nav-item">
|
||||||
<i class="pi pi-image nav-icon" />
|
<i class="pi pi-users nav-icon" />
|
||||||
<span>Sticker</span>
|
<span>Team</span>
|
||||||
</RouterLink>
|
</a>
|
||||||
</li>
|
<a class="nav-item">
|
||||||
<li>
|
<i class="pi pi-calendar nav-icon" />
|
||||||
<a class="nav-item">
|
<span>Events</span>
|
||||||
<i class="pi pi-users nav-icon" />
|
</a>
|
||||||
<span>Team</span>
|
<RouterLink
|
||||||
</a>
|
class="nav-item"
|
||||||
</li>
|
to="/about">
|
||||||
<li>
|
<i class="pi pi-info-circle nav-icon" />
|
||||||
<a class="nav-item">
|
<span>About</span>
|
||||||
<i class="pi pi-calendar nav-icon" />
|
</RouterLink>
|
||||||
<span>Events</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<RouterLink
|
|
||||||
class="nav-item"
|
|
||||||
to="/about">
|
|
||||||
<i class="pi pi-info-circle nav-icon" />
|
|
||||||
<span>About</span>
|
|
||||||
</RouterLink>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@import "@/assets/nav-items.css";
|
@import "@/assets/nav-items.css";
|
||||||
.nav-icon {
|
.nav-icon {
|
||||||
@apply mr-2 lg:mr-0 mb-0 lg:mb-2 text-base lg:text-lg;
|
@apply mr-2 lg:mr-0 mb-0 lg:mb-2 text-base lg:text-lg;
|
||||||
}
|
}
|
||||||
|
nav {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
@media (screen(sm)) {
|
||||||
|
nav {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,33 @@
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
import Navigation from "@/components/Navigation.vue";
|
import Navigation from "@/components/Navigation.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<aside id="app-sidebar-5" class="bg-surface-900 h-screen hidden lg:block flex-shrink-0 absolute lg:static left-0 top-0 z-10 border-surface-800 w-36 lg:w-28 select-none">
|
<aside>
|
||||||
<div class="flex flex-col h-full">
|
<Navigation></Navigation>
|
||||||
<div class="flex items-center justify-center flex-shrink-0 bg-primary h-[60px]">
|
<div class="mt-auto">
|
||||||
Designer
|
<hr class="mb-4 mx-4 border-t border-0 border-surface-800" />
|
||||||
</div>
|
<a class="m-4 nav-item">
|
||||||
<Navigation></Navigation>
|
<img
|
||||||
<div class="mt-auto">
|
alt="user avatar"
|
||||||
<hr class="mb-4 mx-4 border-t border-0 border-surface-800" />
|
src="https://fqjltiegiezfetthbags.supabase.co/storage/v1/render/image/public/block.images/blocks/avatars/circle/avatar-f-1.png" class="mr-2 lg:mr-0 w-8 h-8" />
|
||||||
<a class="m-4 nav-item">
|
<span class="font-medium inline lg:hidden">Amy Elsner</span>
|
||||||
<img
|
</a>
|
||||||
alt="user avatar"
|
|
||||||
src="https://fqjltiegiezfetthbags.supabase.co/storage/v1/render/image/public/block.images/blocks/avatars/circle/avatar-f-1.png" class="mr-2 lg:mr-0 w-8 h-8" />
|
|
||||||
<span class="font-medium inline lg:hidden">Amy Elsner</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@import "@/assets/nav-items.css";
|
@import "@/assets/nav-items.css";
|
||||||
|
aside {
|
||||||
|
background-color: #333;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
@media (screen(sm)) {
|
||||||
|
aside {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -11,21 +11,8 @@ watch(() => route.meta, (newVal, oldVal) => {
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<header class="flex justify-between items-center px-4 bg-surface-0 dark:bg-surface-950 relative lg:static border-b border-surface h-[60px]">
|
<header class="flex justify-between items-center px-4">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<a
|
|
||||||
v-styleclass="{
|
|
||||||
selector: '#app-sidebar-5',
|
|
||||||
enterFromClass: 'hidden',
|
|
||||||
enterActiveClass: 'animate-fadeinleft',
|
|
||||||
leaveToClass: 'hidden',
|
|
||||||
leaveActiveClass: 'animate-fadeoutleft',
|
|
||||||
hideOnOutsideClick: true
|
|
||||||
}"
|
|
||||||
class="cursor-pointer block lg:hidden text-surface-700 dark:text-surface-100 mr-4 mt-2"
|
|
||||||
>
|
|
||||||
<i class="pi pi-bars text-4xl" />
|
|
||||||
</a>
|
|
||||||
<span class="title">{{ page_title }}</span>
|
<span class="title">{{ page_title }}</span>
|
||||||
</div>
|
</div>
|
||||||
<a
|
<a
|
||||||
|
|
@ -43,7 +30,6 @@ watch(() => route.meta, (newVal, oldVal) => {
|
||||||
</a>
|
</a>
|
||||||
<ul
|
<ul
|
||||||
class="list-none p-0 m-0 hidden lg:flex lg:items-center select-none lg:flex-row bg-surface-0 dark:bg-surface-950 border lg:border-0 border-surface right-0 top-full z-10 shadow lg:shadow-none absolute lg:static"
|
class="list-none p-0 m-0 hidden lg:flex lg:items-center select-none lg:flex-row bg-surface-0 dark:bg-surface-950 border lg:border-0 border-surface right-0 top-full z-10 shadow lg:shadow-none absolute lg:static"
|
||||||
id="header-icons"
|
|
||||||
>
|
>
|
||||||
<li>
|
<li>
|
||||||
<a>
|
<a>
|
||||||
|
|
@ -78,10 +64,14 @@ watch(() => route.meta, (newVal, oldVal) => {
|
||||||
.title {
|
.title {
|
||||||
font-size: 160%;
|
font-size: 160%;
|
||||||
}
|
}
|
||||||
#header-icons li a {
|
header {
|
||||||
@apply flex p-4 lg:px-4 lg:py-2 items-center text-surface-600 dark:text-surface-200 hover:text-surface-900 dark:hover:text-surface-0 hover:bg-surface-100 dark:hover:bg-surface-700 font-medium rounded-border cursor-pointer duration-150 transition-colors;
|
background-color: white;
|
||||||
i {
|
border-bottom: 1px solid #BBB;
|
||||||
@apply text-base lg:!text-2xl leading-none;
|
li a {
|
||||||
|
@apply flex p-4 lg:px-4 lg:py-2 items-center text-surface-600 dark:text-surface-200 hover:text-surface-900 dark:hover:text-surface-0 hover:bg-surface-100 dark:hover:bg-surface-700 font-medium rounded-border cursor-pointer duration-150 transition-colors;
|
||||||
|
i {
|
||||||
|
@apply text-base lg:!text-2xl leading-none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue