mirror of
https://github.com/element-plus/element-plus.git
synced 2024-11-27 02:01:15 +08:00
refactor(components): [tree] use useNamespace (#5754)
This commit is contained in:
parent
115a40ce7a
commit
d132e6e000
@ -1,5 +1,6 @@
|
||||
import { provide, ref } from 'vue'
|
||||
import { addClass, removeClass } from '@element-plus/utils/dom'
|
||||
import { useNamespace } from '@element-plus/hooks'
|
||||
import type { InjectionKey } from 'vue'
|
||||
import type Node from './node'
|
||||
|
||||
@ -22,6 +23,7 @@ export interface DragEvents {
|
||||
export const dragEventsKey: InjectionKey<DragEvents> = Symbol('dragEvents')
|
||||
|
||||
export function useDragNodeHandler({ props, ctx, el$, dropIndicator$, store }) {
|
||||
const ns = useNamespace('tree')
|
||||
const dragState = ref({
|
||||
showDropIndicator: false,
|
||||
draggingNode: null,
|
||||
@ -54,7 +56,7 @@ export function useDragNodeHandler({ props, ctx, el$, dropIndicator$, store }) {
|
||||
const dropNode = treeNode
|
||||
const oldDropNode = dragState.value.dropNode
|
||||
if (oldDropNode && oldDropNode !== dropNode) {
|
||||
removeClass(oldDropNode.$el, 'is-drop-inner')
|
||||
removeClass(oldDropNode.$el, ns.is('drop-inner'))
|
||||
}
|
||||
const draggingNode = dragState.value.draggingNode
|
||||
if (!draggingNode || !dropNode) return
|
||||
@ -123,7 +125,7 @@ export function useDragNodeHandler({ props, ctx, el$, dropIndicator$, store }) {
|
||||
}
|
||||
|
||||
const iconPosition = dropNode.$el
|
||||
.querySelector('.el-tree-node__expand-icon')
|
||||
.querySelector(`.${ns.be('node', 'expand-icon')}`)
|
||||
.getBoundingClientRect()
|
||||
const dropIndicator = dropIndicator$.value
|
||||
if (dropType === 'before') {
|
||||
@ -135,9 +137,9 @@ export function useDragNodeHandler({ props, ctx, el$, dropIndicator$, store }) {
|
||||
dropIndicator.style.left = `${iconPosition.right - treePosition.left}px`
|
||||
|
||||
if (dropType === 'inner') {
|
||||
addClass(dropNode.$el, 'is-drop-inner')
|
||||
addClass(dropNode.$el, ns.is('drop-inner'))
|
||||
} else {
|
||||
removeClass(dropNode.$el, 'is-drop-inner')
|
||||
removeClass(dropNode.$el, ns.is('drop-inner'))
|
||||
}
|
||||
|
||||
dragState.value.showDropIndicator =
|
||||
@ -169,7 +171,7 @@ export function useDragNodeHandler({ props, ctx, el$, dropIndicator$, store }) {
|
||||
store.value.registerNode(draggingNodeCopy)
|
||||
}
|
||||
|
||||
removeClass(dropNode.$el, 'is-drop-inner')
|
||||
removeClass(dropNode.$el, ns.is('drop-inner'))
|
||||
|
||||
ctx.emit(
|
||||
'node-drag-end',
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { onMounted, onUpdated, onBeforeUnmount, watch, shallowRef } from 'vue'
|
||||
import { EVENT_CODE } from '@element-plus/utils/aria'
|
||||
import { on, off } from '@element-plus/utils/dom'
|
||||
import { useNamespace } from '@element-plus/hooks'
|
||||
import type TreeStore from './tree-store'
|
||||
|
||||
import type { Ref } from 'vue'
|
||||
@ -10,6 +11,8 @@ interface UseKeydownOption {
|
||||
el$: Ref<HTMLElement>
|
||||
}
|
||||
export function useKeydown({ el$ }: UseKeydownOption, store: Ref<TreeStore>) {
|
||||
const ns = useNamespace('tree')
|
||||
|
||||
const treeItems = shallowRef<Nullable<HTMLElement>[]>([])
|
||||
const checkboxItems = shallowRef<Nullable<HTMLElement>[]>([])
|
||||
|
||||
@ -37,10 +40,10 @@ export function useKeydown({ el$ }: UseKeydownOption, store: Ref<TreeStore>) {
|
||||
|
||||
const handleKeydown = (ev: KeyboardEvent): void => {
|
||||
const currentItem = ev.target as HTMLElement
|
||||
if (currentItem.className.indexOf('el-tree-node') === -1) return
|
||||
if (currentItem.className.indexOf(ns.b('node')) === -1) return
|
||||
const code = ev.code
|
||||
treeItems.value = Array.from(
|
||||
el$.value.querySelectorAll('.is-focusable[role=treeitem]')
|
||||
el$.value.querySelectorAll(`.${ns.is('focusable')}[role=treeitem]`)
|
||||
)
|
||||
const currentIndex = treeItems.value.indexOf(currentItem)
|
||||
let nextIndex
|
||||
@ -108,12 +111,14 @@ export function useKeydown({ el$ }: UseKeydownOption, store: Ref<TreeStore>) {
|
||||
|
||||
const initTabIndex = (): void => {
|
||||
treeItems.value = Array.from(
|
||||
el$.value.querySelectorAll('.is-focusable[role=treeitem]')
|
||||
el$.value.querySelectorAll(`.${ns.is('focusable')}[role=treeitem]`)
|
||||
)
|
||||
checkboxItems.value = Array.from(
|
||||
el$.value.querySelectorAll('input[type=checkbox]')
|
||||
)
|
||||
const checkedItem = el$.value.querySelectorAll('.is-checked[role=treeitem]')
|
||||
const checkedItem = el$.value.querySelectorAll(
|
||||
`.${ns.is('checked')}[role=treeitem]`
|
||||
)
|
||||
if (checkedItem.length) {
|
||||
checkedItem[0].setAttribute('tabindex', '0')
|
||||
return
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { h, defineComponent, inject } from 'vue'
|
||||
|
||||
import { useNamespace } from '@element-plus/hooks'
|
||||
import type { ComponentInternalInstance } from 'vue'
|
||||
import type { RootTreeType } from './tree.type'
|
||||
|
||||
@ -14,6 +15,7 @@ export default defineComponent({
|
||||
renderContent: Function,
|
||||
},
|
||||
setup(props) {
|
||||
const ns = useNamespace('tree')
|
||||
const nodeInstance = inject<ComponentInternalInstance>('NodeInstance')
|
||||
const tree = inject<RootTreeType>('RootTree')
|
||||
return () => {
|
||||
@ -23,7 +25,7 @@ export default defineComponent({
|
||||
? props.renderContent(h, { _self: nodeInstance, node, data, store })
|
||||
: tree.ctx.slots.default
|
||||
? tree.ctx.slots.default({ node, data })
|
||||
: h('span', { class: 'el-tree-node__label' }, [node.label])
|
||||
: h('span', { class: ns.be('node', 'label') }, [node.label])
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -2,15 +2,15 @@
|
||||
<div
|
||||
v-show="node.visible"
|
||||
ref="node$"
|
||||
class="el-tree-node"
|
||||
:class="{
|
||||
'is-expanded': expanded,
|
||||
'is-current': node.isCurrent,
|
||||
'is-hidden': !node.visible,
|
||||
'is-focusable': !node.disabled,
|
||||
'is-checked': !node.disabled && node.checked,
|
||||
...getNodeClass(node),
|
||||
}"
|
||||
:class="[
|
||||
ns.b('node'),
|
||||
ns.is('expanded', expanded),
|
||||
ns.is('current', node.isCurrent),
|
||||
ns.is('hidden', !node.visible),
|
||||
ns.is('focusable', !node.disabled),
|
||||
ns.is('checked', !node.disabled && node.checked),
|
||||
getNodeClass(node),
|
||||
]"
|
||||
role="treeitem"
|
||||
tabindex="-1"
|
||||
:aria-expanded="expanded"
|
||||
@ -26,17 +26,17 @@
|
||||
@drop.stop="handleDrop"
|
||||
>
|
||||
<div
|
||||
class="el-tree-node__content"
|
||||
:class="ns.be('node', 'content')"
|
||||
:style="{ paddingLeft: (node.level - 1) * tree.props.indent + 'px' }"
|
||||
>
|
||||
<el-icon
|
||||
v-if="tree.props.icon || CaretRight"
|
||||
:class="[
|
||||
ns.be('node', 'expand-icon'),
|
||||
ns.is('leaf', node.isLeaf),
|
||||
{
|
||||
'is-leaf': node.isLeaf,
|
||||
expanded: !node.isLeaf && expanded,
|
||||
},
|
||||
'el-tree-node__expand-icon',
|
||||
]"
|
||||
@click.stop="handleExpandIconClick"
|
||||
>
|
||||
@ -52,7 +52,7 @@
|
||||
/>
|
||||
<el-icon
|
||||
v-if="node.loading"
|
||||
class="el-tree-node__loading-icon is-loading"
|
||||
:class="[ns.be('node', 'loading-icon'), ns.is('loading')]"
|
||||
>
|
||||
<loading />
|
||||
</el-icon>
|
||||
@ -62,7 +62,7 @@
|
||||
<div
|
||||
v-if="!renderAfterExpand || childNodeRendered"
|
||||
v-show="expanded"
|
||||
class="el-tree-node__children"
|
||||
:class="ns.be('node', 'children')"
|
||||
role="group"
|
||||
:aria-expanded="expanded"
|
||||
>
|
||||
@ -97,6 +97,7 @@ import ElCheckbox from '@element-plus/components/checkbox'
|
||||
import { ElIcon } from '@element-plus/components/icon'
|
||||
import { CaretRight, Loading } from '@element-plus/icons-vue'
|
||||
import { debugWarn } from '@element-plus/utils-v2'
|
||||
import { useNamespace } from '@element-plus/hooks'
|
||||
import NodeContent from './tree-node-content.vue'
|
||||
import { getNodeKey as getNodeKeyUtil } from './model/util'
|
||||
import { useNodeExpandEventBroadcast } from './model/useNodeExpandEventBroadcast'
|
||||
@ -135,6 +136,7 @@ export default defineComponent({
|
||||
},
|
||||
emits: ['node-expand'],
|
||||
setup(props, ctx) {
|
||||
const ns = useNamespace('tree')
|
||||
const { broadcastExpanded } = useNodeExpandEventBroadcast(props)
|
||||
const tree = inject<RootTreeType>('RootTree')
|
||||
const expanded = ref(false)
|
||||
@ -318,6 +320,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
return {
|
||||
ns,
|
||||
node$,
|
||||
tree,
|
||||
expanded,
|
||||
|
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div
|
||||
ref="el$"
|
||||
class="el-tree"
|
||||
:class="{
|
||||
'el-tree--highlight-current': highlightCurrent,
|
||||
'is-dragging': !!dragState.draggingNode,
|
||||
'is-drop-not-allow': !dragState.allowDrop,
|
||||
'is-drop-inner': dragState.dropType === 'inner',
|
||||
}"
|
||||
:class="[
|
||||
ns.b(),
|
||||
ns.is('dragging', !!dragState.draggingNode),
|
||||
ns.is('drop-not-allow', !dragState.allowDrop),
|
||||
ns.is('drop-inner', dragState.dropType === 'inner'),
|
||||
{ [ns.m('highlight-current')]: highlightCurrent },
|
||||
]"
|
||||
role="tree"
|
||||
>
|
||||
<el-tree-node
|
||||
@ -21,15 +21,15 @@
|
||||
:render-content="renderContent"
|
||||
@node-expand="handleNodeExpand"
|
||||
/>
|
||||
<div v-if="isEmpty" class="el-tree__empty-block">
|
||||
<span class="el-tree__empty-text">{{
|
||||
<div v-if="isEmpty" :class="ns.e('empty-block')">
|
||||
<span :class="ns.e('empty-text')">{{
|
||||
emptyText ?? t('el.tree.emptyText')
|
||||
}}</span>
|
||||
</div>
|
||||
<div
|
||||
v-show="dragState.showDropIndicator"
|
||||
ref="dropIndicator$"
|
||||
class="el-tree__drop-indicator"
|
||||
:class="ns.e('drop-indicator')"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
@ -42,7 +42,7 @@ import {
|
||||
watch,
|
||||
getCurrentInstance,
|
||||
} from 'vue'
|
||||
import { useLocale } from '@element-plus/hooks'
|
||||
import { useLocale, useNamespace } from '@element-plus/hooks'
|
||||
import TreeStore from './model/tree-store'
|
||||
import { getNodeKey as getNodeKeyUtil } from './model/util'
|
||||
import ElTreeNode from './tree-node.vue'
|
||||
@ -150,6 +150,7 @@ export default defineComponent({
|
||||
],
|
||||
setup(props, ctx) {
|
||||
const { t } = useLocale()
|
||||
const ns = useNamespace('tree')
|
||||
|
||||
const store = ref<TreeStore>(
|
||||
new TreeStore({
|
||||
@ -367,6 +368,7 @@ export default defineComponent({
|
||||
} as any)
|
||||
|
||||
return {
|
||||
ns,
|
||||
// ref
|
||||
store,
|
||||
root,
|
||||
|
Loading…
Reference in New Issue
Block a user