Skip to content

Commit

Permalink
command preview
Browse files Browse the repository at this point in the history
  • Loading branch information
nicosampler committed Nov 5, 2024
1 parent e76f100 commit 07c0863
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 115 deletions.
2 changes: 1 addition & 1 deletion packages/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@
"react-infinite-scroll-component": "^6.1.0",
"react-markdown": "^8.0.7",
"react-scroll": "^1.9.0",
"react-syntax-highlighter": "^15.5.0",
"remark-gfm": "^3.0.1",
"shiki": "^1.22.2",
"simple-url": "^1.1.8",
"sonner": "^1.5.0",
"styled-components": "^6.0.7",
Expand Down
156 changes: 69 additions & 87 deletions packages/website/src/components/CommandPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,100 +1,82 @@
'use client';

import { Box, Text, useClipboard } from '@chakra-ui/react';
import { FC } from 'react';
import { Copy } from 'react-feather';

interface ICommandPreviewProps {
command: string;
className?: string;
}

export const CommandPreview: FC<ICommandPreviewProps> = ({
command,
className,
}) => {
const { hasCopied, onCopy } = useClipboard(command);
const index = command.indexOf(' ');
const firstPart = command.substring(0, index);
const secondPart = command.substring(index, command.length);
return (
<Box
py={1}
px={3}
position="relative"
className={className + ' bg-muted/30'}
borderRadius="md"
>
<Text fontFamily="var(--font-mono)">
<Text as="span" color="#61afef">
{firstPart}
</Text>
<Text as="span">{secondPart}</Text>
</Text>
<Box
position="absolute"
top="8px"
right="10px"
cursor="pointer"
onClick={onCopy}
>
{hasCopied ? <Text fontSize="xs">Copied</Text> : <Copy size={16} />}
</Box>
</Box>
);
};

import * as React from 'react';

import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from '@/components/ui/collapsible';
import { Check, Copy } from 'react-feather';
import { codeToHtml } from 'shiki';

interface CodeBlockProps extends React.HTMLAttributes<HTMLDivElement> {
command?: string;
expandButtonTitle?: string;
}

export const CommandPreview2 = function CodeBlockWrapper({
expandButtonTitle = 'View Code',
className,
children,
...props
}: CodeBlockProps) {
const [isOpened, setIsOpened] = React.useState(false);
export const CommandPreview2 = React.forwardRef<HTMLDivElement, CodeBlockProps>(
({ command = '', className, ...props }, ref) => {
const [hasCopied, setHasCopied] = React.useState(false);
const [html, setHtml] = React.useState('');

return (
<Collapsible open={isOpened} onOpenChange={setIsOpened}>
<div className={cn('relative overflow-hidden', className)} {...props}>
<CollapsibleContent
forceMount
className={cn('overflow-hidden', !isOpened && 'max-h-32')}
>
<div
className={cn(
'[&_pre]:my-0 [&_pre]:max-h-[650px] [&_pre]:pb-[100px]',
!isOpened ? '[&_pre]:overflow-hidden' : '[&_pre]:overflow-auto]'
)}
>
{children}
</div>
</CollapsibleContent>
// Handle the async code highlighting
React.useEffect(() => {
const highlightCode = async () => {
if (!command) return;

const highlighted = await codeToHtml(command, {
lang: 'bash',
theme: 'github-dark-default',
transformers: [
{
code(node) {
node.properties['data-line-numbers'] = '';
},
},
],
});

setHtml(highlighted);
};

void highlightCode();
}, [command]);

async function copyToClipboard() {
if (!command) return;
await navigator.clipboard.writeText(command);
setHasCopied(true);
setTimeout(() => setHasCopied(false), 2000);
}

return (
<div
ref={ref}
className={cn(
'relative rounded-md bg-muted/30 py-2.5 pl-4 font-mono text-sm flex items-center',
className
)}
{...props}
>
<div
className={cn(
'absolute flex items-center justify-center bg-gradient-to-b from-zinc-700/30 to-zinc-950/90 p-2',
isOpened ? 'inset-x-0 bottom-0 h-12' : 'inset-0'
)}
>
<CollapsibleTrigger asChild>
<Button variant="secondary" className="h-8 text-xs">
{isOpened ? 'Collapse' : expandButtonTitle}
</Button>
</CollapsibleTrigger>
</div>
className="w-full overflow-x-auto whitespace-nowrap pr-12"
dangerouslySetInnerHTML={{ __html: html }}
/>
{command && (
<Button
size="icon"
variant="ghost"
className="flex-shrink-0 h-7 w-7 bg-background border border-border absolute right-3"
onClick={copyToClipboard}
>
{hasCopied ? (
<Check className="h-3.5 w-3.5 text-green-500" />
) : (
<Copy className="h-3.5 w-3.5 text-muted-foreground" />
)}
<span className="sr-only">Copy command</span>
</Button>
)}
</div>
</Collapsible>
);
};
);
}
);

CommandPreview2.displayName = 'CommandPreview2';
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,11 @@ export default function PackageAccordionHelper({
</CardDescription>
</CardHeader>
<CardContent>
<CommandPreview2>
cannon {packageRef}{' '}
{chainId != 13370 ? `--chain-id ${chainId}` : ''}
</CommandPreview2>
<CommandPreview2
command={`cannon ${packageRef} ${
chainId != 13370 ? `--chain-id ${chainId}` : ''
}`}
/>
</CardContent>
<CardFooter>
<div className="text-sm text-muted-foreground">
Expand Down
Loading

0 comments on commit 07c0863

Please sign in to comment.