From fc0f0d8a966257b43dbe57e23aefa44ebf57ca69 Mon Sep 17 00:00:00 2001 From: bqy_fe <1743369777@qq.com> Date: Tue, 7 Feb 2023 09:57:31 +0800 Subject: [PATCH] refactor(empty): less to cssinjs (#6230) * refactor(empty): less to cssinjs * chore: remove unuse code * fix: reactivity lose --- components/empty/empty.tsx | 101 +++++++++------ components/empty/index.tsx | 123 +++++++++--------- components/empty/simple.tsx | 52 +++++--- components/empty/style/index.less | 151 ----------------------- components/empty/style/index.ts | 80 ++++++++++++ components/empty/style/index.tsx | 2 - components/empty/style/rtl.less | 10 -- components/theme/interface/components.ts | 4 +- 8 files changed, 244 insertions(+), 279 deletions(-) delete mode 100644 components/empty/style/index.less create mode 100644 components/empty/style/index.ts delete mode 100644 components/empty/style/index.tsx delete mode 100644 components/empty/style/rtl.less diff --git a/components/empty/empty.tsx b/components/empty/empty.tsx index a4853758b..090326bf2 100644 --- a/components/empty/empty.tsx +++ b/components/empty/empty.tsx @@ -1,44 +1,73 @@ -import useConfigInject from '../config-provider/hooks/useConfigInject'; +import { useToken } from '../theme/internal'; +import { TinyColor } from '@ctrl/tinycolor'; +import type { CSSProperties } from 'vue'; +import { defineComponent, computed } from 'vue'; -const Empty = () => { - const { getPrefixCls } = useConfigInject('empty', {}); - const prefixCls = getPrefixCls('empty-img-default'); +const Empty = defineComponent({ + setup() { + const [, token] = useToken(); - return ( - - - - + const themeStyle = computed(() => { + const bgColor = new TinyColor(token.value.colorBgBase); + + // Dark Theme need more dark of this + if (bgColor.toHsl().l < 0.5) { + return { + opacity: 0.65, + }; + } + return {}; + }); + + return () => ( + + + + + + + + + - - - + + + + - - - - - - - - ); -}; + + ); + }, +}); Empty.PRESENTED_IMAGE_DEFAULT = true; diff --git a/components/empty/index.tsx b/components/empty/index.tsx index 4565a7b85..b74d7b85f 100644 --- a/components/empty/index.tsx +++ b/components/empty/index.tsx @@ -1,14 +1,16 @@ -import type { CSSProperties, FunctionalComponent, PropType } from 'vue'; +import { defineComponent } from 'vue'; +import type { CSSProperties, PropType, ExtractPropTypes } from 'vue'; import classNames from '../_util/classNames'; import LocaleReceiver from '../locale-provider/LocaleReceiver'; import DefaultEmptyImg from './empty'; import SimpleEmptyImg from './simple'; import { filterEmpty } from '../_util/props-util'; import PropTypes from '../_util/vue-types'; -import type { VueNode } from '../_util/type'; import { withInstall } from '../_util/type'; import useConfigInject from '../config-provider/hooks/useConfigInject'; +import useStyle from './style'; + const defaultEmptyImg = ; const simpleEmptyImg = ; @@ -16,70 +18,73 @@ interface Locale { description?: string; } -export interface EmptyProps { - prefixCls?: string; - class?: any; - style?: string | CSSProperties; - imageStyle?: CSSProperties; - image?: VueNode | null; - description?: VueNode; -} +export const emptyProps = () => ({ + prefixCls: String, + class: PropTypes.any, + style: [String, Object] as PropType, + imageStyle: Object as PropType, + image: PropTypes.any, + description: PropTypes.any, +}); -interface EmptyType extends FunctionalComponent { - displayName: string; - PRESENTED_IMAGE_DEFAULT: VueNode; - PRESENTED_IMAGE_SIMPLE: VueNode; -} +export type EmptyProps = Partial>>; -const Empty: EmptyType = (props, { slots = {}, attrs }) => { - const { direction, prefixCls: prefixClsRef } = useConfigInject('empty', props); - const prefixCls = prefixClsRef.value; +const Empty = defineComponent({ + name: 'AEmpty', + inheritAttrs: false, + props: emptyProps(), + setup(props, { slots = {}, attrs }) { + const { direction, prefixCls: prefixClsRef } = useConfigInject('empty', props); - const { - image = defaultEmptyImg, - description = slots.description?.() || undefined, - imageStyle, - class: className = '', - ...restProps - } = { ...props, ...attrs }; + const [wrapSSR, hashId] = useStyle(prefixClsRef); - return ( - { - const des = typeof description !== 'undefined' ? description : locale.description; - const alt = typeof des === 'string' ? des : 'empty'; - let imageNode: EmptyProps['image'] = null; + return () => { + const prefixCls = prefixClsRef.value; + const { + image = defaultEmptyImg, + description = slots.description?.() || undefined, + imageStyle, + class: className = '', + ...restProps + } = { ...props, ...attrs }; - if (typeof image === 'string') { - imageNode = ; - } else { - imageNode = image; - } + return wrapSSR( + { + const des = typeof description !== 'undefined' ? description : locale.description; + const alt = typeof des === 'string' ? des : 'empty'; + let imageNode: EmptyProps['image'] = null; - return ( - - - {imageNode} - - {des && {des}} - {slots.default && ( - - )} - - ); - }} - /> - ); -}; + if (typeof image === 'string') { + imageNode = ; + } else { + imageNode = image; + } -Empty.displayName = 'AEmpty'; + return ( + + + {imageNode} + + {des && {des}} + {slots.default && ( + + )} + + ); + }} + />, + ); + }; + }, +}); Empty.PRESENTED_IMAGE_DEFAULT = defaultEmptyImg; Empty.PRESENTED_IMAGE_SIMPLE = simpleEmptyImg; diff --git a/components/empty/simple.tsx b/components/empty/simple.tsx index 2be63b3a0..8ae99ecc8 100644 --- a/components/empty/simple.tsx +++ b/components/empty/simple.tsx @@ -1,25 +1,39 @@ -import useConfigInject from '../config-provider/hooks/useConfigInject'; +import { TinyColor } from '@ctrl/tinycolor'; +import { computed, defineComponent } from 'vue'; +import { useToken } from '../theme/internal'; -const Simple = () => { - const { getPrefixCls } = useConfigInject('empty', {}); - const prefixCls = getPrefixCls('empty-img-simple'); +const Simple = defineComponent({ + setup() { + const [, token] = useToken(); - return ( - - - - - - + const color = computed(() => { + const { colorFill, colorFillTertiary, colorFillQuaternary, colorBgContainer } = token.value; + + return { + borderColor: new TinyColor(colorFill).onBackground(colorBgContainer).toHexString(), + shadowColor: new TinyColor(colorFillTertiary).onBackground(colorBgContainer).toHexString(), + contentColor: new TinyColor(colorFillQuaternary) + .onBackground(colorBgContainer) + .toHexString(), + }; + }); + + return () => ( + + + + + + + - - - ); -}; + + ); + }, +}); Simple.PRESENTED_IMAGE_SIMPLE = true; export default Simple; diff --git a/components/empty/style/index.less b/components/empty/style/index.less deleted file mode 100644 index c696372c1..000000000 --- a/components/empty/style/index.less +++ /dev/null @@ -1,151 +0,0 @@ -@import '../../style/themes/index'; -@import '../../style/mixins/index'; - -@empty-prefix-cls: ~'@{ant-prefix}-empty'; -@empty-img-prefix-cls: ~'@{ant-prefix}-empty-img'; - -.@{empty-prefix-cls} { - margin: 0 8px; - font-size: @empty-font-size; - line-height: @line-height-base; - text-align: center; - - &-image { - height: 100px; - margin-bottom: 8px; - - img { - height: 100%; - } - - svg { - height: 100%; - margin: auto; - } - } - - &-footer { - margin-top: 16px; - } - - // antd internal empty style - &-normal { - margin: 32px 0; - color: @disabled-color; - - .@{empty-prefix-cls}-image { - height: 40px; - } - } - - &-small { - margin: 8px 0; - color: @disabled-color; - - .@{empty-prefix-cls}-image { - height: 35px; - } - } -} - -.@{empty-img-prefix-cls}-default { - // not support the definition because the less variables have no meaning - & when (@theme = dark) { - &-ellipse { - fill: @white; - fill-opacity: 0.08; - } - - &-path { - &-1 { - fill: #262626; - } - - &-2 { - fill: url('#linearGradient-1'); - } - - &-3 { - fill: #595959; - } - - &-4 { - fill: #434343; - } - - &-5 { - fill: #595959; - } - } - - &-g { - fill: #434343; - } - } - & when not (@theme = dark) { - &-ellipse { - fill: #f5f5f5; - fill-opacity: 0.8; - } - - &-path { - &-1 { - fill: #aeb8c2; - } - - &-2 { - fill: url('#linearGradient-1'); - } - - &-3 { - fill: #f5f5f7; - } - - &-4 { - fill: #dce0e6; - } - - &-5 { - fill: #dce0e6; - } - } - - &-g { - fill: @white; - } - } -} - -.@{empty-img-prefix-cls}-simple { - // not support the definition because the less variables have no meaning - & when (@theme = dark) { - &-ellipse { - fill: @white; - fill-opacity: 0.08; - } - - &-g { - stroke: #434343; - } - - &-path { - fill: #262626; - stroke: #434343; - } - } - & when not (@theme = dark) { - &-ellipse { - fill: #f5f5f5; - } - - &-g { - stroke: #d9d9d9; - } - - &-path { - fill: #fafafa; - } - } -} - -@import './rtl'; diff --git a/components/empty/style/index.ts b/components/empty/style/index.ts new file mode 100644 index 000000000..f7d32ded4 --- /dev/null +++ b/components/empty/style/index.ts @@ -0,0 +1,80 @@ +import type { CSSObject } from '../../_util/cssinjs'; +import type { FullToken, GenerateStyle } from '../../theme/internal'; +import { genComponentStyleHook, mergeToken } from '../../theme/internal'; + +/** Component only token. Which will handle additional calculation of alias token */ +export interface ComponentToken {} + +interface EmptyToken extends FullToken<'Empty'> { + emptyImgCls: string; + emptyImgHeight: number; + emptyImgHeightSM: number; + emptyImgHeightMD: number; +} + +// ============================== Shared ============================== +const genSharedEmptyStyle: GenerateStyle = (token): CSSObject => { + const { componentCls, margin, marginXS, marginXL, fontSize, lineHeight } = token; + + return { + [componentCls]: { + marginInline: marginXS, + fontSize, + lineHeight, + textAlign: 'center', + + // 原来 &-image 没有父子结构,现在为了外层承担我们的hashId,改成父子结果 + [`${componentCls}-image`]: { + height: token.emptyImgHeight, + marginBottom: marginXS, + opacity: token.opacityImage, + + img: { + height: '100%', + }, + + svg: { + height: '100%', + margin: 'auto', + }, + }, + + // 原来 &-footer 没有父子结构,现在为了外层承担我们的hashId,改成父子结果 + [`${componentCls}-footer`]: { + marginTop: margin, + }, + + '&-normal': { + marginBlock: marginXL, + color: token.colorTextDisabled, + + [`${componentCls}-image`]: { + height: token.emptyImgHeightMD, + }, + }, + + '&-small': { + marginBlock: marginXS, + color: token.colorTextDisabled, + + [`${componentCls}-image`]: { + height: token.emptyImgHeightSM, + }, + }, + }, + }; +}; + +// ============================== Export ============================== +export default genComponentStyleHook('Empty', token => { + const { componentCls, controlHeightLG } = token; + + const emptyToken: EmptyToken = mergeToken(token, { + emptyImgCls: `${componentCls}-img`, + emptyImgHeight: controlHeightLG * 2.5, + emptyImgHeightMD: controlHeightLG, + emptyImgHeightSM: controlHeightLG * 0.875, + }); + + return [genSharedEmptyStyle(emptyToken)]; +}); diff --git a/components/empty/style/index.tsx b/components/empty/style/index.tsx deleted file mode 100644 index 3a3ab0de5..000000000 --- a/components/empty/style/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -import '../../style/index.less'; -import './index.less'; diff --git a/components/empty/style/rtl.less b/components/empty/style/rtl.less deleted file mode 100644 index bf3f6c46e..000000000 --- a/components/empty/style/rtl.less +++ /dev/null @@ -1,10 +0,0 @@ -@import '../../style/themes/index'; -@import '../../style/mixins/index'; - -@empty-prefix-cls: ~'@{ant-prefix}-empty'; - -.@{empty-prefix-cls} { - &-rtl { - direction: rtl; - } -} diff --git a/components/theme/interface/components.ts b/components/theme/interface/components.ts index 8e7a5bf3c..0b73ae637 100644 --- a/components/theme/interface/components.ts +++ b/components/theme/interface/components.ts @@ -14,7 +14,7 @@ import type { ComponentToken as ButtonComponentToken } from '../../button/style' import type { ComponentToken as DividerComponentToken } from '../../divider/style'; import type { ComponentToken as DropdownComponentToken } from '../../dropdown/style'; // import type { ComponentToken as DrawerComponentToken } from '../../drawer/style'; -// import type { ComponentToken as EmptyComponentToken } from '../../empty/style'; +import type { ComponentToken as EmptyComponentToken } from '../../empty/style'; // import type { ComponentToken as ImageComponentToken } from '../../image/style'; // import type { ComponentToken as InputNumberComponentToken } from '../../input-number/style'; // import type { ComponentToken as LayoutComponentToken } from '../../layout/style'; @@ -69,7 +69,7 @@ export interface ComponentTokenMap { Divider?: DividerComponentToken; // Drawer?: DrawerComponentToken; Dropdown?: DropdownComponentToken; - // Empty?: EmptyComponentToken; + Empty?: EmptyComponentToken; // FloatButton?: FloatButtonComponentToken; Form?: {}; Grid?: {};
{des}