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

@tamyla/ui-components

v1.1.3

Published

Professional UI component library with unified API - complete modal integration, developer tools, and production-ready for human and AI developers

Readme

Tamyla UI Components

📦 NPM Package: @tamyla/[email protected]
🔗 GitHub: https://github.com/tamylaa/tamyla-ui-components
✅ Status: Production Ready - Unified API

Professional UI component library with unified API - single entry point for all components, optimized for both human and AI developers.

🚀 Quick Start

npm install @tamyla/ui-components

🎯 RECOMMENDED: Unified API (Single Entry Point)

import { UI } from '@tamyla/ui-components';

// Create ANY component with consistent API
const button = UI.create('button', { variant: 'primary', text: 'Click me!' });
const input = UI.create('input', { type: 'email', label: 'Email Address' });
const card = UI.create('card', { title: 'My Card', content: 'Card content' });
const search = UI.create('search-interface', { enableVoice: true, showFilters: true });

// Batch create multiple components
const components = UI.createMultiple([
  { type: 'button', props: { text: 'Save', variant: 'primary' } },
  { type: 'button', props: { text: 'Cancel', variant: 'secondary' } },
  { type: 'input', props: { placeholder: 'Search...' } }
]);

📦 Alternative: Direct Component Creation

import { createButton, createInput, createCard } from '@tamyla/ui-components';

const button = createButton({ text: 'Click me!' });
const input = createInput({ placeholder: 'Type here...' });
const card = createCard({ title: 'My Card', content: 'Card content' });

🎯 Why Unified API?

| Feature | Unified API | Multiple Imports | |---------|-------------|------------------| | Consistency | ✅ Single pattern for all components | ❌ Different patterns per component | | Discoverability | ✅ UI.create() for everything | ❌ Hunt for specific imports | | Type Safety | ✅ Consistent TypeScript support | ⚠️ Mixed type definitions | | AI-Friendly | ✅ Predictable API patterns | ❌ Complex import decisions | | Maintenance | ✅ Single entry point to maintain | ❌ Multiple export points | | Bundle Size | ✅ Tree-shakable | ⚠️ May import unused code |

📋 Available Components

Atoms (Basic Building Blocks)

UI.create('button', { variant: 'primary', text: 'Click', size: 'md' });
UI.create('input', { type: 'email', label: 'Email', placeholder: '[email protected]' });
UI.create('card', { title: 'Card Title', content: 'Card content', variant: 'elevated' });
UI.create('status-indicator', { status: 'online', label: 'User Status' });

Molecules (Composite Components)

UI.create('search-bar', { placeholder: 'Search...', voiceEnabled: true });
UI.create('action-card', { title: 'Action', description: 'Click to perform action' });
UI.create('content-card', { size: 'default', selectable: true });
UI.create('notification', { type: 'success', message: 'Operation completed' });

Organisms (Complete Interfaces)

UI.create('search-interface', {
  enableVoice: true,
  showFilters: true,
  viewMode: 'grid'
});

🔧 Advanced Usage

Theming

// Apply theme to all components
const themedButton = UI.createThemed('button', 'dark', { text: 'Dark Button' });

// Or apply theme globally
UI.applyTheme('minimal');

Batch Operations

// Create form with multiple components
const formComponents = UI.createMultiple([
  { type: 'input', props: { label: 'Name', required: true } },
  { type: 'input', props: { label: 'Email', type: 'email' } },
  { type: 'button', props: { text: 'Submit', variant: 'primary' } }
]);

Available Types & Variants

// Get all available component types
console.log(UI.getAvailableTypes());

// Get variants for specific component
console.log(UI.getVariants('button')); // ['primary', 'secondary', 'ghost', 'success', 'danger']

🏗️ Architecture

ui-components/
├── src/
│   ├── ui-factory.js       # 🎯 UNIFIED API ENTRY POINT
│   ├── index.js            # Main exports
│   └── ...
├── atoms/                  # Basic components
├── molecules/              # Composite components
├── organisms/              # Complete interfaces
└── applications/           # Full applications

