feat(tree-menu): clearable (#1672)

This commit is contained in:
GaoNeng 2024-06-27 16:32:51 +08:00 committed by GitHub
parent 32076d45da
commit 9c072f2055
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 431 additions and 2 deletions

View File

@ -397,6 +397,17 @@ export default {
},
mode: ['pc'],
pcDemo: 'text-wrap'
},
{
name: 'clearable',
type: 'boolean',
defaultValue: 'false',
desc: {
'zh-CN': '搜索框是否可清空',
'en-US': 'Can the search box be cleared'
},
mode: ['pc'],
pcDemo: 'clearable'
}
],
events: [

View File

@ -0,0 +1,192 @@
<template>
<tiny-tree-menu :data="data" accordion clearable />
</template>
<script setup>
import { TreeMenu as TinyTreeMenu } from '@opentiny/vue'
const data = [
{
id: 100,
label: '组件总览'
},
{
id: 200,
label: '使用指南',
children: [
{
id: 201,
label: '更新日志'
},
{ id: 202, label: '环境准备' },
{ id: 203, label: '安装' },
{
id: 204,
label: '引入组件',
children: [
{ id: 20401, label: '按需引入' },
{ id: 20402, label: '完整引入' }
]
},
{ id: 205, label: '开发示例' },
{ id: 206, label: '国际化' },
{ id: 207, label: '主题配置' },
{ id: 208, label: '表单校验配置' },
{ id: 209, label: '常见问题' }
]
},
{
id: 300,
label: '框架风格',
children: [
{
id: 301,
label: 'Color 色彩'
},
{ id: 302, label: 'Container 版型' },
{ id: 303, label: 'Font 字体' },
{ id: 304, label: 'Icon 图标' },
{ id: 305, label: 'Layout 布局' }
]
},
{
id: 400,
label: '导航组件',
children: [
{
id: 401,
label: 'Anchor 锚点'
},
{ id: 402, label: 'Guide 引导' },
{ id: 403, label: 'Breadcrumb 面包屑' }
]
},
{
id: 500,
label: '容器组件',
children: [
{
id: 501,
label: 'Carousel 走马灯'
},
{ id: 502, label: 'Collapse 折叠面板' },
{ id: 503, label: 'DialogBox 对话框' }
]
},
{
id: 600,
label: '表单组件',
children: [
{
id: 60101,
label: 'Button 按钮',
url: 'button'
},
{
id: 60102,
label: 'DatePicker 日期选择器',
url: 'date-picker'
},
{
id: 60103,
label: 'Select 选择器',
url: 'select'
},
{
id: 60104,
label: 'DropTimes 下拉时间',
url: 'drop-times'
},
{
id: 60105,
label: 'Input 输入框',
url: 'input'
}
]
},
{
id: 700,
label: '业务组件',
children: [
{
id: 701,
label: 'Amount 金额'
},
{ id: 702, label: 'Area 片区' },
{ id: 703, label: 'Company 公司' }
]
},
{
id: 800,
label: '其他组件',
children: [
{
id: 801,
label: '废弃组件',
children: [
{
id: 80101,
label: 'CreditCardForm 信用卡表单',
url: 'credit-card-form'
},
{
id: 80102,
label: 'DetailPage 表头详情栏',
url: 'detail-page'
}
]
},
{
id: 802,
label: '新增组件',
children: [
{
id: 80201,
label: 'QrCode 二维码',
url: 'qr-code'
},
{
id: 80202,
label: 'Watermark 水印',
url: 'watermark'
},
{
id: 80203,
label: 'MindMap 脑图',
url: 'mind-map'
},
{
id: 80204,
label: 'Skeleton 骨架屏',
url: 'skeleton'
}
]
},
{
id: 803,
label: 'BulletinBoard 公告牌'
},
{ id: 804, label: 'Calendar 日历' }
]
}
]
</script>
<!-- <template>
<tiny-tree-menu ></tiny-tree-menu>
</template>
<script>
export default {
components: {
TinyTreeMenu: TreeMenu
},
data() {
return {
treeData:
}
}
}
</script> -->

View File

@ -0,0 +1,20 @@
import type { Page } from '@playwright/test'
import { test, expect } from '@playwright/test'
const getIcon = (page: Page) => page.locator('#clearable').getByRole('img').nth(1)
test('搜索框可清除', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('tree-menu#clearable')
await page.locator('#clearable').getByRole('textbox', { name: '请输入内容进行筛选' }).click()
await page.locator('#clearable').getByRole('textbox', { name: '请输入内容进行筛选' }).click()
await page.locator('#clearable').getByRole('textbox', { name: '请输入内容进行筛选' }).fill('123')
await expect(page.getByText('暂无数据')).toBeVisible()
const icon = getIcon(page)
await icon.click()
const val = await page.locator('#clearable').getByRole('textbox', { name: '请输入内容进行筛选' }).inputValue()
expect(val).toBe('')
await expect(page.getByText('暂无数据')).not.toBeVisible()
})

View File

@ -0,0 +1,182 @@
<template>
<tiny-tree-menu :data="treeData" accordion clearable></tiny-tree-menu>
</template>
<script>
import { TreeMenu } from '@opentiny/vue'
export default {
components: {
TinyTreeMenu: TreeMenu
},
data() {
return {
treeData: [
{
id: 100,
label: '组件总览'
},
{
id: 200,
label: '使用指南',
children: [
{
id: 201,
label: '更新日志'
},
{ id: 202, label: '环境准备' },
{ id: 203, label: '安装' },
{
id: 204,
label: '引入组件',
children: [
{ id: 20401, label: '按需引入' },
{ id: 20402, label: '完整引入' }
]
},
{ id: 205, label: '开发示例' },
{ id: 206, label: '国际化' },
{ id: 207, label: '主题配置' },
{ id: 208, label: '表单校验配置' },
{ id: 209, label: '常见问题' }
]
},
{
id: 300,
label: '框架风格',
children: [
{
id: 301,
label: 'Color 色彩'
},
{ id: 302, label: 'Container 版型' },
{ id: 303, label: 'Font 字体' },
{ id: 304, label: 'Icon 图标' },
{ id: 305, label: 'Layout 布局' }
]
},
{
id: 400,
label: '导航组件',
children: [
{
id: 401,
label: 'Anchor 锚点'
},
{ id: 402, label: 'Guide 引导' },
{ id: 403, label: 'Breadcrumb 面包屑' }
]
},
{
id: 500,
label: '容器组件',
children: [
{
id: 501,
label: 'Carousel 走马灯'
},
{ id: 502, label: 'Collapse 折叠面板' },
{ id: 503, label: 'DialogBox 对话框' }
]
},
{
id: 600,
label: '表单组件',
children: [
{
id: 60101,
label: 'Button 按钮',
url: 'button'
},
{
id: 60102,
label: 'DatePicker 日期选择器',
url: 'date-picker'
},
{
id: 60103,
label: 'Select 选择器',
url: 'select'
},
{
id: 60104,
label: 'DropTimes 下拉时间',
url: 'drop-times'
},
{
id: 60105,
label: 'Input 输入框',
url: 'input'
}
]
},
{
id: 700,
label: '业务组件',
children: [
{
id: 701,
label: 'Amount 金额'
},
{ id: 702, label: 'Area 片区' },
{ id: 703, label: 'Company 公司' }
]
},
{
id: 800,
label: '其他组件',
children: [
{
id: 801,
label: '废弃组件',
children: [
{
id: 80101,
label: 'CreditCardForm 信用卡表单',
url: 'credit-card-form'
},
{
id: 80102,
label: 'DetailPage 表头详情栏',
url: 'detail-page'
}
]
},
{
id: 802,
label: '新增组件',
children: [
{
id: 80201,
label: 'QrCode 二维码',
url: 'qr-code'
},
{
id: 80202,
label: 'Watermark 水印',
url: 'watermark'
},
{
id: 80203,
label: 'MindMap 脑图',
url: 'mind-map'
},
{
id: 80204,
label: 'Skeleton 骨架屏',
url: 'skeleton'
}
]
},
{
id: 803,
label: 'BulletinBoard 公告牌'
},
{ id: 804, label: 'Calendar 日历' }
]
}
]
}
}
}
</script>

View File

@ -346,6 +346,19 @@ export default {
'<div class="tip custom-block"><p class="custom-block-title">Event description</p>\n<p>node-click: Listen for events when a node is clicked.</p>\n<p>current-change: Listen for events where the currently selected node changes.</p>\n<p>node-expand: Listen for events that node expands.</p>\n<p>node-collapse: Listen for events when a node is folded up.</p>\n<p>check-change: When checked, listen for events related to changes in checked nodes.</p>\n</div>\n'
},
codeFiles: ['events.vue']
},
{
demoId: 'clearable',
name: {
'zh-CN': '搜索框是否可清空',
'en-US': 'Can the search box be cleared'
},
desc: {
'zh-CN': '通过设置<code>clearable</code>属性来标明是否允许显示搜索框清空按钮',
'en-US':
'Indicate whether to allow the search box clear button to be displayed by setting the<code>clearable</code>property'
},
codeFiles: ['clearable.vue']
}
]
}

View File

@ -91,7 +91,8 @@ export const renderless = (
treeStyle: computed(() => api.computedTreeStyle()),
defaultExpandedKeys: computed(() =>
props.defaultExpandedKeys && props.defaultExpandedKeys.length ? props.defaultExpandedKeys : state.currentKey
)
),
clearable: computed(() => props.clearable)
})
Object.assign(api, {

View File

@ -1,4 +1,4 @@
import type { ExtractPropTypes } from 'vue'
import type { ComputedRef, ExtractPropTypes } from 'vue'
import type { treeMenuProps } from '@/tree-menu/src'
import type {
initData,
@ -31,6 +31,7 @@ export interface ITreeMenuState {
data?: unknown[]
filterText: string
isCollapsed: boolean
clearable: ComputedRef<boolean>
}
export type ITreeMenuProps = ExtractPropTypes<typeof treeMenuProps>
export interface ITreeMenuApi {

View File

@ -81,6 +81,10 @@ export const treeMenuProps = {
menuCollapsible: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: false
}
}

View File

@ -28,6 +28,7 @@
v-model="state.filterText"
:placeholder="placeholder || t('ui.treeMenu.placeholder')"
:prefix-icon="searchIcon"
:clearable="state.clearable"
/>
<tiny-tree
ref="tree"
@ -209,6 +210,10 @@ export default defineComponent({
menuCollapsible: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: false
}
},
setup(props, context) {