Skip to content

Commit

Permalink
feat(TimePicker): support autoswap API (#3363)
Browse files Browse the repository at this point in the history
* feat(timepicker): support autoswap API

* feat(timepicker): support autoswap API

* chore: live demo
  • Loading branch information
uyarn authored Oct 18, 2024
1 parent fc9b43b commit 5d0db30
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 38 deletions.
6 changes: 6 additions & 0 deletions src/time-picker/_usage/time-range-picker-props.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
"type": "Boolean",
"defaultValue": false,
"options": []
},
{
"name": "autoSwap",
"type": "Boolean",
"defaultValue": true,
"options": []
},
{
"name": "borderless",
Expand Down
1 change: 1 addition & 0 deletions src/time-picker/time-picker.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pick | `(value: TimePickerValue, context: { e: MouseEvent })` | \-
name | type | default | description | required
-- | -- | -- | -- | --
allowInput | Boolean | false | \- | N
autoSwap | Boolean | true | \- | N
borderless | Boolean | false | \- | N
clearable | Boolean | false | \- | N
disableTime | Function | - | Typescript:`(h: number, m: number, s: number, context: { partial: TimeRangePickerPartial }) =>Partial<{ hour: Array<number>, minute: Array<number>, second: Array<number> }>` `type TimeRangePickerPartial = 'start' \| 'end'`[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/time-picker/type.ts) | N
Expand Down
1 change: 1 addition & 0 deletions src/time-picker/time-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pick | `(value: TimePickerValue, context: { e: MouseEvent })` | 面板选中值
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
allowInput | Boolean | false | 是否允许直接输入时间 | N
autoSwap | Boolean | true | 是否自动调换左右区间的顺序,默认为 true;若需要支持跨天的场景,可以设置为 false | N
borderless | Boolean | false | 无边框模式 | N
clearable | Boolean | false | 是否允许清除选中值 | N
disableTime | Function | - | 禁用时间项。TS 类型:`(h: number, m: number, s: number, context: { partial: TimeRangePickerPartial }) =>Partial<{ hour: Array<number>, minute: Array<number>, second: Array<number> }>` `type TimeRangePickerPartial = 'start' \| 'end'`[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/time-picker/type.ts) | N
Expand Down
5 changes: 5 additions & 0 deletions src/time-picker/time-range-picker-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import { PropType } from 'vue';
export default {
/** 是否允许直接输入时间 */
allowInput: Boolean,
/** 是否自动调换左右区间的顺序,默认为 true;若需要支持跨天的场景,可以设置为 false */
autoSwap: {
type: Boolean,
default: true,
},
/** 无边框模式 */
borderless: Boolean,
/** 是否允许清除选中值 */
Expand Down
54 changes: 16 additions & 38 deletions src/time-picker/time-range-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export default defineComponent({
const currentPanelIdx = ref(undefined);
const currentValue = ref<Array<string>>(TIME_PICKER_EMPTY);
const isShowPanel = ref(false);
let openedPanels: number[] = [];

const inputClasses = computed(() => [
`${componentName.value}__group`,
Expand Down Expand Up @@ -73,7 +72,6 @@ export default defineComponent({

const handleClick = ({ position }: { position: 'first' | 'second' }) => {
currentPanelIdx.value = position === 'first' ? 0 : 1;
openedPanels.push(currentPanelIdx.value);
};

const handleTimeChange = (newValue: string) => {
Expand All @@ -84,18 +82,6 @@ export default defineComponent({
}
};

const setCurrentValue2InnerValue = () => {
const [startTime, endTime] = currentValue.value;
const startDayjs = dayjs(startTime, props.format);
const endDayjs = dayjs(endTime, props.format);

if (startDayjs.isAfter(endDayjs, 'second')) {
setInnerValue([currentValue.value[1], currentValue.value[0]]);
} else {
setInnerValue([currentValue.value[0], currentValue.value[1]]);
}
};

const handleInputBlur = (value: TimeRangeValue, { e }: { e: FocusEvent }) => {
if (props.allowInput) {
const isValidTime = validateInputValue(currentValue.value[currentPanelIdx.value], format.value);
Expand All @@ -104,7 +90,6 @@ export default defineComponent({
currentPanelIdx.value === 0
? (currentValue.value = [formattedVal, currentValue.value[1] ?? formattedVal])
: (currentValue.value = [currentValue.value[0] ?? formattedVal, formattedVal]);
setCurrentValue2InnerValue();
}
}
props.onBlur?.({ value, e });
Expand All @@ -120,33 +105,29 @@ export default defineComponent({
};

const handleClickConfirm = () => {
if (openedPanels.length < 2) {
currentPanelIdx.value = currentPanelIdx.value === 1 ? 0 : 1;
openedPanels.push(currentPanelIdx.value);
return;
}

const noValidIndex = currentValue.value.findIndex((v) => !validateInputValue(v, format.value));
if (noValidIndex !== -1) {
currentPanelIdx.value = noValidIndex;
openedPanels.push(currentPanelIdx.value);
return;
}

setCurrentValue2InnerValue();
const isValidTime = !currentValue.value.find((v) => !validateInputValue(v, format.value));
if (isValidTime) setInnerValue(currentValue.value);
if (props.autoSwap) autoSwapTime();
isShowPanel.value = false;
};

const handleFocus = (value: TimeRangeValue, { e, position }: { e: FocusEvent; position: RangeInputPosition }) => {
const panelIndex = position === 'first' ? 0 : 1;
if (isShowPanel.value && currentPanelIdx.value !== panelIndex) {
currentPanelIdx.value = panelIndex;
openedPanels.push(currentPanelIdx.value);
}
props.onFocus?.({ value, e, position: position === 'first' ? 'start' : 'end' });
ctx.emit('focus', { value, e, position: position === 'first' ? 'start' : 'end' });
};

const autoSwapTime = () => {
const [startTime, endTime] = currentValue.value;
const startDayjs = dayjs(startTime, props.format);
const endDayjs = dayjs(endTime, props.format);

if (startDayjs.isAfter(endDayjs, 'second')) {
setInnerValue([currentValue.value[1], currentValue.value[0]]);
} else {
setInnerValue([currentValue.value[0], currentValue.value[1]]);
}
};

const handleOnPick = (pickValue: string, e: MouseEvent) => {
let pickedRangeValue = [];
let context: { e: MouseEvent; position?: TimeRangePickerPartial } = { e };
Expand All @@ -165,10 +146,7 @@ export default defineComponent({
() => isShowPanel.value,
() => {
currentValue.value = isShowPanel.value ? innerValue.value ?? TIME_PICKER_EMPTY : TIME_PICKER_EMPTY;
if (!isShowPanel.value) {
currentPanelIdx.value = undefined;
openedPanels = [];
}
if (!isShowPanel.value) currentPanelIdx.value = undefined;
},
);
return {
Expand Down
5 changes: 5 additions & 0 deletions src/time-picker/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ export interface TdTimeRangePickerProps {
* @default false
*/
allowInput?: boolean;
/**
* 是否自动调换左右区间的顺序,默认为 true;若需要支持跨天的场景,可以设置为 false
* @default true
*/
autoSwap?: boolean;
/**
* 无边框模式
* @default false
Expand Down

0 comments on commit 5d0db30

Please sign in to comment.