Skip to content

Commit

Permalink
feat(Sheet): allow closing the sheet with the keyboard or a screen re…
Browse files Browse the repository at this point in the history
…ader (#1293)

Issue: [Link](https://jira.tid.es/browse/WEB-2083)

## Note

In this PR I'm also fixing a wrong usage in the Sheet's story. It was
using a ResponsiveLayout instead of SheetBody, and therefore causing
issues with horizontal padding in large devices
(https://jira.tid.es/browse/WEB-2101)
  • Loading branch information
marcoskolodny authored Nov 22, 2024
1 parent 1a061d8 commit 42099fb
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 112 deletions.
193 changes: 97 additions & 96 deletions playroom/snippets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2478,100 +2478,102 @@ const exampleScreens: Array<Snippet> = [
setState("isSheetOpen", false);
}}
>
<ResponsiveLayout>
<Box paddingBottom={80} paddingTop={0}>
<Stack space={24}>
<Text4 medium>Summary of your order</Text4>
<Callout
asset={<IconTruckRegular color={colors.brand} />}
description="Products may be shipped separately depending on availability."
/>
{({ modalTitleId }) => (
<SheetBody modalTitleId={modalTitleId}>
<Box paddingBottom={80} paddingTop={0}>
<Stack space={24}>
<Stack space={8}>
<NegativeBox>
<RowList>
<Row
asset={
<Image
src="${imagePlaceholder}"
height={64}
aspectRatio="1:1"
/>
}
title="iPhone 14 Pro"
subtitle="Color: Green"
description="Capacity: 256 GB"
right={
<div
style={{
height: "100%",
display: "flex",
alignItems: "flex-end",
justifyContent: "center",
flexDirection: "column",
}}
>
<Text2 color={colors.textSecondary}>1.379 €</Text2>
<Text4 medium>1.379 €</Text4>
</div>
}
/>
<Row
asset={
<Image
src="${imagePlaceholder}"
height={64}
aspectRatio="1:1"
/>
}
title="AirPods 3ª gen."
subtitle="Color: White"
right={
<div
style={{
height: "100%",
display: "flex",
alignItems: "flex-end",
justifyContent: "center",
<Text4 medium>Summary of your order</Text4>
<Callout
asset={<IconTruckRegular color={colors.brand} />}
description="Products may be shipped separately depending on availability."
/>
flexDirection: "column",
}}
>
<Text4 medium>200 €</Text4>
</div>
}
/>
</RowList>
</NegativeBox>
<Stack space={24}>
<Stack space={8}>
<NegativeBox>
<RowList>
<Row
asset={
<Image
src="${imagePlaceholder}"
height={64}
aspectRatio="1:1"
/>
}
title="iPhone 14 Pro"
subtitle="Color: Green"
description="Capacity: 256 GB"
right={
<div
style={{
height: "100%",
display: "flex",
alignItems: "flex-end",
justifyContent: "center",
flexDirection: "column",
}}
>
<Text2 color={colors.textSecondary}>1.379 €</Text2>
<Text4 medium>1.379 €</Text4>
</div>
}
/>
<Row
asset={
<Image
src="${imagePlaceholder}"
height={64}
aspectRatio="1:1"
/>
}
title="AirPods 3ª gen."
subtitle="Color: White"
right={
<div
style={{
height: "100%",
display: "flex",
alignItems: "flex-end",
justifyContent: "center",
flexDirection: "column",
}}
>
<Text4 medium>200 €</Text4>
</div>
}
/>
</RowList>
</NegativeBox>
<Divider />
</Stack>
<Stack space={16}>
<Inline space="between">
<Text3>Subtotal</Text3>
<Text3>1.369 €</Text3>
</Inline>
<Inline space="between">
<Text3 color={colors.promoHigh}>Promoción 7% descuento</Text3>
<Text3 color={colors.promoHigh}>-100 €</Text3>
</Inline>
<Inline space="between">
<Text3>Shipping costs</Text3>
<Text3>0 €</Text3>
</Inline>
</Stack>
<Divider />
</Stack>
<Stack space={16}>
<Inline space="between">
<Text3>Subtotal</Text3>
<Text3>1.369 €</Text3>
</Inline>
<Inline space="between">
<Text3 color={colors.promoHigh}>Promoción 7% descuento</Text3>
<Text3 color={colors.promoHigh}>-100 €</Text3>
</Inline>
<Inline space="between">
<Text3>Shipping costs</Text3>
<Text3>0 €</Text3>
</Inline>
</Stack>
<Divider />
<Stack space={8}>
<Inline space="between">
<Text4 medium>Total</Text4>
<Text4 medium>1.269 €</Text4>
</Inline>
<Text1 color={colors.textSecondary}>* All taxes included</Text1>
<Stack space={8}>
<Inline space="between">
<Text4 medium>Total</Text4>
<Text4 medium>1.269 €</Text4>
</Inline>
<Text1 color={colors.textSecondary}>* All taxes included</Text1>
</Stack>
</Stack>
</Stack>
</Stack>
</Box>
</ResponsiveLayout>
</SheetBody>
)}
</Sheet>
)}
Expand Down Expand Up @@ -3225,14 +3227,13 @@ const alertSnippets = [
setState("isSheetOpen", false);
}}
>
<ResponsiveLayout>
<Box
paddingBottom={{ mobile: 16, desktop: 40 }}
paddingTop={{ mobile: 0, desktop: 40 }}
>
<Placeholder />
</Box>
</ResponsiveLayout>
{({ modalTitleId }) => (
<SheetBody modalTitleId={modalTitleId}>
<Box paddingBottom={{ mobile: 16, desktop: 0 }}>
<Placeholder />
</Box>
</SheetBody>
)}
</Sheet>
)}`,
},
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/__screenshot_tests__/sheet-screenshot-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {openStoryPage, screen} from '../test-utils';
const TESTABLE_DEVICES = ['MOBILE_IOS', 'DESKTOP'] as const;
const TESTABLE_DEVICES_WITH_LARGE_DESKTOP = [...TESTABLE_DEVICES, 'LARGE_DESKTOP'] as const;

test.each(TESTABLE_DEVICES)('Sheet in %s', async (device) => {
test.each(TESTABLE_DEVICES_WITH_LARGE_DESKTOP)('Sheet in %s', async (device) => {
const page = await openStoryPage({
id: 'components-modals-sheet--default',
device,
Expand Down
19 changes: 12 additions & 7 deletions src/__stories__/sheet-story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
ButtonPrimary,
Inline,
Placeholder,
ResponsiveLayout,
SheetBody,
showSheet,
Stack,
Text2,
Expand Down Expand Up @@ -45,7 +45,10 @@ export const Default: StoryComponent = () => {
description="Check Sheet component docs for more info."
asset={<IconInformationRegular />}
buttonLink={
<ButtonLink href="https://github.com/Telefonica/mistica-web/blob/master/doc/sheet.md">
<ButtonLink
small
href="https://github.com/Telefonica/mistica-web/blob/master/doc/sheet.md"
>
See docs
</ButtonLink>
}
Expand All @@ -58,11 +61,13 @@ export const Default: StoryComponent = () => {
setOpen(false);
}}
>
<ResponsiveLayout>
<Box paddingBottom={{mobile: 16, desktop: 40}} paddingTop={{mobile: 0, desktop: 40}}>
<Placeholder />
</Box>
</ResponsiveLayout>
{({modalTitleId}) => (
<SheetBody modalTitleId={modalTitleId}>
<Box paddingBottom={{mobile: 16, desktop: 0}}>
<Placeholder />
</Box>
</SheetBody>
)}
</Sheet>
)}
</Box>
Expand Down
33 changes: 29 additions & 4 deletions src/sheet-common.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export const children = sprinkles({
flexDirection: 'column',
});

export const handleContainer = style([
export const sheetTopDraggingArea = style([
sprinkles({
// Absolute positioned with a bigger size to increase the touchable area for dragging
position: 'absolute',
Expand All @@ -156,10 +156,35 @@ export const handleContainer = style([
},
]);

export const handle = sprinkles({
export const handleContainer = style([
sprinkles({
display: 'none',
}),
{
'@media': {
// Handle is rendered only in mobile version
[mq.tabletOrSmaller]: {
position: 'absolute',
top: 8,
width: '100%',
display: 'flex',
justifyContent: 'center',
},
},
},
]);

export const handleTouchable = style([
sprinkles({
width: 24,
height: 4,
}),
]);

export const handleBar = sprinkles({
background: skinVars.colors.control,
width: 24,
height: 4,
width: '100%',
height: '100%',
borderRadius: 2,
});

Expand Down
24 changes: 20 additions & 4 deletions src/sheet-common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import ButtonLayout from './button-layout';
import {safeAreaInsetBottom} from './utils/css';
import {MOBILE_SIDE_MARGIN, SMALL_DESKTOP_SIDE_MARGIN, TABLET_SIDE_MARGIN} from './responsive-layout.css';
import * as tokens from './text-tokens';
import Touchable from './touchable';

import type {DataAttributes, RendersNullableElement} from './utils/types';
import type {ButtonLink, ButtonPrimary, ButtonSecondary} from './button';
Expand Down Expand Up @@ -240,9 +241,12 @@ const Sheet = React.forwardRef<HTMLDivElement, SheetProps>(({onClose, children,
>
<div className={styles.Sheet}>
<div className={styles.SheetContent}>
<div className={styles.handleContainer}>
<div className={styles.handle} />
</div>
{/**
* Space rendered on the top part of the sheet on top of
* the content in order to be able to drag the sheet
*/}
<div className={styles.sheetTopDraggingArea} />

<section
role="dialog"
aria-modal="true"
Expand All @@ -252,7 +256,6 @@ const Sheet = React.forwardRef<HTMLDivElement, SheetProps>(({onClose, children,
style={{
paddingBottom: safeAreaInsetBottom,
}}
tabIndex={-1}
>
{typeof children === 'function'
? children({closeModal, modalTitleId})
Expand All @@ -267,6 +270,19 @@ const Sheet = React.forwardRef<HTMLDivElement, SheetProps>(({onClose, children,
bleedY
/>
</div>
{/**
* We put a button behind the top dragging area so that the sheet can
* be closed while navigating with the keyboard or with a screen reader.
*/}
<div className={styles.handleContainer}>
<Touchable
onPress={closeModal}
className={styles.handleTouchable}
aria-label={texts.modalClose || t(tokens.modalClose)}
>
<div className={styles.handleBar} />
</Touchable>
</div>
</section>
</div>
</div>
Expand Down

1 comment on commit 42099fb

@github-actions
Copy link

Choose a reason for hiding this comment

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

Deploy preview for mistica-web ready!

✅ Preview
https://mistica-iyudrb0at-flows-projects-65bb050e.vercel.app

Built with commit 42099fb.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.