@widergy/mobile-ui 1.11.2 → 1.11.4
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 +14 -0
- package/lib/components/UTAutocomplete/index.js +36 -33
- package/lib/components/UTButton/index.js +12 -9
- package/lib/components/UTButton/theme.js +46 -44
- package/lib/components/UTLabel/constants.js +6 -3
- package/lib/components/UTMenu/index.js +30 -17
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [1.11.4](https://github.com/widergy/mobile-ui/compare/v1.11.3...v1.11.4) (2024-06-18)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* configurable avoid utmenu overlapping anchor ([#296](https://github.com/widergy/mobile-ui/issues/296)) ([6ab50ba](https://github.com/widergy/mobile-ui/commit/6ab50babc59deb019947c79067a010e4ddf047dc))
|
|
7
|
+
|
|
8
|
+
## [1.11.3](https://github.com/widergy/mobile-ui/compare/v1.11.2...v1.11.3) (2024-06-12)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* integrate utlabel in utbutton ([#293](https://github.com/widergy/mobile-ui/issues/293)) ([519119b](https://github.com/widergy/mobile-ui/commit/519119be6c9dc7f1daf1b0e8beb6019df66a9a71))
|
|
14
|
+
|
|
1
15
|
## [1.11.2](https://github.com/widergy/mobile-ui/compare/v1.11.1...v1.11.2) (2024-06-03)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -9,18 +9,19 @@ import UTTextInput from '../UTTextInput';
|
|
|
9
9
|
import styles from './styles';
|
|
10
10
|
|
|
11
11
|
const UTAutocomplete = ({
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
autoCompletePlaceholder,
|
|
13
|
+
avoidOverlappingAnchor,
|
|
14
14
|
disabled,
|
|
15
|
+
error,
|
|
16
|
+
filterOptions,
|
|
17
|
+
input,
|
|
15
18
|
label,
|
|
16
19
|
labelBackgroundColor,
|
|
17
|
-
error,
|
|
18
|
-
variant,
|
|
19
|
-
autoCompletePlaceholder,
|
|
20
|
-
MenuOptionComponent,
|
|
21
20
|
ListEmptyComponent,
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
MenuOptionComponent,
|
|
22
|
+
options,
|
|
23
|
+
persistSelectedOption = false,
|
|
24
|
+
variant
|
|
24
25
|
}) => {
|
|
25
26
|
const [selectedOption, setSelectedOption] = useState();
|
|
26
27
|
|
|
@@ -38,30 +39,31 @@ const UTAutocomplete = ({
|
|
|
38
39
|
return (
|
|
39
40
|
<View style={styles.container}>
|
|
40
41
|
<UTMenu
|
|
41
|
-
options={options}
|
|
42
|
-
fullWidth
|
|
43
|
-
selectedOption={selectedOption?.id}
|
|
44
|
-
withAutocomplete
|
|
45
|
-
onPress={handleOnPress}
|
|
46
|
-
onOpen={input.onFocus}
|
|
47
|
-
onClose={input.onBlur}
|
|
48
|
-
disabled={disabled}
|
|
49
|
-
onQueryChange={input.onQueryChange}
|
|
50
42
|
autoCompletePlaceholder={autoCompletePlaceholder}
|
|
43
|
+
avoidOverlappingAnchor={avoidOverlappingAnchor}
|
|
44
|
+
disabled={disabled}
|
|
45
|
+
filterOptions={filterOptions}
|
|
46
|
+
fullWidth
|
|
47
|
+
ListEmptyComponent={ListEmptyComponent}
|
|
51
48
|
maxHeight={WINDOW_HEIGHT * 0.25}
|
|
52
49
|
MenuOptionComponent={MenuOptionComponent}
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
onClose={input.onBlur}
|
|
51
|
+
onOpen={input.onFocus}
|
|
52
|
+
onPress={handleOnPress}
|
|
53
|
+
onQueryChange={input.onQueryChange}
|
|
54
|
+
options={options}
|
|
55
|
+
selectedOption={selectedOption?.id}
|
|
56
|
+
withAutocomplete
|
|
55
57
|
>
|
|
56
58
|
<UTTextInput
|
|
57
|
-
|
|
58
|
-
value={selectedOption?.label || ''}
|
|
59
|
+
disabled={disabled}
|
|
59
60
|
error={error}
|
|
60
61
|
label={label}
|
|
61
62
|
labelBackgroundColor={labelBackgroundColor}
|
|
62
|
-
RightIcon={{ type: 'font-awesome', name: 'caret-down' }}
|
|
63
63
|
onChange={() => {}}
|
|
64
|
-
|
|
64
|
+
RightIcon={{ type: 'font-awesome', name: 'caret-down' }}
|
|
65
|
+
value={selectedOption?.label || ''}
|
|
66
|
+
variant={variant}
|
|
65
67
|
/>
|
|
66
68
|
</UTMenu>
|
|
67
69
|
</View>
|
|
@@ -69,12 +71,21 @@ const UTAutocomplete = ({
|
|
|
69
71
|
};
|
|
70
72
|
|
|
71
73
|
UTAutocomplete.propTypes = {
|
|
74
|
+
avoidOverlappingAnchor: bool,
|
|
75
|
+
autoCompletePlaceholder: string,
|
|
76
|
+
disabled: bool,
|
|
77
|
+
error: oneOf([bool, string]),
|
|
78
|
+
filterOptions: bool,
|
|
72
79
|
input: shape({
|
|
73
80
|
onChange: func.isRequired,
|
|
74
81
|
value: string.isRequired,
|
|
75
82
|
onFocus: func,
|
|
76
83
|
onBlur: func
|
|
77
84
|
}),
|
|
85
|
+
label: string,
|
|
86
|
+
labelBackgroundColor: string,
|
|
87
|
+
ListEmptyComponent: element,
|
|
88
|
+
MenuOptionComponent: element,
|
|
78
89
|
options: arrayOf(
|
|
79
90
|
shape({
|
|
80
91
|
value: string,
|
|
@@ -82,16 +93,8 @@ UTAutocomplete.propTypes = {
|
|
|
82
93
|
label: string
|
|
83
94
|
})
|
|
84
95
|
),
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
labelBackgroundColor: string,
|
|
88
|
-
error: oneOf([bool, string]),
|
|
89
|
-
variant: string,
|
|
90
|
-
autoCompletePlaceholder: string,
|
|
91
|
-
MenuOptionComponent: element,
|
|
92
|
-
ListEmptyComponent: element,
|
|
93
|
-
filterOptions: bool,
|
|
94
|
-
persistSelectedOption: bool
|
|
96
|
+
persistSelectedOption: bool,
|
|
97
|
+
variant: string
|
|
95
98
|
};
|
|
96
99
|
|
|
97
100
|
export default UTAutocomplete;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { bool, func, elementType, string } from 'prop-types';
|
|
3
|
-
import { Pressable,
|
|
3
|
+
import { Pressable, View } from 'react-native';
|
|
4
4
|
import { ViewPropTypes } from 'deprecated-react-native-prop-types';
|
|
5
5
|
|
|
6
6
|
import { themeType, withTheme } from '../../theming';
|
|
7
7
|
import UTIcon from '../UTIcon';
|
|
8
|
+
import UTLabel from '../UTLabel';
|
|
8
9
|
import UTLoading from '../UTLoading';
|
|
9
10
|
|
|
10
11
|
import { DEFAULT_PROPS, ICON_PLACEMENTS } from './constants';
|
|
@@ -29,7 +30,7 @@ const UTButton = ({
|
|
|
29
30
|
childrenContainerStyles: themeChildrenContainerStyles,
|
|
30
31
|
disabledStyles,
|
|
31
32
|
iconStyles: themeIconStyles,
|
|
32
|
-
textStyles
|
|
33
|
+
textStyles
|
|
33
34
|
} = retrieveStyle({
|
|
34
35
|
style,
|
|
35
36
|
colorTheme,
|
|
@@ -39,7 +40,7 @@ const UTButton = ({
|
|
|
39
40
|
variant
|
|
40
41
|
});
|
|
41
42
|
|
|
42
|
-
const
|
|
43
|
+
const iconStyles = children ? themeIconStyles.icon : themeIconStyles.iconOnly;
|
|
43
44
|
|
|
44
45
|
const buttonStyles = ({ pressed }) => [
|
|
45
46
|
themeButtonStyles,
|
|
@@ -47,27 +48,29 @@ const UTButton = ({
|
|
|
47
48
|
pressed ? themeButtonStyles.pressed : themeButtonStyles.notPressed
|
|
48
49
|
];
|
|
49
50
|
|
|
50
|
-
const textStyles = themeTextStyles;
|
|
51
|
-
|
|
52
51
|
const IconToShow =
|
|
53
52
|
Icon &&
|
|
54
53
|
(isUTIcon(Icon) ? (
|
|
55
|
-
<UTIcon color={
|
|
54
|
+
<UTIcon color={iconStyles.color} style={iconStyles} size={iconStyles.fontSize} name={Icon} />
|
|
56
55
|
) : (
|
|
57
|
-
<Icon style={
|
|
56
|
+
<Icon style={iconStyles} fill={iconStyles.color} />
|
|
58
57
|
));
|
|
59
58
|
|
|
60
59
|
const RenderedChildren = (
|
|
61
60
|
<View style={themeChildrenContainerStyles}>
|
|
62
61
|
{iconPlacement === ICON_PLACEMENTS.left && IconToShow}
|
|
63
|
-
{children &&
|
|
62
|
+
{children && (
|
|
63
|
+
<UTLabel colorTheme={textStyles.colorTheme} variant={textStyles.variant} weight={textStyles.weight}>
|
|
64
|
+
{children}
|
|
65
|
+
</UTLabel>
|
|
66
|
+
)}
|
|
64
67
|
{iconPlacement !== ICON_PLACEMENTS.left && IconToShow}
|
|
65
68
|
</View>
|
|
66
69
|
);
|
|
67
70
|
|
|
68
71
|
return (
|
|
69
72
|
<Pressable disabled={disabled || loading} onPress={onPress} style={buttonStyles}>
|
|
70
|
-
<UTLoading color={
|
|
73
|
+
<UTLoading color={iconStyles.color} loading={loading} size={24} thickness={2}>
|
|
71
74
|
{RenderedChildren}
|
|
72
75
|
</UTLoading>
|
|
73
76
|
</Pressable>
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { getShadow } from '../../utils/styleUtils';
|
|
2
|
+
import { COLOR_THEMES } from '../UTLabel/constants';
|
|
2
3
|
|
|
3
4
|
import { COLORS_MAPPER, DEFAULT_PROPS, ELEVATION, PRESSED_ELEVATION } from './constants';
|
|
4
5
|
|
|
5
|
-
const baseButtonTheme =
|
|
6
|
+
const baseButtonTheme = () => ({
|
|
6
7
|
text: {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
fontWeight: '500',
|
|
10
|
-
lineHeight: 22,
|
|
11
|
-
textTransform: 'none'
|
|
8
|
+
variant: 'body',
|
|
9
|
+
weight: 'medium'
|
|
12
10
|
},
|
|
13
11
|
button: {
|
|
14
12
|
borderRadius: 4,
|
|
@@ -37,8 +35,8 @@ const baseButtonTheme = theme => ({
|
|
|
37
35
|
});
|
|
38
36
|
|
|
39
37
|
const variantsColorTheme = (theme, colorTheme, variant) => {
|
|
40
|
-
const
|
|
41
|
-
const actionTheme = theme.Palette[
|
|
38
|
+
const colorName = COLORS_MAPPER[colorTheme] || COLORS_MAPPER[DEFAULT_PROPS.colorTheme];
|
|
39
|
+
const actionTheme = theme.Palette[colorName];
|
|
42
40
|
const negativeTheme = theme.Palette[COLORS_MAPPER.negative];
|
|
43
41
|
const neutralTheme = theme.Palette[COLORS_MAPPER.secondary];
|
|
44
42
|
const shadow = getShadow(ELEVATION);
|
|
@@ -56,12 +54,10 @@ const variantsColorTheme = (theme, colorTheme, variant) => {
|
|
|
56
54
|
}
|
|
57
55
|
},
|
|
58
56
|
text: {
|
|
59
|
-
|
|
57
|
+
colorTheme: colorTheme === COLORS_MAPPER.negative ? COLOR_THEMES.neutral : COLOR_THEMES.negative
|
|
60
58
|
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
color: colorTheme === COLORS_MAPPER.negative ? neutralTheme['05'] : negativeTheme['05'],
|
|
64
|
-
opacity: 0.5
|
|
59
|
+
icon: {
|
|
60
|
+
color: colorTheme === COLORS_MAPPER.negative ? neutralTheme['05'] : negativeTheme['05']
|
|
65
61
|
}
|
|
66
62
|
},
|
|
67
63
|
semitransparent: {
|
|
@@ -75,12 +71,10 @@ const variantsColorTheme = (theme, colorTheme, variant) => {
|
|
|
75
71
|
}
|
|
76
72
|
},
|
|
77
73
|
text: {
|
|
78
|
-
|
|
74
|
+
colorTheme: colorName
|
|
79
75
|
},
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
color: actionTheme['05'],
|
|
83
|
-
opacity: 0.5
|
|
76
|
+
icon: {
|
|
77
|
+
color: actionTheme['05']
|
|
84
78
|
}
|
|
85
79
|
},
|
|
86
80
|
outlined: {
|
|
@@ -93,13 +87,10 @@ const variantsColorTheme = (theme, colorTheme, variant) => {
|
|
|
93
87
|
}
|
|
94
88
|
},
|
|
95
89
|
text: {
|
|
96
|
-
|
|
90
|
+
colorTheme: colorName
|
|
97
91
|
},
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
borderColor: actionTheme['05'],
|
|
101
|
-
color: actionTheme['05'],
|
|
102
|
-
opacity: 0.5
|
|
92
|
+
icon: {
|
|
93
|
+
color: actionTheme['05']
|
|
103
94
|
}
|
|
104
95
|
},
|
|
105
96
|
text: {
|
|
@@ -112,11 +103,10 @@ const variantsColorTheme = (theme, colorTheme, variant) => {
|
|
|
112
103
|
}
|
|
113
104
|
},
|
|
114
105
|
text: {
|
|
115
|
-
|
|
106
|
+
colorTheme: colorName
|
|
116
107
|
},
|
|
117
|
-
|
|
118
|
-
color: actionTheme['05']
|
|
119
|
-
opacity: 0.5
|
|
108
|
+
icon: {
|
|
109
|
+
color: actionTheme['05']
|
|
120
110
|
}
|
|
121
111
|
},
|
|
122
112
|
shadow: {
|
|
@@ -132,11 +122,10 @@ const variantsColorTheme = (theme, colorTheme, variant) => {
|
|
|
132
122
|
notPressed: shadow
|
|
133
123
|
},
|
|
134
124
|
text: {
|
|
135
|
-
|
|
125
|
+
colorTheme: colorName
|
|
136
126
|
},
|
|
137
|
-
|
|
138
|
-
color: actionTheme['05']
|
|
139
|
-
opacity: 0.5
|
|
127
|
+
icon: {
|
|
128
|
+
color: actionTheme['05']
|
|
140
129
|
}
|
|
141
130
|
}
|
|
142
131
|
};
|
|
@@ -152,8 +141,8 @@ const sizeButtonTheme = size => {
|
|
|
152
141
|
paddingVertical: 12
|
|
153
142
|
},
|
|
154
143
|
text: {
|
|
155
|
-
|
|
156
|
-
|
|
144
|
+
variant: 'body',
|
|
145
|
+
weight: 'medium'
|
|
157
146
|
},
|
|
158
147
|
icon: {
|
|
159
148
|
fontSize: 20
|
|
@@ -168,8 +157,8 @@ const sizeButtonTheme = size => {
|
|
|
168
157
|
paddingVertical: 4
|
|
169
158
|
},
|
|
170
159
|
text: {
|
|
171
|
-
|
|
172
|
-
|
|
160
|
+
weight: 'medium',
|
|
161
|
+
variant: 'small'
|
|
173
162
|
},
|
|
174
163
|
icon: {
|
|
175
164
|
fontSize: 20
|
|
@@ -196,7 +185,7 @@ const iconButtonPlacementTheme = iconPlacement => {
|
|
|
196
185
|
};
|
|
197
186
|
|
|
198
187
|
export const retrieveStyle = ({ style = {}, colorTheme, variant, theme, size, iconPlacement }) => {
|
|
199
|
-
const baseTheme = baseButtonTheme(
|
|
188
|
+
const baseTheme = baseButtonTheme();
|
|
200
189
|
const variantTheme = variantsColorTheme(theme, colorTheme, variant);
|
|
201
190
|
const sizeTheme = sizeButtonTheme(size);
|
|
202
191
|
const iconPlacementTheme = iconButtonPlacementTheme(iconPlacement);
|
|
@@ -209,19 +198,32 @@ export const retrieveStyle = ({ style = {}, colorTheme, variant, theme, size, ic
|
|
|
209
198
|
};
|
|
210
199
|
|
|
211
200
|
const textStyles = {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
201
|
+
colorTheme: variantTheme.text.colorTheme,
|
|
202
|
+
variant: sizeTheme.text?.variant || baseTheme.text?.variant,
|
|
203
|
+
weight: sizeTheme.text?.weight || baseTheme.text?.weight
|
|
215
204
|
};
|
|
216
205
|
|
|
217
206
|
const iconStyles = {
|
|
218
|
-
icon: {
|
|
219
|
-
|
|
207
|
+
icon: {
|
|
208
|
+
...baseTheme.icon,
|
|
209
|
+
...sizeTheme.icon,
|
|
210
|
+
...variantTheme.icon,
|
|
211
|
+
...iconPlacementTheme,
|
|
212
|
+
...style.icon
|
|
213
|
+
},
|
|
214
|
+
iconOnly: {
|
|
215
|
+
...baseTheme.iconOnly,
|
|
216
|
+
...sizeTheme.iconOnly,
|
|
217
|
+
...variantTheme.icon,
|
|
218
|
+
...style.icon
|
|
219
|
+
}
|
|
220
220
|
};
|
|
221
221
|
|
|
222
222
|
const childrenContainerStyles = { ...baseTheme.childrenContainer, ...style.childrenContainer };
|
|
223
223
|
|
|
224
|
-
const
|
|
224
|
+
const disabledStyles = {
|
|
225
|
+
opacity: 0.5
|
|
226
|
+
};
|
|
225
227
|
|
|
226
|
-
return { buttonStyles, textStyles, disabledStyles
|
|
228
|
+
return { buttonStyles, textStyles, disabledStyles, iconStyles, childrenContainerStyles };
|
|
227
229
|
};
|
|
@@ -32,13 +32,16 @@ export const WEIGHTS = {
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
export const COLOR_THEMES = {
|
|
35
|
+
accent: 'accent',
|
|
35
36
|
dark: 'dark',
|
|
37
|
+
error: 'error',
|
|
36
38
|
gray: 'gray',
|
|
39
|
+
information: 'information',
|
|
37
40
|
light: 'light',
|
|
41
|
+
negative: 'negative',
|
|
42
|
+
neutral: 'neutral',
|
|
38
43
|
success: 'success',
|
|
39
|
-
|
|
40
|
-
warning: 'warning',
|
|
41
|
-
information: 'information'
|
|
44
|
+
warning: 'warning'
|
|
42
45
|
};
|
|
43
46
|
|
|
44
47
|
export const DEFAULT_PROPS = {
|
|
@@ -10,27 +10,28 @@ import MenuTypes from './proptypes';
|
|
|
10
10
|
import styles from './styles';
|
|
11
11
|
|
|
12
12
|
const UTMenu = ({
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
autoCompletePlaceholder,
|
|
14
|
+
avoidOverlappingAnchor = true,
|
|
15
15
|
children,
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
disabled,
|
|
17
|
+
filterOptions = true,
|
|
18
18
|
fullWidth,
|
|
19
|
-
verticalOffset = 0,
|
|
20
19
|
horizontalOffset = 0,
|
|
21
|
-
|
|
22
|
-
disabled,
|
|
23
|
-
withoutOpacity,
|
|
24
|
-
styles: propStyles,
|
|
25
|
-
MenuOptionComponent = MenuOption,
|
|
20
|
+
isMultiple,
|
|
26
21
|
ItemSeparatorComponent,
|
|
27
22
|
ListEmptyComponent,
|
|
28
23
|
maxHeight,
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
MenuOptionComponent = MenuOption,
|
|
25
|
+
onClose,
|
|
26
|
+
onOpen,
|
|
27
|
+
onPress,
|
|
31
28
|
onQueryChange,
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
options = [],
|
|
30
|
+
selectedOption,
|
|
31
|
+
styles: propStyles,
|
|
32
|
+
verticalOffset = 0,
|
|
33
|
+
withAutocomplete,
|
|
34
|
+
withoutOpacity
|
|
34
35
|
}) => {
|
|
35
36
|
const [isOpen, setIsOpen] = useState(false);
|
|
36
37
|
const anchorRef = useRef(null);
|
|
@@ -70,8 +71,12 @@ const UTMenu = ({
|
|
|
70
71
|
let left = x + horizontalOffset;
|
|
71
72
|
|
|
72
73
|
if (top + menuHeight + height / 2 > usableWindowHeight) {
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
if (avoidOverlappingAnchor) {
|
|
75
|
+
const upPosition = y - menuHeight - verticalOffset;
|
|
76
|
+
top = upPosition > 0 ? upPosition : top - (top + menuHeight - usableWindowHeight + height / 2);
|
|
77
|
+
} else {
|
|
78
|
+
top = usableWindowHeight - menuHeight - 10;
|
|
79
|
+
}
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
if (left - width + menuWidth > windowWidth) {
|
|
@@ -79,7 +84,15 @@ const UTMenu = ({
|
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
setPosition({ top, left });
|
|
82
|
-
}, [
|
|
87
|
+
}, [
|
|
88
|
+
anchorMeasure,
|
|
89
|
+
avoidOverlappingAnchor,
|
|
90
|
+
horizontalOffset,
|
|
91
|
+
menuDimentions,
|
|
92
|
+
usableWindowHeight,
|
|
93
|
+
verticalOffset,
|
|
94
|
+
windowWidth
|
|
95
|
+
]);
|
|
83
96
|
|
|
84
97
|
const openMenu = () => {
|
|
85
98
|
Keyboard.dismiss();
|
package/package.json
CHANGED