Skip to content

Commit

Permalink
Enable defaultValue and forceValue on object and array schema
Browse files Browse the repository at this point in the history
- Run required validation if field changed or there was already an error
  previously
- Update react version
- Update how we build library
  • Loading branch information
tnagorra committed Nov 8, 2023
1 parent fb18e55 commit 09536f8
Show file tree
Hide file tree
Showing 13 changed files with 2,777 additions and 2,280 deletions.
22 changes: 10 additions & 12 deletions lib/.babelrc
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
{
'presets': [
'@babel/preset-env',
'@babel/preset-typescript',
'@babel/preset-react',
],

'plugins': [
'@babel/plugin-transform-runtime',

['polyfill-corejs3', {
"method": "usage-pure",
}],
"presets": [
"@babel/preset-env",
"@babel/preset-typescript",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-transform-runtime",
["polyfill-corejs3", {
"method": "usage-pure"
}]
]
}
2 changes: 1 addition & 1 deletion lib/.browserslistrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Support all browsers with more than 1% market share
>= 1%
> 1%
1 change: 1 addition & 0 deletions lib/.eslintrc.js → lib/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ module.exports = {
allowImportExportEverywhere: true,
},
rules: {
'@typescript-eslint/no-empty-function': 'off',
strict: 1,
indent: ['error', 4, { SwitchCase: 1 }],

Expand Down
65 changes: 33 additions & 32 deletions lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
"files": [
"/build"
],
"type": "module",
"main": "build/cjs/index.js",
"module": "build/esm/index.js",
"typings": "build/esm/index.d.ts",
"scripts": {
"prepare": "install-peers",
"build": "tsc --project tsconfig-typings.json && rollup -c",
"build": "rollup -c && tsc --project tsconfig-typings.json",
"watch": "rollup -c -w",
"prepack": "yarn build",
"typecheck": "tsc",
Expand All @@ -29,44 +30,44 @@
"url": "https://github.com/toggle-corp/toggle-form/issues"
},
"homepage": "https://github.com/toggle-corp/toggle-form#readme",
"peerDependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"dependencies": {
"@babel/runtime": "^7.19.0",
"@babel/runtime-corejs3": "^7.22.3",
"@togglecorp/fujs": "^2.0.0"
},
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@babel/core": "^7.19.1",
"@babel/plugin-transform-runtime": "^7.19.1",
"@babel/preset-env": "^7.19.1",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-commonjs": "^22.0.2",
"@rollup/plugin-eslint": "^8.0.1",
"@rollup/plugin-node-resolve": "^14.1.0",
"@types/jest": "^29.0.3",
"@types/node": "^18.7.22",
"@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6",
"@typescript-eslint/eslint-plugin": "^5.59.8",
"@typescript-eslint/parser": "^5.59.8",
"babel-jest": "^29.0.3",
"babel-plugin-polyfill-corejs3": "^0.6.0",
"eslint": "^8.24.0",
"@babel/core": "^7.22.8",
"@babel/plugin-transform-runtime": "^7.22.7",
"@babel/preset-env": "^7.22.7",
"@babel/preset-react": "^7.22.5",
"@babel/preset-typescript": "^7.22.5",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-commonjs": "^25.0.2",
"@rollup/plugin-eslint": "^9.0.4",
"@rollup/plugin-node-resolve": "^15.1.0",
"@types/jest": "^29.5.2",
"@types/node": "^20.4.1",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@typescript-eslint/eslint-plugin": "^5.61.0",
"@typescript-eslint/parser": "^5.61.0",
"babel-jest": "^29.6.1",
"babel-plugin-polyfill-corejs3": "^0.8.2",
"eslint": "^8.44.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.31.8",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"install-peers-cli": "^2.2.0",
"jest": "^29.0.3",
"rollup": "^2.79.1",
"jest": "^29.6.1",
"rollup": "^3.26.2",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-filesize": "^9.1.2",
"typescript": "^5.0.4",
"unimported": "^1.22.0"
"rollup-plugin-filesize": "^10.0.0",
"typescript": "^5.1.6",
"unimported": "^1.29.2"
}
}
2 changes: 1 addition & 1 deletion lib/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import filesize from 'rollup-plugin-filesize';
import eslint from '@rollup/plugin-eslint';
import copy from 'rollup-plugin-copy';

import pkg from './package.json';
import pkg from './package.json' assert { type: 'json' };

const INPUT_FILE_PATH = 'src/index.ts';

