Skip to content

Commit d916231

Browse files
authored
Merge pull request #35 from toggle-corp/fix/add-condition-typings
Fix/add condition typings
2 parents 810b4c6 + 180a738 commit d916231

14 files changed

+268
-152
lines changed

README.md

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
A simple form library using react hooks
44

5-
65
## Features
76

87
- Reasonably typesafe
@@ -12,13 +11,13 @@ A simple form library using react hooks
1211
- Supports automatic dependency tracking
1312
- Supports restore point
1413

15-
## Introduction
14+
## API
1615

1716
The library exposes three react hooks to define a form.
1817

1918
1. useForm
20-
2. useArrayField
21-
3. useObjectField
19+
2. useFormArray
20+
3. useFormObject
2221

2322
### useForm
2423

@@ -104,7 +103,7 @@ The array schema is an object with these properties:
104103
|property|description|
105104
|----|----|
106105
|validation|Function to validate the array|
107-
|members|Function that defines the schema for each item of the array|
106+
|member|Function that defines the schema for each item of the array|
108107
|keySelector|Function that defines the unique key for each item of the array|
109108

110109
### Literal Schema
@@ -114,7 +113,7 @@ The literal schema is an object with these properties:
114113
|property|description|
115114
|----|----|
116115
|required|If defined, the literal will be required|
117-
|requiredCondition|If defined, this function will be used to check required condition|
116+
|requiredValidation|If defined, this function will be used to check required condition|
118117
|defaultValue|If defined, the literal value will fallback to this value|
119118
|forceValue|If defined, the literal value will always be this value|
120119
|validations|Array of functions to validate the literal|
@@ -138,21 +137,79 @@ The library provides these validation function:
138137
- emailCondition
139138
- urlCondition
140139

141-
#### Symbols
140+
## Helper Functions
141+
142+
### getErrorObject
143+
144+
Function to convert leaf error to object error
145+
146+
### getErrorString
147+
148+
Function to convert object error or array error to string error
149+
150+
### removeNull
151+
152+
Function to recursively remove `null` values from an object
153+
154+
### createSubmitHandler
155+
156+
Predefined function to define submit handler for html form
157+
158+
|argument|description|
159+
|----|----|
160+
|validator|Function to trigger form validation|
161+
|setError|Function to set form error|
162+
|successCallback|Callback for validation success|
163+
|failureCallback|Callback for validation failure|
164+
165+
The return value is the function that can be passed to form `onSubmit` prop
166+
167+
### addCondition
168+
169+
Predefined function to add conditions on schema fields
170+
171+
|argument|description|
172+
|----|----|
173+
|schema|Fields of the object schema|
174+
|value|Value of the object|
175+
|dependentKeys|Keys of the object that are used to define the condition|
176+
|valueKeys|Keys of the object that are affected by the condition|
177+
178+
The return value is the updated fields of the object schema
179+
180+
## Core Functions
181+
182+
### accumulateValues
183+
184+
Function to get validated value from form value and form schema
185+
186+
### accumulateErrors
187+
188+
Function to get form error from form value and form schema
189+
190+
### accumulateDifferentialErrors
191+
192+
Function to get differential form error from form value and form schema
193+
194+
### analyzeErrors
195+
196+
Function to identify if form has errored from the form error
197+
198+
## Symbols
142199

143-
##### nonFieldError
200+
### nonFieldError
144201

145202
Symbol to access non field error on errors returned by `useForm`
146203

147-
##### fieldDependencies
204+
### fieldDependencies
148205

149206
Symbol to define field dependencies on object schema
150207

151-
##### undefinedValue
208+
### undefinedValue
152209

153210
Symbol to define `undefined` on `forceValue` and `defaultValue` on literal schema
154211

155-
##### nullValue
212+
### nullValue
156213

157214
Symbol to define `null` on `forceValue` and `defaultValue` on literal schema
158215

lib/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@togglecorp/toggle-form",
3-
"version": "2.0.2",
3+
"version": "2.0.3",
44
"description": "React form library by Togglecorp",
55
"files": [
66
"/build"
@@ -51,8 +51,8 @@
5151
"@types/node": "^18.7.22",
5252
"@types/react": "^18.0.21",
5353
"@types/react-dom": "^18.0.6",
54-
"@typescript-eslint/eslint-plugin": "^5.38.0",
55-
"@typescript-eslint/parser": "^5.38.0",
54+
"@typescript-eslint/eslint-plugin": "^5.59.8",
55+
"@typescript-eslint/parser": "^5.59.8",
5656
"babel-jest": "^29.0.3",
5757
"babel-plugin-polyfill-corejs3": "^0.6.0",
5858
"eslint": "^8.24.0",
@@ -66,7 +66,7 @@
6666
"rollup": "^2.79.1",
6767
"rollup-plugin-copy": "^3.4.0",
6868
"rollup-plugin-filesize": "^9.1.2",
69-
"typescript": "^4.8.3",
69+
"typescript": "^5.0.4",
7070
"unimported": "^1.22.0"
7171
}
7272
}

