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