|
1 | 1 | import * as React from 'react';
|
| 2 | +import useMemo from 'rc-util/lib/hooks/useMemo'; |
2 | 3 | import { GenerateConfig } from '../../generate';
|
3 | 4 | import { Locale, OnSelect } from '../../interface';
|
4 | 5 | import TimeUnitColumn, { Unit } from './TimeUnitColumn';
|
5 | 6 | import { leftPad } from '../../utils/miscUtil';
|
6 | 7 | import { SharedTimeProps } from '.';
|
| 8 | +import { setTime as utilSetTime } from '../../utils/timeUtil'; |
| 9 | + |
| 10 | +function shouldUnitsUpdate(prevUnits: Unit[], nextUnits: Unit[]) { |
| 11 | + if (prevUnits.length !== nextUnits.length) return true; |
| 12 | + // if any unit's disabled status is different, the units should be re-evaluted |
| 13 | + for (let i = 0; i < prevUnits.length; i += 1) { |
| 14 | + if (prevUnits[i].disabled !== nextUnits[i].disabled) return true; |
| 15 | + } |
| 16 | + return false; |
| 17 | +} |
7 | 18 |
|
8 | 19 | function generateUnits(
|
9 | 20 | start: number,
|
@@ -83,37 +94,60 @@ function TimeBody<DateType>(props: TimeBodyProps<DateType>) {
|
83 | 94 | const mergedMinute = Math.max(0, newMinute);
|
84 | 95 | const mergedSecond = Math.max(0, newSecond);
|
85 | 96 |
|
86 |
| - newDate = generateConfig.setSecond(newDate, mergedSecond); |
87 |
| - newDate = generateConfig.setMinute(newDate, mergedMinute); |
88 |
| - newDate = generateConfig.setHour( |
| 97 | + newDate = utilSetTime( |
| 98 | + generateConfig, |
89 | 99 | newDate,
|
90 | 100 | !use12Hours || !isNewPM ? mergedHour : mergedHour + 12,
|
| 101 | + mergedMinute, |
| 102 | + mergedSecond, |
91 | 103 | );
|
92 | 104 |
|
93 | 105 | return newDate;
|
94 | 106 | };
|
95 | 107 |
|
96 | 108 | // ========================= Unit =========================
|
97 |
| - const hours = generateUnits( |
98 |
| - 0, |
99 |
| - use12Hours ? 11 : 23, |
100 |
| - hourStep, |
101 |
| - disabledHours && disabledHours(), |
102 |
| - ); |
| 109 | + const rawHours = generateUnits(0, 23, hourStep, disabledHours && disabledHours()); |
| 110 | + |
| 111 | + const memorizedRawHours = useMemo(() => rawHours, rawHours, shouldUnitsUpdate); |
103 | 112 |
|
104 | 113 | // Should additional logic to handle 12 hours
|
105 |
| - if (use12Hours && hour !== -1) { |
106 |
| - isPM = hour >= 12; |
| 114 | + if (use12Hours) { |
| 115 | + isPM = hour >= 12; // -1 means should display AM |
107 | 116 | hour %= 12;
|
108 |
| - hours[0].label = '12'; |
109 | 117 | }
|
110 | 118 |
|
111 |
| - const minutes = generateUnits( |
112 |
| - 0, |
113 |
| - 59, |
114 |
| - minuteStep, |
115 |
| - disabledMinutes && disabledMinutes(hour), |
116 |
| - ); |
| 119 | + const [AMDisabled, PMDisabled] = React.useMemo(() => { |
| 120 | + if (!use12Hours) { |
| 121 | + return [false, false]; |
| 122 | + } |
| 123 | + const AMPMDisabled = [true, true]; |
| 124 | + memorizedRawHours.forEach(({ disabled, value: hourValue }) => { |
| 125 | + if (disabled) return; |
| 126 | + if (hourValue >= 12) { |
| 127 | + AMPMDisabled[1] = false; |
| 128 | + } else { |
| 129 | + AMPMDisabled[0] = false; |
| 130 | + } |
| 131 | + }); |
| 132 | + return AMPMDisabled; |
| 133 | + }, [use12Hours, memorizedRawHours]); |
| 134 | + |
| 135 | + const hours = React.useMemo(() => { |
| 136 | + if (!use12Hours) return memorizedRawHours; |
| 137 | + return memorizedRawHours |
| 138 | + .filter(isPM ? hourMeta => hourMeta.value >= 12 : hourMeta => hourMeta.value < 12) |
| 139 | + .map(hourMeta => { |
| 140 | + const hourValue = hourMeta.value % 12; |
| 141 | + const hourLabel = hourValue === 0 ? '12' : leftPad(hourValue, 2); |
| 142 | + return { |
| 143 | + ...hourMeta, |
| 144 | + label: hourLabel, |
| 145 | + value: hourValue, |
| 146 | + }; |
| 147 | + }); |
| 148 | + }, [use12Hours, memorizedRawHours]); |
| 149 | + |
| 150 | + const minutes = generateUnits(0, 59, minuteStep, disabledMinutes && disabledMinutes(hour)); |
117 | 151 |
|
118 | 152 | const seconds = generateUnits(
|
119 | 153 | 0,
|
@@ -207,7 +241,10 @@ function TimeBody<DateType>(props: TimeBodyProps<DateType>) {
|
207 | 241 | use12Hours === true,
|
208 | 242 | <TimeUnitColumn key="12hours" />,
|
209 | 243 | PMIndex,
|
210 |
| - [{ label: 'AM', value: 0 }, { label: 'PM', value: 1 }], |
| 244 | + [ |
| 245 | + { label: 'AM', value: 0, disabled: AMDisabled }, |
| 246 | + { label: 'PM', value: 1, disabled: PMDisabled }, |
| 247 | + ], |
211 | 248 | num => {
|
212 | 249 | onSelect(setTime(!!num, hour, minute, second), 'mouse');
|
213 | 250 | },
|
|
0 commit comments