Skip to content

Commit 36ce39b

Browse files
authored
fix: resolve circular dependencies (#4056)
1 parent 634107f commit 36ce39b

File tree

6 files changed

+111
-72
lines changed

6 files changed

+111
-72
lines changed

src/components/Appbar/Appbar.tsx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@ import {
1111

1212
import color from 'color';
1313

14-
import AppbarAction from './AppbarAction';
15-
import AppbarBackAction from './AppbarBackAction';
1614
import AppbarContent from './AppbarContent';
17-
import AppbarHeader from './AppbarHeader';
1815
import {
1916
AppbarModes,
2017
DEFAULT_APPBAR_HEIGHT,
@@ -287,14 +284,14 @@ const Appbar = ({
287284
children,
288285
isDark,
289286
isV3,
290-
renderOnly: [AppbarBackAction],
287+
renderOnly: ['Appbar.BackAction'],
291288
mode,
292289
})}
293290
{renderAppbarContent({
294291
children: filterAppbarActions(true),
295292
isDark,
296293
isV3,
297-
renderOnly: [AppbarAction],
294+
renderOnly: ['Appbar.Action'],
298295
mode,
299296
})}
300297
{/* Right side of row container, can contain other AppbarAction if they are not leading icons */}
@@ -304,10 +301,10 @@ const Appbar = ({
304301
isDark,
305302
isV3,
306303
renderExcept: [
307-
Appbar,
308-
AppbarBackAction,
309-
AppbarContent,
310-
AppbarHeader,
304+
'Appbar',
305+
'Appbar.BackAction',
306+
'Appbar.Content',
307+
'Appbar.Header',
311308
],
312309
mode,
313310
})}
@@ -318,7 +315,7 @@ const Appbar = ({
318315
children,
319316
isDark,
320317
isV3,
321-
renderOnly: [AppbarContent],
318+
renderOnly: ['Appbar.Content'],
322319
mode,
323320
})}
324321
</View>

src/components/Appbar/utils.ts

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@ import React from 'react';
22
import type { ColorValue, StyleProp, ViewStyle } from 'react-native';
33
import { StyleSheet, Animated } from 'react-native';
44

5-
import AppbarAction from './AppbarAction';
6-
import AppbarBackAction from './AppbarBackAction';
7-
import AppbarContent from './AppbarContent';
85
import overlay from '../../styles/overlay';
96
import { black, white } from '../../styles/themes/v2/colors';
107
import type { InternalTheme, ThemeProp } from '../../types';
11-
import Tooltip from '../Tooltip/Tooltip';
128

139
export type AppbarModes = 'small' | 'medium' | 'large' | 'center-aligned';
1410