lib/src/form.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ interface RestoreRestorePointAction {
3030
interface ClearRestorePointAction {
3131
type: 'CLEAR_RESTORE_POINT';
3232
}
33-
interface ErrorAction<T extends object> {
33+
interface ErrorAction<T> {
3434
type: 'SET_ERROR';
3535
error: SetErrorArg<Error<T>> | undefined;
3636
}
37-
interface ValueAction<T extends object> {
37+
interface ValueAction<T> {
3838
type: 'SET_VALUE';
3939
value: SetBaseValueArg<T>;
4040
partialUpdate: boolean | undefined;
@@ -43,9 +43,9 @@ interface PristineAction {
4343
type: 'SET_PRISTINE';
4444
value: boolean;
4545
}
46-
type ValueFieldAction<T extends object> = EntriesAsKeyValue<T> & { type: 'SET_VALUE_FIELD' };
46+
type ValueFieldAction<T> = EntriesAsKeyValue<T> & { type: 'SET_VALUE_FIELD' };
4747

48-
type Actions<T extends object> = ValueFieldAction<T>
48+
type Actions<T> = ValueFieldAction<T>
4949
| ErrorAction<T>
5050
| ValueAction<T>
5151
| PristineAction
@@ -71,7 +71,7 @@ type State<T> = {
7171
hasRestorePoint: false,
7272
});
7373

74-
function useForm<T extends object>(
74+
function useForm<T>(
7575
schema: Schema<T, T, undefined>,
7676
initialState: {
7777
value: T,
@@ -99,7 +99,7 @@ function useForm<T extends object>(
9999
restore: () => void;
100100
clearRestorePoint: () => void;
101101
};
102-
function useForm<T extends object, C>(
102+
function useForm<T, C>(
103103
schema: Schema<T, T, C>,
104104
initialState: {
105105
value: T,
@@ -127,7 +127,7 @@ function useForm<T extends object, C>(
127127
restore: () => void;
128128
clearRestorePoint: () => void;
129129
};
130-
function useForm<T extends object, C>(
130+
function useForm<T, C>(
131131
schema: Schema<T, T, C>,
132132
initialState: {
133133
value: T,
@@ -447,7 +447,7 @@ function useForm<T extends object, C>(
447447
};
448448
}
449449

450-
export function useFormObject<K extends string | number | undefined, T extends object | undefined>(
450+
export function useFormObject<K, T>(
451451
name: K,
452452
onChange: (value: SetValueArg<T>, name: K) => void,
453453
defaultValue: NonNullable<T> | (() => NonNullable<T>),
@@ -479,7 +479,7 @@ export function useFormObject<K extends string | number | undefined, T extends o
479479
return setFieldValue;
480480
}
481481

482-
export function useFormArray<K extends string | number | undefined, T extends object>(
482+
export function useFormArray<K, T>(
483483
name: K,
484484
onChange: (
485485
newValue: SetValueArg<T[]>,

lib/src/schema.d.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,16 @@ export function addCondition<
118118
Value,
119119
// eslint-disable-next-line @typescript-eslint/no-explicit-any
120120
SchemaType extends { [K in keyof Value ]: Schema<Value[K], any, any> },
121-
DepKey extends NonNullable<Value>,
122-
ValKey extends NonNullable<Value>,
121+
const DepKey extends keyof NonNullable<Value>,
122+
const ValKey extends keyof NonNullable<Value>,
123123
>(
124124
schema: SchemaType,
125125
value: Value,
126126
keys: readonly DepKey[],
127127
values: readonly ValKey[],
128128
updater: (
129-
val: Value extends null | undefined ? null | undefined : Pick<Value, DepKey>,
129+
val: Value extends null | undefined
130+
? null | undefined
131+
: Pick<Value, DepKey>,
130132
) => Pick<SchemaType, ValKey>,
131133
): SchemaType;

lib/src/schemaAccumulateDifferentialErrors.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ const errorFormTypeSchema: FormSchema = {
8282
fields = addCondition(
8383
fields,
8484
value,
85-
['startDate'] as const,
86-
['endDate'] as const,
85+
['startDate'],
86+
['endDate'],
8787
(v) => (v?.startDate ? {
8888
endDate: {
8989
required: true,
@@ -98,8 +98,8 @@ const errorFormTypeSchema: FormSchema = {
9898
fields = addCondition(
9999
fields,
100100
value,
101-
['name'] as const,
102-
['clients'] as const,
101+
['name'],
102+
['clients'],
103103
(v) => {
104104
const clientsSchema: FormSchemaFields['clients'] = {
105105
validation: (clients) => {
@@ -128,8 +128,8 @@ const errorFormTypeSchema: FormSchema = {
128128
return addCondition(
129129
clientFields,
130130
clientValue,
131-
[] as const,
132-
['name', 'strength'] as const,
131+
[],
132+
['name', 'strength'],
133133
() => (v?.name === 'Admin' ? {
134134
name: {},
135135
strength: {},

lib/src/schemaAccumulateErrors.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ const errorFormTypeSchema: FormSchema = {
111111
return addCondition(
112112
fields,
113113
value,
114-
['startDate'] as const,
115-
['endDate'] as const,
114+
['startDate'],
115+
['endDate'],
116116
(v) => (v?.startDate ? {
117117
endDate: {
118118
required: true,

lib/src/schemaAccumulateValues.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ const errorFormTypeSchema: FormSchema = {
100100
return addCondition(
101101
fields,
102102
value,
103-
['startDate'] as const,
104-
['endDate'] as const,
103+
['startDate'],
104+
['endDate'],
105105
(v) => (v?.startDate ? {
106106
endDate: {
107107
required: true,

lib/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export const nonFieldError = Symbol('Non Field Error');
33
export const fieldDependencies = Symbol('Field Dependencies');
44

55
export const undefinedValue = Symbol('Undefined Value');
6-
export const nullValue = Symbol('Undefined Value');
6+
export const nullValue = Symbol('Null Value');
77

88
// declare const undefindValue: unique symbol;
99
// declare const nullValue: unique symbol;

0 commit comments

Comments
 (0)