1import { css } from '@emotion/react'; 2import { theme, typography } from '@expo/styleguide'; 3import * as React from 'react'; 4 5const MDX_CLASS_NAME_TO_TAB_NAME: Record<string, string> = { 6 'language-swift': 'Swift', 7 'language-kotlin': 'Kotlin', 8 'language-javascript': 'JavaScript', 9 'language-typescript': 'TypeScript', 10 'language-json': 'JSON', 11 'language-ruby': 'Ruby', 12 'language-groovy': 'Gradle', 13}; 14 15const CodeSamplesCSS = css` 16 display: flex; 17 flex-direction: row; 18 max-width: 100%; 19 margin: 20px 0px; 20 21 .code-block-column { 22 display: flex; 23 flex-direction: column; 24 flex: 1; 25 margin-right: -1px; 26 min-width: 0px; 27 28 pre { 29 border-top-left-radius: 0px; 30 border-top-right-radius: 0px; 31 } 32 &:not(:first-child) pre { 33 border-bottom-left-radius: 0px; 34 } 35 &:not(:last-child) pre { 36 border-bottom-right-radius: 0px; 37 } 38 &:first-child .code-block-header { 39 border-top-left-radius: 4px; 40 } 41 &:last-child .code-block-header { 42 border-top-right-radius: 4px; 43 } 44 } 45 .code-block-header { 46 padding: 6px 16px; 47 background-color: ${theme.background.secondary}; 48 border: 1px solid ${theme.border.default}; 49 border-bottom-width: 0px; 50 51 span { 52 color: ${theme.text.default}; 53 font-family: ${typography.fontFaces.mono}; 54 font-size: 15px; 55 } 56 } 57 .code-block-content { 58 flex: 1; 59 overflow-x: scroll; 60 61 pre { 62 height: 100%; 63 margin: 0px; 64 } 65 } 66`; 67 68type Props = { 69 children: JSX.Element[]; 70 tabs?: string[]; 71}; 72 73export function CodeBlocksTable({ children, tabs }: Props) { 74 const childrenArray = Array.isArray(children) ? children : [children]; 75 const codeBlocks = childrenArray.filter( 76 ({ props }) => props.mdxType === 'pre' && props.children.props.className 77 ); 78 const tabNames = 79 tabs || 80 codeBlocks.map(child => { 81 const className = child.props.children.props.className; 82 return MDX_CLASS_NAME_TO_TAB_NAME[className] || className.replace('language-', ''); 83 }); 84 85 return ( 86 <div css={CodeSamplesCSS}> 87 {codeBlocks.map((codeBlock, index) => ( 88 <div key={index} className="code-block-column"> 89 <div className="code-block-header"> 90 <span>{tabNames[index]}</span> 91 </div> 92 <div className="code-block-content">{codeBlock}</div> 93 </div> 94 ))} 95 </div> 96 ); 97} 98