@strictly/react-form 0.0.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 (239) hide show
  1. package/.eslintrc.cjs +26 -0
  2. package/.out/.storybook/main.d.ts +3 -0
  3. package/.out/.storybook/main.js +32 -0
  4. package/.out/.storybook/preview.d.ts +4 -0
  5. package/.out/.storybook/preview.js +20 -0
  6. package/.out/.vitest/install_deterministic_random.d.ts +2 -0
  7. package/.out/.vitest/install_deterministic_random.js +15 -0
  8. package/.out/.vitest/install_storybook_preview.d.ts +1 -0
  9. package/.out/.vitest/install_storybook_preview.js +7 -0
  10. package/.out/.vitest/match_media.d.ts +1 -0
  11. package/.out/.vitest/match_media.js +5 -0
  12. package/.out/.vitest/resize_observer.d.ts +1 -0
  13. package/.out/.vitest/resize_observer.js +4 -0
  14. package/.out/core/mobx/field_adapter.d.ts +9 -0
  15. package/.out/core/mobx/field_adapter.js +1 -0
  16. package/.out/core/mobx/field_adapter_builder.d.ts +22 -0
  17. package/.out/core/mobx/field_adapter_builder.js +56 -0
  18. package/.out/core/mobx/flattened_adapters_of_fields.d.ts +9 -0
  19. package/.out/core/mobx/flattened_adapters_of_fields.js +1 -0
  20. package/.out/core/mobx/flattened_list_type_defs_of.d.ts +8 -0
  21. package/.out/core/mobx/flattened_list_type_defs_of.js +1 -0
  22. package/.out/core/mobx/form_presenter.d.ts +61 -0
  23. package/.out/core/mobx/form_presenter.js +425 -0
  24. package/.out/core/mobx/specs/flattened_adapters_of_fields.tests.d.ts +1 -0
  25. package/.out/core/mobx/specs/flattened_adapters_of_fields.tests.js +13 -0
  26. package/.out/core/mobx/specs/flattened_list_type_defs_of.tests.d.ts +1 -0
  27. package/.out/core/mobx/specs/flattened_list_type_defs_of.tests.js +16 -0
  28. package/.out/core/mobx/specs/form_presenter.tests.d.ts +1 -0
  29. package/.out/core/mobx/specs/form_presenter.tests.js +697 -0
  30. package/.out/core/mobx/types.d.ts +19 -0
  31. package/.out/core/mobx/types.js +1 -0
  32. package/.out/core/props.d.ts +12 -0
  33. package/.out/core/props.js +1 -0
  34. package/.out/field_converters/chain_field_converter.d.ts +3 -0
  35. package/.out/field_converters/chain_field_converter.js +46 -0
  36. package/.out/field_converters/identity_converter.d.ts +3 -0
  37. package/.out/field_converters/identity_converter.js +14 -0
  38. package/.out/field_converters/integer_to_string_converter.d.ts +7 -0
  39. package/.out/field_converters/integer_to_string_converter.js +26 -0
  40. package/.out/field_converters/list_converter.d.ts +2 -0
  41. package/.out/field_converters/list_converter.js +8 -0
  42. package/.out/field_converters/maybe_identity_converter.d.ts +8 -0
  43. package/.out/field_converters/maybe_identity_converter.js +15 -0
  44. package/.out/field_converters/nullable_to_boolean_converter.d.ts +11 -0
  45. package/.out/field_converters/nullable_to_boolean_converter.js +31 -0
  46. package/.out/field_converters/select_value_type_converter.d.ts +23 -0
  47. package/.out/field_converters/select_value_type_converter.js +60 -0
  48. package/.out/field_converters/trimming_string_converter.d.ts +6 -0
  49. package/.out/field_converters/trimming_string_converter.js +14 -0
  50. package/.out/field_converters/validating_converter.d.ts +3 -0
  51. package/.out/field_converters/validating_converter.js +21 -0
  52. package/.out/field_validators/minimum_string_length_field_validator.d.ts +2 -0
  53. package/.out/field_validators/minimum_string_length_field_validator.js +8 -0
  54. package/.out/field_value_factories/prototyping_field_value_factory.d.ts +2 -0
  55. package/.out/field_value_factories/prototyping_field_value_factory.js +5 -0
  56. package/.out/index.d.ts +16 -0
  57. package/.out/index.js +16 -0
  58. package/.out/mantine/create_checkbox.d.ts +9 -0
  59. package/.out/mantine/create_checkbox.js +37 -0
  60. package/.out/mantine/create_list.d.ts +15 -0
  61. package/.out/mantine/create_list.js +16 -0
  62. package/.out/mantine/create_pill.d.ts +7 -0
  63. package/.out/mantine/create_pill.js +15 -0
  64. package/.out/mantine/create_radio.d.ts +8 -0
  65. package/.out/mantine/create_radio.js +10 -0
  66. package/.out/mantine/create_radio_group.d.ts +9 -0
  67. package/.out/mantine/create_radio_group.js +34 -0
  68. package/.out/mantine/create_text_input.d.ts +19 -0
  69. package/.out/mantine/create_text_input.js +38 -0
  70. package/.out/mantine/create_value_input.d.ts +17 -0
  71. package/.out/mantine/create_value_input.js +38 -0
  72. package/.out/mantine/hooks.d.ts +56 -0
  73. package/.out/mantine/hooks.js +135 -0
  74. package/.out/mantine/specs/checkbox_constants.d.ts +1 -0
  75. package/.out/mantine/specs/checkbox_constants.js +1 -0
  76. package/.out/mantine/specs/checkbox_hooks.stories.d.ts +13 -0
  77. package/.out/mantine/specs/checkbox_hooks.stories.js +63 -0
  78. package/.out/mantine/specs/checkbox_hooks.tests.d.ts +1 -0
  79. package/.out/mantine/specs/checkbox_hooks.tests.js +74 -0
  80. package/.out/mantine/specs/list_hooks.stories.d.ts +11 -0
  81. package/.out/mantine/specs/list_hooks.stories.js +48 -0
  82. package/.out/mantine/specs/list_hooks.tests.d.ts +1 -0
  83. package/.out/mantine/specs/list_hooks.tests.js +12 -0
  84. package/.out/mantine/specs/radio_group_constants.d.ts +4 -0
  85. package/.out/mantine/specs/radio_group_constants.js +11 -0
  86. package/.out/mantine/specs/radio_group_hooks.stories.d.ts +14 -0
  87. package/.out/mantine/specs/radio_group_hooks.stories.js +68 -0
  88. package/.out/mantine/specs/radio_group_hooks.tests.d.ts +1 -0
  89. package/.out/mantine/specs/radio_group_hooks.tests.js +62 -0
  90. package/.out/mantine/specs/select_hooks.stories.d.ts +12 -0
  91. package/.out/mantine/specs/select_hooks.stories.js +57 -0
  92. package/.out/mantine/specs/select_hooks.tests.d.ts +1 -0
  93. package/.out/mantine/specs/select_hooks.tests.js +12 -0
  94. package/.out/mantine/specs/select_hooks_constant.d.ts +1 -0
  95. package/.out/mantine/specs/select_hooks_constant.js +1 -0
  96. package/.out/mantine/specs/text_input_constants.d.ts +1 -0
  97. package/.out/mantine/specs/text_input_constants.js +1 -0
  98. package/.out/mantine/specs/text_input_hooks.stories.d.ts +21 -0
  99. package/.out/mantine/specs/text_input_hooks.stories.js +88 -0
  100. package/.out/mantine/specs/text_input_hooks.tests.d.ts +1 -0
  101. package/.out/mantine/specs/text_input_hooks.tests.js +79 -0
  102. package/.out/mantine/specs/value_input_constants.d.ts +2 -0
  103. package/.out/mantine/specs/value_input_constants.js +2 -0
  104. package/.out/mantine/specs/value_input_hooks.stories.d.ts +23 -0
  105. package/.out/mantine/specs/value_input_hooks.stories.js +124 -0
  106. package/.out/mantine/specs/value_input_hooks.tests.d.ts +1 -0
  107. package/.out/mantine/specs/value_input_hooks.tests.js +12 -0
  108. package/.out/mantine/types.d.ts +11 -0
  109. package/.out/mantine/types.js +1 -0
  110. package/.out/tsconfig.json +27 -0
  111. package/.out/tsconfig.tsbuildinfo +1 -0
  112. package/.out/tsup.config.d.ts +3 -0
  113. package/.out/tsup.config.js +12 -0
  114. package/.out/types/all_fields_of_fields.d.ts +5 -0
  115. package/.out/types/all_fields_of_fields.js +1 -0
  116. package/.out/types/boolean_fields_of_fields.d.ts +5 -0
  117. package/.out/types/boolean_fields_of_fields.js +1 -0
  118. package/.out/types/error_type_of_field.d.ts +2 -0
  119. package/.out/types/error_type_of_field.js +1 -0
  120. package/.out/types/field.d.ts +7 -0
  121. package/.out/types/field.js +1 -0
  122. package/.out/types/field_converters.d.ts +29 -0
  123. package/.out/types/field_converters.js +5 -0
  124. package/.out/types/field_validator.d.ts +3 -0
  125. package/.out/types/field_validator.js +1 -0
  126. package/.out/types/flattened_form_fields_of.d.ts +9 -0
  127. package/.out/types/flattened_form_fields_of.js +1 -0
  128. package/.out/types/list_fields_of_fields.d.ts +5 -0
  129. package/.out/types/list_fields_of_fields.js +1 -0
  130. package/.out/types/specs/boolean_fields_of_fields.tests.d.ts +1 -0
  131. package/.out/types/specs/boolean_fields_of_fields.tests.js +11 -0
  132. package/.out/types/specs/error_type_of_field.tests.d.ts +1 -0
  133. package/.out/types/specs/error_type_of_field.tests.js +7 -0
  134. package/.out/types/specs/flattened_form_fields_of.tests.d.ts +1 -0
  135. package/.out/types/specs/flattened_form_fields_of.tests.js +13 -0
  136. package/.out/types/specs/string_fields_of_fields.tests.d.ts +1 -0
  137. package/.out/types/specs/string_fields_of_fields.tests.js +19 -0
  138. package/.out/types/specs/value_type_of_field.tests.d.ts +1 -0
  139. package/.out/types/specs/value_type_of_field.tests.js +7 -0
  140. package/.out/types/string_fields_of_fields.d.ts +5 -0
  141. package/.out/types/string_fields_of_fields.js +1 -0
  142. package/.out/types/value_type_of_field.d.ts +2 -0
  143. package/.out/types/value_type_of_field.js +1 -0
  144. package/.out/util/partial.d.ts +11 -0
  145. package/.out/util/partial.js +74 -0
  146. package/.out/vitest.workspace.d.ts +2 -0
  147. package/.out/vitest.workspace.js +22 -0
  148. package/.storybook/main.ts +40 -0
  149. package/.storybook/preview.tsx +28 -0
  150. package/.storybook/vite.config.mts +38 -0
  151. package/.turbo/turbo-build.log +18 -0
  152. package/.turbo/turbo-check-types.log +3 -0
  153. package/.turbo/turbo-release$colon$exports.log +3 -0
  154. package/.vitest/install_deterministic_random.ts +17 -0
  155. package/.vitest/install_storybook_preview.ts +9 -0
  156. package/.vitest/match_media.ts +7 -0
  157. package/.vitest/resize_observer.ts +5 -0
  158. package/README.md +2 -0
  159. package/core/mobx/field_adapter.ts +32 -0
  160. package/core/mobx/field_adapter_builder.ts +313 -0
  161. package/core/mobx/flattened_adapters_of_fields.ts +35 -0
  162. package/core/mobx/flattened_list_type_defs_of.ts +17 -0
  163. package/core/mobx/form_presenter.ts +705 -0
  164. package/core/mobx/specs/flattened_adapters_of_fields.tests.ts +72 -0
  165. package/core/mobx/specs/flattened_list_type_defs_of.tests.ts +35 -0
  166. package/core/mobx/specs/form_presenter.tests.ts +989 -0
  167. package/core/mobx/types.ts +54 -0
  168. package/core/props.ts +21 -0
  169. package/dist/index.cjs +11479 -0
  170. package/dist/index.d.cts +345 -0
  171. package/dist/index.d.ts +345 -0
  172. package/dist/index.js +11486 -0
  173. package/field_converters/chain_field_converter.ts +74 -0
  174. package/field_converters/identity_converter.ts +39 -0
  175. package/field_converters/integer_to_string_converter.ts +32 -0
  176. package/field_converters/list_converter.ts +15 -0
  177. package/field_converters/maybe_identity_converter.ts +23 -0
  178. package/field_converters/nullable_to_boolean_converter.ts +56 -0
  179. package/field_converters/select_value_type_converter.ts +141 -0
  180. package/field_converters/trimming_string_converter.ts +23 -0
  181. package/field_converters/validating_converter.ts +35 -0
  182. package/field_validators/minimum_string_length_field_validator.ts +13 -0
  183. package/field_value_factories/prototyping_field_value_factory.ts +11 -0
  184. package/index.ts +16 -0
  185. package/mantine/create_checkbox.tsx +79 -0
  186. package/mantine/create_list.tsx +58 -0
  187. package/mantine/create_pill.tsx +43 -0
  188. package/mantine/create_radio.tsx +36 -0
  189. package/mantine/create_radio_group.tsx +71 -0
  190. package/mantine/create_text_input.tsx +80 -0
  191. package/mantine/create_value_input.tsx +81 -0
  192. package/mantine/hooks.tsx +394 -0
  193. package/mantine/specs/__snapshots__/check_box_hooks.tests.tsx.snap +227 -0
  194. package/mantine/specs/__snapshots__/checkbox_hooks.tests.tsx.snap +227 -0
  195. package/mantine/specs/__snapshots__/list_hooks.tests.tsx.snap +68 -0
  196. package/mantine/specs/__snapshots__/radio_group_hooks.tests.tsx.snap +695 -0
  197. package/mantine/specs/__snapshots__/select_hooks.tests.tsx.snap +225 -0
  198. package/mantine/specs/__snapshots__/text_input_hooks.tests.tsx.snap +202 -0
  199. package/mantine/specs/__snapshots__/value_input_hooks.tests.tsx.snap +613 -0
  200. package/mantine/specs/checkbox_constants.ts +1 -0
  201. package/mantine/specs/checkbox_hooks.stories.tsx +79 -0
  202. package/mantine/specs/checkbox_hooks.tests.tsx +100 -0
  203. package/mantine/specs/list_hooks.stories.tsx +83 -0
  204. package/mantine/specs/list_hooks.tests.tsx +15 -0
  205. package/mantine/specs/radio_group_constants.ts +12 -0
  206. package/mantine/specs/radio_group_hooks.stories.tsx +103 -0
  207. package/mantine/specs/radio_group_hooks.tests.tsx +92 -0
  208. package/mantine/specs/select_hooks.stories.tsx +77 -0
  209. package/mantine/specs/select_hooks.tests.tsx +14 -0
  210. package/mantine/specs/select_hooks_constant.ts +1 -0
  211. package/mantine/specs/text_input_constants.ts +1 -0
  212. package/mantine/specs/text_input_hooks.stories.tsx +124 -0
  213. package/mantine/specs/text_input_hooks.tests.tsx +106 -0
  214. package/mantine/specs/value_input_constants.ts +2 -0
  215. package/mantine/specs/value_input_hooks.stories.tsx +182 -0
  216. package/mantine/specs/value_input_hooks.tests.tsx +14 -0
  217. package/mantine/types.ts +13 -0
  218. package/package.exports.json +18 -0
  219. package/package.json +74 -0
  220. package/tsconfig.build.json +13 -0
  221. package/tsconfig.json +27 -0
  222. package/tsup.config.ts +16 -0
  223. package/types/all_fields_of_fields.ts +9 -0
  224. package/types/boolean_fields_of_fields.ts +8 -0
  225. package/types/error_type_of_field.ts +3 -0
  226. package/types/field.ts +9 -0
  227. package/types/field_converters.ts +64 -0
  228. package/types/field_validator.ts +7 -0
  229. package/types/flattened_form_fields_of.ts +16 -0
  230. package/types/list_fields_of_fields.ts +7 -0
  231. package/types/specs/boolean_fields_of_fields.tests.ts +23 -0
  232. package/types/specs/error_type_of_field.tests.ts +10 -0
  233. package/types/specs/flattened_form_fields_of.tests.ts +43 -0
  234. package/types/specs/string_fields_of_fields.tests.ts +40 -0
  235. package/types/specs/value_type_of_field.tests.ts +10 -0
  236. package/types/string_fields_of_fields.ts +6 -0
  237. package/types/value_type_of_field.ts +3 -0
  238. package/util/partial.tsx +200 -0
  239. package/vitest.workspace.ts +26 -0
