Skip to content

Commit 2181d7e

Browse files
committed
chore: classNames
1 parent 917262f commit 2181d7e

File tree

2 files changed

+131
-69
lines changed

2 files changed

+131
-69
lines changed

src/Step.tsx

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint react/prop-types: 0 */
22
import * as React from 'react';
3-
import classNames from 'classnames';
3+
import cls from 'classnames';
44
import KeyCode from '@rc-component/util/lib/KeyCode';
55
import type { Status, Icons } from './interface';
66
import type { ProgressDotRender, StepItem, StepsProps } from './Steps';
@@ -19,75 +19,92 @@ export interface StepProps {
1919

2020
// data
2121
data: StepItem;
22+
status: Status;
23+
prevStatus?: Status;
24+
2225
active?: boolean;
2326
disabled?: boolean;
24-
stepIndex?: number;
25-
stepNumber?: number;
26-
status?: Status;
27-
title?: React.ReactNode;
28-
subTitle?: React.ReactNode;
29-
description?: React.ReactNode;
27+
index: number;
28+
29+
// stepIndex?: number;
30+
// stepNumber?: number;
31+
// title?: React.ReactNode;
32+
// subTitle?: React.ReactNode;
33+
// description?: React.ReactNode;
3034

3135
// render
3236
iconRender?: StepsProps['iconRender'];
33-
3437
icon?: React.ReactNode;
35-
onClick?: React.MouseEventHandler<HTMLDivElement>;
36-
onStepClick?: (index: number) => void;
3738
progressDot?: ProgressDotRender | boolean;
3839
render?: (stepItem: React.ReactElement) => React.ReactNode;
40+
41+
// Event
42+
onClick?: (index: number) => void;
3943
}
4044

