Skip to content

Commit

Permalink
feat(Picker): added PickerColumn type to columns attr (#1556)
Browse files Browse the repository at this point in the history
* feat(Picker): added PickerColumn type to columns attr

* fix: fix spelling errors

* fix: fix type error
  • Loading branch information
anlyyao authored Aug 30, 2024
1 parent 84f2262 commit 367bf26
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/_common
23 changes: 20 additions & 3 deletions src/picker/__test__/index.test.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { nextTick, ref } from 'vue';
import isFunction from 'lodash/isFunction';
import { mount } from '@vue/test-utils';
import { describe, it, expect, vi } from 'vitest';
import Picker from '../picker';
import PickerItem from '../picker-item';
import { getPickerColumns } from '../utils';

import { DEFAULT_ITEM_HEIGHT, ANIMATION_TIME_LIMIT } from '../picker.class';

const getRealColumns = (columns) => {
if (isFunction(columns)) {
const _columns = columns();
return getPickerColumns(_columns);
}
return getPickerColumns(columns);
};

const seasonOptions = [
{ label: '春', value: 'spring' },
{ label: '夏', value: 'summer' },
Expand Down Expand Up @@ -111,11 +121,18 @@ describe('picker', () => {
return expect(itemContainers).toHaveLength(0);
}

expect(itemContainers).toHaveLength(seasonOptions.length);
itemContainers.forEach((container, index) => expect(container.text()).toBe(seasonOptions[index].label));
const _columns = getRealColumns(columns);

expect(itemContainers).toHaveLength(_columns[0].length);

itemContainers.forEach((container, index) => {
if (_columns[index]?.label) {
expect(container.text()).toBe(_columns[index]?.label);
}
});
};

testColumns([undefined], false);
testColumns([undefined], true);
testColumns(undefined, false);
testColumns([seasonOptions]);
testColumns(() => [seasonOptions]);
Expand Down
9 changes: 5 additions & 4 deletions src/picker/demos/base.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
import { reactive } from 'vue';
import { PickerValue } from 'tdesign-mobile-vue';
const cityOptions = [
[
const cityOptions = () => {
return [
{
label: '北京市',
value: '北京市',
Expand Down Expand Up @@ -57,8 +57,9 @@ const cityOptions = [
label: '长沙市',
value: '长沙市',
},
],
];
];
};
const currentYear = Number(new Date().getFullYear());
const yearOptions = Array.from(new Array(10), (_, index) => {
return {
Expand Down
6 changes: 3 additions & 3 deletions src/picker/picker-item.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ref, computed, onMounted, toRefs, defineComponent, PropType, watch } from 'vue';
import { ref, computed, onMounted, defineComponent, PropType, watch } from 'vue';
import config from '../config';
import Picker from './picker.class';
import { PickerColumnItem, PickerValue } from './type';
Expand Down Expand Up @@ -31,7 +31,7 @@ export default defineComponent({
const getIndexByValue = (val: number | string | undefined) => {
let defaultIndex = 0;
if (val !== undefined) {
defaultIndex = props.options?.findIndex((item: any) => item.value === val);
defaultIndex = props.options?.findIndex((item: any) => item?.value === val);
}
return defaultIndex < 0 ? 0 : defaultIndex;
};
Expand Down Expand Up @@ -94,7 +94,7 @@ export default defineComponent({
<ul ref={root} class={className.value}>
{(props.options || []).map((option, index) => (
<li key={index} class={itemClassName.value}>
{props.renderLabel ? props.renderLabel(option) : option.label}
{props.renderLabel ? props.renderLabel(option) : option?.label}
</li>
))}
</ul>
Expand Down
8 changes: 4 additions & 4 deletions src/picker/picker.en-US.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
:: BASE_DOC ::

## API

### Picker Props

name | type | default | description | required
-- | -- | -- | -- | --
cancelBtn | String / Boolean | true | Typescript:`boolean \| string` | N
columns | Array / Function | [] | required。Typescript:`Array<PickerColumn> \| ((item: Array<PickerValue>) => Array<PickerColumn>)` `type PickerColumn = PickerColumnItem[]` `interface PickerColumnItem { label: string,value: string}`[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/picker/type.ts) | Y
columns | Array / Function | [] | required。Typescript:`PickerColumn \| Array<PickerColumn> \| ((item: Array<PickerValue>) => Array<PickerColumn>)` `type PickerColumn = PickerColumnItem[]` `interface PickerColumnItem { label: string,value: string}`[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/picker/type.ts) | Y
confirmBtn | String / Boolean | true | Typescript:`boolean \| string` | N
header | Slot / Function | - | Typescript:`TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
renderLabel | Function | - | Typescript:`(item: PickerColumnItem) => string` | N
title | String | '' | \- | N
value | Array | - | `v-model` and `v-model:value` is supported。Typescript:`Array<PickerValue>` `type PickerValue = string \| number`[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/picker/type.ts) | N
defaultValue | Array | - | uncontrolled property。Typescript:`Array<PickerValue>` `type PickerValue = string \| number`[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/picker/type.ts) | N
visible | Boolean | false | \- | N
onCancel | Function | | Typescript:`(context: { e: MouseEvent }) => void`<br/> | N
onChange | Function | | Typescript:`(value: Array<PickerValue>, context: { columns: Array<PickerContext>, e: MouseEvent }) => void`<br/>[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/picker/type.ts)。<br/>`interface PickerContext{ column: number,index: number }`<br/> | N
onConfirm | Function | | Typescript:`(value: Array<PickerValue>, context: { index: number[], e: MouseEvent, label: string[] }) => void`<br/> | N
Expand All @@ -28,8 +28,8 @@ change | `(value: Array<PickerValue>, context: { columns: Array<PickerContext>,
confirm | `(value: Array<PickerValue>, context: { index: number[], e: MouseEvent, label: string[] })` | \-
pick | `(value: Array<PickerValue>,context: PickerContext)` | \-


### CSS Variables

The component provides the following CSS variables, which can be used to customize styles.
Name | Default Value | Description
-- | -- | --
Expand All @@ -51,4 +51,4 @@ Name | Default Value | Description
--td-picker-title-font-size | 18px | -
--td-picker-title-font-weight | 600 | -
--td-picker-title-line-height | 26px | -
--td-picker-toolbar-height | 58px | -
--td-picker-toolbar-height | 58px | -
9 changes: 5 additions & 4 deletions src/picker/picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@


## API

### Picker Props

名称 | 类型 | 默认值 | 说明 | 必传
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
cancelBtn | String / Boolean | true | 取消按钮文字。TS 类型:`boolean \| string` | N
columns | Array / Function | [] | 必需。配置每一列的选项。TS 类型:`Array<PickerColumn> \| ((item: Array<PickerValue>) => Array<PickerColumn>)` `type PickerColumn = PickerColumnItem[]` `interface PickerColumnItem { label: string,value: string}`[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/picker/type.ts) | Y
columns | Array / Function | [] | 必需。配置每一列的选项。TS 类型:`PickerColumn \| Array<PickerColumn> \| ((item: Array<PickerValue>) => Array<PickerColumn>)` `type PickerColumn = PickerColumnItem[]` `interface PickerColumnItem { label: string,value: string}`[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/picker/type.ts) | Y
confirmBtn | String / Boolean | true | 确定按钮文字。TS 类型:`boolean \| string` | N
header | Slot / Function | - | 自定义头部内容。TS 类型:`TNode`[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
renderLabel | Function | - | 自定义label。TS 类型:`(item: PickerColumnItem) => string` | N
Expand All @@ -28,8 +29,8 @@ change | `(value: Array<PickerValue>, context: { columns: Array<PickerContext>,
confirm | `(value: Array<PickerValue>, context: { index: number[], e: MouseEvent, label: string[] })` | 点击确认按钮时触发
pick | `(value: Array<PickerValue>,context: PickerContext)` | 任何一列选中都会触发,不同的列参数不同。`context.column` 表示第几列变化,`context.index` 表示变化那一列的选中项下标


### CSS Variables

组件提供了下列 CSS 变量,可用于自定义样式。
名称 | 默认值 | 描述
-- | -- | --
Expand All @@ -51,4 +52,4 @@ pick | `(value: Array<PickerValue>,context: PickerContext)` | 任何一列选中
--td-picker-title-font-size | 18px | -
--td-picker-title-font-weight | 600 | -
--td-picker-title-line-height | 26px | -
--td-picker-toolbar-height | 58px | -
--td-picker-toolbar-height | 58px | -
17 changes: 12 additions & 5 deletions src/picker/picker.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { computed, defineComponent, toRefs, ref, watch } from 'vue';
import isString from 'lodash/isString';
import isBoolean from 'lodash/isBoolean';

import isFunction from 'lodash/isFunction';
import config from '../config';
import PickerProps from './props';
import { PickerValue, PickerColumn, PickerColumnItem } from './type';
import { useVModel } from '../shared';
import { useTNodeJSX } from '../hooks/tnode';
import PickerItem from './picker-item';
import { useConfig } from '../config-provider/useConfig';
import { getPickerColumns } from './utils';

const { prefix } = config;
const name = `${prefix}-picker`;

const getIndexFromColumns = (column: PickerColumn, value: PickerValue) => {
if (!value) return 0;
return column?.findIndex((item: PickerColumnItem) => item.value === value);
return column?.findIndex((item: PickerColumnItem) => item?.value === value);
};

export default defineComponent({
Expand All @@ -28,20 +30,25 @@ export default defineComponent({

const { value, modelValue } = toRefs(props);
const [pickerValue = ref([]), setPickerValue] = useVModel(value, modelValue, props.defaultValue, props.onChange);

const getDefaultText = (prop: string | boolean, defaultText: string): string => {
if (isString(prop)) return prop;
if (isBoolean(prop) && prop) return defaultText;
return '';
};

const confirmButtonText = computed(() => getDefaultText(props.confirmBtn, globalConfig.value.confirm));
const cancelButtonText = computed(() => getDefaultText(props.cancelBtn, globalConfig.value.cancel));
const curValueArray = ref(pickerValue.value?.map((item: PickerValue) => item) || []);

const realColumns = computed(() => {
if (typeof props.columns === 'function') {
return props.columns(curValueArray.value);
if (isFunction(props.columns)) {
const _columns = props.columns(curValueArray.value);
return getPickerColumns(_columns);
}
return props.columns;
return getPickerColumns(props.columns);
});

const curIndexArray = realColumns.value.map((item: PickerColumn, index: number) => {
return getIndexFromColumns(item, pickerValue.value?.[index]);
});
Expand Down
2 changes: 0 additions & 2 deletions src/picker/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ export default {
defaultValue: {
type: Array as PropType<TdPickerProps['defaultValue']>,
},
/** 是否显示 */
visible: Boolean,
/** 点击取消按钮时触发 */
onCancel: Function as PropType<TdPickerProps['onCancel']>,
/** 选中变化时候触发 */
Expand Down
7 changes: 1 addition & 6 deletions src/picker/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface TdPickerProps {
* 配置每一列的选项
* @default []
*/
columns: Array<PickerColumn> | ((item: Array<PickerValue>) => Array<PickerColumn>);
columns: PickerColumn | Array<PickerColumn> | ((item: Array<PickerValue>) => Array<PickerColumn>);
/**
* 确定按钮文字
* @default true
Expand Down Expand Up @@ -47,11 +47,6 @@ export interface TdPickerProps {
* 选中值
*/
modelValue?: Array<PickerValue>;
/**
* 是否显示
* @default false
*/
visible?: boolean;
/**
* 点击取消按钮时触发
* @default ''
Expand Down
10 changes: 10 additions & 0 deletions src/picker/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import isArray from 'lodash/isArray';
import { PickerColumn } from './type';

export const isMultipleArray = (arr: PickerColumn | PickerColumn[]) => {
return isArray(arr[0]);
};

export const getPickerColumns = (columns: any): PickerColumn[] => {
return isMultipleArray(columns) ? columns : [columns];
};

0 comments on commit 367bf26

Please sign in to comment.