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