Skip to content

Commit

Permalink
feat: Steps support inline (#269)
Browse files Browse the repository at this point in the history
* test: update snapshot

* docs: add inline type

* docs: add inline demo
  • Loading branch information
JarvisArt authored Nov 1, 2022
1 parent e63079a commit 2aefd90
Show file tree
Hide file tree
Showing 9 changed files with 321 additions and 9 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ https://react-component.github.io/steps/
<td>type</td>
<td>string</td>
<td>default</td>
<td>diretypetion of Steps, enum: `default` or `navigation`</td>
<td>diretypetion of Steps, could be `default` `navigation` `inline`</td>
</tr>
<tr>
<td>direction</td>
Expand Down Expand Up @@ -105,6 +105,12 @@ https://react-component.github.io/steps/
<td></td>
<td>specify the default finish icon and error icon</td>
</tr>
<tr>
<td>itemRender</td>
<td>(item: StepProps, stepItem: React.ReactNode) => React.ReactNode</td>
<td></td>
<td>custom step item renderer</td>
</tr>
<tr>
<td>onChange</td>
<td>(current: number) => void</td>
Expand Down Expand Up @@ -168,6 +174,12 @@ https://react-component.github.io/steps/
<td>false</td>
<td>disabled step when onChange exist</td>
</tr>
<tr>
<td>render</td>
<td>(stepItem: React.ReactNode) => React.ReactNode</td>
<td></td>
<td>custom step item renderer</td>
</tr>
</tbody>
</table>

Expand Down
1 change: 1 addition & 0 deletions assets/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,4 @@
@import 'label-placement';
@import 'progress-dot';
@import 'nav';
@import 'inline';
81 changes: 81 additions & 0 deletions assets/inline.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
@import 'variables';

.@{stepsPrefixClass}-inline {
width: auto;
display: inline-flex;

.@{stepsPrefixClass}-item {
flex: none;

&-container {
padding: 9px 4px 0;
margin: 0 2px;
border-radius: 4px;
cursor: pointer;
&:hover {
background: rgba(0, 0, 0, 0.04);
}
&[role='button']:hover {
opacity: 1;
}
}

&-icon {
width: 6px;
height: 6px;
margin-left: calc(50% - 3px);
> .@{stepsPrefixClass}-icon {
top: 0;
}
.@{stepsPrefixClass}-icon-dot {
border-radius: 3px;
}
}

&-content {
width: auto;
margin-top: 7px;
}
&-title {
color: rgba(0, 0, 0, 0.25);
font-size: 12px;
line-height: 20px;
font-weight: normal;
margin-bottom: 2px;
}
&-description {
display: none;
}

&-tail {
margin-left: 0;
top: 11px;
&:after {
height: 1px;
}
}
&:first-child .@{stepsPrefixClass}-item-tail{
width: 50%;
margin-left: 50%;
}
&:last-child .@{stepsPrefixClass}-item-tail{
display: block;
width: 50%;
}

&-finish {
.@{stepsPrefixClass}-item-tail:after {
background-color: @process-tail-color;
}
.@{stepsPrefixClass}-item-icon .@{stepsPrefixClass}-icon .@{stepsPrefixClass}-icon-dot {
background-color: @process-tail-color;
}
}
&-wait {
.@{stepsPrefixClass}-item-icon .@{stepsPrefixClass}-icon .@{stepsPrefixClass}-icon-dot {
background-color: #fff;
border: 1px solid @process-tail-color;
}
}
}
}
2 changes: 2 additions & 0 deletions docs/demo/inline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
## inline
<code src="../examples/inline.jsx">
36 changes: 36 additions & 0 deletions docs/examples/inline.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import '../../assets/index.less';
import React, { useState } from 'react';
import Steps from 'rc-steps';

export default () => {
const [current, setCurrent] = useState(0);

return (
<Steps
type="inline"
current={current}
onChange={setCurrent}
items={[
{
title: '开发',
description: '开发阶段:开发中',
},
{
title: '测试',
description: '测试阶段:测试中',
},
{
title: '预发',
description: '预发阶段:预发中',
},
{
title: '发布',
description: '发布阶段:发布中',
}
]}
itemRender={(item, stepItem) => (
React.cloneElement(stepItem, { title: item.description })
)}
/>
)
};
10 changes: 9 additions & 1 deletion src/Step.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface StepProps {
onStepClick?: (index: number) => void;
progressDot?: ProgressDotRender | boolean;
stepIcon?: StepIconRender;
render?: (stepItem: React.ReactNode) => React.ReactNode;
}

export default class Step extends React.Component<StepProps> {
Expand Down Expand Up @@ -126,6 +127,7 @@ export default class Step extends React.Component<StepProps> {
stepIndex,
onStepClick,
onClick,
render,
...restProps
} = this.props;

Expand All @@ -147,7 +149,7 @@ export default class Step extends React.Component<StepProps> {
accessibilityProps.onClick = this.onClick;
}

return (
let stepNode: React.ReactNode = (
<div {...restProps} className={classString} style={stepItemStyle}>
<div onClick={onClick} {...accessibilityProps} className={`${prefixCls}-item-container`}>
<div className={`${prefixCls}-item-tail`}>{tailContent}</div>
Expand All @@ -169,5 +171,11 @@ export default class Step extends React.Component<StepProps> {
</div>
</div>
);

if (render) {
stepNode = render(stepNode) || null;
}

return stepNode;
}
}
33 changes: 26 additions & 7 deletions src/Steps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export interface StepsProps {
className?: string;
children?: React.ReactNode;
direction?: 'horizontal' | 'vertical';
type?: 'default' | 'navigation';
type?: 'default' | 'navigation' | 'inline';
labelPlacement?: 'horizontal' | 'vertical';
iconPrefix?: string;
status?: Status;
Expand All @@ -40,6 +40,7 @@ export interface StepsProps {
initial?: number;
icons?: Icons;
items?: StepProps[];
itemRender?: (item: StepProps, stepItem: React.ReactNode) => React.ReactNode;
onChange?: (current: number) => void;
}

Expand Down Expand Up @@ -84,16 +85,25 @@ export default class Steps extends React.Component<StepsProps> {
initial,
icons,
onChange,
itemRender,
items = [],
...restProps
} = this.props;
const isNav = type === 'navigation';
const adjustedLabelPlacement = progressDot ? 'vertical' : labelPlacement;
const classString = classNames(prefixCls, `${prefixCls}-${direction}`, className, {
[`${prefixCls}-${size}`]: size,
[`${prefixCls}-label-${adjustedLabelPlacement}`]: direction === 'horizontal',
[`${prefixCls}-dot`]: !!progressDot,
const isInline = type === 'inline';

// inline type requires fixed progressDot direction size.
const mergedProgressDot = isInline || progressDot;
const mergedDirection = isInline ? 'horizontal' : direction;
const mergedSize = isInline ? undefined : size;

const adjustedLabelPlacement = mergedProgressDot ? 'vertical' : labelPlacement;
const classString = classNames(prefixCls, `${prefixCls}-${mergedDirection}`, className, {
[`${prefixCls}-${mergedSize}`]: mergedSize,
[`${prefixCls}-label-${adjustedLabelPlacement}`]: mergedDirection === 'horizontal',
[`${prefixCls}-dot`]: !!mergedProgressDot,
[`${prefixCls}-navigation`]: isNav,
[`${prefixCls}-inline`]: isInline,
});

return (
Expand All @@ -118,6 +128,15 @@ export default class Steps extends React.Component<StepsProps> {
}
}

if (isInline) {
mergedItem.icon = undefined;
mergedItem.subTitle = undefined;
}

if (!mergedItem.render && itemRender) {
mergedItem.render = (stepItem) => itemRender(mergedItem, stepItem);
}

return (
<Step
{...mergedItem}
Expand All @@ -128,7 +147,7 @@ export default class Steps extends React.Component<StepsProps> {
prefixCls={prefixCls}
iconPrefix={iconPrefix}
wrapperStyle={style}
progressDot={progressDot}
progressDot={mergedProgressDot}
stepIcon={stepIcon}
icons={icons}
onStepClick={onChange && this.onStepClick}
Expand Down
Loading

0 comments on commit 2aefd90

Please sign in to comment.