@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
package/dist/index.d.ts
CHANGED
|
@@ -3,16 +3,18 @@
|
|
|
3
3
|
import { StoryApi } from '@storybook/addons';
|
|
4
4
|
import { ClientApi } from '@storybook/client-api';
|
|
5
5
|
import { ReactNode } from 'react';
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
export declare const
|
|
11
|
-
export declare const
|
|
12
|
-
export declare const
|
|
13
|
-
export declare const
|
|
14
|
-
export declare const
|
|
15
|
-
export declare const
|
|
16
|
-
export declare const
|
|
17
|
-
export declare const
|
|
18
|
-
export
|
|
6
|
+
import type { ReactNativeFramework } from './types/types-6.0';
|
|
7
|
+
declare const configure: (loadable: import("@storybook/core-client").Loadable, m: NodeModule) => void;
|
|
8
|
+
export { configure };
|
|
9
|
+
declare type C = ClientApi<ReactNativeFramework>;
|
|
10
|
+
export declare const setAddon: C['setAddon'];
|
|
11
|
+
export declare const addDecorator: C['addDecorator'];
|
|
12
|
+
export declare const addParameters: C['addParameters'];
|
|
13
|
+
export declare const addArgsEnhancer: C['addArgsEnhancer'];
|
|
14
|
+
export declare const addArgTypesEnhancer: C['addArgTypesEnhancer'];
|
|
15
|
+
export declare const clearDecorators: C['clearDecorators'];
|
|
16
|
+
export declare const getStorybook: C['getStorybook'];
|
|
17
|
+
export declare const raw: C['raw'];
|
|
18
|
+
export declare const storiesOf: (kind: string, _module: NodeModule) => StoryApi<ReactNode>;
|
|
19
|
+
export declare const getStorybookUI: (params?: Partial<import("./preview/View").Params>) => () => JSX.Element;
|
|
20
|
+
export * from './types/types-6.0';
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export const
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export const clearDecorators =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export const
|
|
17
|
-
export
|
|
18
|
-
export * from './types-6.0';
|
|
1
|
+
import { start } from './preview/start';
|
|
2
|
+
const { clientApi, configure, view } = start();
|
|
3
|
+
export { configure };
|
|
4
|
+
const rawStoriesOf = clientApi.storiesOf.bind(clientApi);
|
|
5
|
+
export const setAddon = clientApi.setAddon.bind(clientApi);
|
|
6
|
+
export const addDecorator = clientApi.addDecorator.bind(clientApi);
|
|
7
|
+
export const addParameters = clientApi.addParameters.bind(clientApi);
|
|
8
|
+
export const addArgsEnhancer = clientApi.addArgsEnhancer.bind(clientApi);
|
|
9
|
+
export const addArgTypesEnhancer = clientApi.addArgTypesEnhancer.bind(clientApi);
|
|
10
|
+
export const clearDecorators = clientApi.clearDecorators.bind(clientApi);
|
|
11
|
+
export const getStorybook = clientApi.getStorybook.bind(clientApi);
|
|
12
|
+
export const raw = clientApi.raw.bind(clientApi);
|
|
13
|
+
export const storiesOf = (kind, _module) => rawStoriesOf(kind, { hot: () => { } }).addParameters({
|
|
14
|
+
framework: 'react-native',
|
|
15
|
+
});
|
|
16
|
+
export const getStorybookUI = view.getStorybookUI;
|
|
17
|
+
export * from './types/types-6.0';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { StoryIndex, SelectionSpecifier } from '@storybook/store';
|
|
3
|
+
import { StoryContext } from '@storybook/csf';
|
|
4
|
+
import { theme } from './components/Shared/theme';
|
|
5
|
+
import type { ReactNativeFramework } from '../types/types-6.0';
|
|
6
|
+
import { PreviewWeb } from '@storybook/preview-web';
|
|
7
|
+
declare type StoryKind = string;
|
|
8
|
+
declare type StoryName = string;
|
|
9
|
+
declare type InitialSelection = `${StoryKind}--${StoryName}` | {
|
|
10
|
+
/**
|
|
11
|
+
* Kind is the default export name or the storiesOf("name") name
|
|
12
|
+
*/
|
|
13
|
+
kind: StoryKind;
|
|
14
|
+
/**
|
|
15
|
+
* Name is the named export or the .add("name") name
|
|
16
|
+
*/
|
|
17
|
+
name: StoryName;
|
|
18
|
+
};
|
|
19
|
+
export declare type Params = {
|
|
20
|
+
onDeviceUI?: boolean;
|
|
21
|
+
enableWebsockets?: boolean;
|
|
22
|
+
query?: string;
|
|
23
|
+
host?: string;
|
|
24
|
+
port?: number;
|
|
25
|
+
secured?: boolean;
|
|
26
|
+
initialSelection?: InitialSelection;
|
|
27
|
+
shouldPersistSelection?: boolean;
|
|
28
|
+
tabOpen?: number;
|
|
29
|
+
isUIHidden?: boolean;
|
|
30
|
+
shouldDisableKeyboardAvoidingView?: boolean;
|
|
31
|
+
keyboardAvoidingViewVerticalOffset?: number;
|
|
32
|
+
} & {
|
|
33
|
+
theme?: typeof theme;
|
|
34
|
+
};
|
|
35
|
+
export declare class View {
|
|
36
|
+
_storyIndex: StoryIndex;
|
|
37
|
+
_setStory: (story: StoryContext<ReactNativeFramework>) => void;
|
|
38
|
+
_forceRerender: () => void;
|
|
39
|
+
_ready: boolean;
|
|
40
|
+
_preview: PreviewWeb<ReactNativeFramework>;
|
|
41
|
+
_asyncStorageStoryId: string;
|
|
42
|
+
_webUrl: string;
|
|
43
|
+
constructor(preview: PreviewWeb<ReactNativeFramework>);
|
|
44
|
+
_getInitialStory: ({ initialSelection, shouldPersistSelection, }?: Partial<Params>) => Promise<SelectionSpecifier>;
|
|
45
|
+
_getServerChannel: (params?: Partial<Params>) => import("@storybook/channels").Channel;
|
|
46
|
+
getStorybookUI: (params?: Partial<Params>) => () => JSX.Element;
|
|
47
|
+
}
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
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, { useEffect, useState, useReducer } from 'react';
|
|
11
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
12
|
+
import { toId } from '@storybook/csf';
|
|
13
|
+
import { addons } from '@storybook/addons';
|
|
14
|
+
import { ThemeProvider } from 'emotion-theming';
|
|
15
|
+
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
16
|
+
import OnDeviceUI from './components/OnDeviceUI';
|
|
17
|
+
import { theme } from './components/Shared/theme';
|
|
18
|
+
import StoryView from './components/StoryView';
|
|
19
|
+
import createChannel from '@storybook/channel-websocket';
|
|
20
|
+
import getHost from './rn-host-detect';
|
|
21
|
+
import events from '@storybook/core-events';
|
|
22
|
+
const STORAGE_KEY = 'lastOpenedStory';
|
|
23
|
+
export class View {
|
|
24
|
+
constructor(preview) {
|
|
25
|
+
this._setStory = () => { };
|
|
26
|
+
this._ready = false;
|
|
27
|
+
this._getInitialStory = ({ initialSelection, shouldPersistSelection = true, } = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
if (initialSelection) {
|
|
29
|
+
if (typeof initialSelection === 'string') {
|
|
30
|
+
return { storySpecifier: initialSelection, viewMode: 'story' };
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
return {
|
|
34
|
+
storySpecifier: toId(initialSelection.kind, initialSelection.name),
|
|
35
|
+
viewMode: 'story',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (shouldPersistSelection) {
|
|
40
|
+
try {
|
|
41
|
+
let value = this._asyncStorageStoryId;
|
|
42
|
+
if (!value) {
|
|
43
|
+
value = yield AsyncStorage.getItem(STORAGE_KEY);
|
|
44
|
+
this._asyncStorageStoryId = value;
|
|
45
|
+
}
|
|
46
|
+
return { storySpecifier: value !== null && value !== void 0 ? value : '*', viewMode: 'story' };
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
console.warn('storybook-log: error reading from async storage', e);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { storySpecifier: '*', viewMode: 'story' };
|
|
53
|
+
});
|
|
54
|
+
this._getServerChannel = (params = {}) => {
|
|
55
|
+
const host = getHost(params.host || 'localhost');
|
|
56
|
+
const port = `:${params.port || 7007}`;
|
|
57
|
+
const query = params.query || '';
|
|
58
|
+
const websocketType = params.secured ? 'wss' : 'ws';
|
|
59
|
+
const url = `${websocketType}://${host}${port}/${query}`;
|
|
60
|
+
return createChannel({
|
|
61
|
+
url,
|
|
62
|
+
async: true,
|
|
63
|
+
onError: () => __awaiter(this, void 0, void 0, function* () { }),
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
this.getStorybookUI = (params = {}) => {
|
|
67
|
+
const { shouldPersistSelection = true, onDeviceUI = true, enableWebsockets = false } = params;
|
|
68
|
+
const initialStory = this._getInitialStory(params);
|
|
69
|
+
if (enableWebsockets) {
|
|
70
|
+
const channel = this._getServerChannel(params);
|
|
71
|
+
addons.setChannel(channel);
|
|
72
|
+
// TODO: check this with someone who knows what they're doing
|
|
73
|
+
this._preview.channel = channel;
|
|
74
|
+
this._preview.setupListeners();
|
|
75
|
+
channel.emit(events.CHANNEL_CREATED);
|
|
76
|
+
this._preview.initializeWithStoryIndex(this._storyIndex);
|
|
77
|
+
}
|
|
78
|
+
addons.loadAddons({
|
|
79
|
+
store: () => ({
|
|
80
|
+
fromId: (id) => this._preview.storyStore.getStoryContext(this._preview.storyStore.fromId(id)),
|
|
81
|
+
getSelection: () => {
|
|
82
|
+
return this._preview.currentSelection;
|
|
83
|
+
},
|
|
84
|
+
_channel: this._preview.channel,
|
|
85
|
+
}),
|
|
86
|
+
});
|
|
87
|
+
// eslint-disable-next-line consistent-this
|
|
88
|
+
const self = this;
|
|
89
|
+
const appliedTheme = Object.assign(Object.assign({}, theme), params.theme);
|
|
90
|
+
return () => {
|
|
91
|
+
const [context, setContext] = useState();
|
|
92
|
+
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
self._setStory = (newStory) => {
|
|
95
|
+
setContext(newStory);
|
|
96
|
+
if (shouldPersistSelection) {
|
|
97
|
+
AsyncStorage.setItem(STORAGE_KEY, newStory.id).catch((e) => {
|
|
98
|
+
console.warn('storybook-log: error writing to async storage', e);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
self._forceRerender = () => forceUpdate();
|
|
103
|
+
initialStory.then((story) => {
|
|
104
|
+
self._preview.urlStore.selectionSpecifier = story;
|
|
105
|
+
self._preview.selectSpecifiedStory();
|
|
106
|
+
});
|
|
107
|
+
}, []);
|
|
108
|
+
if (onDeviceUI) {
|
|
109
|
+
return (React.createElement(SafeAreaProvider, null,
|
|
110
|
+
React.createElement(ThemeProvider, { theme: appliedTheme },
|
|
111
|
+
React.createElement(OnDeviceUI, { context: context, storyIndex: self._storyIndex, isUIHidden: params.isUIHidden, tabOpen: params.tabOpen, shouldDisableKeyboardAvoidingView: params.shouldDisableKeyboardAvoidingView, keyboardAvoidingViewVerticalOffset: params.keyboardAvoidingViewVerticalOffset }))));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
return React.createElement(StoryView, { context: context });
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
this._preview = preview;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StoryIndex } from '@storybook/client-api';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import { StoryContext } from '@storybook/csf';
|
|
4
|
+
import { ReactNativeFramework } from 'src/types/types-6.0';
|
|
3
5
|
export declare const IS_EXPO: boolean;
|
|
4
6
|
interface OnDeviceUIProps {
|
|
5
|
-
|
|
7
|
+
context: StoryContext<ReactNativeFramework>;
|
|
8
|
+
storyIndex: StoryIndex;
|
|
6
9
|
url?: string;
|
|
7
10
|
tabOpen?: number;
|
|
8
11
|
isUIHidden?: boolean;
|
|
9
12
|
shouldDisableKeyboardAvoidingView?: boolean;
|
|
10
13
|
keyboardAvoidingViewVerticalOffset?: number;
|
|
11
14
|
}
|
|
12
|
-
declare const _default: React.MemoExoticComponent<({
|
|
15
|
+
declare const _default: React.MemoExoticComponent<({ context, storyIndex, isUIHidden, shouldDisableKeyboardAvoidingView, keyboardAvoidingViewVerticalOffset, tabOpen: initialTabOpen, }: OnDeviceUIProps) => JSX.Element>;
|
|
13
16
|
export default _default;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import styled from '@emotion/native';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { Animated, Dimensions, Keyboard, KeyboardAvoidingView, Platform, SafeAreaView, TouchableOpacity, StatusBar, StyleSheet, } from 'react-native';
|
|
5
|
-
import Events from '@storybook/core-events';
|
|
2
|
+
import React, { useState, useRef } from 'react';
|
|
3
|
+
import { Animated, Dimensions, Keyboard, KeyboardAvoidingView, Platform, SafeAreaView, TouchableOpacity, StatusBar, StyleSheet, View, } from 'react-native';
|
|
6
4
|
import StoryListView from '../StoryListView';
|
|
7
5
|
import StoryView from '../StoryView';
|
|
8
6
|
import AbsolutePositionedKeyboardAwareView from './absolute-positioned-keyboard-aware-view';
|
|
@@ -12,6 +10,7 @@ import Navigation from './navigation';
|
|
|
12
10
|
import { PREVIEW, ADDONS } from './navigation/constants';
|
|
13
11
|
import Panel from './Panel';
|
|
14
12
|
import { useWindowDimensions } from 'react-native';
|
|
13
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
15
14
|
const ANIMATION_DURATION = 300;
|
|
16
15
|
const IS_IOS = Platform.OS === 'ios';
|
|
17
16
|
// @ts-ignore: Property 'Expo' does not exist on type 'Global'
|
|
@@ -37,34 +36,18 @@ const absolutePosition = {
|
|
|
37
36
|
const styles = StyleSheet.create({
|
|
38
37
|
expoAndroidContainer: { paddingTop: StatusBar.currentHeight },
|
|
39
38
|
});
|
|
40
|
-
const
|
|
41
|
-
var _a;
|
|
42
|
-
const [storyId, setStoryId] = useState(((_a = storyStore.getSelection()) === null || _a === void 0 ? void 0 : _a.storyId) || '');
|
|
43
|
-
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
44
|
-
const channel = useRef(addons.getChannel());
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
const handleStoryWasSet = ({ id: newStoryId }) => setStoryId(newStoryId);
|
|
47
|
-
const currentChannel = channel.current;
|
|
48
|
-
channel.current.on(Events.SELECT_STORY, handleStoryWasSet);
|
|
49
|
-
//TODO: update preview without force
|
|
50
|
-
channel.current.on(Events.FORCE_RE_RENDER, forceUpdate);
|
|
51
|
-
return () => {
|
|
52
|
-
currentChannel.removeListener(Events.SELECT_STORY, handleStoryWasSet);
|
|
53
|
-
currentChannel.removeListener(Events.FORCE_RE_RENDER, forceUpdate);
|
|
54
|
-
};
|
|
55
|
-
}, []);
|
|
56
|
-
return storyStore.fromId(storyId);
|
|
57
|
-
};
|
|
58
|
-
const OnDeviceUI = ({ storyStore, isUIHidden, shouldDisableKeyboardAvoidingView, keyboardAvoidingViewVerticalOffset, tabOpen: initialTabOpen, }) => {
|
|
39
|
+
const OnDeviceUI = ({ context, storyIndex, isUIHidden, shouldDisableKeyboardAvoidingView, keyboardAvoidingViewVerticalOffset, tabOpen: initialTabOpen, }) => {
|
|
40
|
+
var _a, _b;
|
|
59
41
|
const [tabOpen, setTabOpen] = useState(initialTabOpen || PREVIEW);
|
|
60
42
|
const [slideBetweenAnimation, setSlideBetweenAnimation] = useState(false);
|
|
61
43
|
const [previewDimensions, setPreviewDimensions] = useState({
|
|
62
44
|
width: Dimensions.get('window').width,
|
|
63
45
|
height: Dimensions.get('window').height,
|
|
64
46
|
});
|
|
65
|
-
const story = useSelectedStory(storyStore);
|
|
66
47
|
const animatedValue = useRef(new Animated.Value(tabOpen));
|
|
67
48
|
const wide = useWindowDimensions().width >= BREAKPOINT;
|
|
49
|
+
const insets = useSafeAreaInsets();
|
|
50
|
+
const [isUIVisible, setIsUIVisible] = useState(isUIHidden !== undefined ? !isUIHidden : true);
|
|
68
51
|
const handleToggleTab = (newTabOpen) => {
|
|
69
52
|
if (newTabOpen === tabOpen) {
|
|
70
53
|
return;
|
|
@@ -82,23 +65,38 @@ const OnDeviceUI = ({ storyStore, isUIHidden, shouldDisableKeyboardAvoidingView,
|
|
|
82
65
|
Keyboard.dismiss();
|
|
83
66
|
}
|
|
84
67
|
};
|
|
68
|
+
const noSafeArea = (_b = (_a = context === null || context === void 0 ? void 0 : context.parameters) === null || _a === void 0 ? void 0 : _a.noSafeArea) !== null && _b !== void 0 ? _b : false;
|
|
85
69
|
const previewWrapperStyles = [
|
|
86
70
|
flex,
|
|
87
|
-
getPreviewPosition(
|
|
71
|
+
getPreviewPosition({
|
|
72
|
+
animatedValue: animatedValue.current,
|
|
73
|
+
previewDimensions,
|
|
74
|
+
slideBetweenAnimation,
|
|
75
|
+
wide,
|
|
76
|
+
noSafeArea,
|
|
77
|
+
insets,
|
|
78
|
+
}),
|
|
88
79
|
];
|
|
89
80
|
const previewStyles = [flex, getPreviewScale(animatedValue.current, slideBetweenAnimation, wide)];
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
81
|
+
const WrapperView = noSafeArea ? View : SafeAreaView;
|
|
82
|
+
const wrapperMargin = { marginBottom: isUIVisible ? insets.bottom + 40 : 0 };
|
|
83
|
+
return (React.createElement(React.Fragment, null,
|
|
84
|
+
React.createElement(View, { style: [flex, IS_ANDROID && IS_EXPO && styles.expoAndroidContainer] },
|
|
85
|
+
React.createElement(KeyboardAvoidingView, { enabled: !shouldDisableKeyboardAvoidingView || tabOpen !== PREVIEW, behavior: IS_IOS ? 'padding' : null, keyboardVerticalOffset: keyboardAvoidingViewVerticalOffset, style: flex },
|
|
86
|
+
React.createElement(AbsolutePositionedKeyboardAwareView, { onLayout: setPreviewDimensions, previewDimensions: previewDimensions },
|
|
87
|
+
React.createElement(Animated.View, { style: previewWrapperStyles },
|
|
88
|
+
React.createElement(Animated.View, { style: previewStyles },
|
|
89
|
+
React.createElement(Preview, { disabled: tabOpen === PREVIEW },
|
|
90
|
+
React.createElement(WrapperView, { style: [flex, wrapperMargin] },
|
|
91
|
+
React.createElement(StoryView, { context: context }))),
|
|
92
|
+
tabOpen !== PREVIEW ? (React.createElement(TouchableOpacity, { style: absolutePosition, onPress: () => handleToggleTab(PREVIEW) })) : null)),
|
|
93
|
+
React.createElement(Panel, { style: getNavigatorPanelPosition(animatedValue.current, previewDimensions.width, wide) },
|
|
94
|
+
React.createElement(StoryListView, { storyIndex: storyIndex, selectedStoryContext: context })),
|
|
95
|
+
React.createElement(Panel, { style: [
|
|
96
|
+
getAddonPanelPosition(animatedValue.current, previewDimensions.width, wide),
|
|
97
|
+
wrapperMargin,
|
|
98
|
+
] },
|
|
99
|
+
React.createElement(Addons, { active: tabOpen === ADDONS })))),
|
|
100
|
+
React.createElement(Navigation, { tabOpen: tabOpen, onChangeTab: handleToggleTab, isUIVisible: isUIVisible, setIsUIVisible: setIsUIVisible }))));
|
|
103
101
|
};
|
|
104
102
|
export default React.memo(OnDeviceUI);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { StyleSheet, Animated } from 'react-native';
|
|
3
3
|
import styled from '@emotion/native';
|
|
4
|
+
// @ts-ignore styled is being weird ;(
|
|
4
5
|
const Container = styled(Animated.View)(({ theme }) => ({
|
|
5
6
|
backgroundColor: theme.backgroundColor || 'white',
|
|
6
7
|
}));
|
|
@@ -1,28 +1,38 @@
|
|
|
1
1
|
import { Animated } from 'react-native';
|
|
2
|
+
import { EdgeInsets } from 'react-native-safe-area-context';
|
|
2
3
|
import { PreviewDimens } from './absolute-positioned-keyboard-aware-view';
|
|
3
4
|
export declare const getNavigatorPanelPosition: (animatedValue: Animated.Value, previewWidth: number, wide: boolean) => {
|
|
4
5
|
transform: {
|
|
5
|
-
translateX: Animated.AnimatedInterpolation
|
|
6
|
+
translateX: Animated.AnimatedInterpolation<string | number>;
|
|
6
7
|
}[];
|
|
7
8
|
width: number;
|
|
8
9
|
}[];
|
|
9
10
|
export declare const getAddonPanelPosition: (animatedValue: Animated.Value, previewWidth: number, wide: boolean) => {
|
|
10
11
|
transform: {
|
|
11
|
-
translateX: Animated.AnimatedInterpolation
|
|
12
|
+
translateX: Animated.AnimatedInterpolation<string | number>;
|
|
12
13
|
}[];
|
|
13
14
|
width: number;
|
|
14
15
|
}[];
|
|
15
|
-
|
|
16
|
+
declare type PreviewPositionArgs = {
|
|
17
|
+
animatedValue: Animated.Value;
|
|
18
|
+
previewDimensions: PreviewDimens;
|
|
19
|
+
slideBetweenAnimation: boolean;
|
|
20
|
+
wide: boolean;
|
|
21
|
+
noSafeArea: boolean;
|
|
22
|
+
insets: EdgeInsets;
|
|
23
|
+
};
|
|
24
|
+
export declare const getPreviewPosition: ({ animatedValue, previewDimensions: { width: previewWidth, height: previewHeight }, slideBetweenAnimation, wide, noSafeArea, insets, }: PreviewPositionArgs) => {
|
|
16
25
|
transform: ({
|
|
17
|
-
translateX: Animated.AnimatedInterpolation
|
|
26
|
+
translateX: Animated.AnimatedInterpolation<string | number>;
|
|
18
27
|
translateY?: undefined;
|
|
19
28
|
} | {
|
|
20
|
-
translateY: Animated.AnimatedInterpolation
|
|
29
|
+
translateY: Animated.AnimatedInterpolation<string | number>;
|
|
21
30
|
translateX?: undefined;
|
|
22
31
|
})[];
|
|
23
32
|
};
|
|
24
33
|
export declare const getPreviewScale: (animatedValue: Animated.Value, slideBetweenAnimation: boolean, wide: boolean) => {
|
|
25
34
|
transform: {
|
|
26
|
-
scale: Animated.AnimatedInterpolation
|
|
35
|
+
scale: Animated.AnimatedInterpolation<string | number>;
|
|
27
36
|
}[];
|
|
28
37
|
};
|
|
38
|
+
export {};
|
|
@@ -38,10 +38,11 @@ export const getAddonPanelPosition = (animatedValue, previewWidth, wide) => {
|
|
|
38
38
|
},
|
|
39
39
|
];
|
|
40
40
|
};
|
|
41
|
-
export const getPreviewPosition = (animatedValue, { width: previewWidth, height: previewHeight }, slideBetweenAnimation, wide) => {
|
|
41
|
+
export const getPreviewPosition = ({ animatedValue, previewDimensions: { width: previewWidth, height: previewHeight }, slideBetweenAnimation, wide, noSafeArea, insets, }) => {
|
|
42
42
|
const scale = wide ? PREVIEW_WIDE_SCREEN : PREVIEW_SCALE;
|
|
43
43
|
const translateX = previewWidth / 2 - (previewWidth * scale) / 2 - TRANSLATE_X_OFFSET;
|
|
44
|
-
const
|
|
44
|
+
const marginTop = noSafeArea ? 0 : insets.top;
|
|
45
|
+
const translateY = -(previewHeight / 2 - (previewHeight * scale) / 2 - TRANSLATE_Y_OFFSET) + marginTop;
|
|
45
46
|
return {
|
|
46
47
|
transform: [
|
|
47
48
|
{
|
|
@@ -53,7 +54,7 @@ export const getPreviewPosition = (animatedValue, { width: previewWidth, height:
|
|
|
53
54
|
{
|
|
54
55
|
translateY: animatedValue.interpolate({
|
|
55
56
|
inputRange: [NAVIGATOR, PREVIEW, ADDONS],
|
|
56
|
-
outputRange: [translateY, slideBetweenAnimation ? translateY :
|
|
57
|
+
outputRange: [translateY, slideBetweenAnimation ? translateY : marginTop, translateY],
|
|
57
58
|
}),
|
|
58
59
|
},
|
|
59
60
|
],
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { ViewStyle } from 'react-native';
|
|
2
3
|
export interface Props {
|
|
3
4
|
index: number;
|
|
4
5
|
onPress: (id: number) => void;
|
|
6
|
+
style: ViewStyle;
|
|
5
7
|
}
|
|
6
|
-
declare const _default: React.MemoExoticComponent<({ index, onPress }: Props) => JSX.Element>;
|
|
8
|
+
declare const _default: React.MemoExoticComponent<({ index, onPress, style }: Props) => JSX.Element>;
|
|
7
9
|
export default _default;
|
|
@@ -10,7 +10,7 @@ const Container = styled.View(({ theme }) => ({
|
|
|
10
10
|
borderBottomWidth: 1,
|
|
11
11
|
borderColor: theme.borderColor || '#e6e6e6',
|
|
12
12
|
}));
|
|
13
|
-
const Bar = ({ index, onPress }) => (React.createElement(Container,
|
|
13
|
+
const Bar = ({ index, onPress, style }) => (React.createElement(Container, { style: style },
|
|
14
14
|
React.createElement(Button, { onPress: onPress, testID: "BottomMenu.Navigator", id: NAVIGATOR, active: index === NAVIGATOR }, "NAVIGATOR"),
|
|
15
15
|
React.createElement(Button, { onPress: onPress, testID: "BottomMenu.Preview", id: PREVIEW, active: index === PREVIEW }, "PREVIEW"),
|
|
16
16
|
React.createElement(Button, { onPress: onPress, testID: "BottomMenu.Addons", id: ADDONS, active: index === ADDONS }, "ADDONS")));
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { Dispatch, SetStateAction } from 'react';
|
|
2
2
|
interface Props {
|
|
3
|
-
initialUiVisible?: boolean;
|
|
4
3
|
tabOpen: number;
|
|
5
4
|
onChangeTab: (index: number) => void;
|
|
5
|
+
isUIVisible: boolean;
|
|
6
|
+
setIsUIVisible: Dispatch<SetStateAction<boolean>>;
|
|
6
7
|
}
|
|
7
|
-
declare const _default: React.MemoExoticComponent<({ tabOpen, onChangeTab,
|
|
8
|
+
declare const _default: React.MemoExoticComponent<({ tabOpen, onChangeTab, isUIVisible, setIsUIVisible }: Props) => JSX.Element>;
|
|
8
9
|
export default _default;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import { View
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
3
4
|
import GestureRecognizer from 'react-native-swipe-gestures';
|
|
4
5
|
import Bar from './Bar';
|
|
5
6
|
import VisibilityButton from './VisibilityButton';
|
|
@@ -7,8 +8,14 @@ const SWIPE_CONFIG = {
|
|
|
7
8
|
velocityThreshold: 0.2,
|
|
8
9
|
directionalOffsetThreshold: 80,
|
|
9
10
|
};
|
|
10
|
-
const
|
|
11
|
-
|
|
11
|
+
const navStyle = {
|
|
12
|
+
position: 'absolute',
|
|
13
|
+
left: 0,
|
|
14
|
+
right: 0,
|
|
15
|
+
bottom: 0,
|
|
16
|
+
};
|
|
17
|
+
const Navigation = ({ tabOpen, onChangeTab, isUIVisible, setIsUIVisible }) => {
|
|
18
|
+
const insets = useSafeAreaInsets();
|
|
12
19
|
const handleToggleUI = () => {
|
|
13
20
|
setIsUIVisible((oldIsUIVisible) => !oldIsUIVisible);
|
|
14
21
|
};
|
|
@@ -22,11 +29,9 @@ const Navigation = ({ tabOpen, onChangeTab, initialUiVisible }) => {
|
|
|
22
29
|
onChangeTab(tabOpen - 1);
|
|
23
30
|
}
|
|
24
31
|
};
|
|
25
|
-
return (React.createElement(View,
|
|
26
|
-
React.createElement(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
React.createElement(View, null,
|
|
30
|
-
React.createElement(VisibilityButton, { onPress: handleToggleUI })))));
|
|
32
|
+
return (React.createElement(View, { style: navStyle },
|
|
33
|
+
isUIVisible && (React.createElement(GestureRecognizer, { onSwipeLeft: handleSwipeLeft, onSwipeRight: handleSwipeRight, config: SWIPE_CONFIG },
|
|
34
|
+
React.createElement(Bar, { index: tabOpen, onPress: onChangeTab, style: { paddingBottom: insets.bottom } }))),
|
|
35
|
+
React.createElement(VisibilityButton, { onPress: handleToggleUI, style: { marginBottom: insets.bottom } })));
|
|
31
36
|
};
|
|
32
37
|
export default React.memo(Navigation);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
2
3
|
interface Props {
|
|
3
4
|
onPress: () => void;
|
|
5
|
+
style?: StyleProp<ViewStyle>;
|
|
4
6
|
}
|
|
5
|
-
declare const _default: React.MemoExoticComponent<({ onPress }: Props) => JSX.Element>;
|
|
7
|
+
declare const _default: React.MemoExoticComponent<({ onPress, style }: Props) => JSX.Element>;
|
|
6
8
|
export default _default;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import styled from '@emotion/native';
|
|
3
|
+
import { View } from 'react-native';
|
|
3
4
|
const Touchable = styled.TouchableOpacity({
|
|
4
5
|
backgroundColor: 'transparent',
|
|
5
6
|
position: 'absolute',
|
|
@@ -7,10 +8,38 @@ const Touchable = styled.TouchableOpacity({
|
|
|
7
8
|
bottom: 12,
|
|
8
9
|
zIndex: 100,
|
|
9
10
|
});
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const HIDE_ICON_SIZE = 14;
|
|
12
|
+
const HIDE_ICON_BORDER_WIDTH = 1;
|
|
13
|
+
const Inner = styled.View(({ theme }) => ({
|
|
14
|
+
position: 'absolute',
|
|
15
|
+
top: 0,
|
|
16
|
+
left: 0,
|
|
17
|
+
width: HIDE_ICON_SIZE,
|
|
18
|
+
height: HIDE_ICON_SIZE,
|
|
19
|
+
borderRadius: HIDE_ICON_BORDER_WIDTH,
|
|
20
|
+
overflow: 'hidden',
|
|
21
|
+
borderColor: theme.buttonTextColor || '#999999',
|
|
22
|
+
borderWidth: HIDE_ICON_BORDER_WIDTH * 2,
|
|
13
23
|
}));
|
|
14
|
-
const
|
|
15
|
-
|
|
24
|
+
const Outer = styled.View({
|
|
25
|
+
position: 'absolute',
|
|
26
|
+
top: 0,
|
|
27
|
+
left: 0,
|
|
28
|
+
width: HIDE_ICON_SIZE,
|
|
29
|
+
height: HIDE_ICON_SIZE,
|
|
30
|
+
borderRadius: HIDE_ICON_BORDER_WIDTH,
|
|
31
|
+
overflow: 'hidden',
|
|
32
|
+
borderColor: 'white',
|
|
33
|
+
borderWidth: HIDE_ICON_BORDER_WIDTH,
|
|
34
|
+
});
|
|
35
|
+
const hideIconStyles = {
|
|
36
|
+
width: HIDE_ICON_SIZE,
|
|
37
|
+
height: HIDE_ICON_SIZE,
|
|
38
|
+
marginRight: 4,
|
|
39
|
+
};
|
|
40
|
+
const HideIcon = () => (React.createElement(View, { style: hideIconStyles },
|
|
41
|
+
React.createElement(Inner, null),
|
|
42
|
+
React.createElement(Outer, null)));
|
|
43
|
+
const VisibilityButton = ({ onPress, style }) => (React.createElement(Touchable, { onPress: onPress, style: style, testID: "Storybook.OnDeviceUI.toggleUI", accessibilityLabel: "Storybook.OnDeviceUI.toggleUI", hitSlop: { top: 5, left: 5, bottom: 5, right: 5 } },
|
|
44
|
+
React.createElement(HideIcon, null)));
|
|
16
45
|
export default React.memo(VisibilityButton);
|