Coder Social home page Coder Social logo

andrew-levy / swiftui-react-native Goto Github PK

View Code? Open in Web Editor NEW
491.0 491.0 16.0 147.88 MB

Bringing SwiftUI features to your React Native app. It's like if React Native and SwiftUI had a child.

Home Page: swiftui-react-native.vercel.app

License: MIT License

TypeScript 64.76% JavaScript 0.69% Java 3.27% Ruby 1.44% Objective-C 0.12% Objective-C++ 0.96% Swift 28.73% C 0.04%

swiftui-react-native's Introduction

Andrew Levy

What I like to use to build my projects:

  • ⚛️ React
  • 📳 React Native
  • 🖥️ Next.js
  • 📱 SwiftUI

Buy me a coffee if you like my work!

"Buy Me A Coffee"

swiftui-react-native's People

Contributors

andrew-levy avatar dependabot[bot] avatar felixb1010 avatar sallar avatar swand0g avatar zpg6 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

swiftui-react-native's Issues

Possible new color system

Currently there are a few ways to apply colors to views:

  1. UIColor object. This is an object you can import that has dark and light properties. Inside those, there are each individual colors.

  2. useUIColor hook. this hook returns a dynamic form of the above UIColor object that decides between dark and light based on the current color scheme.

  3. You can also just pass in a hex value or any of the built in react native color values.

Proposed System:

Pass in the name of the swiftui color (as a string) that will map to the correct hex value. This will provide autocomplete and users won't need to use the hook or object.

example:
backgroundColor=“systemBlue”

where,
type backgroundColor = keyof UIColor.light | string or something like that.

The logic would go something like this:

  • if the string is a key of one of the uicolors, use the corresponding value
  • else, just use that value as its probably a hex or rgba value.

In order to incorporate dark mode, we would have to use the useColorScheme hook internally within each component rather than having the user use it (I like this better - less work for the user).

utils/colors

const getColor = (color: string, colorScheme: 'dark' | 'light') => {
  const palette = UIColor[colorScheme];
  if (palette[color]) return palette[color]
  return color
};

then in each component

const colorScheme = useColorSheme();

…getColor(backgroundColor, colorScheme),

Open questions:

  • Should we still include the old way to get colors?
  • Does the autocompleting just work for TS or does it work for JS too?
  • Should we also do this with alignment, fonts, etc? yes i think

Colors and Themes

So the UIColor object currently in the project, contains only light mode colors. This is fine for light mode, but we have to consider dark mode as well.

To fix this:

  • Instead of storing color values, we can use DynamicColorIOS or PlatformColor which can handle light/dark variants automatically.
  • In addition, we have to provide a way for the users of the package to overwrite these colors. Either by using a context that they can wrap their app in, or some other means...

What do you think @andrew-levy

Proposing hot reload for development env

(This is a "nice to have", just proposing at this time)

I have been thinking that putting the example in this repository and using something like nodemon would greatly improve my efficiency.

Here are my steps currently:

On swiftui-react-native:

yarn run clean-build

On swiftui-react-native-example

  1. Quit metro (if running)
  2. Restart metro with:
rm -rf node_modules && yarn install && yarn start --reset-cache
  1. Wait for metro to load up, then hit Rto reload simulator(s).

Text wrapping not working properly

Hi again! I've continued testing the library and found that text does not support number of lines, it just has a ellipsis trailing and wrapping doesn't work fine. The video situation is the following: adding string literal's new line doesn't work straight up, it requires to add two new lines.

Screen.Recording.2024-05-08.at.21.22.43.mov

Use Expo Module API

Once SwiftUI views are supported in the module api (early 2023 maybe?), I would like to switch some components over to it rather than using javascript implementations. Good candidates include:

  • Color
  • Image
  • Label
  • Link
  • Shapes

Maybe:

  • Slider
  • Stepper
  • ProgressView

Notice this list doesn't include any container views like Stacks, this is because there currently isn't an easy way to pass children from RN to the SwiftUI view. This will likely come in later iterations of the module api.

Questions:

Track PR: expo/expo#19888

HeaderScrollContext is not being correctly passed from NavigationViewManager to ScrollView

Issue

There is a HeaderScrollContext context variable in the NavigationViewManager component that eventually gets consumed by the ScrollView component to update the amount the user has scrolled (triggering the header animation). When these components are compiled using Rollup, it is not correctly passing the context from navigation.js (created here) to main.js (consumed here). Instead, navigation.js is creating its own context var, and no data is being shared between the two components.

In main.js line 248,

Current:
const HeaderScrollContext = React.createContext(null);

I think it should be doing something like this:
const HeaderScrollContext = require('./navigation').HeaderScrollContext
so that we can use the context that was created in the other file.

I also see that var stack = require('@react-navigation/stack'); is being required in main.js and stack.createStackNavigator(); is being called randomly. Maybe I messed up my import/export somewhere? The only reference to navigation stuff should be the context var.

Solutions?

