diff --git a/apps/electron/tests/basic.spec.ts b/apps/electron/tests/basic.spec.ts index 59467e5ccc..9bf1e885ab 100644 --- a/apps/electron/tests/basic.spec.ts +++ b/apps/electron/tests/basic.spec.ts @@ -67,7 +67,7 @@ test('affine onboarding button', async ({ page }) => { '[data-testid=onboarding-modal-editing-video]' ); expect(await editingVideo.isVisible()).toEqual(true); - await page.getByTestId('onboarding-modal-ok-button').click(); + await page.getByTestId('onboarding-modal-close-button').click(); expect(await onboardingModal.isVisible()).toEqual(false); }); diff --git a/packages/component/src/components/tour-modal/index.css.ts b/packages/component/src/components/tour-modal/index.css.ts index ea74b2045a..1224837e85 100644 --- a/packages/component/src/components/tour-modal/index.css.ts +++ b/packages/component/src/components/tour-modal/index.css.ts @@ -7,38 +7,90 @@ export const modalStyle = style({ flexDirection: 'column', alignItems: 'center', position: 'relative', - padding: '12px 36px', - backgroundColor: 'var(--affine-white)', - borderRadius: '12px', - boxShadow: 'var(--affine-popover-shadow)', + backgroundColor: 'var(--affine-background-secondary-color)', + borderRadius: '16px', }); export const titleStyle = style({ fontSize: 'var(--affine-font-h6)', fontWeight: '600', + marginTop: '12px', +}); +export const containerStyle = style({ + paddingTop: '25px', + width: '100%', + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', }); export const videoContainerStyle = style({ - paddingTop: '15px', + paddingTop: '25px', + height: '300px', + width: 'calc(100% - 72px)', + display: 'flex', + alignItems: 'center', + flexGrow: 1, + justifyContent: 'space-between', + position: 'relative', +}); +export const videoSlideStyle = style({ width: '100%', + position: 'absolute', + top: 0, + display: 'flex', + justifyContent: 'center', }); export const videoStyle = style({ + position: 'absolute', objectFit: 'fill', height: '300px', - width: '100%', + border: '1px solid var(--affine-border-color)', + transition: 'opacity 0.5s ease-in-out', }); -export const buttonContainerStyle = style({ +export const videoActiveStyle = style({ + opacity: 0, +}); +export const arrowStyle = style({ + wordBreak: 'break-all', + wordWrap: 'break-word', + width: '36px', + fontSize: '32px', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + height: '240px', + flexGrow: 0.2, + cursor: 'pointer', +}); +export const descriptionStyle = style({ marginTop: '15px', width: '100%', display: 'flex', - justifyContent: 'flex-end', + padding: '0 56px', + fontSize: 'var(--affine-font-sm)', + lineHeight: '18px', + marginBottom: '20px', }); -export const buttonStyle = style({ - borderRadius: '8px', - backgroundColor: 'var(--affine-primary-color)', - color: 'var(--affine-white)', - height: '32px', - padding: '4 20px', +export const tabStyle = style({ + width: '40px', + height: '20px', + content: '""', + borderBottom: '2px solid var(--affine-text-primary-color)', + opacity: 0.2, + margin: '0 10px 20px 0', + transition: 'all 0.15s ease-in-out', ':hover': { - backgroundColor: 'var(--affine-primary-color)', - color: 'var(--affine-white)', + opacity: 1, }, }); +export const tabActiveStyle = style({ + opacity: 1, +}); +export const tabContainerStyle = style({ + width: '100%', + marginTop: '20px', + position: 'relative', + height: '2px', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', +}); diff --git a/packages/component/src/components/tour-modal/index.ts b/packages/component/src/components/tour-modal/index.tsx similarity index 100% rename from packages/component/src/components/tour-modal/index.ts rename to packages/component/src/components/tour-modal/index.tsx diff --git a/packages/component/src/components/tour-modal/tour-modal.tsx b/packages/component/src/components/tour-modal/tour-modal.tsx index 396b19f79f..ad9d6279ac 100644 --- a/packages/component/src/components/tour-modal/tour-modal.tsx +++ b/packages/component/src/components/tour-modal/tour-modal.tsx @@ -1,13 +1,22 @@ +import { useAFFiNEI18N } from '@affine/i18n/hooks'; +import { ArrowLeftSmallIcon, ArrowRightSmallIcon } from '@blocksuite/icons'; +import clsx from 'clsx'; import type { FC } from 'react'; import { useState } from 'react'; -import { Button, Modal, ModalCloseButton, ModalWrapper } from '../..'; +import { Modal, ModalCloseButton, ModalWrapper } from '../..'; import { - buttonContainerStyle, - buttonStyle, + arrowStyle, + containerStyle, + descriptionStyle, modalStyle, + tabActiveStyle, + tabContainerStyle, + tabStyle, titleStyle, + videoActiveStyle, videoContainerStyle, + videoSlideStyle, videoStyle, } from './index.css'; @@ -17,6 +26,7 @@ type TourModalProps = { }; export const TourModal: FC = ({ open, onClose }) => { + const t = useAFFiNEI18N(); const [step, setStep] = useState(0); const handleClose = () => { setStep(0); @@ -27,73 +37,85 @@ export const TourModal: FC = ({ open, onClose }) => { open={open} onClose={handleClose} wrapperPosition={['center', 'center']} + hideBackdrop > - + - {step === 0 && ( -
-
Hyper merged whiteboard and docs
-
- -
-
- -
+
+
+ {step === 1 + ? t['com.affine.onboarding.title2']() + : t['com.affine.onboarding.title1']()}
- )} - {step === 1 && ( -
-
- Intuitive & robust block-based editing +
+
setStep(0)} + data-testid="onboarding-modal-pre-button" + > +
- +
+ + +
-
- +
setStep(1)} + data-testid="onboarding-modal-next-button" + > +
- )} +
    +
  • setStep(0)} + >
  • +
  • setStep(1)} + >
  • +
