import * as _ from 'lodash';
export const htmlImageProps = ['alt', 'height', 'src', 'srcSet', 'width'];
export type HtmlInputEvents =
// keyboard
| 'onKeyDown'
| 'onKeyPress'
| 'onKeyUp'
| 'onFocus'
| 'onBlur'
// form
| 'onChange'
| 'onInput'
// mouse
| 'onClick'
| 'onContextMenu'
| 'onDrag'
| 'onDragEnd'
| 'onDragEnter'
| 'onDragExit'
| 'onDragLeave'
| 'onDragOver'
| 'onDragStart'
| 'onDrop'
| 'onMouseDown'
| 'onMouseEnter'
| 'onMouseLeave'
| 'onMouseMove'
| 'onMouseOut'
| 'onMouseOver'
| 'onMouseUp'
// selection
| 'onSelect'
// touch
| 'onTouchCancel'
| 'onTouchEnd'
| 'onTouchMove'
| 'onTouchStart';
export type HtmlInputAttrs =
// REACT |
| 'selected'
| 'defaultValue'
| 'defaultChecked'
// LIMITED HTML PROPS
| 'accept'
| 'autoCapitalize'
| 'autoComplete'
| 'autoCorrect'
| 'autoFocus'
| 'checked'
| 'disabled'
| 'form'
| 'id'
| 'list'
| 'max'
| 'maxLength'
| 'min'
| 'minLength'
| 'multiple'
| 'name'
| 'pattern'
| 'placeholder'
| 'readOnly'
| 'required'
| 'step'
| 'type'
| 'value';
export type SupportedIntrinsicInputProps = {
[K in HtmlInputProps]?: K extends keyof JSX.IntrinsicElements['input'] ? JSX.IntrinsicElements['input'][K] : any;
};
export const htmlInputAttrs: HtmlInputAttrs[] = [
// REACT
'selected',
'defaultValue',
'defaultChecked',
// LIMITED HTML PROPS
'accept',
'autoCapitalize',
'autoComplete',
'autoCorrect',
'autoFocus',
'checked',
'disabled',
'form',
'id',
'list',
'max',
'maxLength',
'min',
'minLength',
'multiple',
'name',
'pattern',
'placeholder',
'readOnly',
'required',
'step',
'type',
'value',
];
export type HtmlInputProps = HtmlInputAttrs | HtmlInputEvents;
export const htmlInputEvents: HtmlInputEvents[] = [
// EVENTS
// keyboard
'onKeyDown',
'onKeyPress',
'onKeyUp',
// focus
'onFocus',
'onBlur',
// form
'onChange',
'onInput',
// mouse
'onClick',
'onContextMenu',
'onDrag',
'onDragEnd',
'onDragEnter',
'onDragExit',
'onDragLeave',
'onDragOver',
'onDragStart',
'onDrop',
'onMouseDown',
'onMouseEnter',
'onMouseLeave',
'onMouseMove',
'onMouseOut',
'onMouseOver',
'onMouseUp',
// selection
'onSelect',
// touch
'onTouchCancel',
'onTouchEnd',
'onTouchMove',
'onTouchStart',
];
export const htmlInputProps: HtmlInputProps[] = [...htmlInputAttrs, ...htmlInputEvents];
export interface PartitionHTMLPropsOptions {
/** An array of html input props */
htmlProps?: HtmlInputProps[];
/** Includes all input props that starts with "aria-" */
includeAria?: boolean;
}
/**
* Returns props of html input element and restProps.
* @param props - A ReactElement props object
* @param options - Options for
* @returns - 2-element array. First element is props of HTML input element and second element is the other props.
*/
export const partitionHTMLProps = (
props: { [key: string]: any },
options: PartitionHTMLPropsOptions = {},
): [{ [key: string]: any }, { [key: string]: any }] => {
const { htmlProps = htmlInputProps, includeAria = true } = options;
const inputProps = {};
const restProps = {};
_.forEach(props, (val, prop) => {
const possibleAria = includeAria && (/^aria-.*$/.test(prop) || prop === 'role');
const target = _.includes(htmlProps, prop) || possibleAria ? inputProps : restProps;
target[prop] = val;
});
return [inputProps, restProps];
};