Skip to content

Commit

Permalink
feat(MultiWords): Adding MultiWords support (#25)
Browse files Browse the repository at this point in the history
* Adding multiwords

* MultiWords and tests

* refacto(examples): Using only one folder example (#26)

* WIP

* Upgrading create-react-app

* Adding multiwords

* MultiWords and tests

* Fix conflicts

* remove package-lock

* Fix shine for MultiWords

* Fix multiwords shine
  • Loading branch information
Marvin Frachet authored Oct 18, 2017
1 parent d24f404 commit 4dcbcfb
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 38 deletions.
5 changes: 5 additions & 0 deletions Example/.expo/packager-info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"expoServerPort": null,
"packagerPort": null,
"packagerPid": null
}
9 changes: 9 additions & 0 deletions Example/.expo/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"hostType": "tunnel",
"lanType": "ip",
"dev": true,
"strict": false,
"minify": false,
"urlType": "exp",
"urlRandomness": null
}
53 changes: 30 additions & 23 deletions Example/components/Card.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,67 @@
import React, { PropTypes } from 'react';
import Placeholder from 'rn-placeholder';
import { View, Text, Image, StyleSheet } from 'react-native';
import React, { PropTypes } from "react";
import Placeholder from "rn-placeholder";
import { View, Text, Image, StyleSheet } from "react-native";

const DEFAULT_SIZE = 12;
const IMAGE_SIZE = 40;
const styles = StyleSheet.create({
card: {
padding: 20,
backgroundColor: '#ffffff',
backgroundColor: "#ffffff",
borderRadius: 2,
shadowColor: '#000000',
shadowColor: "#000000",
shadowOpacity: 0.3,
shadowRadius: 1,
shadowOffset: {
height: 1,
width: 0.3,
width: 0.3
},
marginBottom: DEFAULT_SIZE,
marginRight: DEFAULT_SIZE,
marginLeft: DEFAULT_SIZE,
marginLeft: DEFAULT_SIZE
},
media: {
height: IMAGE_SIZE,
width: IMAGE_SIZE,
marginRight: DEFAULT_SIZE,
marginRight: DEFAULT_SIZE
},
container: {
flex: 1,
flexDirection: 'row',
flexDirection: "row"
},
username: {
flex: 1,
color: '#3F51B5',
fontSize: 16,
color: "#3F51B5",
fontSize: 16
},
date: {
color: '#aaaaaa',
fontSize: 12,
color: "#aaaaaa",
fontSize: 12
},
content: {
marginTop: DEFAULT_SIZE,
lineHeight: DEFAULT_SIZE * 2,
color: '#444444',
},
color: "#444444"
}
});

const words = [
{
width: "20%"
},
{
width: "40%"
},
{
width: "40%"
}
];