Expand Down
File renamed without changes.
13 changes: 11 additions & 2 deletions lib/src/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,14 @@ export function useFormObject<K, T>(
) {
const setFieldValue = useCallback(
(...entries: EntriesAsList<NonNullable<T>>) => {
// NOTE: there was a weird issue when using isCallable after
// typescript upgrade. So using a specific isValueSetCallable here
function isValueSetCallable(
value: SetValueArg<NonNullable<T>[keyof NonNullable<T>]>,
): value is NonNullable<T>[keyof NonNullable<T>] {
return typeof value !== 'function';
}

// NOTE: may need to cast callableValue here
const [callableValue, key] = entries;
onChange(
Expand All @@ -463,10 +471,11 @@ export function useFormObject<K, T>(
? defaultValue()
: defaultValue
);
const val = baseValue[key];
return {
...baseValue,
[key]: isCallable(callableValue)
? callableValue(baseValue[key])
[key]: isValueSetCallable(callableValue)
? callableValue(val)
: callableValue,
};
},
Expand Down
8 changes: 8 additions & 0 deletions lib/src/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ export type ArraySchema<Value, TopValue = Value, Context = undefined> = {
context: Context,
) => Schema<Value, TopValue, Context>;
keySelector: (value: Value) => string | number;

// for accumulateValues
forceValue?: NonNullable<Value[]> | typeof undefinedValue | typeof nullValue,
defaultValue?: NonNullable<Value[]> | typeof undefinedValue | typeof nullValue,
}

export type ObjectSchema<Value, TopValue = Value, Context = undefined> = {
Expand All @@ -63,6 +67,10 @@ export type ObjectSchema<Value, TopValue = Value, Context = undefined> = {
[fieldDependencies]?: { [K in keyof Value]: (keyof Value)[] };
}
);

// for accumulateValues
forceValue?: NonNullable<Value> | typeof undefinedValue | typeof nullValue,
defaultValue?: NonNullable<Value> | typeof undefinedValue | typeof nullValue,
}

export type Error<Value> = (
Expand Down
60 changes: 43 additions & 17 deletions lib/src/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ export function accumulateValues(
keySelector,
} = schema;

if (isDefined(schema.forceValue)) {
if (schema.forceValue === undefinedValue) {
return undefined;
}
if (schema.forceValue === nullValue) {
return null;
}
return schema.forceValue;
}

const isSchemaForArray = (!!member && !!keySelector);
const isSchemaForObject = !!fields;

Expand All @@ -57,7 +67,16 @@ export function accumulateValues(
return value;
});
if (hasNoValues(values)) {
// FIXME: array will always be empty array
if (isDefined(schema.defaultValue)) {
if (schema.defaultValue === undefinedValue) {
return undefined;
}
if (schema.defaultValue === nullValue) {
return null;
}
return schema.defaultValue;
}
// FIXME: should we instead use (return nullable ? null : undefined)?
return [];
}
return values;
Expand All @@ -84,21 +103,20 @@ export function accumulateValues(
{},
);
if (hasNoKeys(values)) {
if (isDefined(schema.defaultValue)) {
if (schema.defaultValue === undefinedValue) {
return undefined;
}
if (schema.defaultValue === nullValue) {
return null;
}
return schema.defaultValue;
}
return nullable ? null : undefined;
}
return values;
}

if (isDefined(schema.forceValue)) {
if (schema.forceValue === undefinedValue) {
return undefined;
}
if (schema.forceValue === nullValue) {
return null;
}
return schema.forceValue;
}

const requiredCondition = schema.requiredValidation ?? genericRequiredCondition;

if (!requiredCondition(obj, baseValue, context)) {
Expand Down Expand Up @@ -208,6 +226,10 @@ export function accumulateDifferentialErrors(
context = undefined,
depsChanged = false,
) {
// NOTE: schema can be undefined if the schema changed
if (!schema) {
return undefined;
}
if (!depsChanged && oldObj === newObj) {
return oldError;
}
Expand Down Expand Up @@ -322,12 +344,16 @@ export function accumulateDifferentialErrors(
return hasNoKeys(errors) ? undefined : errors;
}

// NOTE: we only run required validation when the actual field changes
if (!depsChanged && schema.required) {
const requiredCondition = schema.requiredValidation ?? genericRequiredCondition;
const error = requiredCondition(newObj, baseValue, context);
if (error) {
return error;
if (schema.required) {
if (
(depsChanged && oldObj === newObj && !!oldError)
|| (oldObj !== newObj)
) {
const requiredCondition = schema.requiredValidation ?? genericRequiredCondition;
const error = requiredCondition(newObj, baseValue, context);
if (error) {
return error;
}
}
}

Expand Down
1 change: 0 additions & 1 deletion lib/tsconfig-typings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "build", "coverage", "**/*.test.ts"],
"compilerOptions": {
"noEmit": false,
"emitDeclarationOnly": true,
Expand Down
5 changes: 2 additions & 3 deletions lib/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
"jsx": "react",
"rootDir": "./src",
"sourceMap": true,
"baseUrl": ".",
"baseUrl": "."
},
"exclude": ["node_modules", "build", "coverage"],
"include": ["./src", "./declarations"]
"include": ["./src/index.ts", "./src/declarations"]
}
Loading

0 comments on commit 09536f8

Please sign in to comment.