diff --git a/packages/component/src/components/tour-modal/index.css.ts b/packages/component/src/components/tour-modal/index.css.ts index 1224837e85..2b57246c26 100644 --- a/packages/component/src/components/tour-modal/index.css.ts +++ b/packages/component/src/components/tour-modal/index.css.ts @@ -1,29 +1,91 @@ -import { style } from '@vanilla-extract/css'; +import { keyframes, style } from '@vanilla-extract/css'; export const modalStyle = style({ width: '100%', - height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', position: 'relative', backgroundColor: 'var(--affine-background-secondary-color)', borderRadius: '16px', + overflow: 'hidden', +}); +export const titleContainerStyle = style({ + width: 'calc(100% - 72px)', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + position: 'relative', + height: '60px', + overflow: 'hidden', }); export const titleStyle = style({ fontSize: 'var(--affine-font-h6)', fontWeight: '600', marginTop: '12px', + position: 'absolute', + marginBottom: '12px', }); +const slideToLeft = keyframes({ + '0%': { + transform: 'translateX(0)', + opacity: 1, + }, + '100%': { + transform: 'translateX(-300px)', + opacity: 0, + }, +}); +const slideToRight = keyframes({ + '0%': { + transform: 'translateX(0)', + opacity: 1, + }, + '100%': { + transform: 'translateX(300px)', + opacity: 0, + }, +}); +const slideFormLeft = keyframes({ + '0%': { + transform: 'translateX(300px)', + opacity: 0, + }, + '100%': { + transform: 'translateX(0)', + opacity: 1, + }, +}); +const slideFormRight = keyframes({ + '0%': { + transform: 'translateX(-300px)', + opacity: 0, + }, + '100%': { + transform: 'translateX(0)', + opacity: 1, + }, +}); +export const formSlideToLeftStyle = style({ + animation: `${slideFormLeft} 0.3s ease-in-out forwards`, +}); +export const formSlideToRightStyle = style({ + animation: `${slideFormRight} 0.3s ease-in-out forwards`, +}); +export const slideToLeftStyle = style({ + animation: `${slideToLeft} 0.3s ease-in-out forwards`, +}); +export const slideToRightStyle = style({ + animation: `${slideToRight} 0.3s ease-in-out forwards`, +}); + export const containerStyle = style({ - paddingTop: '25px', width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'space-between', }); export const videoContainerStyle = style({ - paddingTop: '25px', height: '300px', width: 'calc(100% - 72px)', display: 'flex', @@ -31,6 +93,7 @@ export const videoContainerStyle = style({ flexGrow: 1, justifyContent: 'space-between', position: 'relative', + overflow: 'hidden', }); export const videoSlideStyle = style({ width: '100%', @@ -46,9 +109,19 @@ export const videoStyle = style({ border: '1px solid var(--affine-border-color)', transition: 'opacity 0.5s ease-in-out', }); +const fadeIn = keyframes({ + '0%': { + transform: 'translateX(300px)', + }, + '100%': { + transform: 'translateX(0)', + }, +}); export const videoActiveStyle = style({ + animation: `${fadeIn} 0.5s ease-in-out forwards`, opacity: 0, }); + export const arrowStyle = style({ wordBreak: 'break-all', wordWrap: 'break-word', @@ -61,29 +134,52 @@ export const arrowStyle = style({ flexGrow: 0.2, cursor: 'pointer', }); +export const descriptionContainerStyle = style({ + width: 'calc(100% - 112px)', + height: '100px', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + position: 'relative', + overflow: 'hidden', +}); + export const descriptionStyle = style({ marginTop: '15px', width: '100%', display: 'flex', - padding: '0 56px', fontSize: 'var(--affine-font-sm)', lineHeight: '18px', - marginBottom: '20px', + position: 'absolute', }); export const tabStyle = style({ width: '40px', - height: '20px', + height: '40px', content: '""', - borderBottom: '2px solid var(--affine-text-primary-color)', - opacity: 0.2, - margin: '0 10px 20px 0', + margin: '40px 10px 40px 0', transition: 'all 0.15s ease-in-out', + position: 'relative', + cursor: 'pointer', ':hover': { opacity: 1, }, + '::after': { + content: '""', + position: 'absolute', + bottom: '20px', + left: '0', + width: '100%', + height: '2px', + background: 'var(--affine-text-primary-color)', + transition: 'all 0.15s ease-in-out', + opacity: 0.2, + cursor: 'pointer', + }, }); export const tabActiveStyle = style({ - opacity: 1, + '::after': { + opacity: 1, + }, }); export const tabContainerStyle = style({ width: '100%', diff --git a/packages/component/src/components/tour-modal/tour-modal.tsx b/packages/component/src/components/tour-modal/tour-modal.tsx index ad9d6279ac..15569bac3b 100644 --- a/packages/component/src/components/tour-modal/tour-modal.tsx +++ b/packages/component/src/components/tour-modal/tour-modal.tsx @@ -8,13 +8,18 @@ import { Modal, ModalCloseButton, ModalWrapper } from '../..'; import { arrowStyle, containerStyle, + descriptionContainerStyle, descriptionStyle, + formSlideToLeftStyle, + formSlideToRightStyle, modalStyle, + slideToLeftStyle, + slideToRightStyle, tabActiveStyle, tabContainerStyle, tabStyle, + titleContainerStyle, titleStyle, - videoActiveStyle, videoContainerStyle, videoSlideStyle, videoStyle, @@ -27,9 +32,9 @@ type TourModalProps = { export const TourModal: FC = ({ open, onClose }) => { const t = useAFFiNEI18N(); - const [step, setStep] = useState(0); + const [step, setStep] = useState(-1); const handleClose = () => { - setStep(0); + setStep(-1); onClose(); }; return ( @@ -51,39 +56,59 @@ export const TourModal: FC = ({ open, onClose }) => { data-testid="onboarding-modal-close-button" />
-
- {step === 1 - ? t['com.affine.onboarding.title2']() - : t['com.affine.onboarding.title1']()} +
+ {step !== -1 && ( +
+ {t['com.affine.onboarding.title2']()} +
+ )} +
+ {t['com.affine.onboarding.title1']()} +
+
setStep(0)} + onClick={() => step === 1 && setStep(0)} data-testid="onboarding-modal-pre-button" >
+ {step !== -1 && ( + + )} -
  • setStep(0)} >
  • = ({ open, onClose }) => { onClick={() => setStep(1)} >
-
- {step === 1 - ? t['com.affine.onboarding.videoDescription2']() - : t['com.affine.onboarding.videoDescription1']()} +
+ {step !== -1 && ( +
+ {t['com.affine.onboarding.videoDescription2']()} +
+ )} +
+ {t['com.affine.onboarding.videoDescription1']()} +