refactor(empty): less to cssinjs (#6230)

* refactor(empty): less to cssinjs

* chore: remove unuse code

* fix: reactivity lose
pull/6236/head
bqy_fe 2023-02-07 09:57:31 +08:00 committed by GitHub
parent a205615af9
commit fc0f0d8a96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 244 additions and 279 deletions

View File

@ -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 (
<svg class={prefixCls} width="184" height="152" viewBox="0 0 184 152">
<g fill="none" fill-rule="evenodd">
<g transform="translate(24 31.67)">
<ellipse class={`${prefixCls}-ellipse`} cx="67.797" cy="106.89" rx="67.797" ry="12.668" />
const themeStyle = computed<CSSProperties>(() => {
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 () => (
<svg
style={themeStyle.value}
width="184"
height="152"
viewBox="0 0 184 152"
xmlns="http://www.w3.org/2000/svg"
>
<g fill="none" fill-rule="evenodd">
<g transform="translate(24 31.67)">
<ellipse
fill-opacity=".8"
fill="#F5F5F7"
cx="67.797"
cy="106.89"
rx="67.797"
ry="12.668"
/>
<path
d="M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z"
fill="#AEB8C2"
/>
<path
d="M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z"
fill="url(#linearGradient-1)"
transform="translate(13.56)"
/>
<path
d="M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z"
fill="#F5F5F7"
/>
<path
d="M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z"
fill="#DCE0E6"
/>
</g>
<path
class={`${prefixCls}-path-1`}
d="M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z"
/>
<path
class={`${prefixCls}-path-2`}
d="M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z"
transform="translate(13.56)"
/>
<path
class={`${prefixCls}-path-3`}
d="M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z"
/>
<path
class={`${prefixCls}-path-4`}
d="M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z"
d="M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z"
fill="#DCE0E6"
/>
<g transform="translate(149.65 15.383)" fill="#FFF">
<ellipse cx="20.654" cy="3.167" rx="2.849" ry="2.815" />
<path d="M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z" />
</g>
</g>
<path
class={`${prefixCls}-path-5`}
d="M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z"
/>
<g class={`${prefixCls}-g`} transform="translate(149.65 15.383)">
<ellipse cx="20.654" cy="3.167" rx="2.849" ry="2.815" />
<path d="M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z" />
</g>
</g>
</svg>
);
};
</svg>
);
},
});
Empty.PRESENTED_IMAGE_DEFAULT = true;

View File

@ -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 = <DefaultEmptyImg />;
const simpleEmptyImg = <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<string | CSSProperties>,
imageStyle: Object as PropType<CSSProperties>,
image: PropTypes.any,
description: PropTypes.any,
});
interface EmptyType extends FunctionalComponent<EmptyProps> {
displayName: string;
PRESENTED_IMAGE_DEFAULT: VueNode;
PRESENTED_IMAGE_SIMPLE: VueNode;
}
export type EmptyProps = Partial<ExtractPropTypes<ReturnType<typeof emptyProps>>>;
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 (
<LocaleReceiver
componentName="Empty"
children={(locale: Locale) => {
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 = <img alt={alt} src={image} />;
} else {
imageNode = image;
}
return wrapSSR(
<LocaleReceiver
componentName="Empty"
children={(locale: Locale) => {
const des = typeof description !== 'undefined' ? description : locale.description;
const alt = typeof des === 'string' ? des : 'empty';
let imageNode: EmptyProps['image'] = null;
return (
<div
class={classNames(prefixCls, className, {
[`${prefixCls}-normal`]: image === simpleEmptyImg,
[`${prefixCls}-rtl`]: direction.value === 'rtl',
})}
{...restProps}
>
<div class={`${prefixCls}-image`} style={imageStyle}>
{imageNode}
</div>
{des && <p class={`${prefixCls}-description`}>{des}</p>}
{slots.default && (
<div class={`${prefixCls}-footer`}>{filterEmpty(slots.default())}</div>
)}
</div>
);
}}
/>
);
};
if (typeof image === 'string') {
imageNode = <img alt={alt} src={image} />;
} else {
imageNode = image;
}
Empty.displayName = 'AEmpty';
return (
<div
class={classNames(prefixCls, className, hashId.value, {
[`${prefixCls}-normal`]: image === simpleEmptyImg,
[`${prefixCls}-rtl`]: direction.value === 'rtl',
})}
{...restProps}
>
<div class={`${prefixCls}-image`} style={imageStyle}>
{imageNode}
</div>
{des && <p class={`${prefixCls}-description`}>{des}</p>}
{slots.default && (
<div class={`${prefixCls}-footer`}>{filterEmpty(slots.default())}</div>
)}
</div>
);
}}
/>,
);
};
},
});
Empty.PRESENTED_IMAGE_DEFAULT = defaultEmptyImg;
Empty.PRESENTED_IMAGE_SIMPLE = simpleEmptyImg;

View File

@ -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 (
<svg class={prefixCls} width="64" height="41" viewBox="0 0 64 41">
<g transform="translate(0 1)" fill="none" fill-rule="evenodd">
<ellipse class={`${prefixCls}-ellipse`} fill="#F5F5F5" cx="32" cy="33" rx="32" ry="7" />
<g class={`${prefixCls}-g`} fill-rule="nonzero" stroke="#D9D9D9">
<path d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z" />
<path
d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z"
fill="#FAFAFA"
class={`${prefixCls}-path`}
/>
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 () => (
<svg width="64" height="41" viewBox="0 0 64 41" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 1)" fill="none" fill-rule="evenodd">
<ellipse fill={color.value.shadowColor} cx="32" cy="33" rx="32" ry="7" />
<g fill-rule="nonzero" stroke={color.value.borderColor}>
<path d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z" />
<path
d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z"
fill={color.value.contentColor}
/>
</g>
</g>
</g>
</svg>
);
};
</svg>
);
},
});
Simple.PRESENTED_IMAGE_SIMPLE = true;
export default Simple;

View File

@ -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';

View File

@ -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<EmptyToken> = (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<EmptyToken>(token, {
emptyImgCls: `${componentCls}-img`,
emptyImgHeight: controlHeightLG * 2.5,
emptyImgHeightMD: controlHeightLG,
emptyImgHeightSM: controlHeightLG * 0.875,
});
return [genSharedEmptyStyle(emptyToken)];
});

View File

@ -1,2 +0,0 @@
import '../../style/index.less';
import './index.less';

View File

@ -1,10 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@empty-prefix-cls: ~'@{ant-prefix}-empty';
.@{empty-prefix-cls} {
&-rtl {
direction: rtl;
}
}

View File

@ -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?: {};