From 892334131f1aa8dc0240eb8992c288d94de090a6 Mon Sep 17 00:00:00 2001 From: Atticus White Date: Mon, 31 Jul 2017 13:27:45 -0400 Subject: [PATCH 1/4] use ListView over SectionList for backward compatability --- .../preview/components/StoryListView/index.js | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/app/react-native/src/preview/components/StoryListView/index.js b/app/react-native/src/preview/components/StoryListView/index.js index 7340cd5971d..5f36b9b3d47 100644 --- a/app/react-native/src/preview/components/StoryListView/index.js +++ b/app/react-native/src/preview/components/StoryListView/index.js @@ -1,5 +1,5 @@ import React, { Component, PropTypes } from 'react'; -import { SectionList, View, Text, TouchableOpacity } from 'react-native'; +import { ListView, View, Text, TouchableOpacity } from 'react-native'; import style from './style'; const SectionHeader = ({ title, selected }) => @@ -30,8 +30,14 @@ ListItem.propTypes = { export default class StoryListView extends Component { constructor(props, ...args) { super(props, ...args); + + const ds = new ListView.DataSource({ + rowHasChanged: (r1, r2) => r1 !== r2, + sectionHeaderHasChanged: (s1, s2) => s1 !== s2, + }); + this.state = { - sections: [], + dataSource: ds.cloneWithRowsAndSections({}), }; this.storyAddedHandler = this.handleStoryAdded.bind(this); @@ -56,16 +62,20 @@ export default class StoryListView extends Component { handleStoryAdded() { if (this.props.stories) { const data = this.props.stories.dumpStoryBook(); - this.setState({ - sections: data.map(section => ({ - key: section.kind, - title: section.kind, - data: section.stories.map(story => ({ + + const sections = data.reduce( + (map, section) => ({ + ...map, + [section.kind]: section.stories.map(story => ({ key: story, - kind: section.kind, name: story, + kind: section.kind, })), - })), + }), + {} + ); + this.setState({ + dataSource: this.state.dataSource.cloneWithRowsAndSections(sections), }); } } @@ -76,9 +86,9 @@ export default class StoryListView extends Component { render() { return ( - + renderRow={item => this.changeStory(item.kind, item.name)} />} - renderSectionHeader={({ section }) => - } - sections={this.state.sections} + renderSectionHeader={(sectionData, sectionName) => + } + dataSource={this.state.dataSource} stickySectionHeadersEnabled={false} /> ); From 92b397f8441826b5b641c73777b5dab4b9c5098f Mon Sep 17 00:00:00 2001 From: Atticus White Date: Mon, 31 Jul 2017 14:33:51 -0400 Subject: [PATCH 2/4] polyfills for earlier ReactNative versions - StyleSheet.absoluteFillObject polyfill - Polyfill for min/max width/height style rules through a component --- .../preview/components/OnDeviceUI/style.js | 2 +- .../preview/components/StoryListView/index.js | 36 ++++---- .../preview/components/StoryListView/style.js | 1 - .../components/polyfills/MinMaxView.js | 82 +++++++++++++++++++ .../components/polyfills/StyleSheet.js | 18 ++++ .../src/preview/components/polyfills/index.js | 2 + 6 files changed, 124 insertions(+), 17 deletions(-) create mode 100644 app/react-native/src/preview/components/polyfills/MinMaxView.js create mode 100644 app/react-native/src/preview/components/polyfills/StyleSheet.js create mode 100644 app/react-native/src/preview/components/polyfills/index.js diff --git a/app/react-native/src/preview/components/OnDeviceUI/style.js b/app/react-native/src/preview/components/OnDeviceUI/style.js index a69912eac87..9f29411dc9d 100644 --- a/app/react-native/src/preview/components/OnDeviceUI/style.js +++ b/app/react-native/src/preview/components/OnDeviceUI/style.js @@ -1,4 +1,4 @@ -import { StyleSheet } from 'react-native'; +import { StyleSheet } from '../polyfills'; export default { main: { diff --git a/app/react-native/src/preview/components/StoryListView/index.js b/app/react-native/src/preview/components/StoryListView/index.js index 5f36b9b3d47..33c79519363 100644 --- a/app/react-native/src/preview/components/StoryListView/index.js +++ b/app/react-native/src/preview/components/StoryListView/index.js @@ -1,5 +1,6 @@ import React, { Component, PropTypes } from 'react'; import { ListView, View, Text, TouchableOpacity } from 'react-native'; +import { MinMaxView } from '../polyfills'; import style from './style'; const SectionHeader = ({ title, selected }) => @@ -86,21 +87,26 @@ export default class StoryListView extends Component { render() { return ( - - this.changeStory(item.kind, item.name)} - />} - renderSectionHeader={(sectionData, sectionName) => - } - dataSource={this.state.dataSource} - stickySectionHeadersEnabled={false} - /> + + + this.changeStory(item.kind, item.name)} + />} + renderSectionHeader={(sectionData, sectionName) => + } + dataSource={this.state.dataSource} + stickySectionHeadersEnabled={false} + /> + ); } } diff --git a/app/react-native/src/preview/components/StoryListView/style.js b/app/react-native/src/preview/components/StoryListView/style.js index 0a37211c86f..252b50dd69c 100644 --- a/app/react-native/src/preview/components/StoryListView/style.js +++ b/app/react-native/src/preview/components/StoryListView/style.js @@ -1,7 +1,6 @@ export default { list: { flex: 1, - maxWidth: 250, }, header: { paddingTop: 4, diff --git a/app/react-native/src/preview/components/polyfills/MinMaxView.js b/app/react-native/src/preview/components/polyfills/MinMaxView.js new file mode 100644 index 00000000000..42b13dcb124 --- /dev/null +++ b/app/react-native/src/preview/components/polyfills/MinMaxView.js @@ -0,0 +1,82 @@ +import React, { Component, PropTypes } from 'react'; + +/** + * Certain features are only available in later ReactNative version. + * + * This component polfyills the min/max width/height features of the StyleSheet. + * + * Example usage: + * ``` + * + * + * + */ +class MinMaxViewPolyfill extends Component { + static propTypes = { + children: PropTypes.node.isRequired, + onLayout: PropTypes.func, + minWidth: PropTypes.number, + maxWidth: PropTypes.number, + minHeight: PropTypes.number, + maxHeight: PropTypes.number, + }; + + static defaultProps = { + onLayout: null, + minWidth: null, + maxWidth: null, + minHeight: null, + maxHeight: null, + }; + + constructor(...args) { + super(...args); + this.onLayout = this.onLayout.bind(this); + this.state = { + minMaxStyle: null, + }; + } + + onLayout(e) { + const { width, height } = e.nativeEvent.layout; + + const minMaxStyle = {}; + + if (this.props.minWidth !== null) { + minMaxStyle.width = Math.max(this.props.minWidth, width); + } + if (this.props.maxWidth !== null) { + minMaxStyle.width = Math.min(this.props.maxWidth, width); + } + + if (this.props.minHeight !== null) { + minMaxStyle.height = Math.max(this.props.minHeight, height); + } + if (this.props.maxHeight !== null) { + minMaxStyle.height = Math.min(this.props.maxHeight, height); + } + + this.setState({ minMaxStyle }); + + if (this.props.onLayout) { + this.props.onLayout(e); + } + } + + render() { + // Eslint ignored below as `style` is a tricky propType to define when a child is arbitrary. + const { children, style, ...props } = this.props; // eslint-disable-line react/prop-types + return React.cloneElement(React.Children.only(children), { + ...props, + onLayout: this.onLayout, + style: [style, this.state.minMaxStyle], + }); + } +} + +export default MinMaxViewPolyfill; diff --git a/app/react-native/src/preview/components/polyfills/StyleSheet.js b/app/react-native/src/preview/components/polyfills/StyleSheet.js new file mode 100644 index 00000000000..60cff07a91a --- /dev/null +++ b/app/react-native/src/preview/components/polyfills/StyleSheet.js @@ -0,0 +1,18 @@ +import { StyleSheet } from 'react-native'; + +/** + * Certain features of StyleSheet are only available in later ReactNative version. + * + * This module polyfills: + * - absoluteFillObject + */ +export default { + ...StyleSheet, + absoluteFillObject: { + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + left: 0, + }, +}; diff --git a/app/react-native/src/preview/components/polyfills/index.js b/app/react-native/src/preview/components/polyfills/index.js new file mode 100644 index 00000000000..83a56bbd6bb --- /dev/null +++ b/app/react-native/src/preview/components/polyfills/index.js @@ -0,0 +1,2 @@ +export { default as MinMaxView } from './MinMaxView'; +export { default as StyleSheet } from './StyleSheet'; From 38ef3f60d674656ce4b3331a7c8114378c7879a7 Mon Sep 17 00:00:00 2001 From: Atticus White Date: Mon, 31 Jul 2017 18:20:19 -0400 Subject: [PATCH 3/4] react-native-compat dependency for earlier RN versions --- app/react-native/package.json | 1 + .../preview/components/OnDeviceUI/style.js | 2 +- .../preview/components/StoryListView/index.js | 2 +- .../components/polyfills/MinMaxView.js | 82 ------------------- .../components/polyfills/StyleSheet.js | 18 ---- .../src/preview/components/polyfills/index.js | 2 - 6 files changed, 3 insertions(+), 104 deletions(-) delete mode 100644 app/react-native/src/preview/components/polyfills/MinMaxView.js delete mode 100644 app/react-native/src/preview/components/polyfills/StyleSheet.js delete mode 100644 app/react-native/src/preview/components/polyfills/index.js diff --git a/app/react-native/package.json b/app/react-native/package.json index 5428ef02a6c..bbe9de69be8 100644 --- a/app/react-native/package.json +++ b/app/react-native/package.json @@ -56,6 +56,7 @@ "json-loader": "^0.5.4", "json5": "^0.5.1", "postcss-loader": "^2.0.5", + "react-native-compat": "0.0.1", "shelljs": "^0.7.8", "style-loader": "^0.17.0", "url-loader": "^0.5.8", diff --git a/app/react-native/src/preview/components/OnDeviceUI/style.js b/app/react-native/src/preview/components/OnDeviceUI/style.js index 9f29411dc9d..d4126988f42 100644 --- a/app/react-native/src/preview/components/OnDeviceUI/style.js +++ b/app/react-native/src/preview/components/OnDeviceUI/style.js @@ -1,4 +1,4 @@ -import { StyleSheet } from '../polyfills'; +import { StyleSheet } from 'react-native-compat'; export default { main: { diff --git a/app/react-native/src/preview/components/StoryListView/index.js b/app/react-native/src/preview/components/StoryListView/index.js index 33c79519363..45babdb44c7 100644 --- a/app/react-native/src/preview/components/StoryListView/index.js +++ b/app/react-native/src/preview/components/StoryListView/index.js @@ -1,6 +1,6 @@ import React, { Component, PropTypes } from 'react'; import { ListView, View, Text, TouchableOpacity } from 'react-native'; -import { MinMaxView } from '../polyfills'; +import { MinMaxView } from 'react-native-compat'; import style from './style'; const SectionHeader = ({ title, selected }) => diff --git a/app/react-native/src/preview/components/polyfills/MinMaxView.js b/app/react-native/src/preview/components/polyfills/MinMaxView.js deleted file mode 100644 index 42b13dcb124..00000000000 --- a/app/react-native/src/preview/components/polyfills/MinMaxView.js +++ /dev/null @@ -1,82 +0,0 @@ -import React, { Component, PropTypes } from 'react'; - -/** - * Certain features are only available in later ReactNative version. - * - * This component polfyills the min/max width/height features of the StyleSheet. - * - * Example usage: - * ``` - * - * - * - */ -class MinMaxViewPolyfill extends Component { - static propTypes = { - children: PropTypes.node.isRequired, - onLayout: PropTypes.func, - minWidth: PropTypes.number, - maxWidth: PropTypes.number, - minHeight: PropTypes.number, - maxHeight: PropTypes.number, - }; - - static defaultProps = { - onLayout: null, - minWidth: null, - maxWidth: null, - minHeight: null, - maxHeight: null, - }; - - constructor(...args) { - super(...args); - this.onLayout = this.onLayout.bind(this); - this.state = { - minMaxStyle: null, - }; - } - - onLayout(e) { - const { width, height } = e.nativeEvent.layout; - - const minMaxStyle = {}; - - if (this.props.minWidth !== null) { - minMaxStyle.width = Math.max(this.props.minWidth, width); - } - if (this.props.maxWidth !== null) { - minMaxStyle.width = Math.min(this.props.maxWidth, width); - } - - if (this.props.minHeight !== null) { - minMaxStyle.height = Math.max(this.props.minHeight, height); - } - if (this.props.maxHeight !== null) { - minMaxStyle.height = Math.min(this.props.maxHeight, height); - } - - this.setState({ minMaxStyle }); - - if (this.props.onLayout) { - this.props.onLayout(e); - } - } - - render() { - // Eslint ignored below as `style` is a tricky propType to define when a child is arbitrary. - const { children, style, ...props } = this.props; // eslint-disable-line react/prop-types - return React.cloneElement(React.Children.only(children), { - ...props, - onLayout: this.onLayout, - style: [style, this.state.minMaxStyle], - }); - } -} - -export default MinMaxViewPolyfill; diff --git a/app/react-native/src/preview/components/polyfills/StyleSheet.js b/app/react-native/src/preview/components/polyfills/StyleSheet.js deleted file mode 100644 index 60cff07a91a..00000000000 --- a/app/react-native/src/preview/components/polyfills/StyleSheet.js +++ /dev/null @@ -1,18 +0,0 @@ -import { StyleSheet } from 'react-native'; - -/** - * Certain features of StyleSheet are only available in later ReactNative version. - * - * This module polyfills: - * - absoluteFillObject - */ -export default { - ...StyleSheet, - absoluteFillObject: { - position: 'absolute', - top: 0, - right: 0, - bottom: 0, - left: 0, - }, -}; diff --git a/app/react-native/src/preview/components/polyfills/index.js b/app/react-native/src/preview/components/polyfills/index.js deleted file mode 100644 index 83a56bbd6bb..00000000000 --- a/app/react-native/src/preview/components/polyfills/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as MinMaxView } from './MinMaxView'; -export { default as StyleSheet } from './StyleSheet'; From 73ac57e39f5be1f4d55db33f37125bfe80820ba3 Mon Sep 17 00:00:00 2001 From: Atticus White Date: Mon, 31 Jul 2017 19:22:00 -0400 Subject: [PATCH 4/4] react-native-compat@0.0.2 --- app/react-native/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/react-native/package.json b/app/react-native/package.json index bbe9de69be8..cf3b5858703 100644 --- a/app/react-native/package.json +++ b/app/react-native/package.json @@ -56,7 +56,7 @@ "json-loader": "^0.5.4", "json5": "^0.5.1", "postcss-loader": "^2.0.5", - "react-native-compat": "0.0.1", + "react-native-compat": "0.0.2", "shelljs": "^0.7.8", "style-loader": "^0.17.0", "url-loader": "^0.5.8",