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

@t1-org/t1components

v4.7.2

Published

Universal React Component Library

Downloads

9,804

Readme

T1 Components

Una librería de componentes React universal construida con Material-UI, TypeScript y diseño atómico.

npm version TypeScript React Material-UI

🚀 Instalación

# npm
npm install @t1-org/t1components

# yarn
yarn add @t1-org/t1components

# pnpm
pnpm add @t1-org/t1components

Dependencias requeridas

Esta librería requiere las siguientes peer dependencies:

npm install react react-dom @mui/material @emotion/react @emotion/styled

Dependencias opcionales

Para funcionalidades adicionales, puedes instalar:

# Para componentes de navegación
npm install react-router-dom

# Para iconos adicionales
npm install @mui/icons-material

🎯 Configuración básica

1. Importar estilos

// En tu archivo principal (App.tsx o index.tsx)
import '@t1-org/t1components/styles';

2. Configurar el tema (opcional)

import { ThemeProvider } from '@mui/material/styles';
import { theme } from '@t1-org/t1components';

function App() {
  return (
    <ThemeProvider theme={theme}>
      {/* Tu aplicación */}
    </ThemeProvider>
  );
}

3. Uso básico

import { Button, Card, CustomInput } from '@t1-org/t1components';

function MyComponent() {
  return (
    <Card>
      <CustomInput label="Nombre" />
      <Button variant="primary">Guardar</Button>
    </Card>
  );
}

📚 Componentes disponibles

🔬 Átomos (Atoms)

Componentes básicos y reutilizables:

AmountInput

import { AmountInput } from '@t1-org/t1components';

<AmountInput
  value={1000}
  onChange={(value) => console.log(value)}
  currency="MXN"
  placeholder="0.00"
/>

Button

import { Button } from '@t1-org/t1components';

<Button variant="primary" size="medium" onClick={() => {}}>
  Acción primaria
</Button>

<Button variant="secondary" disabled>
  Acción secundaria
</Button>

CustomInput

import { CustomInput } from '@t1-org/t1components';

<CustomInput
  label="Email"
  type="email"
  placeholder="[email protected]"
  required
  error="Campo requerido"
/>

Select

import { Select } from '@t1-org/t1components';

<Select
  options={[
    { value: 'mx', label: 'México' },
    { value: 'us', label: 'Estados Unidos' }
  ]}
  value="mx"
  onChange={(value) => console.log(value)}
  placeholder="Selecciona un país"
/>

CheckBox & Radio

import { CheckBox, Radio, RadioGroup } from '@t1-org/t1components';

<CheckBox
  label="Acepto términos y condiciones"
  checked={true}
  onChange={(checked) => console.log(checked)}
/>

<RadioGroup
  value="option1"
  onChange={(value) => console.log(value)}
>
  <Radio value="option1" label="Opción 1" />
  <Radio value="option2" label="Opción 2" />
</RadioGroup>

Switch

import { Switch, FormSwitch } from '@t1-org/t1components';

<Switch
  checked={true}
  onChange={(checked) => console.log(checked)}
  label="Notificaciones"
/>

PhoneInputT1

import { PhoneInputT1 } from '@t1-org/t1components';

<PhoneInputT1
  value="+525512345678"
  onChange={(phone) => console.log(phone)}
  defaultCountry="MX"
/>

🧬 Moléculas (Molecules)

Componentes compuestos que combinan átomos:

Table

import { Table } from '@t1-org/t1components';

const columns = [
  { key: 'name', label: 'Nombre' },
  { key: 'email', label: 'Email' },
  { key: 'status', label: 'Estado' }
];

const data = [
  { name: 'Juan', email: '[email protected]', status: 'Activo' }
];

<Table
  columns={columns}
  data={data}
  onRowClick={(row) => console.log(row)}
  loading={false}
/>

CustomPagination

import { CustomPagination } from '@t1-org/t1components';

<CustomPagination
  currentPage={1}
  totalPages={10}
  onPageChange={(page) => console.log(page)}
  showFirstLast={true}
/>

