diff --git a/apps/expo/package.json b/apps/expo/package.json index ec9df711b2..acdba13d1b 100644 --- a/apps/expo/package.json +++ b/apps/expo/package.json @@ -36,6 +36,7 @@ "@radix-ui/react-tabs": "^0.1.1", "@react-native-async-storage/async-storage": "^1.15.11", "@react-native-community/netinfo": "7.1.3", + "@react-native-segmented-control/segmented-control": "^2.4.0", "@react-navigation/bottom-tabs": "^6.0.9", "@react-navigation/native": "^6.0.6", "@react-navigation/native-stack": "^6.2.5", diff --git a/apps/storybook-react-native/.storybook/storybook.requires.js b/apps/storybook-react-native/.storybook/storybook.requires.js index 36813676be..6cdc45d57d 100644 --- a/apps/storybook-react-native/.storybook/storybook.requires.js +++ b/apps/storybook-react-native/.storybook/storybook.requires.js @@ -35,6 +35,7 @@ const getStories = () => { require("../../../packages/design-system/tabs/tabs.stories.tsx"), require("../../../packages/design-system/text/text.stories.tsx"), require("../../../packages/design-system/toast/toast.stories.tsx"), + require("../../../packages/design-system/segmented-control/segmented-control.stories.tsx"), ]; }; diff --git a/apps/storybook-react-native/package.json b/apps/storybook-react-native/package.json index 3fc2395b64..7ae1414f8b 100644 --- a/apps/storybook-react-native/package.json +++ b/apps/storybook-react-native/package.json @@ -29,6 +29,7 @@ "@react-native-async-storage/async-storage": "~1.15.0", "@react-native-community/datetimepicker": "4.0.0", "@react-native-community/slider": "4.1.12", + "@react-native-segmented-control/segmented-control": "^2.4.0", "@storybook/addon-actions": "^6.3.12", "@storybook/addon-controls": "^6.3.12", "@storybook/addon-ondevice-actions": "^6.0.1-alpha.6", diff --git a/packages/design-system/segmented-control/index.tsx b/packages/design-system/segmented-control/index.tsx new file mode 100644 index 0000000000..91f0031821 --- /dev/null +++ b/packages/design-system/segmented-control/index.tsx @@ -0,0 +1,40 @@ +import RNSegmentedControl from "@react-native-segmented-control/segmented-control"; +import { useCallback } from "react"; +import { + NativeSegmentedControlIOSChangeEvent, + NativeSyntheticEvent, +} from "react-native"; +import { colors } from "design-system/tailwind/colors"; +import { useIsDarkMode } from "design-system/hooks"; +import { tw } from "design-system/tailwind"; + +type SegmentedControlProps = { + values: Array; + selectedIndex: number; + onChange: (newIndex: number) => void; +}; + +export const SegmentedControl = (props: SegmentedControlProps) => { + const { values, selectedIndex, onChange } = props; + const handleChange = useCallback( + (e: NativeSyntheticEvent) => { + onChange?.(e.nativeEvent.selectedSegmentIndex); + }, + [onChange] + ); + + const isDark = useIsDarkMode(); + + return ( + + ); +}; diff --git a/packages/design-system/segmented-control/segmented-control.stories.tsx b/packages/design-system/segmented-control/segmented-control.stories.tsx new file mode 100644 index 0000000000..072d3fb1fc --- /dev/null +++ b/packages/design-system/segmented-control/segmented-control.stories.tsx @@ -0,0 +1,19 @@ +import { Meta } from "@storybook/react"; +import { SegmentedControl } from "./index"; +import { useState } from "react"; + +export default { + component: SegmentedControl, + title: "Components/SegmentedControl", +} as Meta; + +export const Primary: React.VFC<{}> = () => { + const [selected, setSelected] = useState(0); + return ( + + ); +}; diff --git a/patches/@react-native-segmented-control+segmented-control+2.4.0.patch b/patches/@react-native-segmented-control+segmented-control+2.4.0.patch new file mode 100644 index 0000000000..349631d2c9 --- /dev/null +++ b/patches/@react-native-segmented-control+segmented-control+2.4.0.patch @@ -0,0 +1,33 @@ +diff --git a/node_modules/@react-native-segmented-control/segmented-control/js/SegmentedControlTab.js b/node_modules/@react-native-segmented-control/segmented-control/js/SegmentedControlTab.js +index 85bb622..5eddb89 100644 +--- a/node_modules/@react-native-segmented-control/segmented-control/js/SegmentedControlTab.js ++++ b/node_modules/@react-native-segmented-control/segmented-control/js/SegmentedControlTab.js +@@ -14,7 +14,7 @@ import { + View, + useColorScheme, + } from 'react-native'; +- ++import { Pressable } from "design-system/pressable-scale" + import type {FontStyle, ViewStyle} from './types'; + + type Props = $ReadOnly<{| +@@ -83,8 +83,8 @@ export const SegmentedControlTab = ({ + }; + + return ( +- +@@ -97,7 +97,7 @@ export const SegmentedControlTab = ({ + {value} + )} + +- ++ + ); + }; + diff --git a/yarn.lock b/yarn.lock index 93afc08963..537d3919a6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3320,6 +3320,11 @@ resolved "https://registry.yarnpkg.com/@react-native-community/slider/-/slider-4.1.12.tgz#279ff7bbe487af92ad95ec758a029a54569e2a62" integrity sha512-CiuLZ2orueBiWHYxfaJF57jQY6HY2Q3z5pdAE4MKH8EqIImr/jgDJrJ/UxOVZHK1Ng9P+XlGIKfVIcuWZ6guuA== +"@react-native-segmented-control/segmented-control@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@react-native-segmented-control/segmented-control/-/segmented-control-2.4.0.tgz#0a88f22ad2c0fe07ecc002ee1e5d62c55a3dd0ae" + integrity sha512-2s1AaT6xk/Do5s6u7ioCXucqesAt02NQlLKBOM28dJWI7PTH9o89x6AwsGHIeMkTe4nQ6iENiJKzO7Y3SGG9Ew== + "@react-native/assets@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@react-native/assets/-/assets-1.0.0.tgz#c6f9bf63d274bafc8e970628de24986b30a55c8e"