Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emotion Native #759

Merged
merged 37 commits into from
Jul 28, 2018
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
6b9f575
Init commit
nitin42 Jul 9, 2018
91380c2
add emotion-native
nitin42 Jul 9, 2018
38d3012
remove unused imports
nitin42 Jul 9, 2018
db3d964
added basic types
nitin42 Jul 9, 2018
d545607
fix flow types
nitin42 Jul 9, 2018
6ec1ff3
add jsdom env when testing
nitin42 Jul 9, 2018
94b0c28
fixed import statement
nitin42 Jul 13, 2018
25d75bc
fixed import statement and updated package.json
nitin42 Jul 13, 2018
ae75fe3
added test for Emotion native css/css({})
nitin42 Jul 13, 2018
b80e73f
added new keywords
nitin42 Jul 13, 2018
fc1beb9
added documentation for @emotion/native
nitin42 Jul 13, 2018
ddb2dd2
added docs for @emotion/primitives-core
nitin42 Jul 13, 2018
ee2181c
fixed docs and flow types
nitin42 Jul 14, 2018
f839c70
fixed conflicts
nitin42 Jul 14, 2018
95c28d3
fixed conflicts
nitin42 Jul 14, 2018
47f5035
fixed conflicts
nitin42 Jul 15, 2018
fdc1876
update @emotion/primitives version
nitin42 Jul 15, 2018
abca5e7
Update package.json
emmatown Jul 15, 2018
c656626
Update package.json
emmatown Jul 15, 2018
b967b7d
Change package.json formatting
emmatown Jul 15, 2018
2cf1a06
Most things are fixed
emmatown Jul 15, 2018
1073a66
Update snapshots
emmatown Jul 15, 2018
341e192
added example for react-360
nitin42 Jul 15, 2018
f427e40
fixed flow types
nitin42 Jul 16, 2018
f8483e2
update react-native version
nitin42 Jul 16, 2018
fdaf228
added default value for options
nitin42 Jul 16, 2018
00881d1
update function signature in primitives
nitin42 Jul 16, 2018
df1d259
Update README.md
tkh44 Jul 16, 2018
be12b5c
add react to peerDependencies
nitin42 Jul 18, 2018
6a1b33b
Refactor: default export in native
nitin42 Jul 18, 2018
32b27c1
fix wording in docs
nitin42 Jul 18, 2018
f87c05d
Merge branch 'master' into emotion-native
emmatown Jul 21, 2018
975bc68
Fix snapshots
emmatown Jul 23, 2018
4f3f998
Merge remote-tracking branch 'upstream/master' into emotion-native
emmatown Jul 23, 2018
4e8ca76
Merge branch 'master' into emotion-native
emmatown Jul 27, 2018
8c6694e
Loosen peerDep on react-native
emmatown Jul 28, 2018
84c1bb9
Merge branch 'master' into emotion-native
emmatown Jul 28, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

[declarations]
.*/node_modules/polished/.*
.*/node_modules/react-native/.*


[options]
suppress_comment=.*\\$FlowFixMe
Expand Down
61 changes: 61 additions & 0 deletions __mocks__/react-native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// @flow
/* eslint-env jest */

let components = [
'ActivityIndicator',
'ActivityIndicatorIOS',
'ART',
'Button',
'DatePickerIOS',
'DrawerLayoutAndroid',
'Image',
'ImageBackground',
'ImageEditor',
'ImageStore',
'KeyboardAvoidingView',
'ListView',
'MapView',
'Modal',
'NavigatorIOS',
'Picker',
'PickerIOS',
'ProgressBarAndroid',
'ProgressViewIOS',
'ScrollView',
'SegmentedControlIOS',
'Slider',
'SliderIOS',
'SnapshotViewIOS',
'Switch',
'RecyclerViewBackedScrollView',
'RefreshControl',
'SafeAreaView',
'StatusBar',
'SwipeableListView',
'SwitchAndroid',
'SwitchIOS',
'TabBarIOS',
'Text',
'TextInput',
'ToastAndroid',
'ToolbarAndroid',
'Touchable',
'TouchableHighlight',
'TouchableNativeFeedback',
'TouchableOpacity',
'TouchableWithoutFeedback',
'View',
'ViewPagerAndroid',
'WebView',
'FlatList',
'SectionList',
'VirtualizedList'
]

