From 9c6b26a562aef535b9ff1dffcdecee7af61e2d99 Mon Sep 17 00:00:00 2001 From: torki Date: Sat, 12 Jun 2021 04:24:42 +0430 Subject: [PATCH] feat: add value and initialValue props and fixed reported bugs --- src/components/WheelPicker/index.styles.ts | 7 +++ src/components/WheelPicker/index.tsx | 6 +-- src/components/WheelPicker/index.types.ts | 6 ++- src/hooks/usePicker.ts | 61 ++++++++++++---------- src/index.styles.ts | 3 ++ src/index.tsx | 33 +++++++++--- src/index.types.ts | 2 +- 7 files changed, 76 insertions(+), 42 deletions(-) diff --git a/src/components/WheelPicker/index.styles.ts b/src/components/WheelPicker/index.styles.ts index cc20ef0..d7a6443 100644 --- a/src/components/WheelPicker/index.styles.ts +++ b/src/components/WheelPicker/index.styles.ts @@ -15,6 +15,8 @@ export const StyledCaption = styled.div` font-size: 1.1em; border-bottom: 1px solid #e0e0e0; `; +StyledCaption.displayName = 'PersianTools(WheelPicker)(Caption)'; + export const StyledTitle = styled.div` width: 100%; text-align: center; @@ -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)'; diff --git a/src/components/WheelPicker/index.tsx b/src/components/WheelPicker/index.tsx index ff36dd1..76668ec 100644 --- a/src/components/WheelPicker/index.tsx +++ b/src/components/WheelPicker/index.tsx @@ -18,8 +18,8 @@ import { } from '../../helpers'; import { pickerData, - convertDateObjectToDateInstance, getDayOfYear, + convertDateObjectToDateInstance, } from '../../helpers/date'; // Events import { solarEvents } from '../../events/solar'; @@ -115,6 +115,7 @@ export const WheelPicker: FC = (props) => { props.endYear, ]); + // Call onChange for the first time that the WheelPicker has mounted. React.useEffect(() => { if (selectedDate && defaultPickerValueAsString.length) { onChange(convertSelectedDateObjectToArray(selectedDate)); @@ -254,8 +255,6 @@ export const WheelPicker: FC = (props) => { [selectedDate, props.highlightHolidays, props.highlightWeekends], ); - console.count('rerender'); - return ( {props.title && {props.title}} @@ -332,6 +331,7 @@ export const WheelPicker: FC = (props) => { ); }; +WheelPicker.displayName = 'PersianTools(WheelPicker)'; WheelPicker.defaultProps = { startYear: 30, // past 30 years endYear: 30, // next 30 years diff --git a/src/components/WheelPicker/index.types.ts b/src/components/WheelPicker/index.types.ts index debe166..c3f3f33 100644 --- a/src/components/WheelPicker/index.types.ts +++ b/src/components/WheelPicker/index.types.ts @@ -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; /** diff --git a/src/hooks/usePicker.ts b/src/hooks/usePicker.ts index 5ae7be3..fbadbaf 100644 --- a/src/hooks/usePicker.ts +++ b/src/hooks/usePicker.ts @@ -101,14 +101,14 @@ 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( - () => convertDateInstanceToDateObject(props.defaultValue!), - [props.defaultValue], + const initialValueDateObject = useMemo( + () => convertDateInstanceToDateObject(props.initialValue!), + [props.initialValue], ); /** * Check if the Default Value Date is valid and has filled @@ -116,7 +116,7 @@ export function usePicker(props: WheelPickerProps) { * @type {boolean} * @private */ - const isDefaultValueValid = isValid(props.defaultValue!); + const isInitialValueValid = isValid(props.initialValue!); /** * Get Min Year of the Year Column which should be rendered @@ -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; } @@ -141,8 +141,8 @@ export function usePicker(props: WheelPickerProps) { }, [ isMinDateValid, minDateObject, - isDefaultValueValid, - defaultValueDateObject, + isInitialValueValid, + initialValueDateObject, props.startYear, ]); /** @@ -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; } @@ -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 @@ -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', @@ -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') @@ -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!) @@ -234,8 +236,8 @@ 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!) @@ -243,11 +245,11 @@ export function usePicker(props: WheelPickerProps) { 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.`, ); @@ -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 * @@ -608,8 +611,8 @@ export function usePicker(props: WheelPickerProps) { isMinDateValid, isMaxDateValid, - isDefaultValueValid, - defaultValueDateObject, + isInitialValueValid, + initialValueDateObject, defaultPickerValueAsString, // Functions diff --git a/src/index.styles.ts b/src/index.styles.ts index 1082c7b..7b5c589 100644 --- a/src/index.styles.ts +++ b/src/index.styles.ts @@ -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; @@ -36,3 +38,4 @@ export const StyledFooter = styled.div` align-items: center; border-top: 1px solid #e0e0e0; `; +StyledFooter.displayName = 'PersianTools(Picker)(Footer)'; diff --git a/src/index.tsx b/src/index.tsx index 1e2ec37..53926ab 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -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 = (props) => { const [isOpen, setIsOpen] = React.useState(false); + const [ + selectedDate, + setSelectedDate, + ] = React.useState(); React.useEffect(() => { setIsOpen(props.isOpen); @@ -24,6 +29,16 @@ const Picker: React.FC = (props) => { props.onClose?.(); } + function handleOnChange(selected: WheelPickerSelectEvent) { + setSelectedDate(selected); + props.onChange?.(selected); + } + + function handleSubmit() { + handleClose(); + props.onSubmit(selectedDate!); + } + return ( = (props) => { {props.showCancelButton && ( {props.cancelText} )} - {props.submitText} + + {props.submitText} + @@ -63,6 +81,7 @@ const Picker: React.FC = (props) => { ); }; +Picker.displayName = 'PersianTools(Picker)'; Picker.defaultProps = { isOpen: false, theme: 'android-light', diff --git a/src/index.types.ts b/src/index.types.ts index 0ac9100..3853df6 100644 --- a/src/index.types.ts +++ b/src/index.types.ts @@ -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