├── .babelrc ├── .eslintignore ├── .eslintrc ├── .flowconfig ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── FUNDING.yml ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .prettierrc ├── .travis.yml ├── LICENSE ├── README.md ├── package-lock.json ├── package-scripts.js ├── package.json ├── rollup.config.js └── src ├── index.js ├── index.js.flow ├── setFieldTouched.js └── setFieldTouched.test.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "node": "8" 8 | } 9 | } 10 | ], 11 | "@babel/preset-flow" 12 | ], 13 | "plugins": [ 14 | "@babel/plugin-transform-flow-strip-types", 15 | "@babel/plugin-syntax-dynamic-import", 16 | "@babel/plugin-syntax-import-meta", 17 | "@babel/plugin-proposal-class-properties", 18 | "@babel/plugin-proposal-json-strings", 19 | [ 20 | "@babel/plugin-proposal-decorators", 21 | { 22 | "legacy": true 23 | } 24 | ], 25 | "@babel/plugin-proposal-function-sent", 26 | "@babel/plugin-proposal-export-namespace-from", 27 | "@babel/plugin-proposal-numeric-separator", 28 | "@babel/plugin-proposal-throw-expressions" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | dist 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "react-app", 3 | "rules": { 4 | "jsx-a11y/href-no-hash": 0 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | dist/.* 3 | 4 | [include] 5 | 6 | [libs] 7 | 8 | [options] 9 | esproposal.decorators=ignore 10 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of 9 | experience, nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or reject 41 | comments, commits, code, wiki edits, issues, and other contributions that are 42 | not aligned to this Code of Conduct, or to ban temporarily or permanently any 43 | contributor for other behaviors that they deem inappropriate, threatening, 44 | offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at rasmussenerik@gmail.com. The project 59 | team will review and investigate all complaints, and will respond in a way that 60 | it deems appropriate to the circumstances. The project team is obligated to 61 | maintain confidentiality with regard to the reporter of an incident. Further 62 | details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 71 | version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for your interest in contributing to 🏁 Final Form Set Field Touched! Please 4 | take a moment to review this document **before submitting a pull request**. 5 | 6 | We are open to, and grateful for, any contributions made by the community. 7 | 8 | ## Reporting issues and asking questions 9 | 10 | Before opening an issue, please search the 11 | [issue tracker](https://github.com/final-form/final-form-set-field-touched/issues) 12 | to make sure your issue hasn’t already been reported. 13 | 14 | **We use the issue tracker to keep track of bugs and improvements** to 🏁 Final 15 | Form Set Field Touched itself, its examples, and the documentation. We encourage 16 | you to open issues to discuss improvements, architecture, internal 17 | implementation, etc. If a topic has been discussed before, we will ask you to 18 | join the previous discussion. 19 | 20 | For support or usage questions, please search and ask on 21 | [StackOverflow with a `final-form-set-field-touched` tag](https://stackoverflow.com/questions/tagged/final-form-set-field-touched). 22 | We ask you to do this because StackOverflow has a much better job at keeping 23 | popular questions visible. Unfortunately good answers get lost and outdated on 24 | GitHub. 25 | 26 | **If you already asked at StackOverflow and still got no answers, post an issue 27 | with the question link, so we can either answer it or evolve into a bug/feature 28 | request.** 29 | 30 | ## Sending a pull request 31 | 32 | **Please ask first before starting work on any significant new features.** 33 | 34 | It's never a fun experience to have your pull request declined after investing a 35 | lot of time and effort into a new feature. To avoid this from happening, we 36 | request that contributors create 37 | [an issue](https://github.com/final-form/final-form-set-field-touched/issues) to 38 | first discuss any significant new features. 39 | 40 | Please try to keep your pull request focused in scope and avoid including 41 | unrelated commits. 42 | 43 | After you have submitted your pull request, we’ll try to get back to you as soon 44 | as possible. We may suggest some changes or improvements. 45 | 46 | Please format the code before submitting your pull request by running: 47 | 48 | ``` 49 | npm run precommit 50 | ``` 51 | 52 | ## Coding standards 53 | 54 | Our code formatting rules are defined in 55 | [.eslintrc](https://github.com/final-form/final-form-set-field-touched/blob/master/.eslintrc). 56 | You can check your code against these standards by running: 57 | 58 | ```sh 59 | npm start lint 60 | ``` 61 | 62 | To automatically fix any style violations in your code, you can run: 63 | 64 | ```sh 65 | npm run precommit 66 | ``` 67 | 68 | ## Running tests 69 | 70 | You can run the test suite using the following commands: 71 | 72 | ```sh 73 | npm test 74 | ``` 75 | 76 | Please ensure that the tests are passing when submitting a pull request. If 77 | you're adding new features to 🏁 Final Form Set Field Touched, please include 78 | tests. 79 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: erikras 4 | patreon: erikras 5 | open_collective: final-form 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with a single custom sponsorship URL 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ### Are you submitting a **bug report** or a **feature request**? 8 | 9 | 10 | 11 | ### What is the current behavior? 12 | 13 | 14 | 15 | ### What is the expected behavior? 16 | 17 | ### Sandbox Link 18 | 19 | 20 | 21 | ### What's your environment? 22 | 23 | 24 | 25 | ### Other information 26 | 27 | 28 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | *.iml 3 | .nyc_output 4 | coverage 5 | flow-coverage 6 | node_modules 7 | dist 8 | lib 9 | es 10 | npm-debug.log 11 | .DS_Store 12 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | semi: false 2 | singleQuote: true 3 | trailingComma: none 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | cache: 4 | directories: 5 | - node_modules 6 | notifications: 7 | email: false 8 | node_js: 9 | - '8' 10 | script: 11 | - npm start validate 12 | after_success: 13 | - npx codecov 14 | - npm install --global semantic-release 15 | # - semantic-release pre && npm publish && semantic-release post 16 | branches: 17 | only: 18 | - master -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Erik Rasmussen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🏁 Final Form Set Field Touched 2 | 3 | [![NPM Version](https://img.shields.io/npm/v/final-form-set-field-touched.svg?style=flat)](https://www.npmjs.com/package/final-form-set-field-touched) 4 | [![NPM Downloads](https://img.shields.io/npm/dm/final-form-set-field-touched.svg?style=flat)](https://www.npmjs.com/package/final-form-set-field-touched) 5 | [![Build Status](https://travis-ci.org/final-form/final-form-set-field-touched.svg?branch=master)](https://travis-ci.org/final-form/final-form-set-field-touched) 6 | [![codecov.io](https://codecov.io/gh/final-form/final-form-set-field-touched/branch/master/graph/badge.svg)](https://codecov.io/gh/final-form/final-form-set-field-touched) 7 | [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier) 8 | 9 | Mutator for setting a field as "touched" in [🏁 Final Form](https://github.com/final-form/final-form). 10 | 11 | --- 12 | 13 | ## Installation 14 | 15 | ```bash 16 | npm install --save final-form-set-field-touched 17 | ``` 18 | 19 | or 20 | 21 | ```bash 22 | yarn add final-form-set-field-touched 23 | ``` 24 | 25 | ## Usage 26 | 27 | ```js 28 | import { createForm } from 'final-form' 29 | import setFieldTouched from 'final-form-set-field-touched' 30 | 31 | // Create Form 32 | const form = createForm({ 33 | mutators: { setFieldTouched }, 34 | onSubmit 35 | }) 36 | 37 | form.mutators.setFieldTouched('firstName', true) 38 | 39 | form.registerField( 40 | 'firstName', 41 | fieldState => { 42 | const { touched } = fieldState // true 43 | }, 44 | { 45 | // ...other subscription items 46 | touched: true 47 | } 48 | ) 49 | ``` 50 | 51 | ## Mutator 52 | 53 | ### `form.mutators.setFieldTouched(name: string, touched: boolean) => void` 54 | 55 | Sets the specified field's `touched` flag to the boolean value provided. 56 | -------------------------------------------------------------------------------- /package-scripts.js: -------------------------------------------------------------------------------- 1 | const npsUtils = require('nps-utils') 2 | 3 | const series = npsUtils.series 4 | const concurrent = npsUtils.concurrent 5 | const rimraf = npsUtils.rimraf 6 | const crossEnv = npsUtils.crossEnv 7 | 8 | module.exports = { 9 | scripts: { 10 | test: { 11 | default: crossEnv('NODE_ENV=test jest --coverage'), 12 | update: crossEnv('NODE_ENV=test jest --coverage --updateSnapshot'), 13 | watch: crossEnv('NODE_ENV=test jest --watch'), 14 | codeCov: crossEnv( 15 | 'cat ./coverage/lcov.info | ./node_modules/codecov.io/bin/codecov.io.js' 16 | ), 17 | size: { 18 | description: 'check the size of the bundle', 19 | script: 'bundlesize' 20 | } 21 | }, 22 | build: { 23 | description: 'delete the dist directory and run all builds', 24 | default: series( 25 | rimraf('dist'), 26 | concurrent.nps( 27 | 'build.es', 28 | 'build.cjs', 29 | 'build.umd.main', 30 | 'build.umd.min', 31 | 'copyTypes' 32 | ) 33 | ), 34 | es: { 35 | description: 'run the build with rollup (uses rollup.config.js)', 36 | script: 'rollup --config --environment FORMAT:es' 37 | }, 38 | cjs: { 39 | description: 'run rollup build with CommonJS format', 40 | script: 'rollup --config --environment FORMAT:cjs' 41 | }, 42 | umd: { 43 | min: { 44 | description: 'run the rollup build with sourcemaps', 45 | script: 'rollup --config --sourcemap --environment MINIFY,FORMAT:umd' 46 | }, 47 | main: { 48 | description: 'builds the cjs and umd files', 49 | script: 'rollup --config --sourcemap --environment FORMAT:umd' 50 | } 51 | }, 52 | andTest: series.nps('build', 'test.size') 53 | }, 54 | docs: { 55 | description: 'Generates table of contents in README', 56 | script: 'doctoc README.md' 57 | }, 58 | copyTypes: npsUtils.copy('src/*.js.flow dist'), 59 | lint: { 60 | description: 'lint the entire project', 61 | script: 'eslint .' 62 | }, 63 | flow: { 64 | description: 'flow check the entire project', 65 | script: 'flow check' 66 | }, 67 | validate: { 68 | description: 69 | 'This runs several scripts to make sure things look good before committing or on clean install', 70 | default: concurrent.nps('lint', 'flow', 'build.andTest', 'test') 71 | } 72 | }, 73 | options: { 74 | silent: false 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "final-form-set-field-touched", 3 | "version": "1.0.1", 4 | "description": "Mutator for setting a field as \"touched\" in 🏁 Final Form", 5 | "main": "dist/final-form-set-field-touched.cjs.js", 6 | "jsnext:main": "dist/final-form-set-field-touched.es.js", 7 | "module": "dist/final-form-set-field-touched.es.js", 8 | "files": [ 9 | "dist" 10 | ], 11 | "scripts": { 12 | "start": "nps", 13 | "test": "nps test", 14 | "precommit": "lint-staged && npm start validate" 15 | }, 16 | "author": "Erik Rasmussen (http://github.com/erikras)", 17 | "license": "MIT", 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/final-form/final-form-set-field-touched.git" 21 | }, 22 | "bugs": { 23 | "url": "https://github.com/final-form/final-form-set-field-touched/issues" 24 | }, 25 | "homepage": "https://github.com/final-form/final-form-set-field-touched#readme", 26 | "devDependencies": { 27 | "@babel/core": "^7.0.0", 28 | "@babel/plugin-external-helpers": "^7.0.0", 29 | "@babel/plugin-proposal-class-properties": "^7.0.0", 30 | "@babel/plugin-proposal-decorators": "^7.0.0", 31 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 32 | "@babel/plugin-proposal-function-sent": "^7.0.0", 33 | "@babel/plugin-proposal-json-strings": "^7.0.0", 34 | "@babel/plugin-proposal-numeric-separator": "^7.0.0", 35 | "@babel/plugin-proposal-throw-expressions": "^7.0.0", 36 | "@babel/plugin-syntax-dynamic-import": "^7.0.0", 37 | "@babel/plugin-syntax-import-meta": "^7.0.0", 38 | "@babel/plugin-transform-flow-strip-types": "^7.2.3", 39 | "@babel/plugin-transform-runtime": "^7.2.0", 40 | "@babel/preset-env": "^7.0.0", 41 | "@babel/preset-flow": "^7.0.0", 42 | "babel-core": "^7.0.0-bridge.0", 43 | "babel-eslint": "^10.0.1", 44 | "babel-jest": "^23.4.2", 45 | "bundlesize": "^0.17.1", 46 | "doctoc": "^1.4.0", 47 | "eslint": "^5.13.0", 48 | "eslint-config-react-app": "^3.0.6", 49 | "eslint-plugin-babel": "^5.3.0", 50 | "eslint-plugin-flowtype": "^3.2.1", 51 | "eslint-plugin-import": "^2.16.0", 52 | "eslint-plugin-jsx-a11y": "^6.2.1", 53 | "eslint-plugin-react": "^7.12.4", 54 | "final-form": "^4.11.1", 55 | "flow": "^0.2.3", 56 | "flow-bin": "^0.92.1", 57 | "glow": "^1.2.2", 58 | "husky": "^1.3.1", 59 | "jest": "^24.1.0", 60 | "lint-staged": "^8.1.3", 61 | "nps": "^5.9.3", 62 | "nps-utils": "^1.7.0", 63 | "prettier": "^1.16.4", 64 | "prettier-eslint-cli": "^4.7.1", 65 | "rollup": "^1.1.2", 66 | "rollup-plugin-babel": "^4.3.2", 67 | "rollup-plugin-commonjs": "^9.2.0", 68 | "rollup-plugin-flow": "^1.1.1", 69 | "rollup-plugin-node-resolve": "^4.0.0", 70 | "rollup-plugin-replace": "^2.1.0", 71 | "rollup-plugin-uglify": "^6.0.2" 72 | }, 73 | "peerDependencies": { 74 | "final-form": ">=1.2.0" 75 | }, 76 | "lint-staged": { 77 | "*.{js,json,md,css}": [ 78 | "prettier --write", 79 | "git add" 80 | ] 81 | }, 82 | "bundlesize": [ 83 | { 84 | "path": "dist/final-form-set-field-touched.umd.min.js", 85 | "threshold": "580B" 86 | }, 87 | { 88 | "path": "dist/final-form-set-field-touched.es.js", 89 | "threshold": "640B" 90 | }, 91 | { 92 | "path": "dist/final-form-set-field-touched.cjs.js", 93 | "threshold": "650B" 94 | } 95 | ] 96 | } 97 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from 'rollup-plugin-node-resolve' 2 | import babel from 'rollup-plugin-babel' 3 | import flow from 'rollup-plugin-flow' 4 | import commonjs from 'rollup-plugin-commonjs' 5 | import { uglify } from 'rollup-plugin-uglify' 6 | import replace from 'rollup-plugin-replace' 7 | import pkg from './package.json' 8 | 9 | const makeExternalPredicate = externalArr => { 10 | if (externalArr.length === 0) { 11 | return () => false 12 | } 13 | const pattern = new RegExp(`^(${externalArr.join('|')})($|/)`) 14 | return id => pattern.test(id) 15 | } 16 | 17 | const minify = process.env.MINIFY 18 | const format = process.env.FORMAT 19 | const es = format === 'es' 20 | const umd = format === 'umd' 21 | const cjs = format === 'cjs' 22 | 23 | let output 24 | 25 | if (es) { 26 | output = { file: `dist/final-form-set-field-touched.es.js`, format: 'es' } 27 | } else if (umd) { 28 | if (minify) { 29 | output = { 30 | file: `dist/final-form-set-field-touched.umd.min.js`, 31 | format: 'umd' 32 | } 33 | } else { 34 | output = { file: `dist/final-form-set-field-touched.umd.js`, format: 'umd' } 35 | } 36 | } else if (cjs) { 37 | output = { file: `dist/final-form-set-field-touched.cjs.js`, format: 'cjs' } 38 | } else if (format) { 39 | throw new Error(`invalid format specified: "${format}".`) 40 | } else { 41 | throw new Error('no format specified. --environment FORMAT:xxx') 42 | } 43 | 44 | export default { 45 | input: 'src/index.js', 46 | output: Object.assign( 47 | { 48 | name: 'final-form-set-field-touched', 49 | exports: 'named' 50 | }, 51 | output 52 | ), 53 | external: makeExternalPredicate( 54 | umd 55 | ? Object.keys(pkg.peerDependencies || {}) 56 | : [ 57 | ...Object.keys(pkg.dependencies || {}), 58 | ...Object.keys(pkg.peerDependencies || {}) 59 | ] 60 | ), 61 | plugins: [ 62 | resolve({ jsnext: true, main: true }), 63 | flow(), 64 | commonjs({ include: 'node_modules/**' }), 65 | babel({ 66 | exclude: 'node_modules/**', 67 | babelrc: false, 68 | runtimeHelpers: true, 69 | presets: [ 70 | [ 71 | '@babel/preset-env', 72 | { 73 | modules: false, 74 | loose: true 75 | } 76 | ], 77 | '@babel/preset-flow' 78 | ], 79 | plugins: [ 80 | ['@babel/plugin-transform-runtime', { useESModules: !cjs }], 81 | '@babel/plugin-transform-flow-strip-types', 82 | '@babel/plugin-syntax-dynamic-import', 83 | '@babel/plugin-syntax-import-meta', 84 | '@babel/plugin-proposal-class-properties', 85 | '@babel/plugin-proposal-json-strings', 86 | [ 87 | '@babel/plugin-proposal-decorators', 88 | { 89 | legacy: true 90 | } 91 | ], 92 | '@babel/plugin-proposal-function-sent', 93 | '@babel/plugin-proposal-export-namespace-from', 94 | '@babel/plugin-proposal-numeric-separator', 95 | '@babel/plugin-proposal-throw-expressions' 96 | ] 97 | }), 98 | umd 99 | ? replace({ 100 | 'process.env.NODE_ENV': JSON.stringify( 101 | minify ? 'production' : 'development' 102 | ) 103 | }) 104 | : null, 105 | minify ? uglify() : null 106 | ].filter(Boolean) 107 | } 108 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | export { default } from './setFieldTouched' 3 | -------------------------------------------------------------------------------- /src/index.js.flow: -------------------------------------------------------------------------------- 1 | // @flow 2 | import type { Mutator } from 'final-form' 3 | 4 | declare export default Mutator 5 | -------------------------------------------------------------------------------- /src/setFieldTouched.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import type { MutableState, Mutator } from 'final-form' 3 | 4 | const setFieldTouched: Mutator = (args: any[], state: MutableState) => { 5 | const [name, touched] = args 6 | const field = state.fields[name] 7 | if (field) { 8 | field.touched = !!touched 9 | } 10 | } 11 | 12 | export default setFieldTouched 13 | -------------------------------------------------------------------------------- /src/setFieldTouched.test.js: -------------------------------------------------------------------------------- 1 | import setFieldTouched from './setFieldTouched' 2 | 3 | describe('setFieldTouched', () => { 4 | it('should not call any tools', () => { 5 | const setIn = jest.fn() 6 | const getIn = jest.fn() 7 | const changeValue = jest.fn() 8 | const shallowEqual = jest.fn() 9 | const state = { fields: { foo: { data: {} } } } 10 | const result = setFieldTouched(['foo', { cool: true }], state, { 11 | getIn, 12 | setIn, 13 | changeValue, 14 | shallowEqual 15 | }) 16 | expect(result).toBeUndefined() 17 | expect(getIn).not.toHaveBeenCalled() 18 | expect(setIn).not.toHaveBeenCalled() 19 | expect(changeValue).not.toHaveBeenCalled() 20 | expect(shallowEqual).not.toHaveBeenCalled() 21 | }) 22 | 23 | it('should mark field as touched', () => { 24 | const foo = { touched: false } 25 | const fields = { foo } 26 | const state = { fields } 27 | setFieldTouched(['foo', true], state, {}) 28 | expect(state.fields).toBe(fields) 29 | expect(state.fields.foo).toBe(foo) 30 | expect(state.fields.foo.touched).toBe(true) 31 | }) 32 | 33 | it('should mark field as untouched', () => { 34 | const foo = { touched: true } 35 | const fields = { foo } 36 | const state = { fields } 37 | setFieldTouched(['foo', false], state, {}) 38 | expect(state.fields).toBe(fields) 39 | expect(state.fields.foo).toBe(foo) 40 | expect(state.fields.foo.touched).toBe(false) 41 | }) 42 | 43 | it('should do nothing if field is not found', () => { 44 | const foo = {} 45 | const fields = { foo } 46 | const state = { fields } 47 | setFieldTouched(['bar', true], state, {}) 48 | expect(state.fields).toBe(fields) 49 | expect(state.fields.foo).toBe(foo) 50 | }) 51 | }) 52 | --------------------------------------------------------------------------------