Skip to content
This repository has been archived by the owner on Jan 5, 2023. It is now read-only.

feat(Timepicker): Add combined time column #844

Merged
merged 42 commits into from
Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8a54221
Combined time picker works
elephantcatdog Sep 23, 2022
2ac7ab7
Added stories, tests, and test images. Fixed bugs.
elephantcatdog Sep 29, 2022
0ccea23
Updated tests
elephantcatdog Sep 29, 2022
03bff18
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Sep 29, 2022
caf4e6c
Edited tests & code as suggested.
elephantcatdog Oct 4, 2022
8620c9f
Added story
elephantcatdog Oct 4, 2022
8891beb
Add radio for precision controls
elephantcatdog Oct 4, 2022
a39a5b7
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Oct 5, 2022
0652b1d
Updated from comments
elephantcatdog Oct 6, 2022
d8788a1
Merge branch 'leah/customize-time-picker' of https://github.com/iTwin…
elephantcatdog Oct 6, 2022
6088f5c
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Oct 10, 2022
a83f06e
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Oct 12, 2022
5a8e742
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Oct 14, 2022
413bcb7
Updated time function
elephantcatdog Oct 17, 2022
f9fa039
Merge branch 'leah/customize-time-picker' of https://github.com/iTwin…
elephantcatdog Oct 17, 2022
f1c8197
Moved default combinedRenderer definition
elephantcatdog Oct 17, 2022
62472e6
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Oct 18, 2022
aa3f75f
Added warning message to `useCombinedRenderer`
elephantcatdog Oct 18, 2022
c166fda
Merge branch 'leah/customize-time-picker' of https://github.com/iTwin…
elephantcatdog Oct 18, 2022
7b2ab59
Improved TimePicker logic
elephantcatdog Oct 19, 2022
7c11338
Included virtualization
elephantcatdog Oct 20, 2022
0b2201e
added comment
elephantcatdog Oct 20, 2022
304620c
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Nov 28, 2022
03aba58
Kinda added virtualization - not scrolling
elephantcatdog Dec 9, 2022
cfa4437
IT WORKS :DDD
elephantcatdog Dec 9, 2022
edb5513
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Dec 9, 2022
2924c11
Working on timepicker tests
elephantcatdog Dec 14, 2022
97f816c
Merge branch 'main' into leah/customize-time-picker
gretanausedaite Dec 14, 2022
fa7bb9b
Fix tests except keyboard navigation
elephantcatdog Dec 14, 2022
a5f3415
Comment fixes
elephantcatdog Dec 14, 2022
6cac0dc
Fix bug with keyboard navigation. 'Fix' keyboard nav tests.
elephantcatdog Dec 15, 2022
976b320
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Dec 15, 2022
416dea0
Update combined renderer prop description.
elephantcatdog Dec 15, 2022
8c838a9
Merge branch 'leah/customize-time-picker' of https://github.com/iTwin…
elephantcatdog Dec 15, 2022
175cdc0
Updated tests
elephantcatdog Dec 15, 2022
65ed349
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Dec 15, 2022
4666968
Revert to before virtualization
elephantcatdog Dec 16, 2022
61a5835
Fixed for PR comments. Updated test images.
elephantcatdog Dec 16, 2022
fd17efa
Updated test images
elephantcatdog Dec 16, 2022
22090e2
Increased test wait time.
elephantcatdog Dec 16, 2022
61d0739
Merge branch 'main' into leah/customize-time-picker
elephantcatdog Dec 16, 2022
6bb9c66
Merge branch 'leah/customize-time-picker' of https://github.com/iTwin…
elephantcatdog Dec 16, 2022
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 53 additions & 0 deletions apps/storybook/src/DatePicker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,59 @@ WithTime.args = {
showTime: true,
};

export const WithCombinedTime: Story<DatePickerProps> = (args) => {
const {
date = new Date(2021, 4, 11, 14, 55, 22),
setFocus = true,
showTime = true,
useCombinedRenderer = true,
use12Hours = true,
localizedNames,
...rest
} = args;
const [opened, setOpened] = React.useState(false);
const [currentDate, setCurrentDate] = React.useState(date);
const onChange = (date: Date) => {
setCurrentDate(date);
action(`New date value: ${date}`, { clearOnStoryChange: false })();
};

React.useEffect(() => {
setCurrentDate(new Date(date));
return () => action('', { clearOnStoryChange: true })();
}, [date]);
return (
<>
<IconButton onClick={() => setOpened(!opened)} id='picker-button'>
<SvgCalendar />
</IconButton>
<span style={{ marginLeft: 16 }}>{currentDate.toString()}</span>
{opened && (
<div style={{ marginTop: 4 }}>
<DatePicker
{...rest}
date={currentDate}
onChange={onChange}
localizedNames={localizedNames}
setFocus={setFocus}
showTime={showTime}
useCombinedRenderer={useCombinedRenderer}
use12Hours={use12Hours}
/>
</div>
)}
</>
);
};

