Skip to content

Commit

Permalink
Merge pull request #23 from ExodusMovement/ain/perf
Browse files Browse the repository at this point in the history
Merge `ain/perf` into master to make `master` the default branch
  • Loading branch information
sparten11740 authored Oct 22, 2024
2 parents fd670a0 + c2d8125 commit 5855163
Show file tree
Hide file tree
Showing 58 changed files with 1,285 additions and 1,246 deletions.
4 changes: 0 additions & 4 deletions .babelrc

This file was deleted.

33 changes: 33 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Checks

on:
push:
branches: ['master']
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true

jobs:
check:
runs-on: ubuntu-latest
name: ${{ matrix.name }}
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
include:
- name: Build
cmd: yarn build
- name: Test
cmd: yarn test
- name: Types
cmd: yarn test:types
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- uses: actions/setup-node@aca7b64a59c0063db8564e0ffdadd3887f1cbae5
with:
node-version-file: .nvmrc
- run: yarn
- run: ${{ matrix.cmd }}
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
.DS_Store
coverage/
lib/
node_modules/
yarn-debug.log*
yarn-error.log*
yarn.lock
.idea
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18.17.1
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: node_js

node_js:
- "lts/carbon"
- "lts/*"

cache:
directories:
Expand Down
34 changes: 24 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
# 0.0.16

- fix: support `undefined` style in array of styles https://github.com/ExodusMovement/shakl/pull/15
- refactor: move jest config outside published files https://github.com/ExodusMovement/shakl/pull/16

# 0.0.15

- Feat: add support to composition react-native-reanimated styles. https://github.com/ExodusMovement/shakl/pull/13

# 0.0.12

- **Breaking:** Removed `multi` support for better perf (rarely used).
- **Breaking:** Removed style arrays `style={[{..}, {..}]}` support for better perf (rarely used).

# 0.0.11

- **Breaking:** Removed theme support
- **Breaking:** Removed theme support.
- Support passing default styles to the factory.
- Support passing fixed styles to the factory.

Expand All @@ -13,9 +27,9 @@
- Support dynamic props in `attrs()`. By default `attrs()` only overwrites the `defaultProps` of the component, now when you pass it a function it will allow for computed props.

```js
const MyText = styled.Text({ color: 'red' }).attrs(props => ({
const MyText = styled.Text({ color: 'red' }).attrs((props) => ({
numberOfLines: props.oneLiner ? 1 : 3
}));
}))

// equivalent to
<MyText /> // <Text style={{ color: 'red }} numberOfLines={3} />
Expand All @@ -26,8 +40,8 @@ const MyText = styled.Text({ color: 'red' }).attrs(props => ({
- Support passing a ref to a child in `withChild()` through the parent's `childRef` prop.

```js
const CardText = styled.Text({ color: 'blue' });
const Card = styled.View({ flex: 1 }).withChild(CardText, { numberOfLines: 3 });
const CardText = styled.Text({ color: 'blue' })
const Card = styled.View({ flex: 1 }).withChild(CardText, { numberOfLines: 3 })

// equivalent to
const Card = ({ children, childRef, ...props }) => (
Expand All @@ -36,19 +50,19 @@ const Card = ({ children, childRef, ...props }) => (
{children}
</Text>
</View>
);
)

// you can also access parent props
const Card = styled.View({ flex: 1 }).withChild(CardText, parentProps => ({
const Card = styled.View({ flex: 1 }).withChild(CardText, (parentProps) => ({
numberOfLines: parentProps.onLiner ? 1 : 3
}));
}))

<Card>Hello World!</Card>;
<Card>Hello World!</Card>
// <View ..>
// <Text ..>{children}</Text>
// </View>

