feat(webapp): import resource UI

This commit is contained in:
Ahmed Bouhuolia
2024-03-19 03:57:57 +02:00
parent 1ba26a3b85
commit ff5730d8a7
37 changed files with 1470 additions and 12 deletions

View File

@@ -0,0 +1,111 @@
// @ts-nocheck
import { cloneElement } from 'react';
import styled from 'styled-components';
import { toArray } from 'lodash';
import { Box } from '../Layout';
import { StepperCompleted } from './StepperCompleted';
import { StepperStep } from './StepperStep';
import { StepperStepState } from './types';
export interface StepperProps {
/** <Stepper.Step /> components */
children: React.ReactNode;
/** Index of the active step */
active: number;
/** Called when step is clicked */
onStepClick?: (stepIndex: number) => void;
/** Determines whether next steps can be selected, `true` by default **/
allowNextStepsSelect?: boolean;
classNames?: Record<string, string>;
}
export function Stepper({
active,
onStepClick,
children,
classNames,
}: StepperProps) {
const convertedChildren = toArray(children) as React.ReactElement[];
const _children = convertedChildren.filter(
(child) => child.type !== StepperCompleted,
);
const completedStep = convertedChildren.find(
(item) => item.type === StepperCompleted,
);
const items = _children.reduce<React.ReactElement[]>((acc, item, index) => {
const state =
active === index
? StepperStepState.Progress
: active > index
? StepperStepState.Completed
: StepperStepState.Inactive;
const shouldAllowSelect = () => {
if (typeof onStepClick !== 'function') {
return false;
}
if (typeof item.props.allowStepSelect === 'boolean') {
return item.props.allowStepSelect;
}
return state === 'stepCompleted' || allowNextStepsSelect;
};
const isStepSelectionEnabled = shouldAllowSelect();
acc.push(
cloneElement(item, {
key: index,
step: index + 1,
state,
onClick: () => isStepSelectionEnabled && onStepClick?.(index),
allowStepClick: isStepSelectionEnabled,
}),
);
if (index !== _children.length - 1) {
acc.push(
<StepSeparator
data-active={index < active || undefined}
key={`separator-${index}`}
/>,
);
}
return acc;
}, []);
const stepContent = _children[active]?.props?.children;
const completedContent = completedStep?.props?.children;
const content =
active > _children.length - 1 ? completedContent : stepContent;
return (
<Box>
<StepsItems>{items}</StepsItems>
<StepsContent className={classNames?.content}>{content} </StepsContent>
</Box>
);
}
Stepper.Step = StepperStep;
Stepper.Completed = StepperCompleted;
Stepper.displayName = '@bigcapital/core/stepper';
const StepsItems = styled(Box)`
display: flex;
flex-direction: row;
align-items: center;
gap: 16px;
`;
const StepsContent = styled(Box)`
margin-top: 16px;
margin-bottom: 8px;
`;
const StepSeparator = styled.div`
flex: 1;
display: block;
border-color: #c5cbd3;
border-top-style: solid;
border-top-width: 1px;
`;

View File

@@ -0,0 +1,9 @@
import React from 'react';
export interface StepperCompletedProps {
/** Label content */
children: React.ReactNode;
}
export const StepperCompleted: React.FC<StepperCompletedProps> = () => null;
StepperCompleted.displayName = '@bigcapital/core/StepperCompleted';

View File

@@ -0,0 +1,102 @@
// @ts-nocheck
import { StepperStepState } from './types';
import styled from 'styled-components';
import { Icon } from '../Icon';
interface StepperStepProps {
label: string;
description?: string;
children: React.ReactNode;
step?: number;
active?: boolean;
state?: StepperStepState;
allowStepClick?: boolean;
}
export function StepperStep({
label,
description,
step,
active,
state,
children,
}: StepperStepProps) {
return (
<StepButton>
<StepIconWrap>
<StepIcon
isCompleted={state === StepperStepState.Completed}
isActive={state === StepperStepState.Progress}
>
{state === StepperStepState.Completed && (
<Icon icon={'done'} iconSize={24} />
)}
<StepIconText>{step}</StepIconText>
</StepIcon>
</StepIconWrap>
<StepTextWrap>
<StepTitle
isCompleted={state === StepperStepState.Completed}
isActive={state === StepperStepState.Progress}
>
{label}
</StepTitle>
{description && (
<StepDescription
isCompleted={state === StepperStepState.Completed}
isActive={state === StepperStepState.Progress}
>
{description}
</StepDescription>
)}
</StepTextWrap>
</StepButton>
);
}
const StepButton = styled.button`
background: transparent;
color: inherit;
border: 0;
align-items: center;
display: flex;
gap: 10px;
text-align: left;
`;
const StepIcon = styled.span`
display: block;
height: 24px;
width: 24px;
display: block;
line-height: 24px;
border-radius: 24px;
text-align: center;
background-color: ${(props) =>
props.isCompleted || props.isActive ? 'rgb(0, 82, 204)' : '#9e9e9e'};
color: #fff;
margin: auto;
font-size: 12px;
`;
const StepTitle = styled.div`
color: ${(props) =>
props.isCompleted || props.isActive ? 'rgb(0, 82, 204)' : '#738091'};
`;
const StepDescription = styled.div`
font-size: 12px;
margin-top: 10px;
color: ${(props) =>
props.isCompleted || props.isActive ? 'rgb(0, 82, 204)' : '#738091'};
`;
const StepIconWrap = styled.div`
display: flex;
`;
const StepTextWrap = styled.div`
text-align: left;
`;
const StepIconText = styled.div``;

View File

@@ -0,0 +1 @@
export * from './Stepper';

View File

@@ -0,0 +1,7 @@
export enum StepperStepState {
Progress = 'stepProgress',
Completed = 'stepCompleted',
Inactive = 'stepInactive',
}