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

@cristianrg/vue-components

v1.0.0

Published

A collection of Vue.js components for building modern web applications.

Readme

@cris/vue-components

Librería de componentes Vue 3 moderna y minimalista

Created by @Cristianrg

Una librería de componentes Vue 3 diseñada con un enfoque moderno y minimalista, perfecta para aplicaciones web contemporáneas. Cada componente está construido siguiendo principios de diseño centrado en la experiencia del usuario, con estilos predeterminados elegantes y una arquitectura completamente personalizable.

✨ Características principales

  • 🎨 Diseño minimalista y moderno: Componentes con estilos limpios, elegantes y cohesivos
  • 🏗️ Arquitectura basada en interfaces: Sistema robusto de props tipadas con TypeScript para máxima flexibilidad
  • ⚙️ Totalmente personalizable: Variables CSS y props para adaptar colores, tamaños y comportamientos
  • 📱 Responsive por defecto: Optimizados para cualquier dispositivo y tamaño de pantalla
  • 🚀 TypeScript nativo: Soporte completo con tipado estricto e IntelliSense
  • 🌳 Tree-shaking friendly: Importa solo los componentes que necesitas para bundles optimizados
  • Accesibilidad: Componentes construidos siguiendo estándares WCAG
  • 🎛️ Componentes inteligentes: Lógica de estado interna para funcionalidades complejas

📦 Instalación

npm install @cris/vue-components

🎨 Importar estilos

¡IMPORTANTE! Para que los componentes se muestren correctamente, debes importar los estilos CSS:

// En tu main.js o main.ts
import '@cris/vue-components/vue-components.css'

O alternativamente en tu CSS principal:

@import '@cris/vue-components/vue-components.css';

🚀 Componentes disponibles

La librería incluye los siguientes componentes listos para usar:

  • Button - Botones interactivos con múltiples variantes
  • Modal - Modales con gestión automática de estado y accesibilidad
  • Card - Contenedores con elevación y efectos hover opcionales
  • Input - Campos de entrada con validación y múltiples tipos
  • Form - Formularios completos con validación automática
  • Table - Tablas dinámicas con edición inline
  • Search - Componente de búsqueda con callback personalizable
  • ChoiceBox - Checkboxes estilizados con múltiples tamaños
  • Details - Acordeones expansibles
  • Hero - Secciones destacadas para landing pages
  • Separator - Divisores visuales
  • ConfirmActions - Diálogos de confirmación

💡 Ejemplos de uso

Ejemplo básico - Button y Modal

<template>
  <div>
    <!-- Botón principal que abre modal -->
    <Button :button="primaryButton" />
    
    <!-- Modal con acciones personalizadas -->
    <Modal :modal="confirmModal">
      <p>¿Estás seguro de que quieres realizar esta acción?</p>
      <p>Esta operación no se puede deshacer.</p>
    </Modal>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Button, Modal, type Ibutton, type IModal } from "@cris/vue-components"

const showModal = ref(false)

// Configuración del botón principal
const primaryButton: Ibutton = {
  label: "Abrir Modal",
  class: "primary",
  size: "medium",
  action: () => {
    showModal.value = true
  }
}

// Configuración del modal con botones de acción
const confirmModal: IModal = {
  title: "Confirmar Acción",
  isOpen: showModal,
  onClose: () => {
    showModal.value = false
  },
  buttons: [
    {
      label: "Cancelar",
      class: "secondary",
      action: () => {
        showModal.value = false
      }
    },
    {
      label: "Confirmar",
      class: "primary", 
      action: () => {
        console.log('¡Acción confirmada!')
        showModal.value = false
      }
    }
  ]
}
</script>

Ejemplo avanzado - Formulario completo

<template>
  <Card :elevationInHover="true">
    <Form :form="userForm" @submit="handleSubmit" />
  </Card>
</template>

<script setup lang="ts">
import { reactive } from 'vue'
import { Card, Form, type IForm, type IInput } from "@cris/vue-components"

// Configuración del formulario
const userForm: IForm = {
  id: "user-registration",
  title: "Registro de Usuario",
  inputs: [
    {
      id: "name",
      label: "Nombre completo",
      type: "text",
      placeholder: "Ingresa tu nombre",
      required: true,
      validator: (value: string) => value.length >= 2,
      errorMessage: "El nombre debe tener al menos 2 caracteres"
    },
    {
      id: "email", 
      label: "Correo electrónico",
      type: "email",
      placeholder: "[email protected]",
      required: true,
      validator: (value: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value),
      errorMessage: "Ingresa un email válido"
    },
    {
      id: "role",
      label: "Rol",
      type: "select",
      required: true,
      options: [
        { value: "admin", label: "Administrador" },
        { value: "user", label: "Usuario" },
        { value: "guest", label: "Invitado" }
      ]
    }
  ],
  submit: {
    label: "Registrar Usuario",
    class: "primary",
    action: () => console.log('Formulario enviado')
  },
  cancel: {
    label: "Cancelar",
    class: "secondary", 
    action: () => console.log('Formulario cancelado')
  }
}

const handleSubmit = (data: Record<string, any>) => {
  console.log('Datos del formulario:', data)
  // Aquí puedes enviar los datos a tu API
}
</script>

Ejemplo con Table y búsqueda

<template>
  <div>
    <!-- Buscador -->
    <Search :search="searchConfig" />
    
    <!-- Tabla de datos -->
    <Table :table="usersTable" />
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { Table, Search, type ITable, type ISearch, type IRow } from "@cris/vue-components"

