@widergy/mobile-ui 1.35.0 → 1.36.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 CHANGED
@@ -1,3 +1,17 @@
1
+ ## [1.36.1](https://github.com/widergy/mobile-ui/compare/v1.36.0...v1.36.1) (2025-02-12)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * fixes field label markdown ([#410](https://github.com/widergy/mobile-ui/issues/410)) ([df400b2](https://github.com/widergy/mobile-ui/commit/df400b2449a696ba4358f87f89296772f357d5ab))
7
+
8
+ # [1.36.0](https://github.com/widergy/mobile-ui/compare/v1.35.0...v1.36.0) (2025-02-03)
9
+
10
+
11
+ ### Features
12
+
13
+ * [EVENSA-67] uttabs ([#409](https://github.com/widergy/mobile-ui/issues/409)) ([e82a497](https://github.com/widergy/mobile-ui/commit/e82a49721c179c63fef5cbfe7d61eaed172476d0))
14
+
1
15
  # [1.35.0](https://github.com/widergy/mobile-ui/compare/v1.34.0...v1.35.0) (2025-01-31)
2
16
 
3
17
 
@@ -47,7 +47,7 @@ const UTRating = ({
47
47
  return (
48
48
  <View style={[styles.container, classNames.container]} data-testid={dataTestId}>
49
49
  {title && (
50
- <UTFieldLabel colorTheme="dark" required={required}>
50
+ <UTFieldLabel colorTheme="dark" required={required} withMarkdown>
51
51
  {title}
52
52
  </UTFieldLabel>
53
53
  )}
@@ -41,7 +41,7 @@ export default StyleSheet.create({
41
41
  alignItems: 'center',
42
42
  display: 'flex',
43
43
  gap: 24,
44
- width: '100%'
44
+ width: 'auto'
45
45
  },
46
46
  section: {
47
47
  alignItems: 'center',
@@ -0,0 +1,41 @@
1
+ # UTTabs
2
+
3
+ Tabs component.
4
+
5
+ ## Props
6
+ Here's a new table for the additional props:
7
+
8
+ | Name | Type | Default | Description |
9
+ |------------|---------|------------|-----------------------------------------------------------|
10
+ | colorTheme | string | `accent` | Defines the color theme for the component. |
11
+ | hierarchy | string | `primary` | Determines the hierarchy or importance of the tabs. |
12
+ | onChange | func | | Callback function triggered when the selected tab changes.|
13
+ | style | object | | Custom styles for component. |
14
+ | tabs | array | | Array of tab items to be displayed within the component. |
15
+ | withTabSliding | bool | `true` | Defines if tabs can be changed with gesture. |
16
+
17
+
18
+ ### colorTheme
19
+
20
+ The value of `colorTheme` must be one of the following:
21
+
22
+ - `accent`
23
+ - `negative`
24
+ - `neutral`
25
+
26
+ ### hierarchy
27
+
28
+ The value of `hierarchy` must be one of the following:
29
+
30
+ - `primary`
31
+ - `secondary`
32
+
33
+ ### tabs
34
+
35
+ `tabs` is an array of object with the following optional props:
36
+
37
+ - `label`: text to render
38
+ - `icon`: name of `UTIcon` to render
39
+ - `badge`: not affected by `colorTheme`
40
+
41
+ Besides those, any other prop can be added to a tab to be accessed with the `onChange` callback
@@ -0,0 +1,10 @@
1
+ export const HIERARCHIES = {
2
+ PRIMARY: 'primary',
3
+ SECONDARY: 'secondary'
4
+ };
5
+
6
+ export const COLOR_THEMES = {
7
+ ACCENT: 'accent',
8
+ NEGATIVE: 'negative',
9
+ NEUTRAL: 'neutral'
10
+ };
@@ -0,0 +1,86 @@
1
+ import { Animated, View, Pressable, PanResponder } from 'react-native';
2
+ import { array, bool, func, object, string } from 'prop-types';
3
+ import React, { useEffect, useRef, useState } from 'react';
4
+
5
+ import { withTheme } from '../../theming';
6
+ import UTBadge from '../UTBadge';
7
+ import UTIcon from '../UTIcon';
8
+ import UTLabel from '../UTLabel';
9
+
10
+ import styleSheet from './styles';
11
+ import { COLOR_THEMES, HIERARCHIES } from './constants';
12
+
13
+ const UTTabs = ({
14
+ colorTheme = COLOR_THEMES.ACCENT,
15
+ hierarchy = HIERARCHIES.SECONDARY,
16
+ onChange,
17
+ style,
18
+ tabs,
19
+ theme,
20
+ withTabSliding = true
21
+ }) => {
22
+ const styles = styleSheet(theme);
23
+ const [selectedTab, setSelectedTab] = useState(0);
24
+ const position = useRef(new Animated.Value(0)).current;
25
+
26
+ useEffect(() => {
27
+ onChange?.(tabs[selectedTab]);
28
+ }, []);
29
+
30
+ useEffect(() => {
31
+ Animated.timing(position, {
32
+ toValue: selectedTab,
33
+ duration: 300
34
+ }).start();
35
+ onChange?.(tabs[selectedTab]);
36
+ }, [selectedTab]);
37
+
38
+ const panResponder = useRef(
39
+ PanResponder.create({
40
+ onMoveShouldSetPanResponder: (_, gestureState) => Math.abs(gestureState.dx),
41
+ onPanResponderRelease: (_, gestureState) => {
42
+ if (gestureState.dx > 1) setSelectedTab(prev => Math.max(0, prev - 1));
43
+ else if (gestureState.dx < -1) {
44
+ setSelectedTab(prev => Math.min(tabs.length - 1, prev + 1));
45
+ }
46
+ }
47
+ })
48
+ ).current;
49
+
50
+ return (
51
+ <View style={[styles.container, style]} {...(withTabSliding ? panResponder.panHandlers : {})}>
52
+ {tabs.map(({ badge, label, icon }, index) => {
53
+ const selected = selectedTab === index;
54
+ const colorThemeToUse = selected ? colorTheme : 'gray';
55
+ return (
56
+ <Pressable
57
+ disabled={selected}
58
+ key={`tab-${label || icon}`}
59
+ onPress={() => setSelectedTab(index)}
60
+ style={styles.tab(tabs.length)}
61
+ >
62
+ <UTIcon colorTheme={colorThemeToUse} name={icon} />
63
+ <UTLabel colorTheme={colorThemeToUse} shade="04" weight="medium">
64
+ {label}
65
+ </UTLabel>
66
+ {badge && <UTBadge colorTheme="accent" />}
67
+ </Pressable>
68
+ );
69
+ })}
70
+ <Animated.View style={styles.indicator(position, tabs.length, hierarchy, colorTheme)} />
71
+ <View style={styles.border} />
72
+ </View>
73
+ );
74
+ };
75
+
76
+ UTTabs.propTypes = {
77
+ colorTheme: string,
78
+ hierarchy: string,
79
+ onChange: func,
80
+ style: object,
81
+ tabs: array,
82
+ theme: object,
83
+ withTabSliding: bool
84
+ };
85
+
86
+ export default withTheme(UTTabs);
@@ -0,0 +1,82 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ import { COLOR_THEMES, HIERARCHIES } from './constants';
4
+
5
+ export default StyleSheet.create(({ Palette: { accent, neutral, negative, light } }) => ({
6
+ border: {
7
+ position: 'absolute',
8
+ bottom: 0,
9
+ width: '100%',
10
+ height: 1,
11
+ backgroundColor: light['04'],
12
+ zIndex: 1
13
+ },
14
+ container: { display: 'flex', flexDirection: 'row', width: '100%' },
15
+ indicator: (position, length, hierarchy, colorTheme) =>
16
+ ({
17
+ [HIERARCHIES.PRIMARY]: {
18
+ position: 'absolute',
19
+ bottom: 0,
20
+ width: `${100 / length}%`,
21
+ height: '100%',
22
+ borderRightWidth: position.interpolate({
23
+ inputRange: [0, length - 1],
24
+ outputRange: [1, 0]
25
+ }),
26
+ borderTopRightRadius: position.interpolate({
27
+ inputRange: [0, length - 1],
28
+ outputRange: [4, 0]
29
+ }),
30
+ borderLeftWidth: position.interpolate({
31
+ inputRange: [0, 1],
32
+ outputRange: [0, 1],
33
+ extrapolate: 'clamp'
34
+ }),
35
+ borderTopLeftRadius: position.interpolate({
36
+ inputRange: [0, 1],
37
+ outputRange: [0, 4],
38
+ extrapolate: 'clamp'
39
+ }),
40
+ backgroundColor: light['01'],
41
+ borderTopWidth: 1,
42
+ borderTopColor: light['04'],
43
+ borderLeftColor: light['04'],
44
+ borderRightColor: light['04'],
45
+ borderBottomWidth: 1,
46
+ borderBottomColor: light['01'],
47
+ left: position.interpolate({
48
+ inputRange: [0, length],
49
+ outputRange: ['0%', '100%']
50
+ }),
51
+ zIndex: 2
52
+ },
53
+ [HIERARCHIES.SECONDARY]: {
54
+ position: 'absolute',
55
+ bottom: 0,
56
+ width: `${100 / length}%`,
57
+ height: 4,
58
+ backgroundColor: {
59
+ [COLOR_THEMES.ACCENT]: accent['04'],
60
+ [COLOR_THEMES.NEUTRAL]: neutral['04'],
61
+ [COLOR_THEMES.NEGATIVE]: negative['04']
62
+ }[colorTheme],
63
+ left: position.interpolate({
64
+ inputRange: [0, length],
65
+ outputRange: ['0%', '100%']
66
+ })
67
+ }
68
+ })[hierarchy],
69
+ tab:
70
+ tabs =>
71
+ ({ pressed }) => ({
72
+ alignItems: 'center',
73
+ display: 'flex',
74
+ flexBasis: `${100 / tabs}%`,
75
+ flexDirection: 'row',
76
+ gap: 8,
77
+ height: 48,
78
+ justifyContent: 'center',
79
+ zIndex: 3,
80
+ backgroundColor: pressed ? accent['01'] : null
81
+ })
82
+ }));
package/lib/index.js CHANGED
@@ -65,6 +65,7 @@ export { default as UTSelectableCard } from './components/UTSelectableCard';
65
65
  export { default as UTStatusMessage } from './components/UTStatusMessage';
66
66
  export { default as UTStepFeedback } from './components/UTStepFeedback';
67
67
  export { default as UTSwitch } from './components/UTSwitch';
68
+ export { default as UTTabs } from './components/UTTabs';
68
69
  export { default as UTTextArea } from './components/UTTextArea';
69
70
  export { default as UTTextInput } from './components/UTTextInput';
70
71
  export { default as UTTooltip } from './components/UTTooltip';
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@widergy/mobile-ui",
3
3
  "description": "Widergy Mobile Components",
4
4
  "author": "widergy",
5
- "version": "1.35.0",
5
+ "version": "1.36.1",
6
6
  "repository": "https://github.com/widergy/mobile-ui.git",
7
7
  "main": "lib/index.js",
8
8
  "files": [