Profile

import { Profile, MenuProfile } from '@t1-org/t1components';

<Profile
  name="Juan Pérez"
  email="[email protected]"
  avatar="/avatar.jpg"
  role="Administrador"
/>

<MenuProfile
  user={{
    name: "Juan Pérez",
    email: "[email protected]",
    avatar: "/avatar.jpg"
  }}
  onLogout={() => console.log('Cerrar sesión')}
  menuItems={[
    { label: 'Perfil', onClick: () => {} },
    { label: 'Configuración', onClick: () => {} }
  ]}
/>

StoreSelector

import { StoreSelector } from '@t1-org/t1components';

<StoreSelector
  stores={[
    { id: '1', name: 'Tienda Centro', isActive: true },
    { id: '2', name: 'Tienda Norte', isActive: false }
  ]}
  selectedStoreId="1"
  onStoreChange={(storeId) => console.log(storeId)}
/>

BalanceBanner

import { BalanceBanner } from '@t1-org/t1components';

<BalanceBanner
  balance={15000}
  currency="MXN"
  trend="up"
  trendPercent={12.5}
  period="vs mes anterior"
/>

SimpleModalComponent

import { SimpleModalComponent } from '@t1-org/t1components';

<SimpleModalComponent
  open={true}
  onClose={() => setOpen(false)}
  title="Confirmar acción"
  maxWidth="sm"
>
  <p>¿Estás seguro de que quieres continuar?</p>
</SimpleModalComponent>

🦠 Organismos (Organisms)

Componentes complejos que forman secciones completas:

Navbar

import { Navbar } from '@t1-org/t1components';

<Navbar
  logo="/logo.png"
  user={{
    name: "Juan Pérez",
    email: "[email protected]",
    avatar: "/avatar.jpg"
  }}
  onMenuToggle={() => setMenuOpen(!menuOpen)}
  showSearch={true}
  onSearch={(query) => console.log(query)}
/>

Sidebar

import { Sidebar } from '@t1-org/t1components';

const menuPaths = [
  {
    name: 'dashboard',
    text: 'Dashboard',
    path: '/dashboard',
    icon: 'dashboard'
  },
  {
    name: 'users',
    text: 'Usuarios',
    path: '/users',
    icon: 'users'
  }
];

<Sidebar
  menuPaths={menuPaths}
  currentPath="/dashboard"
  onPathChange={(path) => navigate(path)}
  isCollapsed={false}
  onToggleCollapse={() => setCollapsed(!collapsed)}
/>

LayoutMenu

import { LayoutMenu, MenuProvider } from '@t1-org/t1components';

function App() {
  return (
    <MenuProvider>
      <LayoutMenu
        menuPaths={menuPaths}
        currentPath={pathname}
        onPathChange={(path) => router.push(path)}
        user={{
          name: "Juan Pérez",
          email: "[email protected]"
        }}
      />
    </MenuProvider>
  );
}

📱 Vistas (Views)

Componentes de página completa:

RestrictedAccess

import { RestrictedAccess } from '@t1-org/t1components';

<RestrictedAccess
  message="No tienes permisos para acceder a esta sección"
  showHomeButton={true}
  onHomeClick={() => navigate('/')}
/>

🎨 Iconos y recursos

Iconos disponibles

import { Icons, Logos, MenuIcon } from '@t1-org/t1components';

// Iconos generales
<Icons.ChevronDown />
<Icons.Search />
<Icons.User />

// Logos
<Logos.T1Logo />
<Logos.BrandLogo />

// Iconos de menú
<MenuIcon.Dashboard />
<MenuIcon.Users />

🧭 Navegación y routing

Con React Router

import { BrowserRouter, Routes, Route, useLocation, useNavigate } from 'react-router-dom';
import { LayoutMenu } from '@t1-org/t1components';

