@contember/react-form 2.0.0-beta.2 → 2.0.0-beta.3

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.
@@ -8,6 +8,7 @@ const utilities = require("@contember/utilities");
8
8
  const useFormInputHandler = require("../internal/useFormInputHandler.cjs");
9
9
  const contexts = require("../contexts.cjs");
10
10
  const useFormInputValidationHandler = require("../hooks/useFormInputValidationHandler.cjs");
11
+ const reactUtils = require("@contember/react-utils");
11
12
  const SlotInput = reactSlot.Slot;
12
13
  const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {
13
14
  const accessor = reactBinding.useField(field);
@@ -16,6 +17,7 @@ const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, f
16
17
  const hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0;
17
18
  const dirty = formState?.dirty ?? accessor.hasUnpersistedChanges;
18
19
  const required = formState?.required ?? !accessor.schema.nullable;
20
+ const [state, setState] = React.useState(void 0);
19
21
  const { parseValue, formatValue, defaultInputProps } = useFormInputHandler.useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn });
20
22
  const accessorGetter = accessor.getAccessor;
21
23
  const { ref, onFocus, onBlur } = useFormInputValidationHandler.useFormInputValidationHandler(accessor);
@@ -23,15 +25,15 @@ const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, f
23
25
  SlotInput,
24
26
  {
25
27
  ref,
26
- value: formatValue(accessor.value),
28
+ value: formatValue(accessor.value, { state, setState }),
27
29
  "data-invalid": utilities.dataAttribute(hasErrors),
28
30
  "data-dirty": utilities.dataAttribute(dirty),
29
31
  "data-required": utilities.dataAttribute(required),
30
32
  onFocus,
31
33
  onBlur,
32
- onChange: React.useCallback((e) => {
33
- accessorGetter().updateValue(parseValue(e.target.value));
34
- }, [accessorGetter, parseValue]),
34
+ onChange: reactUtils.useReferentiallyStableCallback((e) => {
35
+ accessorGetter().updateValue(parseValue(e.target.value, { state, setState }));
36
+ }),
35
37
  ...defaultInputProps,
36
38
  id: id ? `${id}-input` : void 0,
37
39
  required,
@@ -41,7 +43,7 @@ const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, f
41
43
  false,
42
44
  {
43
45
  fileName: "/home/runner/work/contember/contember/packages/react-form/src/components/FormInput.tsx",
44
- lineNumber: 37,
46
+ lineNumber: 40,
45
47
  columnNumber: 3
46
48
  },
47
49
  void 0
@@ -49,7 +51,7 @@ const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, f
49
51
  }, ({ field, isNonbearing, defaultValue }) => {
50
52
  return /* @__PURE__ */ jsxDevRuntime.jsxDEV(reactBinding.Field, { field, isNonbearing, defaultValue }, void 0, false, {
51
53
  fileName: "/home/runner/work/contember/contember/packages/react-form/src/components/FormInput.tsx",
52
- lineNumber: 55,
54
+ lineNumber: 58,
53
55
  columnNumber: 9
54
56
  }, void 0);
55
57
  });
@@ -1 +1 @@
1
- {"version":3,"file":"FormInput.cjs","sources":["../../../../../packages/react-form/src/components/FormInput.tsx"],"sourcesContent":["import * as React from 'react'\nimport { ChangeEventHandler, ComponentType, useCallback } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { Component, Field, OptionallyVariableFieldValue, SugaredRelativeSingleField, useField } from '@contember/react-binding'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormInputHandler } from '../internal/useFormInputHandler'\nimport { useFormFieldState } from '../contexts'\nimport { useFormInputValidationHandler } from '../hooks/useFormInputValidationHandler'\nimport { FormInputHandler } from '../types'\n\ntype InputProps = React.JSX.IntrinsicElements['input']\nconst SlotInput = Slot as ComponentType<InputProps>\n\nexport interface FormInputProps {\n\tfield: SugaredRelativeSingleField['field']\n\tisNonbearing?: boolean\n\tdefaultValue?: OptionallyVariableFieldValue\n\tchildren: React.ReactElement\n\tformatValue?: FormInputHandler['formatValue']\n\tparseValue?: FormInputHandler['parseValue']\n}\n\nexport const FormInput = Component<FormInputProps>(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {\n\tconst accessor = useField(field)\n\n\tconst formState = useFormFieldState()\n\tconst id = formState?.htmlId\n\tconst hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0\n\tconst dirty = formState?.dirty ?? accessor.hasUnpersistedChanges\n\tconst required = formState?.required ?? !accessor.schema.nullable\n\n\tconst { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn })\n\tconst accessorGetter = accessor.getAccessor\n\tconst { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor)\n\n\treturn (\n\t\t<SlotInput\n\t\t\tref={ref}\n\t\t\tvalue={formatValue(accessor.value)}\n\t\t\tdata-invalid={dataAttribute(hasErrors)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tdata-required={dataAttribute(required)}\n\t\t\tonFocus={onFocus}\n\t\t\tonBlur={onBlur}\n\t\t\tonChange={useCallback<ChangeEventHandler<HTMLInputElement>>(e => {\n\t\t\t\taccessorGetter().updateValue(parseValue(e.target.value))\n\t\t\t}, [accessorGetter, parseValue])}\n\t\t\t{...defaultInputProps}\n\t\t\tid={id ? `${id}-input` : undefined}\n\t\t\trequired={required}\n\t\t\t{...props}\n\t\t/>\n\t)\n}, ({ field, isNonbearing, defaultValue }) => {\n\treturn <Field field={field} isNonbearing={isNonbearing} defaultValue={defaultValue} />\n})\n"],"names":["Slot","Component","useField","useFormFieldState","useFormInputHandler","useFormInputValidationHandler","jsxDEV","dataAttribute","useCallback","this","Field"],"mappings":";;;;;;;;;;AAWA,MAAM,YAAYA,UAAA;AAWX,MAAM,YAAYC,aAAA,UAA0B,CAAC,EAAE,OAAO,cAAc,cAAc,aAAa,eAAe,YAAY,cAAc,GAAG,YAAY;AACvJ,QAAA,WAAWC,sBAAS,KAAK;AAE/B,QAAM,YAAYC,SAAAA,kBAAkB;AACpC,QAAM,KAAK,WAAW;AAChB,QAAA,aAAa,WAAW,OAAO,UAAU,SAAS,QAAQ,QAAQ,UAAU,KAAK;AACjF,QAAA,QAAQ,WAAW,SAAS,SAAS;AAC3C,QAAM,WAAW,WAAW,YAAY,CAAC,SAAS,OAAO;AAEzD,QAAM,EAAE,YAAY,aAAa,kBAAsB,IAAAC,oBAAA,oBAAoB,UAAU,EAAE,aAAa,eAAe,YAAY,aAAA,CAAc;AAC7I,QAAM,iBAAiB,SAAS;AAChC,QAAM,EAAE,KAAK,SAAS,OAAO,IAAIC,8BAAAA,8BAA8B,QAAQ;AAGtE,SAAAC,8BAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA,OAAO,YAAY,SAAS,KAAK;AAAA,MACjC,gBAAcC,wBAAc,SAAS;AAAA,MACrC,cAAYA,wBAAc,KAAK;AAAA,MAC/B,iBAAeA,wBAAc,QAAQ;AAAA,MACrC;AAAA,MACA;AAAA,MACA,UAAUC,MAAAA,YAAkD,CAAK,MAAA;AAChE,uBAAA,EAAiB,YAAY,WAAW,EAAE,OAAO,KAAK,CAAC;AAAA,MAAA,GACrD,CAAC,gBAAgB,UAAU,CAAC;AAAA,MAC9B,GAAG;AAAA,MACJ,IAAI,KAAK,GAAG,EAAE,WAAW;AAAA,MACzB;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,IAdL;AAAA,IAAA;AAAA,IAAA;AAAA,MAAA,UAAA;AAAA,MAAA,YAAA;AAAA,MAAA,cAAA;AAAA,IAAA;AAAA,IAAAC;AAAAA,EAeA;AAEF,GAAG,CAAC,EAAE,OAAO,cAAc,mBAAmB;AAC7C,SAAQH,8BAAA,OAAAI,aAAA,OAAA,EAAM,OAAc,cAA4B,aAAjD,GAAA,QAAA,OAAA;AAAA,IAAA,UAAA;AAAA,IAAA,YAAA;AAAA,IAAA,cAAA;AAAA,EAA6E,GAAAD,MAAA;AACrF,CAAC;;"}
1
+ {"version":3,"file":"FormInput.cjs","sources":["../../../../../packages/react-form/src/components/FormInput.tsx"],"sourcesContent":["import * as React from 'react'\nimport { ChangeEventHandler, ComponentType, useCallback, useState } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { Component, Field, OptionallyVariableFieldValue, SugaredRelativeSingleField, useField } from '@contember/react-binding'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormInputHandler } from '../internal/useFormInputHandler'\nimport { useFormFieldState } from '../contexts'\nimport { useFormInputValidationHandler } from '../hooks/useFormInputValidationHandler'\nimport { FormInputHandler } from '../types'\nimport { useReferentiallyStableCallback } from '@contember/react-utils'\n\ntype InputProps = React.JSX.IntrinsicElements['input']\nconst SlotInput = Slot as ComponentType<InputProps>\n\nexport interface FormInputProps {\n\tfield: SugaredRelativeSingleField['field']\n\tisNonbearing?: boolean\n\tdefaultValue?: OptionallyVariableFieldValue\n\tchildren: React.ReactElement\n\tformatValue?: FormInputHandler['formatValue']\n\tparseValue?: FormInputHandler['parseValue']\n}\n\nexport const FormInput = Component<FormInputProps>(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {\n\tconst accessor = useField(field)\n\n\tconst formState = useFormFieldState()\n\tconst id = formState?.htmlId\n\tconst hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0\n\tconst dirty = formState?.dirty ?? accessor.hasUnpersistedChanges\n\tconst required = formState?.required ?? !accessor.schema.nullable\n\n\tconst [state, setState] = useState<any>(undefined)\n\n\tconst { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn })\n\tconst accessorGetter = accessor.getAccessor\n\tconst { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor)\n\n\treturn (\n\t\t<SlotInput\n\t\t\tref={ref}\n\t\t\tvalue={formatValue(accessor.value, { state, setState })}\n\t\t\tdata-invalid={dataAttribute(hasErrors)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tdata-required={dataAttribute(required)}\n\t\t\tonFocus={onFocus}\n\t\t\tonBlur={onBlur}\n\t\t\tonChange={useReferentiallyStableCallback<ChangeEventHandler<HTMLInputElement>>(e => {\n\t\t\t\taccessorGetter().updateValue(parseValue(e.target.value, { state, setState }))\n\t\t\t})}\n\t\t\t{...defaultInputProps}\n\t\t\tid={id ? `${id}-input` : undefined}\n\t\t\trequired={required}\n\t\t\t{...props}\n\t\t/>\n\t)\n}, ({ field, isNonbearing, defaultValue }) => {\n\treturn <Field field={field} isNonbearing={isNonbearing} defaultValue={defaultValue} />\n})\n"],"names":["Slot","Component","useField","useFormFieldState","useState","useFormInputHandler","useFormInputValidationHandler","jsxDEV","dataAttribute","useReferentiallyStableCallback","this","Field"],"mappings":";;;;;;;;;;;AAYA,MAAM,YAAYA,UAAA;AAWX,MAAM,YAAYC,aAAA,UAA0B,CAAC,EAAE,OAAO,cAAc,cAAc,aAAa,eAAe,YAAY,cAAc,GAAG,YAAY;AACvJ,QAAA,WAAWC,sBAAS,KAAK;AAE/B,QAAM,YAAYC,SAAAA,kBAAkB;AACpC,QAAM,KAAK,WAAW;AAChB,QAAA,aAAa,WAAW,OAAO,UAAU,SAAS,QAAQ,QAAQ,UAAU,KAAK;AACjF,QAAA,QAAQ,WAAW,SAAS,SAAS;AAC3C,QAAM,WAAW,WAAW,YAAY,CAAC,SAAS,OAAO;AAEzD,QAAM,CAAC,OAAO,QAAQ,IAAIC,eAAc,MAAS;AAEjD,QAAM,EAAE,YAAY,aAAa,kBAAsB,IAAAC,oBAAA,oBAAoB,UAAU,EAAE,aAAa,eAAe,YAAY,aAAA,CAAc;AAC7I,QAAM,iBAAiB,SAAS;AAChC,QAAM,EAAE,KAAK,SAAS,OAAO,IAAIC,8BAAAA,8BAA8B,QAAQ;AAGtE,SAAAC,8BAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA,OAAO,YAAY,SAAS,OAAO,EAAE,OAAO,UAAU;AAAA,MACtD,gBAAcC,wBAAc,SAAS;AAAA,MACrC,cAAYA,wBAAc,KAAK;AAAA,MAC/B,iBAAeA,wBAAc,QAAQ;AAAA,MACrC;AAAA,MACA;AAAA,MACA,UAAUC,WAAAA,+BAAqE,CAAK,MAAA;AACpE,uBAAA,EAAE,YAAY,WAAW,EAAE,OAAO,OAAO,EAAE,OAAO,SAAS,CAAC,CAAC;AAAA,MAAA,CAC5E;AAAA,MACA,GAAG;AAAA,MACJ,IAAI,KAAK,GAAG,EAAE,WAAW;AAAA,MACzB;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,IAdL;AAAA,IAAA;AAAA,IAAA;AAAA,MAAA,UAAA;AAAA,MAAA,YAAA;AAAA,MAAA,cAAA;AAAA,IAAA;AAAA,IAAAC;AAAAA,EAeA;AAEF,GAAG,CAAC,EAAE,OAAO,cAAc,mBAAmB;AAC7C,SAAQH,8BAAA,OAAAI,aAAA,OAAA,EAAM,OAAc,cAA4B,aAAjD,GAAA,QAAA,OAAA;AAAA,IAAA,UAAA;AAAA,IAAA,YAAA;AAAA,IAAA,cAAA;AAAA,EAA6E,GAAAD,MAAA;AACrF,CAAC;;"}
@@ -1,11 +1,12 @@
1
1
  import { jsxDEV } from "react/jsx-dev-runtime";
