react-tiniest-form
Version:
the tiniest form
96 lines (95 loc) • 4.75 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
import { Children, isValidElement, useEffect, useId, useRef, } from 'react';
import createFormContext from '../../context/FormContext/FormContext';
import { useForm } from '../../hooks/Form/useForm';
import { getPolymorphicProps } from '../../utils/@common/polymorphic';
import { resolveRenderProps } from '../../utils/@common/resolveRenderProps';
import createCollection from '../../context/Collection/Collection';
const { FormProvider, useFormContext } = createFormContext();
const { CollectionProvider, CollectionItem, useCollection } = createCollection();
const Form = (props) => {
const method = useForm();
const { children, onValidSubmit, onInValidSubmit } = props, restProps = __rest(props, ["children", "onValidSubmit", "onInValidSubmit"]);
const resolvedChildren = resolveRenderProps(children, method);
return (_jsx(FormProvider, { value: method, children: _jsx(CollectionProvider, { children: _jsx("form", Object.assign({ onSubmit: method.handleSubmit(onValidSubmit, onInValidSubmit) }, restProps, { children: resolvedChildren })) }) }));
};
const FIELD_ATTR = 'field_attr';
const Field = (props) => {
const _a = getPolymorphicProps('input', props), { Element, name, value, autoTab, onChange: onChangeProps, id: idProps = '', validations = [] } = _a, restProps = __rest(_a, ["Element", "name", "value", "autoTab", "onChange", "id", "validations"]);
const id = useId() + idProps;
const { register, getFieldValue, getFieldState } = useFormContext();
const { getItems } = useCollection();
const onChange = (e) => {
getItems().forEach(instance => {
var _a;
if (!(instance instanceof HTMLInputElement) && !(instance instanceof HTMLSelectElement))
return;
if (instance.name !== (autoTab === null || autoTab === void 0 ? void 0 : autoTab.to) || !((_a = getFieldState(name)) === null || _a === void 0 ? void 0 : _a.isValid))
return;
if (e.target instanceof HTMLInputElement &&
getFieldValue(name).length === e.target.maxLength) {
instance.focus();
}
if (e.target instanceof HTMLSelectElement) {
instance.focus();
}
});
onChangeProps === null || onChangeProps === void 0 ? void 0 : onChangeProps(e);
};
return (_jsx(CollectionItem, { children: _jsx(Element, Object.assign({}, register(name, {
value,
validations,
onChange,
}), restProps, { [FIELD_ATTR]: '', id: id })) }));
};
const Label = (props) => {
const { children, htmlFor } = props, restProps = __rest(props, ["children", "htmlFor"]);
const ref = useRef(null);
const { getItems } = useCollection();
useEffect(() => {
getItems().forEach(instance => {
if (!(instance instanceof HTMLInputElement) && !(instance instanceof HTMLSelectElement))
return;
if (!ref.current)
return;
if (instance.name === htmlFor) {
ref.current.htmlFor = instance.id;
}
});
});
return (_jsx("label", Object.assign({ ref: ref }, restProps, { children: children })));
};
const FieldMessage = (props) => {
const _a = getPolymorphicProps('div', props), { Element, type, children, name } = _a, restProps = __rest(_a, ["Element", "type", "children", "name"]);
const { errors } = useFormContext();
if (errors[name] && (!type || errors[name].type === type)) {
return _jsx(Element, Object.assign({}, restProps, { children: children }));
}
return null;
};
const PriorityMessage = (props) => {
const { children, priority } = props;
const { errors } = useFormContext();
const errorField = priority.find(name => errors[name]);
return errorField ? (_jsx(_Fragment, { children: Children.map(children, child => {
if (!isValidElement(child))
return null;
return child.props.name === errorField ? child : null;
}) })) : null;
};
Form.Field = Field;
Form.Label = Label;
Form.FieldMessage = FieldMessage;
Form.PriorityMessage = PriorityMessage;
export default Form;