Skip to content

Commit

Permalink
chore: auto merge branches (ant-design#44739)
Browse files Browse the repository at this point in the history
chore: merge master into feature
  • Loading branch information
github-actions[bot] authored Sep 10, 2023
2 parents eff6743 + 5b75f3f commit 4450178
Show file tree
Hide file tree
Showing 30 changed files with 2,307 additions and 1,733 deletions.
126 changes: 126 additions & 0 deletions .dumi/hooks/useThemeAnimation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { useEffect, useRef } from 'react';
import { removeCSS, updateCSS } from 'rc-util/lib/Dom/dynamicCSS';

import theme from '../../components/theme';

const viewTransitionStyle = `
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
.dark::view-transition-old(root) {
z-index: 1;
}
.dark::view-transition-new(root) {
z-index: 999;
}
::view-transition-old(root) {
z-index: 999;
}
::view-transition-new(root) {
z-index: 1;
}
`;

const useThemeAnimation = () => {
const {
token: { colorBgElevated },
} = theme.useToken();

const animateRef = useRef<{
colorBgElevated: string;
}>({
colorBgElevated,
});

const startAnimationTheme = (clipPath: string[], isDark: boolean) => {
updateCSS(
`
* {
transition: none !important;
}
`,
'disable-transition',
);

document.documentElement
.animate(
{
clipPath: isDark ? [...clipPath].reverse() : clipPath,
},
{
duration: 500,
easing: 'ease-in',
pseudoElement: isDark ? '::view-transition-old(root)' : '::view-transition-new(root)',
},
)
.addEventListener('finish', () => {
removeCSS('disable-transition');
});
};

const toggleAnimationTheme = (event: MouseEvent, isDark: boolean) => {
// @ts-ignore
if (!(event && typeof document.startViewTransition === 'function')) return;
const x = event.clientX;
const y = event.clientY;
const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
updateCSS(
`
[data-prefers-color='dark'] {
color-scheme: light !important;
}
[data-prefers-color='light'] {
color-scheme: dark !important;
}
`,
'color-scheme',
);
document
// @ts-ignore
.startViewTransition(async () => {
// wait for theme change end
while (colorBgElevated === animateRef.current.colorBgElevated) {
// eslint-disable-next-line no-await-in-loop
await new Promise((resolve) => {
setTimeout(resolve, 1000 / 60);
});
}
const root = document.documentElement;
root.classList.remove(isDark ? 'dark' : 'light');
root.classList.add(isDark ? 'light' : 'dark');
})
.ready.then(() => {
const clipPath = [
`circle(0px at ${x}px ${y}px)`,
`circle(${endRadius}px at ${x}px ${y}px)`,
];
removeCSS('color-scheme');
startAnimationTheme(clipPath, isDark);
});
};

// inject transition style
useEffect(() => {
// @ts-ignore
if (typeof document.startViewTransition === 'function') {
updateCSS(viewTransitionStyle, 'view-transition-style');
}
}, []);

useEffect(() => {
if (colorBgElevated !== animateRef.current.colorBgElevated) {
animateRef.current.colorBgElevated = colorBgElevated;
}
}, [colorBgElevated]);

return toggleAnimationTheme;
};

export default useThemeAnimation;
28 changes: 17 additions & 11 deletions .dumi/pages/index/components/Group.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,42 @@
import * as React from 'react';
import { useContext } from 'react';
import { useTheme } from 'antd-style';
import { Typography } from 'antd';
import { useTheme } from 'antd-style';

import SiteContext from '../../../theme/slots/SiteContext';

export interface GroupMaskProps {
style?: React.CSSProperties;
children?: React.ReactNode;
disabled?: boolean;
onMouseMove?: React.MouseEventHandler<HTMLDivElement>;
onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;
onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;
}

export function GroupMask({ children, style, disabled }: GroupMaskProps) {
export const GroupMask: React.FC<GroupMaskProps> = (props) => {
const { children, style, disabled, onMouseMove, onMouseEnter, onMouseLeave } = props;
const additionalStyle: React.CSSProperties = disabled
? {}
: {
position: 'relative',
background: `rgba(255,255,255,0.1)`,
background: `rgba(255, 255, 255, 0.1)`,
backdropFilter: `blur(25px)`,
zIndex: 1,
};

return (
<div
className="site-mask"
style={{
position: 'relative',
...style,
...additionalStyle,
}}
style={{ position: 'relative', ...style, ...additionalStyle }}
onMouseMove={onMouseMove}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
{children}
</div>
);
}
};

export interface GroupProps {
id?: string;
Expand All @@ -48,7 +52,7 @@ export interface GroupProps {
decoration?: React.ReactNode;
}

export default function Group(props: GroupProps) {
const Group: React.FC<GroupProps> = (props) => {
const { id, title, titleColor, description, children, decoration, background, collapse } = props;
const token = useTheme();
const { isMobile } = useContext(SiteContext);
Expand Down Expand Up @@ -114,4 +118,6 @@ export default function Group(props: GroupProps) {
</GroupMask>
</div>
);
}
};

export default Group;
11 changes: 7 additions & 4 deletions .dumi/pages/index/components/PreviewBanner/ComponentsBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,17 @@ const useStyle = createStyles(({ token, css }) => {

export interface ComponentsBlockProps {
className?: string;
style?: React.CSSProperties;
}

export default function ComponentsBlock(props: ComponentsBlockProps) {
const { className } = props;
const ComponentsBlock: React.FC<ComponentsBlockProps> = (props) => {
const { className, style } = props;

const [locale] = useLocale(locales);
const { styles } = useStyle();

return (
<div className={classNames(className, styles.holder)}>
<div className={classNames(className, styles.holder)} style={style}>
<ModalPanel title="Ant Design 5.0" width="100%">
{locale.text}
</ModalPanel>
Expand Down Expand Up @@ -253,4 +254,6 @@ export default function ComponentsBlock(props: ComponentsBlockProps) {
<Alert message="Ant Design love you!" type="success" />
</div>
);
}
};

export default ComponentsBlock;
15 changes: 10 additions & 5 deletions .dumi/pages/index/components/PreviewBanner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SiteContext from '../../../../theme/slots/SiteContext';
import * as utils from '../../../../theme/utils';
import { GroupMask } from '../Group';
import ComponentsBlock from './ComponentsBlock';
import useMouseTransform from './useMouseTransform';

const locales = {
cn: {
Expand Down Expand Up @@ -81,11 +82,12 @@ const useStyle = () => {
};
})();
};

export interface PreviewBannerProps {
children?: React.ReactNode;
}

export default function PreviewBanner(props: PreviewBannerProps) {
const PreviewBanner: React.FC<PreviewBannerProps> = (props) => {
const { children } = props;

const [locale] = useLocale(locales);
Expand All @@ -95,8 +97,10 @@ export default function PreviewBanner(props: PreviewBannerProps) {
const { pathname, search } = useLocation();
const isZhCN = utils.isZhCN(pathname);

const [componentsBlockStyle, mouseEvents] = useMouseTransform();

return (
<GroupMask>
<GroupMask {...mouseEvents}>
{/* Image Left Top */}
<img
style={{ position: 'absolute', left: isMobile ? -120 : 0, top: 0, width: 240 }}
Expand All @@ -112,7 +116,7 @@ export default function PreviewBanner(props: PreviewBannerProps) {

<div className={styles.holder}>
{/* Mobile not show the component preview */}
{!isMobile && <ComponentsBlock className={styles.block} />}
{!isMobile && <ComponentsBlock className={styles.block} style={componentsBlockStyle} />}

<Typography className={styles.typography}>
<h1>Ant Design 5.0</h1>
Expand All @@ -129,9 +133,10 @@ export default function PreviewBanner(props: PreviewBannerProps) {
<Button size="large">{locale.designLanguage}</Button>
</Link>
</Space>

<div className={styles.child}>{children}</div>
</div>
</GroupMask>
);
}
};

export default PreviewBanner;
73 changes: 73 additions & 0 deletions .dumi/pages/index/components/PreviewBanner/useMouseTransform.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React, { startTransition } from 'react';
import { ConfigProvider } from 'antd';

const getTransformRotateStyle = (
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
currentTarget: EventTarget & HTMLDivElement,
multiple: number,
isRTL: boolean,
): string => {
const box = currentTarget?.getBoundingClientRect();
const calcX = -(event.clientY - box.y - box.height / 2) / multiple;
const calcY = (event.clientX - box.x - box.width / 2) / multiple;
return isRTL
? `rotate3d(${24 + calcX}, ${83 + calcY}, -45, 57deg)`
: `rotate3d(${24 + calcX}, ${-83 + calcY}, 45, 57deg)`;
};

const useMouseTransform = ({ transitionDuration = 500, multiple = 36 } = {}) => {
const [componentsBlockStyle, setComponentsBlockStyle] = React.useState<React.CSSProperties>({});

const { direction } = React.useContext(ConfigProvider.ConfigContext);

const isRTL = direction === 'rtl';

const onMouseMove: React.MouseEventHandler<HTMLDivElement> = (event) => {
const { currentTarget } = event;
startTransition(() => {
setComponentsBlockStyle((style) => ({
...style,
transform: getTransformRotateStyle(event, currentTarget, multiple, isRTL),
}));
});
};

const onMouseEnter: React.MouseEventHandler<HTMLDivElement> = () => {
startTransition(() => {
setComponentsBlockStyle((style) => ({
...style,
transition: `transform ${transitionDuration / 1000}s`,
}));
});

setTimeout(() => {
startTransition(() => {
setComponentsBlockStyle((style) => ({
...style,
transition: '',
}));
});
}, transitionDuration);
};

const onMouseLeave: React.MouseEventHandler<HTMLDivElement> = () => {
startTransition(() => {
setComponentsBlockStyle((style) => ({
...style,
transition: `transform ${transitionDuration / 1000}s`,
transform: '',
}));
});
};

return [
componentsBlockStyle,
{
onMouseMove,
onMouseEnter,
onMouseLeave,
},
] as const;
};

export default useMouseTransform;
20 changes: 14 additions & 6 deletions .dumi/theme/common/ThemeSwitch/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react';
import { BgColorsOutlined, SmileOutlined } from '@ant-design/icons';
import { FloatButton } from 'antd';
import { useTheme } from 'antd-style';
import { CompactTheme, DarkTheme } from 'antd-token-previewer/es/icons';
// import { Motion } from 'antd-token-previewer/es/icons';
import { FormattedMessage, Link, useLocation } from 'dumi';
import React from 'react';
import { useTheme } from 'antd-style';
import { FloatButton } from 'antd';

import useThemeAnimation from '../../../hooks/useThemeAnimation';
import { getLocalizedPathname, isZhCN } from '../../utils';
import ThemeIcon from './ThemeIcon';

Expand All @@ -22,6 +24,9 @@ const ThemeSwitch: React.FC<ThemeSwitchProps> = (props) => {

// const isMotionOff = value.includes('motion-off');
const isHappyWork = value.includes('happy-work');
const isDark = value.includes('dark');

const toggleAnimationTheme = useThemeAnimation();

return (
<FloatButton.Group
Expand All @@ -42,9 +47,12 @@ const ThemeSwitch: React.FC<ThemeSwitchProps> = (props) => {
</Link>
<FloatButton
icon={<DarkTheme />}
type={value.includes('dark') ? 'primary' : 'default'}
onClick={() => {
if (value.includes('dark')) {
type={isDark ? 'primary' : 'default'}
onClick={(e) => {
// Toggle animation when switch theme
toggleAnimationTheme(e, isDark);

if (isDark) {
onChange(value.filter((theme) => theme !== 'dark'));
} else {
onChange([...value, 'dark']);
Expand Down
Loading

0 comments on commit 4450178

Please sign in to comment.