Skip to content

Commit

Permalink
feat(ui): add timeline component
Browse files Browse the repository at this point in the history
  • Loading branch information
xiejay97 committed Aug 3, 2022
1 parent 1c0f582 commit 47679f4
Show file tree
Hide file tree
Showing 22 changed files with 552 additions and 120 deletions.
48 changes: 21 additions & 27 deletions packages/ui/src/components/accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,8 @@ export function DAccordion<ID extends DId, T extends DAccordionItem<ID>>(props:

return (
<div {...restProps} className={getClassName(restProps.className, `${dPrefix}accordion`)}>
{dList.map((accordion, index) => {
const {
id: accordionId,
title: accordionTitle,
region: accordionRegion,
arrow: accordionArrow = dArrow,
disabled: accordionDisabled = false,
} = accordion;
{dList.map((item, index) => {
const { id: itemId, title: itemTitle, region: itemRegion, arrow: itemArrow = dArrow, disabled: itemDisabled = false } = item;

const getAccordion = (next: boolean, _index = index): T | undefined => {
for (let focusIndex = next ? _index + 1 : _index - 1, n = 0; n < dList.length; next ? focusIndex++ : focusIndex--, n++) {
Expand All @@ -104,52 +98,52 @@ export function DAccordion<ID extends DId, T extends DAccordionItem<ID>>(props:
}
};

const buttonId = getButtonId(accordionId);
const regionId = getRegionId(accordionId);
const isActive = dActiveOne ? activeId === accordionId : (activeId as ID[]).includes(accordionId);
const buttonId = getButtonId(itemId);
const regionId = getRegionId(itemId);
const isActive = dActiveOne ? activeId === itemId : (activeId as ID[]).includes(itemId);
const iconRotate = (() => {
if (accordionArrow === 'left' && !isActive) {
if (itemArrow === 'left' && !isActive) {
return -90;
}
if (accordionArrow === 'right' && isActive) {
if (itemArrow === 'right' && isActive) {
return 180;
}
return undefined;
})();

const handleClick = () => {
if (dActiveOne) {
changeActiveId(isActive ? null : accordionId);
changeActiveId(isActive ? null : itemId);
} else {
changeActiveId((draft) => {
const index = (draft as ID[]).findIndex((v) => v === accordionId);
const index = (draft as ID[]).findIndex((v) => v === itemId);
if (index !== -1) {
(draft as ID[]).splice(index, 1);
} else {
(draft as ID[]).push(accordionId);
(draft as ID[]).push(itemId);
}
});
}
};

return (
<div
key={accordionId}
key={itemId}
className={getClassName(`${dPrefix}accordion__container`, {
[`${dPrefix}accordion__container--last`]: index === dList.length - 1,
})}
>
<div
id={buttonId}
className={getClassName(`${dPrefix}accordion__button`, {
[`${dPrefix}accordion__button--arrow-left`]: accordionArrow === 'left',
'is-disabled': accordionDisabled,
[`${dPrefix}accordion__button--arrow-left`]: itemArrow === 'left',
'is-disabled': itemDisabled,
})}
tabIndex={accordionDisabled ? -1 : 0}
tabIndex={itemDisabled ? -1 : 0}
role="button"
aria-controls={regionId}
aria-expanded={isActive}
aria-disabled={accordionDisabled}
aria-disabled={itemDisabled}
onClick={handleClick}
onKeyDown={(e) => {
switch (e.code) {
Expand Down Expand Up @@ -194,8 +188,8 @@ export function DAccordion<ID extends DId, T extends DAccordionItem<ID>>(props:
}
}}
>
<div className={`${dPrefix}accordion__title`}>{accordionTitle}</div>
{accordionArrow && <DownOutlined className={`${dPrefix}accordion__arrow`} dRotate={iconRotate} />}
<div className={`${dPrefix}accordion__title`}>{itemTitle}</div>
{itemArrow && <DownOutlined className={`${dPrefix}accordion__arrow`} dRotate={iconRotate} />}
</div>
<DCollapseTransition
dSize={0}
Expand All @@ -217,10 +211,10 @@ export function DAccordion<ID extends DId, T extends DAccordionItem<ID>>(props:
leaved: { display: 'none' },
}}
afterEnter={() => {
afterActiveChange?.(accordionId, accordion, true);
afterActiveChange?.(itemId, item, true);
}}
afterLeave={() => {
afterActiveChange?.(accordionId, accordion, false);
afterActiveChange?.(itemId, item, false);
}}
>
{(ref, collapseStyle) => (
Expand All @@ -230,9 +224,9 @@ export function DAccordion<ID extends DId, T extends DAccordionItem<ID>>(props:
className={`${dPrefix}accordion__region`}
style={collapseStyle}
role="region"
aria-labelledby={getButtonId(accordionId)}
aria-labelledby={getButtonId(itemId)}
>
{accordionRegion}
{itemRegion}
</div>
)}
</DCollapseTransition>
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ export { DTextarea } from './textarea';
export type { DTimePickerProps } from './time-picker';
export { DTimePicker } from './time-picker';

export type { DTimelineProps } from './timeline';
export { DTimeline } from './timeline';

export type { DToastProps } from './toast';
export { ToastService } from './toast';

Expand Down
36 changes: 18 additions & 18 deletions packages/ui/src/components/stepper/Stepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface DStepperItem {
title: React.ReactNode;
description?: React.ReactNode;
icon?: React.ReactNode;
status?: 'completed' | 'process' | 'wait' | 'error';
status?: 'completed' | 'active' | 'wait' | 'error';
}

export interface DStepperProps<T extends DStepperItem> extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
Expand Down Expand Up @@ -56,12 +56,12 @@ export function DStepper<T extends DStepperItem>(props: DStepperProps<T>): JSX.E
[`${dPrefix}stepper--button`]: dClickable,
})}
>
{dList.map((step, index) => {
const { step: stepStep = index + 1, title: stepTitle, description: stepDescription, icon: stepIcon, status: stepStatus } = step;
{dList.map((item, index) => {
const { step: itemStep = index + 1, title: itemTitle, description: itemDescription, icon: itemIcon, status: itemStatus } = item;

const isCompleted = stepStep < active;
const isActive = stepStep === active;
const isWait = stepStep > active;
const isCompleted = itemStep < active;
const isActive = itemStep === active;
const isWait = itemStep > active;

const isProgress = isActive && isNumber(dPercent);

Expand All @@ -70,7 +70,7 @@ export function DStepper<T extends DStepperItem>(props: DStepperProps<T>): JSX.E
className={`${dPrefix}stepper__step-title`}
style={{ marginTop: dLabelBottom ? undefined : `calc((${dIconSize}px - 1.1em) / 2)` }}
>
{stepTitle}
{itemTitle}
</div>
);

Expand All @@ -91,18 +91,18 @@ export function DStepper<T extends DStepperItem>(props: DStepperProps<T>): JSX.E

return (
<div
key={stepStep}
key={itemStep}
className={getClassName(
`${dPrefix}stepper__step`,
isUndefined(stepStatus)
isUndefined(itemStatus)
? {
'is-completed': isCompleted,
'is-active': isActive,
'is-wait': isWait,
}
: {},
{
[`is-${stepStatus}`]: stepStatus,
[`is-${itemStatus}`]: itemStatus,
[`${dPrefix}stepper__step--last`]: index === dList.length - 1,
}
)}
Expand All @@ -117,13 +117,13 @@ export function DStepper<T extends DStepperItem>(props: DStepperProps<T>): JSX.E
if (e.code === 'Enter' || e.code === 'Space') {
e.preventDefault();

onItemClick?.(stepStep, step);
onItemClick?.(itemStep, item);
}
}
}}
onClick={() => {
if (dClickable) {
onItemClick?.(stepStep, step);
onItemClick?.(itemStep, item);
}
}}
>
Expand All @@ -137,14 +137,14 @@ export function DStepper<T extends DStepperItem>(props: DStepperProps<T>): JSX.E
height: dIconSize,
}}
>
{stepIcon === false ? null : checkNodeExist(stepIcon) ? (
stepIcon
) : stepStatus === 'error' ? (
{itemIcon === false ? null : checkNodeExist(itemIcon) ? (
itemIcon
) : itemStatus === 'error' ? (
<CloseOutlined />
) : isCompleted ? (
<CheckOutlined />
) : (
stepStep
itemStep
)}
{isProgress && (
<DProgress
Expand All @@ -163,7 +163,7 @@ export function DStepper<T extends DStepperItem>(props: DStepperProps<T>): JSX.E
</div>
{dLabelBottom && titleNode}
{dVertical && separatoreNode}
{checkNodeExist(stepDescription) && (
{checkNodeExist(itemDescription) && (
<DCollapseTransition
dSize={0}
dIn={!dVertical || isActive}
Expand All @@ -187,7 +187,7 @@ export function DStepper<T extends DStepperItem>(props: DStepperProps<T>): JSX.E
marginLeft: dLabelBottom ? undefined : `calc(${dIconSize}px + 8px)`,
}}
>
{stepDescription}
{itemDescription}
</div>
)}
</DCollapseTransition>
Expand Down
12 changes: 6 additions & 6 deletions packages/ui/src/components/stepper/demos/1.Basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ export default function Demo() {
dActive={active}
dList={[
{
title: `This is a long long long long long title`,
title: 'This is a long long long long long title',
},
{
title: `Step 2`,
title: 'Step 2',
},
{
title: `Step 3`,
description: `This is a long long long long long description.`,
title: 'Step 3',
description: 'This is a long long long long long description.',
},
{
title: `Step 4`,
description: `This is 4 description.`,
title: 'Step 4',
description: 'This is 4 description.',
},
]}
></DStepper>
Expand Down
12 changes: 6 additions & 6 deletions packages/ui/src/components/stepper/demos/2.Clickable.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ export default function Demo() {
dActive={active}
dList={[
{
title: `This is a long long long long long title`,
title: 'This is a long long long long long title',
},
{
title: `Step 2`,
title: 'Step 2',
},
{
title: `Step 3`,
description: `This is a long long long long long description.`,
title: 'Step 3',
description: 'This is a long long long long long description.',
},
{
title: `Step 4`,
description: `This is 4 description.`,
title: 'Step 4',
description: 'This is 4 description.',
},
]}
dClickable
Expand Down
12 changes: 6 additions & 6 deletions packages/ui/src/components/stepper/demos/3.LabelBottom.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ export default function Demo() {
dActive={3}
dList={[
{
title: `This is a long long long long long title`,
title: 'This is a long long long long long title',
},
{
title: `Step 2`,
title: 'Step 2',
},
{
title: `Step 3`,
description: `This is a long long long long long description.`,
title: 'Step 3',
description: 'This is a long long long long long description.',
},
{
title: `Step 4`,
description: `This is 4 description.`,
title: 'Step 4',
description: 'This is 4 description.',
},
]}
dLabelBottom
Expand Down
12 changes: 6 additions & 6 deletions packages/ui/src/components/stepper/demos/4.Status.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ export default function Demo() {
dActive={3}
dList={[
{
title: `Step 1`,
description: `This is 1 description.`,
title: 'Step 1',
description: 'This is 1 description.',
},
{
title: `Step 2`,
title: 'Step 2',
status: 'error',
description: `This is 2 description.`,
description: 'This is 2 description.',
},
{
title: `Step 3`,
description: `This is 3 description.`,
title: 'Step 3',
description: 'This is 3 description.',
},
]}
></DStepper>
Expand Down
24 changes: 12 additions & 12 deletions packages/ui/src/components/stepper/demos/5.CustomIcon.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ export default function Demo() {
dActive={2}
dList={[
{
title: `Step 1`,
description: `This is 1 description.`,
title: 'Step 1',
description: 'This is 1 description.',
icon: false,
},
{
title: `Step 2`,
description: `This is 2 description.`,
title: 'Step 2',
description: 'This is 2 description.',
icon: false,
},
{
title: `Step 3`,
description: `This is 3 description.`,
title: 'Step 3',
description: 'This is 3 description.',
icon: false,
},
]}
Expand All @@ -46,18 +46,18 @@ export default function Demo() {
dActive={2}
dList={[
{
title: `Step 1`,
description: `This is 1 description.`,
title: 'Step 1',
description: 'This is 1 description.',
icon: <PhoneOutlined />,
},
{
title: `Step 2`,
description: `This is 2 description.`,
title: 'Step 2',
description: 'This is 2 description.',
icon: <MessageOutlined />,
},
{
title: `Step 3`,
description: `This is 3 description.`,
title: 'Step 3',
description: 'This is 3 description.',
},
]}
></DStepper>
Expand Down
Loading

0 comments on commit 47679f4

Please sign in to comment.