rn-vs-lb 1.0.3 → 1.0.5
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/.storybook/stories/Button/Button.stories.tsx +34 -0
- package/.storybook/stories/Button/ButtonsGroup.stories.tsx +77 -0
- package/.storybook/stories/Form/AutoComplete.stories.tsx +40 -0
- package/.storybook/stories/Form/DatePickerForm.stories.tsx +54 -0
- package/.storybook/stories/Form/ImageUploader.stories.tsx +45 -0
- package/.storybook/stories/Form/MultiSelect.stories.tsx +54 -0
- package/.storybook/stories/Form/Select.stories.tsx +76 -0
- package/.storybook/stories/Form/TextArea.stories.tsx +69 -0
- package/.storybook/stories/Form/TextInput.stories.tsx +85 -0
- package/.storybook/stories/Forms/FormExample.stories copy.tsx +86 -0
- package/.storybook/stories/Forms/FormExample.stories.tsx +188 -0
- package/README.md +7 -0
- package/dist/components/buttons/Button.js +36 -12
- package/dist/components/form/AutoComplete.js +182 -0
- package/dist/components/form/DatePicker.js +99 -0
- package/dist/components/form/ImageUploader.js +196 -0
- package/dist/components/form/MultiSelect.js +94 -0
- package/dist/components/form/PasswordInput.js +66 -0
- package/dist/components/form/Select.js +52 -0
- package/dist/components/form/TextArea.js +70 -0
- package/dist/components/form/TextInput.js +57 -0
- package/dist/components/form/index.js +20 -0
- package/dist/index.js +28 -1
- package/dist/nodeModules/index.js +6 -0
- package/dist/types/components/buttons/Button.d.ts +9 -5
- package/dist/types/components/form/AutoComplete.d.ts +13 -0
- package/dist/types/components/form/DatePicker.d.ts +14 -0
- package/dist/types/components/form/ImageUploader.d.ts +14 -0
- package/dist/types/components/form/MultiSelect.d.ts +18 -0
- package/dist/types/components/form/PasswordInput.d.ts +10 -0
- package/dist/types/components/form/Select.d.ts +19 -0
- package/dist/types/components/form/TextArea.d.ts +17 -0
- package/dist/types/components/form/TextInput.d.ts +17 -0
- package/dist/types/components/form/index.d.ts +8 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/nodeModules/index.d.ts +2 -0
- package/package.json +11 -3
- package/src/components/buttons/Button.tsx +45 -14
- package/src/components/form/AutoComplete.tsx +160 -0
- package/src/components/form/DatePicker.tsx +162 -0
- package/src/components/form/ImageUploader.tsx +171 -0
- package/src/components/form/MultiSelect.tsx +135 -0
- package/src/components/form/PasswordInput.tsx +66 -0
- package/src/components/form/Select.tsx +99 -0
- package/src/components/form/TextArea.tsx +91 -0
- package/src/components/form/TextInput.tsx +107 -0
- package/src/components/form/index.ts +23 -0
- package/src/index.ts +6 -2
- package/src/nodeModules/index.ts +6 -0
- package/tsconfig.json +3 -3
- package/package copy.json +0 -38
- package/src/stories/Button/Button.stories.tsx +0 -32
- /package/{src/stories/eventCard → .storybook/stories/EventCard}/EventCard.stories.tsx +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
import Button, { ButtonProps } from '../../../src/components/buttons/Button'; // Убедитесь, что путь правильный
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Buttons/Button',
|
|
7
|
+
component: Button,
|
|
8
|
+
argTypes: {
|
|
9
|
+
title: {
|
|
10
|
+
control: 'text',
|
|
11
|
+
description: 'Text displayed on the button',
|
|
12
|
+
},
|
|
13
|
+
type: {
|
|
14
|
+
control: { type: 'radio' },
|
|
15
|
+
options: ['primary', 'gray'],
|
|
16
|
+
description: 'Type of button (primary or gray)',
|
|
17
|
+
},
|
|
18
|
+
onPress: { action: 'pressed' },
|
|
19
|
+
},
|
|
20
|
+
} as Meta;
|
|
21
|
+
|
|
22
|
+
const Template: Story<ButtonProps> = (args) => <Button {...args} />;
|
|
23
|
+
|
|
24
|
+
export const Primary = Template.bind({});
|
|
25
|
+
Primary.args = {
|
|
26
|
+
title: 'Update Profile',
|
|
27
|
+
type: 'primary',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const Gray = Template.bind({});
|
|
31
|
+
Gray.args = {
|
|
32
|
+
title: 'Cancel',
|
|
33
|
+
type: 'gray',
|
|
34
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
import { View, StyleSheet } from 'react-native';
|
|
4
|
+
import Button from '../../../src/components/buttons/Button'; // Убедитесь, что путь правильный
|
|
5
|
+
|
|
6
|
+
// Определение компонента ButtonGroup
|
|
7
|
+
const ButtonGroup = () => {
|
|
8
|
+
const handleUpdateProfile = () => {
|
|
9
|
+
console.log('Update Profile Pressed');
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const handleCancel = () => {
|
|
13
|
+
console.log('Cancel Pressed');
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<View style={styles.container}>
|
|
18
|
+
<Button
|
|
19
|
+
title="Update Profile"
|
|
20
|
+
onPress={handleUpdateProfile}
|
|
21
|
+
type="primary"
|
|
22
|
+
style={styles.button}
|
|
23
|
+
/>
|
|
24
|
+
<Button
|
|
25
|
+
title="Cancel"
|
|
26
|
+
onPress={handleCancel}
|
|
27
|
+
type="gray"
|
|
28
|
+
style={styles.button}
|
|
29
|
+
/>
|
|
30
|
+
</View>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const styles = StyleSheet.create({
|
|
35
|
+
container: {
|
|
36
|
+
flexDirection: 'row',
|
|
37
|
+
justifyContent: 'space-between',
|
|
38
|
+
width: '100%',
|
|
39
|
+
},
|
|
40
|
+
button: {
|
|
41
|
+
width: '48%',
|
|
42
|
+
},
|
|
43
|
+
buttonText: {
|
|
44
|
+
fontSize: 16,
|
|
45
|
+
fontWeight: 'bold',
|
|
46
|
+
},
|
|
47
|
+
primaryButton: {
|
|
48
|
+
backgroundColor: '#6f2da8',
|
|
49
|
+
height: 50,
|
|
50
|
+
justifyContent: 'center',
|
|
51
|
+
alignItems: 'center',
|
|
52
|
+
borderRadius: 25,
|
|
53
|
+
},
|
|
54
|
+
primaryButtonText: {
|
|
55
|
+
color: '#fff',
|
|
56
|
+
},
|
|
57
|
+
grayButton: {
|
|
58
|
+
backgroundColor: '#f5f5f5',
|
|
59
|
+
height: 50,
|
|
60
|
+
justifyContent: 'center',
|
|
61
|
+
alignItems: 'center',
|
|
62
|
+
borderRadius: 25,
|
|
63
|
+
},
|
|
64
|
+
grayButtonText: {
|
|
65
|
+
color: '#333',
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
export default {
|
|
70
|
+
title: 'Buttons/ButtonGroup',
|
|
71
|
+
component: ButtonGroup,
|
|
72
|
+
} as Meta;
|
|
73
|
+
|
|
74
|
+
const Template: Story = () => <ButtonGroup />;
|
|
75
|
+
|
|
76
|
+
export const Default = Template.bind({});
|
|
77
|
+
Default.args = {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
5
|
+
import { AutoComplete, AutoCompleteProps } from '../../../src/components/form';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Form/AutoComplete',
|
|
9
|
+
component: AutoComplete,
|
|
10
|
+
argTypes: {
|
|
11
|
+
label: {
|
|
12
|
+
control: 'text',
|
|
13
|
+
description: 'Label for the location field',
|
|
14
|
+
},
|
|
15
|
+
placeholder: {
|
|
16
|
+
control: 'text',
|
|
17
|
+
description: 'Placeholder text for the location field',
|
|
18
|
+
},
|
|
19
|
+
required: {
|
|
20
|
+
control: 'boolean',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
} as Meta;
|
|
24
|
+
|
|
25
|
+
const Template: Story<AutoCompleteProps> = (args) => {
|
|
26
|
+
const { control } = useForm();
|
|
27
|
+
return (
|
|
28
|
+
<View style={{ padding: 20 }}>
|
|
29
|
+
<AutoComplete {...args} control={control} />
|
|
30
|
+
</View>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const Default = Template.bind({});
|
|
35
|
+
Default.args = {
|
|
36
|
+
name: 'location',
|
|
37
|
+
label: 'City',
|
|
38
|
+
placeholder: 'Enter a city',
|
|
39
|
+
required: true,
|
|
40
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
5
|
+
import { DatePicker, DatePickerProps } from '../../../src/components/form';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Form/DatePicker',
|
|
9
|
+
component: DatePicker,
|
|
10
|
+
argTypes: {
|
|
11
|
+
label: {
|
|
12
|
+
control: 'text',
|
|
13
|
+
description: 'Label for the date picker',
|
|
14
|
+
},
|
|
15
|
+
style: {
|
|
16
|
+
control: 'object',
|
|
17
|
+
description: 'Custom style for the date picker button',
|
|
18
|
+
},
|
|
19
|
+
containerStyle: {
|
|
20
|
+
control: 'object',
|
|
21
|
+
description: 'Custom style for the container',
|
|
22
|
+
},
|
|
23
|
+
required: {
|
|
24
|
+
control: 'boolean',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
} as Meta;
|
|
28
|
+
|
|
29
|
+
const Template: Story<DatePickerProps> = (args) => {
|
|
30
|
+
const { control } = useForm();
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<View style={{ padding: 20 }}>
|
|
34
|
+
<DatePicker {...args} control={control} />
|
|
35
|
+
</View>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const Default = Template.bind({});
|
|
40
|
+
Default.args = {
|
|
41
|
+
name: 'datetime',
|
|
42
|
+
label: 'Select Date and Time',
|
|
43
|
+
rules: { required: 'Date and Time are required!' },
|
|
44
|
+
defaultValue: new Date(),
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const WithCustomStyles = Template.bind({});
|
|
48
|
+
WithCustomStyles.args = {
|
|
49
|
+
name: 'datetime',
|
|
50
|
+
label: 'Custom Date Picker',
|
|
51
|
+
containerStyle: { margin: 20, padding: 10, backgroundColor: '#f0f0f0' },
|
|
52
|
+
rules: { required: 'Please select a date and time!' },
|
|
53
|
+
defaultValue: new Date(),
|
|
54
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
5
|
+
import { ImageUploader, ImageUploaderProps } from '../../../src/components/form';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Form/ImageUploader',
|
|
9
|
+
component: ImageUploader,
|
|
10
|
+
argTypes: {
|
|
11
|
+
label: {
|
|
12
|
+
control: 'text',
|
|
13
|
+
description: 'Label for the image uploader',
|
|
14
|
+
},
|
|
15
|
+
style: {
|
|
16
|
+
control: 'object',
|
|
17
|
+
description: 'Custom style for the upload button',
|
|
18
|
+
},
|
|
19
|
+
containerStyle: {
|
|
20
|
+
control: 'object',
|
|
21
|
+
description: 'Custom style for the container',
|
|
22
|
+
},
|
|
23
|
+
required: {
|
|
24
|
+
control: 'boolean',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
} as Meta;
|
|
28
|
+
|
|
29
|
+
const Template: Story<ImageUploaderProps> = (args) => {
|
|
30
|
+
const { control } = useForm();
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<View style={{ padding: 20 }}>
|
|
34
|
+
<ImageUploader {...args} control={control} />
|
|
35
|
+
</View>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const Default = Template.bind({});
|
|
40
|
+
Default.args = {
|
|
41
|
+
name: 'images',
|
|
42
|
+
label: 'Upload Images',
|
|
43
|
+
rules: { required: 'At least one image is required!' },
|
|
44
|
+
defaultValue: [],
|
|
45
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
5
|
+
import { MultiSelect, MultiSelectProps } from '../../../src/components/form';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Form/MultiSelect',
|
|
9
|
+
component: MultiSelect,
|
|
10
|
+
argTypes: {
|
|
11
|
+
label: {
|
|
12
|
+
control: 'text',
|
|
13
|
+
description: 'Label for the multi-select',
|
|
14
|
+
},
|
|
15
|
+
options: {
|
|
16
|
+
control: 'object',
|
|
17
|
+
description: 'Options for the multi-select',
|
|
18
|
+
},
|
|
19
|
+
placeholder: {
|
|
20
|
+
control: 'text',
|
|
21
|
+
description: 'Placeholder text for the multi-select',
|
|
22
|
+
},
|
|
23
|
+
required: {
|
|
24
|
+
control: 'boolean',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
} as Meta;
|
|
28
|
+
|
|
29
|
+
const Template: Story<MultiSelectProps> = (args) => {
|
|
30
|
+
const { control } = useForm();
|
|
31
|
+
return (
|
|
32
|
+
<View style={{ padding: 20 }}>
|
|
33
|
+
<MultiSelect {...args} control={control} />
|
|
34
|
+
</View>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const Default = Template.bind({});
|
|
39
|
+
Default.args = {
|
|
40
|
+
name: 'categories',
|
|
41
|
+
label: 'Выберите категории',
|
|
42
|
+
options: [
|
|
43
|
+
{ label: 'Выставки', value: 'Выставки' },
|
|
44
|
+
{ label: 'С детьми', value: 'С детьми' },
|
|
45
|
+
{ label: 'Активный отдых', value: 'Активный отдых' },
|
|
46
|
+
{ label: 'Стендап', value: 'Стендап' },
|
|
47
|
+
{ label: 'Образование', value: 'Образование' },
|
|
48
|
+
{ label: 'Театры', value: 'Театры' },
|
|
49
|
+
{ label: 'Игры', value: 'Игры' },
|
|
50
|
+
{ label: 'Кино', value: 'Кино' },
|
|
51
|
+
{ label: 'Концерты', value: 'Концерты' },
|
|
52
|
+
],
|
|
53
|
+
placeholder: 'Выберите...',
|
|
54
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
5
|
+
import { Select, SelectProps } from '../../../src/components/form';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Form/Select',
|
|
9
|
+
component: Select,
|
|
10
|
+
argTypes: {
|
|
11
|
+
label: {
|
|
12
|
+
control: 'text',
|
|
13
|
+
description: 'Label for the select',
|
|
14
|
+
},
|
|
15
|
+
placeholder: {
|
|
16
|
+
control: 'text',
|
|
17
|
+
description: 'Placeholder option text',
|
|
18
|
+
},
|
|
19
|
+
options: {
|
|
20
|
+
control: 'object',
|
|
21
|
+
description: 'Options for the select',
|
|
22
|
+
},
|
|
23
|
+
style: {
|
|
24
|
+
control: 'object',
|
|
25
|
+
description: 'Custom style for the select',
|
|
26
|
+
},
|
|
27
|
+
containerStyle: {
|
|
28
|
+
control: 'object',
|
|
29
|
+
description: 'Custom style for the container',
|
|
30
|
+
},
|
|
31
|
+
required: {
|
|
32
|
+
control: 'boolean',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
} as Meta;
|
|
36
|
+
|
|
37
|
+
const Template: Story<SelectProps> = (args) => {
|
|
38
|
+
const { control } = useForm();
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<View style={{ padding: 10 }}>
|
|
42
|
+
<Select {...args} control={control} />
|
|
43
|
+
</View>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const Default = Template.bind({});
|
|
48
|
+
Default.args = {
|
|
49
|
+
name: 'category',
|
|
50
|
+
label: 'Category',
|
|
51
|
+
placeholder: 'Select a category',
|
|
52
|
+
options: [
|
|
53
|
+
{ label: 'Technology', value: 'tech' },
|
|
54
|
+
{ label: 'Health', value: 'health' },
|
|
55
|
+
{ label: 'Finance', value: 'finance' },
|
|
56
|
+
],
|
|
57
|
+
containerStyle: { margin: 10 },
|
|
58
|
+
rules: { required: 'Category is required!' },
|
|
59
|
+
defaultValue: '',
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const WithCustomStyles = Template.bind({});
|
|
63
|
+
WithCustomStyles.args = {
|
|
64
|
+
name: 'category',
|
|
65
|
+
label: 'Custom Select',
|
|
66
|
+
placeholder: 'Choose an option',
|
|
67
|
+
options: [
|
|
68
|
+
{ label: 'Option 1', value: '1' },
|
|
69
|
+
{ label: 'Option 2', value: '2' },
|
|
70
|
+
{ label: 'Option 3', value: '3' },
|
|
71
|
+
],
|
|
72
|
+
style: { borderColor: 'blue', borderWidth: 2 },
|
|
73
|
+
containerStyle: { margin: 20, padding: 10, backgroundColor: '#f0f0f0' },
|
|
74
|
+
rules: { required: 'Please select an option!' },
|
|
75
|
+
defaultValue: '1',
|
|
76
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { useForm } from 'react-hook-form';
|
|
5
|
+
import { TextArea, TextAreaProps } from '../../../src/components/form';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Form/TextArea',
|
|
9
|
+
component: TextArea,
|
|
10
|
+
argTypes: {
|
|
11
|
+
label: {
|
|
12
|
+
control: 'text',
|
|
13
|
+
description: 'Label for the textarea',
|
|
14
|
+
},
|
|
15
|
+
placeholder: {
|
|
16
|
+
control: 'text',
|
|
17
|
+
description: 'Placeholder text',
|
|
18
|
+
},
|
|
19
|
+
numberOfLines: {
|
|
20
|
+
control: 'number',
|
|
21
|
+
description: 'Number of lines for the textarea',
|
|
22
|
+
},
|
|
23
|
+
style: {
|
|
24
|
+
control: 'object',
|
|
25
|
+
description: 'Custom style for the textarea',
|
|
26
|
+
},
|
|
27
|
+
containerStyle: {
|
|
28
|
+
control: 'object',
|
|
29
|
+
description: 'Custom style for the container',
|
|
30
|
+
},
|
|
31
|
+
required: {
|
|
32
|
+
control: 'boolean',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
} as Meta;
|
|
36
|
+
|
|
37
|
+
const Template: Story<TextAreaProps> = (args) => {
|
|
38
|
+
const { control } = useForm();
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<View style={{ padding: 20 }}>
|
|
42
|
+
<TextArea {...args} control={control} />
|
|
43
|
+
</View>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const Default = Template.bind({});
|
|
48
|
+
Default.args = {
|
|
49
|
+
name: 'description',
|
|
50
|
+
label: 'Description',
|
|
51
|
+
placeholder: 'Enter your description...',
|
|
52
|
+
numberOfLines: 4,
|
|
53
|
+
style: { height: 150, borderColor: 'gray' },
|
|
54
|
+
rules: { required: 'Description is required!' },
|
|
55
|
+
defaultValue: '',
|
|
56
|
+
required: true,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const WithCustomStyles = Template.bind({});
|
|
60
|
+
WithCustomStyles.args = {
|
|
61
|
+
name: 'description',
|
|
62
|
+
label: 'Custom TextArea',
|
|
63
|
+
placeholder: 'Enter custom text...',
|
|
64
|
+
numberOfLines: 6,
|
|
65
|
+
style: { height: 200, borderColor: 'blue', borderWidth: 2 },
|
|
66
|
+
containerStyle: { margin: 20, padding: 10, backgroundColor: '#f0f0f0' },
|
|
67
|
+
rules: { required: 'This field is required!' },
|
|
68
|
+
defaultValue: 'Default value here...',
|
|
69
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import InputWithValidation, { InputWithValidationProps } from '../../../src/components/form/TextInput';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Form/InputWithValidation',
|
|
9
|
+
component: InputWithValidation,
|
|
10
|
+
parameters: {
|
|
11
|
+
controls: { expanded: true },
|
|
12
|
+
},
|
|
13
|
+
argTypes: {
|
|
14
|
+
required: {
|
|
15
|
+
control: 'boolean',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
} as Meta;
|
|
19
|
+
|
|
20
|
+
const Template: Story<InputWithValidationProps> = (args) => (
|
|
21
|
+
<View style={{ padding: 20 }}>
|
|
22
|
+
<InputWithValidation {...args} />
|
|
23
|
+
</View>
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
export const TextField = Template.bind({});
|
|
28
|
+
TextField.args = {
|
|
29
|
+
name: 'Name',
|
|
30
|
+
label: 'Name',
|
|
31
|
+
placeholder: 'Enter your name',
|
|
32
|
+
keyboardType: 'default',
|
|
33
|
+
required: true,
|
|
34
|
+
rules: {
|
|
35
|
+
required: 'Name is required!',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const EmailField = Template.bind({});
|
|
40
|
+
EmailField.args = {
|
|
41
|
+
name: 'email',
|
|
42
|
+
label: 'Email',
|
|
43
|
+
placeholder: 'Enter your email',
|
|
44
|
+
keyboardType: 'email-address',
|
|
45
|
+
required: true,
|
|
46
|
+
rules: {
|
|
47
|
+
required: 'Email is required!',
|
|
48
|
+
pattern: {
|
|
49
|
+
value: /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/,
|
|
50
|
+
message: 'Invalid email address!',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
defaultValue: "example@example.com"
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const PhoneField = Template.bind({});
|
|
57
|
+
PhoneField.args = {
|
|
58
|
+
name: 'phone',
|
|
59
|
+
label: 'Phone Number',
|
|
60
|
+
placeholder: 'Enter your phone number',
|
|
61
|
+
keyboardType: 'phone-pad',
|
|
62
|
+
rules: {
|
|
63
|
+
required: 'Phone number is required!',
|
|
64
|
+
pattern: {
|
|
65
|
+
value: /^[0-9]{10,15}$/,
|
|
66
|
+
message: 'Invalid phone number!',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const PasswordField = Template.bind({});
|
|
72
|
+
PasswordField.args = {
|
|
73
|
+
name: 'password',
|
|
74
|
+
label: 'Password',
|
|
75
|
+
placeholder: 'Enter your password',
|
|
76
|
+
secureTextEntry: true,
|
|
77
|
+
required: true,
|
|
78
|
+
rules: {
|
|
79
|
+
required: 'Password is required!',
|
|
80
|
+
minLength: {
|
|
81
|
+
value: 6,
|
|
82
|
+
message: 'Password must be at least 6 characters!',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, Text, StyleSheet, ScrollView } from 'react-native';
|
|
3
|
+
import { FormProvider, useForm } from 'react-hook-form';
|
|
4
|
+
import { Meta, Story } from '@storybook/react';
|
|
5
|
+
import { action } from '@storybook/addon-actions';
|
|
6
|
+
import Button from '../../../src/components/buttons/Button';
|
|
7
|
+
import { AutoComplete, TextInput, DatePicker, TextArea, MultiSelect, Select } from '../../../src/components/form';
|
|
8
|
+
|
|
9
|
+
// Основной компонент формы
|
|
10
|
+
const FormExample = ({ onSubmitAction, onCancelAction }) => {
|
|
11
|
+
const methods = useForm();
|
|
12
|
+
|
|
13
|
+
const handleSubmit = methods.handleSubmit((data: any) => {
|
|
14
|
+
onSubmitAction(data); // Передаем данные формы в экшен Storybook при отправке
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const handleCancel = () => {
|
|
18
|
+
const formData = methods.getValues(); // Получаем текущие данные формы
|
|
19
|
+
methods.reset(); // Сбрасываем форму до начальных значений
|
|
20
|
+
onCancelAction(formData); // Передаем данные формы в экшен Storybook при отмене
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<ScrollView contentContainerStyle={styles.container}>
|
|
25
|
+
<FormProvider {...methods}>
|
|
26
|
+
<Text style={styles.title}>Example Form</Text>
|
|
27
|
+
|
|
28
|
+
<DatePicker
|
|
29
|
+
name="dob"
|
|
30
|
+
control={methods.control}
|
|
31
|
+
label="Date of Birth"
|
|
32
|
+
rules={{ required: 'Date of birth is required!' }}
|
|
33
|
+
required={true}
|
|
34
|
+
/>
|
|
35
|
+
|
|
36
|
+
<View style={styles.buttonContainer}>
|
|
37
|
+
<Button
|
|
38
|
+
title="Submit"
|
|
39
|
+
onPress={handleSubmit}
|
|
40
|
+
type="primary"
|
|
41
|
+
/>
|
|
42
|
+
<Button
|
|
43
|
+
title="Cancel"
|
|
44
|
+
onPress={handleCancel}
|
|
45
|
+
type="gray"
|
|
46
|
+
/>
|
|
47
|
+
</View>
|
|
48
|
+
</FormProvider>
|
|
49
|
+
</ScrollView>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const styles = StyleSheet.create({
|
|
54
|
+
container: {
|
|
55
|
+
padding: 20,
|
|
56
|
+
backgroundColor: '#fff',
|
|
57
|
+
flexGrow: 1,
|
|
58
|
+
},
|
|
59
|
+
title: {
|
|
60
|
+
fontSize: 24,
|
|
61
|
+
marginBottom: 20,
|
|
62
|
+
},
|
|
63
|
+
buttonContainer: {
|
|
64
|
+
flexDirection: 'row',
|
|
65
|
+
justifyContent: 'space-between',
|
|
66
|
+
marginTop: 20,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Экспорт конфигурации для Storybook
|
|
71
|
+
export default {
|
|
72
|
+
title: 'Forms/FormExample',
|
|
73
|
+
component: FormExample,
|
|
74
|
+
argTypes: {
|
|
75
|
+
onSubmitAction: { action: 'submit' }, // Экшен для кнопки Submit
|
|
76
|
+
onCancelAction: { action: 'cancel' }, // Экшен для кнопки Cancel
|
|
77
|
+
},
|
|
78
|
+
} as Meta;
|
|
79
|
+
|
|
80
|
+
const Template: Story = (args) => <FormExample {...args} />;
|
|
81
|
+
|
|
82
|
+
export const Default = Template.bind({});
|
|
83
|
+
Default.args = {
|
|
84
|
+
onSubmitAction: action('submit'), // Вызов экшена при отправке
|
|
85
|
+
onCancelAction: action('cancel'), // Вызов экшена при отмене
|
|
86
|
+
};
|