Skip to content

Commit

Permalink
feat: [Stepper] support inverted
Browse files Browse the repository at this point in the history
  • Loading branch information
akai committed Jul 5, 2022
1 parent f655b5c commit 29eacf4
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 33 deletions.
80 changes: 80 additions & 0 deletions demo/src/demo/Stepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,85 @@ export default () => (
<Step title="退款成功" />
</Stepper>
</DemoSection>
<DemoSection title="倒序">
<Stepper inverted>
<Step
title="官方客服处理中"
subTitle="05-23 11:23"
desc="客服将在24小时内联系您核实问题,请注意接听。"
/>
<Step
title="您发起投诉"
subTitle="05-23 11:23"
desc={
<div>
<div>投诉原因:物流问题,未放指定代收点。</div>
<div>投诉说明:都说了很多遍不要放驿站,还是放了。</div>
</div>
}
/>
</Stepper>
</DemoSection>
<DemoSection title="倒序&成功">
<Stepper inverted status="success">
<Step
title="官方客服判决,投诉成立"
subTitle="05-23 11:23"
desc="客服将在24小时内联系您核实问题,请注意接听。"
/>
<Step
title="您补充留言"
subTitle="05-23 11:23"
desc="卖家说好要发货怎么不发货,态度太差了!!"
/>
<Step title="买家填写退货并填写物流信息" subTitle="昨天 15:00" />
<Step title="卖家确认收货并退款" subTitle="昨天 16:00" />
<Step title="退款成功" />
</Stepper>
</DemoSection>
<DemoSection title="倒序&失败">
<Stepper inverted status="fail">
<Step
title="官方客服判决,投诉不成立"
subTitle="05-23 11:23"
desc="原因:核实订单还在约定发货时效内,已催促卖家发货,请耐心等待。"
/>
<Step
title="官方客服处理中"
subTitle="05-23 11:23"
desc="客服将在24小时内联系您核实问题,请注意接听。"
/>
<Step
title="您发起投诉"
subTitle="05-23 11:23"
desc={
<div>
<div>投诉原因:物流问题,未放指定代收点。</div>
<div>投诉说明:都说了很多遍不要放驿站,还是放了。</div>
</div>
}
/>
</Stepper>
</DemoSection>
<DemoSection title="倒序&取消">
<Stepper inverted status="abort">
<Step title="您撤销投诉" subTitle="05-23 11:23" desc="若后续遇到有问题,您可联系客服。" />
<Step
title="官方客服处理中"
subTitle="05-23 11:23"
desc="客服将在24小时内联系您核实问题,请注意接听。"
/>
<Step
title="您发起投诉"
subTitle="05-23 11:23"
desc={
<div>
<div>投诉原因:物流问题,未放指定代收点。</div>
<div>投诉说明:都说了很多遍不要放驿站,还是放了。</div>
</div>
}
/>
</Stepper>
</DemoSection>
</DemoPage>
);
31 changes: 28 additions & 3 deletions src/components/Stepper/Step.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,44 @@
import React from 'react';
import clsx from 'clsx';
import { Icon } from '../Icon';

export type StepStatus = 'success' | 'fail' | 'abort';

export type StepProps = {
className?: string;
active?: boolean;
completed?: boolean;
disabled?: boolean;
status?: StepStatus;
index?: number;
title?: string;
desc?: string;
subTitle?: string;
desc?: React.ReactNode;
children?: React.ReactNode;
};

function renderDot(status?: StepStatus) {
if (status) {
const iconMap: Record<string, string> = {
success: 'check-circle-fill',
fail: 'warning-circle-fill',
abort: 'dash-circle-fill',
};
return <Icon type={iconMap[status]} />;
}
return <div className="Step-dot" />;
}

