react-native-molecules 0.5.0-beta.20 → 0.5.0-beta.22

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.
Files changed (59) hide show
  1. package/components/Card/Card.tsx +1 -1
  2. package/components/Checkbox/CheckboxBase.ios.tsx +9 -16
  3. package/components/Checkbox/CheckboxBase.tsx +11 -18
  4. package/components/DateField/DateField.tsx +4 -3
  5. package/components/DatePicker/DateCalendar.tsx +4 -4
  6. package/components/DatePicker/DatePickerModal.tsx +35 -23
  7. package/components/DatePicker/DatePickerProvider.tsx +8 -2
  8. package/components/DatePicker/context.tsx +2 -1
  9. package/components/DatePicker/index.tsx +1 -0
  10. package/components/DatePickerInline/DatePickerDockedHeader.tsx +11 -7
  11. package/components/DatePickerInline/DatePickerInline.tsx +1 -1
  12. package/components/DatePickerInline/DatePickerInlineBase.tsx +3 -3
  13. package/components/DatePickerInline/DatePickerInlineHeader.tsx +50 -20
  14. package/components/DatePickerInline/DayNames.tsx +13 -10
  15. package/components/DatePickerInline/HeaderItem.tsx +2 -2
  16. package/components/DatePickerInline/Month.tsx +4 -3
  17. package/components/DatePickerInline/MonthPicker.tsx +74 -54
  18. package/components/DatePickerInline/Swiper.native.tsx +2 -2
  19. package/components/DatePickerInline/Swiper.tsx +3 -3
  20. package/components/DatePickerInline/YearPicker.tsx +136 -112
  21. package/components/DatePickerInline/{DatePickerContext.tsx → store.tsx} +7 -3
  22. package/components/DatePickerInline/types.ts +4 -3
  23. package/components/Divider/Divider.tsx +192 -0
  24. package/components/Divider/index.tsx +11 -0
  25. package/components/Drawer/DrawerItemGroup.tsx +3 -7
  26. package/components/IconButton/IconButton.tsx +2 -12
  27. package/components/List/List.tsx +507 -0
  28. package/components/List/context.tsx +28 -0
  29. package/components/List/index.ts +9 -0
  30. package/components/List/types.ts +149 -0
  31. package/components/{ListItem → List}/utils.ts +47 -50
  32. package/components/Menu/Menu.tsx +156 -12
  33. package/components/Menu/index.tsx +11 -7
  34. package/components/Menu/utils.ts +21 -70
  35. package/components/RadioButton/RadioButtonAndroid.tsx +38 -54
  36. package/components/RadioButton/RadioButtonIOS.tsx +2 -16
  37. package/components/Select/Select.tsx +139 -497
  38. package/components/Select/context.tsx +14 -32
  39. package/components/Select/types.ts +44 -53
  40. package/components/Select/utils.ts +15 -47
  41. package/components/Text/textFactory.tsx +17 -5
  42. package/components/TimeField/TimeField.tsx +1 -1
  43. package/components/TimePicker/TimeInput.tsx +2 -7
  44. package/components/TimePicker/TimePickerModal.tsx +15 -15
  45. package/components/TimePicker/utils.ts +0 -4
  46. package/components/TouchableRipple/TouchableRipple.native.tsx +36 -5
  47. package/components/TouchableRipple/TouchableRipple.tsx +53 -19
  48. package/components/TouchableRipple/rippleFromForegroundColor.ts +21 -0
  49. package/package.json +4 -2
  50. package/components/HorizontalDivider/HorizontalDivider.tsx +0 -103
  51. package/components/HorizontalDivider/index.tsx +0 -9
  52. package/components/ListItem/ListItem.tsx +0 -138
  53. package/components/ListItem/ListItemDescription.tsx +0 -25
  54. package/components/ListItem/ListItemTitle.tsx +0 -25
  55. package/components/ListItem/index.tsx +0 -14
  56. package/components/Menu/MenuDivider.tsx +0 -13
  57. package/components/Menu/MenuItem.tsx +0 -128
  58. package/components/VerticalDivider/VerticalDivider.tsx +0 -100
  59. package/components/VerticalDivider/index.tsx +0 -9
