diff --git a/docs/.vitepress/crowdin/en-US/pages/component.json b/docs/.vitepress/crowdin/en-US/pages/component.json
index 80079dfa80..79d31e70ff 100644
--- a/docs/.vitepress/crowdin/en-US/pages/component.json
+++ b/docs/.vitepress/crowdin/en-US/pages/component.json
@@ -206,6 +206,11 @@
"link": "/tree",
"text": "Tree"
},
+ {
+ "link": "/tree-select",
+ "text": "TreeSelect",
+ "promotion": "2.1.8"
+ },
{
"link": "/tree-v2",
"text": "Virtualized Tree"
diff --git a/docs/en-US/component/tree-select.md b/docs/en-US/component/tree-select.md
new file mode 100644
index 0000000000..09d614c2a0
--- /dev/null
+++ b/docs/en-US/component/tree-select.md
@@ -0,0 +1,93 @@
+---
+title: TreeSelect
+lang: en-US
+---
+
+# TreeSelect
+
+The tree selector of the dropdown menu,
+it combines the functions of components `el-tree` and `el-select`.
+
+## Basic usage
+
+Selector for tree structures.
+
+:::demo
+
+tree-select/basic
+
+:::
+
+## Select any level
+
+When using the `check-strictly=true` attribute, any node can be checked,
+otherwise only leaf nodes are supported.
+
+:::demo
+
+tree-select/check-strictly
+
+:::
+
+## Multiple Selection
+
+Multiple selection using clicks or checkbox.
+
+:::demo
+
+tree-select/multiple
+
+:::
+
+## Disabled Selection
+
+Disable options using the disabled field.
+
+:::demo
+
+tree-select/disabled
+
+:::
+
+## Filterable
+
+Use keyword filtering or custom filtering methods.
+`filterMethod` can custom filter method for data,
+`filterNodeMethod` can custom filter method for data node.
+
+:::demo
+
+tree-select/filterable
+
+:::
+
+## Custom content
+
+Contents of custom tree nodes.
+
+:::demo
+
+tree-select/slots
+
+:::
+
+## LazyLoad
+
+Lazy loading of tree nodes, suitable for large data lists.
+
+:::demo
+
+tree-select/lazy
+
+:::
+
+## Attributes
+
+Since this component combines the functions of components `el-tree` and `el-select`,
+the original properties have not been changed, so no repetition here,
+and please go to the original component to view the documentation.
+
+| Attributes | Methods | Events | Slots |
+| --------------------------------------- | ----------------------------- | ----------------------------------- | ---------------------------------- |
+| [tree](./tree.md#attributes) | [tree](./tree.md#method) | [tree](./tree.md#events) | [tree](./tree.md#slots) |
+| [select](./select.md#select-attributes) | [select](./select.md#methods) | [select](./select.md#select-events) | [select](./select.md#select-slots) |
diff --git a/docs/examples/tree-select/basic.vue b/docs/examples/tree-select/basic.vue
new file mode 100644
index 0000000000..71798c3101
--- /dev/null
+++ b/docs/examples/tree-select/basic.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
+```
diff --git a/docs/examples/tree-select/check-strictly.vue b/docs/examples/tree-select/check-strictly.vue
new file mode 100644
index 0000000000..f329f59517
--- /dev/null
+++ b/docs/examples/tree-select/check-strictly.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
+```
diff --git a/docs/examples/tree-select/disabled.vue b/docs/examples/tree-select/disabled.vue
new file mode 100644
index 0000000000..c182ed591e
--- /dev/null
+++ b/docs/examples/tree-select/disabled.vue
@@ -0,0 +1,84 @@
+
+
+
+
+
+```
diff --git a/docs/examples/tree-select/filterable.vue b/docs/examples/tree-select/filterable.vue
new file mode 100644
index 0000000000..5ce3745e80
--- /dev/null
+++ b/docs/examples/tree-select/filterable.vue
@@ -0,0 +1,104 @@
+
+
+
+ filter method:
+
+
+ filter node method:
+
+
+
+
+```
diff --git a/docs/examples/tree-select/lazy.vue b/docs/examples/tree-select/lazy.vue
new file mode 100644
index 0000000000..2c94795601
--- /dev/null
+++ b/docs/examples/tree-select/lazy.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+```
diff --git a/docs/examples/tree-select/multiple.vue b/docs/examples/tree-select/multiple.vue
new file mode 100644
index 0000000000..526918afc5
--- /dev/null
+++ b/docs/examples/tree-select/multiple.vue
@@ -0,0 +1,84 @@
+
+
+
+ show checkbox:
+
+
+
+
+```
diff --git a/docs/examples/tree-select/slots.vue b/docs/examples/tree-select/slots.vue
new file mode 100644
index 0000000000..a78c58b46f
--- /dev/null
+++ b/docs/examples/tree-select/slots.vue
@@ -0,0 +1,104 @@
+
+
+
+ {{ label }}(suffix)
+
+
+ use render content:
+
+
+
+
+```
diff --git a/packages/components/index.ts b/packages/components/index.ts
index 5f204b82fb..345806f075 100644
--- a/packages/components/index.ts
+++ b/packages/components/index.ts
@@ -61,6 +61,7 @@ export * from './timeline'
export * from './tooltip'
export * from './transfer'
export * from './tree'
+export * from './tree-select'
export * from './tree-v2'
export * from './upload'
export * from './virtual-list'
diff --git a/packages/components/tree-select/__tests__/tree-select.spec.ts b/packages/components/tree-select/__tests__/tree-select.spec.ts
new file mode 100644
index 0000000000..5f92ef8770
--- /dev/null
+++ b/packages/components/tree-select/__tests__/tree-select.spec.ts
@@ -0,0 +1,312 @@
+import { h, nextTick, ref } from 'vue'
+import { mount } from '@vue/test-utils'
+import TreeSelect from '../src/tree-select.vue'
+import type { RenderFunction } from 'vue'
+import type { VueWrapper } from '@vue/test-utils'
+import type ElSelect from '@element-plus/components/select'
+import type ElTree from '@element-plus/components/tree'
+
+const createComponent = ({
+ slots = {},
+ props = {},
+}: {
+ slots?: Record
+ props?: typeof TreeSelect['props']
+} = {}) => {
+ // vm can not get component expose, use ref
+ const wrapperRef = ref()
+ const value = props.modelValue || ref('')
+ const wrapper = mount({
+ data() {
+ return {
+ modelValue: value,
+ data: [
+ {
+ value: 1,
+ label: '一级 1',
+ children: [
+ {
+ value: 11,
+ label: '二级 1-1',
+ children: [
+ {
+ value: 111,
+ label: '三级 1-1',
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ 'onUpdate:modelValue': (val: string) => (value.value = val),
+ ...props,
+ }
+ },
+ render() {
+ return h(
+ TreeSelect,
+ {
+ ...this.$data,
+ ref: (val: object) => (wrapperRef.value = val),
+ },
+ slots
+ )
+ },
+ })
+
+ return {
+ wrapper,
+ getWrapperRef: () =>
+ new Promise((resolve) =>
+ nextTick(() => resolve(wrapperRef.value))
+ ) as Promise & InstanceType>,
+ select: wrapper.findComponent({ name: 'ElSelect' }) as VueWrapper<
+ InstanceType
+ >,
+ tree: wrapper.findComponent({ name: 'ElTree' }) as VueWrapper<
+ InstanceType
+ >,
+ }
+}
+
+describe('TreeSelect.vue', () => {
+ test('render test', async () => {
+ const { wrapper, tree } = createComponent({
+ props: {
+ defaultExpandAll: true,
+ },
+ })
+
+ expect(wrapper.find('.el-tree')).toBeTruthy()
+ expect(wrapper.find('.el-select')).toBeTruthy()
+
+ expect(tree.findAll('.el-tree > .el-tree-node').length).toBe(1)
+ expect(tree.findAll('.el-tree .el-tree-node').length).toBe(3)
+ expect(tree.findAll('.el-tree .el-select-dropdown__item').length).toBe(3)
+
+ wrapper.vm.data[0].children = []
+
+ await nextTick()
+
+ expect(tree.findAll('.el-tree .el-tree-node').length).toBe(1)
+ })
+
+ test('modelValue', async () => {
+ const value = ref(1)
+ const { getWrapperRef, select, tree } = createComponent({
+ props: {
+ modelValue: value,
+ checkStrictly: true,
+ showCheckbox: true,
+ },
+ })
+
+ const wrapperRef = await getWrapperRef()
+
+ await nextTick()
+ expect(select.vm.modelValue).toBe(1)
+ expect(wrapperRef.getCheckedKeys()).toEqual([1])
+
+ value.value = 11
+ await nextTick(nextTick)
+ expect(select.vm.modelValue).toBe(11)
+ expect(wrapperRef.getCheckedKeys()).toEqual([11])
+
+ await tree
+ .findAll('.el-select-dropdown__item')
+ .slice(-1)[0]
+ .trigger('click')
+ await nextTick()
+ expect(select.vm.modelValue).toBe(111)
+ expect(wrapperRef.getCheckedKeys()).toEqual([111])
+
+ await tree.find('.el-tree-node__content').trigger('click')
+ await nextTick()
+ expect(select.vm.modelValue).toBe(1)
+ expect(wrapperRef.getCheckedKeys()).toEqual([1])
+
+ await tree.findAll('.el-checkbox')[1].trigger('click')
+ await nextTick()
+ expect(select.vm.modelValue).toBe(11)
+ expect(wrapperRef.getCheckedKeys()).toEqual([11])
+ })
+
+ test('disabled', async () => {
+ const { wrapper, tree } = createComponent({
+ props: {
+ data: [
+ {
+ value: '1',
+ label: '1',
+ children: [
+ {
+ value: '2',
+ label: '2',
+ disabled: true,
+ },
+ ],
+ },
+ ],
+ showCheckbox: true,
+ checkStrictly: true,
+ defaultExpandAll: true,
+ },
+ })
+
+ await nextTick()
+ await tree.find('.el-tree-node').trigger('click')
+ await tree.find('.el-tree-node .el-checkbox.is-disabled').trigger('click')
+ await tree
+ .find('.el-tree-node .el-select-dropdown__item.is-disabled')
+ .trigger('click')
+ await nextTick()
+ expect(wrapper.vm.modelValue).toBe('1')
+ })
+
+ test('multiple', async () => {
+ const value = ref([1])
+ const { getWrapperRef, select, tree } = createComponent({
+ props: {
+ modelValue: value,
+ checkStrictly: true,
+ showCheckbox: true,
+ multiple: true,
+ },
+ })
+
+ const wrapperRef = await getWrapperRef()
+
+ await nextTick()
+ expect(select.vm.modelValue).toEqual([1])
+ expect(wrapperRef.getCheckedKeys()).toEqual([1])
+
+ value.value = [11]
+ await nextTick(nextTick)
+ expect(select.vm.modelValue).toEqual([11])
+ expect(wrapperRef.getCheckedKeys()).toEqual([11])
+
+ await tree
+ .findAll('.el-select-dropdown__item')
+ .slice(-1)[0]
+ .trigger('click')
+ await nextTick()
+ expect(select.vm.modelValue).toEqual([11, 111])
+ expect(wrapperRef.getCheckedKeys()).toEqual([11, 111])
+
+ await tree.find('.el-tree-node__content').trigger('click')
+ await nextTick()
+ expect(select.vm.modelValue).toEqual([11, 111, 1])
+ expect(wrapperRef.getCheckedKeys()).toEqual([1, 11, 111])
+
+ await tree.findAll('.el-checkbox')[1].trigger('click')
+ await nextTick()
+ expect(select.vm.modelValue).toEqual([1, 111])
+ expect(wrapperRef.getCheckedKeys()).toEqual([1, 111])
+ })
+
+ test('filter', async () => {
+ const { select, tree } = createComponent({
+ props: {
+ filterable: true,
+ },
+ })
+
+ select.vm.query = '一级 1'
+ await nextTick()
+ expect(tree.findAll('.el-tree-node').length).toBe(1)
+ })
+
+ test('props', async () => {
+ const { wrapper, select, tree } = createComponent({
+ props: {
+ data: [
+ {
+ id: '1',
+ name: '1',
+ childrens: [
+ {
+ id: '2',
+ name: '2',
+ },
+ ],
+ },
+ ],
+ props: {
+ label: 'name',
+ children: 'childrens',
+ },
+ valueKey: 'id',
+ },
+ })
+
+ await nextTick()
+ expect(tree.find('.el-tree-node').text()).toBe('1')
+ wrapper.vm.modelValue = '2'
+ await nextTick()
+ expect(select.vm.selectedLabel).toBe('2')
+ })
+
+ test('slots', async () => {
+ const { select, tree } = createComponent({
+ slots: {
+ default: ({ data }: { data: { label: string } }) => `123${data.label}`,
+ prefix: () => 'prefix',
+ },
+ })
+
+ await nextTick()
+ expect(tree.find('.el-select-dropdown__item').text()).toBe('123一级 1')
+ expect(select.find('.el-input__prefix-inner').text()).toBe('prefix')
+ })
+
+ test('renderContent', async () => {
+ const { tree } = createComponent({
+ props: {
+ renderContent: (
+ h: RenderFunction,
+ { data }: { data: { label: string } }
+ ) => {
+ return `123${data.label}`
+ },
+ },
+ })
+
+ await nextTick()
+ expect(tree.find('.el-select-dropdown__item').text()).toBe('123一级 1')
+ })
+
+ test('lazy', async () => {
+ const { tree } = createComponent({
+ props: {
+ data: [
+ {
+ value: 1,
+ label: 1,
+ },
+ ],
+ lazy: true,
+ load: (node: object, resolve: (p: any) => any[]) => {
+ resolve([{ value: 2, label: 2, isLeaf: true }])
+ },
+ },
+ })
+
+ await nextTick()
+ await tree.find('.el-tree-node').trigger('click')
+ await nextTick()
+ expect(tree.find('.el-tree-node .el-tree-node').text()).toBe('2')
+ })
+
+ test('events', async () => {
+ const onNodeClick = jest.fn()
+ const { tree } = createComponent({
+ props: {
+ onNodeClick,
+ },
+ })
+ await nextTick()
+ await tree.find('.el-tree-node').trigger('click')
+ await nextTick()
+ expect(onNodeClick).toBeCalled()
+ })
+})
diff --git a/packages/components/tree-select/index.ts b/packages/components/tree-select/index.ts
new file mode 100644
index 0000000000..38dccfe16c
--- /dev/null
+++ b/packages/components/tree-select/index.ts
@@ -0,0 +1,13 @@
+import TreeSelect from './src/tree-select.vue'
+
+import type { App } from 'vue'
+import type { SFCWithInstall } from '@element-plus/utils'
+
+TreeSelect.install = (app: App): void => {
+ app.component(TreeSelect.name, TreeSelect)
+}
+
+const _TreeSelect = TreeSelect as SFCWithInstall
+
+export default _TreeSelect
+export const ElTreeSelect = _TreeSelect
diff --git a/packages/components/tree-select/src/select.ts b/packages/components/tree-select/src/select.ts
new file mode 100644
index 0000000000..f8a7beaf9b
--- /dev/null
+++ b/packages/components/tree-select/src/select.ts
@@ -0,0 +1,50 @@
+import { computed, nextTick, toRefs } from 'vue'
+import { pick } from 'lodash-unified'
+import ElSelect from '@element-plus/components/select'
+import { useNamespace } from '@element-plus/hooks'
+import type { Ref } from 'vue'
+import type ElTree from '@element-plus/components/tree'
+
+export const useSelect = (
+ props,
+ { attrs },
+ {
+ tree,
+ key,
+ }: {
+ select: Ref | undefined>
+ tree: Ref | undefined>
+ key: Ref
+ }
+) => {
+ const ns = useNamespace('tree-select')
+
+ const result = {
+ ...pick(toRefs(props), Object.keys(ElSelect.props)),
+ ...attrs,
+ valueKey: key,
+ popperClass: computed(() => {
+ const classes = [ns.e('popper')]
+ if (props.popperClass) classes.push(props.popperClass)
+ return classes.join(' ')
+ }),
+ filterMethod: (keyword = '') => {
+ if (props.filterMethod) props.filterMethod(keyword)
+
+ nextTick(() => {
+ // let tree node expand only, same with tree filter
+ tree.value?.filter(keyword)
+ })
+ },
+ // clear filter text when visible change
+ onVisibleChange: (visible: boolean) => {
+ attrs.onVisibleChange?.(visible)
+
+ if (props.filterable && visible) {
+ result.filterMethod()
+ }
+ },
+ }
+
+ return result
+}
diff --git a/packages/components/tree-select/src/tree-select-option.ts b/packages/components/tree-select/src/tree-select-option.ts
new file mode 100644
index 0000000000..93e19889df
--- /dev/null
+++ b/packages/components/tree-select/src/tree-select-option.ts
@@ -0,0 +1,22 @@
+import { defineComponent } from 'vue'
+import { ElOption } from '@element-plus/components/select'
+
+const component = defineComponent({
+ extends: ElOption,
+ setup(props, ctx) {
+ const result = (ElOption.setup as NonNullable)(props, ctx)
+
+ // use methods.selectOptionClick
+ delete result.selectOptionClick
+
+ return result
+ },
+ methods: {
+ selectOptionClick() {
+ // $el.parentElement => el-tree-node__content
+ this.$el.parentElement.click()
+ },
+ },
+})
+
+export default component
diff --git a/packages/components/tree-select/src/tree-select.vue b/packages/components/tree-select/src/tree-select.vue
new file mode 100644
index 0000000000..5eabf2829e
--- /dev/null
+++ b/packages/components/tree-select/src/tree-select.vue
@@ -0,0 +1,83 @@
+
diff --git a/packages/components/tree-select/src/tree.ts b/packages/components/tree-select/src/tree.ts
new file mode 100644
index 0000000000..305bab0ec7
--- /dev/null
+++ b/packages/components/tree-select/src/tree.ts
@@ -0,0 +1,136 @@
+import { computed, nextTick, toRefs, watch } from 'vue'
+import { isEqual, pick } from 'lodash-unified'
+import { UPDATE_MODEL_EVENT } from '@element-plus/constants'
+import { isFunction } from '@element-plus/utils'
+import ElTree from '@element-plus/components/tree'
+import TreeSelectOption from './tree-select-option'
+import type { Ref } from 'vue'
+import type ElSelect from '@element-plus/components/select'
+import type Node from '@element-plus/components/tree/src/model/node'
+import type { TreeNodeData } from '@element-plus/components/tree/src/tree.type'
+
+export const useTree = (
+ props,
+ { attrs, slots, emit },
+ {
+ select,
+ tree,
+ key,
+ }: {
+ select: Ref | undefined>
+ tree: Ref | undefined>
+ key: Ref
+ }
+) => {
+ watch(
+ () => props.modelValue,
+ () => {
+ if (props.showCheckbox) {
+ nextTick(() => {
+ const treeInstance = tree.value
+ if (
+ treeInstance &&
+ !isEqual(
+ treeInstance.getCheckedKeys(),
+ toValidArray(props.modelValue)
+ )
+ ) {
+ treeInstance.setCheckedKeys(toValidArray(props.modelValue))
+ }
+ })
+ }
+ },
+ {
+ immediate: true,
+ deep: true,
+ }
+ )
+
+ const propsMap = computed(() => ({
+ value: key.value,
+ ...props.props,
+ }))
+
+ const getNodeValByProp = (
+ prop: 'value' | 'label' | 'children' | 'disabled' | 'isLeaf',
+ data: TreeNodeData
+ ) => {
+ const propVal = propsMap.value[prop]
+ if (isFunction(propVal)) {
+ return propVal(
+ data,
+ tree.value?.getNode(getNodeValByProp('value', data)) as Node
+ )
+ } else {
+ return data[propVal as string]
+ }
+ }
+
+ return {
+ ...pick(toRefs(props), Object.keys(ElTree.props)),
+ ...attrs,
+ nodeKey: key,
+ defaultExpandedKeys: computed(() =>
+ props.defaultExpandedKeys
+ ? props.defaultExpandedKeys.concat(props.modelValue)
+ : toValidArray(props.modelValue)
+ ),
+ renderContent: (h, { node, data, store }) => {
+ return h(
+ TreeSelectOption,
+ {
+ value: getNodeValByProp('value', data),
+ label: getNodeValByProp('label', data),
+ disabled: getNodeValByProp('disabled', data),
+ },
+ props.renderContent
+ ? () => props.renderContent(h, { node, data, store })
+ : slots.default
+ ? () => slots.default({ node, data, store })
+ : undefined
+ )
+ },
+ filterNodeMethod: (value, data, node) => {
+ if (props.filterNodeMethod)
+ return props.filterNodeMethod(value, data, node)
+ if (!value) return true
+ return getNodeValByProp('label', data)?.includes(value)
+ },
+ onNodeClick: (data, node, e) => {
+ attrs.onNodeClick?.(data, node, e)
+
+ if (props.checkStrictly || node.isLeaf) {
+ if (!getNodeValByProp('disabled', data)) {
+ const option = select.value?.options.get(
+ getNodeValByProp('value', data)
+ )
+ select.value?.handleOptionSelect(option, true)
+ }
+ } else {
+ e.ctx.handleExpandIconClick()
+ }
+ },
+ onCheck: (data, params) => {
+ attrs.onCheck?.(data, params)
+
+ // remove folder node when `checkStrictly` is false
+ const checkedKeys = !props.checkStrictly
+ ? tree.value?.getCheckedKeys(true)
+ : params.checkedKeys
+
+ const value = getNodeValByProp('value', data)
+ emit(
+ UPDATE_MODEL_EVENT,
+ props.multiple
+ ? checkedKeys
+ : checkedKeys.includes(value)
+ ? value
+ : undefined
+ )
+ },
+ }
+}
+
+function toValidArray(val: any) {
+ return Array.isArray(val) ? val : val || val === 0 ? [val] : []
+}
diff --git a/packages/components/tree-select/style/css.ts b/packages/components/tree-select/style/css.ts
new file mode 100644
index 0000000000..c652f5a0cc
--- /dev/null
+++ b/packages/components/tree-select/style/css.ts
@@ -0,0 +1,3 @@
+import '@element-plus/components/select/style/css'
+import '@element-plus/components/tree/style/css'
+import '@element-plus/theme-chalk/src/tree-select/css'
diff --git a/packages/components/tree-select/style/index.ts b/packages/components/tree-select/style/index.ts
new file mode 100644
index 0000000000..a369976bc9
--- /dev/null
+++ b/packages/components/tree-select/style/index.ts
@@ -0,0 +1,3 @@
+import '@element-plus/components/select/style'
+import '@element-plus/components/tree/style'
+import '@element-plus/theme-chalk/src/tree-select.scss'
diff --git a/packages/element-plus/component.ts b/packages/element-plus/component.ts
index 372c72edc9..99dac40870 100644
--- a/packages/element-plus/component.ts
+++ b/packages/element-plus/component.ts
@@ -94,6 +94,7 @@ import { ElTooltip } from '@element-plus/components/tooltip'
import { ElTooltipV2 } from '@element-plus/components/tooltip-v2'
import { ElTransfer } from '@element-plus/components/transfer'
import { ElTree } from '@element-plus/components/tree'
+import { ElTreeSelect } from '@element-plus/components/tree-select'
import { ElTreeV2 } from '@element-plus/components/tree-v2'
import { ElUpload } from '@element-plus/components/upload'
import type { Plugin } from 'vue'
@@ -188,6 +189,7 @@ export default [
ElTooltipV2,
ElTransfer,
ElTree,
+ ElTreeSelect,
ElTreeV2,
ElUpload,
] as Plugin[]
diff --git a/packages/theme-chalk/src/index.scss b/packages/theme-chalk/src/index.scss
index 1e705e1a4a..933edc01c0 100644
--- a/packages/theme-chalk/src/index.scss
+++ b/packages/theme-chalk/src/index.scss
@@ -92,6 +92,7 @@
@use './tooltip-v2.scss';
@use './transfer.scss';
@use './tree.scss';
+@use './tree-select.scss';
@use './upload.scss';
@use './virtual-list.scss';
@use './popper.scss';
diff --git a/packages/theme-chalk/src/tree-select.scss b/packages/theme-chalk/src/tree-select.scss
new file mode 100644
index 0000000000..59b67b2d78
--- /dev/null
+++ b/packages/theme-chalk/src/tree-select.scss
@@ -0,0 +1,36 @@
+@use 'mixins/mixins' as *;
+@use 'mixins/var' as *;
+@use 'common/var' as *;
+
+@include b(tree-select) {
+ @include set-component-css-var('tree', $tree);
+}
+
+@include b(tree-select) {
+ @include e(popper) {
+ // padding-left same with select option
+ .#{$namespace}-tree-node__expand-icon {
+ margin-left: 8px;
+ }
+
+ // remove icon when show checkbox
+ .#{$namespace}-tree-node.is-checked
+ > .#{$namespace}-tree-node__content
+ .#{$namespace}-select-dropdown__item.selected::after {
+ content: none;
+ }
+
+ .#{$namespace}-select-dropdown__item {
+ flex: 1;
+ background: transparent !important;
+
+ // padding-left move to `el-tree-node__expand-icon`
+ padding-left: 0;
+
+ // fix: select height > tree node height
+ // https://github.com/yujinpan/el-select-tree/pull/33
+ height: 20px;
+ line-height: 20px;
+ }
+ }
+}