Skip to content

feat(shopify-assets)!: migrate react-photo-album to v3 catalog - #1822

Draft
stipsan wants to merge 4 commits into
mainfrom
cursor/react-photo-album-v3-shopify-d80a
Draft

feat(shopify-assets)!: migrate react-photo-album to v3 catalog#1822
stipsan wants to merge 4 commits into
mainfrom
cursor/react-photo-album-v3-shopify-d80a

Conversation

@stipsan

@stipsan stipsan commented Aug 3, 2026

Copy link
Copy Markdown
Member

Replaces #1798 (Renovate-only bump without the v2→v3 API migration).

Summary

  • Bump shared react-photo-album catalog ^3.6.0^3.6.1
  • Migrate sanity-plugin-shopify-assets to the v3 API (major), following sanity-plugin-asset-source-unsplash:
    • PhotoAlbum layout="rows"RowsPhotoAlbum + react-photo-album/rows.css
    • react-infinite-scroll-componentreact-photo-album/scroll
    • Custom photo render → default images + render.extras overlays
    • componentsProps.containerPropscomponentsProps.container
    • Promise-based fetchAssets datastore (drops rxjs subjects for search)
    • Depend on "react-photo-album": "catalog:"
  • Patch changeset for sanity-plugin-asset-source-unsplash (catalog consumer)

Test plan

  • pnpm format
  • pnpm lint
  • pnpm knip
  • Build sanity-plugin-shopify-assets + sanity-plugin-asset-source-unsplash
  • vitest for sanity-plugin-shopify-assets
  • Smoke-test Shopify asset picker gallery/search/infinite scroll in test studio
Open in Web Open in Cursor 

Upgrade the shared react-photo-album catalog to ^3.6.1 and migrate
sanity-plugin-shopify-assets to the v3 RowsPhotoAlbum + scroll API
(matching asset-source-unsplash), so it can use catalog: and drop the
v2-only react-infinite-scroll-component/rxjs search path.
@changeset-bot

changeset-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 827e457

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
sanity-plugin-shopify-assets Major
sanity-plugin-asset-source-unsplash Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
plugins-studio Ready Ready Preview Aug 11, 2026 1:59pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
plugins-e2e-test-studio Ignored Ignored Aug 11, 2026 1:59pm

Request Review

@stipsan stipsan added the 🤖 bot label Aug 3, 2026 — with Cursor
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

✅ E2E Tests

🟢 26 passedview full reportview run

Studio: https://plugins-e2e-test-studio-ifl2oxrxa.sanity.dev

Datasets: pr-1822-chromium-31499027007, pr-1822-firefox-31499027007

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 32.01% 5509 / 17210
🔵 Statements 31.78% 5813 / 18287
🔵 Functions 27.72% 1424 / 5136
🔵 Branches 23.34% 2831 / 12128
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
plugins/sanity-plugin-shopify-assets/src/components/File.styled.tsx 33.33% 100% 0% 33.33% 7-10, 29-32
plugins/sanity-plugin-shopify-assets/src/components/File.tsx 0% 0% 0% 0% 10-27
plugins/sanity-plugin-shopify-assets/src/components/Loader.tsx 0% 100% 0% 0% 4-7
plugins/sanity-plugin-shopify-assets/src/components/ShopifyAssetPicker.tsx 9.23% 0% 0% 9.67% 41-296
plugins/sanity-plugin-shopify-assets/src/datastores/shopify.ts 100% 100% 100% 100%
Generated in workflow #8990 for commit 827e457 by the Vitest Coverage Report Action

Resolve pnpm-lock.yaml conflict by regenerating the lockfile from main's
baseline against the merged manifests.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Debounce clears fetch errors
    • Removed the unconditional setApiError('') from the debounce effect so a fast initial fetch failure keeps its error message, since errors are now discarded automatically when a new request supersedes them.
  • ✅ Fixed: Stale requests overwrite gallery
    • Errors are now tagged with the request that produced them and only rendered when the tag matches the current request, so late failures from superseded queries or unmounted galleries are ignored.

Create PR

Or push these changes by commenting:

@cursor push 3fe368b137
Preview (3fe368b137)
diff --git a/plugins/sanity-plugin-shopify-assets/src/components/ShopifyAssetPicker.tsx b/plugins/sanity-plugin-shopify-assets/src/components/ShopifyAssetPicker.tsx
--- a/plugins/sanity-plugin-shopify-assets/src/components/ShopifyAssetPicker.tsx
+++ b/plugins/sanity-plugin-shopify-assets/src/components/ShopifyAssetPicker.tsx
@@ -89,16 +89,11 @@
 
   const [query, setQuery] = useState('')
   const [debouncedQuery, setDebouncedQuery] = useState('')
-  const [apiError, setApiError] = useState('')
+  const [apiError, setApiError] = useState<{token: object; message: string} | null>(null)
   const scrollContainerRef = useRef<HTMLDivElement>(null)
 
-  const error = shopifyDomain
-    ? apiError
-    : 'Please configure your Shopify domain in the plugin config'
-
   useEffect(() => {
     const timeout = window.setTimeout(() => {
-      setApiError('')
       setDebouncedQuery(query)
     }, SEARCH_DEBOUNCE_MS)
 
@@ -116,18 +111,29 @@
     [projectId, dataset, shopifyDomain, token],
   )
 
-  const initialDataPromise = useMemo(
-    () =>
-      fetcher(debouncedQuery, '').catch((err: unknown) => {
-        setApiError(getErrorMessage(err))
+  const request = useMemo(() => {
+    // Errors are tagged so failures from superseded requests are ignored.
+    const requestToken = {}
+    const onError = (message: string) => setApiError({token: requestToken, message})
+
+    return {
+      token: requestToken,
+      onError,
+      promise: fetcher(debouncedQuery, '').catch((err: unknown) => {
+        onError(getErrorMessage(err))
         return {
           assets: [],
           pageInfo: {cursor: '', hasNextPage: false},
         } satisfies ShopifyAPIResponse
       }),
-    [debouncedQuery, fetcher],
-  )
+    }
+  }, [debouncedQuery, fetcher])
 
+  const apiErrorMessage = apiError?.token === request.token ? apiError.message : ''
+  const error = shopifyDomain
+    ? apiErrorMessage
+    : 'Please configure your Shopify domain in the plugin config'
+
   const handleSearchTermChanged = (event: ChangeEvent<HTMLInputElement>) => {
     setQuery(event.currentTarget.value)
   }
@@ -194,8 +200,8 @@
                 fetcher={fetcher}
                 scrollContainerRef={scrollContainerRef}
                 onSelect={handleSelect}
-                onError={setApiError}
-                initialDataPromise={initialDataPromise}
+                onError={request.onError}
+                initialDataPromise={request.promise}
               />
             </Suspense>
           </>

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 37c832b. Configure here.

Comment thread plugins/sanity-plugin-shopify-assets/src/components/ShopifyAssetPicker.tsx Outdated
Errors lived in component state written from async callbacks that were
not tied to the query that produced them, so the search debounce timer
could clear a fresh failure and a superseded query's rejection could
replace newer results with a blocking error.

Resolve each query's request to a loaded/failed result consumed through
the per-query Suspense boundary, and let load-more rejections surface via
the InfiniteScroll error slot so the search input stays usable.
Resolve pnpm-lock.yaml conflict by regenerating the lockfile from main's
baseline against the merged manifests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants