@storybook/react-native-ui 9.0.0-alpha.8 → 9.0.0-beta.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/react-native-ui",
3
- "version": "9.0.0-alpha.8",
3
+ "version": "9.0.0-beta.10",
4
4
  "description": "ui components for react native storybook",
5
5
  "keywords": [
6
6
  "react",
@@ -49,17 +49,17 @@
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/jest": "^29.4.3",
52
- "@types/react": "~18.3.12",
52
+ "@types/react": "~19.0.10",
53
53
  "babel-jest": "^29.7.0",
54
54
  "jest": "^29.7.0",
55
- "react-test-renderer": "^18.3.1",
55
+ "react-test-renderer": "^19.1.0",
56
56
  "ts-dedent": "^2.2.0",
57
57
  "tsup": "^7.2.0",
58
- "typescript": "^5.3.3"
58
+ "typescript": "~5.8.3"
59
59
  },
60
60
  "dependencies": {
61
- "@storybook/react": "9.0.0-alpha.8",
62
- "@storybook/react-native-theming": "^9.0.0-alpha.8",
61
+ "@storybook/react": "9.0.0-beta.10",
62
+ "@storybook/react-native-theming": "^9.0.0-beta.10",
63
63
  "fuse.js": "^7.0.0",
64
64
  "memoizerific": "^1.11.3",
65
65
  "polished": "^4.3.1",
@@ -73,7 +73,7 @@
73
73
  "react-native-reanimated": ">=3",
74
74
  "react-native-safe-area-context": "*",
75
75
  "react-native-svg": ">=14",
76
- "storybook": "9.0.0-alpha.8"
76
+ "storybook": "9.0.0-beta.10"
77
77
  },
78
78
  "engines": {
79
79
  "node": ">=18.0.0"
@@ -81,5 +81,5 @@
81
81
  "publishConfig": {
82
82
  "access": "public"
83
83
  },
84
- "gitHead": "16659266d8aa9816490af41d0a840579a2f96805"
84
+ "gitHead": "bce7f35509d03e5a5efabb8862e993ea98e201d6"
85
85
  }
package/src/Layout.tsx CHANGED
@@ -30,14 +30,13 @@ const desktopLogoContainer = {
30
30
  paddingRight: 10,
31
31
  justifyContent: 'space-between',
32
32
  } satisfies ViewStyle;
33
+
33
34
  const contentContainerStyle = { flex: 1, overflow: 'hidden' } satisfies ViewStyle;
34
35
 
35
36
  const mobileContentStyle = { flex: 1, overflow: 'hidden' } satisfies ViewStyle;
36
37
 
37
38
  const placeholderObject = {};
38
39
 
39
- const placeholderArray = [];
40
-
41
40
  const iconFloatRightStyle = { marginLeft: 'auto' } satisfies ViewStyle;
42
41
 
43
42
  const navButtonStyle = { flexShrink: 1 } satisfies ViewStyle;