I am actively trying to fix this, which has been making me think about how navigation components fit into this project. Ideally, I would like to keep the navigation components (I think?), but I am open to either making them platform agnostic or moving them to a completely different project. Here are some options:

  • Do nothing. Leave them in this project with the current setup (which works nicely). Just would need to fix this small issue mentioned above.

  • Keep the navigation components, but make them framework agnostic. They would have much less functionality and a lot would be simplified, but we could allow the user to pass in props depending on if they are using react-navigation, react-native-navigation, etc. You could imagine something like this
    <NavigationLink text='Go to SomeView' action={use whatever navigation function you want here} />

  • Don't change any of the navigation components, but move them to a separate project (something like swiftui-react-native-navigation). This could be an optional package that is a wrapper of react-navigation (and maybe more in the future). I definitely want to keep a lot of the animation magic that has been built out in these components already. If you haven't seen some of the animations yet, here is a quick demo:

animated-large.mov
animated-inline.mov

I'm open to more solutions, but these are the 3 that come to mind.

@sallar tagging you if you have any ideas! Just wanted to create an issue to keep track of this.

Navigation Views Proposal

Here are my thoughts on building navigation related swiftui views:

  • Need to make it separate from the original library. We don't want to bloat this library and we don't want to require the user to install so many dependencies. (separate repo? monorepo?)
  • Will use react navigation native stack under the hood
  • Implement basic nav and tab bar nav (and should be able to compose them)

I built a solid prototype that seems to be working really well for me. Need to decide where its going to live tho.


SwiftUI React Native Navigation

Basic Navigation

First, wrap your app with a NavigationProvider to enable navigation. For basic navigation (going from screen to screen and back), use the Navigation component. Its first and only child should be the initial view you want to show.

<NavigationProvider> 
  <Navigation>
    <Home user={{ name: "Andrew" }} />
  </Navigation> 
</NavigationProvider>

Moving along to the actual screen we want to render. Like SwiftUI, we wrap our screen in a NavigationView which will allow the user to customize the navigation bar like displayMode, title, etc. We use the NavigationLink component to navigate to another view.

const Home = ({ user }) => (
  <NavigationView navigationTitle="Welcome" navigationTitleDisplayMode="large">
    <VStack>
       <Text>Welcome {user}</Text>
       <NavigationLink label="To Settings" destination={<Settings theme="dark" />}  /> 
    </VStack>
  </NavigationView>
)

Tab Bar Navigation

Another feature we want to support is TabView. Similar to the above example, wrap the app in a NavigationProvider. Then as children, render a TabItem for each tab you want. You can supply the following props: label, icon, view. You can also send in props via props.

<NavigationProvider>
  <TabView>
      <TabItem  label="Home" icon={homeIcon} >
        <Home />
      </TabItem>
      <TabItem  label="Settings" icon={settingsIcon} >
        <Settings />
      </TabItem>
  <TabView>
</NavigationProvider>

Like in the basic navigation example above, Home and Settings are screens where the screen content is wrapped in a NavigationView:

const Home = () => (
  <NavigationView navigationTitle="Welcome">
    <VStack>
       <Text>Home Screen</Text>
       <NavigationLink label="To Settings" destination={<Settings />} /> 
    </VStack>
  </NavigationView>
)

At this point, we are able to navigate between tabs, but what if we want to navigate to a details screen under the Home tab? Well instead of providing <Home /> as a child of <TabItem>, we can pass a <Navigation> stack like so:

const HomeNavigation = () => <Navigation><Home /></Navigation>
<NavigationProvider>
  <TabView>
      <TabItem  label="Home" icon={homeIcon} >
        <HomeNavigation />
      </TabItem>
      <TabItem  label="Settings" icon={settingsIcon} >
        <Settings />
      </TabItem>
  <TabView>
</NavigationProvider>

VStack and Button not working properly

Hi! I've got to refactor some of my components since I was using v5, and I noticed 2 issues:

VStack does not fill entire view height (small white gap in the top)

Button not respecting modifier order

Expected behavior

Should be similar to SwiftUI for the VStack

VStack()
  .padding()
  .frame(maxWidth: .infinity, maxHeight: .infinity)
  .background(.black)

For the Button, it should respect the order as well, but it doesn't (because of this I can't have full width buttons, it seems)

My code:

 const { height, width } = useWindowDimensions();
  const { stateNavigator } = useContext(NavigationContext);

  return (
    <VStack padding frame={{ width, height }} background="black">
      <Image systemName="face.smiling" fontSize={50} />
      <Text font="title" foregroundStyle="white">
        Hello World!
      </Text>
      <Button
        title="Profile"
        tint="purple"
        buttonStyle="borderedProminent"
        frame={{ width }}
        action={() => stateNavigator.navigate('profile')}
      />
    </VStack>
  );

question about styled-components

Hi!

I was thinking about making something like this, because I love SwiftUI too and I was searching to see if anybody else has done anything similar.

This project is fantastic, however I have one question/concern:

Why do you use styled-components for this? In my experience it's a very heavy and unnecessary dependency for a project like this. Everything here can be achieved nicely via normal RN styles and it would be lighter and more performant.

Also another issue is, styled-components uses units like px which doesnt apply to RN, since everything needs to be unitless, but if you do that, styled-components throws a warning.

