Todos os componentes

Code Block

Code Block é um componente de dados para React e Tailwind CSS, da biblioteca UI Layouts, com licença MIT. Copia e cola no teu projeto.

UI Layouts MIT data

O que é

Code Block é um componente de dados para React e Tailwind CSS, da biblioteca UI Layouts, com licença MIT. Copia e cola no teu projeto.

Como usar

Abre o componente no catálogo, carrega em copiar, e cola no teu projeto. O prompt copiado leva o código e as regras para o teu agente o reproduzir sem alterar nada.

Abrir no catálogo

Cinco cópias grátis por mês. Sem cartão.

Precisa de

npm i shiki

Licença

Este componente vem de UI Layouts e é redistribuído sob a licença MIT, que permite uso comercial. O aviso de copyright viaja com o código.

Code Block

./components/ui/code-block.tsx
'use client';

import { CopyButton } from '@/components/website/code-components/copy-button';
import { cn } from '@/lib/utils';
import { useEffect, useState } from 'react';
import { codeToHtml } from 'shiki/bundle/web';

export function CodeBlock({
  code,
  lang = 'tsx',
  className,
}: {
  code: string;
  lang?: string;
  className?: string;
}) {
  const [html, setHtml] = useState('');
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;

    const highlightCode = async () => {
      try {
        const highlightedHtml = await codeToHtml(code, {
          lang,
          themes: { light: 'github-light', dark: 'slack-dark' },
        });

        if (!cancelled) {
          setHtml(highlightedHtml);
          setIsLoading(false);
        }
      } catch (error) {
        console.error('Error highlighting code:', error);
        if (!cancelled) {
          setIsLoading(false);
        }
      }
    };

    highlightCode();

    return () => {
      cancelled = true;
    };
  }, [code, lang]);

  if (isLoading) {
    return (
      <div className={cn('relative', className)}>
        <div className='p-6 w-full mx-auto h-[400px] dark:bg-neutral-800 bg-neutral-200 animate-pulse rounded-xl'></div>
      </div>
    );
  }

  return (
    <div className={cn('relative', className)}>
      <CopyButton code={code} classname='right-2 top-2 bg-white dark:bg-neutral-800' />

      <div
        className='not-prose max-h-[550px] overflow-x-hidden rounded-md text-sm border dark:border-neutral-800'
        dangerouslySetInnerHTML={{ __html: html }}
      />
    </div>
  );
}
./components/website/code-components/copy-button.tsx
'use client';

import { cn } from '@/lib/utils';
import { Check, CheckCheck, Copy } from 'lucide-react';
import { useState } from 'react';

export function CopyButton({ code, classname }: { code: string; classname?: string }) {
  const [hasCheckIcon, setHasCheckIcon] = useState(false);

  const onCopy = () => {
    navigator.clipboard.writeText(code);
    setHasCheckIcon(true);

    setTimeout(() => {
      setHasCheckIcon(false);
    }, 1000);
  };

  return (
    <>
      <div
        className={cn(
          'absolute right-2 top-2 cursor-pointer dark:hover:shadow-[0px_1px_10px_5px_#3f7ef3] hover:shadow-[0px_1px_10px_5px_#9abaf7] dark:hover:border-blue-500 hover:border-blue-300  dark:bg-zinc-800 backdrop-blur-2xl bg-white rounded-md border-2',
          classname
        )}
        onClick={onCopy}
      >
        <div
          className={` inset-0 transform transition-all duration-300  w-9 h-8 grid place-content-center  ${
            hasCheckIcon ? 'scale-0 opacity-0' : 'scale-100 opacity-100'
          }`}
        >
          <Copy className='h-4 w-4 text-foreground/80' />
        </div>
        <div
          className={`absolute inset-0 transform transition-all duration-300 w-8 h-8 grid place-content-center  ${
            hasCheckIcon ? 'scale-100 opacity-100' : 'scale-0 opacity-0'
          }`}
        >
          <CheckCheck className='h-4 w-4 text-foreground/80' />
        </div>
      </div>
    </>
  );
}

Componentes parecidos