@fluent-windows/core
Version:
React components that inspired by Microsoft's Fluent Design System.
82 lines (81 loc) • 2.29 kB
JavaScript
import * as React from 'react';
import { createUseStyles } from '@fluent-windows/styles';
import { styles } from './Field.styled';
import { FieldPropTypes } from '../../Form.type';
import Typography from '../../../Typography';
import Transition from '../../../Transition';
import { FormContext } from '../../Form.context';
import { createValidator } from '../../Form.validator';
import classNames from 'classnames';
export const name = 'FormField';
const useStyles = createUseStyles(styles, {
name
});
const Field = React.forwardRef((props, ref) => {
const {
children,
onChange,
label,
name,
rules,
...rest
} = props;
const {
state,
dispatch,
descriptor
} = React.useContext(FormContext);
const [value, setValue] = React.useState(state.values[name] || '');
const handleValueChange = React.useCallback(v => {
dispatch({
type: 'onChange',
payload: {
[name]: v
}
});
onChange ? onChange(v) : setValue(v);
}, [onChange, dispatch, name]);
React.useEffect(() => {
createValidator(descriptor, state.values, errors => {
dispatch({
type: 'onError',
payload: errors
});
});
}, [dispatch, descriptor, state.values]);
const required = React.useMemo(() => rules ? !!rules.find(v => v.required === true) : false, [rules]); // About the error message
const {
errors
} = state;
const selfError = errors[name];
const classes = useStyles(props);
const labelClassName = classNames(classes.label, {
[classes.labelRequired]: required
});
return React.createElement("tr", {
ref: ref
}, label && React.createElement(Typography, {
variant: "body1",
as: "td"
}, React.createElement("label", {
className: labelClassName,
htmlFor: name
}, label)), React.createElement("td", null, React.cloneElement(children, {
name,
value,
onChange: handleValueChange,
error: !!selfError,
...rest
}), React.createElement(Transition, {
visible: !!selfError,
wrapper: false,
mountOnEnter: true,
unmountOnExit: true
}, React.createElement(Typography, {
variant: "body2",
color: "error.default"
}, selfError))));
});
Field.displayName = 'FFormField';
Field.propTypes = FieldPropTypes;
export default Field;