WithCombinedTime.args = {
date: new Date(2021, 4, 11, 14, 55, 22),
setFocus: true,
showTime: true,
useCombinedRenderer: true,
use12Hours: true,
};

export const Localized: Story<DatePickerProps> = (args) => {
const {
date = new Date(2021, 4, 11, 14, 55, 22),
Expand Down
9 changes: 8 additions & 1 deletion apps/storybook/src/DatePicker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@
*--------------------------------------------------------------------------------------------*/
describe('DatePicker', () => {
const storyPath = 'Core/DatePicker';
const tests = ['Basic', 'Localized', 'With Time', 'With Year', 'Range'];
const tests = [
'Basic',
'Localized',
'With Time',
'With Combined Time',
'With Year',
'Range',
];

tests.forEach((testName) => {
it(testName, function () {
Expand Down
195 changes: 178 additions & 17 deletions apps/storybook/src/TimePicker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,20 @@ export default {
className: { control: { disable: true } },
style: { control: { disable: true } },
id: { control: { disable: true } },
date: { control: { type: 'date' } },
date: { control: 'date' },
precision: {
control: 'radio',
options: ['hours', 'minutes', 'seconds'],
},
},
args: { use12Hours: false, precision: 'minutes' },
} as Meta<TimePickerProps>;

export const Basic: Story<TimePickerProps> = (args) => {
const {
date = new Date(2021, 4, 11, 14, 55, 22),
setFocusHour = true,
use12Hours = false,
...rest
} = args;
const [opened, setOpened] = React.useState(false);
Expand All @@ -47,7 +53,7 @@ export const Basic: Story<TimePickerProps> = (args) => {
<>
<LabeledInput
displayStyle='inline'
value={currentDate.toLocaleTimeString()}
value={currentDate.toLocaleTimeString('en-US', { timeStyle: 'short' })}
svgIcon={
<IconButton
styleType='borderless'
Expand All @@ -61,14 +67,13 @@ export const Basic: Story<TimePickerProps> = (args) => {
id='time-input'
/>
{opened && (
<div>
<TimePicker
{...rest}
date={currentDate}
onChange={onChange}
setFocusHour={setFocusHour}
/>
</div>
<TimePicker
{...rest}
date={currentDate}
onChange={onChange}
setFocusHour={setFocusHour}
use12Hours={use12Hours}
/>
)}
</>
);
Expand All @@ -77,11 +82,167 @@ export const Basic: Story<TimePickerProps> = (args) => {
Basic.args = {
date: new Date(2021, 4, 11, 14, 55, 22),
setFocusHour: true,
hourRenderer: (date: Date) =>
date.getHours().toLocaleString(undefined, { minimumIntegerDigits: 2 }),
minuteRenderer: (date: Date) =>
date.getMinutes().toLocaleString(undefined, { minimumIntegerDigits: 2 }),
secondRenderer: (date: Date) =>
date.getSeconds().toLocaleString(undefined, { minimumIntegerDigits: 2 }),
meridiemRenderer: (meridiem: MeridiemType) => meridiem,
};
r100-stack marked this conversation as resolved.
Show resolved Hide resolved

export const CustomRenderers: Story<TimePickerProps> = (args) => {
r100-stack marked this conversation as resolved.
Show resolved Hide resolved
const {
date = new Date(2021, 4, 11, 14, 55, 22),
setFocusHour = true,
use12Hours = false,
hourRenderer = (date: Date) => (
<>
{date.getHours() === 1
? `${date.getHours()} hr`
: `${date.getHours()} hrs`}
</>
r100-stack marked this conversation as resolved.
Show resolved Hide resolved
),
minuteRenderer = (date: Date) => (
<>
{date.getMinutes() === 1
? `${date.getMinutes()} min`
: `${date.getMinutes()} mins`}
</>
),
meridiemRenderer = (meridiem: MeridiemType) => (
<>{meridiem === 'AM' ? 'Before' : 'After'}</>
),
...rest
} = args;
const [opened, setOpened] = React.useState(false);
const [currentDate, setCurrentDate] = React.useState(new Date(date));
const onChange = (date: Date) => {
setCurrentDate(date);
action(`New Time value: ${date}`, { clearOnStoryChange: false })();
};

React.useEffect(() => {
setCurrentDate(new Date(date));
return () => action('', { clearOnStoryChange: true })();
}, [date]);
return (
<>
<LabeledInput
displayStyle='inline'
value={currentDate.toLocaleTimeString('en-US', { timeStyle: 'short' })}
svgIcon={
<IconButton
styleType='borderless'
onClick={() => setOpened((v) => !v)}
>
<SvgCalendar />
</IconButton>
}
style={{ width: 150 }}
readOnly
id='time-input'
/>
{opened && (
<TimePicker
{...rest}
date={currentDate}
onChange={onChange}
setFocusHour={setFocusHour}
use12Hours={use12Hours}
hourRenderer={hourRenderer}
minuteRenderer={minuteRenderer}
meridiemRenderer={meridiemRenderer}
/>
)}
</>
);
};

CustomRenderers.args = {
date: new Date(2021, 4, 11, 14, 55, 22),
setFocusHour: true,
hourRenderer: (date: Date) => (
<>
{date.getHours() === 1
? `${date.getHours()} hr`
: `${date.getHours()} hrs`}
</>
),
minuteRenderer: (date: Date) => (
<>
{date.getMinutes() === 1
? `${date.getMinutes()} min`
: `${date.getMinutes()} mins`}
</>
),
meridiemRenderer: (meridiem: MeridiemType) => (
<>{meridiem === 'AM' ? 'Before' : 'After'}</>
),
};

export const Combined: Story<TimePickerProps> = (args) => {
const {
date = new Date(2021, 4, 11, 14, 55, 30),
setFocusHour = true,
precision = 'seconds',
hourStep = 1,
minuteStep = 1,
secondStep = 15,
use12Hours = true,
useCombinedRenderer = true,
r100-stack marked this conversation as resolved.
Show resolved Hide resolved
...rest
} = args;
const [opened, setOpened] = React.useState(false);
const [currentDate, setCurrentDate] = React.useState(new Date(date));
const onChange = (date: Date) => {
setCurrentDate(date);
action(`New Time value: ${date}`, { clearOnStoryChange: false })();
};

const inputValueType = precision === 'seconds' ? 'medium' : 'short';

React.useEffect(() => {
setCurrentDate(new Date(date));
return () => action('', { clearOnStoryChange: true })();
}, [date]);
return (
<>
<LabeledInput
displayStyle='inline'
value={currentDate.toLocaleTimeString('en-US', {
timeStyle: inputValueType,
})}
svgIcon={
<IconButton
styleType='borderless'
onClick={() => setOpened((v) => !v)}
>
<SvgCalendar />
</IconButton>
}
style={{ width: 150 }}
readOnly
id='time-input'
/>
{opened && (
<TimePicker
{...rest}
date={currentDate}
onChange={onChange}
setFocusHour={setFocusHour}
useCombinedRenderer={useCombinedRenderer}
precision={precision}
hourStep={hourStep}
minuteStep={minuteStep}
secondStep={secondStep}
use12Hours={use12Hours}
/>
)}
</>
);
};

Combined.args = {
date: new Date(2021, 4, 11, 14, 55, 30),
setFocusHour: true,
precision: 'seconds',
r100-stack marked this conversation as resolved.
Show resolved Hide resolved
r100-stack marked this conversation as resolved.
Show resolved Hide resolved
hourStep: 1,
minuteStep: 1,
secondStep: 15,
r100-stack marked this conversation as resolved.
Show resolved Hide resolved
use12Hours: true,
useCombinedRenderer: true,
};
2 changes: 1 addition & 1 deletion apps/storybook/src/TimePicker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
describe('TimePicker', () => {
const storyPath = 'Core/TimePicker';
const tests = ['Basic'];
const tests = ['Basic', 'Custom Renderers', 'Combined'];

tests.forEach((testName) => {
it(testName, function () {
Expand Down
12 changes: 12 additions & 0 deletions packages/iTwinUI-react/src/core/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ export const DatePicker = (props: DatePickerProps): JSX.Element => {
hourStep,
minuteStep,
secondStep,
useCombinedRenderer,
combinedRenderer,
hourRenderer,
minuteRenderer,
secondRenderer,
meridiemRenderer,
showYearSelection = false,
enableRangeSelect = false,
startDate,
Expand Down Expand Up @@ -619,6 +625,12 @@ export const DatePicker = (props: DatePickerProps): JSX.Element => {
hourStep={hourStep}
minuteStep={minuteStep}
secondStep={secondStep}
useCombinedRenderer={useCombinedRenderer}
combinedRenderer={combinedRenderer}
hourRenderer={hourRenderer}
minuteRenderer={minuteRenderer}
secondRenderer={secondRenderer}
meridiemRenderer={meridiemRenderer}
onChange={(date) =>
isSingleOnChange(onChange, enableRangeSelect)
? onChange?.(date)
Expand Down
Loading