wix-style-react
Version:
155 lines (147 loc) • 4.97 kB
JavaScript
import React from 'react';
import StatusAlertSmall from 'wix-ui-icons-common/StatusAlertSmall';
import LabelledElement from '../LabelledElement';
import Input from '../Input';
import Text from '../Text';
import PropTypes from 'prop-types';
import { classes } from './InputWithLabel.st.css';
import dataHooks from './dataHooks';
const getSuffixContainer = suffix =>
suffix.map((item, index) => {
return (
<div
data-hook={`suffix-container`}
key={`suffix-container-${index}`}
className={classes.groupIcon}
>
{item}
</div>
);
});
class InputWithLabel extends React.Component {
static propTypes = {
/** Sets a default value for those who want to use this component uncontrolled */
dataHook: PropTypes.string,
/** Pass a component you want to show as the suffix of the input, e.g., text string, icon. */
suffix: PropTypes.arrayOf(PropTypes.element),
/** Sets the field label */
label: PropTypes.string,
/** Sets input value */
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/** Specifies the status of a field */
status: PropTypes.oneOf(['error', 'warning', 'loading']),
/** Defines the message displayed when you hover over the status icon. If not given or empty there will be no tooltip. */
statusMessage: PropTypes.node,
/** Defines a standard input onFocus callback */
onFocus: PropTypes.func,
/** Defines a standard input onBlur callback */
onBlur: PropTypes.func,
/** Defines a standard input onChange callback */
onChange: PropTypes.func,
/** Reference element data when a form is submitted */
name: PropTypes.string,
/** Specifies the type of `<input/>` element to display. Default is text string. */
type: PropTypes.string,
/** Define a string that labels the current element in case where a text label is not visible on the screen */
ariaLabel: PropTypes.string,
/** Focus the element on mount (standard React input autoFocus). */
autoFocus: PropTypes.bool,
/** Sets the value of native autocomplete attribute (consult the [HTML spec](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-autocomplete) for possible values) */
autocomplete: PropTypes.string,
/** Specifies whether the input should be disabled or not */
disabled: PropTypes.bool,
/** Specifies a CSS class name to be appended to the component’s root element */
className: PropTypes.string,
/** Sets the maximum number of characters that can be entered into a field */
maxLength: PropTypes.number,
/** Sets a placeholder message to display */
placeholder: PropTypes.string,
/** Render a custom input component instead of the default html input tag */
customInput: PropTypes.elementType
? PropTypes.oneOfType([
PropTypes.func,
PropTypes.node,
PropTypes.elementType,
])
: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
};
static defaultProps = {
statusMessage: '',
};
render() {
const {
label,
suffix,
value,
dataHook,
status,
statusMessage,
onChange,
onFocus,
onBlur,
name,
type,
ariaLabel,
autoFocus,
autocomplete,
disabled,
className,
maxLength,
placeholder,
customInput,
} = this.props;
return (
<div
data-hook={dataHook}
className={status ? undefined : classes.statusMessagePlaceholder}
>
<LabelledElement
value={value}
label={label}
dataHook={dataHooks.labelledElement}
>
<Input
name={name}
type={type}
ariaLabel={ariaLabel}
autoFocus={autoFocus}
autocomplete={autocomplete}
disabled={disabled}
maxLength={maxLength}
placeholder={placeholder}
onChange={onChange}
onFocus={onFocus}
onBlur={onBlur}
dataHook={dataHooks.input}
className={className}
size="large"
value={value}
suffix={suffix ? getSuffixContainer(suffix) : []}
status={status}
customInput={customInput}
hideStatusSuffix
/>
</LabelledElement>
{status === Input.StatusError && statusMessage && (
<Text
skin="error"
size="small"
weight="normal"
className={classes.statusMessage}
>
<span className={classes.statusMessageIcon}>
<StatusAlertSmall />
</span>
<span
data-hook={dataHooks.errorMessage}
className={classes.errorMessageContent}
>
{statusMessage}
</span>
</Text>
)}
</div>
);
}
}
export default InputWithLabel;