npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@valcis/brand

v2.2.1

Published

Componentes de marca valcis: Logo SVG y Footer React con soporte SSR

Downloads

951

Readme

@valcis/brand

npm version npm downloads bundle size license

Componentes React de marca valcis: Logo SVG, Footer, Spinner, Watermark y tema con soporte SSR.

Instalación

npm install @valcis/brand

Logo

Componente SVG puro, sin hooks ni estado. Compatible con React Server Components.

import { Logo } from '@valcis/brand';

// Icono: <V>
<Logo variant="icon" size="md" />

// Completo: >valcis|
<Logo variant="full" size={40} />

// Mini: solo la V caligráfica
<Logo variant="mini" size="lg" />

// El logo full viene animado por defecto (cursor blink)
// Para desactivarlo:
<Logo variant="full" size={32} animated={false} />

Props

| Prop | Tipo | Default | Descripción | |------|------|---------|-------------| | variant | 'icon' \| 'full' \| 'mini' | 'icon' | Variante del logo | | size | number \| 'sm' \| 'md' \| 'lg' \| 'xl' | 24 | Tamaño en px o preset | | animated | boolean | true (full) / false (icon) | Animación CSS-only (respeta prefers-reduced-motion) | | accentColor | string | — | Color de brackets/chevron/cursor | | textColor | string | — | Color de letras | | className | string | — | Clase CSS adicional | | style | CSSProperties | — | Estilos inline | | ariaLabel | string | — | Label de accesibilidad (si se omite, es decorativo) |

Presets de tamaño

| Preset | Pixels | |--------|--------| | sm | 16 | | md | 24 | | lg | 32 | | xl | 48 |

Spinner

Indicador de carga con el logo animado.

import { Spinner } from '@valcis/brand';

// Básico
<Spinner />

// Con opciones
<Spinner size="lg" animation="spin" label="Cargando datos..." />

Props

| Prop | Tipo | Default | Descripción | |------|------|---------|-------------| | size | number \| 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Tamaño | | animation | 'pulse' \| 'spin' \| 'bounce' | 'pulse' | Tipo de animación | | accentColor | string | — | Color de acento | | textColor | string | — | Color de texto | | label | string | 'Cargando...' | Texto para screen readers | | className | string | — | Clase CSS adicional |

Watermark

Marca de agua posicionable para imágenes o secciones.

import { Watermark } from '@valcis/brand';

// El contenedor padre debe tener position: relative
<div style={{ position: 'relative' }}>
  <img src="foto.jpg" alt="Foto" />
  <Watermark position="bottom-right" opacity={0.3} />
</div>

Props

| Prop | Tipo | Default | Descripción | |------|------|---------|-------------| | position | 'top-left' \| 'top-right' \| 'bottom-left' \| 'bottom-right' \| 'center' | 'bottom-right' | Posición | | opacity | number | 0.3 | Opacidad (0-1) | | size | number | 48 | Tamaño del logo | | rotation | number | 0 | Rotación en grados | | showOnHover | boolean | false | Solo visible en hover | | className | string | — | Clase CSS adicional |

Footer

Footer de atribución con logo, contacto y modos de copyright.

import { Footer } from '@valcis/brand';

// Uso básico
<Footer />

// Con datos SSR
<Footer initialDevInfo={devInfo} theme="dark" />

// Modo owner
<Footer mode="owner" />

Props

| Prop | Tipo | Default | Descripción | |------|------|---------|-------------| | theme | 'light' \| 'dark' | 'light' | Tema visual | | mode | 'owner' \| 'designer' \| 'partner' | 'designer' | Modo de copyright | | showYear | boolean | true | Mostrar año | | showContact | boolean | true | Mostrar email de contacto | | animatedLogo | boolean | true | Animar el logo (cursor blink) | | variant | 'inline' \| 'stacked' | 'inline' | Layout horizontal o vertical | | align | 'left' \| 'center' \| 'right' | 'center' | Alineación | | position | 'static' \| 'sticky' \| 'fixed' | 'sticky' | Posicionamiento CSS | | padding | 'compact' \| 'normal' \| 'spacious' \| { x?, y? } | 'normal' | Densidad | | border | boolean \| 'top' \| 'bottom' \| 'both' \| 'none' | 'top' | Borde separador | | accentColor | string | — | Color de acento (texto, links) | | backgroundColor | string | 'transparent' | Fondo | | textColor | string | — | Color de texto override | | as | 'footer' \| 'div' \| 'section' | 'div' | Tag HTML | | className | string | — | Clase CSS adicional | | initialDevInfo | DevInfo | — | Datos pre-cargados (SSR) | | devInfoUrl | string | — | URL alternativa del JSON |

Modos de copyright

| Modo | Resultado | |------|-----------| | owner | © 2026 >valcis| | | designer | © 2026 · Diseñado por >valcis| | | partner | Powered by >valcis| |

useTheme

Hook para detectar y controlar dark/light mode.

import { useTheme } from '@valcis/brand';

