@formisch/react 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +24 -11
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -9,7 +9,7 @@ Formisch is also available for [Preact][formisch-preact], [Qwik][formisch-qwik],
9
9
  - Small bundle size starting at 2.5 kB
10
10
  - Schema-based validation with Valibot
11
11
  - Type safety with autocompletion in editor
12
- - It's fast – DOM updates are fine-grained
12
+ - It's fast – re-renders only if necessary
13
13
  - Minimal, readable and well thought out API
14
14
  - Supports all native HTML form fields
15
15
 
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as v from "valibot";
2
- import { useEffect, useLayoutEffect, useMemo, useState } from "react";
2
+ import { useCallback, useEffect, useLayoutEffect, useMemo, useReducer, useRef } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
 
5
5
  //#region ../../packages/core/dist/index.vanilla.js
@@ -480,8 +480,8 @@ function setFieldInput(internalFormStore, path, input) {
480
480
  for (let index = 0; index < path.length; index++) {
481
481
  internalFieldStore = internalFieldStore.children[path[index]];
482
482
  if (index < path.length - 1) internalFieldStore.input.value = true;
483
- else setNestedInput(internalFieldStore, input);
484
483
  }
484
+ setNestedInput(internalFieldStore, input);
485
485
  });
486
486
  });
487
487
  }
@@ -868,11 +868,24 @@ function validate(form, config) {
868
868
  * Hook to enable reactive signals within a React component.
869
869
  */
870
870
  function useSignals() {
871
- const [, setTick] = useState({});
872
- const listener$1 = useMemo(() => [() => setTick({}), /* @__PURE__ */ new Set()], []);
873
- for (const subscriber of listener$1[1]) subscriber.delete(listener$1);
871
+ const [, forceUpdate] = useReducer((x) => x + 1, 0);
872
+ const listener$1 = useMemo(() => [forceUpdate, /* @__PURE__ */ new Set()], []);
873
+ const cleanSubscribers = useCallback(() => {
874
+ for (const subscriber of listener$1[1]) subscriber.delete(listener$1);
875
+ }, [listener$1]);
876
+ cleanSubscribers();
874
877
  setListener(listener$1);
875
878
  useLayoutEffect(() => setListener(void 0));
879
+ const timeout = useRef(null);
880
+ useEffect(() => {
881
+ if (timeout.current) {
882
+ clearTimeout(timeout.current);
883
+ timeout.current = null;
884
+ }
885
+ return () => {
886
+ timeout.current = setTimeout(cleanSubscribers);
887
+ };
888
+ }, [cleanSubscribers]);
876
889
  }
877
890
 
878
891
  //#endregion
@@ -887,7 +900,7 @@ function useField(form, config) {
887
900
  internalFieldStore.elements = internalFieldStore.elements.filter((element) => element.isConnected);
888
901
  };
889
902
  }, [internalFieldStore]);
890
- return {
903
+ return useMemo(() => ({
891
904
  path: config.path,
892
905
  get input() {
893
906
  return getFieldInput(internalFieldStore);
@@ -923,7 +936,7 @@ function useField(form, config) {
923
936
  validateIfRequired(internalFormStore, internalFieldStore, "blur");
924
937
  }
925
938
  }
926
- };
939
+ }), [internalFormStore, internalFieldStore]);
927
940
  }
928
941
 
929
942
  //#endregion
@@ -933,7 +946,7 @@ function useFieldArray(form, config) {
933
946
  useSignals();
934
947
  const internalFormStore = form[INTERNAL];
935
948
  const internalFieldStore = getFieldStore(internalFormStore, config.path);
936
- return {
949
+ return useMemo(() => ({
937
950
  path: config.path,
938
951
  get items() {
939
952
  return internalFieldStore.items.value;
@@ -950,7 +963,7 @@ function useFieldArray(form, config) {
950
963
  get isValid() {
951
964
  return !getFieldBool(internalFieldStore, "errors");
952
965
  }
953
- };
966
+ }), [internalFormStore, internalFieldStore]);
954
967
  }
955
968
 
956
969
  //#endregion
@@ -962,7 +975,7 @@ function useForm(config) {
962
975
  useLayoutEffect(() => {
963
976
  if (config.validate === "initial") validateFormInput(internalFormStore);
964
977
  }, []);
965
- return {
978
+ return useMemo(() => ({
966
979
  [INTERNAL]: internalFormStore,
967
980
  get isSubmitting() {
968
981
  return internalFormStore.isSubmitting.value;
@@ -985,7 +998,7 @@ function useForm(config) {
985
998
  get errors() {
986
999
  return internalFormStore.errors.value;
987
1000
  }
988
- };
1001
+ }), [internalFormStore]);
989
1002
  }
990
1003
 
991
1004
  //#endregion
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@formisch/react",
3
3
  "description": "The modular and type-safe form library for React",
4
- "version": "0.1.0",
4
+ "version": "0.2.1",
5
5
  "license": "MIT",
6
6
  "author": "Fabian Hiller",
7
7
  "homepage": "https://formisch.dev",
@@ -48,8 +48,8 @@
48
48
  "typescript": "~5.9.3",
49
49
  "typescript-eslint": "^8.46.4",
50
50
  "vite": "^7.2.4",
51
- "@formisch/core": "0.4.3",
52
- "@formisch/methods": "0.5.1"
51
+ "@formisch/methods": "0.5.2",
52
+ "@formisch/core": "0.4.4"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",