Skip to content

Commit

Permalink
feat: add value and initialValue props and fixed reported bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
ali-master committed Jun 11, 2021
1 parent d919a61 commit 9c6b26a
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 42 deletions.
7 changes: 7 additions & 0 deletions src/components/WheelPicker/index.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export const StyledCaption = styled.div<CaptionProps>`
font-size: 1.1em;
border-bottom: 1px solid #e0e0e0;
`;
StyledCaption.displayName = 'PersianTools(WheelPicker)(Caption)';

export const StyledTitle = styled.div`
width: 100%;
text-align: center;
Expand All @@ -23,5 +25,10 @@ export const StyledTitle = styled.div`
font-weight: bold;
font-size: 1.1em;
`;
StyledTitle.displayName = 'PersianTools(WheelPicker)(Title)';

export const PickerWithStyle = styled(Picker)``;
PickerWithStyle.displayName = 'PersianTools(WheelPicker)(PickerColumns)';

export const PickerItemWithStyle = styled(Picker.Item)``;
PickerItemWithStyle.displayName = 'PersianTools(WheelPicker)(PickerItems)';
6 changes: 3 additions & 3 deletions src/components/WheelPicker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import {
} from '../../helpers';
import {
pickerData,
convertDateObjectToDateInstance,
getDayOfYear,
convertDateObjectToDateInstance,
} from '../../helpers/date';
// Events
import { solarEvents } from '../../events/solar';
Expand Down Expand Up @@ -115,6 +115,7 @@ export const WheelPicker: FC<WheelPickerProps> = (props) => {
props.endYear,
]);

// Call onChange for the first time that the WheelPicker has mounted.
React.useEffect(() => {
if (selectedDate && defaultPickerValueAsString.length) {
onChange(convertSelectedDateObjectToArray(selectedDate));
Expand Down Expand Up @@ -254,8 +255,6 @@ export const WheelPicker: FC<WheelPickerProps> = (props) => {
[selectedDate, props.highlightHolidays, props.highlightWeekends],
);

console.count('rerender');

return (
<React.Fragment>
{props.title && <StyledTitle>{props.title}</StyledTitle>}
Expand Down Expand Up @@ -332,6 +331,7 @@ export const WheelPicker: FC<WheelPickerProps> = (props) => {
);
};

WheelPicker.displayName = 'PersianTools(WheelPicker)';
WheelPicker.defaultProps = {
startYear: 30, // past 30 years
endYear: 30, // next 30 years
Expand Down
6 changes: 4 additions & 2 deletions src/components/WheelPicker/index.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ export interface WheelPickerSelectEvent {
export interface WheelPickerProps {
// CSS classnames prefix
classNamePrefix?: string;
// Default column value
defaultValue?: Date;
// Initial picker value
initialValue?: Date;
// Current picker value
value?: WheelPickerSelectEvent;
// Title
title?: string;
/**
Expand Down
61 changes: 32 additions & 29 deletions src/hooks/usePicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,22 +101,22 @@ export function usePicker(props: WheelPickerProps) {
const isMaxDateValid = isValid(props.maxDate!);

/**
* * Parse and convert the [defaultValue] that filled as a prop to an Object
* * Parse and convert the [initialValue] that filled as a prop to an Object
*
* @type {RequiredPickerDateModel}
* @private
*/
const defaultValueDateObject = useMemo<RequiredPickerDateModel>(
() => convertDateInstanceToDateObject(props.defaultValue!),
[props.defaultValue],
const initialValueDateObject = useMemo<RequiredPickerDateModel>(
() => convertDateInstanceToDateObject(props.initialValue!),
[props.initialValue],
);
/**
* Check if the Default Value Date is valid and has filled
*
* @type {boolean}
* @private
*/
const isDefaultValueValid = isValid(props.defaultValue!);
const isInitialValueValid = isValid(props.initialValue!);

/**
* Get Min Year of the Year Column which should be rendered
Expand All @@ -131,8 +131,8 @@ export function usePicker(props: WheelPickerProps) {
let year: number;
if (isMinDateValid) {
year = minDateObject.year;
} else if (isDefaultValueValid) {
year = defaultValueDateObject.year + startYear;
} else if (isInitialValueValid) {
year = initialValueDateObject.year + startYear;
} else {
year = currentYear + startYear;
}
Expand All @@ -141,8 +141,8 @@ export function usePicker(props: WheelPickerProps) {
}, [
isMinDateValid,
minDateObject,
isDefaultValueValid,
defaultValueDateObject,
isInitialValueValid,
initialValueDateObject,
props.startYear,
]);
/**
Expand All @@ -158,8 +158,8 @@ export function usePicker(props: WheelPickerProps) {
let year: number;
if (isMinDateValid) {
year = maxDateObject.year;
} else if (isDefaultValueValid) {
year = defaultValueDateObject.year + endYear;
} else if (isInitialValueValid) {
year = initialValueDateObject.year + endYear;
} else {
year = currentYear + endYear;
}
Expand All @@ -168,13 +168,13 @@ export function usePicker(props: WheelPickerProps) {
}, [
isMinDateValid,
maxDateObject,
defaultValueDateObject,
initialValueDateObject,
props.endYear,
isDefaultValueValid,
isInitialValueValid,
]);

/**
* Get default selected date by [MinDate], [MaxDate], [DefaultValue] or current date
* Get default selected date by [MinDate], [MaxDate], [initialValue] or current date
*
* @type {PickerDateModel}
* @private
Expand All @@ -187,13 +187,15 @@ export function usePicker(props: WheelPickerProps) {
return selectedDateRef.current;
}

if (isDefaultValueValid) {
if (isValid(props.value?.date!)) {
return props.value?.object!;
} else if (isInitialValueValid) {
const defaultSelectedDateObject = convertDateInstanceToDateObject(
props.defaultValue!,
props.initialValue!,
);
// Default value has no overlap with [minDate], [maxDate] and also can be rendered by the shouldRender in Component's Config prop
if (
// [defaultValue] is in Range of [MinDate] and [MaxDate] - /start
// [initialValue] is in Range of [MinDate] and [MaxDate] - /start
shouldRenderItem(
defaultSelectedDateObject,
'month',
Expand All @@ -209,7 +211,7 @@ export function usePicker(props: WheelPickerProps) {
defaultSelectedDateObject.year,
) &&
// /end
// [defaultValue] can be rendered by the [shouldRender] Config method - /start
// [initialValue] can be rendered by the [shouldRender] Config method - /start
configShouldRender(defaultSelectedDateObject, 'year') &&
configShouldRender(defaultSelectedDateObject, 'month') &&
configShouldRender(defaultSelectedDateObject, 'day')
Expand All @@ -223,8 +225,8 @@ export function usePicker(props: WheelPickerProps) {
const currentDateAsObject = currentDateObject();

if (isMinDateValid) {
// We goes here if `maxDate` or `defaultValue` is not valid as valid date
// Check if the `Current Date` is bigger than or Equals the `Min Date`, if was true, consider the `Current Date` as `defaultValue`
// We goes here if `maxDate` or `initialValue` is not valid as valid date
// Check if the `Current Date` is bigger than or Equals the `Min Date`, if was true, consider the `Current Date` as `initialValue`
if (
isAfter(currentDate, props.minDate!) ||
isEqual(currentDate, props.minDate!)
Expand All @@ -234,20 +236,20 @@ export function usePicker(props: WheelPickerProps) {

return minDateObject;
} else if (isMaxDateValid) {
// We goes here if `defaultValue` is not valid as valid date
// Check if the `Current Date` is less than or Equals the `maxDate`, if was true, consider the `currentDate` as the `defaultValue`
// We goes here if `initialValue` is not valid as valid date
// Check if the `Current Date` is less than or Equals the `maxDate`, if was true, consider the `currentDate` as the `initialValue`
if (
isBefore(currentDate, props.maxDate!) ||
isEqual(currentDate, props.maxDate!)
) {
return currentDateAsObject;
}

// `Current Date` is not in range of [maxDate] and Max Date should be used as `defaultValue`
// `Current Date` is not in range of [maxDate] and Max Date should be used as `initialValue`
return maxDateObject;
}

// I tried my best but `defaultValue`, `maxDate` and `minDate` are not valid dates.
// I tried my best but `initialValue`, `maxDate` and `minDate` are not valid dates.
throw new Error(
`[PersianMobileDatePicker] I tried my best but can't consider a valid default value for using in the Picker's Columns.`,
);
Expand All @@ -256,11 +258,12 @@ export function usePicker(props: WheelPickerProps) {
maxDateObject,
minDateObject,
isMaxDateValid,
props.defaultValue,
isDefaultValueValid,
props.value?.date,
props.value?.object,
props.initialValue,
isInitialValueValid,
selectedDateRef.current,
]);

/**
* Default Picker selected columns value which goes from the parent to local changes
*
Expand Down Expand Up @@ -608,8 +611,8 @@ export function usePicker(props: WheelPickerProps) {
isMinDateValid,
isMaxDateValid,

isDefaultValueValid,
defaultValueDateObject,
isInitialValueValid,
initialValueDateObject,
defaultPickerValueAsString,

// Functions
Expand Down
3 changes: 3 additions & 0 deletions src/index.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ export const StyledSubmitButton = styled.button`
line-height: 1.5;
-webkit-appearance: button;
`;
StyledSubmitButton.displayName = 'PersianTools(Picker)(SubmitButton)';

export const StyledCancelButton = styled(StyledSubmitButton)`
color: #616161;
background-color: transparent;
border: 1px solid #c0c0c0;
`;
StyledCancelButton.displayName = 'PersianTools(Picker)(CancelButton)';

export const StyledFooter = styled.div`
position: absolute;
Expand All @@ -36,3 +38,4 @@ export const StyledFooter = styled.div`
align-items: center;
border-top: 1px solid #e0e0e0;
`;
StyledFooter.displayName = 'PersianTools(Picker)(Footer)';
33 changes: 26 additions & 7 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ import {
} from './index.styles';
// Types
import type { PickerProps } from './index.types';
import type { WheelPickerSelectEvent } from './components/WheelPicker/index.types';

