@shopify/shop-minis-react 0.0.33 → 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.
- package/dist/_virtual/index10.js +2 -2
- package/dist/_virtual/index2.js +4 -4
- package/dist/_virtual/index3.js +4 -4
- package/dist/_virtual/index8.js +2 -2
- package/dist/_virtual/index9.js +2 -2
- package/dist/components/atoms/alert-dialog.js.map +1 -1
- package/dist/components/atoms/icon-button.js +12 -12
- package/dist/components/atoms/icon-button.js.map +1 -1
- package/dist/components/atoms/image.js +52 -0
- package/dist/components/atoms/image.js.map +1 -0
- package/dist/components/atoms/text-input.js +22 -0
- package/dist/components/atoms/text-input.js.map +1 -0
- package/dist/components/commerce/merchant-card.js +2 -1
- package/dist/components/commerce/merchant-card.js.map +1 -1
- package/dist/components/commerce/product-card.js +11 -11
- package/dist/components/commerce/product-card.js.map +1 -1
- package/dist/components/content/image-content-wrapper.js +29 -22
- package/dist/components/content/image-content-wrapper.js.map +1 -1
- package/dist/components/ui/input.js +15 -9
- package/dist/components/ui/input.js.map +1 -1
- package/dist/hooks/content/useCreateImageContent.js +16 -22
- package/dist/hooks/content/useCreateImageContent.js.map +1 -1
- package/dist/hooks/storage/useImageUpload.js +36 -37
- package/dist/hooks/storage/useImageUpload.js.map +1 -1
- package/dist/hooks/util/useKeyboardAvoidingView.js +23 -0
- package/dist/hooks/util/useKeyboardAvoidingView.js.map +1 -0
- package/dist/index.js +218 -212
- package/dist/index.js.map +1 -1
- package/dist/mocks.js +4 -1
- package/dist/mocks.js.map +1 -1
- package/dist/shop-minis-platform/src/types/content.js.map +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/@xmldom_xmldom@0.8.10/node_modules/@xmldom/xmldom/lib/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/color-string@1.9.1/node_modules/color-string/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.0/node_modules/use-sync-external-store/shim/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/video.js@8.23.3/node_modules/video.js/dist/video.es.js +1 -1
- package/dist/utils/colors.js +1 -1
- package/dist/utils/image.js +46 -9
- package/dist/utils/image.js.map +1 -1
- package/package.json +21 -4
- package/src/components/atoms/alert-dialog.test.tsx +67 -0
- package/src/components/atoms/alert-dialog.tsx +13 -11
- package/src/components/atoms/favorite-button.test.tsx +56 -0
- package/src/components/atoms/icon-button.tsx +1 -1
- package/src/components/atoms/image.test.tsx +108 -0
- package/src/components/atoms/{thumbhash-image.tsx → image.tsx} +14 -14
- package/src/components/atoms/product-variant-price.test.tsx +128 -0
- package/src/components/atoms/text-input.test.tsx +104 -0
- package/src/components/atoms/text-input.tsx +31 -0
- package/src/components/commerce/merchant-card.test.tsx +261 -0
- package/src/components/commerce/merchant-card.tsx +4 -2
- package/src/components/commerce/product-card.test.tsx +364 -0
- package/src/components/commerce/product-card.tsx +2 -2
- package/src/components/commerce/product-link.test.tsx +483 -0
- package/src/components/commerce/quantity-selector.test.tsx +382 -0
- package/src/components/commerce/search.test.tsx +487 -0
- package/src/components/content/image-content-wrapper.test.tsx +92 -0
- package/src/components/content/image-content-wrapper.tsx +9 -2
- package/src/components/index.ts +2 -1
- package/src/components/navigation/transition-link.test.tsx +155 -0
- package/src/components/ui/input.test.tsx +21 -0
- package/src/components/ui/input.tsx +10 -1
- package/src/hooks/content/useCreateImageContent.test.ts +352 -0
- package/src/hooks/content/useCreateImageContent.ts +1 -7
- package/src/hooks/index.ts +1 -0
- package/src/hooks/navigation/useNavigateWithTransition.test.ts +371 -0
- package/src/hooks/navigation/useViewTransitions.test.ts +469 -0
- package/src/hooks/product/useProductSearch.test.ts +470 -0
- package/src/hooks/storage/useAsyncStorage.test.ts +225 -0
- package/src/hooks/storage/useImageUpload.test.ts +322 -0
- package/src/hooks/storage/useImageUpload.ts +22 -20
- package/src/hooks/util/useKeyboardAvoidingView.ts +37 -0
- package/src/internal/useHandleAction.test.ts +265 -0
- package/src/internal/useShopActionsDataFetching.test.ts +465 -0
- package/src/mocks.ts +3 -1
- package/src/providers/ImagePickerProvider.test.tsx +467 -0
- package/src/stories/ProductCard.stories.tsx +2 -2
- package/src/stories/TextInput.stories.tsx +26 -0
- package/src/test-setup.ts +34 -0
- package/src/test-utils.tsx +167 -0
- package/src/utils/image.ts +73 -0
- package/src/utils/index.ts +1 -1
- package/dist/components/atoms/thumbhash-image.js +0 -54
- package/dist/components/atoms/thumbhash-image.js.map +0 -1
- package/dist/utils/imageToDataUri.js +0 -10
- package/dist/utils/imageToDataUri.js.map +0 -1
- package/src/utils/imageToDataUri.ts +0 -8
package/src/utils/image.ts
CHANGED
|
@@ -14,5 +14,78 @@ export function getThumbhashDataURL(thumbhash?: string): string | undefined {
|
|
|
14
14
|
return thumbHashToDataURL(thumbhashArray)
|
|
15
15
|
} catch (error) {
|
|
16
16
|
console.warn('Failed to decode thumbhash to data URL', error)
|
|
17
|
+
return undefined
|
|
17
18
|
}
|
|
18
19
|
}
|
|
20
|
+
|
|
21
|
+
/** Converts a file to a data URI
|
|
22
|
+
* @param file The file to convert
|
|
23
|
+
* @returns A promise that resolves to the data URI string
|
|
24
|
+
*/
|
|
25
|
+
export function fileToDataUri(file: File): Promise<string> {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const reader = new FileReader()
|
|
28
|
+
reader.onloadend = () => resolve(reader.result as string)
|
|
29
|
+
reader.onerror = reject
|
|
30
|
+
reader.readAsDataURL(file)
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const ImageSizes = {
|
|
35
|
+
xxsUrl: 32,
|
|
36
|
+
xsUrl: 64,
|
|
37
|
+
sUrl: 128,
|
|
38
|
+
xxsmUrl: 256,
|
|
39
|
+
xsmUrl: 384,
|
|
40
|
+
smUrl: 512,
|
|
41
|
+
mUrl: 640,
|
|
42
|
+
lUrl: 1080,
|
|
43
|
+
xlUrl: 2048,
|
|
44
|
+
} as const
|
|
45
|
+
|
|
46
|
+
type Key = keyof typeof ImageSizes
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Acceptable offset for image sizes. An image could use the size that is within this offset.
|
|
50
|
+
*/
|
|
51
|
+
const offsetPercentage = 0.05
|
|
52
|
+
|
|
53
|
+
const sortedImageSizes = Object.entries(ImageSizes).sort(
|
|
54
|
+
([, firstSize], [, secondSize]) => firstSize - secondSize
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
const getImageSizeKeyWithSize = (size: number): Key => {
|
|
58
|
+
for (const [key, imgSize] of sortedImageSizes) {
|
|
59
|
+
const upperBoundSize = imgSize + imgSize * offsetPercentage
|
|
60
|
+
if (size <= upperBoundSize) return key as Key
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return 'xlUrl'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const resizeImage = (imageUrl: string, width: number) => {
|
|
67
|
+
const pattern = new RegExp(/\?+/g)
|
|
68
|
+
const delimiter = pattern.test(imageUrl) ? '&' : '?'
|
|
69
|
+
return `${imageUrl}${delimiter}width=${width}`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Optimizes Shopify CDN image URLs by adding a width parameter based on screen size
|
|
74
|
+
* @param url The image URL to optimize
|
|
75
|
+
* @returns The optimized URL with width parameter if it's a Shopify CDN image, otherwise returns the original URL
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
export const getResizedImageUrl = (url?: string): string => {
|
|
79
|
+
if (!url) return ''
|
|
80
|
+
|
|
81
|
+
// Only process Shopify CDN images
|
|
82
|
+
if (!url.startsWith('https://cdn.shopify.com')) {
|
|
83
|
+
return url
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const width = window.innerWidth ?? screen.width
|
|
87
|
+
|
|
88
|
+
const key = getImageSizeKeyWithSize(width)
|
|
89
|
+
|
|
90
|
+
return resizeImage(url, ImageSizes[key])
|
|
91
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { jsx as t } from "react/jsx-runtime";
|
|
2
|
-
import { memo as p, useState as g, useMemo as L, useCallback as v } from "react";
|
|
3
|
-
import { cn as s } from "../../lib/utils.js";
|
|
4
|
-
import { getThumbhashDataURL as k } from "../../utils/image.js";
|
|
5
|
-
const j = p(function(r) {
|
|
6
|
-
const {
|
|
7
|
-
src: c,
|
|
8
|
-
alt: m,
|
|
9
|
-
thumbhash: o,
|
|
10
|
-
onLoad: a,
|
|
11
|
-
className: l,
|
|
12
|
-
style: i,
|
|
13
|
-
aspectRatio: n = "auto",
|
|
14
|
-
...u
|
|
15
|
-
} = r, [d, h] = g(!1), e = L(
|
|
16
|
-
() => k(o ?? void 0),
|
|
17
|
-
[o]
|
|
18
|
-
), b = v(
|
|
19
|
-
(f) => {
|
|
20
|
-
h(!0), a?.(f);
|
|
21
|
-
},
|
|
22
|
-
[a]
|
|
23
|
-
);
|
|
24
|
-
return /* @__PURE__ */ t(
|
|
25
|
-
"div",
|
|
26
|
-
{
|
|
27
|
-
className: s("relative w-full ", l),
|
|
28
|
-
style: {
|
|
29
|
-
...i,
|
|
30
|
-
aspectRatio: n,
|
|
31
|
-
backgroundImage: e ? `url(${e})` : void 0,
|
|
32
|
-
backgroundSize: "cover",
|
|
33
|
-
backgroundPosition: "center"
|
|
34
|
-
},
|
|
35
|
-
children: /* @__PURE__ */ t(
|
|
36
|
-
"img",
|
|
37
|
-
{
|
|
38
|
-
className: s(
|
|
39
|
-
"absolute inset-0 w-full h-full opacity-0 object-cover",
|
|
40
|
-
d && "opacity-100"
|
|
41
|
-
),
|
|
42
|
-
src: c,
|
|
43
|
-
alt: m,
|
|
44
|
-
onLoad: b,
|
|
45
|
-
...u
|
|
46
|
-
}
|
|
47
|
-
)
|
|
48
|
-
}
|
|
49
|
-
);
|
|
50
|
-
});
|
|
51
|
-
export {
|
|
52
|
-
j as ThumbhashImage
|
|
53
|
-
};
|
|
54
|
-
//# sourceMappingURL=thumbhash-image.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"thumbhash-image.js","sources":["../../../src/components/atoms/thumbhash-image.tsx"],"sourcesContent":["/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */\nimport {ImgHTMLAttributes, useCallback, useMemo, memo, useState} from 'react'\n\nimport {cn} from '../../lib/utils'\nimport {getThumbhashDataURL} from '../../utils/image'\n\ntype ThumbhashImageProps = ImgHTMLAttributes<HTMLImageElement> & {\n src: string\n thumbhash: string\n alt?: string | null\n aspectRatio?: number | string\n}\n\nexport const ThumbhashImage = memo(function ThumbhashImage(\n props: ThumbhashImageProps\n) {\n const {\n src,\n alt,\n thumbhash,\n onLoad,\n className,\n style,\n aspectRatio = 'auto',\n ...restProps\n } = props\n\n const [isLoaded, setIsLoaded] = useState(false)\n\n const dataURL = useMemo(\n () => getThumbhashDataURL(thumbhash ?? undefined),\n [thumbhash]\n )\n\n const handleLoad = useCallback(\n (event: React.SyntheticEvent<HTMLImageElement, Event>) => {\n setIsLoaded(true)\n onLoad?.(event)\n },\n [onLoad]\n )\n\n return (\n <div\n className={cn('relative w-full ', className)}\n style={{\n ...style,\n aspectRatio,\n backgroundImage: dataURL ? `url(${dataURL})` : undefined,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }}\n >\n <img\n className={cn(\n 'absolute inset-0 w-full h-full opacity-0 object-cover',\n isLoaded && 'opacity-100'\n )}\n src={src}\n alt={alt}\n onLoad={handleLoad}\n {...restProps}\n />\n </div>\n )\n})\n"],"names":["ThumbhashImage","memo","props","src","alt","thumbhash","onLoad","className","style","aspectRatio","restProps","isLoaded","setIsLoaded","useState","dataURL","useMemo","getThumbhashDataURL","handleLoad","useCallback","event","jsx","cn"],"mappings":";;;;AAaO,MAAMA,IAAiBC,EAAK,SACjCC,GACA;AACM,QAAA;AAAA,IACJ,KAAAC;AAAA,IACA,KAAAC;AAAA,IACA,WAAAC;AAAA,IACA,QAAAC;AAAA,IACA,WAAAC;AAAA,IACA,OAAAC;AAAA,IACA,aAAAC,IAAc;AAAA,IACd,GAAGC;AAAA,EAAA,IACDR,GAEE,CAACS,GAAUC,CAAW,IAAIC,EAAS,EAAK,GAExCC,IAAUC;AAAA,IACd,MAAMC,EAAoBX,KAAa,MAAS;AAAA,IAChD,CAACA,CAAS;AAAA,EACZ,GAEMY,IAAaC;AAAA,IACjB,CAACC,MAAyD;AACxD,MAAAP,EAAY,EAAI,GAChBN,IAASa,CAAK;AAAA,IAChB;AAAA,IACA,CAACb,CAAM;AAAA,EACT;AAGE,SAAA,gBAAAc;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAG,oBAAoBd,CAAS;AAAA,MAC3C,OAAO;AAAA,QACL,GAAGC;AAAA,QACH,aAAAC;AAAA,QACA,iBAAiBK,IAAU,OAAOA,CAAO,MAAM;AAAA,QAC/C,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,MACtB;AAAA,MAEA,UAAA,gBAAAM;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWC;AAAA,YACT;AAAA,YACAV,KAAY;AAAA,UACd;AAAA,UACA,KAAAR;AAAA,UACA,KAAAC;AAAA,UACA,QAAQa;AAAA,UACP,GAAGP;AAAA,QAAA;AAAA,MAAA;AAAA,IACN;AAAA,EACF;AAEJ,CAAC;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"imageToDataUri.js","sources":["../../src/utils/imageToDataUri.ts"],"sourcesContent":["export function fileToDataUri(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onloadend = () => resolve(reader.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n}\n"],"names":["fileToDataUri","file","resolve","reject","reader"],"mappings":"AAAO,SAASA,EAAcC,GAA6B;AACzD,SAAO,IAAI,QAAQ,CAACC,GAASC,MAAW;AAChC,UAAAC,IAAS,IAAI,WAAW;AAC9B,IAAAA,EAAO,YAAY,MAAMF,EAAQE,EAAO,MAAgB,GACxDA,EAAO,UAAUD,GACjBC,EAAO,cAAcH,CAAI;AAAA,EAAA,CAC1B;AACH;"}
|