From e8eab9b3eca65d2a480455c6507830ac3a46261b Mon Sep 17 00:00:00 2001 From: Louis Lagrange Date: Sat, 28 Oct 2017 17:32:21 +0200 Subject: [PATCH] [add] ImageBackground component Close #696 --- src/components/Image/ImageBackground.js | 79 +++++++++++++++++++ .../Image/__tests__/ImageBackground-test.js | 36 +++++++++ src/module.js | 3 + 3 files changed, 118 insertions(+) create mode 100644 src/components/Image/ImageBackground.js create mode 100644 src/components/Image/__tests__/ImageBackground-test.js diff --git a/src/components/Image/ImageBackground.js b/src/components/Image/ImageBackground.js new file mode 100644 index 00000000..23ebd8b2 --- /dev/null +++ b/src/components/Image/ImageBackground.js @@ -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 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 ( + + overwrites width and height styles + // (which is not quite correct), and these styles conflict with explicitly set styles + // of and with our internal layout model here. + // So, we have to proxy/reapply these styles explicitly for actual component. + // This workaround should be removed after implementing proper support of + // intrinsic content size of the . + width: style.width, + height: style.height + }, + imageStyle + ]} + /> + {children} + + ); + } +} + +export default ImageBackground; diff --git a/src/components/Image/__tests__/ImageBackground-test.js b/src/components/Image/__tests__/ImageBackground-test.js new file mode 100644 index 00000000..71550b30 --- /dev/null +++ b/src/components/Image/__tests__/ImageBackground-test.js @@ -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( + + Hello World! + + ); + 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(); + 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(); + expect(component.prop('style')).toEqual(style); + }); + }); +}); diff --git a/src/module.js b/src/module.js index d33946e9..5ac67f35 100644 --- a/src/module.js +++ b/src/module.js @@ -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,