Skip to content

Commit

Permalink
chore: use @atmina/linting
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian Schleemann committed Feb 20, 2024
1 parent 3409b68 commit 91c5376
Show file tree
Hide file tree
Showing 15 changed files with 1,133 additions and 556 deletions.
30 changes: 0 additions & 30 deletions .eslintrc.js

This file was deleted.

24 changes: 12 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
name: build

on:
- push
- pull_request
- push
- pull_request

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
cache: yarn
- run: yarn install
- run: yarn build
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
cache: yarn
- run: yarn install
- run: yarn build
30 changes: 15 additions & 15 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
name: Publish to NPM

on:
release:
types: [created]
release:
types: [created]

jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
cache: yarn
- run: yarn install
- run: yarn publish --access public
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
cache: yarn
- run: yarn install
- run: yarn publish --access public
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
24 changes: 12 additions & 12 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
name: test

on:
- push
- pull_request
- push
- pull_request

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
cache: yarn
- run: yarn install
- run: yarn test
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
cache: yarn
- run: yarn install
- run: yarn test
25 changes: 25 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
node_modules
build
dist
storybook-static
.next
.turbo
.yarn

package.json

# Lockfiles
package-lock.json
pnpm-lock.yaml
yarn.lock

# Generated files
generated
__generated__
*.generated*

# IDE
.idea
.vscode