2
- import { useCallback } from "react";
2
+ import { useState } from "react";
3
3
  import { Slot } from "@radix-ui/react-slot";
4
4
  import { Component, useField, Field } from "@contember/react-binding";
5
5
  import { dataAttribute } from "@contember/utilities";
6
6
  import { useFormInputHandler } from "../internal/useFormInputHandler.js";
7
7
  import { useFormFieldState } from "../contexts.js";
8
8
  import { useFormInputValidationHandler } from "../hooks/useFormInputValidationHandler.js";
9
+ import { useReferentiallyStableCallback } from "@contember/react-utils";
9
10
  const SlotInput = Slot;
10
11
  const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {
11
12
  const accessor = useField(field);
@@ -14,6 +15,7 @@ const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: f
14
15
  const hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0;
15
16
  const dirty = formState?.dirty ?? accessor.hasUnpersistedChanges;
16
17
  const required = formState?.required ?? !accessor.schema.nullable;
18
+ const [state, setState] = useState(void 0);
17
19
  const { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn });
18
20
  const accessorGetter = accessor.getAccessor;
19
21
  const { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor);
@@ -21,15 +23,15 @@ const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: f
21
23
  SlotInput,
22
24
  {
23
25
  ref,
24
- value: formatValue(accessor.value),
26
+ value: formatValue(accessor.value, { state, setState }),
25
27
  "data-invalid": dataAttribute(hasErrors),
26
28
  "data-dirty": dataAttribute(dirty),
27
29
  "data-required": dataAttribute(required),
28
30
  onFocus,
29
31
  onBlur,
30
- onChange: useCallback((e) => {
31
- accessorGetter().updateValue(parseValue(e.target.value));
32
- }, [accessorGetter, parseValue]),
32
+ onChange: useReferentiallyStableCallback((e) => {
33
+ accessorGetter().updateValue(parseValue(e.target.value, { state, setState }));
34
+ }),
33
35
  ...defaultInputProps,
34
36
  id: id ? `${id}-input` : void 0,
35
37
  required,
@@ -39,7 +41,7 @@ const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: f
39
41
  false,
40
42
  {
41
43
  fileName: "/home/runner/work/contember/contember/packages/react-form/src/components/FormInput.tsx",
42
- lineNumber: 37,
44
+ lineNumber: 40,
43
45
  columnNumber: 3
44
46
  },
45
47
  void 0
@@ -47,7 +49,7 @@ const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: f
47
49
  }, ({ field, isNonbearing, defaultValue }) => {
48
50
  return /* @__PURE__ */ jsxDEV(Field, { field, isNonbearing, defaultValue }, void 0, false, {
49
51
  fileName: "/home/runner/work/contember/contember/packages/react-form/src/components/FormInput.tsx",
50
- lineNumber: 55,
52
+ lineNumber: 58,
51
53
  columnNumber: 9
52
54
  }, void 0);
53
55
  });
