refactor(components): [tree] use useNamespace (#5754)

This commit is contained in:
bqy 2022-02-11 03:57:10 +08:00 committed by GitHub
parent 115a40ce7a
commit d132e6e000
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 35 deletions

View File

@ -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',

View File

@ -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

View File

@ -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])
}
},
})

View File

@ -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,

View File

@ -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,