You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

119 lines
2.9 KiB

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import cn from 'classnames';
import tailwindConfig from '../../../tailwind.config';
import CodeBlock from './CodeBlock';
interface APIAnatomyProps {
children: React.ReactNode;
}
interface AnatomyContent {
steps: React.ReactElement[];
code: React.ReactNode;
}
const twColors = tailwindConfig.theme.extend.colors;
const colors = [
{
hex: twColors['blue-40'],
border: 'border-blue-40',
background: 'bg-blue-40',
},
{
hex: twColors['yellow-40'],
border: 'border-yellow-40',
background: 'bg-yellow-40',
},
{
hex: twColors['green-50'],
border: 'border-green-50',
background: 'bg-green-50',
},
{
hex: twColors['purple-40'],
border: 'border-purple-40',
background: 'bg-purple-40',
},
];
export function APIAnatomy({children}: APIAnatomyProps) {
const [activeStep, setActiveStep] = React.useState<number | null>(null);
const {steps, code} = React.Children.toArray(children).reduce(
(acc: AnatomyContent, child) => {
if (!React.isValidElement(child)) return acc;
switch (child.props.mdxType) {
case 'AnatomyStep':
acc.steps.push(
React.cloneElement(child, {
...child.props,
activeStep,
handleStepChange: setActiveStep,
stepNumber: acc.steps.length + 1,
})
);
break;
case 'pre':
acc.code = (
<CodeBlock {...child.props.children.props} noMargin={true} />
);
break;
}
return acc;
},
{steps: [], code: null}
);
return (
<section className="my-8 grid grid-cols-1 lg:grid-cols-2 gap-x-8 gap-y-4">
<div className="lg:order-2">{code}</div>
<div className="lg:order-1 flex flex-col justify-center gap-y-2">
{steps}
</div>
</section>
);
}
interface AnatomyStepProps {
children: React.ReactNode;
title: string;
stepNumber: number;
activeStep?: number;
handleStepChange: (stepNumber: number) => void;
}
export function AnatomyStep({
title,
stepNumber,
children,
activeStep,
handleStepChange,
}: AnatomyStepProps) {
const color = colors[stepNumber - 1];
return (
<div
className={cn(
'border-l-4 rounded-lg px-5 pt-8 pb-2 bg-opacity-5 shadow-inner',
color.border,
color.background
)}>
<div className="relative flex items-center justify-between">
<div
className={cn(
'inline align-middle text-center rounded-full w-5 h-5 absolute font-bold text-white text-code font-mono leading-tight -left-8',
color.background
)}>
{stepNumber}
</div>
<div className="text-primary dark:text-primary-dark leading-3 font-bold">
{title}
</div>
</div>
<div>{children}</div>
</div>
);
}