Files
sigpro-ui/docs/components_old/swap.md
2026-04-02 19:31:39 +02:00

15 KiB

Swap

Toggle component that swaps between two states (on/off) with customizable icons or content.

Tag

Swap

Props

Prop Type Default Description
value boolean | Signal<boolean> false Swap state (true = on, false = off)
on string | VNode - Content to show when state is on
off string | VNode - Content to show when state is off
class string '' Additional CSS classes (DaisyUI + Tailwind)
onclick function - Click event handler

Live Examples

Basic Swap

Live Demo

const BasicDemo = () => {
  const isOn = $(false);
  
  return Swap({
    value: isOn,
    on: "🌟 ON",
    off: "💫 OFF",
    onclick: () => isOn(!isOn())
  });
};
$mount(BasicDemo, '#demo-basic');

Icon Swap

Live Demo

const IconsDemo = () => {
  const isOn = $(false);
  
  return Swap({
    value: isOn,
    on: Icons.iconShow,
    off: Icons.iconHide,
    onclick: () => isOn(!isOn())
  });
};
$mount(IconsDemo, '#demo-icons');

Emoji Swap

Live Demo

const EmojiDemo = () => {
  const isOn = $(false);
  
  return Swap({
    value: isOn,
    on: "❤️",
    off: "🖤",
    onclick: () => isOn(!isOn())
  });
};
$mount(EmojiDemo, '#demo-emoji');

Custom Content Swap

Live Demo

const CustomDemo = () => {
  const isOn = $(false);
  
  return Swap({
    value: isOn,
    on: Div({ class: "badge badge-success gap-1" }, ["✅", " Active"]),
    off: Div({ class: "badge badge-ghost gap-1" }, ["⭕", " Inactive"]),
    onclick: () => isOn(!isOn())
  });
};
$mount(CustomDemo, '#demo-custom');

With Reactive State

Live Demo

const ReactiveDemo = () => {
  const isOn = $(false);
  
  return Div({ class: 'flex flex-col gap-4 items-center' }, [
    Swap({
      value: isOn,
      on: Icons.iconShow,
      off: Icons.iconHide,
      onclick: () => isOn(!isOn())
    }),
    Div({ class: 'text-center' }, () => 
      isOn() 
        ? Div({ class: 'alert alert-success' }, 'Content is visible')
        : Div({ class: 'alert alert-soft' }, 'Content is hidden')
    )
  ]);
};
$mount(ReactiveDemo, '#demo-reactive');

Toggle Mode Swap

Live Demo

const ModeDemo = () => {
  const darkMode = $(false);
  const notifications = $(true);
  const sound = $(false);
  
  return Div({ class: 'flex flex-col gap-4 w-full' }, [
    Div({ class: 'flex justify-between items-center' }, [
      Span({}, 'Dark mode'),
      Swap({
        value: darkMode,
        on: "🌙",
        off: "☀️",
        onclick: () => darkMode(!darkMode())
      })
    ]),
    Div({ class: 'flex justify-between items-center' }, [
      Span({}, 'Notifications'),
      Swap({
        value: notifications,
        on: "🔔",
        off: "🔕",
        onclick: () => notifications(!notifications())
      })
    ]),
    Div({ class: 'flex justify-between items-center' }, [
      Span({}, 'Sound effects'),
      Swap({
        value: sound,
        on: "🔊",
        off: "🔇",
        onclick: () => sound(!sound())
      })
    ]),
    Div({ class: 'mt-2 p-3 rounded-lg', style: () => darkMode() ? 'background: #1f2937; color: white' : 'background: #f3f4f6' }, [
      Div({ class: 'text-sm' }, () => `Mode: ${darkMode() ? 'Dark' : 'Light'} | Notifications: ${notifications() ? 'On' : 'Off'} | Sound: ${sound() ? 'On' : 'Off'}`)
    ])
  ]);
};
$mount(ModeDemo, '#demo-mode');

All Variants

Live Demo