export const Step = React.forwardRef<HTMLLIElement, StepProps>((props, ref) => {
const {
className,
active = false,
completed = false,
disabled = false,
status,
index,
title,
subTitle,
desc,
children,
...other
Expand All @@ -37,12 +56,18 @@ export const Step = React.forwardRef<HTMLLIElement, StepProps>((props, ref) => {
className,
)}
ref={ref}
data-status={status}
{...other}
>
<div className="Step-dot" />
<div className="Step-icon">{renderDot(status)}</div>
<div className="Step-line" />
<div className="Step-content">
{title && <div className="Step-title">{title}</div>}
{title && (
<div className="Step-title">
{title && <span>{title}</span>}
{subTitle && <small>{subTitle}</small>}
</div>
)}
{desc && <div className="Step-desc">{desc}</div>}
{children}
</div>
Expand Down
11 changes: 8 additions & 3 deletions src/components/Stepper/Stepper.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import React from 'react';
import clsx from 'clsx';
import type { StepProps, StepStatus } from './Step';

export type StepperProps = {
className?: string;
current?: number;
status?: StepStatus;
inverted?: boolean;
children?: React.ReactNode;
};

export const Stepper = React.forwardRef<HTMLUListElement, StepperProps>((props, ref) => {
const { className, current = 0, children, ...other } = props;
const { className, current = 0, status, inverted, children, ...other } = props;

const childrenArray = React.Children.toArray(children);
const steps = childrenArray.map((child, index) => {
const state = {
const state: StepProps = {
index,
active: false,
completed: false,
Expand All @@ -21,10 +24,12 @@ export const Stepper = React.forwardRef<HTMLUListElement, StepperProps>((props,

if (current === index) {
state.active = true;
state.status = status;
} else if (current > index) {
state.completed = true;
} else {
state.disabled = true;
state.disabled = !inverted;
state.completed = inverted;
}

return React.isValidElement(child)
Expand Down
79 changes: 52 additions & 27 deletions src/components/Stepper/style.less
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@step-icon-width: 24px;

.Stepper {
margin: 0;
padding: 0;
Expand All @@ -6,8 +8,8 @@

.Step {
position: relative;
padding-left: 24px;
padding-bottom: 10px;
padding-left: (@step-icon-width + 5px);
padding-bottom: 18px;

&:last-child {
padding-bottom: 0;
Expand All @@ -20,54 +22,77 @@

.Step--active {
.Step-dot {
transform: scale(1.5);
background: var(--brand-1);
}
.Step-line {
background: var(--gray-6);
.Step-title {
span {
color: var(--brand-1);
font-weight: 500;
}
}
.Step-title,
.Step-desc {
color: var(--gray-1);
}
}

.Step--disabled {
.Step-dot,
.Step-line {
background: var(--gray-6);
&[data-status] {
.Step-line {
top: (@step-icon-width + 2px);
}
.Step-icon {
color: var(--red);
}
}
.Step-title,
.Step-desc {
color: var(--gray-4);
&[data-status='success'] {
.Step-icon {
color: var(--green);
}
}
}

.Step-dot {
.Step-icon {
position: absolute;
top: 6px;
left: 2px;
z-index: @zindex-step-dot;
top: 0;
left: 0;
width: @step-icon-width;
height: @step-icon-width;
font-size: @step-icon-width;
display: flex;
justify-content: center;
align-items: center;
}

.Step-dot {
width: 8px;
height: 8px;
background: var(--white);
border: 1px solid var(--brand-1);
border-radius: 50%;
background: var(--brand-3);
}

.Step-line {
position: absolute;
top: 13px;
left: 5px;
bottom: -7px;
width: 2px;
background: var(--brand-3);
top: (@step-icon-width / 2 + 5px + 3px);
left: (@step-icon-width / 2);
bottom: -4px;
width: 1px;
background: var(--brand-1);
opacity: 0.5;
}

.Step-title {
color: var(--gray-2);
display: flex;
align-items: center;
color: var(--gray-1);
font-size: var(--font-size-md);

small {
margin-left: 12px;
color: var(--gray-3);
font-size: var(--font-size-xs);
}
}

.Step-desc {
margin-top: 3px;
color: var(--gray-3);
font-size: @font-size-xs;
font-size: var(--font-size-sm);
}

0 comments on commit 29eacf4

Please sign in to comment.