@widergy/mobile-ui 1.15.0 → 1.15.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/CHANGELOG.md +7 -0
- package/lib/components/Button/index.js +1 -1
- package/lib/components/UTBadge/index.js +2 -2
- package/lib/components/UTBadge/theme.js +9 -6
- package/lib/components/UTBaseInputField/README.md +45 -31
- package/lib/components/UTBaseInputField/components/ActionAdornment/index.js +5 -16
- package/lib/components/UTBaseInputField/components/BadgeAdornment/index.js +13 -0
- package/lib/components/UTBaseInputField/components/IconAdornment/constants.js +2 -0
- package/lib/components/UTBaseInputField/components/IconAdornment/index.js +20 -15
- package/lib/components/UTBaseInputField/components/IconAdornment/proptypes.js +20 -0
- package/lib/components/UTBaseInputField/components/IconAdornment/utils.js +7 -2
- package/lib/components/UTBaseInputField/constants.js +12 -1
- package/lib/components/UTBaseInputField/index.js +69 -72
- package/lib/components/UTBaseInputField/proptypes.js +60 -0
- package/lib/components/UTBaseInputField/theme.js +72 -32
- package/lib/components/UTBottomSheet/README.md +53 -0
- package/lib/components/UTBottomSheet/index.js +139 -0
- package/lib/components/UTBottomSheet/styles.js +46 -0
- package/lib/components/UTButton/constants.js +5 -14
- package/lib/components/UTButton/index.js +6 -22
- package/lib/components/UTButton/proptypes.js +29 -0
- package/lib/components/UTButton/theme.js +6 -5
- package/lib/components/UTCheckBox/README.md +4 -30
- package/lib/components/UTCheckBox/constants.js +4 -1
- package/lib/components/UTCheckBox/index.js +33 -22
- package/lib/components/UTCheckBox/proptypes.js +12 -3
- package/lib/components/UTCheckBox/styles.js +7 -0
- package/lib/components/UTCheckBox/theme.js +98 -54
- package/lib/components/UTCheckList/README.MD +14 -10
- package/lib/components/UTCheckList/constants.js +6 -1
- package/lib/components/UTCheckList/index.js +44 -66
- package/lib/components/UTCheckList/proptypes.js +48 -0
- package/lib/components/UTCheckList/styles.js +10 -5
- package/lib/components/UTCheckList/utils.js +5 -0
- package/lib/components/UTFieldLabel/index.js +4 -3
- package/lib/components/UTLabel/constants.js +11 -11
- package/lib/components/UTLabel/index.js +3 -17
- package/lib/components/UTLabel/proptypes.js +19 -0
- package/lib/components/UTLabel/theme.js +2 -2
- package/lib/components/UTMenu/index.js +1 -1
- package/lib/components/UTPasswordField/versions/V0/components/PasswordValidations/styles.js +1 -0
- package/lib/components/UTPasswordField/versions/V1/index.js +3 -2
- package/lib/components/UTSearchField/README.md +42 -0
- package/lib/components/UTSearchField/index.js +59 -0
- package/lib/components/UTSearchField/proptypes.js +28 -0
- package/lib/components/UTSelect/index.js +10 -97
- package/lib/components/UTSelect/{componentes → versions/V0/componentes}/MultipleItem/index.js +1 -1
- package/lib/components/UTSelect/versions/V0/index.js +103 -0
- package/lib/components/UTSelect/versions/V1/README.md +82 -0
- package/lib/components/UTSelect/versions/V1/index.js +171 -0
- package/lib/components/UTSelect/versions/V1/proptypes.js +45 -0
- package/lib/components/UTSelect/versions/V1/styles.js +18 -0
- package/lib/components/UTTextArea/index.js +1 -1
- package/lib/components/UTTextInput/versions/V0/components/BaseInput/index.js +3 -3
- package/lib/components/UTTextInput/versions/V1/README.md +36 -35
- package/lib/components/UTTextInput/versions/V1/components/TextInputField/index.js +18 -12
- package/lib/components/UTTextInput/versions/V1/constants.js +3 -5
- package/lib/components/UTTextInput/versions/V1/index.js +21 -18
- package/lib/components/UTTextInput/versions/V1/proptypes.js +23 -6
- package/lib/index.js +47 -52
- package/package.json +2 -2
- /package/lib/components/UTSelect/{componentes → versions/V0/componentes}/MultipleItem/styles.js +0 -0
- /package/lib/components/UTSelect/{proptypes.js → versions/V0/proptypes.js} +0 -0
- /package/lib/components/UTSelect/{styles.js → versions/V0/styles.js} +0 -0
|
@@ -32,20 +32,20 @@ export const WEIGHTS = {
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
export const COLOR_THEMES = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
ACCENT: 'accent',
|
|
36
|
+
DARK: 'dark',
|
|
37
|
+
ERROR: 'error',
|
|
38
|
+
GRAY: 'gray',
|
|
39
|
+
INFORMATION: 'information',
|
|
40
|
+
LIGHT: 'light',
|
|
41
|
+
NEGATIVE: 'negative',
|
|
42
|
+
NEUTRAL: 'neutral',
|
|
43
|
+
SUCCESS: 'success',
|
|
44
|
+
WARNING: 'warning'
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
export const DEFAULT_PROPS = {
|
|
48
|
-
colorTheme:
|
|
48
|
+
colorTheme: COLOR_THEMES.DARK,
|
|
49
49
|
field: {},
|
|
50
50
|
style: {},
|
|
51
51
|
variant: 'body',
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { any, bool, func, number, objectOf, string } from 'prop-types';
|
|
3
2
|
import { Text } from 'react-native';
|
|
4
|
-
import { ViewPropTypes } from 'deprecated-react-native-prop-types';
|
|
5
3
|
import Markdown from 'react-native-markdown-display';
|
|
6
4
|
|
|
7
5
|
import { useTheme } from '../../theming';
|
|
8
6
|
|
|
9
|
-
import { DEFAULT_PROPS } from './constants';
|
|
10
7
|
import { markdownFormat } from './utils';
|
|
11
8
|
import { retrieveStyle } from './theme';
|
|
9
|
+
import { defaultProps, propTypes } from './proptypes';
|
|
12
10
|
|
|
13
11
|
const UTLabel = ({
|
|
14
12
|
children,
|
|
@@ -44,19 +42,7 @@ const UTLabel = ({
|
|
|
44
42
|
);
|
|
45
43
|
};
|
|
46
44
|
|
|
47
|
-
UTLabel.defaultProps =
|
|
48
|
-
|
|
49
|
-
UTLabel.propTypes = {
|
|
50
|
-
colorTheme: string,
|
|
51
|
-
// eslint-disable-next-line react/forbid-prop-types
|
|
52
|
-
field: any,
|
|
53
|
-
markdownRenderers: objectOf(func),
|
|
54
|
-
numberOfLines: number,
|
|
55
|
-
shade: string,
|
|
56
|
-
style: ViewPropTypes.style,
|
|
57
|
-
variant: string,
|
|
58
|
-
weight: string,
|
|
59
|
-
withMarkdown: bool
|
|
60
|
-
};
|
|
45
|
+
UTLabel.defaultProps = defaultProps;
|
|
46
|
+
UTLabel.propTypes = propTypes;
|
|
61
47
|
|
|
62
48
|
export default UTLabel;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { any, bool, func, number, objectOf, string } from 'prop-types';
|
|
2
|
+
import { TextPropTypes } from 'deprecated-react-native-prop-types';
|
|
3
|
+
|
|
4
|
+
import { DEFAULT_PROPS } from './constants';
|
|
5
|
+
|
|
6
|
+
export const propTypes = {
|
|
7
|
+
colorTheme: string,
|
|
8
|
+
// eslint-disable-next-line react/forbid-prop-types
|
|
9
|
+
field: any,
|
|
10
|
+
markdownRenderers: objectOf(func),
|
|
11
|
+
numberOfLines: number,
|
|
12
|
+
shade: string,
|
|
13
|
+
style: TextPropTypes.style,
|
|
14
|
+
variant: string,
|
|
15
|
+
weight: string,
|
|
16
|
+
withMarkdown: bool
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const defaultProps = DEFAULT_PROPS;
|
|
@@ -3,9 +3,9 @@ import { IS_IOS } from '../../utils/platformUtils/constants';
|
|
|
3
3
|
import { COLOR_THEMES, DEFAULT_PROPS, SHADES, VARIANTS_SIZES, WEIGHTS } from './constants';
|
|
4
4
|
|
|
5
5
|
const getDefaultColorShade = colorTheme =>
|
|
6
|
-
colorTheme === COLOR_THEMES.
|
|
6
|
+
colorTheme === COLOR_THEMES.GRAY
|
|
7
7
|
? SHADES.shade04
|
|
8
|
-
: colorTheme === COLOR_THEMES.
|
|
8
|
+
: colorTheme === COLOR_THEMES.LIGHT
|
|
9
9
|
? SHADES.shade01
|
|
10
10
|
: SHADES.shade05;
|
|
11
11
|
|
|
@@ -162,7 +162,7 @@ const UTMenu = ({
|
|
|
162
162
|
{withAutocomplete && (
|
|
163
163
|
<View style={[styles.searchContainer, propStyles?.searchContainer]}>
|
|
164
164
|
<UTTextInput
|
|
165
|
-
|
|
165
|
+
inputRef={searchTextInputRef}
|
|
166
166
|
onChange={handleQueryChange}
|
|
167
167
|
onSubmitEditing={
|
|
168
168
|
query && filteredOptions[0]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import propTypes from '../../../UTTextInput/versions/V1/proptypes';
|
|
3
|
+
import { propTypes, defaultProps } from '../../../UTTextInput/versions/V1/proptypes';
|
|
4
4
|
import UTTextInput from '../../../UTTextInput';
|
|
5
5
|
|
|
6
6
|
import { ICON_EYE, ICON_EYE_OFF, INPUT_TYPE } from './constants';
|
|
@@ -13,7 +13,7 @@ const UTPasswordField = props => {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
const action = {
|
|
16
|
-
|
|
16
|
+
Icon: isPasswordVisible ? ICON_EYE : ICON_EYE_OFF,
|
|
17
17
|
onPress: toggleVisibility
|
|
18
18
|
};
|
|
19
19
|
|
|
@@ -27,6 +27,7 @@ const UTPasswordField = props => {
|
|
|
27
27
|
);
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
+
UTPasswordField.defaultProps = defaultProps;
|
|
30
31
|
UTPasswordField.propTypes = propTypes;
|
|
31
32
|
|
|
32
33
|
export default UTPasswordField;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# UTSearchField
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
`UTSearchField` is a customizable search field component that includes a search icon on the left and an optional clear button on the right.
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
|
|
9
|
+
| Name | Type | Default | Description |
|
|
10
|
+
| --------------- | -------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------ |
|
|
11
|
+
| inputRef | func | | Reference to the input field. |
|
|
12
|
+
| input | shape({ value: string.isRequired, onChange: func.isRequired }) | { value: '', onChange: () => {} } | Input object containing the value and onChange handler. |
|
|
13
|
+
| onBlur | func | | Function to call when the input field loses focus. |
|
|
14
|
+
| onFocus | func | | Function to call when the input field gains focus. |
|
|
15
|
+
| onSubmitEditing | func | | Function to call when the input field is submitted. |
|
|
16
|
+
| placeholder | string | | Placeholder text for the input field. |
|
|
17
|
+
| returnKeyType | string | | Determines the return key type on the keyboard. |
|
|
18
|
+
| size | string | medium | Size of the input field. One of: `small`, `medium`, `large`. |
|
|
19
|
+
| style | object | | Style object to customize the input field. |
|
|
20
|
+
| type | string | | Type of input (e.g., 'text', 'password', 'email'). |
|
|
21
|
+
| variant | string | white | Variant of the input field. One of: `white`, `gray`. |
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
|
|
25
|
+
```jsx
|
|
26
|
+
import React, { useState } from 'react';
|
|
27
|
+
import { View, Text } from 'react-native';
|
|
28
|
+
import UTSearchField from './UTSearchField';
|
|
29
|
+
|
|
30
|
+
const UTSearchFieldExample = () => {
|
|
31
|
+
const [searchValue, setSearchValue] = useState('');
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<View style={{ padding: 20 }}>
|
|
35
|
+
<UTSearchField placeholder="Search..." value={searchValue} onChange={setSearchValue} />
|
|
36
|
+
<Text>Search Value: {searchValue}</Text>
|
|
37
|
+
</View>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default UTSearchFieldExample;
|
|
42
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { COMPONENT_KEYS } from '../UTBaseInputField/constants';
|
|
4
|
+
import UTBaseInputField from '../UTBaseInputField';
|
|
5
|
+
|
|
6
|
+
import { defaultProps, propTypes } from './proptypes';
|
|
7
|
+
|
|
8
|
+
const UTSearchField = ({
|
|
9
|
+
disabled,
|
|
10
|
+
input,
|
|
11
|
+
inputRef,
|
|
12
|
+
onBlur,
|
|
13
|
+
onFocus,
|
|
14
|
+
onSubmitEditing,
|
|
15
|
+
placeholder,
|
|
16
|
+
returnKeyType,
|
|
17
|
+
size,
|
|
18
|
+
style,
|
|
19
|
+
type,
|
|
20
|
+
variant
|
|
21
|
+
}) => {
|
|
22
|
+
const clearText = () => {
|
|
23
|
+
input.onChange('');
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const action = { Icon: 'IconX', onPress: clearText, size: 'small' };
|
|
27
|
+
|
|
28
|
+
const leftAdornments = [
|
|
29
|
+
{ name: COMPONENT_KEYS.ICON, props: { Icon: 'IconSearch', changeOnFocus: true, shade: '02' } }
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const rightAdornments = input.value ? [{ name: COMPONENT_KEYS.ACTION, props: { action } }] : [];
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<UTBaseInputField
|
|
36
|
+
alwaysShowPlaceholder
|
|
37
|
+
disabled={disabled}
|
|
38
|
+
input={input}
|
|
39
|
+
inputSize={size}
|
|
40
|
+
leftAdornments={leftAdornments}
|
|
41
|
+
onBlur={onBlur}
|
|
42
|
+
onFocus={onFocus}
|
|
43
|
+
onSubmitEditing={onSubmitEditing}
|
|
44
|
+
placeholder={placeholder}
|
|
45
|
+
ref={inputRef}
|
|
46
|
+
returnKeyType={returnKeyType}
|
|
47
|
+
rightAdornments={rightAdornments}
|
|
48
|
+
style={{ container: style }}
|
|
49
|
+
type={type}
|
|
50
|
+
variant={variant}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
UTSearchField.defaultProps = defaultProps;
|
|
56
|
+
|
|
57
|
+
UTSearchField.propTypes = propTypes;
|
|
58
|
+
|
|
59
|
+
export default UTSearchField;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { func, oneOf, string, object, shape, instanceOf, oneOfType } from 'prop-types';
|
|
2
|
+
|
|
3
|
+
import { SIZES, VARIANT } from '../UTBaseInputField/constants';
|
|
4
|
+
|
|
5
|
+
export const defaultProps = {
|
|
6
|
+
input: {
|
|
7
|
+
value: [],
|
|
8
|
+
onChange: () => {}
|
|
9
|
+
},
|
|
10
|
+
variant: VARIANT.WHITE
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const propTypes = {
|
|
14
|
+
input: shape({
|
|
15
|
+
value: string,
|
|
16
|
+
onChange: func
|
|
17
|
+
}),
|
|
18
|
+
inputRef: oneOfType([func, instanceOf(Object)]),
|
|
19
|
+
onBlur: func,
|
|
20
|
+
onFocus: func,
|
|
21
|
+
onSubmitEditing: func,
|
|
22
|
+
placeholder: string,
|
|
23
|
+
returnKeyType: string,
|
|
24
|
+
size: oneOf(Object.values(SIZES)),
|
|
25
|
+
style: object,
|
|
26
|
+
type: string,
|
|
27
|
+
variant: oneOf(Object.values(VARIANT))
|
|
28
|
+
};
|
|
@@ -1,103 +1,16 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import {
|
|
3
|
-
import { View } from 'react-native';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { string } from 'prop-types';
|
|
4
3
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import UTTextInput from '../UTTextInput';
|
|
4
|
+
import V0 from './versions/V0';
|
|
5
|
+
import V1 from './versions/V1';
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const UTSelect = ({
|
|
14
|
-
options = [],
|
|
15
|
-
value,
|
|
16
|
-
onChange,
|
|
17
|
-
error,
|
|
18
|
-
UTMenuProps,
|
|
19
|
-
label,
|
|
20
|
-
styles: propStyles,
|
|
21
|
-
variant,
|
|
22
|
-
disabled,
|
|
23
|
-
UTTextInputProps,
|
|
24
|
-
isMultiple,
|
|
25
|
-
verticalOffset = 5,
|
|
26
|
-
title,
|
|
27
|
-
titleProps,
|
|
28
|
-
changeOnClose
|
|
29
|
-
}) => {
|
|
30
|
-
const [focused, setFocused] = useState(false);
|
|
31
|
-
|
|
32
|
-
const selectedOption = useMemo(
|
|
33
|
-
() => (!isMultiple ? options.find(option => option.value === value) : value || []),
|
|
34
|
-
[isMultiple, options, value]
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
const handleChange = option => {
|
|
38
|
-
if (!changeOnClose) onChange(option.value);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const handleChangeMultiple = newValue => {
|
|
42
|
-
const newValues = !selectedOption?.find?.(elem => elem === newValue.value)
|
|
43
|
-
? [...(selectedOption || []), newValue.value]
|
|
44
|
-
: selectedOption?.filter(elem => elem !== newValue.value);
|
|
45
|
-
|
|
46
|
-
const finalValue = isEmpty(newValues) ? null : newValues;
|
|
47
|
-
if (!changeOnClose) {
|
|
48
|
-
onChange(finalValue);
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const handleOpen = () => setFocused(true);
|
|
53
|
-
// eslint-disable-next-line consistent-return
|
|
54
|
-
const handleClose = () => {
|
|
55
|
-
setFocused(false);
|
|
56
|
-
if (changeOnClose) {
|
|
57
|
-
return isMultiple
|
|
58
|
-
? onChange(selectedOption)
|
|
59
|
-
: onChange(options.find(_option => _option.id === selectedOption.id).value);
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<View style={[styles.container, propStyles]}>
|
|
65
|
-
{title && (
|
|
66
|
-
<Label medium primary {...titleProps}>
|
|
67
|
-
{title}
|
|
68
|
-
</Label>
|
|
69
|
-
)}
|
|
70
|
-
<UTMenu
|
|
71
|
-
options={options}
|
|
72
|
-
selectedOption={isMultiple ? selectedOption : selectedOption?.id}
|
|
73
|
-
fullWidth
|
|
74
|
-
verticalOffset={verticalOffset}
|
|
75
|
-
disabled={disabled}
|
|
76
|
-
onPress={isMultiple ? handleChangeMultiple : handleChange}
|
|
77
|
-
onOpen={handleOpen}
|
|
78
|
-
onClose={handleClose}
|
|
79
|
-
withoutOpacity
|
|
80
|
-
MenuOptionComponent={isMultiple && MultipleItem}
|
|
81
|
-
isMultiple={isMultiple}
|
|
82
|
-
{...UTMenuProps}
|
|
83
|
-
>
|
|
84
|
-
<UTTextInput
|
|
85
|
-
variant={variant}
|
|
86
|
-
value={isMultiple ? value?.join(', ') || '' : selectedOption?.label || selectedOption?.value || ''}
|
|
87
|
-
error={error}
|
|
88
|
-
label={label}
|
|
89
|
-
select
|
|
90
|
-
controlledFocus={focused}
|
|
91
|
-
disabled={disabled}
|
|
92
|
-
version="V0"
|
|
93
|
-
RightIcon={{ type: 'font-awesome', name: 'caret-down' }}
|
|
94
|
-
{...UTTextInputProps}
|
|
95
|
-
/>
|
|
96
|
-
</UTMenu>
|
|
97
|
-
</View>
|
|
98
|
-
);
|
|
7
|
+
const UTSelect = ({ version = 'V0', ...props }) => {
|
|
8
|
+
const Component = { V0, V1 }[version];
|
|
9
|
+
return <Component {...props} />;
|
|
99
10
|
};
|
|
100
11
|
|
|
101
|
-
UTSelect.propTypes =
|
|
12
|
+
UTSelect.propTypes = {
|
|
13
|
+
version: string
|
|
14
|
+
};
|
|
102
15
|
|
|
103
16
|
export default UTSelect;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import React, { useState, useMemo } from 'react';
|
|
2
|
+
import { isEmpty } from '@widergy/web-utils/lib/array';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import Label from '../../../Label';
|
|
6
|
+
import UTMenu from '../../../UTMenu';
|
|
7
|
+
import UTTextInput from '../../../UTTextInput';
|
|
8
|
+
|
|
9
|
+
import MultipleItem from './componentes/MultipleItem';
|
|
10
|
+
import styles from './styles';
|
|
11
|
+
import UTSelectTypes from './proptypes';
|
|
12
|
+
|
|
13
|
+
const UTSelect = ({
|
|
14
|
+
options = [],
|
|
15
|
+
value,
|
|
16
|
+
onChange,
|
|
17
|
+
error,
|
|
18
|
+
UTMenuProps,
|
|
19
|
+
label,
|
|
20
|
+
styles: propStyles,
|
|
21
|
+
variant,
|
|
22
|
+
disabled,
|
|
23
|
+
UTTextInputProps,
|
|
24
|
+
isMultiple,
|
|
25
|
+
verticalOffset = 5,
|
|
26
|
+
title,
|
|
27
|
+
titleProps,
|
|
28
|
+
changeOnClose
|
|
29
|
+
}) => {
|
|
30
|
+
const [focused, setFocused] = useState(false);
|
|
31
|
+
|
|
32
|
+
const selectedOption = useMemo(
|
|
33
|
+
() => (!isMultiple ? options.find(option => option.value === value) : value || []),
|
|
34
|
+
[isMultiple, options, value]
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const handleChange = option => {
|
|
38
|
+
if (!changeOnClose) onChange(option.value);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const handleChangeMultiple = newValue => {
|
|
42
|
+
const newValues = !selectedOption?.find?.(elem => elem === newValue.value)
|
|
43
|
+
? [...(selectedOption || []), newValue.value]
|
|
44
|
+
: selectedOption?.filter(elem => elem !== newValue.value);
|
|
45
|
+
|
|
46
|
+
const finalValue = isEmpty(newValues) ? null : newValues;
|
|
47
|
+
if (!changeOnClose) {
|
|
48
|
+
onChange(finalValue);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const handleOpen = () => setFocused(true);
|
|
53
|
+
// eslint-disable-next-line consistent-return
|
|
54
|
+
const handleClose = () => {
|
|
55
|
+
setFocused(false);
|
|
56
|
+
if (changeOnClose) {
|
|
57
|
+
return isMultiple
|
|
58
|
+
? onChange(selectedOption)
|
|
59
|
+
: onChange(options.find(_option => _option.id === selectedOption.id).value);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<View style={[styles.container, propStyles]}>
|
|
65
|
+
{title && (
|
|
66
|
+
<Label medium primary {...titleProps}>
|
|
67
|
+
{title}
|
|
68
|
+
</Label>
|
|
69
|
+
)}
|
|
70
|
+
<UTMenu
|
|
71
|
+
options={options}
|
|
72
|
+
selectedOption={isMultiple ? selectedOption : selectedOption?.id}
|
|
73
|
+
fullWidth
|
|
74
|
+
verticalOffset={verticalOffset}
|
|
75
|
+
disabled={disabled}
|
|
76
|
+
onPress={isMultiple ? handleChangeMultiple : handleChange}
|
|
77
|
+
onOpen={handleOpen}
|
|
78
|
+
onClose={handleClose}
|
|
79
|
+
withoutOpacity
|
|
80
|
+
MenuOptionComponent={isMultiple && MultipleItem}
|
|
81
|
+
isMultiple={isMultiple}
|
|
82
|
+
{...UTMenuProps}
|
|
83
|
+
>
|
|
84
|
+
<UTTextInput
|
|
85
|
+
variant={variant}
|
|
86
|
+
value={isMultiple ? value?.join(', ') || '' : selectedOption?.label || selectedOption?.value || ''}
|
|
87
|
+
error={error}
|
|
88
|
+
label={label}
|
|
89
|
+
select
|
|
90
|
+
controlledFocus={focused}
|
|
91
|
+
disabled={disabled}
|
|
92
|
+
version="V0"
|
|
93
|
+
RightIcon={{ type: 'font-awesome', name: 'caret-down' }}
|
|
94
|
+
{...UTTextInputProps}
|
|
95
|
+
/>
|
|
96
|
+
</UTMenu>
|
|
97
|
+
</View>
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
UTSelect.propTypes = UTSelectTypes;
|
|
102
|
+
|
|
103
|
+
export default UTSelect;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# UTSelect
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
`UTSelect` is a customizable dropdown select component that allows users to select single or multiple options from a provided list. It includes features like search, select all, and dynamic option filtering.
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
|
|
9
|
+
| Name | Type | Default | Description |
|
|
10
|
+
| --------------------- | ------ | ------- | ---------------------------------------------------------------------------------------------------- |
|
|
11
|
+
| action | shape | | Action object containing `Icon`, `onPress`, and `size` for the action button. |
|
|
12
|
+
| alwaysShowPlaceholder | bool | true | Determines if the placeholder should always be shown. |
|
|
13
|
+
| helpText | string | | Help text displayed below the input field. |
|
|
14
|
+
| noMatchesText | string | | Text to display when no matches are found in the search. |
|
|
15
|
+
| input | shape | | Input configuration object containing `value` and `onChange`. |
|
|
16
|
+
| isMultiple | bool | false | Allows multiple selection if true. |
|
|
17
|
+
| label | string | | Label for the select field. |
|
|
18
|
+
| options | array | | Array of options to be displayed in the dropdown. Each option is an object with `label` and `value`. |
|
|
19
|
+
| placeholder | string | | Placeholder text for the select field. |
|
|
20
|
+
| prefix | string | | Text to display as a prefix inside the input field. |
|
|
21
|
+
| required | bool | false | Indicates if the select field is required. |
|
|
22
|
+
| searchPlaceholder | string | | Placeholder text for the search field. |
|
|
23
|
+
| selectAllLabel | string | | Label for the "Select All" checkbox. |
|
|
24
|
+
| showSelectAll | bool | false | Determines whether to show the "Select All" checkbox. |
|
|
25
|
+
| style | shape | {} | Custom styles to apply to the select field. Can contain `root`, `noMatchesText`, `scrollview`. |
|
|
26
|
+
| suffix | string | | Text to display as a suffix inside the input field. |
|
|
27
|
+
|
|
28
|
+
### Input Object
|
|
29
|
+
|
|
30
|
+
The `input` prop is an object that should contain the following keys:
|
|
31
|
+
|
|
32
|
+
| Name | Type | Description |
|
|
33
|
+
| -------- | ----------------------- | -------------------------------------------- |
|
|
34
|
+
| value | arrayOf(string, number) | Array of selected values. |
|
|
35
|
+
| onChange | func | Function to call when the selection changes. |
|
|
36
|
+
|
|
37
|
+
### Option Object
|
|
38
|
+
|
|
39
|
+
The `options` prop is an array of objects, each representing an option:
|
|
40
|
+
|
|
41
|
+
| Name | Type | Description |
|
|
42
|
+
| ----- | -------------- | -------------------------------- |
|
|
43
|
+
| label | string | Label to display for the option. |
|
|
44
|
+
| value | string, number | Value of the option. |
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
```jsx
|
|
49
|
+
import React, { useState } from 'react';
|
|
50
|
+
import { View, Text } from 'react-native';
|
|
51
|
+
import UTSelect from './UTSelect';
|
|
52
|
+
|
|
53
|
+
const options = [
|
|
54
|
+
{ label: 'Option 1', value: '1' },
|
|
55
|
+
{ label: 'Option 2', value: '2' },
|
|
56
|
+
{ label: 'Option 3', value: '3' }
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
const UTSelectExample = () => {
|
|
60
|
+
const [selectedOptions, setSelectedOptions] = useState([]);
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<View style={{ padding: 20 }}>
|
|
64
|
+
<UTSelect
|
|
65
|
+
label="Select Options"
|
|
66
|
+
options={options}
|
|
67
|
+
input={{
|
|
68
|
+
value: selectedOptions,
|
|
69
|
+
onChange: setSelectedOptions
|
|
70
|
+
}}
|
|
71
|
+
placeholder="Select an option"
|
|
72
|
+
searchPlaceholder="Search options"
|
|
73
|
+
selectAllLabel="Select All"
|
|
74
|
+
noMatchesText="No matches found"
|
|
75
|
+
/>
|
|
76
|
+
<Text>Selected Options: {selectedOptions.join(', ')}</Text>
|
|
77
|
+
</View>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export default UTSelectExample;
|
|
82
|
+
```
|