@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,38 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createUnsafePartialObserverComponent } from 'util/partial';
3
+ export function createTextInput(valuePath, TextInput, ErrorRenderer) {
4
+ const onChange = (e) => {
5
+ this.onFieldValueChange?.(valuePath, e.target.value);
6
+ };
7
+ const onFocus = () => {
8
+ this.onFieldFocus?.(valuePath);
9
+ };
10
+ const onBlur = () => {
11
+ this.onFieldBlur?.(valuePath);
12
+ };
13
+ const onKeyUp = (e) => {
14
+ if (e.key === 'Enter') {
15
+ if (this.onFieldSubmit?.(valuePath)) {
16
+ e.preventDefault();
17
+ }
18
+ }
19
+ };
20
+ const propSource = () => {
21
+ const { disabled, required, value, error,
22
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
23
+ } = this.fields[valuePath];
24
+ return {
25
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
26
+ name: valuePath,
27
+ value,
28
+ disabled,
29
+ required,
30
+ error: error && _jsx(ErrorRenderer, { error: error }),
31
+ onChange,
32
+ onFocus,
33
+ onBlur,
34
+ onKeyUp,
35
+ };
36
+ };
37
+ return createUnsafePartialObserverComponent(TextInput, propSource);
38
+ }
@@ -0,0 +1,17 @@
1
+ import { type AllFieldsOfFields } from 'types/all_fields_of_fields';
2
+ import { type ErrorTypeOfField } from 'types/error_type_of_field';
3
+ import { type Fields } from 'types/field';
4
+ import { type ValueTypeOfField } from 'types/value_type_of_field';
5
+ import { type ErrorRenderer } from './hooks';
6
+ import { type MantineFieldComponent, type MantineForm } from './types';
7
+ export type SuppliedValueInputProps<V, T extends Element = Element> = Partial<{
8
+ name: string;
9
+ value: V;
10
+ disabled: boolean;
11
+ required: boolean;
12
+ onChange: (value: V) => void;
13
+ onFocus: (e: React.FocusEvent<T>) => void;
14
+ onBlur: (e: React.FocusEvent<T>) => void;
15
+ onKeyUp: (e: React.KeyboardEvent<T>) => void;
16
+ }>;
17
+ export declare function createValueInput<F extends Fields, K extends keyof AllFieldsOfFields<F>, Props extends SuppliedValueInputProps<ValueTypeOfField<F[K]>>>(this: MantineForm<F>, valuePath: K, ValueInput: React.ComponentType<Props>, ErrorRenderer: ErrorRenderer<ErrorTypeOfField<F[K]>>): MantineFieldComponent<SuppliedValueInputProps<ValueTypeOfField<F[K]>>, Props>;
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createUnsafePartialObserverComponent } from 'util/partial';
3
+ export function createValueInput(valuePath, ValueInput, ErrorRenderer) {
4
+ const onChange = (value) => {
5
+ this.onFieldValueChange?.(valuePath, value);
6
+ };
7
+ const onFocus = () => {
8
+ this.onFieldFocus?.(valuePath);
9
+ };
10
+ const onBlur = () => {
11
+ this.onFieldBlur?.(valuePath);
12
+ };
13
+ const onKeyUp = (e) => {
14
+ if (e.key === 'Enter') {
15
+ if (this.onFieldSubmit?.(valuePath)) {
16
+ e.preventDefault();
17
+ }
18
+ }
19
+ };
20
+ const propSource = () => {
21
+ const { disabled, required, value, error,
22
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
23
+ } = this.fields[valuePath];
24
+ return {
25
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
26
+ name: valuePath,
27
+ value,
28
+ disabled,
29
+ required,
30
+ error: error && _jsx(ErrorRenderer, { error: error }),
31
+ onChange,
32
+ onFocus,
33
+ onBlur,
34
+ onKeyUp,
35
+ };
36
+ };
37
+ return createUnsafePartialObserverComponent(ValueInput, propSource);
38
+ }
@@ -0,0 +1,56 @@
1
+ import { type CheckboxProps, type PillProps, type RadioGroupProps, type RadioProps, type SelectProps, type TextInputProps } from '@mantine/core';
2
+ import { type ElementOfArray } from '@strictly/base';
3
+ import { type FormProps } from 'core/props';
4
+ import { type ComponentProps, type ComponentType } from 'react';
5
+ import { type AllFieldsOfFields } from 'types/all_fields_of_fields';
6
+ import { type BooleanFieldsOfFields } from 'types/boolean_fields_of_fields';
7
+ import { type ErrorTypeOfField } from 'types/error_type_of_field';
8
+ import { type Fields } from 'types/field';
9
+ import { type ListFieldsOfFields } from 'types/list_fields_of_fields';
10
+ import { type StringFieldsOfFields } from 'types/string_fields_of_fields';
11
+ import { type ValueTypeOfField } from 'types/value_type_of_field';
12
+ import { type SuppliedCheckboxProps } from './create_checkbox';
13
+ import { DefaultList, type SuppliedListProps } from './create_list';
14
+ import { type SuppliedPillProps } from './create_pill';
15
+ import { type SuppliedRadioProps } from './create_radio';
16
+ import { type SuppliedRadioGroupProps } from './create_radio_group';
17
+ import { type SuppliedTextInputProps } from './create_text_input';
18
+ import { type SuppliedValueInputProps } from './create_value_input';
19
+ import { type MantineFieldComponent, type MantineForm } from './types';
20
+ declare function SimpleSelect(props: SelectProps & {
21
+ onChange?: (value: string | null) => void;
22
+ }): import("react/jsx-runtime").JSX.Element;
23
+ export type ErrorRendererProps<E> = {
24
+ error: E;
25
+ };
26
+ export type ErrorRenderer<E = any> = React.ComponentType<ErrorRendererProps<E>>;
27
+ export declare function useMantineForm<F extends Fields>({ onFieldValueChange, onFieldBlur, onFieldFocus, onFieldSubmit, fields, }: FormProps<F>): MantineFormImpl<F>;
28
+ declare class MantineFormImpl<F extends Fields> implements MantineForm<F> {
29
+ private readonly textInputCache;
30
+ private readonly valueInputCache;
31
+ private readonly checkboxCache;
32
+ private readonly radioGroupCache;
33
+ private readonly radioCache;
34
+ private readonly pillCache;
35
+ private readonly listCache;
36
+ accessor fields: F;
37
+ onFieldValueChange: (<K extends keyof F>(this: void, key: K, value: F[K]['value']) => void) | undefined;
38
+ onFieldFocus: ((this: void, key: keyof F) => void) | undefined;
39
+ onFieldBlur: ((this: void, key: keyof F) => void) | undefined;
40
+ onFieldSubmit: ((this: void, key: keyof F) => boolean | void) | undefined;
41
+ constructor(fields: F);
42
+ textInput<K extends keyof StringFieldsOfFields<F>>(valuePath: K): MantineFieldComponent<SuppliedTextInputProps, TextInputProps>;
43
+ textInput<K extends keyof StringFieldsOfFields<F>, P extends SuppliedTextInputProps<any>>(valuePath: K, TextInput?: ComponentType<P>, ErrorRenderer?: ErrorRenderer<ErrorTypeOfField<F[K]>>): MantineFieldComponent<SuppliedTextInputProps, P>;
44
+ valueInput<K extends keyof AllFieldsOfFields<F>, P extends SuppliedValueInputProps<ValueTypeOfField<F[K]>, any>>(valuePath: K, ValueInput: ComponentType<P>, ErrorRenderer?: ErrorRenderer<ErrorTypeOfField<F[K]>>): MantineFieldComponent<SuppliedValueInputProps<ValueTypeOfField<F[K]>>, P>;
45
+ select<K extends keyof StringFieldsOfFields<F>>(valuePath: K, ErrorRenderer?: ErrorRenderer<ErrorTypeOfField<F[K]>>): MantineFieldComponent<SuppliedTextInputProps, ComponentProps<typeof SimpleSelect>>;
46
+ checkbox<K extends keyof BooleanFieldsOfFields<F>>(valuePath: K): MantineFieldComponent<SuppliedCheckboxProps, CheckboxProps>;
47
+ checkbox<K extends keyof BooleanFieldsOfFields<F>, P extends SuppliedCheckboxProps>(valuePath: K, Checkbox: ComponentType<P>, ErrorRenderer?: ErrorRenderer<ErrorTypeOfField<F[K]>>): MantineFieldComponent<SuppliedCheckboxProps, P>;
48
+ radioGroup<K extends keyof StringFieldsOfFields<F>>(valuePath: K): MantineFieldComponent<SuppliedRadioGroupProps, RadioGroupProps>;
49
+ radioGroup<K extends keyof StringFieldsOfFields<F>, P extends SuppliedRadioGroupProps>(valuePath: K, RadioGroup: ComponentType<P>, ErrorRenderer?: ErrorRenderer<ErrorTypeOfField<F[K]>>): MantineFieldComponent<SuppliedRadioGroupProps, P>;
50
+ radio<K extends keyof StringFieldsOfFields<F>>(valuePath: K, value: ValueTypeOfField<F[K]>): MantineFieldComponent<SuppliedRadioProps, RadioProps>;
51
+ radio<K extends keyof StringFieldsOfFields<F>, P extends SuppliedRadioProps>(valuePath: K, value: ValueTypeOfField<F[K]>, Radio: ComponentType<P>): MantineFieldComponent<SuppliedRadioProps, P>;
52
+ pill<K extends keyof AllFieldsOfFields<F>>(valuePath: K): MantineFieldComponent<SuppliedPillProps, PillProps>;
53
+ pill<K extends keyof AllFieldsOfFields<F>, P extends SuppliedPillProps>(valuePath: K, Pill: ComponentType<P>): MantineFieldComponent<SuppliedPillProps, P>;
54
+ list<K extends keyof ListFieldsOfFields<F>>(valuePath: K): MantineFieldComponent<SuppliedListProps<ElementOfArray<F[K]>>, ComponentProps<typeof DefaultList<ElementOfArray<F[K]>>>>;
55
+ }
56
+ export {};
@@ -0,0 +1,135 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Checkbox as CheckboxImpl, Pill as PillImpl, Radio as RadioImpl, Select, TextInput as TextInputImpl, } from '@mantine/core';
3
+ import { Cache, } from '@strictly/base';
4
+ import { observable, runInAction, } from 'mobx';
5
+ import { useEffect, useMemo, } from 'react';
6
+ import { createCheckbox, } from './create_checkbox';
7
+ import { createList, DefaultList, } from './create_list';
8
+ import { createPill, } from './create_pill';
9
+ import { createRadio, } from './create_radio';
10
+ import { createRadioGroup, } from './create_radio_group';
11
+ import { createTextInput, } from './create_text_input';
12
+ import { createValueInput, } from './create_value_input';
13
+ function SimpleSelect(props) {
14
+ return _jsx(Select, { ...props });
15
+ }
16
+ function DefaultErrorRenderer({ error,
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
+ }) {
19
+ return error;
20
+ }
21
+ export function useMantineForm({ onFieldValueChange, onFieldBlur, onFieldFocus, onFieldSubmit, fields, }) {
22
+ const form = useMemo(function () {
23
+ return new MantineFormImpl(fields);
24
+ },
25
+ // handled separately below
26
+ // eslint-disable-next-line react-hooks/exhaustive-deps
27
+ []);
28
+ useEffect(function () {
29
+ runInAction(function () {
30
+ form.fields = fields;
31
+ });
32
+ }, [
33
+ form,
34
+ fields,
35
+ ]);
36
+ useEffect(function () {
37
+ form.onFieldValueChange = onFieldValueChange;
38
+ }, [
39
+ form,
40
+ onFieldValueChange,
41
+ ]);
42
+ useEffect(function () {
43
+ form.onFieldBlur = onFieldBlur;
44
+ }, [
45
+ form,
46
+ onFieldBlur,
47
+ ]);
48
+ useEffect(function () {
49
+ form.onFieldFocus = onFieldFocus;
50
+ }, [
51
+ form,
52
+ onFieldFocus,
53
+ ]);
54
+ useEffect(function () {
55
+ form.onFieldSubmit = onFieldSubmit;
56
+ }, [
57
+ form,
58
+ onFieldSubmit,
59
+ ]);
60
+ return form;
61
+ }
62
+ class MantineFormImpl {
63
+ textInputCache = new Cache(createTextInput.bind(this));
64
+ valueInputCache = new Cache(createValueInput.bind(this));
65
+ checkboxCache = new Cache(createCheckbox.bind(this));
66
+ radioGroupCache = new Cache(createRadioGroup.bind(this));
67
+ radioCache = new Cache(createRadio.bind(this));
68
+ pillCache = new Cache(createPill.bind(this));
69
+ listCache = new Cache(createList.bind(this));
70
+ @observable.ref
71
+ accessor fields;
72
+ onFieldValueChange;
73
+ onFieldFocus;
74
+ onFieldBlur;
75
+ onFieldSubmit;
76
+ constructor(fields) {
77
+ this.fields = fields;
78
+ }
79
+ textInput(valuePath,
80
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
81
+ TextInput = TextInputImpl, ErrorRenderer = DefaultErrorRenderer) {
82
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
83
+ return this.textInputCache.retrieveOrCreate(valuePath,
84
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
85
+ TextInput, ErrorRenderer);
86
+ }
87
+ valueInput(valuePath, ValueInput, ErrorRenderer = DefaultErrorRenderer) {
88
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
89
+ return this.valueInputCache.retrieveOrCreate(valuePath,
90
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
91
+ ValueInput, ErrorRenderer);
92
+ }
93
+ select(valuePath, ErrorRenderer = DefaultErrorRenderer) {
94
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
95
+ return this.valueInputCache.retrieveOrCreate(valuePath,
96
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
97
+ SimpleSelect, ErrorRenderer);
98
+ }
99
+ checkbox(valuePath,
100
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
101
+ Checkbox = CheckboxImpl, ErrorRenderer = DefaultErrorRenderer) {
102
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
103
+ return this.checkboxCache.retrieveOrCreate(valuePath,
104
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
105
+ Checkbox, ErrorRenderer);
106
+ }
107
+ radioGroup(valuePath,
108
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
109
+ RadioGroup = RadioImpl.Group, ErrorRenderer = DefaultErrorRenderer) {
110
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
111
+ return this.radioGroupCache.retrieveOrCreate(valuePath,
112
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
113
+ RadioGroup, ErrorRenderer);
114
+ }
115
+ radio(valuePath, value,
116
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
117
+ Radio = RadioImpl) {
118
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
119
+ return this.radioCache.retrieveOrCreate(valuePath, value,
120
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
121
+ Radio);
122
+ }
123
+ pill(valuePath,
124
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
125
+ Pill = PillImpl) {
126
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
127
+ return this.pillCache.retrieveOrCreate(valuePath,
128
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
129
+ Pill);
130
+ }
131
+ list(valuePath) {
132
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
133
+ return this.listCache.retrieveOrCreate(valuePath, DefaultList);
134
+ }
135
+ }
@@ -0,0 +1 @@
1
+ export declare const CHECKBOX_LABEL = "Checkbox";
@@ -0,0 +1 @@
1
+ export const CHECKBOX_LABEL = 'Checkbox';
@@ -0,0 +1,13 @@
1
+ import { type Meta, type StoryObj } from '@storybook/react';
2
+ import { type FormProps } from 'core/props';
3
+ import { type Field } from 'types/field';
4
+ declare function Component(props: FormProps<{
5
+ $: Field<boolean, string>;
6
+ }>): import("react/jsx-runtime").JSX.Element;
7
+ declare const meta: Meta<typeof Component>;
8
+ export default meta;
9
+ type Story = StoryObj<typeof Component>;
10
+ export declare const Off: Story;
11
+ export declare const On: Story;
12
+ export declare const Required: Story;
13
+ export declare const Disabled: Story;
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { action } from '@storybook/addon-actions';
3
+ import { useMantineForm } from 'mantine/hooks';
4
+ import { CHECKBOX_LABEL } from './checkbox_constants';
5
+ function Component(props) {
6
+ const inputProps = useMantineForm(props);
7
+ const CheckboxComponent = inputProps.checkbox('$');
8
+ return _jsx(CheckboxComponent, { label: CHECKBOX_LABEL });
9
+ }
10
+ const meta = {
11
+ component: Component,
12
+ args: {
13
+ onFieldBlur: action('onFieldBlur'),
14
+ onFieldFocus: action('onFieldFocus'),
15
+ onFieldSubmit: action('onFieldSubmit'),
16
+ onFieldValueChange: action('onFieldValueChange'),
17
+ },
18
+ };
19
+ export default meta;
20
+ export const Off = {
21
+ args: {
22
+ fields: {
23
+ $: {
24
+ disabled: false,
25
+ required: false,
26
+ value: false,
27
+ },
28
+ },
29
+ },
30
+ };
31
+ export const On = {
32
+ args: {
33
+ fields: {
34
+ $: {
35
+ disabled: false,
36
+ required: false,
37
+ value: true,
38
+ },
39
+ },
40
+ },
41
+ };
42
+ export const Required = {
43
+ args: {
44
+ fields: {
45
+ $: {
46
+ disabled: false,
47
+ required: true,
48
+ value: false,
49
+ },
50
+ },
51
+ },
52
+ };
53
+ export const Disabled = {
54
+ args: {
55
+ fields: {
56
+ $: {
57
+ disabled: true,
58
+ required: false,
59
+ value: false,
60
+ },
61
+ },
62
+ },
63
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { composeStories } from '@storybook/react';
3
+ import { toArray } from '@strictly/base';
4
+ import { fireEvent, render, } from '@testing-library/react';
5
+ import { vi, } from 'vitest';
6
+ import { CHECKBOX_LABEL } from './checkbox_constants';
7
+ import * as stories from './checkbox_hooks.stories';
8
+ const composedStories = composeStories(stories);
9
+ const { Off, On, } = composedStories;
10
+ describe('mantine checkbox hooks', function () {
11
+ it.each(toArray(composedStories))('renders %s', function (_name, Story) {
12
+ const wrapper = render(_jsx(Story, {}));
13
+ expect(wrapper.container).toMatchSnapshot();
14
+ });
15
+ describe.each([
16
+ [
17
+ 'Off',
18
+ Off,
19
+ true,
20
+ ],
21
+ [
22
+ 'On',
23
+ On,
24
+ false,
25
+ ],
26
+ ])('value change %s', function (_name, Component, expectedValue) {
27
+ let onFieldValueChange;
28
+ let wrapper;
29
+ let checkbox;
30
+ beforeEach(async function () {
31
+ onFieldValueChange = vi.fn();
32
+ wrapper = render(_jsx(Component, { onFieldValueChange: onFieldValueChange }));
33
+ checkbox = await wrapper.findByLabelText(CHECKBOX_LABEL);
34
+ });
35
+ it('requests toggle', function () {
36
+ fireEvent.click(checkbox);
37
+ expect(onFieldValueChange).toHaveBeenCalledOnce();
38
+ expect(onFieldValueChange).toHaveBeenCalledWith('$', expectedValue);
39
+ });
40
+ });
41
+ describe('other events', function () {
42
+ let onFieldFocus;
43
+ let onFieldBlur;
44
+ let wrapper;
45
+ let checkbox;
46
+ beforeEach(async function () {
47
+ onFieldFocus = vi.fn();
48
+ onFieldBlur = vi.fn();
49
+ wrapper = render((_jsx(Off, { onFieldBlur: onFieldBlur, onFieldFocus: onFieldFocus })));
50
+ checkbox = await wrapper.findByLabelText(CHECKBOX_LABEL);
51
+ });
52
+ describe('focus', function () {
53
+ beforeEach(function () {
54
+ fireEvent.focus(checkbox);
55
+ });
56
+ it('fires focus event', function () {
57
+ expect(onFieldFocus).toHaveBeenCalledOnce();
58
+ expect(onFieldFocus).toHaveBeenCalledWith('$');
59
+ });
60
+ describe('blur', function () {
61
+ beforeEach(function () {
62
+ fireEvent.blur(checkbox);
63
+ });
64
+ it('fires blur event', function () {
65
+ expect(onFieldBlur).toHaveBeenCalledOnce();
66
+ expect(onFieldBlur).toHaveBeenCalledWith('$');
67
+ });
68
+ it('does not refire focus event', function () {
69
+ expect(onFieldFocus).toHaveBeenCalledOnce();
70
+ });
71
+ });
72
+ });
73
+ });
74
+ });
@@ -0,0 +1,11 @@
1
+ import { type Meta, type StoryObj } from '@storybook/react';
2
+ import { type FormProps } from 'core/props';
3
+ import { type Field } from 'types/field';
4
+ declare function Component(props: FormProps<{
5
+ $: Field<string[], string>;
6
+ }>): import("react/jsx-runtime").JSX.Element;
7
+ declare const meta: Meta<typeof Component>;
8
+ export default meta;
9
+ type Story = StoryObj<typeof Component>;
10
+ export declare const Empty: Story;
11
+ export declare const Populated: Story;
@@ -0,0 +1,48 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Code, Paper, Stack, } from '@mantine/core';
3
+ import { action } from '@storybook/addon-actions';
4
+ import { useMantineForm } from 'mantine/hooks';
5
+ function Component(props) {
6
+ const form = useMantineForm(props);
7
+ const List = form.list('$');
8
+ return (_jsx(Paper, { p: 'sm', withBorder: true, children: _jsx(Stack, { children: _jsx(List, { children: function (valuePath) {
9
+ return (_jsxs(Code, { children: ["ValuePath: ", valuePath] }, valuePath));
10
+ } }) }) }));
11
+ }
12
+ const meta = {
13
+ component: Component,
14
+ args: {
15
+ onFieldBlur: action('onFieldBlur'),
16
+ onFieldFocus: action('onFieldFocus'),
17
+ onFieldSubmit: action('onFieldSubmit'),
18
+ onFieldValueChange: action('onFieldValueChange'),
19
+ },
20
+ };
21
+ export default meta;
22
+ export const Empty = {
23
+ args: {
24
+ fields: {
25
+ $: {
26
+ disabled: false,
27
+ required: false,
28
+ value: [],
29
+ },
30
+ },
31
+ },
32
+ };
33
+ export const Populated = {
34
+ args: {
35
+ fields: {
36
+ $: {
37
+ disabled: false,
38
+ required: false,
39
+ value: [
40
+ '$.4',
41
+ '$.6',
42
+ '$.19',
43
+ '$.0',
44
+ ],
45
+ },
46
+ },
47
+ },
48
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { composeStories } from '@storybook/react';
3
+ import { toArray } from '@strictly/base';
4
+ import { render, } from '@testing-library/react';
5
+ import * as stories from './list_hooks.stories';
6
+ const composedStories = composeStories(stories);
7
+ describe('mantine list hooks', function () {
8
+ it.each(toArray(composedStories))('renders %s', function (_name, Story) {
9
+ const wrapper = render(_jsx(Story, {}));
10
+ expect(wrapper.container).toMatchSnapshot();
11
+ });
12
+ });
@@ -0,0 +1,4 @@
1
+ export declare const RADIO_GROUP_LABEL = "Radio Group";
2
+ export declare const RADIO_VALUES: readonly ["1", "2", "3"];
3
+ export type RadioValue = typeof RADIO_VALUES[number];
4
+ export declare const RADIO_LABELS: Record<RadioValue, string>;
@@ -0,0 +1,11 @@
1
+ export const RADIO_GROUP_LABEL = 'Radio Group';
2
+ export const RADIO_VALUES = [
3
+ '1',
4
+ '2',
5
+ '3',
6
+ ];
7
+ export const RADIO_LABELS = {
8
+ 1: 'One',
9
+ 2: 'Two',
10
+ 3: 'Three',
11
+ };
@@ -0,0 +1,14 @@
1
+ import { type Meta, type StoryObj } from '@storybook/react';
2
+ import { type FormProps } from 'core/props';
3
+ import { type Field } from 'types/field';
4
+ import { type RadioValue } from './radio_group_constants';
5
+ declare function Component(props: FormProps<{
6
+ $: Field<RadioValue | null, string>;
7
+ }>): import("react/jsx-runtime").JSX.Element;
8
+ declare const meta: Meta<typeof Component>;
9
+ export default meta;
10
+ type Story = StoryObj<typeof Component>;
11
+ export declare const Empty: Story;
12
+ export declare const Populated: Story;
13
+ export declare const Required: Story;
14
+ export declare const Disabled: Story;
@@ -0,0 +1,68 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Stack, } from '@mantine/core';
3
+ import { action } from '@storybook/addon-actions';
4
+ import { useMantineForm } from 'mantine/hooks';
5
+ import { RADIO_GROUP_LABEL, RADIO_LABELS, RADIO_VALUES, } from './radio_group_constants';
6
+ function Component(props) {
7
+ const form = useMantineForm(props);
8
+ const RadioGroupComponent = form.radioGroup('$');
9
+ return (_jsx(RadioGroupComponent, { label: RADIO_GROUP_LABEL, children: _jsx(Stack, { children: RADIO_VALUES.map(function (value) {
10
+ const label = RADIO_LABELS[value];
11
+ const RadioComponent = form.radio('$', value);
12
+ return (_jsx(RadioComponent, { label: label }, label));
13
+ }) }) }));
14
+ }
15
+ const meta = {
16
+ component: Component,
17
+ args: {
18
+ onFieldBlur: action('onFieldBlur'),
19
+ onFieldFocus: action('onFieldFocus'),
20
+ onFieldSubmit: action('onFieldSubmit'),
21
+ onFieldValueChange: action('onFieldValueChange'),
22
+ },
23
+ };
24
+ export default meta;
25
+ export const Empty = {
26
+ args: {
27
+ fields: {
28
+ $: {
29
+ disabled: false,
30
+ required: false,
31
+ value: null,
32
+ },
33
+ },
34
+ },
35
+ };
36
+ export const Populated = {
37
+ args: {
38
+ fields: {
39
+ $: {
40
+ disabled: false,
41
+ required: false,
42
+ value: '3',
43
+ },
44
+ },
45
+ },
46
+ };
47
+ export const Required = {
48
+ args: {
49
+ fields: {
50
+ $: {
51
+ disabled: false,
52
+ required: true,
53
+ value: '1',
54
+ },
55
+ },
56
+ },
57
+ };
58
+ export const Disabled = {
59
+ args: {
60
+ fields: {
61
+ $: {
62
+ disabled: true,
63
+ required: false,
64
+ value: '2',
65
+ },
66
+ },
67
+ },
68
+ };
@@ -0,0 +1 @@
1
+ export {};