Skip to content

Commit

Permalink
fix(text-field): make props optional (#735)
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Goo committed Mar 18, 2019
1 parent 09ad132 commit 93e8c15
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 41 deletions.
39 changes: 19 additions & 20 deletions packages/text-field/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,27 @@ import * as classnames from 'classnames';
// @ts-ignore no .d.ts file
import {MDCTextFieldFoundation} from '@material/textfield/dist/mdc.textfield';

export interface InputProps<T> {
className: string;
inputType: 'input' | 'textarea';
disabled: boolean;
export interface InputProps<T extends HTMLElement = HTMLInputElement> {
className?: string;
inputType?: 'input' | 'textarea';
isValid?: boolean;
foundation?: MDCTextFieldFoundation;
handleValueChange: (value: string | number | string[] | undefined, cb: () => void) => void;
id: string;
handleValueChange?: (value: string | number | string[] | undefined, cb: () => void) => void;
ref?: (inputInstance: Input<T>) => void,
onBlur?: Pick<React.HTMLProps<T>, 'onBlur'>;
onChange?: Pick<React.HTMLProps<T>, 'onChange'>;
onFocus?: Pick<React.HTMLProps<T>, 'onFocus'>;
onMouseDown?: Pick<React.HTMLProps<T>, 'onMouseDown'>;
onTouchStart?: Pick<React.HTMLProps<T>, 'onTouchStart'>;
setDisabled: (disabled: boolean) => void;
setInputId: (id: string | number) => void;
handleFocusChange: (isFocused: boolean) => void;
setDisabled?: (disabled: boolean) => void;
setInputId?: (id: string | number) => void;
handleFocusChange?: (isFocused: boolean) => void;
};

type InputElementProps = Exclude<React.HTMLProps<HTMLInputElement>, 'ref'>;
type TextareaElementProps = Exclude<React.HTMLProps<HTMLTextAreaElement>, 'ref'>;
type Props<T> = InputProps<T> & (T extends HTMLInputElement ? InputElementProps : TextareaElementProps);
type Props<T extends HTMLElement = HTMLInputElement>
= InputProps<T> & (T extends HTMLInputElement ? InputElementProps : TextareaElementProps);

interface InputState {
wasUserTriggeredChange: boolean;
Expand All @@ -61,7 +60,7 @@ const VALIDATION_ATTR_WHITELIST: ValidationAttrWhiteList[] = [
];


export default class Input<T extends {}> extends React.Component<
export default class Input<T extends HTMLElement = HTMLInputElement> extends React.Component<
Props<T>, InputState
> {
inputElement_: React.RefObject<
Expand Down Expand Up @@ -94,7 +93,7 @@ export default class Input<T extends {}> extends React.Component<
isValid,
} = this.props;
if (setInputId && id) {
setInputId(id);
setInputId(id!);
}
if (setDisabled && disabled) {
setDisabled(true);
Expand All @@ -111,28 +110,28 @@ export default class Input<T extends {}> extends React.Component<
componentDidUpdate(prevProps: Props<T>) {
const {
id,
handleValueChange,
setInputId,
setDisabled,
foundation,
value,
disabled,
isValid,
handleValueChange,
setInputId,
setDisabled,
} = this.props;

this.handleValidationAttributeUpdate(prevProps);

if (disabled !== prevProps.disabled) {
setDisabled(disabled);
setDisabled && setDisabled(disabled!);
foundation.setDisabled(disabled);
}

if (id !== prevProps.id) {
setInputId(id);
setInputId && setInputId(id!);
}

if (value !== prevProps.value) {
handleValueChange(value, () => {
handleValueChange && handleValueChange(value, () => {
// only call #foundation.setValue on programatic changes;
// not changes by the user.
if (this.state.wasUserTriggeredChange) {
Expand Down Expand Up @@ -165,14 +164,14 @@ export default class Input<T extends {}> extends React.Component<
handleFocus = (evt: React.FocusEvent<T extends HTMLInputElement ? HTMLInputElement : HTMLTextAreaElement>) => {
const {foundation, handleFocusChange, onFocus = () => {}} = this.props;
foundation.activateFocus();
handleFocusChange(true);
handleFocusChange && handleFocusChange(true);
onFocus(evt);
};

handleBlur = (evt: React.FocusEvent<T extends HTMLInputElement ? HTMLInputElement : HTMLTextAreaElement>) => {
const {foundation, handleFocusChange, onBlur = () => {}} = this.props;
foundation.deactivateFocus();
handleFocusChange(false);
handleFocusChange && handleFocusChange(false);
onBlur(evt);
};

Expand Down
16 changes: 8 additions & 8 deletions packages/text-field/helper-text/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ import * as classnames from 'classnames';
import {MDCTextFieldHelperTextFoundation} from '@material/textfield/dist/mdc.textfield';

export interface HelperTextProps {
'aria-hidden': boolean;
'aria-hidden'?: boolean;
children: React.ReactNode;
className: string;
isValid: boolean;
isValidationMessage: boolean;
persistent: boolean;
className?: string;
isValid?: boolean;
isValidationMessage?: boolean;
persistent?: boolean;
role?: string;
showToScreenReader: boolean;
validation: boolean;
showToScreenReader?: boolean;
validation?: boolean;
};

interface HelperTextState {
Expand Down Expand Up @@ -61,7 +61,7 @@ export default class HelperText extends React.Component<
constructor(props: HelperTextProps) {
super(props);
this.state = {
'aria-hidden': props['aria-hidden'],
'aria-hidden': props['aria-hidden']!,
'role': props.role,
'classList': new Set(),
};
Expand Down
26 changes: 13 additions & 13 deletions packages/text-field/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,28 @@ import FloatingLabel from '@material/react-floating-label';
import LineRipple from '@material/react-line-ripple';
import NotchedOutline from '@material/react-notched-outline';

export interface Props<T> {
export interface Props<T extends HTMLElement = HTMLInputElement> {
// InputProps<T> includes the prop `id`, which we use below in the constructor
'children.props'?: InputProps<T>;
children: React.ReactElement<Input<T>>;
className: string;
dense: boolean;
floatingLabelClassName: string;
fullWidth: boolean;
className?: string;
dense?: boolean;
floatingLabelClassName?: string;
fullWidth?: boolean;
helperText?: React.ReactElement<any>;
isRtl: boolean;
label: React.ReactNode;
isRtl?: boolean;
label?: React.ReactNode;
leadingIcon?: React.ReactElement<React.HTMLProps<HTMLOrSVGElement>>;
lineRippleClassName: string;
notchedOutlineClassName: string;
outlined: boolean;
lineRippleClassName?: string;
notchedOutlineClassName?: string;
outlined?: boolean;
onLeadingIconSelect?: () => void;
onTrailingIconSelect?: () => void;
textarea: boolean;
textarea?: boolean;
trailingIcon?: React.ReactElement<React.HTMLProps<HTMLOrSVGElement>>;
};

type TextFieldProps<T> = Props<T> & React.HTMLProps<HTMLDivElement>;
type TextFieldProps<T extends HTMLElement = HTMLInputElement> = Props<T> & React.HTMLProps<HTMLDivElement>;

interface TextFieldState {
foundation?: MDCTextFieldFoundation;
Expand All @@ -71,7 +71,7 @@ interface TextFieldState {
isValid: boolean;
};

class TextField<T extends {}> extends React.Component<TextFieldProps<T>, TextFieldState> {
class TextField<T extends HTMLElement = HTMLInputElement> extends React.Component<TextFieldProps<T>, TextFieldState> {
floatingLabelElement: React.RefObject<FloatingLabel> = React.createRef();
inputComponent_: null | Input<T> = null;

Expand Down

0 comments on commit 93e8c15

Please sign in to comment.