Swap

Swap toggles the visibility of two elements with a smooth transition. Perfect for toggle buttons, theme switchers, and animated icons.

Usage Example

Swap with transition effects and state binding.

await import('/components/actions/swap.js');
await import('/components/actions/button.js');

const { signal, tags, $ } = Lightview;
const { div, p, Swap, Button } = tags;

const isActive = signal(false);

// Controlled swap
const swap = Swap({ 
    effect: 'flip',
    class: 'text-6xl',
    active: () => isActive.value,
    onChange: (checked) => { isActive.value = checked; }
},
    Swap.On({}, '🥳'),
    Swap.Off({}, '😭')
);

// External control
const demo = div({ style: 'display: flex; flex-direction: column; gap: 1rem; align-items: center' },
    swap,
    p({ class: 'text-sm' }, 
        () => isActive.value ? 'Party time! 🎉' : 'So sad... 💔'
    ),
    Button({ 
        color: 'primary',
        size: 'sm',
        onclick: () => { isActive.value = !isActive.value; }
    }, 'Toggle from button')
);

$('#example').content(demo);
await import('/components/actions/swap.js');
await import('/components/actions/button.js');
const { signal, $, tags } = Lightview;
const { Swap, Button, div, p } = tags;

const isActive = signal(false);

const demo = {
    tag: div,
    attributes: { style: 'display: flex; flex-direction: column; gap: 1rem; align-items: center' },
    children: [
        {
            tag: Swap,
            attributes: {
                effect: 'flip',
                class: 'text-6xl',
                active: () => isActive.value,
                onChange: (checked) => { isActive.value = checked; }
            },
            children: [
                { tag: Swap.On, children: ['🥳'] },
                { tag: Swap.Off, children: ['😭'] }
            ]
        },
        {
            tag: p,
            attributes: { class: 'text-sm' },
            children: [() => isActive.value ? 'Party time! 🎉' : 'So sad... 💔']
        },
        {
            tag: Button,
            attributes: {
                color: 'primary',
                size: 'sm',
                onclick: () => { isActive.value = !isActive.value; }
            },
            children: ['Toggle from button']
        }
    ]
};

$('#example').content(demo);
await import('/components/actions/swap.js');
await import('/components/actions/button.js');
const { signal, $ } = Lightview;

const isActive = signal(false);

const demo = {
    div: {
        style: 'display: flex; flex-direction: column; gap: 1rem; align-items: center',
        children: [
            {
                Swap: {
                    effect: 'flip',
                    class: 'text-6xl',
                    active: () => isActive.value,
                    onChange: (checked) => { isActive.value = checked; },
                    children: [
                        { 'Swap.On': { children: ['🥳'] } },
                        { 'Swap.Off': { children: ['😭'] } }
                    ]
                }
            },
            {
                p: {
                    class: 'text-sm',
                    children: [() => isActive.value ? 'Party time! 🎉' : 'So sad... 💔']
                }
            },
            {
                Button: {
                    color: 'primary',
                    size: 'sm',
                    onclick: () => { isActive.value = !isActive.value; },
                    children: ['Toggle from button']
                }
            }
        ]
    }
};

$('#example').content(demo);
<!-- Import components -->
<script type="module" src="/components/actions/swap.js"></script>
<script type="module" src="/components/actions/button.js"></script>

<div id="demo-root" style="display: flex; flex-direction: column; gap: 1rem; align-items: center">
    <lv-swap id="my-swap" effect="flip" class="text-6xl">
        <on>🥳</on>
        <off>😭</off>
    </lv-swap>
    
    <p id="status-text" class="text-sm">Waiting...</p>
    
    <lv-button id="toggle-btn" color="primary" size="sm">Toggle State</lv-button>
</div>

