yai

YaiJS

Advanced web components with YEH (Yai Event Hub) - Enterprise-grade tabs with O(1) event delegation

Build deeply nested, event-heavy interfaces with constant-time listener delegation and zero manual lifecycle handling. Everything you need in one package.

NPM version Tests License


Why YaiJS?


Quick Start

CDN (No Build Required)

Live on JSFiddle

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@yaijs/core@latest/tabs/yai-tabs.css">
</head>
<body>
    <div data-yai-tabs data-theme="default">
        <nav data-controller>
            <button data-tab-action="open" data-open="1">Tab 1</button>
            <button data-tab-action="open" data-open="2">Tab 2</button>
        </nav>
        <div data-content>
            <div data-tab="1">Content 1</div>
            <div data-tab="2">Content 2</div>
        </div>
    </div>

    <script type="module">
        import { YaiTabs } from 'https://cdn.jsdelivr.net/npm/@yaijs/core@latest/dist/yai-bundle.js';
        new YaiTabs();
    </script>
</body>
</html>

NPM Installation

npm install @yaijs/core
import { YaiTabs, YEH } from '@yaijs/core';

const tabs = new YaiTabs({
    defaultBehavior: 'fade',
    autoFocus: true
});

// Or extend YEH directly for custom event orchestration
class AppBus extends YEH {
    constructor() {
        super({ '#app': ['click', 'input', 'change'] });
    }
}

Component Highlights

YaiTabs

Complete Documentation → Live Demo →

YEH Event Hub

Complete Documentation →

Utilities

Complete Documentation →


Event Hub & Hooks

YaiTabs doubles as an application event hub. Add any event type and get automatic hooks:

const tabs = new YaiTabs({
    events: {
        setListener: {
            '[data-yai-tabs]': ['click', 'keydown', 'input', 'change', 'submit']
        }
    }
});

// All events automatically available as hooks
tabs.hook('eventClick', ({ event, target, container, action }) => {
    console.log('Click action:', action); // Extracted from data-click
});

tabs.hook('eventInput', ({ event, target, container, action }) => {
    console.log('Input action:', action); // Extracted from data-input
});

tabs.hook('tabOpened', ({ detail }) => {
    console.log('Tab opened:', detail.id);
});

Multiple hooks per event:

tabs
    .hook('tabOpened', (ctx) => trackAnalytics(ctx))
    .hook('tabOpened', (ctx) => updateUI(ctx))
    .hook('tabOpened', (ctx) => loadContent(ctx));

See YaiTabs Documentation and YEH Documentation for complete hook catalog.


EventListener Orchestration

Define listener placement declaratively for optimal performance:

const tabs = new YaiTabs({
    events: {
        setListener: {
            '[data-yai-tabs]': ['click', 'keydown'],              // Core events
            '[data-yai-forms]': ['change', 'input', 'submit'],    // Form sections only
            '[data-swipe]': [
                'mousedown', 'mousemove', 'mouseup',
                'touchstart', 'touchmove', 'touchend'
            ]  // Swipe-enabled elements only
        }
    }
});

Real-world results (60 nested components with recursive AJAX loading):

Approach Elements Listeners Reduction
Without orchestration 60 484+ baseline
With orchestration 12 45 91%

≈439 fewer event listeners while maintaining full functionality!


Available Bundles

// Minimal: YaiCore + YaiTabs + YEH
import { YaiTabs } from 'https://cdn.jsdelivr.net/npm/@yaijs/core@latest/dist/yai-bundle-core.js';

// Recommended: + YaiTabsSwipe + YaiViewport
import { YaiTabs, YaiTabsSwipe, YaiViewport } from 'https://cdn.jsdelivr.net/npm/@yaijs/core@latest/dist/yai-bundle.js';

// Full: + YaiAutoSwitch + YaiSearchAndClick
import { YaiTabs, YaiTabsSwipe, YaiViewport } from 'https://cdn.jsdelivr.net/npm/@yaijs/core@latest/dist/yai-bundle-full.js';

Documentation


Live Examples


Browser Support


Resources


License

MIT License – Free for personal and commercial use

Authors


Happy building! 🚀