@ithinkdt/naive
Version:
iThinkDT Naive UI
109 lines (96 loc) • 3.46 kB
JSX
import { defineComponent, shallowRef, watch, inject } from 'vue'
import { useRouter } from 'vue-router'
import { NBreadcrumb, NBreadcrumbItem, NDropdown, NIcon } from 'ithinkdt-ui'
import { cB, cE, CSS_MOUNT_ANCHOR_META_NAME, CSS_STYLE_PREFIX as p } from '@ithinkdt/core/cssr'
import { IMenu, IMenuDown } from '../assets.jsx'
export const DtBreadcrumb = defineComponent({
name: 'DtBreadcrumb',
props: {
prefix: {
type: Array,
default: () => [],
},
},
setup(props) {
const cls = `${p}-breadcrumb`
createStyle(cls)
const auth = inject('__INJECTED_AUTH__')
const theme = inject('__INJECTED_THEME__')
const router = useRouter()
function to(path) {
path && router.push({ path })
}
const Icon = shallowRef(IMenu)
watch(
() => auth.activedModulePath,
(menus) => {
const icon = menus[0]?.icon
if (icon) {
Promise.resolve(theme.menuIconLoader(icon))
.then((Icon) => {
if (Icon) {
Icon.value = Icon
} else {
console.debug(`[theme] not found icon: ${icon}`)
}
})
.catch((error) => {
console.debug(`[theme] load icon: ${icon} failured`, error)
})
}
},
{ immediate: true },
)
return () => (
<NBreadcrumb class={cls}>
{[...props.prefix, ...auth.activedModulePath].map((m, i, arr) => (
<NBreadcrumbItem
key={m.key}
clickable={!!m.path}
onClick={() => {
i < arr.length - 1 && to(m.path)
}}
>
{m.dropdown?.length ? (
<NDropdown
options={m.dropdown}
onSelect={(_, op) => {
op.action?.()
}}
>
<span>
{m._label ?? m.label}
<NIcon class={`${cls}__dropdown-icon`}>
<IMenuDown />
</NIcon>
</span>
</NDropdown>
) : (
<>
{i === 0 ? <NIcon class={`${cls}__prefix`}>{Icon.value?.()}</NIcon> : undefined}
{m._label ?? m.label}
</>
)}
</NBreadcrumbItem>
))}
</NBreadcrumb>
)
},
})
let style
function createStyle(cls) {
if (!style) {
style = cB('breadcrumb', [
cE('prefix', {
marginRight: '6px',
}),
cE('dropdown-icon', {
marginLeft: '4px',
}),
])
style.mount({
id: cls,
anchorMetaName: CSS_MOUNT_ANCHOR_META_NAME,
})
}
}