@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.
- package/.eslintrc.cjs +26 -0
- package/.out/.storybook/main.d.ts +3 -0
- package/.out/.storybook/main.js +32 -0
- package/.out/.storybook/preview.d.ts +4 -0
- package/.out/.storybook/preview.js +20 -0
- package/.out/.vitest/install_deterministic_random.d.ts +2 -0
- package/.out/.vitest/install_deterministic_random.js +15 -0
- package/.out/.vitest/install_storybook_preview.d.ts +1 -0
- package/.out/.vitest/install_storybook_preview.js +7 -0
- package/.out/.vitest/match_media.d.ts +1 -0
- package/.out/.vitest/match_media.js +5 -0
- package/.out/.vitest/resize_observer.d.ts +1 -0
- package/.out/.vitest/resize_observer.js +4 -0
- package/.out/core/mobx/field_adapter.d.ts +9 -0
- package/.out/core/mobx/field_adapter.js +1 -0
- package/.out/core/mobx/field_adapter_builder.d.ts +22 -0
- package/.out/core/mobx/field_adapter_builder.js +56 -0
- package/.out/core/mobx/flattened_adapters_of_fields.d.ts +9 -0
- package/.out/core/mobx/flattened_adapters_of_fields.js +1 -0
- package/.out/core/mobx/flattened_list_type_defs_of.d.ts +8 -0
- package/.out/core/mobx/flattened_list_type_defs_of.js +1 -0
- package/.out/core/mobx/form_presenter.d.ts +61 -0
- package/.out/core/mobx/form_presenter.js +425 -0
- package/.out/core/mobx/specs/flattened_adapters_of_fields.tests.d.ts +1 -0
- package/.out/core/mobx/specs/flattened_adapters_of_fields.tests.js +13 -0
- package/.out/core/mobx/specs/flattened_list_type_defs_of.tests.d.ts +1 -0
- package/.out/core/mobx/specs/flattened_list_type_defs_of.tests.js +16 -0
- package/.out/core/mobx/specs/form_presenter.tests.d.ts +1 -0
- package/.out/core/mobx/specs/form_presenter.tests.js +697 -0
- package/.out/core/mobx/types.d.ts +19 -0
- package/.out/core/mobx/types.js +1 -0
- package/.out/core/props.d.ts +12 -0
- package/.out/core/props.js +1 -0
- package/.out/field_converters/chain_field_converter.d.ts +3 -0
- package/.out/field_converters/chain_field_converter.js +46 -0
- package/.out/field_converters/identity_converter.d.ts +3 -0
- package/.out/field_converters/identity_converter.js +14 -0
- package/.out/field_converters/integer_to_string_converter.d.ts +7 -0
- package/.out/field_converters/integer_to_string_converter.js +26 -0
- package/.out/field_converters/list_converter.d.ts +2 -0
- package/.out/field_converters/list_converter.js +8 -0
- package/.out/field_converters/maybe_identity_converter.d.ts +8 -0
- package/.out/field_converters/maybe_identity_converter.js +15 -0
- package/.out/field_converters/nullable_to_boolean_converter.d.ts +11 -0
- package/.out/field_converters/nullable_to_boolean_converter.js +31 -0
- package/.out/field_converters/select_value_type_converter.d.ts +23 -0
- package/.out/field_converters/select_value_type_converter.js +60 -0
- package/.out/field_converters/trimming_string_converter.d.ts +6 -0
- package/.out/field_converters/trimming_string_converter.js +14 -0
- package/.out/field_converters/validating_converter.d.ts +3 -0
- package/.out/field_converters/validating_converter.js +21 -0
- package/.out/field_validators/minimum_string_length_field_validator.d.ts +2 -0
- package/.out/field_validators/minimum_string_length_field_validator.js +8 -0
- package/.out/field_value_factories/prototyping_field_value_factory.d.ts +2 -0
- package/.out/field_value_factories/prototyping_field_value_factory.js +5 -0
- package/.out/index.d.ts +16 -0
- package/.out/index.js +16 -0
- package/.out/mantine/create_checkbox.d.ts +9 -0
- package/.out/mantine/create_checkbox.js +37 -0
- package/.out/mantine/create_list.d.ts +15 -0
- package/.out/mantine/create_list.js +16 -0
- package/.out/mantine/create_pill.d.ts +7 -0
- package/.out/mantine/create_pill.js +15 -0
- package/.out/mantine/create_radio.d.ts +8 -0
- package/.out/mantine/create_radio.js +10 -0
- package/.out/mantine/create_radio_group.d.ts +9 -0
- package/.out/mantine/create_radio_group.js +34 -0
- package/.out/mantine/create_text_input.d.ts +19 -0
- package/.out/mantine/create_text_input.js +38 -0
- package/.out/mantine/create_value_input.d.ts +17 -0
- package/.out/mantine/create_value_input.js +38 -0
- package/.out/mantine/hooks.d.ts +56 -0
- package/.out/mantine/hooks.js +135 -0
- package/.out/mantine/specs/checkbox_constants.d.ts +1 -0
- package/.out/mantine/specs/checkbox_constants.js +1 -0
- package/.out/mantine/specs/checkbox_hooks.stories.d.ts +13 -0
- package/.out/mantine/specs/checkbox_hooks.stories.js +63 -0
- package/.out/mantine/specs/checkbox_hooks.tests.d.ts +1 -0
- package/.out/mantine/specs/checkbox_hooks.tests.js +74 -0
- package/.out/mantine/specs/list_hooks.stories.d.ts +11 -0
- package/.out/mantine/specs/list_hooks.stories.js +48 -0
- package/.out/mantine/specs/list_hooks.tests.d.ts +1 -0
- package/.out/mantine/specs/list_hooks.tests.js +12 -0
- package/.out/mantine/specs/radio_group_constants.d.ts +4 -0
- package/.out/mantine/specs/radio_group_constants.js +11 -0
- package/.out/mantine/specs/radio_group_hooks.stories.d.ts +14 -0
- package/.out/mantine/specs/radio_group_hooks.stories.js +68 -0
- package/.out/mantine/specs/radio_group_hooks.tests.d.ts +1 -0
- package/.out/mantine/specs/radio_group_hooks.tests.js +62 -0
- package/.out/mantine/specs/select_hooks.stories.d.ts +12 -0
- package/.out/mantine/specs/select_hooks.stories.js +57 -0
- package/.out/mantine/specs/select_hooks.tests.d.ts +1 -0
- package/.out/mantine/specs/select_hooks.tests.js +12 -0
- package/.out/mantine/specs/select_hooks_constant.d.ts +1 -0
- package/.out/mantine/specs/select_hooks_constant.js +1 -0
- package/.out/mantine/specs/text_input_constants.d.ts +1 -0
- package/.out/mantine/specs/text_input_constants.js +1 -0
- package/.out/mantine/specs/text_input_hooks.stories.d.ts +21 -0
- package/.out/mantine/specs/text_input_hooks.stories.js +88 -0
- package/.out/mantine/specs/text_input_hooks.tests.d.ts +1 -0
- package/.out/mantine/specs/text_input_hooks.tests.js +79 -0
- package/.out/mantine/specs/value_input_constants.d.ts +2 -0
- package/.out/mantine/specs/value_input_constants.js +2 -0
- package/.out/mantine/specs/value_input_hooks.stories.d.ts +23 -0
- package/.out/mantine/specs/value_input_hooks.stories.js +124 -0
- package/.out/mantine/specs/value_input_hooks.tests.d.ts +1 -0
- package/.out/mantine/specs/value_input_hooks.tests.js +12 -0
- package/.out/mantine/types.d.ts +11 -0
- package/.out/mantine/types.js +1 -0
- package/.out/tsconfig.json +27 -0
- package/.out/tsconfig.tsbuildinfo +1 -0
- package/.out/tsup.config.d.ts +3 -0
- package/.out/tsup.config.js +12 -0
- package/.out/types/all_fields_of_fields.d.ts +5 -0
- package/.out/types/all_fields_of_fields.js +1 -0
- package/.out/types/boolean_fields_of_fields.d.ts +5 -0
- package/.out/types/boolean_fields_of_fields.js +1 -0
- package/.out/types/error_type_of_field.d.ts +2 -0
- package/.out/types/error_type_of_field.js +1 -0
- package/.out/types/field.d.ts +7 -0
- package/.out/types/field.js +1 -0
- package/.out/types/field_converters.d.ts +29 -0
- package/.out/types/field_converters.js +5 -0
- package/.out/types/field_validator.d.ts +3 -0
- package/.out/types/field_validator.js +1 -0
- package/.out/types/flattened_form_fields_of.d.ts +9 -0
- package/.out/types/flattened_form_fields_of.js +1 -0
- package/.out/types/list_fields_of_fields.d.ts +5 -0
- package/.out/types/list_fields_of_fields.js +1 -0
- package/.out/types/specs/boolean_fields_of_fields.tests.d.ts +1 -0
- package/.out/types/specs/boolean_fields_of_fields.tests.js +11 -0
- package/.out/types/specs/error_type_of_field.tests.d.ts +1 -0
- package/.out/types/specs/error_type_of_field.tests.js +7 -0
- package/.out/types/specs/flattened_form_fields_of.tests.d.ts +1 -0
- package/.out/types/specs/flattened_form_fields_of.tests.js +13 -0
- package/.out/types/specs/string_fields_of_fields.tests.d.ts +1 -0
- package/.out/types/specs/string_fields_of_fields.tests.js +19 -0
- package/.out/types/specs/value_type_of_field.tests.d.ts +1 -0
- package/.out/types/specs/value_type_of_field.tests.js +7 -0
- package/.out/types/string_fields_of_fields.d.ts +5 -0
- package/.out/types/string_fields_of_fields.js +1 -0
- package/.out/types/value_type_of_field.d.ts +2 -0
- package/.out/types/value_type_of_field.js +1 -0
- package/.out/util/partial.d.ts +11 -0
- package/.out/util/partial.js +74 -0
- package/.out/vitest.workspace.d.ts +2 -0
- package/.out/vitest.workspace.js +22 -0
- package/.storybook/main.ts +40 -0
- package/.storybook/preview.tsx +28 -0
- package/.storybook/vite.config.mts +38 -0
- package/.turbo/turbo-build.log +18 -0
- package/.turbo/turbo-check-types.log +3 -0
- package/.turbo/turbo-release$colon$exports.log +3 -0
- package/.vitest/install_deterministic_random.ts +17 -0
- package/.vitest/install_storybook_preview.ts +9 -0
- package/.vitest/match_media.ts +7 -0
- package/.vitest/resize_observer.ts +5 -0
- package/README.md +2 -0
- package/core/mobx/field_adapter.ts +32 -0
- package/core/mobx/field_adapter_builder.ts +313 -0
- package/core/mobx/flattened_adapters_of_fields.ts +35 -0
- package/core/mobx/flattened_list_type_defs_of.ts +17 -0
- package/core/mobx/form_presenter.ts +705 -0
- package/core/mobx/specs/flattened_adapters_of_fields.tests.ts +72 -0
- package/core/mobx/specs/flattened_list_type_defs_of.tests.ts +35 -0
- package/core/mobx/specs/form_presenter.tests.ts +989 -0
- package/core/mobx/types.ts +54 -0
- package/core/props.ts +21 -0
- package/dist/index.cjs +11479 -0
- package/dist/index.d.cts +345 -0
- package/dist/index.d.ts +345 -0
- package/dist/index.js +11486 -0
- package/field_converters/chain_field_converter.ts +74 -0
- package/field_converters/identity_converter.ts +39 -0
- package/field_converters/integer_to_string_converter.ts +32 -0
- package/field_converters/list_converter.ts +15 -0
- package/field_converters/maybe_identity_converter.ts +23 -0
- package/field_converters/nullable_to_boolean_converter.ts +56 -0
- package/field_converters/select_value_type_converter.ts +141 -0
- package/field_converters/trimming_string_converter.ts +23 -0
- package/field_converters/validating_converter.ts +35 -0
- package/field_validators/minimum_string_length_field_validator.ts +13 -0
- package/field_value_factories/prototyping_field_value_factory.ts +11 -0
- package/index.ts +16 -0
- package/mantine/create_checkbox.tsx +79 -0
- package/mantine/create_list.tsx +58 -0
- package/mantine/create_pill.tsx +43 -0
- package/mantine/create_radio.tsx +36 -0
- package/mantine/create_radio_group.tsx +71 -0
- package/mantine/create_text_input.tsx +80 -0
- package/mantine/create_value_input.tsx +81 -0
- package/mantine/hooks.tsx +394 -0
- package/mantine/specs/__snapshots__/check_box_hooks.tests.tsx.snap +227 -0
- package/mantine/specs/__snapshots__/checkbox_hooks.tests.tsx.snap +227 -0
- package/mantine/specs/__snapshots__/list_hooks.tests.tsx.snap +68 -0
- package/mantine/specs/__snapshots__/radio_group_hooks.tests.tsx.snap +695 -0
- package/mantine/specs/__snapshots__/select_hooks.tests.tsx.snap +225 -0
- package/mantine/specs/__snapshots__/text_input_hooks.tests.tsx.snap +202 -0
- package/mantine/specs/__snapshots__/value_input_hooks.tests.tsx.snap +613 -0
- package/mantine/specs/checkbox_constants.ts +1 -0
- package/mantine/specs/checkbox_hooks.stories.tsx +79 -0
- package/mantine/specs/checkbox_hooks.tests.tsx +100 -0
- package/mantine/specs/list_hooks.stories.tsx +83 -0
- package/mantine/specs/list_hooks.tests.tsx +15 -0
- package/mantine/specs/radio_group_constants.ts +12 -0
- package/mantine/specs/radio_group_hooks.stories.tsx +103 -0
- package/mantine/specs/radio_group_hooks.tests.tsx +92 -0
- package/mantine/specs/select_hooks.stories.tsx +77 -0
- package/mantine/specs/select_hooks.tests.tsx +14 -0
- package/mantine/specs/select_hooks_constant.ts +1 -0
- package/mantine/specs/text_input_constants.ts +1 -0
- package/mantine/specs/text_input_hooks.stories.tsx +124 -0
- package/mantine/specs/text_input_hooks.tests.tsx +106 -0
- package/mantine/specs/value_input_constants.ts +2 -0
- package/mantine/specs/value_input_hooks.stories.tsx +182 -0
- package/mantine/specs/value_input_hooks.tests.tsx +14 -0
- package/mantine/types.ts +13 -0
- package/package.exports.json +18 -0
- package/package.json +74 -0
- package/tsconfig.build.json +13 -0
- package/tsconfig.json +27 -0
- package/tsup.config.ts +16 -0
- package/types/all_fields_of_fields.ts +9 -0
- package/types/boolean_fields_of_fields.ts +8 -0
- package/types/error_type_of_field.ts +3 -0
- package/types/field.ts +9 -0
- package/types/field_converters.ts +64 -0
- package/types/field_validator.ts +7 -0
- package/types/flattened_form_fields_of.ts +16 -0
- package/types/list_fields_of_fields.ts +7 -0
- package/types/specs/boolean_fields_of_fields.tests.ts +23 -0
- package/types/specs/error_type_of_field.tests.ts +10 -0
- package/types/specs/flattened_form_fields_of.tests.ts +43 -0
- package/types/specs/string_fields_of_fields.tests.ts +40 -0
- package/types/specs/value_type_of_field.tests.ts +10 -0
- package/types/string_fields_of_fields.ts +6 -0
- package/types/value_type_of_field.ts +3 -0
- package/util/partial.tsx +200 -0
- package/vitest.workspace.ts +26 -0
|
@@ -0,0 +1,62 @@
|
|
|
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 { RADIO_GROUP_LABEL, RADIO_LABELS, RADIO_VALUES, } from './radio_group_constants';
|
|
7
|
+
import * as stories from './radio_group_hooks.stories';
|
|
8
|
+
const composedStories = composeStories(stories);
|
|
9
|
+
const { Empty, } = composedStories;
|
|
10
|
+
describe('mantine radio group 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('events', function () {
|
|
16
|
+
let onFieldValueChange;
|
|
17
|
+
let onFieldFocus;
|
|
18
|
+
let onFieldBlur;
|
|
19
|
+
let wrapper;
|
|
20
|
+
let radioGroup;
|
|
21
|
+
beforeEach(async function () {
|
|
22
|
+
onFieldValueChange = vi.fn();
|
|
23
|
+
onFieldFocus = vi.fn();
|
|
24
|
+
onFieldBlur = vi.fn();
|
|
25
|
+
wrapper = render((_jsx(Empty, { onFieldBlur: onFieldBlur, onFieldFocus: onFieldFocus, onFieldValueChange: onFieldValueChange })));
|
|
26
|
+
radioGroup = await wrapper.findByLabelText(RADIO_GROUP_LABEL);
|
|
27
|
+
});
|
|
28
|
+
describe.each(RADIO_VALUES)('selects %s', function (value) {
|
|
29
|
+
let radio;
|
|
30
|
+
beforeEach(async function () {
|
|
31
|
+
const label = RADIO_LABELS[value];
|
|
32
|
+
radio = await wrapper.findByLabelText(label);
|
|
33
|
+
fireEvent.click(radio);
|
|
34
|
+
});
|
|
35
|
+
it('fires onFieldValueChange', function () {
|
|
36
|
+
expect(onFieldValueChange).toHaveBeenCalledOnce();
|
|
37
|
+
expect(onFieldValueChange).toHaveBeenCalledWith('$', value);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe('focus', function () {
|
|
41
|
+
beforeEach(function () {
|
|
42
|
+
fireEvent.focus(radioGroup);
|
|
43
|
+
});
|
|
44
|
+
it('fires focus event', function () {
|
|
45
|
+
expect(onFieldFocus).toHaveBeenCalledOnce();
|
|
46
|
+
expect(onFieldFocus).toHaveBeenCalledWith('$');
|
|
47
|
+
});
|
|
48
|
+
describe('blur', function () {
|
|
49
|
+
beforeEach(function () {
|
|
50
|
+
fireEvent.blur(radioGroup);
|
|
51
|
+
});
|
|
52
|
+
it('fires blur event', function () {
|
|
53
|
+
expect(onFieldBlur).toHaveBeenCalledOnce();
|
|
54
|
+
expect(onFieldBlur).toHaveBeenCalledWith('$');
|
|
55
|
+
});
|
|
56
|
+
it('does not refire focus event', function () {
|
|
57
|
+
expect(onFieldFocus).toHaveBeenCalledOnce();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
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 | null, 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 EmptySelect: Story;
|
|
11
|
+
export declare const PopulatedSelect: Story;
|
|
12
|
+
export declare const InvalidSelect: Story;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { action } from '@storybook/addon-actions';
|
|
3
|
+
import { useMantineForm } from 'mantine/hooks';
|
|
4
|
+
import { SELECT_LABEL } from './select_hooks_constant';
|
|
5
|
+
function Component(props) {
|
|
6
|
+
const form = useMantineForm(props);
|
|
7
|
+
const SelectComponent = form.select('$');
|
|
8
|
+
return (_jsx(SelectComponent, { data: [
|
|
9
|
+
'a',
|
|
10
|
+
'b',
|
|
11
|
+
'c',
|
|
12
|
+
], label: SELECT_LABEL }));
|
|
13
|
+
}
|
|
14
|
+
const meta = {
|
|
15
|
+
component: Component,
|
|
16
|
+
args: {
|
|
17
|
+
onFieldBlur: action('onFieldBlur'),
|
|
18
|
+
onFieldFocus: action('onFieldFocus'),
|
|
19
|
+
onFieldSubmit: action('onFieldSubmit'),
|
|
20
|
+
onFieldValueChange: action('onFieldValueChange'),
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
export default meta;
|
|
24
|
+
export const EmptySelect = {
|
|
25
|
+
args: {
|
|
26
|
+
fields: {
|
|
27
|
+
$: {
|
|
28
|
+
disabled: false,
|
|
29
|
+
required: true,
|
|
30
|
+
value: '',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
export const PopulatedSelect = {
|
|
36
|
+
args: {
|
|
37
|
+
fields: {
|
|
38
|
+
$: {
|
|
39
|
+
disabled: false,
|
|
40
|
+
required: true,
|
|
41
|
+
value: 'a',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export const InvalidSelect = {
|
|
47
|
+
args: {
|
|
48
|
+
fields: {
|
|
49
|
+
$: {
|
|
50
|
+
disabled: false,
|
|
51
|
+
required: true,
|
|
52
|
+
value: 'd',
|
|
53
|
+
error: 'invalid option',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
@@ -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 './select_hooks.stories';
|
|
6
|
+
const composedStories = composeStories(stories);
|
|
7
|
+
describe('mantine select 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 @@
|
|
|
1
|
+
export declare const SELECT_LABEL = "Select";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SELECT_LABEL = 'Select';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TEXT_INPUT_LABEL = "Text Input";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const TEXT_INPUT_LABEL = 'Text Input';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type TextInputProps } from '@mantine/core';
|
|
2
|
+
import { type Meta, type StoryObj } from '@storybook/react';
|
|
3
|
+
import { type FormProps } from 'core/props';
|
|
4
|
+
import { type SuppliedTextInputProps, type TextInputTarget } from 'mantine/create_text_input';
|
|
5
|
+
import { type ComponentType } from 'react';
|
|
6
|
+
import { type Field } from 'types/field';
|
|
7
|
+
type StoryTextInputProps<T extends TextInputTarget> = SuppliedTextInputProps<T> & Pick<TextInputProps, 'label'>;
|
|
8
|
+
declare function Component<T extends TextInputTarget>({ TextInput, ...props }: FormProps<{
|
|
9
|
+
$: Field<string, string>;
|
|
10
|
+
}> & {
|
|
11
|
+
TextInput?: ComponentType<StoryTextInputProps<T>>;
|
|
12
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
declare const meta: Meta<typeof Component>;
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story<T extends TextInputTarget = HTMLInputElement> = StoryObj<typeof Component<T>>;
|
|
16
|
+
export declare const Empty: Story;
|
|
17
|
+
export declare const Populated: Story;
|
|
18
|
+
export declare const Required: Story;
|
|
19
|
+
export declare const Disabled: Story;
|
|
20
|
+
export declare const OverriddenTextarea: Story<HTMLTextAreaElement>;
|
|
21
|
+
export declare const OverriddenPillsInputField: Story;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { PillsInputField, Textarea, } from '@mantine/core';
|
|
3
|
+
import { action } from '@storybook/addon-actions';
|
|
4
|
+
import { useMantineForm } from 'mantine/hooks';
|
|
5
|
+
import { TEXT_INPUT_LABEL } from './text_input_constants';
|
|
6
|
+
function Component({ TextInput, ...props }) {
|
|
7
|
+
const form = useMantineForm(props);
|
|
8
|
+
const TextInputComponent = form.textInput('$', TextInput);
|
|
9
|
+
return _jsx(TextInputComponent, { label: TEXT_INPUT_LABEL });
|
|
10
|
+
}
|
|
11
|
+
const meta = {
|
|
12
|
+
component: Component,
|
|
13
|
+
args: {
|
|
14
|
+
onFieldBlur: action('onFieldBlur'),
|
|
15
|
+
onFieldFocus: action('onFieldFocus'),
|
|
16
|
+
onFieldSubmit: action('onFieldSubmit'),
|
|
17
|
+
onFieldValueChange: action('onFieldValueChange'),
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
export default meta;
|
|
21
|
+
export const Empty = {
|
|
22
|
+
args: {
|
|
23
|
+
fields: {
|
|
24
|
+
$: {
|
|
25
|
+
disabled: false,
|
|
26
|
+
required: false,
|
|
27
|
+
value: '',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
export const Populated = {
|
|
33
|
+
args: {
|
|
34
|
+
fields: {
|
|
35
|
+
$: {
|
|
36
|
+
disabled: false,
|
|
37
|
+
required: false,
|
|
38
|
+
value: 'Hello',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
export const Required = {
|
|
44
|
+
args: {
|
|
45
|
+
fields: {
|
|
46
|
+
$: {
|
|
47
|
+
disabled: false,
|
|
48
|
+
required: true,
|
|
49
|
+
value: 'xxx',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
export const Disabled = {
|
|
55
|
+
args: {
|
|
56
|
+
fields: {
|
|
57
|
+
$: {
|
|
58
|
+
disabled: true,
|
|
59
|
+
required: false,
|
|
60
|
+
value: 'xxx',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
export const OverriddenTextarea = {
|
|
66
|
+
args: {
|
|
67
|
+
fields: {
|
|
68
|
+
$: {
|
|
69
|
+
disabled: false,
|
|
70
|
+
required: false,
|
|
71
|
+
value: 'Textarea',
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
TextInput: Textarea,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
export const OverriddenPillsInputField = {
|
|
78
|
+
args: {
|
|
79
|
+
fields: {
|
|
80
|
+
$: {
|
|
81
|
+
disabled: false,
|
|
82
|
+
required: false,
|
|
83
|
+
value: 'PillsInputField',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
TextInput: PillsInputField,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
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 { TEXT_INPUT_LABEL } from './text_input_constants';
|
|
7
|
+
import * as stories from './text_input_hooks.stories';
|
|
8
|
+
const composedStories = composeStories(stories);
|
|
9
|
+
const { Populated, } = 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('events', function () {
|
|
16
|
+
let onFieldValueChange;
|
|
17
|
+
let onFieldFocus;
|
|
18
|
+
let onFieldBlur;
|
|
19
|
+
let onFieldSubmit;
|
|
20
|
+
let wrapper;
|
|
21
|
+
let textInput;
|
|
22
|
+
beforeEach(async function () {
|
|
23
|
+
onFieldValueChange = vi.fn();
|
|
24
|
+
onFieldFocus = vi.fn();
|
|
25
|
+
onFieldBlur = vi.fn();
|
|
26
|
+
onFieldSubmit = vi.fn();
|
|
27
|
+
wrapper = render((_jsx(Populated, { onFieldBlur: onFieldBlur, onFieldFocus: onFieldFocus, onFieldSubmit: onFieldSubmit, onFieldValueChange: onFieldValueChange })));
|
|
28
|
+
textInput = await wrapper.findByLabelText(TEXT_INPUT_LABEL);
|
|
29
|
+
});
|
|
30
|
+
it('fires change event', function () {
|
|
31
|
+
const value = 'new value';
|
|
32
|
+
fireEvent.change(textInput, {
|
|
33
|
+
target: {
|
|
34
|
+
value,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
expect(onFieldValueChange).toHaveBeenCalledOnce();
|
|
38
|
+
expect(onFieldValueChange).toHaveBeenCalledWith('$', value);
|
|
39
|
+
});
|
|
40
|
+
it('fires submit event on enter', function () {
|
|
41
|
+
fireEvent.keyUp(textInput, {
|
|
42
|
+
key: 'Enter',
|
|
43
|
+
});
|
|
44
|
+
expect(onFieldSubmit).toHaveBeenCalledOnce();
|
|
45
|
+
expect(onFieldSubmit).toHaveBeenLastCalledWith('$');
|
|
46
|
+
});
|
|
47
|
+
it.each([
|
|
48
|
+
'Tab',
|
|
49
|
+
'Space',
|
|
50
|
+
'x',
|
|
51
|
+
])('does not fire submit event on %s', function (key) {
|
|
52
|
+
fireEvent.keyUp(textInput, {
|
|
53
|
+
key,
|
|
54
|
+
});
|
|
55
|
+
expect(onFieldSubmit).not.toHaveBeenCalled();
|
|
56
|
+
});
|
|
57
|
+
describe('focus', function () {
|
|
58
|
+
beforeEach(function () {
|
|
59
|
+
fireEvent.focus(textInput);
|
|
60
|
+
});
|
|
61
|
+
it('fires focus event', function () {
|
|
62
|
+
expect(onFieldFocus).toHaveBeenCalledOnce();
|
|
63
|
+
expect(onFieldFocus).toHaveBeenCalledWith('$');
|
|
64
|
+
});
|
|
65
|
+
describe('blur', function () {
|
|
66
|
+
beforeEach(function () {
|
|
67
|
+
fireEvent.blur(textInput);
|
|
68
|
+
});
|
|
69
|
+
it('fires blur event', function () {
|
|
70
|
+
expect(onFieldBlur).toHaveBeenCalledOnce();
|
|
71
|
+
expect(onFieldBlur).toHaveBeenCalledWith('$');
|
|
72
|
+
});
|
|
73
|
+
it('does not refire focus event', function () {
|
|
74
|
+
expect(onFieldFocus).toHaveBeenCalledOnce();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type JsonInputProps, type NumberInputProps, type RatingProps, type SliderProps } from '@mantine/core';
|
|
2
|
+
import { type Meta, type StoryObj } from '@storybook/react';
|
|
3
|
+
import { type FormProps } from 'core/props';
|
|
4
|
+
import { type SuppliedValueInputProps } from 'mantine/create_value_input';
|
|
5
|
+
import { type ComponentType } from 'react';
|
|
6
|
+
import { type Field } from 'types/field';
|
|
7
|
+
type StoryValueInputProps<V> = SuppliedValueInputProps<V, any>;
|
|
8
|
+
declare function Component<V, P extends StoryValueInputProps<V>>({ ValueInput, inputs, ...props }: FormProps<{
|
|
9
|
+
$: Field<V, string>;
|
|
10
|
+
}> & {
|
|
11
|
+
ValueInput: ComponentType<P>;
|
|
12
|
+
} & {
|
|
13
|
+
inputs: P;
|
|
14
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
declare const meta: Meta<typeof Component>;
|
|
16
|
+
export default meta;
|
|
17
|
+
type Story<V, P extends StoryValueInputProps<V>> = StoryObj<typeof Component<V, P>>;
|
|
18
|
+
export declare const EmptyNumberInput: Story<number | string, NumberInputProps>;
|
|
19
|
+
export declare const PopulatedNumberInput: Story<number | string, NumberInputProps>;
|
|
20
|
+
export declare const DisabledNumberInput: Story<number | string, NumberInputProps>;
|
|
21
|
+
export declare const AnSlider: Story<number, SliderProps>;
|
|
22
|
+
export declare const AnRating: Story<number, RatingProps>;
|
|
23
|
+
export declare const AnJsonInput: Story<string, JsonInputProps>;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { JsonInput, NumberInput, Rating, Slider, } from '@mantine/core';
|
|
3
|
+
import { action } from '@storybook/addon-actions';
|
|
4
|
+
import { useMantineForm } from 'mantine/hooks';
|
|
5
|
+
import { NUMBER_INPUT_LABEL, SLIDER_LABEL, } from './value_input_constants';
|
|
6
|
+
function Component({ ValueInput, inputs, ...props }) {
|
|
7
|
+
const form = useMantineForm(props);
|
|
8
|
+
const ValueInputComponent = form.valueInput('$', ValueInput);
|
|
9
|
+
return (_jsx(ValueInputComponent, { ...inputs }));
|
|
10
|
+
}
|
|
11
|
+
const meta = {
|
|
12
|
+
component: Component,
|
|
13
|
+
args: {
|
|
14
|
+
onFieldBlur: action('onFieldBlur'),
|
|
15
|
+
onFieldFocus: action('onFieldFocus'),
|
|
16
|
+
onFieldSubmit: action('onFieldSubmit'),
|
|
17
|
+
onFieldValueChange: action('onFieldValueChange'),
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
export default meta;
|
|
21
|
+
export const EmptyNumberInput = {
|
|
22
|
+
args: {
|
|
23
|
+
fields: {
|
|
24
|
+
$: {
|
|
25
|
+
disabled: false,
|
|
26
|
+
required: true,
|
|
27
|
+
value: '',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
ValueInput: NumberInput,
|
|
31
|
+
inputs: {
|
|
32
|
+
label: NUMBER_INPUT_LABEL,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
export const PopulatedNumberInput = {
|
|
37
|
+
args: {
|
|
38
|
+
fields: {
|
|
39
|
+
$: {
|
|
40
|
+
disabled: false,
|
|
41
|
+
required: false,
|
|
42
|
+
value: 3,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
ValueInput: NumberInput,
|
|
46
|
+
inputs: {
|
|
47
|
+
label: NUMBER_INPUT_LABEL,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
export const DisabledNumberInput = {
|
|
52
|
+
args: {
|
|
53
|
+
fields: {
|
|
54
|
+
$: {
|
|
55
|
+
disabled: true,
|
|
56
|
+
required: false,
|
|
57
|
+
value: 3,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
ValueInput: NumberInput,
|
|
61
|
+
inputs: {
|
|
62
|
+
label: NUMBER_INPUT_LABEL,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
export const AnSlider = {
|
|
67
|
+
args: {
|
|
68
|
+
fields: {
|
|
69
|
+
$: {
|
|
70
|
+
disabled: false,
|
|
71
|
+
required: false,
|
|
72
|
+
value: 3,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
ValueInput: Slider,
|
|
76
|
+
inputs: {
|
|
77
|
+
label: SLIDER_LABEL,
|
|
78
|
+
min: 1,
|
|
79
|
+
max: 10,
|
|
80
|
+
marks: [
|
|
81
|
+
{
|
|
82
|
+
value: 1,
|
|
83
|
+
label: 'min',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
value: 5,
|
|
87
|
+
label: 'mid',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
value: 10,
|
|
91
|
+
label: 'max',
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
export const AnRating = {
|
|
98
|
+
args: {
|
|
99
|
+
fields: {
|
|
100
|
+
$: {
|
|
101
|
+
disabled: false,
|
|
102
|
+
required: false,
|
|
103
|
+
value: 2,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
ValueInput: Rating,
|
|
107
|
+
inputs: {},
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
export const AnJsonInput = {
|
|
111
|
+
args: {
|
|
112
|
+
fields: {
|
|
113
|
+
$: {
|
|
114
|
+
disabled: false,
|
|
115
|
+
required: false,
|
|
116
|
+
value: '{}',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
ValueInput: JsonInput,
|
|
120
|
+
inputs: {
|
|
121
|
+
rows: 8,
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
};
|
|
@@ -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 './value_input_hooks.stories';
|
|
6
|
+
const composedStories = composeStories(stories);
|
|
7
|
+
describe('mantine value input 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,11 @@
|
|
|
1
|
+
import { type ComponentType } from 'react';
|
|
2
|
+
import { type Fields } from 'types/field';
|
|
3
|
+
import { type UnsafePartialComponent } from 'util/partial';
|
|
4
|
+
export type MantineForm<F extends Fields> = {
|
|
5
|
+
fields: F;
|
|
6
|
+
onFieldValueChange: (<K extends keyof F>(this: void, key: K, value: F[K]['value']) => void) | undefined;
|
|
7
|
+
onFieldFocus: ((this: void, key: keyof F) => void) | undefined;
|
|
8
|
+
onFieldBlur: ((this: void, key: keyof F) => void) | undefined;
|
|
9
|
+
onFieldSubmit: ((this: void, key: keyof F) => boolean | void) | undefined;
|
|
10
|
+
};
|
|
11
|
+
export type MantineFieldComponent<T, P = T> = UnsafePartialComponent<ComponentType<P>, T>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"baseUrl": ".",
|
|
4
|
+
"outDir": "./.out"
|
|
5
|
+
},
|
|
6
|
+
"extends": "../../tsconfig.json",
|
|
7
|
+
"include": [
|
|
8
|
+
"**/*.ts",
|
|
9
|
+
"**/*.tsx",
|
|
10
|
+
".storybook/**/*.ts",
|
|
11
|
+
".storybook/**/*.tsx",
|
|
12
|
+
".vitest/**/*.ts",
|
|
13
|
+
"babel.config.cjs",
|
|
14
|
+
"tsconfig.json"
|
|
15
|
+
],
|
|
16
|
+
"references": [
|
|
17
|
+
{
|
|
18
|
+
"path": "../../support/vite"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"path": "../define"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "../base"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|