@shopify/shop-minis-react 0.0.33 → 0.0.34
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/index4.js +2 -2
- package/dist/_virtual/index5.js +3 -2
- package/dist/_virtual/index5.js.map +1 -1
- package/dist/_virtual/index6.js +2 -2
- package/dist/_virtual/index7.js +2 -3
- package/dist/_virtual/index7.js.map +1 -1
- package/dist/_virtual/index8.js +2 -2
- package/dist/_virtual/index9.js +2 -2
- package/dist/components/atoms/image.js +52 -0
- package/dist/components/atoms/image.js.map +1 -0
- package/dist/components/commerce/merchant-card.js +1 -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/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/index.js +56 -54
- package/dist/shop-minis-platform/src/types/content.js.map +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/@radix-ui_react-use-is-hydrated@0.1.0_@types_react@19.1.6_react@19.1.0/node_modules/@radix-ui/react-use-is-hydrated/dist/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/@videojs_xhr@2.7.0/node_modules/@videojs/xhr/lib/index.js +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/mpd-parser@1.3.1/node_modules/mpd-parser/dist/mpd-parser.es.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/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 +45 -9
- package/dist/utils/image.js.map +1 -1
- package/package.json +2 -2
- package/src/components/atoms/{thumbhash-image.tsx → image.tsx} +14 -14
- package/src/components/commerce/merchant-card.tsx +2 -2
- package/src/components/commerce/product-card.tsx +2 -2
- package/src/components/content/image-content-wrapper.tsx +9 -2
- package/src/components/index.ts +1 -1
- package/src/hooks/content/useCreateImageContent.ts +1 -7
- package/src/hooks/storage/useImageUpload.ts +22 -20
- package/src/utils/image.ts +72 -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
|
@@ -1,51 +1,50 @@
|
|
|
1
1
|
import { useCallback as m } from "react";
|
|
2
|
-
import { useShopActions as
|
|
2
|
+
import { useShopActions as c } from "../../internal/useShopActions.js";
|
|
3
|
+
import { fileToDataUri as u } from "../../utils/image.js";
|
|
3
4
|
const d = async (e) => {
|
|
4
|
-
const r = await (await fetch(
|
|
5
|
+
const r = await u(e), o = await (await fetch(r)).blob();
|
|
5
6
|
return {
|
|
6
|
-
|
|
7
|
-
fileSize: e.
|
|
8
|
-
fileBlob:
|
|
7
|
+
mimeType: e.type,
|
|
8
|
+
fileSize: e.size ?? o.size,
|
|
9
|
+
fileBlob: o
|
|
9
10
|
};
|
|
10
|
-
}, f = async (e,
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}),
|
|
15
|
-
const
|
|
11
|
+
}, f = async (e, r) => {
|
|
12
|
+
const t = new FormData();
|
|
13
|
+
r.parameters.forEach(({ name: s, value: a }) => {
|
|
14
|
+
t.append(s, a);
|
|
15
|
+
}), t.append("file", e.fileBlob);
|
|
16
|
+
const o = await fetch(r.url, {
|
|
16
17
|
method: "POST",
|
|
17
|
-
body:
|
|
18
|
+
body: t
|
|
18
19
|
});
|
|
19
|
-
return
|
|
20
|
-
response: await
|
|
20
|
+
return o.ok ? {} : (console.error("Failed to upload image", {
|
|
21
|
+
response: await o.text()
|
|
21
22
|
}), { error: "Failed to upload image" });
|
|
22
|
-
},
|
|
23
|
-
const { createImageUploadLink: e, completeImageUpload:
|
|
23
|
+
}, U = () => {
|
|
24
|
+
const { createImageUploadLink: e, completeImageUpload: r } = c();
|
|
24
25
|
return {
|
|
25
26
|
uploadImage: m(
|
|
26
|
-
async (
|
|
27
|
-
|
|
28
|
-
throw new Error("Multiple image upload is not supported yet");
|
|
29
|
-
const l = a[0], t = await d(l), s = await e({
|
|
27
|
+
async (o) => {
|
|
28
|
+
const s = await d(o), a = await e({
|
|
30
29
|
input: [
|
|
31
30
|
{
|
|
32
|
-
mimeType:
|
|
33
|
-
fileSize:
|
|
31
|
+
mimeType: s.mimeType,
|
|
32
|
+
fileSize: s.fileSize
|
|
34
33
|
}
|
|
35
34
|
]
|
|
36
35
|
});
|
|
37
|
-
if (!
|
|
38
|
-
throw new Error(
|
|
39
|
-
const { error:
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
if (!a.ok)
|
|
37
|
+
throw new Error(a.error.message);
|
|
38
|
+
const { error: n } = await f(
|
|
39
|
+
s,
|
|
40
|
+
a?.data?.targets?.[0]
|
|
42
41
|
);
|
|
43
|
-
if (
|
|
44
|
-
throw new Error(
|
|
45
|
-
let
|
|
46
|
-
for (;
|
|
47
|
-
const i = await
|
|
48
|
-
resourceUrls:
|
|
42
|
+
if (n)
|
|
43
|
+
throw new Error(n);
|
|
44
|
+
let p = 0;
|
|
45
|
+
for (; p < 30; ) {
|
|
46
|
+
const i = await r({
|
|
47
|
+
resourceUrls: a?.data?.targets?.map((l) => l.resourceUrl) || []
|
|
49
48
|
});
|
|
50
49
|
if (!i.ok)
|
|
51
50
|
throw new Error(i.error.message);
|
|
@@ -54,18 +53,18 @@ const d = async (e) => {
|
|
|
54
53
|
{
|
|
55
54
|
id: i.data.files[0].id,
|
|
56
55
|
imageUrl: i.data.files[0].image?.url,
|
|
57
|
-
resourceUrl:
|
|
56
|
+
resourceUrl: a?.data?.targets?.[0]?.resourceUrl
|
|
58
57
|
}
|
|
59
58
|
];
|
|
60
|
-
await new Promise((
|
|
59
|
+
await new Promise((l) => setTimeout(l, 1e3)), p++;
|
|
61
60
|
}
|
|
62
61
|
throw new Error("Image upload completion timed out");
|
|
63
62
|
},
|
|
64
|
-
[e,
|
|
63
|
+
[e, r]
|
|
65
64
|
)
|
|
66
65
|
};
|
|
67
66
|
};
|
|
68
67
|
export {
|
|
69
|
-
|
|
68
|
+
U as useImageUpload
|
|
70
69
|
};
|
|
71
70
|
//# sourceMappingURL=useImageUpload.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useImageUpload.js","sources":["../../../src/hooks/storage/useImageUpload.ts"],"sourcesContent":["import {useCallback} from 'react'\n\nimport {useShopActions} from '../../internal/useShopActions'\n\nimport type {UploadTarget} from '@shopify/shop-minis-platform/actions'\n\nexport interface UploadImageParams {\n /**\n * The MIME type of the image.\n */\n mimeType: string\n /**\n * The size of the image in bytes.\n */\n fileSize
|
|
1
|
+
{"version":3,"file":"useImageUpload.js","sources":["../../../src/hooks/storage/useImageUpload.ts"],"sourcesContent":["import {useCallback} from 'react'\n\nimport {useShopActions} from '../../internal/useShopActions'\nimport {fileToDataUri} from '../../utils'\n\nimport type {UploadTarget} from '@shopify/shop-minis-platform/actions'\n\nexport interface UploadImageParams {\n /**\n * The file to upload.\n */\n image: File\n}\n\ninterface ProcessedImage {\n /**\n * The MIME type of the image.\n */\n mimeType: string\n /**\n * The size of the image in bytes.\n */\n fileSize: number\n /**\n * The file blob of the image.\n */\n fileBlob: Blob\n}\n\nexport interface UploadedImage {\n /**\n * The ID of the uploaded image.\n */\n id: string\n /**\n * The URL of the uploaded image.\n */\n imageUrl?: string\n /**\n * The resource URL of the uploaded image.\n */\n resourceUrl?: string\n}\n\ninterface UseImageUploadReturns {\n /**\n * Upload an image which will be attached to the current user.\n */\n uploadImage: (image: File) => Promise<UploadedImage[]>\n}\n\n// Fetch file data and detect file sizes if not provided\n// Works with file://, data:, and http(s):// URIs\nconst processFileData = async (image: File): Promise<ProcessedImage> => {\n const uri = await fileToDataUri(image)\n\n const response = await fetch(uri)\n const blob = await response.blob()\n\n return {\n mimeType: image.type,\n fileSize: image.size ?? blob.size,\n fileBlob: blob,\n }\n}\n\nconst uploadFileToGCS = async (image: ProcessedImage, target: UploadTarget) => {\n const formData = new FormData()\n target.parameters.forEach(({name, value}: {name: string; value: string}) => {\n formData.append(name, value)\n })\n\n formData.append('file', image.fileBlob)\n\n const uploadResponse = await fetch(target.url, {\n method: 'POST',\n body: formData,\n })\n\n if (!uploadResponse.ok) {\n console.error('Failed to upload image', {\n response: await uploadResponse.text(),\n })\n return {error: 'Failed to upload image'}\n }\n\n return {}\n}\n\nexport const useImageUpload = (): UseImageUploadReturns => {\n const {createImageUploadLink, completeImageUpload} = useShopActions()\n\n const uploadImage = useCallback(\n async (image: File) => {\n const processedImageParams = await processFileData(image)\n\n const links = await createImageUploadLink({\n input: [\n {\n mimeType: processedImageParams.mimeType,\n fileSize: processedImageParams.fileSize,\n },\n ],\n })\n\n if (!links.ok) {\n throw new Error(links.error.message)\n }\n\n // Upload single file to GCS\n const {error: uploadError} = await uploadFileToGCS(\n processedImageParams,\n links?.data?.targets?.[0]!\n )\n\n if (uploadError) {\n throw new Error(uploadError)\n }\n\n // 10 second polling for image upload\n let count = 0\n while (count < 30) {\n const result = await completeImageUpload({\n resourceUrls:\n links?.data?.targets?.map(target => target.resourceUrl) || [],\n })\n\n if (!result.ok) {\n throw new Error(result.error.message)\n }\n\n if (result.data?.files?.[0]?.fileStatus === 'READY') {\n return [\n {\n id: result.data.files[0].id,\n imageUrl: result.data.files[0].image?.url,\n resourceUrl: links?.data?.targets?.[0]?.resourceUrl,\n },\n ]\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000))\n count++\n }\n\n throw new Error('Image upload completion timed out')\n },\n [createImageUploadLink, completeImageUpload]\n )\n\n return {\n uploadImage,\n }\n}\n"],"names":["processFileData","image","uri","fileToDataUri","blob","uploadFileToGCS","target","formData","name","value","uploadResponse","useImageUpload","createImageUploadLink","completeImageUpload","useShopActions","useCallback","processedImageParams","links","uploadError","count","result","resolve"],"mappings":";;;AAqDA,MAAMA,IAAkB,OAAOC,MAAyC;AAChE,QAAAC,IAAM,MAAMC,EAAcF,CAAK,GAG/BG,IAAO,OADI,MAAM,MAAMF,CAAG,GACJ,KAAK;AAE1B,SAAA;AAAA,IACL,UAAUD,EAAM;AAAA,IAChB,UAAUA,EAAM,QAAQG,EAAK;AAAA,IAC7B,UAAUA;AAAA,EACZ;AACF,GAEMC,IAAkB,OAAOJ,GAAuBK,MAAyB;AACvE,QAAAC,IAAW,IAAI,SAAS;AAC9B,EAAAD,EAAO,WAAW,QAAQ,CAAC,EAAC,MAAAE,GAAM,OAAAC,QAA0C;AACjE,IAAAF,EAAA,OAAOC,GAAMC,CAAK;AAAA,EAAA,CAC5B,GAEQF,EAAA,OAAO,QAAQN,EAAM,QAAQ;AAEtC,QAAMS,IAAiB,MAAM,MAAMJ,EAAO,KAAK;AAAA,IAC7C,QAAQ;AAAA,IACR,MAAMC;AAAA,EAAA,CACP;AAEG,SAACG,EAAe,KAOb,CAAC,KANN,QAAQ,MAAM,0BAA0B;AAAA,IACtC,UAAU,MAAMA,EAAe,KAAK;AAAA,EAAA,CACrC,GACM,EAAC,OAAO,yBAAwB;AAI3C,GAEaC,IAAiB,MAA6B;AACzD,QAAM,EAAC,uBAAAC,GAAuB,qBAAAC,EAAmB,IAAIC,EAAe;AA4D7D,SAAA;AAAA,IACL,aA3DkBC;AAAA,MAClB,OAAOd,MAAgB;AACf,cAAAe,IAAuB,MAAMhB,EAAgBC,CAAK,GAElDgB,IAAQ,MAAML,EAAsB;AAAA,UACxC,OAAO;AAAA,YACL;AAAA,cACE,UAAUI,EAAqB;AAAA,cAC/B,UAAUA,EAAqB;AAAA,YAAA;AAAA,UACjC;AAAA,QACF,CACD;AAEG,YAAA,CAACC,EAAM;AACT,gBAAM,IAAI,MAAMA,EAAM,MAAM,OAAO;AAIrC,cAAM,EAAC,OAAOC,EAAW,IAAI,MAAMb;AAAA,UACjCW;AAAA,UACAC,GAAO,MAAM,UAAU,CAAC;AAAA,QAC1B;AAEA,YAAIC;AACI,gBAAA,IAAI,MAAMA,CAAW;AAI7B,YAAIC,IAAQ;AACZ,eAAOA,IAAQ,MAAI;AACX,gBAAAC,IAAS,MAAMP,EAAoB;AAAA,YACvC,cACEI,GAAO,MAAM,SAAS,IAAI,CAAUX,MAAAA,EAAO,WAAW,KAAK,CAAA;AAAA,UAAC,CAC/D;AAEG,cAAA,CAACc,EAAO;AACV,kBAAM,IAAI,MAAMA,EAAO,MAAM,OAAO;AAGtC,cAAIA,EAAO,MAAM,QAAQ,CAAC,GAAG,eAAe;AACnC,mBAAA;AAAA,cACL;AAAA,gBACE,IAAIA,EAAO,KAAK,MAAM,CAAC,EAAE;AAAA,gBACzB,UAAUA,EAAO,KAAK,MAAM,CAAC,EAAE,OAAO;AAAA,gBACtC,aAAaH,GAAO,MAAM,UAAU,CAAC,GAAG;AAAA,cAAA;AAAA,YAE5C;AAGF,gBAAM,IAAI,QAAQ,CAAAI,MAAW,WAAWA,GAAS,GAAI,CAAC,GACtDF;AAAA,QAAA;AAGI,cAAA,IAAI,MAAM,mCAAmC;AAAA,MACrD;AAAA,MACA,CAACP,GAAuBC,CAAmB;AAAA,IAC7C;AAAA,EAIA;AACF;"}
|
package/dist/index.js
CHANGED
|
@@ -3,17 +3,17 @@ import { MinisContainer as i } from "./components/MinisContainer.js";
|
|
|
3
3
|
import { ProductCard as n, ProductCardBadge as m, ProductCardContainer as l, ProductCardFavoriteButton as s, ProductCardImage as u, ProductCardImageContainer as f, ProductCardInfo as c, ProductCardPrice as x, ProductCardTitle as d } from "./components/commerce/product-card.js";
|
|
4
4
|
import { ProductLink as g } from "./components/commerce/product-link.js";
|
|
5
5
|
import { MerchantCard as D, MerchantCardContainer as P, MerchantCardHeader as A, MerchantCardInfo as h, MerchantCardName as T, MerchantCardRating as I } from "./components/commerce/merchant-card.js";
|
|
6
|
-
import { ProductCardSkeleton as
|
|
6
|
+
import { ProductCardSkeleton as v } from "./components/commerce/product-card-skeleton.js";
|
|
7
7
|
import { MerchantCardSkeleton as M } from "./components/commerce/merchant-card-skeleton.js";
|
|
8
|
-
import { QuantitySelector as
|
|
9
|
-
import { Search as
|
|
8
|
+
import { QuantitySelector as k } from "./components/commerce/quantity-selector.js";
|
|
9
|
+
import { Search as E, SearchInput as F, SearchProvider as b, SearchResultsList as L } from "./components/commerce/search.js";
|
|
10
10
|
import { ImageContentWrapper as y } from "./components/content/image-content-wrapper.js";
|
|
11
11
|
import { MinisRouter as H } from "./components/navigation/minis-router.js";
|
|
12
12
|
import { TransitionLink as V } from "./components/navigation/transition-link.js";
|
|
13
13
|
import { Button as _ } from "./components/atoms/button.js";
|
|
14
14
|
import { FavoriteButton as Y } from "./components/atoms/favorite-button.js";
|
|
15
15
|
import { IconButton as j } from "./components/atoms/icon-button.js";
|
|
16
|
-
import {
|
|
16
|
+
import { Image as J } from "./components/atoms/image.js";
|
|
17
17
|
import { Touchable as X } from "./components/atoms/touchable.js";
|
|
18
18
|
import { LongPressDetector as $ } from "./components/atoms/long-press-detector.js";
|
|
19
19
|
import { AlertDialogAtom as er } from "./components/atoms/alert-dialog.js";
|
|
@@ -21,9 +21,9 @@ import { List as tr } from "./components/atoms/list.js";
|
|
|
21
21
|
import { VideoPlayer as ir } from "./components/atoms/video-player.js";
|
|
22
22
|
import { Accordion as nr, AccordionContent as mr, AccordionItem as lr, AccordionTrigger as sr } from "./components/ui/accordion.js";
|
|
23
23
|
import { Alert as fr, AlertDescription as cr, AlertTitle as xr } from "./components/ui/alert.js";
|
|
24
|
-
import { AlertDialog as Cr, AlertDialogAction as gr, AlertDialogCancel as Sr, AlertDialogContent as Dr, AlertDialogDescription as Pr, AlertDialogFooter as Ar, AlertDialogHeader as hr, AlertDialogOverlay as Tr, AlertDialogPortal as Ir, AlertDialogTitle as
|
|
25
|
-
import { Avatar as Mr, AvatarFallback as
|
|
26
|
-
import { Badge as
|
|
24
|
+
import { AlertDialog as Cr, AlertDialogAction as gr, AlertDialogCancel as Sr, AlertDialogContent as Dr, AlertDialogDescription as Pr, AlertDialogFooter as Ar, AlertDialogHeader as hr, AlertDialogOverlay as Tr, AlertDialogPortal as Ir, AlertDialogTitle as Rr, AlertDialogTrigger as vr } from "./components/ui/alert-dialog.js";
|
|
25
|
+
import { Avatar as Mr, AvatarFallback as Ur, AvatarImage as kr } from "./components/ui/avatar.js";
|
|
26
|
+
import { Badge as Er, badgeVariants as Fr } from "./components/ui/badge.js";
|
|
27
27
|
import { Card as Lr, CardAction as Nr, CardContent as yr, CardDescription as Gr, CardFooter as Hr, CardHeader as Or, CardTitle as Vr } from "./components/ui/card.js";
|
|
28
28
|
import { Carousel as _r, CarouselContent as Wr, CarouselItem as Yr, CarouselNext as Qr, CarouselPrevious as jr } from "./components/ui/carousel.js";
|
|
29
29
|
import { Checkbox as Jr } from "./components/ui/checkbox.js";
|
|
@@ -32,9 +32,9 @@ import { Drawer as me, DrawerClose as le, DrawerContent as se, DrawerDescription
|
|
|
32
32
|
import { Input as De } from "./components/ui/input.js";
|
|
33
33
|
import { Label as Ae } from "./components/ui/label.js";
|
|
34
34
|
import { Progress as Te } from "./components/ui/progress.js";
|
|
35
|
-
import { RadioGroup as
|
|
36
|
-
import { ResizableHandle as Me, ResizablePanel as
|
|
37
|
-
import { ScrollArea as
|
|
35
|
+
import { RadioGroup as Re, RadioGroupItem as ve } from "./components/ui/radio-group.js";
|
|
36
|
+
import { ResizableHandle as Me, ResizablePanel as Ue, ResizablePanelGroup as ke } from "./components/ui/resizable.js";
|
|
37
|
+
import { ScrollArea as Ee, ScrollBar as Fe } from "./components/ui/scroll-area.js";
|
|
38
38
|
import { Select as Le, SelectContent as Ne, SelectGroup as ye, SelectItem as Ge, SelectLabel as He, SelectScrollDownButton as Oe, SelectScrollUpButton as Ve, SelectSeparator as ze, SelectTrigger as _e, SelectValue as We } from "./components/ui/select.js";
|
|
39
39
|
import { Separator as Qe } from "./components/ui/separator.js";
|
|
40
40
|
import { Sheet as qe, SheetClose as Je, SheetContent as Ke, SheetDescription as Xe, SheetFooter as Ze, SheetHeader as $e, SheetTitle as ro, SheetTrigger as eo } from "./components/ui/sheet.js";
|
|
@@ -49,11 +49,11 @@ import { useFollowedShopsActions as So } from "./hooks/user/useFollowedShopsActi
|
|
|
49
49
|
import { useCurrentUser as Po } from "./hooks/user/useCurrentUser.js";
|
|
50
50
|
import { useOrders as ho } from "./hooks/user/useOrders.js";
|
|
51
51
|
import { useBuyerAttributes as Io } from "./hooks/user/useBuyerAttributes.js";
|
|
52
|
-
import { useGenerateUserToken as
|
|
52
|
+
import { useGenerateUserToken as vo } from "./hooks/user/useGenerateUserToken.js";
|
|
53
53
|
import { useProductListActions as Mo } from "./hooks/product/useProductListActions.js";
|
|
54
|
-
import { useProductLists as
|
|
55
|
-
import { useProductList as
|
|
56
|
-
import { useProduct as
|
|
54
|
+
import { useProductLists as ko } from "./hooks/product/useProductLists.js";
|
|
55
|
+
import { useProductList as Eo } from "./hooks/product/useProductList.js";
|
|
56
|
+
import { useProduct as bo } from "./hooks/product/useProduct.js";
|
|
57
57
|
import { useProducts as No } from "./hooks/product/useProducts.js";
|
|
58
58
|
import { useProductVariants as Go } from "./hooks/product/useProductVariants.js";
|
|
59
59
|
import { useProductMedia as Oo } from "./hooks/product/useProductMedia.js";
|
|
@@ -76,13 +76,13 @@ import { useErrorToast as St } from "./hooks/util/useErrorToast.js";
|
|
|
76
76
|
import { useErrorScreen as Pt } from "./hooks/util/useErrorScreen.js";
|
|
77
77
|
import { useShare as ht } from "./hooks/util/useShare.js";
|
|
78
78
|
import { useImagePicker as It } from "./hooks/util/useImagePicker.js";
|
|
79
|
-
import { MiniEntityNotFoundError as
|
|
80
|
-
import { extractBrandTheme as
|
|
79
|
+
import { MiniEntityNotFoundError as vt, MiniError as wt, MiniNetworkError as Mt, formatError as Ut } from "./utils/errors.js";
|
|
80
|
+
import { extractBrandTheme as Bt, formatReviewCount as Et, getFeaturedImages as Ft, normalizeRating as bt } from "./utils/merchant-card.js";
|
|
81
81
|
import { parseUrl as Nt } from "./utils/parseUrl.js";
|
|
82
|
-
import { fileToDataUri as Gt } from "./utils/
|
|
83
|
-
import { UserState as
|
|
84
|
-
import { ContentCreateUserErrorCode as
|
|
85
|
-
import { Consent as
|
|
82
|
+
import { fileToDataUri as Gt, getResizedImageUrl as Ht, getThumbhashDataURL as Ot } from "./utils/image.js";
|
|
83
|
+
import { UserState as zt, UserTokenGenerateUserErrorCode as _t } from "./shop-minis-platform/src/types/user.js";
|
|
84
|
+
import { ContentCreateUserErrorCode as Yt } from "./shop-minis-platform/src/types/content.js";
|
|
85
|
+
import { Consent as jt, ConsentStatus as qt } from "./shop-minis-platform/src/types/permissions.js";
|
|
86
86
|
export {
|
|
87
87
|
nr as Accordion,
|
|
88
88
|
mr as AccordionContent,
|
|
@@ -100,13 +100,13 @@ export {
|
|
|
100
100
|
hr as AlertDialogHeader,
|
|
101
101
|
Tr as AlertDialogOverlay,
|
|
102
102
|
Ir as AlertDialogPortal,
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
Rr as AlertDialogTitle,
|
|
104
|
+
vr as AlertDialogTrigger,
|
|
105
105
|
xr as AlertTitle,
|
|
106
106
|
Mr as Avatar,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
Ur as AvatarFallback,
|
|
108
|
+
kr as AvatarImage,
|
|
109
|
+
Er as Badge,
|
|
110
110
|
_ as Button,
|
|
111
111
|
Lr as Card,
|
|
112
112
|
Nr as CardAction,
|
|
@@ -121,9 +121,9 @@ export {
|
|
|
121
121
|
Qr as CarouselNext,
|
|
122
122
|
jr as CarouselPrevious,
|
|
123
123
|
Jr as Checkbox,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
jt as Consent,
|
|
125
|
+
qt as ConsentStatus,
|
|
126
|
+
Yt as ContentCreateUserErrorCode,
|
|
127
127
|
o as DATA_NAVIGATION_TYPE_ATTRIBUTE,
|
|
128
128
|
Xr as Dialog,
|
|
129
129
|
Zr as DialogClose,
|
|
@@ -147,6 +147,7 @@ export {
|
|
|
147
147
|
ge as DrawerTrigger,
|
|
148
148
|
Y as FavoriteButton,
|
|
149
149
|
j as IconButton,
|
|
150
|
+
J as Image,
|
|
150
151
|
y as ImageContentWrapper,
|
|
151
152
|
De as Input,
|
|
152
153
|
Ae as Label,
|
|
@@ -159,8 +160,8 @@ export {
|
|
|
159
160
|
T as MerchantCardName,
|
|
160
161
|
I as MerchantCardRating,
|
|
161
162
|
M as MerchantCardSkeleton,
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
vt as MiniEntityNotFoundError,
|
|
164
|
+
wt as MiniError,
|
|
164
165
|
Mt as MiniNetworkError,
|
|
165
166
|
i as MinisContainer,
|
|
166
167
|
H as MinisRouter,
|
|
@@ -173,21 +174,21 @@ export {
|
|
|
173
174
|
f as ProductCardImageContainer,
|
|
174
175
|
c as ProductCardInfo,
|
|
175
176
|
x as ProductCardPrice,
|
|
176
|
-
|
|
177
|
+
v as ProductCardSkeleton,
|
|
177
178
|
d as ProductCardTitle,
|
|
178
179
|
g as ProductLink,
|
|
179
180
|
Te as Progress,
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
k as QuantitySelector,
|
|
182
|
+
Re as RadioGroup,
|
|
183
|
+
ve as RadioGroupItem,
|
|
183
184
|
Me as ResizableHandle,
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
185
|
+
Ue as ResizablePanel,
|
|
186
|
+
ke as ResizablePanelGroup,
|
|
187
|
+
Ee as ScrollArea,
|
|
188
|
+
Fe as ScrollBar,
|
|
189
|
+
E as Search,
|
|
190
|
+
F as SearchInput,
|
|
191
|
+
b as SearchProvider,
|
|
191
192
|
L as SearchResultsList,
|
|
192
193
|
Le as Select,
|
|
193
194
|
Ne as SelectContent,
|
|
@@ -209,20 +210,21 @@ export {
|
|
|
209
210
|
ro as SheetTitle,
|
|
210
211
|
eo as SheetTrigger,
|
|
211
212
|
io as Skeleton,
|
|
212
|
-
J as ThumbhashImage,
|
|
213
213
|
to as Toaster,
|
|
214
214
|
X as Touchable,
|
|
215
215
|
V as TransitionLink,
|
|
216
|
-
|
|
217
|
-
|
|
216
|
+
zt as UserState,
|
|
217
|
+
_t as UserTokenGenerateUserErrorCode,
|
|
218
218
|
ir as VideoPlayer,
|
|
219
|
-
|
|
220
|
-
|
|
219
|
+
Fr as badgeVariants,
|
|
220
|
+
Bt as extractBrandTheme,
|
|
221
221
|
Gt as fileToDataUri,
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
222
|
+
Ut as formatError,
|
|
223
|
+
Et as formatReviewCount,
|
|
224
|
+
Ft as getFeaturedImages,
|
|
225
|
+
Ht as getResizedImageUrl,
|
|
226
|
+
Ot as getThumbhashDataURL,
|
|
227
|
+
bt as normalizeRating,
|
|
226
228
|
Nt as parseUrl,
|
|
227
229
|
Ko as useAsyncStorage,
|
|
228
230
|
Io as useBuyerAttributes,
|
|
@@ -235,16 +237,16 @@ export {
|
|
|
235
237
|
St as useErrorToast,
|
|
236
238
|
Co as useFollowedShops,
|
|
237
239
|
So as useFollowedShopsActions,
|
|
238
|
-
|
|
240
|
+
vo as useGenerateUserToken,
|
|
239
241
|
It as useImagePicker,
|
|
240
242
|
rt as useImageUpload,
|
|
241
243
|
mt as useNavigateWithTransition,
|
|
242
244
|
ho as useOrders,
|
|
243
245
|
Qo as usePopularProducts,
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
bo as useProduct,
|
|
247
|
+
Eo as useProductList,
|
|
246
248
|
Mo as useProductListActions,
|
|
247
|
-
|
|
249
|
+
ko as useProductLists,
|
|
248
250
|
Oo as useProductMedia,
|
|
249
251
|
zo as useProductSearch,
|
|
250
252
|
Go as useProductVariants,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.js","sources":["../../../../../shop-minis-platform/src/types/content.ts"],"sourcesContent":["/* eslint-disable @shopify/typescript/prefer-pascal-case-enums */\nexport interface
|
|
1
|
+
{"version":3,"file":"content.js","sources":["../../../../../shop-minis-platform/src/types/content.ts"],"sourcesContent":["/* eslint-disable @shopify/typescript/prefer-pascal-case-enums */\nexport interface ImageType {\n url: string\n altText?: string | null\n height?: number | null\n width?: number | null\n /**\n * @deprecated This property will be removed in a future version\n */\n sensitive: boolean\n thumbhash?: string | null\n}\n\nexport interface ContentImage {\n id?: string | null\n url: string\n width?: number | null\n height?: number | null\n thumbhash?: string | null\n altText?: string | null\n}\n\nexport interface ContentProduct {\n id: string\n title: string\n featuredImage?: ContentImage | null\n}\n\nexport type ContentVisibility = 'DISCOVERABLE' | 'LINKABLE'\n\nexport interface Content {\n publicId: string\n externalId?: string | null\n image: ContentImage\n title: string\n description?: string | null\n visibility: ContentVisibility[]\n shareableUrl?: string | null\n products?: ContentProduct[] | null\n}\n\nexport enum ContentCreateUserErrorCode {\n DUPLICATE_EXTERNAL_ID = 'DUPLICATE_EXTERNAL_ID',\n INELIGIBLE_PRODUCTS = 'INELIGIBLE_PRODUCTS',\n}\n\nexport interface ContentCreateUserErrors {\n code: ContentCreateUserErrorCode\n message: string\n}\n\nexport interface ContentIdentifierInput {\n externalId?: string | null\n publicId?: string | null\n}\n"],"names":["ContentCreateUserErrorCode"],"mappings":"AAyCY,IAAAA,sBAAAA,OACVA,EAAA,wBAAwB,yBACxBA,EAAA,sBAAsB,uBAFZA,IAAAA,KAAA,CAAA,CAAA;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as q } from "../../../../../../../../_virtual/
|
|
1
|
+
import { __module as q } from "../../../../../../../../_virtual/index4.js";
|
|
2
2
|
import { __require as F } from "../../../../../global@4.4.0/node_modules/global/window.js";
|
|
3
3
|
import { __require as N } from "../../../../../@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/extends.js";
|
|
4
4
|
import { __require as J } from "../../../../../is-function@1.0.2/node_modules/is-function/index.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as p } from "../../../../../../_virtual/
|
|
1
|
+
import { __module as p } from "../../../../../../_virtual/index8.js";
|
|
2
2
|
import { __require as F } from "../../../color-name@1.1.4/node_modules/color-name/index.js";
|
|
3
3
|
import { __require as x } from "../../../simple-swizzle@0.2.2/node_modules/simple-swizzle/index.js";
|
|
4
4
|
var M;
|
|
@@ -2,7 +2,7 @@ import L from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-ut
|
|
|
2
2
|
import T from "../../../../../../../_virtual/window.js";
|
|
3
3
|
import { forEachMediaGroup as Z } from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-utils/es/media-groups.js";
|
|
4
4
|
import J from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-utils/es/decode-b64-to-uint8-array.js";
|
|
5
|
-
import { l as Q } from "../../../../../../../_virtual/
|
|
5
|
+
import { l as Q } from "../../../../../../../_virtual/index5.js";
|
|
6
6
|
/*! @name mpd-parser @version 1.3.1 @license Apache-2.0 */
|
|
7
7
|
const w = (e) => !!e && typeof e == "object", E = (...e) => e.reduce((n, t) => (typeof t != "object" || Object.keys(t).forEach((r) => {
|
|
8
8
|
Array.isArray(n[r]) && Array.isArray(t[r]) ? n[r] = n[r].concat(t[r]) : w(n[r]) && w(t[r]) ? n[r] = E(n[r], t[r]) : n[r] = t[r];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as r } from "../../../../../../../_virtual/
|
|
1
|
+
import { __module as r } from "../../../../../../../_virtual/index10.js";
|
|
2
2
|
import { __require as o } from "../cjs/use-sync-external-store-shim.production.js";
|
|
3
3
|
import { __require as i } from "../cjs/use-sync-external-store-shim.development.js";
|
|
4
4
|
var e;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import S from "../../../../../../../_virtual/window.js";
|
|
2
2
|
import B from "../../../../../../../_virtual/document.js";
|
|
3
|
-
import il from "../../../../../../../_virtual/
|
|
3
|
+
import il from "../../../../../../../_virtual/index3.js";
|
|
4
4
|
import ao from "../../../../../../../_virtual/browser-index.js";
|
|
5
5
|
import xe from "../../../../@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/extends.js";
|
|
6
6
|
import Kc from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-utils/es/resolve-url.js";
|
package/dist/utils/colors.js
CHANGED
package/dist/utils/image.js
CHANGED
|
@@ -1,15 +1,51 @@
|
|
|
1
|
-
import { toUint8Array as
|
|
2
|
-
import { thumbHashToDataURL as
|
|
3
|
-
function
|
|
4
|
-
if (
|
|
1
|
+
import { toUint8Array as s } from "../shop-minis-react/node_modules/.pnpm/js-base64@3.7.7/node_modules/js-base64/base64.js";
|
|
2
|
+
import { thumbHashToDataURL as i } from "../shop-minis-react/node_modules/.pnpm/thumbhash@0.1.1/node_modules/thumbhash/thumbhash.js";
|
|
3
|
+
function U(t) {
|
|
4
|
+
if (t)
|
|
5
5
|
try {
|
|
6
|
-
const
|
|
7
|
-
return
|
|
8
|
-
} catch (
|
|
9
|
-
console.warn("Failed to decode thumbhash to data URL",
|
|
6
|
+
const e = s(t);
|
|
7
|
+
return i(e);
|
|
8
|
+
} catch (e) {
|
|
9
|
+
console.warn("Failed to decode thumbhash to data URL", e);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
function f(t) {
|
|
13
|
+
return new Promise((e, n) => {
|
|
14
|
+
const r = new FileReader();
|
|
15
|
+
r.onloadend = () => e(r.result), r.onerror = n, r.readAsDataURL(t);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const o = {
|
|
19
|
+
xxsUrl: 32,
|
|
20
|
+
xsUrl: 64,
|
|
21
|
+
sUrl: 128,
|
|
22
|
+
xxsmUrl: 256,
|
|
23
|
+
xsmUrl: 384,
|
|
24
|
+
smUrl: 512,
|
|
25
|
+
mUrl: 640,
|
|
26
|
+
lUrl: 1080,
|
|
27
|
+
xlUrl: 2048
|
|
28
|
+
}, a = 0.05, c = Object.entries(o).sort(
|
|
29
|
+
([, t], [, e]) => t - e
|
|
30
|
+
), d = (t) => {
|
|
31
|
+
for (const [e, n] of c) {
|
|
32
|
+
const r = n + n * a;
|
|
33
|
+
if (t <= r) return e;
|
|
34
|
+
}
|
|
35
|
+
return "xlUrl";
|
|
36
|
+
}, m = (t, e) => {
|
|
37
|
+
const r = new RegExp(/\?+/g).test(t) ? "&" : "?";
|
|
38
|
+
return `${t}${r}width=${e}`;
|
|
39
|
+
}, u = (t) => {
|
|
40
|
+
if (!t) return "";
|
|
41
|
+
if (!t.startsWith("https://cdn.shopify.com"))
|
|
42
|
+
return t;
|
|
43
|
+
const e = window.innerWidth ?? screen.width, n = d(e);
|
|
44
|
+
return m(t, o[n]);
|
|
45
|
+
};
|
|
12
46
|
export {
|
|
13
|
-
|
|
47
|
+
f as fileToDataUri,
|
|
48
|
+
u as getResizedImageUrl,
|
|
49
|
+
U as getThumbhashDataURL
|
|
14
50
|
};
|
|
15
51
|
//# sourceMappingURL=image.js.map
|
package/dist/utils/image.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.js","sources":["../../src/utils/image.ts"],"sourcesContent":["import {toUint8Array} from 'js-base64'\nimport {thumbHashToDataURL} from 'thumbhash'\n\n/**\n * Converts a thumbhash string to a data URL for use as an image placeholder\n * @param thumbhash Base64 encoded thumbhash string\n * @returns Data URL that can be used as image source or undefined if conversion fails\n */\nexport function getThumbhashDataURL(thumbhash?: string): string | undefined {\n if (!thumbhash) return\n\n try {\n const thumbhashArray = toUint8Array(thumbhash)\n return thumbHashToDataURL(thumbhashArray)\n } catch (error) {\n console.warn('Failed to decode thumbhash to data URL', error)\n }\n}\n"],"names":["getThumbhashDataURL","thumbhash","thumbhashArray","toUint8Array","thumbHashToDataURL","error"],"mappings":";;AAQO,SAASA,EAAoBC,GAAwC;AAC1E,MAAKA;AAED,QAAA;AACI,YAAAC,IAAiBC,EAAaF,CAAS;AAC7C,aAAOG,EAAmBF,CAAc;AAAA,aACjCG,GAAO;AACN,cAAA,KAAK,0CAA0CA,CAAK;AAAA,IAAA;AAEhE;"}
|
|
1
|
+
{"version":3,"file":"image.js","sources":["../../src/utils/image.ts"],"sourcesContent":["import {toUint8Array} from 'js-base64'\nimport {thumbHashToDataURL} from 'thumbhash'\n\n/**\n * Converts a thumbhash string to a data URL for use as an image placeholder\n * @param thumbhash Base64 encoded thumbhash string\n * @returns Data URL that can be used as image source or undefined if conversion fails\n */\nexport function getThumbhashDataURL(thumbhash?: string): string | undefined {\n if (!thumbhash) return\n\n try {\n const thumbhashArray = toUint8Array(thumbhash)\n return thumbHashToDataURL(thumbhashArray)\n } catch (error) {\n console.warn('Failed to decode thumbhash to data URL', error)\n }\n}\n\n/** Converts a file to a data URI\n * @param file The file to convert\n * @returns A promise that resolves to the data URI string\n */\nexport 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\nconst ImageSizes = {\n xxsUrl: 32,\n xsUrl: 64,\n sUrl: 128,\n xxsmUrl: 256,\n xsmUrl: 384,\n smUrl: 512,\n mUrl: 640,\n lUrl: 1080,\n xlUrl: 2048,\n} as const\n\ntype Key = keyof typeof ImageSizes\n\n/**\n * Acceptable offset for image sizes. An image could use the size that is within this offset.\n */\nconst offsetPercentage = 0.05\n\nconst sortedImageSizes = Object.entries(ImageSizes).sort(\n ([, firstSize], [, secondSize]) => firstSize - secondSize\n)\n\nconst getImageSizeKeyWithSize = (size: number): Key => {\n for (const [key, imgSize] of sortedImageSizes) {\n const upperBoundSize = imgSize + imgSize * offsetPercentage\n if (size <= upperBoundSize) return key as Key\n }\n\n return 'xlUrl'\n}\n\nconst resizeImage = (imageUrl: string, width: number) => {\n const pattern = new RegExp(/\\?+/g)\n const delimiter = pattern.test(imageUrl) ? '&' : '?'\n return `${imageUrl}${delimiter}width=${width}`\n}\n\n/**\n * Optimizes Shopify CDN image URLs by adding a width parameter based on screen size\n * @param url The image URL to optimize\n * @returns The optimized URL with width parameter if it's a Shopify CDN image, otherwise returns the original URL\n */\n\nexport const getResizedImageUrl = (url?: string): string => {\n if (!url) return ''\n\n // Only process Shopify CDN images\n if (!url.startsWith('https://cdn.shopify.com')) {\n return url\n }\n\n const width = window.innerWidth ?? screen.width\n\n const key = getImageSizeKeyWithSize(width)\n\n return resizeImage(url, ImageSizes[key])\n}\n"],"names":["getThumbhashDataURL","thumbhash","thumbhashArray","toUint8Array","thumbHashToDataURL","error","fileToDataUri","file","resolve","reject","reader","ImageSizes","offsetPercentage","sortedImageSizes","firstSize","secondSize","getImageSizeKeyWithSize","size","key","imgSize","upperBoundSize","resizeImage","imageUrl","width","delimiter","getResizedImageUrl","url"],"mappings":";;AAQO,SAASA,EAAoBC,GAAwC;AAC1E,MAAKA;AAED,QAAA;AACI,YAAAC,IAAiBC,EAAaF,CAAS;AAC7C,aAAOG,EAAmBF,CAAc;AAAA,aACjCG,GAAO;AACN,cAAA,KAAK,0CAA0CA,CAAK;AAAA,IAAA;AAEhE;AAMO,SAASC,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;AAEA,MAAMI,IAAa;AAAA,EACjB,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT,GAOMC,IAAmB,MAEnBC,IAAmB,OAAO,QAAQF,CAAU,EAAE;AAAA,EAClD,CAAC,CAAG,EAAAG,CAAS,GAAG,GAAGC,CAAU,MAAMD,IAAYC;AACjD,GAEMC,IAA0B,CAACC,MAAsB;AACrD,aAAW,CAACC,GAAKC,CAAO,KAAKN,GAAkB;AACvC,UAAAO,IAAiBD,IAAUA,IAAUP;AACvC,QAAAK,KAAQG,EAAuB,QAAAF;AAAA,EAAA;AAG9B,SAAA;AACT,GAEMG,IAAc,CAACC,GAAkBC,MAAkB;AAEvD,QAAMC,IADU,IAAI,OAAO,MAAM,EACP,KAAKF,CAAQ,IAAI,MAAM;AACjD,SAAO,GAAGA,CAAQ,GAAGE,CAAS,SAASD,CAAK;AAC9C,GAQaE,IAAqB,CAACC,MAAyB;AACtD,MAAA,CAACA,EAAY,QAAA;AAGjB,MAAI,CAACA,EAAI,WAAW,yBAAyB;AACpC,WAAAA;AAGH,QAAAH,IAAQ,OAAO,cAAc,OAAO,OAEpCL,IAAMF,EAAwBO,CAAK;AAEzC,SAAOF,EAAYK,GAAKf,EAAWO,CAAG,CAAC;AACzC;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shopify/shop-minis-react",
|
|
3
3
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.34",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"typescript": ">=5.0.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@shopify/shop-minis-platform": "0.0.
|
|
41
|
+
"@shopify/shop-minis-platform": "0.0.11",
|
|
42
42
|
"@tailwindcss/vite": "4.1.8",
|
|
43
43
|
"@types/color": "3.0.6",
|
|
44
44
|
"@types/lodash": "4.17.20",
|
|
@@ -1,22 +1,19 @@
|
|
|
1
|
+
/* eslint-disable jsx-a11y/alt-text */
|
|
1
2
|
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
|
|
2
3
|
import {ImgHTMLAttributes, useCallback, useMemo, memo, useState} from 'react'
|
|
3
4
|
|
|
4
5
|
import {cn} from '../../lib/utils'
|
|
5
|
-
import {getThumbhashDataURL} from '../../utils
|
|
6
|
+
import {getThumbhashDataURL, getResizedImageUrl} from '../../utils'
|
|
6
7
|
|
|
7
|
-
type
|
|
8
|
-
src
|
|
9
|
-
thumbhash
|
|
10
|
-
alt?: string | null
|
|
8
|
+
type ImageProps = ImgHTMLAttributes<HTMLImageElement> & {
|
|
9
|
+
src?: string
|
|
10
|
+
thumbhash?: string | null
|
|
11
11
|
aspectRatio?: number | string
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export const
|
|
15
|
-
props: ThumbhashImageProps
|
|
16
|
-
) {
|
|
14
|
+
export const Image = memo(function Image(props: ImageProps) {
|
|
17
15
|
const {
|
|
18
16
|
src,
|
|
19
|
-
alt,
|
|
20
17
|
thumbhash,
|
|
21
18
|
onLoad,
|
|
22
19
|
className,
|
|
@@ -27,7 +24,7 @@ export const ThumbhashImage = memo(function ThumbhashImage(
|
|
|
27
24
|
|
|
28
25
|
const [isLoaded, setIsLoaded] = useState(false)
|
|
29
26
|
|
|
30
|
-
const
|
|
27
|
+
const thumbhashDataURL = useMemo(
|
|
31
28
|
() => getThumbhashDataURL(thumbhash ?? undefined),
|
|
32
29
|
[thumbhash]
|
|
33
30
|
)
|
|
@@ -40,24 +37,27 @@ export const ThumbhashImage = memo(function ThumbhashImage(
|
|
|
40
37
|
[onLoad]
|
|
41
38
|
)
|
|
42
39
|
|
|
40
|
+
const resizedImageSrc = useMemo(() => getResizedImageUrl(src), [src])
|
|
41
|
+
|
|
43
42
|
return (
|
|
44
43
|
<div
|
|
45
44
|
className={cn('relative w-full ', className)}
|
|
46
45
|
style={{
|
|
47
46
|
...style,
|
|
48
47
|
aspectRatio,
|
|
49
|
-
backgroundImage:
|
|
48
|
+
backgroundImage: thumbhashDataURL
|
|
49
|
+
? `url(${thumbhashDataURL})`
|
|
50
|
+
: undefined,
|
|
50
51
|
backgroundSize: 'cover',
|
|
51
52
|
backgroundPosition: 'center',
|
|
52
53
|
}}
|
|
53
54
|
>
|
|
54
55
|
<img
|
|
55
56
|
className={cn(
|
|
56
|
-
'absolute inset-0
|
|
57
|
+
'absolute inset-0 opacity-0 object-cover',
|
|
57
58
|
isLoaded && 'opacity-100'
|
|
58
59
|
)}
|
|
59
|
-
src={
|
|
60
|
-
alt={alt}
|
|
60
|
+
src={resizedImageSrc}
|
|
61
61
|
onLoad={handleLoad}
|
|
62
62
|
{...restProps}
|
|
63
63
|
/>
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
normalizeRating,
|
|
15
15
|
} from '../../utils'
|
|
16
16
|
import {isDarkColor} from '../../utils/colors'
|
|
17
|
-
import {
|
|
17
|
+
import {Image} from '../atoms/image'
|
|
18
18
|
import {Touchable} from '../atoms/touchable'
|
|
19
19
|
|
|
20
20
|
interface MerchantCardContextValue {
|
|
@@ -100,7 +100,7 @@ function MerchantCardImage({
|
|
|
100
100
|
|
|
101
101
|
if (thumbhash) {
|
|
102
102
|
return (
|
|
103
|
-
<
|
|
103
|
+
<Image
|
|
104
104
|
data-slot="merchant-card-image"
|
|
105
105
|
src={src}
|
|
106
106
|
alt={alt}
|