const searchTerm = ref('')

// Configuración del buscador
const searchConfig: ISearch = {
  placeholder: "Buscar usuarios...",
  value: searchTerm.value,
  onSearch: (value: string) => {
    searchTerm.value = value
  }
}

// Datos de ejemplo
const allUsers = [
  { name: 'Juan Pérez', email: '[email protected]', role: 'Admin' },
  { name: 'María García', email: '[email protected]', role: 'Usuario' },
  { name: 'Carlos López', email: '[email protected]', role: 'Invitado' }
]

// Tabla con filtrado dinámico
const usersTable = computed((): ITable => {
  const filteredUsers = allUsers.filter(user => 
    user.name.toLowerCase().includes(searchTerm.value.toLowerCase()) ||
    user.email.toLowerCase().includes(searchTerm.value.toLowerCase())
  )
  
  return {
    name: "Usuarios del Sistema",
    headers: ["Nombre", "Email", "Rol", "Acciones"],
    rows: filteredUsers.map((user): IRow => ({
      cells: [
        { value: user.name, type: 'text' },
        { value: user.email, type: 'text' },
        { value: user.role, type: 'text' }
      ],
      actions: [
        {
          label: "Editar",
          class: "primary",
          size: "small",
          action: () => console.log('Editando:', user.name)
        },
        {
          label: "Eliminar", 
          class: "danger",
          size: "small",
          action: () => console.log('Eliminando:', user.name)
        }
      ]
    }))
  }
})
</script>

🎨 Personalización y temas

Variables CSS personalizables

Todos los componentes pueden ser personalizados mediante variables CSS globales:

:root {
  /* Colores principales */
  --primary-color: #007bff;
  --primary-color-hover: #0056b3;
  --secondary-color: #6c757d;
  --secondary-color-hover: #545b62;
  --secondary-color-light: #f8f9fa;
  --secondary-color-light-hover: #e9ecef;
  
  /* Colores de estado */
  --danger-color: #dc3545;
  --success-color: #28a745;
  --warning-color: #ffc107;
  
  /* Tipografía */
  --font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  
  /* Espaciado */
  --spacing-xs: 0.25rem;
  --spacing-sm: 0.5rem;
  --spacing-md: 1rem;
  --spacing-lg: 1.5rem;
  --spacing-xl: 2rem;
  
  /* Bordes y sombras */
  --border-radius: 0.375rem;
  --box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  --box-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.15);
}

Personalización por componente

<template>
  <!-- Botón con estilos personalizados -->
  <Button 
    :button="customButton"
    :style="customButtonStyle"
  />
  
  <!-- Card con tema oscuro -->
  <Card 
    :elevationInHover="true"
    class="dark-theme"
  >
    <h3>Contenido en tema oscuro</h3>
  </Card>
</template>

<script setup lang="ts">
import { Button, Card } from "@cris/vue-components"

const customButton = {
  label: "Botón Personalizado",
  class: "primary" as const,
  size: "large" as const,
  action: () => console.log('Click!')
}

// Estilos CSS personalizados
const customButtonStyle = {
  '--primary-color': '#ff6b6b',
  '--primary-color-hover': '#ff5252',
  '--border-radius': '50px',
  '--font-weight': 'bold'
}
</script>

<style scoped>
.dark-theme {
  --secondary-color-light: #2d3748;
  --text-color: #f7fafc;
  color: var(--text-color);
}
</style>

🔧 Configuración avanzada

Importación selectiva

Para optimizar el bundle, importa solo los componentes que necesitas:

// Importación específica (recomendado)
import { Button, Modal, type Ibutton, type IModal } from "@cris/vue-components"

// Importación completa (no recomendado para producción)
import * as CrisComponents from "@cris/vue-components"

Configuración global

Puedes configurar estilos globales en tu aplicación principal:

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import '@cris/vue-components/dist/style.css' // Estilos base

const app = createApp(App)

// Configuración de variables CSS globales
document.documentElement.style.setProperty('--primary-color', '#your-brand-color')

app.mount('#app')

📚 Interfaces TypeScript

La librería proporciona interfaces TypeScript completas para todos los componentes:

import type { 
  Ibutton,
  IModal, 
  IInput,
  IForm,
  ITable,
  IRow,
  ICell,
  ISearch,
  IChoiceBox,
  IDetails,
  IConfirmAction
} from "@cris/vue-components"

// Ejemplo de tipado estricto
const myButton: Ibutton = {
  label: "Mi Botón",
  class: "primary", // Solo acepta: 'primary' | 'secondary' | 'danger'
  size: "medium",   // Solo acepta: 'small' | 'medium' | 'large' | 'xlarge'
  disabled: false,
  action: () => {
    // Tu lógica aquí
  }
}

🚀 Mejores prácticas

  1. Reactivity: Usa ref() o reactive() para datos que cambien dinámicamente
  2. Performance: Implementa computed() para datos derivados complejos
  3. Accessibility: Los componentes incluyen ARIA labels, aprovecha las funcionalidades integradas
  4. Validación: Utiliza las funciones validator en inputs para UX mejorada
  5. Gestión de estado: Para aplicaciones complejas, considera usar Pinia o Vuex

🤝 Contribución y soporte

Esta librería está en desarrollo activo. Para reportar bugs, solicitar features o contribuir:

  • Reporta issues detallados con ejemplos reproducibles
  • Sigue las convenciones de código existentes
  • Incluye tests para nuevas funcionalidades
  • Documenta cambios en el README