From aea82ff1bb6e066ed8b70433f4d72cd34bf0ccae Mon Sep 17 00:00:00 2001
From: Chenwei Zhang <40295569+zchenwei@users.noreply.github.com>
Date: Wed, 19 Jul 2023 12:00:29 -0700
Subject: [PATCH] chore(ui-react-storage): add docs and e2e tests for
StorageImage (#4262)
* test(react-storage): add e2e tests for StorageImage (#4253)
* docs: add docs for StorageImage (#4259)
* Create stale-dancers-flash.md
* test: update sitemap snapshot
---
.changeset/stale-dancers-flash.md | 14 ++++
docs/src/data/links.tsx | 7 ++
.../examples/DefaultStorageImageExample.tsx | 5 ++
.../StorageImageErrorHandlingExample.tsx | 13 ++++
.../storage/storageimage/examples/index.ts | 2 +
.../storage/storageimage/index.page.mdx | 21 ++++++
.../storage/storageimage/props.ts | 35 ++++++++++
.../storage/storageimage/react.mdx | 67 +++++++++++++++++++
docs/tests/__snapshots__/sitemap.test.ts.snap | 1 +
.../private-access-level/aws-exports.js | 2 +
.../private-access-level/index.page.tsx | 42 ++++++++++++
.../protected-access-level/aws-exports.js | 2 +
.../protected-access-level/index.page.tsx | 42 ++++++++++++
.../public-access-level/aws-exports.js | 2 +
.../public-access-level/index.page.tsx | 34 ++++++++++
.../load-private-image-from-s3.feature | 16 +++++
.../load-protected-image-from-s3.feature | 16 +++++
.../load-public-image-from-s3.feature | 10 +++
.../components/StorageImage/StorageImage.tsx | 20 ++----
.../src/components/StorageImage/types.ts | 1 +
.../src/hooks/__tests__/useStorageURL.test.ts | 41 +++++++-----
packages/react/src/hooks/useStorageURL.ts | 18 ++---
.../react/src/primitives/shared/constants.ts | 1 +
23 files changed, 373 insertions(+), 39 deletions(-)
create mode 100644 .changeset/stale-dancers-flash.md
create mode 100644 docs/src/pages/[platform]/connected-components/storage/storageimage/examples/DefaultStorageImageExample.tsx
create mode 100644 docs/src/pages/[platform]/connected-components/storage/storageimage/examples/StorageImageErrorHandlingExample.tsx
create mode 100644 docs/src/pages/[platform]/connected-components/storage/storageimage/examples/index.ts
create mode 100644 docs/src/pages/[platform]/connected-components/storage/storageimage/index.page.mdx
create mode 100644 docs/src/pages/[platform]/connected-components/storage/storageimage/props.ts
create mode 100644 docs/src/pages/[platform]/connected-components/storage/storageimage/react.mdx
create mode 100644 examples/next/pages/ui/components/storage/storage-image/private-access-level/aws-exports.js
create mode 100644 examples/next/pages/ui/components/storage/storage-image/private-access-level/index.page.tsx
create mode 100644 examples/next/pages/ui/components/storage/storage-image/protected-access-level/aws-exports.js
create mode 100644 examples/next/pages/ui/components/storage/storage-image/protected-access-level/index.page.tsx
create mode 100644 examples/next/pages/ui/components/storage/storage-image/public-access-level/aws-exports.js
create mode 100644 examples/next/pages/ui/components/storage/storage-image/public-access-level/index.page.tsx
create mode 100644 packages/e2e/features/ui/components/storage/storage-image/load-private-image-from-s3.feature
create mode 100644 packages/e2e/features/ui/components/storage/storage-image/load-protected-image-from-s3.feature
create mode 100644 packages/e2e/features/ui/components/storage/storage-image/load-public-image-from-s3.feature
diff --git a/.changeset/stale-dancers-flash.md b/.changeset/stale-dancers-flash.md
new file mode 100644
index 00000000000..33cf03c73f7
--- /dev/null
+++ b/.changeset/stale-dancers-flash.md
@@ -0,0 +1,14 @@
+---
+"@aws-amplify/ui-react-storage": minor
+"@aws-amplify/ui-react": patch
+"@aws-amplify/ui": patch
+---
+
+feat(ui-react-storage): Add a new connected component `StorageImage`. It allows you load the images managed by Amplify Storage.
+
+*Example:*
+```jsx
+import { StorageImage } from '@aws-amplify/ui-react-storage';
+
+
+```
diff --git a/docs/src/data/links.tsx b/docs/src/data/links.tsx
index 61c2c64a271..21dc45efb8d 100644
--- a/docs/src/data/links.tsx
+++ b/docs/src/data/links.tsx
@@ -199,6 +199,13 @@ export const connectedComponents: ComponentNavItem[] = [
body: "Amplify UI Storage components allow you to store files in the cloud using Amplify's Storage category",
platforms: ['react'],
},
+ {
+ href: '/connected-components/storage/storageimage',
+ label: 'Storage Image',
+ body: 'StorageImage component allows users to load an image managed by Amplify Storage.',
+ platforms: ['react'],
+ tertiary: true,
+ },
{
href: '/connected-components/storage/storagemanager',
label: 'Storage Manager',
diff --git a/docs/src/pages/[platform]/connected-components/storage/storageimage/examples/DefaultStorageImageExample.tsx b/docs/src/pages/[platform]/connected-components/storage/storageimage/examples/DefaultStorageImageExample.tsx
new file mode 100644
index 00000000000..9189dfaa338
--- /dev/null
+++ b/docs/src/pages/[platform]/connected-components/storage/storageimage/examples/DefaultStorageImageExample.tsx
@@ -0,0 +1,5 @@
+import { StorageImage } from '@aws-amplify/ui-react-storage';
+
+export const DefaultStorageImageExample = () => {
+ return ;
+};
diff --git a/docs/src/pages/[platform]/connected-components/storage/storageimage/examples/StorageImageErrorHandlingExample.tsx b/docs/src/pages/[platform]/connected-components/storage/storageimage/examples/StorageImageErrorHandlingExample.tsx
new file mode 100644
index 00000000000..e18c95d8a05
--- /dev/null
+++ b/docs/src/pages/[platform]/connected-components/storage/storageimage/examples/StorageImageErrorHandlingExample.tsx
@@ -0,0 +1,13 @@
+import { StorageImage } from '@aws-amplify/ui-react-storage';
+
+export const StorageImageErrorHandlingExample = () => {
+ return (
+ console.error(error)}
+ />
+ );
+};
diff --git a/docs/src/pages/[platform]/connected-components/storage/storageimage/examples/index.ts b/docs/src/pages/[platform]/connected-components/storage/storageimage/examples/index.ts
new file mode 100644
index 00000000000..80c9129aadf
--- /dev/null
+++ b/docs/src/pages/[platform]/connected-components/storage/storageimage/examples/index.ts
@@ -0,0 +1,2 @@
+export { DefaultStorageImageExample } from './DefaultStorageImageExample';
+export { StorageImageErrorHandlingExample } from './StorageImageErrorHandlingExample';
diff --git a/docs/src/pages/[platform]/connected-components/storage/storageimage/index.page.mdx b/docs/src/pages/[platform]/connected-components/storage/storageimage/index.page.mdx
new file mode 100644
index 00000000000..f488969506f
--- /dev/null
+++ b/docs/src/pages/[platform]/connected-components/storage/storageimage/index.page.mdx
@@ -0,0 +1,21 @@
+---
+title: Storage Image
+description: The Storage Image lets you load images from Amplify Storage.
+reactSource: packages/react-storage/src/components/StorageImage/StorageImage.tsx
+supportedFrameworks: react
+---
+
+import { Fragment } from '@/components/Fragment';
+import { getCustomStaticPath } from "@/utils/getCustomStaticPath";
+
+export async function getStaticPaths() {
+ return getCustomStaticPath(frontmatter.supportedFrameworks);
+}
+
+{/* `getStaticProps` is required to prevent "Error: getStaticPaths was added without a getStaticProps. Without getStaticProps, getStaticPaths does nothing" */}
+
+export async function getStaticProps() {
+ return { props: {} }
+}
+
+{({ platform }) => import(`./${platform}.mdx`)}
diff --git a/docs/src/pages/[platform]/connected-components/storage/storageimage/props.ts b/docs/src/pages/[platform]/connected-components/storage/storageimage/props.ts
new file mode 100644
index 00000000000..cb76578e761
--- /dev/null
+++ b/docs/src/pages/[platform]/connected-components/storage/storageimage/props.ts
@@ -0,0 +1,35 @@
+export const STORAGE_IMAGE = [
+ {
+ name: 'alt',
+ description: 'Alternative text description of the image',
+ type: 'string',
+ },
+ {
+ name: 'imgKey',
+ description: 'The key of an image.',
+ type: 'string',
+ },
+ {
+ name: 'accessLevel',
+ description:
+ 'Access level for files in Storage. See https://docs.amplify.aws/lib/storage/configureaccess/q/platform/js/',
+ type: `'public' | 'private' | 'protected'`,
+ },
+ {
+ name: 'identityId?',
+ description:
+ 'The unique Amazon Cognito Identity ID of the image owner. Required when loading a protected image.',
+ type: 'string',
+ },
+ {
+ name: 'fallbackSrc?',
+ description:
+ 'A fallback image source to be loaded when the component fails to load the image from Storage',
+ type: 'string',
+ },
+ {
+ name: 'onStorageGetError?',
+ description: 'Triggered when an error happens calling Storage.get',
+ type: `(error: Error) => void;`,
+ },
+];
diff --git a/docs/src/pages/[platform]/connected-components/storage/storageimage/react.mdx b/docs/src/pages/[platform]/connected-components/storage/storageimage/react.mdx
new file mode 100644
index 00000000000..19dfae813a9
--- /dev/null
+++ b/docs/src/pages/[platform]/connected-components/storage/storageimage/react.mdx
@@ -0,0 +1,67 @@
+import { Alert, Image } from '@aws-amplify/ui-react';
+
+import { ComponentStyleDisplay } from '@/components/ComponentStyleDisplay';
+import { Example, ExampleCode } from '@/components/Example';
+import { Fragment } from '@/components/Fragment';
+import { AppDirectoryAlert } from '@/components/AppDirectoryAlert';
+import { InstallScripts } from '@/components/InstallScripts';
+import ReactPropsTable from '@/components/propsTable/ReactPropsTable';
+import { STORAGE_IMAGE } from './props';
+import {
+ DefaultStorageImageExample,
+ StorageImageErrorHandlingExample
+} from './examples'
+
+## Basic Usage
+
+
+ Did you follow the [quick start instructions](/connected-components/storage#quick-start) to set up the storage and auth services?
+
+
+
+ {({ platform }) => import('@/components/AppDirectoryAlert')}
+
+
+To use the StorageImage component, import it into your React application with the included styles.
+
+
+
+
+```js
+import { StorageImage } from '@aws-amplify/ui-react-storage';
+import '@aws-amplify/ui-react/styles.css';
+```
+
+
+At a minimum you must include the `alt`, `imgKey` and `accessLevel` props. `accessLevel` refers to the [Amplify Storage access level](https://docs.amplify.aws/lib/storage/configureaccess/q/platform/js/), which is `'public' | 'private' | 'protected'`.
+
+
+
+
+ ```jsx file=./examples/DefaultStorageImageExample.tsx
+ ```
+
+
+
+## Props
+
+
+
+Note: A new `Storage.get` request is made only when the `imgKey` changes.
+
+## Error Handling
+
+To handle the error caused by `Storage.get`, you can pass a `onStorageGetError` handler and optionally provide a `fallbackSrc` for the component to load a fallback image.
+
+
+
+
+ ```jsx file=./examples/StorageImageErrorHandlingExample.tsx
+ ```
+
+
+
+## Customization
+
+### Target Classes
+
diff --git a/docs/tests/__snapshots__/sitemap.test.ts.snap b/docs/tests/__snapshots__/sitemap.test.ts.snap
index 64df423f69f..a2f2d27d920 100644
--- a/docs/tests/__snapshots__/sitemap.test.ts.snap
+++ b/docs/tests/__snapshots__/sitemap.test.ts.snap
@@ -104,6 +104,7 @@ exports[`Sitemap Snapshot 1`] = `
/react/connected-components/liveness/troubleshooting,
/react/connected-components/storage,
/react/connected-components/storage/fileuploader,
+/react/connected-components/storage/storageimage,
/react/connected-components/storage/storagemanager,
/react/getting-started/accessibility,
/react/getting-started/figma,
diff --git a/examples/next/pages/ui/components/storage/storage-image/private-access-level/aws-exports.js b/examples/next/pages/ui/components/storage/storage-image/private-access-level/aws-exports.js
new file mode 100644
index 00000000000..4245c81a219
--- /dev/null
+++ b/examples/next/pages/ui/components/storage/storage-image/private-access-level/aws-exports.js
@@ -0,0 +1,2 @@
+import awsExports from '@environments/storage/file-uploader/src/aws-exports';
+export default awsExports;
diff --git a/examples/next/pages/ui/components/storage/storage-image/private-access-level/index.page.tsx b/examples/next/pages/ui/components/storage/storage-image/private-access-level/index.page.tsx
new file mode 100644
index 00000000000..c4945fbfd64
--- /dev/null
+++ b/examples/next/pages/ui/components/storage/storage-image/private-access-level/index.page.tsx
@@ -0,0 +1,42 @@
+import * as React from 'react';
+
+import { Amplify } from 'aws-amplify';
+import {
+ Button,
+ Text,
+ Loader,
+ useAuthenticator,
+ withAuthenticator,
+} from '@aws-amplify/ui-react';
+import { StorageImage } from '@aws-amplify/ui-react-storage';
+import '@aws-amplify/ui-react/styles.css';
+import awsExports from './aws-exports';
+
+Amplify.configure(awsExports);
+
+export function StorageImageExample() {
+ const [isLoaded, setIsLoaded] = React.useState(false);
+ const { signOut } = useAuthenticator((context) => [context.signOut]);
+
+ const onLoad = () => {
+ setIsLoaded(true);
+ };
+
+ return (
+ <>
+
+ {isLoaded ? (
+ The private image is loaded.
+ ) : (
+
+ )}
+
+ >
+ );
+}
+export default withAuthenticator(StorageImageExample);
diff --git a/examples/next/pages/ui/components/storage/storage-image/protected-access-level/aws-exports.js b/examples/next/pages/ui/components/storage/storage-image/protected-access-level/aws-exports.js
new file mode 100644
index 00000000000..4245c81a219
--- /dev/null
+++ b/examples/next/pages/ui/components/storage/storage-image/protected-access-level/aws-exports.js
@@ -0,0 +1,2 @@
+import awsExports from '@environments/storage/file-uploader/src/aws-exports';
+export default awsExports;
diff --git a/examples/next/pages/ui/components/storage/storage-image/protected-access-level/index.page.tsx b/examples/next/pages/ui/components/storage/storage-image/protected-access-level/index.page.tsx
new file mode 100644
index 00000000000..36f7d68fd10
--- /dev/null
+++ b/examples/next/pages/ui/components/storage/storage-image/protected-access-level/index.page.tsx
@@ -0,0 +1,42 @@
+import * as React from 'react';
+
+import { Amplify } from 'aws-amplify';
+import {
+ Button,
+ Text,
+ Loader,
+ useAuthenticator,
+ withAuthenticator,
+} from '@aws-amplify/ui-react';
+import { StorageImage } from '@aws-amplify/ui-react-storage';
+import '@aws-amplify/ui-react/styles.css';
+import awsExports from './aws-exports';
+
+Amplify.configure(awsExports);
+
+export function StorageImageExample() {
+ const [isLoaded, setIsLoaded] = React.useState(false);
+ const { signOut } = useAuthenticator((context) => [context.signOut]);
+
+ const onLoad = () => {
+ setIsLoaded(true);
+ };
+
+ return (
+ <>
+
+ {isLoaded ? (
+ The protected image is loaded.
+ ) : (
+
+ )}
+
+ >
+ );
+}
+export default withAuthenticator(StorageImageExample);
diff --git a/examples/next/pages/ui/components/storage/storage-image/public-access-level/aws-exports.js b/examples/next/pages/ui/components/storage/storage-image/public-access-level/aws-exports.js
new file mode 100644
index 00000000000..4245c81a219
--- /dev/null
+++ b/examples/next/pages/ui/components/storage/storage-image/public-access-level/aws-exports.js
@@ -0,0 +1,2 @@
+import awsExports from '@environments/storage/file-uploader/src/aws-exports';
+export default awsExports;
diff --git a/examples/next/pages/ui/components/storage/storage-image/public-access-level/index.page.tsx b/examples/next/pages/ui/components/storage/storage-image/public-access-level/index.page.tsx
new file mode 100644
index 00000000000..663cd1c9d40
--- /dev/null
+++ b/examples/next/pages/ui/components/storage/storage-image/public-access-level/index.page.tsx
@@ -0,0 +1,34 @@
+import * as React from 'react';
+
+import { Amplify } from 'aws-amplify';
+import { Text, Loader } from '@aws-amplify/ui-react';
+import { StorageImage } from '@aws-amplify/ui-react-storage';
+import '@aws-amplify/ui-react/styles.css';
+import awsExports from './aws-exports';
+
+Amplify.configure(awsExports);
+
+export function StorageImageExample() {
+ const [isLoaded, setIsLoaded] = React.useState(false);
+
+ const onLoad = () => {
+ setIsLoaded(true);
+ };
+
+ return (
+ <>
+
+ {isLoaded ? (
+ The public image is loaded.
+ ) : (
+
+ )}
+ >
+ );
+}
+export default StorageImageExample;
diff --git a/packages/e2e/features/ui/components/storage/storage-image/load-private-image-from-s3.feature b/packages/e2e/features/ui/components/storage/storage-image/load-private-image-from-s3.feature
new file mode 100644
index 00000000000..5cce682daac
--- /dev/null
+++ b/packages/e2e/features/ui/components/storage/storage-image/load-private-image-from-s3.feature
@@ -0,0 +1,16 @@
+Feature: Load an image from S3 with private access level settings
+
+ Background:
+ Given I'm running the example "ui/components/storage/storage-image/private-access-level"
+
+ @react
+ Scenario: I successfully load a private image
+ When I type my "email" with status "CONFIRMED"
+ And I type my password
+ And I click the "Sign in" button
+ Then I see "Loader" element
+ Then I see the "private cat" image
+ Then I see "The private image is loaded."
+ Then I see "Sign out"
+ Then I click "Sign out"
+ Then I see "Sign in"
diff --git a/packages/e2e/features/ui/components/storage/storage-image/load-protected-image-from-s3.feature b/packages/e2e/features/ui/components/storage/storage-image/load-protected-image-from-s3.feature
new file mode 100644
index 00000000000..7cc5127cc16
--- /dev/null
+++ b/packages/e2e/features/ui/components/storage/storage-image/load-protected-image-from-s3.feature
@@ -0,0 +1,16 @@
+Feature: Load an image from S3 with protected access level settings
+
+ Background:
+ Given I'm running the example "ui/components/storage/storage-image/protected-access-level"
+
+ @react
+ Scenario: I successfully load a protected image
+ When I type my "email" with status "CONFIRMED"
+ And I type my password
+ And I click the "Sign in" button
+ Then I see "Loader" element
+ Then I see the "protected cat" image
+ Then I see "The protected image is loaded."
+ Then I see "Sign out"
+ Then I click "Sign out"
+ Then I see "Sign in"
diff --git a/packages/e2e/features/ui/components/storage/storage-image/load-public-image-from-s3.feature b/packages/e2e/features/ui/components/storage/storage-image/load-public-image-from-s3.feature
new file mode 100644
index 00000000000..f1195d691ab
--- /dev/null
+++ b/packages/e2e/features/ui/components/storage/storage-image/load-public-image-from-s3.feature
@@ -0,0 +1,10 @@
+Feature: Load an image from S3 with public access level settings
+
+ Background:
+ Given I'm running the example "ui/components/storage/storage-image/public-access-level"
+
+ @react
+ Scenario: I successfully load a public image
+ Then I see "Loader" element
+ Then I see the "public cat" image
+ Then I see "The public image is loaded."
diff --git a/packages/react-storage/src/components/StorageImage/StorageImage.tsx b/packages/react-storage/src/components/StorageImage/StorageImage.tsx
index 9cea6daabd6..07d6242e03a 100644
--- a/packages/react-storage/src/components/StorageImage/StorageImage.tsx
+++ b/packages/react-storage/src/components/StorageImage/StorageImage.tsx
@@ -16,22 +16,16 @@ export const StorageImage = ({
...rest
}: StorageImageProps): JSX.Element => {
const options = React.useMemo(
- () => ({
- accessLevel,
- identityId,
- }),
+ () => ({ level: accessLevel, identityId }),
[accessLevel, identityId]
);
- const errorConfig = React.useMemo(
- () => ({
- fallbackURL: fallbackSrc,
- onStorageGetError,
- }),
- [fallbackSrc, onStorageGetError]
- );
-
- const url = useStorageURL(imgKey, options, errorConfig);
+ const url = useStorageURL({
+ key: imgKey,
+ options,
+ fallbackURL: fallbackSrc,
+ onStorageGetError,
+ });
return (
{
// Use imgKey instead of key because key is a reserved keyword
// and cannot be accessed via props in React components
+ // Note: a new Storage.get request is made only when the imgKey gets updated after the initial
imgKey: string;
accessLevel: StorageAccessLevel;
identityId?: string;
diff --git a/packages/react/src/hooks/__tests__/useStorageURL.test.ts b/packages/react/src/hooks/__tests__/useStorageURL.test.ts
index 2cb2af00f37..a2d622436f2 100644
--- a/packages/react/src/hooks/__tests__/useStorageURL.test.ts
+++ b/packages/react/src/hooks/__tests__/useStorageURL.test.ts
@@ -7,30 +7,35 @@ jest.mock('@aws-amplify/storage');
describe('useStorageURL', () => {
afterEach(() => jest.clearAllMocks());
- const storageKey = 'file.jpg';
- const storageOptions: S3ProviderGetConfig = { level: 'public' };
- const storageUrl = 'https://amplify.s3.amazonaws.com/path/to/the/file.jpg';
- const errorConfig = {
- fallbackURL: 'https://amplify.s3.amazonaws.com/path/to/the/fallback.jpg',
- onStorageGetError: jest.fn(),
+ const key = 'file.jpg';
+ const options: S3ProviderGetConfig = { level: 'public' };
+ const url = 'https://amplify.s3.amazonaws.com/path/to/the/file.jpg';
+ const fallbackURL =
+ 'https://amplify.s3.amazonaws.com/path/to/the/fallback.jpg';
+ const onStorageGetError = jest.fn();
+ const useStorageURLParams = {
+ key,
+ options,
+ fallbackURL,
+ onStorageGetError,
};
it('should return a Storage URL', async () => {
- (Storage.get as jest.Mock).mockResolvedValue(storageUrl);
+ (Storage.get as jest.Mock).mockResolvedValue(url);
const { result, waitForNextUpdate } = renderHook(() =>
- useStorageURL(storageKey, storageOptions)
+ useStorageURL(useStorageURLParams)
);
// should return undefined at initialization
expect(result.current).toBeUndefined();
- expect(Storage.get).toHaveBeenCalledWith(storageKey, storageOptions);
+ expect(Storage.get).toHaveBeenCalledWith(key, options);
// Next update will happen when Storage.get resolves
await waitForNextUpdate();
- expect(result.current).toBe(storageUrl);
+ expect(result.current).toBe(url);
expect(Storage.get).toHaveBeenCalledTimes(1);
});
@@ -40,27 +45,27 @@ describe('useStorageURL', () => {
(Storage.get as jest.Mock).mockRejectedValue(customError);
const { result, waitForNextUpdate } = renderHook(() =>
- useStorageURL(storageKey, storageOptions, errorConfig)
+ useStorageURL(useStorageURLParams)
);
- expect(Storage.get).toHaveBeenCalledWith(storageKey, storageOptions);
+ expect(Storage.get).toHaveBeenCalledWith(key, options);
// Next update will happen when Storage.get resolves
await waitForNextUpdate();
- expect(result.current).toBe(errorConfig.fallbackURL);
- expect(errorConfig.onStorageGetError).toHaveBeenCalledTimes(1);
- expect(errorConfig.onStorageGetError).toHaveBeenCalledWith(customError);
+ expect(result.current).toBe(fallbackURL);
+ expect(onStorageGetError).toHaveBeenCalledTimes(1);
+ expect(onStorageGetError).toHaveBeenCalledWith(customError);
});
it('should execute Storage.cancel before rerendering', async () => {
- (Storage.get as jest.Mock).mockResolvedValue(storageUrl);
+ (Storage.get as jest.Mock).mockResolvedValue(url);
const { waitForNextUpdate } = renderHook(() =>
- useStorageURL(storageKey, storageOptions)
+ useStorageURL(useStorageURLParams)
);
- expect(Storage.get).toHaveBeenCalledWith(storageKey, storageOptions);
+ expect(Storage.get).toHaveBeenCalledWith(key, options);
// Next update will happen when Storage.get resolves
await waitForNextUpdate();
diff --git a/packages/react/src/hooks/useStorageURL.ts b/packages/react/src/hooks/useStorageURL.ts
index e8b2cbade12..24532a62e49 100644
--- a/packages/react/src/hooks/useStorageURL.ts
+++ b/packages/react/src/hooks/useStorageURL.ts
@@ -4,7 +4,9 @@ import { isFunction } from '@aws-amplify/ui';
import { useHasValueUpdated } from '@aws-amplify/ui-react-core';
import { S3ProviderGetConfig, Storage } from '@aws-amplify/storage';
-interface UseStorageURLErrorConfig {
+interface UseStorageURLParams {
+ key: string;
+ options?: S3ProviderGetConfig;
fallbackURL?: string;
onStorageGetError?: (error: Error) => void;
}
@@ -13,11 +15,12 @@ interface UseStorageURLErrorConfig {
* Computes a public URL for an Amplify Storage file
* @internal
*/
-export const useStorageURL = (
- key: string,
- options?: S3ProviderGetConfig,
- errorConfig?: UseStorageURLErrorConfig
-): string | undefined => {
+export const useStorageURL = ({
+ key,
+ options,
+ fallbackURL,
+ onStorageGetError,
+}: UseStorageURLParams): string | undefined => {
const [url, setURL] = React.useState();
const hasKeyUpdated = useHasValueUpdated(key);
@@ -29,7 +32,6 @@ export const useStorageURL = (
const promise = Storage.get(key, options)
.then((url) => setURL(url))
.catch((error: Error) => {
- const { fallbackURL, onStorageGetError } = errorConfig ?? {};
if (isFunction(onStorageGetError)) {
onStorageGetError(error);
}
@@ -40,7 +42,7 @@ export const useStorageURL = (
// Cancel current promise on unmount
return () => Storage.cancel(promise);
- }, [key, options, errorConfig, hasKeyUpdated]);
+ }, [key, options, fallbackURL, onStorageGetError, hasKeyUpdated]);
return url;
};
diff --git a/packages/react/src/primitives/shared/constants.ts b/packages/react/src/primitives/shared/constants.ts
index 535ab61287b..6c8e827df33 100644
--- a/packages/react/src/primitives/shared/constants.ts
+++ b/packages/react/src/primitives/shared/constants.ts
@@ -551,6 +551,7 @@ export const ComponentClassObject: ComponentClassNameItems = {
StorageImage: {
className: ComponentClassName.StorageImage,
components: ['StorageImage'],
+ description: 'Class applied to the img tag',
},
StorageManager: {
className: ComponentClassName.StorageManager,