Skip to content

Commit

Permalink
Fix Animation handling in Modal component (#1489)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Taranto <[email protected]>
  • Loading branch information
felixhabib and michaeltaranto authored May 16, 2024
1 parent 2dfbe30 commit e9fae1b
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 81 deletions.
10 changes: 10 additions & 0 deletions .changeset/calm-fireants-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'braid-design-system': patch
---

---
updated:
- Drawer
---

Fix minor bug which prevented the `Drawer` exit animation from occurring.
10 changes: 10 additions & 0 deletions .changeset/gentle-ads-stare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'braid-design-system': minor
---

---
updated:
- Dialog
---

Add exit animation to `Dialog` which mirrors the existing entrance animation.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
IconLanguage,
Checkbox,
Alert,
TextDropdown,
} from '../';
import { Placeholder } from '../../playroom/components';
import { DialogContent } from './Dialog';
Expand Down Expand Up @@ -193,33 +194,39 @@ const docs: ComponentDocs = {
of the dialog.
</Text>
),
Example: ({ id, setState, getState, resetState }) =>

Example: ({ id, setDefaultState, setState, getState }) =>
source(
<>
<Inline space="small" align="center">
<Button onClick={() => setState('width', 'content')}>
Content width
</Button>
<Button onClick={() => setState('width', 'xsmall')}>
XSmall width
</Button>
<Button onClick={() => setState('width', 'small')}>
Small width
</Button>
<Button onClick={() => setState('width', 'medium')}>
Medium width
</Button>
<Button onClick={() => setState('width', 'large')}>
Large width
</Button>
</Inline>
{setDefaultState('open', false)}
{setDefaultState('width', 'xsmall')}

<Stack space="medium">
<Text>
Select width:{' '}
<Strong>
<TextDropdown
id="width"
label="Width"
options={['content', 'xsmall', 'small', 'medium', 'large']}
value={getState('width')}
onChange={(width) => setState('width', width)}
/>
</Strong>
</Text>
<Inline space="none">
<Button onClick={() => setState('open', true)}>
Open dialog
</Button>
</Inline>
</Stack>

<Dialog
id={id}
title={`Width: ${getState('width')}`}
open={getState('width') !== undefined}
open={getState('open')}
width={getState('width')}
onClose={() => resetState('width')}
onClose={() => setState('open', false)}
>
{getState('width') === 'content' ? (
<Placeholder height={100} width={200} label="200px wide" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ export const resetStackingContext = atoms({ position: 'relative', zIndex: 0 });
export const backdrop = style(
colorModeStyle({
lightMode: {
background: '#000',
opacity: 0.4,
background: 'rgba(0, 0, 0, 0.4)',
},
darkMode: {
background: '#000',
opacity: 0.6,
background: 'rgba(0, 0, 0, 0.6)',
},
}),
);
Expand All @@ -34,56 +32,43 @@ const reducedMotion = style({
},
});

const rightAnimation = style([
reducedMotion,
responsiveStyle({
mobile: { opacity: 1, transform: 'translateX(110%)' },
tablet: { opacity: 0, transform: 'translateX(40px)' },
}),
]);

const leftAnimation = style([
reducedMotion,
responsiveStyle({
mobile: { opacity: 1, transform: 'translateX(-110%)' },
tablet: { opacity: 0, transform: 'translateX(-40px)' },
}),
]);

const centerAnimation = style([
reducedMotion,
{
transform: 'scale(.8)',
},
]);

export const entrance = {
center: [
reducedMotion,
style({
transform: 'scale(.8)',
}),
],
right: [
reducedMotion,
style(
responsiveStyle({
mobile: { opacity: 1, transform: 'translateX(110%)' },
tablet: { opacity: 0, transform: 'translateX(40px)' },
}),
),
],
left: [
reducedMotion,
style(
responsiveStyle({
mobile: { opacity: 1, transform: 'translateX(-110%)' },
tablet: { opacity: 0, transform: 'translateX(-40px)' },
}),
),
],
center: centerAnimation,
right: rightAnimation,
left: leftAnimation,
};

export const exit = {
right: [
reducedMotion,
style(
responsiveStyle({
mobile: { opacity: 1, transform: 'translateX(110%)' },
tablet: { opacity: 0, transform: 'translateX(10px)' },
}),
),
],
left: [
reducedMotion,
style(
responsiveStyle({
mobile: { opacity: 1, transform: 'translateX(-110%)' },
tablet: { opacity: 0, transform: 'translateX(-10px)' },
}),
),
],
center: centerAnimation,
right: rightAnimation,
left: leftAnimation,
};

const easeOut = 'cubic-bezier(0.4, 0, 0, 1)';
export const horiztontalTransition = style(
const horizontalTransition = style(
responsiveStyle({
mobile: {
transition: `transform .3s ${easeOut}, opacity .3s ${easeOut}`,
Expand All @@ -94,6 +79,12 @@ export const horiztontalTransition = style(
}),
);

export const transition = {
center: atoms({ transition: 'fast' }),
right: horizontalTransition,
left: horizontalTransition,
};

export const pointerEventsAll = style({
pointerEvents: 'all',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const reducer: Reducer<State, Action> = (prevState, action) => {
return OPENING;
}
}
return prevState;
}

case CLOSE_MODAL: {
Expand All @@ -97,6 +98,7 @@ const reducer: Reducer<State, Action> = (prevState, action) => {
return CLOSING;
}
}
return prevState;
}

case ANIMATION_COMPLETE: {
Expand All @@ -109,10 +111,13 @@ const reducer: Reducer<State, Action> = (prevState, action) => {
return OPEN;
}
}
return prevState;
}
}

return prevState;
default: {
return prevState;
}
}
};

const ANIMATION_DURATION = 300;
Expand Down Expand Up @@ -221,34 +226,25 @@ export const Modal = ({
position="fixed"
inset={0}
zIndex="modalBackdrop"
transition={position === 'center' ? 'fast' : undefined}
opacity={state !== OPEN ? 0 : undefined}
pointerEvents={state === CLOSING ? 'none' : undefined}
className={[
styles.backdrop,
position === 'left' ||
(position === 'right' && styles.horiztontalTransition),
]}
className={[styles.backdrop, styles.transition[position]]}
/>

<Box
position="fixed"
inset={0}
zIndex="modal"
pointerEvents="none"
transition="fast"
opacity={state !== OPEN ? 0 : undefined}
paddingLeft={position === 'right' ? ['none', 'xlarge'] : undefined}
paddingRight={position === 'left' ? ['none', 'xlarge'] : undefined}
padding={position === 'center' ? externalGutter : undefined}
className={[
styles.modalContainer,
(position === 'left' || position === 'right') &&
styles.horiztontalTransition,
styles.transition[position],
state === OPENING && styles.entrance[position],
state === CLOSING &&
position in styles.exit &&
styles.exit[position as keyof typeof styles.exit],
state === CLOSING && styles.exit[position],
]}
>
<ModalContent
Expand Down

0 comments on commit e9fae1b

Please sign in to comment.