{"_id":"@awardit/formaggio","_rev":"2-fdd1d479609edf739089ec379ab6c349","name":"@awardit/formaggio","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@awardit/formaggio","version":"1.0.0","description":"The cheesy form library","keywords":["form","react"],"authors":["Martin Wernstål <m4rw3r@gmail.com>","Peter Asplund <peterasplund0@gmail.com>"],"license":"MIT","repository":{"type":"git","url":"git+ssh://git@github.com/awardit/formaggio.git"},"module":"dist/esm/index.js","main":"dist/cjs/index.js","sideEffects":false,"scripts":{"build":"npm-run-all build:*","build:rollup":"rollup -c rollup.config.js","build:flow":"cp build/stub/flow.js dist/esm/index.js.flow && cp build/stub/flow.js dist/cjs/index.js.flow","coverage":"nyc --reporter=html ava --verbose","clean":"rm -rf dist","distclean":"rm -rf package-lock.json node_modules dist","flow":"flow check","prepack":"npm run clean && npm run test && npm run build","test":"npm-run-all test:*","test:flow":"flow status","test:ava":"ava --verbose","test:xo":"xo","watch":"nodemon -w src -w test --exec \"npm run -q test || true\""},"dependencies":{},"devDependencies":{"@ava/babel":"1.0.0","@awardit/eslint-config-xo":"0.3.0","@babel/core":"7.8.4","@babel/plugin-proposal-nullish-coalescing-operator":"7.8.3","@babel/plugin-syntax-flow":"7.8.3","@babel/plugin-transform-flow-strip-types":"7.8.3","@babel/preset-env":"7.8.4","@babel/preset-react":"7.8.3","@babel/register":"7.8.3","@testing-library/react":"9.4.0","ava":"3.2.0","cross-env":"7.0.0","flow-bin":"0.117.0","jsdom":"16.1.0","jsdom-global":"3.0.2","ninos":"3.0.0","nodemon":"2.0.2","npm-run-all":"4.1.5","nyc":"15.0.0","react":"16.12.0","react-dom":"16.12.0","rollup":"1.31.0","rollup-plugin-babel":"4.3.3","xo":"0.25.3"},"peerDependency":{"react":">=16.8.0"},"publishConfig":{"access":"public"},"xo":{"envs":["node","browser"],"extends":["@awardit/eslint-config-xo"],"ignores":["dist","rollup.config.js"],"overrides":[{"files":"test/*.js","rules":{"ava/use-test":"off","flowtype/require-parameter-type":"off","flowtype/require-return-type":"off","flowtype/no-unused-expressions":"off","no-unused-expressions":"off","max-len":["warn",140,{"ignoreStrings":true}]}}]},"gitHead":"28b550f7238476ca95733ecd34da3af0472a49b2","bugs":{"url":"https://github.com/awardit/formaggio/issues"},"homepage":"https://github.com/awardit/formaggio#readme","_id":"@awardit/formaggio@1.0.0","_nodeVersion":"13.7.0","_npmVersion":"6.13.6","dist":{"integrity":"sha512-gQwBAcL4WZUu7MO5y+vdHHVJA64CubSUSK1Kln+AGfY/pr51jnuXPWS/UOmXV6TJBLdyiE/9wFWNAyXAiWR2vg==","shasum":"0b274b7f25942b1628b4ad88eb80243c16b62b56","tarball":"https://registry.npmjs.org/@awardit/formaggio/-/formaggio-1.0.0.tgz","fileCount":42,"unpackedSize":105506,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeOtOcCRA9TVsSAnZWagAA+5YP/1tQb9DjhuK22HhK56Tb\nt9wSAN5/wBrssbf/9BAK2uvAtTSXvRnxgbSbeQGUNvMJM6ZFRevxnrkcBySN\ncfQO/mfQFtYxKDBkMMReCBpENVpOTtmWZKGNm17Dw0d4I0PAbLoaQz/SLjW3\ncRyn68ruzRRxNBWryvwt+X9ond3svttkSUIiCxkmKxt/24UDSMwOh174Bacj\n1WCqDVIp6dtpZys1LyTHmgRDqQQATTJwWPLgiDEx/vAWK6VEYDasuDXxp5XA\nh3Ayqtw6xyvMz2H9QR0PZNtHifKoAIKl2tNWk2j/KwOkWGgw+Bu/8ejS8F6q\nb/hb2hcn/m8rHteeBc2a/PJgUTm5iIFaLmxXRUe3RR3nY74rN8cT7XXVIUKD\ngEZPtUWEkxD/PXsH9drGkjkUlgsH7pEqjpJ3mdtoMjmGd32NnJcMnmh3lYb9\nekUaQ2+qsDC0FkzesXVfxvtbMi/hFFdiWGYXRNOCrCSfJbnKAxY+K1SgmAEr\n+aHCjjwGIDwF9dB3mUc0SJJ+3zdK0IkmNU6dLZQRDxNh9wYYfiPQ/LluwAMo\nl8NI2+AsAA8rN5IlY9y7aprK3ydx86w/VmlRt1x9K33/9MjZkGB5ztgsX/hf\nv9C2w675Z0GAI7HPHyNeLhkPjj0x/aKv8JmuBYo4ZsX4MH+YMPcF4xiVQPad\ny+Ov\r\n=oIGG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD8ToIrWiKyU1zzcPPERFp8MLGq6TbQTgX7pFSODd3BNQIhAKjuGDJHVU7vhGvEjqWf+vHk18lkHzoLyagI2KX0Lgl7"}]},"maintainers":[{"name":"poggen","email":"oscar@crossroads.se"},{"name":"peterasplund","email":"peterasplund0@gmail.com"},{"name":"lokecarlsson","email":"carlssonloke@gmail.com"},{"name":"m4rw3r","email":"m4rw3r@gmail.com"}],"_npmUser":{"name":"m4rw3r","email":"m4rw3r@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/formaggio_1.0.0_1580913564004_0.347698922564861"},"_hasShrinkwrap":false}},"time":{"created":"2020-02-05T14:39:23.761Z","1.0.0":"2020-02-05T14:39:24.141Z","modified":"2022-04-04T16:49:23.285Z"},"maintainers":[{"email":"m4rw3r@gmail.com","name":"m4rw3r"},{"email":"carlssonloke@gmail.com","name":"lokecarlsson"},{"email":"oscar@crossroads.se","name":"poggen"}],"description":"The cheesy form library","homepage":"https://github.com/awardit/formaggio#readme","keywords":["form","react"],"repository":{"type":"git","url":"git+ssh://git@github.com/awardit/formaggio.git"},"bugs":{"url":"https://github.com/awardit/formaggio/issues"},"license":"MIT","readme":"![Formaggio Logo](https://raw.githubusercontent.com/awardit/formaggio/master/doc/logo_primary.svg?raw=true&sanitize=true)\n<p align=\"center\">The cheesy form library 🧀</p>\n\n[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@awardit/formaggio.svg)](https://bundlephobia.com/result?p=@awardit/formaggio)\n[![Dependencies](https://img.shields.io/david/awardit/formaggio.svg)](https://www.npmjs.com/package/@awardit/formaggio)\n[![Build Status](https://travis-ci.org/awardit/formaggio.svg?branch=master)](https://travis-ci.org/awardit/formaggio)\n[![Codecov](https://img.shields.io/codecov/c/gh/awardit/formaggio)](https://codecov.io/gh/awardit/formaggio)\n![License](https://img.shields.io/npm/l/@awardit/formaggio)\n[![npm](https://img.shields.io/npm/v/@awardit/formaggio)](https://www.npmjs.com/package/@awardit/formaggio)\n[![Greenkeeper badge](https://badges.greenkeeper.io/awardit/formaggio.svg)](https://greenkeeper.io/)\n\n## Installation\n\n```bash\nnpm i @awardit/formaggio\n```\n\n## Forms\n\n### Example\n\n```javascript\nimport {\n  Form,\n  isEmail,\n  required,\n  rules,\n  useFormField,\n} from \"@awardit/formaggio\";\n\nconst TextInput = ({ name }) => {\n  const { dirty, errors, submitted, inputProps } = useFormField(name);\n  const className = (dirty || submitted) && errors.length ?\n    \"form__text-input form__text-input--error\" :\n    \"form__text-input\";\n\n  return <input type=\"text\" className={className} {...inputProps} />;\n};\n\nconst validateMyForm = rules([\n  required(\"name\"),\n  required(\"email\"),\n  isEmail(\"email\")\n]);\n\nconst MyForm = () => {\n  const [data, setData] = useState({});\n  const errors = validateMyForm(data);\n\n  return (\n    <Form\n      noValidate\n      name=\"my-form\"\n      value={data}\n      onChange={setData}\n      onSubmit={console.log}\n    >\n      <TextInput name=\"name\" />\n      <TextInput name=\"email\" />\n\n      <button type=\"submit\">Submit</button>\n    </Form>\n  );\n};\n```\n\n### `useFormField` hook\n\nThe library provided React Hook `useFormField` is used to provide access to the\nstate for the given field name which include:\n\n * `dirty: boolean`: True if the user has modified this field.\n * `submitted: boolean`: True if the user has tried to submit the form.\n * `errors: Array<ValidationError>`: List of errors which apply to this field.\n * `inputProps: Object`: Properties to apply to the `<input />` element.\n\nThe `inputProps` object contains `id`, `name`, `value` and an `onChange`\ncallback, the idea is to spread the properties into an `<input />`.\n\n### `Form` component\n\nThe `<Form />` component provides the form state to any nested uses of\n`useFormField`. It will wrap all its children in a `<form />` tag.\n\nProperties: \n\n * `errors?: Array<ValidationErrors>`: Any validation errors for this form.\n * `name?: string`: This string will prefix any `name` and `id` properties\n   in nested uses of `useFormField`.\n * `onChange: (FormData) => void`: Callback for when the form data\n   changes, these changes are performed immutably.\n * `onError?: (SyntheticEvent<HTMLFormElement>, Array<ValidationError>, FormData) => void`:\n   Callback fired instead of `onSubmit` if there is an error in the form when\n   the user tries to submit the form.\n * `onSubmit: (SyntheticEvent<HTMLFormElement>, FormData) => void`: Callback\n   fired with the current form data when the user submits the form.\n * `value: FormData`: The data for the form.\n\nAny properties not listed above will be propagated to the `<form />` element.\n\nTo properly handle validation and `onChange` events in nested `<input />`\nelements it is recommended to set the property `noValidate` on `<Form />`.\n\n## Validation\n\nValidation is done using functions which take a value to validate and return\na list of errors. The validation functions are created using rule-constructors\nor combinators.\n\n### Example\n\n```javascript\nimport {\n  conditional,\n  isEmail,\n  lengthGt,\n  required,\n  rules,\n} from \"@awardit/formaggio\";\n\nconst validator = rules([\n  isEmail(\"email\"),\n  required(\"firstname\"), \n  required(\"lastname\"),\n  conditional(s => s.password, lengthGt(\"password\", 6)),\n]);\n\nconst data = {\n  firstname: \"foo\",\n  lastname: \"bar\",\n  email: \"foo@bar\",\n};\n\nconst errors = validator(data);\n\nconsole.log(errors); // [{ error: \"EMAIL\", field: \"email\" }]\n```\n\n### Rules\n\nValidation rules are constructed in a declarative manner using rule constructors\nand rule combinators.\n\nA basic validator has the following type, where `T` is the type to be validated:\n\n```javascript\ntype Validator<T> = (t: T) => Array<ValidationError>;\n```\n\n### Errors\n\nErrors are objects containing an error code and a field path. The field path is\npreserved through combinators and is used to determine which field caused the\nspecific error. Additional properties are allowed but are error-specific.\n\n```javascript\ntype ValidationError = {\n  error: string,\n  field: string,\n};\n","readmeFilename":"README.md"}