feature: stepper component (#91)
This commit is contained in:
parent
77b20d527d
commit
325fdb8361
|
|
@ -2,6 +2,7 @@ import { BrowserRouter, Route, Routes, Navigate } from 'react-router-dom';
|
||||||
import { initializeWallet } from './store';
|
import { initializeWallet } from './store';
|
||||||
import { themeGlobals } from '@/theme/globals';
|
import { themeGlobals } from '@/theme/globals';
|
||||||
import { Home } from './views';
|
import { Home } from './views';
|
||||||
|
import { Mint } from './views/mint';
|
||||||
import { SVGTestScreen } from './views/svg-test'; // TODO: remove when done
|
import { SVGTestScreen } from './views/svg-test'; // TODO: remove when done
|
||||||
|
|
||||||
initializeWallet();
|
initializeWallet();
|
||||||
|
|
@ -13,6 +14,7 @@ export const App = () => {
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/home" element={<Home />} />
|
<Route path="/home" element={<Home />} />
|
||||||
|
<Route path="/mint" element={<Mint />} />
|
||||||
<Route path="/svg" element={<SVGTestScreen />} />
|
<Route path="/svg" element={<SVGTestScreen />} />
|
||||||
<Route path="*" element={<Navigate to="/home" />} />
|
<Route path="*" element={<Navigate to="/home" />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { dripStitches } from '../../theme/stitches'; //TODO replace with absolute path
|
import { dripStitches } from '../../theme'; //TODO replace with absolute path
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const { styled } = dripStitches;
|
const { styled } = dripStitches;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './stepper';
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { Button } from '../../core';
|
||||||
|
import { Stepper } from './stepper';
|
||||||
|
import { Flex } from '../flex.styled';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Components/Layout/Stepper',
|
||||||
|
component: Stepper,
|
||||||
|
};
|
||||||
|
|
||||||
|
const StepperButton: React.FC = () => {
|
||||||
|
const { nextStep, prevStep, setStep } = Stepper.useContext();
|
||||||
|
return (
|
||||||
|
<Flex css={{ gap: '$md' }}>
|
||||||
|
<Button onClick={prevStep}>Prev</Button>
|
||||||
|
<Button onClick={nextStep}>Next</Button>
|
||||||
|
<Button onClick={() => setStep(4)}>Set final step</Button>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Default = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Stepper.Root initialStep={1} totalSteps={4}>
|
||||||
|
<Stepper.Container>
|
||||||
|
<Stepper.Step>
|
||||||
|
{/* Step 1 */}
|
||||||
|
<Stepper.Indicator />
|
||||||
|
</Stepper.Step>
|
||||||
|
<Stepper.Step>
|
||||||
|
{/* Step 2*/}
|
||||||
|
<Stepper.Indicator />
|
||||||
|
</Stepper.Step>
|
||||||
|
<Stepper.Step>
|
||||||
|
{/* Step 3 */}
|
||||||
|
<Stepper.Indicator />
|
||||||
|
</Stepper.Step>
|
||||||
|
<Stepper.Step>
|
||||||
|
{/* Step 4 */}
|
||||||
|
<Stepper.Indicator />
|
||||||
|
</Stepper.Step>
|
||||||
|
</Stepper.Container>
|
||||||
|
|
||||||
|
<StepperButton />
|
||||||
|
</Stepper.Root>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { dripStitches } from '../../../theme';
|
||||||
|
|
||||||
|
const { styled } = dripStitches;
|
||||||
|
|
||||||
|
export abstract class StepperStyles {
|
||||||
|
static readonly Rail = styled('div', {
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '0.8rem',
|
||||||
|
width: '100%',
|
||||||
|
|
||||||
|
'&:before': {
|
||||||
|
content: '""',
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 0,
|
||||||
|
height: '1px',
|
||||||
|
width: '100%',
|
||||||
|
backgroundColor: '$border-default',
|
||||||
|
zIndex: -1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
static readonly RailDivision = styled('div', {
|
||||||
|
height: '$2h',
|
||||||
|
width: '$13',
|
||||||
|
borderRadius: '$full',
|
||||||
|
backgroundColor: '$slate6',
|
||||||
|
'&[data-active="true"]': {
|
||||||
|
backgroundColor: '$blue10',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
static readonly RailDivisionLabel = styled('span', {
|
||||||
|
color: '$blue10',
|
||||||
|
mt: '$3',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
import React, { useMemo, useState } from 'react';
|
||||||
|
import { createContext } from '../../..//utils';
|
||||||
|
import { Flex } from '../flex.styled';
|
||||||
|
import { StepperStyles } from './stepper.styles';
|
||||||
|
|
||||||
|
export type SelectContext = {
|
||||||
|
totalSteps: number;
|
||||||
|
currentStep: number;
|
||||||
|
nextStep: () => void;
|
||||||
|
prevStep: () => void;
|
||||||
|
setStep: (step: number) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const [Provider, useContext] = createContext<SelectContext>({
|
||||||
|
name: 'Stepper.Context',
|
||||||
|
hookName: 'Stepper.useContext',
|
||||||
|
providerName: 'Stepper.Provider',
|
||||||
|
});
|
||||||
|
|
||||||
|
const getStepsLength = (node: React.ReactNode): number => {
|
||||||
|
let length = 0;
|
||||||
|
|
||||||
|
React.Children.forEach(node, (child) => {
|
||||||
|
if (React.isValidElement(child)) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||||
|
if (child.type === Stepper.Step) length += 1;
|
||||||
|
else length += getStepsLength(child.props.children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return length;
|
||||||
|
};
|
||||||
|
|
||||||
|
export abstract class Stepper {
|
||||||
|
static readonly useContext = useContext;
|
||||||
|
|
||||||
|
static readonly Root: React.FC<Stepper.RootProps> = ({
|
||||||
|
children,
|
||||||
|
initialStep = 0,
|
||||||
|
}) => {
|
||||||
|
const [currentStep, setCurrentStep] = useState(initialStep - 1);
|
||||||
|
const totalSteps = useMemo(() => getStepsLength(children), [children]);
|
||||||
|
|
||||||
|
const nextStep = (): void => {
|
||||||
|
if (currentStep < totalSteps - 1) {
|
||||||
|
setCurrentStep(currentStep + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const prevStep = (): void => {
|
||||||
|
if (currentStep > 0) {
|
||||||
|
setCurrentStep(currentStep - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const setStep = (step: number): void => {
|
||||||
|
if (step > 0 && step <= totalSteps) {
|
||||||
|
setCurrentStep(step - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Provider
|
||||||
|
value={{ totalSteps, currentStep, nextStep, prevStep, setStep }}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
static readonly Container = (props: Stepper.ContainerProps): JSX.Element => {
|
||||||
|
const { children } = props;
|
||||||
|
const { currentStep } = this.useContext();
|
||||||
|
|
||||||
|
const filteredChildren = useMemo(
|
||||||
|
() =>
|
||||||
|
React.Children.toArray(children).map((child, index) => {
|
||||||
|
if (!React.isValidElement(child)) {
|
||||||
|
throw new Error(
|
||||||
|
'Stepper.Container children must be a valid React element'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child.type !== Stepper.Step) {
|
||||||
|
throw new Error(
|
||||||
|
'Stepper.Container children must be a Stepper.Step component'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index === currentStep) {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
[children, currentStep]
|
||||||
|
);
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||||
|
return <>{filteredChildren}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
static readonly Step = ({
|
||||||
|
children,
|
||||||
|
}: // eslint-disable-next-line react/jsx-no-useless-fragment
|
||||||
|
Stepper.StepProps): JSX.Element => <>{children}</>;
|
||||||
|
|
||||||
|
static readonly Indicator: React.FC<Stepper.IndicatorProps> = (props) => {
|
||||||
|
const { currentStep, totalSteps } = this.useContext();
|
||||||
|
const steps = Array.from(Array(totalSteps).keys());
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex css={{ flexDirection: 'column' }}>
|
||||||
|
<StepperStyles.Rail {...props}>
|
||||||
|
{steps.map((step) => (
|
||||||
|
<StepperStyles.RailDivision
|
||||||
|
key={step}
|
||||||
|
data-active={step <= currentStep}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</StepperStyles.Rail>
|
||||||
|
<StepperStyles.RailDivisionLabel>
|
||||||
|
Step {currentStep + 1}
|
||||||
|
</StepperStyles.RailDivisionLabel>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace Stepper {
|
||||||
|
export type RootProps = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
initialStep?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type StepIndex = string | number;
|
||||||
|
|
||||||
|
export type ContainerProps = {
|
||||||
|
children: React.ReactNode | React.ReactNode[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type StepProps = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type IndicatorProps = React.ComponentProps<typeof StepperStyles.Rail>;
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,7 @@ export const spacing = {
|
||||||
10: '2.5rem',
|
10: '2.5rem',
|
||||||
11: '2.75rem',
|
11: '2.75rem',
|
||||||
12: '3rem',
|
12: '3rem',
|
||||||
|
13: '3.25rem', // 52px
|
||||||
14: '3.5rem',
|
14: '3.5rem',
|
||||||
16: '4rem',
|
16: '4rem',
|
||||||
20: '5rem', // 80px
|
20: '5rem', // 80px
|
||||||
|
|
@ -23,6 +24,7 @@ export const spacing = {
|
||||||
24: '6rem',
|
24: '6rem',
|
||||||
28: '7rem',
|
28: '7rem',
|
||||||
32: '8rem',
|
32: '8rem',
|
||||||
|
34: '8.5rem',
|
||||||
36: '9rem',
|
36: '9rem',
|
||||||
40: '10rem',
|
40: '10rem',
|
||||||
44: '11rem',
|
44: '11rem',
|
||||||
|
|
@ -34,4 +36,9 @@ export const spacing = {
|
||||||
72: '18rem',
|
72: '18rem',
|
||||||
80: '20rem',
|
80: '20rem',
|
||||||
96: '24rem',
|
96: '24rem',
|
||||||
|
100: '25rem',
|
||||||
|
102: '25.5rem', // 408px
|
||||||
|
104: '26rem', // 416px
|
||||||
|
106: '26.5rem', // 424px
|
||||||
|
128: '32rem', // 512px
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
import {
|
||||||
|
createContext as createReactContext,
|
||||||
|
useContext as useReactContext,
|
||||||
|
} from 'react';
|
||||||
|
|
||||||
|
export interface CreateContextOptions {
|
||||||
|
hookName: string;
|
||||||
|
providerName: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CreateContextReturn<T> = [
|
||||||
|
React.Provider<T>,
|
||||||
|
() => T,
|
||||||
|
React.Context<T>
|
||||||
|
];
|
||||||
|
|
||||||
|
const getErrorMessage = (hook: string, provider: string): string =>
|
||||||
|
`${hook} returned \`undefined\`. Seems you forgot to wrap component within ${provider}`;
|
||||||
|
|
||||||
|
export const createContext = <T>({
|
||||||
|
name,
|
||||||
|
hookName,
|
||||||
|
providerName,
|
||||||
|
}: CreateContextOptions): CreateContextReturn<T> => {
|
||||||
|
const Context = createReactContext<T | undefined>(undefined);
|
||||||
|
|
||||||
|
Context.displayName = name;
|
||||||
|
|
||||||
|
const useContext = (): T => {
|
||||||
|
const context = useReactContext(Context);
|
||||||
|
|
||||||
|
if (!context) {
|
||||||
|
const error = new Error(getErrorMessage(hookName, providerName));
|
||||||
|
error.name = 'ContextError';
|
||||||
|
Error.captureStackTrace?.(error, useContext);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
};
|
||||||
|
|
||||||
|
return [Context.Provider, useContext, Context] as CreateContextReturn<T>;
|
||||||
|
};
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
export * from './format';
|
export * from './format';
|
||||||
export * from './validation';
|
export * from './validation';
|
||||||
export * from './object';
|
export * from './object';
|
||||||
|
export * from './context';
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,3 @@
|
||||||
import { Flex } from '@/components';
|
|
||||||
import { Form } from '@/components';
|
|
||||||
import React, { useState } from 'react';
|
|
||||||
|
|
||||||
export const Home = () => {
|
export const Home = () => {
|
||||||
const [file, setFile] = useState<File | null>(null);
|
return <h1>Home</h1>;
|
||||||
return (
|
|
||||||
<Flex
|
|
||||||
css={{
|
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<h1>Home</h1>
|
|
||||||
<Form.Field css={{ width: '$24' }}>
|
|
||||||
<Form.Label>Label</Form.Label>
|
|
||||||
<Form.LogoFileInput value={file} onChange={(file) => setFile(file)} />
|
|
||||||
</Form.Field>
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './mint';
|
||||||
|
|
@ -0,0 +1,168 @@
|
||||||
|
import { Button, Flex } from '@/components';
|
||||||
|
import { IconButton } from '@/components/core/button/icon-button';
|
||||||
|
import { Icon } from '@/components/core/icon';
|
||||||
|
import React from 'react';
|
||||||
|
import { Stepper } from '@/components/layout/stepper/stepper';
|
||||||
|
|
||||||
|
// TODO remove after flow integration
|
||||||
|
const StepperButton: React.FC = () => {
|
||||||
|
const { nextStep, prevStep, setStep } = Stepper.useContext();
|
||||||
|
return (
|
||||||
|
<Flex css={{ gap: '$md' }}>
|
||||||
|
<Button onClick={prevStep} variant="outline">
|
||||||
|
Prev
|
||||||
|
</Button>
|
||||||
|
<Button onClick={nextStep} variant="outline">
|
||||||
|
Next
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => setStep(4)} variant="outline">
|
||||||
|
Set final step
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const CardHeading = ({ title }: { title: string }) => {
|
||||||
|
const { currentStep, prevStep } = Stepper.useContext();
|
||||||
|
return (
|
||||||
|
<Flex css={{ justifyContent: 'space-between' }}>
|
||||||
|
<Flex>
|
||||||
|
{currentStep > 0 && (
|
||||||
|
<IconButton
|
||||||
|
aria-label="Add"
|
||||||
|
colorScheme="gray"
|
||||||
|
variant="link"
|
||||||
|
icon={<Icon name="back" />}
|
||||||
|
onClick={prevStep}
|
||||||
|
css={{ mr: '$2' }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<h3 style={{ fontSize: '20px', fontWeight: '700' }}>{title}</h3>
|
||||||
|
</Flex>
|
||||||
|
<IconButton
|
||||||
|
aria-label="Add"
|
||||||
|
colorScheme="gray"
|
||||||
|
variant="link"
|
||||||
|
icon={<Icon name="info" />}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type CardProps = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
title: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO create card component for all the project and then remove this
|
||||||
|
const Card = ({ children, title }: CardProps) => (
|
||||||
|
// TODO style with stitches
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '424px',
|
||||||
|
backgroundColor: '#1A1D1E',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderColor: '#313538',
|
||||||
|
borderRadius: '20px',
|
||||||
|
padding: '28px',
|
||||||
|
minHeight: '378px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardHeading title={title} />
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Heading = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
// TODO style with stitches or we can use tailwind
|
||||||
|
<h2 className="text-4xl">{children}</h2>
|
||||||
|
);
|
||||||
|
|
||||||
|
type StepperIndicatorContainerProps = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const StepperIndicatorContainer = ({
|
||||||
|
children,
|
||||||
|
}: StepperIndicatorContainerProps) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
css={{
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
mr: '$34',
|
||||||
|
width: '$106',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type MintStepContainerProps = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MintStepContainer = ({ children }: MintStepContainerProps) => (
|
||||||
|
<Flex css={{ flexDirection: 'row', justifyContent: 'center' }}>
|
||||||
|
{children}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const MintStepper = () => (
|
||||||
|
<Stepper.Root initialStep={1}>
|
||||||
|
<Stepper.Container>
|
||||||
|
<Stepper.Step>
|
||||||
|
<MintStepContainer>
|
||||||
|
<StepperIndicatorContainer>
|
||||||
|
<Stepper.Indicator />
|
||||||
|
<Heading>Connect your Ethereum Wallet to mint an NFA</Heading>
|
||||||
|
</StepperIndicatorContainer>
|
||||||
|
{/* TODO create component to handle the wallet connection */}
|
||||||
|
<Card title="Get Started">
|
||||||
|
<span>Step 1</span>
|
||||||
|
</Card>
|
||||||
|
</MintStepContainer>
|
||||||
|
</Stepper.Step>
|
||||||
|
<Stepper.Step>
|
||||||
|
<MintStepContainer>
|
||||||
|
<StepperIndicatorContainer>
|
||||||
|
<Stepper.Indicator />
|
||||||
|
<Heading>Connect GitHub and select repository</Heading>
|
||||||
|
</StepperIndicatorContainer>
|
||||||
|
{/* TODO create component to handle the github connection */}
|
||||||
|
<Card title="Connect GitHub">
|
||||||
|
<span>Step 2</span>
|
||||||
|
</Card>
|
||||||
|
</MintStepContainer>
|
||||||
|
</Stepper.Step>
|
||||||
|
<Stepper.Step>
|
||||||
|
<MintStepContainer>
|
||||||
|
<StepperIndicatorContainer>
|
||||||
|
<Stepper.Indicator />
|
||||||
|
<Heading>Finalize a few key things for your DyDx NFA</Heading>
|
||||||
|
</StepperIndicatorContainer>
|
||||||
|
{/* TODO create component to handle the NFA details */}
|
||||||
|
<Card title="NFA Details">
|
||||||
|
<span>Step 3</span>
|
||||||
|
</Card>
|
||||||
|
</MintStepContainer>
|
||||||
|
</Stepper.Step>
|
||||||
|
<Stepper.Step>
|
||||||
|
<MintStepContainer>
|
||||||
|
<StepperIndicatorContainer>
|
||||||
|
<Stepper.Indicator />
|
||||||
|
<Heading>Review your DyDx NFA and mint it on Polygon</Heading>
|
||||||
|
</StepperIndicatorContainer>
|
||||||
|
{/* TODO create component to handle the NFA mint */}
|
||||||
|
<Card title="Mint NFA">
|
||||||
|
<span>Step 4</span>
|
||||||
|
</Card>
|
||||||
|
</MintStepContainer>
|
||||||
|
</Stepper.Step>
|
||||||
|
</Stepper.Container>
|
||||||
|
{/* TODO remove buttons when finish to integrate all the flow */}
|
||||||
|
<StepperButton />
|
||||||
|
</Stepper.Root>
|
||||||
|
);
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Flex } from '@/components';
|
||||||
|
import { MintStepper } from './mint-stepper';
|
||||||
|
|
||||||
|
export const Mint = () => (
|
||||||
|
<Flex css={{ height: 'inherit', justifyContent: 'center' }}>
|
||||||
|
<Flex
|
||||||
|
css={{
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MintStepper />
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
Loading…
Reference in New Issue