1.0.15 • Published 6 months ago

clean-indent v1.0.15

Weekly downloads
-
License
ISC
Repository
-
Last release
6 months ago

Clean Indent

npm npm bundle size npm

Descripción

clean-indent es una utilidad ligera y eficiente para limpiar las indentaciones de cadenas de código. Ideal para formatear textos y asegurarte de que no queden espacios innecesarios al inicio o al final de cada línea. Ideal para presentaciones de código dentro de los elementos <pre>.

Características

  • Fácil de usar: Simplemente pasa la cadena que quieres limpiar.
  • Ligera: Sin dependencias adicionales.
  • Rápida: Procesa incluso cadenas grandes rápidamente.
  • Compatibilidad: Funciona con Node.js y navegadores.
  • Especializada: Esta utilidad está principalmente diseñada para preparar fragmentos de código para su presentación en el renderizado del HTML <pre>, para limpiar las indentaciones y formatear el código.

Instalación

Puedes instalar este paquete usando npm, pnpm o yarn:

npm

npm install clean-indent

pnpm

pnpm install clean-indent

yarn

yarn install clean-indent
  • Si no quieres instalar el paquete puedes usar el cdn:
import cleanIndent from 'https://cdn.jsdelivr.net/gh/liquidsnk86/cdn-js@main/clean-indent.js';

const code = document.querySelector('pre > code');
code.innerText = cleanIndent(code)

Ejemplo de uso

  • Componente:
import cleanIndent from 'clean-indent';

export const Pre = (lang: string, stringCode: string) => {
  return (
    <pre lang={lang}>
      {cleanIndent(stringCode)}
    </pre>
  );
};
  • Uso estándar del componente:
import { Pre } from '@/components/Pre';

export default function Page() {
  return (
    <main>
      <Pre lang="typescript">
        {`
          async function getData() {
            const url = 'https://solid-geolocation.vercel.app/location';
            const response = await fetch(url);
            const jsonData = await response.json();
            return jsonData;
          }
        `}
      </Pre>
    </main>
  );
}

Aquí les dejo este componente que he creado en React más completo con otras dependencias:

Instalamos las dependencias.

pnpm install prism-react-renderer lucide-react clean-indent
import { useMemo, useRef, useState } from 'react';
import styles from './pre.module.css';
import { Highlight, themes } from 'prism-react-renderer';
import { Copy, CopyCheck } from 'lucide-react';
import cleanIndent from 'clean-indent';

interface PreProps {
  stringCode: string;
  lang: string;
}

export const Pre = ({ stringCode, lang }: PreProps) => {
  const code = useMemo(() => stringCode, [stringCode]);
  const content = useRef<HTMLPreElement>();
  const [copied, setCopied] = useState(false);

  const copyCode = async () => {
    if (!content.current) return;

    try {
      await navigator.clipboard.writeText(content.current.textContent || '');
      setCopied(true);

      setTimeout(() => setCopied(false), 2000);
    } catch (err) {
      console.error('Error al copiar en el portapapeles:', err);
    }
  };

  return (
    <Highlight code={code} theme={themes.oneDark} language={lang}>
      {({ tokens, getLineProps, getTokenProps }) => (
        <pre className={styles.custom_pre} ref={content as any}>
          <span className={styles.icon} onClick={copyCode}>
            {copied ? (
              <CopyCheck width={16} height={16} className={styles.copied} />
            ) : (
              <Copy className="cursor-pointer" width={16} height={16} />
            )}
          </span>
          {tokens.map((line, lineIndex) => (
            <code {...getLineProps({ line })} key={lineIndex + 1}>
              <span className={styles.line_number} key={lineIndex}>
                {lineIndex}
              </span>
              {line.map((token, tokenIndex) => (
                <span
                  key={tokenIndex}
                  {...getTokenProps({ token })}
                  className={styles.line_content}
                />
              ))}
            </code>
          ))}
        </pre>
      )}
    </Highlight>
  );
};
  • Uso del componente:
import { Pre } from '@/components/Pre'

export default function Page() {
  return (
    <Pre
        lang="typescript"
        stringCode={`
        export default async function getApiData({ user }: { user: string }) {
            const response = await fetch('https://calcagni-gabriel/api/non-followers?user=\${user}');
            const data = await response.json();
            return data;
        }
      `}
    />
  )
}
  • Estilos del componente:
.custom_pre {
  position: relative;
  display: flex;
  flex-direction: column;
  margin: 0 auto;
  padding: 16px 16px 16px 8px;
  border-radius: 0 0 10px 10px;
  border-left: 1px solid #333;
  border-right: 1px solid #333;
  border-bottom: 1px solid #333;
  background-color: #222;
  font-family: 'Cascadia Code PL';
  font-size: 13px;
  font-weight: 400;
  line-height: 1.4;
}

.line_number {
  user-select: none;
  width: 1em;
  font-weight: 300;
  user-select: none;
  opacity: 0.5;
  text-align: right;
  margin-right: 1.3em;
}

.line_content {
  color: #ddd;
  flex: 1;
}

.lang_container {
  background-color: #04090b;
  width: 100%;
  padding-inline: 12px;
  border-top: 1px solid #333;
  border-right: 1px solid #333;
  border-left: 1px solid #333;
  border-radius: 10px 10px 0 0;
  overflow: hidden;
}

.lang {
  width: fit-content;
  color: #ec4899;
  text-transform: capitalize;
  background-color: #222;
  padding: 6px 16px;
  transform: translateX(-15px);
  z-index: 99;
}

.icon {
  position: absolute;
  top: -26px;
  right: 12px;
  color: #888;
  transition: opacity 0.6s ease-in-out;
  cursor: pointer;
}

.icon:hover {
  filter: drop-shadow(0 0 6px #2f9);
}

.custom_pre:hover .icon {
  opacity: 1;
}

.copied {
  animation-name: insideOut;
  animation-duration: 0.3s;
  animation-timing-function: ease-in;
  text-rendering: optimizeLegibility;
}

@keyframes insideOut {
  0% {
    transform: rotateY(90deg);
    opacity: 0;
  }
  50% {
    transform: rotateY(30deg);
    opacity: 0.5;
  }
  100% {
    transform: rotateY(0);
    opacity: 1;
  }
}

Imagen del componente


1.0.15

6 months ago

1.0.14

6 months ago

1.0.13

6 months ago

1.0.12

6 months ago

1.0.11

7 months ago

1.0.0

7 months ago