[add] ImageBackground component

Close #696
This commit is contained in:
Louis Lagrange
2017-10-28 17:32:21 +02:00
committed by Nicolas Gallagher
parent 6bc76c3c92
commit e8eab9b3ec
3 changed files with 118 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
*/
import ensureComponentIsNative from '../Touchable/ensureComponentIsNative';
import Image from './';
import StyleSheet from '../../apis/StyleSheet';
import View from '../View';
import ViewPropTypes from '../View/ViewPropTypes';
import React, { Component } from 'react';
const emptyObject = {};
/**
* Very simple drop-in replacement for <Image> which supports nesting views.
*/
class ImageBackground extends Component<*> {
static propTypes = {
...Image.propTypes,
imageStyle: Image.propTypes.style,
style: ViewPropTypes.style
};
static defaultProps = {
style: emptyObject
};
setNativeProps(props: Object) {
// Work-around flow
const viewRef = this._viewRef;
if (viewRef) {
ensureComponentIsNative(viewRef);
viewRef.setNativeProps(props);
}
}
_viewRef: ?View = null;
_captureRef = (ref: View) => {
this._viewRef = ref;
};
render() {
const { children, style, imageStyle, imageRef, ...props } = this.props;
return (
<View ref={this._captureRef} style={style}>
<Image
{...props}
ref={imageRef}
style={[
StyleSheet.absoluteFill,
{
// Temporary Workaround:
// Current (imperfect yet) implementation of <Image> overwrites width and height styles
// (which is not quite correct), and these styles conflict with explicitly set styles
// of <ImageBackground> and with our internal layout model here.
// So, we have to proxy/reapply these styles explicitly for actual <Image> component.
// This workaround should be removed after implementing proper support of
// intrinsic content size of the <Image>.
width: style.width,
height: style.height
},
imageStyle
]}
/>
{children}
</View>
);
}
}
export default ImageBackground;

View File

@@ -0,0 +1,36 @@
/* eslint-env jasmine, jest */
import Image from '..';
import ImageBackground from '../ImageBackground';
import React from 'react';
import { shallow } from 'enzyme';
import Text from '../../Text';
describe('components/ImageBackground', () => {
describe('prop "children"', () => {
it('render child content', () => {
const component = shallow(
<ImageBackground>
<Text>Hello World!</Text>
</ImageBackground>
);
expect(component.find(Text)).toBeDefined();
});
});
describe('prop "imageStyle"', () => {
it('sets the style of the underlying Image', () => {
const imageStyle = { width: 40, height: 60 };
const component = shallow(<ImageBackground imageStyle={imageStyle} />);
expect(component.find(Image).prop('style')).toContain(imageStyle);
});
});
describe('prop "style"', () => {
it('sets the style of the container View', () => {
const style = { margin: 40 };
const component = shallow(<ImageBackground style={style} />);
expect(component.prop('style')).toEqual(style);
});
});
});

View File

@@ -30,6 +30,7 @@ import ActivityIndicator from './components/ActivityIndicator';
import Button from './components/Button';
import FlatList from './components/FlatList';
import Image from './components/Image';
import ImageBackground from './components/Image/ImageBackground';
import KeyboardAvoidingView from './components/KeyboardAvoidingView';
import ListView from './components/ListView';
import Modal from './components/Modal';
@@ -93,6 +94,7 @@ export {
Button,
FlatList,
Image,
ImageBackground,
KeyboardAvoidingView,
ListView,
Modal,
@@ -159,6 +161,7 @@ const ReactNative = {
Button,
FlatList,
Image,
ImageBackground,
KeyboardAvoidingView,
ListView,
Modal,