fix(component): nested modal view-transition support (#8073)

<div class='graphite__hidden'>
          <div>🎥 Video uploaded on Graphite:</div>
            <a href="https://app.graphite.dev/media/video/LakojjjzZNf6ogjOVwKE/b8033923-8f08-4c72-96b6-d790fc0ff703.mp4">
              <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/LakojjjzZNf6ogjOVwKE/b8033923-8f08-4c72-96b6-d790fc0ff703.mp4">
            </a>
          </div>
<video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/LakojjjzZNf6ogjOVwKE/b8033923-8f08-4c72-96b6-d790fc0ff703.mp4">CleanShot 2024-09-03 at 18.36.17.mp4</video>
This commit is contained in:
CatsJuice 2024-09-04 01:29:22 +00:00
parent ec3b97d069
commit 0d6f468385
No known key found for this signature in database
GPG Key ID: 1C1E76924FAFDDE4
3 changed files with 45 additions and 2 deletions

View File

@ -139,3 +139,37 @@ export const Animations = () => {
</div> </div>
); );
}; };
export const Nested = () => {
const [openRoot, setOpenRoot] = useState(false);
const [openNested, setOpenNested] = useState(false);
return (
<>
<Button onClick={() => setOpenRoot(true)}>Open Root Modal</Button>
<Modal
animation="slideBottom"
open={openRoot}
onOpenChange={setOpenRoot}
contentOptions={{
style: {
transition: 'all .3s ease 0.1s',
transform: openNested
? `scale(0.95) translateY(-20px)`
: 'scale(1) translateY(0)',
},
}}
>
<Button onClick={() => setOpenNested(true)}>Open Nested Modal</Button>
</Modal>
<Modal
animation="slideBottom"
open={openNested}
onOpenChange={setOpenNested}
overlayOptions={{ style: { background: 'transparent' } }}
>
Nested Modal
</Modal>
</>
);
};

View File

@ -89,6 +89,11 @@ class ModalTransitionContainer extends HTMLElement {
this.animationFrame = requestAnimationFrame(() => { this.animationFrame = requestAnimationFrame(() => {
if (typeof document.startViewTransition === 'function') { if (typeof document.startViewTransition === 'function') {
const nodes = this.pendingTransitionNodes; const nodes = this.pendingTransitionNodes;
nodes.forEach(child => {
if (child instanceof HTMLElement) {
child.classList.add('vt-active');
}
});
document.startViewTransition(() => { document.startViewTransition(() => {
nodes.forEach(child => { nodes.forEach(child => {
// eslint-disable-next-line unicorn/prefer-dom-node-remove // eslint-disable-next-line unicorn/prefer-dom-node-remove

View File

@ -92,14 +92,18 @@ export const modalContentWrapper = style({
}, },
'&.anim-fadeScaleTop': { '&.anim-fadeScaleTop': {
animation: `${contentShowFadeScaleTop} 150ms cubic-bezier(0.42, 0, 0.58, 1)`, animation: `${contentShowFadeScaleTop} 150ms cubic-bezier(0.42, 0, 0.58, 1)`,
viewTransitionName: modalContentViewTransitionNameFadeScaleTop,
animationFillMode: 'forwards', animationFillMode: 'forwards',
}, },
'&.anim-fadeScaleTop.vt-active': {
viewTransitionName: modalContentViewTransitionNameFadeScaleTop,
},
'&.anim-slideBottom': { '&.anim-slideBottom': {
animation: `${contentShowSlideBottom} 0.23s ease`, animation: `${contentShowSlideBottom} 0.23s ease`,
viewTransitionName: modalContentViewTransitionNameSlideBottom,
animationFillMode: 'forwards', animationFillMode: 'forwards',
}, },
'&.anim-slideBottom.vt-active': {
viewTransitionName: modalContentViewTransitionNameSlideBottom,
},
}, },
}); });
globalStyle( globalStyle(