mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-30 12:52:43 +08:00
feat(dropdown): clsPrefix
This commit is contained in:
parent
0af36ac95b
commit
e7c0d7d269
@ -20,7 +20,7 @@ For some special case, you may want to manually position the dropdown. For examp
|
||||
```
|
||||
|
||||
```js
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import { defineComponent, ref, nextTick } from 'vue'
|
||||
import { useMessage } from 'naive-ui'
|
||||
|
||||
const options = [
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* istanbul ignore file */
|
||||
export { default as NDropdown } from './src/Dropdown'
|
||||
export type { DropdownProps } from './src/Dropdown'
|
||||
export type {
|
||||
DropdownOption,
|
||||
DropdownGroupOption,
|
||||
|
@ -8,14 +8,21 @@ import {
|
||||
watch,
|
||||
provide,
|
||||
reactive,
|
||||
CSSProperties
|
||||
CSSProperties,
|
||||
InjectionKey
|
||||
} from 'vue'
|
||||
import { createTreeMate, Key, TreeMateOptions, TreeNode } from 'treemate'
|
||||
import { useMergedState, useKeyboard, useMemo } from 'vooks'
|
||||
import { useTheme } from '../../_mixins'
|
||||
import { useConfig, useTheme } from '../../_mixins'
|
||||
import type { ThemeProps } from '../../_mixins'
|
||||
import { NPopover, popoverBaseProps } from '../../popover'
|
||||
import { keep, call, createKey, MaybeArray } from '../../_utils'
|
||||
import {
|
||||
keep,
|
||||
call,
|
||||
createKey,
|
||||
MaybeArray,
|
||||
ExtractPublicPropTypes
|
||||
} from '../../_utils'
|
||||
import { dropdownLight } from '../styles'
|
||||
import type { DropdownTheme } from '../styles'
|
||||
import NDropdownMenu from './DropdownMenu'
|
||||
@ -57,7 +64,11 @@ export interface DropdownInjection {
|
||||
doUpdateShow: (value: boolean) => void
|
||||
}
|
||||
|
||||
const dropdownProps = {
|
||||
export const dropdownInjectionKey: InjectionKey<DropdownInjection> = Symbol(
|
||||
'dropdown'
|
||||
)
|
||||
|
||||
const dropdownBaseProps = {
|
||||
animated: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
@ -83,10 +94,6 @@ const dropdownProps = {
|
||||
type: Array as PropType<DropdownMixedOption[]>,
|
||||
default: () => []
|
||||
},
|
||||
containerClass: {
|
||||
type: String,
|
||||
default: 'n-dropdown'
|
||||
},
|
||||
// for menu
|
||||
value: [String, Number] as PropType<Key | null>
|
||||
} as const
|
||||
@ -95,13 +102,17 @@ const popoverPropKeys = Object.keys(popoverBaseProps) as Array<
|
||||
keyof typeof popoverBaseProps
|
||||
>
|
||||
|
||||
const dropdownProps = {
|
||||
...popoverBaseProps,
|
||||
...dropdownBaseProps,
|
||||
...(useTheme.props as ThemeProps<DropdownTheme>)
|
||||
} as const
|
||||
|
||||
export type DropdownProps = ExtractPublicPropTypes<typeof dropdownProps>
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Dropdown',
|
||||
props: {
|
||||
...popoverBaseProps,
|
||||
...dropdownProps,
|
||||
...(useTheme.props as ThemeProps<DropdownTheme>)
|
||||
},
|
||||
props: dropdownProps,
|
||||
setup (props) {
|
||||
const uncontrolledShowRef = ref(false)
|
||||
const mergedShowRef = useMergedState(
|
||||
@ -171,16 +182,19 @@ export default defineComponent({
|
||||
keyboardEnabledRef
|
||||
)
|
||||
|
||||
const { mergedClsPrefix } = useConfig(props)
|
||||
|
||||
const themeRef = useTheme(
|
||||
'Dropdown',
|
||||
'Dropdown',
|
||||
style,
|
||||
dropdownLight,
|
||||
props
|
||||
props,
|
||||
mergedClsPrefix
|
||||
)
|
||||
|
||||
provide<DropdownInjection>(
|
||||
'NDropdown',
|
||||
provide(
|
||||
dropdownInjectionKey,
|
||||
reactive({
|
||||
hoverKey: hoverKeyRef,
|
||||
keyboardKey: keyboardKeyRef,
|
||||
@ -278,6 +292,7 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
return {
|
||||
cPrefix: mergedClsPrefix,
|
||||
mergedTheme: themeRef,
|
||||
// data
|
||||
tmNodes: tmNodesRef,
|
||||
@ -339,17 +354,19 @@ export default defineComponent({
|
||||
NPopover,
|
||||
keep(this.$props, popoverPropKeys, {
|
||||
show: this.mergedShow,
|
||||
'onUpdate:show': this.doUpdateShow,
|
||||
onUpdateShow: this.doUpdateShow,
|
||||
showArrow: false,
|
||||
raw: true,
|
||||
shadow: false,
|
||||
theme: this.mergedTheme.peers.Popover,
|
||||
themeOverrides: this.mergedTheme.peerOverrides.Popover
|
||||
themeOverrides: this.mergedTheme.peerOverrides.Popover,
|
||||
internalExtraClass: 'dropdown'
|
||||
}),
|
||||
{
|
||||
trigger: this.$slots.default,
|
||||
default: () => {
|
||||
return h(NDropdownMenu, {
|
||||
clsPrefix: this.cPrefix,
|
||||
tmNodes: this.tmNodes,
|
||||
style: this.cssVars as CSSProperties
|
||||
})
|
||||
|
@ -2,7 +2,13 @@ import { h, defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DropdownDivider',
|
||||
props: {
|
||||
clsPrefix: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
render () {
|
||||
return <div class="n-dropdown-divider" />
|
||||
return <div class={`${this.clsPrefix}-dropdown-divider`} />
|
||||
}
|
||||
})
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { defineComponent, Fragment, h, PropType, VNode } from 'vue'
|
||||
import { defineComponent, Fragment, h, PropType } from 'vue'
|
||||
import { TreeNode } from 'treemate'
|
||||
import { warn } from '../../_utils'
|
||||
import NDropdownOption from './DropdownOption'
|
||||
@ -14,6 +14,10 @@ import {
|
||||
export default defineComponent({
|
||||
name: 'NDropdownGroup',
|
||||
props: {
|
||||
clsPrefix: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
tmNode: {
|
||||
type: Object as PropType<
|
||||
TreeNode<DropdownOption, DropdownGroupOption, DropdownIgnoredOption>
|
||||
@ -26,19 +30,19 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { tmNode, parentKey } = this
|
||||
const { tmNode, parentKey, clsPrefix } = this
|
||||
const { children } = tmNode
|
||||
return h(
|
||||
Fragment,
|
||||
[
|
||||
h(NDropdownGroupHeader, {
|
||||
tmNode,
|
||||
key: tmNode.key
|
||||
})
|
||||
].concat(
|
||||
children?.map((child) => {
|
||||
return (
|
||||
<>
|
||||
<NDropdownGroupHeader
|
||||
clsPrefix={clsPrefix}
|
||||
tmNode={tmNode}
|
||||
key={tmNode.key}
|
||||
/>
|
||||
{children?.map((child) => {
|
||||
if (isDividerNode(child.rawNode)) {
|
||||
return h(NDropdownDivider, {
|
||||
clsPrefix,
|
||||
key: child.key
|
||||
})
|
||||
}
|
||||
@ -50,12 +54,13 @@ export default defineComponent({
|
||||
return null
|
||||
}
|
||||
return h(NDropdownOption, {
|
||||
clsPrefix,
|
||||
tmNode: child,
|
||||
parentKey,
|
||||
key: child.key
|
||||
})
|
||||
}) as VNode[]
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)
|
||||
}
|
||||
})
|
@ -1,72 +0,0 @@
|
||||
import { defineComponent, h, inject } from 'vue'
|
||||
import { render } from '../../_utils'
|
||||
import { NDropdownMenuInjection } from './DropdownMenu'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DropdownGroupHeader',
|
||||
props: {
|
||||
tmNode: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup () {
|
||||
return {
|
||||
NDropdownMenu: inject<NDropdownMenuInjection>(
|
||||
'NDropdownMenu'
|
||||
) as NDropdownMenuInjection
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { rawNode } = this.tmNode
|
||||
return h(
|
||||
'div',
|
||||
{
|
||||
class: 'n-dropdown-option'
|
||||
},
|
||||
[
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
class: 'n-dropdown-option-body n-dropdown-option-body--group'
|
||||
},
|
||||
[
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
class: [
|
||||
'n-dropdown-option-body__prefix',
|
||||
{
|
||||
'n-dropdown-option-body__prefix--show-icon': this
|
||||
.NDropdownMenu.showIcon
|
||||
}
|
||||
],
|
||||
'n-dropdown-option': true
|
||||
},
|
||||
[h(render, { render: rawNode.icon })]
|
||||
),
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
class: 'n-dropdown-option-body__label',
|
||||
'n-dropdown-option': true
|
||||
},
|
||||
// TODO: Workaround, menu campatible
|
||||
[h(render, { render: rawNode.label ?? rawNode.title })]
|
||||
),
|
||||
h('div', {
|
||||
class: [
|
||||
'n-dropdown-option-body__suffix',
|
||||
{
|
||||
'n-dropdown-option-body__suffix--has-submenu': this
|
||||
.NDropdownMenu.hasSubmenu
|
||||
}
|
||||
],
|
||||
'n-dropdown-option': true
|
||||
})
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
})
|
59
src/dropdown/src/DropdownGroupHeader.tsx
Normal file
59
src/dropdown/src/DropdownGroupHeader.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import { defineComponent, h, inject } from 'vue'
|
||||
import { render } from '../../_utils'
|
||||
import { dropdownMenuInjectionKey } from './DropdownMenu'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DropdownGroupHeader',
|
||||
props: {
|
||||
clsPrefix: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
tmNode: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup () {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
NDropdownMenu: inject(dropdownMenuInjectionKey)!
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { clsPrefix } = this
|
||||
const { rawNode } = this.tmNode
|
||||
return (
|
||||
<div class={`${clsPrefix}-dropdown-option`}>
|
||||
<div
|
||||
class={`${clsPrefix}-dropdown-option-body ${clsPrefix}-dropdown-option-body--group`}
|
||||
>
|
||||
<div
|
||||
__dropdown-option
|
||||
class={[
|
||||
`${clsPrefix}-dropdown-option-body__prefix`,
|
||||
this.NDropdownMenu.showIcon &&
|
||||
`${clsPrefix}-dropdown-option-body__prefix--show-icon`
|
||||
]}
|
||||
>
|
||||
{h(render, { render: rawNode.icon })}
|
||||
</div>
|
||||
<div
|
||||
class={`${clsPrefix}-dropdown-option-body__label`}
|
||||
__dropdown-option
|
||||
>
|
||||
{h(render, { render: rawNode.label ?? rawNode.title })}
|
||||
</div>
|
||||
<div
|
||||
class={[
|
||||
`${clsPrefix}-dropdown-option-body__suffix`,
|
||||
this.NDropdownMenu.hasSubmenu &&
|
||||
`${clsPrefix}-dropdown-option-body__suffix--has-submenu`
|
||||
]}
|
||||
__dropdown-option
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
@ -1,4 +1,12 @@
|
||||
import { computed, defineComponent, h, PropType, provide, reactive } from 'vue'
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
h,
|
||||
InjectionKey,
|
||||
PropType,
|
||||
provide,
|
||||
reactive
|
||||
} from 'vue'
|
||||
import { TreeNode } from 'treemate'
|
||||
import NDropdownOption from './DropdownOption'
|
||||
import NDropdownDivider from './DropdownDivider'
|
||||
@ -15,9 +23,17 @@ export interface NDropdownMenuInjection {
|
||||
hasSubmenu: boolean
|
||||
}
|
||||
|
||||
export const dropdownMenuInjectionKey: InjectionKey<NDropdownMenuInjection> = Symbol(
|
||||
'dropdownMenu'
|
||||
)
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DropdownMenu',
|
||||
props: {
|
||||
clsPrefix: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
tmNodes: {
|
||||
type: Array as PropType<
|
||||
Array<
|
||||
@ -32,8 +48,8 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
provide<NDropdownMenuInjection>(
|
||||
'NDropdownMenu',
|
||||
provide(
|
||||
dropdownMenuInjectionKey,
|
||||
reactive({
|
||||
showIcon: computed(() => {
|
||||
return props.tmNodes.some((tmNode) => {
|
||||
@ -61,31 +77,33 @@ export default defineComponent({
|
||||
)
|
||||
},
|
||||
render () {
|
||||
const { parentKey } = this
|
||||
return h(
|
||||
'div',
|
||||
{
|
||||
class: 'n-dropdown-menu'
|
||||
},
|
||||
this.tmNodes.map((tmNode) => {
|
||||
if (isDividerNode(tmNode.rawNode)) {
|
||||
return h(NDropdownDivider, {
|
||||
key: tmNode.key
|
||||
})
|
||||
}
|
||||
if (isGroupNode(tmNode.rawNode)) {
|
||||
return h(NDropdownGroup, {
|
||||
tmNode,
|
||||
parentKey,
|
||||
key: tmNode.key
|
||||
})
|
||||
}
|
||||
return h(NDropdownOption, {
|
||||
tmNode: tmNode,
|
||||
parentKey,
|
||||
key: tmNode.key
|
||||
})
|
||||
})
|
||||
const { parentKey, clsPrefix } = this
|
||||
return (
|
||||
<div class={`${clsPrefix}-dropdown-menu`}>
|
||||
{this.tmNodes.map((tmNode) => {
|
||||
if (isDividerNode(tmNode.rawNode)) {
|
||||
return <NDropdownDivider clsPrefix={clsPrefix} key={tmNode.key} />
|
||||
}
|
||||
if (isGroupNode(tmNode.rawNode)) {
|
||||
return (
|
||||
<NDropdownGroup
|
||||
clsPrefix={clsPrefix}
|
||||
tmNode={tmNode}
|
||||
parentKey={parentKey}
|
||||
key={tmNode.key}
|
||||
/>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<NDropdownOption
|
||||
clsPrefix={clsPrefix}
|
||||
tmNode={tmNode}
|
||||
parentKey={parentKey}
|
||||
key={tmNode.key}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
@ -7,7 +7,8 @@ import {
|
||||
defineComponent,
|
||||
provide,
|
||||
reactive,
|
||||
PropType
|
||||
PropType,
|
||||
InjectionKey
|
||||
} from 'vue'
|
||||
import { VBinder, VTarget, VFollower, FollowerPlacement } from 'vueuc'
|
||||
import { useMemo } from 'vooks'
|
||||
@ -15,8 +16,8 @@ import { ChevronRightIcon } from '../../_internal/icons'
|
||||
import { useDeferredTrue } from '../../_utils/composable'
|
||||
import { render } from '../../_utils'
|
||||
import { NIcon } from '../../icon'
|
||||
import NDropdownMenu, { NDropdownMenuInjection } from './DropdownMenu'
|
||||
import { DropdownInjection } from './Dropdown'
|
||||
import NDropdownMenu, { dropdownMenuInjectionKey } from './DropdownMenu'
|
||||
import { dropdownInjectionKey } from './Dropdown'
|
||||
import { isSubmenuNode } from './utils'
|
||||
import { TreeNode } from 'treemate'
|
||||
import {
|
||||
@ -29,9 +30,17 @@ interface NDropdownOptionInjection {
|
||||
enteringSubmenu: boolean
|
||||
}
|
||||
|
||||
const dropdownOptionInjectionKey: InjectionKey<NDropdownOptionInjection> = Symbol(
|
||||
'dropdown-option'
|
||||
)
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DropdownOption',
|
||||
props: {
|
||||
clsPrefix: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
tmNode: {
|
||||
type: Object as PropType<
|
||||
TreeNode<DropdownOption, DropdownGroupOption, DropdownIgnoredOption>
|
||||
@ -48,16 +57,11 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
const NDropdown = inject<DropdownInjection>(
|
||||
'NDropdown'
|
||||
) as DropdownInjection
|
||||
const NDropdownOption = inject<NDropdownOptionInjection | null>(
|
||||
'NDropdownOption',
|
||||
null
|
||||
)
|
||||
const NDropdownMenu = inject<NDropdownMenuInjection>(
|
||||
'NDropdownMenu'
|
||||
) as NDropdownMenuInjection
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const NDropdown = inject(dropdownInjectionKey)!
|
||||
const NDropdownOption = inject(dropdownOptionInjectionKey, null)
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const NDropdownMenu = inject(dropdownMenuInjectionKey)!
|
||||
const rawNodeRef = computed(() => props.tmNode.rawNode)
|
||||
const hasSubmenuRef = computed(() => {
|
||||
return isSubmenuNode(props.tmNode.rawNode)
|
||||
@ -93,8 +97,8 @@ export default defineComponent({
|
||||
return !!NDropdownOption?.enteringSubmenu
|
||||
})
|
||||
const enteringSubmenuRef = ref(false)
|
||||
provide<NDropdownOptionInjection>(
|
||||
'NDropdownOption',
|
||||
provide(
|
||||
dropdownOptionInjectionKey,
|
||||
reactive({
|
||||
enteringSubmenu: enteringSubmenuRef
|
||||
})
|
||||
@ -124,7 +128,7 @@ export default defineComponent({
|
||||
const { relatedTarget } = e
|
||||
if (
|
||||
relatedTarget &&
|
||||
!(relatedTarget as HTMLElement).getAttribute('n-dropdown-option')
|
||||
!(relatedTarget as HTMLElement).hasAttribute('__dropdown-option')
|
||||
) {
|
||||
NDropdown.hoverKey = null
|
||||
}
|
||||
@ -171,136 +175,120 @@ export default defineComponent({
|
||||
const {
|
||||
NDropdown: { animated },
|
||||
rawNode,
|
||||
mergedShowSubmenu
|
||||
mergedShowSubmenu,
|
||||
clsPrefix
|
||||
} = this
|
||||
const submenuVNode = mergedShowSubmenu
|
||||
? h(NDropdownMenu, {
|
||||
clsPrefix,
|
||||
tmNodes: this.tmNode.children,
|
||||
parentKey: this.tmNode.key
|
||||
})
|
||||
: null
|
||||
return h(
|
||||
'div',
|
||||
{
|
||||
class: 'n-dropdown-option'
|
||||
},
|
||||
[
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
class: [
|
||||
'n-dropdown-option-body',
|
||||
{
|
||||
'n-dropdown-option-body--pending': this.pending,
|
||||
'n-dropdown-option-body--active': this.active
|
||||
}
|
||||
],
|
||||
onMousemove: this.handleMouseMove,
|
||||
onMouseenter: this.handleMouseEnter,
|
||||
onMouseleave: this.handleMouseLeave,
|
||||
onClick: this.handleClick
|
||||
},
|
||||
[
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
class: [
|
||||
'n-dropdown-option-body__prefix',
|
||||
{
|
||||
'n-dropdown-option-body__prefix--show-icon': this
|
||||
.NDropdownMenu.showIcon
|
||||
}
|
||||
],
|
||||
'n-dropdown-option': true
|
||||
},
|
||||
[h(render, { render: rawNode.icon })]
|
||||
),
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
class: 'n-dropdown-option-body__label',
|
||||
'n-dropdown-option': true
|
||||
},
|
||||
// TODO: Workaround, menu campatible
|
||||
[h(render, { render: rawNode.label ?? rawNode.title })]
|
||||
),
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
class: [
|
||||
'n-dropdown-option-body__suffix',
|
||||
{
|
||||
'n-dropdown-option-body__suffix--has-submenu': this
|
||||
.NDropdownMenu.hasSubmenu
|
||||
}
|
||||
],
|
||||
'n-dropdown-option': true
|
||||
},
|
||||
[
|
||||
this.hasSubmenu
|
||||
? h(NIcon, null, {
|
||||
default: () => h(ChevronRightIcon)
|
||||
})
|
||||
: null
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
this.hasSubmenu
|
||||
? h(VBinder, null, {
|
||||
default: () => {
|
||||
return h(VTarget, null, {
|
||||
default: () => {
|
||||
return h(
|
||||
'div',
|
||||
{
|
||||
class: 'n-dropdown-offset-container'
|
||||
},
|
||||
[
|
||||
h(
|
||||
VFollower,
|
||||
{
|
||||
show: this.mergedShowSubmenu,
|
||||
teleportDisabled: true,
|
||||
placement: this.placement
|
||||
},
|
||||
{
|
||||
default: () => {
|
||||
return h(
|
||||
'div',
|
||||
{
|
||||
class: 'n-dropdown-menu-wrapper'
|
||||
},
|
||||
[
|
||||
animated
|
||||
? h(
|
||||
Transition,
|
||||
{
|
||||
onBeforeEnter: this
|
||||
.handleSubmenuBeforeEnter,
|
||||
onAfterEnter: this
|
||||
.handleSubmenuAfterEnter,
|
||||
name: 'n-fade-in-scale-up-transition',
|
||||
appear: true
|
||||
},
|
||||
{
|
||||
default: () => submenuVNode
|
||||
}
|
||||
)
|
||||
: submenuVNode
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
})
|
||||
return (
|
||||
<div class={`${clsPrefix}-dropdown-option`}>
|
||||
<div
|
||||
class={[
|
||||
`${clsPrefix}-dropdown-option-body`,
|
||||
{
|
||||
[`${clsPrefix}-dropdown-option-body--pending`]: this.pending,
|
||||
[`${clsPrefix}-dropdown-option-body--active`]: this.active
|
||||
}
|
||||
})
|
||||
: null
|
||||
]
|
||||
]}
|
||||
onMousemove={this.handleMouseMove}
|
||||
onMouseenter={this.handleMouseEnter}
|
||||
onMouseleave={this.handleMouseLeave}
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
<div
|
||||
__dropdown-option
|
||||
class={[
|
||||
`${clsPrefix}-dropdown-option-body__prefix`,
|
||||
{
|
||||
[`${clsPrefix}-dropdown-option-body__prefix--show-icon`]: this
|
||||
.NDropdownMenu.showIcon
|
||||
}
|
||||
]}
|
||||
>
|
||||
{h(render, { render: rawNode.icon })}
|
||||
</div>
|
||||
<div
|
||||
__dropdown-option
|
||||
class={`${clsPrefix}-dropdown-option-body__label`}
|
||||
>
|
||||
{/* TODO: Workaround, menu campatible */}
|
||||
{h(render, { render: rawNode.label ?? rawNode.title })}
|
||||
</div>
|
||||
<div
|
||||
__dropdown-option
|
||||
class={[
|
||||
`${clsPrefix}-dropdown-option-body__suffix`,
|
||||
{
|
||||
[`${clsPrefix}-dropdown-option-body__suffix--has-submenu`]: this
|
||||
.NDropdownMenu.hasSubmenu
|
||||
}
|
||||
]}
|
||||
>
|
||||
{this.hasSubmenu ? (
|
||||
<NIcon>
|
||||
{{
|
||||
default: () => <ChevronRightIcon />
|
||||
}}
|
||||
</NIcon>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
{this.hasSubmenu ? (
|
||||
<VBinder>
|
||||
{{
|
||||
default: () => [
|
||||
<VTarget>
|
||||
{{
|
||||
default: () => (
|
||||
<div class={`${clsPrefix}-dropdown-offset-container`}>
|
||||
<VFollower
|
||||
show={this.mergedShowSubmenu}
|
||||
placement={this.placement}
|
||||
teleportDisabled
|
||||
>
|
||||
{{
|
||||
default: () => {
|
||||
return (
|
||||
<div
|
||||
class={`${clsPrefix}-dropdown-menu-wrapper`}
|
||||
>
|
||||
{animated ? (
|
||||
<Transition
|
||||
onBeforeEnter={
|
||||
this.handleSubmenuBeforeEnter
|
||||
}
|
||||
onAfterEnter={
|
||||
this.handleSubmenuAfterEnter
|
||||
}
|
||||
name="n-fade-in-scale-up-transition"
|
||||
appear
|
||||
>
|
||||
{{
|
||||
default: () => submenuVNode
|
||||
}}
|
||||
</Transition>
|
||||
) : (
|
||||
submenuVNode
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}}
|
||||
</VFollower>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</VTarget>
|
||||
]
|
||||
}}
|
||||
</VBinder>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue
Block a user