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

refactor(@clayui/time-picker): rewrites the timer to mimic browser time behavior #2175

Merged
merged 4 commits into from
Jul 22, 2019
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
22 changes: 16 additions & 6 deletions packages/clay-date-picker/src/Hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,28 @@ const useCurrentTime = (format: string) => {
.format(format)
);

function setCurrentTime(hours: number, minutes: number): void {
set(
moment()
function setCurrentTime(
hours: number | string,
minutes: number | string
): void {
if (typeof hours !== 'string') {
hours = moment()
.set('h', hours)
.format('H');
}

if (typeof minutes !== 'string') {
minutes = moment()
.set('m', minutes)
.format(format)
);
.format('m');
}

set(`${hours}:${minutes}`);
}

return [currentTime, setCurrentTime] as [
string,
(hours: number, minutes: number) => void
(hours: number | string, minutes: number | string) => void
];
};

Expand Down
66 changes: 41 additions & 25 deletions packages/clay-date-picker/src/TimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,66 @@
* SPDX-License-Identifier: BSD-3-Clause
*/

import ClayTimePicker from '@clayui/time-picker';
import Icon from '@clayui/icon';
import moment from 'moment';
import React, {ChangeEventHandler, FunctionComponent} from 'react';
import ClayTimePicker, {Input} from '@clayui/time-picker';
import React, {useEffect, useState} from 'react';

interface IProps {
currentTime: string;
onTimeChange: (hours: number, minutes: number) => void;
onTimeChange: (hours: number | string, minutes: number | string) => void;
spritemap: string;
timeFormat: string;
timezone?: string;
}