@@ -0,0 +1,3 @@
1
+ import { type Options } from 'tsup';
2
+ declare const _default: Options | Options[] | ((overrideOptions: Options) => Options | Options[] | Promise<Options | Options[]>);
3
+ export default _default;
@@ -0,0 +1,12 @@
1
+ import { defineConfig, } from 'tsup';
2
+ export default defineConfig((options) => ({
3
+ entry: ['index.ts'],
4
+ tsconfig: './tsconfig.build.json',
5
+ clean: false,
6
+ dts: true,
7
+ format: [
8
+ 'cjs',
9
+ 'esm',
10
+ ],
11
+ ...options,
12
+ }));
@@ -0,0 +1,5 @@
1
+ import { type Fields } from './field';
2
+ import { type ValueTypeOfField } from './value_type_of_field';
3
+ export type AllFieldsOfFields<F extends Fields> = {
4
+ [K in keyof F as ValueTypeOfField<F[K]> extends any ? K : never]: F[K];
5
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import { type Fields } from './field';
2
+ import { type ValueTypeOfField } from './value_type_of_field';
3
+ export type BooleanFieldsOfFields<F extends Fields> = {
4
+ [K in keyof F as ValueTypeOfField<F[K]> extends boolean ? K : never]: F[K];
5
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import { type Field } from './field';
2
+ export type ErrorTypeOfField<F extends Field> = F extends Field<infer _V, infer E> ? E : never;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ export type Field<V = any, E = any> = {
2
+ readonly value: V;
3
+ readonly error?: E | undefined;
4
+ readonly disabled: boolean;
5
+ readonly required: boolean;
6
+ };
7
+ export type Fields = Readonly<Record<string, Field>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ import { type Maybe } from '@strictly/base';
2
+ export declare enum FieldConversionResult {
3
+ Success = 0,
4
+ Failure = 1
5
+ }
6
+ export type FieldConversion<V, E> = {
7
+ type: FieldConversionResult.Success;
8
+ value: V;
9
+ } | {
10
+ type: FieldConversionResult.Failure;
11
+ error: E;
12
+ value: Maybe<V>;
13
+ };
14
+ export type FieldConverter<From, To, E, ValuePath extends string, Context> = {
15
+ (from: From, valuePath: ValuePath, context: Context): FieldConversion<To, E>;
16
+ };
17
+ export type SafeFieldConverter<From, To, ValuePath extends string, Context> = {
18
+ (from: From, valuePath: ValuePath, context: Context): To;
19
+ };
20
+ export type TwoWayFieldConverter<From, To, E, ValuePath extends string, Context> = {
21
+ convert: SafeFieldConverter<From, To, ValuePath, Context>;
22
+ revert: FieldConverter<To, From, E, ValuePath, Context>;
23
+ };
24
+ export type FieldValueFactory<V, ValuePath extends string, Context> = {
25
+ (valuePath: ValuePath, context: Context): V;
26
+ };
27
+ export type TwoWayFieldConverterWithValueFactory<From, To, E, ValuePath extends string, Context> = TwoWayFieldConverter<From, To, E, ValuePath, Context> & {
28
+ readonly create: FieldValueFactory<From, ValuePath, Context>;
29
+ };
@@ -0,0 +1,5 @@
1
+ export var FieldConversionResult;
2
+ (function (FieldConversionResult) {
3
+ FieldConversionResult[FieldConversionResult["Success"] = 0] = "Success";
4
+ FieldConversionResult[FieldConversionResult["Failure"] = 1] = "Failure";
5
+ })(FieldConversionResult || (FieldConversionResult = {}));
@@ -0,0 +1,3 @@
1
+ export type FieldValidator<V, E, ValuePath extends string, Context> = {
2
+ (value: V, valuePath: ValuePath, context: Context): E | null;
3
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import { type PrintableOf } from '@strictly/base';
2
+ import { type ValueOf } from 'type-fest';
3
+ import { type Field } from './field';
4
+ /**
5
+ * Maps type paths to value paths for
6
+ */
7
+ export type FlattenedFormFieldsOf<JsonPaths extends Record<string, string>, TypePathsToFormFields extends Partial<Readonly<Record<ValueOf<JsonPaths>, Field>>>> = keyof TypePathsToFormFields extends ValueOf<JsonPaths> ? {
8
+ readonly [K in keyof JsonPaths as unknown extends TypePathsToFormFields[JsonPaths[K]] ? never : K]: TypePathsToFormFields[JsonPaths[K]];
9
+ } : `fields missing paths: ${PrintableOf<Exclude<keyof TypePathsToFormFields, ValueOf<JsonPaths>>>}`;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import { type Fields } from './field';
2
+ import { type ValueTypeOfField } from './value_type_of_field';
3
+ export type ListFieldsOfFields<F extends Fields> = {
4
+ [K in keyof F as ValueTypeOfField<F[K]> extends readonly any[] ? K : never]: F[K];
5
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ describe('BooleanFieldsOfFields', function () {
2
+ describe('filtering', function () {
3
+ const e1 = Symbol();
4
+ const e2 = Symbol();
5
+ const e3 = Symbol();
6
+ it('equals expected type', function () {
7
+ expectTypeOf().toEqualTypeOf();
8
+ });
9
+ });
10
+ });
11
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ describe('ErrorTypeOfField', function () {
2
+ it('equals expected type', function () {
3
+ const e = Symbol();
4
+ expectTypeOf().toEqualTypeOf();
5
+ });
6
+ });
7
+ export {};
@@ -0,0 +1,13 @@
1
+ describe('FlattenedFormFieldsOf', function () {
2
+ describe('subset', function () {
3
+ it('equals expected type', function () {
4
+ expectTypeOf().toEqualTypeOf();
5
+ });
6
+ });
7
+ describe('overlap', function () {
8
+ it('errors to callee', function () {
9
+ expectTypeOf().toEqualTypeOf();
10
+ });
11
+ });
12
+ });
13
+ export {};
@@ -0,0 +1,19 @@
1
+ describe('StringFieldsOfFields', function () {
2
+ describe('filtering', function () {
3
+ const e1 = Symbol();
4
+ const e2 = Symbol();
5
+ const e3 = Symbol();
6
+ it('equals expected type', function () {
7
+ expectTypeOf().toEqualTypeOf();
8
+ });
9
+ });
10
+ describe('string union with null', function () {
11
+ const e = Symbol();
12
+ describe('StringFieldsOfFields', function () {
13
+ it('equals expected type', function () {
14
+ expectTypeOf().toEqualTypeOf();
15
+ });
16
+ });
17
+ });
18
+ });
19
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ describe('ValueTypeOfField', function () {
2
+ it('equals expected type', function () {
3
+ const v = Symbol();
4
+ expectTypeOf().toEqualTypeOf();
5
+ });
6
+ });
7
+ export {};
@@ -0,0 +1,5 @@
1
+ import { type Fields } from './field';
2
+ import { type ValueTypeOfField } from './value_type_of_field';
3
+ export type StringFieldsOfFields<F extends Fields> = {
4
+ [K in keyof F as ValueTypeOfField<F[K]> extends string | undefined | null ? K : never]: F[K];
5
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import { type Field } from './field';
2
+ export type ValueTypeOfField<F extends Field> = F extends Field<infer V> ? V : never;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { type ComponentProps, type ComponentType, type DependencyList, type ForwardRefExoticComponent, type PropsWithoutRef } from 'react';
2
+ export type PartialComponent<Component extends ComponentType<any>, CurriedProps, AdditionalProps = {}> = Exclude<keyof CurriedProps, keyof ComponentProps<Component>> extends never ? UnsafePartialComponent<Component, CurriedProps, AdditionalProps> : keyof CurriedProps extends (string | number) ? `unmatched prop: ${Exclude<keyof CurriedProps, keyof ComponentProps<Component>>}` : Exclude<keyof CurriedProps, keyof ComponentProps<Component>>;
3
+ export type UnsafePartialComponent<Component extends ComponentType<any>, CurriedProps, AdditionalProps = {}> = ForwardRefExoticComponent<PropsWithoutRef<RemainingComponentProps<Component, CurriedProps> & AdditionalProps>>;
4
+ export declare function createSimplePartialComponent<Component extends ComponentType<any>, CurriedProps extends Partial<ComponentProps<Component>>>(Component: Component, curriedProps: CurriedProps): PartialComponent<Component, CurriedProps>;
5
+ export declare function createPartialComponent<Component extends ComponentType<any>, CurriedProps extends Partial<ComponentProps<Component>>, AdditionalProps = {}>(Component: Component, curriedPropsSource: (additionalProps: AdditionalProps) => CurriedProps): PartialComponent<Component, CurriedProps, AdditionalProps>;
6
+ export declare function usePartialComponent<Component extends ComponentType<any>, CurriedProps extends Partial<ComponentProps<Component>>, AdditionalProps = {}>(createCurriedProps: (additionalProps: AdditionalProps) => CurriedProps, deps: DependencyList, Component: Component): PartialComponent<Component, CurriedProps, AdditionalProps>;
7
+ export declare function createPartialObserverComponent<Component extends ComponentType<any>, CurriedProps extends Partial<ComponentProps<Component>>, AdditionalProps = {}>(Component: Component, curriedPropsSource: (additionalProps: AdditionalProps) => CurriedProps): PartialComponent<Component, CurriedProps, AdditionalProps>;
8
+ export declare function createUnsafePartialObserverComponent<Component extends ComponentType<any>, CurriedProps, AdditionalProps = {}>(Component: Component, curriedPropsSource: (additionalProps: AdditionalProps) => CurriedProps): UnsafePartialComponent<Component, CurriedProps, AdditionalProps>;
9
+ export declare function usePartialObserverComponent<Component extends ComponentType<any>, CurriedProps extends Partial<ComponentProps<Component>>, AdditionalProps = {}>(curriedPropsSource: (additionalProps: AdditionalProps) => CurriedProps, deps: DependencyList, Component: Component): PartialComponent<Component, CurriedProps, AdditionalProps>;
10
+ type RemainingComponentProps<Component extends ComponentType, CurriedProps> = Omit<ComponentProps<Component>, keyof CurriedProps> & JSX.IntrinsicAttributes;
11
+ export {};
@@ -0,0 +1,74 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { observer } from 'mobx-react';
3
+ import { forwardRef, useMemo, } from 'react';
4
+ export function createSimplePartialComponent(Component, curriedProps) {
5
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
6
+ return forwardRef(function (exposedProps, ref) {
7
+ // forward ref types are really difficult to work with
8
+ // still needs a cast as `extends ComponentType<any>` != `ComponentType<any>`
9
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unnecessary-type-assertion
10
+ const C = Component;
11
+ return (_jsx(C, { ref: ref, ...curriedProps, ...exposedProps }));
12
+ });
13
+ }
14
+ export function createPartialComponent(Component, curriedPropsSource) {
15
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
16
+ return forwardRef(function (exposedProps, ref) {
17
+ // forward ref types are really difficult to work with
18
+ // still needs a cast as `extends ComponentType<any>` != `ComponentType<any>`
19
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unnecessary-type-assertion
20
+ const C = Component;
21
+ // TODO is there any way we can memoize this transformation?
22
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
23
+ const curriedProps = curriedPropsSource(exposedProps);
24
+ return (_jsx(C, { ref: ref, ...curriedProps, ...exposedProps }));
25
+ });
26
+ }
27
+ export function usePartialComponent(
28
+ // has to be first so eslint react-hooks/exhaustive-deps can find the callback
29
+ // has to be a function so eslint react-hooks/exhaustive-deps can reason about it :(
30
+ createCurriedProps,
31
+ // has to be next so eslint react-hooks/exhaustive-deps can find the deps
32
+ deps, Component) {
33
+ return useMemo(function () {
34
+ return createPartialComponent(Component, createCurriedProps);
35
+ },
36
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37
+ [
38
+ // eslint-disable-next-line react-hooks/exhaustive-deps
39
+ ...deps,
40
+ Component,
41
+ ]);
42
+ }
43
+ export function createPartialObserverComponent(Component, curriedPropsSource) {
44
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
45
+ return createUnsafePartialObserverComponent(Component, curriedPropsSource);
46
+ }
47
+ export function createUnsafePartialObserverComponent(Component, curriedPropsSource) {
48
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
49
+ return observer(forwardRef(function (exposedProps, ref) {
50
+ // forward ref types are really difficult to work with
51
+ // still needs a cast as `extends ComponentType<any>` != `ComponentType<any>`
52
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unnecessary-type-assertion
53
+ const C = Component;
54
+ // TODO is there any way we can memoize this transformation?
55
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
56
+ const curriedProps = curriedPropsSource(exposedProps);
57
+ return (_jsx(C, { ref: ref, ...curriedProps, ...exposedProps }));
58
+ }));
59
+ }
60
+ export function usePartialObserverComponent(
61
+ // has to be first so eslint react-hooks/exhaustive-deps can find the callback
62
+ curriedPropsSource,
63
+ // has to be next so eslint react-hooks/exhaustive-deps can find the deps
64
+ deps, Component) {
65
+ return useMemo(function () {
66
+ return createPartialObserverComponent(Component, curriedPropsSource);
67
+ },
68
+ // eslint-disable-next-line react-hooks/exhaustive-deps
69
+ [
70
+ // eslint-disable-next-line react-hooks/exhaustive-deps
71
+ ...deps,
72
+ Component,
73
+ ]);
74
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vitest/config").WorkspaceProjectConfiguration[];
2
+ export default _default;
@@ -0,0 +1,22 @@
1
+ import { createVitestUserConfig } from '@strictly/support-vite';
2
+ import { defineWorkspace, } from 'vitest/config';
3
+ import tsconfig from './tsconfig.json';
4
+ const config = createVitestUserConfig(tsconfig);
5
+ export default defineWorkspace([
6
+ '.',
7
+ {
8
+ ...config,
9
+ extends: './.storybook/vite.config.mts',
10
+ test: {
11
+ ...(config.test || {}),
12
+ environment: 'jsdom',
13
+ setupFiles: [
14
+ './.vitest/install_deterministic_random.ts',
15
+ // install storybook setup for unit tests that import stories directly
16
+ './.vitest/install_storybook_preview.ts',
17
+ './.vitest/match_media.ts',
18
+ './.vitest/resize_observer.ts',
19
+ ],
20
+ },
21
+ },
22
+ ]);
@@ -0,0 +1,40 @@
1
+ /* eslint-env node */
2
+ import { type StorybookConfig } from '@storybook/react-vite'
3
+ import {
4
+ dirname,
5
+ join,
6
+ } from 'path'
7
+
8
+ /**
9
+ * This function is used to resolve the absolute path of a package.
10
+ * It is needed in projects that use Yarn PnP or are set up within a monorepo.
11
+ */
12
+ function getAbsolutePath(value: string) {
13
+ return dirname(require.resolve(join(value, 'package.json')))
14
+ }
15
+
16
+ const config: StorybookConfig = {
17
+ stories: ['../**/*.stories.@(ts|tsx)'],
18
+
19
+ addons: [
20
+ getAbsolutePath('@storybook/addon-links'),
21
+ getAbsolutePath('@storybook/addon-essentials'),
22
+ getAbsolutePath('@chromatic-com/storybook'),
23
+ getAbsolutePath('@storybook/addon-interactions'),
24
+ ],
25
+ core: {
26
+ builder: {
27
+ name: getAbsolutePath('@storybook/builder-vite'),
28
+ options: {
29
+ viteConfigPath: './.storybook/vite.config.mts',
30
+ },
31
+ },
32
+ },
33
+ framework: {
34
+ // NOTE: the documentation says this should be @storybook/react-vite, which fails completely
35
+ // https://storybook.js.org/docs/get-started/frameworks/react-vite
36
+ name: getAbsolutePath('@storybook/react'),
37
+ options: {},
38
+ },
39
+ }
40
+ export default config
@@ -0,0 +1,28 @@
1
+ import '@mantine/core/styles.css'
2
+ import { MantineProvider } from '@mantine/core'
3
+ import { type Preview } from '@storybook/react'
4
+ import { StrictMode } from 'react'
5
+
6
+ const preview: Preview = {
7
+ parameters: {
8
+ controls: {
9
+ matchers: {
10
+ color: /(background|color)$/i,
11
+ date: /Date$/i,
12
+ },
13
+ },
14
+ },
15
+ decorators: [
16
+ function (Story: React.ComponentType) {
17
+ return (
18
+ <MantineProvider>
19
+ <StrictMode>
20
+ <Story />
21
+ </StrictMode>
22
+ </MantineProvider>
23
+ )
24
+ },
25
+ ],
26
+ }
27
+
28
+ export default preview
@@ -0,0 +1,38 @@
1
+ import reactSupport from '@vitejs/plugin-react'
2
+ import tsconfigPaths from 'vite-tsconfig-paths'
3
+ import { defineConfig } from 'vitest/config'
4
+ // eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
5
+ import tsconfig from '../tsconfig.json'
6
+ // unfortunately, unlike vitest, vite cannot import this in its configuration
7
+ // const config: UserConfig = createViteUserConfig(tsconfig)
8
+ // export default config
9
+ export default defineConfig({
10
+ plugins: [
11
+ reactSupport({
12
+ babel: {
13
+ plugins: [
14
+ [
15
+ '@babel/plugin-proposal-decorators',
16
+ {
17
+ version: '2023-05',
18
+ },
19
+ ],
20
+ ['@babel/plugin-transform-class-static-block'],
21
+ ['@babel/plugin-proposal-class-properties'],
22
+ ],
23
+ assumptions: {
24
+ setPublicClassFields: false,
25
+ },
26
+ },
27
+ }),
28
+ tsconfigPaths({
29
+ // must specify projects otherwise we get configuration errors for unrelated projects
30
+ projects: [
31
+ '.',
32
+ ...tsconfig.references.map(function ({ path }) {
33
+ return path
34
+ }),
35
+ ],
36
+ }),
37
+ ],
38
+ })
@@ -0,0 +1,18 @@
1
+ yarn run v1.22.22
2
+ $ tsup
3
+ CLI Building entry: index.ts
4
+ CLI Using tsconfig: tsconfig.build.json
5
+ CLI tsup v8.3.5
6
+ CLI Using tsup config: /home/runner/work/de/de/packages/react-form/tsup.config.ts
7
+ CLI Target: esnext
8
+ CJS Build start
9
+ ESM Build start
10
+ DTS Build start
11
+ ESM dist/index.js 356.07 KB
12
+ ESM ⚡️ Build success in 1306ms
13
+ CJS dist/index.cjs 365.80 KB
14
+ CJS ⚡️ Build success in 1307ms
15
+ DTS ⚡️ Build success in 10156ms
16
+ DTS dist/index.d.cts 26.90 KB
17
+ DTS dist/index.d.ts 26.90 KB
18
+ Done in 11.09s.
@@ -0,0 +1,3 @@
1
+ yarn run v1.22.22
2
+ $ tsc
3
+ Done in 6.90s.
@@ -0,0 +1,3 @@
1
+ yarn run v1.22.22
2
+ $ json -f package.json -f package.exports.json --merge > package.release.json
3
+ Done in 0.09s.
@@ -0,0 +1,17 @@
1
+ // sadly Mantine uses randomness to generate certain fields (e.g. label mappings), we
2
+ // override Math.random to ensure these seeds remain the same between runs
3
+ const originalMathRandom = Math.random
4
+
5
+ const LIMIT = 100
6
+
7
+ beforeEach(function () {
8
+ let count = 0
9
+ Math.random = function () {
10
+ count++
11
+ return (count % LIMIT) / LIMIT
12
+ }
13
+ })
14
+
15
+ afterEach(function () {
16
+ Math.random = originalMathRandom
17
+ })
@@ -0,0 +1,9 @@
1
+ // adapted from https://storybook.js.org/docs/api/portable-stories/portable-stories-jest
2
+ import { setProjectAnnotations } from '@storybook/react'
3
+ // eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
4
+ import * as previewAnnotations from '../.storybook/preview'
5
+
6
+ const annotations = setProjectAnnotations([previewAnnotations])
7
+
8
+ // Run Storybook's beforeAll hook
9
+ beforeAll(annotations.beforeAll)
@@ -0,0 +1,7 @@
1
+ import MatchMediaMock from 'vitest-matchmedia-mock'
2
+
3
+ const matchMediaMock = new MatchMediaMock()
4
+
5
+ beforeAll(function () {
6
+ matchMediaMock.clear()
7
+ })
@@ -0,0 +1,5 @@
1
+ import ResizeObserver from 'resize-observer-polyfill'
2
+
3
+ beforeAll(function () {
4
+ window.ResizeObserver = window.ResizeObserver || ResizeObserver
5
+ })
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # Form (React and Mobx)
2
+
@@ -0,0 +1,32 @@
1
+ import {
2
+ type FieldConverter,
3
+ type FieldValueFactory,
4
+ type SafeFieldConverter,
5
+ } from 'types/field_converters'
6
+
7
+ export type FieldAdapter<
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ From = any,
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ To = any,
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ E = any,
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ ValuePath extends string = any,
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ Context = any,
18
+ > = {
19
+ readonly convert: SafeFieldConverter<From, To, ValuePath, Context>,
20
+ readonly create: FieldValueFactory<From, ValuePath, Context>,
21
+ readonly revert?: FieldConverter<To, From, E, ValuePath, Context>,
22
+ }
23
+
24
+ export type FromTypeOfFieldAdapter<C extends FieldAdapter> = C extends FieldAdapter<infer From> ? From
25
+ : never
26
+
27
+ export type ToTypeOfFieldAdapter<C extends FieldAdapter> = C extends FieldAdapter<infer _F, infer To> ? To
28
+ : never
29
+
30
+ export type ErrorTypeOfFieldAdapter<C extends FieldAdapter> = C extends FieldAdapter<infer _From, infer _To, infer E>
31
+ ? NonNullable<E>
32
+ : never