@@ -93,8 +89,9 @@ type BaseProps = {
9389
type RenderAppbarContentProps = BaseProps & {
9490
children: React.ReactNode;
9591
shouldCenterContent?: boolean;
96-
renderOnly?: (React.ComponentType<any> | false)[];
97-
renderExcept?: React.ComponentType<any>[];
92+
isV3: boolean;
93+
renderOnly?: (string | boolean)[];
94+
renderExcept?: string[];
9895
mode?: AppbarModes;
9996
theme?: ThemeProp;
10097
};
@@ -126,50 +123,56 @@ export const renderAppbarContent = ({
126123
mode = 'small',
127124
theme,
128125
}: RenderAppbarContentProps) => {
129-
return (
130-
React.Children.toArray(children as React.ReactNode | React.ReactNode[])
131-
.filter((child) => child != null && typeof child !== 'boolean')
132-
.filter((child) =>
133-
// @ts-expect-error: TypeScript complains about the type of type but it doesn't matter
134-
renderExcept ? !renderExcept.includes(child.type) : child
135-
)
126+
return React.Children.toArray(children as React.ReactNode | React.ReactNode[])
127+
.filter((child) => child != null && typeof child !== 'boolean')
128+
.filter((child) =>
129+
// @ts-expect-error: TypeScript complains about the type of type but it doesn't matter
130+
renderExcept ? !renderExcept.includes(child.type.displayName) : child
131+
)
132+
.filter((child) =>
133+
// @ts-expect-error: TypeScript complains about the type of type but it doesn't matter
134+
renderOnly ? renderOnly.includes(child.type.displayName) : child
135+
)
136+
.map((child, i) => {
137+
if (
138+
!React.isValidElement(child) ||
139+
![
140+
'Appbar.Content',
141+
'Appbar.Action',
142+
'Appbar.BackAction',
143+
'Tooltip',
144+
].includes(
145+
// @ts-expect-error: TypeScript complains about the type of type but it doesn't matter
146+
child.type.displayName
147+
)
148+
) {
149+
return child;
150+
}
151+
152+
const props: {
153+
color?: string;
154+
style?: StyleProp<ViewStyle>;
155+
mode?: AppbarModes;
156+
theme?: ThemeProp;
157+
} = {
158+
theme,
159+
color: getAppbarColor({ color: child.props.color, isDark, isV3 }),
160+
};
161+
136162
// @ts-expect-error: TypeScript complains about the type of type but it doesn't matter
137-
.filter((child) => (renderOnly ? renderOnly.includes(child.type) : child))
138-
.map((child, i) => {
139-
if (
140-
!React.isValidElement(child) ||
141-
![AppbarContent, AppbarAction, AppbarBackAction, Tooltip].includes(
142-
// @ts-expect-error: TypeScript complains about the type of type but it doesn't matter
143-
child.type
144-
)
145-
) {
146-
return child;
147-
}
148-
149-
const props: {
150-
color?: string;
151-
style?: StyleProp<ViewStyle>;
152-
mode?: AppbarModes;
153-
theme?: ThemeProp;
154-
} = {
155-
theme,
156-
color: getAppbarColor({ color: child.props.color, isDark, isV3 }),
157-
};
158-
159-
if (child.type === AppbarContent) {
160-
props.mode = mode;
161-
props.style = [
162-
isV3
163-
? i === 0 && !shouldCenterContent && styles.v3Spacing
164-
: i !== 0 && styles.v2Spacing,
165-
shouldCenterContent && styles.centerAlignedContent,
166-
child.props.style,
167-
];
168-
props.color;
169-
}
170-
return React.cloneElement(child, props);
171-
})
172-
);
163+
if (child.type.displayName === 'Appbar.Content') {
164+
props.mode = mode;
165+
props.style = [
166+
isV3
167+
? i === 0 && !shouldCenterContent && styles.v3Spacing
168+
: i !== 0 && styles.v2Spacing,
169+
shouldCenterContent && styles.centerAlignedContent,
170+
child.props.style,
171+
];
172+
props.color;
173+
}
174+
return React.cloneElement(child, props);
175+
});
173176
};
174177

175178
const styles = StyleSheet.create({

src/components/TextInput/types.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as React from 'react';
12
import type {
23
TextInput as NativeTextInput,
34
Animated,
@@ -6,13 +7,44 @@ import type {
67
ColorValue,
78
StyleProp,
89
ViewProps,
10+
ViewStyle,
911
} from 'react-native';
1012

1113
import type { $Omit, InternalTheme, ThemeProp } from './../../types';
12-
import type { Props as TextInputProps } from './TextInput';
1314

1415
export type TextInputLabelProp = string | React.ReactElement;
1516

17+
type TextInputProps = React.ComponentPropsWithRef<typeof NativeTextInput> & {
18+
mode?: 'flat' | 'outlined';
19+
left?: React.ReactNode;
20+
right?: React.ReactNode;
21+
disabled?: boolean;
22+
label?: TextInputLabelProp;
23+
placeholder?: string;
24+
error?: boolean;
25+
onChangeText?: Function;
26+
selectionColor?: string;
27+
cursorColor?: string;
28+
underlineColor?: string;
29+
activeUnderlineColor?: string;
30+
outlineColor?: string;
31+
activeOutlineColor?: string;
32+
textColor?: string;
33+
dense?: boolean;
34+
multiline?: boolean;
35+
numberOfLines?: number;
36+
onFocus?: (args: any) => void;
37+
onBlur?: (args: any) => void;
38+
render?: (props: RenderProps) => React.ReactNode;
39+
value?: string;
40+
style?: StyleProp<TextStyle>;
41+
theme?: ThemeProp;
42+
testID?: string;
43+
contentStyle?: StyleProp<TextStyle>;
44+
outlineStyle?: StyleProp<ViewStyle>;
45+
underlineStyle?: StyleProp<ViewStyle>;
46+
};
47+
1648
export type RenderProps = {
1749
ref: (a?: NativeTextInput | null) => void;
1850
onChangeText?: (a: string) => void;

src/components/Tooltip/Tooltip.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ const Tooltip = ({
212212
);
213213
};
214214

215+
Tooltip.displayName = 'Tooltip';
216+
215217
const styles = StyleSheet.create({
216218
tooltip: {
217219
alignSelf: 'flex-start',

src/components/__tests__/Appbar/Appbar.test.tsx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ import { getTheme } from '../../../core/theming';
99
import overlay from '../../../styles/overlay';
1010
import { tokens } from '../../../styles/themes/v3/tokens';
1111
import Appbar from '../../Appbar';
12-
import AppbarAction from '../../Appbar/AppbarAction';
13-
import AppbarBackAction from '../../Appbar/AppbarBackAction';
14-
import AppbarContent from '../../Appbar/AppbarContent';
15-
import AppbarHeader from '../../Appbar/AppbarHeader';
1612
import {
1713
getAppbarBackgroundColor,
1814
modeTextVariant,
@@ -86,7 +82,12 @@ describe('renderAppbarContent', () => {
8682
</Menu>,
8783
],
8884
isDark: false,
89-
renderExcept: [Appbar, AppbarHeader, AppbarBackAction, AppbarContent],
85+
renderExcept: [
86+
'Appbar',
87+
'Appbar.Header',
88+
'Appbar.BackAction',
89+
'Appbar.Content',
90+
],
9091
});
9192

9293
expect(result).toHaveLength(3);
@@ -97,7 +98,7 @@ describe('renderAppbarContent', () => {
9798
isV3: false,
9899
children,
99100
isDark: false,
100-
renderOnly: [AppbarAction],
101+
renderOnly: ['Appbar.Action'],
101102
});
102103

103104
expect(result).toHaveLength(2);
@@ -108,7 +109,7 @@ describe('renderAppbarContent', () => {
108109
isV3: false,
109110
children,
110111
isDark: false,
111-
renderOnly: [AppbarContent],
112+
renderOnly: ['Appbar.Content'],
112113
mode: 'large',
113114
});
114115

@@ -121,7 +122,7 @@ describe('renderAppbarContent', () => {
121122
children,
122123
isDark: false,
123124
isV3,
124-
renderOnly: [AppbarContent],
125+
renderOnly: ['Appbar.Content'],
125126
mode: 'center-aligned',
126127
shouldCenterContent: true,
127128
});
@@ -146,7 +147,7 @@ describe('renderAppbarContent', () => {
146147
children,
147148
isDark: false,
148149
isV3,
149-
renderOnly: [AppbarContent],
150+
renderOnly: ['Appbar.Content'],
150151
mode: 'center-aligned',
151152
shouldCenterContent: !isV3 && Platform.OS === 'ios',
152153
});
@@ -167,7 +168,7 @@ describe('renderAppbarContent', () => {
167168
children,
168169
isDark: false,
169170
isV3,
170-
renderOnly: [AppbarContent],
171+
renderOnly: ['Appbar.Content'],
171172
mode: 'center-aligned',
172173
shouldCenterContent: !isV3 && Platform.OS === 'ios',
173174
});
@@ -187,7 +188,10 @@ describe('renderAppbarContent', () => {
187188
children,
188189
isDark: false,
189190
isV3,
190-
renderOnly: [AppbarContent, withAppbarBackAction && AppbarBackAction],
191+
renderOnly: [
192+
'Appbar.Content',
193+
withAppbarBackAction && 'Appbar.BackAction',
194+
],
191195
});
192196

193197
const v2Spacing = {

src/react-navigation/types.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import type {
77
TabActionHelpers,
88
TabNavigationState,
99
} from '@react-navigation/native';
10-
import type { BottomNavigation } from 'react-native-paper';
10+
11+
import type BottomNavigation from '../components/BottomNavigation/BottomNavigation';
1112

1213
export type MaterialBottomTabNavigationEventMap = {
1314
/**

0 commit comments

Comments
 (0)