@contember/react-form 2.0.0-alpha.9 → 2.0.0-beta.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 (137) hide show
  1. package/dist/development/index.cjs +6 -2
  2. package/dist/development/index.cjs.map +1 -1
  3. package/dist/development/index.js +5 -1
  4. package/dist/development/index.js.map +1 -1
  5. package/dist/development/src/components/FormCheckbox.cjs +9 -6
  6. package/dist/development/src/components/FormCheckbox.cjs.map +1 -1
  7. package/dist/development/src/components/FormCheckbox.js +10 -7
  8. package/dist/development/src/components/FormCheckbox.js.map +1 -1
  9. package/dist/development/src/components/FormError.cjs +5 -5
  10. package/dist/development/src/components/FormError.cjs.map +1 -1
  11. package/dist/development/src/components/FormError.js +6 -6
  12. package/dist/development/src/components/FormError.js.map +1 -1
  13. package/dist/development/src/components/FormFieldScope.cjs +24 -14
  14. package/dist/development/src/components/FormFieldScope.cjs.map +1 -1
  15. package/dist/development/src/components/FormFieldScope.js +25 -15
  16. package/dist/development/src/components/FormFieldScope.js.map +1 -1
  17. package/dist/development/src/components/FormFieldStateProvider.cjs +56 -0
  18. package/dist/development/src/components/FormFieldStateProvider.cjs.map +1 -0
  19. package/dist/development/src/components/FormFieldStateProvider.js +56 -0
  20. package/dist/development/src/components/FormFieldStateProvider.js.map +1 -0
  21. package/dist/development/src/components/FormHasManyRelationScope.cjs +25 -15
  22. package/dist/development/src/components/FormHasManyRelationScope.cjs.map +1 -1
  23. package/dist/development/src/components/FormHasManyRelationScope.js +26 -16
  24. package/dist/development/src/components/FormHasManyRelationScope.js.map +1 -1
  25. package/dist/development/src/components/FormHasOneRelationScope.cjs +25 -15
  26. package/dist/development/src/components/FormHasOneRelationScope.cjs.map +1 -1
  27. package/dist/development/src/components/FormHasOneRelationScope.js +25 -15
  28. package/dist/development/src/components/FormHasOneRelationScope.js.map +1 -1
  29. package/dist/development/src/components/FormInput.cjs +11 -6
  30. package/dist/development/src/components/FormInput.cjs.map +1 -1
  31. package/dist/development/src/components/FormInput.js +12 -7
  32. package/dist/development/src/components/FormInput.js.map +1 -1
  33. package/dist/development/src/components/FormLabel.cjs +7 -5
  34. package/dist/development/src/components/FormLabel.cjs.map +1 -1
  35. package/dist/development/src/components/FormLabel.js +8 -6
  36. package/dist/development/src/components/FormLabel.js.map +1 -1
  37. package/dist/development/src/components/FormRadioInput.cjs +17 -13
  38. package/dist/development/src/components/FormRadioInput.cjs.map +1 -1
  39. package/dist/development/src/components/FormRadioInput.js +18 -14
  40. package/dist/development/src/components/FormRadioInput.js.map +1 -1
  41. package/dist/development/src/contexts.cjs +7 -8
  42. package/dist/development/src/contexts.cjs.map +1 -1
  43. package/dist/development/src/contexts.js +8 -9
  44. package/dist/development/src/contexts.js.map +1 -1
  45. package/dist/development/src/hooks/useFormInputValidationHandler.cjs +12 -3
  46. package/dist/development/src/hooks/useFormInputValidationHandler.cjs.map +1 -1
  47. package/dist/development/src/hooks/useFormInputValidationHandler.js +12 -3
  48. package/dist/development/src/hooks/useFormInputValidationHandler.js.map +1 -1
  49. package/dist/development/src/internal/useFormInputHandler.cjs.map +1 -1
  50. package/dist/development/src/internal/useFormInputHandler.js.map +1 -1
  51. package/dist/production/index.cjs +6 -2
  52. package/dist/production/index.cjs.map +1 -1
  53. package/dist/production/index.js +5 -1
  54. package/dist/production/index.js.map +1 -1
  55. package/dist/production/src/components/FormCheckbox.cjs +7 -4
  56. package/dist/production/src/components/FormCheckbox.cjs.map +1 -1
  57. package/dist/production/src/components/FormCheckbox.js +8 -5
  58. package/dist/production/src/components/FormCheckbox.js.map +1 -1
  59. package/dist/production/src/components/FormError.cjs +5 -5
  60. package/dist/production/src/components/FormError.cjs.map +1 -1
  61. package/dist/production/src/components/FormError.js +6 -6
  62. package/dist/production/src/components/FormError.js.map +1 -1
  63. package/dist/production/src/components/FormFieldScope.cjs +16 -6
  64. package/dist/production/src/components/FormFieldScope.cjs.map +1 -1
  65. package/dist/production/src/components/FormFieldScope.js +17 -7
  66. package/dist/production/src/components/FormFieldScope.js.map +1 -1
  67. package/dist/production/src/components/FormFieldStateProvider.cjs +34 -0
  68. package/dist/production/src/components/FormFieldStateProvider.cjs.map +1 -0
  69. package/dist/production/src/components/FormFieldStateProvider.js +34 -0
  70. package/dist/production/src/components/FormFieldStateProvider.js.map +1 -0
  71. package/dist/production/src/components/FormHasManyRelationScope.cjs +17 -7
  72. package/dist/production/src/components/FormHasManyRelationScope.cjs.map +1 -1
  73. package/dist/production/src/components/FormHasManyRelationScope.js +18 -8
  74. package/dist/production/src/components/FormHasManyRelationScope.js.map +1 -1
  75. package/dist/production/src/components/FormHasOneRelationScope.cjs +17 -7
  76. package/dist/production/src/components/FormHasOneRelationScope.cjs.map +1 -1
  77. package/dist/production/src/components/FormHasOneRelationScope.js +17 -7
  78. package/dist/production/src/components/FormHasOneRelationScope.js.map +1 -1
  79. package/dist/production/src/components/FormInput.cjs +9 -4
  80. package/dist/production/src/components/FormInput.cjs.map +1 -1
  81. package/dist/production/src/components/FormInput.js +10 -5
  82. package/dist/production/src/components/FormInput.js.map +1 -1
  83. package/dist/production/src/components/FormLabel.cjs +7 -5
  84. package/dist/production/src/components/FormLabel.cjs.map +1 -1
  85. package/dist/production/src/components/FormLabel.js +8 -6
  86. package/dist/production/src/components/FormLabel.js.map +1 -1
  87. package/dist/production/src/components/FormRadioInput.cjs +15 -11
  88. package/dist/production/src/components/FormRadioInput.cjs.map +1 -1
  89. package/dist/production/src/components/FormRadioInput.js +16 -12
  90. package/dist/production/src/components/FormRadioInput.js.map +1 -1
  91. package/dist/production/src/contexts.cjs +7 -8
  92. package/dist/production/src/contexts.cjs.map +1 -1
  93. package/dist/production/src/contexts.js +8 -9
  94. package/dist/production/src/contexts.js.map +1 -1
  95. package/dist/production/src/hooks/useFormInputValidationHandler.cjs +12 -3
  96. package/dist/production/src/hooks/useFormInputValidationHandler.cjs.map +1 -1
  97. package/dist/production/src/hooks/useFormInputValidationHandler.js +12 -3
  98. package/dist/production/src/hooks/useFormInputValidationHandler.js.map +1 -1
  99. package/dist/production/src/internal/useFormInputHandler.cjs.map +1 -1
  100. package/dist/production/src/internal/useFormInputHandler.js.map +1 -1
  101. package/dist/types/components/FormCheckbox.d.ts.map +1 -1
  102. package/dist/types/components/FormFieldScope.d.ts +2 -1
  103. package/dist/types/components/FormFieldScope.d.ts.map +1 -1
  104. package/dist/types/components/FormFieldStateProvider.d.ts +36 -0
  105. package/dist/types/components/FormFieldStateProvider.d.ts.map +1 -0
  106. package/dist/types/components/FormHasManyRelationScope.d.ts +5 -1
  107. package/dist/types/components/FormHasManyRelationScope.d.ts.map +1 -1
  108. package/dist/types/components/FormHasOneRelationScope.d.ts +2 -1
  109. package/dist/types/components/FormHasOneRelationScope.d.ts.map +1 -1
  110. package/dist/types/components/FormInput.d.ts.map +1 -1
  111. package/dist/types/components/FormLabel.d.ts.map +1 -1
  112. package/dist/types/components/FormRadioInput.d.ts +1 -1
  113. package/dist/types/components/FormRadioInput.d.ts.map +1 -1
  114. package/dist/types/components/index.d.ts +1 -0
  115. package/dist/types/components/index.d.ts.map +1 -1
  116. package/dist/types/contexts.d.ts +10 -6
  117. package/dist/types/contexts.d.ts.map +1 -1
  118. package/dist/types/hooks/useFormInputValidationHandler.d.ts.map +1 -1
  119. package/dist/types/tsconfig.tsbuildinfo +1 -1
  120. package/dist/types/types/index.d.ts +12 -0
  121. package/dist/types/types/index.d.ts.map +1 -1
  122. package/package.json +7 -6
  123. package/src/components/FormCheckbox.tsx +17 -6
  124. package/src/components/FormError.tsx +6 -6
  125. package/src/components/FormFieldScope.tsx +17 -12
  126. package/src/components/FormFieldStateProvider.tsx +71 -0
  127. package/src/components/FormHasManyRelationScope.tsx +22 -14
  128. package/src/components/FormHasOneRelationScope.tsx +17 -13
  129. package/src/components/FormInput.tsx +12 -5
  130. package/src/components/FormLabel.tsx +8 -6
  131. package/src/components/FormRadioInput.tsx +22 -15
  132. package/src/components/index.ts +1 -0
  133. package/src/contexts.tsx +18 -0
  134. package/src/hooks/useFormInputValidationHandler.tsx +13 -3
  135. package/src/tsconfig.json +5 -2
  136. package/src/types/index.ts +13 -0
  137. package/src/contexts.ts +0 -12
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const contexts = require("../contexts.cjs");
6
+ const emptyArr = [];
7
+ const FormFieldStateProvider = ({ children, required = false, errors = emptyArr, dirty = false, htmlId, field }) => {
8
+ const generatedId = React.useId();
9
+ htmlId ?? (htmlId = generatedId);
10
+ const value = React.useMemo(() => ({ htmlId, required, errors, dirty, field }), [htmlId, required, errors, dirty, field]);
11
+ return /* @__PURE__ */ jsxRuntime.jsx(contexts.FormFieldStateContext.Provider, { value, children });
12
+ };
13
+ const FormFieldIdContext = {
14
+ /**
15
+ * @deprecated use `FormFieldStateProvider` instead
16
+ */
17
+ Provider: ({ children, value }) => {
18
+ const state = contexts.useFormFieldState();
19
+ return /* @__PURE__ */ jsxRuntime.jsx(FormFieldStateProvider, { ...state, htmlId: value, children });
20
+ }
21
+ };
22
+ const FormErrorContext = {
23
+ /**
24
+ * @deprecated use `FormFieldStateProvider` instead
25
+ */
26
+ Provider: ({ children, value }) => {
27
+ const state = contexts.useFormFieldState();
28
+ return /* @__PURE__ */ jsxRuntime.jsx(FormFieldStateProvider, { ...state, errors: value, children });
29
+ }
30
+ };
31
+ exports.FormErrorContext = FormErrorContext;
32
+ exports.FormFieldIdContext = FormFieldIdContext;
33
+ exports.FormFieldStateProvider = FormFieldStateProvider;
34
+ //# sourceMappingURL=FormFieldStateProvider.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormFieldStateProvider.cjs","sources":["../../../../../packages/react-form/src/components/FormFieldStateProvider.tsx"],"sourcesContent":["import { ErrorAccessor } from '@contember/react-binding'\nimport { useEffect, useId, useMemo } from 'react'\nimport { FormFieldStateContext, useFormFieldState } from '../contexts'\nimport { FormFieldState } from '../types'\n\nconst emptyArr: [] = []\n\nexport type FormFieldStateProvider =\n\t& Partial<FormFieldState>\n\t& {\n\t\tchildren: React.ReactNode\n\t}\n\nexport const FormFieldStateProvider = ({ children, required = false, errors = emptyArr, dirty = false, htmlId, field }: FormFieldStateProvider) => {\n\tconst generatedId = useId()\n\thtmlId ??= generatedId\n\tconst value = useMemo(() => ({ htmlId, required, errors, dirty, field }), [htmlId, required, errors, dirty, field])\n\treturn <FormFieldStateContext.Provider value={value}>{children}</FormFieldStateContext.Provider>\n}\n\n/**\n * BC for\n * \t<FormFieldIdContext.Provider value={id}>\n * \t<FormErrorContext.Provider value={[]}>\n */\n\n/**\n * @deprecated use `FormFieldStateProvider` instead\n */\nexport const FormFieldIdContext = {\n\t/**\n\t * @deprecated use `FormFieldStateProvider` instead\n\t */\n\tProvider: ({ children, value }: { children: React.ReactNode; value: string }) => {\n\t\tconst state = useFormFieldState()\n\t\tif (import.meta.env.DEV) {\n\t\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\t\tuseEffect(() => {\n\t\t\t\tconsole.warn('FormFieldIdContext.Provider is deprecated, use FormFieldStateProvider instead')\n\t\t\t}, [])\n\t\t}\n\t\treturn (\n\t\t\t<FormFieldStateProvider {...state} htmlId={value}>\n\t\t\t\t{children}\n\t\t\t</FormFieldStateProvider>\n\t\t)\n\t},\n}\n\n/**\n * @deprecated use `FormFieldStateProvider` instead\n */\nexport const FormErrorContext = {\n\t/**\n\t * @deprecated use `FormFieldStateProvider` instead\n\t */\n\tProvider: ({ children, value }: { children: React.ReactNode; value: ErrorAccessor.Error[] }) => {\n\t\tconst state = useFormFieldState()\n\t\tif (import.meta.env.DEV) {\n\t\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\t\tuseEffect(() => {\n\t\t\t\tconsole.warn('FormErrorContext.Provider is deprecated, use FormFieldStateProvider instead')\n\t\t\t}, [])\n\t\t}\n\t\treturn (\n\t\t\t<FormFieldStateProvider {...state} errors={value}>\n\t\t\t\t{children}\n\t\t\t</FormFieldStateProvider>\n\t\t)\n\t},\n}\n"],"names":["useId","useMemo","FormFieldStateContext","useFormFieldState"],"mappings":";;;;;AAKA,MAAM,WAAe,CAAC;AAQf,MAAM,yBAAyB,CAAC,EAAE,UAAU,WAAW,OAAO,SAAS,UAAU,QAAQ,OAAO,QAAQ,MAAA,MAAoC;AAClJ,QAAM,cAAcA,MAAAA,MAAM;AACf,aAAA,SAAA;AACX,QAAM,QAAQC,MAAAA,QAAQ,OAAO,EAAE,QAAQ,UAAU,QAAQ,OAAO,MAAM,IAAI,CAAC,QAAQ,UAAU,QAAQ,OAAO,KAAK,CAAC;AAClH,wCAAQC,SAAAA,sBAAsB,UAAtB,EAA+B,OAAe,UAAS;AAChE;AAWO,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA,EAIjC,UAAU,CAAC,EAAE,UAAU,YAA0D;AAChF,UAAM,QAAQC,SAAAA,kBAAkB;0CAQ9B,wBAAwB,EAAA,GAAG,OAAO,QAAQ,OACzC,UACF;AAAA,EAAA;AAGH;AAKO,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA,EAI/B,UAAU,CAAC,EAAE,UAAU,YAAyE;AAC/F,UAAM,QAAQA,SAAAA,kBAAkB;0CAQ9B,wBAAwB,EAAA,GAAG,OAAO,QAAQ,OACzC,UACF;AAAA,EAAA;AAGH;;;;"}
@@ -0,0 +1,34 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useId, useMemo } from "react";
3
+ import { FormFieldStateContext, useFormFieldState } from "../contexts.js";
4
+ const emptyArr = [];
5
+ const FormFieldStateProvider = ({ children, required = false, errors = emptyArr, dirty = false, htmlId, field }) => {
6
+ const generatedId = useId();
7
+ htmlId ?? (htmlId = generatedId);
8
+ const value = useMemo(() => ({ htmlId, required, errors, dirty, field }), [htmlId, required, errors, dirty, field]);
9
+ return /* @__PURE__ */ jsx(FormFieldStateContext.Provider, { value, children });
10
+ };
11
+ const FormFieldIdContext = {
12
+ /**
13
+ * @deprecated use `FormFieldStateProvider` instead
14
+ */
15
+ Provider: ({ children, value }) => {
16
+ const state = useFormFieldState();
17
+ return /* @__PURE__ */ jsx(FormFieldStateProvider, { ...state, htmlId: value, children });
18
+ }
19
+ };
20
+ const FormErrorContext = {
21
+ /**
22
+ * @deprecated use `FormFieldStateProvider` instead
23
+ */
24
+ Provider: ({ children, value }) => {
25
+ const state = useFormFieldState();
26
+ return /* @__PURE__ */ jsx(FormFieldStateProvider, { ...state, errors: value, children });
27
+ }
28
+ };
29
+ export {
30
+ FormErrorContext,
31
+ FormFieldIdContext,
32
+ FormFieldStateProvider
33
+ };
34
+ //# sourceMappingURL=FormFieldStateProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormFieldStateProvider.js","sources":["../../../../../packages/react-form/src/components/FormFieldStateProvider.tsx"],"sourcesContent":["import { ErrorAccessor } from '@contember/react-binding'\nimport { useEffect, useId, useMemo } from 'react'\nimport { FormFieldStateContext, useFormFieldState } from '../contexts'\nimport { FormFieldState } from '../types'\n\nconst emptyArr: [] = []\n\nexport type FormFieldStateProvider =\n\t& Partial<FormFieldState>\n\t& {\n\t\tchildren: React.ReactNode\n\t}\n\nexport const FormFieldStateProvider = ({ children, required = false, errors = emptyArr, dirty = false, htmlId, field }: FormFieldStateProvider) => {\n\tconst generatedId = useId()\n\thtmlId ??= generatedId\n\tconst value = useMemo(() => ({ htmlId, required, errors, dirty, field }), [htmlId, required, errors, dirty, field])\n\treturn <FormFieldStateContext.Provider value={value}>{children}</FormFieldStateContext.Provider>\n}\n\n/**\n * BC for\n * \t<FormFieldIdContext.Provider value={id}>\n * \t<FormErrorContext.Provider value={[]}>\n */\n\n/**\n * @deprecated use `FormFieldStateProvider` instead\n */\nexport const FormFieldIdContext = {\n\t/**\n\t * @deprecated use `FormFieldStateProvider` instead\n\t */\n\tProvider: ({ children, value }: { children: React.ReactNode; value: string }) => {\n\t\tconst state = useFormFieldState()\n\t\tif (import.meta.env.DEV) {\n\t\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\t\tuseEffect(() => {\n\t\t\t\tconsole.warn('FormFieldIdContext.Provider is deprecated, use FormFieldStateProvider instead')\n\t\t\t}, [])\n\t\t}\n\t\treturn (\n\t\t\t<FormFieldStateProvider {...state} htmlId={value}>\n\t\t\t\t{children}\n\t\t\t</FormFieldStateProvider>\n\t\t)\n\t},\n}\n\n/**\n * @deprecated use `FormFieldStateProvider` instead\n */\nexport const FormErrorContext = {\n\t/**\n\t * @deprecated use `FormFieldStateProvider` instead\n\t */\n\tProvider: ({ children, value }: { children: React.ReactNode; value: ErrorAccessor.Error[] }) => {\n\t\tconst state = useFormFieldState()\n\t\tif (import.meta.env.DEV) {\n\t\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\t\tuseEffect(() => {\n\t\t\t\tconsole.warn('FormErrorContext.Provider is deprecated, use FormFieldStateProvider instead')\n\t\t\t}, [])\n\t\t}\n\t\treturn (\n\t\t\t<FormFieldStateProvider {...state} errors={value}>\n\t\t\t\t{children}\n\t\t\t</FormFieldStateProvider>\n\t\t)\n\t},\n}\n"],"names":[],"mappings":";;;AAKA,MAAM,WAAe,CAAC;AAQf,MAAM,yBAAyB,CAAC,EAAE,UAAU,WAAW,OAAO,SAAS,UAAU,QAAQ,OAAO,QAAQ,MAAA,MAAoC;AAClJ,QAAM,cAAc,MAAM;AACf,aAAA,SAAA;AACX,QAAM,QAAQ,QAAQ,OAAO,EAAE,QAAQ,UAAU,QAAQ,OAAO,MAAM,IAAI,CAAC,QAAQ,UAAU,QAAQ,OAAO,KAAK,CAAC;AAClH,6BAAQ,sBAAsB,UAAtB,EAA+B,OAAe,UAAS;AAChE;AAWO,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA,EAIjC,UAAU,CAAC,EAAE,UAAU,YAA0D;AAChF,UAAM,QAAQ,kBAAkB;+BAQ9B,wBAAwB,EAAA,GAAG,OAAO,QAAQ,OACzC,UACF;AAAA,EAAA;AAGH;AAKO,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA,EAI/B,UAAU,CAAC,EAAE,UAAU,YAAyE;AAC/F,UAAM,QAAQ,kBAAkB;+BAQ9B,wBAAwB,EAAA,GAAG,OAAO,QAAQ,OACzC,UACF;AAAA,EAAA;AAGH;"}
@@ -2,14 +2,24 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const reactBinding = require("@contember/react-binding");
5
+ const FormFieldStateProvider = require("./FormFieldStateProvider.cjs");
5
6
  const React = require("react");
