@shopify/shop-minis-cli 0.0.35

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.
Files changed (152) hide show
  1. package/README.md +8 -0
  2. package/build/commands/create-mini/index.d.ts +2 -0
  3. package/build/commands/create-mini/index.js +116 -0
  4. package/build/commands/create-mini/index.js.map +1 -0
  5. package/build/commands/create-mini/utils/template-app.d.ts +1 -0
  6. package/build/commands/create-mini/utils/template-app.js +44 -0
  7. package/build/commands/create-mini/utils/template-app.js.map +1 -0
  8. package/build/commands/dev/index.d.ts +6 -0
  9. package/build/commands/dev/index.js +31 -0
  10. package/build/commands/dev/index.js.map +1 -0
  11. package/build/commands/dev/utils/android.d.ts +16 -0
  12. package/build/commands/dev/utils/android.js +165 -0
  13. package/build/commands/dev/utils/android.js.map +1 -0
  14. package/build/commands/dev/utils/binaries.d.ts +83 -0
  15. package/build/commands/dev/utils/binaries.js +173 -0
  16. package/build/commands/dev/utils/binaries.js.map +1 -0
  17. package/build/commands/dev/utils/binaries.test.d.ts +1 -0
  18. package/build/commands/dev/utils/binaries.test.js +275 -0
  19. package/build/commands/dev/utils/binaries.test.js.map +1 -0
  20. package/build/commands/dev/utils/deeplink.d.ts +3 -0
  21. package/build/commands/dev/utils/deeplink.js +30 -0
  22. package/build/commands/dev/utils/deeplink.js.map +1 -0
  23. package/build/commands/dev/utils/interactive-terminal.d.ts +23 -0
  24. package/build/commands/dev/utils/interactive-terminal.js +252 -0
  25. package/build/commands/dev/utils/interactive-terminal.js.map +1 -0
  26. package/build/commands/dev/utils/metro/metro-config.d.ts +2 -0
  27. package/build/commands/dev/utils/metro/metro-config.js +31 -0
  28. package/build/commands/dev/utils/metro/metro-config.js.map +1 -0
  29. package/build/commands/dev/utils/metro/metro-reporter.d.ts +14 -0
  30. package/build/commands/dev/utils/metro/metro-reporter.js +34 -0
  31. package/build/commands/dev/utils/metro/metro-reporter.js.map +1 -0
  32. package/build/commands/dev/utils/metro/metro-server-middleware.d.ts +6 -0
  33. package/build/commands/dev/utils/metro/metro-server-middleware.js +45 -0
  34. package/build/commands/dev/utils/metro/metro-server-middleware.js.map +1 -0
  35. package/build/commands/dev/utils/metro/metro-server.d.ts +2 -0
  36. package/build/commands/dev/utils/metro/metro-server.js +24 -0
  37. package/build/commands/dev/utils/metro/metro-server.js.map +1 -0
  38. package/build/commands/dev/utils/minis-manifest.d.ts +1 -0
  39. package/build/commands/dev/utils/minis-manifest.js +24 -0
  40. package/build/commands/dev/utils/minis-manifest.js.map +1 -0
  41. package/build/commands/dev/utils/qr-code.d.ts +1 -0
  42. package/build/commands/dev/utils/qr-code.js +12 -0
  43. package/build/commands/dev/utils/qr-code.js.map +1 -0
  44. package/build/commands/dev/utils/simulator.d.ts +19 -0
  45. package/build/commands/dev/utils/simulator.js +89 -0
  46. package/build/commands/dev/utils/simulator.js.map +1 -0
  47. package/build/commands/dev/utils/with-retries.d.ts +4 -0
  48. package/build/commands/dev/utils/with-retries.js +28 -0
  49. package/build/commands/dev/utils/with-retries.js.map +1 -0
  50. package/build/commands/generate-graphql-types/index.d.ts +5 -0
  51. package/build/commands/generate-graphql-types/index.js +90 -0
  52. package/build/commands/generate-graphql-types/index.js.map +1 -0
  53. package/build/commands/utils/exec-async-child-process.d.ts +18 -0
  54. package/build/commands/utils/exec-async-child-process.js +48 -0
  55. package/build/commands/utils/exec-async-child-process.js.map +1 -0
  56. package/build/commands/utils/wrap-with-loading-indicator.d.ts +9 -0
  57. package/build/commands/utils/wrap-with-loading-indicator.js +23 -0
  58. package/build/commands/utils/wrap-with-loading-indicator.js.map +1 -0
  59. package/build/dev-panel/images/bottomsheet.png +0 -0
  60. package/build/dev-panel/images/checkmark.svg +3 -0
  61. package/build/dev-panel/images/chevron.svg +3 -0
  62. package/build/dev-panel/images/copy.svg +4 -0
  63. package/build/dev-panel/images/get-started.svg +3 -0
  64. package/build/dev-panel/images/how-to.svg +3 -0
  65. package/build/dev-panel/images/navigation.png +0 -0
  66. package/build/dev-panel/images/references.svg +3 -0
  67. package/build/dev-panel/images/shop-minis-logo-inverse.svg +5 -0
  68. package/build/dev-panel/images/shop-minis-logo.svg +5 -0
  69. package/build/dev-panel/images/stories.png +0 -0
  70. package/build/dev-panel/images/topics.svg +3 -0
  71. package/build/dev-panel/index.html +302 -0
  72. package/build/dev-panel/middleware.d.ts +4 -0
  73. package/build/dev-panel/middleware.js +11 -0
  74. package/build/dev-panel/middleware.js.map +1 -0
  75. package/build/dev-panel/middleware.ts +6 -0
  76. package/build/dev-panel/styles.css +507 -0
  77. package/build/index.d.ts +2 -0
  78. package/build/index.js +26 -0
  79. package/build/index.js.map +1 -0
  80. package/package.json +83 -0
  81. package/templates/__template_blank/src/custom.d.ts +4 -0
  82. package/templates/__template_blank/src/index.tsx +9 -0
  83. package/templates/__template_blank/src/screens/HomeScreen.tsx +12 -0
  84. package/templates/__template_blank/src/types.ts +5 -0
  85. package/templates/__template_common/.eslintignore +1 -0
  86. package/templates/__template_common/.eslintrc.json +132 -0
  87. package/templates/__template_common/.prettierrc.json +8 -0
  88. package/templates/__template_common/babel.config.js +19 -0
  89. package/templates/__template_common/gitignore +3 -0
  90. package/templates/__template_common/index.tsx +43 -0
  91. package/templates/__template_common/metro.config.js +31 -0
  92. package/templates/__template_common/package.json +68 -0
  93. package/templates/__template_common/patches/react-native+0.68.5.patch +173 -0
  94. package/templates/__template_common/src/manifest.json +29 -0
  95. package/templates/__template_common/tsconfig.json +36 -0
  96. package/templates/__template_hello_world/src/assets/Modal-component-thumbnail.png +0 -0
  97. package/templates/__template_hello_world/src/assets/ProductCard-component-thumbnail.png +0 -0
  98. package/templates/__template_hello_world/src/assets/ProductLink-component-thumbnail.png +0 -0
  99. package/templates/__template_hello_world/src/assets/assets.d.ts +4 -0
  100. package/templates/__template_hello_world/src/assets/figma-logo.svg +14 -0
  101. package/templates/__template_hello_world/src/assets/shop-minis-logo.svg +7 -0
  102. package/templates/__template_hello_world/src/components/ButtonCTA.tsx +31 -0
  103. package/templates/__template_hello_world/src/components/ComponentLink.ts +70 -0
  104. package/templates/__template_hello_world/src/components/ComponentListItem.tsx +38 -0
  105. package/templates/__template_hello_world/src/components/FeaturedComponents.tsx +108 -0
  106. package/templates/__template_hello_world/src/components/Header.tsx +40 -0
  107. package/templates/__template_hello_world/src/data/Test.graphql +33 -0
  108. package/templates/__template_hello_world/src/data/Test.graphql.d.ts +114 -0
  109. package/templates/__template_hello_world/src/data/TestProducts.graphql +34 -0
  110. package/templates/__template_hello_world/src/data/TestProducts.graphql.d.ts +119 -0
  111. package/templates/__template_hello_world/src/index.tsx +9 -0
  112. package/templates/__template_hello_world/src/routes.tsx +107 -0
  113. package/templates/__template_hello_world/src/screens/AvatarScreen.tsx +95 -0
  114. package/templates/__template_hello_world/src/screens/BottomSheetScreen.tsx +711 -0
  115. package/templates/__template_hello_world/src/screens/ButtonsScreen.tsx +90 -0
  116. package/templates/__template_hello_world/src/screens/GridScreen.tsx +74 -0
  117. package/templates/__template_hello_world/src/screens/HomeScreen.tsx +70 -0
  118. package/templates/__template_hello_world/src/screens/IconsScreen.tsx +181 -0
  119. package/templates/__template_hello_world/src/screens/MediaScreen.tsx +130 -0
  120. package/templates/__template_hello_world/src/screens/ModalScreen.tsx +379 -0
  121. package/templates/__template_hello_world/src/screens/ProductCardGridScreen.tsx +68 -0
  122. package/templates/__template_hello_world/src/screens/ProductCardScreen.tsx +62 -0
  123. package/templates/__template_hello_world/src/screens/ProductLinkScreen.tsx +215 -0
  124. package/templates/__template_hello_world/src/screens/ProgressIndicatorScreen.tsx +77 -0
  125. package/templates/__template_hello_world/src/screens/QuantityPickerScreen.tsx +76 -0
  126. package/templates/__template_hello_world/src/screens/SpinnerScreen.tsx +63 -0
  127. package/templates/__template_hello_world/src/screens/TypographyScreen.tsx +274 -0
  128. package/templates/__template_hello_world/src/screens/WebViewScreen.tsx +42 -0
  129. package/templates/__template_hello_world/src/types.ts +25 -0
  130. package/templates/__template_snowboardz/src/assets/assets.d.ts +4 -0
  131. package/templates/__template_snowboardz/src/assets/circle-blue.svg +9 -0
  132. package/templates/__template_snowboardz/src/assets/circle-green.svg +9 -0
  133. package/templates/__template_snowboardz/src/assets/circle-purple.svg +9 -0
  134. package/templates/__template_snowboardz/src/assets/circle-rainbow.svg +34 -0
  135. package/templates/__template_snowboardz/src/assets/circle-red.svg +9 -0
  136. package/templates/__template_snowboardz/src/assets/circle-yellow.svg +9 -0
  137. package/templates/__template_snowboardz/src/assets/skill-level-icon-advanced.svg +3 -0
  138. package/templates/__template_snowboardz/src/assets/skill-level-icon-beginner.svg +3 -0
  139. package/templates/__template_snowboardz/src/assets/skill-level-icon-intermediate.svg +3 -0
  140. package/templates/__template_snowboardz/src/components/ColorButton.tsx +79 -0
  141. package/templates/__template_snowboardz/src/components/ColorPicker.tsx +40 -0
  142. package/templates/__template_snowboardz/src/components/EmptyResult.tsx +52 -0
  143. package/templates/__template_snowboardz/src/components/SkillLevelIcon.tsx +44 -0
  144. package/templates/__template_snowboardz/src/components/SkillLevelPicker.tsx +86 -0
  145. package/templates/__template_snowboardz/src/data/TestProducts.graphql +34 -0
  146. package/templates/__template_snowboardz/src/data/TestProducts.graphql.d.ts +108 -0
  147. package/templates/__template_snowboardz/src/hooks/useSnowboardData.tsx +37 -0
  148. package/templates/__template_snowboardz/src/index.tsx +9 -0
  149. package/templates/__template_snowboardz/src/routes.tsx +17 -0
  150. package/templates/__template_snowboardz/src/screens/HomeScreen.tsx +126 -0
  151. package/templates/__template_snowboardz/src/types.ts +12 -0
  152. package/templates/__template_snowboardz/src/utils.ts +17 -0
