Skip to content

Commit

Permalink
Merge pull request #6448 from storybooks/react-native/typescript
Browse files Browse the repository at this point in the history
Migrate app/react-native to typescript
  • Loading branch information
benoitdion committed Apr 16, 2019
2 parents 904bfed + 29ddf5a commit 34aa90d
Show file tree
Hide file tree
Showing 30 changed files with 457 additions and 428 deletions.
3 changes: 2 additions & 1 deletion addons/knobs/src/KnobManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ export default class KnobManager {
existingKnob &&
options.type === existingKnob.type &&
navigator &&
!navigator.userAgent.includes('jsdom')
// userAgent is not set in react-native
(!navigator.userAgent || !navigator.userAgent.includes('jsdom'))
) {
return this.getKnobValue(existingKnob);
}
Expand Down
2 changes: 1 addition & 1 deletion app/react-native/readme.md → app/react-native/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ npx -p @storybook/cli sb init
```

During installation it will ask if you want to install storybook server.
It allows you to control the storybook from your web browser.
It allows you to control the storybook from your web browser.

The next thing you need to do is make Storybook UI visible in your app.

Expand Down
6 changes: 2 additions & 4 deletions app/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
},
"license": "MIT",
"main": "dist/index.js",
"jsnext:main": "src/index.js",
"scripts": {
"prepare": "node ../../scripts/prepare.js"
},
Expand All @@ -28,13 +27,12 @@
"@storybook/channels": "5.1.0-alpha.27",
"@storybook/client-api": "5.1.0-alpha.27",
"@storybook/core-events": "5.1.0-alpha.27",
"core-js": "^2.6.5",
"prop-types": "^15.7.2",
"react-native-swipe-gestures": "^1.0.3",
"rn-host-detect": "^1.1.5"
},
"devDependencies": {
"react-native": "^0.57.8"
"react-native": "^0.57.8",
"@types/react-native": "^0.57.42"
},
"peerDependencies": {
"react": "*",
Expand Down
13 changes: 0 additions & 13 deletions app/react-native/src/index.js

This file was deleted.

13 changes: 13 additions & 0 deletions app/react-native/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Preview from './preview';

const preview = new Preview();

export const storiesOf = preview.api().storiesOf.bind(preview);
export const setAddon = preview.api().setAddon.bind(preview);
export const addDecorator = preview.api().addDecorator.bind(preview);
export const addParameters = preview.api().addParameters.bind(preview);
export const clearDecorators = preview.api().clearDecorators.bind(preview);
export const configure = preview.configure;
export const getStorybook = preview.api().getStorybook.bind(preview);
export const getStorybookUI = preview.getStorybookUI;
export const raw = preview.api().raw.bind(preview);
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Platform, Keyboard, Dimensions, View } from 'react-native';

import {
Platform,
Keyboard,
Dimensions,
View,
EmitterSubscription,
LayoutChangeEvent,
KeyboardEvent,
} from 'react-native';
import style from './style';

export interface PreviewDimens {
previewWidth: number;
previewHeight: number;
}

type Props = {
onLayout: (dimens: PreviewDimens) => void;
} & PreviewDimens;

// Android changes screen size when keyboard opens.
// To avoid issues we use absolute positioned element with predefined screen size
export default class AbsolutePositionedKeyboardAwareView extends PureComponent {
export default class AbsolutePositionedKeyboardAwareView extends PureComponent<Props> {
keyboardDidShowListener: EmitterSubscription;
keyboardDidHideListener: EmitterSubscription;
keyboardOpen: boolean;

componentWillMount() {
this.keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
Expand All @@ -25,7 +44,7 @@ export default class AbsolutePositionedKeyboardAwareView extends PureComponent {
Dimensions.removeEventListener('change', this.removeKeyboardOnOrientationChange);
}

keyboardDidShowHandler = e => {
keyboardDidShowHandler = (e: KeyboardEvent) => {
if (Platform.OS === 'android') {
const { previewWidth } = this.props;
// There is bug in RN android that keyboardDidShow event is called simply when you go from portrait to landscape.
Expand All @@ -50,7 +69,7 @@ export default class AbsolutePositionedKeyboardAwareView extends PureComponent {
}
};

onLayoutHandler = ({ nativeEvent }) => {
onLayoutHandler = ({ nativeEvent }: LayoutChangeEvent) => {
if (!this.keyboardOpen) {
const { width, height } = nativeEvent.layout;
const { onLayout } = this.props;
Expand Down Expand Up @@ -80,10 +99,3 @@ export default class AbsolutePositionedKeyboardAwareView extends PureComponent {
);
}
}

AbsolutePositionedKeyboardAwareView.propTypes = {
children: PropTypes.node.isRequired,
previewWidth: PropTypes.number.isRequired,
previewHeight: PropTypes.number.isRequired,
onLayout: PropTypes.func.isRequired,
};
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import React, { PureComponent } from 'react';
import { View, Text } from 'react-native';
import addons from '@storybook/addons';

import AddonsList from './list';
import AddonWrapper from './wrapper';
import style from '../style';

export default class Addons extends PureComponent {
constructor() {
super();
this.panels = addons.getElements('panel');
export default class Addons extends PureComponent<{}, { addonSelected: string }> {
panels = addons.getElements('panel');

constructor(props: {}) {
super(props);

this.state = {
addonSelected: Object.keys(this.panels)[0] || null,
};
}

onPressAddon = addonSelected => {
onPressAddon = (addonSelected: string) => {
this.setState({ addonSelected });
};

Expand All @@ -26,7 +26,7 @@ export default class Addons extends PureComponent {
if (Object.keys(this.panels).length === 0) {
return (
<View style={[style.flex, style.center]}>
<Text style={style.text}>No onDevice addons loaded.</Text>
<Text style={style.text}>No addons loaded.</Text>
</View>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { View, ScrollView, StyleSheet } from 'react-native';

import { Collection } from '@storybook/addons';
import Button from '../navigation/button';

const style = StyleSheet.create({
Expand All @@ -13,12 +12,18 @@ const style = StyleSheet.create({
},
});

export default class AddonList extends PureComponent {
renderTab = (id, title) => {
export interface Props {
panels: Collection;
addonSelected: string;
onPressAddon: (id: string) => void;
}

export default class AddonList extends PureComponent<Props> {
renderTab = (id: string, title: string) => {
const { addonSelected, onPressAddon } = this.props;

return (
<Button active={id === addonSelected} key={id} id={id} onPress={onPressAddon}>
<Button active={id === addonSelected} key={id} id={id} onPress={() => onPressAddon(id)}>
{title}
</Button>
);
Expand All @@ -30,21 +35,10 @@ export default class AddonList extends PureComponent {

return (
<View style={style.list}>
<ScrollView showsHorizontalScrollIndicator={false} horizontal style={style.addonList}>
<ScrollView showsHorizontalScrollIndicator={false} horizontal>
{addonKeys.map(id => this.renderTab(id, panels[id].title))}
</ScrollView>
</View>
);
}
}

AddonList.propTypes = {
panels: PropTypes.objectOf(
PropTypes.shape({
title: PropTypes.string.isRequired,
render: PropTypes.func.isRequired,
}).isRequired
).isRequired,
onPressAddon: PropTypes.func.isRequired,
addonSelected: PropTypes.string.isRequired,
};
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { TouchableOpacity, Text } from 'react-native';

import style from '../style';

export default class Tab extends PureComponent {
export interface Props {
id: string;
title: string;
onPress: (id: string) => void;
}

export default class Tab extends PureComponent<Props> {
onPressHandler = () => {
const { onPress, id } = this.props;
onPress(id);
Expand All @@ -19,9 +24,3 @@ export default class Tab extends PureComponent {
);
}
}

Tab.propTypes = {
onPress: PropTypes.func.isRequired,
id: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
};

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React, { PureComponent } from 'react';
import { View, ScrollView } from 'react-native';
import { Collection } from '@storybook/addons';
import style from '../style';

export interface Props {
panels: Collection;
addonSelected: string;
}

export default class Wrapper extends PureComponent<Props> {
static defaultProps = {
addonSelected: '',
};

render() {
const { panels, addonSelected } = this.props;

const addonKeys = Object.keys(panels);

return addonKeys.map(id => {
const selected = addonSelected === id;

return (
<View key={id} style={selected ? style.flex : style.invisible}>
<ScrollView style={style.flex}>
{panels[id].render({ active: selected, key: id })}
</ScrollView>
</View>
);
});
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { NAVIGATOR, PREVIEW, ADDONS } from './navigation/consts';
import { NAVIGATOR, PREVIEW, ADDONS } from './navigation/constants';
import { Animated, ViewProps } from 'react-native';

const PREVIEW_SCALE = 0.3;

const panelWidth = width => width * (1 - PREVIEW_SCALE - 0.05);
const panelWidth = (width: number) => width * (1 - PREVIEW_SCALE - 0.05);

export function getNavigatorPanelPosition(animatedValue, previewWidth) {
export const getNavigatorPanelPosition = (animatedValue: Animated.Value, previewWidth: number) => {
return [
{
transform: [
Expand All @@ -18,9 +19,9 @@ export function getNavigatorPanelPosition(animatedValue, previewWidth) {
width: panelWidth(previewWidth),
},
];
}
};

export function getAddonPanelPosition(animatedValue, previewWidth) {
export const getAddonPanelPosition = (animatedValue: Animated.Value, previewWidth: number) => {
return [
{
transform: [
Expand All @@ -34,14 +35,14 @@ export function getAddonPanelPosition(animatedValue, previewWidth) {
width: panelWidth(previewWidth),
},
];
}
};

export function getPreviewPosition(
animatedValue,
previewWidth,
previewHeight,
slideBetweenAnimation
) {
export const getPreviewPosition = (
animatedValue: Animated.Value,
previewWidth: number,
previewHeight: number,
slideBetweenAnimation: boolean
) => {
const translateX = previewWidth / 2 - (previewWidth * PREVIEW_SCALE) / 2 - 6;
const translateY = -(previewHeight / 2 - (previewHeight * PREVIEW_SCALE) / 2 - 12);

Expand All @@ -61,9 +62,9 @@ export function getPreviewPosition(
},
],
};
}
};

export function getPreviewScale(animatedValue, slideBetweenAnimation) {
export const getPreviewScale = (animatedValue: Animated.Value, slideBetweenAnimation: boolean) => {
return {
transform: [
{
Expand All @@ -74,4 +75,4 @@ export function getPreviewScale(animatedValue, slideBetweenAnimation) {
},
],
};
}
};

0 comments on commit 34aa90d

Please sign in to comment.