diff --git a/src/__private_stories__/sheet-presets-story.tsx b/src/__private_stories__/sheet-presets-story.tsx index 1aa0eaab0..f72e671c9 100644 --- a/src/__private_stories__/sheet-presets-story.tsx +++ b/src/__private_stories__/sheet-presets-story.tsx @@ -215,6 +215,7 @@ ActionsList.argTypes = { type InfoSheetArgs = SheetArgs & { numItems: number; + buttonText: string; iconType: 'bullet' | 'regular' | 'small'; }; @@ -222,6 +223,7 @@ export const Info: StoryComponent = ({ title, subtitle, description, + buttonText, multiparagraphDescription, numItems, iconType, @@ -246,6 +248,7 @@ export const Info: StoryComponent = ({ onClose={() => { setOpen(false); }} + button={buttonText ? {text: buttonText} : undefined} title={title} subtitle={subtitle} description={ @@ -276,6 +279,7 @@ Info.storyName = 'InfoSheet'; Info.args = { title: 'Title', subtitle: 'Subtitle', + buttonText: '', description: 'Description', numItems: 5, iconType: 'bullet', diff --git a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-in-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-in-desktop-1-snap.png index 3c8a46a9e..567a9546a 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-in-desktop-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-in-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-in-mobile-ios-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-in-mobile-ios-1-snap.png index cda7ca937..83c2cf678 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-in-mobile-ios-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-in-mobile-ios-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-with-dismiss-button-in-desktop-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-with-dismiss-button-in-desktop-1-snap.png new file mode 100644 index 000000000..e73641e6c Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-with-dismiss-button-in-desktop-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-with-dismiss-button-in-mobile-ios-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-with-dismiss-button-in-mobile-ios-1-snap.png new file mode 100644 index 000000000..5796b63ec Binary files /dev/null and b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-with-dismiss-button-in-mobile-ios-1-snap.png differ diff --git a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-with-multiple-description-paragraphs-1-snap.png b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-with-multiple-description-paragraphs-1-snap.png index 12abfebf6..484a04a6a 100644 Binary files a/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-with-multiple-description-paragraphs-1-snap.png and b/src/__screenshot_tests__/__image_snapshots__/sheet-screenshot-test-tsx-info-sheet-with-multiple-description-paragraphs-1-snap.png differ diff --git a/src/__screenshot_tests__/sheet-screenshot-test.tsx b/src/__screenshot_tests__/sheet-screenshot-test.tsx index 447a20f85..e06711c4d 100644 --- a/src/__screenshot_tests__/sheet-screenshot-test.tsx +++ b/src/__screenshot_tests__/sheet-screenshot-test.tsx @@ -87,6 +87,23 @@ test('InfoSheet with multiple description paragraphs', async () => { expect(image).toMatchImageSnapshot(); }); +test.each(TESTABLE_DEVICES)('InfoSheet with dismiss button in %s', async (device) => { + const page = await openStoryPage({ + id: 'private-sheet-presets--info', + device, + args: {buttonText: 'Dismiss'}, + }); + + const button = await screen.findByRole('button', {name: 'Open'}); + await button.click(); + + await screen.findByRole('dialog'); + + const image = await page.screenshot(); + + expect(image).toMatchImageSnapshot(); +}); + test.each(TESTABLE_DEVICES_WITH_LARGE_DESKTOP)('ActionsSheet in %s', async (device) => { const page = await openStoryPage({ id: 'private-sheet-presets--actions', diff --git a/src/__stories__/sheet-story.tsx b/src/__stories__/sheet-story.tsx index c7be17190..1f64727b9 100644 --- a/src/__stories__/sheet-story.tsx +++ b/src/__stories__/sheet-story.tsx @@ -129,6 +129,7 @@ export const ShowSheet: StoryComponent = ({ }, }, ], + button: {text: 'Dismiss'}, }, }).then((response) => { setOpenDialogType(undefined); diff --git a/src/__tests__/sheet-test.tsx b/src/__tests__/sheet-test.tsx index 123edc5de..21ead7375 100644 --- a/src/__tests__/sheet-test.tsx +++ b/src/__tests__/sheet-test.tsx @@ -299,7 +299,7 @@ test('showSheet INFO', async () => { {timeout: 5000} ); - expect(resultSpy).toHaveBeenCalledWith(undefined); + expect(resultSpy).toHaveBeenCalledWith({action: 'DISMISS'}); }, 30000); test('showSheet ACTIONS_LIST', async () => { @@ -593,7 +593,7 @@ test('showSheet fails if there is already a sheet open', async () => { test('showSheet with native implementation INFO', async () => { const resultSpy = jest.fn(); - const nativeImplementation = jest.fn(); + const nativeImplementation = jest.fn(() => Promise.resolve({action: 'DISMISS' as const, result: []})); render( diff --git a/src/sheet-info.css.ts b/src/sheet-info.css.ts index 1a78b8229..54d4bd05f 100644 --- a/src/sheet-info.css.ts +++ b/src/sheet-info.css.ts @@ -5,3 +5,15 @@ export const infoItemIcon = sprinkles({ alignItems: 'center', height: 24, }); + +export const infoItemIconContainer = sprinkles({ + height: '100%', + display: 'flex', +}); + +export const itemContainer = sprinkles({ + display: 'flex', + alignItems: 'center', + minHeight: 72, + paddingY: 16, +}); diff --git a/src/sheet-info.tsx b/src/sheet-info.tsx index c5199e8c3..c0e2afba2 100644 --- a/src/sheet-info.tsx +++ b/src/sheet-info.tsx @@ -10,6 +10,8 @@ import {Text3, Text2} from './text'; import {vars as skinVars} from './skins/skin-contract.css'; import * as styles from './sheet-info.css'; import Image from './image'; +import {ButtonPrimary} from './button'; +import Divider from './divider'; import type {ExclusifyUnion} from './utils/utility-types'; import type {DataAttributes, IconProps} from './utils/types'; @@ -38,10 +40,13 @@ type InfoSheetProps = { }>; onClose?: () => void; dataAttributes?: DataAttributes; + button?: { + text: string; + }; }; const InfoSheet = React.forwardRef( - ({title, subtitle, description, items, onClose, dataAttributes}, ref) => { + ({title, subtitle, description, items, onClose, button, dataAttributes}, ref) => { const {isDarkMode} = useTheme(); return ( ( ref={ref} dataAttributes={{'component-name': 'InfoSheet', ...dataAttributes}} > - {({modalTitleId}) => ( + {({closeModal, modalTitleId}) => ( {button.text} + ) : undefined + } > - - - {items.map((item, idx) => ( - -
- {item.icon.type === 'bullet' ? ( - - ) : item.icon.Icon ? ( - - ) : ( - - )} -
- - {item.title} - {item.description && ( - - {item.description} - - )} - -
- ))} -
+ + {items.map((item, idx) => ( + +
+ +
+
+ {item.icon.type === 'bullet' ? ( + + ) : item.icon.Icon ? ( + + ) : ( + + )} +
+
+ + {item.title} + {item.description && ( + + {item.description} + + )} + +
+
+ {idx < items.length - 1 && } +
+ ))}
)} diff --git a/src/sheet-native.tsx b/src/sheet-native.tsx index d587d903b..76690db81 100644 --- a/src/sheet-native.tsx +++ b/src/sheet-native.tsx @@ -88,25 +88,36 @@ const showActionsListNativeSheet = ( const showInfoNativeSheet = async ( nativeSheetImplementation: NativeSheetImplementation, - {title, subtitle, description, items}: SheetPropsByType['INFO'] + {title, subtitle, description, items, button}: SheetPropsByType['INFO'] ): Promise => { - // nothing to return, this is an informative sheet - await (nativeSheetImplementation as NativeSheetImplementation)({ + const infoSheetContent = { + type: 'LIST' as const, + id: 'list-0', + listType: 'INFORMATIVE' as const, + autoSubmit: false, + selectedIds: [], + items, + }; + + return await (nativeSheetImplementation as NativeSheetImplementation)({ title, subtitle, // TODO: add multiline support to native sheet description: normalizeDescriptionForNative(description), - content: [ - { - type: 'LIST', - id: 'list-0', - listType: 'INFORMATIVE', - autoSubmit: false, - selectedIds: [], - items, - }, - ], - }); + content: button + ? [ + infoSheetContent, + { + type: 'BOTTOM_ACTIONS', + id: 'bottom-actions-0', + button, + }, + ] + : [infoSheetContent], + }).then(() => ({ + // this is an informative sheet, it can only be dismissed + action: 'DISMISS', + })); }; const showActionsNativeSheet = ( diff --git a/src/sheet-types.tsx b/src/sheet-types.tsx index a03f3c070..dda289205 100644 --- a/src/sheet-types.tsx +++ b/src/sheet-types.tsx @@ -51,6 +51,9 @@ export type SheetPropsByType = { description?: string; icon: InfoIcon; }>; + button?: { + text: string; + }; }>; ACTIONS: SheetProps<{ button: { @@ -71,7 +74,7 @@ export type SheetType = keyof SheetPropsByType; export type SheetResultByType = { RADIO_LIST: {action: 'SUBMIT'; selectedId: string} | {action: 'DISMISS'}; ACTIONS_LIST: {action: 'SUBMIT'; selectedId: string} | {action: 'DISMISS'}; - INFO: void; + INFO: {action: 'DISMISS'}; ACTIONS: {action: 'PRIMARY' | 'SECONDARY' | 'LINK' | 'DISMISS'}; }; diff --git a/src/sheet-web.tsx b/src/sheet-web.tsx index 2370ffe15..edeacf564 100644 --- a/src/sheet-web.tsx +++ b/src/sheet-web.tsx @@ -55,7 +55,7 @@ const SheetWeb = ({sheetProps, onResolve}: SheetWebProps): JSX.Element => { } switch (sheetProps.type) { case 'INFO': - onResolve<'INFO'>(undefined); + onResolve<'INFO'>({action: 'DISMISS'}); break; case 'ACTIONS_LIST': if (selectionRef.current) {