function AppWithRouter() {
  const location = useLocation();
  const navigate = useNavigate();

  return (
    <LayoutMenu
      currentPath={location.pathname}
      onPathChange={(path) => navigate(path)}
      menuPaths={menuPaths}
    />
  );
}

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/*" element={<AppWithRouter />} />
      </Routes>
    </BrowserRouter>
  );
}

Con Next.js

import { usePathname, useRouter } from 'next/navigation';
import { LayoutMenu } from '@t1-org/t1components';

function Layout({ children }) {
  const pathname = usePathname();
  const router = useRouter();

  return (
    <LayoutMenu
      currentPath={pathname}
      onPathChange={(path) => router.push(path)}
      menuPaths={menuPaths}
    >
      {children}
    </LayoutMenu>
  );
}

Navegación personalizada

import { Sidebar } from '@t1-org/t1components';

const handleCustomNavigation = (path, context) => {
  console.log('Navegando a:', path, 'Contexto:', context);
  
  // Validaciones
  if (path === '/admin' && !user.isAdmin) {
    alert('No tienes permisos');
    return;
  }
  
  // Analytics
  if (context?.isMenuItem) {
    analytics.track('sidebar_navigation', { path });
  }
  
  // Navegar
  router.push(path);
};

<Sidebar
  currentPath={pathname}
  onCustomNavigate={handleCustomNavigation}
  menuPaths={menuPaths}
/>

🎛️ Context y estado global

MenuProvider

import { MenuProvider, useMenu } from '@t1-org/t1components';

function App() {
  return (
    <MenuProvider>
      <MyApp />
    </MenuProvider>
  );
}

function MyComponent() {
  const { isMenuOpen, toggleMenu, closeMenu } = useMenu();
  
  return (
    <div>
      <button onClick={toggleMenu}>
        {isMenuOpen ? 'Cerrar' : 'Abrir'} menú
      </button>
    </div>
  );
}

🎨 Personalización y temas

Usar el tema incluido

import { ThemeProvider } from '@mui/material/styles';
import { theme } from '@t1-org/t1components';

<ThemeProvider theme={theme}>
  <App />
</ThemeProvider>

Extender el tema

import { createTheme, ThemeProvider } from '@mui/material/styles';
import { theme as t1Theme } from '@t1-org/t1components';

const customTheme = createTheme({
  ...t1Theme,
  palette: {
    ...t1Theme.palette,
    primary: {
      main: '#your-color'
    }
  }
});

<ThemeProvider theme={customTheme}>
  <App />
</ThemeProvider>

🔧 Configuración avanzada

Configuración de Vite

Si usas Vite, asegúrate de configurar correctamente las dependencias:

// vite.config.js
export default defineConfig({
  optimizeDeps: {
    include: ['@t1-org/t1components']
  }
});

Configuración de Webpack

Para proyectos con Webpack, agrega la configuración necesaria:

// webpack.config.js
module.exports = {
  resolve: {
    alias: {
      '@t1-org/t1components': require.resolve('@t1-org/t1components')
    }
  }
};

📝 Ejemplos prácticos

Dashboard completo

import {
  LayoutMenu,
  MenuProvider,
  Table,
  Card,
  Button,
  CustomPagination,
  BalanceBanner
} from '@t1-org/t1components';

function Dashboard() {
  return (
    <MenuProvider>
      <LayoutMenu
        currentPath="/dashboard"
        onPathChange={(path) => router.push(path)}
        menuPaths={menuPaths}
      >
        <div className="p-6 space-y-6">
          <BalanceBanner
            balance={45000}
            currency="MXN"
            trend="up"
            trendPercent={15.2}
          />
          
          <Card>
            <Table
              columns={[
                { key: 'name', label: 'Nombre' },
                { key: 'status', label: 'Estado' },
                { key: 'amount', label: 'Monto' }
              ]}
              data={transactions}
              loading={loading}
            />
            <CustomPagination
              currentPage={page}
              totalPages={totalPages}
              onPageChange={setPage}
            />
          </Card>
        </div>
      </LayoutMenu>
    </MenuProvider>
  );
}

Formulario completo

import {
  Card,
  CustomInput,
  Select,
  PhoneInputT1,
  CheckBox,
  Button
} from '@t1-org/t1components';

function UserForm() {
  return (
    <Card>
      <form className="space-y-4">
        <CustomInput
          label="Nombre completo"
          required
          placeholder="Ingresa tu nombre"
        />
        
        <CustomInput
          label="Email"
          type="email"
          required
          placeholder="[email protected]"
        />
        
        <PhoneInputT1
          label="Teléfono"
          defaultCountry="MX"
        />
        
        <Select
          label="País"
          options={countries}
          placeholder="Selecciona tu país"
        />
        
        <CheckBox
          label="Acepto términos y condiciones"
          required
        />
        
        <div className="flex gap-4">
          <Button variant="secondary" type="button">
            Cancelar
          </Button>
          <Button variant="primary" type="submit">
            Guardar
          </Button>
        </div>
      </form>
    </Card>
  );
}

🐛 Troubleshooting

Problemas comunes

Error: "Module not found"

# Asegúrate de instalar todas las peer dependencies
npm install react react-dom @mui/material @emotion/react @emotion/styled

Estilos no se aplican

// Asegúrate de importar los estilos
import '@t1-org/t1components/styles';

Navegación no funciona

// Para React Router, asegúrate de estar dentro del Router
<BrowserRouter>
  <LayoutMenu />
</BrowserRouter>

// Para Next.js, usa los hooks correctos
const pathname = usePathname();
const router = useRouter();

TypeScript errors

# Asegúrate de tener TypeScript configurado correctamente
npm install --save-dev typescript @types/react @types/react-dom

📊 Compatibilidad

  • React: 16.8+ (Hooks requeridos)
  • TypeScript: 4.0+
  • Material-UI: 5.0+
  • Node.js: 16+

Navegadores soportados

  • Chrome 90+
  • Firefox 88+
  • Safari 14+
  • Edge 90+

🤝 Contribución

Desarrollo local

# Clonar el repositorio
git clone [repository-url]

# Instalar dependencias
npm install

# Ejecutar Storybook
npm run storybook

# Construir la librería
npm run build

# Ejecutar en modo desarrollo
npm run dev

Scripts disponibles

  • npm run build - Construir la librería para producción
  • npm run dev - Modo desarrollo con hot reload
  • npm run storybook - Ejecutar Storybook
  • npm run build-storybook - Construir Storybook estático

📄 Licencia

[Especificar licencia]

🆘 Soporte

Para reportar bugs o solicitar features:

  • [Issues en GitHub]
  • [Documentación completa]
  • [Ejemplos en Storybook]

🆕 Componentes recientes

ProductCheckList

Componente profesional para listas de productos con checkboxes, optimizado para checkout y selección múltiple.

import { ProductCheckList } from '@t1-org/t1components';

const items = [
  {
    id: '1',
    title: 'Vestido midi casual Tommy Hilfiger para mujer',
    imageUrl: 'https://images.unsplash.com/photo-1595777457583-95e059d581b8?w=200',
    variants: [
      { id: 'color', label: 'Rosa', variant: 'primary' },
      { id: 'size', label: 'Grande', variant: 'primary' }
    ],
    checked: false
  }
];

function App() {
  const [products, setProducts] = useState(items);
  
  const handleItemToggle = (itemId: string, checked: boolean) => {
    setProducts(prev => 
      prev.map(item => 
        item.id === itemId ? { ...item, checked } : item
      )
    );
  };

  return (
    <ProductCheckList
      items={products}
      onItemToggle={handleItemToggle}
      showSelectAll
      showSeparators
      size="medium"
      maxSelectable={5}
    />
  );
}

Características principales:

  • Principios SOLID: Código modular y mantenible
  • 🎨 Pixel perfect: Diseño fiel a mockups de Figma
  • 📱 Responsive: Tamaños small, medium, large
  • Accesible: ARIA labels, navegación por teclado
  • Performance: Memoización y lazy loading
  • 🌐 URLs reales: Imágenes de Unsplash
  • 🎛️ Configurable: Límites de selección, estados de carga

Desarrollado con ❤️ por el equipo T1