🎨 Design Philosophy

Atomic Design with Unified API:

  • Atoms: Basic building blocks (buttons, inputs, cards)
  • Molecules: Combinations of atoms (search bars, content cards)
  • Organisms: Complete interface sections (search interfaces)
  • Applications: Full-featured applications

Single Responsibility: Each component has one clear purpose and API.

📚 API Reference

UI.create(type, props)

Primary method for creating all components

  • type (string): Component type
  • props (object): Component properties
  • Returns: HTMLElement

UI.createMultiple(configs)

Create multiple components at once

  • configs (array): Array of { type, props } objects
  • Returns: Array of HTMLElements

UI.createThemed(type, theme, props)

Create component with theme applied

  • type (string): Component type
  • theme (string): Theme name
  • props (object): Component properties
  • Returns: HTMLElement

UI.getAvailableTypes()

Get all available component types

  • Returns: Object with atoms, molecules, organisms, applications

UI.getVariants(type)

Get available variants for component type

  • type (string): Component type
  • Returns: Array of variant names

🔄 Migration Guide

From Multiple Imports → Unified API

// OLD WAY (confusing)
import { createButton, createInput, SearchInterfaceFactory } from '@tamyla/ui-components';

const button = createButton({ text: 'Click' });
const search = SearchInterfaceFactory.create({ enableVoice: true }); // ❌ Doesn't work

// NEW WAY (consistent)
import { UI } from '@tamyla/ui-components';

const button = UI.create('button', { text: 'Click' });
const search = UI.create('search-interface', { enableVoice: true }); // ✅ Works perfectly

🤖 AI Developer Friendly

This unified API is designed specifically for AI agents:

  1. Predictable Patterns: UI.create(type, props) works for everything
  2. Consistent Parameters: Same parameter structure across all components
  3. Clear Error Messages: Helpful error messages when something goes wrong
  4. Type Safety: Full TypeScript support with consistent interfaces
  5. Self-Documenting: Method names clearly indicate their purpose

📖 Documentation

🐛 Troubleshooting

Common Issues

"Component type not found"

// Check available types
console.log(UI.getAvailableTypes());

"Method not available"

// Use the unified API instead of direct Web Component manipulation
const search = UI.create('search-interface', { enableVoice: true });
// ✅ search.updateResults() will be available immediately

"Import not found"

// Use the unified import
import { UI } from '@tamyla/ui-components'; // ✅ Recommended
// NOT: import { SearchInterfaceFactory } from '...'; // ❌ May not work

📄 License

MIT License - see LICENSE file for details.

📚 Documentation

🎯 Design Philosophy

Instead of monolithic, standalone components, this design system follows atomic design methodology:

  • Atoms: Basic building blocks (buttons, inputs, cards)
  • Molecules: Combinations of atoms (search bars, content cards)
  • Organisms: Complete interface sections (search interfaces, dashboards)

🏗️ Architecture

ui-components/
├── core/
│   ├── tokens.css          # Design tokens (colors, spacing, typography)
│   └── utilities.css       # Utility classes for rapid development
├── atoms/
│   ├── tmyl-button.js      # Versatile button component
│   ├── tmyl-input.js       # Input field with variants
│   └── tmyl-card.js        # Container component
├── molecules/
│   ├── tmyl-search-bar.js  # Search with voice & suggestions
│   └── tmyl-content-card.js # Content display with actions
├── organisms/
│   └── tmyl-search-interface.js # Complete search experience
├── demo.html               # Interactive component showcase
├── index.js               # Main export file
└── README.md              # This file

🚀 Quick Start

1. Basic Setup

<!DOCTYPE html>
<html>
<head>
    <!-- Load core design tokens -->
    <link rel="stylesheet" href="./ui-components/core/tokens.css">
    <link rel="stylesheet" href="./ui-components/core/utilities.css">