Are you interested in removing this dependency? It's ok if you're set on it, in that case I would still be making my own version.

Thanks again!

Chevron accessory of Link component

I've been searching for iOS-style React Native component library for a while and this is just what I want. Thanks for the awesome project!

While using Link component in a List, I found that the chevron icon on the right side is missing. The screenshots in README shows a Link component with chevron icon, but it does not appear in my app nor the example app.

Is there any way to add this in the latest version of swiftui-react-native? Thanks!

P.S. I've tried something like this but it looks much different with the native UITableViewCell.AccessoryType.disclosureIndicator.

<Button action={() => navigation.navigate('Drawing')}>
  <Text alignment="leading">Button</Text>
  <Image systemName="chevron.forward" />
</Button>

ERROR TypeError: null is not an object (evaluating '_useColorScheme.colorScheme')

I keep getting this error when trying to use any of the components. I'm fairly certain I have installed all the dependencies correctly. Here's my package.json:

  "dependencies": {
    "@gorhom/bottom-sheet": "^3",
    "@react-native-community/masked-view": "^0.1.11",
    "@react-native-mapbox-gl/maps": "^8.2.0-beta2",
    "@react-navigation/bottom-tabs": "^5.11.11",
    "@react-navigation/native": "^5.9.4",
    "@react-navigation/stack": "^5.14.5",
    "react": "17.0.1",
    "react-native": "0.64.2",
    "react-native-gesture-handler": "^1.10.3",
    "react-native-reanimated": "^2.2.0",
    "react-native-safe-area-context": "^3.2.0",
    "react-native-screens": "^3.3.0",
    "react-native-vector-icons": "^8.1.0",
    "swiftui-react-native": "^1.9.3"
  },

and I'm attempting to just use very simple components as a test,

import {Text} from 'swiftui-react-native';
....
<Text font="title">Some cool text</Text>

I've tried a few components and they all produce the same error. Any ideas? Here's the error

ERROR  TypeError: null is not an object (evaluating '_useColorScheme.colorScheme')

This error is located at:
  in Text (at MapButtons.js:65)
  in RCTView (at View.js:34)
  in View (at createAnimatedComponent.js:448)
  in AnimatedComponent(View) (at createAnimatedComponent.js:459)
  in AnimatedComponentWrapper (at BottomSheetDraggableView.tsx:74)
  in PanGestureHandler (at BottomSheetDraggableView.tsx:62)
  in BottomSheetDraggableView (at BottomSheet.tsx:948)
  in RCTView (at View.js:34)
  in View (at createAnimatedComponent.js:448)
  in AnimatedComponent(View) (at createAnimatedComponent.js:459)
  in AnimatedComponentWrapper (at BottomSheet.tsx:943)
  in RCTView (at View.js:34)
  in View (at createAnimatedComponent.js:448)
  in AnimatedComponent(View) (at createAnimatedComponent.js:459)
  in AnimatedComponentWrapper (at BottomSheet.tsx:930)
  in RCTView (at View.js:34)
  in View (at BottomSheetContainer.tsx:40)
  in BottomSheetContainer (at BottomSheet.tsx:924)
  in BottomSheet (created by BottomSheet)
  in PortalHost (at PortalProvider.tsx:13)
  in PortalProvider (at BottomSheetModalProvider.tsx:186)
  in BottomSheetModalProviderWrapper (at HomeScreen.js:224)
  in HomeScreen (at SceneView.tsx:122)
  in StaticContainer
  in EnsureSingleNavigator (at SceneView.tsx:114)
  in SceneView (at useDescriptors.tsx:153)
  in RCTView (at View.js:34)
  in View (at BottomTabView.tsx:55)
  in SceneContent (at BottomTabView.tsx:172)
  in RNSScreen (at createAnimatedComponent.js:217)
  in AnimatedComponent (at createAnimatedComponent.js:278)
  in AnimatedComponentWrapper (at src/index.native.tsx:147)
  in Screen (at ResourceSavingScene.tsx:30)
  in ResourceSavingScene (at BottomTabView.tsx:166)
  in RNSScreenContainer (at src/index.native.tsx:186)
  in ScreenContainer (at BottomTabView.tsx:146)
  in RNCSafeAreaProvider (at SafeAreaContext.tsx:76)
  in SafeAreaProvider (at SafeAreaProviderCompat.tsx:42)
  in SafeAreaProviderCompat (at BottomTabView.tsx:145)
  in BottomTabView (at createBottomTabNavigator.tsx:45)
  in BottomTabNavigator (at App.js:20)
  in EnsureSingleNavigator (at BaseNavigationContainer.tsx:409)
  in BaseNavigationContainer (at NavigationContainer.tsx:91)
  in ThemeProvider (at NavigationContainer.tsx:90)
  in NavigationContainer (at App.js:19)
  in App (at renderApplication.js:47)
  in RCTView (at View.js:34)
  in View (at AppContainer.js:107)
  in RCTView (at View.js:34)
  in View (at AppContainer.js:134)
  in AppContainer (at renderApplication.js:40)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.