Skip to content

Commit

Permalink
feat(tree-select): add tree-select component
Browse files Browse the repository at this point in the history
  • Loading branch information
kagol committed Jun 18, 2024
1 parent 5e02624 commit adab1b0
Show file tree
Hide file tree
Showing 15 changed files with 479 additions and 1 deletion.
118 changes: 118 additions & 0 deletions examples/sites/demos/apis/tree-select.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
export default {
mode: ['pc'],
apis: [
{
name: 'tree-select',
type: 'component',
props: [
{
name: 'clearable',
type: 'boolean',
defaultValue: 'false',
desc: {
'zh-CN': '是否启用一键清除的功能',
'en-US': 'Whether to display the one click clear button, only applicable to radio selection'
},
mode: ['pc'],
pcDemo: 'filter'
},
{
name: 'filter-method',
type: '(query: string) => void',
defaultValue: '',
desc: {
'zh-CN': '自定义过滤方法',
'en-US': 'Custom filtering method'
},
mode: ['pc'],
pcDemo: 'filter'
},
{
name: 'filterable',
type: 'boolean',
defaultValue: 'false',
desc: {
'zh-CN': '是否可搜索',
'en-US': 'Is it searchable'
},
mode: ['pc'],
pcDemo: 'filter'
},
{
name: 'modelValue / v-model',
type: 'string | number | Array<string|number>',
defaultValue: '',
desc: {
'zh-CN': '绑定值',
'en-US': 'Bind value'
},
mode: ['pc'],
pcDemo: 'basic-usage'
},
{
name: 'multiple',
type: 'boolean',
defaultValue: 'false',
desc: {
'zh-CN': '是否允许选择多个选项',
'en-US': 'Allow multiple options to be selected'
},
mode: ['pc'],
pcDemo: 'multiple'
},
{
name: 'text-field',
type: 'string',
defaultValue: "'label'",
desc: {
'zh-CN': '显示值字段',
'en-US': 'Show Value Fields'
},
mode: ['pc'],
pcDemo: 'map-field'
},
{
name: 'tree-op',
typeAnchorName: 'ITreeOption',
type: 'ITreeOption',
defaultValue: '',
desc: {
'zh-CN': '下拉树时,内置树组件的配置,用法同 Tree 组件。',
'en-US':
'When pulling down a tree, the configuration of the built-in tree component is the same as that of the Tree component. To be used in conjunction with the render type attribute'
},
mode: ['pc'],
pcDemo: 'basic-usage'
},
{
name: 'value-field',
type: 'string',
defaultValue: "'value'",
desc: {
'zh-CN': '绑定值字段',
'en-US': 'Bind Value Field'
},
mode: ['pc'],
pcDemo: 'map-field'
}
]
}
],
types: [
{
name: 'ITreeOption',
type: 'interface',
code: `
interface ITreeNode {
label: string // 默认树节点的文本字段
id: number|string // 树节点唯一标识
children: ITreeNode[] // 子节点
}
interface ITreeOption {
data: ITreeNode[] // 树数据,用法同 Tree
}
`
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<tiny-tree-select v-model="value" :tree-op="treeOp"></tiny-tree-select>
</template>

<script setup>
import { ref } from 'vue'
import { TreeSelect as TinyTreeSelect } from '@opentiny/vue'
const value = ref('')
const treeOp = ref({
data: [
{
value: 1,
label: '一级 1',
children: [
{
value: 4,
label: '二级 1-1',
children: [
{
value: 9,
label: '三级 1-1-1'
},
{
value: 10,
label: '三级 1-1-2'
}
]
}
]
},
{
value: 2,
label: '一级 2',
children: [
{
value: 5,
label: '二级 2-1'
},
{
value: 6,
label: '二级 2-2'
}
]
}
]
})
</script>
20 changes: 20 additions & 0 deletions examples/sites/demos/pc/app/tree-select/basic-usage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect, test } from '@playwright/test'

test('测试基本用法', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('tree-select#basic-usage')

const wrap = page.locator('#basic-usage')
const select = wrap.locator('.tiny-tree-select').nth(0)
const input = select.locator('.tiny-input__inner')
const dropdown = page.locator('body > .tiny-select-dropdown')
const treeNode = dropdown.locator('.tiny-tree-node')

await input.click()
await expect(treeNode).toHaveCount(7)

await treeNode.filter({ hasText: /^ 2-1$/ }).click()
await expect(input).toHaveValue('二级 2-1')
await input.click()
await expect(treeNode.filter({ hasText: /^ 2-1$/ })).toHaveClass(/is-current/)
})
55 changes: 55 additions & 0 deletions examples/sites/demos/pc/app/tree-select/basic-usage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template>
<tiny-tree-select v-model="value" :tree-op="treeOp"></tiny-tree-select>
</template>

<script>
import { TreeSelect } from '@opentiny/vue'
export default {
components: {
TinyTreeSelect: TreeSelect
},
data() {
return {
treeOp: {
data: [
{
value: 1,
label: '一级 1',
children: [
{
value: 4,
label: '二级 1-1',
children: [
{
value: 9,
label: '三级 1-1-1'
},
{
value: 10,
label: '三级 1-1-2'
}
]
}
]
},
{
value: 2,
label: '一级 2',
children: [
{
value: 5,
label: '二级 2-1'
},
{
value: 6,
label: '二级 2-2'
}
]
}
]
}
}
}
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: TreeSelect 树形选择器
---

# TreeSelect 树形选择器

结合了 BaseSelect 和 Tree 组件的选择器,用于从一个下拉树中选择一个或多个选项。
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: TreeSelect
---

# TreeSelect

A selector that combines the BaseSelect and Tree components to select one or more options from a drop-down tree.
18 changes: 18 additions & 0 deletions examples/sites/demos/pc/app/tree-select/webdoc/tree-select.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export default {
column: '2',
owner: '',
demos: [
{
demoId: 'basic-usage',
name: {
'zh-CN': '基本用法',
'en-US': 'Basic Usage'
},
desc: {
'zh-CN': '<p>最基础的用法,通过 <code>tree-op</code> 设置下拉树的数据源,<code>v-model</code> 设置绑定值。</p>',
'en-US': ''
},
codeFiles: ['basic-usage.vue']
}
]
}
8 changes: 7 additions & 1 deletion examples/sites/demos/pc/menus.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,13 @@ export const cmpMenus = [
{ 'nameCn': '开关', 'name': 'Switch', 'key': 'switch' },
{ 'nameCn': '时间选择器', 'name': 'TimePicker', 'key': 'time-picker' },
{ 'nameCn': '时间选择', 'name': 'TimeSelect', 'key': 'time-select' },
{ 'nameCn': '穿梭框', 'name': 'Transfer', 'key': 'transfer' }
{ 'nameCn': '穿梭框', 'name': 'Transfer', 'key': 'transfer' },
{
'nameCn': '树形选择器',
'name': 'TreeSelect',
'key': 'tree-select',
'mark': { 'type': 'warning', 'text': 'Beta' }
}
]
},
{
Expand Down
13 changes: 13 additions & 0 deletions packages/modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -2978,6 +2978,19 @@
"type": "template",
"exclude": false
},
"TreeSelect": {
"path": "vue/src/tree-select/index.ts",
"type": "component",
"exclude": false,
"mode": [
"pc"
]
},
"TreeSelectPc": {
"path": "vue/src/tree-select/src/pc.vue",
"type": "template",
"exclude": false
},
"Upload": {
"path": "vue/src/upload/index.ts",
"type": "component",
Expand Down
38 changes: 38 additions & 0 deletions packages/renderless/src/tree-select/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export const filter =
({ vm }) =>
(value) => {
vm.$refs.treeRef.filter(value)
}

export const nodeClick =
({ props }) =>
(data, { updateSelectedData, hidePanel }) => {
if (!props.multiple) {
updateSelectedData({
...data,
currentLabel: data[props.textField],
value: data[props.valueField],
state: {
currentLabel: data[props.textField]
}
})

hidePanel()
}
}

export const check =
({ props }) =>
(checkedNodes, { updateSelectedData }) => {
if (props.multiple) {
updateSelectedData(
checkedNodes.map((node) => {
return {
...node,
currentLabel: node[props.textField],
value: node[props.valueField]
}
})
)
}
}
21 changes: 21 additions & 0 deletions packages/renderless/src/tree-select/vue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { filter, nodeClick, check } from './index'

export const api = ['state', 'filter', 'nodeClick', 'check']

export const renderless = (props, { reactive }, { vm }) => {
const api = {}

const state = reactive({
value: props.modelValue,
treeData: props.treeOp.data
})

Object.assign(api, {
state,
filter: filter({ vm }),
nodeClick: nodeClick({ props }),
check: check({ props })
})

return api
}
1 change: 1 addition & 0 deletions packages/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@
"@opentiny/vue-transfer-panel": "workspace:~",
"@opentiny/vue-tree": "workspace:~",
"@opentiny/vue-tree-menu": "workspace:~",
"@opentiny/vue-tree-select": "workspace:~",
"@opentiny/vue-upload": "workspace:~",
"@opentiny/vue-upload-dragger": "workspace:~",
"@opentiny/vue-upload-list": "workspace:~",
Expand Down
Loading

0 comments on commit adab1b0

Please sign in to comment.