@valcis/brand
v2.2.1
Published
Componentes de marca valcis: Logo SVG y Footer React con soporte SSR
Downloads
951
Maintainers
Readme
@valcis/brand
Componentes React de marca valcis: Logo SVG, Footer, Spinner, Watermark y tema con soporte SSR.
Instalación
npm install @valcis/brandLogo
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-textTailwind 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.svgLas 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-visiblecon 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 proporcionaariaLabel) - 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 watchLicencia
MIT
