Zum Inhalt

src/ui/ToggleRow.tsx

import type { Component } from 'solid-js';

interface Props {
  label: string;
  sub?: string;
  checked: boolean;
  onChange: (v: boolean) => void;
}

export const ToggleRow: Component<Props> = (props) => {
  return (
    <button
      type="button"
      onClick={() => props.onChange(!props.checked)}
      style={{
        display: 'flex',
        'align-items': 'center',
        gap: '12px',
        padding: '4px 0',
        background: 'transparent',
        border: '0',
        width: '100%',
        cursor: 'pointer',
        'text-align': 'left',
      }}
    >
      <div style={{ flex: '1', display: 'flex', 'flex-direction': 'column', gap: '2px' }}>
        <span
          style={{
            'font-family': 'var(--font-body)',
            'font-size': '12.5px',
            'font-weight': '500',
            color: 'var(--fg-primary)',
          }}
        >
          {props.label}
        </span>
        {props.sub && (
          <span style={{ 'font-size': '11px', color: 'var(--fg-tertiary)' }}>{props.sub}</span>
        )}
      </div>
      <div
        style={{
          width: '36px',
          height: '20px',
          'border-radius': '999px',
          background: props.checked ? 'var(--accent)' : 'var(--surface-inset)',
          border: '1px solid var(--border-default)',
          position: 'relative',
          transition: 'background var(--dur-base) var(--ease-signal)',
          'box-shadow': props.checked ? '0 0 12px -2px var(--accent-glow)' : 'none',
        }}
      >
        <div
          style={{
            position: 'absolute',
            top: '2px',
            left: props.checked ? '18px' : '2px',
            width: '14px',
            height: '14px',
            'border-radius': '50%',
            background: props.checked ? 'var(--fg-on-accent)' : 'var(--fg-primary)',
            transition: 'left var(--dur-base) var(--ease-signal)',
          }}
        />
      </div>
    </button>
  );
};