-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
/
app.tsx
117 lines (102 loc) · 3.24 KB
/
app.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import React, { FunctionComponent, useMemo } from 'react';
import sizeMe from 'react-sizeme';
import { State } from '@storybook/api';
import { Symbols } from '@storybook/components';
import { Route } from '@storybook/router';
import { Global, createGlobal, styled } from '@storybook/theming';
import { Mobile } from './components/layout/mobile';
import { Desktop } from './components/layout/desktop';
import Sidebar from './containers/sidebar';
import Preview from './containers/preview';
import Panel from './containers/panel';
import Notifications from './containers/notifications';
import SettingsPages from './settings';
const View = styled.div({
position: 'fixed',
overflow: 'hidden',
height: '100vh',
width: '100vw',
});
export interface AppProps {
viewMode: State['viewMode'];
docsOnly: boolean;
layout: State['layout'];
panelCount: number;
size: {
width: number;
height: number;
};
}
const App = React.memo<AppProps>(
({ viewMode, docsOnly, layout, panelCount, size: { width, height } }) => {
let content;
const props = useMemo(
() => ({
Sidebar,
Preview,
Panel,
Notifications,
pages: [
{
key: 'settings',
render: () => <SettingsPages />,
route: (({ children }) => (
<Route path="/settings" startsWith>
{children}
</Route>
)) as FunctionComponent,
},
],
}),
[]
);
if (!width || !height) {
content = <div />;
} else if (width < 600) {
content = <Mobile {...props} viewMode={viewMode} options={layout} docsOnly={docsOnly} />;
} else {
content = (
<Desktop
{...props}
viewMode={viewMode}
options={layout}
docsOnly={docsOnly}
{...{ width, height }}
panelCount={panelCount}
/>
);
}
return (
<View>
<Global styles={createGlobal} />
<Symbols icons={['folder', 'component', 'document', 'bookmarkhollow']} />
{content}
</View>
);
},
// This is the default shallowEqual implementation, but with custom behavior for the `size` prop.
(prevProps: any, nextProps: any) => {
if (Object.is(prevProps, nextProps)) return true;
if (typeof prevProps !== 'object' || prevProps === null) return false;
if (typeof nextProps !== 'object' || nextProps === null) return false;
const keysA = Object.keys(prevProps);
const keysB = Object.keys(nextProps);
if (keysA.length !== keysB.length) return false;
// eslint-disable-next-line no-restricted-syntax
for (const key of keysA) {
if (key === 'size') {
// SizeMe injects a new `size` object every time, even if the width/height doesn't change,
// so we chech that one manually.
if (prevProps[key].width !== nextProps[key].width) return false;
if (prevProps[key].height !== nextProps[key].height) return false;
} else {
if (!Object.prototype.hasOwnProperty.call(nextProps, key)) return false;
if (!Object.is(prevProps[key], nextProps[key])) return false;
}
}
return true;
}
);
const SizedApp = sizeMe({ monitorHeight: true })(App);
App.displayName = 'App';
export default SizedApp;