@@ -0,0 +1,379 @@
1
+ import {ComponentProps, useCallback, useState} from 'react'
2
+ import {SafeAreaView, ScrollView, FlatList} from 'react-native'
3
+ import {
4
+ Button,
5
+ Box,
6
+ Text,
7
+ Modal,
8
+ FastImageBox,
9
+ ModalSafeArea,
10
+ useTheme,
11
+ } from '@shopify/shop-minis-platform-sdk'
12
+
13
+ import {Header} from '../components/Header'
14
+
15
+ const DemoContent = ({length = 50}: {length?: number}) => (
16
+ <>
17
+ {Array.from({length}, (_, index) => (
18
+ <Box key={`item-${index}`} marginBottom="s" marginHorizontal="gutter">
19
+ <Text>item {index + 1}</Text>
20
+ </Box>
21
+ ))}
22
+ </>
23
+ )
24
+
25
+ const ExampleAutoHeight = ({
26
+ isOpen,
27
+ onDismiss,
28
+ }: {
29
+ isOpen: boolean
30
+ onDismiss: ComponentProps<typeof Modal>['onDismiss']
31
+ }) => {
32
+ return (
33
+ <Modal isOpen={isOpen} onDismiss={onDismiss} headerText="Hey there!">
34
+ <DemoContent length={5} />
35
+ </Modal>
36
+ )
37
+ }
38
+
39
+ const ExampleFixedHeight = ({
40
+ isOpen,
41
+ onDismiss,
42
+ }: {
43
+ isOpen: boolean
44
+ onDismiss: ComponentProps<typeof Modal>['onDismiss']
45
+ }) => {
46
+ return (
47
+ <Modal
48
+ isOpen={isOpen}
49
+ onDismiss={onDismiss}
50
+ height="50%"
51
+ headerText="Hello Friend! more text goes here"
52
+ >
53
+ <Box
54
+ flex={1}
55
+ borderColor="backgrounds-dangerous"
56
+ borderWidth={5}
57
+ justifyContent="center"
58
+ alignItems="center"
59
+ >
60
+ <Text>Fill the space</Text>
61
+ </Box>
62
+ </Modal>
63
+ )
64
+ }
65
+
66
+ const ExampleScrollingAutoHeight = ({
67
+ isOpen,
68
+ onDismiss,
69
+ }: {
70
+ isOpen: boolean
71
+ onDismiss: ComponentProps<typeof Modal>['onDismiss']
72
+ }) => {
73
+ const [length, setLength] = useState(2)
74
+
75
+ return (
76
+ <Modal
77
+ isOpen={isOpen}
78
+ onDismiss={onDismiss}
79
+ headerText="Hi Buddy!"
80
+ maxHeight="80%"
81
+ >
82
+ <ScrollView>
83
+ <Box marginBottom="s" marginHorizontal="gutter">
84
+ <Text>
85
+ This modal will have an auto height up until the maxHeight value
86
+ </Text>
87
+ </Box>
88
+
89
+ <Box marginBottom="s" marginHorizontal="gutter">
90
+ <Text>
91
+ Use this toggle to see how that would work with more or less content
92
+ (note: changing content height dynamically is currently not
93
+ recommended)
94
+ </Text>
95
+ </Box>
96
+
97
+ <Box marginBottom="s" marginHorizontal="gutter">
98
+ <Button
99
+ onPress={() =>
100
+ setLength(currentLength => (currentLength === 2 ? 20 : 2))
101
+ }
102
+ text="Toggle content"
103
+ />
104
+ </Box>
105
+
106
+ <DemoContent length={length} />
107
+ </ScrollView>
108
+ </Modal>
109
+ )
110
+ }
111
+
112
+ const ExampleScrollingAutoHeight2 = ({
113
+ isOpen,
114
+ onDismiss,
115
+ }: {
116
+ isOpen: boolean
117
+ onDismiss: ComponentProps<typeof Modal>['onDismiss']
118
+ }) => {
119
+ const [length, setLength] = useState(4)
120
+
121
+ return (
122
+ <Modal
123
+ isOpen={isOpen}
124
+ onDismiss={onDismiss}
125
+ headerText="Hi Buddy!"
126
+ maxHeight="60%"
127
+ >
128
+ <FlatList
129
+ data={Array.from({length}, (_, index) => ({
130
+ key: index,
131
+ title: `Thing ${index + 1}`,
132
+ }))}
133
+ renderItem={({item}) => {
134
+ if (item.key === 2) {
135
+ return (
136
+ <Box key={3} marginBottom="s" marginHorizontal="gutter">
137
+ <Button
138
+ onPress={() =>
139
+ setLength(currentLength => (currentLength === 4 ? 50 : 4))
140
+ }
141
+ text="Toggle content"
142
+ />
143
+ </Box>
144
+ )
145
+ }
146
+
147
+ return (
148
+ <Box key={item.key} marginBottom="s" marginHorizontal="gutter">
149
+ <Text>{item.title}</Text>
150
+ </Box>
151
+ )
152
+ }}
153
+ />
154
+ </Modal>
155
+ )
156
+ }
157
+
158
+ const ExampleScrollingFixedHeight = ({
159
+ isOpen,
160
+ onDismiss,
161
+ }: {
162
+ isOpen: boolean
163
+ onDismiss: ComponentProps<typeof Modal>['onDismiss']
164
+ }) => {
165
+ return (
166
+ <Modal
167
+ isOpen={isOpen}
168
+ onDismiss={onDismiss}
169
+ height={400}
170
+ headerText="Howdy!"
171
+ >
172
+ <ScrollView>
173
+ <DemoContent length={40} />
174
+ </ScrollView>
175
+ </Modal>
176
+ )
177
+ }
178
+
179
+ const ExampleHeaderLayoutVariant = ({
180
+ isOpen,
181
+ onDismiss,
182
+ }: {
183
+ isOpen: boolean
184
+ onDismiss: ComponentProps<typeof Modal>['onDismiss']
185
+ }) => {
186
+ const [debugMode, setDebugMode] = useState(false)
187
+
188
+ return (
189
+ <Modal isOpen={isOpen} onDismiss={onDismiss} headerLayoutVariant="overlay">
190
+ {/* This first box is constrained to make sure there's no overlap */}
191
+ <ModalSafeArea
192
+ alignItems="center"
193
+ paddingTop="m"
194
+ paddingBottom="xs"
195
+ backgroundColor={debugMode ? 'backgrounds-success' : undefined}
196
+ >
197
+ <FastImageBox
198
+ height={100}
199
+ width={100}
200
+ resizeMode="contain"
201
+ source={{uri: 'https://picsum.photos/100/100'}}
202
+ borderRadius={16}
203
+ />
204
+ </ModalSafeArea>
205
+
206
+ {/* These boxes can take as much space as they want */}
207
+ <Box
208
+ marginHorizontal="gutter"
209
+ marginTop="xs"
210
+ marginBottom="s"
211
+ backgroundColor={debugMode ? 'backgrounds-success' : undefined}
212
+ >
213
+ <Text variant="subtitle" textAlign="center">
214
+ ALWAYS EXCITING
215
+ </Text>
216
+ </Box>
217
+
218
+ <Box
219
+ marginHorizontal="gutter"
220
+ marginBottom="m"
221
+ backgroundColor={debugMode ? 'backgrounds-success' : undefined}
222
+ >
223
+ <Text variant="heroBold" textAlign="center">
224
+ Discover the world&apos;s greatest brands
225
+ </Text>
226
+ </Box>
227
+
228
+ <Box
229
+ marginHorizontal="gutter"
230
+ marginBottom="m"
231
+ backgroundColor={debugMode ? 'backgrounds-success' : undefined}
232
+ >
233
+ <Text textAlign="center">
234
+ Fan-favorites, future-classics - if they shine, they&apos;re on Shop.
235
+ </Text>
236
+ </Box>
237
+
238
+ <Box
239
+ marginHorizontal="gutter"
240
+ marginBottom="m"
241
+ backgroundColor={debugMode ? 'backgrounds-success' : undefined}
242
+ >
243
+ <Button
244
+ text={`${debugMode ? 'Hide' : 'Show'} bounding boxes`}
245
+ onPress={() => setDebugMode(!debugMode)}
246
+ />
247
+ </Box>
248
+ </Modal>
249
+ )
250
+ }
251
+
252
+ export const ModalScreen = () => {
253
+ const theme = useTheme()
254
+ const [examples, setExamples] = useState([
255
+ {
256
+ Component: ExampleAutoHeight,
257
+ title: 'Auto Height',
258
+ description:
259
+ 'This modal takes the height of whatever content you place in it. You must be sure this content will always fit on the smallest devices',
260
+ isVisible: false,
261
+ cta: null,
262
+ },
263
+ {
264
+ Component: ExampleFixedHeight,
265
+ title: 'Fixed Height',
266
+ description:
267
+ 'This modal has a hardcoded height. The contents can fill this space and no more',
268
+ isVisible: false,
269
+ },
270
+ {
271
+ Component: ExampleScrollingAutoHeight,
272
+ title: 'Scrolling Auto Height',
273
+ description:
274
+ 'This modal has scrolling contents. The modal will be as big as the scrolling contents up until the maxHeight is reached',
275
+ isVisible: false,
276
+ },
277
+ {
278
+ Component: ExampleScrollingAutoHeight2,
279
+ description: 'Same as above but with a flatlist',
280
+ isVisible: false,
281
+ },
282
+ {
283
+ Component: ExampleScrollingFixedHeight,
284
+ title: 'Scrolling Fixed Height',
285
+ description:
286
+ 'This modal has scrolling contents. The contents can fill this space and scroll when needed',
287
+ isVisible: false,
288
+ },
289
+ {
290
+ Component: ExampleHeaderLayoutVariant,
291
+ title: 'Header Layout Variant',
292
+ description:
293
+ 'In overlay mode your contents can use the header space for modal content',
294
+ isVisible: false,
295
+ },
296
+ ])
297
+
298
+ const openExample = useCallback((index: number) => {
299
+ setExamples(existingExamples =>
300
+ existingExamples.map((existingExample, i) => {
301
+ if (i !== index) return existingExample
302
+
303
+ return {
304
+ ...existingExample,
305
+ isVisible: true,
306
+ }
307
+ })
308
+ )
309
+ }, [])
310
+
311
+ const closeExample = useCallback((index: number) => {
312
+ setExamples(existingExamples =>
313
+ existingExamples.map((existingExample, i) => {
314
+ if (i !== index) return existingExample
315
+
316
+ return {
317
+ ...existingExample,
318
+ isVisible: false,
319
+ }
320
+ })
321
+ )
322
+ }, [])
323
+
324
+ return (
325
+ <>
326
+ <SafeAreaView
327
+ style={{flex: 1, backgroundColor: theme.colors['backgrounds-regular']}}
328
+ >
329
+ <ScrollView
330
+ style={{
331
+ flex: 1,
332
+ backgroundColor: theme.colors['backgrounds-regular'],
333
+ }}
334
+ >
335
+ <Header />
336
+ <Box px="gutter">
337
+ <Box marginBottom="s">
338
+ <Text variant="headerBold">Modal</Text>
339
+ </Box>
340
+
341
+ {examples.map(({title, cta, isVisible, description}, i) => (
342
+ <Box key={title || description} marginBottom="xl">
343
+ {title ? (
344
+ <Box marginBottom="xs">
345
+ <Text variant="bodyLargeBold">{title}</Text>
346
+ </Box>
347
+ ) : null}
348
+
349
+ {description ? (
350
+ <Box marginBottom="s">
351
+ <Text>{description}</Text>
352
+ </Box>
353
+ ) : null}
354
+
355
+ <Button
356
+ text={`Launch ${cta ?? 'example'}`}
357
+ disabled={isVisible}
358
+ onPress={() => openExample(i)}
359
+ />
360
+ </Box>
361
+ ))}
362
+ </Box>
363
+ </ScrollView>
364
+ </SafeAreaView>
365
+
366
+ {/* Notice that the modal component itself lives outside the SafeAreaView */}
367
+
368
+ {examples.map(({Component, title, description, isVisible}, i) => {
369
+ return (
370
+ <Component
371
+ key={title || description}
372
+ isOpen={isVisible}
373
+ onDismiss={() => closeExample(i)}
374
+ />
375
+ )
376
+ })}
377
+ </>
378
+ )
379
+ }
@@ -0,0 +1,68 @@
1
+ import {SafeAreaView} from 'react-native'
2
+ import {
3
+ useMinisQuery,
4
+ Box,
5
+ Text,
6
+ TouchableProduct,
7
+ ProductCard,
8
+ ProductCardGrid,
9
+ useTheme,
10
+ } from '@shopify/shop-minis-platform-sdk'
11
+
12
+ import TestProductsQuery from '../data/TestProducts.graphql'
13
+ import {Header} from '../components/Header'
14
+
15
+ const SHOP_GID = 'gid://shopify/Shop/68822335510'
16
+ const PRODUCT_GIDS = [
17
+ 'gid://shopify/Product/7982542651414',
18
+ 'gid://shopify/Product/7982528397334',
19
+ 'gid://shopify/Product/7982535704598',
20
+ 'gid://shopify/Product/7982577352726',
21
+ 'gid://shopify/Product/7982564245526',
22
+ 'gid://shopify/Product/7982547763222',
23
+ 'gid://shopify/Product/7982499495958',
24
+ 'gid://shopify/Product/7982540521494',
25
+ 'gid://shopify/Product/7982554710038',
26
+ 'gid://shopify/Product/7982557200406',
27
+ 'gid://shopify/Product/7982571257878',
28
+ 'gid://shopify/Product/7982372388886',
29
+ ]
30
+
31
+ export const ProductCardGridScreen = () => {
32
+ const theme = useTheme()
33
+ const {loading, data} = useMinisQuery(TestProductsQuery, {
34
+ variables: {
35
+ shopId: SHOP_GID,
36
+ productIds: PRODUCT_GIDS,
37
+ },
38
+ fetchPolicy: 'cache-and-network',
39
+ })
40
+
41
+ const products = data?.shop?.productsByIds ?? []
42
+
43
+ if (loading || !products) return null
44
+
45
+ return (
46
+ <SafeAreaView
47
+ style={{flex: 1, backgroundColor: theme.colors['backgrounds-regular']}}
48
+ >
49
+ <Header />
50
+ <ProductCardGrid
51
+ products={products}
52
+ ListHeaderComponent={
53
+ <Box pb="s">
54
+ <Text variant="headerBold" mb="xs">
55
+ ProductCardGrid
56
+ </Text>
57
+ </Box>
58
+ }
59
+ renderItem={({product}) => (
60
+ <TouchableProduct product={product} key={product.id}>
61
+ <ProductCard shopId={SHOP_GID} product={product} />
62
+ </TouchableProduct>
63
+ )}
64
+ contentContainerStyle={{padding: theme.spacing.gutter}}
65
+ />
66
+ </SafeAreaView>
67
+ )
68
+ }
@@ -0,0 +1,62 @@
1
+ import {SafeAreaView, ScrollView} from 'react-native'
2
+ import {
3
+ Box,
4
+ ProductCard,
5
+ Text,
6
+ TouchableProduct,
7
+ useMinisQuery,
8
+ useTheme,
9
+ } from '@shopify/shop-minis-platform-sdk'
10
+
11
+ import TestQuery from '../data/Test.graphql'
12
+ import {Header} from '../components/Header'
13
+
14
+ const SHOP_GID = 'gid://shopify/Shop/68822335510'
15
+ const PRODUCT_GID = 'gid://shopify/Product/7982542651414'
16
+
17
+ export const ProductCardScreen = () => {
18
+ const theme = useTheme()
19
+ const {loading, data} = useMinisQuery(TestQuery, {
20
+ variables: {
21
+ shopId: SHOP_GID,
22
+ productId: PRODUCT_GID,
23
+ },
24
+ fetchPolicy: 'cache-and-network',
25
+ })
26
+
27
+ if (loading || !data?.shop?.product) return null
28
+
29
+ return (
30
+ <SafeAreaView
31
+ style={{flex: 1, backgroundColor: theme.colors['backgrounds-regular']}}
32
+ >
33
+ <ScrollView>
34
+ <Header />
35
+ <Box px="gutter">
36
+ <Text variant="headerBold" mb="xs">
37
+ ProductCard
38
+ </Text>
39
+ </Box>
40
+ <Box flexDirection="row" px="gutter" pt="m">
41
+ <Box flex={1} padding="xs">
42
+ <Text variant="label">Default</Text>
43
+ <TouchableProduct product={data.shop.product}>
44
+ <ProductCard shopId={SHOP_GID} product={data.shop.product} />
45
+ </TouchableProduct>
46
+ </Box>
47
+ <Box flex={1} padding="xs">
48
+ <Text variant="label">With a badge</Text>
49
+ <TouchableProduct product={data.shop.product}>
50
+ <ProductCard
51
+ shopId={SHOP_GID}
52
+ product={data.shop.product}
53
+ badgeText="New"
54
+ badgeColor="backgrounds-dangerous"
55
+ />
56
+ </TouchableProduct>
57
+ </Box>
58
+ </Box>
59
+ </ScrollView>
60
+ </SafeAreaView>
61
+ )
62
+ }