@ithinkdt/naive
Version:
iThinkDT Naive UI
87 lines (73 loc) • 2.4 kB
JSX
import { defineComponent, watch, shallowRef, inject, ref } from 'vue'
import { NMenu } from 'ithinkdt-ui'
import { getFirstPageModule } from '@ithinkdt/core'
import { c, cB, CSS_MOUNT_ANCHOR_META_NAME, CSS_STYLE_PREFIX as p, flexGap } from '@ithinkdt/core/cssr'
import { renderLabel, mapModules } from './l-side-menu'
import { IBookmark } from '../assets.jsx'
export const DtNavMenu = defineComponent({
name: 'DtNavMenu',
props: {
full: { type: Boolean, required: false, default: true },
},
setup(props) {
const cls = `${p}-nav-menu`
createStyle(cls)
const auth = inject('__INJECTED_AUTH__')
const theme = inject('__INJECTED_THEME__')
const menus = shallowRef([])
const menuRef = ref()
watch(
[() => props.full, () => auth.menus],
([full, modules]) => {
if (!full) {
for (const m of modules) {
m._path ??= getFirstPageModule(m.children ?? [])?.path
}
}
menus.value = mapModules(modules, IBookmark, theme.menuIconLoader)
},
{ immediate: true },
)
return () => {
return (
<NMenu
class={cls}
options={menus.value}
mode="horizontal"
renderLabel={renderLabel}
// eslint-disable-next-line unicorn/no-null
value={auth.activedMenuPath[0]?.key ?? null}
rootIndent={16}
ref={menuRef}
childrenField={props.full ? 'children' : '_children'}
/>
)
}
},
})
let style
function createStyle(cls) {
if (!style) {
style = cB(
'nav-menu',
{
lineHeight: '1',
...flexGap('4px'),
},
[
c('&.n-menu--horizontal', [
c('.n-menu-item', {
marginTop: '1px',
}),
c('.n-menu-item-content', {
padding: '0 18px',
}),
]),
],
)
style.mount({
id: cls,
anchorMetaName: CSS_MOUNT_ANCHOR_META_NAME,
})
}
}