Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .eslintignore

This file was deleted.

1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v20.19.6
54 changes: 51 additions & 3 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import js from '@eslint/js'
import tsPlugin from '@typescript-eslint/eslint-plugin'
import tsParser from '@typescript-eslint/parser'
import reactPlugin from 'eslint-plugin-react'
import reactHooksPlugin from 'eslint-plugin-react-hooks'
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y'
import importPlugin from 'eslint-plugin-import'

export default [
js.configs.recommended,
Expand All @@ -11,14 +15,36 @@ export default [
parserOptions: {
project: './tsconfig.json',
ecmaVersion: 'latest',
sourceType: 'module'
sourceType: 'module',
ecmaFeatures: {
jsx: true
}
},
globals: {
document: 'readonly'
}
},
plugins: {
'@typescript-eslint': tsPlugin
'@typescript-eslint': tsPlugin,
react: reactPlugin,
'react-hooks': reactHooksPlugin,
'jsx-a11y': jsxA11yPlugin,
import: importPlugin
},
settings: {
react: {
version: 'detect'
},
'import/resolver': {
typescript: {
alwaysTryTypes: true,
project: './tsconfig.json'
},
node: true
},
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx']
}
},
rules: {
...tsPlugin.configs.recommended.rules,
Expand All @@ -28,7 +54,29 @@ export default [
],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off'
'@typescript-eslint/no-explicit-any': 'off',
// React rules
'react/react-in-jsx-scope': 'off',
'react/prop-types': 'off',
// React Hooks rules
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
// Import rules
'import/order': [
'warn',
{
groups: [
'builtin',
'external',
'internal',
'parent',
'sibling',
'index'
],
'newlines-between': 'never'
}
],
'import/no-duplicates': 'warn'
}
},
{
Expand Down
24 changes: 13 additions & 11 deletions package-scripts.js → package-scripts.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import npsUtils from 'nps-utils'
const npsUtils = require('nps-utils')

const { series, rimraf, concurrent } = npsUtils
const { series, rimraf } = npsUtils

export default {
const nps = (script) => `nps -c ./package-scripts.cjs ${script}`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this in the documentation of nps-utils nor in main final-form repository.

I think it would be a good idea to have consistency for tooling across final-form repositories.


module.exports = {
scripts: {
test: {
default: 'jest --coverage',
Expand All @@ -17,14 +19,14 @@ export default {
},
build: {
description: 'delete the dist directory and run all builds',
default: series(rimraf('dist'), 'nps build.rollup'),
default: series(rimraf('dist'), nps('build.rollup')),
rollup: {
description: 'Run all rollup builds sequentially',
default: series.nps(
'build.rollup.es',
'build.rollup.cjs',
'build.rollup.umd.main',
'build.rollup.umd.min'
default: series(
nps('build.rollup.es'),
nps('build.rollup.cjs'),
nps('build.rollup.umd.main'),
nps('build.rollup.umd.min')
),
es: {
description: 'run the build with rollup (uses rollup.config.js)',
Expand All @@ -47,7 +49,7 @@ export default {
}
}
},
andTest: series.nps('build', 'test.size')
andTest: series(nps('build'), nps('test.size'))
},
docs: {
description: 'Generates table of contents in README',
Expand All @@ -65,7 +67,7 @@ export default {
validate: {
description:
'This runs several scripts to make sure things look good before committing or on clean install',
default: series.nps('lint', 'build.andTest', 'test')
default: series(nps('lint'), nps('build.andTest'), nps('test'))
},
clean: {
description: 'delete the dist directory',
Expand Down
29 changes: 17 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@
"name": "final-form-focus",
"version": "2.0.0",
"description": "Decorator that will attempt to apply focus to the first field with an error upon an attempted form submission in 🏁 Final Form",
"main": "dist/final-form-focus.cjs.js",
"main": "dist/final-form-focus.cjs",
Copy link
Copy Markdown

@iamdey iamdey Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get why it's necessary

(not consistent with other libs)

"jsnext:main": "dist/final-form-focus.es.js",
"module": "dist/final-form-focus.es.js",
"type": "module",
"exports": {
".": {
"import": "./dist/final-form-focus.es.js",
"require": "./dist/final-form-focus.cjs"
}
},
"files": [
"dist"
],
"scripts": {
"start": "nps",
"test": "nps test",
"start": "nps -c ./package-scripts.cjs",
"test": "nps -c ./package-scripts.cjs test",
"precommit": "lint-staged && npm start validate"
},
"author": "Erik Rasmussen <rasmussenerik@gmail.com> (http://github.com/erikras)",
Expand Down Expand Up @@ -41,21 +47,24 @@
"@babel/preset-env": "^7.27.2",
"@babel/preset-typescript": "^7.27.1",
"@eslint/js": "^9.27.0",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-replace": "^6.0.2",
"@rollup/plugin-terser": "^0.4.4",
"@types/jest": "^29.5.14",
"@types/node": "^22.15.27",
"@typescript-eslint/eslint-plugin": "^8.33.0",
"@typescript-eslint/parser": "^8.33.0",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^29.7.0",
"bundlesize": "^0.18.2",
"doctoc": "^2.2.1",
"eslint": "^9.27.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-babel": "^5.3.1",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"final-form": "^5.0.0",
"husky": "^9.1.7",
"jest": "^29.7.0",
Expand All @@ -66,10 +75,6 @@
"prettier": "^3.5.3",
"prettier-eslint-cli": "^8.0.1",
"rollup": "^4.41.1",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-uglify": "^6.0.4",
"typescript": "^5.8.3"
},
Expand All @@ -92,7 +97,7 @@
"threshold": "1.2kB"
},
{
"path": "dist/final-form-focus.cjs.js",
"path": "dist/final-form-focus.cjs",
"threshold": "1.2kB"
}
]
Expand Down
13 changes: 7 additions & 6 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import resolve from 'rollup-plugin-node-resolve'
import babel from 'rollup-plugin-babel'
import commonjs from 'rollup-plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import babel from '@rollup/plugin-babel'
import commonjs from '@rollup/plugin-commonjs'
import { uglify } from 'rollup-plugin-uglify'
import replace from 'rollup-plugin-replace'
import replace from '@rollup/plugin-replace'
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
const pkg = require('./package.json')
Expand All @@ -27,7 +27,7 @@ if (es) {
output = { file: `dist/final-form-focus.umd.js`, format: 'umd' }
}
} else if (cjs) {
output = { file: `dist/final-form-focus.cjs.js`, format: 'cjs' }
output = { file: `dist/final-form-focus.cjs`, format: 'cjs' }
} else if (format) {
throw new Error(`invalid format specified: "${format}".`)
} else {
Expand Down Expand Up @@ -58,7 +58,7 @@ export default {
babel({
exclude: 'node_modules/**',
babelrc: false,
runtimeHelpers: true,
babelHelpers: 'runtime',
extensions: ['.js', '.jsx', '.ts', '.tsx'],
presets: [
[
Expand Down Expand Up @@ -95,6 +95,7 @@ export default {
}),
umd
? replace({
preventAssignment: true,
'process.env.NODE_ENV': JSON.stringify(
minify ? 'production' : 'development'
)
Expand Down
2 changes: 1 addition & 1 deletion src/decorator.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import createDecorator from './decorator'
import { createForm } from 'final-form'
import createDecorator from './decorator'
import { FocusableInput } from './types'

const sleep = (ms: number): Promise<void> => new Promise(resolve => setTimeout(resolve, ms))
Expand Down
2 changes: 1 addition & 1 deletion src/findInput.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FindInput, FocusableInput } from './types';
import { getIn } from 'final-form';
import { FindInput, FocusableInput } from './types';

/**
* Finds the input by looking if the name attribute path is existing in the errors object
Expand Down
Loading