@@ -177,7 +176,6 @@ export const Layout = ({
177
176
  </View>
178
177
 
179
178
  <Sidebar
180
- extra={placeholderArray}
181
179
  previewInitialized
182
180
  indexError={undefined}
183
181
  refs={placeholderObject}
@@ -257,7 +255,6 @@ export const Layout = ({
257
255
  </View>
258
256
 
259
257
  <Sidebar
260
- extra={placeholderArray}
261
258
  previewInitialized
262
259
  indexError={undefined}
263
260
  refs={placeholderObject}
@@ -1,6 +1,6 @@
1
1
  import { BottomSheetModal } from '@gorhom/bottom-sheet';
2
2
  import { addons } from 'storybook/internal/manager-api';
3
- import { styled } from '@storybook/react-native-theming';
3
+ import { styled, useTheme } from '@storybook/react-native-theming';
4
4
  import { Addon_TypesEnum } from 'storybook/internal/types';
5
5
  import { forwardRef, useImperativeHandle, useMemo, useRef, useState } from 'react';
6
6
  import { Platform, StyleProp, Text, View, ViewStyle, useWindowDimensions } from 'react-native';
@@ -12,7 +12,6 @@ import Animated, {
12
12
  useSharedValue,
13
13
  } from 'react-native-reanimated';
14
14
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
15
- import { useTheme } from '@storybook/react-native-theming';
16
15
  import { IconButton } from './IconButton';
17
16
  import { CloseIcon } from './icon/CloseIcon';
18
17
  import { useStyle } from './util/useStyle';
@@ -108,6 +107,8 @@ export const MobileAddonsPanel = forwardRef<MobileAddonsPanelRef, { storyId?: st
108
107
  }
109
108
  );
110
109
 
110
+ MobileAddonsPanel.displayName = 'MobileAddonsPanel';
111
+
111
112
  const addonsTabsContainerStyle = {
112
113
  flex: 1,
113
114
  } satisfies StyleProp<ViewStyle>;
package/src/Refs.tsx CHANGED
@@ -13,70 +13,70 @@ export interface RefProps {
13
13
  setSelection: (selection: { refId: string; storyId: string }) => void;
14
14
  }
15
15
 
16
- const Wrapper = styled.View<{ isMain: boolean }>(({}) => ({
16
+ const Wrapper = styled.View<{ isMain: boolean }>(() => ({
17
17
  position: 'relative',
18
18
  }));
19
19
 
20
- export const Ref: FC<RefType & RefProps & { status?: State['status'] }> = React.memo(function Ref(
21
- props
22
- ) {
23
- const {
24
- index,
25
- id: refId,
26
- title = refId,
27
- isLoading: isLoadingMain,
28
- isBrowsing,
29
- selectedStoryId,
30
- loginUrl,
31
- type,
32
- expanded = true,
33
- indexError,
34
- previewInitialized,
35
- setSelection,
36
- } = props;
37
- const length = useMemo(() => (index ? Object.keys(index).length : 0), [index]);
20
+ export const Ref: FC<RefType & RefProps & { status?: State['status'] }> = React.memo(
21
+ function Ref(props) {
22
+ const {
23
+ index,
24
+ id: refId,
25
+ title = refId,
26
+ isLoading: isLoadingMain,
27
+ isBrowsing,
28
+ selectedStoryId,
29
+ loginUrl,
30
+ type,
31
+ expanded = true,
32
+ indexError,
33
+ previewInitialized,
34
+ setSelection,
35
+ } = props;
36
+ const length = useMemo(() => (index ? Object.keys(index).length : 0), [index]);
38
37
 
39
- const isLoadingInjected =
40
- (type === 'auto-inject' && !previewInitialized) || type === 'server-checked';
41
- const isLoading = isLoadingMain || isLoadingInjected || type === 'unknown';
42
- const isError = !!indexError;
43
- const isEmpty = !isLoading && length === 0;
44
- const isAuthRequired = !!loginUrl && length === 0;
38
+ const isLoadingInjected =
39
+ (type === 'auto-inject' && !previewInitialized) || type === 'server-checked';
40
+ const isLoading = isLoadingMain || isLoadingInjected || type === 'unknown';
41
+ const isError = !!indexError;
42
+ const isEmpty = !isLoading && length === 0;
43
+ const isAuthRequired = !!loginUrl && length === 0;
45
44
 
46
- const state = getStateType(isLoading, isAuthRequired, isError, isEmpty);
47
- const [isExpanded, setExpanded] = useState<boolean>(expanded);
45
+ const state = getStateType(isLoading, isAuthRequired, isError, isEmpty);
46
+ const [isExpanded, setExpanded] = useState<boolean>(expanded);
48
47
 
49
- useEffect(() => {
50
- if (index && selectedStoryId && index[selectedStoryId]) {
51
- setExpanded(true);
52
- }
53
- }, [setExpanded, index, selectedStoryId]);
48
+ useEffect(() => {
49
+ if (index && selectedStoryId && index[selectedStoryId]) {
50
+ setExpanded(true);
51
+ }
52
+ }, [setExpanded, index, selectedStoryId]);
54
53
 
55
- const onSelectStoryId = useCallback(
56
- (storyId: string) => {
57
- setSelection({ refId, storyId });
58
- },
59
- [refId, setSelection]
60
- );
54
+ const onSelectStoryId = useCallback(
55
+ (storyId: string) => {
56
+ setSelection({ refId, storyId });
57
+ },
58
+ [refId, setSelection]
59
+ );
61
60
 
62
- return (
63
- <>
64
- {isExpanded && (
65
- <Wrapper data-title={title} isMain={true}>
66
- {state === 'ready' && (
67
- <Tree
68
- status={props.status}
69
- isBrowsing={isBrowsing}
70
- isMain={true}
71
- refId={refId}
72
- data={index}
73
- docsMode={false}
74
- selectedStoryId={selectedStoryId}
75
- onSelectStoryId={onSelectStoryId}
76
- />
77
- )}
78
- </Wrapper>
79
- )}
80
- </>
81
- );
82
- });
61
+ return (
62
+ <>
63
+ {isExpanded && (
64
+ <Wrapper data-title={title} isMain={true}>
65
+ {state === 'ready' && (
66
+ <Tree
67
+ status={props.status}
68
+ isBrowsing={isBrowsing}
69
+ isMain={true}
70
+ refId={refId}
71
+ data={index}
72
+ docsMode={false}
73
+ selectedStoryId={selectedStoryId}
74
+ onSelectStoryId={onSelectStoryId}
75
+ />
76
+ )}
77
+ </Wrapper>
78
+ )}
79
+ </>
80
+ );
81
+ }
82
+ );
package/src/Search.tsx CHANGED
@@ -2,11 +2,11 @@ import { BottomSheetTextInput, useBottomSheetInternal } from '@gorhom/bottom-she
2
2
  import { styled } from '@storybook/react-native-theming';
3
3
  import type { IFuseOptions } from 'fuse.js';
4
4
  import Fuse from 'fuse.js';
5
- import React, { useCallback, useContext, useDeferredValue, useRef, useState } from 'react';
5
+ import React, { useCallback, useDeferredValue, useRef, useState } from 'react';
6
6
  import { Platform, TextInput, View } from 'react-native';
7
7
  import { CloseIcon } from './icon/CloseIcon';
8
8
  import { SearchIcon } from './icon/SearchIcon';
9
- import { useLayout } from './LayoutProvider';
9
+ import { useSelectedNode } from './SelectedNodeProvider';
10
10
  import {
11
11
  type CombinedDataset,
12
12
  type GetSearchItemProps,
@@ -17,7 +17,6 @@ import {
17
17
  type Selection,
18
18
  } from './types';
19
19
  import { searchItem } from './util/tree';
20
- import { useSelectedNode } from './SelectedNodeProvider';
21
20
 
22
21
  const DEFAULT_MAX_SEARCH_RESULTS = 50;
23
22
 
@@ -112,7 +111,7 @@ export const Search = React.memo<{
112
111
  const [inputValue, setInputValue] = useState(initialQuery);
113
112
  const [isOpen, setIsOpen] = useState(false);
114
113
  const [allComponents, showAllComponents] = useState(false);
115
- const { isMobile } = useLayout();
114
+ // const { isMobile } = useLayout();
116
115
  const { scrollToSelectedNode } = useSelectedNode();
117
116
 
118
117
  const selectStory = useCallback(
@@ -36,7 +36,8 @@ export const SelectedNodeProvider: FC<PropsWithChildren> = ({ children }) => {
36
36
  nodeRef.current.measureLayout?.(scrollRef.current as any, (_x, y) => {
37
37
  scrollRef.current?.scrollTo({ y: y - 100, animated: true });
38
38
  });
39
- } catch (error) {}
39
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
40
+ } catch (_error) {}
40
41
  }
41
42
  }, 500);
42
43
  }, []);
@@ -1,16 +1,12 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
1
2
  import React from 'react';
2
3
  import type { IndexHash, State } from 'storybook/internal/manager-api';
3
- import { types } from 'storybook/internal/manager-api';
4
- import type { StoryObj, Meta } from '@storybook/react';
5
- import type { Addon_SidebarTopType } from 'storybook/internal/types';
4
+ import { Button } from './Button';
5
+ import { LayoutProvider } from './LayoutProvider';
6
6
  import { Sidebar } from './Sidebar';
7
+ import { DEFAULT_REF_ID } from './constants';
7
8
  import { mockDataset } from './mockdata';
8
9
  import type { RefType } from './types';
9
- import { LayoutProvider } from './LayoutProvider';
10
- import { Button } from './Button';
11
- import { IconButton } from './IconButton';
12
- import { FaceHappyIcon } from './icon/FaceHappyIcon';
13
- import { DEFAULT_REF_ID } from './constants';
14
10
 
15
11
  const index = mockDataset.withRoot as IndexHash;
16
12
  const storyId = 'root-1-child-a2--grandchild-a1-1';
@@ -22,7 +18,6 @@ const meta = {
22
18
  parameters: { layout: 'fullscreen' },
23
19
  args: {
24
20
  previewInitialized: true,
25
- extra: [] as Addon_SidebarTopType[],
26
21
  index: index,
27
22
  storyId,
28
23
  refId: DEFAULT_REF_ID,
@@ -159,37 +154,6 @@ export const Searching: Story = {
159
154
  parameters: { chromatic: { delay: 2200 } },
160
155
  };
161
156
 
162
- export const Bottom: Story = {
163
- args: {
164
- bottom: [
165
- {
166
- id: '1',
167
- type: types.experimental_SIDEBAR_BOTTOM,
168
- render: () => (
169
- <Button>
170
- <FaceHappyIcon />
171
- Custom addon A
172
- </Button>
173
- ),
174
- },
175
- {
176
- id: '2',
177
- type: types.experimental_SIDEBAR_BOTTOM,
178
- render: () => <Button text="Custom addon B" Icon={FaceHappyIcon} />,
179
- },
180
- {
181
- id: '3',
182
- type: types.experimental_SIDEBAR_BOTTOM,
183
- render: () => (
184
- <IconButton>
185
- <FaceHappyIcon />
186
- </IconButton>
187
- ),
188
- },
189
- ],
190
- },
191
- };
192
-
193
157
  /**
194
158
  * Given the following sequence of events:
195
159
  * 1. Story is selected at the top of the sidebar
package/src/Sidebar.tsx CHANGED
@@ -1,11 +1,7 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { styled } from '@storybook/react-native-theming';
3
3
  import type { State } from 'storybook/internal/manager-api';
4
- import type {
5
- Addon_SidebarBottomType,
6
- Addon_SidebarTopType,
7
- API_LoadedRefData,
8
- } from 'storybook/internal/types';
4
+ import type { API_LoadedRefData } from 'storybook/internal/types';
9
5
  import { Explorer } from './Explorer';
10
6
  import { Search } from './Search';
11
7
  import { SearchResults } from './SearchResults';
@@ -74,8 +70,6 @@ export const useCombination = (
74
70
  export interface SidebarProps extends API_LoadedRefData {
75
71
  refs: State['refs'];
76
72
  status: State['status'];
77
- extra: Addon_SidebarTopType[];
78
- bottom?: Addon_SidebarBottomType[];
79
73
  storyId?: string;
80
74
  refId?: string;
81
75
  menuHighlighted?: boolean;
package/src/Tree.tsx CHANGED
@@ -16,7 +16,6 @@ import { ExpandAllIcon } from './icon/ExpandAllIcon';
16
16
  import { Item } from './types';
17
17
  import type { ExpandAction, ExpandedState } from './hooks/useExpanded';
18
18
  import { useExpanded } from './hooks/useExpanded';
19
- import { getGroupStatus, statusMapping } from './util/status';
20
19
  import { createId, getAncestorIds, getDescendantIds, isStoryHoistable } from './util/tree';
21
20
  import { useSelectedNode } from './SelectedNodeProvider';
22
21
 
@@ -158,7 +157,7 @@ export const LeafNodeStyleWrapper = styled.View(({ theme }) => ({
158
157
  borderRadius: 4,
159
158
  }));
160
159
 
161
- export const RootNode = styled.View(({}) => ({
160
+ export const RootNode = styled.View(() => ({
162
161
  display: 'flex',
163
162
  flexDirection: 'row',
164
163
  alignItems: 'center',
@@ -177,7 +176,7 @@ export const RootNodeText = styled.Text(({ theme }) => ({
177
176
  textTransform: 'uppercase',
178
177
  }));
179
178
 
180
- const CollapseButton = styled.TouchableOpacity(({}) => ({
179
+ const CollapseButton = styled.TouchableOpacity(() => ({
181
180
  display: 'flex',
182
181
  flexDirection: 'row',
183
182
  paddingVertical: 0,
package/src/TreeNode.tsx CHANGED
@@ -3,10 +3,9 @@ import { ComponentIcon } from './icon/ComponentIcon';
3
3
  import { GroupIcon } from './icon/GroupIcon';
4
4
  import { StoryIcon } from './icon/StoryIcon';
5
5
  import { CollapseIcon } from './icon/CollapseIcon';
6
- import { ComponentProps, FC, forwardRef, useMemo } from 'react';
6
+ import React, { ComponentProps, FC, forwardRef, useMemo } from 'react';
7
7
  import { transparentize } from 'polished';
8
8
  import { View } from 'react-native';
9
- import React from 'react';
10
9
 
11
10
  export interface NodeProps {
12
11
  children: React.ReactNode | React.ReactNode[];
@@ -1,5 +1,5 @@
1
1
  import type { StoriesHash } from 'storybook/internal/manager-api';
2
- import type { Dispatch, Reducer } from 'react';
2
+ import type { Dispatch } from 'react';
3
3
  import { useCallback, useEffect, useReducer } from 'react';
4
4
  import { getAncestorIds } from '../util/tree';
5
5
 
@@ -44,16 +44,8 @@ export const useExpanded = ({
44
44
  }: ExpandedProps): [ExpandedState, Dispatch<ExpandAction>] => {
45
45
  // Track the set of currently expanded nodes within this tree.
46
46
  // Root nodes are expanded by default.
47
- const [expanded, setExpanded] = useReducer<
48
- Reducer<ExpandedState, ExpandAction>,
49
- {
50
- refId: string;
51
- data: StoriesHash;
52
- rootIds: string[];
53
- initialExpanded: ExpandedState;
54
- }
55
- >(
56
- (state, { ids, value }) =>
47
+ const [expanded, setExpanded] = useReducer(
48
+ (state: ExpandedState, { ids, value }: ExpandAction) =>
57
49
  ids.reduce((acc, id) => Object.assign(acc, { [id]: value }), { ...state }),
58
50
  { refId, data, rootIds, initialExpanded },
59
51
  initializeExpanded
@@ -17,6 +17,10 @@ import type {
17
17
  } from 'storybook/internal/types';
18
18
  import countBy from 'lodash/countBy.js';
19
19
  import { dedent } from 'ts-dedent';
20
+ import isEqual from 'lodash/isEqual.js';
21
+ import mergeWith from 'lodash/mergeWith.js';
22
+ import { logger } from 'storybook/internal/client-logger';
23
+
20
24
  type ToStoriesHashOptions = {
21
25
  provider: API_Provider<API>;
22
26
  docsOptions: DocsOptions;
@@ -24,11 +28,6 @@ type ToStoriesHashOptions = {
24
28
  status: State['status'];
25
29
  };
26
30
 
27
- import isEqual from 'lodash/isEqual.js';
28
- import mergeWith from 'lodash/mergeWith.js';
29
-
30
- import { logger } from 'storybook/internal/client-logger';
31
-
32
31
  const merge = <TObj = any>(a: TObj, b: Partial<TObj>) =>
33
32
  mergeWith({}, a, b, (objValue: TObj, srcValue: Partial<TObj>) => {
34
33
  if (Array.isArray(srcValue) && Array.isArray(objValue)) {
@@ -202,16 +201,19 @@ export const transformStoryIndexToStoriesHash = (
202
201
  export const transformStoryIndexV2toV3 = (index: StoryIndexV2): StoryIndexV3 => {
203
202
  return {
204
203
  v: 3,
205
- stories: Object.values(index.stories).reduce((acc, entry) => {
206
- acc[entry.id] = {
207
- ...entry,
208
- title: entry.kind,
209
- name: entry.name || entry.story,
210
- importPath: entry.parameters.fileName || '',
211
- };
212
-
213
- return acc;
214
- }, {} as StoryIndexV3['stories']),
204
+ stories: Object.values(index.stories).reduce(
205
+ (acc, entry) => {
206
+ acc[entry.id] = {
207
+ ...entry,
208
+ title: entry.kind,
209
+ name: entry.name || entry.story,
210
+ importPath: entry.parameters.fileName || '',
211
+ };
212
+
213
+ return acc;
214
+ },
215
+ {} as StoryIndexV3['stories']
216
+ ),
215
217
  };
216
218
  };
217
219
 
@@ -219,26 +221,29 @@ export const transformStoryIndexV3toV4 = (index: StoryIndexV3): API_PreparedStor
219
221
  const countByTitle = countBy(Object.values(index.stories), 'title');
220
222
  return {
221
223
  v: 4,
222
- entries: Object.values(index.stories).reduce((acc, entry: any) => {
223
- let type: IndexEntry['type'] = 'story';
224
- if (
225
- entry.parameters?.docsOnly ||
226
- (entry.name === 'Page' && countByTitle[entry.title] === 1)
227
- ) {
228
- type = 'docs';
229
- }
230
- acc[entry.id] = {
231
- type,
232
- ...(type === 'docs' && { tags: ['stories-mdx'], storiesImports: [] }),
233
- ...entry,
234
- };
235
-
236
- // @ts-expect-error (we're removing something that should not be there)
237
- delete acc[entry.id].story;
238
- // @ts-expect-error (we're removing something that should not be there)
239
- delete acc[entry.id].kind;
240
-
241
- return acc;
242
- }, {} as API_PreparedStoryIndex['entries']),
224
+ entries: Object.values(index.stories).reduce(
225
+ (acc, entry: any) => {
226
+ let type: IndexEntry['type'] = 'story';
227
+ if (
228
+ entry.parameters?.docsOnly ||
229
+ (entry.name === 'Page' && countByTitle[entry.title] === 1)
230
+ ) {
231
+ type = 'docs';
232
+ }
233
+ acc[entry.id] = {
234
+ type,
235
+ ...(type === 'docs' && { tags: ['stories-mdx'], storiesImports: [] }),
236
+ ...entry,
237
+ };
238
+
239
+ // @ts-expect-error (we're removing something that should not be there)
240
+ delete acc[entry.id].story;
241
+ // @ts-expect-error (we're removing something that should not be there)
242
+ delete acc[entry.id].kind;
243
+
244
+ return acc;
245
+ },
246
+ {} as API_PreparedStoryIndex['entries']
247
+ ),
243
248
  };
244
249
  };
package/src/util/tree.ts CHANGED
@@ -29,18 +29,20 @@ export const getAncestorIds = memoize(1000)((data: IndexHash, id: string): strin
29
29
  getParents(id, data).map((item) => item.id)
30
30
  );
31
31
 
32
- export const getDescendantIds = memoize(1000)(
33
- (data: IndexHash, id: string, skipLeafs: boolean): string[] => {
34
- const entry = data[id];
35
- const children = entry.type === 'story' || entry.type === 'docs' ? [] : entry.children;
36
- return children.reduce((acc, childId) => {
37
- const child = data[childId];
38
- if (!child || (skipLeafs && (child.type === 'story' || child.type === 'docs'))) return acc;
39
- acc.push(childId, ...getDescendantIds(data, childId, skipLeafs));
40
- return acc;
41
- }, []);
42
- }
43
- );
32
+ export const getDescendantIds = memoize(1000)((
33
+ data: IndexHash,
34
+ id: string,
35
+ skipLeafs: boolean
36
+ ): string[] => {
37
+ const entry = data[id];
38
+ const children = entry.type === 'story' || entry.type === 'docs' ? [] : entry.children;
39
+ return children.reduce((acc, childId) => {
40
+ const child = data[childId];
41
+ if (!child || (skipLeafs && (child.type === 'story' || child.type === 'docs'))) return acc;
42
+ acc.push(childId, ...getDescendantIds(data, childId, skipLeafs));
43
+ return acc;
44
+ }, []);
45
+ });
44
46
 
45
47
  export function getPath(item: Item, ref: RefType): string[] {
46
48
  const parent = item.type !== 'root' && item.parent ? ref.index[item.parent] : null;
@@ -19,7 +19,7 @@ import { ImageStyle, StyleProp, TextStyle, ViewStyle } from 'react-native';
19
19
  */
20
20
  export const useStyle = <
21
21
  TStyle extends ViewStyle | TextStyle | ImageStyle,
22
- TOutput extends StyleProp<TStyle>
22
+ TOutput extends StyleProp<TStyle>,
23
23
  >(
24
24
  styleFactory: () => TOutput,
25
25
  deps?: DependencyList