From 422b52365ce14bf3e31f866135dbc8cfad6d3d45 Mon Sep 17 00:00:00 2001 From: Artur Yorsh <10753921+artyorsh@users.noreply.github.com> Date: Fri, 7 Feb 2020 12:17:27 +0300 Subject: [PATCH] feat(components): add onFocus and onBlur props to input-based components --- .../datepicker/baseDatepicker.component.tsx | 37 +++++++++++++------ .../ui/datepicker/datepicker.component.tsx | 6 ++- .../datepicker/rangeDatepicker.component.tsx | 6 ++- src/components/ui/select/select.component.tsx | 14 +++++++ 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/components/ui/datepicker/baseDatepicker.component.tsx b/src/components/ui/datepicker/baseDatepicker.component.tsx index dada53f6d..6730b4c01 100644 --- a/src/components/ui/datepicker/baseDatepicker.component.tsx +++ b/src/components/ui/datepicker/baseDatepicker.component.tsx @@ -51,6 +51,8 @@ export interface BaseDatepickerProps extends StyledComponentProps, captionStyle?: StyleProp; placement?: PopoverPlacement | string; backdropStyle?: StyleProp; + onFocus?: () => void; + onBlur?: () => void; } interface State { @@ -80,11 +82,11 @@ export abstract class BaseDatepickerComponent extends React.Compone }; public focus = (): void => { - this.setState({ visible: true }, this.dispatchActive); + this.setState({ visible: true }, this.onPickerVisible); }; public blur = (): void => { - this.setState({ visible: true }, this.dispatchActive); + this.setState({ visible: false }, this.onPickerInvisible); }; public isFocused = (): boolean => { @@ -178,7 +180,7 @@ export abstract class BaseDatepickerComponent extends React.Compone }; private onPress = (event: GestureResponderEvent): void => { - this.toggleVisibility(); + this.setPickerVisible(); if (this.props.onPress) { this.props.onPress(event); @@ -201,19 +203,30 @@ export abstract class BaseDatepickerComponent extends React.Compone } }; - private toggleVisibility = (): void => { - const visible: boolean = !this.state.visible; - this.setState({ visible }, this.dispatchActive); + private onPickerVisible = (): void => { + this.props.dispatch([Interaction.ACTIVE]); + + if (this.props.onFocus) { + this.props.onFocus(); + } }; - private dispatchActive = (): void => { - if (this.state.visible) { - this.props.dispatch([Interaction.ACTIVE]); - } else { - this.props.dispatch([]); + private onPickerInvisible = (): void => { + this.props.dispatch([]); + + if (this.props.onBlur) { + this.props.onBlur(); } }; + private setPickerVisible = (): void => { + this.setState({ visible: true }, this.onPickerVisible); + }; + + private setPickerInvisible = (): void => { + this.setState({ visible: false }, this.onPickerInvisible); + }; + private renderIconElement = (style: StyleType): React.ReactElement => { const iconElement: React.ReactElement = this.props.icon(style); @@ -319,7 +332,7 @@ export abstract class BaseDatepickerComponent extends React.Compone placement={placement} visible={this.state.visible} content={calendarElement} - onBackdropPress={this.toggleVisibility}> + onBackdropPress={this.setPickerInvisible}> {controlElement} diff --git a/src/components/ui/datepicker/datepicker.component.tsx b/src/components/ui/datepicker/datepicker.component.tsx index 468c72ac7..f7bef9dce 100644 --- a/src/components/ui/datepicker/datepicker.component.tsx +++ b/src/components/ui/datepicker/datepicker.component.tsx @@ -78,7 +78,11 @@ export type DatepickerElement = React.ReactElement> * * @property {(date: D) => boolean} filter - Predicate that decides which cells will be disabled. * - * @property {(date: D) => void} onSelect - Selection emitter. Fires when another day cell is pressed. + * @property {(date: D) => void} onSelect - Fires when day cell is pressed. + * + * @property {() => void} onFocus - Fires when picker becomes visible. + * + * @property {() => void} onBlur - Fires when picker becomes invisible. * * @property {(date: D, style: StyleType) => ReactElement} renderDay - Should return the content of day cell. * diff --git a/src/components/ui/datepicker/rangeDatepicker.component.tsx b/src/components/ui/datepicker/rangeDatepicker.component.tsx index 16b79c2a0..9fc6d8c13 100644 --- a/src/components/ui/datepicker/rangeDatepicker.component.tsx +++ b/src/components/ui/datepicker/rangeDatepicker.component.tsx @@ -78,7 +78,11 @@ export type RangeDatepickerElement = React.ReactElement boolean} filter - Predicate that decides which cells will be disabled. * - * @property {(date: D) => void} onSelect - Selection emitter. Fires when another day cell is pressed. + * @property {(date: D) => void} onSelect - Fires when day cell is pressed. + * + * @property {() => void} onFocus - Fires when picker becomes visible. + * + * @property {() => void} onBlur - Fires when picker becomes invisible. * * @property {(date: D, style: StyleType) => ReactElement} renderDay - Should return the content of day cell. * diff --git a/src/components/ui/select/select.component.tsx b/src/components/ui/select/select.component.tsx index eacbce804..cecf7307e 100644 --- a/src/components/ui/select/select.component.tsx +++ b/src/components/ui/select/select.component.tsx @@ -72,6 +72,8 @@ export interface SelectProps extends StyledComponentProps, TouchableOpacityProps controlStyle?: StyleProp; icon?: IconProp; onSelect: (option: SelectOption, event?: GestureResponderEvent) => void; + onFocus: () => void; + onBlur: () => void; status?: string; size?: string; keyExtractor?: KeyExtractorType; @@ -124,6 +126,10 @@ interface State { * @property {(option: SelectOption, event?: GestureResponderEvent) => void} onSelect - Fires on option select. * Returns selected option/options. * + * @property {() => void} onFocus - Fires when options list becomes visible. + * + * @property {() => void} onBlur - Fires when options list becomes invisible. + * * @property {StyleProp} label - Determines the `label` of the component. * * @property {StyleProp} placeholder - Determines the `placeholder` of the component. @@ -273,11 +279,19 @@ class SelectComponent extends React.Component implements Web private onOptionsListVisible = (): void => { this.props.dispatch([Interaction.ACTIVE]); this.createIconAnimation(-180).start(); + + if (this.props.onFocus) { + this.props.onFocus(); + } }; private onOptionsListInvisible = (): void => { this.props.dispatch([]); this.createIconAnimation(0).start(); + + if (this.props.onBlur) { + this.props.onBlur(); + } }; private setOptionsListVisible = (): void => {