From 7e4139815e5a419759f6704af8c30d722b7e5d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Mon, 9 Jan 2023 14:08:02 +0800 Subject: [PATCH] chore: init wrapper --- .dumi/theme/layouts/GlobalLayout.tsx | 15 +++--- components/_util/wave/WaveEffect.tsx | 21 +++++--- components/_util/wave/index.ts | 6 +-- components/_util/wave/style.ts | 7 +-- components/_util/wave/useWave.ts | 11 ++-- components/button/demo/basic.tsx | 2 +- components/config-provider/context.ts | 27 +++------- components/config-provider/index.tsx | 5 ++ components/theme/index.ts | 2 + components/theme/internal.ts | 6 ++- components/theme/themesToken/happy/index.tsx | 11 ++-- .../theme/themesToken/happy/style/wave.ts | 32 +++++++++++ components/theme/themesToken/happy/wave.tsx | 53 +++++++++++++++---- 13 files changed, 133 insertions(+), 65 deletions(-) create mode 100644 components/theme/themesToken/happy/style/wave.ts diff --git a/.dumi/theme/layouts/GlobalLayout.tsx b/.dumi/theme/layouts/GlobalLayout.tsx index 856ed438d8..2c5a01ed0a 100644 --- a/.dumi/theme/layouts/GlobalLayout.tsx +++ b/.dumi/theme/layouts/GlobalLayout.tsx @@ -36,14 +36,6 @@ const getAlgorithm = (themes: ThemeName[] = []) => }) .filter((algorithm) => algorithm); -const getComponents = (themes: ThemeName[] = []): OverrideToken => { - if (themes.includes('happy')) { - return antdTheme.happyThemeToken; - } - - return null; -}; - const GlobalLayout: React.FC = () => { const outlet = useOutlet(); const { pathname } = useLocation(); @@ -115,14 +107,19 @@ const GlobalLayout: React.FC = () => { [isMobile, direction, updateSiteConfig, theme], ); + // Happy Work Theme + const components = theme.includes('happy') ? antdTheme.happyThemeToken.token : null; + const wave = theme.includes('happy') ? antdTheme.happyThemeToken.wave : null; + return ( {outlet} {!pathname.startsWith('/~demos') && ( diff --git a/components/_util/wave/WaveEffect.tsx b/components/_util/wave/WaveEffect.tsx index 4c68009b6d..5eb3296420 100644 --- a/components/_util/wave/WaveEffect.tsx +++ b/components/_util/wave/WaveEffect.tsx @@ -4,7 +4,8 @@ import raf from 'rc-util/lib/raf'; import { render, unmount } from 'rc-util/lib/React/render'; import classNames from 'classnames'; import { getTargetWaveColor } from './util'; -import type { GlobalToken } from '../../theme/interface'; +import type { ConfigProviderProps } from '../../config-provider'; +import type { useToken } from '../../theme/internal'; function validateNum(value: number) { return Number.isNaN(value) ? 0 : value; @@ -123,20 +124,26 @@ const WaveEffect: React.FC = (props) => { export interface WaveWrapperProps { className: string; target: HTMLElement; - token: GlobalToken; + token: ReturnType; + wave: ConfigProviderProps['wave']; } function WaveWrapper(props: WaveWrapperProps) { - const { token, target } = props; + const { token, target, wave } = props; - if (token?.Wave?.render) { - return token?.Wave?.render(target, token); + if (wave?.render) { + return wave?.render(target, token) as React.ReactElement; } return ; } -export default function showWaveEffect(node: HTMLElement, className: string, token: GlobalToken) { +export default function showWaveEffect( + node: HTMLElement, + className: string, + token: ReturnType, + wave: ConfigProviderProps['wave'], +) { // Create holder const holder = document.createElement('div'); holder.style.position = 'absolute'; @@ -144,5 +151,5 @@ export default function showWaveEffect(node: HTMLElement, className: string, tok holder.style.top = `0px`; node.parentElement?.appendChild(holder); - render(, holder); + render(, holder); } diff --git a/components/_util/wave/index.ts b/components/_util/wave/index.ts index 8595d8c612..dac3f41b82 100644 --- a/components/_util/wave/index.ts +++ b/components/_util/wave/index.ts @@ -16,16 +16,16 @@ export interface WaveProps { const Wave: React.FC = (props) => { const { children, disabled } = props; - const { getPrefixCls } = useContext(ConfigContext); + const { getPrefixCls, wave } = useContext(ConfigContext); const containerRef = useRef(null); // ============================== Style =============================== const prefixCls = getPrefixCls('wave'); const [, hashId] = useStyle(prefixCls); - const [, token] = useToken(); + const token = useToken(); // =============================== Wave =============================== - const showWave = useWave(containerRef, classNames(prefixCls, hashId), token); + const showWave = useWave(containerRef, classNames(prefixCls, hashId), token, wave); // ============================== Effect ============================== React.useEffect(() => { diff --git a/components/_util/wave/style.ts b/components/_util/wave/style.ts index f455dccc3b..b412e86e3d 100644 --- a/components/_util/wave/style.ts +++ b/components/_util/wave/style.ts @@ -1,10 +1,7 @@ import { genComponentStyleHook } from '../../theme/internal'; -import type { AliasToken, FullToken, GenerateStyle } from '../../theme/internal'; +import type { FullToken, GenerateStyle } from '../../theme/internal'; -export interface ComponentToken { - /** @deprecated Dev only. Do not use. */ - render?: (target: HTMLElement, token: AliasToken) => React.ReactElement; -} +export interface ComponentToken {} export interface WaveToken extends FullToken<'Wave'> {} diff --git a/components/_util/wave/useWave.ts b/components/_util/wave/useWave.ts index 50fb8aa1bd..61a1fe37be 100644 --- a/components/_util/wave/useWave.ts +++ b/components/_util/wave/useWave.ts @@ -1,16 +1,19 @@ -import type { ComponentToken } from './style'; +import useEvent from 'rc-util/lib/hooks/useEvent'; +import type { ConfigProviderProps } from '../../config-provider'; import showWaveEffect from './WaveEffect'; +import type { useToken } from '../../theme/internal'; export default function useWave( nodeRef: React.RefObject, className: string, - waveToken?: ComponentToken, + token: ReturnType, + wave: ConfigProviderProps['wave'], ): VoidFunction { function showWave() { const node = nodeRef.current!; - showWaveEffect(node, className, waveToken); + showWaveEffect(node, className, token, wave); } - return showWave; + return useEvent(showWave); } diff --git a/components/button/demo/basic.tsx b/components/button/demo/basic.tsx index da2b2fc5bd..db5acb80f6 100644 --- a/components/button/demo/basic.tsx +++ b/components/button/demo/basic.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Button, Space } from 'antd'; const App: React.FC = () => ( - + diff --git a/components/config-provider/context.ts b/components/config-provider/context.ts index ba30dbeb7c..fc9dcce4ce 100644 --- a/components/config-provider/context.ts +++ b/components/config-provider/context.ts @@ -6,6 +6,7 @@ import type { Locale } from '../locale'; import type { AliasToken, MapToken, OverrideToken, SeedToken } from '../theme/interface'; import type { RenderEmptyHandler } from './defaultRenderEmpty'; import type { SizeType } from './SizeContext'; +import type { ConfigProviderProps } from '.'; export const defaultIconPrefixCls = 'anticon'; @@ -34,7 +35,11 @@ export interface ThemeConfig { inherit?: boolean; } -export interface ConfigConsumerProps { +export interface ConfigConsumerProps + extends Pick< + ConfigProviderProps, + 'input' | 'pagination' | 'space' | 'form' | 'select' | 'pageHeader' | 'wave' + > { getTargetContainer?: () => HTMLElement; getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement; rootPrefixCls?: string; @@ -43,31 +48,11 @@ export interface ConfigConsumerProps { renderEmpty?: RenderEmptyHandler; csp?: CSPConfig; autoInsertSpaceInButton?: boolean; - input?: { - autoComplete?: string; - }; - pagination?: { - showSizeChanger?: boolean; - }; locale?: Locale; - pageHeader?: { - ghost: boolean; - }; direction?: DirectionType; - space?: { - size?: SizeType | number; - }; virtual?: boolean; dropdownMatchSelectWidth?: boolean; - form?: { - requiredMark?: RequiredMark; - colon?: boolean; - scrollToFirstError?: Options | boolean; - }; theme?: ThemeConfig; - select?: { - showSearch?: boolean; - }; } const defaultGetPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => { diff --git a/components/config-provider/index.tsx b/components/config-provider/index.tsx index 2d0d808bba..a4d41b02d9 100644 --- a/components/config-provider/index.tsx +++ b/components/config-provider/index.tsx @@ -12,6 +12,7 @@ import LocaleProvider, { ANT_MARK } from '../locale'; import LocaleReceiver from '../locale/LocaleReceiver'; import defaultLocale from '../locale/en_US'; import { DesignTokenContext } from '../theme/internal'; +import type { useToken } from '../theme/internal'; import defaultSeedToken from '../theme/themes/seed'; import type { ConfigConsumerProps, CSPConfig, DirectionType, Theme, ThemeConfig } from './context'; import { ConfigConsumer, ConfigContext, defaultIconPrefixCls } from './context'; @@ -55,6 +56,7 @@ const PASSED_PROPS: Exclude) => React.ReactNode; + }; locale?: Locale; pageHeader?: { ghost: boolean; diff --git a/components/theme/index.ts b/components/theme/index.ts index cf7e143906..06b8d35861 100644 --- a/components/theme/index.ts +++ b/components/theme/index.ts @@ -26,5 +26,7 @@ export default { defaultAlgorithm, darkAlgorithm, compactAlgorithm, + + // TODO: Remove this after to be third part package happyThemeToken, }; diff --git a/components/theme/internal.ts b/components/theme/internal.ts index 24f378a518..dfefa16539 100644 --- a/components/theme/internal.ts +++ b/components/theme/internal.ts @@ -57,7 +57,11 @@ export const DesignTokenContext = React.createContext<{ }>(defaultConfig); // ================================== Hook ================================== -export function useToken(): [Theme, GlobalToken, string] { +export function useToken(): [ + theme: Theme, + globalToken: GlobalToken, + hashId: string, +] { const { token: rootDesignToken, hashed, diff --git a/components/theme/themesToken/happy/index.tsx b/components/theme/themesToken/happy/index.tsx index 1e9b07a6f6..98c826938d 100644 --- a/components/theme/themesToken/happy/index.tsx +++ b/components/theme/themesToken/happy/index.tsx @@ -1,8 +1,9 @@ import type { OverrideToken } from '../../interface'; -import Wave from './wave'; +import wave from './wave'; -const token: OverrideToken = { - Wave, -}; +const token: OverrideToken = {}; -export default token; +export default { + token, + wave, +}; diff --git a/components/theme/themesToken/happy/style/wave.ts b/components/theme/themesToken/happy/style/wave.ts new file mode 100644 index 0000000000..2f7c67b84c --- /dev/null +++ b/components/theme/themesToken/happy/style/wave.ts @@ -0,0 +1,32 @@ +import { useStyleRegister } from '@ant-design/cssinjs'; +import type { UseTokenType } from '../wave'; + +export default function useStyle(tokenConfig: UseTokenType) { + const [theme, token, hashId] = tokenConfig; + + useStyleRegister({ theme, token, hashId, path: ['Customize', 'Wave', 'Effect'] }, () => { + const prefixCls = '.happy-wave'; + + return [ + { + [prefixCls]: { + position: 'fixed', + left: 0, + top: 0, + width: 20, + height: 20, + background: 'green', + + [`${prefixCls}-dot`]: { + position: 'absolute', + left: 0, + top: 0, + width: 10, + height: 10, + background: 'red', + }, + }, + }, + ]; + }); +} diff --git a/components/theme/themesToken/happy/wave.tsx b/components/theme/themesToken/happy/wave.tsx index 99eeab2d86..8c78061b22 100644 --- a/components/theme/themesToken/happy/wave.tsx +++ b/components/theme/themesToken/happy/wave.tsx @@ -1,23 +1,58 @@ +import classNames from 'classnames'; +import CSSMotion from 'rc-motion'; import * as React from 'react'; -import type { GlobalToken, OverrideToken } from '../../interface'; -import type { ComponentToken } from '../../../_util/wave/style'; +import type { ConfigProviderProps } from '../../../config-provider'; +import useWaveStyle from './style/wave'; + +export type WaveRender = Required['wave']>['render']; +export type UseTokenType = Parameters[1]; interface HappyWaveProps { target: HTMLElement; - token: GlobalToken; + token: UseTokenType; } function HappyWave({ target, token }: HappyWaveProps) { - React.useEffect(() => {}, []); + const prefixCls = 'happy-wave'; + const dotPrefixCls = `${prefixCls}-dot`; + + const [left, setLeft] = React.useState(0); + const [top, setTop] = React.useState(0); + + const [, , hashId] = token; + useWaveStyle(token); + + React.useEffect(() => { + const rect = target.getBoundingClientRect(); + + setLeft(rect.left + rect.width / 2); + setTop(rect.top + rect.height / 2); + }, []); + + return ( +
+ {new Array(7).fill(null).map((_, index) => { + const name = `${dotPrefixCls}-${index}`; - return
2333
; + return ( + + {() =>
} + + ); + })} +
+ ); } -const renderWave: ComponentToken['render'] = (target, token) => ( - -); +const renderWave: WaveRender = (target, token) => ; -const Wave: OverrideToken['Wave'] = { +const Wave: ConfigProviderProps['wave'] = { render: renderWave, };