Skip to content

Commit d24474d

Browse files
committed
chore: support components
1 parent 2815305 commit d24474d

File tree

4 files changed

+78
-7
lines changed

4 files changed

+78
-7
lines changed

src/Context.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import * as React from 'react';
2+
import type { StepsProps } from './Steps';
3+
4+
export interface StepsContextProps {
5+
prefixCls: string;
6+
classNames: NonNullable<StepsProps['classNames']>;
7+
styles: NonNullable<StepsProps['styles']>;
8+
}
9+
10+
export const StepsContext = React.createContext<StepsContextProps>(null!);

src/Step.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import KeyCode from '@rc-component/util/lib/KeyCode';
55
import type { Status, StepItem, StepsProps } from './Steps';
66
import Rail from './Rail';
77
import { UnstableContext } from './UnstableContext';
8+
import StepIcon from './StepIcon';
89

910
function hasContent<T>(value: T) {
1011
return value !== undefined && value !== null;
@@ -133,11 +134,21 @@ export default function Step(props: StepProps) {
133134
classNames.item,
134135
);
135136

137+
let iconNode = <StepIcon />;
138+
if (iconRender) {
139+
iconNode = iconRender(iconNode, {
140+
...renderInfo,
141+
components: {
142+
icon: StepIcon,
143+
},
144+
}) as React.ReactElement;
145+
}
146+
136147
const wrapperNode = (
137148
<div className={cls(`${itemCls}-wrapper`, classNames.itemWrapper)} style={styles.itemWrapper}>
138-
<div className={cls(`${itemCls}-icon`, classNames.itemIcon)} style={styles.itemIcon}>
139-
{iconRender?.(renderInfo)}
140-
</div>
149+
{/* Icon */}
150+
{iconNode}
151+
141152
<div className={cls(`${itemCls}-section`, classNames.itemSection)} style={styles.itemSection}>
142153
<div className={cls(`${itemCls}-header`, classNames.itemHeader)} style={styles.itemHeader}>
143154
{hasTitle && (

src/StepIcon.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import * as React from 'react';
2+
import cls from 'classnames';
3+
import { StepsContext } from './Context';
4+
import pickAttrs from '@rc-component/util/lib/pickAttrs';
5+
6+
export type StepIconProps = React.HTMLAttributes<HTMLDivElement>;
7+
8+
const StepIcon = React.forwardRef<HTMLDivElement, StepIconProps>((props, ref) => {
9+
const { className, style, ...restProps } = props;
10+
const { prefixCls, classNames, styles } = React.useContext(StepsContext);
11+
12+
const itemCls = `${prefixCls}-item`;
13+
14+
return (
15+
<div
16+
{...pickAttrs(restProps, false)}
17+
ref={ref}
18+
className={cls(`${itemCls}-icon`, classNames.itemIcon, className)}
19+
style={{
20+
...styles.itemIcon,
21+
...style,
22+
}}
23+
/>
24+
);
25+
});
26+
27+
export default StepIcon;

src/Steps.tsx

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
import cls from 'classnames';
33
import React from 'react';
44
import Step from './Step';
5+
import { StepsContext, type StepsContextProps } from './Context';
6+
import type StepIcon from './StepIcon';
57

68
export type Status = 'error' | 'process' | 'finish' | 'wait';
79

10+
const EmptyObject = {};
11+
812
export type SemanticName =
913
| 'root'
1014
| 'item'
@@ -65,7 +69,14 @@ export interface StepsProps {
6569
onChange?: (current: number) => void;
6670

6771
// render
68-
iconRender?: (info: RenderInfo) => React.ReactNode;
72+
iconRender?: (
73+
originNode: React.ReactElement,
74+
info: RenderInfo & {
75+
components: {
76+
icon: typeof StepIcon;
77+
};
78+
},
79+
) => React.ReactNode;
6980
itemRender?: (originNode: React.ReactElement, info: RenderInfo) => React.ReactNode;
7081
itemWrapperRender?: (originNode: React.ReactElement) => React.ReactNode;
7182
}
@@ -76,8 +87,8 @@ export default function Steps(props: StepsProps) {
7687
prefixCls = 'rc-steps',
7788
style,
7889
className,
79-
classNames = {},
80-
styles = {},
90+
classNames = EmptyObject as NonNullable<StepsProps['classNames']>,
91+
styles = EmptyObject as NonNullable<StepsProps['styles']>,
8192
rootClassName,
8293

8394
// layout
@@ -143,6 +154,16 @@ export default function Steps(props: StepsProps) {
143154
}
144155
};
145156

157+
// ============================ contexts ============================
158+
const stepIconContext = React.useMemo<StepsContextProps>(
159+
() => ({
160+
prefixCls,
161+
classNames,
162+
styles,
163+
}),
164+
[prefixCls, classNames, styles],
165+
);
166+
146167
// ============================= render =============================
147168
const renderStep = (item: StepItem, index: number) => {
148169
const stepIndex = initial + index;
@@ -186,7 +207,9 @@ export default function Steps(props: StepsProps) {
186207
}}
187208
{...restProps}
188209
>
189-
{mergedItems.map<React.ReactNode>(renderStep)}
210+
<StepsContext.Provider value={stepIconContext}>
211+
{mergedItems.map<React.ReactNode>(renderStep)}
212+
</StepsContext.Provider>
190213
</div>
191214
);
192215
}

0 commit comments

Comments
 (0)