function App() {
  const { theme, isDark, toggleTheme, setTheme } = useTheme();

  return (
    <div className={isDark ? 'dark' : 'light'}>
      <button onClick={toggleTheme}>
        {isDark ? '☀️' : '🌙'}
      </button>

      {/* Volver a preferencia del sistema */}
      <button onClick={() => setTheme(null)}>Auto</button>
    </div>
  );
}

Retorno

| Propiedad | Tipo | Descripción | |-----------|------|-------------| | theme | 'light' \| 'dark' | Tema actual | | isDark | boolean | true si es dark mode | | isLight | boolean | true si es light mode | | setTheme | (theme: 'light' \| 'dark' \| null) => void | Forzar tema (null = auto) | | toggleTheme | () => void | Alternar entre light/dark |

Paleta de colores

Colores de marca exportados como constantes.

import { colors, primary, text, cssVariables } from '@valcis/brand';

// Usar en estilos
const style = { color: primary.DEFAULT }; // '#3B82F6'

// Paleta completa
console.log(colors.primary[500]); // '#3B82F6'
console.log(colors.text.DEFAULT); // '#1E293B'
console.log(colors.semantic.success); // '#22C55E'

// Inyectar CSS custom properties
const GlobalStyles = () => <style>{cssVariables}</style>;

Colores disponibles

colors.primary    // Azules de marca (50-900, DEFAULT, light, dark)
colors.text       // Colores de texto (DEFAULT, dark, muted, mutedDark)
colors.background // Fondos (light, dark, muted, mutedDark)
colors.border     // Bordes (light, dark)
colors.semantic   // Semánticos (success, warning, error, info)

CSS Custom Properties

/* Disponibles tras inyectar cssVariables */
--valcis-primary
--valcis-primary-light
--valcis-primary-dark
--valcis-text
--valcis-text-muted
--valcis-bg
--valcis-bg-muted
--valcis-border
--valcis-logo-accent
--valcis-logo-text

Tailwind CSS Preset

Preset con la paleta de marca para proyectos que usan Tailwind CSS.

// tailwind.config.ts
import { valcisPreset } from '@valcis/brand';

export default {
  presets: [valcisPreset],
  content: ['./src/**/*.{ts,tsx}'],
};

Clases disponibles:

<!-- Colores primarios -->
<div class="bg-valcis text-valcis-dark border-valcis-light">

<!-- Texto -->
<p class="text-valcis-text dark:text-valcis-text-dark">

<!-- Fondos -->
<div class="bg-valcis-bg-light dark:bg-valcis-bg-dark">

<!-- Semánticos -->
<span class="text-valcis-success">OK</span>
<span class="text-valcis-error">Error</span>

Datos del desarrollador

El Footer y el hook useDevInfo obtienen los datos de marca desde https://valcis.net/api/dev-info.json. Si el servidor no está disponible o el fetch falla (timeout de 2s, error de red, JSON inválido), se usa automáticamente un fallback local:

{
  version: 1,
  brand: 'valcis',
  contact: '[email protected]',
  website: 'https://valcis.net',
  year: new Date().getFullYear(),
}

En cliente, las respuestas se cachean en localStorage durante 1 hora para minimizar peticiones.

SSR

Para evitar el fetch en cliente, puedes pre-cargar los datos en el servidor con getDevInfo():

import { getDevInfo, Footer } from '@valcis/brand';

// Next.js
export async function getStaticProps() {
  const devInfo = await getDevInfo();
  return { props: { devInfo }, revalidate: 3600 };
}

export default function Page({ devInfo }) {
  return <Footer initialDevInfo={devInfo} />;
}

Si se pasa initialDevInfo, el componente no hace fetch.

Assets estáticos

El paquete incluye SVGs en assets/ para uso fuera de React:

@valcis/brand/assets/favicon.svg
@valcis/brand/assets/logo-icon.svg
@valcis/brand/assets/logo-icon-light.svg
@valcis/brand/assets/logo-icon-dark.svg
@valcis/brand/assets/logo-full.svg
@valcis/brand/assets/logo-full-light.svg
@valcis/brand/assets/logo-full-dark.svg

Las variantes sin sufijo son adaptativas (usan prefers-color-scheme).

SVG paths

Para uso sin React, se exportan los paths SVG crudos:

import { V_CALLIGRAPHIC_PATH, BRACKET_LEFT_PATH, VIEWBOXES } from '@valcis/brand';

Accesibilidad

El componente cumple con WCAG 2.2:

  • Contraste: Colores con ratio AA (4.5:1)
  • Focus visible: :focus-visible con outline
  • Target size: Links con área mínima 44x44px
  • Semántica: Uso de <nav>, <footer>, aria-label
  • Logo decorativo: aria-hidden="true" (excepto si se proporciona ariaLabel)
  • Reduced motion: Animaciones respetan prefers-reduced-motion

Desarrollo

npm run build        # Build de producción
npm run dev          # Build en modo watch
npm run lint         # Ejecutar ESLint
npm run lint:fix     # Arreglar errores de lint
npm run format       # Formatear con Prettier
npm test             # Ejecutar tests (81 tests)
npm run test:watch   # Tests en modo watch

Licencia

MIT