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(Picker): added PickerColumn type to columns attr #1556

Merged
merged 3 commits into from
Aug 30, 2024
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
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];
};
Loading