Skip to content

Commit e3eff68

Browse files
shu-harinishu
andauthored
feat: collapse css var (#8331)
Co-authored-by: nishu <[email protected]>
1 parent 10382c4 commit e3eff68

File tree

2 files changed

+160
-65
lines changed

2 files changed

+160
-65
lines changed

components/collapse/Collapse.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import collapseMotion from '../_util/collapseMotion';
1919
import type { CustomSlotsType } from '../_util/type';
2020

2121
// CSSINJS
22+
import useCSSVarCls from '../config-provider/hooks/useCssVarCls';
2223
import useStyle from './style';
2324

2425
type Key = number | string;
@@ -63,7 +64,8 @@ export default defineComponent({
6364
const { prefixCls, direction, rootPrefixCls } = useConfigInject('collapse', props);
6465

6566
// style
66-
const [wrapSSR, hashId] = useStyle(prefixCls);
67+
const rootCls = useCSSVarCls(prefixCls);
68+
const [wrapSSR, hashId, cssVarCls] = useStyle(prefixCls, rootCls);
6769

6870
const iconPosition = computed(() => {
6971
const { expandIconPosition } = props;
@@ -186,6 +188,8 @@ export default defineComponent({
186188
[`${prefixCls.value}-ghost`]: !!ghost,
187189
[attrs.class as string]: !!attrs.class,
188190
},
191+
cssVarCls.value,
192+
rootCls.value,
189193
hashId.value,
190194
);
191195
return wrapSSR(

components/collapse/style/index.tsx

Lines changed: 155 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,63 @@
1-
import { genCollapseMotion } from '../../style/motion';
2-
import type { FullToken, GenerateStyle } from '../../theme/internal';
3-
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
4-
import { resetComponent, resetIcon } from '../../style';
1+
import type { CSSProperties } from 'vue';
2+
import { unit } from '../../_util/cssinjs';
53

6-
export interface ComponentToken {}
4+
import { genFocusStyle, resetComponent, resetIcon } from '../../style';
5+
import { genCollapseMotion } from '../../style/motion';
6+
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
7+
import { genStyleHooks, mergeToken } from '../../theme/internal';
8+
9+
/** Component only token. Which will handle additional calculation of alias token */
10+
export interface ComponentToken {
11+
// Component token here
12+
/**
13+
* @desc 折叠面板头部内边距
14+
* @descEN Padding of header
15+
*/
16+
headerPadding: CSSProperties['padding'];
17+
/**
18+
* @desc 折叠面板头部背景
19+
* @descEN Background of header
20+
*/
21+
headerBg: string;
22+
/**
23+
* @desc 折叠面板内容内边距
24+
* @descEN Padding of content
25+
*/
26+
contentPadding: CSSProperties['padding'];
27+
/**
28+
* @desc 折叠面板内容背景
29+
* @descEN Background of content
30+
*/
31+
contentBg: string;
32+
}
733

834
type CollapseToken = FullToken<'Collapse'> & {
9-
collapseContentBg: string;
10-
collapseHeaderBg: string;
11-
collapseHeaderPadding: string;
35+
/**
36+
* @desc 小号折叠面板头部内边距
37+
* @descEN Padding of small header
38+
*/
39+
collapseHeaderPaddingSM: string;
40+
/**
41+
* @desc 大号折叠面板头部内边距
42+
* @descEN Padding of large header
43+
*/
44+
collapseHeaderPaddingLG: string;
45+
/**
46+
* @desc 折叠面板边框圆角
47+
* @descEN Border radius of collapse panel
48+
*/
1249
collapsePanelBorderRadius: number;
13-
collapseContentPaddingHorizontal: number;
1450
};
1551

1652
export const genBaseStyle: GenerateStyle<CollapseToken> = token => {
1753
const {
1854
componentCls,
19-
collapseContentBg,
55+
contentBg,
2056
padding,
21-
collapseContentPaddingHorizontal,
22-
collapseHeaderBg,
23-
collapseHeaderPadding,
57+
headerBg,
58+
headerPadding,
59+
collapseHeaderPaddingSM,
60+
collapseHeaderPaddingLG,
2461
collapsePanelBorderRadius,
2562

2663
lineWidth,
@@ -29,35 +66,52 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = token => {
2966
colorText,
3067
colorTextHeading,
3168
colorTextDisabled,
32-
fontSize,
69+
fontSizeLG,
3370
lineHeight,
71+
lineHeightLG,
3472
marginSM,
3573
paddingSM,
74+
paddingLG,
75+
paddingXS,
3676
motionDurationSlow,
3777
fontSizeIcon,
78+
contentPadding,
79+
fontHeight,
80+
fontHeightLG,
3881
} = token;
3982

40-
const borderBase = `${lineWidth}px ${lineType} ${colorBorder}`;
83+
const borderBase = `${unit(lineWidth)} ${lineType} ${colorBorder}`;
4184

4285
return {
4386
[componentCls]: {
4487
...resetComponent(token),
45-
backgroundColor: collapseHeaderBg,
88+
backgroundColor: headerBg,
4689
border: borderBase,
47-
borderBottom: 0,
48-
borderRadius: `${collapsePanelBorderRadius}px`,
90+
borderRadius: collapsePanelBorderRadius,
4991

50-
[`&-rtl`]: {
92+
'&-rtl': {
5193
direction: 'rtl',
5294
},
5395

5496
[`& > ${componentCls}-item`]: {
5597
borderBottom: borderBase,
56-
[`&:last-child`]: {
98+
'&:first-child': {
99+
[`
100+
&,
101+
& > ${componentCls}-header`]: {
102+
borderRadius: `${unit(collapsePanelBorderRadius)} ${unit(
103+
collapsePanelBorderRadius,
104+
)} 0 0`,
105+
},
106+
},
107+
108+
'&:last-child': {
57109
[`
58110
&,
59111
& > ${componentCls}-header`]: {
60-
borderRadius: `0 0 ${collapsePanelBorderRadius}px ${collapsePanelBorderRadius}px`,
112+
borderRadius: `0 0 ${unit(collapsePanelBorderRadius)} ${unit(
113+
collapsePanelBorderRadius,
114+
)}`,
61115
},
62116
},
63117

@@ -66,23 +120,20 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = token => {
66120
display: 'flex',
67121
flexWrap: 'nowrap',
68122
alignItems: 'flex-start',
69-
padding: collapseHeaderPadding,
123+
padding: headerPadding,
70124
color: colorTextHeading,
71125
lineHeight,
72126
cursor: 'pointer',
73127
transition: `all ${motionDurationSlow}, visibility 0s`,
128+
...genFocusStyle(token),
74129

75130
[`> ${componentCls}-header-text`]: {
76131
flex: 'auto',
77132
},
78133

79-
'&:focus': {
80-
outline: 'none',
81-
},
82-
83134
// >>>>> Arrow
84135
[`${componentCls}-expand-icon`]: {
85-
height: fontSize * lineHeight,
136+
height: fontHeight,
86137
display: 'flex',
87138
alignItems: 'center',
88139
paddingInlineEnd: marginSM,
@@ -91,7 +142,9 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = token => {
91142
[`${componentCls}-arrow`]: {
92143
...resetIcon(),
93144
fontSize: fontSizeIcon,
94-
145+
// when `transform: rotate()` is applied to icon's root element
146+
transition: `transform ${motionDurationSlow}`,
147+
// when `transform: rotate()` is applied to icon's child element
95148
svg: {
96149
transition: `transform ${motionDurationSlow}`,
97150
},
@@ -103,50 +156,79 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = token => {
103156
},
104157
},
105158

106-
[`${componentCls}-header-collapsible-only`]: {
159+
[`${componentCls}-collapsible-header`]: {
107160
cursor: 'default',
108-
109161
[`${componentCls}-header-text`]: {
110162
flex: 'none',
111163
cursor: 'pointer',
112164
},
113-
[`${componentCls}-expand-icon`]: {
114-
cursor: 'pointer',
115-
},
116165
},
117166

118-
[`${componentCls}-icon-collapsible-only`]: {
119-
cursor: 'default',
167+
[`${componentCls}-collapsible-icon`]: {
168+
cursor: 'unset',
120169

121170
[`${componentCls}-expand-icon`]: {
122171
cursor: 'pointer',
123172
},
124173
},
125-
126-
[`&${componentCls}-no-arrow`]: {
127-
[`> ${componentCls}-header`]: {
128-
paddingInlineStart: paddingSM,
129-
},
130-
},
131174
},
132175

133176
[`${componentCls}-content`]: {
134177
color: colorText,
135-
backgroundColor: collapseContentBg,
178+
backgroundColor: contentBg,
136179
borderTop: borderBase,
137180

138181
[`& > ${componentCls}-content-box`]: {
139-
padding: `${padding}px ${collapseContentPaddingHorizontal}px`,
182+
padding: contentPadding,
140183
},
141184

142-
[`&-hidden`]: {
185+
'&-hidden': {
143186
display: 'none',
144187
},
145188
},
146189

190+
'&-small': {
191+
[`> ${componentCls}-item`]: {
192+
[`> ${componentCls}-header`]: {
193+
padding: collapseHeaderPaddingSM,
194+
paddingInlineStart: paddingXS,
195+
196+
[`> ${componentCls}-expand-icon`]: {
197+
// Arrow offset
198+
marginInlineStart: token.calc(paddingSM).sub(paddingXS).equal(),
199+
},
200+
},
201+
[`> ${componentCls}-content > ${componentCls}-content-box`]: {
202+
padding: paddingSM,
203+
},
204+
},
205+
},
206+
207+
'&-large': {
208+
[`> ${componentCls}-item`]: {
209+
fontSize: fontSizeLG,
210+
lineHeight: lineHeightLG,
211+
[`> ${componentCls}-header`]: {
212+
padding: collapseHeaderPaddingLG,
213+
paddingInlineStart: padding,
214+
215+
[`> ${componentCls}-expand-icon`]: {
216+
height: fontHeightLG,
217+
// Arrow offset
218+
marginInlineStart: token.calc(paddingLG).sub(padding).equal(),
219+
},
220+
},
221+
[`> ${componentCls}-content > ${componentCls}-content-box`]: {
222+
padding: paddingLG,
223+
},
224+
},
225+
},
226+
147227
[`${componentCls}-item:last-child`]: {
228+
borderBottom: 0,
229+
148230
[`> ${componentCls}-content`]: {
149-
borderRadius: `0 0 ${collapsePanelBorderRadius}px ${collapsePanelBorderRadius}px`,
231+
borderRadius: `0 0 ${unit(collapsePanelBorderRadius)} ${unit(collapsePanelBorderRadius)}`,
150232
},
151233
},
152234

@@ -179,7 +261,7 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = token => {
179261
const genArrowStyle: GenerateStyle<CollapseToken> = token => {
180262
const { componentCls } = token;
181263

182-
const fixedSelector = `> ${componentCls}-item > ${componentCls}-header ${componentCls}-arrow svg`;
264+
const fixedSelector = `> ${componentCls}-item > ${componentCls}-header ${componentCls}-arrow`;
183265

184266
return {
185267
[`${componentCls}-rtl`]: {
@@ -193,15 +275,15 @@ const genArrowStyle: GenerateStyle<CollapseToken> = token => {
193275
const genBorderlessStyle: GenerateStyle<CollapseToken> = token => {
194276
const {
195277
componentCls,
196-
collapseHeaderBg,
278+
headerBg,
197279
paddingXXS,
198280

199281
colorBorder,
200282
} = token;
201283

202284
return {
203285
[`${componentCls}-borderless`]: {
204-
backgroundColor: collapseHeaderBg,
286+
backgroundColor: headerBg,
205287
border: 0,
206288

207289
[`> ${componentCls}-item`]: {
@@ -252,20 +334,29 @@ const genGhostStyle: GenerateStyle<CollapseToken> = token => {
252334
};
253335
};
254336

255-
export default genComponentStyleHook('Collapse', token => {
256-
const collapseToken = mergeToken<CollapseToken>(token, {
257-
collapseContentBg: token.colorBgContainer,
258-
collapseHeaderBg: token.colorFillAlter,
259-
collapseHeaderPadding: `${token.paddingSM}px ${token.padding}px`,
260-
collapsePanelBorderRadius: token.borderRadiusLG,
261-
collapseContentPaddingHorizontal: 16, // Fixed value
262-
});
263-
264-
return [
265-
genBaseStyle(collapseToken),
266-
genBorderlessStyle(collapseToken),
267-
genGhostStyle(collapseToken),
268-
genArrowStyle(collapseToken),
269-
genCollapseMotion(collapseToken),
270-
];
337+
export const prepareComponentToken: GetDefaultToken<'Collapse'> = token => ({
338+
headerPadding: `${token.paddingSM}px ${token.padding}px`,
339+
headerBg: token.colorFillAlter,
340+
contentPadding: `${token.padding}px 16px`, // Fixed Value
341+
contentBg: token.colorBgContainer,
271342
});
343+
344+
export default genStyleHooks(
345+
'Collapse',
346+
token => {
347+
const collapseToken = mergeToken<CollapseToken>(token, {
348+
collapseHeaderPaddingSM: `${unit(token.paddingXS)} ${unit(token.paddingSM)}`,
349+
collapseHeaderPaddingLG: `${unit(token.padding)} ${unit(token.paddingLG)}`,
350+
collapsePanelBorderRadius: token.borderRadiusLG,
351+
});
352+
353+
return [
354+
genBaseStyle(collapseToken),
355+
genBorderlessStyle(collapseToken),
356+
genGhostStyle(collapseToken),
357+
genArrowStyle(collapseToken),
358+
genCollapseMotion(collapseToken),
359+
];
360+
},
361+
prepareComponentToken,
362+
);

0 commit comments

Comments
 (0)