</head>
<body>
    <!-- Use components -->
    <tmyl-search-bar voice-enabled clearable></tmyl-search-bar>
    <tmyl-button variant="primary" size="lg">Get Started</tmyl-button>
    
    <!-- Load component library -->
    <script type="module" src="./ui-components/index.js"></script>
</body>
</html>

2. Module Import

// Import entire design system
import './ui-components/index.js';

// Or import specific components
import { TmylButton, TmylSearchBar } from './ui-components/index.js';

3. Component Usage

<!-- Atoms: Basic building blocks -->
<tmyl-button variant="primary" icon="search" loading>Search</tmyl-button>
<tmyl-input label="Email" type="email" icon="email" clearable></tmyl-input>
<tmyl-card variant="elevated" hover clickable>Content here</tmyl-card>

<!-- Molecules: Composite components -->
<tmyl-search-bar 
    placeholder="Search content..." 
    voice-enabled
    clearable
></tmyl-search-bar>

<tmyl-content-card 
    .content="${contentObj}"
    selectable
    show-actions
></tmyl-content-card>

<!-- Organisms: Complete interfaces -->
<tmyl-search-interface 
    enable-voice-search
    enable-selection
    show-filters
></tmyl-search-interface>

🎨 Design Tokens

The system uses CSS custom properties for consistent theming:

/* Colors */
--tmyl-primary-500: #3B82F6;
--tmyl-success-500: #22C55E;
--tmyl-error-500: #EF4444;

/* Typography */
--tmyl-text-base: 1rem;
--tmyl-font-semibold: 600;

/* Spacing */
--tmyl-space-4: 1rem;
--tmyl-space-6: 1.5rem;

/* Shadows */
--tmyl-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);

📦 Component Reference

Atoms

TmylButton

<tmyl-button 
    variant="primary|secondary|ghost|danger|success"
    size="sm|md|lg|xl"
    icon="search|plus|download|etc"
    loading
    disabled
    full-width
>Button Text</tmyl-button>

Events: tmyl-click

TmylInput

<tmyl-input 
    type="text|email|password|etc"
    label="Field Label"
    placeholder="Placeholder text"
    icon="email|search|lock|etc"
    error-text="Error message"
    helper-text="Help text"
    clearable
    required
></tmyl-input>

Events: tmyl-input, tmyl-change, tmyl-focus, tmyl-blur, tmyl-clear

TmylCard

<tmyl-card 
    variant="flat|outlined|elevated|raised"
    padding="none|sm|md|lg|xl"
    clickable
    hover
>
    <div slot="header">Header content</div>
    <div>Main content</div>
    <div slot="footer">Footer content</div>
</tmyl-card>

Events: tmyl-card-click

Molecules

TmylSearchBar

<tmyl-search-bar 
    placeholder="Search..."
    voice-enabled
    clearable
    .suggestions="${suggestionsArray}"
    show-suggestions
></tmyl-search-bar>

Events: tmyl-search, tmyl-search-input, tmyl-suggestions-request, tmyl-voice-result

Methods: focus(), clear(), setSuggestions(array)

TmylContentCard

<tmyl-content-card 
    .content="${contentObject}"
    size="compact|default|detailed"
    selectable
    selected
    show-actions
    .highlightTerms="${['search', 'term']}"
></tmyl-content-card>

Events: tmyl-content-select, tmyl-content-action

Organisms

TmylSearchInterface

<tmyl-search-interface 
    enable-voice-search
    enable-selection
    show-filters
    view-mode="grid|list"
    .results="${resultsArray}"
    .filters="${filtersObject}"
></tmyl-search-interface>

Events: tmyl-search-request, tmyl-suggestions-request, tmyl-content-select, tmyl-content-action, tmyl-bulk-action

Methods: setResults(array, total), setLoading(boolean), setSuggestions(array), clearResults()

🎧 Voice Search Integration

The design system includes built-in voice search capabilities:

// Voice search is automatically enabled when supported
searchBar.addEventListener('tmyl-voice-result', (e) => {
    console.log('Voice input:', e.detail.transcript);
});