<Card onLiner>Hello World!</Card>;
<Card onLiner>Hello World!</Card>
// <View ..>
// <Text numberOfLines={1} ..>{children}</Text>
// </View>
Expand Down
102 changes: 42 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
- Supports static and [dynamic styles](#dynamic-styles) (based on props).
- Supports component extension using [`extend()`](#extending-styles) and [`attrs()`](#custom-props).
- Supports component composition using [`withComponent()`](#wrapping-another-component) and [`withChild()`](#wrapping-a-child).
- Supports [styling other style props](#multiple-style-props), e.g. `contentContainerStyle`, you can "truly" style any component.
- Uses regular inline styles under the hood (performance boost).
- Works [with React DOM](#usage-with-react-dom) too, same simple API, same benefits.
- No dependencies, all just React goodness.
Expand All @@ -33,32 +32,32 @@ yarn add shakl
### Creating a styled component

```js
import styled from 'shakl';
import styled from 'shakl'

const Foo = styled(View)({ flex: 1 });
const Foo = styled(View)({ flex: 1 })

<Foo />; // <View style={{ flex: 1 }} />
<Foo /> // <View style={{ flex: 1 }} />
```

### Primitives

By default, React Native's `View`, `Text`, and `TouchableOpacity` are exposed to you, they can be directly used.

```js
styled.View({ flex: 1 });
styled.Text({ color: 'blue' });
styled.Touchable({ padding: 10 });
styled.View({ flex: 1 })
styled.Text({ color: 'blue' })
styled.Touchable({ padding: 10 })

// equivalent to
styled(View)({ flex: 1 });
styled(Text)({ color: 'blue' });
styled(TouchableOpacity)({ padding: 10 });
styled(View)({ flex: 1 })
styled(Text)({ color: 'blue' })
styled(TouchableOpacity)({ padding: 10 })
```

### Dynamic styles

```js
const Foo = styled.View(props => ({ padding: props.padded ? 10 : 0 }));
const Foo = styled.View((props) => ({ padding: props.padded ? 10 : 0 }))

<Foo /> // <View style={{ padding: 0 }} />
<Foo padded /> // <View style={{ padding: 10 }} />
Expand All @@ -67,30 +66,30 @@ const Foo = styled.View(props => ({ padding: props.padded ? 10 : 0 }));
### Extending styles

```js
const Title = styled.Text({ fontSize: 20 });
const Title = styled.Text({ fontSize: 20 })
// <Text style={{ fontSize: 20 }} />

const BoldTitle = Title.extend({ fontWeight: 'bold' });
const BoldTitle = Title.extend({ fontWeight: 'bold' })
// <Text style={{ fontSize: 20, fontWeight: 'bold' }} />

const RedBoldTitle = BoldTitle.extend({ color: 'red' });
const RedBoldTitle = BoldTitle.extend({ color: 'red' })
// <Text style={{ fontSize: 20, fontWeight: 'bold', color: 'red' }} />

const RedHeadline = styled(RedBoldTitle)({ fontSize: 28 }); // this works too
const RedHeadline = styled(RedBoldTitle)({ fontSize: 28 }) // this works too
```

### Custom props

```js
const Foo = styled.Text({ color: 'blue' }).attrs({ numberOfLines: 1 });
// <Text style={{ color: 'blue' }} numberOfLines={1} />;
const Foo = styled.Text({ color: 'blue' }).attrs({ numberOfLines: 1 })
// <Text style={{ color: 'blue' }} numberOfLines={1} />

// attrs({ .. }) only overwrites the `defaultProps` of the component
// for dynamic props however we can pass it a function

const MyText = styled.Text({ color: 'red' }).attrs(props => ({
const MyText = styled.Text({ color: 'red' }).attrs((props) => ({
numberOfLines: props.oneLiner ? 1 : 3
}));
}))

// equivalent to
<MyText /> // <Text style={{ color: 'red }} numberOfLines={3} />
Expand All @@ -100,34 +99,34 @@ const MyText = styled.Text({ color: 'red' }).attrs(props => ({
### Wrapping another component

```js
const Button = styled(TouchableOpacity)({ flex: 1 });
const HighlightedButton = Button.withComponent(TouchableHighlight);
const Button = styled(TouchableOpacity)({ flex: 1 })
const HighlightedButton = Button.withComponent(TouchableHighlight)

// equivalent to
const Button = props => <TouchableOpacity style={{ flex: 1 }} {...props} />;
const Button = (props) => <TouchableOpacity style={{ flex: 1 }} {...props} />

const HighlightedButton = props => (
const HighlightedButton = (props) => (
<TouchableHighlight style={{ flex: 1 }} {...props} />
);
)
```

### Wrapping a child

```js
const ButtonText = styled.Text({ color: 'blue' });
const Button = styled.Touchable({ flex: 1 }).withChild(ButtonText);
const ButtonText = styled.Text({ color: 'blue' })
const Button = styled.Touchable({ flex: 1 }).withChild(ButtonText)

// equivalent to
const Button = ({ children, ...props }) => (
<TouchableOpacity style={{ flex: 1 }} {...props}>
<Text style={{ color: 'blue' }}>{children}</Text>
</TouchableOpacity>
);
)

// to pass a ref to a child, use the `childRef` prop on the parent
// to pass custom props to a child, use `.withChild(Child, childProps)`
const CardText = styled.Text({ color: 'blue' });
const Card = styled.View({ flex: 1 }).withChild(CardText, { numberOfLines: 3 });
const CardText = styled.Text({ color: 'blue' })
const Card = styled.View({ flex: 1 }).withChild(CardText, { numberOfLines: 3 })

// equivalent to
const Card = ({ children, childRef, ...props }) => (
Expand All @@ -136,12 +135,12 @@ const Card = ({ children, childRef, ...props }) => (
{children}
</Text>
</View>
);
)

// you can also access parent props by passing a function `.withChild(Child, parentProps => childProps)`
const Card = styled.View({ flex: 1 }).withChild(CardText, parentProps => ({
// you can also access parent props by passing a function `.withChild(Child, (parentProps) => childProps)`
const Card = styled.View({ flex: 1 }).withChild(CardText, (parentProps) => ({
numberOfLines: parentProps.onLiner ? 1 : 3
}));
}))

<Card />
// <View ..>
Expand All @@ -154,29 +153,12 @@ const Card = styled.View({ flex: 1 }).withChild(CardText, parentProps => ({
// </View>
```

### Multiple style props

```js
const Foo = styled(FlatList, { multi: true })({
style: { flex: 1 },
contentContainerStyle: { flex: 2 },
anotherStyleProp: { flex: 3 }
});

// dynamic styles work too
const Foo = styled(FlatList, { multi: true })({
style: ({ padded }) => ({ padding: padded ? 10 : 0 }),
contentContainerStyle: ({ padded }) => ({ padding: padded ? 20 : 0 }),
anotherStyleProp: ({ padded }) => ({ padding: padded ? 30 : 0 })
});
```

### Using refs

```js
const List = styled(FlatList)({ flex: 1 });
const List = styled(FlatList)({ flex: 1 })

<List ref={this.list} />; // based on React's forwardRef API (16.3.0)
<List ref={this.list} /> // based on React's forwardRef API (16.3.0)

// this.list.scrollTo({ y: 0 })
// or this.list.current.scrollTo({ y: 0 }) (with React.createRef)
Expand All @@ -185,33 +167,33 @@ const List = styled(FlatList)({ flex: 1 });
### Using a custom display name for debugging

```js
styled(View, { name: 'YetAnotherView' });
styled(View, { name: 'YetAnotherView' })
```

Default display names are `styled(View)`, `styled(Text)`, `styled(Touchable)`, `styled(Component)`, etc.

### Using propTypes and defaultProps

```js
const Foo = styled.View({ flex: 1 });
const Foo = styled.View({ flex: 1 })

Foo.propTypes = { .. };
Foo.defaultProps = { .. };
Foo.propTypes = { .. }
Foo.defaultProps = { .. }
```

### Usage with React DOM

Shakl is internally decoupled from React Native and can be used in the DOM.

```js
import styled from 'shakl';
import styled from 'shakl'

// no exposed primitives however, feel free to add your own
const styled.div = styled('div');
const styled.div = styled('div')

const Foo = styled.div({ background: '#eee' });
const Foo = styled.div({ background: '#eee' })

<Foo />; // <div style={{ background: '#eee' }} />
<Foo /> // <div style={{ background: '#eee' }} />
```

[![Edit shakl](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/52kw0jrn94?module=%2Fsrc%2FExample.js)
Expand Down
3 changes: 3 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
"presets": ["module:metro-react-native-babel-preset"],
}
Loading

0 comments on commit 5855163

Please sign in to comment.