@storybook/react-native-ui 8.0.0-alpha.4 → 8.2.0-alpha.1
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 -283
- package/dist/index.js +3138 -823
- package/package.json +10 -11
- package/src/Button.tsx +2 -74
- package/src/Explorer.stories.tsx +0 -6
- package/src/Explorer.tsx +0 -16
- package/src/Layout.stories.tsx +1 -6
- package/src/Layout.tsx +32 -25
- package/src/MobileAddonsPanel.tsx +141 -126
- package/src/MobileMenuDrawer.tsx +15 -10
- package/src/Refs.tsx +3 -63
- package/src/Search.tsx +4 -97
- package/src/SearchResults.tsx +3 -73
- package/src/Sidebar.stories.tsx +4 -42
- package/src/Sidebar.tsx +7 -70
- package/src/Tree.stories.tsx +2 -10
- package/src/Tree.tsx +7 -61
- package/src/TreeNode.stories.tsx +0 -5
- package/src/TreeNode.tsx +0 -1
- package/src/icon/CloseIcon.tsx +21 -20
- package/src/icon/MenuIcon.tsx +0 -1
- package/src/icon/SearchIcon.tsx +17 -14
- package/src/index.tsx +1 -0
- package/src/mockdata.ts +1 -1
- package/src/types.ts +3 -15
- package/src/useExpanded.ts +4 -62
- package/src/util/StoryHash.ts +244 -0
- package/src/util/status.tsx +1 -1
- package/src/util/tree.ts +1 -1
package/src/Sidebar.tsx
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
|
-
|
|
3
2
|
import { styled } from '@storybook/react-native-theming';
|
|
4
|
-
|
|
5
|
-
import type { State } from '@storybook/manager-api';
|
|
6
|
-
|
|
3
|
+
import type { State } from '@storybook/core/manager-api';
|
|
7
4
|
import type {
|
|
8
5
|
Addon_SidebarBottomType,
|
|
9
6
|
Addon_SidebarTopType,
|
|
10
7
|
API_LoadedRefData,
|
|
11
|
-
} from '@storybook/types';
|
|
12
|
-
// import type { HeadingProps } from './Heading';
|
|
13
|
-
// import { Heading } from './Heading';
|
|
14
|
-
|
|
8
|
+
} from '@storybook/core/types';
|
|
15
9
|
import { Explorer } from './Explorer';
|
|
16
|
-
|
|
17
10
|
import { Search } from './Search';
|
|
18
|
-
|
|
19
11
|
import { SearchResults } from './SearchResults';
|
|
20
12
|
import type { CombinedDataset, Selection } from './types';
|
|
21
13
|
import { useLastViewed } from './useLastViewed';
|
|
@@ -23,43 +15,21 @@ import { DEFAULT_REF_ID } from './constants';
|
|
|
23
15
|
import { View } from 'react-native';
|
|
24
16
|
|
|
25
17
|
const Container = styled.View(({ theme }) => ({
|
|
26
|
-
// position: 'absolute',
|
|
27
|
-
// zIndex: 1,
|
|
28
|
-
// left: 0,
|
|
29
|
-
// top: 0,
|
|
30
|
-
// bottom: 0,
|
|
31
|
-
// right: 0,
|
|
32
18
|
width: '100%',
|
|
33
19
|
height: '100%',
|
|
34
20
|
display: 'flex',
|
|
35
21
|
flexDirection: 'column',
|
|
36
22
|
background: theme.background.content,
|
|
37
|
-
|
|
38
|
-
// [MEDIA_DESKTOP_BREAKPOINT]: {
|
|
39
|
-
// background: theme.background.app,
|
|
40
|
-
// },
|
|
41
23
|
}));
|
|
42
24
|
|
|
43
25
|
const Top = styled.View({
|
|
44
26
|
paddingLeft: 4,
|
|
45
27
|
paddingRight: 4,
|
|
46
|
-
// paddingBottom: 20,
|
|
47
28
|
paddingTop: 16,
|
|
48
29
|
flex: 1,
|
|
49
30
|
flexDirection: 'row',
|
|
50
31
|
});
|
|
51
32
|
|
|
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
33
|
const Swap = React.memo(function Swap({
|
|
64
34
|
children,
|
|
65
35
|
condition,
|
|
@@ -104,15 +74,12 @@ export const useCombination = (
|
|
|
104
74
|
export interface SidebarProps extends API_LoadedRefData {
|
|
105
75
|
refs: State['refs'];
|
|
106
76
|
status: State['status'];
|
|
107
|
-
// menu: any[];
|
|
108
77
|
extra: Addon_SidebarTopType[];
|
|
109
78
|
bottom?: Addon_SidebarBottomType[];
|
|
110
79
|
storyId?: string;
|
|
111
80
|
refId?: string;
|
|
112
81
|
menuHighlighted?: boolean;
|
|
113
82
|
setSelection: (selection: Selection) => void;
|
|
114
|
-
// enableShortcuts?: boolean;
|
|
115
|
-
// onMenuClick?: HeadingProps['onMenuClick'];
|
|
116
83
|
}
|
|
117
84
|
|
|
118
85
|
export const Sidebar = React.memo(function Sidebar({
|
|
@@ -122,25 +89,16 @@ export const Sidebar = React.memo(function Sidebar({
|
|
|
122
89
|
indexError,
|
|
123
90
|
status,
|
|
124
91
|
previewInitialized,
|
|
125
|
-
// menu,
|
|
126
|
-
// extra,
|
|
127
|
-
// bottom = [],
|
|
128
|
-
// menuHighlighted = false,
|
|
129
|
-
// enableShortcuts = true,
|
|
130
92
|
refs = {},
|
|
131
93
|
setSelection,
|
|
132
|
-
}:
|
|
133
|
-
SidebarProps) {
|
|
94
|
+
}: SidebarProps) {
|
|
134
95
|
const selected: Selection = useMemo(() => storyId && { storyId, refId }, [storyId, refId]);
|
|
135
96
|
const dataset = useCombination(index, indexError, previewInitialized, status, refs);
|
|
136
|
-
// const isLoading = !index && !indexError;
|
|
137
97
|
const lastViewedProps = useLastViewed(selected);
|
|
138
98
|
|
|
139
|
-
// const scrollRef = useRef<ScrollView>(null);
|
|
140
|
-
// const insets = useSafeAreaInsets();
|
|
141
99
|
return (
|
|
142
|
-
<Container style={{ paddingHorizontal: 10 }}
|
|
143
|
-
<Top
|
|
100
|
+
<Container style={{ paddingHorizontal: 10 }}>
|
|
101
|
+
<Top>
|
|
144
102
|
{/* <Heading
|
|
145
103
|
className="sidebar-header"
|
|
146
104
|
menuHighlighted={menuHighlighted}
|
|
@@ -150,20 +108,8 @@ SidebarProps) {
|
|
|
150
108
|
isLoading={isLoading}
|
|
151
109
|
onMenuClick={onMenuClick}
|
|
152
110
|
/> */}
|
|
153
|
-
<Search
|
|
154
|
-
|
|
155
|
-
setSelection={setSelection}
|
|
156
|
-
/* enableShortcuts={enableShortcuts} */ {...lastViewedProps}
|
|
157
|
-
>
|
|
158
|
-
{({
|
|
159
|
-
query,
|
|
160
|
-
results,
|
|
161
|
-
isBrowsing,
|
|
162
|
-
closeMenu,
|
|
163
|
-
// getMenuProps,
|
|
164
|
-
getItemProps,
|
|
165
|
-
highlightedIndex,
|
|
166
|
-
}) => (
|
|
111
|
+
<Search dataset={dataset} setSelection={setSelection} {...lastViewedProps}>
|
|
112
|
+
{({ query, results, isBrowsing, closeMenu, getItemProps, highlightedIndex }) => (
|
|
167
113
|
<Swap condition={isBrowsing}>
|
|
168
114
|
<Explorer
|
|
169
115
|
dataset={dataset}
|
|
@@ -177,10 +123,8 @@ SidebarProps) {
|
|
|
177
123
|
query={query}
|
|
178
124
|
results={results}
|
|
179
125
|
closeMenu={closeMenu}
|
|
180
|
-
// getMenuProps={getMenuProps}
|
|
181
126
|
getItemProps={getItemProps}
|
|
182
127
|
highlightedIndex={highlightedIndex}
|
|
183
|
-
// enableShortcuts={enableShortcuts}
|
|
184
128
|
isLoading={false}
|
|
185
129
|
clearLastViewed={lastViewedProps.clearLastViewed}
|
|
186
130
|
/>
|
|
@@ -188,13 +132,6 @@ SidebarProps) {
|
|
|
188
132
|
)}
|
|
189
133
|
</Search>
|
|
190
134
|
</Top>
|
|
191
|
-
{/* {isLoading ? null : (
|
|
192
|
-
<Bottom>
|
|
193
|
-
{bottom.map(({ id, render: Render }) => (
|
|
194
|
-
<Render key={id} />
|
|
195
|
-
))}
|
|
196
|
-
</Bottom>
|
|
197
|
-
)} */}
|
|
198
135
|
</Container>
|
|
199
136
|
);
|
|
200
137
|
});
|
package/src/Tree.stories.tsx
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import type { ComponentEntry, IndexHash } from '@storybook/manager-api';
|
|
3
|
-
|
|
2
|
+
import type { ComponentEntry, IndexHash } from '@storybook/core/manager-api';
|
|
4
3
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
5
4
|
import { Tree } from './Tree';
|
|
6
5
|
import { index } from './mockdata.large';
|
|
@@ -54,13 +53,7 @@ export const Full: Story = {
|
|
|
54
53
|
render: function Render(args) {
|
|
55
54
|
const [selectedId, setSelectedId] = useState(storyId);
|
|
56
55
|
return (
|
|
57
|
-
<Tree
|
|
58
|
-
{...args}
|
|
59
|
-
data={index}
|
|
60
|
-
selectedStoryId={selectedId}
|
|
61
|
-
onSelectStoryId={setSelectedId}
|
|
62
|
-
// highlightedRef={{ current: { itemId: selectedId, refId: DEFAULT_REF_ID } }}
|
|
63
|
-
/>
|
|
56
|
+
<Tree {...args} data={index} selectedStoryId={selectedId} onSelectStoryId={setSelectedId} />
|
|
64
57
|
);
|
|
65
58
|
},
|
|
66
59
|
};
|
|
@@ -130,7 +123,6 @@ export const SingleStoryComponents: Story = {
|
|
|
130
123
|
return acc;
|
|
131
124
|
}, {} as IndexHash),
|
|
132
125
|
}}
|
|
133
|
-
// highlightedRef={{ current: { itemId: selectedId, refId: DEFAULT_REF_ID } }}
|
|
134
126
|
selectedStoryId={selectedId}
|
|
135
127
|
onSelectStoryId={setSelectedId}
|
|
136
128
|
/>
|
package/src/Tree.tsx
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
API,
|
|
3
2
|
ComponentEntry,
|
|
4
3
|
GroupEntry,
|
|
5
4
|
State,
|
|
6
5
|
StoriesHash,
|
|
7
6
|
StoryEntry,
|
|
8
|
-
} from '@storybook/manager-api';
|
|
9
|
-
import { useStorybookApi } from '@storybook/manager-api';
|
|
7
|
+
} from '@storybook/core/manager-api';
|
|
10
8
|
import { styled } from '@storybook/react-native-theming';
|
|
11
9
|
import React, { useCallback, useMemo, useRef } from 'react';
|
|
12
10
|
import { IconButton } from './IconButton';
|
|
@@ -22,20 +20,6 @@ import { CollapseAllIcon } from './icon/CollapseAllIcon';
|
|
|
22
20
|
import { Item } from './types';
|
|
23
21
|
import { useLayout } from './LayoutProvider';
|
|
24
22
|
|
|
25
|
-
// export type Item = StoriesHash[keyof StoriesHash];
|
|
26
|
-
|
|
27
|
-
// export const createId = (itemId: string, refId?: string) =>
|
|
28
|
-
// !refId || refId === DEFAULT_REF_ID ? itemId : `${refId}_${itemId}`;
|
|
29
|
-
|
|
30
|
-
// export const statusPriority: API_StatusValue[] = ['unknown', 'pending', 'success', 'warn', 'error'];
|
|
31
|
-
|
|
32
|
-
// export const getHighestStatus = (statuses: API_StatusValue[]): API_StatusValue => {
|
|
33
|
-
// return statusPriority.reduce(
|
|
34
|
-
// (acc, status) => (statuses.includes(status) ? status : acc),
|
|
35
|
-
// 'unknown'
|
|
36
|
-
// );
|
|
37
|
-
// };
|
|
38
|
-
|
|
39
23
|
interface NodeProps {
|
|
40
24
|
item: Item;
|
|
41
25
|
refId: string;
|
|
@@ -50,12 +34,10 @@ interface NodeProps {
|
|
|
50
34
|
setFullyExpanded?: () => void;
|
|
51
35
|
onSelectStoryId: (itemId: string) => void;
|
|
52
36
|
status: State['status'][keyof State['status']];
|
|
53
|
-
api: API;
|
|
54
37
|
}
|
|
55
38
|
|
|
56
39
|
export const Node = React.memo<NodeProps>(function Node({
|
|
57
40
|
item,
|
|
58
|
-
// status,
|
|
59
41
|
refId,
|
|
60
42
|
isOrphan,
|
|
61
43
|
isDisplayed,
|
|
@@ -66,7 +48,6 @@ export const Node = React.memo<NodeProps>(function Node({
|
|
|
66
48
|
isExpanded,
|
|
67
49
|
setExpanded,
|
|
68
50
|
onSelectStoryId,
|
|
69
|
-
api: _1,
|
|
70
51
|
}) {
|
|
71
52
|
const { isDesktop, isMobile, closeMobileMenu } = useLayout();
|
|
72
53
|
|
|
@@ -78,16 +59,12 @@ export const Node = React.memo<NodeProps>(function Node({
|
|
|
78
59
|
|
|
79
60
|
if (item.type === 'story') {
|
|
80
61
|
const LeafNode = StoryNode;
|
|
81
|
-
// const statusValue = getHighestStatus(Object.values(status || {}).map((s) => s.status));
|
|
82
|
-
// const [icon, textColor] = statusMapping[statusValue];
|
|
83
62
|
|
|
84
63
|
return (
|
|
85
64
|
<LeafNodeStyleWrapper>
|
|
86
65
|
<LeafNode
|
|
87
66
|
selected={isSelected}
|
|
88
|
-
// style={isSelected ? {} : { color: textColor }}
|
|
89
67
|
key={id}
|
|
90
|
-
// href={getLink(item, refId)}
|
|
91
68
|
id={id}
|
|
92
69
|
depth={isOrphan ? item.depth : item.depth - 1}
|
|
93
70
|
onPress={() => {
|
|
@@ -103,16 +80,8 @@ export const Node = React.memo<NodeProps>(function Node({
|
|
|
103
80
|
|
|
104
81
|
if (item.type === 'root') {
|
|
105
82
|
return (
|
|
106
|
-
<RootNode
|
|
107
|
-
key={id}
|
|
108
|
-
id={id}
|
|
109
|
-
// className="sidebar-subheading"
|
|
110
|
-
// data-ref-id={refId}
|
|
111
|
-
// data-item-id={item.id}
|
|
112
|
-
// data-nodetype="root"
|
|
113
|
-
>
|
|
83
|
+
<RootNode key={id} id={id}>
|
|
114
84
|
<CollapseButton
|
|
115
|
-
// type="button"
|
|
116
85
|
data-action="collapse-root"
|
|
117
86
|
onPress={(event) => {
|
|
118
87
|
event.preventDefault();
|
|
@@ -121,11 +90,10 @@ export const Node = React.memo<NodeProps>(function Node({
|
|
|
121
90
|
aria-expanded={isExpanded}
|
|
122
91
|
>
|
|
123
92
|
<CollapseIcon isExpanded={isExpanded} />
|
|
124
|
-
<Text>{item.renderLabel?.(item) || item.name}</Text>
|
|
93
|
+
<Text>{item.renderLabel?.(item, {}) || item.name}</Text>
|
|
125
94
|
</CollapseButton>
|
|
126
95
|
{isExpanded && (
|
|
127
96
|
<IconButton
|
|
128
|
-
// className="sidebar-subheading-action"
|
|
129
97
|
aria-label={isFullyExpanded ? 'Expand' : 'Collapse'}
|
|
130
98
|
data-action="expand-all"
|
|
131
99
|
data-expanded={isFullyExpanded}
|
|
@@ -147,12 +115,6 @@ export const Node = React.memo<NodeProps>(function Node({
|
|
|
147
115
|
<BranchNode
|
|
148
116
|
key={id}
|
|
149
117
|
id={id}
|
|
150
|
-
// className="sidebar-item"
|
|
151
|
-
// data-ref-id={refId}
|
|
152
|
-
// data-item-id={item.id}
|
|
153
|
-
// data-parent-id={item.parent}
|
|
154
|
-
// data-nodetype={item.type === 'component' ? 'component' : 'group'}
|
|
155
|
-
// data-highlightable={isDisplayed}
|
|
156
118
|
aria-controls={item.children && item.children[0]}
|
|
157
119
|
aria-expanded={isExpanded}
|
|
158
120
|
depth={isOrphan ? item.depth : item.depth - 1}
|
|
@@ -202,7 +164,6 @@ export const RootNodeText = styled.Text(({ theme }) => ({
|
|
|
202
164
|
color: theme.textMutedColor,
|
|
203
165
|
lineHeight: 16,
|
|
204
166
|
letterSpacing: 2.5,
|
|
205
|
-
// letterSpacing: '0.16em',
|
|
206
167
|
textTransform: 'uppercase',
|
|
207
168
|
}));
|
|
208
169
|
|
|
@@ -212,7 +173,6 @@ const CollapseButton = styled.TouchableOpacity(({}) => ({
|
|
|
212
173
|
paddingVertical: 0,
|
|
213
174
|
paddingHorizontal: 8,
|
|
214
175
|
borderRadius: 4,
|
|
215
|
-
// transition: 'color 150ms, box-shadow 150ms',
|
|
216
176
|
gap: 6,
|
|
217
177
|
alignItems: 'center',
|
|
218
178
|
cursor: 'pointer',
|
|
@@ -228,18 +188,8 @@ export const Tree = React.memo<{
|
|
|
228
188
|
docsMode: boolean;
|
|
229
189
|
selectedStoryId: string | null;
|
|
230
190
|
onSelectStoryId: (storyId: string) => void;
|
|
231
|
-
}>(function Tree({
|
|
232
|
-
// isBrowsing,
|
|
233
|
-
isMain,
|
|
234
|
-
refId,
|
|
235
|
-
data,
|
|
236
|
-
status,
|
|
237
|
-
docsMode,
|
|
238
|
-
selectedStoryId,
|
|
239
|
-
onSelectStoryId,
|
|
240
|
-
}) {
|
|
191
|
+
}>(function Tree({ isMain, refId, data, status, docsMode, selectedStoryId, onSelectStoryId }) {
|
|
241
192
|
const containerRef = useRef<View>(null);
|
|
242
|
-
const api = useStorybookApi();
|
|
243
193
|
|
|
244
194
|
// Find top-level nodes and group them so we can hoist any orphans and expand any roots.
|
|
245
195
|
const [rootIds, orphanIds, initialExpanded] = useMemo(
|
|
@@ -331,14 +281,10 @@ export const Tree = React.memo<{
|
|
|
331
281
|
|
|
332
282
|
// Track expanded nodes, keep it in sync with props and enable keyboard shortcuts.
|
|
333
283
|
const [expanded, setExpanded] = useExpanded({
|
|
334
|
-
// containerRef,
|
|
335
|
-
// isBrowsing,
|
|
336
284
|
refId,
|
|
337
285
|
data: collapsedData,
|
|
338
286
|
initialExpanded,
|
|
339
287
|
rootIds,
|
|
340
|
-
// highlightedRef,
|
|
341
|
-
// setHighlightedItemId,
|
|
342
288
|
selectedStoryId,
|
|
343
289
|
onSelectStoryId,
|
|
344
290
|
});
|
|
@@ -354,7 +300,6 @@ export const Tree = React.memo<{
|
|
|
354
300
|
const descendants = expandableDescendants[item.id];
|
|
355
301
|
const isFullyExpanded = descendants.every((d: string) => expanded[d]);
|
|
356
302
|
return (
|
|
357
|
-
// @ts-expect-error (TODO)
|
|
358
303
|
<Root
|
|
359
304
|
key={id}
|
|
360
305
|
item={item}
|
|
@@ -367,6 +312,9 @@ export const Tree = React.memo<{
|
|
|
367
312
|
isFullyExpanded={isFullyExpanded}
|
|
368
313
|
expandableDescendants={descendants}
|
|
369
314
|
onSelectStoryId={onSelectStoryId}
|
|
315
|
+
docsMode={false}
|
|
316
|
+
color=""
|
|
317
|
+
status={{}}
|
|
370
318
|
/>
|
|
371
319
|
);
|
|
372
320
|
}
|
|
@@ -376,7 +324,6 @@ export const Tree = React.memo<{
|
|
|
376
324
|
|
|
377
325
|
return (
|
|
378
326
|
<Node
|
|
379
|
-
api={api}
|
|
380
327
|
key={id}
|
|
381
328
|
item={item}
|
|
382
329
|
status={status?.[itemId]}
|
|
@@ -394,7 +341,6 @@ export const Tree = React.memo<{
|
|
|
394
341
|
});
|
|
395
342
|
}, [
|
|
396
343
|
ancestry,
|
|
397
|
-
api,
|
|
398
344
|
collapsedData,
|
|
399
345
|
collapsedItems,
|
|
400
346
|
docsMode,
|
package/src/TreeNode.stories.tsx
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
// import { HighlightStyles } from './HighlightStyles';
|
|
3
|
-
// import { LeafNodeStyleWrapper } from './Tree';
|
|
4
1
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
5
2
|
import { ComponentNode, GroupNode, StoryNode } from './TreeNode';
|
|
6
3
|
import { View } from 'react-native';
|
|
7
4
|
|
|
8
|
-
// import { IconSymbols } from './IconSymbols';
|
|
9
|
-
|
|
10
5
|
const meta = {
|
|
11
6
|
title: 'UI/Sidebar/TreeNode',
|
|
12
7
|
parameters: { layout: 'fullscreen' },
|
package/src/TreeNode.tsx
CHANGED
package/src/icon/CloseIcon.tsx
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
|
|
3
1
|
import { Path, Svg, SvgProps } from 'react-native-svg';
|
|
4
2
|
|
|
5
|
-
export const CloseIcon =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
3
|
+
export const CloseIcon = ({
|
|
4
|
+
color = 'currentColor',
|
|
5
|
+
width = 14,
|
|
6
|
+
height = 14,
|
|
7
|
+
...props
|
|
8
|
+
}: SvgProps) => {
|
|
9
|
+
return (
|
|
10
|
+
<Svg width={width} height={height} viewBox="0 0 14 14" fill="none" {...props}>
|
|
11
|
+
<Path
|
|
12
|
+
d="M9.854 4.146a.5.5 0 010 .708L7.707 7l2.147 2.146a.5.5 0 01-.708.708L7 7.707 4.854 9.854a.5.5 0 01-.708-.708L6.293 7 4.146 4.854a.5.5 0 11.708-.708L7 6.293l2.146-2.147a.5.5 0 01.708 0z"
|
|
13
|
+
fill={color}
|
|
14
|
+
/>
|
|
15
|
+
<Path
|
|
16
|
+
fillRule="evenodd"
|
|
17
|
+
clipRule="evenodd"
|
|
18
|
+
d="M7 14A7 7 0 107 0a7 7 0 000 14zm0-1A6 6 0 107 1a6 6 0 000 12z"
|
|
19
|
+
fill={color}
|
|
20
|
+
/>
|
|
21
|
+
</Svg>
|
|
22
|
+
);
|
|
23
|
+
};
|
package/src/icon/MenuIcon.tsx
CHANGED
package/src/icon/SearchIcon.tsx
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Path, Svg, SvgProps } from 'react-native-svg';
|
|
3
3
|
|
|
4
|
-
export const SearchIcon =
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
export const SearchIcon = ({
|
|
5
|
+
color = 'currentColor',
|
|
6
|
+
width = 14,
|
|
7
|
+
height = 14,
|
|
8
|
+
...props
|
|
9
|
+
}: SvgProps) => {
|
|
10
|
+
return (
|
|
11
|
+
<Svg width={width} height={height} viewBox="0 0 14 14" fill="none" {...props}>
|
|
12
|
+
<Path
|
|
13
|
+
fillRule="evenodd"
|
|
14
|
+
clipRule="evenodd"
|
|
15
|
+
d="M9.544 10.206a5.5 5.5 0 11.662-.662.5.5 0 01.148.102l3 3a.5.5 0 01-.708.708l-3-3a.5.5 0 01-.102-.148zM10.5 6a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0z"
|
|
16
|
+
fill={color}
|
|
17
|
+
/>
|
|
18
|
+
</Svg>
|
|
19
|
+
);
|
|
20
|
+
};
|
package/src/index.tsx
CHANGED
package/src/mockdata.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { StoriesHash, State } from '@storybook/manager-api';
|
|
2
|
-
|
|
3
|
-
import type { API_StatusState, API_StatusValue } from '@storybook/types';
|
|
1
|
+
import type { StoriesHash, State } from '@storybook/core/manager-api';
|
|
2
|
+
import type { API_StatusState, API_StatusValue } from '@storybook/core/types';
|
|
4
3
|
import * as Fuse from 'fuse.js';
|
|
5
4
|
import { PressableProps } from 'react-native';
|
|
6
5
|
|
|
@@ -26,19 +25,10 @@ export interface StoryRef {
|
|
|
26
25
|
export type Highlight = ItemRef | null;
|
|
27
26
|
export type Selection = StoryRef | null;
|
|
28
27
|
|
|
29
|
-
// export interface Match {
|
|
30
|
-
// value: string;
|
|
31
|
-
// indices: [number, number][];
|
|
32
|
-
// key: 'name' | 'path';
|
|
33
|
-
// arrayIndex: number;
|
|
34
|
-
// }
|
|
35
|
-
|
|
36
28
|
export function isExpandType(x: any): x is ExpandType {
|
|
37
29
|
return !!(x && x.showAll);
|
|
38
30
|
}
|
|
39
|
-
|
|
40
|
-
// return !!(x && x.item);
|
|
41
|
-
// }
|
|
31
|
+
|
|
42
32
|
export interface ExpandType {
|
|
43
33
|
showAll: () => void;
|
|
44
34
|
totalCount: number;
|
|
@@ -60,7 +50,6 @@ export type SearchResultProps = SearchResult & {
|
|
|
60
50
|
onPress: PressableProps['onPress'];
|
|
61
51
|
};
|
|
62
52
|
|
|
63
|
-
// export type DownshiftItem = SearchResult | ExpandType;
|
|
64
53
|
export type GetSearchItemProps = (args: {
|
|
65
54
|
item: SearchResult;
|
|
66
55
|
index: number;
|
|
@@ -72,7 +61,6 @@ export type SearchChildrenFn = (args: {
|
|
|
72
61
|
results: SearchResult[]; // TODO fix this type
|
|
73
62
|
isBrowsing: boolean;
|
|
74
63
|
closeMenu: (cb?: () => void) => void;
|
|
75
|
-
// getMenuProps: ControllerStateAndHelpers<DownshiftItem>['getMenuProps'];
|
|
76
64
|
getItemProps: GetSearchItemProps;
|
|
77
65
|
highlightedIndex: number | null;
|
|
78
66
|
}) => React.ReactNode;
|
package/src/useExpanded.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import type { StoriesHash } from '@storybook/manager-api';
|
|
2
|
-
import {
|
|
3
|
-
import { STORIES_COLLAPSE_ALL, STORIES_EXPAND_ALL } from '@storybook/core-events';
|
|
4
|
-
|
|
5
|
-
import type { Dispatch, /* MutableRefObject, */ Reducer } from 'react';
|
|
1
|
+
import type { StoriesHash } from '@storybook/core/manager-api';
|
|
2
|
+
import type { Dispatch, Reducer } from 'react';
|
|
6
3
|
import { useCallback, useEffect, useReducer } from 'react';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import { /* isAncestor */ getAncestorIds /* getDescendantIds */ } from './util/tree';
|
|
4
|
+
import { getAncestorIds } from './util/tree';
|
|
10
5
|
|
|
11
6
|
export type ExpandedState = Record<string, boolean>;
|
|
12
7
|
|
|
@@ -16,29 +11,21 @@ export interface ExpandAction {
|
|
|
16
11
|
}
|
|
17
12
|
|
|
18
13
|
export interface ExpandedProps {
|
|
19
|
-
// containerRef: MutableRefObject<HTMLElement>;
|
|
20
|
-
// isBrowsing: boolean;
|
|
21
14
|
refId: string;
|
|
22
15
|
data: StoriesHash;
|
|
23
16
|
initialExpanded?: ExpandedState;
|
|
24
17
|
rootIds: string[];
|
|
25
|
-
// highlightedRef: MutableRefObject<Highlight>;
|
|
26
|
-
// setHighlightedItemId: (storyId: string) => void;
|
|
27
18
|
selectedStoryId: string | null;
|
|
28
19
|
onSelectStoryId: (storyId: string) => void;
|
|
29
20
|
}
|
|
30
21
|
|
|
31
22
|
const initializeExpanded = ({
|
|
32
|
-
// refId,
|
|
33
|
-
// data,
|
|
34
23
|
initialExpanded,
|
|
35
|
-
// highlightedRef,
|
|
36
24
|
rootIds,
|
|
37
25
|
}: {
|
|
38
26
|
refId: string;
|
|
39
27
|
data: StoriesHash;
|
|
40
28
|
initialExpanded?: ExpandedState;
|
|
41
|
-
// highlightedRef: MutableRefObject<Highlight>;
|
|
42
29
|
rootIds: string[];
|
|
43
30
|
}) => {
|
|
44
31
|
const highlightedAncestors = [];
|
|
@@ -48,22 +35,13 @@ const initializeExpanded = ({
|
|
|
48
35
|
);
|
|
49
36
|
};
|
|
50
37
|
|
|
51
|
-
const noop = () => {};
|
|
52
|
-
|
|
53
38
|
export const useExpanded = ({
|
|
54
|
-
// containerRef,
|
|
55
|
-
// isBrowsing,
|
|
56
39
|
refId,
|
|
57
40
|
data,
|
|
58
41
|
initialExpanded,
|
|
59
42
|
rootIds,
|
|
60
|
-
// highlightedRef,
|
|
61
|
-
// setHighlightedItemId,
|
|
62
|
-
// onSelectStoryId,
|
|
63
43
|
selectedStoryId,
|
|
64
44
|
}: ExpandedProps): [ExpandedState, Dispatch<ExpandAction>] => {
|
|
65
|
-
const api = useStorybookApi();
|
|
66
|
-
|
|
67
45
|
// Track the set of currently expanded nodes within this tree.
|
|
68
46
|
// Root nodes are expanded by default.
|
|
69
47
|
const [expanded, setExpanded] = useReducer<
|
|
@@ -71,33 +49,18 @@ export const useExpanded = ({
|
|
|
71
49
|
{
|
|
72
50
|
refId: string;
|
|
73
51
|
data: StoriesHash;
|
|
74
|
-
// highlightedRef: MutableRefObject<Highlight>;
|
|
75
52
|
rootIds: string[];
|
|
76
53
|
initialExpanded: ExpandedState;
|
|
77
54
|
}
|
|
78
55
|
>(
|
|
79
56
|
(state, { ids, value }) =>
|
|
80
57
|
ids.reduce((acc, id) => Object.assign(acc, { [id]: value }), { ...state }),
|
|
81
|
-
{ refId, data,
|
|
58
|
+
{ refId, data, rootIds, initialExpanded },
|
|
82
59
|
initializeExpanded
|
|
83
60
|
);
|
|
84
61
|
|
|
85
|
-
// const highlightElement = useCallback(
|
|
86
|
-
// (element: Element) => {
|
|
87
|
-
// setHighlightedItemId(element.getAttribute('data-item-id'));
|
|
88
|
-
// // scrollIntoView(element);
|
|
89
|
-
// },
|
|
90
|
-
// [setHighlightedItemId]
|
|
91
|
-
// );
|
|
92
|
-
|
|
93
62
|
const updateExpanded = useCallback(({ ids, value }: ExpandAction) => {
|
|
94
63
|
setExpanded({ ids, value });
|
|
95
|
-
// if (ids.length === 1) {
|
|
96
|
-
// const element = containerRef.current?.querySelector(
|
|
97
|
-
// `[data-item-id="${ids[0]}"][data-ref-id="${refId}"]`
|
|
98
|
-
// );
|
|
99
|
-
// if (element) highlightElement(element);
|
|
100
|
-
// }
|
|
101
64
|
}, []);
|
|
102
65
|
|
|
103
66
|
// Expand the whole ancestry of the currently selected story whenever it changes.
|
|
@@ -105,26 +68,5 @@ export const useExpanded = ({
|
|
|
105
68
|
setExpanded({ ids: getAncestorIds(data, selectedStoryId), value: true });
|
|
106
69
|
}, [data, selectedStoryId]);
|
|
107
70
|
|
|
108
|
-
const collapseAll = useCallback(() => {
|
|
109
|
-
const ids = Object.keys(data).filter((id) => !rootIds.includes(id));
|
|
110
|
-
setExpanded({ ids, value: false });
|
|
111
|
-
}, [data, rootIds]);
|
|
112
|
-
|
|
113
|
-
const expandAll = useCallback(() => {
|
|
114
|
-
setExpanded({ ids: Object.keys(data), value: true });
|
|
115
|
-
}, [data]);
|
|
116
|
-
|
|
117
|
-
useEffect(() => {
|
|
118
|
-
if (!api) return noop;
|
|
119
|
-
|
|
120
|
-
api.on(STORIES_COLLAPSE_ALL, collapseAll);
|
|
121
|
-
api.on(STORIES_EXPAND_ALL, expandAll);
|
|
122
|
-
|
|
123
|
-
return () => {
|
|
124
|
-
api.off(STORIES_COLLAPSE_ALL, collapseAll);
|
|
125
|
-
api.off(STORIES_EXPAND_ALL, expandAll);
|
|
126
|
-
};
|
|
127
|
-
}, [api, collapseAll, expandAll]);
|
|
128
|
-
|
|
129
71
|
return [expanded, updateExpanded];
|
|
130
72
|
};
|