@shopify/shop-minis-react 0.0.0-snapshot.20251211183509 → 0.0.0-snapshot.20251215163043

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.
@@ -58,7 +58,7 @@ function MerchantCardContainer({
58
58
  backgroundColor: cardTheme.backgroundColor,
59
59
  }}
60
60
  className={cn(
61
- 'relative w-full overflow-hidden rounded-xl bg-white flex flex-col border border-gray-200 aspect-square',
61
+ 'relative w-full overflow-hidden rounded-xl bg-white flex flex-col border border-gray-200 aspect-square isolate',
62
62
 
63
63
  className
64
64
  )}
@@ -40,7 +40,7 @@ vi.mock('../../hooks/user/useSavedProductsActions', () => ({
40
40
  }))
41
41
 
42
42
  // Mock formatMoney
43
- vi.mock('../../lib/formatMoney', () => ({
43
+ vi.mock('../../utils/formatMoney', () => ({
44
44
  formatMoney: vi.fn((amount: string, currencyCode: string) => {
45
45
  const numAmount = parseFloat(amount)
46
46
  return currencyCode === 'USD'
@@ -6,8 +6,8 @@ import {type Product, type ProductVariant} from '@shopify/shop-minis-platform'
6
6
  import {useShopNavigation} from '../../hooks/navigation/useShopNavigation'
7
7
  import {useSavedProductsActions} from '../../hooks/user/useSavedProductsActions'
8
8
  import {ProductReviewStars} from '../../internal/components/product-review-stars'
9
- import {formatMoney} from '../../lib/formatMoney'
10
9
  import {cn} from '../../lib/utils'
10
+ import {formatMoney} from '../../utils/formatMoney'
11
11
  import {Image} from '../atoms/image'
12
12
  import {ProductVariantPrice} from '../atoms/product-variant-price'
13
13
  import {Touchable} from '../atoms/touchable'
@@ -61,7 +61,7 @@ function ProductCardContainer({
61
61
  const content = (
62
62
  <div
63
63
  className={cn(
64
- 'relative size-full overflow-hidden rounded-xl border-0',
64
+ 'relative size-full overflow-hidden rounded-xl border-0 isolate',
65
65
  className
66
66
  )}
67
67
  {...props}
@@ -28,7 +28,7 @@ vi.mock('../../hooks/user/useSavedProductsActions', () => ({
28
28
  }))
29
29
 
30
30
  // Mock formatMoney
31
- vi.mock('../../lib/formatMoney', () => ({
31
+ vi.mock('../../utils/formatMoney', () => ({
32
32
  formatMoney: vi.fn((amount: string, currencyCode: string) => {
33
33
  const numAmount = parseFloat(amount)
34
34
  return currencyCode === 'USD'
@@ -7,8 +7,8 @@ import {Slot as SlotPrimitive} from 'radix-ui'
7
7
  import {useShopNavigation} from '../../hooks/navigation/useShopNavigation'
8
8
  import {useSavedProductsActions} from '../../hooks/user/useSavedProductsActions'
9
9
  import {ProductReviewStars} from '../../internal/components/product-review-stars'
10
- import {formatMoney} from '../../lib/formatMoney'
11
10
  import {cn} from '../../lib/utils'
11
+ import {formatMoney} from '../../utils/formatMoney'
12
12
  import {Touchable} from '../atoms/touchable'
13
13
  import {Card, CardContent, CardAction} from '../ui/card'
14
14
 
@@ -107,6 +107,19 @@ export const useImageUpload = (): UseImageUploadReturns => {
107
107
  throw new Error(links.error.message)
108
108
  }
109
109
 
110
+ if (links.mocked) {
111
+ // Skip upload and return mock data
112
+ return [
113
+ {
114
+ id: 'uploaded-image-id',
115
+ imageUrl:
116
+ 'https://cdn.shopify.com/s/files/1/0621/0463/3599/files/Mr._Bean_2007_800x800.jpg?v=1763126175',
117
+ resourceUrl:
118
+ 'https://cdn.shopify.com/s/files/1/0621/0463/3599/files/Mr._Bean_2007_800x800.jpg?v=1763126175',
119
+ },
120
+ ]
121
+ }
122
+
110
123
  // Upload single file to GCS
111
124
  const {error: uploadError} = await uploadFileToGCS(
112
125
  processedImageParams,
package/src/mocks.ts CHANGED
@@ -6,28 +6,50 @@ import {
6
6
  } from '@shopify/shop-minis-platform'
7
7
  import {ShopActions} from '@shopify/shop-minis-platform/actions'
8
8
 
9
+ const SAMPLE_IMAGE_NAMES = [
10
+ 'garnished.jpeg',
11
+ 'bath.jpeg',
12
+ 'teapot.jpg',
13
+ 'shoes.jpeg',
14
+ ]
15
+
16
+ // Simple hash function to get a deterministic index from a string
17
+ const hashString = (str: string): number => {
18
+ let hash = 0
19
+ for (let i = 0; i < str.length; i++) {
20
+ hash = (hash << 5) - hash + str.charCodeAt(i)
21
+ hash |= 0
22
+ }
23
+ return Math.abs(hash)
24
+ }
25
+
9
26
  // Helper functions for common data structures
10
27
  export const createProduct = (
11
28
  id: string,
12
29
  title: string,
13
30
  price = '99.99',
14
31
  compareAtPrice?: string
15
- ): Product => ({
16
- id,
17
- title,
18
- price: {amount: price, currencyCode: 'USD'},
19
- ...(compareAtPrice && {
20
- compareAtPrice: {amount: compareAtPrice, currencyCode: 'USD'},
21
- }),
22
- reviewAnalytics: {averageRating: 4.5, reviewCount: 10},
23
- shop: createShop('shop1', 'Mock Shop'),
24
- defaultVariantId: `variant-${id}`,
25
- isFavorited: false,
26
- featuredImage: {
27
- url: `https://cdn.shopify.com/static/sample-images/teapot.jpg`,
28
- altText: title,
29
- },
30
- })
32
+ ): Product => {
33
+ const imageIndex = hashString(id) % SAMPLE_IMAGE_NAMES.length
34
+ const imageName = SAMPLE_IMAGE_NAMES[imageIndex]
35
+
36
+ return {
37
+ id,
38
+ title,
39
+ price: {amount: price, currencyCode: 'USD'},
40
+ ...(compareAtPrice && {
41
+ compareAtPrice: {amount: compareAtPrice, currencyCode: 'USD'},
42
+ }),
43
+ reviewAnalytics: {averageRating: 4.5, reviewCount: 10},
44
+ shop: createShop('shop1', 'Mock Shop'),
45
+ defaultVariantId: `variant-${id}`,
46
+ isFavorited: false,
47
+ featuredImage: {
48
+ url: `https://cdn.shopify.com/static/sample-images/${imageName}`,
49
+ altText: title,
50
+ },
51
+ }
52
+ }
31
53
 
32
54
  export const createShop = (
33
55
  id: string,
@@ -202,7 +224,11 @@ function makeMockMethod<K extends keyof ShopActions>(
202
224
  ): ShopActions[K] {
203
225
  return ((params: Parameters<ShopActions[K]>[0]) => {
204
226
  logMockAction(String(key), params)
205
- return Promise.resolve({ok: true as const, data: result})
227
+ return Promise.resolve({
228
+ ok: true as const,
229
+ data: result,
230
+ mocked: true,
231
+ })
206
232
  }) as ShopActions[K]
207
233
  }
208
234
 
@@ -249,6 +275,7 @@ export function makeMockActions(): ShopActions {
249
275
  navigateToOrder: undefined,
250
276
  navigateToCheckout: undefined,
251
277
  createImageUploadLink: {
278
+ // This action is mocked in the actual hook. See `useImageUpload` for more details.
252
279
  targets: [
253
280
  {
254
281
  url: 'https://example.com/upload',
@@ -262,7 +289,9 @@ export function makeMockActions(): ShopActions {
262
289
  {
263
290
  id: 'file-123',
264
291
  fileStatus: 'READY',
265
- image: {url: 'https://example.com/image.jpg'},
292
+ image: {
293
+ url: 'https://example.com/image.jpg',
294
+ },
266
295
  },
267
296
  ],
268
297
  },
@@ -318,6 +347,9 @@ export function makeMockActions(): ShopActions {
318
347
  data: [
319
348
  createShop('shop-1', 'Amazing Store'),
320
349
  createShop('shop-2', 'Best Deals Shop'),
350
+ createShop('shop-3', 'Great Products'),
351
+ createShop('shop-4', 'Top Brands'),
352
+ createShop('shop-5', 'Exclusive Offers'),
321
353
  ],
322
354
  pageInfo: createPagination(),
323
355
  },
@@ -325,6 +357,9 @@ export function makeMockActions(): ShopActions {
325
357
  data: [
326
358
  createProduct('search-1', 'Search Result 1', '59.99'),
327
359
  createProduct('search-2', 'Search Result 2', '89.99'),
360
+ createProduct('search-3', 'Search Result 3', '119.99'),
361
+ createProduct('search-4', 'Search Result 4', '149.99'),
362
+ createProduct('search-5', 'Search Result 5', '179.99'),
328
363
  ],
329
364
  pageInfo: createPagination(),
330
365
  },
@@ -387,11 +422,23 @@ export function makeMockActions(): ShopActions {
387
422
  pageInfo: createPagination(),
388
423
  },
389
424
  getSavedProducts: {
390
- data: [createProduct('saved-1', 'Saved Product 1', '49.99')],
425
+ data: [
426
+ createProduct('saved-1', 'Saved Product 1', '49.99'),
427
+ createProduct('saved-2', 'Saved Product 2', '59.99'),
428
+ createProduct('saved-3', 'Saved Product 3', '69.99'),
429
+ createProduct('saved-4', 'Saved Product 4', '79.99'),
430
+ createProduct('saved-5', 'Saved Product 5', '89.99'),
431
+ ],
391
432
  pageInfo: createPagination(),
392
433
  },
393
434
  getRecentProducts: {
394
- data: [createProduct('recent-1', 'Recent Product 1', '59.99')],
435
+ data: [
436
+ createProduct('recent-1', 'Recent Product 1', '59.99'),
437
+ createProduct('recent-2', 'Recent Product 2', '69.99'),
438
+ createProduct('recent-3', 'Recent Product 3', '79.99'),
439
+ createProduct('recent-4', 'Recent Product 4', '89.99'),
440
+ createProduct('recent-5', 'Recent Product 5', '99.99'),
441
+ ],
395
442
  pageInfo: createPagination(),
396
443
  },
397
444
  getProductSearch: {
@@ -404,7 +451,15 @@ export function makeMockActions(): ShopActions {
404
451
  ],
405
452
  pageInfo: createPagination(),
406
453
  },
407
- getProducts: {data: [createProduct('prod-2', 'Product 2', '19.99')]},
454
+ getProducts: {
455
+ data: [
456
+ createProduct('prod-1', 'Product 1', '9.99'),
457
+ createProduct('prod-2', 'Product 2', '19.99'),
458
+ createProduct('prod-3', 'Product 3', '29.99'),
459
+ createProduct('prod-4', 'Product 4', '39.99'),
460
+ createProduct('prod-5', 'Product 5', '49.99'),
461
+ ],
462
+ },
408
463
  getProduct: {data: createProduct('prod-1', 'Sample Product')},
409
464
  getProductVariants: {
410
465
  data: [
@@ -434,11 +489,19 @@ export function makeMockActions(): ShopActions {
434
489
  data: createShop('shop-1', 'Sample Shop', {featuredImagesLimit: 4}),
435
490
  },
436
491
  getRecentShops: {
437
- data: [createShop('recent-shop-1', 'Recent Shop 1')],
492
+ data: [
493
+ createShop('recent-shop-1', 'Recent Shop 1'),
494
+ createShop('recent-shop-2', 'Recent Shop 2'),
495
+ createShop('recent-shop-3', 'Recent Shop 3'),
496
+ ],
438
497
  pageInfo: createPagination(),
439
498
  },
440
499
  getFollowedShops: {
441
- data: [createShop('followed-shop-1', 'Followed Shop 1')],
500
+ data: [
501
+ createShop('followed-shop-1', 'Followed Shop 1'),
502
+ createShop('followed-shop-2', 'Followed Shop 2'),
503
+ createShop('followed-shop-3', 'Followed Shop 3'),
504
+ ],
442
505
  pageInfo: createPagination(),
443
506
  },
444
507
  previewProductInAr: undefined,
@@ -522,7 +585,7 @@ export const injectMocks = ({force}: {force?: boolean} = {}) => {
522
585
  window.minisSDK = makeMockActions()
523
586
  window.minisParams = {
524
587
  handle: 'mock-handle',
525
- initialUrl: '/mock-initial-url',
588
+ initialUrl: '/',
526
589
  platform: 'web',
527
590
  }
528
591
  }
@@ -2,3 +2,4 @@ export * from './errors'
2
2
  export * from './merchant-card'
3
3
  export * from './parseUrl'
4
4
  export * from './image'
5
+ export * from './formatMoney'
@@ -1 +0,0 @@
1
- {"version":3,"file":"formatMoney.js","sources":["../../src/lib/formatMoney.ts"],"sourcesContent":["/**\n * Formats money amount with appropriate currency symbol\n * Uses browser's Intl.NumberFormat for consistent currency formatting\n */\nexport function formatMoney(amount: string, currencyCode: string): string {\n try {\n // Use en-US specifically for USD to get $ instead of US$\n // For other currencies, use browser locale but fallback to en-US\n const locale =\n currencyCode === 'USD' ? 'en-US' : navigator.language || 'en-US'\n\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currencyCode,\n }).format(Number(amount))\n } catch (error) {\n // Fallback if currency code is invalid or not supported\n console.warn(`Invalid currency code: ${currencyCode}`, error)\n return `${currencyCode} ${amount}`\n }\n}\n"],"names":["formatMoney","amount","currencyCode","locale","error"],"mappings":"AAIgB,SAAAA,EAAYC,GAAgBC,GAA8B;AACpE,MAAA;AAGF,UAAMC,IACJD,MAAiB,QAAQ,UAAU,UAAU,YAAY;AAEpD,WAAA,IAAI,KAAK,aAAaC,GAAQ;AAAA,MACnC,OAAO;AAAA,MACP,UAAUD;AAAA,IACX,CAAA,EAAE,OAAO,OAAOD,CAAM,CAAC;AAAA,WACjBG,GAAO;AAEd,mBAAQ,KAAK,0BAA0BF,CAAY,IAAIE,CAAK,GACrD,GAAGF,CAAY,IAAID,CAAM;AAAA,EAAA;AAEpC;"}
File without changes
File without changes