Skip to content

Commit 9269984

Browse files
Wxh16144MadCcc
andauthored
feat: optimize time selector panel step precision logic (#596)
* test: add case * chore: optimize time selector panel step precision logic * test: update snapshot * feat(type): update TS type * test: add case * fix: fix negative number error * perf: update performance * Update tests/picker.spec.tsx Co-authored-by: MadCcc <[email protected]> --------- Co-authored-by: MadCcc <[email protected]>
1 parent 730dd9a commit 9269984

File tree

5 files changed

+317
-5
lines changed

5 files changed

+317
-5
lines changed

src/interface.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,10 @@ export interface PresetDate<T> {
112112
label: React.ReactNode;
113113
value: T;
114114
}
115+
116+
// https://stackoverflow.com/a/39495173; need TypeScript >= 4.5
117+
type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N
118+
? Acc[number]
119+
: Enumerate<N, [...Acc, Acc['length']]>
120+
121+
export type IntRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>

src/panels/TimePanel/TimeBody.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ function generateUnits(
2424
disabledUnits: number[] | undefined,
2525
) {
2626
const units: Unit[] = [];
27-
for (let i = start; i <= end; i += step) {
27+
const integerStep = step >= 1 ? step | 0 : 1
28+
for (let i = start; i <= end; i += integerStep) {
2829
units.push({
2930
label: leftPad(i, 2),
3031
value: i,

src/panels/TimePanel/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import classNames from 'classnames';
33
import TimeHeader from './TimeHeader';
44
import type { BodyOperationRef } from './TimeBody';
55
import TimeBody from './TimeBody';
6-
import type { PanelSharedProps, DisabledTimes } from '../../interface';
6+
import type { PanelSharedProps, DisabledTimes, IntRange } from '../../interface';
77
import { createKeyDownHandler } from '../../utils/uiUtil';
88

99
export type SharedTimeProps<DateType> = {
@@ -13,9 +13,9 @@ export type SharedTimeProps<DateType> = {
1313
showMinute?: boolean;
1414
showSecond?: boolean;
1515
use12Hours?: boolean;
16-
hourStep?: number;
17-
minuteStep?: number;
18-
secondStep?: number;
16+
hourStep?: IntRange<1, 23>;
17+
minuteStep?: IntRange<1, 59>;
18+
secondStep?: IntRange<1, 59>;
1919
hideDisabledOptions?: boolean;
2020
defaultValue?: DateType;
2121

tests/__snapshots__/picker.spec.tsx.snap

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,288 @@ exports[`Picker.Basic should render correctly in rtl 1`] = `
103103
</div>
104104
</div>
105105
`;
106+
107+
exports[`Picker.Basic time step should show integer when step is not integer (hour) 1`] = `
108+
<ul
109+
class="rc-picker-time-panel-column"
110+
style="position: relative;"
111+
>
112+
<li
113+
class="rc-picker-time-panel-cell"
114+
>
115+
<div
116+
class="rc-picker-time-panel-cell-inner"
117+
>
118+
00
119+
</div>
120+
</li>
121+
<li
122+
class="rc-picker-time-panel-cell"
123+
>
124+
<div
125+
class="rc-picker-time-panel-cell-inner"
126+
>
127+
05
128+
</div>
129+
</li>
130+
<li
131+
class="rc-picker-time-panel-cell"
132+
>
133+
<div
134+
class="rc-picker-time-panel-cell-inner"
135+
>
136+
10
137+
</div>
138+
</li>
139+
<li
140+
class="rc-picker-time-panel-cell"
141+
>
142+
<div
143+
class="rc-picker-time-panel-cell-inner"
144+
>
145+
15
146+
</div>
147+
</li>
148+
<li
149+
class="rc-picker-time-panel-cell"
150+
>
151+
<div
152+
class="rc-picker-time-panel-cell-inner"
153+
>
154+
20
155+
</div>
156+
</li>
157+
</ul>
158+
`;
159+
160+
exports[`Picker.Basic time step should show integer when step is not integer (minute) 1`] = `
161+
<ul
162+
class="rc-picker-time-panel-column"
163+
style="position: relative;"
164+
>
165+
<li
166+
class="rc-picker-time-panel-cell"
167+
>
168+
<div
169+
class="rc-picker-time-panel-cell-inner"
170+
>
171+
00
172+
</div>
173+
</li>
174+
<li
175+
class="rc-picker-time-panel-cell"
176+
>
177+
<div
178+
class="rc-picker-time-panel-cell-inner"
179+
>
180+
05
181+
</div>
182+
</li>
183+
<li
184+
class="rc-picker-time-panel-cell"
185+
>
186+
<div
187+
class="rc-picker-time-panel-cell-inner"
188+
>
189+
10
190+
</div>
191+
</li>
192+
<li
193+
class="rc-picker-time-panel-cell"
194+
>
195+
<div
196+
class="rc-picker-time-panel-cell-inner"
197+
>
198+
15
199+
</div>
200+
</li>
201+
<li
202+
class="rc-picker-time-panel-cell"
203+
>
204+
<div
205+
class="rc-picker-time-panel-cell-inner"
206+
>
207+
20
208+
</div>
209+
</li>
210+
<li
211+
class="rc-picker-time-panel-cell"
212+
>
213+
<div
214+
class="rc-picker-time-panel-cell-inner"
215+
>
216+
25
217+
</div>
218+
</li>
219+
<li
220+
class="rc-picker-time-panel-cell"
221+
>
222+
<div
223+
class="rc-picker-time-panel-cell-inner"
224+
>
225+
30
226+
</div>
227+
</li>
228+
<li
229+
class="rc-picker-time-panel-cell"
230+
>
231+
<div
232+
class="rc-picker-time-panel-cell-inner"
233+
>
234+
35
235+
</div>
236+
</li>
237+
<li
238+
class="rc-picker-time-panel-cell"
239+
>
240+
<div
241+
class="rc-picker-time-panel-cell-inner"
242+
>
243+
40
244+
</div>
245+
</li>
246+
<li
247+
class="rc-picker-time-panel-cell"
248+
>
249+
<div
250+
class="rc-picker-time-panel-cell-inner"
251+
>
252+
45
253+
</div>
254+
</li>
255+
<li
256+
class="rc-picker-time-panel-cell"
257+
>
258+
<div
259+
class="rc-picker-time-panel-cell-inner"
260+
>
261+
50
262+
</div>
263+
</li>
264+
<li
265+
class="rc-picker-time-panel-cell"
266+
>
267+
<div
268+
class="rc-picker-time-panel-cell-inner"
269+
>
270+
55
271+
</div>
272+
</li>
273+
</ul>
274+
`;
275+
276+
exports[`Picker.Basic time step should show integer when step is not integer (second) 1`] = `
277+
<ul
278+
class="rc-picker-time-panel-column"
279+
style="position: relative;"
280+
>
281+
<li
282+
class="rc-picker-time-panel-cell"
283+
>
284+
<div
285+
class="rc-picker-time-panel-cell-inner"
286+
>
287+
00
288+
</div>
289+
</li>
290+
<li
291+
class="rc-picker-time-panel-cell"
292+
>
293+
<div
294+
class="rc-picker-time-panel-cell-inner"
295+
>
296+
05
297+
</div>
298+
</li>
299+
<li
300+
class="rc-picker-time-panel-cell"
301+
>
302+
<div
303+
class="rc-picker-time-panel-cell-inner"
304+
>
305+
10
306+
</div>
307+
</li>
308+
<li
309+
class="rc-picker-time-panel-cell"
310+
>
311+
<div
312+
class="rc-picker-time-panel-cell-inner"
313+
>
314+
15
315+
</div>
316+
</li>
317+
<li
318+
class="rc-picker-time-panel-cell"
319+
>
320+
<div
321+
class="rc-picker-time-panel-cell-inner"
322+
>
323+
20
324+
</div>
325+
</li>
326+
<li
327+
class="rc-picker-time-panel-cell"
328+
>
329+
<div
330+
class="rc-picker-time-panel-cell-inner"
331+
>
332+
25
333+
</div>
334+
</li>
335+
<li
336+
class="rc-picker-time-panel-cell"
337+
>
338+
<div
339+
class="rc-picker-time-panel-cell-inner"
340+
>
341+
30
342+
</div>
343+
</li>
344+
<li
345+
class="rc-picker-time-panel-cell"
346+
>
347+
<div
348+
class="rc-picker-time-panel-cell-inner"
349+
>
350+
35
351+
</div>
352+
</li>
353+
<li
354+
class="rc-picker-time-panel-cell"
355+
>
356+
<div
357+
class="rc-picker-time-panel-cell-inner"
358+
>
359+
40
360+
</div>
361+
</li>
362+
<li
363+
class="rc-picker-time-panel-cell"
364+
>
365+
<div
366+
class="rc-picker-time-panel-cell-inner"
367+
>
368+
45
369+
</div>
370+
</li>
371+
<li
372+
class="rc-picker-time-panel-cell"
373+
>
374+
<div
375+
class="rc-picker-time-panel-cell-inner"
376+
>
377+
50
378+
</div>
379+
</li>
380+
<li
381+
class="rc-picker-time-panel-cell"
382+
>
383+
<div
384+
class="rc-picker-time-panel-cell-inner"
385+
>
386+
55
387+
</div>
388+
</li>
389+
</ul>
390+
`;

tests/picker.spec.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,25 @@ describe('Picker.Basic', () => {
616616
);
617617
spy.mockRestore();
618618
});
619+
620+
// https://github.com/ant-design/ant-design/issues/40914
621+
['hour', 'minute', 'second'].forEach((unit, index) => {
622+
it(`should show integer when step is not integer (${unit})`, () => {
623+
const props = {
624+
[`${unit}Step`]: 5.5,
625+
}
626+
const { container } = render(<MomentPicker picker="time" {...props} />);
627+
openPicker(container);
628+
expect(document.querySelectorAll('.rc-picker-time-panel-column')[index]).toMatchSnapshot();
629+
});
630+
});
631+
632+
it('should work when hourStep < 0', () => {
633+
// @ts-ignore
634+
const { container } = render(<MomentPicker picker="time" hourStep={-1} />);
635+
openPicker(container);
636+
expect(document.querySelectorAll('.rc-picker-time-panel-column')[0].children.length).toBe(24);
637+
});
619638
});
620639

621640
it('pass data- & aria- & role', () => {

0 commit comments

Comments
 (0)