module.exports = {
...jest.requireActual('react-primitives'),
...components.reduce((obj, key) => {
obj[key] = key
return obj
}, {})
}
8 changes: 8 additions & 0 deletions __mocks__/react-primitives.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// @flow
/* eslint-env jest */
module.exports = {
...jest.requireActual('react-primitives'),
View: 'View',
Image: 'Image',
Text: 'Text'
}
181 changes: 181 additions & 0 deletions packages/native/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# @emotion/native

> Style and render React Native components using emotion

## Install

```
npm install @emotion/native
```

or if you use yarn

```
yarn add @emotion/native
```

This package also depends on `react`, `react-native` and `prop-types` so make sure you've them installed.

## Example

```js
import React from 'react'
import { AppRegistry } from 'react-native';
import styled, { css } from '@emotion/native'

const Container = styled.View`
display: flex;
justify-content: center;
align-items: center;
margin: 50px;
`

const Description = styled.Text({
color: 'hotpink'
})

const Image = styled.Image`
padding: 40px;
`

const emotionLogo =
'https://cdn.rawgit.com/emotion-js/emotion/master/emotion.png'

class App extends React.Component {
render() {
return (
<Container
style={css`
border-radius: 10px;
`}
>
<Description style={{ fontSize: 45, fontWeight: 'bold' }}>
Emotion Primitives
</Description>
<Image
source={{
uri: emotionLogo,
height: 150,
width: 150
}}
/>
</Container>
)
}
}

AppRegistry.registerComponent('ExampleApp', () => App);
```

## Theming

Use `emotion-theming` for theming support.

```js
import React from 'react'
import styled, { css } from '@emotion/native'

import { ThemeProvider } from 'emotion-theming'

const theme = {
color: 'hotpink',
backgroundColor: 'purple'
}

const Container = styled.View`
display: flex;
justify-content: center;
align-items: center;
margin: 50px;
border: 5px solid red;
background-color: ${props => props.theme.backgroundColor};
`

const Description = styled.Text({
color: 'hotpink'
})

const Image = styled.Image`
padding: 40px;
`

const emotionLogo =
'https://cdn.rawgit.com/emotion-js/emotion/master/emotion.png'

class App extends React.Component {
render() {
return (
<ThemeProvider theme={theme}>
<Container
style={css`
border-radius: 10px;
`}
>
<Description style={{ fontSize: 45, fontWeight: 'bold' }}>
Emotion Primitives
</Description>
<Image
source={{
uri: emotionLogo,
height: 150,
width: 150
}}
/>
</Container>
</ThemeProvider>
)
}
}
```

## Usage with `react-360`