@@ -1 +1 @@
1
- {"version":3,"file":"FormInput.js","sources":["../../../../../packages/react-form/src/components/FormInput.tsx"],"sourcesContent":["import * as React from 'react'\nimport { ChangeEventHandler, ComponentType, useCallback } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { Component, Field, OptionallyVariableFieldValue, SugaredRelativeSingleField, useField } from '@contember/react-binding'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormInputHandler } from '../internal/useFormInputHandler'\nimport { useFormFieldState } from '../contexts'\nimport { useFormInputValidationHandler } from '../hooks/useFormInputValidationHandler'\nimport { FormInputHandler } from '../types'\n\ntype InputProps = React.JSX.IntrinsicElements['input']\nconst SlotInput = Slot as ComponentType<InputProps>\n\nexport interface FormInputProps {\n\tfield: SugaredRelativeSingleField['field']\n\tisNonbearing?: boolean\n\tdefaultValue?: OptionallyVariableFieldValue\n\tchildren: React.ReactElement\n\tformatValue?: FormInputHandler['formatValue']\n\tparseValue?: FormInputHandler['parseValue']\n}\n\nexport const FormInput = Component<FormInputProps>(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {\n\tconst accessor = useField(field)\n\n\tconst formState = useFormFieldState()\n\tconst id = formState?.htmlId\n\tconst hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0\n\tconst dirty = formState?.dirty ?? accessor.hasUnpersistedChanges\n\tconst required = formState?.required ?? !accessor.schema.nullable\n\n\tconst { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn })\n\tconst accessorGetter = accessor.getAccessor\n\tconst { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor)\n\n\treturn (\n\t\t<SlotInput\n\t\t\tref={ref}\n\t\t\tvalue={formatValue(accessor.value)}\n\t\t\tdata-invalid={dataAttribute(hasErrors)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tdata-required={dataAttribute(required)}\n\t\t\tonFocus={onFocus}\n\t\t\tonBlur={onBlur}\n\t\t\tonChange={useCallback<ChangeEventHandler<HTMLInputElement>>(e => {\n\t\t\t\taccessorGetter().updateValue(parseValue(e.target.value))\n\t\t\t}, [accessorGetter, parseValue])}\n\t\t\t{...defaultInputProps}\n\t\t\tid={id ? `${id}-input` : undefined}\n\t\t\trequired={required}\n\t\t\t{...props}\n\t\t/>\n\t)\n}, ({ field, isNonbearing, defaultValue }) => {\n\treturn <Field field={field} isNonbearing={isNonbearing} defaultValue={defaultValue} />\n})\n"],"names":["this"],"mappings":";;;;;;;;AAWA,MAAM,YAAY;AAWX,MAAM,YAAY,UAA0B,CAAC,EAAE,OAAO,cAAc,cAAc,aAAa,eAAe,YAAY,cAAc,GAAG,YAAY;AACvJ,QAAA,WAAW,SAAS,KAAK;AAE/B,QAAM,YAAY,kBAAkB;AACpC,QAAM,KAAK,WAAW;AAChB,QAAA,aAAa,WAAW,OAAO,UAAU,SAAS,QAAQ,QAAQ,UAAU,KAAK;AACjF,QAAA,QAAQ,WAAW,SAAS,SAAS;AAC3C,QAAM,WAAW,WAAW,YAAY,CAAC,SAAS,OAAO;AAEzD,QAAM,EAAE,YAAY,aAAa,kBAAsB,IAAA,oBAAoB,UAAU,EAAE,aAAa,eAAe,YAAY,aAAA,CAAc;AAC7I,QAAM,iBAAiB,SAAS;AAChC,QAAM,EAAE,KAAK,SAAS,OAAO,IAAI,8BAA8B,QAAQ;AAGtE,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA,OAAO,YAAY,SAAS,KAAK;AAAA,MACjC,gBAAc,cAAc,SAAS;AAAA,MACrC,cAAY,cAAc,KAAK;AAAA,MAC/B,iBAAe,cAAc,QAAQ;AAAA,MACrC;AAAA,MACA;AAAA,MACA,UAAU,YAAkD,CAAK,MAAA;AAChE,uBAAA,EAAiB,YAAY,WAAW,EAAE,OAAO,KAAK,CAAC;AAAA,MAAA,GACrD,CAAC,gBAAgB,UAAU,CAAC;AAAA,MAC9B,GAAG;AAAA,MACJ,IAAI,KAAK,GAAG,EAAE,WAAW;AAAA,MACzB;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,IAdL;AAAA,IAAA;AAAA,IAAA;AAAA,MAAA,UAAA;AAAA,MAAA,YAAA;AAAA,MAAA,cAAA;AAAA,IAAA;AAAA,IAAAA;AAAAA,EAeA;AAEF,GAAG,CAAC,EAAE,OAAO,cAAc,mBAAmB;AAC7C,SAAQ,uBAAA,OAAA,EAAM,OAAc,cAA4B,aAAjD,GAAA,QAAA,OAAA;AAAA,IAAA,UAAA;AAAA,IAAA,YAAA;AAAA,IAAA,cAAA;AAAA,EAA6E,GAAAA,MAAA;AACrF,CAAC;"}
1
+ {"version":3,"file":"FormInput.js","sources":["../../../../../packages/react-form/src/components/FormInput.tsx"],"sourcesContent":["import * as React from 'react'\nimport { ChangeEventHandler, ComponentType, useCallback, useState } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { Component, Field, OptionallyVariableFieldValue, SugaredRelativeSingleField, useField } from '@contember/react-binding'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormInputHandler } from '../internal/useFormInputHandler'\nimport { useFormFieldState } from '../contexts'\nimport { useFormInputValidationHandler } from '../hooks/useFormInputValidationHandler'\nimport { FormInputHandler } from '../types'\nimport { useReferentiallyStableCallback } from '@contember/react-utils'\n\ntype InputProps = React.JSX.IntrinsicElements['input']\nconst SlotInput = Slot as ComponentType<InputProps>\n\nexport interface FormInputProps {\n\tfield: SugaredRelativeSingleField['field']\n\tisNonbearing?: boolean\n\tdefaultValue?: OptionallyVariableFieldValue\n\tchildren: React.ReactElement\n\tformatValue?: FormInputHandler['formatValue']\n\tparseValue?: FormInputHandler['parseValue']\n}\n\nexport const FormInput = Component<FormInputProps>(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {\n\tconst accessor = useField(field)\n\n\tconst formState = useFormFieldState()\n\tconst id = formState?.htmlId\n\tconst hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0\n\tconst dirty = formState?.dirty ?? accessor.hasUnpersistedChanges\n\tconst required = formState?.required ?? !accessor.schema.nullable\n\n\tconst [state, setState] = useState<any>(undefined)\n\n\tconst { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn })\n\tconst accessorGetter = accessor.getAccessor\n\tconst { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor)\n\n\treturn (\n\t\t<SlotInput\n\t\t\tref={ref}\n\t\t\tvalue={formatValue(accessor.value, { state, setState })}\n\t\t\tdata-invalid={dataAttribute(hasErrors)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tdata-required={dataAttribute(required)}\n\t\t\tonFocus={onFocus}\n\t\t\tonBlur={onBlur}\n\t\t\tonChange={useReferentiallyStableCallback<ChangeEventHandler<HTMLInputElement>>(e => {\n\t\t\t\taccessorGetter().updateValue(parseValue(e.target.value, { state, setState }))\n\t\t\t})}\n\t\t\t{...defaultInputProps}\n\t\t\tid={id ? `${id}-input` : undefined}\n\t\t\trequired={required}\n\t\t\t{...props}\n\t\t/>\n\t)\n}, ({ field, isNonbearing, defaultValue }) => {\n\treturn <Field field={field} isNonbearing={isNonbearing} defaultValue={defaultValue} />\n})\n"],"names":["this"],"mappings":";;;;;;;;;AAYA,MAAM,YAAY;AAWX,MAAM,YAAY,UAA0B,CAAC,EAAE,OAAO,cAAc,cAAc,aAAa,eAAe,YAAY,cAAc,GAAG,YAAY;AACvJ,QAAA,WAAW,SAAS,KAAK;AAE/B,QAAM,YAAY,kBAAkB;AACpC,QAAM,KAAK,WAAW;AAChB,QAAA,aAAa,WAAW,OAAO,UAAU,SAAS,QAAQ,QAAQ,UAAU,KAAK;AACjF,QAAA,QAAQ,WAAW,SAAS,SAAS;AAC3C,QAAM,WAAW,WAAW,YAAY,CAAC,SAAS,OAAO;AAEzD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAc,MAAS;AAEjD,QAAM,EAAE,YAAY,aAAa,kBAAsB,IAAA,oBAAoB,UAAU,EAAE,aAAa,eAAe,YAAY,aAAA,CAAc;AAC7I,QAAM,iBAAiB,SAAS;AAChC,QAAM,EAAE,KAAK,SAAS,OAAO,IAAI,8BAA8B,QAAQ;AAGtE,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA,OAAO,YAAY,SAAS,OAAO,EAAE,OAAO,UAAU;AAAA,MACtD,gBAAc,cAAc,SAAS;AAAA,MACrC,cAAY,cAAc,KAAK;AAAA,MAC/B,iBAAe,cAAc,QAAQ;AAAA,MACrC;AAAA,MACA;AAAA,MACA,UAAU,+BAAqE,CAAK,MAAA;AACpE,uBAAA,EAAE,YAAY,WAAW,EAAE,OAAO,OAAO,EAAE,OAAO,SAAS,CAAC,CAAC;AAAA,MAAA,CAC5E;AAAA,MACA,GAAG;AAAA,MACJ,IAAI,KAAK,GAAG,EAAE,WAAW;AAAA,MACzB;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,IAdL;AAAA,IAAA;AAAA,IAAA;AAAA,MAAA,UAAA;AAAA,MAAA,YAAA;AAAA,MAAA,cAAA;AAAA,IAAA;AAAA,IAAAA;AAAAA,EAeA;AAEF,GAAG,CAAC,EAAE,OAAO,cAAc,mBAAmB;AAC7C,SAAQ,uBAAA,OAAA,EAAM,OAAc,cAA4B,aAAjD,GAAA,QAAA,OAAA;AAAA,IAAA,UAAA;AAAA,IAAA,YAAA;AAAA,IAAA,cAAA;AAAA,EAA6E,GAAAA,MAAA;AACrF,CAAC;"}
@@ -41,14 +41,20 @@ const ColumnTypeHandlerFactories = {
41
41
  }
42
42
  }),