const VariantsDemo = () => {
  return Div({ class: 'flex flex-wrap gap-8 justify-center items-center' }, [
    Div({ class: 'text-center' }, [
      Div({ class: 'text-xs mb-2' }, 'Volume'),
      Swap({
        value: $(false),
        on: "🔊",
        off: "🔇"
      })
    ]),
    Div({ class: 'text-center' }, [
      Div({ class: 'text-xs mb-2' }, 'Like'),
      Swap({
        value: $(true),
        on: "❤️",
        off: "🤍"
      })
    ]),
    Div({ class: 'text-center' }, [
      Div({ class: 'text-xs mb-2' }, 'Star'),
      Swap({
        value: $(false),
        on: "⭐",
        off: "☆"
      })
    ]),
    Div({ class: 'text-center' }, [
      Div({ class: 'text-xs mb-2' }, 'Check'),
      Swap({
        value: $(true),
        on: Icons.iconSuccess,
        off: Icons.iconError
      })
    ])
  ]);
};
$mount(VariantsDemo, '#demo-variants');

Simple Todo Toggle

Live Demo

const TodoDemo = () => {
  const todos = [
    { id: 1, text: 'Complete documentation', completed: $(true) },
    { id: 2, text: 'Review pull requests', completed: $(false) },
    { id: 3, text: 'Deploy to production', completed: $(false) }
  ];
  
  return Div({ class: 'flex flex-col gap-3' }, [
    Div({ class: 'text-sm font-bold mb-2' }, 'Todo list'),
    ...todos.map(todo => 
      Div({ class: 'flex items-center justify-between p-2 bg-base-200 rounded-lg' }, [
        Span({ class: todo.completed() ? 'line-through opacity-50' : '' }, todo.text),
        Swap({
          value: todo.completed,
          on: Icons.iconSuccess,
          off: Icons.iconClose,
          onclick: () => todo.completed(!todo.completed())
        })
      ])
    ),
    Div({ class: 'mt-2 text-sm opacity-70' }, () => {
      const completed = todos.filter(t => t.completed()).length;
      return `${completed} of ${todos.length} tasks completed`;
    })
  ]);
};
$mount(TodoDemo, '#demo-todo');
<script> (function() { const initSwapExamples = () => { // 1. Basic Swap const basicTarget = document.querySelector('#demo-basic'); if (basicTarget && !basicTarget.hasChildNodes()) { const BasicDemo = () => { const isOn = $(false); return Swap({ value: isOn, on: "🌟 ON", off: "💫 OFF", onclick: () => isOn(!isOn()) }); }; $mount(BasicDemo, basicTarget); } // 2. Icon Swap const iconsTarget = document.querySelector('#demo-icons'); if (iconsTarget && !iconsTarget.hasChildNodes()) { const IconsDemo = () => { const isOn = $(false); return Swap({ value: isOn, on: Icons.iconShow, off: Icons.iconHide, onclick: () => isOn(!isOn()) }); }; $mount(IconsDemo, iconsTarget); } // 3. Emoji Swap const emojiTarget = document.querySelector('#demo-emoji'); if (emojiTarget && !emojiTarget.hasChildNodes()) { const EmojiDemo = () => { const isOn = $(false); return Swap({ value: isOn, on: "❤️", off: "🖤", onclick: () => isOn(!isOn()) }); }; $mount(EmojiDemo, emojiTarget); } // 4. Custom Content Swap const customTarget = document.querySelector('#demo-custom'); if (customTarget && !customTarget.hasChildNodes()) { const CustomDemo = () => { const isOn = $(false); return Swap({ value: isOn, on: Div({ class: "badge badge-success gap-1" }, ["", " Active"]), off: Div({ class: "badge badge-ghost gap-1" }, ["", " Inactive"]), onclick: () => isOn(!isOn()) }); }; $mount(CustomDemo, customTarget); } // 5. Reactive State const reactiveTarget = document.querySelector('#demo-reactive'); if (reactiveTarget && !reactiveTarget.hasChildNodes()) { const ReactiveDemo = () => { const isOn = $(false); return Div({ class: 'flex flex-col gap-4 items-center' }, [ Swap({ value: isOn, on: Icons.iconShow, off: Icons.iconHide, onclick: () => isOn(!isOn()) }), Div({ class: 'text-center' }, () => isOn() ? Div({ class: 'alert alert-success' }, 'Content is visible') : Div({ class: 'alert alert-soft' }, 'Content is hidden') ) ]); }; $mount(ReactiveDemo, reactiveTarget); } // 6. Toggle Mode Swap const modeTarget = document.querySelector('#demo-mode'); if (modeTarget && !modeTarget.hasChildNodes()) { const ModeDemo = () => { const darkMode = $(false); const notifications = $(true); const sound = $(false); return Div({ class: 'flex flex-col gap-4 w-full' }, [ Div({ class: 'flex justify-between items-center' }, [ Span({}, 'Dark mode'), Swap({ value: darkMode, on: "🌙", off: "☀️", onclick: () => darkMode(!darkMode()) }) ]), Div({ class: 'flex justify-between items-center' }, [ Span({}, 'Notifications'), Swap({ value: notifications, on: "🔔", off: "🔕", onclick: () => notifications(!notifications()) }) ]), Div({ class: 'flex justify-between items-center' }, [ Span({}, 'Sound effects'), Swap({ value: sound, on: "🔊", off: "🔇", onclick: () => sound(!sound()) }) ]), Div({ class: 'mt-2 p-3 rounded-lg', style: () => darkMode() ? 'background: #1f2937; color: white' : 'background: #f3f4f6' }, [ Div({ class: 'text-sm' }, () => `Mode: ${darkMode() ? 'Dark' : 'Light'} | Notifications: ${notifications() ? 'On' : 'Off'} | Sound: ${sound() ? 'On' : 'Off'}`) ]) ]); }; $mount(ModeDemo, modeTarget); } // 7. All Variants const variantsTarget = document.querySelector('#demo-variants'); if (variantsTarget && !variantsTarget.hasChildNodes()) { const VariantsDemo = () => { return Div({ class: 'flex flex-wrap gap-8 justify-center items-center' }, [ Div({ class: 'text-center' }, [ Div({ class: 'text-xs mb-2' }, 'Volume'), Swap({ value: $(false), on: "🔊", off: "🔇" }) ]), Div({ class: 'text-center' }, [ Div({ class: 'text-xs mb-2' }, 'Like'), Swap({ value: $(true), on: "❤️", off: "🤍" }) ]), Div({ class: 'text-center' }, [ Div({ class: 'text-xs mb-2' }, 'Star'), Swap({ value: $(false), on: "", off: "☆" }) ]), Div({ class: 'text-center' }, [ Div({ class: 'text-xs mb-2' }, 'Check'), Swap({ value: $(true), on: Icons.iconSuccess, off: Icons.iconError }) ]) ]); }; $mount(VariantsDemo, variantsTarget); } // 8. Simple Todo Toggle const todoTarget = document.querySelector('#demo-todo'); if (todoTarget && !todoTarget.hasChildNodes()) { const TodoDemo = () => { const todos = [ { id: 1, text: 'Complete documentation', completed: $(true) }, { id: 2, text: 'Review pull requests', completed: $(false) }, { id: 3, text: 'Deploy to production', completed: $(false) } ]; return Div({ class: 'flex flex-col gap-3' }, [ Div({ class: 'text-sm font-bold mb-2' }, 'Todo list'), ...todos.map(todo => Div({ class: 'flex items-center justify-between p-2 bg-base-200 rounded-lg' }, [ Span({ class: todo.completed() ? 'line-through opacity-50' : '' }, todo.text), Swap({ value: todo.completed, on: Icons.iconSuccess, off: Icons.iconClose, onclick: () => todo.completed(!todo.completed()) }) ]) ), Div({ class: 'mt-2 text-sm opacity-70' }, () => { const completed = todos.filter(t => t.completed()).length; return `${completed} of ${todos.length} tasks completed`; }) ]); }; $mount(TodoDemo, todoTarget); } }; initSwapExamples(); if (window.$docsify) { window.$docsify.plugins = [].concat(window.$docsify.plugins || [], (hook) => { hook.doneEach(initSwapExamples); }); } })(); </script>