<script type="module">
    const { signal, effect, $ } = Lightview;
    const isActive = signal(false);
    
    // Link swap state
    const swap = document.getElementById('my-swap');
    swap.addEventListener('change', (e) => { isActive.value = e.target.checked; });
    
    // External toggle
    document.getElementById('toggle-btn').onclick = () => {
        isActive.value = !isActive.value;
    };
    
    // Reactive sync
    effect(() => {
        swap.setAttribute('active', isActive.value);
        document.getElementById('status-text').textContent = 
            isActive.value ? 'Party time! 🎉' : 'So sad... 💔';
    });
</script>

Reactive Toggle

Controlled swap with signal binding

await import('/components/actions/swap.js');
await import('/components/actions/button.js');

const { signal, tags, $ } = Lightview;
const { div, p, Swap, Button } = tags;

const isActive = signal(false);

// Controlled swap
const swap = Swap({ 
    effect: 'flip',
    class: 'text-6xl',
    active: () => isActive.value,
    onChange: (checked) => { isActive.value = checked; }
},
    Swap.On({}, '🥳'),
    Swap.Off({}, '😭')
);

// External control
const demo = div({ style: 'display: flex; flex-direction: column; gap: 1rem; align-items: center' },
    swap,
    p({ class: 'text-sm' }, 
        () => isActive.value ? 'Party time! 🎉' : 'So sad... 💔'
    ),
    Button({ 
        color: 'primary',
        size: 'sm',
        onclick: () => { isActive.value = !isActive.value; }
    }, 'Toggle from button')
);

$('#example').content(demo);
await import('/components/actions/swap.js');
await import('/components/actions/button.js');
const { signal, $, tags } = Lightview;
const { Swap, Button, div, p } = tags;

const isActive = signal(false);

const demo = {
    tag: div,
    attributes: { style: 'display: flex; flex-direction: column; gap: 1rem; align-items: center' },
    children: [
        {
            tag: Swap,
            attributes: {
                effect: 'flip',
                class: 'text-6xl',
                active: () => isActive.value,
                onChange: (checked) => { isActive.value = checked; }
            },
            children: [
                { tag: Swap.On, children: ['🥳'] },
                { tag: Swap.Off, children: ['😭'] }
            ]
        },
        {
            tag: p,
            attributes: { class: 'text-sm' },
            children: [() => isActive.value ? 'Party time! 🎉' : 'So sad... 💔']
        },
        {
            tag: Button,
            attributes: {
                color: 'primary',
                size: 'sm',
                onclick: () => { isActive.value = !isActive.value; }
            },
            children: ['Toggle from button']
        }
    ]
};

$('#example').content(demo);
await import('/components/actions/swap.js');
await import('/components/actions/button.js');
const { signal, $ } = Lightview;

const isActive = signal(false);

const demo = {
    div: {
        style: 'display: flex; flex-direction: column; gap: 1rem; align-items: center',
        children: [
            {
                Swap: {
                    effect: 'flip',
                    class: 'text-6xl',
                    active: () => isActive.value,
                    onChange: (checked) => { isActive.value = checked; },
                    children: [
                        { 'Swap.On': { children: ['🥳'] } },
                        { 'Swap.Off': { children: ['😭'] } }
                    ]
                }
            },
            {
                p: {
                    class: 'text-sm',
                    children: [() => isActive.value ? 'Party time! 🎉' : 'So sad... 💔']
                }
            },
            {
                Button: {
                    color: 'primary',
                    size: 'sm',
                    onclick: () => { isActive.value = !isActive.value; },
                    children: ['Toggle from button']
                }
            }
        ]
    }
};

$('#example').content(demo);

Props

Prop Type Default Description
active boolean | function false Control swap state (reactive)
effect string - 'rotate' | 'flip'
onChange function - Callback when state changes: (checked) => void

Sub-components

Component Description
Swap.On Content visible when active/checked
Swap.Off Content visible when inactive/unchecked

Swap Gallery

Live examples using <lv-swap> custom elements.

Effects

Rotate

😈 😇

Flip

🥳 😭

Interactive Icons

❤️ 🤍