6
- const contexts = require("../contexts.cjs");
7
- const emptyArr = [];
8
- const FormHasManyRelationScope = ({ field, children }) => {
9
- const id = React.useId();
10
- const entityRelation = reactBinding.useEntityList({ field });
11
- const errors = entityRelation.errors?.errors;
12
- return /* @__PURE__ */ jsxRuntime.jsx(contexts.FormFieldIdContext.Provider, { value: id, children: /* @__PURE__ */ jsxRuntime.jsx(contexts.FormErrorContext.Provider, { value: errors ?? emptyArr, children }) });
7
+ const FormHasManyRelationScope = ({ children, required, ...props }) => {
8
+ const entityRelation = reactBinding.useEntityList(props);
9
+ const entityName = entityRelation.getParent().name;
10
+ const marker = entityRelation.getMarker();
11
+ const fieldName = marker.parameters.field;
12
+ const fieldInfo = React.useMemo(() => ({ entityName, fieldName }), [entityName, fieldName]);
13
+ return /* @__PURE__ */ jsxRuntime.jsx(
14
+ FormFieldStateProvider.FormFieldStateProvider,
15
+ {
16
+ errors: entityRelation.errors?.errors,
17
+ dirty: entityRelation.hasUnpersistedChanges,
18
+ required,
19
+ field: fieldInfo,
20
+ children
21
+ }
22
+ );
13
23
  };
14
24
  exports.FormHasManyRelationScope = FormHasManyRelationScope;
15
25
  //# sourceMappingURL=FormHasManyRelationScope.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormHasManyRelationScope.cjs","sources":["../../../../../packages/react-form/src/components/FormHasManyRelationScope.tsx"],"sourcesContent":["import { SugaredRelativeEntityList, useEntityList } from '@contember/react-binding'\nimport * as React from 'react'\nimport { useId } from 'react'\nimport { FormErrorContext, FormFieldIdContext } from '../contexts'\n\nconst emptyArr: [] = []\n\nexport type FormHasManyRelationScopeProps = {\n\tfield: SugaredRelativeEntityList['field']\n\tchildren: React.ReactNode\n}\n\nexport const FormHasManyRelationScope = ({ field, children }: FormHasManyRelationScopeProps) => {\n\tconst id = useId()\n\tconst entityRelation = useEntityList({ field })\n\tconst errors = entityRelation.errors?.errors\n\treturn (\n\t\t<FormFieldIdContext.Provider value={id}>\n\t\t\t<FormErrorContext.Provider value={errors ?? emptyArr}>\n\t\t\t\t{children}\n\t\t\t</FormErrorContext.Provider>\n\t\t</FormFieldIdContext.Provider>\n\t)\n}\n"],"names":["useId","useEntityList","jsx","FormFieldIdContext","FormErrorContext"],"mappings":";;;;;;AAKA,MAAM,WAAe,CAAA;AAOd,MAAM,2BAA2B,CAAC,EAAE,OAAO,eAA8C;AAC/F,QAAM,KAAKA,MAAAA;AACX,QAAM,iBAAiBC,aAAAA,cAAc,EAAE,MAAO,CAAA;AACxC,QAAA,SAAS,eAAe,QAAQ;AACtC,SACEC,2BAAAA,IAAAC,SAAAA,mBAAmB,UAAnB,EAA4B,OAAO,IACnC,UAAAD,2BAAA,IAACE,SAAiB,iBAAA,UAAjB,EAA0B,OAAO,UAAU,UAC1C,UACF,EACD,CAAA;AAEF;;"}
1
+ {"version":3,"file":"FormHasManyRelationScope.cjs","sources":["../../../../../packages/react-form/src/components/FormHasManyRelationScope.tsx"],"sourcesContent":["import { HasManyRelationMarker, SugaredRelativeEntityList, useEntityList } from '@contember/react-binding'\nimport * as React from 'react'\nimport { FormFieldStateProvider } from './FormFieldStateProvider'\nimport { useMemo } from 'react'\n\nexport type FormHasManyRelationScopeProps = {\n\tfield: SugaredRelativeEntityList['field']\n\torderBy?: SugaredRelativeEntityList['orderBy']\n\tlimit?: SugaredRelativeEntityList['limit']\n\toffset?: SugaredRelativeEntityList['offset']\n\tchildren: React.ReactNode\n\trequired?: boolean\n}\n\nexport const FormHasManyRelationScope = ({ children, required, ...props }: FormHasManyRelationScopeProps) => {\n\tconst entityRelation = useEntityList(props)\n\tconst entityName = entityRelation.getParent()!.name\n\tconst marker = entityRelation.getMarker() as HasManyRelationMarker\n\tconst fieldName = marker.parameters.field\n\tconst fieldInfo = useMemo(() => ({ entityName, fieldName }), [entityName, fieldName])\n\n\treturn (\n\t\t<FormFieldStateProvider\n\t\t\terrors={entityRelation.errors?.errors}\n\t\t\tdirty={entityRelation.hasUnpersistedChanges}\n\t\t\trequired={required}\n\t\t\tfield={fieldInfo}\n\t\t>\n\t\t\t{children}\n\t\t</FormFieldStateProvider>\n\t)\n}\n"],"names":["useEntityList","useMemo","jsx","FormFieldStateProvider"],"mappings":";;;;;;AAcO,MAAM,2BAA2B,CAAC,EAAE,UAAU,UAAU,GAAG,YAA2C;AACtG,QAAA,iBAAiBA,2BAAc,KAAK;AACpC,QAAA,aAAa,eAAe,UAAA,EAAa;AACzC,QAAA,SAAS,eAAe,UAAU;AAClC,QAAA,YAAY,OAAO,WAAW;AAC9B,QAAA,YAAYC,cAAQ,OAAO,EAAE,YAAY,cAAc,CAAC,YAAY,SAAS,CAAC;AAGnF,SAAAC,2BAAA;AAAA,IAACC,uBAAA;AAAA,IAAA;AAAA,MACA,QAAQ,eAAe,QAAQ;AAAA,MAC/B,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,OAAO;AAAA,MAEN;AAAA,IAAA;AAAA,EACF;AAEF;;"}
@@ -1,13 +1,23 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useEntityList } from "@contember/react-binding";
3
- import { useId } from "react";
4
- import { FormFieldIdContext, FormErrorContext } from "../contexts.js";
5
- const emptyArr = [];
6
- const FormHasManyRelationScope = ({ field, children }) => {
7
- const id = useId();
8
- const entityRelation = useEntityList({ field });
9
- const errors = entityRelation.errors?.errors;
10
- return /* @__PURE__ */ jsx(FormFieldIdContext.Provider, { value: id, children: /* @__PURE__ */ jsx(FormErrorContext.Provider, { value: errors ?? emptyArr, children }) });
3
+ import { FormFieldStateProvider } from "./FormFieldStateProvider.js";
4
+ import { useMemo } from "react";
5
+ const FormHasManyRelationScope = ({ children, required, ...props }) => {
6
+ const entityRelation = useEntityList(props);
7
+ const entityName = entityRelation.getParent().name;
8
+ const marker = entityRelation.getMarker();
9
+ const fieldName = marker.parameters.field;
10
+ const fieldInfo = useMemo(() => ({ entityName, fieldName }), [entityName, fieldName]);
11
+ return /* @__PURE__ */ jsx(
12
+ FormFieldStateProvider,
13
+ {
14
+ errors: entityRelation.errors?.errors,
15
+ dirty: entityRelation.hasUnpersistedChanges,
16
+ required,
17
+ field: fieldInfo,
18
+ children
19
+ }
20
+ );
11
21
  };
12
22
  export {
13
23
  FormHasManyRelationScope
@@ -1 +1 @@
1
- {"version":3,"file":"FormHasManyRelationScope.js","sources":["../../../../../packages/react-form/src/components/FormHasManyRelationScope.tsx"],"sourcesContent":["import { SugaredRelativeEntityList, useEntityList } from '@contember/react-binding'\nimport * as React from 'react'\nimport { useId } from 'react'\nimport { FormErrorContext, FormFieldIdContext } from '../contexts'\n\nconst emptyArr: [] = []\n\nexport type FormHasManyRelationScopeProps = {\n\tfield: SugaredRelativeEntityList['field']\n\tchildren: React.ReactNode\n}\n\nexport const FormHasManyRelationScope = ({ field, children }: FormHasManyRelationScopeProps) => {\n\tconst id = useId()\n\tconst entityRelation = useEntityList({ field })\n\tconst errors = entityRelation.errors?.errors\n\treturn (\n\t\t<FormFieldIdContext.Provider value={id}>\n\t\t\t<FormErrorContext.Provider value={errors ?? emptyArr}>\n\t\t\t\t{children}\n\t\t\t</FormErrorContext.Provider>\n\t\t</FormFieldIdContext.Provider>\n\t)\n}\n"],"names":[],"mappings":";;;;AAKA,MAAM,WAAe,CAAA;AAOd,MAAM,2BAA2B,CAAC,EAAE,OAAO,eAA8C;AAC/F,QAAM,KAAK;AACX,QAAM,iBAAiB,cAAc,EAAE,MAAO,CAAA;AACxC,QAAA,SAAS,eAAe,QAAQ;AACtC,SACE,oBAAA,mBAAmB,UAAnB,EAA4B,OAAO,IACnC,UAAA,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,UAAU,UAC1C,UACF,EACD,CAAA;AAEF;"}
1
+ {"version":3,"file":"FormHasManyRelationScope.js","sources":["../../../../../packages/react-form/src/components/FormHasManyRelationScope.tsx"],"sourcesContent":["import { HasManyRelationMarker, SugaredRelativeEntityList, useEntityList } from '@contember/react-binding'\nimport * as React from 'react'\nimport { FormFieldStateProvider } from './FormFieldStateProvider'\nimport { useMemo } from 'react'\n\nexport type FormHasManyRelationScopeProps = {\n\tfield: SugaredRelativeEntityList['field']\n\torderBy?: SugaredRelativeEntityList['orderBy']\n\tlimit?: SugaredRelativeEntityList['limit']\n\toffset?: SugaredRelativeEntityList['offset']\n\tchildren: React.ReactNode\n\trequired?: boolean\n}\n\nexport const FormHasManyRelationScope = ({ children, required, ...props }: FormHasManyRelationScopeProps) => {\n\tconst entityRelation = useEntityList(props)\n\tconst entityName = entityRelation.getParent()!.name\n\tconst marker = entityRelation.getMarker() as HasManyRelationMarker\n\tconst fieldName = marker.parameters.field\n\tconst fieldInfo = useMemo(() => ({ entityName, fieldName }), [entityName, fieldName])\n\n\treturn (\n\t\t<FormFieldStateProvider\n\t\t\terrors={entityRelation.errors?.errors}\n\t\t\tdirty={entityRelation.hasUnpersistedChanges}\n\t\t\trequired={required}\n\t\t\tfield={fieldInfo}\n\t\t>\n\t\t\t{children}\n\t\t</FormFieldStateProvider>\n\t)\n}\n"],"names":[],"mappings":";;;;AAcO,MAAM,2BAA2B,CAAC,EAAE,UAAU,UAAU,GAAG,YAA2C;AACtG,QAAA,iBAAiB,cAAc,KAAK;AACpC,QAAA,aAAa,eAAe,UAAA,EAAa;AACzC,QAAA,SAAS,eAAe,UAAU;AAClC,QAAA,YAAY,OAAO,WAAW;AAC9B,QAAA,YAAY,QAAQ,OAAO,EAAE,YAAY,cAAc,CAAC,YAAY,SAAS,CAAC;AAGnF,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA,QAAQ,eAAe,QAAQ;AAAA,MAC/B,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,OAAO;AAAA,MAEN;AAAA,IAAA;AAAA,EACF;AAEF;"}
@@ -1,15 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
- const React = require("react");
5
- const contexts = require("../contexts.cjs");
6
4
  const reactBinding = require("@contember/react-binding");
7
- const emptyArr = [];
8
- const FormHasOneRelationScope = ({ field, children }) => {
9
- const id = React.useId();
5
+ const FormFieldStateProvider = require("./FormFieldStateProvider.cjs");
6
+ const React = require("react");
7
+ const FormHasOneRelationScope = ({ field, children, required }) => {
10
8
  const entityRelation = reactBinding.useEntity({ field });
11
- const errors = entityRelation.errors?.errors;
12
- return /* @__PURE__ */ jsxRuntime.jsx(contexts.FormFieldIdContext.Provider, { value: id, children: /* @__PURE__ */ jsxRuntime.jsx(contexts.FormErrorContext.Provider, { value: errors ?? emptyArr, children }) });
9
+ const marker = entityRelation.getMarker();
10
+ const fieldName = marker.parameters.field;
11
+ const entityName = entityRelation.getParent().name;
12
+ const fieldInfo = React.useMemo(() => ({ entityName, fieldName }), [entityName, fieldName]);
13
+ return /* @__PURE__ */ jsxRuntime.jsx(
14
+ FormFieldStateProvider.FormFieldStateProvider,
15
+ {
16
+ errors: entityRelation.errors?.errors,
17
+ dirty: entityRelation.hasUnpersistedChanges,
18
+ required,
19
+ field: fieldInfo,
20
+ children
21
+ }
22
+ );
13
23
  };
14
24
  exports.FormHasOneRelationScope = FormHasOneRelationScope;
15
25
  //# sourceMappingURL=FormHasOneRelationScope.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormHasOneRelationScope.cjs","sources":["../../../../../packages/react-form/src/components/FormHasOneRelationScope.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useId } from 'react'\nimport { FormErrorContext, FormFieldIdContext } from '../contexts'\nimport { SugaredRelativeSingleEntity, useEntity } from '@contember/react-binding'\n\nconst emptyArr: [] = []\n\nexport type FormHasOneRelationScopeProps = {\n\tfield: SugaredRelativeSingleEntity['field']\n\tchildren: React.ReactNode\n}\n\nexport const FormHasOneRelationScope = ({ field, children }: FormHasOneRelationScopeProps) => {\n\tconst id = useId()\n\tconst entityRelation = useEntity({ field })\n\tconst errors = entityRelation.errors?.errors\n\treturn (\n\t\t<FormFieldIdContext.Provider value={id}>\n\t\t\t<FormErrorContext.Provider value={errors ?? emptyArr}>\n\t\t\t\t{children}\n\t\t\t</FormErrorContext.Provider>\n\t\t</FormFieldIdContext.Provider>\n\t)\n}\n"],"names":["useId","useEntity","jsx","FormFieldIdContext","FormErrorContext"],"mappings":";;;;;;AAKA,MAAM,WAAe,CAAA;AAOd,MAAM,0BAA0B,CAAC,EAAE,OAAO,eAA6C;AAC7F,QAAM,KAAKA,MAAAA;AACX,QAAM,iBAAiBC,aAAAA,UAAU,EAAE,MAAO,CAAA;AACpC,QAAA,SAAS,eAAe,QAAQ;AACtC,SACEC,2BAAAA,IAAAC,SAAAA,mBAAmB,UAAnB,EAA4B,OAAO,IACnC,UAAAD,2BAAA,IAACE,SAAiB,iBAAA,UAAjB,EAA0B,OAAO,UAAU,UAC1C,UACF,EACD,CAAA;AAEF;;"}
1
+ {"version":3,"file":"FormHasOneRelationScope.cjs","sources":["../../../../../packages/react-form/src/components/FormHasOneRelationScope.tsx"],"sourcesContent":["import * as React from 'react'\nimport { HasOneRelationMarker, SugaredRelativeSingleEntity, useEntity } from '@contember/react-binding'\nimport { FormFieldStateProvider } from './FormFieldStateProvider'\nimport { useMemo } from 'react'\n\nexport type FormHasOneRelationScopeProps = {\n\tfield: SugaredRelativeSingleEntity['field']\n\tchildren: React.ReactNode\n\trequired?: boolean\n}\n\nexport const FormHasOneRelationScope = ({ field, children, required }: FormHasOneRelationScopeProps) => {\n\tconst entityRelation = useEntity({ field })\n\tconst marker = entityRelation.getMarker() as HasOneRelationMarker\n\tconst fieldName = marker.parameters.field\n\tconst entityName = entityRelation.getParent()!.name\n\tconst fieldInfo = useMemo(() => ({ entityName, fieldName }), [entityName, fieldName])\n\treturn (\n\t\t<FormFieldStateProvider\n\t\t\terrors={entityRelation.errors?.errors}\n\t\t\tdirty={entityRelation.hasUnpersistedChanges}\n\t\t\trequired={required}\n\t\t\tfield={fieldInfo}\n\t\t>\n\t\t\t{children}\n\t\t</FormFieldStateProvider>\n\t)\n}\n"],"names":["useEntity","useMemo","jsx","FormFieldStateProvider"],"mappings":";;;;;;AAWO,MAAM,0BAA0B,CAAC,EAAE,OAAO,UAAU,eAA6C;AACvG,QAAM,iBAAiBA,aAAAA,UAAU,EAAE,OAAO;AACpC,QAAA,SAAS,eAAe,UAAU;AAClC,QAAA,YAAY,OAAO,WAAW;AAC9B,QAAA,aAAa,eAAe,UAAA,EAAa;AACzC,QAAA,YAAYC,cAAQ,OAAO,EAAE,YAAY,cAAc,CAAC,YAAY,SAAS,CAAC;AAEnF,SAAAC,2BAAA;AAAA,IAACC,uBAAA;AAAA,IAAA;AAAA,MACA,QAAQ,eAAe,QAAQ;AAAA,MAC/B,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,OAAO;AAAA,MAEN;AAAA,IAAA;AAAA,EACF;AAEF;;"}
@@ -1,13 +1,23 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { useId } from "react";
3
- import { FormFieldIdContext, FormErrorContext } from "../contexts.js";
4
2
  import { useEntity } from "@contember/react-binding";
5
- const emptyArr = [];
6
- const FormHasOneRelationScope = ({ field, children }) => {
7
- const id = useId();
3
+ import { FormFieldStateProvider } from "./FormFieldStateProvider.js";
4
+ import { useMemo } from "react";
5
+ const FormHasOneRelationScope = ({ field, children, required }) => {
8
6
  const entityRelation = useEntity({ field });
9
- const errors = entityRelation.errors?.errors;
10
- return /* @__PURE__ */ jsx(FormFieldIdContext.Provider, { value: id, children: /* @__PURE__ */ jsx(FormErrorContext.Provider, { value: errors ?? emptyArr, children }) });
7
+ const marker = entityRelation.getMarker();
8
+ const fieldName = marker.parameters.field;
9
+ const entityName = entityRelation.getParent().name;
10
+ const fieldInfo = useMemo(() => ({ entityName, fieldName }), [entityName, fieldName]);
11
+ return /* @__PURE__ */ jsx(
12
+ FormFieldStateProvider,
13
+ {
14
+ errors: entityRelation.errors?.errors,
15
+ dirty: entityRelation.hasUnpersistedChanges,
16
+ required,
17
+ field: fieldInfo,
18
+ children
19
+ }
20
+ );
11
21
  };
12
22
  export {
13
23
  FormHasOneRelationScope
@@ -1 +1 @@
1
- {"version":3,"file":"FormHasOneRelationScope.js","sources":["../../../../../packages/react-form/src/components/FormHasOneRelationScope.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useId } from 'react'\nimport { FormErrorContext, FormFieldIdContext } from '../contexts'\nimport { SugaredRelativeSingleEntity, useEntity } from '@contember/react-binding'\n\nconst emptyArr: [] = []\n\nexport type FormHasOneRelationScopeProps = {\n\tfield: SugaredRelativeSingleEntity['field']\n\tchildren: React.ReactNode\n}\n\nexport const FormHasOneRelationScope = ({ field, children }: FormHasOneRelationScopeProps) => {\n\tconst id = useId()\n\tconst entityRelation = useEntity({ field })\n\tconst errors = entityRelation.errors?.errors\n\treturn (\n\t\t<FormFieldIdContext.Provider value={id}>\n\t\t\t<FormErrorContext.Provider value={errors ?? emptyArr}>\n\t\t\t\t{children}\n\t\t\t</FormErrorContext.Provider>\n\t\t</FormFieldIdContext.Provider>\n\t)\n}\n"],"names":[],"mappings":";;;;AAKA,MAAM,WAAe,CAAA;AAOd,MAAM,0BAA0B,CAAC,EAAE,OAAO,eAA6C;AAC7F,QAAM,KAAK;AACX,QAAM,iBAAiB,UAAU,EAAE,MAAO,CAAA;AACpC,QAAA,SAAS,eAAe,QAAQ;AACtC,SACE,oBAAA,mBAAmB,UAAnB,EAA4B,OAAO,IACnC,UAAA,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,UAAU,UAC1C,UACF,EACD,CAAA;AAEF;"}
1
+ {"version":3,"file":"FormHasOneRelationScope.js","sources":["../../../../../packages/react-form/src/components/FormHasOneRelationScope.tsx"],"sourcesContent":["import * as React from 'react'\nimport { HasOneRelationMarker, SugaredRelativeSingleEntity, useEntity } from '@contember/react-binding'\nimport { FormFieldStateProvider } from './FormFieldStateProvider'\nimport { useMemo } from 'react'\n\nexport type FormHasOneRelationScopeProps = {\n\tfield: SugaredRelativeSingleEntity['field']\n\tchildren: React.ReactNode\n\trequired?: boolean\n}\n\nexport const FormHasOneRelationScope = ({ field, children, required }: FormHasOneRelationScopeProps) => {\n\tconst entityRelation = useEntity({ field })\n\tconst marker = entityRelation.getMarker() as HasOneRelationMarker\n\tconst fieldName = marker.parameters.field\n\tconst entityName = entityRelation.getParent()!.name\n\tconst fieldInfo = useMemo(() => ({ entityName, fieldName }), [entityName, fieldName])\n\treturn (\n\t\t<FormFieldStateProvider\n\t\t\terrors={entityRelation.errors?.errors}\n\t\t\tdirty={entityRelation.hasUnpersistedChanges}\n\t\t\trequired={required}\n\t\t\tfield={fieldInfo}\n\t\t>\n\t\t\t{children}\n\t\t</FormFieldStateProvider>\n\t)\n}\n"],"names":[],"mappings":";;;;AAWO,MAAM,0BAA0B,CAAC,EAAE,OAAO,UAAU,eAA6C;AACvG,QAAM,iBAAiB,UAAU,EAAE,OAAO;AACpC,QAAA,SAAS,eAAe,UAAU;AAClC,QAAA,YAAY,OAAO,WAAW;AAC9B,QAAA,aAAa,eAAe,UAAA,EAAa;AACzC,QAAA,YAAY,QAAQ,OAAO,EAAE,YAAY,cAAc,CAAC,YAAY,SAAS,CAAC;AAEnF,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA,QAAQ,eAAe,QAAQ;AAAA,MAC/B,OAAO,eAAe;AAAA,MACtB;AAAA,MACA,OAAO;AAAA,MAEN;AAAA,IAAA;AAAA,EACF;AAEF;"}
@@ -10,9 +10,12 @@ const contexts = require("../contexts.cjs");
10
10
  const useFormInputValidationHandler = require("../hooks/useFormInputValidationHandler.cjs");
11
11
  const SlotInput = reactSlot.Slot;
12
12
  const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {
13
- const id = contexts.useFormFieldId();
14
13
  const accessor = reactBinding.useField(field);
15
- const errors = contexts.useFormError() ?? accessor.errors?.errors ?? [];
14
+ const formState = contexts.useFormFieldState();
15
+ const id = formState?.htmlId;
16
+ const hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0;
17
+ const dirty = formState?.dirty ?? accessor.hasUnpersistedChanges;
18
+ const required = formState?.required ?? !accessor.schema.nullable;
16
19
  const { parseValue, formatValue, defaultInputProps } = useFormInputHandler.useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn });
17
20
  const accessorGetter = accessor.getAccessor;
18
21
  const { ref, onFocus, onBlur } = useFormInputValidationHandler.useFormInputValidationHandler(accessor);
@@ -21,7 +24,9 @@ const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, f
21
24
  {
22
25
  ref,
23
26
  value: formatValue(accessor.value),
24
- "data-invalid": utilities.dataAttribute(errors.length > 0),
27
+ "data-invalid": utilities.dataAttribute(hasErrors),
28
+ "data-dirty": utilities.dataAttribute(dirty),
29
+ "data-required": utilities.dataAttribute(required),
25
30
  onFocus,
26
31
  onBlur,
27
32
  onChange: React.useCallback((e) => {
@@ -29,7 +34,7 @@ const FormInput = reactBinding.Component(({ field, isNonbearing, defaultValue, f
29
34
  }, [accessorGetter, parseValue]),
30
35
  ...defaultInputProps,
31
36
  id: id ? `${id}-input` : void 0,
32
- required: !accessor.schema.nullable,
37
+ required,
33
38
  ...props
34
39
  }
35
40
  );
@@ -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 { useFormError, useFormFieldId } 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 id = useFormFieldId()\n\tconst accessor = useField(field)\n\tconst errors = useFormError() ?? accessor.errors?.errors ?? []\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(errors.length > 0)}\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={!accessor.schema.nullable}\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","useFormFieldId","useField","useFormError","useFormInputHandler","useFormInputValidationHandler","jsx","dataAttribute","useCallback","Field"],"mappings":";;;;;;;;;;AAWA,MAAM,YAAYA,UAAAA;AAWX,MAAM,YAAYC,aAAA,UAA0B,CAAC,EAAE,OAAO,cAAc,cAAc,aAAa,eAAe,YAAY,cAAc,GAAG,YAAY;AAC7J,QAAM,KAAKC,SAAAA;AACL,QAAA,WAAWC,sBAAS,KAAK;AAC/B,QAAM,SAASC,SAAAA,aAAa,KAAK,SAAS,QAAQ,UAAU;AAC5D,QAAM,EAAE,YAAY,aAAa,kBAAsB,IAAAC,oBAAA,oBAAoB,UAAU,EAAE,aAAa,eAAe,YAAY,aAAc,CAAA;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,UAAA,cAAc,OAAO,SAAS,CAAC;AAAA,MAC7C;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,UAAU,CAAC,SAAS,OAAO;AAAA,MAC1B,GAAG;AAAA,IAAA;AAAA,EAAA;AAGP,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 } 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;;"}
@@ -4,13 +4,16 @@ 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
- import { useFormFieldId, useFormError } from "../contexts.js";
7
+ import { useFormFieldState } from "../contexts.js";
8
8
  import { useFormInputValidationHandler } from "../hooks/useFormInputValidationHandler.js";
9
9
  const SlotInput = Slot;
10
10
  const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: formatValueIn, parseValue: parseValueIn, ...props }) => {
11
- const id = useFormFieldId();
12
11
  const accessor = useField(field);
13
- const errors = useFormError() ?? accessor.errors?.errors ?? [];
12
+ const formState = useFormFieldState();
13
+ const id = formState?.htmlId;
14
+ const hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0;
15
+ const dirty = formState?.dirty ?? accessor.hasUnpersistedChanges;
16
+ const required = formState?.required ?? !accessor.schema.nullable;
14
17
  const { parseValue, formatValue, defaultInputProps } = useFormInputHandler(accessor, { formatValue: formatValueIn, parseValue: parseValueIn });
15
18
  const accessorGetter = accessor.getAccessor;
16
19
  const { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor);
@@ -19,7 +22,9 @@ const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: f
19
22
  {
20
23
  ref,
21
24
  value: formatValue(accessor.value),
22
- "data-invalid": dataAttribute(errors.length > 0),
25
+ "data-invalid": dataAttribute(hasErrors),
26
+ "data-dirty": dataAttribute(dirty),
27
+ "data-required": dataAttribute(required),
23
28
  onFocus,
24
29
  onBlur,
25
30
  onChange: useCallback((e) => {
@@ -27,7 +32,7 @@ const FormInput = Component(({ field, isNonbearing, defaultValue, formatValue: f
27
32
  }, [accessorGetter, parseValue]),
28
33
  ...defaultInputProps,
29
34
  id: id ? `${id}-input` : void 0,
30
- required: !accessor.schema.nullable,
35
+ required,
31
36
  ...props
32
37
  }
33
38
  );
@@ -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 { useFormError, useFormFieldId } 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 id = useFormFieldId()\n\tconst accessor = useField(field)\n\tconst errors = useFormError() ?? accessor.errors?.errors ?? []\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(errors.length > 0)}\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={!accessor.schema.nullable}\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;AAC7J,QAAM,KAAK;AACL,QAAA,WAAW,SAAS,KAAK;AAC/B,QAAM,SAAS,aAAa,KAAK,SAAS,QAAQ,UAAU;AAC5D,QAAM,EAAE,YAAY,aAAa,kBAAsB,IAAA,oBAAoB,UAAU,EAAE,aAAa,eAAe,YAAY,aAAc,CAAA;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,OAAO,SAAS,CAAC;AAAA,MAC7C;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,UAAU,CAAC,SAAS,OAAO;AAAA,MAC1B,GAAG;AAAA,IAAA;AAAA,EAAA;AAGP,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 } 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;"}
@@ -6,16 +6,18 @@ const utilities = require("@contember/utilities");
6
6
  const contexts = require("../contexts.cjs");
7
7
  const reactBinding = require("@contember/react-binding");
8
8
  const FormLabel = (props) => {
9
- const id = contexts.useFormFieldId();
10
- const errors = contexts.useFormError();
11
- if (errors === void 0 || id === void 0) {
12
- throw new reactBinding.BindingError("FormLabel must be used inside a FormField");
9
+ const formState = contexts.useFormFieldState();
10
+ if (!formState) {
11
+ throw new reactBinding.BindingError("FormError must be used inside a FormField");
13
12
  }
13
+ const { errors, htmlId, dirty, required } = formState;
14
14
  return /* @__PURE__ */ jsxRuntime.jsx(
15
15
  reactSlot.Slot,
16
16
  {
17
17
  "data-invalid": utilities.dataAttribute(errors.length > 0),
18
- ...{ htmlFor: `${id}-input` },
18
+ "data-dirty": utilities.dataAttribute(dirty),
19
+ "data-required": utilities.dataAttribute(required),
20
+ ...htmlId ? { htmlFor: `${htmlId}-input` } : {},
19
21
  ...props
20
22
  }
21
23
  );
@@ -1 +1 @@
1
- {"version":3,"file":"FormLabel.cjs","sources":["../../../../../packages/react-form/src/components/FormLabel.tsx"],"sourcesContent":["import * as React from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormError, useFormFieldId } from '../contexts'\nimport { BindingError } from '@contember/react-binding'\n\nexport const FormLabel = (props: {\n\tchildren: React.ReactElement\n}) => {\n\tconst id = useFormFieldId()\n\tconst errors = useFormError()\n\tif (errors === undefined || id === undefined) {\n\t\tthrow new BindingError('FormLabel must be used inside a FormField')\n\t}\n\treturn (\n\t\t<Slot\n\t\t\tdata-invalid={dataAttribute(errors.length > 0)}\n\t\t\t{...{ htmlFor: `${id}-input` }}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n"],"names":["useFormFieldId","useFormError","BindingError","jsx","Slot","dataAttribute"],"mappings":";;;;;;;AAMa,MAAA,YAAY,CAAC,UAEpB;AACL,QAAM,KAAKA,SAAAA;AACX,QAAM,SAASC,SAAAA;AACX,MAAA,WAAW,UAAa,OAAO,QAAW;AACvC,UAAA,IAAIC,aAAAA,aAAa,2CAA2C;AAAA,EACnE;AAEC,SAAAC,2BAAA;AAAA,IAACC,UAAA;AAAA,IAAA;AAAA,MACA,gBAAcC,UAAA,cAAc,OAAO,SAAS,CAAC;AAAA,MAC5C,GAAG,EAAE,SAAS,GAAG,EAAE,SAAS;AAAA,MAC5B,GAAG;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
1
+ {"version":3,"file":"FormLabel.cjs","sources":["../../../../../packages/react-form/src/components/FormLabel.tsx"],"sourcesContent":["import * as React from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormFieldState } from '../contexts'\nimport { BindingError } from '@contember/react-binding'\n\nexport const FormLabel = (props: {\n\tchildren: React.ReactElement\n}) => {\n\tconst formState = useFormFieldState()\n\tif (!formState) {\n\t\tthrow new BindingError('FormError must be used inside a FormField')\n\t}\n\tconst { errors, htmlId, dirty, required } = formState\n\treturn (\n\t\t<Slot\n\t\t\tdata-invalid={dataAttribute(errors.length > 0)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tdata-required={dataAttribute(required)}\n\t\t\t{...(htmlId ? { htmlFor: `${htmlId}-input` } : {})}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n"],"names":["useFormFieldState","BindingError","jsx","Slot","dataAttribute"],"mappings":";;;;;;;AAMa,MAAA,YAAY,CAAC,UAEpB;AACL,QAAM,YAAYA,SAAAA,kBAAkB;AACpC,MAAI,CAAC,WAAW;AACT,UAAA,IAAIC,0BAAa,2CAA2C;AAAA,EAAA;AAEnE,QAAM,EAAE,QAAQ,QAAQ,OAAO,SAAa,IAAA;AAE3C,SAAAC,2BAAA;AAAA,IAACC,UAAA;AAAA,IAAA;AAAA,MACA,gBAAcC,UAAA,cAAc,OAAO,SAAS,CAAC;AAAA,MAC7C,cAAYA,wBAAc,KAAK;AAAA,MAC/B,iBAAeA,wBAAc,QAAQ;AAAA,MACpC,GAAI,SAAS,EAAE,SAAS,GAAG,MAAM,SAAA,IAAa,CAAC;AAAA,MAC/C,GAAG;AAAA,IAAA;AAAA,EACL;AAEF;;"}
@@ -1,19 +1,21 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { Slot } from "@radix-ui/react-slot";
3
3
  import { dataAttribute } from "@contember/utilities";
4
- import { useFormFieldId, useFormError } from "../contexts.js";
4
+ import { useFormFieldState } from "../contexts.js";
5
5
  import { BindingError } from "@contember/react-binding";
6
6
  const FormLabel = (props) => {
7
- const id = useFormFieldId();
8
- const errors = useFormError();
9
- if (errors === void 0 || id === void 0) {
10
- throw new BindingError("FormLabel must be used inside a FormField");
7
+ const formState = useFormFieldState();
8
+ if (!formState) {
9
+ throw new BindingError("FormError must be used inside a FormField");
11
10
  }
11
+ const { errors, htmlId, dirty, required } = formState;
12
12
  return /* @__PURE__ */ jsx(
13
13
  Slot,
14
14
  {
15
15
  "data-invalid": dataAttribute(errors.length > 0),
16
- ...{ htmlFor: `${id}-input` },
16
+ "data-dirty": dataAttribute(dirty),
17
+ "data-required": dataAttribute(required),
18
+ ...htmlId ? { htmlFor: `${htmlId}-input` } : {},
17
19
  ...props
18
20
  }
19
21
  );
@@ -1 +1 @@
1
- {"version":3,"file":"FormLabel.js","sources":["../../../../../packages/react-form/src/components/FormLabel.tsx"],"sourcesContent":["import * as React from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormError, useFormFieldId } from '../contexts'\nimport { BindingError } from '@contember/react-binding'\n\nexport const FormLabel = (props: {\n\tchildren: React.ReactElement\n}) => {\n\tconst id = useFormFieldId()\n\tconst errors = useFormError()\n\tif (errors === undefined || id === undefined) {\n\t\tthrow new BindingError('FormLabel must be used inside a FormField')\n\t}\n\treturn (\n\t\t<Slot\n\t\t\tdata-invalid={dataAttribute(errors.length > 0)}\n\t\t\t{...{ htmlFor: `${id}-input` }}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n"],"names":[],"mappings":";;;;;AAMa,MAAA,YAAY,CAAC,UAEpB;AACL,QAAM,KAAK;AACX,QAAM,SAAS;AACX,MAAA,WAAW,UAAa,OAAO,QAAW;AACvC,UAAA,IAAI,aAAa,2CAA2C;AAAA,EACnE;AAEC,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA,gBAAc,cAAc,OAAO,SAAS,CAAC;AAAA,MAC5C,GAAG,EAAE,SAAS,GAAG,EAAE,SAAS;AAAA,MAC5B,GAAG;AAAA,IAAA;AAAA,EAAA;AAGP;"}
1
+ {"version":3,"file":"FormLabel.js","sources":["../../../../../packages/react-form/src/components/FormLabel.tsx"],"sourcesContent":["import * as React from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { dataAttribute } from '@contember/utilities'\nimport { useFormFieldState } from '../contexts'\nimport { BindingError } from '@contember/react-binding'\n\nexport const FormLabel = (props: {\n\tchildren: React.ReactElement\n}) => {\n\tconst formState = useFormFieldState()\n\tif (!formState) {\n\t\tthrow new BindingError('FormError must be used inside a FormField')\n\t}\n\tconst { errors, htmlId, dirty, required } = formState\n\treturn (\n\t\t<Slot\n\t\t\tdata-invalid={dataAttribute(errors.length > 0)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tdata-required={dataAttribute(required)}\n\t\t\t{...(htmlId ? { htmlFor: `${htmlId}-input` } : {})}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n"],"names":[],"mappings":";;;;;AAMa,MAAA,YAAY,CAAC,UAEpB;AACL,QAAM,YAAY,kBAAkB;AACpC,MAAI,CAAC,WAAW;AACT,UAAA,IAAI,aAAa,2CAA2C;AAAA,EAAA;AAEnE,QAAM,EAAE,QAAQ,QAAQ,OAAO,SAAa,IAAA;AAE3C,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA,gBAAc,cAAc,OAAO,SAAS,CAAC;AAAA,MAC7C,cAAY,cAAc,KAAK;AAAA,MAC/B,iBAAe,cAAc,QAAQ;AAAA,MACpC,GAAI,SAAS,EAAE,SAAS,GAAG,MAAM,SAAA,IAAa,CAAC;AAAA,MAC/C,GAAG;AAAA,IAAA;AAAA,EACL;AAEF;"}
@@ -2,33 +2,37 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const reactBinding = require("@contember/react-binding");
5
- const React = require("react");
5
+ const utilities = require("@contember/utilities");
6
6
  const reactSlot = require("@radix-ui/react-slot");
7
+ const React = require("react");
7
8
  const contexts = require("../contexts.cjs");
8
- const utilities = require("@contember/utilities");
9
9
  const useFormInputValidationHandler = require("../hooks/useFormInputValidationHandler.cjs");
10
10
  const SlotInput = reactSlot.Slot;
11
11
  const FormRadioInput = reactBinding.Component(({ field, value, defaultValue, isNonbearing, ...props }) => {
12
- const id = contexts.useFormFieldId();
13
12
  const accessor = reactBinding.useField(field);
14
- const errors = contexts.useFormError() ?? accessor.errors?.errors ?? [];
13
+ const formState = contexts.useFormFieldState();
14
+ const id = formState?.htmlId;
15
+ const hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0;
16
+ const dirty = formState?.dirty ?? accessor.hasUnpersistedChanges;
15
17
  const accessorGetter = accessor.getAccessor;
16
18
  const { ref, onFocus, onBlur } = useFormInputValidationHandler.useFormInputValidationHandler(accessor);
19
+ const handleChange = React.useCallback((e) => {
20
+ accessorGetter().updateValue(value);
21
+ }, [accessorGetter, value]);
17
22
  return /* @__PURE__ */ jsxRuntime.jsx(
18
23
  SlotInput,
19
24
  {
20
25
  ref,
21
26
  type: "radio",
22
- value,
27
+ value: typeof value === "string" ? value : void 0,
23
28
  checked: accessor.value === value,
24
- "data-invalid": utilities.dataAttribute(errors.length > 0),
25
- name: id + "-input",
26
- id: `${id}-input-${value}`,
29
+ "data-invalid": utilities.dataAttribute(hasErrors),
30
+ "data-dirty": utilities.dataAttribute(dirty),
31
+ name: id ? id + "-input" : void 0,
32
+ id: id ? `${id}-input` : void 0,
27
33
  onFocus,
28
34
  onBlur,
29
- onChange: React.useCallback((e) => {
30
- accessorGetter().updateValue(value);
31
- }, [accessorGetter, value]),
35
+ onChange: handleChange,
32
36
  ...props
33
37
  }
34
38
  );
@@ -1 +1 @@
1
- {"version":3,"file":"FormRadioInput.cjs","sources":["../../../../../packages/react-form/src/components/FormRadioInput.tsx"],"sourcesContent":["import { Component, Field, OptionallyVariableFieldValue, SugaredRelativeSingleField, useField } from '@contember/react-binding'\nimport * as React from 'react'\nimport { ChangeEventHandler, useCallback } from 'react'\nimport { Slot } from '@radix-ui/react-slot'\nimport { useFormError, useFormFieldId } from '../contexts'\nimport { useFormInputValidationHandler } from '../hooks'\nimport { dataAttribute } from '@contember/utilities'\n\nconst SlotInput = Slot as React.ForwardRefExoticComponent<React.RefAttributes<HTMLInputElement> & React.InputHTMLAttributes<HTMLInputElement>>\n\nexport interface FormRadioItemProps {\n\tfield: SugaredRelativeSingleField['field']\n\tvalue: string\n\tisNonbearing?: boolean\n\tdefaultValue?: OptionallyVariableFieldValue\n\tchildren: React.ReactNode\n}\n\nexport const FormRadioInput = Component<FormRadioItemProps>(({ field, value, defaultValue, isNonbearing, ...props }) => {\n\tconst id = useFormFieldId()\n\tconst accessor = useField<string>(field)\n\tconst errors = useFormError() ?? accessor.errors?.errors ?? []\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\ttype=\"radio\"\n\t\t\tvalue={value}\n\t\t\tchecked={accessor.value === value}\n\t\t\tdata-invalid={dataAttribute(errors.length > 0)}\n\t\t\tname={id + '-input'}\n\t\t\tid={`${id}-input-${value}`}\n\t\t\tonFocus={onFocus}\n\t\t\tonBlur={onBlur}\n\t\t\tonChange={useCallback<ChangeEventHandler<HTMLInputElement>>(e => {\n\t\t\t\taccessorGetter().updateValue(value)\n\t\t\t}, [accessorGetter, value])}\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","useFormFieldId","useField","useFormError","useFormInputValidationHandler","jsx","dataAttribute","useCallback","Field"],"mappings":";;;;;;;;;AAQA,MAAM,YAAYA,UAAAA;AAUL,MAAA,iBAAiBC,aAAAA,UAA8B,CAAC,EAAE,OAAO,OAAO,cAAc,cAAc,GAAG,YAAY;AACvH,QAAM,KAAKC,SAAAA;AACL,QAAA,WAAWC,sBAAiB,KAAK;AACvC,QAAM,SAASC,SAAAA,aAAa,KAAK,SAAS,QAAQ,UAAU;AAC5D,QAAM,iBAAiB,SAAS;AAChC,QAAM,EAAE,KAAK,SAAS,OAAO,IAAIC,8BAAAA,8BAA8B,QAAQ;AAGtE,SAAAC,2BAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MACL;AAAA,MACA,SAAS,SAAS,UAAU;AAAA,MAC5B,gBAAcC,UAAA,cAAc,OAAO,SAAS,CAAC;AAAA,MAC7C,MAAM,KAAK;AAAA,MACX,IAAI,GAAG,EAAE,UAAU,KAAK;AAAA,MACxB;AAAA,MACA;AAAA,MACA,UAAUC,MAAAA,YAAkD,CAAK,MAAA;AACjD,uBAAA,EAAE,YAAY,KAAK;AAAA,MAAA,GAChC,CAAC,gBAAgB,KAAK,CAAC;AAAA,MACzB,GAAG;AAAA,IAAA;AAAA,EAAA;AAGP,GAAG,CAAC,EAAE,OAAO,cAAc,mBAAmB;AAC7C,SAAQF,2BAAAA,IAAAG,aAAAA,OAAA,EAAM,OAAc,cAA4B,aAA4B,CAAA;AACrF,CAAC;;"}
1
+ {"version":3,"file":"FormRadioInput.cjs","sources":["../../../../../packages/react-form/src/components/FormRadioInput.tsx"],"sourcesContent":["import { Component, Field, OptionallyVariableFieldValue, SugaredRelativeSingleField, useField } from '@contember/react-binding'\nimport { dataAttribute } from '@contember/utilities'\nimport { Slot } from '@radix-ui/react-slot'\nimport * as React from 'react'\nimport { ChangeEventHandler, useCallback } from 'react'\nimport { useFormFieldState } from '../contexts'\nimport { useFormInputValidationHandler } from '../hooks'\n\nconst SlotInput = Slot as React.ForwardRefExoticComponent<React.RefAttributes<HTMLInputElement> & React.InputHTMLAttributes<HTMLInputElement>>\n\nexport interface FormRadioItemProps {\n\tfield: SugaredRelativeSingleField['field']\n\tvalue: string | null | number | boolean\n\tisNonbearing?: boolean\n\tdefaultValue?: OptionallyVariableFieldValue\n\tchildren: React.ReactNode\n}\n\nexport const FormRadioInput = Component<FormRadioItemProps>(({ field, value, defaultValue, isNonbearing, ...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\n\tconst accessorGetter = accessor.getAccessor\n\tconst { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor)\n\n\tconst handleChange = useCallback<ChangeEventHandler<HTMLInputElement>>(e => {\n\t\taccessorGetter().updateValue(value)\n\t}, [accessorGetter, value])\n\n\treturn (\n\t\t<SlotInput\n\t\t\tref={ref}\n\t\t\ttype=\"radio\"\n\t\t\tvalue={typeof value === 'string' ? value : undefined}\n\t\t\tchecked={accessor.value === value}\n\t\t\tdata-invalid={dataAttribute(hasErrors)}\n\t\t\tdata-dirty={dataAttribute(dirty)}\n\t\t\tname={id ? id + '-input' : undefined}\n\t\t\tid={id ? `${id}-input` : undefined}\n\t\t\tonFocus={onFocus}\n\t\t\tonBlur={onBlur}\n\t\t\tonChange={handleChange}\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","useFormInputValidationHandler","useCallback","jsx","dataAttribute","Field"],"mappings":";;;;;;;;;AAQA,MAAM,YAAYA,UAAA;AAUL,MAAA,iBAAiBC,aAAAA,UAA8B,CAAC,EAAE,OAAO,OAAO,cAAc,cAAc,GAAG,YAAY;AACjH,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;AAE3C,QAAM,iBAAiB,SAAS;AAChC,QAAM,EAAE,KAAK,SAAS,OAAO,IAAIC,8BAAAA,8BAA8B,QAAQ;AAEjE,QAAA,eAAeC,kBAAkD,CAAK,MAAA;AAC5D,mBAAA,EAAE,YAAY,KAAK;AAAA,EAAA,GAChC,CAAC,gBAAgB,KAAK,CAAC;AAGzB,SAAAC,2BAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MACL,OAAO,OAAO,UAAU,WAAW,QAAQ;AAAA,MAC3C,SAAS,SAAS,UAAU;AAAA,MAC5B,gBAAcC,wBAAc,SAAS;AAAA,MACrC,cAAYA,wBAAc,KAAK;AAAA,MAC/B,MAAM,KAAK,KAAK,WAAW;AAAA,MAC3B,IAAI,KAAK,GAAG,EAAE,WAAW;AAAA,MACzB;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACT,GAAG;AAAA,IAAA;AAAA,EACL;AAEF,GAAG,CAAC,EAAE,OAAO,cAAc,mBAAmB;AAC7C,SAAQD,2BAAAA,IAAAE,aAAAA,OAAA,EAAM,OAAc,cAA4B,aAA2B,CAAA;AACpF,CAAC;;"}
@@ -1,32 +1,36 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { Component, useField, Field } from "@contember/react-binding";
3
- import { useCallback } from "react";
4
- import { Slot } from "@radix-ui/react-slot";
5
- import { useFormFieldId, useFormError } from "../contexts.js";
6
3
  import { dataAttribute } from "@contember/utilities";
4
+ import { Slot } from "@radix-ui/react-slot";
5
+ import { useCallback } from "react";
6
+ import { useFormFieldState } from "../contexts.js";
7
7
  import { useFormInputValidationHandler } from "../hooks/useFormInputValidationHandler.js";
8
8
  const SlotInput = Slot;
9
9
  const FormRadioInput = Component(({ field, value, defaultValue, isNonbearing, ...props }) => {
10
- const id = useFormFieldId();
11
10
  const accessor = useField(field);
12
- const errors = useFormError() ?? accessor.errors?.errors ?? [];
11
+ const formState = useFormFieldState();
12
+ const id = formState?.htmlId;
13
+ const hasErrors = (formState?.errors.length ?? accessor.errors?.errors?.length ?? 0) > 0;
14
+ const dirty = formState?.dirty ?? accessor.hasUnpersistedChanges;
13
15
  const accessorGetter = accessor.getAccessor;
14
16
  const { ref, onFocus, onBlur } = useFormInputValidationHandler(accessor);
17
+ const handleChange = useCallback((e) => {
18
+ accessorGetter().updateValue(value);
19
+ }, [accessorGetter, value]);
15
20
  return /* @__PURE__ */ jsx(
16
21
  SlotInput,
17
22
  {
18
23
  ref,
19
24
  type: "radio",
20
- value,
25
+ value: typeof value === "string" ? value : void 0,
21
26
  checked: accessor.value === value,
22
- "data-invalid": dataAttribute(errors.length > 0),
23
- name: id + "-input",
24
- id: `${id}-input-${value}`,
27
+ "data-invalid": dataAttribute(hasErrors),
28
+ "data-dirty": dataAttribute(dirty),
29
+ name: id ? id + "-input" : void 0,
30
+ id: id ? `${id}-input` : void 0,
25
31
  onFocus,
26
32
  onBlur,
27
- onChange: useCallback((e) => {
28
- accessorGetter().updateValue(value);
29
- }, [accessorGetter, value]),
33
+ onChange: handleChange,
30
34
  ...props
31
35
  }
32
36
  );