@storybook/react-native 6.0.1-beta.1 → 6.0.1-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +15 -13
- package/dist/index.js +17 -18
- package/dist/preview/View.d.ts +48 -0
- package/dist/preview/View.js +120 -0
- package/dist/preview/components/OnDeviceUI/OnDeviceUI.d.ts +6 -3
- package/dist/preview/components/OnDeviceUI/OnDeviceUI.js +36 -38
- package/dist/preview/components/OnDeviceUI/Panel.js +1 -0
- package/dist/preview/components/OnDeviceUI/animation.d.ts +16 -6
- package/dist/preview/components/OnDeviceUI/animation.js +4 -3
- package/dist/preview/components/OnDeviceUI/navigation/Bar.d.ts +3 -1
- package/dist/preview/components/OnDeviceUI/navigation/Bar.js +1 -1
- package/dist/preview/components/OnDeviceUI/navigation/Navigation.d.ts +4 -3
- package/dist/preview/components/OnDeviceUI/navigation/Navigation.js +15 -10
- package/dist/preview/components/OnDeviceUI/navigation/VisibilityButton.d.ts +3 -1
- package/dist/preview/components/OnDeviceUI/navigation/VisibilityButton.js +34 -5
- package/dist/preview/components/Shared/icons.d.ts +5 -0
- package/dist/preview/components/Shared/icons.js +21 -0
- package/dist/preview/components/Shared/text.d.ts +3 -32
- package/dist/preview/components/Shared/text.js +3 -4
- package/dist/preview/components/Shared/theme.d.ts +4 -0
- package/dist/preview/components/Shared/theme.js +4 -0
- package/dist/preview/components/StoryListView/StoryListView.d.ts +7 -4
- package/dist/preview/components/StoryListView/StoryListView.js +46 -27
- package/dist/preview/components/StoryView/StoryView.d.ts +5 -3
- package/dist/preview/components/StoryView/StoryView.js +6 -24
- package/dist/preview/executeLoadable.d.ts +24 -0
- package/dist/preview/executeLoadable.js +79 -0
- package/dist/preview/rn-host-detect.d.ts +1 -0
- package/dist/preview/rn-host-detect.js +61 -0
- package/dist/preview/start.d.ts +16 -0
- package/dist/preview/start.js +99 -0
- package/dist/types/types-6.0.d.ts +72 -0
- package/dist/{types-6.0.js → types/types-6.0.js} +0 -0
- package/dist/types/types.d.ts +14 -0
- package/dist/{preview/global.js → types/types.js} +0 -0
- package/package.json +16 -13
- package/scripts/__snapshots__/loader.test.js.snap +82 -7
- package/scripts/loader.js +40 -10
- package/scripts/loader.test.js +47 -5
- package/scripts/mocks/file-extensions/FakeComponent.tsx +1 -0
- package/scripts/mocks/file-extensions/FakeStory.stories.tsx +10 -0
- package/scripts/mocks/file-extensions/main.ts +13 -0
- package/scripts/mocks/file-extensions/preview.tsx +23 -0
- package/scripts/mocks/preview-files/js/preview.js +24 -0
- package/scripts/mocks/preview-files/jsx/preview.jsx +24 -0
- package/scripts/mocks/preview-files/ts/preview.ts +9 -0
- package/scripts/mocks/preview-files/tsx/preview.tsx +9 -0
- package/scripts/mocks/wrong-extension-preview/FakeComponent.tsx +1 -0
- package/scripts/mocks/wrong-extension-preview/FakeStory.stories.tsx +10 -0
- package/scripts/mocks/wrong-extension-preview/main.js +9 -0
- package/scripts/mocks/wrong-extension-preview/preview.txt +24 -0
- package/scripts/watcher.js +7 -4
- package/dist/preview/Preview.d.ts +0 -55
- package/dist/preview/Preview.js +0 -117
- package/dist/preview/global.d.ts +0 -8
- package/dist/preview/index.d.ts +0 -1
- package/dist/preview/index.js +0 -1
- package/dist/preview/loadCsf.d.ts +0 -16
- package/dist/preview/loadCsf.js +0 -175
- package/dist/types-6.0.d.ts +0 -34
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Image, StyleSheet } from 'react-native';
|
|
3
|
+
export const GridIcon = () => {
|
|
4
|
+
return (React.createElement(Image, { source: {
|
|
5
|
+
uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAMAAABHPGVmAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAALdQTFRFAAAAIJ//Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqj9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Haf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqb9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqf9Hqj9Hqf9Hmz01QAAAD10Uk5TAAAEGjNefYqLXDUFAjSY0e79/9KZAghmyMkBQbz6vUIBBnD1cQcOo6Sp76qBePTHVOoC+RQTX4mCDZsBMmX5zDcAAAHcSURBVHic7ZrrcoIwEIVX8W5VpAiUaq33GyJqrfby/s9VacsCDojUJNNx9vzCTLLfZJdkHM4ChJTJSrl8oVj6s4qFckWqZiBed7V6Q24qV6op36uVVgxC042rAQh60LUIhPnY7rBCuOo8dZ9PGb3+gCXC1WA4CjPGE9YIV9NxiNHmwVCUWYAy4rIPV1PMmNnnxVCUoVf9LvOa+xp0f89HqCDzhbWMle3NsuPnWIt5MF7757zogfOxcqLOEGrtzVufm6U5Kz9iR3eHNgYObNWXc4svhQDs1C0GNTbHgZp/l6hnt5ECApqKQZu1471b93O1S1h6OQR2fsbqGcg28JeTtDIFBBwM28iCJON7lZSsVBAN3zFZCpRkkbgwDQQWWJQcvOK2LLYQCwPnoYDPS7aQJQYuwJ4/ZA8l/pASQQhCEIIQhCAEIQhBghB7nSj839xMnmtHQriJIAS5IYiQw3g7dxdBCEIQghCEIAQhyH+ECPmMLsQQKOMzY2vjgIHLYkwaIXaTEOMM+FuAIMbMhJYIW1aIwczaKj9EWuVCTH++7Quml8Qev0aMnl+qtxkfxnu4cYXLXiYhhpg2H4AP1g1L7a55ygDGrVdGZOuVKwFNZN/KSp/XtsPVpOpJ0C+2naE/XA0rpwAAAABJRU5ErkJggg==',
|
|
6
|
+
}, style: styles.navigatorIcon }));
|
|
7
|
+
};
|
|
8
|
+
const whiteOutline = 'data:image/png;base64,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';
|
|
9
|
+
const blueOutline = 'data:image/png;base64,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';
|
|
10
|
+
export const StoryIcon = ({ selected }) => {
|
|
11
|
+
return (React.createElement(Image, { source: {
|
|
12
|
+
uri: selected ? whiteOutline : blueOutline,
|
|
13
|
+
}, style: styles.navigatorIcon }));
|
|
14
|
+
};
|
|
15
|
+
const styles = StyleSheet.create({
|
|
16
|
+
navigatorIcon: {
|
|
17
|
+
width: 18,
|
|
18
|
+
height: 18,
|
|
19
|
+
marginRight: 5,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -1,32 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const
|
|
3
|
-
|
|
4
|
-
}, {
|
|
5
|
-
backgroundColor: string;
|
|
6
|
-
headerTextColor: string;
|
|
7
|
-
labelColor: string;
|
|
8
|
-
borderColor: string;
|
|
9
|
-
previewBorderColor: string;
|
|
10
|
-
buttonTextColor: string;
|
|
11
|
-
buttonActiveTextColor: string;
|
|
12
|
-
}>;
|
|
13
|
-
export declare const Name: import("@emotion/styled-base").StyledComponent<import("react-native").TextProps & import("react").RefAttributes<import("react-native").Text>, {
|
|
14
|
-
selected: boolean;
|
|
15
|
-
}, {
|
|
16
|
-
backgroundColor: string;
|
|
17
|
-
headerTextColor: string;
|
|
18
|
-
labelColor: string;
|
|
19
|
-
borderColor: string;
|
|
20
|
-
previewBorderColor: string;
|
|
21
|
-
buttonTextColor: string;
|
|
22
|
-
buttonActiveTextColor: string;
|
|
23
|
-
}>;
|
|
24
|
-
export declare const Label: import("@emotion/styled-base").StyledComponent<import("react-native").TextProps & import("react").RefAttributes<import("react-native").Text>, Pick<import("react-native").TextProps & import("react").RefAttributes<import("react-native").Text>, keyof import("react-native").TextProps>, {
|
|
25
|
-
backgroundColor: string;
|
|
26
|
-
headerTextColor: string;
|
|
27
|
-
labelColor: string;
|
|
28
|
-
borderColor: string;
|
|
29
|
-
previewBorderColor: string;
|
|
30
|
-
buttonTextColor: string;
|
|
31
|
-
buttonActiveTextColor: string;
|
|
32
|
-
}>;
|
|
1
|
+
export declare const Header: any;
|
|
2
|
+
export declare const Name: any;
|
|
3
|
+
export declare const Label: any;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import styled from '@emotion/native';
|
|
2
2
|
export const Header = styled.Text(({ theme }) => ({
|
|
3
|
-
fontSize:
|
|
3
|
+
fontSize: 18,
|
|
4
4
|
color: theme.headerTextColor || 'black',
|
|
5
5
|
}), ({ selected }) => (selected ? { fontWeight: 'bold' } : {}));
|
|
6
|
-
export const Name = styled.Text(
|
|
6
|
+
export const Name = styled.Text({
|
|
7
7
|
fontSize: 16,
|
|
8
|
-
|
|
9
|
-
}), ({ selected }) => (selected ? { fontWeight: 'bold' } : {}));
|
|
8
|
+
}, ({ selected, theme }) => selected ? { fontWeight: 'bold', color: 'white' } : { color: theme.headerTextColor || 'black' });
|
|
10
9
|
export const Label = styled.Text(({ theme }) => ({
|
|
11
10
|
fontSize: 18,
|
|
12
11
|
color: theme.labelColor || 'black',
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export declare const theme: {
|
|
2
2
|
backgroundColor: string;
|
|
3
|
+
storyListBackgroundColor: string;
|
|
4
|
+
listItemActiveColor: string;
|
|
5
|
+
listItemActiveTextColor: string;
|
|
3
6
|
headerTextColor: string;
|
|
4
7
|
labelColor: string;
|
|
5
8
|
borderColor: string;
|
|
6
9
|
previewBorderColor: string;
|
|
7
10
|
buttonTextColor: string;
|
|
8
11
|
buttonActiveTextColor: string;
|
|
12
|
+
secondaryLabelColor: string;
|
|
9
13
|
};
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export const theme = {
|
|
2
2
|
backgroundColor: 'white',
|
|
3
|
+
storyListBackgroundColor: '#f6f9fc',
|
|
4
|
+
listItemActiveColor: '#1ea7fd',
|
|
5
|
+
listItemActiveTextColor: 'white',
|
|
3
6
|
headerTextColor: 'black',
|
|
4
7
|
labelColor: 'black',
|
|
5
8
|
borderColor: '#e6e6e6',
|
|
6
9
|
previewBorderColor: '#b3b3b3',
|
|
7
10
|
buttonTextColor: '#999999',
|
|
8
11
|
buttonActiveTextColor: '#444444',
|
|
12
|
+
secondaryLabelColor: '#999999',
|
|
9
13
|
};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { StoryIndex } from '@storybook/client-api';
|
|
3
|
+
import { StoryContext } from '@storybook/csf';
|
|
4
|
+
import { ReactNativeFramework } from 'src/types/types-6.0';
|
|
2
5
|
interface Props {
|
|
3
|
-
|
|
4
|
-
|
|
6
|
+
storyIndex: StoryIndex;
|
|
7
|
+
selectedStoryContext: StoryContext<ReactNativeFramework>;
|
|
5
8
|
}
|
|
6
|
-
declare const StoryListView: ({
|
|
9
|
+
declare const StoryListView: ({ selectedStoryContext, storyIndex }: Props) => JSX.Element;
|
|
7
10
|
export default StoryListView;
|
|
@@ -2,22 +2,29 @@ import styled from '@emotion/native';
|
|
|
2
2
|
import { addons } from '@storybook/addons';
|
|
3
3
|
import Events from '@storybook/core-events';
|
|
4
4
|
import React, { useMemo, useState } from 'react';
|
|
5
|
-
import { SectionList, StyleSheet } from 'react-native';
|
|
5
|
+
import { SectionList, StyleSheet, View } from 'react-native';
|
|
6
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
7
|
+
import { GridIcon, StoryIcon } from '../Shared/icons';
|
|
6
8
|
import { Header, Name } from '../Shared/text';
|
|
7
9
|
const SearchBar = styled.TextInput({
|
|
8
|
-
borderRadius:
|
|
10
|
+
borderRadius: 16,
|
|
11
|
+
borderWidth: 2,
|
|
9
12
|
fontSize: 16,
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
marginVertical: 4,
|
|
14
|
+
marginHorizontal: 8,
|
|
15
|
+
paddingVertical: 8,
|
|
16
|
+
paddingHorizontal: 15,
|
|
12
17
|
}, ({ theme }) => ({
|
|
13
|
-
|
|
18
|
+
borderColor: theme.borderColor,
|
|
14
19
|
color: theme.buttonActiveTextColor,
|
|
15
20
|
}));
|
|
16
21
|
const HeaderContainer = styled.View({
|
|
17
22
|
paddingVertical: 5,
|
|
18
23
|
paddingHorizontal: 5,
|
|
24
|
+
flexDirection: 'row',
|
|
25
|
+
alignItems: 'center',
|
|
19
26
|
});
|
|
20
|
-
const StoryListContainer = styled.View(Object.assign(Object.assign({ top: 0 }, StyleSheet.absoluteFillObject), {
|
|
27
|
+
const StoryListContainer = styled.View(({ theme }) => (Object.assign(Object.assign({ top: 0 }, StyleSheet.absoluteFillObject), {
|
|
21
28
|
// for this to work I need to get the top margin from safeareview context
|
|
22
29
|
// shadowColor: '#000',
|
|
23
30
|
// shadowOffset: {
|
|
@@ -27,34 +34,40 @@ const StoryListContainer = styled.View(Object.assign(Object.assign({ top: 0 }, S
|
|
|
27
34
|
// shadowOpacity: 0.2,
|
|
28
35
|
// shadowRadius: 1.41,
|
|
29
36
|
// elevation: 2,
|
|
30
|
-
borderRightWidth: StyleSheet.hairlineWidth, borderRightColor:
|
|
31
|
-
const SectionHeader = ({ title, selected }) => (React.createElement(HeaderContainer, { key: title },
|
|
32
|
-
React.createElement(
|
|
37
|
+
borderRightWidth: StyleSheet.hairlineWidth, borderRightColor: theme.borderColor, backgroundColor: theme.storyListBackgroundColor })));
|
|
38
|
+
const SectionHeader = React.memo(({ title, selected }) => (React.createElement(HeaderContainer, { key: title },
|
|
39
|
+
React.createElement(GridIcon, null),
|
|
40
|
+
React.createElement(Header, { selected: selected }, title))));
|
|
33
41
|
const ItemTouchable = styled.TouchableOpacity({
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
42
|
+
padding: 5,
|
|
43
|
+
paddingLeft: 40,
|
|
44
|
+
flexDirection: 'row',
|
|
45
|
+
alignItems: 'center',
|
|
46
|
+
}, ({ selected, theme }) => { var _a; return (selected ? { backgroundColor: (_a = theme === null || theme === void 0 ? void 0 : theme.listItemActiveColor) !== null && _a !== void 0 ? _a : '#1ea7fd' } : {}); });
|
|
47
|
+
const ListItem = React.memo(({ kind, title, selected, onPress }) => (React.createElement(ItemTouchable, { key: title, onPress: onPress, activeOpacity: 0.8, testID: `Storybook.ListItem.${kind}.${title}`, accessibilityLabel: `Storybook.ListItem.${title}`, selected: selected },
|
|
48
|
+
React.createElement(StoryIcon, { selected: selected }),
|
|
49
|
+
React.createElement(Name, { selected: selected }, title))), (prevProps, nextProps) => prevProps.selected === nextProps.selected);
|
|
50
|
+
const getStories = (storyIndex) => {
|
|
51
|
+
if (!storyIndex) {
|
|
41
52
|
return [];
|
|
42
53
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
title: story
|
|
48
|
-
data: (acc[story.kind] ? acc[story.kind].data : []).concat(story),
|
|
54
|
+
const groupedStories = Object.values(storyIndex.stories).reduce((acc, story) => {
|
|
55
|
+
var _a, _b;
|
|
56
|
+
acc[story.title] = {
|
|
57
|
+
title: story.title,
|
|
58
|
+
data: ((_b = (_a = acc[story.title]) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : []).concat(story),
|
|
49
59
|
};
|
|
50
60
|
return acc;
|
|
51
|
-
}, {})
|
|
61
|
+
}, {});
|
|
62
|
+
return Object.values(groupedStories);
|
|
52
63
|
};
|
|
53
64
|
const styles = StyleSheet.create({
|
|
54
65
|
sectionList: { flex: 1 },
|
|
55
66
|
});
|
|
56
|
-
const
|
|
57
|
-
|
|
67
|
+
const tabBarHeight = 40;
|
|
68
|
+
const StoryListView = ({ selectedStoryContext, storyIndex }) => {
|
|
69
|
+
const insets = useSafeAreaInsets();
|
|
70
|
+
const originalData = useMemo(() => getStories(storyIndex), [storyIndex]);
|
|
58
71
|
const [data, setData] = useState(originalData);
|
|
59
72
|
const handleChangeSearchText = (text) => {
|
|
60
73
|
const query = text.trim();
|
|
@@ -79,8 +92,14 @@ const StoryListView = ({ selectedStory, storyStore }) => {
|
|
|
79
92
|
const channel = addons.getChannel();
|
|
80
93
|
channel.emit(Events.SET_CURRENT_STORY, { storyId });
|
|
81
94
|
};
|
|
95
|
+
const safeStyle = { flex: 1, marginTop: insets.top, paddingBottom: insets.bottom + tabBarHeight };
|
|
82
96
|
return (React.createElement(StoryListContainer, null,
|
|
83
|
-
React.createElement(
|
|
84
|
-
|
|
97
|
+
React.createElement(View, { style: safeStyle },
|
|
98
|
+
React.createElement(SearchBar, { testID: "Storybook.ListView.SearchBar", clearButtonMode: "while-editing", disableFullscreenUI: true, onChangeText: handleChangeSearchText, placeholder: "Filter", returnKeyType: "search" }),
|
|
99
|
+
React.createElement(SectionList
|
|
100
|
+
// contentInset={{ bottom: insets.bottom, top: 0 }}
|
|
101
|
+
, {
|
|
102
|
+
// contentInset={{ bottom: insets.bottom, top: 0 }}
|
|
103
|
+
style: styles.sectionList, testID: "Storybook.ListView", renderItem: ({ item }) => (React.createElement(ListItem, { title: item.name, kind: item.title, selected: selectedStoryContext && item.id === selectedStoryContext.id, onPress: () => changeStory(item.id) })), renderSectionHeader: ({ section: { title } }) => (React.createElement(SectionHeader, { title: title, selected: selectedStoryContext && title === selectedStoryContext.title })), keyExtractor: (item, index) => item.id + index, sections: data, stickySectionHeadersEnabled: false }))));
|
|
85
104
|
};
|
|
86
105
|
export default StoryListView;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { StoryContext } from '@storybook/csf';
|
|
3
|
+
import { ReactNativeFramework } from 'src/types/types-6.0';
|
|
2
4
|
interface Props {
|
|
3
|
-
|
|
5
|
+
context?: StoryContext<ReactNativeFramework>;
|
|
4
6
|
}
|
|
5
|
-
declare const StoryView: ({
|
|
7
|
+
declare const StoryView: ({ context }: Props) => JSX.Element;
|
|
6
8
|
export default StoryView;
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import React, { useState, useEffect } from 'react';
|
|
1
|
+
import React from 'react';
|
|
11
2
|
import { Text, View, StyleSheet } from 'react-native';
|
|
12
3
|
const styles = StyleSheet.create({
|
|
13
4
|
container: { flex: 1 },
|
|
@@ -19,20 +10,11 @@ const styles = StyleSheet.create({
|
|
|
19
10
|
justifyContent: 'center',
|
|
20
11
|
},
|
|
21
12
|
});
|
|
22
|
-
const StoryView = ({
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (story && story.unboundStoryFn && story.applyLoaders) {
|
|
28
|
-
setContext(yield story.applyLoaders());
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
loadContext();
|
|
32
|
-
}, [story, id]);
|
|
33
|
-
if (story && story.unboundStoryFn) {
|
|
34
|
-
const { unboundStoryFn } = story;
|
|
35
|
-
return (React.createElement(View, { key: id, testID: id, style: styles.container }, context && context.id === story.id ? unboundStoryFn(context) : null));
|
|
13
|
+
const StoryView = ({ context }) => {
|
|
14
|
+
const id = context === null || context === void 0 ? void 0 : context.id;
|
|
15
|
+
if (context && context.unboundStoryFn) {
|
|
16
|
+
const { unboundStoryFn: StoryComponent } = context;
|
|
17
|
+
return (React.createElement(View, { key: id, testID: id, style: styles.container }, StoryComponent && React.createElement(StoryComponent, Object.assign({}, context))));
|
|
36
18
|
}
|
|
37
19
|
return (React.createElement(View, { style: styles.helpContainer },
|
|
38
20
|
React.createElement(Text, null, "Please open navigator and select a story to preview.")));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/// <reference types="webpack-env" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { ModuleExports } from '@storybook/store';
|
|
4
|
+
import { Loadable } from '../types/types';
|
|
5
|
+
/**
|
|
6
|
+
* Executes a Loadable (function that returns exports or require context(s))
|
|
7
|
+
* and returns a map of filename => module exports
|
|
8
|
+
*
|
|
9
|
+
* @param loadable Loadable
|
|
10
|
+
* @returns Map<Path, ModuleExports>
|
|
11
|
+
*/
|
|
12
|
+
export declare function executeLoadable(loadable: Loadable): Map<string, ModuleExports>;
|
|
13
|
+
/**
|
|
14
|
+
* Executes a Loadable (function that returns exports or require context(s))
|
|
15
|
+
* and compares it's output to the last time it was run (as stored on a node module)
|
|
16
|
+
*
|
|
17
|
+
* @param loadable Loadable
|
|
18
|
+
* @param m NodeModule
|
|
19
|
+
* @returns { added: Map<Path, ModuleExports>, removed: Map<Path, ModuleExports> }
|
|
20
|
+
*/
|
|
21
|
+
export declare function executeLoadableForChanges(loadable: Loadable, m?: NodeModule): {
|
|
22
|
+
added: Map<string, ModuleExports>;
|
|
23
|
+
removed: Map<string, ModuleExports>;
|
|
24
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { logger } from '@storybook/client-logger';
|
|
2
|
+
/**
|
|
3
|
+
* Executes a Loadable (function that returns exports or require context(s))
|
|
4
|
+
* and returns a map of filename => module exports
|
|
5
|
+
*
|
|
6
|
+
* @param loadable Loadable
|
|
7
|
+
* @returns Map<Path, ModuleExports>
|
|
8
|
+
*/
|
|
9
|
+
export function executeLoadable(loadable) {
|
|
10
|
+
let reqs = null;
|
|
11
|
+
// todo discuss / improve type check
|
|
12
|
+
if (Array.isArray(loadable)) {
|
|
13
|
+
reqs = loadable;
|
|
14
|
+
}
|
|
15
|
+
else if (loadable.keys) {
|
|
16
|
+
reqs = [loadable];
|
|
17
|
+
}
|
|
18
|
+
let exportsMap = new Map();
|
|
19
|
+
if (reqs) {
|
|
20
|
+
reqs.forEach((req) => {
|
|
21
|
+
req.keys().forEach((filename) => {
|
|
22
|
+
try {
|
|
23
|
+
const fileExports = req(filename);
|
|
24
|
+
exportsMap.set(typeof req.resolve === 'function' ? req.resolve(filename) : filename, fileExports);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
const errorString = error.message && error.stack ? `${error.message}\n ${error.stack}` : error.toString();
|
|
28
|
+
logger.error(`Unexpected error while loading ${filename}: ${errorString}`);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const exported = loadable();
|
|
35
|
+
if (Array.isArray(exported) /*FIXME && exported.every((obj) => obj.default != null)*/) {
|
|
36
|
+
const csfExports = exported.filter((obj) => obj.default != null);
|
|
37
|
+
exportsMap = new Map(csfExports.map((fileExports, index) => [`exports-map-${index}`, fileExports]));
|
|
38
|
+
}
|
|
39
|
+
// else if (exported) {
|
|
40
|
+
// logger.warn(
|
|
41
|
+
// `Loader function passed to 'configure' should return void or an array of module exports that all contain a 'default' export. Received: ${JSON.stringify(
|
|
42
|
+
// exported
|
|
43
|
+
// )}`
|
|
44
|
+
// );
|
|
45
|
+
// }
|
|
46
|
+
}
|
|
47
|
+
return exportsMap;
|
|
48
|
+
}
|
|
49
|
+
global.lastExportsMap = new Map();
|
|
50
|
+
/**
|
|
51
|
+
* Executes a Loadable (function that returns exports or require context(s))
|
|
52
|
+
* and compares it's output to the last time it was run (as stored on a node module)
|
|
53
|
+
*
|
|
54
|
+
* @param loadable Loadable
|
|
55
|
+
* @param m NodeModule
|
|
56
|
+
* @returns { added: Map<Path, ModuleExports>, removed: Map<Path, ModuleExports> }
|
|
57
|
+
*/
|
|
58
|
+
export function executeLoadableForChanges(loadable, m) {
|
|
59
|
+
var _a;
|
|
60
|
+
if ((_a = m === null || m === void 0 ? void 0 : m.hot) === null || _a === void 0 ? void 0 : _a.accept) {
|
|
61
|
+
m.hot.accept();
|
|
62
|
+
}
|
|
63
|
+
const lastExportsMap = global.lastExportsMap;
|
|
64
|
+
const exportsMap = executeLoadable(loadable);
|
|
65
|
+
const added = new Map();
|
|
66
|
+
Array.from(exportsMap.entries())
|
|
67
|
+
// Ignore files that do not have a default export
|
|
68
|
+
.filter(([, fileExports]) => !!fileExports.default)
|
|
69
|
+
// Ignore exports that are equal (by reference) to last time, this means the file hasn't changed
|
|
70
|
+
.filter(([fileName, fileExports]) => lastExportsMap.get(fileName) !== fileExports)
|
|
71
|
+
.forEach(([fileName, fileExports]) => added.set(fileName, fileExports));
|
|
72
|
+
const removed = new Map();
|
|
73
|
+
Array.from(lastExportsMap.keys())
|
|
74
|
+
.filter((fileName) => !exportsMap.has(fileName))
|
|
75
|
+
.forEach((fileName) => removed.set(fileName, lastExportsMap.get(fileName)));
|
|
76
|
+
// Save the value for the dispose() call above
|
|
77
|
+
global.lastExportsMap = exportsMap;
|
|
78
|
+
return { added, removed };
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function getHost(hostname: any): any;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/*
|
|
3
|
+
* It only for Debug Remotely mode for Android
|
|
4
|
+
* When __DEV__ === false, we can't use window.require('NativeModules')
|
|
5
|
+
*/
|
|
6
|
+
function getByRemoteConfig(hostname) {
|
|
7
|
+
var _a;
|
|
8
|
+
var remoteModuleConfig = (_a = window === null || window === void 0 ? void 0 : window.__fbBatchedBridgeConfig) === null || _a === void 0 ? void 0 : _a.remoteModuleConfig;
|
|
9
|
+
if (!Array.isArray(remoteModuleConfig) ||
|
|
10
|
+
(hostname !== 'localhost' && hostname !== '127.0.0.1')) {
|
|
11
|
+
return { hostname: hostname, passed: false };
|
|
12
|
+
}
|
|
13
|
+
var constants = (remoteModuleConfig.find(getConstants) || [])[1];
|
|
14
|
+
if (constants) {
|
|
15
|
+
var serverHost = constants.ServerHost || hostname;
|
|
16
|
+
return { hostname: serverHost.split(':')[0], passed: true };
|
|
17
|
+
}
|
|
18
|
+
return { hostname: hostname, passed: false };
|
|
19
|
+
}
|
|
20
|
+
function getConstants(config) {
|
|
21
|
+
return config && (config[0] === 'AndroidConstants' || config[0] === 'PlatformConstants');
|
|
22
|
+
}
|
|
23
|
+
function getByRNRequirePolyfill(hostname) {
|
|
24
|
+
var NativeModules;
|
|
25
|
+
var PlatformConstants;
|
|
26
|
+
var AndroidConstants;
|
|
27
|
+
if (typeof window === 'undefined' ||
|
|
28
|
+
!window.__DEV__ ||
|
|
29
|
+
typeof window.require !== 'function' ||
|
|
30
|
+
// RN >= 0.56
|
|
31
|
+
// TODO: Get NativeModules for RN >= 0.56
|
|
32
|
+
window.require.name === 'metroRequire') {
|
|
33
|
+
return hostname;
|
|
34
|
+
}
|
|
35
|
+
NativeModules = window.require('NativeModules');
|
|
36
|
+
if (!NativeModules || (!NativeModules.PlatformConstants && !NativeModules.AndroidConstants)) {
|
|
37
|
+
return hostname;
|
|
38
|
+
}
|
|
39
|
+
PlatformConstants = NativeModules.PlatformConstants;
|
|
40
|
+
AndroidConstants = NativeModules.AndroidConstants;
|
|
41
|
+
var serverHost = (PlatformConstants ? PlatformConstants.ServerHost : AndroidConstants.ServerHost) || hostname;
|
|
42
|
+
return serverHost.split(':')[0];
|
|
43
|
+
}
|
|
44
|
+
/*
|
|
45
|
+
* Get React Native server IP if hostname is `localhost`
|
|
46
|
+
* On Android emulator, the IP of host is `10.0.2.2` (Genymotion: 10.0.3.2)
|
|
47
|
+
*/
|
|
48
|
+
export default function getHost(hostname) {
|
|
49
|
+
// Check if it in React Native environment
|
|
50
|
+
if (typeof __fbBatchedBridge !== 'object' ||
|
|
51
|
+
(hostname !== 'localhost' && hostname !== '127.0.0.1')) {
|
|
52
|
+
return hostname;
|
|
53
|
+
}
|
|
54
|
+
var result = getByRemoteConfig(hostname);
|
|
55
|
+
// Leave if get hostname by remote config successful
|
|
56
|
+
if (result.passed) {
|
|
57
|
+
return result.hostname;
|
|
58
|
+
}
|
|
59
|
+
// Otherwise, use RN's require polyfill
|
|
60
|
+
return getByRNRequirePolyfill(hostname);
|
|
61
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="webpack-env" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { Loadable } from '@storybook/core-client';
|
|
4
|
+
import { PreviewWeb } from '@storybook/preview-web';
|
|
5
|
+
import { ClientApi } from '@storybook/client-api';
|
|
6
|
+
import type { ReactNativeFramework } from '../types/types-6.0';
|
|
7
|
+
import { View } from './View';
|
|
8
|
+
import type { ArgsStoryFn } from '@storybook/csf';
|
|
9
|
+
export declare const render: ArgsStoryFn<ReactNativeFramework>;
|
|
10
|
+
export declare function start(): {
|
|
11
|
+
view: View;
|
|
12
|
+
forceReRender: () => void;
|
|
13
|
+
clientApi: ClientApi<ReactNativeFramework>;
|
|
14
|
+
preview: PreviewWeb<ReactNativeFramework>;
|
|
15
|
+
configure(loadable: Loadable, m: NodeModule): void;
|
|
16
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Channel from '@storybook/channels';
|
|
3
|
+
import { addons } from '@storybook/addons';
|
|
4
|
+
import Events from '@storybook/core-events';
|
|
5
|
+
import { PreviewWeb } from '@storybook/preview-web';
|
|
6
|
+
import { ClientApi, setGlobalRender } from '@storybook/client-api';
|
|
7
|
+
import { View } from './View';
|
|
8
|
+
import { executeLoadableForChanges } from './executeLoadable';
|
|
9
|
+
export const render = (args, context) => {
|
|
10
|
+
const { id, component: Component } = context;
|
|
11
|
+
if (!Component) {
|
|
12
|
+
throw new Error(`Unable to render story ${id} as the component annotation is missing from the default export`);
|
|
13
|
+
}
|
|
14
|
+
return React.createElement(Component, Object.assign({}, args));
|
|
15
|
+
};
|
|
16
|
+
export function start() {
|
|
17
|
+
// TODO: can we get settings from main.js and set the channel here?
|
|
18
|
+
const channel = new Channel({ async: true });
|
|
19
|
+
addons.setChannel(channel);
|
|
20
|
+
const clientApi = new ClientApi();
|
|
21
|
+
const previewView = {
|
|
22
|
+
prepareForStory: () => null,
|
|
23
|
+
showNoPreview: () => { },
|
|
24
|
+
showPreparingStory: () => { },
|
|
25
|
+
applyLayout: () => { },
|
|
26
|
+
showErrorDisplay: (e) => {
|
|
27
|
+
console.log(e);
|
|
28
|
+
},
|
|
29
|
+
showStoryDuringRender: () => { },
|
|
30
|
+
showMain: () => { },
|
|
31
|
+
checkIfLayoutExists: () => { },
|
|
32
|
+
showStory: () => { },
|
|
33
|
+
docsRoot: null,
|
|
34
|
+
prepareForDocs: () => null,
|
|
35
|
+
showDocs: () => { },
|
|
36
|
+
preparingTimeout: setTimeout(() => { }, 0),
|
|
37
|
+
showMode: () => { },
|
|
38
|
+
showPreparingDocs: () => { },
|
|
39
|
+
storyRoot: null,
|
|
40
|
+
testing: false,
|
|
41
|
+
};
|
|
42
|
+
const urlStore = {
|
|
43
|
+
selection: { storyId: '', viewMode: 'story' },
|
|
44
|
+
selectionSpecifier: null,
|
|
45
|
+
setQueryParams: () => { },
|
|
46
|
+
setSelection: (selection) => {
|
|
47
|
+
preview.urlStore.selection = selection;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
const preview = new PreviewWeb(urlStore, previewView);
|
|
51
|
+
clientApi.storyStore = preview.storyStore;
|
|
52
|
+
setGlobalRender(render);
|
|
53
|
+
let initialized = false;
|
|
54
|
+
function onStoriesChanged() {
|
|
55
|
+
const storyIndex = clientApi.getStoryIndex();
|
|
56
|
+
preview.onStoriesChanged({ storyIndex });
|
|
57
|
+
view._storyIndex = storyIndex;
|
|
58
|
+
}
|
|
59
|
+
const view = new View(preview);
|
|
60
|
+
return {
|
|
61
|
+
view,
|
|
62
|
+
forceReRender: () => channel.emit(Events.FORCE_RE_RENDER),
|
|
63
|
+
clientApi,
|
|
64
|
+
preview,
|
|
65
|
+
// This gets called each time the user calls configure (i.e. once per HMR)
|
|
66
|
+
// The first time, it constructs thecurrentSelection preview, subsequently it updates it
|
|
67
|
+
configure(loadable, m) {
|
|
68
|
+
clientApi.addParameters({ framework: 'react-native' });
|
|
69
|
+
// We need to run the `executeLoadableForChanges` function *inside* the `getProjectAnnotations
|
|
70
|
+
// function in case it throws. So we also need to process its output there also
|
|
71
|
+
const getProjectAnnotations = () => {
|
|
72
|
+
const { added, removed } = executeLoadableForChanges(loadable, m);
|
|
73
|
+
Array.from(added.entries()).forEach(([fileName, fileExports]) => clientApi.facade.addStoriesFromExports(fileName, fileExports));
|
|
74
|
+
Array.from(removed.entries()).forEach(([fileName]) => clientApi.facade.clearFilenameExports(fileName));
|
|
75
|
+
return Object.assign(Object.assign({}, clientApi.facade.projectAnnotations), { renderToDOM: (context) => {
|
|
76
|
+
view._setStory(context.storyContext);
|
|
77
|
+
} });
|
|
78
|
+
};
|
|
79
|
+
const importFn = (path) => clientApi.importFn(path);
|
|
80
|
+
if (!initialized) {
|
|
81
|
+
preview.initialize({
|
|
82
|
+
getStoryIndex: () => {
|
|
83
|
+
const index = clientApi.getStoryIndex();
|
|
84
|
+
view._storyIndex = index;
|
|
85
|
+
return index;
|
|
86
|
+
},
|
|
87
|
+
importFn,
|
|
88
|
+
getProjectAnnotations,
|
|
89
|
+
});
|
|
90
|
+
initialized = true;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// TODO -- why don't we care about the new annotations?
|
|
94
|
+
getProjectAnnotations();
|
|
95
|
+
onStoriesChanged();
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|