fix: circular-dependencies (#2381)

# Summary
- Require cycles are allowed, but can result in uninitialized values.
Consider refactoring to remove the need for a cycle.
- extract SVG web components.
- extract web types.
- extract utils function.

## Test Plan
You can test that problem by running a test example `Test1813`

### What are the steps to reproduce (after prerequisites)?
Without those changes, you can occur that problem by running a test
example `Test1813`

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |         |
| Android |         |

---------

Co-authored-by: Jakub Grzywacz <jakub.grzywacz@swmansion.com>
This commit is contained in:
Bohdan Artiukhov
2024-07-31 11:45:04 +02:00
committed by GitHub
parent 129e8ed8b5
commit a27e17f505
13 changed files with 886 additions and 808 deletions

View File

@@ -1,18 +1,17 @@
import React from 'react';
import { PlatformColor, Platform, Button, DynamicColorIOS } from 'react-native';
import {
Svg,
Circle,
Rect,
Text,
TSpan,
} from 'react-native-svg';
import {PlatformColor, Platform, Button, DynamicColorIOS} from 'react-native';
import {Svg, Circle, Rect, Text, TSpan} from 'react-native-svg';
const color = PlatformColor(Platform.select({
ios: 'systemTealColor',
android: '@android:color/holo_blue_bright',
default: 'black',
}))
const color =
Platform.OS !== 'web'
? PlatformColor(
Platform.select({
ios: 'systemTealColor',
android: '@android:color/holo_blue_bright',
default: 'black',
}),
)
: 'black';
// const customContrastDynamicTextColor = DynamicColorIOS({
// dark: 'hsla(360, 40%, 30%, 1.0)',
@@ -27,13 +26,7 @@ export default () => {
return (
<>
<Svg height="100" width="100" color={color}>
<Circle
cx="50"
cy="50"
r={test}
strokeWidth="2.5"
fill={color}
/>
<Circle cx="50" cy="50" r={test} strokeWidth="2.5" fill={color} />
<Rect
x="15"
y="15"
@@ -45,12 +38,13 @@ export default () => {
</Svg>
<Svg height="300" width="300" fill="red">
<Text x={0} y={0} fontSize={20}>
<TSpan dx={test} inlineSize={"100%"} fill="currentColor">
Testing word-wrap... Testing word-wrap... Testing word-wrap... Testing word-wrap...
<TSpan dx={test} inlineSize={'100%'} fill="currentColor">
Testing word-wrap... Testing word-wrap... Testing word-wrap...
Testing word-wrap...
</TSpan>
</Text>
</Svg>
<Button title="Click me" onPress={()=> setTest(test + 1)}/>
<Button title="Click me" onPress={() => setTest(test + 1)} />
</>
);
}
};

View File

@@ -1,61 +1,65 @@
import React from 'react';
import {
SafeAreaView,
useColorScheme,
} from 'react-native';
import {Svg, Ellipse} from 'react-native-svg';
import Animated, {createAnimatedPropAdapter, processColor, useAnimatedProps, useSharedValue, withRepeat, withTiming} from 'react-native-reanimated';
import {Colors} from 'react-native/Libraries/NewAppScreen';
const AnimatedEllipse = Animated.createAnimatedComponent(Ellipse);
const App = () => {
const isDarkMode = useColorScheme() === 'dark';
const offset = useSharedValue(0);
offset.value = withRepeat(withTiming(1.0), -1, true);
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
flex: 1,
};
const ellipseAnimatedProps =
useAnimatedProps(() =>
{
const coordinates = {cx: 50, cy: 50, rx: 40, ry: 40};
return {
cx: coordinates.cx,
cy: coordinates.cy,
rx: coordinates.rx,
ry: coordinates.ry,
stroke: 'rgb(255,0,0)',
fill: 'yellow',
opacity: offset.value,
strokeWidth: 2,
};
}
, [], createAnimatedPropAdapter(
(props) => {
if (Object.keys(props).includes('fill')) {
props.fill = {type: 0, payload: processColor(props.fill)}
}
if (Object.keys(props).includes('stroke')) {
props.stroke = {type: 0, payload: processColor(props.stroke)}
}
import React from 'react';
import {SafeAreaView, useColorScheme} from 'react-native';
import {Svg, Ellipse} from 'react-native-svg';
import Animated, {
createAnimatedPropAdapter,
processColor,
useAnimatedProps,
useSharedValue,
withRepeat,
withTiming,
} from 'react-native-reanimated';
const AnimatedEllipse = Animated.createAnimatedComponent(Ellipse);
const App = () => {
const isDarkMode = useColorScheme() === 'dark';
const offset = useSharedValue(0);
offset.value = withRepeat(withTiming(1.0), -1, true);
const backgroundStyle = {
backgroundColor: isDarkMode ? '#333333' : '#fafafa',
flex: 1,
};
const ellipseAnimatedProps = useAnimatedProps(
() => {
const coordinates = {cx: 50, cy: 50, rx: 40, ry: 40};
return {
cx: coordinates.cx,
cy: coordinates.cy,
rx: coordinates.rx,
ry: coordinates.ry,
stroke: 'rgb(255,0,0)',
fill: 'yellow',
opacity: offset.value,
strokeWidth: 2,
};
},
['fill', 'stroke']));
return (
<SafeAreaView style={backgroundStyle}>
<Svg width="100%" height="100%">
<AnimatedEllipse
// {...coordinates}
animatedProps={ellipseAnimatedProps}
[],
createAnimatedPropAdapter(
props => {
if (Object.keys(props).includes('fill')) {
props.fill = {type: 0, payload: processColor(props.fill)};
}
if (Object.keys(props).includes('stroke')) {
props.stroke = {type: 0, payload: processColor(props.stroke)};
}
},
['fill', 'stroke'],
),
);
return (
<SafeAreaView style={backgroundStyle}>
<Svg width="100%" height="100%">
<AnimatedEllipse
// {...coordinates}
animatedProps={ellipseAnimatedProps}
/>
</Svg>
</SafeAreaView>
);
};
export default App;
</Svg>
</SafeAreaView>
);
};
export default App;