mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2026-01-01 02:27:32 +01:00
* feat: add shadcn * feat: add themes * feat: make sidebar use shadcn * feat: sort bg * feat: lint fixes * feat: make daisyui toggleable, add tooltips to sidebar, add work in progress docs page * fix: theme switching for shadcn * Fix minor profile.vue issue * feat: update docs, enlarge SidebarMenuButton and refine profile layout * feat: add testing page * feat: update css and remove comments from template * fix: create dropdown not opening due to tooltip interference also lint * fix: correct CSS selector for homebox in main.css to ensure proper theming functionality * feat: make theme switching actually kinda work for shadcn * fix: sidebar colours * fix: remove unused router import, made sidebar indicate active page and sort tailwind config linting * style: update styles * chore: remove unused duplicate code * style: refine theme management, CSS variables, get styles closer to original * feat: implement suggested changes * feat: better button size --------- Co-authored-by: Matt Kilgore <tankerkiller125@users.noreply.github.com>
91 lines
2.4 KiB
Vue
91 lines
2.4 KiB
Vue
<script setup lang="ts">
|
|
import { useEventListener, useMediaQuery, useVModel } from "@vueuse/core";
|
|
import { TooltipProvider } from "radix-vue";
|
|
import { computed, type HTMLAttributes, type Ref, ref } from "vue";
|
|
import {
|
|
provideSidebarContext,
|
|
SIDEBAR_COOKIE_MAX_AGE,
|
|
SIDEBAR_COOKIE_NAME,
|
|
SIDEBAR_KEYBOARD_SHORTCUT,
|
|
SIDEBAR_WIDTH,
|
|
SIDEBAR_WIDTH_ICON,
|
|
} from "./utils";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
defaultOpen?: boolean;
|
|
open?: boolean;
|
|
class?: HTMLAttributes["class"];
|
|
}>(),
|
|
{
|
|
defaultOpen: true,
|
|
open: undefined,
|
|
}
|
|
);
|
|
|
|
const emits = defineEmits<{
|
|
"update:open": [open: boolean];
|
|
}>();
|
|
|
|
const isMobile = useMediaQuery("(max-width: 768px)");
|
|
const openMobile = ref(false);
|
|
|
|
const open = useVModel(props, "open", emits, {
|
|
defaultValue: props.defaultOpen ?? false,
|
|
passive: (props.open === undefined) as false,
|
|
}) as Ref<boolean>;
|
|
|
|
function setOpen(value: boolean) {
|
|
open.value = value; // emits('update:open', value)
|
|
|
|
// This sets the cookie to keep the sidebar state.
|
|
document.cookie = `${SIDEBAR_COOKIE_NAME}=${open.value}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
|
|
}
|
|
|
|
function setOpenMobile(value: boolean) {
|
|
openMobile.value = value;
|
|
}
|
|
|
|
// Helper to toggle the sidebar.
|
|
function toggleSidebar() {
|
|
return isMobile.value ? setOpenMobile(!openMobile.value) : setOpen(!open.value);
|
|
}
|
|
|
|
useEventListener("keydown", (event: KeyboardEvent) => {
|
|
if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
|
|
event.preventDefault();
|
|
toggleSidebar();
|
|
}
|
|
});
|
|
|
|
// We add a state so that we can do data-state="expanded" or "collapsed".
|
|
// This makes it easier to style the sidebar with Tailwind classes.
|
|
const state = computed(() => (open.value ? "expanded" : "collapsed"));
|
|
|
|
provideSidebarContext({
|
|
state,
|
|
open,
|
|
setOpen,
|
|
isMobile,
|
|
openMobile,
|
|
setOpenMobile,
|
|
toggleSidebar,
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<TooltipProvider :delay-duration="0">
|
|
<div
|
|
:style="{
|
|
'--sidebar-width': SIDEBAR_WIDTH,
|
|
'--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
|
|
}"
|
|
:class="cn('group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar', props.class)"
|
|
v-bind="$attrs"
|
|
>
|
|
<slot />
|
|
</div>
|
|
</TooltipProvider>
|
|
</template>
|