const Picker: React.FC<PickerProps> = (props) => {
const [isOpen, setIsOpen] = React.useState<boolean>(false);
const [
selectedDate,
setSelectedDate,
] = React.useState<WheelPickerSelectEvent>();

React.useEffect(() => {
setIsOpen(props.isOpen);
Expand All @@ -24,6 +29,16 @@ const Picker: React.FC<PickerProps> = (props) => {
props.onClose?.();
}

function handleOnChange(selected: WheelPickerSelectEvent) {
setSelectedDate(selected);
props.onChange?.(selected);
}

function handleSubmit() {
handleClose();
props.onSubmit(selectedDate!);
}

return (
<Sheet
isOpen={isOpen}
Expand All @@ -36,25 +51,28 @@ const Picker: React.FC<PickerProps> = (props) => {
<Sheet.Content disableDrag={props.disableSheetDrag}>
<WheelPicker
title={props.title}
value={props.value}
config={props.config}
minDate={props.minDate}
maxDate={props.maxDate}
defaultValue={props.defaultValue}
classNamePrefix={props.classNamePrefix}
highlightWeekends={props.highlightWeekends}
highlightHolidays={props.highlightHolidays}
endYear={props.endYear}
startYear={props.startYear}
onChange={props.onChange}
onChange={handleOnChange}
disabled={props.disabled}
startYear={props.startYear}
addDayName={props.addDayName}
initialValue={props.initialValue}
classNamePrefix={props.classNamePrefix}
highlightWeekends={props.highlightWeekends}
highlightHolidays={props.highlightHolidays}
/>

<StyledFooter>
{props.showCancelButton && (
<StyledCancelButton>{props.cancelText}</StyledCancelButton>
)}
<StyledSubmitButton>{props.submitText}</StyledSubmitButton>
<StyledSubmitButton onClick={handleSubmit}>
{props.submitText}
</StyledSubmitButton>
</StyledFooter>
</Sheet.Content>
</Sheet.Container>
Expand All @@ -63,6 +81,7 @@ const Picker: React.FC<PickerProps> = (props) => {
);
};

Picker.displayName = 'PersianTools(Picker)';
Picker.defaultProps = {
isOpen: false,
theme: 'android-light',
Expand Down
2 changes: 1 addition & 1 deletion src/index.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface PickerProps extends WheelPickerProps {
// Cancel button text
cancelText?: string;
// Triggered when you click OK
onSelect: (selected: WheelPickerSelectEvent) => void;
onSubmit: (selected: WheelPickerSelectEvent) => void;
// Triggered when click Cancel,
onCancel?: () => void;
// Display Cancel button
Expand Down

0 comments on commit 9c6b26a

Please sign in to comment.