4145
export default function Step(props: StepProps) {
4246
const {
43-
className,
47+
// style
4448
prefixCls,
49+
className,
4550
style,
46-
active,
51+
classNames,
52+
styles,
53+
54+
// data
55+
data,
4756
status,
48-
icon,
49-
stepNumber,
57+
prevStatus,
58+
59+
active,
5060
disabled,
51-
description,
52-
title,
53-
subTitle,
61+
index,
62+
63+
// render
64+
icon,
5465
progressDot,
55-
stepIndex,
56-
onStepClick,
57-
onClick,
5866
render,
59-
data,
67+
68+
// events
69+
onClick,
70+
6071
...restProps
6172
} = props;
6273

74+
// ========================== Data ==========================
75+
const { onClick: onItemClick, title, subTitle, content, description } = data;
76+
const mergedContent = content ?? description;
77+
6378
// ========================= Click ==========================
64-
const clickable = !!onStepClick && !disabled;
79+
const clickable = !!(onItemClick || onItemClick) && !disabled;
6580

6681
const accessibilityProps: {
6782
role?: string;
6883
tabIndex?: number;
6984
onClick?: React.MouseEventHandler<HTMLDivElement>;
7085
onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
7186
} = {};
87+
7288
if (clickable) {
7389
accessibilityProps.role = 'button';
7490
accessibilityProps.tabIndex = 0;
7591
accessibilityProps.onClick = (e) => {
76-
onClick?.(e);
77-
onStepClick(stepIndex);
92+
onItemClick?.(e);
93+
onClick(index);
7894
};
95+
7996
accessibilityProps.onKeyDown = (e) => {
8097
const { which } = e;
8198
if (which === KeyCode.ENTER || which === KeyCode.SPACE) {
82-
onStepClick(stepIndex);
99+
onClick(index);
83100
}
84101
};
85102
}
86103

87104
// ========================= Render =========================
88105
const renderIconNode = () => {
89106
let iconNode: React.ReactNode;
90-
const iconClassName = classNames(`${prefixCls}-icon`, `${iconPrefix}icon`, {
107+
const iconClassName = cls(`${prefixCls}-icon`, `${iconPrefix}icon`, {
91108
[`${iconPrefix}icon-${icon}`]: icon && isString(icon),
92109
[`${iconPrefix}icon-check`]:
93110
!icon && status === 'finish' && ((icons && !icons.finish) || !icons),
@@ -105,6 +122,7 @@ export default function Step(props: StepProps) {
105122
status,
106123
title,
107124
description,
125+
content: mergedContent,
108126
})}
109127
</span>
110128
);
@@ -125,10 +143,11 @@ export default function Step(props: StepProps) {
125143

126144
if (stepIcon) {
127145
iconNode = stepIcon({
128-
index: stepNumber - 1,
146+
index,
129147
status,
130148
title,
131149
description,
150+
content: mergedContent,
132151
node: iconNode,
133152
});
134153
}
@@ -138,16 +157,11 @@ export default function Step(props: StepProps) {
138157

139158
const mergedStatus = status || 'wait';
140159

141-
const classString = classNames(
142-
`${prefixCls}-item`,
143-
`${prefixCls}-item-${mergedStatus}`,
144-
className,
145-
{
146-
[`${prefixCls}-item-custom`]: icon,
147-
[`${prefixCls}-item-active`]: active,
148-
[`${prefixCls}-item-disabled`]: disabled === true,
149-
},
150-
);
160+
const classString = cls(`${prefixCls}-item`, `${prefixCls}-item-${mergedStatus}`, className, {
161+
[`${prefixCls}-item-custom`]: icon,
162+
[`${prefixCls}-item-active`]: active,
163+
[`${prefixCls}-item-disabled`]: disabled === true,
164+
});
151165

152166
const stepItemStyle: React.CSSProperties = { ...style };
153167

src/Steps.tsx

Lines changed: 80 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export type StepItem = {
1616
status?: Status;
1717
subTitle?: React.ReactNode;
1818
title?: React.ReactNode;
19+
20+
onClick?: React.MouseEventHandler<HTMLDivElement>;
1921
};
2022

2123
export type StepIconRender = (info: {
@@ -47,6 +49,7 @@ export interface StepsProps {
4749
className?: string;
4850
classNames?: Partial<Record<SemanticName, string>>;
4951
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
52+
rootClassName?: string;
5053

5154
// layout
5255
orientation?: 'horizontal' | 'vertical';
@@ -78,6 +81,7 @@ export default function Steps(props: StepsProps) {
7881
className,
7982
classNames,
8083
styles,
84+
rootClassName,
8185

8286
// layout
8387
orientation = 'horizontal',
@@ -107,13 +111,38 @@ export default function Steps(props: StepsProps) {
107111
}, [orientation, progressDot, labelPlacement]);
108112

109113
// ============================= styles =============================
110-
const classString = cls(prefixCls, `${prefixCls}-${mergedOrientation}`, className, {
111-
[`${prefixCls}-label-${mergeLabelPlacement}`]: mergedOrientation === 'horizontal',
112-
[`${prefixCls}-dot`]: !!progressDot,
113-
});
114+
const classString = cls(
115+
prefixCls,
116+
`${prefixCls}-${mergedOrientation}`,
117+
{
118+
[`${prefixCls}-label-${mergeLabelPlacement}`]: mergedOrientation === 'horizontal',
119+
[`${prefixCls}-dot`]: !!progressDot,
120+
},
121+
rootClassName,
122+
className,
123+
classNames.root,
124+
);
114125

115126
// ============================== Data ==============================
116127
const mergedItems = React.useMemo(() => (items || []).filter(Boolean), [items]);
128+
const statuses = React.useMemo(
129+
() =>
130+
mergedItems.map(({ status: itemStatus }, index) => {
131+
const stepNumber = initial + index;
132+
133+
if (!itemStatus) {
134+
if (stepNumber === current) {
135+
return status;
136+
} else if (stepNumber < current) {
137+
return 'finish';
138+
}
139+
return 'wait';
140+
}
141+
142+
return itemStatus;
143+
}),
144+
[mergedItems, status, current, initial],
145+
);
117146

118147
// ============================= events =============================
119148
const onStepClick = (next: number) => {
@@ -123,47 +152,66 @@ export default function Steps(props: StepsProps) {
123152
};
124153

125154
// ============================= render =============================
126-
const renderStep = (item: StepProps, index: number) => {
127-
const prevItem = mergedItems[index - 1];
155+
const renderStep = (item: StepItem, index: number) => {
156+
const stepIndex = initial + index;
128157

129-
const data: StepProps = { ...item };
130-
const stepNumber = initial + index;
131158
// fix tail color
132-
if (status === 'error' && index === current - 1) {
133-
data.className = `${prefixCls}-next-error`;
134-
}
135-
136-
if (!data.status) {
137-
if (stepNumber === current) {
138-
data.status = status;
139-
} else if (stepNumber < current) {
140-
data.status = 'finish';
141-
} else {
142-
data.status = 'wait';
143-
}
144-
}
145-
146-
if (!data.render && itemRender) {
147-
data.render = (stepItem) => itemRender(data, stepItem);
148-
}
159+
// if (status === 'error' && index === current - 1) {
160+
// data.className = `${prefixCls}-next-error`;
161+
// }
162+
163+
// const { status: currentStatus = status } = item;
164+
// const { status: prevStatus = currentStatus } = prevItem || {};
165+
166+
// if (!data.status) {
167+
// if (stepNumber === current) {
168+
// data.status = status;
169+
// } else if (stepNumber < current) {
170+
// data.status = 'finish';
171+
// } else {
172+
// data.status = 'wait';
173+
// }
174+
// }
175+
176+
const prevStatus = statuses[index - 1];
177+
const itemStatus = statuses[index];
178+
179+
// if (!data.render && itemRender) {
180+
// data.render = (stepItem) => itemRender(data, stepItem);
181+
// }
149182

150183
return (
151184
<Step
152-
data={data}
153-
active={stepNumber === current}
154-
stepNumber={stepNumber + 1}
155-
stepIndex={stepNumber}
156-
key={stepNumber}
185+
// Style
157186
prefixCls={prefixCls}
187+
classNames={classNames}
188+
styles={styles}
189+
// Data
190+
data={item}
191+
status={itemStatus}
192+
prevStatus={prevStatus}
193+
active={stepIndex === current}
194+
index={stepIndex}
195+
// stepNumber={stepNumber + 1}
196+
// stepIndex={stepNumber}
197+
// Render
198+
key={stepIndex}
158199
progressDot={progressDot}
159200
iconRender={iconRender}
160-
onStepClick={onChange && onStepClick}
201+
onClick={onChange && onStepClick}
161202
/>
162203
);
163204
};
164205

165206
return (
166-
<div className={classString} style={style} {...restProps}>
207+
<div
208+
className={classString}
209+
style={{
210+
...style,
211+
...styles?.root,
212+
}}
213+
{...restProps}
214+
>
167215
{mergedItems.map<React.ReactNode>(renderStep)}
168216
</div>
169217
);

0 commit comments

Comments
 (0)