mirror of
https://github.com/setube/ogame-vue-ts.git
synced 2026-05-12 07:55:11 +08:00
重构并精简了部分UI组件,移除冗余弹窗与详情组件,新增NPC相关逻辑(npcBehaviorLogic、npcGrowthLogic、npcStore等)及外交逻辑(diplomaticLogic、DiplomacyView)。完善分页、标签、复选框等通用UI组件。优化战报弹窗,调整README下载链接为相对路径,修复部分国际化内容。
93 lines
2.5 KiB
Vue
93 lines
2.5 KiB
Vue
<template>
|
|
<TooltipProvider :delay-duration="0">
|
|
<div
|
|
data-slot="sidebar-wrapper"
|
|
:style="{
|
|
'--sidebar-width': SIDEBAR_WIDTH,
|
|
'--sidebar-width-icon': SIDEBAR_WIDTH_ICON
|
|
}"
|
|
:class="cn('group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full', props.class)"
|
|
v-bind="$attrs"
|
|
>
|
|
<slot />
|
|
</div>
|
|
</TooltipProvider>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { HTMLAttributes, Ref } from 'vue'
|
|
import { defaultDocument, useEventListener, useMediaQuery, useVModel } from '@vueuse/core'
|
|
import { TooltipProvider } from 'reka-ui'
|
|
import { computed, ref } from 'vue'
|
|
import { cn } from '@/lib/utils'
|
|
import {
|
|
provideSidebarContext,
|
|
SIDEBAR_COOKIE_MAX_AGE,
|
|
SIDEBAR_COOKIE_NAME,
|
|
SIDEBAR_KEYBOARD_SHORTCUT,
|
|
SIDEBAR_WIDTH,
|
|
SIDEBAR_WIDTH_ICON
|
|
} from './utils'
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
defaultOpen?: boolean
|
|
open?: boolean
|
|
class?: HTMLAttributes['class']
|
|
}>(),
|
|
{
|
|
defaultOpen: !defaultDocument?.cookie.includes(`${SIDEBAR_COOKIE_NAME}=false`),
|
|
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>
|
|
|
|
const 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}`
|
|
}
|
|
|
|
const setOpenMobile = (value: boolean) => {
|
|
openMobile.value = value
|
|
}
|
|
|
|
// Helper to toggle the sidebar.
|
|
const 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>
|