+
+ {step === 1 + ? t['com.affine.onboarding.videoDescription2']() + : t['com.affine.onboarding.videoDescription1']()} +
+
); diff --git a/packages/component/src/ui/modal/modal-wrapper.tsx b/packages/component/src/ui/modal/modal-wrapper.tsx index 3da6cabeb8..d958315fb6 100644 --- a/packages/component/src/ui/modal/modal-wrapper.tsx +++ b/packages/component/src/ui/modal/modal-wrapper.tsx @@ -12,7 +12,7 @@ export const ModalWrapper = styled('div')<{ height, minHeight, backgroundColor: 'var(--affine-background-secondary-color)', - boxShadow: 'var(--affine-popover-shadow)', + boxShadow: 'var(--affine-shadow-3)', borderRadius: '16px', position: 'relative', maxHeight: 'calc(100vh - 32px)', diff --git a/packages/i18n/src/resources/en.json b/packages/i18n/src/resources/en.json index eb3c0f6729..61f0ff209e 100644 --- a/packages/i18n/src/resources/en.json +++ b/packages/i18n/src/resources/en.json @@ -267,5 +267,9 @@ "dark": "dark", "system": "system", "com.affine.pageMode": "Page Mode", - "com.affine.edgelessMode": "Edgeless Mode" + "com.affine.edgelessMode": "Edgeless Mode", + "com.affine.onboarding.title1": "Hyper merged whiteboard and docs", + "com.affine.onboarding.title2": "Intuitive & robust block-based editing", + "com.affine.onboarding.videoDescription1": "Easily switch between Page mode for structured document creation and Whiteboard mode for the freeform visual expression of creative ideas.", + "com.affine.onboarding.videoDescription2": "Create structured documents with ease, using a modular interface to drag and drop blocks of text, images, and other content." }