Added first sidebar draft

This commit is contained in:
Alexis
2025-04-28 17:18:06 +02:00
parent 93a03ca4e2
commit a5f7e1ded9
8 changed files with 111 additions and 16 deletions

28
app.vue
View File

@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ConfigProvider } from "radix-vue" import { ConfigProvider } from "radix-vue"
import { cn } from "./lib/utils";
useHead({ useHead({
titleTemplate: (titleChunk) => { titleTemplate: (titleChunk) => {
@@ -26,6 +27,8 @@ useHead({
}) })
const useIdFunction = () => useId() const useIdFunction = () => useId()
const { isSidebarOpened } = storeToRefs(useUiStore())
</script> </script>
<template> <template>
@@ -34,10 +37,18 @@ const useIdFunction = () => useId()
<NuxtLayout> <NuxtLayout>
<ConfigProvider :use-id="useIdFunction"> <ConfigProvider :use-id="useIdFunction">
<div class="h-full grid grid-cols-[auto_1fr] dark:bg-black transition-colors"> <div
class="h-full grid md:grid-cols-[auto_1fr] dark:bg-black shadow-body-light dark:shadow-body-dark transition-colors after:absolute after:transition-colors"
:class="cn({
'max-md:after:bg-transparent': isSidebarOpened,
'has-sidebar max-md:after:bg-black/20 md:after:opacity-0 md:after:pointer-events-none': isSidebarOpened
})"
>
<Sidebar /> <Sidebar />
<div class="wrapper max-h-screen shadow-body-light dark:shadow-body-dark transition-all"> <div
class="wrapper max-h-screen transition-all"
>
<NuxtPage /> <NuxtPage />
</div> </div>
</div> </div>
@@ -54,4 +65,17 @@ const useIdFunction = () => useId()
.wrapper > * { .wrapper > * {
height: 100%; height: 100%;
} }
.has-sidebar {
position: relative;
isolation: isolate;
&::after {
content: '';
display: block;
position: fixed;
inset: 0;
z-index: 30;
}
}
</style> </style>

View File

@@ -2,7 +2,7 @@
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core" import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
import { PhMagnifyingGlass } from "@phosphor-icons/vue" import { PhMagnifyingGlass } from "@phosphor-icons/vue"
const { revealAdvancedSearch, } = useCalendar() const { revealAdvancedSearch } = useCalendar()
const breakpoints = useBreakpoints( const breakpoints = useBreakpoints(
breakpointsTailwind breakpointsTailwind

View File

@@ -16,7 +16,10 @@ const { isReadOnly, defaultDate } = storeToRefs(useCalendar())
<li> <li>
<LazyCalendarDialogQuickCreateEvent v-if="!isReadOnly" /> <LazyCalendarDialogQuickCreateEvent v-if="!isReadOnly" />
</li> </li>
<li> <li class="md:hidden">
<SidebarToggle />
</li>
<li class="max-md:hidden">
<LazyCalendarMenuToday v-if="defaultDate" /> <LazyCalendarMenuToday v-if="defaultDate" />
</li> </li>
<li class="ml-4"> <li class="ml-4">

View File

@@ -139,7 +139,7 @@ function toFutureFar(): void {
<template> <template>
<div class="flex gap-2"> <div class="flex gap-2">
<div class="grid items-end w-40 px-4 py-2 bg-white dark:bg-black border-border border-x-[1px] border-t-[1px] rounded-t-sm text-sm transition-colors"> <div class="grid items-center w-40 px-3 md:px-4 py-2 bg-white dark:bg-black border-border border-x-[1px] border-t-[1px] rounded-t-sm text-sm max-md:text-xs transition-colors">
<ClientOnly> <ClientOnly>
<span>{{ currentDate.currentDateTitle }}</span> <span>{{ currentDate.currentDateTitle }}</span>

View File

@@ -1,9 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import { PhCompass, PhGlobeHemisphereEast, PhHurricane, PhList } from "@phosphor-icons/vue" import { PhCompass, PhGlobeHemisphereEast, PhHurricane, PhX } from "@phosphor-icons/vue"
import type { SidebarMenuActionType, SidebarMenuIcon } from "./SidebarProps"; import type { SidebarMenuActionType, SidebarMenuIcon } from "./SidebarProps";
import { cn } from "~/lib/utils";
const { revealAdvancedSearch } = useCalendar() const { revealAdvancedSearch } = useCalendar()
const { currentMenu } = storeToRefs(useUiStore()) const { toggleSidebar } = useUiStore()
const { currentMenu, isSidebarOpened } = storeToRefs(useUiStore())
function handleMenuItemAction(actionType: SidebarMenuActionType) { function handleMenuItemAction(actionType: SidebarMenuActionType) {
if (actionType === "event-search") { if (actionType === "event-search") {
@@ -21,14 +23,32 @@ function computeMenuItemIcon(iconString: SidebarMenuIcon) {
return PhCompass return PhCompass
} }
} }
// const sidebarRef = ref(null)
// onClickOutside(sidebarRef, () => {
// isSidebarOpened.value = false
// })
</script> </script>
<template> <template>
<nav class="w-16 py-6 border-r-[1px] bg-indigo-700 dark:bg-black text-white border-r-indigo-700 dark:border-r-indigo-950 grid grid-rows-[1fr_auto] justify-center transition-colors after:opacity-50 after:contrast-125 dark:after:opacity-75 dark:after:contrast-175 after:-hue-rotate-60"> <nav
ref="sidebarRef"
:class="cn(
['md:relative md:isolate w-16 py-6 grid grid-rows-[1fr_auto] justify-center transition-all'], // Base appearance
['after:opacity-50 after:contrast-125 dark:after:opacity-75 dark:after:contrast-175 after:-hue-rotate-60'], // After styling
['border-r-[1px] bg-indigo-700 dark:bg-black text-white border-r-indigo-700 dark:border-r-indigo-950 shadow-navbar-light dark:shadow-navbar-dark'], // Colours
['max-md:absolute max-md:left-0 max-md:inset-0 max-md:z-50'], // Responsive behaviours
{
'max-md:-translate-x-16': !isSidebarOpened,
'max-md:-translate-x-0 shadow-navbar-dark dark:bg-slate-950': isSidebarOpened
}
)"
>
<menu class="flex flex-col gap-4"> <menu class="flex flex-col gap-4">
<li class="mb-12"> <li class="mb-12">
<UiButton variant="ghost" size="icon" class="rounded-full" @click="console.log"> <UiButton variant="ghost" size="icon" class="rounded-full" @click="toggleSidebar">
<PhList size="27" /> <PhX size="24" />
</UiButton> </UiButton>
</li> </li>
@@ -86,15 +106,14 @@ function computeMenuItemIcon(iconString: SidebarMenuIcon) {
</ClientOnly> </ClientOnly>
</menu> </menu>
<UserCTA /> <div ref="userMenuRef">
<UserCTA />
</div>
</nav> </nav>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
nav { nav {
position: relative;
isolation: isolate;
&::after { &::after {
display: block; display: block;
content: ''; content: '';

View File

@@ -0,0 +1,15 @@
<script lang="ts" setup>
import { PhList } from "@phosphor-icons/vue"
const { toggleSidebar } = useUiStore()
</script>
<template>
<UiButton
size="icon"
variant="outline"
@click="toggleSidebar"
>
<PhList size="19" weight="light" />
</UiButton>
</template>

View File

@@ -1,7 +1,13 @@
import { breakpointsTailwind } from "@vueuse/core"
import type { SidebarMenuItem } from "~/components/global/sidebar/SidebarProps" import type { SidebarMenuItem } from "~/components/global/sidebar/SidebarProps"
const breakpoints = useBreakpoints(
breakpointsTailwind
)
export const useUiStore = defineStore("ui", () => { export const useUiStore = defineStore("ui", () => {
const currentMenu: Ref<SidebarMenuItem[]> = ref<SidebarMenuItem[]>([]) const currentMenu = ref<SidebarMenuItem[]>([])
const isSidebarOpened = ref<boolean>(false)
function setCurrentMenu(items: SidebarMenuItem[]) { function setCurrentMenu(items: SidebarMenuItem[]) {
currentMenu.value = items currentMenu.value = items
@@ -11,9 +17,35 @@ export const useUiStore = defineStore("ui", () => {
currentMenu.value = [] currentMenu.value = []
} }
function openSidebar() {
if (breakpoints.isGreater("md")) return
isSidebarOpened.value = true
}
function closeSidebar() {
if (breakpoints.isGreater("md")) return
isSidebarOpened.value = false
}
function toggleSidebar() {
if (breakpoints.isGreater("md")) return
isSidebarOpened.value = !isSidebarOpened.value
}
watch(breakpoints.md, () => {
isSidebarOpened.value = false
})
return { return {
currentMenu, currentMenu,
setCurrentMenu, setCurrentMenu,
resetMenu resetMenu,
isSidebarOpened,
openSidebar,
closeSidebar,
toggleSidebar
} }
}) })

View File

@@ -66,6 +66,8 @@ module.exports = {
boxShadow: { boxShadow: {
"body-dark": "hsla(250, 50%, 10%, 0.75) 0 0 32px 2px inset", "body-dark": "hsla(250, 50%, 10%, 0.75) 0 0 32px 2px inset",
"body-light": "hsl(250, 60%, 85%) 0 0 18px 3px inset", "body-light": "hsl(250, 60%, 85%) 0 0 18px 3px inset",
"navbar-dark": "hsla(250, 50%, 10%, 0.75) 0 0 32px 2px",
"navbar-light": "hsl(250, 60%, 85%) 0 0 18px 3px",
}, },
borderRadius: { borderRadius: {
xl: "calc(var(--radius) + 4px)", xl: "calc(var(--radius) + 4px)",