- Sketch App: https://www.sketchapp.com/
- React Native: https://facebook.github.io/react-native/
Do you have designs in Sketch, and need to turn those into a mobile app? This will take those designs, and automatically create React Native components.
Send me your Sketch file and instructions, and I'll run it and email the output back to you: chris@nanohop.com
We offer that! We also offer a human in the loop, where we'll clean up the output before it goes back to you. Send me an email to learn more: chris@nanohop.com
- Node 8.5.0+ https://nodejs.org/en/
- Python 3.6.1+ https://www.python.org/downloads/
- Install TensorFlow https://www.tensorflow.org/install/
> git clone https://github.com/nanohop/sketch-to-react-native.git
> cd sketch-to-react-native
> npm install && npm link
> sketch-to-react-native ~/Desktop/myfile.svg
> sketch-to-react-native input-file.svg
It will run and save the output to the ./output folder. Make sure to grab both the .js file, and the associated images folder! Drop that into your React Native application, and see the magic!
Please let me know! This is early software, and I'm trying to solve as many edge cases as I can find. Please file an issue or send me an email.
Sketch exports a fairly clean SVG, which makes the process easier, but there is still a lot of processing involved. Here's the basic steps:
- Prep the SVG to make processing easier
- Use a deep neural net to filter out unwanted elements
- Get component bounding boxes using headless Chrome
- Figure out all the child/parent relationships
- Convert from absolute (pixel) positioning to Flex Box
- Extract images from SVG paths and polygons
- Generate styles for every component
- Generate components
- Export to an output file
Sketch (and the SVG export) is a pixel based (absolute positioned) system - but that's no good for React Native. One of the primary difficulties was figuring out what the proper parent / sibling relationships were between all the components, and then converting from absolute positioning to flexBox. There is still some work to clean this part up, but in general it's working fairly well for most inputs.
This also means that components in Sketch can partially overlap - which doesn't do well during the conversion process. I'm working on a fix for that; but until then - you'll get best results if there are no partially overlapping components in your Sketch file. (Fully overlapping is fine - those will get properly converted to a parent => child relationship)
Nope! You're probably thinking of react-sketchapp that takes react components, and generates Sketch files. This goes the opposite direction: it takes Sketch files, and creates React Native components.
I started with mobile because the app designs for mobile are generally more straightforward, with less variation - so it was easier to make the first version. I'm planning to do React for web as well though! Send me an email if you'd like updates when it's available: chris@nanohop.com
I'm a mobile developer myself - and we're rightfully fearful of any generated code. It is really high on my priority list to keep the output as clean and readable as possible. It's not perfect all the time, but it is one of my top priorities.
I've found that screens that would normally take me about an hour to create, take as little as 10 minutes - so that's as much as 80% time savings! The output does have to be cleaned up a little bit generally, but I find it usually provides good starting point.
It seems like overkill, but headless Chrome has a great SVG rendering engine, and it was the easiest way to get bounding boxes to work, and to export the SVG assets as pngs. That will probably change in the future.
I plan to get a hosted version up at some point, but until then you can email me your Sketch file and instructions, and I'll run it and email the component back to you: chris@nanohop.com
This is a work in progress, so there are a few things it doesn't do well: overlapping components, reusing component styles, reusing common components, collapsing unnecessary wrapping Views, (and more). I have a long roadmap of features to add.
Not yet, but it's on the roadmap!
If you'd like to help, I'd love to have you involved! Feel free to file issues, or send me an email with any Sketch file that doesn't work quite right, and I'll also review and merge pull requests as well.
You can see that it's not perfect - but it provides a really good starting point, and it's getting better all the time!
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
TextInput,
ScrollView,
Image
} from 'react-native';
import BackArrow from './Log_In_Page_images/Back-Arrow.png'
import Logo from './Log_In_Page_images/Logo.png'
export default class Main extends Component {
render() {
return (
<ScrollView style={{
flex: 1, alignSelf: 'stretch',
paddingTop: 20,
backgroundColor: '#5CC5F8'}}>
<View style={styles.Base}>
<Image source={BackArrow} style={styles.BackArrow} />
<Image source={Logo} style={styles.Logo} />
<View style={styles.EmailInput}>
<Text style={styles.EmailAddress}>Email Address</Text>
</View>
<View style={styles.PasswordInput}>
<Text style={styles.Passsord}>Password</Text>
</View>
<View style={styles.LoginButton}>
<Text style={styles.LogIn}>Log In</Text>
</View>
</View>
</ScrollView>
)
}
}
const styles = StyleSheet.create({
Base: {
height: 680,
backgroundColor: '#5CC5F8',
borderRadius: 6,
paddingTop: 20,
paddingBottom: 122
},
BackArrow: {
alignSelf: 'flex-start',
marginLeft: 18
},
Logo: {
alignSelf: 'center',
marginTop: 25
},
EmailInput: {
height: 64,
backgroundColor: '#FAFAFA',
borderRadius: 6,
alignSelf: 'center',
marginTop: 49,
width: 292,
alignItems: 'flex-start',
marginLeft: 30,
justifyContent: 'center'
},
EmailAddress: {
backgroundColor: 'transparent',
fontSize: 18,
fontWeight: '300',
color: '#444444',
textAlign: 'left',
marginLeft: 30
},
PasswordInput: {
height: 64,
backgroundColor: '#FAFAFA',
borderRadius: 6,
alignSelf: 'center',
marginTop: 14,
width: 292,
alignItems: 'flex-start',
marginLeft: 30,
justifyContent: 'center'
},
Passsord: {
backgroundColor: 'transparent',
fontSize: 18,
fontWeight: '300',
color: '#444444',
textAlign: 'left',
marginLeft: 30
},
LoginButton: {
height: 64,
backgroundColor: '#332AC6',
borderRadius: 6,
alignSelf: 'center',
marginTop: 121,
width: 292,
alignItems: 'center',
justifyContent: 'center'
},
LogIn: {
backgroundColor: 'transparent',
fontSize: 24,
fontWeight: '300',
color: '#FFFFFF',
textAlign: 'center'
}
})