Skip to content

Commit

Permalink
feat: Normalize props
Browse files Browse the repository at this point in the history
Always pass a blur handler. This caters for the case when MaterialUi invokes onBlur without an event.

Always pass props last so that the use can override onChange.

Make sure all properties can always be overriden by the end user
  • Loading branch information
cliedeman committed Jul 27, 2020
1 parent 10bb151 commit 129d5c9
Show file tree
Hide file tree
Showing 14 changed files with 183 additions and 102 deletions.
27 changes: 7 additions & 20 deletions packages/formik-material-ui-lab/src/Autocomplete.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import * as React from 'react';
import MuiAutocomplete, {
AutocompleteProps as MuiAutocompleteProps,
AutocompleteChangeReason,
AutocompleteChangeDetails,
AutocompleteInputChangeReason,
} from '@material-ui/lab/Autocomplete';
import { FieldProps } from 'formik';
import invariant from 'tiny-warning';
import type { Value } from '@material-ui/lab/useAutocomplete';

export { AutocompleteRenderInputParams } from '@material-ui/lab/Autocomplete';

Expand Down Expand Up @@ -64,31 +60,22 @@ export function fieldToAutocomplete<

return {
freeSolo,
onBlur: onBlur
? onBlur
: (event: React.FocusEvent<unknown>) => {
field.onBlur(event ?? field.name);
},
onBlur:
onBlur ??
function (event) {
field.onBlur(event ?? field.name);
},
onInputChange: onInputChange
? onInputChange
: freeSolo
? (
_event: React.ChangeEvent<{}>,
value: string,
_reason: AutocompleteInputChangeReason
) => {
? function (_event, value) {
setFieldValue(field.name, value);
}
: undefined,
onChange: onChange
? onChange
: !freeSolo
? (
_event: React.ChangeEvent<{}>,
value: Value<T, Multiple, DisableClearable, FreeSolo>,
_reason: AutocompleteChangeReason,
_details?: AutocompleteChangeDetails<T>
) => {
? function (_event, value) {
setFieldValue(field.name, value);
}
: undefined,
Expand Down
26 changes: 12 additions & 14 deletions packages/formik-material-ui-lab/src/ToggleButtonGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface ToggleButtonGroupProps
}

export function fieldToToggleButtonGroup({
field,
field: { onChange: _onChange, onBlur: fieldOnBlur, ...field },
type,
onChange,
onBlur,
Expand All @@ -34,20 +34,18 @@ export function fieldToToggleButtonGroup({
}
}

const { onChange: _onChange, onBlur: _onBlur, ...fieldSubselection } = field;

return {
onBlur: onBlur
? onBlur
: (event: React.FocusEvent<unknown>) => {
field.onBlur(event ?? field.name);
},
onChange: onChange
? onChange
: (_event: React.MouseEvent<HTMLElement>, newValue: unknown) => {
form.setFieldValue(field.name, newValue);
},
...fieldSubselection,
onBlur:
onBlur ??
function () {
fieldOnBlur(field.name);
},
onChange:
onChange ??
function (_event, newValue) {
form.setFieldValue(field.name, newValue);
},
...field,
...props,
};
}
Expand Down
27 changes: 19 additions & 8 deletions packages/formik-material-ui-pickers/src/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,35 @@ export interface DatePickerProps
Omit<MuiDatePickerProps, 'name' | 'value' | 'error'> {}

export function fieldToDatePicker({
field,
field: { onChange: _onChange, onBlur: fieldOnBlur, ...field },
form: { isSubmitting, touched, errors, setFieldValue, setFieldError },
disabled,
onChange,
onBlur,
onError,
...props
}: DatePickerProps): MuiDatePickerProps {
const fieldError = getIn(errors, field.name);
const showError = getIn(touched, field.name) && !!fieldError;

return {
...props,
...field,
error: showError,
helperText: showError ? fieldError : props.helperText,
disabled: disabled != undefined ? disabled : isSubmitting,
onChange(date) {
props.onChange ? props.onChange(date) : setFieldValue(field.name, date);
},
onError: createErrorHandler(fieldError, field.name, setFieldError),
disabled: disabled ?? isSubmitting,
onChange:
onChange ??
function (date) {
setFieldValue(field.name, date);
},
onBlur:
onBlur ??
function (e) {
fieldOnBlur(e ?? field.name);
},
onError:
onError ?? createErrorHandler(fieldError, field.name, setFieldError),
...field,
...props,
};
}

Expand Down
27 changes: 19 additions & 8 deletions packages/formik-material-ui-pickers/src/DateTimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,34 @@ export interface DateTimePickerProps

export function fieldToDateTimePicker({
disabled,
field,
field: { onChange: _onChange, onBlur: fieldOnBlur, ...field },
form: { isSubmitting, touched, errors, setFieldValue, setFieldError },
onChange,
onBlur,
onError,
...props
}: DateTimePickerProps): MuiDateTimePickerProps {
const fieldError = getIn(errors, field.name);
const showError = getIn(touched, field.name) && !!fieldError;

return {
...props,
...field,
error: showError,
helperText: showError ? fieldError : props.helperText,
disabled: disabled != undefined ? disabled : isSubmitting,
onChange(date) {
props.onChange ? props.onChange(date) : setFieldValue(field.name, date);
},
onError: createErrorHandler(fieldError, field.name, setFieldError),
disabled: disabled ?? isSubmitting,
onChange:
onChange ??
function (date) {
setFieldValue(field.name, date);
},
onBlur:
onBlur ??
function (e) {
fieldOnBlur(e ?? field.name);
},
onError:
onError ?? createErrorHandler(fieldError, field.name, setFieldError),
...field,
...props,
};
}

Expand Down
27 changes: 19 additions & 8 deletions packages/formik-material-ui-pickers/src/KeyboardDatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,34 @@ export interface KeyboardDatePickerProps

export function fieldToKeyboardDatePicker({
disabled,
field,
field: { onChange: _onChange, onBlur: fieldOnBlur, ...field },
form: { isSubmitting, touched, errors, setFieldValue, setFieldError },
onChange,
onBlur,
onError,
...props
}: KeyboardDatePickerProps): MuiKeyboardDatePickerProps {
const fieldError = getIn(errors, field.name);
const showError = getIn(touched, field.name) && !!fieldError;

return {
...props,
...field,
error: showError,
helperText: showError ? fieldError : props.helperText,
disabled: disabled != undefined ? disabled : isSubmitting,
onChange(date) {
props.onChange ? props.onChange(date) : setFieldValue(field.name, date);
},
onError: createErrorHandler(fieldError, field.name, setFieldError),
disabled: disabled ?? isSubmitting,
onChange:
onChange ??
function (date) {
setFieldValue(field.name, date);
},
onBlur:
onBlur ??
function (e) {
fieldOnBlur(e ?? field.name);
},
onError:
onError ?? createErrorHandler(fieldError, field.name, setFieldError),
...field,
...props,
};
}

Expand Down
27 changes: 19 additions & 8 deletions packages/formik-material-ui-pickers/src/KeyboardDateTimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,34 @@ export interface KeyboardDateTimePickerProps

export function fieldToKeyboardDateTimePicker({
disabled,
field,
field: { onChange: _onChange, onBlur: fieldOnBlur, ...field },
form: { isSubmitting, touched, errors, setFieldValue, setFieldError },
onChange,
onBlur,
onError,
...props
}: KeyboardDateTimePickerProps): MuiKeyboardDateTimePickerProps {
const fieldError = getIn(errors, field.name);
const showError = getIn(touched, field.name) && !!fieldError;

return {
...props,
...field,
error: showError,
helperText: showError ? fieldError : props.helperText,
disabled: disabled != undefined ? disabled : isSubmitting,
onChange(date) {
props.onChange ? props.onChange(date) : setFieldValue(field.name, date);
},
onError: createErrorHandler(fieldError, field.name, setFieldError),
disabled: disabled ?? isSubmitting,
onChange:
onChange ??
function (date) {
setFieldValue(field.name, date);
},
onBlur:
onBlur ??
function (e) {
fieldOnBlur(e ?? field.name);
},
onError:
onError ?? createErrorHandler(fieldError, field.name, setFieldError),
...field,
...props,
};
}

Expand Down
25 changes: 18 additions & 7 deletions packages/formik-material-ui-pickers/src/KeyboardTimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,34 @@ export interface KeyboardTimePickerProps

export function fieldToKeyboardTimePicker({
disabled,
field,
field: { onChange: _onChange, onBlur: fieldOnBlur, ...field },
form: { isSubmitting, touched, errors, setFieldValue, setFieldError },
onChange,
onBlur,
onError,
...props
}: KeyboardTimePickerProps): MuiKeyboardTimePickerProps {
const fieldError = getIn(errors, field.name);
const showError = getIn(touched, field.name) && !!fieldError;

return {
...props,
...field,
error: showError,
helperText: showError ? fieldError : props.helperText,
disabled: disabled != undefined ? disabled : isSubmitting,
onChange(date) {
setFieldValue(field.name, date);
},
onError: createErrorHandler(fieldError, field.name, setFieldError),
onChange:
onChange ??
function (date) {
setFieldValue(field.name, date);
},
onBlur:
onBlur ??
function (e) {
fieldOnBlur(e ?? field.name);
},
onError:
onError ?? createErrorHandler(fieldError, field.name, setFieldError),
...field,
...props,
};
}

Expand Down
34 changes: 20 additions & 14 deletions packages/formik-material-ui-pickers/src/TimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,42 @@ import {
TimePickerProps as MuiTimePickerProps,
} from '@material-ui/pickers';
import { FieldProps, getIn } from 'formik';
import { createErrorHandler } from './errorHandler';

export interface TimePickerProps
extends FieldProps,
Omit<MuiTimePickerProps, 'name' | 'value' | 'error'> {}

export function fieldToTimePicker({
disabled,
field,
field: { onChange: _onChange, onBlur: fieldOnBlur, ...field },
form: { isSubmitting, touched, errors, setFieldValue, setFieldError },
onChange,
onBlur,
onError,
...props
}: TimePickerProps): MuiTimePickerProps {
const fieldError = getIn(errors, field.name);
const showError = getIn(touched, field.name) && !!fieldError;

return {
...props,
...field,
error: showError,
helperText: showError ? fieldError : props.helperText,
disabled: disabled != undefined ? disabled : isSubmitting,
onChange(date) {
props.onChange ? props.onChange(date) : setFieldValue(field.name, date);
},
onError(error) {
if (error !== fieldError && !(error == '' && !fieldError)) {
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore - https://github.com/jaredpalmer/formik/pull/2286
setFieldError(field.name, error ? String(error) : undefined);
}
},
disabled: disabled ?? isSubmitting,
onChange:
onChange ??
function (date) {
setFieldValue(field.name, date);
},
onBlur:
onBlur ??
function (e) {
fieldOnBlur(e ?? field.name);
},
onError:
onError ?? createErrorHandler(fieldError, field.name, setFieldError),
...field,
...props,
};
}

Expand Down
10 changes: 8 additions & 2 deletions packages/formik-material-ui/src/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ export interface CheckboxProps

export function fieldToCheckbox({
disabled,
field,
field: { onBlur: fieldOnBlur, ...field },
form: { isSubmitting },
type,
onBlur,
...props
}: CheckboxProps): MuiCheckboxProps {
const indeterminate = !Array.isArray(field.value) && field.value == null;
Expand All @@ -40,8 +41,13 @@ export function fieldToCheckbox({
return {
disabled: disabled ?? isSubmitting,
indeterminate,
...props,
onBlur:
onBlur ??
function (e) {
fieldOnBlur(e ?? field.name);
},
...field,
...props,
};
}

Expand Down
Loading

0 comments on commit 129d5c9

Please sign in to comment.