mirror of
https://github.com/cupcakearmy/formhero.git
synced 2024-12-22 08:06:24 +00:00
commit
b3865cc243
19
.github/actions/build/action.yaml
vendored
Normal file
19
.github/actions/build/action.yaml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
name: "Build"
|
||||
description: "Build the project."
|
||||
|
||||
runs:
|
||||
using: "composite" # This is the magic
|
||||
steps:
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 7
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "pnpm"
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
shell: bash
|
||||
- run: pnpm run build
|
||||
shell: bash
|
11
.github/workflows/docs.yaml
vendored
11
.github/workflows/docs.yaml
vendored
@ -23,16 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 7
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "pnpm"
|
||||
|
||||
- run: pnpm install
|
||||
- run: pnpm run build
|
||||
- uses: ./.github/actions/build
|
||||
|
||||
- uses: actions/configure-pages@v3
|
||||
- uses: actions/upload-pages-artifact@v1
|
||||
|
18
.github/workflows/release.yaml
vendored
Normal file
18
.github/workflows/release.yaml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/build
|
||||
|
||||
- run: pnpm test
|
||||
- run: pnpm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
11
.github/workflows/test.yaml
vendored
11
.github/workflows/test.yaml
vendored
@ -14,14 +14,5 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 7
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "pnpm"
|
||||
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm run compile
|
||||
- uses: ./.github/actions/build
|
||||
- run: pnpm run test
|
||||
|
50
README.md
50
README.md
@ -1,9 +1,9 @@
|
||||
![Logo](https://raw.githubusercontent.com/cupcakearmy/formhero/master/.github/Logo.jpg)
|
||||
|
||||
![dependencies](https://badgen.net/david/dep/cupcakearmy/formhero)
|
||||
![downloads badge](https://badgen.net/npm/dt/formhero)
|
||||
![types badge](https://badgen.net/npm/types/formhero)
|
||||
![version badge](https://badgen.net/npm/v/formhero)
|
||||
![types badge](https://badgen.net/npm/types/formhero)
|
||||
![downloads badge](https://badgen.net/npm/dt/formhero)
|
||||
![dependencies](https://badgen.net//bundlephobia/dependency-count/formhero)
|
||||
![minzip size badge](https://badgen.net/bundlephobia/minzip/formhero)
|
||||
|
||||
**Fully customisable react form utility.**
|
||||
@ -22,7 +22,7 @@
|
||||
npm i formhero
|
||||
```
|
||||
|
||||
*Note:* Requires at least typescript version `3.5`, otherwise the error object will not have the right inherited types.
|
||||
_Note:_ Requires at least typescript version `3.5`, otherwise the error object will not have the right inherited types.
|
||||
|
||||
### 👁 Demos
|
||||
|
||||
@ -99,7 +99,7 @@ const Form = () => {
|
||||
password: '',
|
||||
},
|
||||
{
|
||||
username: value => value.length > 3,
|
||||
username: (value) => value.length > 3,
|
||||
email: {
|
||||
validator: /@/,
|
||||
message: 'Must contain an @',
|
||||
@ -146,7 +146,7 @@ const Form = () => {
|
||||
|
||||
return (
|
||||
<form
|
||||
onSubmit={e => {
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault()
|
||||
console.log(form)
|
||||
}}
|
||||
@ -159,7 +159,7 @@ const Form = () => {
|
||||
{...field('awesome', {
|
||||
setter: 'checked',
|
||||
getter: 'onChange',
|
||||
extractor: e => e.target.checked,
|
||||
extractor: (e) => e.target.checked,
|
||||
})}
|
||||
/>
|
||||
Is it awesome?
|
||||
@ -176,28 +176,28 @@ const Form = () => {
|
||||
Sometimes you don't know all the fields upfront. You can simply define a generic type and assign it to the initial object. Of course type assistance is limited in this case as formhero cannot be sure what keys are valid.
|
||||
|
||||
```typescript
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { useForm } from "formhero";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { useForm } from 'formhero'
|
||||
|
||||
type MyForm = { [field: string]: string | number };
|
||||
type MyForm = { [field: string]: string | number }
|
||||
|
||||
const init: MyForm = {
|
||||
username: "unicorn",
|
||||
password: ""
|
||||
};
|
||||
username: 'unicorn',
|
||||
password: '',
|
||||
}
|
||||
|
||||
const Form: React.FC = () => {
|
||||
const { field, form, errors } = useForm(init);
|
||||
const { field, form, errors } = useForm(init)
|
||||
|
||||
return (
|
||||
<form>
|
||||
<input {...field("username")} placeholder="Username" />
|
||||
<input {...field("someother")} placeholder="Something else" />
|
||||
<input {...field("password")} placeholder="Password" type="password" />
|
||||
<input {...field('username')} placeholder="Username" />
|
||||
<input {...field('someother')} placeholder="Something else" />
|
||||
<input {...field('password')} placeholder="Password" type="password" />
|
||||
</form>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## 📖 Documentation
|
||||
@ -267,9 +267,9 @@ const validators = {
|
||||
message: 'My custom error message',
|
||||
},
|
||||
/[\d]/,
|
||||
async value => value.length > 0,
|
||||
async (value) => value.length > 0,
|
||||
{
|
||||
validator: value => true,
|
||||
validator: (value) => true,
|
||||
message: 'Some other error',
|
||||
},
|
||||
],
|
||||
@ -283,7 +283,7 @@ const validators = {
|
||||
username: async (s: string) => {
|
||||
const taken = await API.isUsernameTaken(s)
|
||||
return taken ? 'Username is taken' : true
|
||||
}
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@ -307,7 +307,7 @@ const validators = {}
|
||||
const options = {
|
||||
setter: 'value', // This is not stricly necessarry as 'value' would already be the default.
|
||||
getter: 'onChangeText',
|
||||
extractor: text => text.toLowerCase(),
|
||||
extractor: (text) => text.toLowerCase(),
|
||||
}
|
||||
|
||||
export default () => {
|
||||
@ -339,7 +339,7 @@ export default () => {
|
||||
{...field('username', {
|
||||
setter: 'value', // This is not stricly necessarry as 'value' would already be the default.
|
||||
getter: 'onChangeText',
|
||||
extractor: text => text.toLowerCase(),
|
||||
extractor: (text) => text.toLowerCase(),
|
||||
})}
|
||||
/>
|
||||
<Text>{form.username}</Text>
|
||||
|
65
lib/index.ts
65
lib/index.ts
@ -1,60 +1,62 @@
|
||||
import * as React from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
|
||||
export type FieldOptions<G extends string = 'onChange', S extends string = 'value'> = {
|
||||
extractor?: useFormExtractor
|
||||
getter: G
|
||||
setter: S
|
||||
// Possible future ideas
|
||||
// TODO: Scroll to error field
|
||||
// TODO: Focus on error field
|
||||
|
||||
export type FieldOptions<G extends string = 'onChange', S extends string = 'value', T = any> = {
|
||||
extractor?: useFormExtractor<T> | null
|
||||
getter?: G
|
||||
setter?: S
|
||||
}
|
||||
|
||||
type RuleFunctionReturn = boolean | string
|
||||
type RuleFunction<I> = (value: I) => RuleFunctionReturn | Promise<RuleFunctionReturn>
|
||||
type Rule<I> = RuleFunction<I> | RegExp
|
||||
type RuleObject<I> = Rule<I> | { rule: Rule<I>; message: string }
|
||||
type RuleSet<I> = RuleObject<I> | RuleObject<I>[]
|
||||
type RuleFunction<I, F> = (value: I, data: F) => RuleFunctionReturn | Promise<RuleFunctionReturn>
|
||||
type Rule<I, F> = RuleFunction<I, F> | RegExp
|
||||
type RuleObject<I, F> = Rule<I, F> | { rule: Rule<I, F>; message: string }
|
||||
type RuleSet<I, F> = RuleObject<I, F> | RuleObject<I, F>[]
|
||||
|
||||
function isSimpleRule<I>(obj: RuleObject<I>): obj is Rule<I> {
|
||||
function isSimpleRule<I, F>(obj: RuleObject<I, F>): obj is Rule<I, F> {
|
||||
return obj instanceof RegExp || typeof obj === 'function'
|
||||
}
|
||||
|
||||
export type useFormExtractor = (from: any) => any
|
||||
export type useFormExtractor<T = any> = (from: any) => T
|
||||
export const NoExtractor: useFormExtractor = (v: unknown) => v
|
||||
export const HTMLInputExtractor: useFormExtractor = (e: React.FormEvent<HTMLInputElement>) => e.currentTarget.value
|
||||
export const HTMLCheckboxExtractor: useFormExtractor = (e: React.FormEvent<HTMLInputElement>) => e.currentTarget.checked
|
||||
|
||||
export type FormOptions<R> = {
|
||||
rules: R
|
||||
// fields: FieldOptions
|
||||
}
|
||||
|
||||
// Form = Type of form
|
||||
// F = Type of form
|
||||
// R = Rules, derived from F
|
||||
// E = Errors, derived from F
|
||||
export const useForm = <Form extends object, R extends { [K in keyof Form]?: RuleSet<Form[K]> }, E extends { [key in keyof R]?: RuleFunctionReturn }>(init: Form, options?: FormOptions<R>) => {
|
||||
export const useForm = <F extends object, R extends { [K in keyof F]?: RuleSet<F[K], F> }, E extends { [key in keyof R]?: RuleFunctionReturn }>(init: F, options?: FormOptions<R>) => {
|
||||
const validators: R = options?.rules ?? ({} as R)
|
||||
|
||||
const [form, setForm] = useState<Form>(init)
|
||||
const [form, setForm] = useState<F>(init)
|
||||
const [errors, setErrors] = useState<E>({} as E)
|
||||
const [isValid, setIsValid] = useState<boolean>(true)
|
||||
|
||||
useEffect(() => {
|
||||
setIsValid(!Object.values(errors).reduce((acc, cur) => acc || cur !== undefined, false))
|
||||
const isValid = useMemo(() => {
|
||||
return !Object.values(errors).reduce((acc, cur) => acc || cur !== undefined, false)
|
||||
}, [errors])
|
||||
|
||||
const setField = <A extends keyof Form>(key: A, value: Form[A]) => {
|
||||
const setField = <A extends keyof F>(key: A, value: F[A]) => {
|
||||
setForm({
|
||||
...form,
|
||||
[key]: value,
|
||||
})
|
||||
}
|
||||
|
||||
async function applyRule<I>(value: any, rule: Rule<I>): Promise<RuleFunctionReturn> {
|
||||
if (typeof rule === 'function') return await rule(value)
|
||||
async function applyRule<I>(value: any, rule: Rule<I, F>): Promise<RuleFunctionReturn> {
|
||||
if (typeof rule === 'function') return await rule(value, form)
|
||||
if (rule instanceof RegExp) return rule.test(value)
|
||||
throw new Error(`Unsupported validator: ${rule}`)
|
||||
}
|
||||
|
||||
async function validate<K extends keyof Form>(key: K, value: Form[K]) {
|
||||
const set: RuleSet<Form[K]> | undefined = validators[key] as any
|
||||
async function validate<K extends keyof F>(key: K, value: F[K]) {
|
||||
const set: RuleSet<F[K], F> | undefined = validators[key] as any
|
||||
if (!set) return
|
||||
|
||||
const rules = Array.isArray(set) ? set : [set]
|
||||
@ -74,18 +76,19 @@ export const useForm = <Form extends object, R extends { [K in keyof Form]?: Rul
|
||||
})
|
||||
}
|
||||
|
||||
function update<A extends keyof Form, RAW = any>(key: A, extractor?: (e: RAW) => Form[A]) {
|
||||
return (value: RAW) => {
|
||||
const extracted = extractor ? extractor(value) : HTMLInputExtractor(value)
|
||||
// Internal use
|
||||
function update<A extends keyof F>(key: A, extractor?: useFormExtractor<F[A]> | null) {
|
||||
return (value: any) => {
|
||||
const extracted = extractor ? extractor(value) : extractor === undefined ? HTMLInputExtractor(value) : value
|
||||
setField(key, extracted)
|
||||
validate(key, extracted)
|
||||
}
|
||||
}
|
||||
|
||||
type FieldReturn<K extends keyof Form, G extends string, S extends string> = { [getter in G]: ReturnType<typeof update<K>> } & { [setter in S]: Form[K] }
|
||||
function field<K extends keyof Form>(key: K): FieldReturn<K, 'onChange', 'value'>
|
||||
function field<K extends keyof Form, G extends string, S extends string>(key: K, opts: FieldOptions<G, S>): FieldReturn<K, G, S>
|
||||
function field<K extends keyof Form, G extends string, S extends string>(key: K, opts?: FieldOptions<G, S>): FieldReturn<K, G, S> {
|
||||
type FieldReturn<K extends keyof F, G extends string, S extends string> = { [getter in G]: ReturnType<typeof update<K>> } & { [setter in S]: F[K] }
|
||||
function field<K extends keyof F>(key: K): FieldReturn<K, 'onChange', 'value'>
|
||||
function field<K extends keyof F, G extends string, S extends string>(key: K, opts: FieldOptions<G, S, F[K]>): FieldReturn<K, G, S>
|
||||
function field<K extends keyof F, G extends string, S extends string>(key: K, opts?: FieldOptions<G, S, F[K]>): FieldReturn<K, G, S> {
|
||||
return {
|
||||
[opts?.getter || 'onChange']: update<K>(key, opts?.extractor),
|
||||
[opts?.setter || 'value']: form[key],
|
||||
|
17
package.json
17
package.json
@ -1,9 +1,12 @@
|
||||
{
|
||||
"name": "formhero",
|
||||
"version": "0.1.0",
|
||||
"version": "1.0.0-rc.0",
|
||||
"type": "module",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rm -rf ./dist",
|
||||
"prepublishOnly": "run-s clean build test",
|
||||
@ -21,16 +24,16 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@types/react": "^18.0.27",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"@types/react": "^18.0.28",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"@vitejs/plugin-react": "^3.1.0",
|
||||
"@vitest/coverage-c8": "^0.28.4",
|
||||
"happy-dom": "^8.2.6",
|
||||
"@vitest/coverage-c8": "^0.29.2",
|
||||
"happy-dom": "^8.9.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^4.1.1",
|
||||
"vitest": "^0.28.4"
|
||||
"vite": "^4.1.4",
|
||||
"vitest": "^0.29.2"
|
||||
}
|
||||
}
|
||||
|
365
pnpm-lock.yaml
generated
365
pnpm-lock.yaml
generated
@ -2,31 +2,31 @@ lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
'@testing-library/react': ^13.4.0
|
||||
'@types/react': ^18.0.27
|
||||
'@types/react-dom': ^18.0.10
|
||||
'@types/react': ^18.0.28
|
||||
'@types/react-dom': ^18.0.11
|
||||
'@vitejs/plugin-react': ^3.1.0
|
||||
'@vitest/coverage-c8': ^0.28.4
|
||||
happy-dom: ^8.2.6
|
||||
'@vitest/coverage-c8': ^0.29.2
|
||||
happy-dom: ^8.9.0
|
||||
npm-run-all: ^4.1.5
|
||||
react: ^18.2.0
|
||||
react-dom: ^18.2.0
|
||||
typescript: ^4.9.5
|
||||
vite: ^4.1.1
|
||||
vitest: ^0.28.4
|
||||
vite: ^4.1.4
|
||||
vitest: ^0.29.2
|
||||
|
||||
devDependencies:
|
||||
'@testing-library/react': 13.4.0_biqbaboplfbrettd7655fr4n2y
|
||||
'@types/react': 18.0.27
|
||||
'@types/react-dom': 18.0.10
|
||||
'@vitejs/plugin-react': 3.1.0_vite@4.1.1
|
||||
'@vitest/coverage-c8': 0.28.4_happy-dom@8.2.6
|
||||
happy-dom: 8.2.6
|
||||
'@types/react': 18.0.28
|
||||
'@types/react-dom': 18.0.11
|
||||
'@vitejs/plugin-react': 3.1.0_vite@4.1.4
|
||||
'@vitest/coverage-c8': 0.29.2_vitest@0.29.2
|
||||
happy-dom: 8.9.0
|
||||
npm-run-all: 4.1.5
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
typescript: 4.9.5
|
||||
vite: 4.1.1
|
||||
vitest: 0.28.4_happy-dom@8.2.6
|
||||
vite: 4.1.4
|
||||
vitest: 0.29.2_happy-dom@8.9.0
|
||||
|
||||
packages:
|
||||
|
||||
@ -45,25 +45,25 @@ packages:
|
||||
'@babel/highlight': 7.18.6
|
||||
dev: true
|
||||
|
||||
/@babel/compat-data/7.20.14:
|
||||
resolution: {integrity: sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==}
|
||||
/@babel/compat-data/7.21.0:
|
||||
resolution: {integrity: sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/@babel/core/7.20.12:
|
||||
resolution: {integrity: sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==}
|
||||
/@babel/core/7.21.0:
|
||||
resolution: {integrity: sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.2.0
|
||||
'@babel/code-frame': 7.18.6
|
||||
'@babel/generator': 7.20.14
|
||||
'@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12
|
||||
'@babel/helper-module-transforms': 7.20.11
|
||||
'@babel/helpers': 7.20.13
|
||||
'@babel/parser': 7.20.15
|
||||
'@babel/generator': 7.21.1
|
||||
'@babel/helper-compilation-targets': 7.20.7_@babel+core@7.21.0
|
||||
'@babel/helper-module-transforms': 7.21.2
|
||||
'@babel/helpers': 7.21.0
|
||||
'@babel/parser': 7.21.2
|
||||
'@babel/template': 7.20.7
|
||||
'@babel/traverse': 7.20.13
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/traverse': 7.21.2
|
||||
'@babel/types': 7.21.2
|
||||
convert-source-map: 1.9.0
|
||||
debug: 4.3.4
|
||||
gensync: 1.0.0-beta.2
|
||||
@ -73,24 +73,25 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@babel/generator/7.20.14:
|
||||
resolution: {integrity: sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==}
|
||||
/@babel/generator/7.21.1:
|
||||
resolution: {integrity: sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/types': 7.21.2
|
||||
'@jridgewell/gen-mapping': 0.3.2
|
||||
'@jridgewell/trace-mapping': 0.3.17
|
||||
jsesc: 2.5.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.12:
|
||||
/@babel/helper-compilation-targets/7.20.7_@babel+core@7.21.0:
|
||||
resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
dependencies:
|
||||
'@babel/compat-data': 7.20.14
|
||||
'@babel/core': 7.20.12
|
||||
'@babel/helper-validator-option': 7.18.6
|
||||
'@babel/compat-data': 7.21.0
|
||||
'@babel/core': 7.21.0
|
||||
'@babel/helper-validator-option': 7.21.0
|
||||
browserslist: 4.21.5
|
||||
lru-cache: 5.1.1
|
||||
semver: 6.3.0
|
||||
@ -101,30 +102,30 @@ packages:
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/@babel/helper-function-name/7.19.0:
|
||||
resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==}
|
||||
/@babel/helper-function-name/7.21.0:
|
||||
resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/template': 7.20.7
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-hoist-variables/7.18.6:
|
||||
resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-module-imports/7.18.6:
|
||||
resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-module-transforms/7.20.11:
|
||||
resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==}
|
||||
/@babel/helper-module-transforms/7.21.2:
|
||||
resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/helper-environment-visitor': 7.18.9
|
||||
@ -133,8 +134,8 @@ packages:
|
||||
'@babel/helper-split-export-declaration': 7.18.6
|
||||
'@babel/helper-validator-identifier': 7.19.1
|
||||
'@babel/template': 7.20.7
|
||||
'@babel/traverse': 7.20.13
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/traverse': 7.21.2
|
||||
'@babel/types': 7.21.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@ -148,14 +149,14 @@ packages:
|
||||
resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-split-export-declaration/7.18.6:
|
||||
resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-string-parser/7.19.4:
|
||||
@ -168,18 +169,18 @@ packages:
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/@babel/helper-validator-option/7.18.6:
|
||||
resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==}
|
||||
/@babel/helper-validator-option/7.21.0:
|
||||
resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/@babel/helpers/7.20.13:
|
||||
resolution: {integrity: sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==}
|
||||
/@babel/helpers/7.21.0:
|
||||
resolution: {integrity: sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/template': 7.20.7
|
||||
'@babel/traverse': 7.20.13
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/traverse': 7.21.2
|
||||
'@babel/types': 7.21.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@ -193,36 +194,36 @@ packages:
|
||||
js-tokens: 4.0.0
|
||||
dev: true
|
||||
|
||||
/@babel/parser/7.20.15:
|
||||
resolution: {integrity: sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==}
|
||||
/@babel/parser/7.21.2:
|
||||
resolution: {integrity: sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.12:
|
||||
resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==}
|
||||
/@babel/plugin-transform-react-jsx-self/7.21.0_@babel+core@7.21.0:
|
||||
resolution: {integrity: sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
'@babel/core': 7.20.12
|
||||
'@babel/core': 7.21.0
|
||||
'@babel/helper-plugin-utils': 7.20.2
|
||||
dev: true
|
||||
|
||||
/@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.12:
|
||||
/@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.21.0:
|
||||
resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
'@babel/core': 7.20.12
|
||||
'@babel/core': 7.21.0
|
||||
'@babel/helper-plugin-utils': 7.20.2
|
||||
dev: true
|
||||
|
||||
/@babel/runtime/7.20.13:
|
||||
resolution: {integrity: sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==}
|
||||
/@babel/runtime/7.21.0:
|
||||
resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
regenerator-runtime: 0.13.11
|
||||
@ -233,30 +234,30 @@ packages:
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.18.6
|
||||
'@babel/parser': 7.20.15
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/parser': 7.21.2
|
||||
'@babel/types': 7.21.2
|
||||
dev: true
|
||||
|
||||
/@babel/traverse/7.20.13:
|
||||
resolution: {integrity: sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==}
|
||||
/@babel/traverse/7.21.2:
|
||||
resolution: {integrity: sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.18.6
|
||||
'@babel/generator': 7.20.14
|
||||
'@babel/generator': 7.21.1
|
||||
'@babel/helper-environment-visitor': 7.18.9
|
||||
'@babel/helper-function-name': 7.19.0
|
||||
'@babel/helper-function-name': 7.21.0
|
||||
'@babel/helper-hoist-variables': 7.18.6
|
||||
'@babel/helper-split-export-declaration': 7.18.6
|
||||
'@babel/parser': 7.20.15
|
||||
'@babel/types': 7.20.7
|
||||
'@babel/parser': 7.21.2
|
||||
'@babel/types': 7.21.2
|
||||
debug: 4.3.4
|
||||
globals: 11.12.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@babel/types/7.20.7:
|
||||
resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==}
|
||||
/@babel/types/7.21.2:
|
||||
resolution: {integrity: sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/helper-string-parser': 7.19.4
|
||||
@ -514,7 +515,7 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.18.6
|
||||
'@babel/runtime': 7.20.13
|
||||
'@babel/runtime': 7.21.0
|
||||
'@types/aria-query': 5.0.1
|
||||
aria-query: 5.1.3
|
||||
chalk: 4.1.2
|
||||
@ -530,9 +531,9 @@ packages:
|
||||
react: ^18.0.0
|
||||
react-dom: ^18.0.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.13
|
||||
'@babel/runtime': 7.21.0
|
||||
'@testing-library/dom': 8.20.0
|
||||
'@types/react-dom': 18.0.10
|
||||
'@types/react-dom': 18.0.11
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: true
|
||||
@ -555,22 +556,22 @@ packages:
|
||||
resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
|
||||
dev: true
|
||||
|
||||
/@types/node/18.11.19:
|
||||
resolution: {integrity: sha512-YUgMWAQBWLObABqrvx8qKO1enAvBUdjZOAWQ5grBAkp5LQv45jBvYKZ3oFS9iKRCQyFjqw6iuEa1vmFqtxYLZw==}
|
||||
/@types/node/18.14.5:
|
||||
resolution: {integrity: sha512-CRT4tMK/DHYhw1fcCEBwME9CSaZNclxfzVMe7GsO6ULSwsttbj70wSiX6rZdIjGblu93sTJxLdhNIT85KKI7Qw==}
|
||||
dev: true
|
||||
|
||||
/@types/prop-types/15.7.5:
|
||||
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
|
||||
dev: true
|
||||
|
||||
/@types/react-dom/18.0.10:
|
||||
resolution: {integrity: sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==}
|
||||
/@types/react-dom/18.0.11:
|
||||
resolution: {integrity: sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==}
|
||||
dependencies:
|
||||
'@types/react': 18.0.27
|
||||
'@types/react': 18.0.28
|
||||
dev: true
|
||||
|
||||
/@types/react/18.0.27:
|
||||
resolution: {integrity: sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==}
|
||||
/@types/react/18.0.28:
|
||||
resolution: {integrity: sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==}
|
||||
dependencies:
|
||||
'@types/prop-types': 15.7.5
|
||||
'@types/scheduler': 0.16.2
|
||||
@ -581,67 +582,57 @@ packages:
|
||||
resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
|
||||
dev: true
|
||||
|
||||
/@vitejs/plugin-react/3.1.0_vite@4.1.1:
|
||||
/@vitejs/plugin-react/3.1.0_vite@4.1.4:
|
||||
resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
vite: ^4.1.0-beta.0
|
||||
dependencies:
|
||||
'@babel/core': 7.20.12
|
||||
'@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.12
|
||||
'@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.12
|
||||
'@babel/core': 7.21.0
|
||||
'@babel/plugin-transform-react-jsx-self': 7.21.0_@babel+core@7.21.0
|
||||
'@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.21.0
|
||||
magic-string: 0.27.0
|
||||
react-refresh: 0.14.0
|
||||
vite: 4.1.1
|
||||
vite: 4.1.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@vitest/coverage-c8/0.28.4_happy-dom@8.2.6:
|
||||
resolution: {integrity: sha512-btelLBxaWhHnywXRQxDlrvPhGdnuIaD3XulsxcZRIcnpLPbFu39dNTT0IYu2QWP2ZZrV0AmNtdLIfD4c77zMAg==}
|
||||
/@vitest/coverage-c8/0.29.2_vitest@0.29.2:
|
||||
resolution: {integrity: sha512-NmD3WirQCeQjjKfHu4iEq18DVOBFbLn9TKVdMpyi5YW2EtnS+K22/WE+9/wRrepOhyeTxuEFgxUVkCAE1GhbnQ==}
|
||||
peerDependencies:
|
||||
vitest: '>=0.29.0 <1'
|
||||
dependencies:
|
||||
c8: 7.12.0
|
||||
c8: 7.13.0
|
||||
picocolors: 1.0.0
|
||||
std-env: 3.3.2
|
||||
vitest: 0.28.4_happy-dom@8.2.6
|
||||
transitivePeerDependencies:
|
||||
- '@edge-runtime/vm'
|
||||
- '@vitest/browser'
|
||||
- '@vitest/ui'
|
||||
- happy-dom
|
||||
- jsdom
|
||||
- less
|
||||
- sass
|
||||
- stylus
|
||||
- sugarss
|
||||
- supports-color
|
||||
- terser
|
||||
vitest: 0.29.2_happy-dom@8.9.0
|
||||
dev: true
|
||||
|
||||
/@vitest/expect/0.28.4:
|
||||
resolution: {integrity: sha512-JqK0NZ4brjvOSL8hXAnIsfi+jxDF7rH/ZWCGCt0FAqRnVFc1hXsfwXksQvEnKqD84avRt3gmeXoK4tNbmkoVsQ==}
|
||||
/@vitest/expect/0.29.2:
|
||||
resolution: {integrity: sha512-wjrdHB2ANTch3XKRhjWZN0UueFocH0cQbi2tR5Jtq60Nb3YOSmakjdAvUa2JFBu/o8Vjhj5cYbcMXkZxn1NzmA==}
|
||||
dependencies:
|
||||
'@vitest/spy': 0.28.4
|
||||
'@vitest/utils': 0.28.4
|
||||
'@vitest/spy': 0.29.2
|
||||
'@vitest/utils': 0.29.2
|
||||
chai: 4.3.7
|
||||
dev: true
|
||||
|
||||
/@vitest/runner/0.28.4:
|
||||
resolution: {integrity: sha512-Q8UV6GjDvBSTfUoq0QXVCNpNOUrWu4P2qvRq7ssJWzn0+S0ojbVOxEjMt+8a32X6SdkhF8ak+2nkppsqV0JyNQ==}
|
||||
/@vitest/runner/0.29.2:
|
||||
resolution: {integrity: sha512-A1P65f5+6ru36AyHWORhuQBJrOOcmDuhzl5RsaMNFe2jEkoj0faEszQS4CtPU/LxUYVIazlUtZTY0OEZmyZBnA==}
|
||||
dependencies:
|
||||
'@vitest/utils': 0.28.4
|
||||
'@vitest/utils': 0.29.2
|
||||
p-limit: 4.0.0
|
||||
pathe: 1.1.0
|
||||
dev: true
|
||||
|
||||
/@vitest/spy/0.28.4:
|
||||
resolution: {integrity: sha512-8WuhfXLlvCXpNXEGJW6Gc+IKWI32435fQJLh43u70HnZ1otJOa2Cmg2Wy2Aym47ZnNCP4NolF+8cUPwd0MigKQ==}
|
||||
/@vitest/spy/0.29.2:
|
||||
resolution: {integrity: sha512-Hc44ft5kaAytlGL2PyFwdAsufjbdOvHklwjNy/gy/saRbg9Kfkxfh+PklLm1H2Ib/p586RkQeNFKYuJInUssyw==}
|
||||
dependencies:
|
||||
tinyspy: 1.0.2
|
||||
tinyspy: 1.1.1
|
||||
dev: true
|
||||
|
||||
/@vitest/utils/0.28.4:
|
||||
resolution: {integrity: sha512-l2QztOLdc2LkR+w/lP52RGh8hW+Ul4KESmCAgVE8q737I7e7bQoAfkARKpkPJ4JQtGpwW4deqlj1732VZD7TFw==}
|
||||
/@vitest/utils/0.29.2:
|
||||
resolution: {integrity: sha512-F14/Uc+vCdclStS2KEoXJlOLAEyqRhnw0gM27iXw9bMTcyKRPJrQ+rlC6XZ125GIPvvKYMPpVxNhiou6PsEeYQ==}
|
||||
dependencies:
|
||||
cli-truncate: 3.1.0
|
||||
diff: 5.1.0
|
||||
@ -726,18 +717,14 @@ packages:
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001450
|
||||
electron-to-chromium: 1.4.286
|
||||
node-releases: 2.0.9
|
||||
caniuse-lite: 1.0.30001460
|
||||
electron-to-chromium: 1.4.319
|
||||
node-releases: 2.0.10
|
||||
update-browserslist-db: 1.0.10_browserslist@4.21.5
|
||||
dev: true
|
||||
|
||||
/buffer-from/1.1.2:
|
||||
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
|
||||
dev: true
|
||||
|
||||
/c8/7.12.0:
|
||||
resolution: {integrity: sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==}
|
||||
/c8/7.13.0:
|
||||
resolution: {integrity: sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==}
|
||||
engines: {node: '>=10.12.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
@ -750,7 +737,7 @@ packages:
|
||||
istanbul-reports: 3.1.5
|
||||
rimraf: 3.0.2
|
||||
test-exclude: 6.0.0
|
||||
v8-to-istanbul: 9.0.1
|
||||
v8-to-istanbul: 9.1.0
|
||||
yargs: 16.2.0
|
||||
yargs-parser: 20.2.9
|
||||
dev: true
|
||||
@ -767,8 +754,8 @@ packages:
|
||||
get-intrinsic: 1.2.0
|
||||
dev: true
|
||||
|
||||
/caniuse-lite/1.0.30001450:
|
||||
resolution: {integrity: sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==}
|
||||
/caniuse-lite/1.0.30001460:
|
||||
resolution: {integrity: sha512-Bud7abqjvEjipUkpLs4D7gR0l8hBYBHoa+tGtKJHvT2AYzLp1z7EmVkUT4ERpVUfca8S2HGIVs883D8pUH1ZzQ==}
|
||||
dev: true
|
||||
|
||||
/chai/4.3.7:
|
||||
@ -904,7 +891,7 @@ packages:
|
||||
es-get-iterator: 1.1.3
|
||||
get-intrinsic: 1.2.0
|
||||
is-arguments: 1.1.1
|
||||
is-array-buffer: 3.0.1
|
||||
is-array-buffer: 3.0.2
|
||||
is-date-object: 1.0.5
|
||||
is-regex: 1.1.4
|
||||
is-shared-array-buffer: 1.0.2
|
||||
@ -919,8 +906,8 @@ packages:
|
||||
which-typed-array: 1.1.9
|
||||
dev: true
|
||||
|
||||
/define-properties/1.1.4:
|
||||
resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==}
|
||||
/define-properties/1.2.0:
|
||||
resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
has-property-descriptors: 1.0.0
|
||||
@ -940,8 +927,8 @@ packages:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
dev: true
|
||||
|
||||
/electron-to-chromium/1.4.286:
|
||||
resolution: {integrity: sha512-Vp3CVhmYpgf4iXNKAucoQUDcCrBQX3XLBtwgFqP9BUXuucgvAV9zWp1kYU7LL9j4++s9O+12cb3wMtN4SJy6UQ==}
|
||||
/electron-to-chromium/1.4.319:
|
||||
resolution: {integrity: sha512-WeoI6NwZUgteKB+Wmn692S35QycwwNxwgTomNnoCJ79znBAjtBi6C/cIW62JkXmpJRX5rKNYSLDBdAM8l5fH0w==}
|
||||
dev: true
|
||||
|
||||
/emoji-regex/8.0.0:
|
||||
@ -976,8 +963,8 @@ packages:
|
||||
has-property-descriptors: 1.0.0
|
||||
has-proto: 1.0.1
|
||||
has-symbols: 1.0.3
|
||||
internal-slot: 1.0.4
|
||||
is-array-buffer: 3.0.1
|
||||
internal-slot: 1.0.5
|
||||
is-array-buffer: 3.0.2
|
||||
is-callable: 1.2.7
|
||||
is-negative-zero: 2.0.2
|
||||
is-regex: 1.1.4
|
||||
@ -1112,7 +1099,7 @@ packages:
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.1.4
|
||||
define-properties: 1.2.0
|
||||
es-abstract: 1.21.1
|
||||
functions-have-names: 1.2.3
|
||||
dev: true
|
||||
@ -1171,7 +1158,7 @@ packages:
|
||||
resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
define-properties: 1.1.4
|
||||
define-properties: 1.2.0
|
||||
dev: true
|
||||
|
||||
/gopd/1.0.1:
|
||||
@ -1184,11 +1171,12 @@ packages:
|
||||
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
|
||||
dev: true
|
||||
|
||||
/happy-dom/8.2.6:
|
||||
resolution: {integrity: sha512-s53VwyMFpQPEZdN00M82i3tFTzz0T4kBVD4tu8b+im99s1NkLK6tfKGCCl2Jmf3ZWfFCRwS+DV2qkR7S1wmIhQ==}
|
||||
/happy-dom/8.9.0:
|
||||
resolution: {integrity: sha512-JZwJuGdR7ko8L61136YzmrLv7LgTh5b8XaEM3P709mLjyQuXJ3zHTDXvUtBBahRjGlcYW0zGjIiEWizoTUGKfA==}
|
||||
dependencies:
|
||||
css.escape: 1.5.1
|
||||
he: 1.2.0
|
||||
iconv-lite: 0.6.3
|
||||
node-fetch: 2.6.9
|
||||
webidl-conversions: 7.0.0
|
||||
whatwg-encoding: 2.0.0
|
||||
@ -1272,8 +1260,8 @@ packages:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
dev: true
|
||||
|
||||
/internal-slot/1.0.4:
|
||||
resolution: {integrity: sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==}
|
||||
/internal-slot/1.0.5:
|
||||
resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.0
|
||||
@ -1289,8 +1277,8 @@ packages:
|
||||
has-tostringtag: 1.0.0
|
||||
dev: true
|
||||
|
||||
/is-array-buffer/3.0.1:
|
||||
resolution: {integrity: sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==}
|
||||
/is-array-buffer/3.0.2:
|
||||
resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
get-intrinsic: 1.2.0
|
||||
@ -1544,13 +1532,13 @@ packages:
|
||||
brace-expansion: 1.1.11
|
||||
dev: true
|
||||
|
||||
/mlly/1.1.0:
|
||||
resolution: {integrity: sha512-cwzBrBfwGC1gYJyfcy8TcZU1f+dbH/T+TuOhtYP2wLv/Fb51/uV7HJQfBPtEupZ2ORLRU1EKFS/QfS3eo9+kBQ==}
|
||||
/mlly/1.1.1:
|
||||
resolution: {integrity: sha512-Jnlh4W/aI4GySPo6+DyTN17Q75KKbLTyFK8BrGhjNP4rxuUjbRWhE6gHg3bs33URWAF44FRm7gdQA348i3XxRw==}
|
||||
dependencies:
|
||||
acorn: 8.8.2
|
||||
pathe: 1.1.0
|
||||
pkg-types: 1.0.1
|
||||
ufo: 1.0.1
|
||||
pkg-types: 1.0.2
|
||||
ufo: 1.1.1
|
||||
dev: true
|
||||
|
||||
/ms/2.1.2:
|
||||
@ -1579,8 +1567,8 @@ packages:
|
||||
whatwg-url: 5.0.0
|
||||
dev: true
|
||||
|
||||
/node-releases/2.0.9:
|
||||
resolution: {integrity: sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==}
|
||||
/node-releases/2.0.10:
|
||||
resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==}
|
||||
dev: true
|
||||
|
||||
/normalize-package-data/2.5.0:
|
||||
@ -1617,7 +1605,7 @@ packages:
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.1.4
|
||||
define-properties: 1.2.0
|
||||
dev: true
|
||||
|
||||
/object-keys/1.1.1:
|
||||
@ -1630,7 +1618,7 @@ packages:
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.1.4
|
||||
define-properties: 1.2.0
|
||||
has-symbols: 1.0.3
|
||||
object-keys: 1.1.1
|
||||
dev: true
|
||||
@ -1724,11 +1712,11 @@ packages:
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/pkg-types/1.0.1:
|
||||
resolution: {integrity: sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==}
|
||||
/pkg-types/1.0.2:
|
||||
resolution: {integrity: sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ==}
|
||||
dependencies:
|
||||
jsonc-parser: 3.2.0
|
||||
mlly: 1.1.0
|
||||
mlly: 1.1.1
|
||||
pathe: 1.1.0
|
||||
dev: true
|
||||
|
||||
@ -1794,7 +1782,7 @@ packages:
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.1.4
|
||||
define-properties: 1.2.0
|
||||
functions-have-names: 1.2.3
|
||||
dev: true
|
||||
|
||||
@ -1819,8 +1807,8 @@ packages:
|
||||
glob: 7.2.3
|
||||
dev: true
|
||||
|
||||
/rollup/3.14.0:
|
||||
resolution: {integrity: sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==}
|
||||
/rollup/3.18.0:
|
||||
resolution: {integrity: sha512-J8C6VfEBjkvYPESMQYxKHxNOh4A5a3FlP+0BETGo34HEcE4eTlgCrO2+eWzlu2a/sHs2QUkZco+wscH7jhhgWg==}
|
||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
@ -1912,13 +1900,6 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/source-map-support/0.5.21:
|
||||
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
|
||||
dependencies:
|
||||
buffer-from: 1.1.2
|
||||
source-map: 0.6.1
|
||||
dev: true
|
||||
|
||||
/source-map/0.6.1:
|
||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -1958,7 +1939,7 @@ packages:
|
||||
resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
internal-slot: 1.0.4
|
||||
internal-slot: 1.0.5
|
||||
dev: true
|
||||
|
||||
/string-width/4.2.3:
|
||||
@ -1984,7 +1965,7 @@ packages:
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.1.4
|
||||
define-properties: 1.2.0
|
||||
es-abstract: 1.21.1
|
||||
dev: true
|
||||
|
||||
@ -1992,7 +1973,7 @@ packages:
|
||||
resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.1.4
|
||||
define-properties: 1.2.0
|
||||
es-abstract: 1.21.1
|
||||
dev: true
|
||||
|
||||
@ -2000,7 +1981,7 @@ packages:
|
||||
resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.1.4
|
||||
define-properties: 1.2.0
|
||||
es-abstract: 1.21.1
|
||||
dev: true
|
||||
|
||||
@ -2066,8 +2047,8 @@ packages:
|
||||
engines: {node: '>=14.0.0'}
|
||||
dev: true
|
||||
|
||||
/tinyspy/1.0.2:
|
||||
resolution: {integrity: sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==}
|
||||
/tinyspy/1.1.1:
|
||||
resolution: {integrity: sha512-UVq5AXt/gQlti7oxoIg5oi/9r0WpF7DGEVwXgqWSMmyN16+e3tl5lIvTaOpJ3TAtu5xFzWccFRM4R5NaWHF+4g==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
dev: true
|
||||
|
||||
@ -2099,8 +2080,8 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/ufo/1.0.1:
|
||||
resolution: {integrity: sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==}
|
||||
/ufo/1.1.1:
|
||||
resolution: {integrity: sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==}
|
||||
dev: true
|
||||
|
||||
/unbox-primitive/1.0.2:
|
||||
@ -2123,8 +2104,8 @@ packages:
|
||||
picocolors: 1.0.0
|
||||
dev: true
|
||||
|
||||
/v8-to-istanbul/9.0.1:
|
||||
resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==}
|
||||
/v8-to-istanbul/9.1.0:
|
||||
resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==}
|
||||
engines: {node: '>=10.12.0'}
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.17
|
||||
@ -2139,19 +2120,17 @@ packages:
|
||||
spdx-expression-parse: 3.0.1
|
||||
dev: true
|
||||
|
||||
/vite-node/0.28.4_@types+node@18.11.19:
|
||||
resolution: {integrity: sha512-KM0Q0uSG/xHHKOJvVHc5xDBabgt0l70y7/lWTR7Q0pR5/MrYxadT+y32cJOE65FfjGmJgxpVEEY+69btJgcXOQ==}
|
||||
/vite-node/0.29.2_@types+node@18.14.5:
|
||||
resolution: {integrity: sha512-5oe1z6wzI3gkvc4yOBbDBbgpiWiApvuN4P55E8OI131JGrSuo4X3SOZrNmZYo4R8Zkze/dhi572blX0zc+6SdA==}
|
||||
engines: {node: '>=v14.16.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
cac: 6.7.14
|
||||
debug: 4.3.4
|
||||
mlly: 1.1.0
|
||||
mlly: 1.1.1
|
||||
pathe: 1.1.0
|
||||
picocolors: 1.0.0
|
||||
source-map: 0.6.1
|
||||
source-map-support: 0.5.21
|
||||
vite: 4.1.1_@types+node@18.11.19
|
||||
vite: 4.1.4_@types+node@18.14.5
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- less
|
||||
@ -2162,8 +2141,8 @@ packages:
|
||||
- terser
|
||||
dev: true
|
||||
|
||||
/vite/4.1.1:
|
||||
resolution: {integrity: sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==}
|
||||
/vite/4.1.4:
|
||||
resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@ -2190,13 +2169,13 @@ packages:
|
||||
esbuild: 0.16.17
|
||||
postcss: 8.4.21
|
||||
resolve: 1.22.1
|
||||
rollup: 3.14.0
|
||||
rollup: 3.18.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/vite/4.1.1_@types+node@18.11.19:
|
||||
resolution: {integrity: sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==}
|
||||
/vite/4.1.4_@types+node@18.14.5:
|
||||
resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@ -2220,17 +2199,17 @@ packages:
|
||||
terser:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/node': 18.11.19
|
||||
'@types/node': 18.14.5
|
||||
esbuild: 0.16.17
|
||||
postcss: 8.4.21
|
||||
resolve: 1.22.1
|
||||
rollup: 3.14.0
|
||||
rollup: 3.18.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/vitest/0.28.4_happy-dom@8.2.6:
|
||||
resolution: {integrity: sha512-sfWIy0AdlbyGRhunm+TLQEJrFH9XuRPdApfubsyLcDbCRrUX717BRQKInTgzEfyl2Ipi1HWoHB84Nqtcwxogcg==}
|
||||
/vitest/0.29.2_happy-dom@8.9.0:
|
||||
resolution: {integrity: sha512-ydK9IGbAvoY8wkg29DQ4ivcVviCaUi3ivuPKfZEVddMTenFHUfB8EEDXQV8+RasEk1ACFLgMUqAaDuQ/Nk+mQA==}
|
||||
engines: {node: '>=v14.16.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@ -2253,17 +2232,17 @@ packages:
|
||||
dependencies:
|
||||
'@types/chai': 4.3.4
|
||||
'@types/chai-subset': 1.3.3
|
||||
'@types/node': 18.11.19
|
||||
'@vitest/expect': 0.28.4
|
||||
'@vitest/runner': 0.28.4
|
||||
'@vitest/spy': 0.28.4
|
||||
'@vitest/utils': 0.28.4
|
||||
'@types/node': 18.14.5
|
||||
'@vitest/expect': 0.29.2
|
||||
'@vitest/runner': 0.29.2
|
||||
'@vitest/spy': 0.29.2
|
||||
'@vitest/utils': 0.29.2
|
||||
acorn: 8.8.2
|
||||
acorn-walk: 8.2.0
|
||||
cac: 6.7.14
|
||||
chai: 4.3.7
|
||||
debug: 4.3.4
|
||||
happy-dom: 8.2.6
|
||||
happy-dom: 8.9.0
|
||||
local-pkg: 0.4.3
|
||||
pathe: 1.1.0
|
||||
picocolors: 1.0.0
|
||||
@ -2272,9 +2251,9 @@ packages:
|
||||
strip-literal: 1.0.1
|
||||
tinybench: 2.3.1
|
||||
tinypool: 0.3.1
|
||||
tinyspy: 1.0.2
|
||||
vite: 4.1.1_@types+node@18.11.19
|
||||
vite-node: 0.28.4_@types+node@18.11.19
|
||||
tinyspy: 1.1.1
|
||||
vite: 4.1.4_@types+node@18.14.5
|
||||
vite-node: 0.29.2_@types+node@18.14.5
|
||||
why-is-node-running: 2.2.2
|
||||
transitivePeerDependencies:
|
||||
- less
|
||||
|
@ -1,34 +1,15 @@
|
||||
import { act, cleanup, fireEvent, render, screen } from '@testing-library/react'
|
||||
import React, { useEffect } from 'react'
|
||||
import { act, cleanup, fireEvent, render } from '@testing-library/react'
|
||||
import React from 'react'
|
||||
import { beforeEach, describe, expect, test } from 'vitest'
|
||||
|
||||
import { useForm } from '../lib'
|
||||
import { Insight, Util } from './shared'
|
||||
|
||||
beforeEach(cleanup)
|
||||
|
||||
const Insight = {
|
||||
Portal({ data }: { data: any }) {
|
||||
return <div data-testid="result">{JSON.stringify(data)}</div>
|
||||
},
|
||||
async verify(obj: any) {
|
||||
const result = await screen.findByTestId('result')
|
||||
const data = JSON.parse(result.innerText)
|
||||
expect(data).toMatchObject(obj)
|
||||
},
|
||||
}
|
||||
|
||||
const Util = {
|
||||
find<E extends HTMLElement = HTMLInputElement>(id: string) {
|
||||
return screen.findByTestId<E>(id)
|
||||
},
|
||||
writeToField(node: HTMLInputElement, value: string) {
|
||||
fireEvent.change(node, { target: { value } })
|
||||
},
|
||||
}
|
||||
|
||||
describe('Field', () => {
|
||||
test('Basic Form', async () => {
|
||||
const BasicForm = () => {
|
||||
function Component() {
|
||||
const form = useForm({ username: '', password: '' })
|
||||
const { field } = form
|
||||
return (
|
||||
@ -47,7 +28,7 @@ describe('Field', () => {
|
||||
)
|
||||
}
|
||||
|
||||
render(<BasicForm />)
|
||||
render(<Component />)
|
||||
async function inputIntoForm(id: string, value: string) {
|
||||
const node = await Util.find(id)
|
||||
await act(() => {
|
||||
@ -60,27 +41,65 @@ describe('Field', () => {
|
||||
await inputIntoForm('password', 'bar')
|
||||
})
|
||||
|
||||
test('setField', async () => {
|
||||
const value = 'foo'
|
||||
const Component = () => {
|
||||
const { field, setField, form } = useForm({ username: '', password: '' })
|
||||
useEffect(() => setField('username', value), [])
|
||||
test.skip('Checkbox', async () => {
|
||||
function Component() {
|
||||
const { field, form } = useForm({ cool: false })
|
||||
return (
|
||||
<div>
|
||||
<input data-testid="field" {...field('username')}></input>
|
||||
<form>
|
||||
<input
|
||||
data-testid="field"
|
||||
type="checkbox"
|
||||
{...field('cool', {
|
||||
setter: 'checked',
|
||||
getter: 'onChange',
|
||||
extractor: (e) => e.target.checked,
|
||||
})}
|
||||
/>
|
||||
<Insight.Portal data={form} />
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
render(<Component />)
|
||||
const node = await screen.findByTestId<HTMLInputElement>('field')
|
||||
expect(node.value).toBe(value)
|
||||
Insight.verify({ username: value, password: '' })
|
||||
const field = await Util.find('field')
|
||||
expect(field.checked).toBe(false)
|
||||
await Insight.verify({ cool: false })
|
||||
await act(() => {
|
||||
// Bugged for now
|
||||
fireEvent.click(field)
|
||||
})
|
||||
expect(field.checked).toBe(true)
|
||||
await Insight.verify({ cool: true })
|
||||
})
|
||||
|
||||
test('Select', async () => {
|
||||
function Component() {
|
||||
const { form, field } = useForm({ letter: '' })
|
||||
return (
|
||||
<>
|
||||
<select data-testid="field" {...field('letter')}>
|
||||
<option value="a">A</option>
|
||||
<option value="b">B</option>
|
||||
<option value="c">C</option>
|
||||
</select>
|
||||
<Insight.Portal data={form} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
render(<Component />)
|
||||
const field = await Util.find('field')
|
||||
const value = 'b'
|
||||
await act(() => {
|
||||
fireEvent.change(field, { target: { value } })
|
||||
})
|
||||
expect(field.value).toBe(value)
|
||||
await Insight.verify({ letter: value })
|
||||
})
|
||||
|
||||
test('Field sync', async () => {
|
||||
const value = 'foo'
|
||||
const Component = () => {
|
||||
function Component() {
|
||||
const { field, form } = useForm({ name: '' })
|
||||
return (
|
||||
<form>
|
||||
@ -101,54 +120,3 @@ describe('Field', () => {
|
||||
expect(a.value).toBe(b.value)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Validation', () => {
|
||||
test('Basic', async () => {
|
||||
const Component = () => {
|
||||
const { errors, field } = useForm({ password: '' }, { rules: { password: [(p) => p.length > 8] } })
|
||||
|
||||
return (
|
||||
<div>
|
||||
<input {...field('password')} data-testid="field" />
|
||||
<Insight.Portal data={errors} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
render(<Component />)
|
||||
const node = await Util.find('field')
|
||||
await act(() => {
|
||||
Util.writeToField(node, '123')
|
||||
})
|
||||
Insight.verify({ password: true })
|
||||
})
|
||||
|
||||
test('Array of rules', async () => {
|
||||
const Component = () => {
|
||||
const { errors, field } = useForm({ password: '' }, { rules: { password: [(p) => p.length > 8, /#/] } })
|
||||
|
||||
return (
|
||||
<div>
|
||||
<input {...field('password')} data-testid="field" />
|
||||
<Insight.Portal data={errors} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
render(<Component />)
|
||||
const node = await Util.find('field')
|
||||
await act(() => {
|
||||
Util.writeToField(node, '12345678')
|
||||
})
|
||||
Insight.verify({ password: true })
|
||||
await act(() => {
|
||||
Util.writeToField(node, '1234#5678')
|
||||
})
|
||||
Insight.verify({})
|
||||
})
|
||||
})
|
||||
|
||||
// Is valid
|
||||
// Reset / setForm
|
||||
// Set error
|
||||
// Checkbox
|
||||
// Extractor
|
||||
// Custom extractor
|
||||
|
11
test/blocks.tsx
Normal file
11
test/blocks.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react'
|
||||
|
||||
// Custom field with non standard setter and getter. Emulate custom component from a library
|
||||
export function NumberField(props: { number: number; update: (value: number) => void }) {
|
||||
return <input data-testid="field" value={props.number} onChange={(e) => props.update(parseInt(e.target.value))} />
|
||||
}
|
||||
|
||||
// Component that needs a different extractor, as it's returning the actual value and not the event.
|
||||
export function DirectReturnInput(props: { value: string; onChange: (v: string) => void }) {
|
||||
return <input data-testid="field" value={props.value} onChange={(e) => props.onChange(e.target.value)} />
|
||||
}
|
57
test/options.test.tsx
Normal file
57
test/options.test.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import { act, cleanup, render } from '@testing-library/react'
|
||||
import React from 'react'
|
||||
import { beforeEach, describe, test } from 'vitest'
|
||||
|
||||
import { useForm } from '../lib'
|
||||
import { DirectReturnInput, NumberField } from './blocks'
|
||||
import { Insight, Util } from './shared'
|
||||
|
||||
beforeEach(cleanup)
|
||||
|
||||
describe('Options', () => {
|
||||
test('Custom component props', async () => {
|
||||
function Component() {
|
||||
const { form, field } = useForm({ foo: 5 })
|
||||
|
||||
return (
|
||||
<div>
|
||||
<NumberField
|
||||
{...field('foo', {
|
||||
setter: 'number',
|
||||
getter: 'update',
|
||||
extractor: null,
|
||||
})}
|
||||
/>
|
||||
<Insight.Portal data={form} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render(<Component />)
|
||||
const node = await Util.find('field')
|
||||
await act(() => {
|
||||
Util.writeToField(node, '123')
|
||||
})
|
||||
Insight.verify({ foo: 123 })
|
||||
})
|
||||
|
||||
test('Disable default extractor', async () => {
|
||||
function Component() {
|
||||
const { form, field } = useForm({ username: '' })
|
||||
|
||||
return (
|
||||
<div>
|
||||
<DirectReturnInput {...field('username', { extractor: null })} />
|
||||
<Insight.Portal data={form} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render(<Component />)
|
||||
const node = await Util.find('field')
|
||||
await act(() => {
|
||||
Util.writeToField(node, '123')
|
||||
})
|
||||
Insight.verify({ username: '123' })
|
||||
})
|
||||
})
|
23
test/shared.tsx
Normal file
23
test/shared.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import { fireEvent, screen } from '@testing-library/react'
|
||||
import React from 'react'
|
||||
import { expect } from 'vitest'
|
||||
|
||||
export const Insight = {
|
||||
Portal({ data }: { data: any }) {
|
||||
return <div data-testid="result">{JSON.stringify(data)}</div>
|
||||
},
|
||||
async verify(obj: any) {
|
||||
const result = await screen.findByTestId('result')
|
||||
const data = JSON.parse(result.innerText)
|
||||
expect(data).toMatchObject(obj)
|
||||
},
|
||||
}
|
||||
|
||||
export const Util = {
|
||||
find<E extends HTMLElement = HTMLInputElement>(id: string) {
|
||||
return screen.findByTestId<E>(id)
|
||||
},
|
||||
writeToField(node: HTMLInputElement, value: string) {
|
||||
fireEvent.change(node, { target: { value } })
|
||||
},
|
||||
}
|
53
test/utility.test.tsx
Normal file
53
test/utility.test.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import { cleanup, render } from '@testing-library/react'
|
||||
import React, { useEffect } from 'react'
|
||||
import { beforeEach, describe, expect, test } from 'vitest'
|
||||
|
||||
import { useForm } from '../lib'
|
||||
import { Insight, Util } from './shared'
|
||||
|
||||
beforeEach(cleanup)
|
||||
|
||||
describe('Utility', () => {
|
||||
test('Manually set a single field', async () => {
|
||||
const value = 'foo'
|
||||
function Component() {
|
||||
const { field, setField, form } = useForm({ username: '', password: '' })
|
||||
useEffect(() => setField('username', value), [])
|
||||
return (
|
||||
<div>
|
||||
<input data-testid="field" {...field('username')}></input>
|
||||
<Insight.Portal data={form} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
render(<Component />)
|
||||
const node = await Util.find('field')
|
||||
expect(node.value).toBe(value)
|
||||
Insight.verify({ username: value, password: '' })
|
||||
})
|
||||
|
||||
test('Manually set the form state later on', async () => {
|
||||
const value = 'foo'
|
||||
function Component() {
|
||||
const { form, field, setForm } = useForm({ username: '' })
|
||||
|
||||
useEffect(() => {
|
||||
setForm({
|
||||
username: value,
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<form>
|
||||
<input data-testid="username" {...field('username')} />
|
||||
<Insight.Portal data={form} />
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
render(<Component />)
|
||||
const node = await Util.find('username')
|
||||
expect(node.value).toBe(value)
|
||||
await Insight.verify({ username: value })
|
||||
})
|
||||
})
|
109
test/validation.test.tsx
Normal file
109
test/validation.test.tsx
Normal file
@ -0,0 +1,109 @@
|
||||
import { act, cleanup, fireEvent, render } from '@testing-library/react'
|
||||
import React from 'react'
|
||||
import { beforeEach, describe, test } from 'vitest'
|
||||
|
||||
import { useForm } from '../lib'
|
||||
import { Insight, Util } from './shared'
|
||||
|
||||
beforeEach(cleanup)
|
||||
|
||||
describe('Validation', () => {
|
||||
test('Basic', async () => {
|
||||
function Component() {
|
||||
const { errors, field } = useForm({ password: '' }, { rules: { password: [(p) => p.length > 8] } })
|
||||
|
||||
return (
|
||||
<div>
|
||||
<input {...field('password')} data-testid="field" />
|
||||
<Insight.Portal data={errors} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
render(<Component />)
|
||||
const node = await Util.find('field')
|
||||
await act(() => {
|
||||
Util.writeToField(node, '123')
|
||||
})
|
||||
Insight.verify({ password: true })
|
||||
})
|
||||
|
||||
test('Array of rules', async () => {
|
||||
function Component() {
|
||||
const { errors, field } = useForm({ password: '' }, { rules: { password: [(p) => p.length > 8, /#/] } })
|
||||
|
||||
return (
|
||||
<div>
|
||||
<input {...field('password')} data-testid="field" />
|
||||
<Insight.Portal data={errors} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
render(<Component />)
|
||||
const node = await Util.find('field')
|
||||
await act(() => {
|
||||
Util.writeToField(node, '12345678')
|
||||
})
|
||||
Insight.verify({ password: true })
|
||||
await act(() => {
|
||||
Util.writeToField(node, '1234#5678')
|
||||
})
|
||||
Insight.verify({})
|
||||
})
|
||||
|
||||
// https://github.com/testing-library/react-testing-library/issues/828
|
||||
test.skip('Invalid rule', async () => {
|
||||
function Component() {
|
||||
const { field } = useForm(
|
||||
{ username: '' },
|
||||
{
|
||||
rules: {
|
||||
username: [
|
||||
// @ts-ignore Give an invalid rules and expect to fail
|
||||
5,
|
||||
],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
return (
|
||||
<form>
|
||||
<input data-testid="field" {...field('username')} />
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
render(<Component />)
|
||||
const field = await Util.find('field')
|
||||
await act(() => {
|
||||
Util.writeToField(field, 'abc')
|
||||
})
|
||||
})
|
||||
|
||||
test('Invalid dependency on other component', async () => {
|
||||
function Component() {
|
||||
const { errors, field } = useForm(
|
||||
{ min: 10, max: 20 },
|
||||
{
|
||||
rules: {
|
||||
max: (value, form) => value > form.min,
|
||||
},
|
||||
}
|
||||
)
|
||||
return (
|
||||
<form>
|
||||
<input type="number" {...field('min')} />
|
||||
<input type="number" {...field('max')} data-testid="max" />
|
||||
<Insight.Portal data={errors} />
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
render(<Component />)
|
||||
const field = await Util.find('max')
|
||||
const value = 5
|
||||
await act(() => {
|
||||
fireEvent.change(field, { target: { value } })
|
||||
})
|
||||
await Insight.verify({ max: true })
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user