sanity-plugin-asset-source-unsplash

7.0.257.0.26
~

Modified (4 files)

Index: package/package.json
===================================================================
--- package/package.json
+++ package/package.json
@@ -1,7 +1,7 @@
 {
   "name": "sanity-plugin-asset-source-unsplash",
-  "version": "7.0.25",
+  "version": "7.0.26",
   "description": "Use images from Unsplash.com in your Sanity Studio",
   "keywords": [
     "assets",
     "images",
@@ -30,22 +30,22 @@
     ".": "./dist/index.js",
     "./package.json": "./package.json"
   },
   "dependencies": {
-    "@sanity/icons": "^5.2.1",
-    "@sanity/ui": "^4.0.4",
+    "@sanity/icons": "^5.2.2",
+    "@sanity/ui": "^4.2.7",
     "lodash-es": "^4.18.1",
     "react-photo-album": "^3.6.0"
   },
   "devDependencies": {
     "@sanity/tsconfig": "^2.2.1",
-    "@sanity/tsdown-config": "^0.26.0",
+    "@sanity/tsdown-config": "^0.27.1",
     "@types/lodash-es": "^4.17.12",
     "@types/node": "^24.13.3",
-    "@types/react": "^19.2.18",
-    "oxc-transform-react": "^0.145.0",
-    "react": "^19.2.8",
-    "sanity": "^6.10.1",
+    "@types/react": "^19.3.0",
+    "oxc-transform-react": "^0.147.0",
+    "react": "^19.3.0",
+    "sanity": "^6.16.0",
     "styled-components": "^6.5.3",
     "tsdown": "^0.22.14"
   },
   "peerDependencies": {
Index: package/dist/index.js.map
===================================================================
--- package/dist/index.js.map
+++ package/dist/index.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","names":["<svg\n      // oxlint-disable-next-line prefer-tag-over-role\n      role=\"img\"\n      viewBox=\"0 0 25 25\"\n      width=\"1em\"\n      height=\"1em\"\n      fill=\"currentColor\"\n    >\n      <title>Unsplash</title>\n      <path d=\"M9 9V4h7v5H9Zm7 3h5v9H4v-9h5v5h7v-5Z\" />\n    </svg>","{\n  value,\n  changeAction,\n}: {\n  value: string\n  changeAction: (value: string) => Promise<void> | void\n}","function handleChange(newValue: string) {\n    startTransition(async () => {\n      setInputValue(newValue)\n      await changeAction(newValue)\n    })\n  }","(event) => handleChange(event.currentTarget.value)","() => handleChange('')","<TextInput\n      clearButton={inputValue.length > 0 && !isPending}\n      icon={SearchIcon}\n      onChange={(event) => handleChange(event.currentTarget.value)}\n      onClear={() => handleChange('')}\n      placeholder=\"Search by topics or colors\"\n      value={inputValue}\n      iconRight={isPending && AnimatedSpinnerIcon}\n    />","inputValue.length > 0 && !isPending","isPending && AnimatedSpinnerIcon","{onClose, onSelect}: AssetSourceComponentProps","{apiVersion: '2022-09-01'}","memoize(\n        async function fetcher(query: string, page: number): Promise<FetcherResult> {\n          const searchParams = new URLSearchParams({\n            page: `${page}`,\n            per_page: `${RESULTS_PER_PAGE}`,\n          })\n          if (query.trim()) {\n            searchParams.set('query', query.trim())\n            return client.request<{\n              results: UnsplashPhoto[]\n              total: number\n              total_pages: number\n            }>({\n              url: `/addons/unsplash/search/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n          }\n          searchParams.set('order_by', 'popular')\n          return client\n            .request<UnsplashPhoto[]>({\n              url: `/addons/unsplash/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n            .then((results) => ({\n              results,\n              total: results.length,\n              total_pages: Math.ceil(results.length / RESULTS_PER_PAGE),\n            }))\n        },\n        (query, page) => JSON.stringify({query, page}),\n      )","(results) => ({\n              results,\n              total: results.length,\n              total_pages: Math.ceil(results.length / RESULTS_PER_PAGE),\n            })","(query, page) => JSON.stringify({query, page})","useMemo(\n    () =>\n      memoize(\n        async function fetcher(query: string, page: number): Promise<FetcherResult> {\n          const searchParams = new URLSearchParams({\n            page: `${page}`,\n            per_page: `${RESULTS_PER_PAGE}`,\n          })\n          if (query.trim()) {\n            searchParams.set('query', query.trim())\n            return client.request<{\n              results: UnsplashPhoto[]\n              total: number\n              total_pages: number\n            }>({\n              url: `/addons/unsplash/search/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n          }\n          searchParams.set('order_by', 'popular')\n          return client\n            .request<UnsplashPhoto[]>({\n              url: `/addons/unsplash/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n            .then((results) => ({\n              results,\n              total: results.length,\n              total_pages: Math.ceil(results.length / RESULTS_PER_PAGE),\n            }))\n        },\n        (query, page) => JSON.stringify({query, page}),\n      ),\n    [client],\n  )","query","() => onClose()","{overflow: 'hidden scroll', overflowX: 'clip', overflowY: 'scroll'}","{position: 'sticky', top: 0, zIndex: 1}","<Box style={{position: 'sticky', top: 0, zIndex: 1}}>\n          <SearchInput changeAction={setQuery} value={query} />\n        </Box>","<Loader />","fetcher(query, 1)","<Suspense fallback={<Loader />}>\n          <UnsplashAssetSourceGallery\n            client={client}\n            query={query}\n            fetcher={fetcher}\n            scrollContainerRef={scrollContainerRef}\n            onSelect={onSelect}\n            initialDataPromise={fetcher(query, 1)}\n          />\n        </Suspense>","<Stack\n        ref={scrollContainerRef}\n        gap={1}\n        paddingLeft={3}\n        height=\"stretch\"\n        style={{overflow: 'hidden scroll', overflowX: 'clip', overflowY: 'scroll'}}\n      >\n        <Box style={{position: 'sticky', top: 0, zIndex: 1}}>\n          <SearchInput changeAction={setQuery} value={query} />\n        </Box>\n        <Suspense fallback={<Loader />}>\n          <UnsplashAssetSourceGallery\n            client={client}\n            query={query}\n            fetcher={fetcher}\n            scrollContainerRef={scrollContainerRef}\n            onSelect={onSelect}\n            initialDataPromise={fetcher(query, 1)}\n          />\n        </Suspense>\n      </Stack>","<StyledDialog\n      animate\n      id=\"unsplash-asset-source\"\n      header=\"Select image from Unsplash\"\n      onClose={() => onClose()}\n      open\n      height=\"100%\"\n      width={4}\n    >\n      <Stack\n        ref={scrollContainerRef}\n        gap={1}\n        paddingLeft={3}\n        height=\"stretch\"\n        style={{overflow: 'hidden scroll', overflowX: 'clip', overflowY: 'scroll'}}\n      >\n        <Box style={{position: 'sticky', top: 0, zIndex: 1}}>\n          <SearchInput changeAction={setQuery} value={query} />\n        </Box>\n        <Suspense fallback={<Loader />}>\n          <UnsplashAssetSourceGallery\n            client={client}\n            query={query}\n            fetcher={fetcher}\n            scrollContainerRef={scrollContainerRef}\n            onSelect={onSelect}\n            initialDataPromise={fetcher(query, 1)}\n          />\n        </Suspense>\n      </Stack>\n    </StyledDialog>"],"sources":["../src/components/Icon.tsx","../src/components/SearchInput.tsx","../src/components/UnsplashAssetSource.tsx","../src/index.ts"],"sourcesContent":["/**\n * @public\n */\nexport function UnsplashIcon(): React.JSX.Element {\n  return (\n    <svg\n      // oxlint-disable-next-line prefer-tag-over-role\n      role=\"img\"\n      viewBox=\"0 0 25 25\"\n      width=\"1em\"\n      height=\"1em\"\n      fill=\"currentColor\"\n    >\n      <title>Unsplash</title>\n      <path d=\"M9 9V4h7v5H9Zm7 3h5v9H4v-9h5v5h7v-5Z\" />\n    </svg>\n  )\n}\n","import {SearchIcon} from '@sanity/icons/Search'\nimport {SpinnerIcon} from '@sanity/icons/Spinner'\nimport {TextInput} from '@sanity/ui'\nimport {startTransition, useOptimistic} from 'react'\nimport {styled, keyframes} from 'styled-components'\n\nconst rotate = keyframes`\n  from {\n    transform: rotate(0deg);\n  }\n\n  to {\n    transform: rotate(360deg);\n  }\n`\n\nconst AnimatedSpinnerIcon = styled(SpinnerIcon)`\n  animation: ${rotate} 500ms linear infinite;\n`\n\nexport function SearchInput({\n  value,\n  changeAction,\n}: {\n  value: string\n  changeAction: (value: string) => Promise<void> | void\n}) {\n  const [inputValue, setInputValue] = useOptimistic(value)\n  const isPending = inputValue !== value\n  function handleChange(newValue: string) {\n    startTransition(async () => {\n      setInputValue(newValue)\n      await changeAction(newValue)\n    })\n  }\n\n  return (\n    <TextInput\n      clearButton={inputValue.length > 0 && !isPending}\n      icon={SearchIcon}\n      onChange={(event) => handleChange(event.currentTarget.value)}\n      onClear={() => handleChange('')}\n      placeholder=\"Search by topics or colors\"\n      value={inputValue}\n      iconRight={isPending && AnimatedSpinnerIcon}\n    />\n  )\n}\n","import {Dialog, Stack, Box} from '@sanity/ui'\nimport memoize from 'lodash-es/memoize.js'\nimport {lazy, Suspense, useMemo, useRef, useState} from 'react'\nimport {type AssetSourceComponentProps, useClient} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport type {FetcherResult, UnsplashPhoto} from '../types'\nimport {Loader} from './Loader'\nimport {SearchInput} from './SearchInput'\n\nconst RESULTS_PER_PAGE = 42\n\nconst StyledDialog = styled(Dialog)`\n  & > [data-ui='DialogCard'] > [data-ui='Card'] {\n    height: 100%;\n  }\n`\n\nconst UnsplashAssetSourceGallery = lazy(() => import('./UnsplashPhotoGallery'))\n\nexport function UnsplashAssetSource({onClose, onSelect}: AssetSourceComponentProps) {\n  const client = useClient({apiVersion: '2022-09-01'})\n  const fetcher = useMemo(\n    () =>\n      memoize(\n        async function fetcher(query: string, page: number): Promise<FetcherResult> {\n          const searchParams = new URLSearchParams({\n            page: `${page}`,\n            per_page: `${RESULTS_PER_PAGE}`,\n          })\n          if (query.trim()) {\n            searchParams.set('query', query.trim())\n            return client.request<{\n              results: UnsplashPhoto[]\n              total: number\n              total_pages: number\n            }>({\n              url: `/addons/unsplash/search/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n          }\n          searchParams.set('order_by', 'popular')\n          return client\n            .request<UnsplashPhoto[]>({\n              url: `/addons/unsplash/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n            .then((results) => ({\n              results,\n              total: results.length,\n              total_pages: Math.ceil(results.length / RESULTS_PER_PAGE),\n            }))\n        },\n        (query, page) => JSON.stringify({query, page}),\n      ),\n    [client],\n  )\n\n  const [query, setQuery] = useState('')\n  const scrollContainerRef = useRef<HTMLDivElement>(null)\n\n  return (\n    <StyledDialog\n      animate\n      id=\"unsplash-asset-source\"\n      header=\"Select image from Unsplash\"\n      onClose={() => onClose()}\n      open\n      height=\"100%\"\n      width={4}\n    >\n      <Stack\n        ref={scrollContainerRef}\n        gap={1}\n        paddingLeft={3}\n        height=\"stretch\"\n        style={{overflow: 'hidden scroll', overflowX: 'clip', overflowY: 'scroll'}}\n      >\n        <Box style={{position: 'sticky', top: 0, zIndex: 1}}>\n          <SearchInput changeAction={setQuery} value={query} />\n        </Box>\n        <Suspense fallback={<Loader />}>\n          <UnsplashAssetSourceGallery\n            client={client}\n            query={query}\n            fetcher={fetcher}\n            scrollContainerRef={scrollContainerRef}\n            onSelect={onSelect}\n            initialDataPromise={fetcher(query, 1)}\n          />\n        </Suspense>\n      </Stack>\n    </StyledDialog>\n  )\n}\n","import '@sanity/ui/styles.css'\nimport {type AssetSource, definePlugin, type Plugin} from 'sanity'\n\nimport {UnsplashIcon} from './components/Icon'\nimport {UnsplashAssetSource} from './components/UnsplashAssetSource'\n\nexport type {Asset, AssetDocument, UnsplashPhoto} from './types'\n\n/**\n * @public\n */\nexport const unsplashAssetSource: AssetSource = {\n  name: 'unsplash',\n  // oxlint-disable-next-line no-deprecated -- `i18nKey` requires a locale bundle; a plain title is intentional here\n  title: 'Unsplash',\n  component: UnsplashAssetSource,\n  icon: UnsplashIcon,\n}\n\n/**\n * @public\n */\nexport const unsplashImageAsset: Plugin = definePlugin({\n  name: 'asset-source-unsplash-plugin',\n\n  form: {\n    image: {\n      assetSources: [unsplashAssetSource],\n    },\n  },\n})\n\nexport {UnsplashIcon}\n"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"index.js","names":["<svg\n      // oxlint-disable-next-line prefer-tag-over-role\n      role=\"img\"\n      viewBox=\"0 0 25 25\"\n      width=\"1em\"\n      height=\"1em\"\n      fill=\"currentColor\"\n    >\n      <title>Unsplash</title>\n      <path d=\"M9 9V4h7v5H9Zm7 3h5v9H4v-9h5v5h7v-5Z\" />\n    </svg>","_c","{\n  value,\n  changeAction,\n}: {\n  value: string\n  changeAction: (value: string) => Promise<void> | void\n}","function handleChange(newValue: string) {\n    startTransition(async () => {\n      setInputValue(newValue)\n      await changeAction(newValue)\n    })\n  }","(event) => handleChange(event.currentTarget.value)","() => handleChange('')","<TextInput\n      clearButton={inputValue.length > 0 && !isPending}\n      icon={SearchIcon}\n      onChange={(event) => handleChange(event.currentTarget.value)}\n      onClear={() => handleChange('')}\n      placeholder=\"Search by topics or colors\"\n      value={inputValue}\n      iconRight={isPending && AnimatedSpinnerIcon}\n    />","inputValue.length > 0 && !isPending","isPending && AnimatedSpinnerIcon","_c","{onClose, onSelect}: AssetSourceComponentProps","{apiVersion: '2022-09-01'}","memoize(\n        async function fetcher(query: string, page: number): Promise<FetcherResult> {\n          const searchParams = new URLSearchParams({\n            page: `${page}`,\n            per_page: `${RESULTS_PER_PAGE}`,\n          })\n          if (query.trim()) {\n            searchParams.set('query', query.trim())\n            return client.request<{\n              results: UnsplashPhoto[]\n              total: number\n              total_pages: number\n            }>({\n              url: `/addons/unsplash/search/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n          }\n          searchParams.set('order_by', 'popular')\n          return client\n            .request<UnsplashPhoto[]>({\n              url: `/addons/unsplash/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n            .then((results) => ({\n              results,\n              total: results.length,\n              total_pages: Math.ceil(results.length / RESULTS_PER_PAGE),\n            }))\n        },\n        (query, page) => JSON.stringify({query, page}),\n      )","(results) => ({\n              results,\n              total: results.length,\n              total_pages: Math.ceil(results.length / RESULTS_PER_PAGE),\n            })","(query, page) => JSON.stringify({query, page})","useMemo(\n    () =>\n      memoize(\n        async function fetcher(query: string, page: number): Promise<FetcherResult> {\n          const searchParams = new URLSearchParams({\n            page: `${page}`,\n            per_page: `${RESULTS_PER_PAGE}`,\n          })\n          if (query.trim()) {\n            searchParams.set('query', query.trim())\n            return client.request<{\n              results: UnsplashPhoto[]\n              total: number\n              total_pages: number\n            }>({\n              url: `/addons/unsplash/search/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n          }\n          searchParams.set('order_by', 'popular')\n          return client\n            .request<UnsplashPhoto[]>({\n              url: `/addons/unsplash/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n            .then((results) => ({\n              results,\n              total: results.length,\n              total_pages: Math.ceil(results.length / RESULTS_PER_PAGE),\n            }))\n        },\n        (query, page) => JSON.stringify({query, page}),\n      ),\n    [client],\n  )","query","() => onClose()","{overflow: 'hidden scroll', overflowX: 'clip', overflowY: 'scroll'}","{position: 'sticky', top: 0, zIndex: 1}","<Box style={{position: 'sticky', top: 0, zIndex: 1}}>\n          <SearchInput changeAction={setQuery} value={query} />\n        </Box>","<Loader />","fetcher(query, 1)","<Suspense fallback={<Loader />}>\n          <UnsplashAssetSourceGallery\n            client={client}\n            query={query}\n            fetcher={fetcher}\n            scrollContainerRef={scrollContainerRef}\n            onSelect={onSelect}\n            initialDataPromise={fetcher(query, 1)}\n          />\n        </Suspense>","<Stack\n        ref={scrollContainerRef}\n        gap={1}\n        paddingLeft={3}\n        height=\"stretch\"\n        style={{overflow: 'hidden scroll', overflowX: 'clip', overflowY: 'scroll'}}\n      >\n        <Box style={{position: 'sticky', top: 0, zIndex: 1}}>\n          <SearchInput changeAction={setQuery} value={query} />\n        </Box>\n        <Suspense fallback={<Loader />}>\n          <UnsplashAssetSourceGallery\n            client={client}\n            query={query}\n            fetcher={fetcher}\n            scrollContainerRef={scrollContainerRef}\n            onSelect={onSelect}\n            initialDataPromise={fetcher(query, 1)}\n          />\n        </Suspense>\n      </Stack>","<StyledDialog\n      animate\n      id=\"unsplash-asset-source\"\n      header=\"Select image from Unsplash\"\n      onClose={() => onClose()}\n      open\n      height=\"100%\"\n      width={4}\n    >\n      <Stack\n        ref={scrollContainerRef}\n        gap={1}\n        paddingLeft={3}\n        height=\"stretch\"\n        style={{overflow: 'hidden scroll', overflowX: 'clip', overflowY: 'scroll'}}\n      >\n        <Box style={{position: 'sticky', top: 0, zIndex: 1}}>\n          <SearchInput changeAction={setQuery} value={query} />\n        </Box>\n        <Suspense fallback={<Loader />}>\n          <UnsplashAssetSourceGallery\n            client={client}\n            query={query}\n            fetcher={fetcher}\n            scrollContainerRef={scrollContainerRef}\n            onSelect={onSelect}\n            initialDataPromise={fetcher(query, 1)}\n          />\n        </Suspense>\n      </Stack>\n    </StyledDialog>","_c"],"sources":["../src/components/Icon.tsx","../src/components/SearchInput.tsx","../src/components/UnsplashAssetSource.tsx","../src/index.ts"],"sourcesContent":["/**\n * @public\n */\nexport function UnsplashIcon(): React.JSX.Element {\n  return (\n    <svg\n      // oxlint-disable-next-line prefer-tag-over-role\n      role=\"img\"\n      viewBox=\"0 0 25 25\"\n      width=\"1em\"\n      height=\"1em\"\n      fill=\"currentColor\"\n    >\n      <title>Unsplash</title>\n      <path d=\"M9 9V4h7v5H9Zm7 3h5v9H4v-9h5v5h7v-5Z\" />\n    </svg>\n  )\n}\n","import {SearchIcon} from '@sanity/icons/Search'\nimport {SpinnerIcon} from '@sanity/icons/Spinner'\nimport {TextInput} from '@sanity/ui'\nimport {startTransition, useOptimistic} from 'react'\nimport {styled, keyframes} from 'styled-components'\n\nconst rotate = keyframes`\n  from {\n    transform: rotate(0deg);\n  }\n\n  to {\n    transform: rotate(360deg);\n  }\n`\n\nconst AnimatedSpinnerIcon = styled(SpinnerIcon)`\n  animation: ${rotate} 500ms linear infinite;\n`\n\nexport function SearchInput({\n  value,\n  changeAction,\n}: {\n  value: string\n  changeAction: (value: string) => Promise<void> | void\n}) {\n  const [inputValue, setInputValue] = useOptimistic(value)\n  const isPending = inputValue !== value\n  function handleChange(newValue: string) {\n    startTransition(async () => {\n      setInputValue(newValue)\n      await changeAction(newValue)\n    })\n  }\n\n  return (\n    <TextInput\n      clearButton={inputValue.length > 0 && !isPending}\n      icon={SearchIcon}\n      onChange={(event) => handleChange(event.currentTarget.value)}\n      onClear={() => handleChange('')}\n      placeholder=\"Search by topics or colors\"\n      value={inputValue}\n      iconRight={isPending && AnimatedSpinnerIcon}\n    />\n  )\n}\n","import {Dialog, Stack, Box} from '@sanity/ui'\nimport memoize from 'lodash-es/memoize.js'\nimport {lazy, Suspense, useMemo, useRef, useState} from 'react'\nimport {type AssetSourceComponentProps, useClient} from 'sanity'\nimport {styled} from 'styled-components'\n\nimport type {FetcherResult, UnsplashPhoto} from '../types'\nimport {Loader} from './Loader'\nimport {SearchInput} from './SearchInput'\n\nconst RESULTS_PER_PAGE = 42\n\nconst StyledDialog = styled(Dialog)`\n  & > [data-ui='DialogCard'] > [data-ui='Card'] {\n    height: 100%;\n  }\n`\n\nconst UnsplashAssetSourceGallery = lazy(() => import('./UnsplashPhotoGallery'))\n\nexport function UnsplashAssetSource({onClose, onSelect}: AssetSourceComponentProps) {\n  const client = useClient({apiVersion: '2022-09-01'})\n  const fetcher = useMemo(\n    () =>\n      memoize(\n        async function fetcher(query: string, page: number): Promise<FetcherResult> {\n          const searchParams = new URLSearchParams({\n            page: `${page}`,\n            per_page: `${RESULTS_PER_PAGE}`,\n          })\n          if (query.trim()) {\n            searchParams.set('query', query.trim())\n            return client.request<{\n              results: UnsplashPhoto[]\n              total: number\n              total_pages: number\n            }>({\n              url: `/addons/unsplash/search/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n          }\n          searchParams.set('order_by', 'popular')\n          return client\n            .request<UnsplashPhoto[]>({\n              url: `/addons/unsplash/photos?${searchParams}`,\n              withCredentials: true,\n              method: 'GET',\n            })\n            .then((results) => ({\n              results,\n              total: results.length,\n              total_pages: Math.ceil(results.length / RESULTS_PER_PAGE),\n            }))\n        },\n        (query, page) => JSON.stringify({query, page}),\n      ),\n    [client],\n  )\n\n  const [query, setQuery] = useState('')\n  const scrollContainerRef = useRef<HTMLDivElement>(null)\n\n  return (\n    <StyledDialog\n      animate\n      id=\"unsplash-asset-source\"\n      header=\"Select image from Unsplash\"\n      onClose={() => onClose()}\n      open\n      height=\"100%\"\n      width={4}\n    >\n      <Stack\n        ref={scrollContainerRef}\n        gap={1}\n        paddingLeft={3}\n        height=\"stretch\"\n        style={{overflow: 'hidden scroll', overflowX: 'clip', overflowY: 'scroll'}}\n      >\n        <Box style={{position: 'sticky', top: 0, zIndex: 1}}>\n          <SearchInput changeAction={setQuery} value={query} />\n        </Box>\n        <Suspense fallback={<Loader />}>\n          <UnsplashAssetSourceGallery\n            client={client}\n            query={query}\n            fetcher={fetcher}\n            scrollContainerRef={scrollContainerRef}\n            onSelect={onSelect}\n            initialDataPromise={fetcher(query, 1)}\n          />\n        </Suspense>\n      </Stack>\n    </StyledDialog>\n  )\n}\n","import '@sanity/ui/styles.css'\nimport {type AssetSource, definePlugin, type Plugin} from 'sanity'\n\nimport {UnsplashIcon} from './components/Icon'\nimport {UnsplashAssetSource} from './components/UnsplashAssetSource'\n\nexport type {Asset, AssetDocument, UnsplashPhoto} from './types'\n\n/**\n * @public\n */\nexport const unsplashAssetSource: AssetSource = {\n  name: 'unsplash',\n  // oxlint-disable-next-line no-deprecated -- `i18nKey` requires a locale bundle; a plain title is intentional here\n  title: 'Unsplash',\n  component: UnsplashAssetSource,\n  icon: UnsplashIcon,\n}\n\n/**\n * @public\n */\nexport const unsplashImageAsset: Plugin = definePlugin({\n  name: 'asset-source-unsplash-plugin',\n\n  form: {\n    image: {\n      assetSources: [unsplashAssetSource],\n    },\n  },\n})\n\nexport {UnsplashIcon}\n"],"mappings":"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"}
\ No newline at end of file
Index: package/dist/Loader-BKAt74MR.js.map
===================================================================
--- package/dist/Loader-BKAt74MR.js.map
+++ package/dist/Loader-BKAt74MR.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"Loader-BKAt74MR.js","names":["<Flex align=\"center\" justify=\"center\" padding={3}>\n      <Spinner muted />\n    </Flex>"],"sources":["../src/components/Loader.tsx"],"sourcesContent":["import {Flex, Spinner} from '@sanity/ui'\n\nexport function Loader() {\n  return (\n    <Flex align=\"center\" justify=\"center\" padding={3}>\n      <Spinner muted />\n    </Flex>\n  )\n}\n"],"mappings":";;;AAEA,SAAgB,SAAS;eAErBA;CADF,2DACG,KAAA,oBAAA,MAAD;EAAM,OAAM;EAAS,SAAQ;EAAS,SAAS;EAC7C,UAAA,oBAAC,SAAD,EAAS,OAAA,GAAO,CAAA;CACZ,CAAA,2BAFNA;AAIJ"}
\ No newline at end of file
+{"version":3,"file":"Loader-BKAt74MR.js","names":["<Flex align=\"center\" justify=\"center\" padding={3}>\n      <Spinner muted />\n    </Flex>","_c"],"sources":["../src/components/Loader.tsx"],"sourcesContent":["import {Flex, Spinner} from '@sanity/ui'\n\nexport function Loader() {\n  return (\n    <Flex align=\"center\" justify=\"center\" padding={3}>\n      <Spinner muted />\n    </Flex>\n  )\n}\n"],"mappings":";;;AAEA,SAAgB,SAAS;eAErBA;CADF,2DACG,KAAA,oBAAA,MAAD;EAAM,OAAM;EAAS,SAAQ;EAAS,SAAS;EAC7C,UAAA,oBAAC,SAAD,EAAS,OAAA,GAAO,CAAA;CACZ,CAAA,2BAFNA;AAIJ"}
\ No newline at end of file
Index: package/dist/UnsplashPhotoGallery-95ChILH4.js.map
===================================================================
--- package/dist/UnsplashPhotoGallery-95ChILH4.js.map
+++ package/dist/UnsplashPhotoGallery-95ChILH4.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"UnsplashPhotoGallery-95ChILH4.js","names":["{\n  link,\n  id,\n  userName,\n}: {\n  link: string\n  id: string\n  userName: string\n}","CreditLineLink","url.toString()","<CreditLine padding={1} radius={1} margin={1}>\n        <Text size={0} title={`Open image by ${userName} on Unsplash in new window`}>\n          By @{userName}\n        </Text>\n      </CreditLine>","`Open image by ${userName} on Unsplash in new window`","<CreditLineLink\n      href={url.toString()}\n      target={id}\n      rel=\"noreferrer noopener\"\n      onClick={(event) => event.stopPropagation()}\n    >\n      <CreditLine padding={1} radius={1} margin={1}>\n        <Text size={0} title={`Open image by ${userName} on Unsplash in new window`}>\n          By @{userName}\n        </Text>\n      </CreditLine>\n    </CreditLineLink>","(event) => event.stopPropagation()","{\n  client,\n  query,\n  fetcher,\n  scrollContainerRef,\n  onSelect,\n  initialDataPromise,\n}: {\n  client: SanityClient\n  query: string\n  fetcher: (query: string, index: number) => Promise<FetcherResult>\n  scrollContainerRef: React.RefObject<HTMLDivElement | null>\n  initialDataPromise: Promise<FetcherResult>\n} & Pick<AssetSourceComponentProps, 'onSelect'>","<Box paddingX={2} paddingY={3}>\n          <Text size={1} muted>\n            No results found for \"{query}\"\n          </Text>\n        </Box>","<Activity mode={data.total === 0 ? 'visible' : 'hidden'}>\n        <Box paddingX={2} paddingY={3}>\n          <Text size={1} muted>\n            No results found for \"{query}\"\n          </Text>\n        </Box>\n      </Activity>","data.total === 0 ? 'visible' : 'hidden'","() => scrollContainerRef.current","scrollContainerRef.current","data.results.map(mapUnsplashToPhotoAlbumPhoto)","results","async (index) => {\n            const {results, total_pages} = await fetcher(query, index + 1)\n\n            if (index < total_pages) {\n              return results.map(mapUnsplashToPhotoAlbumPhoto)\n            }\n\n            return null\n          }","<Loader />","query && (\n              <Box paddingX={2} paddingY={3}>\n                <Text size={1} muted>\n                  No more results\n                </Text>\n              </Box>\n            )","async ({photo: {data: photo}}) => {\n            const downloadUrl = await fetchDownloadUrl(client, photo)\n\n            const description = photo.description || undefined\n            const asset: AssetFromSource = {\n              kind: 'url',\n              value: downloadUrl,\n              // @ts-expect-error TODO: this is a partial assetDocumentProps, update types.\n              assetDocumentProps: {\n                _type: 'sanity.imageAsset',\n                source: {\n                  name: 'unsplash',\n                  id: photo.id,\n                  url: photo.links.html,\n                },\n                description,\n                creditLine: `${photo.user.name} by Unsplash`,\n              },\n            }\n            return onSelect([asset])\n          }","{data: photo}","{photo: {data: photo}}","[]","<RowsPhotoAlbum<ReturnType<typeof mapUnsplashToPhotoAlbumPhoto>>\n            photos={[]}\n            spacing={PHOTO_SPACING}\n            padding={PHOTO_PADDING}\n            targetRowHeight={(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }}\n            render={{\n              extras: (_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              },\n            }}\n            componentsProps={{container: {style: {marginBottom: PHOTO_SPACING}}}}\n          />","(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }","(_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              }","<InfiniteScroll\n          key={query}\n          scrollContainer={() => scrollContainerRef.current}\n          photos={data.results.map(mapUnsplashToPhotoAlbumPhoto)}\n          fetch={async (index) => {\n            const {results, total_pages} = await fetcher(query, index + 1)\n\n            if (index < total_pages) {\n              return results.map(mapUnsplashToPhotoAlbumPhoto)\n            }\n\n            return null\n          }}\n          loading={<Loader />}\n          finished={\n            query && (\n              <Box paddingX={2} paddingY={3}>\n                <Text size={1} muted>\n                  No more results\n                </Text>\n              </Box>\n            )\n          }\n          onClick={async ({photo: {data: photo}}) => {\n            const downloadUrl = await fetchDownloadUrl(client, photo)\n\n            const description = photo.description || undefined\n            const asset: AssetFromSource = {\n              kind: 'url',\n              value: downloadUrl,\n              // @ts-expect-error TODO: this is a partial assetDocumentProps, update types.\n              assetDocumentProps: {\n                _type: 'sanity.imageAsset',\n                source: {\n                  name: 'unsplash',\n                  id: photo.id,\n                  url: photo.links.html,\n                },\n                description,\n                creditLine: `${photo.user.name} by Unsplash`,\n              },\n            }\n            return onSelect([asset])\n          }}\n        >\n          <RowsPhotoAlbum<ReturnType<typeof mapUnsplashToPhotoAlbumPhoto>>\n            photos={[]}\n            spacing={PHOTO_SPACING}\n            padding={PHOTO_PADDING}\n            targetRowHeight={(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }}\n            render={{\n              extras: (_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              },\n            }}\n            componentsProps={{container: {style: {marginBottom: PHOTO_SPACING}}}}\n          />\n        </InfiniteScroll>","<Activity mode={data.total === 0 ? 'hidden' : 'visible'}>\n        <InfiniteScroll\n          key={query}\n          scrollContainer={() => scrollContainerRef.current}\n          photos={data.results.map(mapUnsplashToPhotoAlbumPhoto)}\n          fetch={async (index) => {\n            const {results, total_pages} = await fetcher(query, index + 1)\n\n            if (index < total_pages) {\n              return results.map(mapUnsplashToPhotoAlbumPhoto)\n            }\n\n            return null\n          }}\n          loading={<Loader />}\n          finished={\n            query && (\n              <Box paddingX={2} paddingY={3}>\n                <Text size={1} muted>\n                  No more results\n                </Text>\n              </Box>\n            )\n          }\n          onClick={async ({photo: {data: photo}}) => {\n            const downloadUrl = await fetchDownloadUrl(client, photo)\n\n            const description = photo.description || undefined\n            const asset: AssetFromSource = {\n              kind: 'url',\n              value: downloadUrl,\n              // @ts-expect-error TODO: this is a partial assetDocumentProps, update types.\n              assetDocumentProps: {\n                _type: 'sanity.imageAsset',\n                source: {\n                  name: 'unsplash',\n                  id: photo.id,\n                  url: photo.links.html,\n                },\n                description,\n                creditLine: `${photo.user.name} by Unsplash`,\n              },\n            }\n            return onSelect([asset])\n          }}\n        >\n          <RowsPhotoAlbum<ReturnType<typeof mapUnsplashToPhotoAlbumPhoto>>\n            photos={[]}\n            spacing={PHOTO_SPACING}\n            padding={PHOTO_PADDING}\n            targetRowHeight={(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }}\n            render={{\n              extras: (_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              },\n            }}\n            componentsProps={{container: {style: {marginBottom: PHOTO_SPACING}}}}\n          />\n        </InfiniteScroll>\n      </Activity>","data.total === 0 ? 'hidden' : 'visible'","<>\n      <Activity mode={data.total === 0 ? 'visible' : 'hidden'}>\n        <Box paddingX={2} paddingY={3}>\n          <Text size={1} muted>\n            No results found for \"{query}\"\n          </Text>\n        </Box>\n      </Activity>\n      <Activity mode={data.total === 0 ? 'hidden' : 'visible'}>\n        <InfiniteScroll\n          key={query}\n          scrollContainer={() => scrollContainerRef.current}\n          photos={data.results.map(mapUnsplashToPhotoAlbumPhoto)}\n          fetch={async (index) => {\n            const {results, total_pages} = await fetcher(query, index + 1)\n\n            if (index < total_pages) {\n              return results.map(mapUnsplashToPhotoAlbumPhoto)\n            }\n\n            return null\n          }}\n          loading={<Loader />}\n          finished={\n            query && (\n              <Box paddingX={2} paddingY={3}>\n                <Text size={1} muted>\n                  No more results\n                </Text>\n              </Box>\n            )\n          }\n          onClick={async ({photo: {data: photo}}) => {\n            const downloadUrl = await fetchDownloadUrl(client, photo)\n\n            const description = photo.description || undefined\n            const asset: AssetFromSource = {\n              kind: 'url',\n              value: downloadUrl,\n              // @ts-expect-error TODO: this is a partial assetDocumentProps, update types.\n              assetDocumentProps: {\n                _type: 'sanity.imageAsset',\n                source: {\n                  name: 'unsplash',\n                  id: photo.id,\n                  url: photo.links.html,\n                },\n                description,\n                creditLine: `${photo.user.name} by Unsplash`,\n              },\n            }\n            return onSelect([asset])\n          }}\n        >\n          <RowsPhotoAlbum<ReturnType<typeof mapUnsplashToPhotoAlbumPhoto>>\n            photos={[]}\n            spacing={PHOTO_SPACING}\n            padding={PHOTO_PADDING}\n            targetRowHeight={(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }}\n            render={{\n              extras: (_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              },\n            }}\n            componentsProps={{container: {style: {marginBottom: PHOTO_SPACING}}}}\n          />\n        </InfiniteScroll>\n      </Activity>\n    </>"],"sources":["../src/datastores/unsplash.ts","../src/components/UnsplashCreditLine.tsx","../src/components/UnsplashPhotoGallery.tsx"],"sourcesContent":["import type {SanityClient} from 'sanity'\n\nimport type {UnsplashPhoto} from '../types'\n\nexport async function fetchDownloadUrl(\n  client: SanityClient,\n  photo: UnsplashPhoto,\n): Promise<string> {\n  const downloadUrl = photo.links.download_location.replace(\n    'https://api.unsplash.com',\n    '/addons/unsplash',\n  )\n  const {url} = await client.request<{url: string}>({\n    url: downloadUrl,\n    withCredentials: true,\n    method: 'GET',\n  })\n\n  return url\n}\n","import {Text, Card} from '@sanity/ui'\nimport {getTheme_v2} from '@sanity/ui/theme'\nimport {styled} from 'styled-components'\n\nconst CreditLineLink = styled.a`\n  text-decoration: none;\n  cursor: pointer;\n  &:hover,\n  &:focus {\n    [data-ui='Text'] {\n      text-decoration: underline;\n    }\n  }\n`\n\nconst CreditLine = styled(Card)`\n  ${({theme}) => {\n    const v2 = getTheme_v2({sanity: theme.sanity})\n    return `\n     --creditline-fg: ${v2.color.fg};\n     --creditline-bg: ${v2.color.bg};\n   `\n  }};\n  -webkit-user-drag: none;\n  position: absolute;\n  background-color: var(--creditline-bg);\n  bottom: 0;\n\n  [data-ui='Text'] {\n    color: var(--creditline-fg);\n  }\n`\n\nconst UTM_SOURCE = 'sanity-plugin-asset-source-unsplash'\nexport function UnsplashCreditLine({\n  link,\n  id,\n  userName,\n}: {\n  link: string\n  id: string\n  userName: string\n}) {\n  const url = new URL(link)\n  url.searchParams.set('utm_source', UTM_SOURCE)\n  url.searchParams.set('utm_medium', 'referral')\n\n  return (\n    <CreditLineLink\n      href={url.toString()}\n      target={id}\n      rel=\"noreferrer noopener\"\n      onClick={(event) => event.stopPropagation()}\n    >\n      <CreditLine padding={1} radius={1} margin={1}>\n        <Text size={0} title={`Open image by ${userName} on Unsplash in new window`}>\n          By @{userName}\n        </Text>\n      </CreditLine>\n    </CreditLineLink>\n  )\n}\n","import {Box, Text} from '@sanity/ui'\nimport {use, Activity} from 'react'\n\nimport 'react-photo-album/rows.css'\nimport {RowsPhotoAlbum} from 'react-photo-album'\nimport InfiniteScroll from 'react-photo-album/scroll'\nimport {type AssetFromSource, type AssetSourceComponentProps, type SanityClient} from 'sanity'\n\nimport {fetchDownloadUrl} from '../datastores/unsplash'\nimport type {FetcherResult, UnsplashPhoto} from '../types'\nimport {Loader} from './Loader'\nimport {UnsplashCreditLine} from './UnsplashCreditLine'\n\nconst PHOTO_SPACING = 2\nconst PHOTO_PADDING = 1 // offset the 1px border width\n\nfunction mapUnsplashToPhotoAlbumPhoto(photo: UnsplashPhoto) {\n  return {\n    src: photo.urls.small,\n    width: photo.width,\n    height: photo.height,\n    key: photo.id,\n    data: photo,\n  }\n}\n\nexport default function UnsplashAssetSourceGallery({\n  client,\n  query,\n  fetcher,\n  scrollContainerRef,\n  onSelect,\n  initialDataPromise,\n}: {\n  client: SanityClient\n  query: string\n  fetcher: (query: string, index: number) => Promise<FetcherResult>\n  scrollContainerRef: React.RefObject<HTMLDivElement | null>\n  initialDataPromise: Promise<FetcherResult>\n} & Pick<AssetSourceComponentProps, 'onSelect'>) {\n  const data = use(initialDataPromise)\n\n  return (\n    <>\n      <Activity mode={data.total === 0 ? 'visible' : 'hidden'}>\n        <Box paddingX={2} paddingY={3}>\n          <Text size={1} muted>\n            No results found for \"{query}\"\n          </Text>\n        </Box>\n      </Activity>\n      <Activity mode={data.total === 0 ? 'hidden' : 'visible'}>\n        <InfiniteScroll\n          key={query}\n          scrollContainer={() => scrollContainerRef.current}\n          photos={data.results.map(mapUnsplashToPhotoAlbumPhoto)}\n          fetch={async (index) => {\n            const {results, total_pages} = await fetcher(query, index + 1)\n\n            if (index < total_pages) {\n              return results.map(mapUnsplashToPhotoAlbumPhoto)\n            }\n\n            return null\n          }}\n          loading={<Loader />}\n          finished={\n            query && (\n              <Box paddingX={2} paddingY={3}>\n                <Text size={1} muted>\n                  No more results\n                </Text>\n              </Box>\n            )\n          }\n          onClick={async ({photo: {data: photo}}) => {\n            const downloadUrl = await fetchDownloadUrl(client, photo)\n\n            const description = photo.description || undefined\n            const asset: AssetFromSource = {\n              kind: 'url',\n              value: downloadUrl,\n              // @ts-expect-error TODO: this is a partial assetDocumentProps, update types.\n              assetDocumentProps: {\n                _type: 'sanity.imageAsset',\n                source: {\n                  name: 'unsplash',\n                  id: photo.id,\n                  url: photo.links.html,\n                },\n                description,\n                creditLine: `${photo.user.name} by Unsplash`,\n              },\n            }\n            return onSelect([asset])\n          }}\n        >\n          <RowsPhotoAlbum<ReturnType<typeof mapUnsplashToPhotoAlbumPhoto>>\n            photos={[]}\n            spacing={PHOTO_SPACING}\n            padding={PHOTO_PADDING}\n            targetRowHeight={(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }}\n            render={{\n              extras: (_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              },\n            }}\n            componentsProps={{container: {style: {marginBottom: PHOTO_SPACING}}}}\n          />\n        </InfiniteScroll>\n      </Activity>\n    </>\n  )\n}\n"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"UnsplashPhotoGallery-95ChILH4.js","names":["{\n  link,\n  id,\n  userName,\n}: {\n  link: string\n  id: string\n  userName: string\n}","CreditLineLink","url.toString()","<CreditLine padding={1} radius={1} margin={1}>\n        <Text size={0} title={`Open image by ${userName} on Unsplash in new window`}>\n          By @{userName}\n        </Text>\n      </CreditLine>","`Open image by ${userName} on Unsplash in new window`","<CreditLineLink\n      href={url.toString()}\n      target={id}\n      rel=\"noreferrer noopener\"\n      onClick={(event) => event.stopPropagation()}\n    >\n      <CreditLine padding={1} radius={1} margin={1}>\n        <Text size={0} title={`Open image by ${userName} on Unsplash in new window`}>\n          By @{userName}\n        </Text>\n      </CreditLine>\n    </CreditLineLink>","(event) => event.stopPropagation()","_c","_temp","{\n  client,\n  query,\n  fetcher,\n  scrollContainerRef,\n  onSelect,\n  initialDataPromise,\n}: {\n  client: SanityClient\n  query: string\n  fetcher: (query: string, index: number) => Promise<FetcherResult>\n  scrollContainerRef: React.RefObject<HTMLDivElement | null>\n  initialDataPromise: Promise<FetcherResult>\n} & Pick<AssetSourceComponentProps, 'onSelect'>","<Box paddingX={2} paddingY={3}>\n          <Text size={1} muted>\n            No results found for \"{query}\"\n          </Text>\n        </Box>","<Activity mode={data.total === 0 ? 'visible' : 'hidden'}>\n        <Box paddingX={2} paddingY={3}>\n          <Text size={1} muted>\n            No results found for \"{query}\"\n          </Text>\n        </Box>\n      </Activity>","data.total === 0 ? 'visible' : 'hidden'","() => scrollContainerRef.current","scrollContainerRef.current","data.results.map(mapUnsplashToPhotoAlbumPhoto)","results","async (index) => {\n            const {results, total_pages} = await fetcher(query, index + 1)\n\n            if (index < total_pages) {\n              return results.map(mapUnsplashToPhotoAlbumPhoto)\n            }\n\n            return null\n          }","<Loader />","query && (\n              <Box paddingX={2} paddingY={3}>\n                <Text size={1} muted>\n                  No more results\n                </Text>\n              </Box>\n            )","async ({photo: {data: photo}}) => {\n            const downloadUrl = await fetchDownloadUrl(client, photo)\n\n            const description = photo.description || undefined\n            const asset: AssetFromSource = {\n              kind: 'url',\n              value: downloadUrl,\n              // @ts-expect-error TODO: this is a partial assetDocumentProps, update types.\n              assetDocumentProps: {\n                _type: 'sanity.imageAsset',\n                source: {\n                  name: 'unsplash',\n                  id: photo.id,\n                  url: photo.links.html,\n                },\n                description,\n                creditLine: `${photo.user.name} by Unsplash`,\n              },\n            }\n            return onSelect([asset])\n          }","{data: photo}","{photo: {data: photo}}","[]","<RowsPhotoAlbum<ReturnType<typeof mapUnsplashToPhotoAlbumPhoto>>\n            photos={[]}\n            spacing={PHOTO_SPACING}\n            padding={PHOTO_PADDING}\n            targetRowHeight={(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }}\n            render={{\n              extras: (_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              },\n            }}\n            componentsProps={{container: {style: {marginBottom: PHOTO_SPACING}}}}\n          />","(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }","(_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              }","<InfiniteScroll\n          key={query}\n          scrollContainer={() => scrollContainerRef.current}\n          photos={data.results.map(mapUnsplashToPhotoAlbumPhoto)}\n          fetch={async (index) => {\n            const {results, total_pages} = await fetcher(query, index + 1)\n\n            if (index < total_pages) {\n              return results.map(mapUnsplashToPhotoAlbumPhoto)\n            }\n\n            return null\n          }}\n          loading={<Loader />}\n          finished={\n            query && (\n              <Box paddingX={2} paddingY={3}>\n                <Text size={1} muted>\n                  No more results\n                </Text>\n              </Box>\n            )\n          }\n          onClick={async ({photo: {data: photo}}) => {\n            const downloadUrl = await fetchDownloadUrl(client, photo)\n\n            const description = photo.description || undefined\n            const asset: AssetFromSource = {\n              kind: 'url',\n              value: downloadUrl,\n              // @ts-expect-error TODO: this is a partial assetDocumentProps, update types.\n              assetDocumentProps: {\n                _type: 'sanity.imageAsset',\n                source: {\n                  name: 'unsplash',\n                  id: photo.id,\n                  url: photo.links.html,\n                },\n                description,\n                creditLine: `${photo.user.name} by Unsplash`,\n              },\n            }\n            return onSelect([asset])\n          }}\n        >\n          <RowsPhotoAlbum<ReturnType<typeof mapUnsplashToPhotoAlbumPhoto>>\n            photos={[]}\n            spacing={PHOTO_SPACING}\n            padding={PHOTO_PADDING}\n            targetRowHeight={(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }}\n            render={{\n              extras: (_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              },\n            }}\n            componentsProps={{container: {style: {marginBottom: PHOTO_SPACING}}}}\n          />\n        </InfiniteScroll>","<Activity mode={data.total === 0 ? 'hidden' : 'visible'}>\n        <InfiniteScroll\n          key={query}\n          scrollContainer={() => scrollContainerRef.current}\n          photos={data.results.map(mapUnsplashToPhotoAlbumPhoto)}\n          fetch={async (index) => {\n            const {results, total_pages} = await fetcher(query, index + 1)\n\n            if (index < total_pages) {\n              return results.map(mapUnsplashToPhotoAlbumPhoto)\n            }\n\n            return null\n          }}\n          loading={<Loader />}\n          finished={\n            query && (\n              <Box paddingX={2} paddingY={3}>\n                <Text size={1} muted>\n                  No more results\n                </Text>\n              </Box>\n            )\n          }\n          onClick={async ({photo: {data: photo}}) => {\n            const downloadUrl = await fetchDownloadUrl(client, photo)\n\n            const description = photo.description || undefined\n            const asset: AssetFromSource = {\n              kind: 'url',\n              value: downloadUrl,\n              // @ts-expect-error TODO: this is a partial assetDocumentProps, update types.\n              assetDocumentProps: {\n                _type: 'sanity.imageAsset',\n                source: {\n                  name: 'unsplash',\n                  id: photo.id,\n                  url: photo.links.html,\n                },\n                description,\n                creditLine: `${photo.user.name} by Unsplash`,\n              },\n            }\n            return onSelect([asset])\n          }}\n        >\n          <RowsPhotoAlbum<ReturnType<typeof mapUnsplashToPhotoAlbumPhoto>>\n            photos={[]}\n            spacing={PHOTO_SPACING}\n            padding={PHOTO_PADDING}\n            targetRowHeight={(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }}\n            render={{\n              extras: (_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              },\n            }}\n            componentsProps={{container: {style: {marginBottom: PHOTO_SPACING}}}}\n          />\n        </InfiniteScroll>\n      </Activity>","data.total === 0 ? 'hidden' : 'visible'","<>\n      <Activity mode={data.total === 0 ? 'visible' : 'hidden'}>\n        <Box paddingX={2} paddingY={3}>\n          <Text size={1} muted>\n            No results found for \"{query}\"\n          </Text>\n        </Box>\n      </Activity>\n      <Activity mode={data.total === 0 ? 'hidden' : 'visible'}>\n        <InfiniteScroll\n          key={query}\n          scrollContainer={() => scrollContainerRef.current}\n          photos={data.results.map(mapUnsplashToPhotoAlbumPhoto)}\n          fetch={async (index) => {\n            const {results, total_pages} = await fetcher(query, index + 1)\n\n            if (index < total_pages) {\n              return results.map(mapUnsplashToPhotoAlbumPhoto)\n            }\n\n            return null\n          }}\n          loading={<Loader />}\n          finished={\n            query && (\n              <Box paddingX={2} paddingY={3}>\n                <Text size={1} muted>\n                  No more results\n                </Text>\n              </Box>\n            )\n          }\n          onClick={async ({photo: {data: photo}}) => {\n            const downloadUrl = await fetchDownloadUrl(client, photo)\n\n            const description = photo.description || undefined\n            const asset: AssetFromSource = {\n              kind: 'url',\n              value: downloadUrl,\n              // @ts-expect-error TODO: this is a partial assetDocumentProps, update types.\n              assetDocumentProps: {\n                _type: 'sanity.imageAsset',\n                source: {\n                  name: 'unsplash',\n                  id: photo.id,\n                  url: photo.links.html,\n                },\n                description,\n                creditLine: `${photo.user.name} by Unsplash`,\n              },\n            }\n            return onSelect([asset])\n          }}\n        >\n          <RowsPhotoAlbum<ReturnType<typeof mapUnsplashToPhotoAlbumPhoto>>\n            photos={[]}\n            spacing={PHOTO_SPACING}\n            padding={PHOTO_PADDING}\n            targetRowHeight={(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }}\n            render={{\n              extras: (_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              },\n            }}\n            componentsProps={{container: {style: {marginBottom: PHOTO_SPACING}}}}\n          />\n        </InfiniteScroll>\n      </Activity>\n    </>","_c","_Fragment"],"sources":["../src/datastores/unsplash.ts","../src/components/UnsplashCreditLine.tsx","../src/components/UnsplashPhotoGallery.tsx"],"sourcesContent":["import type {SanityClient} from 'sanity'\n\nimport type {UnsplashPhoto} from '../types'\n\nexport async function fetchDownloadUrl(\n  client: SanityClient,\n  photo: UnsplashPhoto,\n): Promise<string> {\n  const downloadUrl = photo.links.download_location.replace(\n    'https://api.unsplash.com',\n    '/addons/unsplash',\n  )\n  const {url} = await client.request<{url: string}>({\n    url: downloadUrl,\n    withCredentials: true,\n    method: 'GET',\n  })\n\n  return url\n}\n","import {Text, Card} from '@sanity/ui'\nimport {getTheme_v2} from '@sanity/ui/theme'\nimport {styled} from 'styled-components'\n\nconst CreditLineLink = styled.a`\n  text-decoration: none;\n  cursor: pointer;\n  &:hover,\n  &:focus {\n    [data-ui='Text'] {\n      text-decoration: underline;\n    }\n  }\n`\n\nconst CreditLine = styled(Card)`\n  ${({theme}) => {\n    const v2 = getTheme_v2({sanity: theme.sanity})\n    return `\n     --creditline-fg: ${v2.color.fg};\n     --creditline-bg: ${v2.color.bg};\n   `\n  }};\n  -webkit-user-drag: none;\n  position: absolute;\n  background-color: var(--creditline-bg);\n  bottom: 0;\n\n  [data-ui='Text'] {\n    color: var(--creditline-fg);\n  }\n`\n\nconst UTM_SOURCE = 'sanity-plugin-asset-source-unsplash'\nexport function UnsplashCreditLine({\n  link,\n  id,\n  userName,\n}: {\n  link: string\n  id: string\n  userName: string\n}) {\n  const url = new URL(link)\n  url.searchParams.set('utm_source', UTM_SOURCE)\n  url.searchParams.set('utm_medium', 'referral')\n\n  return (\n    <CreditLineLink\n      href={url.toString()}\n      target={id}\n      rel=\"noreferrer noopener\"\n      onClick={(event) => event.stopPropagation()}\n    >\n      <CreditLine padding={1} radius={1} margin={1}>\n        <Text size={0} title={`Open image by ${userName} on Unsplash in new window`}>\n          By @{userName}\n        </Text>\n      </CreditLine>\n    </CreditLineLink>\n  )\n}\n","import {Box, Text} from '@sanity/ui'\nimport {use, Activity} from 'react'\n\nimport 'react-photo-album/rows.css'\nimport {RowsPhotoAlbum} from 'react-photo-album'\nimport InfiniteScroll from 'react-photo-album/scroll'\nimport {type AssetFromSource, type AssetSourceComponentProps, type SanityClient} from 'sanity'\n\nimport {fetchDownloadUrl} from '../datastores/unsplash'\nimport type {FetcherResult, UnsplashPhoto} from '../types'\nimport {Loader} from './Loader'\nimport {UnsplashCreditLine} from './UnsplashCreditLine'\n\nconst PHOTO_SPACING = 2\nconst PHOTO_PADDING = 1 // offset the 1px border width\n\nfunction mapUnsplashToPhotoAlbumPhoto(photo: UnsplashPhoto) {\n  return {\n    src: photo.urls.small,\n    width: photo.width,\n    height: photo.height,\n    key: photo.id,\n    data: photo,\n  }\n}\n\nexport default function UnsplashAssetSourceGallery({\n  client,\n  query,\n  fetcher,\n  scrollContainerRef,\n  onSelect,\n  initialDataPromise,\n}: {\n  client: SanityClient\n  query: string\n  fetcher: (query: string, index: number) => Promise<FetcherResult>\n  scrollContainerRef: React.RefObject<HTMLDivElement | null>\n  initialDataPromise: Promise<FetcherResult>\n} & Pick<AssetSourceComponentProps, 'onSelect'>) {\n  const data = use(initialDataPromise)\n\n  return (\n    <>\n      <Activity mode={data.total === 0 ? 'visible' : 'hidden'}>\n        <Box paddingX={2} paddingY={3}>\n          <Text size={1} muted>\n            No results found for \"{query}\"\n          </Text>\n        </Box>\n      </Activity>\n      <Activity mode={data.total === 0 ? 'hidden' : 'visible'}>\n        <InfiniteScroll\n          key={query}\n          scrollContainer={() => scrollContainerRef.current}\n          photos={data.results.map(mapUnsplashToPhotoAlbumPhoto)}\n          fetch={async (index) => {\n            const {results, total_pages} = await fetcher(query, index + 1)\n\n            if (index < total_pages) {\n              return results.map(mapUnsplashToPhotoAlbumPhoto)\n            }\n\n            return null\n          }}\n          loading={<Loader />}\n          finished={\n            query && (\n              <Box paddingX={2} paddingY={3}>\n                <Text size={1} muted>\n                  No more results\n                </Text>\n              </Box>\n            )\n          }\n          onClick={async ({photo: {data: photo}}) => {\n            const downloadUrl = await fetchDownloadUrl(client, photo)\n\n            const description = photo.description || undefined\n            const asset: AssetFromSource = {\n              kind: 'url',\n              value: downloadUrl,\n              // @ts-expect-error TODO: this is a partial assetDocumentProps, update types.\n              assetDocumentProps: {\n                _type: 'sanity.imageAsset',\n                source: {\n                  name: 'unsplash',\n                  id: photo.id,\n                  url: photo.links.html,\n                },\n                description,\n                creditLine: `${photo.user.name} by Unsplash`,\n              },\n            }\n            return onSelect([asset])\n          }}\n        >\n          <RowsPhotoAlbum<ReturnType<typeof mapUnsplashToPhotoAlbumPhoto>>\n            photos={[]}\n            spacing={PHOTO_SPACING}\n            padding={PHOTO_PADDING}\n            targetRowHeight={(width) => {\n              if (width < 300) return 150\n              if (width < 600) return 200\n              return 300\n            }}\n            render={{\n              extras: (_, context) => {\n                return (\n                  <UnsplashCreditLine\n                    id={context.photo.data.id}\n                    link={context.photo.data.links.html}\n                    userName={context.photo.data.user.username}\n                  />\n                )\n              },\n            }}\n            componentsProps={{container: {style: {marginBottom: PHOTO_SPACING}}}}\n          />\n        </InfiniteScroll>\n      </Activity>\n    </>\n  )\n}\n"],"mappings":"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"}
\ No newline at end of file