Skip to content

Commit

Permalink
Add sidebar examples, fix sidebars
Browse files Browse the repository at this point in the history
  • Loading branch information
dolanske committed Jan 27, 2025
1 parent ec7d59b commit 2be8b7c
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 16 deletions.
3 changes: 3 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import ExampleKBD from './examples/ExampleKBD.vue'
import ExampleModals from './examples/ExampleModals.vue'
import ExamplePopouts from './examples/ExamplePopouts.vue'
import ExampleSheets from './examples/ExampleSheets.vue'
import ExampleSidebars from './examples/ExampleSidebars.vue'
import ExampleSkeletons from './examples/ExampleSkeletons.vue'
import ExampleSpinners from './examples/ExampleSpinners.vue'
import ExampleTables from './examples/ExampleTables.vue'
Expand Down Expand Up @@ -84,6 +85,8 @@ import ExampleTooltips from './examples/ExampleTooltips.vue'
<ExampleFlexGrid />
<Divider :size="64" />
<ExampleTables />
<Divider :size="64" />
<ExampleSidebars />
</div>
</main>
</template>
35 changes: 24 additions & 11 deletions src/components/Sidebar/Sidebar.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang='ts'>
import { useCssVar, useMouse, useTimeoutFn, watchThrottled } from '@vueuse/core'
import { computed, useSlots, useTemplateRef } from 'vue'
import { useCssVar, useMouse, useMouseInElement, useTimeoutFn, watchThrottled } from '@vueuse/core'
import { computed, onMounted, useSlots, useTemplateRef } from 'vue'
import { isNil } from '../../shared/helpers'
import './sidebar.scss'
Expand All @@ -27,38 +27,51 @@ interface Props {
}
const sidebar = useTemplateRef('sidebar')
const open = defineModel<boolean>()
const open = defineModel<boolean>({
default: true,
})
const slots = useSlots()
const offset = useCssVar('--vui-sidebar-float-offset', sidebar, {
initialValue: '8px',
})
const width = computed(() => {
if (props.mini)
return `65px`
if (props.mini) {
return props.floaty ? '73px' : `65px`
}
if (!props.floaty)
return `${props.width}px`
return `calc(${props.width}px - ${offset.value})`
return `calc(${props.width}px + ${offset.value})`
})
const slotProps = computed(() => ({
mini: props.mini,
floaty: props.floaty,
width: props.width,
open,
close: () => open.value = false,
}))
// Sidebar `appear` implementation
const { start, stop, isPending } = useTimeoutFn(() => {
open.value = true
if (props.appear) {
open.value = true
}
}, 250)
const APPEAR_OFFSET = 32
const { x } = useMouse()
const wrap = useTemplateRef('wrap')
const { elementX } = useMouseInElement(wrap)
onMounted(() => {
if (props.appear && open.value) {
open.value = false
}
})
watchThrottled(x, (pos) => {
if (!props.appear)
watchThrottled(elementX, (pos) => {
if (!props.appear || (pos <= APPEAR_OFFSET && pos >= 0 && isPending.value))
return
if (pos <= APPEAR_OFFSET && pos >= 0 && !open.value && !isPending.value) {
Expand All @@ -83,7 +96,7 @@ watchThrottled(x, (pos) => {
</script>

<template>
<div class="vui-sidebar-outer" :style="{ width }" :class="{ open }">
<div ref="wrap" class="vui-sidebar-outer" :style="{ width }" :class="{ open }">
<aside ref="sidebar" class="vui-sidebar" :class="{ open, floaty: props.floaty, mini: props.mini }" :style="{ width: `${props.mini ? 65 : props.width}px` }">
<div v-if="slots.header" class="vui-sidebar-header">
<slot name="header" v-bind="slotProps" />
Expand Down
10 changes: 5 additions & 5 deletions src/components/Sidebar/sidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
.vui-sidebar-layout {
display: flex;
flex-wrap: nowrap;
gap: 32px;
gap: 0;
height: 100vh;
position: relative;

main {
flex: 1;
padding: 2rem;
}

.vui-sidebar-outer {
Expand All @@ -22,11 +22,11 @@
.vui-sidebar {
--vui-sidebar-float-offset: 8px;
display: flex;
height: 100%;
flex-direction: column;
gap: var(--space-sm);
height: 100vh;
width: 224px;
position: fixed;
position: absolute;
top: 0;
z-index: 50;
background-color: var(--color-bg);
Expand All @@ -47,7 +47,7 @@
top: var(--vui-sidebar-float-offset);
left: var(--vui-sidebar-float-offset);
bottom: var(--vui-sidebar-float-offset);
height: calc(100vh - calc(var(--vui-sidebar-float-offset) * 2));
height: calc(100% - calc(var(--vui-sidebar-float-offset) * 2));
border-radius: var(--border-radius-m);
border: 1px solid var(--color-border);
transform: translateX(calc(-100% - calc(var(--vui-sidebar-float-offset) * 2)));
Expand Down
265 changes: 265 additions & 0 deletions src/examples/ExampleSidebars.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
<script setup lang='ts'>
import { ref } from 'vue'
import Avatar from '../components/Avatar/Avatar.vue'
import Button from '../components/Button/Button.vue'
import Divider from '../components/Divider/Divider.vue'
import DropdownItem from '../components/Dropdown/DropdownItem.vue'
import Flex from '../components/Flex/Flex.vue'
import Grid from '../components/Grid/Grid.vue'
import Sidebar from '../components/Sidebar/Sidebar.vue'
const s1 = ref(true)
const s2 = ref(true)
const s3 = ref(true)
</script>

<template>
<div class="mb-xxl">
<h3 class="mb-l">
Sidebars
</h3>

<Grid :columns="2" gap="xl">
<div>
<span class="mb-m block">Base + slots</span>
<div class="vui-sidebar-layout" :style="{ height: '512px' }">
<Sidebar>
<template #header>
<Flex align-center>
<img src="https://dolansky.dev/backgrounds/star.png" style="filter:invert()" width="40" alt="">
<h3>ABC</h3>
</Flex>
</template>
<DropdownItem icon="ph:house">
Home
</DropdownItem>
<DropdownItem icon="ph:user">
About
</DropdownItem>
<DropdownItem icon="ph:phone">
Contact
</DropdownItem>

<template #footer>
<Flex align-center>
<Avatar size="m" />
<span class="flex-1">dolanske</span>
<Button plain size="s" icon="ph:sign-out" />
</Flex>
</template>
</Sidebar>
<main class="p-l typeset">
<h4>My page</h4>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Atque deleniti asperiores quibusdam et commodi deserunt libero officia doloremque. Possimus ipsum sunt odit culpa consequatur hic reiciendis doloremque consequuntur tempore excepturi?</p>
<hr>
<p>Yes that's correct</p>
<ul>
<li>Secure</li>
<li>Reliant</li>
<li>Ublumf</li>
</ul>
</main>
</div>
</div>

<div>
<span class="mb-m block">Toggleable + floaty</span>
<div class="vui-sidebar-layout" :style="{ height: '512px' }">
<Sidebar v-model="s1" floaty>
<template #header="{ close }">
<Flex align-center>
<img src="https://dolansky.dev/backgrounds/star.png" style="filter:invert()" width="40" alt="">
<h3 class="flex-1">
ABC
</h3>
<Button plain size="s" icon="ph:x" @click="close" />
</Flex>
</template>
<DropdownItem icon="ph:house">
Outside
</DropdownItem>
<DropdownItem icon="ph:user">
About You
</DropdownItem>
<DropdownItem icon="ph:phone">
No contact
</DropdownItem>
</Sidebar>
<main class="p-l">
<Flex align-center class="mb-m">
<Button plain size="s" icon="ph:sidebar-simple" @click="s1 = !s1" />
<h4>
My page
</h4>
</Flex>

<div class="typeset">
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Atque deleniti asperiores quibusdam et commodi deserunt libero officia doloremque. Possimus ipsum sunt odit culpa consequatur hic reiciendis doloremque consequuntur tempore excepturi?</p>
<hr>
<p>Yes that's correct</p>
<ul>
<li>Secure</li>
<li>Reliant</li>
<li>Ublumf</li>
</ul>
</div>
</main>
</div>
</div>

<div>
<span class="mb-m block">Mini </span>
<div class="vui-sidebar-layout" :style="{ height: '512px' }">
<Sidebar v-model="s2" mini>
<template #header>
<Flex align-center>
<img src="https://dolansky.dev/backgrounds/star.png" style="filter:invert()" width="40" alt="">
</Flex>
</template>
<DropdownItem icon="ph:house">
Home
</DropdownItem>
<DropdownItem icon="ph:user">
About
</DropdownItem>
<DropdownItem icon="ph:phone">
Contact
</DropdownItem>

<template #footer="{ close }">
<Flex justify-center>
<Button plain icon="ph:x" @click="close" />
</Flex>
</template>
</Sidebar>
<main class="p-l">
<Flex align-center class="mb-m">
<Button plain size="s" icon="ph:sidebar-simple" @click="s2 = !s2" />
<h4>
My page
</h4>
</Flex>

<div class="typeset">
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Atque deleniti asperiores quibusdam et commodi deserunt libero officia doloremque. Possimus ipsum sunt odit culpa consequatur hic reiciendis doloremque consequuntur tempore excepturi?</p>
<hr>
<p>Yes that's correct</p>
<ul>
<li>Secure</li>
<li>Reliant</li>
<li>Ublumf</li>
</ul>
</div>
</main>
</div>
</div>

<div>
<span class="mb-m block">Mini & floaty </span>
<div class="vui-sidebar-layout" :style="{ height: '512px' }">
<Sidebar v-model="s3" mini floaty>
<template #header>
<Flex align-center>
<img src="https://dolansky.dev/backgrounds/star.png" style="filter:invert()" width="40" alt="">
</Flex>
</template>
<DropdownItem icon="ph:house">
Home
</DropdownItem>
<DropdownItem icon="ph:user">
About
</DropdownItem>
<DropdownItem icon="ph:phone">
Contact
</DropdownItem>

<template #footer="{ close }">
<Flex justify-center>
<Button plain icon="ph:x" @click="close" />
</Flex>
</template>
</Sidebar>
<main class="p-l">
<Flex align-center class="mb-m">
<Button plain size="s" icon="ph:sidebar-simple" @click="s3 = !s3" />
<h4>
My page
</h4>
</Flex>

<div class="typeset">
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Atque deleniti asperiores quibusdam et commodi deserunt libero officia doloremque. Possimus ipsum sunt odit culpa consequatur hic reiciendis doloremque consequuntur tempore excepturi?</p>
<hr>
<p>Yes that's correct</p>
<ul>
<li>Secure</li>
<li>Reliant</li>
<li>Ublumf</li>
</ul>
</div>
</main>
</div>
</div>

<div>
<span class="mb-m block">Appear + custom width</span>
<div class="vui-sidebar-layout" :style="{ height: '512px' }">
<Sidebar appear :width="300">
<template #header>
<img src="https://dolansky.dev/backgrounds/star.png" style="filter:invert()" width="40" alt="">
</template>
<DropdownItem icon="ph:house">
Home
</DropdownItem>
<DropdownItem icon="ph:user">
About
</DropdownItem>
<DropdownItem icon="ph:phone">
Contact
</DropdownItem>
</Sidebar>
<main class="p-l typeset">
<h4>
Appear sidebar
</h4>
<p>This sidebar will appear automatically whenever the curosor is close to the edge of the sidebar wrapper.</p>
</main>
</div>
</div>

<div>
<span class="mb-m block">Appear + mini + floaty</span>
<div class="vui-sidebar-layout" :style="{ height: '512px' }">
<Sidebar appear mini floaty>
<template #header>
<img src="https://dolansky.dev/backgrounds/star.png" style="filter:invert()" width="40" alt="">
</template>
<DropdownItem icon="ph:house">
Home
</DropdownItem>
<DropdownItem icon="ph:user">
About
</DropdownItem>
<DropdownItem icon="ph:phone">
Contact
</DropdownItem>
</Sidebar>
<main class="p-l typeset">
<h4>
Appear sidebar
</h4>
<p>This sidebar will appear automatically whenever the curosor is close to the edge of the sidebar wrapper.</p>
</main>
</div>
</div>
</Grid>
</div>
</template>

<style scoped>
.vui-sidebar-layout {
border: 1px solid var(--color-border);
border-radius: var(--border-radius-m);
overflow: hidden;
}
</style>

0 comments on commit 2be8b7c

Please sign in to comment.