diff --git a/README.md b/README.md index 339c129..b96eec6 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,16 @@ Props that can be passed to the component are listed below: undefined + + completedNodeStyle?: object + Custom styles for completed nodes + undefined + + + currentNodeStyle?: object + Custom styles for current nodes + undefined + @@ -159,7 +169,8 @@ function App() { }), CompletedNode: () => ({ backgroundColor: "#028A0F", - }; + }) + }; return ( = (props) => { currentStepIndex, handleStepClick, showCursor, - getStyles + getStyles, + nodeStyle } = props; + const isCompleted = step.completed; + const isActive = index === currentStepIndex; + return (
handleStepClick && handleStepClick()} role="presentation" id="stepper-node" @@ -44,13 +42,15 @@ const Node: FC = (props) => { {(renderNode && renderNode(step, index)) || ( <> - {step?.completed && ( + {isCompleted ? ( ) - || index + 1} + /> + ) : ( + index + 1 + )} )}
diff --git a/src/node/types.d.ts b/src/node/types.d.ts index 9ac608b..ac7aba7 100644 --- a/src/node/types.d.ts +++ b/src/node/types.d.ts @@ -1,13 +1,14 @@ -import { ReactElement } from "react"; -import { IStep } from "../stepper/types"; +import { ReactElement, CSSProperties } from "react"; import { Elements } from "../constants"; +import type { IStep } from "../stepper/types"; -export type INodeProps = { +export interface INodeProps { step: IStep; - renderNode?(step: IStep, index: number): ReactElement; index: number; - currentStepIndex?: number; - handleStepClick(): void; + currentStepIndex: number; + handleStepClick?: () => void; showCursor: boolean; - getStyles(element: Elements): object; -}; + renderNode?: (step: IStep, stepIndex: number) => ReactElement; + getStyles: (element: Elements) => object; + nodeStyle?: CSSProperties; +} diff --git a/src/stepper/step.tsx b/src/stepper/step.tsx index 5fb13c5..3cadd66 100644 --- a/src/stepper/step.tsx +++ b/src/stepper/step.tsx @@ -1,6 +1,6 @@ import React, { useRef, useEffect, useState } from "react"; import "./styles.scss"; -import type { IStepProps } from "../stepper/types"; +import type { IStepProps } from "./types"; import { LABEL_POSITION, ORIENTATION } from "../constants"; import StepContent from "./stepContent"; import StepInfo from "./stepInfo"; @@ -26,7 +26,9 @@ const Step: (props: IStepProps) => JSX.Element = ({ showDescriptionsForAllSteps = false, stepContent, onStepClick, - renderNode + renderNode, + completedNodeStyle, + currentNodeStyle } = stepperProps; const [nodeWidth, setNodeWidth] = useState(0); @@ -68,51 +70,39 @@ const Step: (props: IStepProps) => JSX.Element = ({ currentStepIndex > index ? "activeConnector" : "" } ${index === steps.length - 1 ? "hiddenConnector" : ""}`; + const stepInfoProps = { + orientation, + labelPosition, + isVertical, + isInlineLabelsAndSteps, + index, + currentStepIndex, + step, + showDescriptionsForAllSteps, + onStepClick, + renderNode, + styles, + nodeRef, + prevConnectorClassName, + nextConnectorClassName, + steps, + completedNodeStyle, + currentNodeStyle + }; + return orientation !== ORIENTATION.VERTICAL && labelPosition === LABEL_POSITION.TOP ? ( - + ) : (
- + JSX.Element = ({ nodeRef, prevConnectorClassName, nextConnectorClassName, - steps -}: IStepInfoProps) => ( -
- {!isInlineLabelsAndSteps && ( -
onStepClick && onStepClick(step, index)}> -
- {step.stepLabel} -
- {step.stepDescription && (showDescriptionsForAllSteps || index === currentStepIndex) && - orientation !== ORIENTATION.VERTICAL && - labelPosition === LABEL_POSITION.TOP && ( + steps, + completedNodeStyle, + currentNodeStyle +}: IStepInfoProps) => { + const getNodeStyle = (): CSSProperties => { + const defaultStyles = getStyles(styles, Elements.Node, step, index) as CSSProperties; + const isCompleted = step.completed; + const isActive = index === currentStepIndex; + + const getNodeStyles = (): NodeStyles => { + switch (true) { + case isCompleted: + return { + elementStyle: Elements.CompletedNode, + customStyle: completedNodeStyle + }; + case isActive: + return { + elementStyle: Elements.ActiveNode, + customStyle: currentNodeStyle + }; + default: + return { + elementStyle: Elements.InActiveNode, + customStyle: undefined + }; + } + }; + + const { elementStyle, customStyle } = getNodeStyles(); + + return { + ...defaultStyles, + ...(getStyles(styles, elementStyle, step, index) as CSSProperties), + ...(customStyle || {}) + }; + }; + + return ( +
+ {!isInlineLabelsAndSteps && ( +
onStepClick && onStepClick(step, index)}>
- {step.stepDescription} + {step.stepLabel}
- )} -
- )} -
-
-
- onStepClick && onStepClick(step, index)} - showCursor={!!onStepClick} - renderNode={renderNode} - getStyles={(element: Elements): object => - getStyles(styles, element, step, index) - } + {step.stepDescription && (showDescriptionsForAllSteps || index === currentStepIndex) && + orientation !== ORIENTATION.VERTICAL && + labelPosition === LABEL_POSITION.TOP && ( +
+ {step.stepDescription} +
+ )} +
+ )} +
+
-
- {isInlineLabelsAndSteps && (
+ onStepClick && onStepClick(step, index)} + showCursor={!!onStepClick} + renderNode={renderNode} + getStyles={(element: Elements): object => + getStyles(styles, element, step, index) + } + nodeStyle={getNodeStyle()} + /> +
+ {isInlineLabelsAndSteps && (
onStepClick && onStepClick(step, index)} + className={`labelContainer ${ + [LABEL_POSITION.TOP, LABEL_POSITION.LEFT].includes(labelPosition) + ? "reversedLabelContainer" + : "" + }`} > - {step.stepLabel} +
onStepClick && onStepClick(step, index)} + > + {step.stepLabel} +
-
- )} -
+ )} +
+
-
-); + ); +}; export default StepInfo; diff --git a/src/stepper/types.d.ts b/src/stepper/types.d.ts index dd62f3b..fb7ccd1 100644 --- a/src/stepper/types.d.ts +++ b/src/stepper/types.d.ts @@ -1,4 +1,4 @@ -import { LegacyRef, ReactElement } from "react"; +import { LegacyRef, ReactElement, CSSProperties } from "react"; import { LABEL_POSITION, ORIENTATION } from "../constants"; import { Elements } from "../constants"; @@ -18,6 +18,8 @@ export type IStepperProps = { stepContent?(step: IStep, stepIndex: number): ReactElement; onStepClick?(step: IStep, stepIndex: number): void; renderNode?(step: IStep, stepIndex: number): ReactElement; + completedNodeStyle?: CSSProperties; + currentNodeStyle?: CSSProperties; }; export type IStyleFunction = (step: IStep, stepIndex: number) => object; @@ -44,6 +46,8 @@ export type IStepInfoProps = { prevConnectorClassName: string; nextConnectorClassName: string; steps: IStep[]; + completedNodeStyle?: CSSProperties; + currentNodeStyle?: CSSProperties; } export type IStepContentProps = {