`@emotion/native` can also be used with `react-360` for styling VR applications. Check out [this](https://facebook.github.io/react-360/docs/setup.html) guide for setting up a `react-360` project.

### Example

```js
import React from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-360';
import styled from '@emotion/native';

const StyledName = styled.Text`
font-size: 40px;
color: hotpink;
`;

export default class App extends React.Component {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation is different here than in other examples (in this file), this could be enforced with prettier + lint-staged on precommit hook (with husky) as it can handle .md too, cc @mitchellhamilton

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd be great. This will also resolve all the formatting issues!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Andarist If you could submit a PR for it, that would be great!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to remember to do that later :)

render() {
return (
<View style={styles.panel}>
<View style={styles.greetingBox}>
<StyledName>Emotion Native</StyledName>
</View>
</View>
);
}
}

const styles = StyleSheet.create({
panel: {
// Fill the entire surface
width: 1000,
height: 600,
backgroundColor: 'rgba(255, 255, 255, 0.4)',
justifyContent: 'center',
alignItems: 'center',
},
greetingBox: {
padding: 20,
backgroundColor: '#000000',
borderColor: '#639dda',
borderWidth: 2,
},
greeting: {
fontSize: 30,
},
});

AppRegistry.registerComponent('App', () => App);

```
27 changes: 27 additions & 0 deletions packages/native/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "@emotion/native",
"version": "1.0.0",
"description": "Style and render React Native components using emotion",
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
"files": ["src", "dist"],
"devDependencies": {
"emotion-theming": "^9.2.5",
"react": "^16.4.1",
"react-native": "^0.56.0"
},
"dependencies": {
"@emotion/primitives-core": "1.0.0"
},
"peerDependencies": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldnt a peer on react be here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops! Done ✅

"prop-types": "15.x",
"react-native": "^0.56.0"
},
"homepage": "https://emotion.sh",
"license": "MIT",
"repository": "https://github.com/emotion-js/emotion/tree/master/packages/native",
"keywords": ["styles", "emotion", "react", "css", "css-in-js", "native"],
"bugs": {
"url": "https://github.com/emotion-js/emotion/issues"
}
}
71 changes: 71 additions & 0 deletions packages/native/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import reactNative from 'react-native'
import { createCss } from '@emotion/primitives-core'

import { styled } from './styled'

const css = createCss(reactNative.StyleSheet)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be annotated with PURE


const components = [
'ActivityIndicator',
'ActivityIndicatorIOS',
'ART',
'Button',
'DatePickerIOS',
'DrawerLayoutAndroid',
'Image',
'ImageBackground',
'ImageEditor',
'ImageStore',
'KeyboardAvoidingView',
'ListView',
'MapView',
'Modal',
'NavigatorIOS',
'Picker',
'PickerIOS',
'ProgressBarAndroid',
'ProgressViewIOS',
'ScrollView',
'SegmentedControlIOS',
'Slider',
'SliderIOS',
'SnapshotViewIOS',
'Switch',
'RecyclerViewBackedScrollView',
'RefreshControl',
'SafeAreaView',
'StatusBar',
'SwipeableListView',
'SwitchAndroid',
'SwitchIOS',
'TabBarIOS',
'Text',
'TextInput',
'ToastAndroid',
'ToolbarAndroid',
'Touchable',
'TouchableHighlight',
'TouchableNativeFeedback',
'TouchableOpacity',
'TouchableWithoutFeedback',
'View',
'ViewPagerAndroid',
'WebView',
'FlatList',
'SectionList',
'VirtualizedList'
]

components.forEach(comp =>
Object.defineProperty(styled, comp, {
enumerable: true,
configurable: false,
get() {
return styled(reactNative[comp])
}
})
)

export { css }

export default /* #__PURE__ */ styled
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesnt make much sense here, #__PURE__ comments are useful for call expressions, this is just exported identifier

Not sure what actual value it gives in context of react-native (it's not that much bytes-constrained as web), it certainly won't hurt, but would have to be used differently.

I would convert this to:

export default components.reduce((acc, comp) =>
  Object.defineProperty(acc, comp, {
    enumerable: true,
    configurable: false,
    get() {
      return styled(reactNative[comp])
    }
  })
, styled)

This would make it self contained expression that can be more safely annotated with PURE.

You could also use my plugin to insert those PURE annotations automatically - https://github.com/Andarist/babel-plugin-annotate-pure-calls , but ofc that's not obligatory 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I'll refactor the code to use your solution.

9 changes: 9 additions & 0 deletions packages/native/src/styled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { StyleSheet } from 'react-native'
import { createStyled } from '@emotion/primitives-core'

/**
* a function that returns a styled component which render styles in React Native
*/
let styled = createStyled(StyleSheet)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is also a good candidate for PURE

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there any side-effects of using PURE here ?


export { styled }
Loading