mirror of
https://github.com/nexu-io/open-design.git
synced 2026-05-31 19:04:39 +07:00
fix: replace PreviewModal motion with CSS animation, add motion test mock
- PreviewModal no longer uses motion/react — prevents test failures from AnimatePresence exit animations never completing in test env - Add CSS animations for .ds-modal-backdrop (fade-in) and .ds-modal (scale-in) - Add vitest alias to mock motion/react so AnimatePresence in other components (UpdaterPopup, ExamplesTab) completes synchronously in tests
This commit is contained in:
parent
9c331129e9
commit
e367d2879e
4 changed files with 54 additions and 14 deletions
|
|
@ -1,5 +1,4 @@
|
|||
import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import { useT } from '../i18n';
|
||||
import { copyToClipboard } from '../lib/copy-to-clipboard';
|
||||
import {
|
||||
|
|
@ -12,7 +11,6 @@ import {
|
|||
} from '../runtime/exports';
|
||||
import { buildSrcdoc } from '../runtime/srcdoc';
|
||||
import { Icon } from './Icon';
|
||||
import { modalOverlay, modalContent } from '../motion';
|
||||
|
||||
export interface PreviewView {
|
||||
id: string;
|
||||
|
|
@ -471,22 +469,14 @@ export function PreviewModal({
|
|||
const canOpenTemplateShareMenu = canExportFiles || Boolean(previewShareUrl);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
<div
|
||||
className="ds-modal-backdrop"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label={`${title} preview`}
|
||||
variants={modalOverlay}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
exit="exit"
|
||||
>
|
||||
<motion.div
|
||||
<div
|
||||
className={`ds-modal ${fullscreen ? 'ds-modal-fullscreen' : ''}`}
|
||||
variants={modalContent}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
exit="exit"
|
||||
>
|
||||
<header className="ds-modal-header">
|
||||
<div className="ds-modal-header-top">
|
||||
|
|
@ -941,7 +931,7 @@ export function PreviewModal({
|
|||
</aside>
|
||||
) : null}
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -462,6 +462,18 @@
|
|||
================================================================ */
|
||||
|
||||
|
||||
/* ================================================================
|
||||
Preview modal
|
||||
================================================================ */
|
||||
|
||||
.ds-modal-backdrop {
|
||||
animation: od-fade-in 200ms cubic-bezier(0.23, 1, 0.32, 1) both;
|
||||
}
|
||||
|
||||
.ds-modal {
|
||||
animation: od-scale-in 250ms cubic-bezier(0.23, 1, 0.32, 1) both;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
Plugin detail view
|
||||
================================================================ */
|
||||
|
|
|
|||
32
apps/web/tests/helpers/motion-mock.tsx
Normal file
32
apps/web/tests/helpers/motion-mock.tsx
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { forwardRef, type ComponentProps, type ElementType } from 'react';
|
||||
|
||||
function AnimatePresence({ children }: { children?: React.ReactNode }) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
const motionHandler: ProxyHandler<object> = {
|
||||
get(_target, prop: string) {
|
||||
const Component = forwardRef<unknown, ComponentProps<ElementType>>((props, ref) => {
|
||||
const {
|
||||
variants: _variants,
|
||||
initial: _initial,
|
||||
animate: _animate,
|
||||
exit: _exit,
|
||||
whileHover: _whileHover,
|
||||
whileTap: _whileTap,
|
||||
transition: _transition,
|
||||
layout: _layout,
|
||||
layoutId: _layoutId,
|
||||
...rest
|
||||
} = props as Record<string, unknown>;
|
||||
const Tag = prop as ElementType;
|
||||
return <Tag ref={ref} {...rest} />;
|
||||
});
|
||||
Component.displayName = `motion.${prop}`;
|
||||
return Component;
|
||||
},
|
||||
};
|
||||
|
||||
const motion = new Proxy({}, motionHandler);
|
||||
|
||||
export { AnimatePresence, motion };
|
||||
|
|
@ -1,6 +1,12 @@
|
|||
import { resolve } from 'node:path';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'motion/react': resolve(__dirname, 'tests/helpers/motion-mock.tsx'),
|
||||
},
|
||||
},
|
||||
test: {
|
||||
environment: 'node',
|
||||
include: ['tests/**/*.test.{ts,tsx}'],
|
||||
|
|
|
|||
Loading…
Reference in a new issue