// Voice recognition errors
searchBar.addEventListener('tmyl-voice-error', (e) => {
    console.log('Voice error:', e.detail.error);
});

🎯 Event Handling

All components emit custom events with detailed payloads:

// Search events
searchInterface.addEventListener('tmyl-search-request', (e) => {
    const { query, filters, page, sortBy } = e.detail;
    // Perform search API call
});

// Selection events
searchInterface.addEventListener('tmyl-content-select', (e) => {
    const { content, selected } = e.detail;
    // Handle content selection
});

// Bulk actions
searchInterface.addEventListener('tmyl-bulk-action', (e) => {
    const { action, items } = e.detail;
    // Handle bulk operations
});

🎨 Customization

Theme Customization

:root {
    /* Override default tokens */
    --tmyl-primary-500: #your-brand-color;
    --tmyl-border-radius: 8px;
    --tmyl-font-sans: 'Your Font', sans-serif;
}

Component Customization

/* Target specific components */
tmyl-button {
    --tmyl-button-height-md: 3rem;
}

tmyl-search-bar {
    --tmyl-search-bar-height: 4rem;
}

📱 Responsive Design

All components are responsive by default with mobile-first design:

/* Automatic responsive behavior */
.tmyl-grid-cols-3 {
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

/* Breakpoint utilities */
@media (max-width: 768px) {
    .tmyl-md\:hidden { display: none; }
}

♿ Accessibility

The design system includes accessibility features:

  • Keyboard Navigation: Full keyboard support for all interactive elements
  • Screen Reader Support: Proper ARIA labels and semantic HTML
  • Focus Management: Visible focus indicators and logical tab order
  • Color Contrast: WCAG compliant color combinations
  • Reduced Motion: Respects prefers-reduced-motion setting

🔄 Integration Examples

Meilisearch Integration

import { TmylSearchInterface } from './ui-components/index.js';

const searchInterface = document.querySelector('tmyl-search-interface');

searchInterface.addEventListener('tmyl-search-request', async (e) => {
    const { query, filters, page } = e.detail;
    
    try {
        searchInterface.setLoading(true);
        const response = await fetch('/api/search', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ query, filters, page })
        });
        
        const { results, total } = await response.json();
        searchInterface.setResults(results, total);
    } catch (error) {
        console.error('Search failed:', error);
        searchInterface.setResults([], 0);
    }
});

Campaign Integration

searchInterface.addEventListener('tmyl-bulk-action', async (e) => {
    if (e.detail.action === 'add-to-campaign') {
        const contentIds = e.detail.items.map(item => item.id);
        
        // Add to campaign API call
        await fetch('/api/campaigns/add-content', {
            method: 'POST',
            body: JSON.stringify({ contentIds })
        });
        
        alert(`Added ${contentIds.length} items to campaign`);
    }
});

🧪 Development

Running the Demo

# Serve the demo locally
npx http-server . -p 8080

# Open in browser
open http://localhost:8080/ui-components/demo.html

Creating New Components

  1. Atoms: Single-purpose, reusable components
  2. Molecules: Combinations of atoms with specific functionality
  3. Organisms: Complex components that form complete interface sections
// New component template
import { LitElement, html, css } from 'lit';

export class TmylNewComponent extends LitElement {
    static properties = {
        // Define reactive properties
    };
    
    static styles = css`
        /* Use design tokens */
        :host {
            font-family: var(--tmyl-font-sans);
            color: var(--tmyl-text-primary);
        }
    `;
    
    render() {
        return html`<!-- Template -->`;
    }
}

customElements.define('tmyl-new-component', TmylNewComponent);

🤝 Contributing

  1. Follow atomic design principles
  2. Use design tokens for all styling
  3. Emit meaningful custom events
  4. Include accessibility features
  5. Write comprehensive documentation
  6. Test responsive behavior

📄 License

This design system is part of the Tamyla platform and follows the project's licensing terms.


Built with ❤️ for the Tamyla ecosystem

Modular • Reusable • Consistent • Accessible