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