const ClayDatePickerTimePicker: FunctionComponent<IProps> = ({
const DEFAULT_VALUE = '--';

const ClayDatePickerTimePicker: React.FunctionComponent<IProps> = ({
currentTime,
onTimeChange,
spritemap,
timeFormat,
timezone,
}) => {
const [values, setValues] = useState<Input>({
ampm: DEFAULT_VALUE,
hours: DEFAULT_VALUE,
minutes: DEFAULT_VALUE,
});

/**
* Handles the control time picker
*/
const handleOnChange: ChangeEventHandler<HTMLInputElement> = event => {
const date = moment(event.target.value, timeFormat);
onTimeChange(date.hours(), date.minutes());
const handleOnChange = (values: Input) => {
const hours =
values.hours === DEFAULT_VALUE
? DEFAULT_VALUE
: Number(values.hours);
const minutes =
values.minutes === DEFAULT_VALUE
? DEFAULT_VALUE
: Number(values.minutes);

setValues(values);
onTimeChange(hours, minutes);
};

useEffect(() => {
const time = currentTime.split(':');

setValues(prevValues => ({
...prevValues,
hours: String(time[0]),
minutes: String(time[1]),
matuzalemsteles marked this conversation as resolved.
Show resolved Hide resolved
}));
}, [currentTime]);
matuzalemsteles marked this conversation as resolved.
Show resolved Hide resolved

return (
<div className="time-picker">
<div className="input-group">
<div className="input-group-item input-group-item-shrink">
<span className="input-group-text">
<Icon spritemap={spritemap} symbol="time" />
</span>
</div>
<ClayTimePicker
name="timer"
onChange={handleOnChange}
timezone={timezone}
value={currentTime}
wrapTime={false}
/>
</div>
<ClayTimePicker
icon
onInputChange={handleOnChange}
spritemap={spritemap}
timezone={timezone}
values={values}
/>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,13 +357,9 @@ describe('IncrementalInteractions', () => {
);

const input: any = getByLabelText(ariaLabels.input);
const inputTimePicker: any = getByTestId('time-picker-input');
const hoursEl = getByTestId('hours') as HTMLInputElement;

fireEvent.change(inputTimePicker, {
target: {
value: '00:20',
},
});
fireEvent.keyDown(hoursEl, {key: '10'});
matuzalemsteles marked this conversation as resolved.
Show resolved Hide resolved

expect(input.value).toBe('');
});
Expand All @@ -381,17 +377,13 @@ describe('IncrementalInteractions', () => {

const input: any = getByLabelText(ariaLabels.input);
const dayNumber = getByLabelText('2019 04 24');
const inputTimePicker: any = getByTestId('time-picker-input');
const hoursEl = getByTestId('hours') as HTMLInputElement;

fireEvent.click(dayNumber);

fireEvent.change(inputTimePicker, {
target: {
value: '00:20',
},
});
fireEvent.keyDown(hoursEl, {key: '10'});
matuzalemsteles marked this conversation as resolved.
Show resolved Hide resolved

expect(input.value).toBe('2019-04-24 00:20');
expect(input.value).toBe('2019-04-24 10:0');
});

it('value entered in the input value must be reflected in the time picker', () => {
Expand All @@ -406,15 +398,17 @@ describe('IncrementalInteractions', () => {
);

const input: any = getByLabelText(ariaLabels.input);
const inputTimePicker: any = getByTestId('time-picker-input');
const hoursEl = getByTestId('hours') as HTMLInputElement;
const minutesEl = getByTestId('minutes') as HTMLInputElement;

fireEvent.change(input, {
target: {
value: '2019-04-18 01:20',
},
});

expect(inputTimePicker.value).toBe('01:20');
expect(hoursEl.value).toBe('1');
expect(minutesEl.value).toBe('20');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -1609,43 +1609,130 @@ exports[`BasicRendering renders date picker with time 1`] = `
class="time-picker"
>
<div
class="input-group"
class="clay-time"
>
<div
class="input-group-item input-group-item-shrink"
class="input-group"
>
<span
class="input-group-text"
<div
class="input-group-item input-group-item-shrink"
>
<svg
class="lexicon-icon lexicon-icon-time"
role="presentation"
<div
class="input-group-text"
>
<use
xlink:href="icons.svg#time"
/>
</svg>
</span>
</div>
<div
class="input-group-item"
>
<input
class="form-control"
data-testid="time-picker-input"
name="timer"
type="time"
value="00:00"
/>
</div>
<div
class="input-group-item input-group-item-shrink"
>
<span
class="input-group-text"
>
(GMT+01:00)
</span>
<svg
class="lexicon-icon lexicon-icon-time"
role="presentation"
>
<use
xlink:href="icons.svg#time"
/>
</svg>
</div>
</div>
<div
class="input-group-item input-group-item-shrink"
>
<div
class="form-control"
data-testid="formControl"
>
<div
class="clay-time-edit"
>
<input
class="clay-time-hours form-control-inset"
data-testid="hours"
maxlength="2"
type="text"
value="0"
/>
<span
class="clay-time-divider"
>
:
</span>
<input
class="clay-time-minutes form-control-inset"
data-testid="minutes"
maxlength="2"
type="text"
value="0"
/>
</div>
<div
class="clay-time-action-group"
>
<div
class="clay-time-action-group-item"
data-testid="containerReset"
style="opacity: 0; pointer-events: none;"
>
<button
class="clay-time-clear-btn btn btn-unstyled"
type="button"
>
<svg
class="lexicon-icon lexicon-icon-times-circle"
role="presentation"
>
<use
xlink:href="icons.svg#times-circle"
/>
</svg>
</button>
</div>
<div
class="clay-time-action-group-item"
data-testid="containerSpin"
style="opacity: 0;"
>
<div
class="btn-group-vertical clay-time-inner-spin"
role="group"
>
<button
class="clay-time-inner-spin-btn clay-time-inner-spin-btn-inc btn btn-secondary"
data-testid="spinInc"
type="button"
>
<svg
class="lexicon-icon lexicon-icon-angle-up"
role="presentation"
>
<use
xlink:href="icons.svg#angle-up"
/>
</svg>
</button>
<button
class="clay-time-inner-spin-btn clay-time-inner-spin-btn-dec btn btn-secondary"
data-testid="spinDec"
type="button"
>
<svg
class="lexicon-icon lexicon-icon-angle-down"
role="presentation"
>
<use
xlink:href="icons.svg#angle-down"
/>
</svg>
</button>
</div>
</div>
</div>
</div>
</div>
<div
class="input-group-item input-group-item-shrink"
>
<span
class="input-group-text"
>
(GMT+01:00)
</span>
</div>
</div>
</div>
</div>
Expand Down
Loading