Skip to content

Commit

Permalink
feat: add disableFutureTime and disablePastTime in TimePicker Component
Browse files Browse the repository at this point in the history
affects: @medly-components/core, @medly-components/forms
  • Loading branch information
gmukul01 committed Oct 13, 2024
1 parent 99a61fc commit ea74e4b
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 251 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@ const Component = () => {
return (
<TimePicker
id="dob"
size={select('Size', ['S', 'M'], 'M')}
value={time}
onChange={setTime}
disabled={boolean('Disabled', false)}
label={text('Label', 'Time')}
required={boolean('Required', false)}
variant={select('variant', variants, 'outlined')}
disableFutureTime={boolean('Disable future time', false)}
disablePastTime={boolean('Disable past time', false)}
popoverPlacement={select('Popover placement', placements, 'bottom-start')}
/>
);
Expand Down
23 changes: 20 additions & 3 deletions packages/core/src/components/TimePicker/TimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,25 @@ const Component: FC<TimePickerProps> = memo(
const wrapperRef = useRef<HTMLDivElement>(null);
const inputRef = useCombinedRefs<HTMLInputElement>(ref, useRef(null));
const id = props.id || props.label?.toLowerCase().replace(/\s/g, '') || 'medly-timepicker';
const { value, onChange, disabled, className, fullWidth, minWidth, maxWidth, popoverDistance, popoverPlacement, ...restProps } =
props;
const {
value,
onChange,
disabled,
className,
fullWidth,
minWidth,
maxWidth,
popoverDistance,
popoverPlacement,
disableFutureTime,
disablePastTime,
clearOnCancel,
...restProps
} = props;

const handleReset = () => {
setTextfieldKey(key => key + 1);
onChange('');
clearOnCancel && onChange('');
};
const handleChange = (value: string) => {
setTextfieldKey(key => key + 1);
Expand All @@ -40,6 +53,8 @@ const Component: FC<TimePickerProps> = memo(
onChange={onChange}
value={value}
key={textFieldKey.toString()}
minWidth={minWidth}
maxWidth={maxWidth}
{...restProps}
/>
{!disabled && (
Expand All @@ -50,6 +65,8 @@ const Component: FC<TimePickerProps> = memo(
onReset={handleReset}
popoverDistance={popoverDistance}
popoverPlacement={popoverPlacement}
disableFutureTime={disableFutureTime}
disablePastTime={disablePastTime}
/>
)}
</TimePickerWrapper>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { WithStyle } from '@medly-components/utils';
import { FC, useContext, useEffect, useRef, useState } from 'react';
import { FC, useContext, useEffect, useMemo, useRef, useState } from 'react';
import Button from '../../Button';
import Popover from '../../Popover';
import Popup from '../../Popover/Popup';
Expand All @@ -8,12 +8,38 @@ import type { TIME_OPTION_TYPE } from '../TimeOptionList/types';
import { TimePickerActions, TimePickerCard, TimePickerWrapper } from './TimePickerPopup.styled';
import type { TimePickerPopupProps } from './types';

export const Component: FC<TimePickerPopupProps> = ({ value, onChange, onReset, popoverDistance, popoverPlacement }) => {
export const Component: FC<TimePickerPopupProps> = ({
value,
onChange,
onReset,
popoverDistance,
popoverPlacement,
disableFutureTime,
disablePastTime
}) => {
const hourRef = useRef<HTMLUListElement>(null);
const minutesRef = useRef<HTMLUListElement>(null);
const periodRef = useRef<HTMLUListElement>(null);
const [open, setPopupState] = useContext(Popover.Context);
const [{ hour, minutes, period }, setValues] = useState({ hour: 1, minutes: 0, period: 0 });
const isFutureTime = useMemo(() => {
const currentTime = new Date();
const currentHour = currentTime.getHours();
const currentMinutes = currentTime.getMinutes();
const selectedHour = period === 0 ? hour : hour + 12;
const isFutureHour = currentHour < (period === 0 ? hour : hour + 12);
const isFutureMinutes = currentMinutes < minutes;
return isFutureHour || (selectedHour === currentHour && isFutureMinutes);
}, [hour, minutes, period]);
const isPastTime = useMemo(() => {
const currentTime = new Date();
const currentHour = currentTime.getHours();
const currentMinutes = currentTime.getMinutes();
const selectedHour = period === 0 ? hour : hour + 12;
const isPastHour = currentHour > (period === 0 ? hour : hour + 12);
const isPastMinutes = currentMinutes > minutes;
return isPastHour || (selectedHour === currentHour && isPastMinutes);
}, [hour, minutes, period]);

const handleCancel = () => {
hourRef.current?.scrollTo({ top: 0, behavior: 'smooth' });
Expand Down Expand Up @@ -64,7 +90,11 @@ export const Component: FC<TimePickerPopupProps> = ({ value, onChange, onReset,
<Button size="S" variant="flat" onClick={handleCancel}>
Cancel
</Button>
<Button size="S" onClick={handleSubmit}>
<Button
size="S"
onClick={handleSubmit}
disabled={(disableFutureTime && isFutureTime) || (disablePastTime && isPastTime)}
>
Apply
</Button>
</TimePickerActions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ export type TimePickerPopupProps = {
onReset: () => void;
popoverDistance?: string;
popoverPlacement?: Placement;
disableFutureTime?: boolean;
disablePastTime?: boolean;
};
6 changes: 6 additions & 0 deletions packages/core/src/components/TimePicker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ export interface TimePickerProps extends Omit<TextFieldProps, 'value' | 'onChang
popoverPlacement?: Placement;
/** Distance from Textfield */
popoverDistance?: string;
/** Disable future time */
disableFutureTime?: boolean;
/** Disable past time */
disablePastTime?: boolean;
/** Should clear on cancel */
clearOnCancel?: boolean;
}
Loading

0 comments on commit ea74e4b

Please sign in to comment.