mirror of
https://github.com/toeverything/AFFiNE.git
synced 2025-01-03 05:02:33 +03:00
feat(core): adjust ui for new design (#5322)
feat(core): add bg and hover state for onboarding feat(core): adjust onboarding styles for web feat(core): add get started page for onboarding
This commit is contained in:
parent
07f10f55bf
commit
197d1d4136
@ -14,11 +14,16 @@ export const tooltip = style({
|
||||
fontSize: '20px',
|
||||
lineHeight: '28px',
|
||||
fontWeight: 600,
|
||||
textShadow: '0px 0px 4px rgba(66, 65, 73, 0.14)',
|
||||
color: 'white',
|
||||
opacity: 0,
|
||||
animation: `${fadeIn} 1s ease forwards`,
|
||||
animationDelay: onboardingVars.animateIn.tooltipShowUpDelay,
|
||||
color: '#121212',
|
||||
selectors: {
|
||||
'[data-is-desktop="true"] &': {
|
||||
color: 'white',
|
||||
textShadow: '0px 0px 4px rgba(66, 65, 73, 0.14)',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const next = style({
|
||||
|
@ -3,6 +3,7 @@ import type { OnboardingBlockOption } from '../types';
|
||||
import bookmark1png from './assets/article-0-bookmark-1.png';
|
||||
import bookmark2png from './assets/article-0-bookmark-2.png';
|
||||
import embed1png from './assets/article-0-embed-1.png';
|
||||
import { BlogLink } from './blog-link';
|
||||
|
||||
export const article0: Array<OnboardingBlockOption> = [
|
||||
{
|
||||
@ -245,6 +246,7 @@ export const article0: Array<OnboardingBlockOption> = [
|
||||
work. Obviously if you attend one of these, you should stop. But what
|
||||
else can you do?
|
||||
</p>
|
||||
<BlogLink />
|
||||
</>
|
||||
),
|
||||
offset: { x: 1200, y: -1600 },
|
||||
|
@ -7,6 +7,7 @@ import bookmark1png from './assets/article-1-bookmark-1.png';
|
||||
import illustration1png from './assets/article-1-illustration-1.png';
|
||||
import Article1Illustration2 from './assets/article-1-illustration-2';
|
||||
import { hr, link, quote } from './blocks.css';
|
||||
import { BlogLink } from './blog-link';
|
||||
|
||||
export const article1: Array<OnboardingBlockOption> = [
|
||||
{
|
||||
@ -256,6 +257,7 @@ export const article1: Array<OnboardingBlockOption> = [
|
||||
intricate algorithm, designing a user interface, or figuring out how
|
||||
to lead a team towards some goal are also creative efforts.)
|
||||
</p>
|
||||
<BlogLink />
|
||||
</>
|
||||
),
|
||||
offset: { x: 900, y: -950 },
|
||||
|
@ -4,6 +4,7 @@ import illustration1png from './assets/article-2-illustration-1.jpg';
|
||||
import illustration2png from './assets/article-2-illustration-2.jpg';
|
||||
import note1png from './assets/article-2-note-1.png';
|
||||
import note2png from './assets/article-2-note-2.png';
|
||||
import { BlogLink } from './blog-link';
|
||||
|
||||
export const article2: Array<OnboardingBlockOption> = [
|
||||
{
|
||||
@ -140,6 +141,7 @@ export const article2: Array<OnboardingBlockOption> = [
|
||||
media can also be an echo chamber that can push us to unwittingly
|
||||
become more extreme in our beliefs.
|
||||
</p>
|
||||
<BlogLink />
|
||||
</>
|
||||
),
|
||||
offset: { x: 150, y: -680 },
|
||||
|
@ -5,6 +5,7 @@ import illustration2jpg from './assets/article-3-illustration-2.jpg';
|
||||
import illustration3jpg from './assets/article-3-illustration-3.jpg';
|
||||
import illustration4jpg from './assets/article-3-illustration-4.jpg';
|
||||
import illustration5jpg from './assets/article-3-illustration-5.jpg';
|
||||
import { BlogLink } from './blog-link';
|
||||
|
||||
export const article3: Array<OnboardingBlockOption> = [
|
||||
{
|
||||
@ -191,6 +192,7 @@ export const article3: Array<OnboardingBlockOption> = [
|
||||
game world in creative and flexible ways, leading to fresh and
|
||||
unexpected discoveries.
|
||||
</p>
|
||||
<BlogLink />
|
||||
</>
|
||||
),
|
||||
offset: { x: 450, y: -1400 },
|
||||
|
@ -4,6 +4,7 @@ import bookmark1png from './assets/article-4-bookmark-1.png';
|
||||
import bookmark2png from './assets/article-4-bookmark-2.png';
|
||||
import illustration1jpg from './assets/article-4-illustration-1.jpg';
|
||||
import illustration2jpg from './assets/article-4-illustration-2.jpg';
|
||||
import { BlogLink } from './blog-link';
|
||||
|
||||
export const article4: Array<OnboardingBlockOption> = [
|
||||
{
|
||||
@ -180,6 +181,7 @@ export const article4: Array<OnboardingBlockOption> = [
|
||||
degree as in the previous one. Psychology is not applied biology, nor
|
||||
is biology applied chemistry.
|
||||
</p>
|
||||
<BlogLink />
|
||||
</>
|
||||
),
|
||||
|
||||
|
@ -0,0 +1,9 @@
|
||||
import { link } from './blocks.css';
|
||||
|
||||
export const BlogLink = () => {
|
||||
return (
|
||||
<a className={link} href="https://affine.pro/blog">
|
||||
Check other articles
|
||||
</a>
|
||||
);
|
||||
};
|
@ -36,7 +36,7 @@ const paperLocations = {
|
||||
/** paper enter animation config */
|
||||
const paperEnterAnimationOriginal = {
|
||||
'0': {
|
||||
curveCenter: 4,
|
||||
curveCenter: 3,
|
||||
curve: 292,
|
||||
delay: 800,
|
||||
fromZ: 1230,
|
||||
@ -54,7 +54,7 @@ const paperEnterAnimationOriginal = {
|
||||
},
|
||||
'1': {
|
||||
curveCenter: 4,
|
||||
curve: 280,
|
||||
curve: 390,
|
||||
delay: 0,
|
||||
fromZ: 3697,
|
||||
fromX: 25,
|
||||
@ -71,9 +71,9 @@ const paperEnterAnimationOriginal = {
|
||||
},
|
||||
'2': {
|
||||
curveCenter: 3,
|
||||
curve: 660,
|
||||
curve: 1240,
|
||||
delay: 1700,
|
||||
fromZ: 57379,
|
||||
fromZ: 27379,
|
||||
fromX: 2,
|
||||
fromY: -77,
|
||||
fromRotateX: 0,
|
||||
@ -87,8 +87,8 @@ const paperEnterAnimationOriginal = {
|
||||
easing: 'ease',
|
||||
},
|
||||
'3': {
|
||||
curveCenter: 4,
|
||||
curve: 260,
|
||||
curveCenter: 1,
|
||||
curve: 300,
|
||||
delay: 1500,
|
||||
fromZ: 4303,
|
||||
fromX: -37,
|
||||
@ -104,8 +104,8 @@ const paperEnterAnimationOriginal = {
|
||||
easing: 'ease',
|
||||
},
|
||||
'4': {
|
||||
curveCenter: 3,
|
||||
curve: 270,
|
||||
curveCenter: 4,
|
||||
curve: 470,
|
||||
delay: 1571,
|
||||
fromZ: 1876,
|
||||
fromX: 65,
|
||||
|
File diff suppressed because one or more lines are too long
@ -35,7 +35,11 @@ export const Onboarding = ({ onOpenApp }: OnboardingProps) => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={styles.onboarding} data-is-desktop={environment.isDesktop}>
|
||||
<div
|
||||
className={styles.onboarding}
|
||||
data-is-desktop={environment.isDesktop}
|
||||
data-is-window={!!status.activeId || !!status.unfoldingId}
|
||||
>
|
||||
<div className={styles.offsetOrigin}>
|
||||
{(Object.entries(articles) as Array<[ArticleId, ArticleOption]>).map(
|
||||
([id, article]) => {
|
||||
|
@ -55,7 +55,6 @@ export const PaperSteps = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (stage === 'unfold' && status.unfoldingId === article.id) {
|
||||
console.log('unfold', article.id);
|
||||
setFold(false);
|
||||
}
|
||||
}, [article.id, stage, status.unfoldingId]);
|
||||
|
@ -12,8 +12,8 @@ interface AnimateInProps {
|
||||
onFinished?: () => void;
|
||||
}
|
||||
|
||||
const easing = 'spring(5, 100, 10, 0)';
|
||||
const segments = 4;
|
||||
const easing = 'spring(3.2, 100, 10, 0)';
|
||||
const segments = 6;
|
||||
|
||||
const animeSync = (params: Parameters<typeof anime>[0]) => {
|
||||
return new Promise(resolve => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { globalStyle, style } from '@vanilla-extract/css';
|
||||
import { globalStyle, keyframes, style } from '@vanilla-extract/css';
|
||||
|
||||
import { onboardingVars } from '../style.css';
|
||||
|
||||
@ -7,9 +7,9 @@ export const edgelessSwitchWindow = style({
|
||||
borderRadius: onboardingVars.paper.r,
|
||||
backgroundColor: onboardingVars.paper.bg,
|
||||
position: 'relative',
|
||||
transition: `width ${onboardingVars.window.transition.size}, height ${onboardingVars.window.transition.size}`,
|
||||
transition: `width ${onboardingVars.window.transition.size}, height ${onboardingVars.window.transition.size}, border-radius ${onboardingVars.window.transition.size}`,
|
||||
overflow: 'hidden',
|
||||
boxShadow: 'var(--affine-shadow-2)',
|
||||
boxShadow: onboardingVars.web.windowShadow,
|
||||
|
||||
fontFamily: 'var(--affine-font-family)',
|
||||
color: onboardingVars.paper.textColor,
|
||||
@ -18,11 +18,43 @@ export const edgelessSwitchWindow = style({
|
||||
'&[data-mode="edgeless"]': {
|
||||
width: onboardingVars.edgeless.w,
|
||||
height: onboardingVars.edgeless.h,
|
||||
borderRadius: onboardingVars.edgeless.r,
|
||||
},
|
||||
'&[data-mode="page"]': {
|
||||
width: onboardingVars.article.w,
|
||||
height: onboardingVars.article.h,
|
||||
borderRadius: onboardingVars.article.r,
|
||||
},
|
||||
'&[data-mode="well-done"]': {
|
||||
width: onboardingVars.wellDone.w,
|
||||
height: onboardingVars.wellDone.h,
|
||||
borderRadius: onboardingVars.wellDone.r,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const orbit = style({
|
||||
width: '200%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
transition: 'transform 0.4s ease',
|
||||
willChange: 'transform',
|
||||
selectors: {
|
||||
'[data-mode="well-done"] &': {
|
||||
transform: 'translateX(-50%)',
|
||||
},
|
||||
},
|
||||
});
|
||||
export const orbitItem = style({
|
||||
width: '50%',
|
||||
height: '100%',
|
||||
flexShrink: 0,
|
||||
flexGrow: 0,
|
||||
overflow: 'hidden',
|
||||
});
|
||||
|
||||
export const doc = style({
|
||||
selectors: {
|
||||
// grid background
|
||||
'&::before': {
|
||||
content: '""',
|
||||
@ -39,12 +71,56 @@ export const edgelessSwitchWindow = style({
|
||||
pointerEvents: 'none',
|
||||
transition: 'opacity 0.3s ease',
|
||||
},
|
||||
'&[data-mode="edgeless"]::before': {
|
||||
'[data-mode="edgeless"] &::before': {
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const wellDone = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 8,
|
||||
textAlign: 'center',
|
||||
userSelect: 'none',
|
||||
});
|
||||
|
||||
const wellDoneSlideIn = keyframes({
|
||||
from: {
|
||||
transform: 'translateX(100px)',
|
||||
opacity: 0,
|
||||
},
|
||||
to: {
|
||||
transform: 'translateX(0)',
|
||||
opacity: 1,
|
||||
},
|
||||
});
|
||||
export const wellDoneEnterAnim = style({
|
||||
opacity: 0,
|
||||
selectors: {
|
||||
'[data-mode="well-done"] &': {
|
||||
animation: `${wellDoneSlideIn} 0.25s cubic-bezier(0.25, 0.1, 0.25, 1) forwards`,
|
||||
},
|
||||
'&:nth-child(1)': { animationDelay: '0.1s' },
|
||||
'&:nth-child(2)': { animationDelay: '0.15s' },
|
||||
'&:nth-child(3)': { animationDelay: '0.2s' },
|
||||
'&:nth-child(4)': { animationDelay: '0.25s' },
|
||||
},
|
||||
});
|
||||
|
||||
export const wellDoneTitle = style({
|
||||
fontSize: 28,
|
||||
lineHeight: '36px',
|
||||
fontWeight: '600',
|
||||
});
|
||||
export const wellDoneContent = style({
|
||||
fontSize: 15,
|
||||
lineHeight: '24px',
|
||||
fontWeight: '400',
|
||||
});
|
||||
|
||||
export const toolbar = style({
|
||||
position: 'absolute',
|
||||
bottom: '20px',
|
||||
@ -77,11 +153,11 @@ export const canvas = style({
|
||||
'[data-mode="edgeless"] &': {
|
||||
cursor: 'grab',
|
||||
},
|
||||
'.grabbing[data-mode="edgeless"] &': {
|
||||
'[data-mode="edgeless"] .grabbing &': {
|
||||
cursor: 'grabbing',
|
||||
transition: 'none',
|
||||
},
|
||||
'.scaling[data-mode="edgeless"] &': {
|
||||
'[data-mode="edgeless"] .scaling &': {
|
||||
transition: 'none',
|
||||
},
|
||||
},
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button } from '@affine/component';
|
||||
import clsx from 'clsx';
|
||||
import { debounce } from 'lodash-es';
|
||||
import {
|
||||
type CSSProperties,
|
||||
@ -8,6 +9,7 @@ import {
|
||||
useState,
|
||||
} from 'react';
|
||||
|
||||
import Logo from '../assets/logo';
|
||||
import { OnboardingBlock } from '../switch-widgets/block';
|
||||
import { EdgelessSwitchButtons } from '../switch-widgets/switch';
|
||||
import { ToolbarSVG } from '../switch-widgets/toolbar';
|
||||
@ -39,7 +41,8 @@ export const EdgelessSwitch = ({
|
||||
onBack,
|
||||
onNext,
|
||||
}: EdgelessSwitchProps) => {
|
||||
const windowRef = useRef<HTMLDivElement>(null);
|
||||
// const windowRef = useRef<HTMLDivElement>(null);
|
||||
const docRef = useRef<HTMLDivElement>(null);
|
||||
const canvasRef = useRef<HTMLDivElement>(null);
|
||||
const mouseDownRef = useRef(false);
|
||||
const prevStateRef = useRef<EdgelessSwitchState | null>(
|
||||
@ -59,12 +62,12 @@ export const EdgelessSwitch = ({
|
||||
const onSwitchToPageMode = useCallback(() => setMode('page'), []);
|
||||
const onSwitchToEdgelessMode = useCallback(() => setMode('edgeless'), []);
|
||||
const toggleGrabbing = useCallback((v: boolean) => {
|
||||
if (!windowRef.current) return;
|
||||
windowRef.current.classList.toggle('grabbing', v);
|
||||
if (!docRef.current) return;
|
||||
docRef.current.classList.toggle('grabbing', v);
|
||||
}, []);
|
||||
const turnOnScaling = useCallback(() => {
|
||||
if (!windowRef.current) return;
|
||||
windowRef.current.classList.add('scaling');
|
||||
if (!docRef.current) return;
|
||||
docRef.current.classList.add('scaling');
|
||||
}, []);
|
||||
|
||||
const enableScrollWithDelay = useCallback(() => {
|
||||
@ -86,20 +89,21 @@ export const EdgelessSwitch = ({
|
||||
}, []);
|
||||
const onNextClick = useCallback(() => {
|
||||
if (mode === 'page') setMode('edgeless');
|
||||
else if (mode === 'edgeless') setMode('well-done');
|
||||
else onNext?.();
|
||||
}, [mode, onNext]);
|
||||
|
||||
useEffect(() => {
|
||||
turnOffScalingRef.current = debounce(() => {
|
||||
if (!windowRef.current) return;
|
||||
windowRef.current.classList.remove('scaling');
|
||||
if (!docRef.current) return;
|
||||
docRef.current.classList.remove('scaling');
|
||||
}, 100);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (mode === 'page') return;
|
||||
const canvas = canvasRef.current;
|
||||
const win = windowRef.current;
|
||||
const win = docRef.current;
|
||||
if (!win || !canvas) return;
|
||||
|
||||
const onWheel = (e: WheelEvent) => {
|
||||
@ -197,40 +201,71 @@ export const EdgelessSwitch = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={windowRef}
|
||||
data-mode={mode}
|
||||
data-scroll={scrollable}
|
||||
className={styles.edgelessSwitchWindow}
|
||||
style={canvasStyle}
|
||||
>
|
||||
<div className={styles.canvas} ref={canvasRef}>
|
||||
<div className={styles.page}>
|
||||
{
|
||||
/* render blocks */
|
||||
article.blocks.map((block, key) => {
|
||||
return <OnboardingBlock key={key} mode={mode} {...block} />;
|
||||
})
|
||||
}
|
||||
<div className={styles.orbit}>
|
||||
<div
|
||||
ref={docRef}
|
||||
className={clsx(styles.orbitItem, styles.doc)}
|
||||
data-scroll={scrollable}
|
||||
>
|
||||
<div className={styles.canvas} ref={canvasRef}>
|
||||
<div className={styles.page}>
|
||||
{
|
||||
/* render blocks */
|
||||
article.blocks.map((block, key) => {
|
||||
return <OnboardingBlock key={key} mode={mode} {...block} />;
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-no-drag className={styles.noDragWrapper}>
|
||||
<header className={styles.header}>
|
||||
<Button size="extraLarge" onClick={onBack}>
|
||||
Back
|
||||
</Button>
|
||||
<EdgelessSwitchButtons
|
||||
mode={mode}
|
||||
onSwitchToPageMode={onSwitchToPageMode}
|
||||
onSwitchToEdgelessMode={onSwitchToEdgelessMode}
|
||||
/>
|
||||
<Button size="extraLarge" type="primary" onClick={onNextClick}>
|
||||
Next
|
||||
</Button>
|
||||
</header>
|
||||
|
||||
<div className={styles.toolbar}>
|
||||
<ToolbarSVG />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-no-drag className={styles.noDragWrapper}>
|
||||
<header className={styles.header}>
|
||||
<Button size="extraLarge" onClick={onBack}>
|
||||
Back
|
||||
<div className={clsx(styles.orbitItem, styles.wellDone)}>
|
||||
<div
|
||||
className={styles.wellDoneEnterAnim}
|
||||
onDoubleClick={() => setMode('edgeless')}
|
||||
>
|
||||
<Logo />
|
||||
</div>
|
||||
<h1 className={clsx(styles.wellDoneTitle, styles.wellDoneEnterAnim)}>
|
||||
Well Done !
|
||||
</h1>
|
||||
<p className={clsx(styles.wellDoneContent, styles.wellDoneEnterAnim)}>
|
||||
You have the flexibility to switch between Page and Edgeless
|
||||
<br /> Mode at any point during content creation.
|
||||
</p>
|
||||
<Button
|
||||
className={styles.wellDoneEnterAnim}
|
||||
onClick={onNextClick}
|
||||
type="primary"
|
||||
size="extraLarge"
|
||||
style={{ marginTop: 40 }}
|
||||
>
|
||||
Get Start
|
||||
</Button>
|
||||
<EdgelessSwitchButtons
|
||||
mode={mode}
|
||||
onSwitchToPageMode={onSwitchToPageMode}
|
||||
onSwitchToEdgelessMode={onSwitchToEdgelessMode}
|
||||
/>
|
||||
<Button size="extraLarge" type="primary" onClick={onNextClick}>
|
||||
Next
|
||||
</Button>
|
||||
</header>
|
||||
|
||||
<div className={styles.toolbar}>
|
||||
<ToolbarSVG />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -20,11 +20,16 @@ const fadeOut = keyframes({
|
||||
export const unfoldingWrapper = style([
|
||||
paperLocation,
|
||||
{
|
||||
vars: {
|
||||
'--hover-offset-y': '0px',
|
||||
'--hover-scale': '1',
|
||||
},
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
|
||||
transform: 'rotate(var(--toRotateZ))',
|
||||
transform:
|
||||
'rotate(var(--toRotateZ)) translateY(var(--hover-offset-y)) scale(var(--hover-scale))',
|
||||
cursor: 'pointer',
|
||||
|
||||
backgroundColor: onboardingVars.paper.bg,
|
||||
@ -38,6 +43,13 @@ export const unfoldingWrapper = style([
|
||||
|
||||
transition: `all 0.23s ease, width ${unfolding.sizeTransition}, height ${unfolding.sizeTransition}, transform ${unfolding.transformTransition}`,
|
||||
|
||||
':hover': {
|
||||
vars: {
|
||||
'--hover-offset-y': '-10px',
|
||||
'--hover-scale': '1.03',
|
||||
},
|
||||
},
|
||||
|
||||
'::before': {
|
||||
// hack border
|
||||
content: '""',
|
||||
@ -53,6 +65,9 @@ export const unfoldingWrapper = style([
|
||||
'&[data-fold="false"]': {
|
||||
vars: {
|
||||
'--toRotateZ': '0deg',
|
||||
// reset hover to avoid flickering
|
||||
'--hover-offset-y': '0px',
|
||||
'--hover-scale': '1',
|
||||
},
|
||||
width: onboardingVars.article.w,
|
||||
height: onboardingVars.article.h,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { globalStyle, style } from '@vanilla-extract/css';
|
||||
import { globalStyle, keyframes, style } from '@vanilla-extract/css';
|
||||
|
||||
// in case that we need to support dark mode later
|
||||
export const onboardingVars = {
|
||||
@ -23,16 +23,25 @@ export const onboardingVars = {
|
||||
transformTransition: '0.3s ease',
|
||||
},
|
||||
web: {
|
||||
bg: '#fafafa',
|
||||
bg: '#F4F4F5',
|
||||
windowShadow:
|
||||
'1px 18px 39px 0px rgba(0, 0, 0, 0.15), 5px 71px 71px 0px rgba(0, 0, 0, 0.09), 12px 160px 96px 0px rgba(0, 0, 0, 0.05), 20px 284px 114px 0px rgba(0, 0, 0, 0.01), 32px 443px 124px 0px rgba(0, 0, 0, 0.00)',
|
||||
},
|
||||
|
||||
article: {
|
||||
w: '1200px',
|
||||
h: '800px',
|
||||
r: '8px',
|
||||
},
|
||||
edgeless: {
|
||||
w: '1200px',
|
||||
h: '800px',
|
||||
r: '8px',
|
||||
},
|
||||
wellDone: {
|
||||
w: '800px',
|
||||
h: '600px',
|
||||
r: '12px',
|
||||
},
|
||||
|
||||
canvas: {
|
||||
@ -62,6 +71,11 @@ export const perspective = style({
|
||||
transformStyle: 'preserve-3d',
|
||||
});
|
||||
|
||||
export const fadeIn = keyframes({
|
||||
from: { opacity: 0 },
|
||||
to: { opacity: 1 },
|
||||
});
|
||||
|
||||
export const onboarding = style([
|
||||
perspective,
|
||||
{
|
||||
@ -80,9 +94,17 @@ export const onboarding = style([
|
||||
inset: 0,
|
||||
background: onboardingVars.web.bg,
|
||||
transform: 'translateZ(-1000px) scale(2)',
|
||||
transition: 'opacity 0.3s ease',
|
||||
},
|
||||
'&[data-is-desktop="true"]::after': {
|
||||
content: 'unset',
|
||||
animation: `${fadeIn} 0.8s linear`,
|
||||
// content: 'unset',
|
||||
background:
|
||||
// 'linear-gradient(180deg, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0) 99.58%)',
|
||||
'linear-gradient(180deg, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0) 80%)',
|
||||
},
|
||||
'&[data-is-window="true"][data-is-desktop="true"]::after': {
|
||||
opacity: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -47,7 +47,7 @@ export const OnboardingBlock = ({
|
||||
const blockStyles = {
|
||||
...baseStyles,
|
||||
...style,
|
||||
...customStyle?.[mode],
|
||||
...customStyle?.[mode === 'page' ? 'page' : 'edgeless'],
|
||||
} as CSSProperties;
|
||||
|
||||
return (
|
||||
@ -58,7 +58,7 @@ export const OnboardingBlock = ({
|
||||
}}
|
||||
className={onboardingBlock}
|
||||
data-mode={mode}
|
||||
data-bg-mode={bg && mode === 'edgeless'}
|
||||
data-bg-mode={bg && mode !== 'page'}
|
||||
data-invisible={mode === 'page' && edgelessOnly}
|
||||
>
|
||||
{children}
|
||||
|
@ -109,7 +109,7 @@ export const onboardingBlock = style([
|
||||
'&:last-child': {
|
||||
marginBottom: 0,
|
||||
},
|
||||
'&[data-mode="edgeless"]': {
|
||||
'&[data-mode="edgeless"], &[data-mode="well-done"]': {
|
||||
transition: `all ${onboardingVars.block.transition} var(--enter-delay)`,
|
||||
},
|
||||
'&[data-mode="page"]': {
|
||||
|
@ -3,7 +3,7 @@ import type { PropsWithChildren, ReactNode } from 'react';
|
||||
|
||||
export type OnboardingStep = 'enter' | 'unfold' | 'edgeless-switch';
|
||||
export type ArticleId = '0' | '1' | '2' | '3' | '4';
|
||||
export type EdgelessSwitchMode = 'edgeless' | 'page';
|
||||
export type EdgelessSwitchMode = 'edgeless' | 'page' | 'well-done';
|
||||
|
||||
/**
|
||||
* Paper enter animation options
|
||||
@ -77,10 +77,7 @@ export interface OnboardingBlockOption extends PropsWithChildren {
|
||||
style?: CSSProperties;
|
||||
|
||||
/** customize style for different mode */
|
||||
customStyle?: {
|
||||
page?: CSSProperties;
|
||||
edgeless?: CSSProperties;
|
||||
};
|
||||
customStyle?: Partial<Record<EdgelessSwitchMode, CSSProperties>>;
|
||||
|
||||
/** attach a sub block to current block */
|
||||
sub?: OnboardingBlockOption;
|
||||
|
Loading…
Reference in New Issue
Block a user