@shopify/shop-minis-react 0.0.32 → 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.
Files changed (50) hide show
  1. package/dist/_virtual/index2.js +4 -4
  2. package/dist/_virtual/index3.js +4 -4
  3. package/dist/_virtual/index4.js +2 -2
  4. package/dist/_virtual/index5.js +3 -2
  5. package/dist/_virtual/index5.js.map +1 -1
  6. package/dist/_virtual/index6.js +2 -2
  7. package/dist/_virtual/index7.js +2 -3
  8. package/dist/_virtual/index7.js.map +1 -1
  9. package/dist/_virtual/index8.js +2 -2
  10. package/dist/_virtual/index9.js +2 -2
  11. package/dist/components/atoms/image.js +52 -0
  12. package/dist/components/atoms/image.js.map +1 -0
  13. package/dist/components/commerce/merchant-card.js +188 -245
  14. package/dist/components/commerce/merchant-card.js.map +1 -1
  15. package/dist/components/commerce/product-card.js +11 -11
  16. package/dist/components/commerce/product-card.js.map +1 -1
  17. package/dist/components/content/image-content-wrapper.js +29 -22
  18. package/dist/components/content/image-content-wrapper.js.map +1 -1
  19. package/dist/hooks/content/useCreateImageContent.js +16 -22
  20. package/dist/hooks/content/useCreateImageContent.js.map +1 -1
  21. package/dist/hooks/storage/useImageUpload.js +36 -37
  22. package/dist/hooks/storage/useImageUpload.js.map +1 -1
  23. package/dist/index.js +252 -246
  24. package/dist/shop-minis-platform/src/types/content.js.map +1 -1
  25. 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
  26. package/dist/shop-minis-react/node_modules/.pnpm/@videojs_xhr@2.7.0/node_modules/@videojs/xhr/lib/index.js +1 -1
  27. package/dist/shop-minis-react/node_modules/.pnpm/@xmldom_xmldom@0.8.10/node_modules/@xmldom/xmldom/lib/index.js +1 -1
  28. package/dist/shop-minis-react/node_modules/.pnpm/color-string@1.9.1/node_modules/color-string/index.js +1 -1
  29. package/dist/shop-minis-react/node_modules/.pnpm/mpd-parser@1.3.1/node_modules/mpd-parser/dist/mpd-parser.es.js +1 -1
  30. package/dist/shop-minis-react/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.js +1 -1
  31. package/dist/shop-minis-react/node_modules/.pnpm/video.js@8.23.3/node_modules/video.js/dist/video.es.js +1 -1
  32. package/dist/utils/colors.js +1 -1
  33. package/dist/utils/image.js +45 -9
  34. package/dist/utils/image.js.map +1 -1
  35. package/package.json +2 -2
  36. package/src/components/atoms/{thumbhash-image.tsx → image.tsx} +14 -14
  37. package/src/components/commerce/merchant-card.tsx +224 -225
  38. package/src/components/commerce/product-card.tsx +2 -2
  39. package/src/components/content/image-content-wrapper.tsx +9 -2
  40. package/src/components/index.ts +1 -1
  41. package/src/hooks/content/useCreateImageContent.ts +1 -7
  42. package/src/hooks/storage/useImageUpload.ts +22 -20
  43. package/src/stories/MerchantCard.stories.tsx +0 -3
  44. package/src/utils/image.ts +72 -0
  45. package/src/utils/index.ts +1 -1
  46. package/dist/components/atoms/thumbhash-image.js +0 -54
  47. package/dist/components/atoms/thumbhash-image.js.map +0 -1
  48. package/dist/utils/imageToDataUri.js +0 -10
  49. package/dist/utils/imageToDataUri.js.map +0 -1
  50. package/src/utils/imageToDataUri.ts +0 -8
@@ -1,15 +1,51 @@
1
- import { toUint8Array as o } from "../shop-minis-react/node_modules/.pnpm/js-base64@3.7.7/node_modules/js-base64/base64.js";
2
- import { thumbHashToDataURL as a } from "../shop-minis-react/node_modules/.pnpm/thumbhash@0.1.1/node_modules/thumbhash/thumbhash.js";
3
- function n(r) {
4
- if (r)
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 t = o(r);
7
- return a(t);
8
- } catch (t) {
9
- console.warn("Failed to decode thumbhash to data URL", t);
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
- n as getThumbhashDataURL
47
+ f as fileToDataUri,
48
+ u as getResizedImageUrl,
49
+ U as getThumbhashDataURL
14
50
  };
15
51
  //# sourceMappingURL=image.js.map
@@ -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.32",
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.10",
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/image'
6
+ import {getThumbhashDataURL, getResizedImageUrl} from '../../utils'
6
7
 
7
- type ThumbhashImageProps = ImgHTMLAttributes<HTMLImageElement> & {
8
- src: string
9
- thumbhash: string
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 ThumbhashImage = memo(function ThumbhashImage(
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 dataURL = useMemo(
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: dataURL ? `url(${dataURL})` : undefined,
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 w-full h-full opacity-0 object-cover',
57
+ 'absolute inset-0 opacity-0 object-cover',
57
58
  isLoaded && 'opacity-100'
58
59
  )}
59
- src={src}
60
- alt={alt}
60
+ src={resizedImageSrc}
61
61
  onLoad={handleLoad}
62
62
  {...restProps}
63
63
  />