diff --git a/examples/bare/ios/AMAExample.xcodeproj/project.pbxproj b/examples/bare/ios/AMAExample.xcodeproj/project.pbxproj index b4ada9b0..80b38fc6 100644 --- a/examples/bare/ios/AMAExample.xcodeproj/project.pbxproj +++ b/examples/bare/ios/AMAExample.xcodeproj/project.pbxproj @@ -470,6 +470,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = NO; INFOPLIST_FILE = AMAExample/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "AMA Example"; @@ -498,6 +499,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = AMAExample/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "AMA Example"; LD_RUNPATH_SEARCH_PATHS = ( @@ -586,8 +588,10 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", ); + OTHER_LDFLAGS = "$(inherited) "; REACT_NATIVE_PATH = "${PODS_ROOT}/../../../../node_modules/react-native"; SDKROOT = iphoneos; + USE_HERMES = true; }; name = Debug; }; @@ -652,8 +656,10 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", ); + OTHER_LDFLAGS = "$(inherited) "; REACT_NATIVE_PATH = "${PODS_ROOT}/../../../../node_modules/react-native"; SDKROOT = iphoneos; + USE_HERMES = true; VALIDATE_PRODUCT = YES; }; name = Release; diff --git a/examples/bare/src/AppNavigator.tsx b/examples/bare/src/AppNavigator.tsx index 5adaa2fd..bfe4eab8 100644 --- a/examples/bare/src/AppNavigator.tsx +++ b/examples/bare/src/AppNavigator.tsx @@ -9,11 +9,14 @@ import { Header, HomeScreen, PressableScreen, + SwitchListItemScreen, TextScreen, TouchableOpacityScreen, TouchableWithoutFeedbackScreen, UseAMAContextScreen, + UseAnimationDurationScreen, UseAnimationScreen, + UseReanimatedAnimationBuilderScreen, UseReanimatedTimingScreen, UseTimedActionScreen, } from '@examples/shared-ui'; @@ -51,6 +54,16 @@ export const AppNavigator = () => { headerTitle: () =>
, }} /> + , + headerTitle: () => ( +
+ ), + }} + /> { ), }} /> + , + headerTitle: () => ( +
+ ), + }} + /> { ), }} /> + , + headerTitle: () => ( +
+ ), + }} + /> { headerTitle: () =>
, }} /> + , + headerTitle: () => ( +
+ ), + }} + /> { ), }} /> + , + headerTitle: () => ( +
+ ), + }} + /> { ), }} /> + , + headerTitle: () => ( +
+ ), + }} + /> { onPress={() => navigate('TouchableWithoutFeedback')} /> + navigate('SwitchListItem')} + /> + navigate('ExpandablePressable')} @@ -57,6 +62,16 @@ export const HomeScreen = ({ navigation }) => { onPress={() => navigate('UseAnimation')} /> + navigate('UseAnimationDuration')} + /> + + navigate('UseReanimatedAnimationBuilder')} + /> + navigate('UseReanimatedTiming')} diff --git a/examples/shared/src/screens/SwitchListItemScreen.tsx b/examples/shared/src/screens/SwitchListItemScreen.tsx new file mode 100644 index 00000000..38337c2a --- /dev/null +++ b/examples/shared/src/screens/SwitchListItemScreen.tsx @@ -0,0 +1,200 @@ +import { + SwitchListItem, + Text, + useSwitch, +} from '@react-native-ama/react-native'; +import React, { useState } from 'react'; +import { Linking, StyleSheet, TouchableOpacity } from 'react-native'; +import { View } from 'react-native'; +import { Path, Svg } from 'react-native-svg'; + +import { CTAPressable } from '../components/CTAPressable'; +import { Spacer } from '../components/Spacer'; +import { theme } from '../theme'; + +const getStyles = (value, isError) => { + return isError + ? { + ...styles.touchableOpacityError, + backgroundColor: value ? '#4CAF50' : 'white', + } + : { + ...styles.touchableOpacity, + backgroundColor: value ? '#4CAF50' : 'white', + }; +}; + +const CheckCircle = props => { + return ( + + + + + ); +}; + +const Circle = props => { + return ( + + + + ); +}; +const CustomSwitch = ({ value, onValueChange, isError = false }) => { + const props = useSwitch({ + accessibilityLabel: 'My Switch', + style: getStyles(value, isError), + }); + return ( + + {value ? : } + + ); +}; + +export const SwitchListItemScreen = () => { + const [isSwitchOn, setIsSwitchOn] = useState(false); + const [isCustomSwitchOn, setCustomIsSwitchOn] = useState(false); + const [isErrorCustomSwitchOn, setErrorCustomIsSwitchOn] = useState(false); + const [showTouchableAreaError, setShowTouchableAreaError] = useState(false); + const toggleRNSwitch = () => { + setIsSwitchOn(previousState => !previousState); + }; + + const toggleCustomSwitch = () => { + setCustomIsSwitchOn(previousState => !previousState); + }; + + const toggleErrorCustomSwitch = () => { + setErrorCustomIsSwitchOn(previousState => !previousState); + }; + + return ( + + + This example shows how to use the{' '} + + Linking.openURL( + 'https://commerce.nearform.com/open-source/react-native-ama/react-native/SwitchListItem', + ) + }> + SwitchListItem. + + + + React Native Switch + } + style={styles.switchListItem} + value={isSwitchOn} + onValueChange={toggleRNSwitch} + /> + + Custom Switch with{'\n'} + height:46px{'\n'} + width:46px{'\n'} + and no error + + } + style={styles.switchListItem} + value={isCustomSwitchOn} + onValueChange={toggleCustomSwitch}> + + + + + setShowTouchableAreaError(true)} + /> + {showTouchableAreaError ? ( + <> + + Custom Switch with breaking guidelines: + + Custom Switch{'\n'} + height:40px{'\n'} + width:40px{'\n'} + + } + style={styles.switchListItem} + value={isErrorCustomSwitchOn} + onValueChange={toggleErrorCustomSwitch}> + + + + ) : null} + + + ); +}; + +const styles = StyleSheet.create({ + view: { + paddingHorizontal: theme.padding.big, + paddingTop: theme.padding.big, + }, + container: { + paddingHorizontal: theme.padding.normal, + paddingTop: theme.padding.normal, + }, + intro: { + lineHeight: theme.lineHeight.medium, + }, + underline: { + textDecorationLine: 'underline', + }, + labelComponent: { + paddingBottom: theme.padding.small, + }, + switchText: { + flex: 1, + paddingRight: theme.padding.normal, + }, + switchListItem: { + marginVertical: theme.padding.normal, + }, + touchableOpacity: { + width: 46, + height: 46, + borderRadius: 100, + padding: 10, + justifyContent: 'center', + alignItems: 'center', + }, + touchableOpacityError: { + width: 40, + height: 40, + borderRadius: 100, + padding: 10, + justifyContent: 'center', + alignItems: 'center', + }, +}); diff --git a/examples/shared/src/screens/UseAnimationDurationScreen.tsx b/examples/shared/src/screens/UseAnimationDurationScreen.tsx new file mode 100644 index 00000000..8ca19afb --- /dev/null +++ b/examples/shared/src/screens/UseAnimationDurationScreen.tsx @@ -0,0 +1,114 @@ +import { useAnimationDuration } from '@react-native-ama/animations'; +import { useAMAContext } from '@react-native-ama/core'; +import { Text } from '@react-native-ama/react-native'; +import React from 'react'; +import { Linking, Platform, StyleSheet, View } from 'react-native'; +import Animated, { + useAnimatedStyle, + useSharedValue, + withTiming, +} from 'react-native-reanimated'; + +import { CTAPressable } from '../components/CTAPressable'; +import { Spacer } from '../components/Spacer'; +import { theme } from '../theme'; + +const isIOS = Platform.OS === 'ios'; +const isAndroid = Platform.OS === 'android'; + +export const UseAnimationDurationScreen = () => { + const value = useSharedValue(0); + const { isReduceMotionEnabled } = useAMAContext(); + + const { getAnimationDuration } = useAnimationDuration(); + + const animatedStyles = useAnimatedStyle(() => { + return { + transform: [{ translateX: value.value * 255 }], + }; + }); + + const playAnimation = () => { + value.value = withTiming(Math.random(), { + duration: getAnimationDuration('translateX', 300), + }); + }; + return ( + <> + + + + To test the hook{' '} + + Linking.openURL( + 'https://commerce.nearform.com/open-source/react-native-ama/animations/hooks/useAnimationDuration', + ) + }> + 'useAnimatedDuration' + + {`, enable / disable the ${ + isIOS ? "'Reduced Motion'" : "'Remove Animations'" + } phone setting. To do this:`} + + {isIOS ? ( + <> + + + Go to Settings > Accessibility > Motion > Reduce Motion. + + + ) : null} + {isAndroid ? ( + <> + + + Go to Settings > Accessibility > Visibility Enhancements + > Remove Animations. + + + ) : null} + + + Reduce Motion Enabled status:{' '} + {isReduceMotionEnabled?.toString()} + + + + The below button will not animate if the Reduce Motion option is + enabled + + + + + + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + paddingHorizontal: theme.padding.big, + }, + text: { + color: theme.color.black, + fontSize: theme.fontSize.normal, + }, + box: { + width: 100, + height: 100, + borderRadius: 20, + backgroundColor: theme.color.mixed, + }, + underline: { + textDecorationLine: 'underline', + }, + bold: { + fontWeight: 'bold', + }, +}); diff --git a/examples/shared/src/screens/UseReanimatedAnimationBuilderScreen.tsx b/examples/shared/src/screens/UseReanimatedAnimationBuilderScreen.tsx new file mode 100644 index 00000000..593f8228 --- /dev/null +++ b/examples/shared/src/screens/UseReanimatedAnimationBuilderScreen.tsx @@ -0,0 +1,69 @@ +import { useReanimatedAnimationBuilder } from '@react-native-ama/animations'; +import { Text } from '@react-native-ama/react-native'; +import React from 'react'; +import { Linking, StyleSheet, View } from 'react-native'; +import Animated from 'react-native-reanimated'; + +import { Spacer } from '../components/Spacer'; +import { theme } from '../theme'; + +export const UseReanimatedAnimationBuilderScreen = () => { + const { entering, exiting } = useReanimatedAnimationBuilder({ + from: { transform: [{ translateY: 100 }] }, + to: { transform: [{ translateY: 0 }] }, + exitFrom: { transform: [{ translateY: 0 }] }, + exitTo: { transform: [{ translateY: 100 }] }, + duration: 3000, + }); + + return ( + + + + The animation below is an example built with the{' '} + + Linking.openURL( + 'https://commerce.nearform.com/open-source/react-native-ama/animations/hooks/useReanimatedAnimationBuilder', + ) + }> + useReanimatedAnimationBuilder + {' '} + hook. + + + + This hook allows for animations to be built with accessibility in mind, + honoring the reduce motion preference of users. + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + paddingHorizontal: theme.padding.big, + }, + box: { + width: 100, + height: 100, + borderRadius: 20, + backgroundColor: theme.color.mixed, + }, + intro: { + lineHeight: theme.lineHeight.medium, + }, + text: { + paddingTop: theme.padding.normal, + paddingHorizontal: theme.padding.big, + color: theme.color.white, + fontSize: theme.fontSize.medium, + }, + underline: { + textDecorationLine: 'underline', + }, +}); diff --git a/examples/shared/src/screens/UseReanimatedTimingScreen.tsx b/examples/shared/src/screens/UseReanimatedTimingScreen.tsx index e972c7ea..a703d2bb 100644 --- a/examples/shared/src/screens/UseReanimatedTimingScreen.tsx +++ b/examples/shared/src/screens/UseReanimatedTimingScreen.tsx @@ -47,7 +47,7 @@ export const UseReanimatedTimingScreen = () => { style={styles.underline} onPress={() => Linking.openURL( - 'https://commerce.nearform.com/open-source/react-native-ama/docs/hooks/useAnimationDuration#getanimationduration', + 'https://commerce.nearform.com/open-source/react-native-ama/animations/hooks/useReanimatedTiming', ) }> getAnimationDuration diff --git a/packages/animations/docs/hooks/useAnimationDuration.md b/packages/animations/docs/hooks/useAnimationDuration.md index c3e6031f..0408acbf 100644 --- a/packages/animations/docs/hooks/useAnimationDuration.md +++ b/packages/animations/docs/hooks/useAnimationDuration.md @@ -5,9 +5,9 @@ When passing a motion property, returns 0 if [Reduce Motion](../hooks/useAMACont ## Usage ```js -import { useAnimationDuration } from 'react-native-ama'; +import { useAnimationDuration } from 'react-native-ama/animations'; -const { getAnimationDuration } = useAccessibleAnimationDuration(); +const { getAnimationDuration } = useAnimationDuration(); ``` ## getAnimationDuration @@ -40,10 +40,9 @@ const animatedStyles = useAnimatedStyle(() => { }); const playAnimation = () => { - value.value = withTiming( - Math.random(), - getAnimationDuration('translateX', 300), - ); + value.value = withTiming(Math.random(), { + duration: getAnimationDuration('translateX', 300), + }); }; ``` diff --git a/packages/animations/docs/hooks/useReanimatedAnimationBuilder.md b/packages/animations/docs/hooks/useReanimatedAnimationBuilder.md index 3f05934b..220fc33a 100644 --- a/packages/animations/docs/hooks/useReanimatedAnimationBuilder.md +++ b/packages/animations/docs/hooks/useReanimatedAnimationBuilder.md @@ -33,7 +33,7 @@ If the property `exitFrom` is not specified, it will then play the animation in ## Accessibility -For both, `from` and `exitFrom` starting animation, the hook will use a `duration={0}` for each [motion property](../utils/isMotionAnimation) when [Reduce Motion](../hooks/useAMAContext#isreducemotionenabled) option is enabled. +For both, `from` and `exitFrom` starting animation, the hook will use a `duration={0}` for each [motion property](../utils/isMotionAnimation) when [Reduce Motion](/core/hooks/useAMAContext#isreducemotionenabled) option is enabled. ## Props @@ -47,7 +47,7 @@ The preferred animation duration. :::note -The hook will use a `duration={0}` for each [motion property](../utils/isMotionAnimation) when [Reduce Motion](../hooks/useAMAContext#isreducemotionenabled) option is enabled. +The hook will use a `duration={0}` for each [motion property](../utils/isMotionAnimation) when [Reduce Motion](/core/hooks/useAMAContext#isreducemotionenabled) option is enabled. ::: diff --git a/packages/animations/docs/utilities/_category_.json b/packages/animations/docs/utils/_category_.json similarity index 100% rename from packages/animations/docs/utilities/_category_.json rename to packages/animations/docs/utils/_category_.json diff --git a/packages/animations/docs/utilities/isMotionAnimation.md b/packages/animations/docs/utils/isMotionAnimation.md similarity index 93% rename from packages/animations/docs/utilities/isMotionAnimation.md rename to packages/animations/docs/utils/isMotionAnimation.md index ef8921a1..f12a0948 100644 --- a/packages/animations/docs/utilities/isMotionAnimation.md +++ b/packages/animations/docs/utils/isMotionAnimation.md @@ -20,7 +20,7 @@ import { StyleSheet, View } from 'react-native'; import { isMotionAnimation, useAMAContext, - useAccessibleAnimationDuration, + useAnimationDuration, } from 'react-native-ama'; import Animated, { useAnimatedStyle, @@ -30,7 +30,7 @@ import Animated, { } from 'react-native-reanimated'; export const ReanimatedReduceMotionScreen = () => { - const { getAnimationDuration } = useAccessibleAnimationDuration(); + const { getAnimationDuration } = useAnimationDuration(); const { isReduceMotionEnabled } = useAMAContext(); const value = useSharedValue(0); diff --git a/website/versioned_docs/version-0.7.x/components/SwitchListItem.md b/website/versioned_docs/version-0.7.x/components/SwitchListItem.md index 0391940e..f44560c5 100644 --- a/website/versioned_docs/version-0.7.x/components/SwitchListItem.md +++ b/website/versioned_docs/version-0.7.x/components/SwitchListItem.md @@ -2,7 +2,7 @@ import { Required } from '@site/src/components'; # SwitchListItem -It is a utility component that provides a list item with a customisable label and switch control [focused on accessibility](#accessibility). +It is a utility component that provides a list item with a customizable label and switch control [focused on accessibility](#accessibility). ## Usage @@ -25,7 +25,7 @@ The component: - is announced as a "switch" - handles the `accessibilityState` **checked** -- user the label text as `accessibilityLabel` +- uses the label text as `accessibilityLabel` ## Props @@ -65,7 +65,7 @@ By default, the component uses the [React Native switch](https://reactnative.dev ```jsx I'm a switch} + labelComponent={I'm a switch} style={styles.switchListItem} value={isSwitchOn} onValueChange={toggleSwitch}> diff --git a/website/versioned_docs/version-0.7.x/hooks/useAnimationDuration.md b/website/versioned_docs/version-0.7.x/hooks/useAnimationDuration.md index 5100e677..6d5648f1 100644 --- a/website/versioned_docs/version-0.7.x/hooks/useAnimationDuration.md +++ b/website/versioned_docs/version-0.7.x/hooks/useAnimationDuration.md @@ -2,13 +2,12 @@ When passing a motion property, returns 0 if [Reduce Motion](../hooks/useAMAContext#isreducemotionenabled) is enabled otherwise the given value. - ## Usage ```js import { useAnimationDuration } from 'react-native-ama'; -const { getAnimationDuration } = useAccessibleAnimationDuration(); +const { getAnimationDuration } = useAnimationDuration(); ``` ## getAnimationDuration @@ -41,10 +40,9 @@ const animatedStyles = useAnimatedStyle(() => { }); const playAnimation = () => { - value.value = withTiming( - Math.random(), - getAnimationDuration('translateX', 300), - ); + value.value = withTiming(Math.random(), { + duration: getAnimationDuration('translateX', 300), + }); }; ``` diff --git a/website/versioned_docs/version-0.7.x/utils/isMotionAnimation.md b/website/versioned_docs/version-0.7.x/utils/isMotionAnimation.md index ef8921a1..f12a0948 100644 --- a/website/versioned_docs/version-0.7.x/utils/isMotionAnimation.md +++ b/website/versioned_docs/version-0.7.x/utils/isMotionAnimation.md @@ -20,7 +20,7 @@ import { StyleSheet, View } from 'react-native'; import { isMotionAnimation, useAMAContext, - useAccessibleAnimationDuration, + useAnimationDuration, } from 'react-native-ama'; import Animated, { useAnimatedStyle, @@ -30,7 +30,7 @@ import Animated, { } from 'react-native-reanimated'; export const ReanimatedReduceMotionScreen = () => { - const { getAnimationDuration } = useAccessibleAnimationDuration(); + const { getAnimationDuration } = useAnimationDuration(); const { isReduceMotionEnabled } = useAMAContext(); const value = useSharedValue(0);