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

[comp:transfer] add transfer component #782

Closed
1 task done
sallerli1 opened this issue Mar 2, 2022 · 1 comment
Closed
1 task done

[comp:transfer] add transfer component #782

sallerli1 opened this issue Mar 2, 2022 · 1 comment
Assignees
Labels

Comments

@sallerli1
Copy link
Contributor

sallerli1 commented Mar 2, 2022

  • I have searched the issues of this repository and believe that this is not a duplicate.

What problem does this feature solve?

add basic transfer component

What does the proposed API look like?

Components Structure

Transfer____ TransferSourceList____ TransferListItem
             |                |____ TransferListHeader
             |                |____ TransferListBody
             |                |____ TransferListFooter
             |
             |____ TransferOperations

API

TransferBindings

穿梭框列表统一使用的参数集合,在插槽与依赖注入时使用,通常用于穿梭框列表自定义,参数根据源数据列表与目标数据列表而划分,详细见下方文档

export interface TransferBindings<T = unknown> {
  // 分割好的数据
  data: ComputedRef<T[]>
  // 过滤后的数据
  filteredData: ComputedRef<T[]>
  // 分页处理过后的数据
  paginatedData: ComputedRef<T[]>
  // 源数据
  dataSource: ComputedRef<T[]>
  // 数据key与数据项对应Map
  dataKeyMap: ComputedRef<Map<VKey, T>>
  // 过滤后的源数据
  filteredDataSource: ComputedRef<T[]>
  // 分页后的源数据
  paginatedDataSource: ComputedRef<T[]>
  // 已选数据
  selectedData: ComputedRef<T[]>
  // 已选数据key集合
  selectedKeys: ComputedRef<Set<VKey>>
  // 已勾选数据
  checkedKeys: ComputedRef<Set<VKey>>
  // 禁用数据key集合
  disabledKeys: ComputedRef<Set<VKey>>
  // 全部勾选状态
  checkAllStatus: ComputedRef<boolean>

  // 是否展示左右箭头操作按钮
  showOperations: ComputedRef<boolean>
  // 是否展示全部勾选框
  showCheckAll: ComputedRef<boolean>
  // 是否可搜索
  searchable: ComputedRef<boolean>
  // 分页配置
  pagination: ComputedRef<PaginationProps | null>

  // 勾选状态改变触发函数
  handleCheckChange: (keys: Set<VKey> | VKey[]) => void
  // 增加已选数据触发函数
  triggerAppend: (data?: T[]) => void
  // 移除已选数据触发函数
  triggerRemove: (keys?: VKey[]) => void
  // 清除已选数据触发函数
  triggerClear: () => void
  // 数据key获取函数
  getRowKey: GetRowKey
  // 全部勾选触发函数
  checkAll: (checked?: boolean) => void

  // 搜索输入
  searchValue: ComputedRef<string | undefined>
  // 搜索输入触发函数
  handleSearchChange: (value: string | undefined) => void
}

IxTransfer

TransferProps

名称 说明 类型 默认值 全局配置 备注
dataSource 源数据数组 object[] [] - -
v-model:selectedData 已选数据数组 - - - -
disabled 是否禁用穿梭框 boolean false - -
itemDisabled 数据项禁用判断逻辑 (item: unknown) => boolean item => item.disabled - -
rowKey 数据项 key 的取值 string | (item: unknown) => string | number 'key' - -
virtual 是否开启虚拟滚动 boolean false - 需要设置 scroll.y
onSourceScroll 源数据列表滚动事件 (evt: Event) => void - - 仅使用默认列表并开启 virtual 下可用
onSourceScrolledChange 源数据列表滚动的位置发生变化 (startIndex: number, endIndex: number, visibleNodes: unknown[]) => void - - 仅使用默认列表并开启 virtual 下可用
onSourceScrolledBottom 源数据列表滚动到底部时触发 () => void - - 仅使用默认列表并开启 virtual 下可用
onSourceScroll 目标列表滚动事件 (evt: Event) => void - - 仅使用默认列表并开启 virtual 下可用
onSourceScrolledChange 目标列表滚动的位置发生变化 (startIndex: number, endIndex: number, visibleNodes: unknown[]) => void - - 仅使用默认列表并开启 virtual 下可用
onSourceScrolledBottom 目标列表滚动到底部时触发 () => void - - 仅使用默认列表并开启 virtual 下可用
customLabel 自定义数据 label 渲染 string | (item: unknown) => VNodeChild - - 仅使用默认列表时可用
listStyle 自定义列表样式 - - - 仅使用默认列表时可用
searchable 是否可搜索 boolean true 仅使用默认列表头部时可用
v-model:searchValue 搜索框内容 `string undefined` - 仅使用默认列表头部时可用
searchPlaceholder 搜索框placeholder string '搜索关键字' - 仅使用默认列表头部时可用
sourcePagination 源数据列表分页配置 boolean | PaginationProps false 仅使用默认列表底部时可用
targetPagination 目标数据列表分页配置 boolean | PaginationProps false 仅使用默认列表底部时可用
showOperations 是否展示左右穿梭箭头 boolean true 不展示穿梭箭头时以勾选作为选中
showListHeader 是否展示列表头部 boolean true -
showListFooter 是否展示列表底部 boolean false -
showCheckAll 是否展示全选框 boolean true -
onSelectChange 穿梭框数据改变回调函数 (data: unknown[]) => void - - -
onSearchChange 穿梭框搜索输入回调函数 `(searchValue: string undefined) => void` - -
onSourceCheckAll 源数据列表全部勾选回调函数 (checked: boolean) => void - - -
onTargetCheckAll 目标数据列表全部勾选回调函数 (checked: boolean) => void - - -
onSourceNodeClick 源数据列表数据项点击回调 (evt: Event, item: unknown) => void - - 仅使用默认列表底部时可用
onTargetNodeClick 目标数据列表数据项点击回调 (evt: Event, item: unknown) => void - - 仅使用默认列表底部时可用
onSourceNodeContextmenu 源数据列表数据右键列表回调 (evt: Event, item: unknown) => void - - 仅使用默认列表底部时可用
onTargetNodeContextmenu 目标数据列表数据右键列表回调 (evt: Event, item: unknown) => void - - 仅使用默认列表底部时可用

