Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(comp:cascader): add IxCascaderPanel component #1481

Merged
merged 1 commit into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions packages/components/cascader/__tests__/cascader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MountingOptions, VueWrapper, mount } from '@vue/test-utils'
import { renderWork } from '@tests'

import Cascader from '../src/Cascader'
import OverlayContent from '../src/contents/OverlayContent'
import Panel from '../src/panel/Panel'
import { CascaderData, CascaderProps } from '../src/types'

const defaultDataSource: CascaderData[] = [
Expand Down Expand Up @@ -125,8 +125,7 @@ const defaultMultipleValue = [
]
const defaultExpandedKeys = ['components', 'general']

const getAllOptionGroup = (wrapper: VueWrapper) =>
wrapper.findComponent(OverlayContent).findAll('.ix-cascader-option-group')
const getAllOptionGroup = (wrapper: VueWrapper) => wrapper.findComponent(Panel).findAll('.ix-cascader-option-group')

describe('Cascader', () => {
describe('single work', () => {
Expand Down Expand Up @@ -200,7 +199,7 @@ describe('Cascader', () => {
expect(getAllOptionGroup(wrapper).length).toBe(2)

await wrapper
.findComponent(OverlayContent)
.findComponent(Panel)
.findAll('.ix-cascader-option-group')[1]
.find('.ix-cascader-option')
.trigger('click')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with a brief overview:

The code patch above includes modifications to the imports, functions, and tests for a Cascader component. The changes include importing Panel instead of OverlayContent, changing the getAllOptionGroup function to use Panel instead of OverlayContent, and modifying a test to use Panel instead of OverlayContent.

Overall, the code looks good and there do not appear to be any bug risks or issues with the modifications. However, it would be beneficial to add more comments explaining the purpose and details of the modifications, as well as why they were made. This will help other developers better understand the code. Additionally, if possible, it would also be beneficial to add unit tests to ensure the changes work as expected.

Expand Down
14 changes: 14 additions & 0 deletions packages/components/cascader/demo/Panel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
order: 80
title:
zh: 级联选择面板
en: Cascader Panel
---

## zh

单独使用级联选择面板。

## en

use `IxCascaderPanel` only.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.

This code patch is written in YAML language and it is probably used for a documentation. It has the following components: order, title (with zh and en version), zh and en documentations.

From a code review perspective, it seems there are no bugs or risks. However, it could be improved by adding more details to the description of the components and documentations to make them more clear. Also, consider using other languages if needed to better explain the components and documentations.

150 changes: 150 additions & 0 deletions packages/components/cascader/demo/Panel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<template>
<IxSpace vertical>
<IxDropdown trigger="click">
<IxButton>{{ selectedText }}</IxButton>
<template #overlay>
<IxCascaderPanel v-model:selectedKeys="fullPathValue" :dataSource="dataSource" @select="onSelect" />
</template>
</IxDropdown>
<IxDropdown trigger="click">
<IxButton>{{ singlePathValue }}</IxButton>
<template #overlay>
<IxCascaderPanel
v-model:selectedKeys="singlePathValue"
:dataSource="dataSource"
:fullPath="false"
@select="onSelect"
/>
</template>
</IxDropdown>
</IxSpace>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'

import { CascaderData } from '@idux/components/cascader'

const fullPathValue = ref(['components', 'general', 'button'])
const selectedText = computed(() => fullPathValue.value.join('/'))
const singlePathValue = ref('button')

const onSelect = (option: CascaderData, isSelected: boolean) => {
console.log(option, isSelected)
}

const dataSource: CascaderData[] = [
{
key: 'components',
label: 'Components',
children: [
{
key: 'general',
label: 'General',
children: [
{
key: 'button',
label: 'Button',
},
{
key: 'header',
label: 'Header',
},
{
key: 'icon',
label: 'Icon',
},
],
},
{
key: 'layout',
label: 'Layout',
children: [
{
key: 'divider',
label: 'Divider',
},
{
key: 'grid',
label: 'Grid',
},
{
key: 'space',
label: 'Space',
},
],
},
{
key: 'navigation',
label: 'Navigation',
children: [
{
key: 'breadcrumb',
label: 'Breadcrumb',
},
{
key: 'dropdown',
label: 'Dropdown',
},
{
key: 'menu',
label: 'Menu',
},
{
key: 'pagination',
label: 'Pagination',
},
],
},
],
},
{
key: 'pro',
label: 'Pro',
children: [
{
key: 'pro-layout',
label: 'Layout',
},
{
key: 'pro-table',
label: 'Table',
disabled: true,
},
{
key: 'pro-transfer',
label: 'Transfer',
},
],
},
{
key: 'cdk',
label: 'CDK',
disabled: true,
children: [
{
key: 'a11y',
label: 'Accessibility',
},
{
key: 'breakpoint',
label: 'Breakpoint',
},
{
key: 'click-outside',
label: 'ClickOutside',
},
{
key: 'clipboard',
label: 'Clipboard',
},
{
key: 'forms',
label: 'Forms',
},
],
},
]
</script>

<style scoped lang="less"></style>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the code review:

  1. The code looks valid and complete, and there is no obvious bug risk.
  2. It might be better to consider using a more descriptive name for the 'onSelect' function instead of just 'onSelect'.
  3. If 'dataSource' is going to be used in multiple components, it could be stored in a separate file and imported into each component that needs it. This would make the code easier to maintain.
  4. The code could use some minor formatting changes to make it easier to read, such as indenting the code and using consistent spacing.

44 changes: 44 additions & 0 deletions packages/components/cascader/docs/Api.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,47 @@ interface SelectedItemProps {
| --- | --- | --- | --- |
| `blur` | 失去焦点 | - | - |
| `focus` | 获取焦点 | - | - |

### IxCascaderPanel

级联选择面板

#### CascaderPanelProps

| 名称 | 说明 | 类型 | 默认值 | 全局配置 | 备注 |
| --- | --- | --- | --- | --- | --- |
| `v-model:selectedKeys` | 当前选中的的值 | `any \| any[] \| any[][]` | - | - | - |
| `v-model:expandedKeys` | 展开节点的 `key` 数组 | `VKey[]` | - | - | - |
| `v-model:loadedKeys` | 已经加载完毕的节点的 `key` | `VKey[]` | - | - | - |
| `childrenKey` | 替代[CascaderData](#CascaderData)中的`children`字段 | `string` | `children` | ✅ | - |
| `customAdditional` | 自定义下拉选项的额外属性 | `CascaderCustomAdditional` | - | - | 例如 `class`, 或者原生事件 |
| `dataSource` | 树型数据数组,参见[CascaderData](#CascaderData) | `CascaderData[]` | `[]` | - | - |
| `disabled` | 禁用选择器 | `boolean` | - | - | - |
| `disableData` | 动态禁用某些项 | `(data: CascaderData) => boolean` | - | - | - |
| `empty` | 空数据时的内容 | `'default' \| 'simple' \| EmptyProps` | `'simple'` | - | - |
| `expandIcon` | 展开图标 | `string \| #expandIcon="{key: VKey, expanded: boolean, data: CascaderData}"` | `right` | ✅ | - |
| `expandTrigger` | 触发展开的方式 | `'click' \| 'hover'` | `click` | - | - |
| `fullPath` | 选中后的值是否包含全部路径 | `boolean` | `true` | ✅ | 会影响值的类型,参见 [基本使用](#components-cascader-demo-Basic) 和 [多选模式](#components-cascader-demo-Multiple) |
| `getKey` | 获取数据的唯一标识 | `string \| (data: CascaderData) => VKey` | `key` | ✅ | - |
| `labelKey` | 替代[CascaderData](#CascaderData)中的`label`字段 | `string` | `label` | ✅ | -
| `loadChildren` | 加载子节点数据 | `(data: CascaderData) => Promise<CascaderData[]>` | - | - | - |
| `maxLabel` | 最多显示多少个标签 | `number \| 'responsive'` | - | - | 响应式模式会对性能产生损耗 |
| `multiple` | 多选模式 | `boolean` | `false` | - | - |
| `multipleLimit` | 最多选中多少项 | `number` | - | - | - |
| `searchable` | 是否可搜索 | `boolean \| 'overlay'` | `false` | - | 当为 `true` 时搜索功能集成在选择器上,当为 `overlay` 时,搜索功能集成在悬浮层上 |
| `searchFn` | 根据搜索的文本进行筛选 | `boolean \| SelectSearchFn` | `true` | - | 为 `true` 时使用默认的搜索规则, 如果使用远程搜索,应该设置为 `false` |
| `separator` | 设置分割符 | `string` | `/` | - | - |
| `strategy` | 设置级联策略 | `'all' \| 'parent' \| 'child' \| 'off'` | `'all'` | - | 具体用法参见 [级联策略](#components-cascader-demo-Strategy) |
| `virtual` | 是否开启虚拟滚动 | `boolean` | `false` | - | 需要设置 `height` |
| `onSelect` | 选中值触发 | `(option: CascaderData, oldValue: any) => void` | - | - | - |
| `onExpand` | 点击展开图标时触发 | `(expanded: boolean, isSelected: boolean) => void` | - | - | - |
| `onExpandedChange` | 展开状态发生变化时触发 | `(expendedKeys: VKey[], expendedData: CascaderData[]) => void` | - | - | - |
| `onLoaded` | 子节点加载完毕时触发 | `(loadedKeys: VKey[], data: CascaderData) => void` | - | - | - |
| `onSearch` | 开启搜索功能后,输入后的回调 | `(searchValue: string) => void` | - | - | 通常用于服务端搜索 |

#### CascaderPanelSlots

| 名称 | 说明 | 参数类型 | 备注 |
| --- | --- | --- | --- |
| `empty` | 自定义空状态 | - | - |
| `optionLabel` | 自定义选项的文本 | `data: SelectOption` | - |
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with a code review.

The code looks generally well-structured and easy to read. The variable and function names are descriptive, making it easier to understand what each component does. However, there are a few areas where the code could be improved:

  1. The indentation of the code could be improved to make it more readable.
  2. Consider adding comments to explain any complex logic or abstract concepts.
  3. Make sure all variables are properly typed and checked for errors.
  4. Avoid using unnecessary global variables or constants.
  5. Make sure that all functions and classes are properly documented.
  6. Verify that all code is optimized for performance.
  7. Make sure that all data structures are properly validated before use.
  8. Make sure that all user input is properly sanitized.
  9. Verify that all functions and classes are thoroughly unit tested.

9 changes: 7 additions & 2 deletions packages/components/cascader/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import type { CascaderComponent } from './src/types'
import type { CascaderComponent, CascaderPanelComponent } from './src/types'

import Cascader from './src/Cascader'
import CascaderPanel from './src/panel/Panel'

const IxCascader = Cascader as unknown as CascaderComponent
const IxCascaderPanel = CascaderPanel as unknown as CascaderPanelComponent

export { IxCascader }
export { IxCascader, IxCascaderPanel }

export type {
CascaderInstance,
CascaderComponent,
CascaderPublicProps as CascaderProps,
CascaderPanelInstance,
CascaderPanelComponent,
CascaderPanelPublicProps as CascaderPanelProps,
CascaderData,
CascaderExpandTrigger,
CascaderSearchFn,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the code review:

  1. The code looks well-structured and correctly indented.
  2. The types of variables are properly declared.
  3. The imports and exports are correctly formatted.
  4. The code is not optimized for performance, as there are redundant lines of code that can be removed.
  5. There are no obvious bugs present in the code.
  6. The code could be improved by optimizing it for better performance, as mentioned above.

Expand Down
Loading