43
43
  Double: () => ({
44
- parseValue: (value) => {
44
+ parseValue: (value, ctx) => {
45
45
  if (value === "") {
46
+ ctx.setState({ rawValue: "", parsedValue: null });
46
47
  return null;
47
48
  }
48
49
  const parsed = parseFloat(value);
49
- return isNaN(parsed) ? null : parsed;
50
+ const parsedValue = isNaN(parsed) ? null : parsed;
51
+ ctx.setState({ rawValue: value, parsedValue });
52
+ return parsedValue;
50
53
  },
51
- formatValue: (value) => {
54
+ formatValue: (value, ctx) => {
55
+ if (value === ctx.state?.parsedValue) {
56
+ return ctx.state.rawValue;
57
+ }
52
58
  return value === null ? "" : value.toString(10);
53
59
  },
54
60
  defaultInputProps: {
@@ -1 +1 @@
1
- {"version":3,"file":"useFormInputHandler.cjs","sources":["../../../../../packages/react-form/src/internal/useFormInputHandler.ts"],"sourcesContent":["import { FieldAccessor, SchemaColumn, SchemaKnownColumnType } from '@contember/react-binding'\nimport { useMemo } from 'react'\nimport { FormInputHandler } from '../types'\n\nexport const useFormInputHandler = (field: FieldAccessor, { formatValue, parseValue }: Partial<FormInputHandler>): FormInputHandler => {\n\treturn useMemo(() => {\n\t\tconst schema = field.schema\n\t\tconst columnType = schema.type\n\t\tconst handlerFactory = ColumnTypeHandlerFactories[columnType as SchemaKnownColumnType] ?? defaultHandlerFactory\n\t\tconst handler = handlerFactory(schema, field.getAccessor)\n\t\treturn {\n\t\t\tdefaultInputProps: handler.defaultInputProps,\n\t\t\tformatValue: formatValue ?? handler.formatValue,\n\t\t\tparseValue: parseValue ?? handler.parseValue,\n\t\t}\n\t}, [field.getAccessor, field.schema, formatValue, parseValue])\n}\n\ntype ColumnTypeHandlerFactory = (column: SchemaColumn, getAccessor: FieldAccessor.GetFieldAccessor) => FormInputHandler\n\nconst defaultHandlerFactory: ColumnTypeHandlerFactory = (schema, field) => ({\n\tparseValue: (value: string) => {\n\t\tif (value === '' && schema.nullable && field().valueOnServer === null) {\n\t\t\treturn null\n\t\t}\n\t\treturn value\n\t},\n\tformatValue: (value: string | null) => value ?? '',\n})\n\nconst ColumnTypeHandlerFactories: Record<SchemaKnownColumnType, ColumnTypeHandlerFactory | undefined> = {\n\tString: defaultHandlerFactory,\n\tInteger: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseInt(value, 10)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\tDouble: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseFloat(value)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\n\tDate: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString().split('T')[0]\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : new Date(parsed).toISOString().split('T')[0]\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'date',\n\t\t},\n\t}),\n\tDateTime: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString()\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : toLocalDate(new Date(parsed))\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'datetime-local',\n\t\t},\n\t}),\n\tBool: undefined,\n\tEnum: undefined,\n\tUuid: undefined,\n}\n\nconst toLocalDate = (date: Date) => {\n\tconst pad = (num: number, length: number = 2) => {\n\t\tconst str = num.toString()\n\t\treturn '0'.repeat(Math.max(0, length - str.length)) + str\n\t}\n\n\treturn pad(date.getFullYear(), 4) +\n\t\t'-' + pad(date.getMonth() + 1) +\n\t\t'-' + pad(date.getDate()) +\n\t\t'T' + pad(date.getHours()) +\n\t\t':' + pad(date.getMinutes()) +\n\t\t':' + pad(date.getSeconds())\n}\n"],"names":["useMemo"],"mappings":"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"}
1
+ {"version":3,"file":"useFormInputHandler.cjs","sources":["../../../../../packages/react-form/src/internal/useFormInputHandler.ts"],"sourcesContent":["import { FieldAccessor, SchemaColumn, SchemaKnownColumnType } from '@contember/react-binding'\nimport { useMemo } from 'react'\nimport { FormInputHandler } from '../types'\n\nexport const useFormInputHandler = (field: FieldAccessor, { formatValue, parseValue }: Partial<FormInputHandler>): FormInputHandler => {\n\treturn useMemo(() => {\n\t\tconst schema = field.schema\n\t\tconst columnType = schema.type\n\t\tconst handlerFactory = ColumnTypeHandlerFactories[columnType as SchemaKnownColumnType] ?? defaultHandlerFactory\n\t\tconst handler = handlerFactory(schema, field.getAccessor)\n\t\treturn {\n\t\t\tdefaultInputProps: handler.defaultInputProps,\n\t\t\tformatValue: formatValue ?? handler.formatValue,\n\t\t\tparseValue: parseValue ?? handler.parseValue,\n\t\t}\n\t}, [field.getAccessor, field.schema, formatValue, parseValue])\n}\n\ntype ColumnTypeHandlerFactory = (column: SchemaColumn, getAccessor: FieldAccessor.GetFieldAccessor) => FormInputHandler<any>\n\nconst defaultHandlerFactory: ColumnTypeHandlerFactory = (schema, field) => ({\n\tparseValue: (value: string) => {\n\t\tif (value === '' && schema.nullable && field().valueOnServer === null) {\n\t\t\treturn null\n\t\t}\n\t\treturn value\n\t},\n\tformatValue: (value: string | null) => value ?? '',\n})\n\nconst ColumnTypeHandlerFactories: Record<SchemaKnownColumnType, ColumnTypeHandlerFactory | undefined> = {\n\tString: defaultHandlerFactory,\n\tInteger: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseInt(value, 10)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\tDouble: (): FormInputHandler<{ rawValue: string; parsedValue: number | null }> => ({\n\t\tparseValue: (value: string, ctx) => {\n\t\t\tif (value === '') {\n\t\t\t\tctx.setState({ rawValue: '', parsedValue: null })\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseFloat(value)\n\t\t\tconst parsedValue = isNaN(parsed) ? null : parsed\n\t\t\tctx.setState({ rawValue: value, parsedValue })\n\t\t\treturn parsedValue\n\t\t},\n\t\tformatValue: (value: number | null, ctx) => {\n\t\t\tif (value === ctx.state?.parsedValue) {\n\t\t\t\treturn ctx.state.rawValue\n\t\t\t}\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\n\tDate: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString().split('T')[0]\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : new Date(parsed).toISOString().split('T')[0]\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'date',\n\t\t},\n\t}),\n\tDateTime: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString()\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : toLocalDate(new Date(parsed))\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'datetime-local',\n\t\t},\n\t}),\n\tBool: undefined,\n\tEnum: undefined,\n\tUuid: undefined,\n}\n\nconst toLocalDate = (date: Date) => {\n\tconst pad = (num: number, length: number = 2) => {\n\t\tconst str = num.toString()\n\t\treturn '0'.repeat(Math.max(0, length - str.length)) + str\n\t}\n\n\treturn pad(date.getFullYear(), 4) +\n\t\t'-' + pad(date.getMonth() + 1) +\n\t\t'-' + pad(date.getDate()) +\n\t\t'T' + pad(date.getHours()) +\n\t\t':' + pad(date.getMinutes()) +\n\t\t':' + pad(date.getSeconds())\n}\n"],"names":["useMemo"],"mappings":"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"}
@@ -39,14 +39,20 @@ const ColumnTypeHandlerFactories = {
39
39
  }
40
40
  }),
41
41
  Double: () => ({
42
- parseValue: (value) => {
42
+ parseValue: (value, ctx) => {
43
43
  if (value === "") {
44
+ ctx.setState({ rawValue: "", parsedValue: null });
44
45
  return null;
45
46
  }
46
47
  const parsed = parseFloat(value);
47
- return isNaN(parsed) ? null : parsed;
48
+ const parsedValue = isNaN(parsed) ? null : parsed;
49
+ ctx.setState({ rawValue: value, parsedValue });
50
+ return parsedValue;
48
51
  },
49
- formatValue: (value) => {
52
+ formatValue: (value, ctx) => {
53
+ if (value === ctx.state?.parsedValue) {
54
+ return ctx.state.rawValue;
55
+ }
50
56
  return value === null ? "" : value.toString(10);
51
57
  },
52
58
  defaultInputProps: {
@@ -1 +1 @@
1
- {"version":3,"file":"useFormInputHandler.js","sources":["../../../../../packages/react-form/src/internal/useFormInputHandler.ts"],"sourcesContent":["import { FieldAccessor, SchemaColumn, SchemaKnownColumnType } from '@contember/react-binding'\nimport { useMemo } from 'react'\nimport { FormInputHandler } from '../types'\n\nexport const useFormInputHandler = (field: FieldAccessor, { formatValue, parseValue }: Partial<FormInputHandler>): FormInputHandler => {\n\treturn useMemo(() => {\n\t\tconst schema = field.schema\n\t\tconst columnType = schema.type\n\t\tconst handlerFactory = ColumnTypeHandlerFactories[columnType as SchemaKnownColumnType] ?? defaultHandlerFactory\n\t\tconst handler = handlerFactory(schema, field.getAccessor)\n\t\treturn {\n\t\t\tdefaultInputProps: handler.defaultInputProps,\n\t\t\tformatValue: formatValue ?? handler.formatValue,\n\t\t\tparseValue: parseValue ?? handler.parseValue,\n\t\t}\n\t}, [field.getAccessor, field.schema, formatValue, parseValue])\n}\n\ntype ColumnTypeHandlerFactory = (column: SchemaColumn, getAccessor: FieldAccessor.GetFieldAccessor) => FormInputHandler\n\nconst defaultHandlerFactory: ColumnTypeHandlerFactory = (schema, field) => ({\n\tparseValue: (value: string) => {\n\t\tif (value === '' && schema.nullable && field().valueOnServer === null) {\n\t\t\treturn null\n\t\t}\n\t\treturn value\n\t},\n\tformatValue: (value: string | null) => value ?? '',\n})\n\nconst ColumnTypeHandlerFactories: Record<SchemaKnownColumnType, ColumnTypeHandlerFactory | undefined> = {\n\tString: defaultHandlerFactory,\n\tInteger: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseInt(value, 10)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\tDouble: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseFloat(value)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\n\tDate: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString().split('T')[0]\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : new Date(parsed).toISOString().split('T')[0]\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'date',\n\t\t},\n\t}),\n\tDateTime: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString()\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : toLocalDate(new Date(parsed))\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'datetime-local',\n\t\t},\n\t}),\n\tBool: undefined,\n\tEnum: undefined,\n\tUuid: undefined,\n}\n\nconst toLocalDate = (date: Date) => {\n\tconst pad = (num: number, length: number = 2) => {\n\t\tconst str = num.toString()\n\t\treturn '0'.repeat(Math.max(0, length - str.length)) + str\n\t}\n\n\treturn pad(date.getFullYear(), 4) +\n\t\t'-' + pad(date.getMonth() + 1) +\n\t\t'-' + pad(date.getDate()) +\n\t\t'T' + pad(date.getHours()) +\n\t\t':' + pad(date.getMinutes()) +\n\t\t':' + pad(date.getSeconds())\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useFormInputHandler.js","sources":["../../../../../packages/react-form/src/internal/useFormInputHandler.ts"],"sourcesContent":["import { FieldAccessor, SchemaColumn, SchemaKnownColumnType } from '@contember/react-binding'\nimport { useMemo } from 'react'\nimport { FormInputHandler } from '../types'\n\nexport const useFormInputHandler = (field: FieldAccessor, { formatValue, parseValue }: Partial<FormInputHandler>): FormInputHandler => {\n\treturn useMemo(() => {\n\t\tconst schema = field.schema\n\t\tconst columnType = schema.type\n\t\tconst handlerFactory = ColumnTypeHandlerFactories[columnType as SchemaKnownColumnType] ?? defaultHandlerFactory\n\t\tconst handler = handlerFactory(schema, field.getAccessor)\n\t\treturn {\n\t\t\tdefaultInputProps: handler.defaultInputProps,\n\t\t\tformatValue: formatValue ?? handler.formatValue,\n\t\t\tparseValue: parseValue ?? handler.parseValue,\n\t\t}\n\t}, [field.getAccessor, field.schema, formatValue, parseValue])\n}\n\ntype ColumnTypeHandlerFactory = (column: SchemaColumn, getAccessor: FieldAccessor.GetFieldAccessor) => FormInputHandler<any>\n\nconst defaultHandlerFactory: ColumnTypeHandlerFactory = (schema, field) => ({\n\tparseValue: (value: string) => {\n\t\tif (value === '' && schema.nullable && field().valueOnServer === null) {\n\t\t\treturn null\n\t\t}\n\t\treturn value\n\t},\n\tformatValue: (value: string | null) => value ?? '',\n})\n\nconst ColumnTypeHandlerFactories: Record<SchemaKnownColumnType, ColumnTypeHandlerFactory | undefined> = {\n\tString: defaultHandlerFactory,\n\tInteger: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseInt(value, 10)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\tDouble: (): FormInputHandler<{ rawValue: string; parsedValue: number | null }> => ({\n\t\tparseValue: (value: string, ctx) => {\n\t\t\tif (value === '') {\n\t\t\t\tctx.setState({ rawValue: '', parsedValue: null })\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseFloat(value)\n\t\t\tconst parsedValue = isNaN(parsed) ? null : parsed\n\t\t\tctx.setState({ rawValue: value, parsedValue })\n\t\t\treturn parsedValue\n\t\t},\n\t\tformatValue: (value: number | null, ctx) => {\n\t\t\tif (value === ctx.state?.parsedValue) {\n\t\t\t\treturn ctx.state.rawValue\n\t\t\t}\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\n\tDate: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString().split('T')[0]\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : new Date(parsed).toISOString().split('T')[0]\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'date',\n\t\t},\n\t}),\n\tDateTime: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString()\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : toLocalDate(new Date(parsed))\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'datetime-local',\n\t\t},\n\t}),\n\tBool: undefined,\n\tEnum: undefined,\n\tUuid: undefined,\n}\n\nconst toLocalDate = (date: Date) => {\n\tconst pad = (num: number, length: number = 2) => {\n\t\tconst str = num.toString()\n\t\treturn '0'.repeat(Math.max(0, length - str.length)) + str\n\t}\n\n\treturn pad(date.getFullYear(), 4) +\n\t\t'-' + pad(date.getMonth() + 1) +\n\t\t'-' + pad(date.getDate()) +\n\t\t'T' + pad(date.getHours()) +\n\t\t':' + pad(date.getMinutes()) +\n\t\t':' + pad(date.getSeconds())\n}\n"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ const utilities = require("@contember/utilities");
8
8
  const useFormInputHandler = require("../internal/useFormInputHandler.cjs");
9
9
  const contexts = require("../contexts.cjs");
10
10
  const useFormInputValidationHandler = require("../hooks/useFormInputValidationHandler.cjs");
11
+ const reactUtils = require("@contember/react-utils");
11
12
  const SlotInput = reactSlot.Slot;
12
13
  const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {
13
14
  const accessor = reactBinding.useField(field);
@@ -16,6 +17,7 @@ const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, f
16
17
  const hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0;
17
18
  const dirty = formState?.dirty ?? accessor.hasUnpersistedChanges;
18
19
  const required = formState?.required ?? !accessor.schema.nullable;
20
+ const [state, setState] = React.useState(void 0);
19
21
  const { parseValue, formatValue, defaultInputProps } = useFormInputHandler.useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn });
20
22
  const accessorGetter = accessor.getAccessor;
21
23
  const { ref, onFocus, onBlur } = useFormInputValidationHandler.useFormInputValidationHandler(accessor);
@@ -23,15 +25,15 @@ const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, f
23
25
  SlotInput,
24
26
  {
25
27
  ref,
26
- value: formatValue(accessor.value),
28
+ value: formatValue(accessor.value, { state, setState }),
27
29
  "data-invalid": utilities.dataAttribute(hasErrors),
28
30
  "data-dirty": utilities.dataAttribute(dirty),
29
31
  "data-required": utilities.dataAttribute(required),
30
32
  onFocus,
31
33
  onBlur,
32
- onChange: React.useCallback((e) => {
33
- accessorGetter().updateValue(parseValue(e.target.value));
34
- }, [accessorGetter, parseValue]),
34
+ onChange: reactUtils.useReferentiallyStableCallback((e) => {
35
+ accessorGetter().updateValue(parseValue(e.target.value, { state, setState }));
36
+ }),
35
37
  ...defaultInputProps,
36
38
  id: id ? `${id}-input` : void 0,
37
39
  required,
@@ -1 +1 @@
1
- {"version":3,"file":"FormInput.cjs","sources":["../../../../../packages/react-form/src/components/FormInput.tsx"],"sourcesContent":["import * as React from 'react'\nimport { ChangeEventHandler, ComponentType, useCallback } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { Component, Field, OptionallyVariableFieldValue, SugaredRelativeSingleField, useField } from '@contember/react-binding'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormInputHandler } from '../internal/useFormInputHandler'\nimport { useFormFieldState } from '../contexts'\nimport { useFormInputValidationHandler } from '../hooks/useFormInputValidationHandler'\nimport { FormInputHandler } from '../types'\n\ntype InputProps = React.JSX.IntrinsicElements['input']\nconst SlotInput = Slot as ComponentType<InputProps>\n\nexport interface FormInputProps {\n\tfield: SugaredRelativeSingleField['field']\n\tisNonbearing?: boolean\n\tdefaultValue?: OptionallyVariableFieldValue\n\tchildren: React.ReactElement\n\tformatValue?: FormInputHandler['formatValue']\n\tparseValue?: FormInputHandler['parseValue']\n}\n\nexport const FormInput = Component<FormInputProps>(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {\n\tconst accessor = useField(field)\n\n\tconst formState = useFormFieldState()\n\tconst id = formState?.htmlId\n\tconst hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0\n\tconst dirty = formState?.dirty ?? accessor.hasUnpersistedChanges\n\tconst required = formState?.required ?? !accessor.schema.nullable\n\n\tconst { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn })\n\tconst accessorGetter = accessor.getAccessor\n\tconst { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor)\n\n\treturn (\n\t\t<SlotInput\n\t\t\tref={ref}\n\t\t\tvalue={formatValue(accessor.value)}\n\t\t\tdata-invalid={dataAttribute(hasErrors)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tdata-required={dataAttribute(required)}\n\t\t\tonFocus={onFocus}\n\t\t\tonBlur={onBlur}\n\t\t\tonChange={useCallback<ChangeEventHandler<HTMLInputElement>>(e => {\n\t\t\t\taccessorGetter().updateValue(parseValue(e.target.value))\n\t\t\t}, [accessorGetter, parseValue])}\n\t\t\t{...defaultInputProps}\n\t\t\tid={id ? `${id}-input` : undefined}\n\t\t\trequired={required}\n\t\t\t{...props}\n\t\t/>\n\t)\n}, ({ field, isNonbearing, defaultValue }) => {\n\treturn <Field field={field} isNonbearing={isNonbearing} defaultValue={defaultValue} />\n})\n"],"names":["Slot","Component","useField","useFormFieldState","useFormInputHandler","useFormInputValidationHandler","jsx","dataAttribute","useCallback","Field"],"mappings":";;;;;;;;;;AAWA,MAAM,YAAYA,UAAA;AAWX,MAAM,YAAYC,aAAA,UAA0B,CAAC,EAAE,OAAO,cAAc,cAAc,aAAa,eAAe,YAAY,cAAc,GAAG,YAAY;AACvJ,QAAA,WAAWC,sBAAS,KAAK;AAE/B,QAAM,YAAYC,SAAAA,kBAAkB;AACpC,QAAM,KAAK,WAAW;AAChB,QAAA,aAAa,WAAW,OAAO,UAAU,SAAS,QAAQ,QAAQ,UAAU,KAAK;AACjF,QAAA,QAAQ,WAAW,SAAS,SAAS;AAC3C,QAAM,WAAW,WAAW,YAAY,CAAC,SAAS,OAAO;AAEzD,QAAM,EAAE,YAAY,aAAa,kBAAsB,IAAAC,oBAAA,oBAAoB,UAAU,EAAE,aAAa,eAAe,YAAY,aAAA,CAAc;AAC7I,QAAM,iBAAiB,SAAS;AAChC,QAAM,EAAE,KAAK,SAAS,OAAO,IAAIC,8BAAAA,8BAA8B,QAAQ;AAGtE,SAAAC,2BAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA,OAAO,YAAY,SAAS,KAAK;AAAA,MACjC,gBAAcC,wBAAc,SAAS;AAAA,MACrC,cAAYA,wBAAc,KAAK;AAAA,MAC/B,iBAAeA,wBAAc,QAAQ;AAAA,MACrC;AAAA,MACA;AAAA,MACA,UAAUC,MAAAA,YAAkD,CAAK,MAAA;AAChE,uBAAA,EAAiB,YAAY,WAAW,EAAE,OAAO,KAAK,CAAC;AAAA,MAAA,GACrD,CAAC,gBAAgB,UAAU,CAAC;AAAA,MAC9B,GAAG;AAAA,MACJ,IAAI,KAAK,GAAG,EAAE,WAAW;AAAA,MACzB;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,EACL;AAEF,GAAG,CAAC,EAAE,OAAO,cAAc,mBAAmB;AAC7C,SAAQF,2BAAAA,IAAAG,aAAAA,OAAA,EAAM,OAAc,cAA4B,aAA4B,CAAA;AACrF,CAAC;;"}
1
+ {"version":3,"file":"FormInput.cjs","sources":["../../../../../packages/react-form/src/components/FormInput.tsx"],"sourcesContent":["import * as React from 'react'\nimport { ChangeEventHandler, ComponentType, useCallback, useState } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { Component, Field, OptionallyVariableFieldValue, SugaredRelativeSingleField, useField } from '@contember/react-binding'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormInputHandler } from '../internal/useFormInputHandler'\nimport { useFormFieldState } from '../contexts'\nimport { useFormInputValidationHandler } from '../hooks/useFormInputValidationHandler'\nimport { FormInputHandler } from '../types'\nimport { useReferentiallyStableCallback } from '@contember/react-utils'\n\ntype InputProps = React.JSX.IntrinsicElements['input']\nconst SlotInput = Slot as ComponentType<InputProps>\n\nexport interface FormInputProps {\n\tfield: SugaredRelativeSingleField['field']\n\tisNonbearing?: boolean\n\tdefaultValue?: OptionallyVariableFieldValue\n\tchildren: React.ReactElement\n\tformatValue?: FormInputHandler['formatValue']\n\tparseValue?: FormInputHandler['parseValue']\n}\n\nexport const FormInput = Component<FormInputProps>(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {\n\tconst accessor = useField(field)\n\n\tconst formState = useFormFieldState()\n\tconst id = formState?.htmlId\n\tconst hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0\n\tconst dirty = formState?.dirty ?? accessor.hasUnpersistedChanges\n\tconst required = formState?.required ?? !accessor.schema.nullable\n\n\tconst [state, setState] = useState<any>(undefined)\n\n\tconst { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn })\n\tconst accessorGetter = accessor.getAccessor\n\tconst { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor)\n\n\treturn (\n\t\t<SlotInput\n\t\t\tref={ref}\n\t\t\tvalue={formatValue(accessor.value, { state, setState })}\n\t\t\tdata-invalid={dataAttribute(hasErrors)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tdata-required={dataAttribute(required)}\n\t\t\tonFocus={onFocus}\n\t\t\tonBlur={onBlur}\n\t\t\tonChange={useReferentiallyStableCallback<ChangeEventHandler<HTMLInputElement>>(e => {\n\t\t\t\taccessorGetter().updateValue(parseValue(e.target.value, { state, setState }))\n\t\t\t})}\n\t\t\t{...defaultInputProps}\n\t\t\tid={id ? `${id}-input` : undefined}\n\t\t\trequired={required}\n\t\t\t{...props}\n\t\t/>\n\t)\n}, ({ field, isNonbearing, defaultValue }) => {\n\treturn <Field field={field} isNonbearing={isNonbearing} defaultValue={defaultValue} />\n})\n"],"names":["Slot","Component","useField","useFormFieldState","useState","useFormInputHandler","useFormInputValidationHandler","jsx","dataAttribute","useReferentiallyStableCallback","Field"],"mappings":";;;;;;;;;;;AAYA,MAAM,YAAYA,UAAA;AAWX,MAAM,YAAYC,aAAA,UAA0B,CAAC,EAAE,OAAO,cAAc,cAAc,aAAa,eAAe,YAAY,cAAc,GAAG,YAAY;AACvJ,QAAA,WAAWC,sBAAS,KAAK;AAE/B,QAAM,YAAYC,SAAAA,kBAAkB;AACpC,QAAM,KAAK,WAAW;AAChB,QAAA,aAAa,WAAW,OAAO,UAAU,SAAS,QAAQ,QAAQ,UAAU,KAAK;AACjF,QAAA,QAAQ,WAAW,SAAS,SAAS;AAC3C,QAAM,WAAW,WAAW,YAAY,CAAC,SAAS,OAAO;AAEzD,QAAM,CAAC,OAAO,QAAQ,IAAIC,eAAc,MAAS;AAEjD,QAAM,EAAE,YAAY,aAAa,kBAAsB,IAAAC,oBAAA,oBAAoB,UAAU,EAAE,aAAa,eAAe,YAAY,aAAA,CAAc;AAC7I,QAAM,iBAAiB,SAAS;AAChC,QAAM,EAAE,KAAK,SAAS,OAAO,IAAIC,8BAAAA,8BAA8B,QAAQ;AAGtE,SAAAC,2BAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA,OAAO,YAAY,SAAS,OAAO,EAAE,OAAO,UAAU;AAAA,MACtD,gBAAcC,wBAAc,SAAS;AAAA,MACrC,cAAYA,wBAAc,KAAK;AAAA,MAC/B,iBAAeA,wBAAc,QAAQ;AAAA,MACrC;AAAA,MACA;AAAA,MACA,UAAUC,WAAAA,+BAAqE,CAAK,MAAA;AACpE,uBAAA,EAAE,YAAY,WAAW,EAAE,OAAO,OAAO,EAAE,OAAO,SAAS,CAAC,CAAC;AAAA,MAAA,CAC5E;AAAA,MACA,GAAG;AAAA,MACJ,IAAI,KAAK,GAAG,EAAE,WAAW;AAAA,MACzB;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,EACL;AAEF,GAAG,CAAC,EAAE,OAAO,cAAc,mBAAmB;AAC7C,SAAQF,2BAAAA,IAAAG,aAAAA,OAAA,EAAM,OAAc,cAA4B,aAA4B,CAAA;AACrF,CAAC;;"}
@@ -1,11 +1,12 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { useCallback } from "react";
2
+ import { useState } from "react";
3
3
  import { Slot } from "@radix-ui/react-slot";
4
4
  import { Component, useField, Field } from "@contember/react-binding";
5
5
  import { dataAttribute } from "@contember/utilities";
6
6
  import { useFormInputHandler } from "../internal/useFormInputHandler.js";
7
7
  import { useFormFieldState } from "../contexts.js";
8
8
  import { useFormInputValidationHandler } from "../hooks/useFormInputValidationHandler.js";
9
+ import { useReferentiallyStableCallback } from "@contember/react-utils";
9
10
  const SlotInput = Slot;
10
11
  const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {
11
12
  const accessor = useField(field);
@@ -14,6 +15,7 @@ const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: f
14
15
  const hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0;
15
16
  const dirty = formState?.dirty ?? accessor.hasUnpersistedChanges;
16
17
  const required = formState?.required ?? !accessor.schema.nullable;
18
+ const [state, setState] = useState(void 0);
17
19
  const { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn });
18
20
  const accessorGetter = accessor.getAccessor;
19
21
  const { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor);
@@ -21,15 +23,15 @@ const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: f
21
23
  SlotInput,
22
24
  {
23
25
  ref,
24
- value: formatValue(accessor.value),
26
+ value: formatValue(accessor.value, { state, setState }),
25
27
  "data-invalid": dataAttribute(hasErrors),
26
28
  "data-dirty": dataAttribute(dirty),
27
29
  "data-required": dataAttribute(required),
28
30
  onFocus,
29
31
  onBlur,
30
- onChange: useCallback((e) => {
31
- accessorGetter().updateValue(parseValue(e.target.value));
32
- }, [accessorGetter, parseValue]),
32
+ onChange: useReferentiallyStableCallback((e) => {
33
+ accessorGetter().updateValue(parseValue(e.target.value, { state, setState }));
34
+ }),
33
35
  ...defaultInputProps,
34
36
  id: id ? `${id}-input` : void 0,
35
37
  required,
@@ -1 +1 @@
1
- {"version":3,"file":"FormInput.js","sources":["../../../../../packages/react-form/src/components/FormInput.tsx"],"sourcesContent":["import * as React from 'react'\nimport { ChangeEventHandler, ComponentType, useCallback } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { Component, Field, OptionallyVariableFieldValue, SugaredRelativeSingleField, useField } from '@contember/react-binding'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormInputHandler } from '../internal/useFormInputHandler'\nimport { useFormFieldState } from '../contexts'\nimport { useFormInputValidationHandler } from '../hooks/useFormInputValidationHandler'\nimport { FormInputHandler } from '../types'\n\ntype InputProps = React.JSX.IntrinsicElements['input']\nconst SlotInput = Slot as ComponentType<InputProps>\n\nexport interface FormInputProps {\n\tfield: SugaredRelativeSingleField['field']\n\tisNonbearing?: boolean\n\tdefaultValue?: OptionallyVariableFieldValue\n\tchildren: React.ReactElement\n\tformatValue?: FormInputHandler['formatValue']\n\tparseValue?: FormInputHandler['parseValue']\n}\n\nexport const FormInput = Component<FormInputProps>(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {\n\tconst accessor = useField(field)\n\n\tconst formState = useFormFieldState()\n\tconst id = formState?.htmlId\n\tconst hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0\n\tconst dirty = formState?.dirty ?? accessor.hasUnpersistedChanges\n\tconst required = formState?.required ?? !accessor.schema.nullable\n\n\tconst { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn })\n\tconst accessorGetter = accessor.getAccessor\n\tconst { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor)\n\n\treturn (\n\t\t<SlotInput\n\t\t\tref={ref}\n\t\t\tvalue={formatValue(accessor.value)}\n\t\t\tdata-invalid={dataAttribute(hasErrors)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tdata-required={dataAttribute(required)}\n\t\t\tonFocus={onFocus}\n\t\t\tonBlur={onBlur}\n\t\t\tonChange={useCallback<ChangeEventHandler<HTMLInputElement>>(e => {\n\t\t\t\taccessorGetter().updateValue(parseValue(e.target.value))\n\t\t\t}, [accessorGetter, parseValue])}\n\t\t\t{...defaultInputProps}\n\t\t\tid={id ? `${id}-input` : undefined}\n\t\t\trequired={required}\n\t\t\t{...props}\n\t\t/>\n\t)\n}, ({ field, isNonbearing, defaultValue }) => {\n\treturn <Field field={field} isNonbearing={isNonbearing} defaultValue={defaultValue} />\n})\n"],"names":[],"mappings":";;;;;;;;AAWA,MAAM,YAAY;AAWX,MAAM,YAAY,UAA0B,CAAC,EAAE,OAAO,cAAc,cAAc,aAAa,eAAe,YAAY,cAAc,GAAG,YAAY;AACvJ,QAAA,WAAW,SAAS,KAAK;AAE/B,QAAM,YAAY,kBAAkB;AACpC,QAAM,KAAK,WAAW;AAChB,QAAA,aAAa,WAAW,OAAO,UAAU,SAAS,QAAQ,QAAQ,UAAU,KAAK;AACjF,QAAA,QAAQ,WAAW,SAAS,SAAS;AAC3C,QAAM,WAAW,WAAW,YAAY,CAAC,SAAS,OAAO;AAEzD,QAAM,EAAE,YAAY,aAAa,kBAAsB,IAAA,oBAAoB,UAAU,EAAE,aAAa,eAAe,YAAY,aAAA,CAAc;AAC7I,QAAM,iBAAiB,SAAS;AAChC,QAAM,EAAE,KAAK,SAAS,OAAO,IAAI,8BAA8B,QAAQ;AAGtE,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA,OAAO,YAAY,SAAS,KAAK;AAAA,MACjC,gBAAc,cAAc,SAAS;AAAA,MACrC,cAAY,cAAc,KAAK;AAAA,MAC/B,iBAAe,cAAc,QAAQ;AAAA,MACrC;AAAA,MACA;AAAA,MACA,UAAU,YAAkD,CAAK,MAAA;AAChE,uBAAA,EAAiB,YAAY,WAAW,EAAE,OAAO,KAAK,CAAC;AAAA,MAAA,GACrD,CAAC,gBAAgB,UAAU,CAAC;AAAA,MAC9B,GAAG;AAAA,MACJ,IAAI,KAAK,GAAG,EAAE,WAAW;AAAA,MACzB;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,EACL;AAEF,GAAG,CAAC,EAAE,OAAO,cAAc,mBAAmB;AAC7C,SAAQ,oBAAA,OAAA,EAAM,OAAc,cAA4B,aAA4B,CAAA;AACrF,CAAC;"}
1
+ {"version":3,"file":"FormInput.js","sources":["../../../../../packages/react-form/src/components/FormInput.tsx"],"sourcesContent":["import * as React from 'react'\nimport { ChangeEventHandler, ComponentType, useCallback, useState } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { Component, Field, OptionallyVariableFieldValue, SugaredRelativeSingleField, useField } from '@contember/react-binding'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormInputHandler } from '../internal/useFormInputHandler'\nimport { useFormFieldState } from '../contexts'\nimport { useFormInputValidationHandler } from '../hooks/useFormInputValidationHandler'\nimport { FormInputHandler } from '../types'\nimport { useReferentiallyStableCallback } from '@contember/react-utils'\n\ntype InputProps = React.JSX.IntrinsicElements['input']\nconst SlotInput = Slot as ComponentType<InputProps>\n\nexport interface FormInputProps {\n\tfield: SugaredRelativeSingleField['field']\n\tisNonbearing?: boolean\n\tdefaultValue?: OptionallyVariableFieldValue\n\tchildren: React.ReactElement\n\tformatValue?: FormInputHandler['formatValue']\n\tparseValue?: FormInputHandler['parseValue']\n}\n\nexport const FormInput = Component<FormInputProps>(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {\n\tconst accessor = useField(field)\n\n\tconst formState = useFormFieldState()\n\tconst id = formState?.htmlId\n\tconst hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0\n\tconst dirty = formState?.dirty ?? accessor.hasUnpersistedChanges\n\tconst required = formState?.required ?? !accessor.schema.nullable\n\n\tconst [state, setState] = useState<any>(undefined)\n\n\tconst { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn })\n\tconst accessorGetter = accessor.getAccessor\n\tconst { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor)\n\n\treturn (\n\t\t<SlotInput\n\t\t\tref={ref}\n\t\t\tvalue={formatValue(accessor.value, { state, setState })}\n\t\t\tdata-invalid={dataAttribute(hasErrors)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tdata-required={dataAttribute(required)}\n\t\t\tonFocus={onFocus}\n\t\t\tonBlur={onBlur}\n\t\t\tonChange={useReferentiallyStableCallback<ChangeEventHandler<HTMLInputElement>>(e => {\n\t\t\t\taccessorGetter().updateValue(parseValue(e.target.value, { state, setState }))\n\t\t\t})}\n\t\t\t{...defaultInputProps}\n\t\t\tid={id ? `${id}-input` : undefined}\n\t\t\trequired={required}\n\t\t\t{...props}\n\t\t/>\n\t)\n}, ({ field, isNonbearing, defaultValue }) => {\n\treturn <Field field={field} isNonbearing={isNonbearing} defaultValue={defaultValue} />\n})\n"],"names":[],"mappings":";;;;;;;;;AAYA,MAAM,YAAY;AAWX,MAAM,YAAY,UAA0B,CAAC,EAAE,OAAO,cAAc,cAAc,aAAa,eAAe,YAAY,cAAc,GAAG,YAAY;AACvJ,QAAA,WAAW,SAAS,KAAK;AAE/B,QAAM,YAAY,kBAAkB;AACpC,QAAM,KAAK,WAAW;AAChB,QAAA,aAAa,WAAW,OAAO,UAAU,SAAS,QAAQ,QAAQ,UAAU,KAAK;AACjF,QAAA,QAAQ,WAAW,SAAS,SAAS;AAC3C,QAAM,WAAW,WAAW,YAAY,CAAC,SAAS,OAAO;AAEzD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAc,MAAS;AAEjD,QAAM,EAAE,YAAY,aAAa,kBAAsB,IAAA,oBAAoB,UAAU,EAAE,aAAa,eAAe,YAAY,aAAA,CAAc;AAC7I,QAAM,iBAAiB,SAAS;AAChC,QAAM,EAAE,KAAK,SAAS,OAAO,IAAI,8BAA8B,QAAQ;AAGtE,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA,OAAO,YAAY,SAAS,OAAO,EAAE,OAAO,UAAU;AAAA,MACtD,gBAAc,cAAc,SAAS;AAAA,MACrC,cAAY,cAAc,KAAK;AAAA,MAC/B,iBAAe,cAAc,QAAQ;AAAA,MACrC;AAAA,MACA;AAAA,MACA,UAAU,+BAAqE,CAAK,MAAA;AACpE,uBAAA,EAAE,YAAY,WAAW,EAAE,OAAO,OAAO,EAAE,OAAO,SAAS,CAAC,CAAC;AAAA,MAAA,CAC5E;AAAA,MACA,GAAG;AAAA,MACJ,IAAI,KAAK,GAAG,EAAE,WAAW;AAAA,MACzB;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,EACL;AAEF,GAAG,CAAC,EAAE,OAAO,cAAc,mBAAmB;AAC7C,SAAQ,oBAAA,OAAA,EAAM,OAAc,cAA4B,aAA4B,CAAA;AACrF,CAAC;"}
@@ -41,14 +41,20 @@ const ColumnTypeHandlerFactories = {
41
41
  }
42
42
  }),
43
43
  Double: () => ({
44
- parseValue: (value) => {
44
+ parseValue: (value, ctx) => {
45
45
  if (value === "") {
46
+ ctx.setState({ rawValue: "", parsedValue: null });
46
47
  return null;
47
48
  }
48
49
  const parsed = parseFloat(value);
49
- return isNaN(parsed) ? null : parsed;
50
+ const parsedValue = isNaN(parsed) ? null : parsed;
51
+ ctx.setState({ rawValue: value, parsedValue });
52
+ return parsedValue;
50
53
  },
51
- formatValue: (value) => {
54
+ formatValue: (value, ctx) => {
55
+ if (value === ctx.state?.parsedValue) {
56
+ return ctx.state.rawValue;
57
+ }
52
58
  return value === null ? "" : value.toString(10);
53
59
  },
54
60
  defaultInputProps: {
@@ -1 +1 @@
1
- {"version":3,"file":"useFormInputHandler.cjs","sources":["../../../../../packages/react-form/src/internal/useFormInputHandler.ts"],"sourcesContent":["import { FieldAccessor, SchemaColumn, SchemaKnownColumnType } from '@contember/react-binding'\nimport { useMemo } from 'react'\nimport { FormInputHandler } from '../types'\n\nexport const useFormInputHandler = (field: FieldAccessor, { formatValue, parseValue }: Partial<FormInputHandler>): FormInputHandler => {\n\treturn useMemo(() => {\n\t\tconst schema = field.schema\n\t\tconst columnType = schema.type\n\t\tconst handlerFactory = ColumnTypeHandlerFactories[columnType as SchemaKnownColumnType] ?? defaultHandlerFactory\n\t\tconst handler = handlerFactory(schema, field.getAccessor)\n\t\treturn {\n\t\t\tdefaultInputProps: handler.defaultInputProps,\n\t\t\tformatValue: formatValue ?? handler.formatValue,\n\t\t\tparseValue: parseValue ?? handler.parseValue,\n\t\t}\n\t}, [field.getAccessor, field.schema, formatValue, parseValue])\n}\n\ntype ColumnTypeHandlerFactory = (column: SchemaColumn, getAccessor: FieldAccessor.GetFieldAccessor) => FormInputHandler\n\nconst defaultHandlerFactory: ColumnTypeHandlerFactory = (schema, field) => ({\n\tparseValue: (value: string) => {\n\t\tif (value === '' && schema.nullable && field().valueOnServer === null) {\n\t\t\treturn null\n\t\t}\n\t\treturn value\n\t},\n\tformatValue: (value: string | null) => value ?? '',\n})\n\nconst ColumnTypeHandlerFactories: Record<SchemaKnownColumnType, ColumnTypeHandlerFactory | undefined> = {\n\tString: defaultHandlerFactory,\n\tInteger: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseInt(value, 10)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\tDouble: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseFloat(value)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\n\tDate: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString().split('T')[0]\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : new Date(parsed).toISOString().split('T')[0]\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'date',\n\t\t},\n\t}),\n\tDateTime: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString()\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : toLocalDate(new Date(parsed))\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'datetime-local',\n\t\t},\n\t}),\n\tBool: undefined,\n\tEnum: undefined,\n\tUuid: undefined,\n}\n\nconst toLocalDate = (date: Date) => {\n\tconst pad = (num: number, length: number = 2) => {\n\t\tconst str = num.toString()\n\t\treturn '0'.repeat(Math.max(0, length - str.length)) + str\n\t}\n\n\treturn pad(date.getFullYear(), 4) +\n\t\t'-' + pad(date.getMonth() + 1) +\n\t\t'-' + pad(date.getDate()) +\n\t\t'T' + pad(date.getHours()) +\n\t\t':' + pad(date.getMinutes()) +\n\t\t':' + pad(date.getSeconds())\n}\n"],"names":["useMemo"],"mappings":"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"}
1
+ {"version":3,"file":"useFormInputHandler.cjs","sources":["../../../../../packages/react-form/src/internal/useFormInputHandler.ts"],"sourcesContent":["import { FieldAccessor, SchemaColumn, SchemaKnownColumnType } from '@contember/react-binding'\nimport { useMemo } from 'react'\nimport { FormInputHandler } from '../types'\n\nexport const useFormInputHandler = (field: FieldAccessor, { formatValue, parseValue }: Partial<FormInputHandler>): FormInputHandler => {\n\treturn useMemo(() => {\n\t\tconst schema = field.schema\n\t\tconst columnType = schema.type\n\t\tconst handlerFactory = ColumnTypeHandlerFactories[columnType as SchemaKnownColumnType] ?? defaultHandlerFactory\n\t\tconst handler = handlerFactory(schema, field.getAccessor)\n\t\treturn {\n\t\t\tdefaultInputProps: handler.defaultInputProps,\n\t\t\tformatValue: formatValue ?? handler.formatValue,\n\t\t\tparseValue: parseValue ?? handler.parseValue,\n\t\t}\n\t}, [field.getAccessor, field.schema, formatValue, parseValue])\n}\n\ntype ColumnTypeHandlerFactory = (column: SchemaColumn, getAccessor: FieldAccessor.GetFieldAccessor) => FormInputHandler<any>\n\nconst defaultHandlerFactory: ColumnTypeHandlerFactory = (schema, field) => ({\n\tparseValue: (value: string) => {\n\t\tif (value === '' && schema.nullable && field().valueOnServer === null) {\n\t\t\treturn null\n\t\t}\n\t\treturn value\n\t},\n\tformatValue: (value: string | null) => value ?? '',\n})\n\nconst ColumnTypeHandlerFactories: Record<SchemaKnownColumnType, ColumnTypeHandlerFactory | undefined> = {\n\tString: defaultHandlerFactory,\n\tInteger: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseInt(value, 10)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\tDouble: (): FormInputHandler<{ rawValue: string; parsedValue: number | null }> => ({\n\t\tparseValue: (value: string, ctx) => {\n\t\t\tif (value === '') {\n\t\t\t\tctx.setState({ rawValue: '', parsedValue: null })\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseFloat(value)\n\t\t\tconst parsedValue = isNaN(parsed) ? null : parsed\n\t\t\tctx.setState({ rawValue: value, parsedValue })\n\t\t\treturn parsedValue\n\t\t},\n\t\tformatValue: (value: number | null, ctx) => {\n\t\t\tif (value === ctx.state?.parsedValue) {\n\t\t\t\treturn ctx.state.rawValue\n\t\t\t}\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\n\tDate: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString().split('T')[0]\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : new Date(parsed).toISOString().split('T')[0]\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'date',\n\t\t},\n\t}),\n\tDateTime: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString()\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : toLocalDate(new Date(parsed))\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'datetime-local',\n\t\t},\n\t}),\n\tBool: undefined,\n\tEnum: undefined,\n\tUuid: undefined,\n}\n\nconst toLocalDate = (date: Date) => {\n\tconst pad = (num: number, length: number = 2) => {\n\t\tconst str = num.toString()\n\t\treturn '0'.repeat(Math.max(0, length - str.length)) + str\n\t}\n\n\treturn pad(date.getFullYear(), 4) +\n\t\t'-' + pad(date.getMonth() + 1) +\n\t\t'-' + pad(date.getDate()) +\n\t\t'T' + pad(date.getHours()) +\n\t\t':' + pad(date.getMinutes()) +\n\t\t':' + pad(date.getSeconds())\n}\n"],"names":["useMemo"],"mappings":"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"}
@@ -39,14 +39,20 @@ const ColumnTypeHandlerFactories = {
39
39
  }
40
40
  }),
41
41
  Double: () => ({
42
- parseValue: (value) => {
42
+ parseValue: (value, ctx) => {
43
43
  if (value === "") {
44
+ ctx.setState({ rawValue: "", parsedValue: null });
44
45
  return null;
45
46
  }
46
47
  const parsed = parseFloat(value);
47
- return isNaN(parsed) ? null : parsed;
48
+ const parsedValue = isNaN(parsed) ? null : parsed;
49
+ ctx.setState({ rawValue: value, parsedValue });
50
+ return parsedValue;
48
51
  },
49
- formatValue: (value) => {
52
+ formatValue: (value, ctx) => {
53
+ if (value === ctx.state?.parsedValue) {
54
+ return ctx.state.rawValue;
55
+ }
50
56
  return value === null ? "" : value.toString(10);
51
57
  },
52
58
  defaultInputProps: {
@@ -1 +1 @@
1
- {"version":3,"file":"useFormInputHandler.js","sources":["../../../../../packages/react-form/src/internal/useFormInputHandler.ts"],"sourcesContent":["import { FieldAccessor, SchemaColumn, SchemaKnownColumnType } from '@contember/react-binding'\nimport { useMemo } from 'react'\nimport { FormInputHandler } from '../types'\n\nexport const useFormInputHandler = (field: FieldAccessor, { formatValue, parseValue }: Partial<FormInputHandler>): FormInputHandler => {\n\treturn useMemo(() => {\n\t\tconst schema = field.schema\n\t\tconst columnType = schema.type\n\t\tconst handlerFactory = ColumnTypeHandlerFactories[columnType as SchemaKnownColumnType] ?? defaultHandlerFactory\n\t\tconst handler = handlerFactory(schema, field.getAccessor)\n\t\treturn {\n\t\t\tdefaultInputProps: handler.defaultInputProps,\n\t\t\tformatValue: formatValue ?? handler.formatValue,\n\t\t\tparseValue: parseValue ?? handler.parseValue,\n\t\t}\n\t}, [field.getAccessor, field.schema, formatValue, parseValue])\n}\n\ntype ColumnTypeHandlerFactory = (column: SchemaColumn, getAccessor: FieldAccessor.GetFieldAccessor) => FormInputHandler\n\nconst defaultHandlerFactory: ColumnTypeHandlerFactory = (schema, field) => ({\n\tparseValue: (value: string) => {\n\t\tif (value === '' && schema.nullable && field().valueOnServer === null) {\n\t\t\treturn null\n\t\t}\n\t\treturn value\n\t},\n\tformatValue: (value: string | null) => value ?? '',\n})\n\nconst ColumnTypeHandlerFactories: Record<SchemaKnownColumnType, ColumnTypeHandlerFactory | undefined> = {\n\tString: defaultHandlerFactory,\n\tInteger: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseInt(value, 10)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\tDouble: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseFloat(value)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\n\tDate: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString().split('T')[0]\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : new Date(parsed).toISOString().split('T')[0]\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'date',\n\t\t},\n\t}),\n\tDateTime: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString()\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : toLocalDate(new Date(parsed))\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'datetime-local',\n\t\t},\n\t}),\n\tBool: undefined,\n\tEnum: undefined,\n\tUuid: undefined,\n}\n\nconst toLocalDate = (date: Date) => {\n\tconst pad = (num: number, length: number = 2) => {\n\t\tconst str = num.toString()\n\t\treturn '0'.repeat(Math.max(0, length - str.length)) + str\n\t}\n\n\treturn pad(date.getFullYear(), 4) +\n\t\t'-' + pad(date.getMonth() + 1) +\n\t\t'-' + pad(date.getDate()) +\n\t\t'T' + pad(date.getHours()) +\n\t\t':' + pad(date.getMinutes()) +\n\t\t':' + pad(date.getSeconds())\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useFormInputHandler.js","sources":["../../../../../packages/react-form/src/internal/useFormInputHandler.ts"],"sourcesContent":["import { FieldAccessor, SchemaColumn, SchemaKnownColumnType } from '@contember/react-binding'\nimport { useMemo } from 'react'\nimport { FormInputHandler } from '../types'\n\nexport const useFormInputHandler = (field: FieldAccessor, { formatValue, parseValue }: Partial<FormInputHandler>): FormInputHandler => {\n\treturn useMemo(() => {\n\t\tconst schema = field.schema\n\t\tconst columnType = schema.type\n\t\tconst handlerFactory = ColumnTypeHandlerFactories[columnType as SchemaKnownColumnType] ?? defaultHandlerFactory\n\t\tconst handler = handlerFactory(schema, field.getAccessor)\n\t\treturn {\n\t\t\tdefaultInputProps: handler.defaultInputProps,\n\t\t\tformatValue: formatValue ?? handler.formatValue,\n\t\t\tparseValue: parseValue ?? handler.parseValue,\n\t\t}\n\t}, [field.getAccessor, field.schema, formatValue, parseValue])\n}\n\ntype ColumnTypeHandlerFactory = (column: SchemaColumn, getAccessor: FieldAccessor.GetFieldAccessor) => FormInputHandler<any>\n\nconst defaultHandlerFactory: ColumnTypeHandlerFactory = (schema, field) => ({\n\tparseValue: (value: string) => {\n\t\tif (value === '' && schema.nullable && field().valueOnServer === null) {\n\t\t\treturn null\n\t\t}\n\t\treturn value\n\t},\n\tformatValue: (value: string | null) => value ?? '',\n})\n\nconst ColumnTypeHandlerFactories: Record<SchemaKnownColumnType, ColumnTypeHandlerFactory | undefined> = {\n\tString: defaultHandlerFactory,\n\tInteger: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseInt(value, 10)\n\t\t\treturn isNaN(parsed) ? null : parsed\n\t\t},\n\t\tformatValue: (value: number | null) => {\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\tDouble: (): FormInputHandler<{ rawValue: string; parsedValue: number | null }> => ({\n\t\tparseValue: (value: string, ctx) => {\n\t\t\tif (value === '') {\n\t\t\t\tctx.setState({ rawValue: '', parsedValue: null })\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = parseFloat(value)\n\t\t\tconst parsedValue = isNaN(parsed) ? null : parsed\n\t\t\tctx.setState({ rawValue: value, parsedValue })\n\t\t\treturn parsedValue\n\t\t},\n\t\tformatValue: (value: number | null, ctx) => {\n\t\t\tif (value === ctx.state?.parsedValue) {\n\t\t\t\treturn ctx.state.rawValue\n\t\t\t}\n\t\t\treturn value === null ? '' : value.toString(10)\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'number',\n\t\t},\n\t}),\n\n\tDate: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString().split('T')[0]\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : new Date(parsed).toISOString().split('T')[0]\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'date',\n\t\t},\n\t}),\n\tDateTime: () => ({\n\t\tparseValue: (value: string) => {\n\t\t\tif (value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst parsed = Date.parse(value)\n\t\t\treturn isNaN(parsed) ? null : (new Date(parsed)).toISOString()\n\t\t},\n\t\tformatValue: (value: string | null) => {\n\t\t\tconst parsed = value ? Date.parse(value) : null\n\t\t\treturn !parsed || isNaN(parsed) ? '' : toLocalDate(new Date(parsed))\n\t\t},\n\t\tdefaultInputProps: {\n\t\t\ttype: 'datetime-local',\n\t\t},\n\t}),\n\tBool: undefined,\n\tEnum: undefined,\n\tUuid: undefined,\n}\n\nconst toLocalDate = (date: Date) => {\n\tconst pad = (num: number, length: number = 2) => {\n\t\tconst str = num.toString()\n\t\treturn '0'.repeat(Math.max(0, length - str.length)) + str\n\t}\n\n\treturn pad(date.getFullYear(), 4) +\n\t\t'-' + pad(date.getMonth() + 1) +\n\t\t'-' + pad(date.getDate()) +\n\t\t'T' + pad(date.getHours()) +\n\t\t':' + pad(date.getMinutes()) +\n\t\t':' + pad(date.getSeconds())\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FormInput.d.ts","sourceRoot":"","sources":["../../../src/components/FormInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,EAAoB,4BAA4B,EAAE,0BAA0B,EAAY,MAAM,0BAA0B,CAAA;AAK/H,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAK3C,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,0BAA0B,CAAC,OAAO,CAAC,CAAA;IAC1C,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,YAAY,CAAC,EAAE,4BAA4B,CAAA;IAC3C,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAA;IAC5B,WAAW,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAA;IAC7C,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAA;CAC3C;AAED,eAAO,MAAM,SAAS,4CAiCpB,CAAA"}
1
+ {"version":3,"file":"FormInput.d.ts","sourceRoot":"","sources":["../../../src/components/FormInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,EAAoB,4BAA4B,EAAE,0BAA0B,EAAY,MAAM,0BAA0B,CAAA;AAK/H,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAM3C,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,0BAA0B,CAAC,OAAO,CAAC,CAAA;IAC1C,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,YAAY,CAAC,EAAE,4BAA4B,CAAA;IAC3C,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAA;IAC5B,WAAW,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAA;IAC7C,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAA;CAC3C;AAED,eAAO,MAAM,SAAS,4CAmCpB,CAAA"}