UNPKG

@fluent-windows/core

Version:

React components that inspired by Microsoft's Fluent Design System.

82 lines (81 loc) 2.29 kB
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;