@@ -1,6 +1,7 @@
1
- import { forwardRef, memo, type ReactNode, useCallback, useMemo, useRef } from 'react';
1
+ import { forwardRef, memo, type ReactNode, useCallback, useRef } from 'react';
2
2
  import {
3
3
  type GestureResponderEvent,
4
+ Platform,
4
5
  Pressable,
5
6
  type PressableProps,
6
7
  type StyleProp,
@@ -9,7 +10,9 @@ import {
9
10
  } from 'react-native';
10
11
  import { StyleSheet } from 'react-native-unistyles';
11
12
 
13
+ import { useTheme } from '../../hooks/useTheme';
12
14
  import { Slot } from '../Slot';
15
+ import { rippleColorFromBackground } from './rippleFromForegroundColor';
13
16
  import { touchableRippleStyles } from './utils';
14
17
 
15
18
  export type Props = PressableProps & {
@@ -46,6 +49,11 @@ export type Props = PressableProps & {
46
49
  * Color of the underlay for the highlight effect (Android < 5.0 and iOS).
47
50
  */
48
51
  underlayColor?: string;
52
+ /**
53
+ * Alpha used for auto-derived ripple color when `rippleColor` is not provided.
54
+ * @default 0.24
55
+ */
56
+ rippleAlpha?: number;
49
57
  /**
50
58
  * Content of the `TouchableRipple`.
51
59
  */
@@ -114,6 +122,7 @@ const TouchableRipple = (
114
122
  disabled: disabledProp,
115
123
  rippleColor: rippleColorProp,
116
124
  underlayColor: _underlayColor,
125
+ rippleAlpha = 0.24,
117
126
  onPress,
118
127
  children,
119
128
  onPressIn: onPressInProp,
@@ -126,24 +135,27 @@ const TouchableRipple = (
126
135
  ) => {
127
136
  // TODO - enable ripple onLongPress, need to check for mobile as well
128
137
  const disabled = disabledProp;
138
+ const theme = useTheme();
129
139
 
130
140
  const componentStyles = touchableRippleStyles;
131
141
 
132
- const { rippleColor, containerStyle } = useMemo(() => {
133
- const { rippleColor: defaultRippleColor } = componentStyles.root;
134
-
135
- return {
136
- rippleColor: rippleColorProp || defaultRippleColor,
137
- containerStyle: [
138
- styles.touchable,
139
- { borderRadius: 'inherit' },
140
- borderless && styles.borderless,
141
- // ...(Platform.OS === 'web' && !disabled ? ({ cursor: 'pointer' } as any) : {}),
142
- componentStyles.root,
143
- style,
144
- ],
145
- };
146
- }, [borderless, componentStyles.root, rippleColorProp, style]);
142
+ const { rippleColor: themeRippleFallback } = componentStyles.root;
143
+
144
+ const tokenResolvedColor =
145
+ typeof rippleColorProp === 'string'
146
+ ? theme.colors[rippleColorProp as keyof typeof theme.colors]
147
+ : undefined;
148
+
149
+ const rippleColorResolvedProp =
150
+ typeof tokenResolvedColor === 'string' ? tokenResolvedColor : rippleColorProp;
151
+ const containerStyle = [
152
+ styles.touchable,
153
+ { borderRadius: 'inherit' },
154
+ borderless && styles.borderless,
155
+ // ...(Platform.OS === 'web' && !disabled ? ({ cursor: 'pointer' } as any) : {}),
156
+ componentStyles.root,
157
+ style,
158
+ ];
147
159
 
148
160
  // Track whether pointer is currently down for handling pointer leave
149
161
  const isPointerDownRef = useRef(false);
@@ -165,6 +177,16 @@ const TouchableRipple = (
165
177
  const computedStyle = window.getComputedStyle(button);
166
178
  const dimensions = button.getBoundingClientRect();
167
179
 
180
+ const resolvedRippleColor =
181
+ rippleColorResolvedProp ??
182
+ (Platform.OS === 'web'
183
+ ? rippleColorFromBackground(
184
+ computedStyle.backgroundColor,
185
+ String(themeRippleFallback),
186
+ rippleAlpha,
187
+ )
188
+ : String(themeRippleFallback));
189
+
168
190
  let touchX: number;
169
191
  let touchY: number;
170
192
 
@@ -225,7 +247,7 @@ const TouchableRipple = (
225
247
  Object.assign(ripple.style, {
226
248
  position: 'absolute',
227
249
  pointerEvents: 'none',
228
- backgroundColor: rippleColor,
250
+ backgroundColor: resolvedRippleColor,
229
251
  borderRadius: '50%',
230
252
 
231
253
  /* Transition configuration */
@@ -261,7 +283,14 @@ const TouchableRipple = (
261
283
  });
262
284
  });
263
285
  },
264
- [onPressInProp, disabled, centered, rippleColor],
286
+ [
287
+ onPressInProp,
288
+ disabled,
289
+ centered,
290
+ rippleColorResolvedProp,
291
+ themeRippleFallback,
292
+ rippleAlpha,
293
+ ],
265
294
  );
266
295
 
267
296
  const fadeOutRipples = useCallback((target: HTMLElement) => {
@@ -345,9 +374,14 @@ const TouchableRipple = (
345
374
  onPointerCancel: handlePointerCancel,
346
375
  };
347
376
 
377
+ const accessibilityRoleProp = (rest as { accessibilityRole?: unknown }).accessibilityRole;
378
+ const roleProp = (rest as { role?: unknown }).role;
379
+ const applyDefaultWebButtonRole =
380
+ !!onPress && accessibilityRoleProp === undefined && roleProp === undefined;
381
+
348
382
  return (
349
383
  <Component
350
- {...(onPress ? { role: 'button' } : {})}
384
+ {...(applyDefaultWebButtonRole ? { role: 'button' } : {})}
351
385
  {...rest}
352
386
  style={containerStyle}
353
387
  ref={ref}
@@ -0,0 +1,21 @@
1
+ import setColor from 'color';
2
+
3
+ /** Ripple ink derived from background color for better contrast. */
4
+ export function rippleColorFromBackground(
5
+ backgroundColor: string | undefined,
6
+ fallback: string,
7
+ alpha: number = 0.24,
8
+ ): string {
9
+ if (!backgroundColor || backgroundColor === '') {
10
+ return fallback;
11
+ }
12
+ try {
13
+ const base = setColor(backgroundColor);
14
+ if (base.alpha() < 0.05) {
15
+ return fallback;
16
+ }
17
+ return base.isLight() ? `rgba(0, 0, 0, ${alpha})` : `rgba(255, 255, 255, ${alpha})`;
18
+ } catch {
19
+ return fallback;
20
+ }
21
+ }
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "react-native-molecules",
3
- "version": "0.5.0-beta.20",
3
+ "version": "0.5.0-beta.22",
4
4
  "author": "Thet Aung <thetaung.dev@gmail.com>",
5
5
  "license": "MIT",
6
6
  "main": "index.ts",
7
7
  "sideEffects": [
8
8
  "components/DatePicker/context.tsx",
9
+ "components/DatePickerInline/store.tsx",
10
+ "components/List/context.tsx",
9
11
  "components/Select/context.tsx",
10
12
  "components/TimePicker/context.tsx"
11
13
  ],
@@ -78,7 +80,7 @@
78
80
  "react-native": "0.81.4",
79
81
  "react-native-builder-bob": "^0.17.1",
80
82
  "react-native-reanimated": "~4.1.1",
81
- "react-native-unistyles": "^3.0.22",
83
+ "react-native-unistyles": "^3.2.4",
82
84
  "react-native-web": "~0.21.1"
83
85
  },
84
86
  "eslintIgnore": [
@@ -1,103 +0,0 @@
1
- import { memo } from 'react';
2
- import { type StyleProp, View, type ViewProps, type ViewStyle } from 'react-native';
3
- import { StyleSheet } from 'react-native-unistyles';
4
-
5
- import { getRegisteredComponentStylesWithFallback } from '../../core';
6
-
7
- export type Props = Omit<ViewProps, 'children'> & {
8
- /**
9
- * left inset of the divider.
10
- */
11
- leftInset?: number;
12
- /**
13
- * right inset of the divider.
14
- */
15
- rightInset?: number;
16
- /**
17
- * Whether divider should be bolded.
18
- */
19
- bold?: boolean;
20
- /**
21
- * Vertical spacing of the Divider
22
- */
23
- spacing?: number;
24
- style?: StyleProp<ViewStyle>;
25
- };
26
-
27
- /**
28
- * A divider is a thin, lightweight separator that groups content in lists and page layouts.
29
- *
30
- * <div class="screenshots">
31
- * <figure>
32
- * <img class="medium" src="screenshots/divider.png" />
33
- * </figure>
34
- * </div>
35
- *
36
- * ## Usage
37
- * ```js
38
- * import * as React from 'react';
39
- * import { View } from 'react-native';
40
- * import { Divider, Text } from 'react-native-paper';
41
- *
42
- * const MyComponent = () => (
43
- * <View>
44
- * <Text>Lemon</Text>
45
- * <Divider />
46
- * <Text>Mango</Text>
47
- * <Divider />
48
- * </View>
49
- * );
50
- *
51
- * export default MyComponent;
52
- * ```
53
- */
54
-
55
- const HorizontalDivider = ({
56
- leftInset = 0,
57
- rightInset = 0,
58
- style,
59
- bold = false,
60
- spacing = 0,
61
- ...rest
62
- }: Props) => {
63
- horizontalDividerStyles.useVariants({
64
- isBold: bold,
65
- });
66
-
67
- return (
68
- <View
69
- {...rest}
70
- style={
71
- [
72
- horizontalDividerStyles.root,
73
- leftInset && { marginLeft: leftInset },
74
- rightInset && { marginRight: rightInset },
75
- spacing && { marginVertical: spacing },
76
- style,
77
- ] as StyleProp<ViewStyle>
78
- }
79
- />
80
- );
81
- };
82
-
83
- export const horizontalDividerStylesDefault = StyleSheet.create(theme => ({
84
- root: {
85
- height: StyleSheet.hairlineWidth,
86
- background: theme.colors.outlineVariant,
87
-
88
- variants: {
89
- isBold: {
90
- true: {
91
- height: 1,
92
- },
93
- },
94
- },
95
- },
96
- }));
97
-
98
- export const horizontalDividerStyles = getRegisteredComponentStylesWithFallback(
99
- 'HorizontalDivider',
100
- horizontalDividerStylesDefault,
101
- );
102
-
103
- export default memo(HorizontalDivider);
@@ -1,9 +0,0 @@
1
- import { getRegisteredComponentWithFallback } from '../../core';
2
- import HorizontalDividerDefault from './HorizontalDivider';
3
-
4
- export const HorizontalDivider = getRegisteredComponentWithFallback(
5
- 'HorizontalDivider',
6
- HorizontalDividerDefault,
7
- );
8
-
9
- export { type Props as HorizontalDividerProps, horizontalDividerStyles } from './HorizontalDivider';
@@ -1,138 +0,0 @@
1
- import { createContext, forwardRef, memo, type ReactNode, useMemo } from 'react';
2
- import { type StyleProp, View, type ViewStyle } from 'react-native';
3
-
4
- import { useActionState } from '../../hooks';
5
- import type { WithElements } from '../../types';
6
- import { resolveStateVariant } from '../../utils';
7
- import { HorizontalDivider } from '../HorizontalDivider';
8
- import { StateLayer } from '../StateLayer';
9
- import { TouchableRipple, type TouchableRippleProps } from '../TouchableRipple';
10
- import { listItemStyles } from './utils';
11
-
12
- export type Props = Omit<TouchableRippleProps, 'children'> &
13
- WithElements<ReactNode | ((renderArgs: { hovered: boolean }) => ReactNode)> & {
14
- hovered?: boolean;
15
- /**
16
- * Description text for the list item or callback which returns a React element to display the description.
17
- */
18
- children: ReactNode;
19
- /**
20
- * Style that is passed to the wrapping TouchableRipple element.
21
- */
22
- style?: StyleProp<ViewStyle>;
23
- /**
24
- * Whether the divider shows or not.
25
- */
26
- divider?: boolean;
27
- /**
28
- * variant of the ListItem
29
- */
30
- variant?: 'default' | 'menuItem';
31
- /**
32
- * Whether the ListItem is selected or not
33
- */
34
- selected?: boolean;
35
- /**
36
- * Whether the ListItem is hoverable or not
37
- * @default true if onPress is passed
38
- */
39
- hoverable?: boolean;
40
- contentStyle?: StyleProp<ViewStyle>;
41
- };
42
-
43
- const ListItem = (
44
- {
45
- left,
46
- right,
47
- children,
48
- style: styleProp,
49
- disabled = false,
50
- divider = false,
51
- variant = 'default',
52
- selected = false,
53
- onPress,
54
- hoverable: hoverableProp = false,
55
- hovered: hoveredProp = false,
56
- contentStyle: contentStyleProp,
57
- ...props
58
- }: Props,
59
- ref: any,
60
- ) => {
61
- const { hovered: _hovered, actionsRef } = useActionState({ ref, actionsToListen: ['hover'] });
62
- const hoverable = hoverableProp || !!onPress;
63
- const hovered = hoveredProp || _hovered;
64
-
65
- const state = resolveStateVariant({
66
- selected,
67
- disabled,
68
- hovered: hoverable && hovered,
69
- }) as any;
70
-
71
- listItemStyles.useVariants({
72
- state,
73
- variant: variant as any,
74
- });
75
-
76
- const {
77
- containerStyles,
78
- innerContainerStyle,
79
- contentStyle,
80
- leftElementStyle,
81
- rightElementStyle,
82
- } = useMemo(() => {
83
- const { innerContainer, content, leftElement, rightElement } = listItemStyles;
84
- return {
85
- containerStyles: [listItemStyles.root, styleProp],
86
- innerContainerStyle: innerContainer,
87
- contentStyle: content,
88
- leftElementStyle: leftElement,
89
- rightElementStyle: rightElement,
90
- };
91
- // eslint-disable-next-line react-hooks/exhaustive-deps
92
- }, [styleProp, state, variant]);
93
-
94
- const contextValue = useMemo(
95
- () => ({ disabled, hovered: hoverable && hovered, selected, variant }),
96
- [disabled, hoverable, hovered, selected, variant],
97
- );
98
-
99
- return (
100
- <TouchableRipple
101
- {...props}
102
- style={containerStyles}
103
- disabled={disabled}
104
- onPress={onPress}
105
- ref={actionsRef}>
106
- <>
107
- <View style={innerContainerStyle}>
108
- {left ? (
109
- <View style={leftElementStyle}>
110
- {typeof left === 'function' ? left({ hovered }) : left}
111
- </View>
112
- ) : null}
113
- <View style={[contentStyle, contentStyleProp]}>
114
- <ListItemContext.Provider value={contextValue}>
115
- <>{children}</>
116
- </ListItemContext.Provider>
117
- </View>
118
- {right ? (
119
- <View style={rightElementStyle}>
120
- {typeof right === 'function' ? right({ hovered }) : right}
121
- </View>
122
- ) : null}
123
- </View>
124
- {divider && <HorizontalDivider />}
125
- <StateLayer style={listItemStyles.stateLayer} />
126
- </>
127
- </TouchableRipple>
128
- );
129
- };
130
-
131
- export const ListItemContext = createContext({
132
- disabled: false,
133
- hovered: false,
134
- selected: false,
135
- variant: 'default',
136
- });
137
-
138
- export default memo(forwardRef(ListItem));
@@ -1,25 +0,0 @@
1
- import { memo, useContext } from 'react';
2
- import { type TextProps } from 'react-native';
3
-
4
- import { resolveStateVariant } from '../../utils';
5
- import { Text } from '../Text';
6
- import { ListItemContext } from './ListItem';
7
- import { listItemDescriptionStyles } from './utils';
8
-
9
- type Props = TextProps & {};
10
-
11
- const ListItemDescription = ({ style, ...rest }: Props) => {
12
- const { disabled, hovered, variant } = useContext(ListItemContext);
13
-
14
- listItemDescriptionStyles.useVariants({
15
- state: resolveStateVariant({
16
- disabled,
17
- hovered,
18
- }) as any,
19
- variant: variant as any,
20
- });
21
-
22
- return <Text selectable={false} {...rest} style={[listItemDescriptionStyles.root, style]} />;
23
- };
24
-
25
- export default memo(ListItemDescription);
@@ -1,25 +0,0 @@
1
- import { memo, useContext } from 'react';
2
- import { type TextProps } from 'react-native';
3
-
4
- import { resolveStateVariant } from '../../utils';
5
- import { Text } from '../Text';
6
- import { ListItemContext } from './ListItem';
7
- import { listItemTitleStyles } from './utils';
8
-
9
- type Props = TextProps & {};
10
-
11
- const ListItemTitle = ({ style, ...rest }: Props) => {
12
- const { disabled, hovered, variant } = useContext(ListItemContext);
13
-
14
- listItemTitleStyles.useVariants({
15
- state: resolveStateVariant({
16
- disabled,
17
- hovered,
18
- }) as any,
19
- variant: variant as any,
20
- });
21
-
22
- return <Text selectable={false} {...rest} style={[listItemTitleStyles.root, style]} />;
23
- };
24
-
25
- export default memo(ListItemTitle);
@@ -1,14 +0,0 @@
1
- import { getRegisteredComponentWithFallback } from '../../core';
2
- import ListItemComponent from './ListItem';
3
- import ListItemDescription from './ListItemDescription';
4
- import ListItemTitle from './ListItemTitle';
5
-
6
- const ListItemDefault = Object.assign(ListItemComponent, {
7
- Title: ListItemTitle,
8
- Description: ListItemDescription,
9
- });
10
-
11
- export const ListItem = getRegisteredComponentWithFallback('ListItem', ListItemDefault);
12
-
13
- export type { Props as ListItemProps } from './ListItem';
14
- export { listItemDescriptionStyles, listItemStyles, listItemTitleStyles } from './utils';
@@ -1,13 +0,0 @@
1
- import { memo } from 'react';
2
-
3
- import { HorizontalDivider, type HorizontalDividerProps } from '../HorizontalDivider';
4
-
5
- export type Props = HorizontalDividerProps & {};
6
-
7
- const MenuDivider = memo(({ spacing = 8, ...rest }: Props) => {
8
- return <HorizontalDivider spacing={spacing} {...rest} />;
9
- });
10
-
11
- MenuDivider.displayName = 'Menu_Divider';
12
-
13
- export default MenuDivider;
@@ -1,128 +0,0 @@
1
- import { forwardRef, memo, type ReactNode, useCallback, useContext, useMemo } from 'react';
2
- import {
3
- type GestureResponderEvent,
4
- type StyleProp,
5
- Text,
6
- type TextProps,
7
- View,
8
- type ViewStyle,
9
- } from 'react-native';
10
-
11
- import { useActionState } from '../../hooks';
12
- import type { WithElements } from '../../types';
13
- import { resolveStateVariant } from '../../utils';
14
- import { StateLayer, type StateLayerProps } from '../StateLayer';
15
- import { TouchableRipple, type TouchableRippleProps } from '../TouchableRipple';
16
- import { MenuContext } from './Menu';
17
- import { menuItemStyles } from './utils';
18
-
19
- export type Props = TouchableRippleProps &
20
- WithElements<ReactNode> & {
21
- size?: 'default' | 'dense';
22
- stateLayerProps?: StateLayerProps;
23
- textProps?: Omit<TextProps, 'children'>;
24
- leftElementStyle?: StyleProp<ViewStyle>;
25
- rightElementStyle?: StyleProp<ViewStyle>;
26
- };
27
-
28
- const emptyObj = {};
29
-
30
- const _MenuItem = (
31
- {
32
- onPress,
33
- left,
34
- right,
35
- children,
36
- disabled = false,
37
- size = 'default',
38
- style,
39
- testID,
40
- stateLayerProps,
41
- textProps = emptyObj,
42
- leftElementStyle: _leftElementStyle,
43
- rightElementStyle: _rightElementStyle,
44
- ...rest
45
- }: Props,
46
- ref: any,
47
- ) => {
48
- const { hovered, actionsRef } = useActionState({ ref, actionsToListen: ['hover'] });
49
-
50
- const { closeOnSelect, onClose } = useContext(MenuContext);
51
-
52
- const state = resolveStateVariant({
53
- disabled,
54
- hovered,
55
- });
56
-
57
- menuItemStyles.useVariants({
58
- size: size as any,
59
- state: state as any,
60
- });
61
-
62
- const onPressItem = useCallback(
63
- (e: GestureResponderEvent) => {
64
- if (closeOnSelect) onClose();
65
-
66
- onPress?.(e);
67
- },
68
- [closeOnSelect, onClose, onPress],
69
- );
70
-
71
- const { containerStyle, leftElementStyle, rightElementStyle, textStyle, stateLayerStyle } =
72
- useMemo(() => {
73
- const { text, leftElement, rightElement, stateLayer } = menuItemStyles;
74
-
75
- return {
76
- containerStyle: [menuItemStyles.root, style],
77
- textStyle: [text, textProps?.style],
78
- leftElementStyle: [leftElement, _leftElementStyle],
79
- rightElementStyle: [rightElement, _rightElementStyle],
80
- stateLayerStyle: stateLayer,
81
- };
82
- // eslint-disable-next-line react-hooks/exhaustive-deps
83
- }, [_leftElementStyle, _rightElementStyle, style, textProps?.style, state, size]);
84
-
85
- return (
86
- <TouchableRipple
87
- {...rest}
88
- testID={testID}
89
- style={containerStyle}
90
- disabled={disabled}
91
- onPress={onPressItem}
92
- ref={actionsRef}>
93
- <>
94
- {left ? (
95
- <View style={leftElementStyle} testID={testID ? `${testID}-left` : ''}>
96
- {left}
97
- </View>
98
- ) : null}
99
-
100
- <Text
101
- style={textStyle}
102
- numberOfLines={1}
103
- {...textProps}
104
- testID={testID ? `${testID}-text` : ''}>
105
- {children}
106
- </Text>
107
-
108
- {right ? (
109
- <View style={rightElementStyle} testID={testID ? `${testID}-right` : ''}>
110
- {right}
111
- </View>
112
- ) : null}
113
-
114
- <StateLayer
115
- testID={testID ? `${testID}-stateLayer` : ''}
116
- {...stateLayerProps}
117
- style={stateLayerStyle}
118
- />
119
- </>
120
- </TouchableRipple>
121
- );
122
- };
123
-
124
- const MenuItem = memo(forwardRef(_MenuItem));
125
-
126
- MenuItem.displayName = 'Menu_Item';
127
-
128
- export default MenuItem;