@storybook/react-native-ui 8.0.0-alpha.3
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/LICENSE +21 -0
- package/dist/index.d.ts +492 -0
- package/dist/index.js +2860 -0
- package/package.json +85 -0
- package/src/Button.stories.tsx +134 -0
- package/src/Button.tsx +243 -0
- package/src/Explorer.stories.tsx +46 -0
- package/src/Explorer.tsx +54 -0
- package/src/IconButton.tsx +11 -0
- package/src/Layout.stories.tsx +38 -0
- package/src/Layout.tsx +103 -0
- package/src/LayoutProvider.tsx +90 -0
- package/src/MobileAddonsPanel.tsx +166 -0
- package/src/MobileMenuDrawer.tsx +75 -0
- package/src/Refs.tsx +142 -0
- package/src/Search.tsx +336 -0
- package/src/SearchResults.tsx +315 -0
- package/src/Sidebar.stories.tsx +262 -0
- package/src/Sidebar.tsx +200 -0
- package/src/Tree.stories.tsx +139 -0
- package/src/Tree.tsx +441 -0
- package/src/TreeNode.stories.tsx +122 -0
- package/src/TreeNode.tsx +146 -0
- package/src/constants.ts +4 -0
- package/src/icon/BottomBarToggleIcon.tsx +23 -0
- package/src/icon/CloseIcon.tsx +22 -0
- package/src/icon/CollapseAllIcon.tsx +17 -0
- package/src/icon/CollapseIcon.tsx +39 -0
- package/src/icon/ComponentIcon.tsx +14 -0
- package/src/icon/ExpandAllIcon.tsx +17 -0
- package/src/icon/FaceHappyIcon.tsx +18 -0
- package/src/icon/GroupIcon.tsx +14 -0
- package/src/icon/MenuIcon.tsx +18 -0
- package/src/icon/SearchIcon.tsx +17 -0
- package/src/icon/StoryIcon.tsx +14 -0
- package/src/index.tsx +9 -0
- package/src/mockdata.large.ts +25217 -0
- package/src/mockdata.ts +287 -0
- package/src/types.ts +78 -0
- package/src/useExpanded.ts +130 -0
- package/src/useLastViewed.ts +48 -0
- package/src/util/status.tsx +70 -0
- package/src/util/tree.ts +91 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { IndexHash, State } from '@storybook/manager-api';
|
|
4
|
+
import { /* ManagerContext */ types } from '@storybook/manager-api';
|
|
5
|
+
import type { StoryObj, Meta } from '@storybook/react';
|
|
6
|
+
import type { Addon_SidebarTopType } from '@storybook/types';
|
|
7
|
+
|
|
8
|
+
import { Sidebar } from './Sidebar';
|
|
9
|
+
// import { standardData as standardHeaderData } from './Heading.stories';
|
|
10
|
+
import { mockDataset } from './mockdata';
|
|
11
|
+
import type { RefType } from './types';
|
|
12
|
+
import { LayoutProvider } from './LayoutProvider';
|
|
13
|
+
import { Button } from './Button';
|
|
14
|
+
import { IconButton } from './IconButton';
|
|
15
|
+
import { FaceHappyIcon } from './icon/FaceHappyIcon';
|
|
16
|
+
import { DEFAULT_REF_ID } from './constants';
|
|
17
|
+
|
|
18
|
+
// const menuItems = [
|
|
19
|
+
// { title: 'Menu Item 1', onClick: () => console.log('onActivateMenuItem'), id: '1' },
|
|
20
|
+
// { title: 'Menu Item 2', onClick: () => console.log('onActivateMenuItem'), id: '2' },
|
|
21
|
+
// { title: 'Menu Item 3', onClick: () => console.log('onActivateMenuItem'), id: '3' },
|
|
22
|
+
// ];
|
|
23
|
+
// export const menu = menuItems;
|
|
24
|
+
const index = mockDataset.withRoot as IndexHash;
|
|
25
|
+
const storyId = 'root-1-child-a2--grandchild-a1-1';
|
|
26
|
+
|
|
27
|
+
// export const simpleData = { menu, index, storyId };
|
|
28
|
+
// export const loadingData = { menu };
|
|
29
|
+
|
|
30
|
+
const meta = {
|
|
31
|
+
component: Sidebar,
|
|
32
|
+
title: 'UI/Sidebar/Sidebar',
|
|
33
|
+
excludeStories: /.*Data$/,
|
|
34
|
+
parameters: { layout: 'fullscreen' },
|
|
35
|
+
args: {
|
|
36
|
+
previewInitialized: true,
|
|
37
|
+
// menu,
|
|
38
|
+
extra: [] as Addon_SidebarTopType[],
|
|
39
|
+
index: index,
|
|
40
|
+
storyId,
|
|
41
|
+
refId: DEFAULT_REF_ID,
|
|
42
|
+
refs: {},
|
|
43
|
+
status: {},
|
|
44
|
+
setSelection: () => {},
|
|
45
|
+
},
|
|
46
|
+
decorators: [
|
|
47
|
+
(storyFn) => (
|
|
48
|
+
// <ManagerContext.Provider
|
|
49
|
+
// value={
|
|
50
|
+
// {
|
|
51
|
+
// state: {
|
|
52
|
+
// docsOptions: {
|
|
53
|
+
// defaultName: 'Docs',
|
|
54
|
+
// autodocs: 'tag',
|
|
55
|
+
// docsMode: false,
|
|
56
|
+
// },
|
|
57
|
+
// },
|
|
58
|
+
// api: {
|
|
59
|
+
// emit: () => {},
|
|
60
|
+
// on: () => {},
|
|
61
|
+
// off: () => {},
|
|
62
|
+
// getShortcutKeys: () => ({ search: ['control', 'shift', 's'] }),
|
|
63
|
+
// },
|
|
64
|
+
// } as any
|
|
65
|
+
// }
|
|
66
|
+
// >
|
|
67
|
+
<LayoutProvider>{storyFn()}</LayoutProvider>
|
|
68
|
+
// </ManagerContext.Provider>
|
|
69
|
+
),
|
|
70
|
+
],
|
|
71
|
+
} satisfies Meta<typeof Sidebar>;
|
|
72
|
+
|
|
73
|
+
export default meta;
|
|
74
|
+
|
|
75
|
+
type Story = StoryObj<typeof meta>;
|
|
76
|
+
|
|
77
|
+
const refs: Record<string, RefType> = {
|
|
78
|
+
optimized: {
|
|
79
|
+
id: 'optimized',
|
|
80
|
+
title: 'This is a ref',
|
|
81
|
+
url: 'https://example.com',
|
|
82
|
+
type: 'lazy',
|
|
83
|
+
index,
|
|
84
|
+
previewInitialized: true,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const indexError = new Error('Failed to load index');
|
|
89
|
+
|
|
90
|
+
const refsError = {
|
|
91
|
+
optimized: {
|
|
92
|
+
...refs.optimized,
|
|
93
|
+
index: undefined as IndexHash,
|
|
94
|
+
indexError,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const refsEmpty = {
|
|
99
|
+
optimized: {
|
|
100
|
+
...refs.optimized,
|
|
101
|
+
// type: 'auto-inject',
|
|
102
|
+
index: {} as IndexHash,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const Simple: Story = {};
|
|
107
|
+
|
|
108
|
+
export const Loading: Story = {
|
|
109
|
+
args: {
|
|
110
|
+
previewInitialized: false,
|
|
111
|
+
index: undefined,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const Empty: Story = {
|
|
116
|
+
args: {
|
|
117
|
+
index: {},
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const IndexError: Story = {
|
|
122
|
+
args: {
|
|
123
|
+
indexError,
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export const WithRefs: Story = {
|
|
128
|
+
args: {
|
|
129
|
+
refs,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export const LoadingWithRefs: Story = {
|
|
134
|
+
args: {
|
|
135
|
+
...Loading.args,
|
|
136
|
+
refs,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const LoadingWithRefError: Story = {
|
|
141
|
+
args: {
|
|
142
|
+
...Loading.args,
|
|
143
|
+
refs: refsError,
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const WithRefEmpty: Story = {
|
|
148
|
+
args: {
|
|
149
|
+
...Empty.args,
|
|
150
|
+
refs: refsEmpty,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export const StatusesCollapsed: Story = {
|
|
155
|
+
args: {
|
|
156
|
+
status: Object.entries(index).reduce<State['status']>((acc, [id, item]) => {
|
|
157
|
+
if (item.type !== 'story') {
|
|
158
|
+
return acc;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (item.name.includes('B')) {
|
|
162
|
+
return {
|
|
163
|
+
...acc,
|
|
164
|
+
[id]: {
|
|
165
|
+
addonA: { status: 'warn', title: 'Addon A', description: 'We just wanted you to know' },
|
|
166
|
+
addonB: { status: 'error', title: 'Addon B', description: 'This is a big deal!' },
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return acc;
|
|
171
|
+
}, {}),
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
export const StatusesOpen: Story = {
|
|
176
|
+
...StatusesCollapsed,
|
|
177
|
+
args: {
|
|
178
|
+
...StatusesCollapsed.args,
|
|
179
|
+
status: Object.entries(index).reduce<State['status']>((acc, [id, item]) => {
|
|
180
|
+
if (item.type !== 'story') {
|
|
181
|
+
return acc;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
...acc,
|
|
186
|
+
[id]: {
|
|
187
|
+
addonA: { status: 'warn', title: 'Addon A', description: 'We just wanted you to know' },
|
|
188
|
+
addonB: { status: 'error', title: 'Addon B', description: 'This is a big deal!' },
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}, {}),
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export const Searching: Story = {
|
|
196
|
+
...StatusesOpen,
|
|
197
|
+
parameters: { chromatic: { delay: 2200 } },
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
export const Bottom: Story = {
|
|
201
|
+
args: {
|
|
202
|
+
bottom: [
|
|
203
|
+
{
|
|
204
|
+
id: '1',
|
|
205
|
+
type: types.experimental_SIDEBAR_BOTTOM,
|
|
206
|
+
render: () => (
|
|
207
|
+
<Button>
|
|
208
|
+
<FaceHappyIcon />
|
|
209
|
+
Custom addon A
|
|
210
|
+
</Button>
|
|
211
|
+
),
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
id: '2',
|
|
215
|
+
type: types.experimental_SIDEBAR_BOTTOM,
|
|
216
|
+
render: () => <Button text="Custom addon B" Icon={FaceHappyIcon} />,
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
id: '3',
|
|
220
|
+
type: types.experimental_SIDEBAR_BOTTOM,
|
|
221
|
+
render: () => (
|
|
222
|
+
<IconButton>
|
|
223
|
+
<FaceHappyIcon />
|
|
224
|
+
</IconButton>
|
|
225
|
+
),
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Given the following sequence of events:
|
|
233
|
+
* 1. Story is selected at the top of the sidebar
|
|
234
|
+
* 2. The sidebar is scrolled to the bottom
|
|
235
|
+
* 3. Some re-rendering happens because of a changed state/prop
|
|
236
|
+
* The sidebar should remain scrolled to the bottom
|
|
237
|
+
*/
|
|
238
|
+
export const Scrolled: Story = {
|
|
239
|
+
parameters: {
|
|
240
|
+
// we need a very short viewport
|
|
241
|
+
viewport: {
|
|
242
|
+
defaultViewport: 'mobile1',
|
|
243
|
+
defaultOrientation: 'landscape',
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
args: {
|
|
247
|
+
storyId: 'group-1--child-b1',
|
|
248
|
+
},
|
|
249
|
+
render: function Render(args) {
|
|
250
|
+
const [, setState] = React.useState(0);
|
|
251
|
+
return (
|
|
252
|
+
<>
|
|
253
|
+
<Button
|
|
254
|
+
style={{ position: 'absolute', zIndex: 10 }}
|
|
255
|
+
onPress={() => setState(() => Math.random())}
|
|
256
|
+
text="Change state"
|
|
257
|
+
/>
|
|
258
|
+
<Sidebar {...args} />
|
|
259
|
+
</>
|
|
260
|
+
);
|
|
261
|
+
},
|
|
262
|
+
};
|
package/src/Sidebar.tsx
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
import { styled } from '@storybook/react-native-theming';
|
|
4
|
+
// import { ScrollArea, Spaced } from '@storybook/components';
|
|
5
|
+
import type { State } from '@storybook/manager-api';
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
Addon_SidebarBottomType,
|
|
9
|
+
Addon_SidebarTopType,
|
|
10
|
+
API_LoadedRefData,
|
|
11
|
+
} from '@storybook/types';
|
|
12
|
+
// import type { HeadingProps } from './Heading';
|
|
13
|
+
// import { Heading } from './Heading';
|
|
14
|
+
|
|
15
|
+
import { Explorer } from './Explorer';
|
|
16
|
+
|
|
17
|
+
import { Search } from './Search';
|
|
18
|
+
|
|
19
|
+
import { SearchResults } from './SearchResults';
|
|
20
|
+
import type { CombinedDataset, Selection } from './types';
|
|
21
|
+
import { useLastViewed } from './useLastViewed';
|
|
22
|
+
import { DEFAULT_REF_ID } from './constants';
|
|
23
|
+
import { View } from 'react-native';
|
|
24
|
+
|
|
25
|
+
const Container = styled.View(({ theme }) => ({
|
|
26
|
+
// position: 'absolute',
|
|
27
|
+
// zIndex: 1,
|
|
28
|
+
// left: 0,
|
|
29
|
+
// top: 0,
|
|
30
|
+
// bottom: 0,
|
|
31
|
+
// right: 0,
|
|
32
|
+
width: '100%',
|
|
33
|
+
height: '100%',
|
|
34
|
+
display: 'flex',
|
|
35
|
+
flexDirection: 'column',
|
|
36
|
+
background: theme.background.content,
|
|
37
|
+
|
|
38
|
+
// [MEDIA_DESKTOP_BREAKPOINT]: {
|
|
39
|
+
// background: theme.background.app,
|
|
40
|
+
// },
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
const Top = styled.View({
|
|
44
|
+
paddingLeft: 4,
|
|
45
|
+
paddingRight: 4,
|
|
46
|
+
// paddingBottom: 20,
|
|
47
|
+
paddingTop: 16,
|
|
48
|
+
flex: 1,
|
|
49
|
+
flexDirection: 'row',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// const Bottom = styled.View(({ theme }) => ({
|
|
53
|
+
// borderTopWidth: 1,
|
|
54
|
+
// borderTopColor: theme.appBorderColor,
|
|
55
|
+
// padding: theme.layoutMargin / 2,
|
|
56
|
+
// display: 'flex',
|
|
57
|
+
// flexDirection: 'row',
|
|
58
|
+
// flexWrap: 'wrap',
|
|
59
|
+
// gap: theme.layoutMargin / 2,
|
|
60
|
+
// backgroundColor: theme.barBg,
|
|
61
|
+
// }));
|
|
62
|
+
|
|
63
|
+
const Swap = React.memo(function Swap({
|
|
64
|
+
children,
|
|
65
|
+
condition,
|
|
66
|
+
}: {
|
|
67
|
+
children: React.ReactNode;
|
|
68
|
+
condition: boolean;
|
|
69
|
+
}) {
|
|
70
|
+
const [a, b] = React.Children.toArray(children);
|
|
71
|
+
return (
|
|
72
|
+
<>
|
|
73
|
+
<View style={{ display: condition ? 'flex' : 'none' }}>{a}</View>
|
|
74
|
+
<View style={{ display: condition ? 'none' : 'flex' }}>{b}</View>
|
|
75
|
+
</>
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export const useCombination = (
|
|
80
|
+
index: SidebarProps['index'],
|
|
81
|
+
indexError: SidebarProps['indexError'],
|
|
82
|
+
previewInitialized: SidebarProps['previewInitialized'],
|
|
83
|
+
status: SidebarProps['status'],
|
|
84
|
+
refs: SidebarProps['refs']
|
|
85
|
+
): CombinedDataset => {
|
|
86
|
+
const hash = useMemo(
|
|
87
|
+
() => ({
|
|
88
|
+
[DEFAULT_REF_ID]: {
|
|
89
|
+
index,
|
|
90
|
+
indexError,
|
|
91
|
+
previewInitialized,
|
|
92
|
+
status,
|
|
93
|
+
title: null,
|
|
94
|
+
id: DEFAULT_REF_ID,
|
|
95
|
+
url: 'iframe.html',
|
|
96
|
+
},
|
|
97
|
+
...refs,
|
|
98
|
+
}),
|
|
99
|
+
[refs, index, indexError, previewInitialized, status]
|
|
100
|
+
);
|
|
101
|
+
return useMemo(() => ({ hash, entries: Object.entries(hash) }), [hash]);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export interface SidebarProps extends API_LoadedRefData {
|
|
105
|
+
refs: State['refs'];
|
|
106
|
+
status: State['status'];
|
|
107
|
+
// menu: any[];
|
|
108
|
+
extra: Addon_SidebarTopType[];
|
|
109
|
+
bottom?: Addon_SidebarBottomType[];
|
|
110
|
+
storyId?: string;
|
|
111
|
+
refId?: string;
|
|
112
|
+
menuHighlighted?: boolean;
|
|
113
|
+
setSelection: (selection: Selection) => void;
|
|
114
|
+
// enableShortcuts?: boolean;
|
|
115
|
+
// onMenuClick?: HeadingProps['onMenuClick'];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const Sidebar = React.memo(function Sidebar({
|
|
119
|
+
storyId = null,
|
|
120
|
+
refId = DEFAULT_REF_ID,
|
|
121
|
+
index,
|
|
122
|
+
indexError,
|
|
123
|
+
status,
|
|
124
|
+
previewInitialized,
|
|
125
|
+
// menu,
|
|
126
|
+
// extra,
|
|
127
|
+
// bottom = [],
|
|
128
|
+
// menuHighlighted = false,
|
|
129
|
+
// enableShortcuts = true,
|
|
130
|
+
refs = {},
|
|
131
|
+
setSelection,
|
|
132
|
+
}: // onMenuClick,
|
|
133
|
+
SidebarProps) {
|
|
134
|
+
const selected: Selection = useMemo(() => storyId && { storyId, refId }, [storyId, refId]);
|
|
135
|
+
const dataset = useCombination(index, indexError, previewInitialized, status, refs);
|
|
136
|
+
// const isLoading = !index && !indexError;
|
|
137
|
+
const lastViewedProps = useLastViewed(selected);
|
|
138
|
+
|
|
139
|
+
// const scrollRef = useRef<ScrollView>(null);
|
|
140
|
+
// const insets = useSafeAreaInsets();
|
|
141
|
+
return (
|
|
142
|
+
<Container style={{ paddingHorizontal: 10 }} /* className="container sidebar-container" */>
|
|
143
|
+
<Top /* row={1.6} */>
|
|
144
|
+
{/* <Heading
|
|
145
|
+
className="sidebar-header"
|
|
146
|
+
menuHighlighted={menuHighlighted}
|
|
147
|
+
menu={menu}
|
|
148
|
+
extra={extra}
|
|
149
|
+
skipLinkHref="#storybook-preview-wrapper"
|
|
150
|
+
isLoading={isLoading}
|
|
151
|
+
onMenuClick={onMenuClick}
|
|
152
|
+
/> */}
|
|
153
|
+
<Search
|
|
154
|
+
dataset={dataset}
|
|
155
|
+
setSelection={setSelection}
|
|
156
|
+
/* enableShortcuts={enableShortcuts} */ {...lastViewedProps}
|
|
157
|
+
>
|
|
158
|
+
{({
|
|
159
|
+
query,
|
|
160
|
+
results,
|
|
161
|
+
isBrowsing,
|
|
162
|
+
closeMenu,
|
|
163
|
+
// getMenuProps,
|
|
164
|
+
getItemProps,
|
|
165
|
+
highlightedIndex,
|
|
166
|
+
}) => (
|
|
167
|
+
<Swap condition={isBrowsing}>
|
|
168
|
+
<Explorer
|
|
169
|
+
dataset={dataset}
|
|
170
|
+
selected={selected}
|
|
171
|
+
isLoading={false}
|
|
172
|
+
isBrowsing={isBrowsing} //todo check me
|
|
173
|
+
setSelection={setSelection}
|
|
174
|
+
/>
|
|
175
|
+
|
|
176
|
+
<SearchResults
|
|
177
|
+
query={query}
|
|
178
|
+
results={results}
|
|
179
|
+
closeMenu={closeMenu}
|
|
180
|
+
// getMenuProps={getMenuProps}
|
|
181
|
+
getItemProps={getItemProps}
|
|
182
|
+
highlightedIndex={highlightedIndex}
|
|
183
|
+
// enableShortcuts={enableShortcuts}
|
|
184
|
+
isLoading={false}
|
|
185
|
+
clearLastViewed={lastViewedProps.clearLastViewed}
|
|
186
|
+
/>
|
|
187
|
+
</Swap>
|
|
188
|
+
)}
|
|
189
|
+
</Search>
|
|
190
|
+
</Top>
|
|
191
|
+
{/* {isLoading ? null : (
|
|
192
|
+
<Bottom>
|
|
193
|
+
{bottom.map(({ id, render: Render }) => (
|
|
194
|
+
<Render key={id} />
|
|
195
|
+
))}
|
|
196
|
+
</Bottom>
|
|
197
|
+
)} */}
|
|
198
|
+
</Container>
|
|
199
|
+
);
|
|
200
|
+
});
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import type { ComponentEntry, IndexHash } from '@storybook/manager-api';
|
|
3
|
+
|
|
4
|
+
import type { StoryObj, Meta } from '@storybook/react';
|
|
5
|
+
import { Tree } from './Tree';
|
|
6
|
+
import { index } from './mockdata.large';
|
|
7
|
+
import { DEFAULT_REF_ID } from './constants';
|
|
8
|
+
import { ScrollView, Text } from 'react-native';
|
|
9
|
+
|
|
10
|
+
const customViewports = {
|
|
11
|
+
sized: {
|
|
12
|
+
name: 'Sized',
|
|
13
|
+
styles: {
|
|
14
|
+
width: '380px',
|
|
15
|
+
height: '90%',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const meta = {
|
|
21
|
+
component: Tree,
|
|
22
|
+
title: 'UI/Sidebar/Tree',
|
|
23
|
+
excludeStories: /.*Data$/,
|
|
24
|
+
parameters: {
|
|
25
|
+
layout: 'fullscreen',
|
|
26
|
+
theme: 'light',
|
|
27
|
+
viewport: {
|
|
28
|
+
defaultViewport: 'sized',
|
|
29
|
+
viewports: customViewports,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
decorators: [
|
|
33
|
+
(Story) => (
|
|
34
|
+
<ScrollView>
|
|
35
|
+
<Story />
|
|
36
|
+
</ScrollView>
|
|
37
|
+
),
|
|
38
|
+
],
|
|
39
|
+
} as Meta<typeof Tree>;
|
|
40
|
+
|
|
41
|
+
export default meta;
|
|
42
|
+
|
|
43
|
+
const storyId = Object.values(index).find((story) => story.type === 'story').id;
|
|
44
|
+
|
|
45
|
+
type Story = StoryObj<typeof meta>;
|
|
46
|
+
|
|
47
|
+
export const Full: Story = {
|
|
48
|
+
args: {
|
|
49
|
+
docsMode: false,
|
|
50
|
+
isBrowsing: true,
|
|
51
|
+
isMain: true,
|
|
52
|
+
refId: DEFAULT_REF_ID,
|
|
53
|
+
},
|
|
54
|
+
render: function Render(args) {
|
|
55
|
+
const [selectedId, setSelectedId] = useState(storyId);
|
|
56
|
+
return (
|
|
57
|
+
<Tree
|
|
58
|
+
{...args}
|
|
59
|
+
data={index}
|
|
60
|
+
selectedStoryId={selectedId}
|
|
61
|
+
onSelectStoryId={setSelectedId}
|
|
62
|
+
// highlightedRef={{ current: { itemId: selectedId, refId: DEFAULT_REF_ID } }}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
export const Dark: Story = {
|
|
68
|
+
...Full,
|
|
69
|
+
parameters: { theme: 'dark' },
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const SingleStoryComponents: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
docsMode: false,
|
|
75
|
+
isBrowsing: true,
|
|
76
|
+
isMain: true,
|
|
77
|
+
refId: DEFAULT_REF_ID,
|
|
78
|
+
},
|
|
79
|
+
render: function Render(args) {
|
|
80
|
+
const [selectedId, setSelectedId] = useState('tooltip-tooltipbuildlist--default');
|
|
81
|
+
return (
|
|
82
|
+
<Tree
|
|
83
|
+
{...args}
|
|
84
|
+
data={{
|
|
85
|
+
...{
|
|
86
|
+
single: {
|
|
87
|
+
type: 'component',
|
|
88
|
+
name: 'Single',
|
|
89
|
+
id: 'single',
|
|
90
|
+
parent: null,
|
|
91
|
+
depth: 0,
|
|
92
|
+
children: ['single--single'],
|
|
93
|
+
renderLabel: () => <Text>🔥 Single</Text>,
|
|
94
|
+
},
|
|
95
|
+
'single--single': {
|
|
96
|
+
type: 'story',
|
|
97
|
+
id: 'single--single',
|
|
98
|
+
title: 'Single',
|
|
99
|
+
name: 'Single',
|
|
100
|
+
tags: [],
|
|
101
|
+
prepared: true,
|
|
102
|
+
args: {},
|
|
103
|
+
argTypes: {},
|
|
104
|
+
initialArgs: {},
|
|
105
|
+
depth: 1,
|
|
106
|
+
parent: 'single',
|
|
107
|
+
renderLabel: () => <Text>🔥 Single</Text>,
|
|
108
|
+
importPath: './single.stories.js',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
...Object.keys(index).reduce((acc, key) => {
|
|
112
|
+
if (key === 'tooltip-tooltipselect--default') {
|
|
113
|
+
acc['tooltip-tooltipselect--tooltipselect'] = {
|
|
114
|
+
...index[key],
|
|
115
|
+
id: 'tooltip-tooltipselect--tooltipselect',
|
|
116
|
+
name: 'TooltipSelect',
|
|
117
|
+
};
|
|
118
|
+
return acc;
|
|
119
|
+
}
|
|
120
|
+
if (key === 'tooltip-tooltipselect') {
|
|
121
|
+
acc[key] = {
|
|
122
|
+
...(index[key] as ComponentEntry),
|
|
123
|
+
children: ['tooltip-tooltipselect--tooltipselect'],
|
|
124
|
+
};
|
|
125
|
+
return acc;
|
|
126
|
+
}
|
|
127
|
+
if (key.startsWith('tooltip')) {
|
|
128
|
+
acc[key] = index[key];
|
|
129
|
+
}
|
|
130
|
+
return acc;
|
|
131
|
+
}, {} as IndexHash),
|
|
132
|
+
}}
|
|
133
|
+
// highlightedRef={{ current: { itemId: selectedId, refId: DEFAULT_REF_ID } }}
|
|
134
|
+
selectedStoryId={selectedId}
|
|
135
|
+
onSelectStoryId={setSelectedId}
|
|
136
|
+
/>
|
|
137
|
+
);
|
|
138
|
+
},
|
|
139
|
+
};
|