export default function Card({ image, username, content, isLoaded, date }) {
const heightStyle = { height: 150 };
return (
<View style={[styles.card, !isLoaded && heightStyle]}>
<Placeholder.ImageContent
onReady={isLoaded}
lineNumber={2}
animate="shine"
lastLineWidth="40%"
>
<Placeholder.MultiWords onReady={isLoaded} words={words} animate="fade">
<View>
<View style={styles.container}>
<Image source={{ uri: image }} style={styles.media} />
Expand All @@ -65,7 +72,7 @@ export default function Card({ image, username, content, isLoaded, date }) {
</View>
<Text style={styles.content}>{content}</Text>
</View>
</Placeholder.ImageContent>
</Placeholder.MultiWords>
</View>
);
}
Expand All @@ -75,5 +82,5 @@ Card.propTypes = {
username: PropTypes.string.isRequired,
content: PropTypes.string.isRequired,
date: PropTypes.string.isRequired,
isLoaded: PropTypes.bool.isRequired,
isLoaded: PropTypes.bool.isRequired
};
30 changes: 15 additions & 15 deletions src/animation/shine.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React from 'react';
import { Animated, View, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';
import React from "react";
import { Animated, View, StyleSheet } from "react-native";
import PropTypes from "prop-types";

const styles = StyleSheet.create({
shine: {
width: 30,
position: 'absolute',
height: '100%',
backgroundColor: '#ffffff',
opacity: 0.4,
},
position: "absolute",
height: "100%",
backgroundColor: "#ffffff",
opacity: 0.4
}
});
/**
* Create a repetitive Shine animation
Expand All @@ -22,34 +22,34 @@ const Shine = ({ children }) => {
Animated.sequence([
Animated.timing(animation, {
toValue: 100,
duration: 750,
}),
duration: 750
})
]).start(() => {
start();
});
}

start();

const left = animation.interpolate({
const marginLeft = animation.interpolate({
inputRange: [0, 100],
outputRange: ['0%', '100%'],
outputRange: ["0%", "100%"]
});

return (
<View>
{children}
<Animated.View style={[styles.shine, { left }]} />
<Animated.View style={[styles.shine, { marginLeft }]} />
</View>
);
};

Shine.propTypes = {
children: PropTypes.shape({}),
children: PropTypes.shape({})
};

Shine.defaultProps = {
children: null,
children: null
};

export default Shine;
82 changes: 82 additions & 0 deletions src/multiWords/__tests__/multiWords.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React from 'react';
import { View } from 'react-native';
import { shallow } from 'enzyme';
import MultiWords from './../multiWords';
import Line from './../../line/line';

const TEXT_SIZE = 12;
const words = [
{
width: '20%',
color: 'red',
},
{
width: '10%',
color: 'blue',
},
{
width: '30%',
color: 'green',
},
];

/** @test {MultiWords#render} */
describe('MultiWords#render', () => {
let wrapper;

beforeEach(() => {
wrapper = shallow(<MultiWords words={words} textSize={TEXT_SIZE} />);
});

it('shouldnt have any line', () => {
wrapper = shallow(<MultiWords />);
expect(wrapper.find(Line).length).toEqual(0);
});

it('should have 3 lines', () => {
expect(wrapper.find(Line).length).toEqual(3);
});

words.forEach((word, index) => {
it(`should have the ${index} word with props textSize equals to ${TEXT_SIZE}`, () => {
expect(
wrapper
.find(Line)
.at(index)
.prop('textSize'),
).toEqual(TEXT_SIZE);
});

it(`should have the ${index} word with props colors equals to ${word.color}`, () => {
expect(
wrapper
.find(Line)
.at(index)
.prop('color'),
).toEqual(word.color);
});

it(`should have the ${index + 1} View with props style.width equals to ${word.width}`, () => {
expect(
wrapper
.find(View)
.at(index + 1)
.prop('style')[1].width,
).toEqual(word.width);
});

it(`should have the ${index + 1} View with props style to have a special border style`, () => {
const realIndex = index + 1;
const view = wrapper.find(View).at(realIndex);
const lastIndex = words.length;
const result =
lastIndex === realIndex
? false
: {
borderRightWidth: 12,
borderRightColor: 'transparent',
};
expect(view.prop('style')[0]).toEqual(result);
});
});
});
49 changes: 49 additions & 0 deletions src/multiWords/multiWords.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "react";
import { View, StyleSheet } from "react-native";
import PropTypes from "prop-types";
import Line from "./../line/line";

const styles = StyleSheet.create({
container: {
flexDirection: "row"
}
});

function MultiWords({ words, textSize }) {
const borderStyle = {
borderRightWidth: textSize,
borderRightColor: "transparent"
};

const lastIndex = words.length - 1;

return (
<View style={styles.container}>
{words.map((word, index) => (
<View
key={index}
style={[lastIndex !== index && borderStyle, { width: word.width }]}
>
<Line textSize={textSize} color={word.color} />
</View>
))}
</View>
);
}

MultiWords.propTypes = {
words: PropTypes.arrayOf(
PropTypes.shape({
color: PropTypes.string,
width: PropTypes.string.isRequired
})
),
textSize: PropTypes.number
};

MultiWords.defaultProps = {
words: [],
textSize: 12
};

export default MultiWords;
2 changes: 2 additions & 0 deletions src/placeholder.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Paragraph from './paragraph/paragraph';
import Media from './media/media';
import Line from './line/line';
import ImageContent from './imageContent/imageContent';
import MultiWords from './multiWords/multiWords';

/**
* Export the placeholder
Expand All @@ -12,5 +13,6 @@ export default {
Paragraph: connect(Paragraph),
Media: connect(Media),
Line: connect(Line),
MultiWords: connect(MultiWords),
connect,
};

0 comments on commit 4dcbcfb

Please sign in to comment.