import { css } from '@emotion/react';
import { spacing } from '@expo/styleguide-base';
import { Snippet } from '../Snippet';
import { SnippetContent } from '../SnippetContent';
import { SnippetHeader } from '../SnippetHeader';
import { CopyAction } from '../actions/CopyAction';
import { CODE } from '~/ui/components/Text';
type TerminalProps = {
cmd: string[];
cmdCopy?: string;
hideOverflow?: boolean;
includeMargin?: boolean;
title?: string;
};
export const Terminal = ({
cmd,
cmdCopy,
hideOverflow,
includeMargin = true,
title = 'Terminal',
}: TerminalProps) => (
{renderCopyButton({ cmd, cmdCopy })}
{cmd.map(cmdMapper)}
);
/**
* This method attempts to naively generate the basic cmdCopy from the given cmd list.
* Currently, the implementation is simple, but we can add multiline support in the future.
*/
function getDefaultCmdCopy(cmd: TerminalProps['cmd']) {
const validLines = cmd.filter(line => !line.startsWith('#') && line !== '');
if (validLines.length === 1) {
return validLines[0].startsWith('$') ? validLines[0].slice(2) : validLines[0];
}
return undefined;
}
function renderCopyButton({ cmd, cmdCopy }: TerminalProps) {
const copyText = cmdCopy || getDefaultCmdCopy(cmd);
return copyText && ;
}
/**
* Map all provided lines and render the correct component.
* This method supports:
* - Render newlines for empty strings
* - Render a line with `#` prefix as comment with secondary text
* - Render a line without `$` prefix as primary text
* - Render a line with `$` prefix, as secondary and primary text
*/
function cmdMapper(line: string, index: number) {
const key = `line-${index}`;
if (line.trim() === '') {
return
;
}
if (line.startsWith('#')) {
return (
{line}
);
}
if (line.startsWith('$')) {
return (
-
{line.substring(1).trim()}
);
}
return (
{line}
);
}
const wrapperStyle = css`
li & {
margin-top: ${spacing[4]}px;
display: flex;
}
`;