.DS_Store
86 changes: 48 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ yarn add @atmina/formbuilder
`FormBuilder` exposes a single hook `useFormBuilder` which is mostly compatible with `useForm` from `react-hook-form`.
It contains an additional member, `fields`, which represents an alternative, object-oriented API on top of React Hook
Form. Each field in the form data can be accessed as a property, including nested fields. The field can be called as a
function to [register](https://react-hook-form.com/api/useform/register/) an input. It also exposes RHF functions via
function to [register](https://react-hook-form.com/api/useform/register/) an input. It also exposes RHF functions via
field-level methods, e.g. `$setValue`. These methods are prefixed with `$` to prevent potential conflicts with form
data members.

```tsx
import { useFormBuilder } from '@atmina/formbuilder';
import {useFormBuilder} from '@atmina/formbuilder';

interface Address {
state: string;
Expand All @@ -31,43 +31,51 @@ interface Address {
}

const App = () => {
const {fields, handleSubmit} = useFormBuilder<{name: string, address: Address}>();

const {fields, handleSubmit} = useFormBuilder<{
name: string;
address: Address;
}>();

const handleFormSubmit = handleSubmit((data) => {
console.log(data);
console.log(data);
});

return (
<form onSubmit={handleFormSubmit}>
<input {...fields.name()} />
<input {...fields.address.city()} />
{/* etc. */}
</form>
);


}
};
```

## Fields

You can create components that encapsulate a single (typed) field by accepting a `FormBuilder<T>` prop where `T` is
You can create components that encapsulate a single (typed) field by accepting a `FormBuilder<T>` prop where `T` is
the type of the field. We like to call this `on` or `field`, but you are free to name it however you like.

```tsx
import { FC } from "react";
import {FC} from 'react';

const TextField: FC<{on: FormBuilder<string>, label: string}> = ({on: field}) => {
return <div>
<label>
<span>{label}</span>
<input type="text" {...field()} />
</label>
<button type="button" onClick={() => field.$setValue(getRandomName())}>
Randomize
</button>
</div>
}
const TextField: FC<{on: FormBuilder<string>; label: string}> = ({
on: field,
}) => {
return (
<div>
<label>
<span>{label}</span>
<input type='text' {...field()} />
</label>
<button
type='button'
onClick={() => field.$setValue(getRandomName())}
>
Randomize
</button>
</div>
);
};
```

The field component would be used like this:
Expand All @@ -86,15 +94,17 @@ You can create components which encapsulate a group of related fields, such as a
composition, letting you piece together complex data structures and adding a lot of reusability to your forms.

```tsx
import { FC } from "react";
import {FC} from 'react';

const AddressSubform: FC<{field: FormBuilder<Address>}> = ({field}) => {
return <div>
<TextField label="State" field={field.state} />
<TextField label="City" field={field.city} />
{/* etc. */}
</div>
}
return (
<div>
<TextField label='State' field={field.state} />
<TextField label='City' field={field.city} />
{/* etc. */}
</div>
);
};
```

## Field arrays
Expand Down Expand Up @@ -133,21 +143,22 @@ In case of a form that contains fields with object unions, the `$discriminate()`
using a specific member like this:

```tsx
import { FC } from 'react';
import {FC} from 'react';

type DiscriminatedForm =
| { __typename: 'foo'; foo: string; }
| { __typename: 'bar'; bar: number; }
type DiscriminatedForm =
| {__typename: 'foo'; foo: string}
| {__typename: 'bar'; bar: number};

const DiscriminatedSubform: FC<{field: FormBuilder<DiscriminatedForm>}> = ({field}) => {
const DiscriminatedSubform: FC<{field: FormBuilder<DiscriminatedForm>}> = ({
field,
}) => {
const fooForm = field.$discriminate('__typename', 'foo');

return <input {...fooForm.foo()} />;
};
```

> [!IMPORTANT]
> `$discriminate` currently does **not** perform any runtime checks, it's strictly used for type narrowing at this time.
> [!IMPORTANT] > `$discriminate` currently does **not** perform any runtime checks, it's strictly used for type narrowing at this time.

## Compatibility with `useForm`

Expand All @@ -156,7 +167,6 @@ Currently, `useFormBuilder` is almost compatible with `useForm`. This means you
`useFormBuilder`. However, future versions of the library may see us diverging further from `useForm` in an effort to
streamline this API and increase its type-safety.


## License

MIT
7 changes: 7 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @type {import('eslint').Linter.FlatConfig[]}
*/
module.exports = [
...require('@atmina/linting/eslint/recommended'),
require('@atmina/linting/eslint/react'),
];
6 changes: 3 additions & 3 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "jsdom",
setupFilesAfterEnv: ["@testing-library/jest-dom/extend-expect"],
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
};
28 changes: 12 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
"scripts": {
"build": "rimraf lib && microbundle --jsx React.createElement src/index.ts",
"prepublishOnly": "npm test && npm run build",
"lint": "yarn lint:eslint:fix && yarn prettier:fix",
"lint:eslint": "eslint .",
"lint:eslint:fix": "eslint . --fix",
"prettier:check": "prettier --check \"src/**/*.{tsx,graphql,ts,js,css}\"",
"prettier:fix": "prettier --write \"src/**/*.{tsx,graphql,ts,js,css}\"",
"lint": "yarn run lint:fix && yarn run prettier:fix",
"lint:check": "eslint . --report-unused-disable-directives --max-warnings 0",
"lint:fix": "eslint . --fix --report-unused-disable-directives --max-warnings 0",
"prettier:check": "prettier . --check",
"prettier:fix": "prettier . --write",
"test": "jest src"
},
"repository": {
Expand All @@ -38,26 +38,21 @@
},
"homepage": "https://github.com/atmina/formbuilder#readme",
"devDependencies": {
"@atmina/linting": "^2.1.2",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.2.0",
"@testing-library/user-event": "^14.1.1",
"@types/eslint": "^8.56.2",
"@types/jest": "^27.5.0",
"@types/react": "^18.0.8",
"@types/react": "^18.1.0",
"@typescript-eslint/eslint-plugin": "^5.26.0",
"@typescript-eslint/parser": "^5.26.0",
"eslint": "^8.16.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-standard-with-typescript": "^21.0.1",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-react": "^7.30.0",
"eslint": "^8.56.0",
"expect-type": "^0.13.0",
"jest": "^28.0.3",
"jest-environment-jsdom": "^28.0.2",
"microbundle": "^0.15.0",
"prettier": "^2.7.1",
"prettier": "^3.2.5",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-hook-form": "^7.33.0",
Expand All @@ -74,5 +69,6 @@
"optional": true
}
},
"packageManager": "[email protected]+sha256.dbed5b7e10c552ba0e1a545c948d5473bc6c5a28ce22a8fd27e493e3e5eb6370"
"packageManager": "[email protected]+sha256.dbed5b7e10c552ba0e1a545c948d5473bc6c5a28ce22a8fd27e493e3e5eb6370",
"prettier": "@atmina/linting/prettier"
}
Loading

0 comments on commit 91c5376

Please sign in to comment.