UNPKG

@ithinkdt/naive

Version:

iThinkDT Naive UI

204 lines (177 loc) 7.83 kB
import { defineComponent, ref, toRef, computed, useSlots, provide } from 'vue' import { useRouter } from 'vue-router' import { until, useElementSize, throttledWatch } from '@vueuse/core' import { NScrollbar, NButton, NIcon, NTooltip } from 'ithinkdt-ui' import { useAuth, useTheme, DtLayoutView, modals } from '@ithinkdt/core' import { useClass } from '@ithinkdt/common' import { IModals } from '../assets' import { ThemeProvider } from '../naive' import { CSS_STYLE_PREFIX as p } from '@ithinkdt/core/cssr' import { createStyle } from './layout.style.js' export const DtLayout = defineComponent({ name: 'DtLayout', setup() { const cls = `${p}-layout` createStyle(cls) const auth = useAuth() const theme = useTheme() const router = useRouter() const layoutRef = ref() const hidden = useClass( layoutRef, `${cls}--hide-sidebar`, computed( () => !theme.hasSidebar || theme.menuPlacement === 'topbar' || (theme.logoPlacement === 'split' && !auth.activedMenuPath[0]?.children?.length) || (theme.menuPlacement === 'sidebar' && !auth.modules?.length), ), ) useClass( layoutRef, `${cls}--collpased-sidebar`, computed(() => !hidden.value && !theme.isFixedSidebar), ) useClass(document.body, 'dark', toRef(theme, 'isDark')) const transition = ref(false) until(router.currentRoute) .toBeTruthy() .then(() => (transition.value = true)) const transitionBind = { name: `${cls}__main-content-`, // mode: 'out-in', } const slots = useSlots() provide('__INJECT_SLOTS__', slots) const Top = () => ( <> {theme.logoPlacement === 'topbar' || hidden.value ? ( <div class={`${cls}__topbar-logo-wrapper`}>{slots.logo?.()}</div> ) : undefined} {theme.collpaseBtnPlacement === 'topbar' ? ( <div class={`${cls}__topbar-collpase-btn`}>{slots.collpase?.({ size: 'medium' })}</div> ) : undefined} {theme.menuPlacement === 'sidebar' ? ( theme.hasBreadcrumb && slots.breadcrumb ? ( <div class={`${cls}__topbar-breadcrumb`}>{slots.breadcrumb()}</div> ) : undefined ) : ( slots.nav?.({ full: theme.menuPlacement === 'topbar' }) )} <div class={`${cls}__topbar-space`} /> {modals.some((m) => m.visible === null) ? ( <NTooltip> {{ default: () => '打开已收起的对话框', trigger: () => ( <NButton text style="font-size: 18px" onClick={() => { for (const m of modals) m.visible ??= true }} > <NIcon> <IModals /> </NIcon> </NButton> ), }} </NTooltip> ) : undefined} {slots.extra?.()} {theme.showAppearence ? slots.appearence?.() : undefined} {theme.showI18n ? slots.language?.() : undefined} {theme.showFullscreen ? slots.fullscreen?.() : undefined} {theme.showMessage ? slots.message?.() : undefined} {slots.avator?.()} </> ) const Side = () => ( <> {theme.logoPlacement === 'sidebar' ? ( <div class={`${cls}__sidebar-logo-wrapper`}>{slots.logo?.()}</div> ) : undefined} {theme.menuPlacement === 'topbar' ? undefined : ( <NScrollbar>{slots.side?.({ full: theme.menuPlacement === 'sidebar' })}</NScrollbar> )} {theme.collpaseBtnPlacement === 'sidebar' ? ( <div class={`${cls}__sidebar-collpase-btn`}>{slots.collpase?.({ size: 'large' })}</div> ) : undefined} </> ) const contentRef = ref() const { width: contentwidth, height: contentHeight } = useElementSize(contentRef) const style = ref({}) throttledWatch( [contentwidth, contentHeight], ([w, h]) => { style.value = { [`--${p}_body-width`]: w + 'px', [`--${p}_body-height`]: h + 'px', } }, { immediate: true, throttle: 1000 / 25 }, ) return () => { return ( <div class={[ cls, theme.logoPlacement === 'sidebar' && !hidden.value ? `${cls}--logo-in-sidebar` : `${cls}--logo-in-topbar`, { [`${cls}--dark`]: theme.isDark, [`${cls}--full-tab`]: theme.fullTab, [`${cls}--transition`]: transition.value, }, ]} ref={layoutRef} > <header v-show={theme.hasTopbar} class={`${cls}__topbar`}> {theme.topbarDark && !theme.isDark ? ( <ThemeProvider theme="dark"> <Top /> </ThemeProvider> ) : ( <Top /> )} </header> <aside v-show={theme.hasSidebar} class={{ [`${cls}__sidebar`]: true }}> {theme.sidebarDark && !theme.isDark ? ( <ThemeProvider theme="dark"> <Side /> </ThemeProvider> ) : ( <Side /> )} </aside> <main class={`${cls}__main`}> {theme.multiTab ? ( <div class={`${cls}__tabsbar`}> {slots.tabs?.({ showBreadcrumb: theme.hasBreadcrumb && theme.menuPlacement !== 'sidebar', })} </div> ) : undefined} <div class={`${cls}__main-body`} ref={contentRef} style={style.value}> {/* */} {/* <NScrollbar xScrollable> */} {/* <div class={`${cls}__main-content`}> */} <DtLayoutView transition={transitionBind} /> {/* </div> */} {/* </NScrollbar> */} </div> </main> {theme.hasFooter ? ( <footer class={[`${cls}__footer`, theme.floatFooter ? `${cls}__footer--float` : undefined]}> {slots.footer?.({ description: theme.footer })} </footer> ) : undefined} </div> ) } }, })