refactor: descriptions (#6213)

* refactor: descriptions

* fix: ts error

Co-authored-by: tangjinzhou <415800467@qq.com>
pull/6215/head
zkwolf 2023-01-27 16:46:58 +08:00 committed by GitHub
parent 2d54e2124f
commit 9d5343ae9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 326 additions and 303 deletions

View File

@ -1,19 +1,21 @@
import type { Ref } from 'vue'; import type { Ref } from 'vue';
import { onMounted, onUnmounted, ref } from 'vue'; import { onMounted, onUnmounted, ref } from 'vue';
import type { ScreenMap } from '../../_util/responsiveObserve'; import type { ScreenMap } from '../../_util/responsiveObserve';
import ResponsiveObserve from '../../_util/responsiveObserve'; import useResponsiveObserve from '../../_util/responsiveObserve';
function useBreakpoint(): Ref<ScreenMap> { function useBreakpoint(): Ref<ScreenMap> {
const screens = ref<ScreenMap>({}); const screens = ref<ScreenMap>({});
let token = null; let token = null;
const responsiveObserve = useResponsiveObserve();
onMounted(() => { onMounted(() => {
token = ResponsiveObserve.subscribe(supportScreens => { token = responsiveObserve.value.subscribe(supportScreens => {
screens.value = supportScreens; screens.value = supportScreens;
}); });
}); });
onUnmounted(() => { onUnmounted(() => {
ResponsiveObserve.unsubscribe(token); responsiveObserve.value.unsubscribe(token);
}); });
return screens; return screens;

View File

@ -1,75 +1,86 @@
import type { GlobalToken } from '../theme/interface';
import { useToken } from '../theme/internal';
import useMemo from './hooks/useMemo';
export type Breakpoint = 'xxxl' | 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; export type Breakpoint = 'xxxl' | 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs';
export type BreakpointMap = Record<Breakpoint, string>; export type BreakpointMap = Record<Breakpoint, string>;
export type ScreenMap = Partial<Record<Breakpoint, boolean>>; export type ScreenMap = Partial<Record<Breakpoint, boolean>>;
export type ScreenSizeMap = Partial<Record<Breakpoint, number>>; export type ScreenSizeMap = Partial<Record<Breakpoint, number>>;
export const responsiveArray: Breakpoint[] = ['xxxl', 'xxl', 'xl', 'lg', 'md', 'sm', 'xs']; export const responsiveArray: Breakpoint[] = ['xxxl', 'xxl', 'xl', 'lg', 'md', 'sm', 'xs'];
export const responsiveMap: BreakpointMap = {
xs: '(max-width: 575px)',
sm: '(min-width: 576px)',
md: '(min-width: 768px)',
lg: '(min-width: 992px)',
xl: '(min-width: 1200px)',
xxl: '(min-width: 1600px)',
xxxl: '(min-width: 2000px)',
};
type SubscribeFunc = (screens: ScreenMap) => void; type SubscribeFunc = (screens: ScreenMap) => void;
const subscribers = new Map<Number, SubscribeFunc>();
let subUid = -1;
let screens = {};
const responsiveObserve = { const getResponsiveMap = (token: GlobalToken): BreakpointMap => ({
matchHandlers: {} as { xs: `(max-width: ${token.screenXSMax}px)`,
[prop: string]: { sm: `(min-width: ${token.screenSM}px)`,
mql: MediaQueryList; md: `(min-width: ${token.screenMD}px)`,
listener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null; lg: `(min-width: ${token.screenLG}px)`,
}; xl: `(min-width: ${token.screenXL}px)`,
}, xxl: `(min-width: ${token.screenXXL}px)`,
dispatch(pointMap: ScreenMap) { xxxl: `{min-width: ${token.screenXXXL}px}`,
screens = pointMap; });
subscribers.forEach(func => func(screens));
return subscribers.size >= 1; export default function useResponsiveObserver() {
}, const [, token] = useToken();
subscribe(func: SubscribeFunc): number { const responsiveMap: BreakpointMap = getResponsiveMap(token.value);
if (!subscribers.size) this.register();
subUid += 1; // To avoid repeat create instance, we add `useMemo` here.
subscribers.set(subUid, func); return useMemo(() => {
func(screens); const subscribers = new Map<Number, SubscribeFunc>();
return subUid; let subUid = -1;
}, let screens = {};
unsubscribe(token: number) {
subscribers.delete(token); return {
if (!subscribers.size) this.unregister(); matchHandlers: {} as {
}, [prop: string]: {
unregister() { mql: MediaQueryList;
Object.keys(responsiveMap).forEach((screen: string) => { listener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null;
const matchMediaQuery = responsiveMap[screen]; };
const handler = this.matchHandlers[matchMediaQuery]; },
handler?.mql.removeListener(handler?.listener); dispatch(pointMap: ScreenMap) {
}); screens = pointMap;
subscribers.clear(); subscribers.forEach(func => func(screens));
}, return subscribers.size >= 1;
register() { },
Object.keys(responsiveMap).forEach((screen: string) => { subscribe(func: SubscribeFunc): number {
const matchMediaQuery = responsiveMap[screen]; if (!subscribers.size) this.register();
const listener = ({ matches }: { matches: boolean }) => { subUid += 1;
this.dispatch({ subscribers.set(subUid, func);
...screens, func(screens);
[screen]: matches, return subUid;
},
unsubscribe(paramToken: number) {
subscribers.delete(paramToken);
if (!subscribers.size) this.unregister();
},
unregister() {
Object.keys(responsiveMap).forEach((screen: string) => {
const matchMediaQuery = responsiveMap[screen];
const handler = this.matchHandlers[matchMediaQuery];
handler?.mql.removeListener(handler?.listener);
}); });
}; subscribers.clear();
const mql = window.matchMedia(matchMediaQuery); },
mql.addListener(listener); register() {
this.matchHandlers[matchMediaQuery] = { Object.keys(responsiveMap).forEach((screen: string) => {
mql, const matchMediaQuery = responsiveMap[screen];
listener, const listener = ({ matches }: { matches: boolean }) => {
}; this.dispatch({
...screens,
[screen]: matches,
});
};
const mql = window.matchMedia(matchMediaQuery);
mql.addListener(listener);
this.matchHandlers[matchMediaQuery] = {
mql,
listener,
};
listener(mql); listener(mql);
}); });
}, },
}; responsiveMap,
};
export default responsiveObserve; }, [token]);
}

View File

@ -11,8 +11,8 @@ interface CellProps extends HTMLAttributes {
labelStyle?: CSSProperties; labelStyle?: CSSProperties;
contentStyle?: CSSProperties; contentStyle?: CSSProperties;
bordered?: boolean; bordered?: boolean;
label?: VNodeTypes; label?: number | VNodeTypes;
content?: VNodeTypes; content?: number | VNodeTypes;
colon?: boolean; colon?: boolean;
} }
@ -49,7 +49,7 @@ const Cell: FunctionalComponent<CellProps> = props => {
return ( return (
<Component class={[`${itemPrefixCls}-item`]} colSpan={span}> <Component class={[`${itemPrefixCls}-item`]} colSpan={span}>
<div class={`${itemPrefixCls}-item-container`}> <div class={`${itemPrefixCls}-item-container`}>
{label && ( {(label || label === 0) && (
<span <span
class={[ class={[
`${itemPrefixCls}-item-label`, `${itemPrefixCls}-item-label`,
@ -62,7 +62,7 @@ const Cell: FunctionalComponent<CellProps> = props => {
{label} {label}
</span> </span>
)} )}
{content && ( {(content || content === 0) && (
<span class={`${itemPrefixCls}-item-content`} style={contentStyle}> <span class={`${itemPrefixCls}-item-content`} style={contentStyle}>
{content} {content}
</span> </span>

View File

@ -2,7 +2,7 @@
category: Components category: Components
type: Data Display type: Data Display
title: Descriptions title: Descriptions
cover: https://gw.alipayobjects.com/zos/alicdn/MjtG9_FOI/Descriptions.svg cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*fHdlTpif6XQAAAAAAAAAAAAADrJ8AQ/original
--- ---
Display multiple read-only fields in groups. Display multiple read-only fields in groups.

View File

@ -20,13 +20,15 @@ import {
} from 'vue'; } from 'vue';
import warning from '../_util/warning'; import warning from '../_util/warning';
import type { Breakpoint, ScreenMap } from '../_util/responsiveObserve'; import type { Breakpoint, ScreenMap } from '../_util/responsiveObserve';
import ResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve'; import useResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve';
import Row from './Row'; import Row from './Row';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import { cloneElement } from '../_util/vnode'; import { cloneElement } from '../_util/vnode';
import { flattenChildren } from '../_util/props-util'; import { flattenChildren } from '../_util/props-util';
import useConfigInject from '../config-provider/hooks/useConfigInject'; import useConfigInject from '../config-provider/hooks/useConfigInject';
import useStyle from './style';
export const DescriptionsItemProps = { export const DescriptionsItemProps = {
prefixCls: String, prefixCls: String,
label: PropTypes.any, label: PropTypes.any,
@ -82,7 +84,7 @@ function getColumn(column: DescriptionsProps['column'], screens: ScreenMap): num
return 3; return 3;
} }
function getFilledItem(node: VNode, span: number | undefined, rowRestCol: number): VNode { function getFilledItem(node: VNode, rowRestCol: number, span?: number): VNode {
let clone = node; let clone = node;
if (span === undefined || span > rowRestCol) { if (span === undefined || span > rowRestCol) {
@ -106,12 +108,12 @@ function getRows(children: VNode[], column: number) {
let tmpRow: VNode[] = []; let tmpRow: VNode[] = [];
let rowRestCol = column; let rowRestCol = column;
childNodes.forEach((node, index) => { childNodes.forEach((node, index) => {
const span: number | undefined = node.props?.span; const span: number = node.props?.span;
const mergedSpan = span || 1; const mergedSpan = span || 1;
// Additional handle last one // Additional handle last one
if (index === childNodes.length - 1) { if (index === childNodes.length - 1) {
tmpRow.push(getFilledItem(node, span, rowRestCol)); tmpRow.push(getFilledItem(node, rowRestCol, span));
rows.push(tmpRow); rows.push(tmpRow);
return; return;
} }
@ -120,7 +122,7 @@ function getRows(children: VNode[], column: number) {
rowRestCol -= mergedSpan; rowRestCol -= mergedSpan;
tmpRow.push(node); tmpRow.push(node);
} else { } else {
tmpRow.push(getFilledItem(node, mergedSpan, rowRestCol)); tmpRow.push(getFilledItem(node, rowRestCol, mergedSpan));
rows.push(tmpRow); rows.push(tmpRow);
rowRestCol = column; rowRestCol = column;
tmpRow = []; tmpRow = [];
@ -167,8 +169,12 @@ const Descriptions = defineComponent({
const { prefixCls, direction } = useConfigInject('descriptions', props); const { prefixCls, direction } = useConfigInject('descriptions', props);
let token: number; let token: number;
const screens = ref<ScreenMap>({}); const screens = ref<ScreenMap>({});
const [wrapSSR, hashId] = useStyle(prefixCls);
const responsiveObserve = useResponsiveObserve();
onBeforeMount(() => { onBeforeMount(() => {
token = ResponsiveObserve.subscribe(screen => { token = responsiveObserve.value.subscribe(screen => {
if (typeof props.column !== 'object') { if (typeof props.column !== 'object') {
return; return;
} }
@ -177,7 +183,7 @@ const Descriptions = defineComponent({
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
ResponsiveObserve.unsubscribe(token); responsiveObserve.value.unsubscribe(token);
}); });
provide(descriptionsContext, { provide(descriptionsContext, {
@ -200,7 +206,7 @@ const Descriptions = defineComponent({
const children = slots.default?.(); const children = slots.default?.();
const rows = getRows(children, mergeColumn.value); const rows = getRows(children, mergeColumn.value);
return ( return wrapSSR(
<div <div
class={[ class={[
prefixCls.value, prefixCls.value,
@ -209,6 +215,7 @@ const Descriptions = defineComponent({
[`${prefixCls.value}-bordered`]: !!bordered, [`${prefixCls.value}-bordered`]: !!bordered,
[`${prefixCls.value}-rtl`]: direction.value === 'rtl', [`${prefixCls.value}-rtl`]: direction.value === 'rtl',
}, },
hashId.value,
]} ]}
> >
{(title || extra) && ( {(title || extra) && (
@ -234,7 +241,7 @@ const Descriptions = defineComponent({
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>,
); );
}; };
}, },

View File

@ -3,7 +3,7 @@ category: Components
type: 数据展示 type: 数据展示
title: Descriptions title: Descriptions
subtitle: 描述列表 subtitle: 描述列表
cover: https://gw.alipayobjects.com/zos/alicdn/MjtG9_FOI/Descriptions.svg cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*fHdlTpif6XQAAAAAAAAAAAAADrJ8AQ/original
--- ---
成组展示多个只读字段。 成组展示多个只读字段。

View File

@ -1,179 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@descriptions-prefix-cls: ~'@{ant-prefix}-descriptions';
.@{descriptions-prefix-cls} {
&-header {
display: flex;
align-items: center;
margin-bottom: @descriptions-title-margin-bottom;
}
&-title {
flex: auto;
overflow: hidden;
color: @heading-color;
font-weight: bold;
font-size: @font-size-lg;
line-height: @line-height-base;
white-space: nowrap;
text-overflow: ellipsis;
}
&-extra {
margin-left: auto;
color: @descriptions-extra-color;
font-size: @font-size-base;
}
&-view {
width: 100%;
border-radius: @border-radius-base;
table {
width: 100%;
table-layout: fixed;
}
}
&-row {
> th,
> td {
padding-bottom: @descriptions-item-padding-bottom;
}
&:last-child {
border-bottom: none;
}
}
&-item-label {
color: @heading-color;
font-weight: normal;
font-size: @font-size-base;
line-height: @line-height-base;
text-align: start;
&::after {
& when (@descriptions-item-trailing-colon=true) {
content: ':';
}
& when not (@descriptions-item-trailing-colon=true) {
content: ' ';
}
position: relative;
top: -0.5px;
margin: 0 @descriptions-item-label-colon-margin-right 0
@descriptions-item-label-colon-margin-left;
}
&.@{descriptions-prefix-cls}-item-no-colon::after {
content: ' ';
}
}
&-item-no-label {
&::after {
margin: 0;
content: '';
}
}
&-item-content {
display: table-cell;
flex: 1;
color: @text-color;
font-size: @font-size-base;
line-height: @line-height-base;
word-break: break-word;
overflow-wrap: break-word;
}
&-item {
padding-bottom: 0;
vertical-align: top;
&-container {
display: flex;
.@{descriptions-prefix-cls}-item-label,
.@{descriptions-prefix-cls}-item-content {
display: inline-flex;
align-items: baseline;
}
}
}
&-middle {
.@{descriptions-prefix-cls}-row {
> th,
> td {
padding-bottom: @padding-sm;
}
}
}
&-small {
.@{descriptions-prefix-cls}-row {
> th,
> td {
padding-bottom: @padding-xs;
}
}
}
&-bordered {
.@{descriptions-prefix-cls}-view {
border: 1px solid @border-color-split;
> table {
table-layout: auto;
border-collapse: collapse;
}
}
.@{descriptions-prefix-cls}-item-label,
.@{descriptions-prefix-cls}-item-content {
padding: @descriptions-default-padding;
border-right: 1px solid @border-color-split;
&:last-child {
border-right: none;
}
}
.@{descriptions-prefix-cls}-item-label {
background-color: @descriptions-bg;
&::after {
display: none;
}
}
.@{descriptions-prefix-cls}-row {
border-bottom: 1px solid @border-color-split;
&:last-child {
border-bottom: none;
}
}
&.@{descriptions-prefix-cls}-middle {
.@{descriptions-prefix-cls}-item-label,
.@{descriptions-prefix-cls}-item-content {
padding: @descriptions-middle-padding;
}
}
&.@{descriptions-prefix-cls}-small {
.@{descriptions-prefix-cls}-item-label,
.@{descriptions-prefix-cls}-item-content {
padding: @descriptions-small-padding;
}
}
}
}
@import './rtl';

View File

@ -0,0 +1,208 @@
import type { CSSObject } from '../../_util/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
import { resetComponent, textEllipsis } from '../../_style';
interface DescriptionsToken extends FullToken<'Descriptions'> {
descriptionsTitleMarginBottom: number;
descriptionsExtraColor: string;
descriptionItemPaddingBottom: number;
descriptionsDefaultPadding: string;
descriptionsBg: string;
descriptionsMiddlePadding: string;
descriptionsSmallPadding: string;
descriptionsItemLabelColonMarginRight: number;
descriptionsItemLabelColonMarginLeft: number;
}
const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
const {
componentCls,
descriptionsSmallPadding,
descriptionsDefaultPadding,
descriptionsMiddlePadding,
descriptionsBg,
} = token;
return {
[`&${componentCls}-bordered`]: {
[`${componentCls}-view`]: {
border: `${token.lineWidth}px ${token.lineType} ${token.colorSplit}`,
'> table': {
tableLayout: 'auto',
borderCollapse: 'collapse',
},
},
[`${componentCls}-item-label, ${componentCls}-item-content`]: {
padding: descriptionsDefaultPadding,
borderInlineEnd: `${token.lineWidth}px ${token.lineType} ${token.colorSplit}`,
'&:last-child': {
borderInlineEnd: 'none',
},
},
[`${componentCls}-item-label`]: {
backgroundColor: descriptionsBg,
'&::after': {
display: 'none',
},
},
[`${componentCls}-row`]: {
borderBottom: `${token.lineWidth}px ${token.lineType} ${token.colorSplit}`,
'&:last-child': {
borderBottom: 'none',
},
},
[`&${componentCls}-middle`]: {
[`${componentCls}-item-label, ${componentCls}-item-content`]: {
padding: descriptionsMiddlePadding,
},
},
[`&${componentCls}-small`]: {
[`${componentCls}-item-label, ${componentCls}-item-content`]: {
padding: descriptionsSmallPadding,
},
},
},
};
};
const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token: DescriptionsToken) => {
const {
componentCls,
descriptionsExtraColor,
descriptionItemPaddingBottom,
descriptionsItemLabelColonMarginRight,
descriptionsItemLabelColonMarginLeft,
descriptionsTitleMarginBottom,
} = token;
return {
[componentCls]: {
...resetComponent(token),
...genBorderedStyle(token),
[`&-rtl`]: {
direction: 'rtl',
},
[`${componentCls}-header`]: {
display: 'flex',
alignItems: 'center',
marginBottom: descriptionsTitleMarginBottom,
},
[`${componentCls}-title`]: {
...textEllipsis,
flex: 'auto',
color: token.colorText,
fontWeight: token.fontWeightStrong,
fontSize: token.fontSizeLG,
lineHeight: token.lineHeightLG,
},
[`${componentCls}-extra`]: {
marginInlineStart: 'auto',
color: descriptionsExtraColor,
fontSize: token.fontSize,
},
[`${componentCls}-view`]: {
width: '100%',
borderRadius: token.borderRadiusLG,
table: {
width: '100%',
tableLayout: 'fixed',
},
},
[`${componentCls}-row`]: {
'> th, > td': {
paddingBottom: descriptionItemPaddingBottom,
},
'&:last-child': {
borderBottom: 'none',
},
},
[`${componentCls}-item-label`]: {
color: token.colorText,
fontWeight: 'normal',
fontSize: token.fontSize,
lineHeight: token.lineHeight,
textAlign: `start`,
'&::after': {
content: '":"',
position: 'relative',
top: -0.5, // magic for position
marginInline: `${descriptionsItemLabelColonMarginLeft}px ${descriptionsItemLabelColonMarginRight}px`,
},
[`&${componentCls}-item-no-colon::after`]: {
content: '""',
},
},
[`${componentCls}-item-no-label`]: {
'&::after': {
margin: 0,
content: '""',
},
},
[`${componentCls}-item-content`]: {
display: 'table-cell',
flex: 1,
color: token.colorText,
fontSize: token.fontSize,
lineHeight: token.lineHeight,
wordBreak: 'break-word',
overflowWrap: 'break-word',
},
[`${componentCls}-item`]: {
paddingBottom: 0,
verticalAlign: 'top',
'&-container': {
display: 'flex',
[`${componentCls}-item-label`]: {
display: 'inline-flex',
alignItems: 'baseline',
},
[`${componentCls}-item-content`]: {
display: 'inline-flex',
alignItems: 'baseline',
},
},
},
'&-middle': {
[`${componentCls}-row`]: {
'> th, > td': {
paddingBottom: token.paddingSM,
},
},
},
'&-small': {
[`${componentCls}-row`]: {
'> th, > td': {
paddingBottom: token.paddingXS,
},
},
},
},
};
};
// ============================== Export ==============================
export default genComponentStyleHook('Descriptions', token => {
const descriptionsBg = token.colorFillAlter;
const descriptionsTitleMarginBottom = token.fontSizeSM * token.lineHeightSM;
const descriptionsExtraColor = token.colorText;
const descriptionsSmallPadding = `${token.paddingXS}px ${token.padding}px`;
const descriptionsDefaultPadding = `${token.padding}px ${token.paddingLG}px`;
const descriptionsMiddlePadding = `${token.paddingSM}px ${token.paddingLG}px`;
const descriptionItemPaddingBottom = token.padding;
const descriptionsItemLabelColonMarginRight = token.marginXS;
const descriptionsItemLabelColonMarginLeft = token.marginXXS / 2;
const descriptionToken = mergeToken<DescriptionsToken>(token, {
descriptionsBg,
descriptionsTitleMarginBottom,
descriptionsExtraColor,
descriptionItemPaddingBottom,
descriptionsSmallPadding,
descriptionsDefaultPadding,
descriptionsMiddlePadding,
descriptionsItemLabelColonMarginRight,
descriptionsItemLabelColonMarginLeft,
});
return [genDescriptionStyles(descriptionToken)];
});

View File

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

View File

@ -1,33 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@descriptions-prefix-cls: ~'@{ant-prefix}-descriptions';
.@{descriptions-prefix-cls} {
&-rtl {
direction: rtl;
}
&-item-label {
&::after {
.@{descriptions-prefix-cls}-rtl & {
margin: 0 @descriptions-item-label-colon-margin-left 0
@descriptions-item-label-colon-margin-right;
}
}
}
&-bordered {
.@{descriptions-prefix-cls}-item-label,
.@{descriptions-prefix-cls}-item-content {
.@{descriptions-prefix-cls}-rtl& {
border-right: none;
border-left: 1px solid @border-color-split;
&:last-child {
border-left: none;
}
}
}
}
}

View File

@ -3,7 +3,7 @@ import { defineComponent, ref, onMounted, onBeforeUnmount, computed } from 'vue'
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import { tuple } from '../_util/type'; import { tuple } from '../_util/type';
import type { Breakpoint, ScreenMap } from '../_util/responsiveObserve'; import type { Breakpoint, ScreenMap } from '../_util/responsiveObserve';
import ResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve'; import useResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve';
import useConfigInject from '../config-provider/hooks/useConfigInject'; import useConfigInject from '../config-provider/hooks/useConfigInject';
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport'; import useFlexGapSupport from '../_util/hooks/useFlexGapSupport';
import useProvideRow from './context'; import useProvideRow from './context';
@ -19,8 +19,8 @@ export interface rowContextState {
} }
export const rowProps = () => ({ export const rowProps = () => ({
align: String as PropType<typeof RowAligns[number]>, align: String as PropType<(typeof RowAligns)[number]>,
justify: String as PropType<typeof RowJustify[number]>, justify: String as PropType<(typeof RowJustify)[number]>,
prefixCls: String, prefixCls: String,
gutter: { gutter: {
type: [Number, Array, Object] as PropType<Gutter | [Gutter, Gutter]>, type: [Number, Array, Object] as PropType<Gutter | [Gutter, Gutter]>,
@ -40,6 +40,8 @@ const ARow = defineComponent({
let token: number; let token: number;
const responsiveObserve = useResponsiveObserve();
const screens = ref<ScreenMap>({ const screens = ref<ScreenMap>({
xs: true, xs: true,
sm: true, sm: true,
@ -53,7 +55,7 @@ const ARow = defineComponent({
const supportFlexGap = useFlexGapSupport(); const supportFlexGap = useFlexGapSupport();
onMounted(() => { onMounted(() => {
token = ResponsiveObserve.subscribe(screen => { token = responsiveObserve.value.subscribe(screen => {
const currentGutter = props.gutter || 0; const currentGutter = props.gutter || 0;
if ( if (
(!Array.isArray(currentGutter) && typeof currentGutter === 'object') || (!Array.isArray(currentGutter) && typeof currentGutter === 'object') ||
@ -66,7 +68,7 @@ const ARow = defineComponent({
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
ResponsiveObserve.unsubscribe(token); responsiveObserve.value.unsubscribe(token);
}); });
const gutter = computed(() => { const gutter = computed(() => {

View File

@ -55,7 +55,7 @@ import './comment/style';
import './empty/style'; import './empty/style';
import './statistic/style'; import './statistic/style';
import './result/style'; import './result/style';
import './descriptions/style'; // import './descriptions/style';
import './page-header/style'; import './page-header/style';
import './form/style'; import './form/style';
import './space/style'; import './space/style';

View File

@ -120,6 +120,9 @@ export interface AliasToken extends MapToken {
screenXLMax: number; screenXLMax: number;
screenXXL: number; screenXXL: number;
screenXXLMin: number; screenXXLMin: number;
screenXXLMax: number;
screenXXXL: number;
screenXXXLMin: number;
/** Used for DefaultButton, Switch which has default outline */ /** Used for DefaultButton, Switch which has default outline */
controlTmpOutline: string; controlTmpOutline: string;

View File

@ -30,6 +30,7 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken
const screenLG = 992; const screenLG = 992;
const screenXL = 1200; const screenXL = 1200;
const screenXXL = 1600; const screenXXL = 1600;
const screenXXXL = 2000;
// Generate alias token // Generate alias token
const aliasToken: AliasToken = { const aliasToken: AliasToken = {
@ -151,6 +152,9 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken
screenXLMax: screenXXL - 1, screenXLMax: screenXXL - 1,
screenXXL, screenXXL,
screenXXLMin: screenXXL, screenXXLMin: screenXXL,
screenXXLMax: screenXXXL - 1,
screenXXXL,
screenXXXLMin: screenXXXL,
// FIXME: component box-shadow, should be removed // FIXME: component box-shadow, should be removed
boxShadowPopoverArrow: '3px 3px 7px rgba(0, 0, 0, 0.1)', boxShadowPopoverArrow: '3px 3px 7px rgba(0, 0, 0, 0.1)',