TransferSlots

名称 说明 参数类型 备注
default 穿梭框列表主体 TransferBindings & { isSource: boolean } -
header 穿梭框列表头部 TransferBindings & { isSource: boolean } -
footer 穿梭框列表底部 TransferBindings & { isSource: boolean } -

TransferMethods

名称 说明 参数类型 备注
sourceScrollTo 源数据滚动到指定位置 (option?: number | VirtualScrollToOptions) => void 仅使用默认列表并开启 virtual 下可用
targetScrollTo 目标数据滚动到指定位置 (option?: number | VirtualScrollToOptions) => void 仅使用默认列表并开启 virtual 下可用

Tokens

TRANSFER_SOURCE_TOKEN

可以结合插槽注入该 token 来获取自定义源数据穿梭框所需要的API与参数

export const TRANSFER_SOURCE_TOKEN: InjectionKey<TransferBindings> = Symbol('TRANSFER_SOURCE_TOKEN')

TRANSFER_TARGET_TOKEN

可以结合插槽注入该 token 来获取自定义源数据穿梭框所需要的API与参数

export const TRANSFER_TARGET_TOKEN: InjectionKey<TransferBindings> = Symbol('TRANSFER_TARGET_TOKEN')

TRANSFER_DATA_STRATEGIES

可以通过该 token 注入自定义的数据处理逻辑来自定义穿梭框,例如自定义树形数据的处理逻辑

export interface SeparatedData<T = unknown> {
  sourceData: T[]
  targetData: T[]
}
export interface TransferDataStrategies<T = unknown> {
  genDataKeys: (data: T[], getRowKey: GetRowKey) => Set<VKey>
  genDataKeyMap: (dataSource: T[], getRowKey: GetRowKey) => Map<VKey, T>
  separateDataSource: (
    dataSource: T[],
    selectedData: T[],
    selectedKeys: Set<VKey>,
    getRowKey: GetRowKey,
  ) => SeparatedData<T>
  checkDisabled: (item: T, dataSource: T[], itemDisabled: ((item: T) => boolean) | undefined) => boolean
  dataFilter: (data: T[], searchValue: string | undefined, searchFn: SearchFn<T> | undefined) => T[]
  appendSelectedData: (
    data: T[],
    selectedData: T[],
    selectedKeys: Set<VKey>,
    getRowKey: GetRowKey,
    setSelectedData: (value: T[]) => void,
  ) => void
  removeSelectedData: (
    keys: VKey[],
    selectedData: T[],
    selectedKeys: Set<VKey>,
    getRowKey: GetRowKey,
    setSelectedData: (value: T[]) => void,
  ) => void
}
export const TRANSFER_DATA_STRATEGIES: InjectionKey<TransferDataStrategies | null> = Symbol('TRANSFER_DATA_STRATEGIES')
@idux-bot idux-bot bot added the Comp:* label Mar 2, 2022
@sallerli1 sallerli1 changed the title [comp:*] add transfer component [comp:transfer] add transfer component Mar 2, 2022
@danranVm
Copy link
Member

danranVm commented Mar 4, 2022

  • v-model:selectedData,不提供。
    • 新增一个 v-model:value, 表示已经到 target 中的 keys
    • 新增一个 v-model:sourceSelectedKeys, 表示在 source 中被选中的 keys
    • 新增一个 v-model:targetSelectedKeys, 表示在 target 中被选中的 keys
  • itemDisabled 不提供,dataSource 的 item 里支持配置 disabled 就好了。
  • rowKey => getKey 吧, 后面其他组件也都会改成这个。
  • onSourceScroll, onTargetScroll => 合并成 onScroll 吧,第1个参数给个标识是source 还是 target 就好了,其他事件(ScrolledChange,ScrolledBottom)也一样处理。
  • customLabel 不提供,直接提供一个 label 的插槽就好了。
  • listStyle 不通过,暂时不提供吧,不太想直接提供设置 style 的 API
  • searchValue 不支持 v-model, 也就是非受控模式,同时提供一个 onSearch 的钩子就好了
  • searchPlaceholder 的默认值,通过 locales 内置, 而且可能要支持分别设置 source 和 target 的情况
  • sourcePagination, targetPagination => pgination, 暂时不用支持两个分页器不一样的情况
  • showOperations => operations, 类型为一个字符串或VNode 数组吧,元素为字符串时就是图标的 name, 为空数组时,就不显示
  • showListHeader 和 showListFooter 都干掉吧,提供一个 header/footer 插槽就可以了,
  • showCheckAll => showSelectAll
  • onSelectChange 不提供,通过新增的 2 个 v-model 就可以解决需求
  • onSearchChange => onSearch
  • onSourceCheckAll, onTargetCheckAll => onSelectAll, 第1个参数给个标识是source 还是 target 就好了
  • onNodeClick 和 onNodeContextMenu 都不提供,在 item 里给个 additional 就好了。
export interface TransferData {
key?: VKey
label?: string
disabled?: boolean
additional?: {
    class?: any
    style?: any
    [key: string]: unknown
  }
}

其他的一些 API,例如 methods, 或者对外暴露的 token 的内容,你再仔细斟酌一下。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants