SCALE — Build Lab
UI部品 · REACT COMPONENT

タブ切替部品

CATEGORYUI部品 TYPEReact Component EFFORT60〜120分 DIFFICULTY
PRIMARY CODE
tsx
'use client';
import { useState, ReactNode } from 'react';

export function Tabs({ tabs }: { tabs: { label: string; content: ReactNode }[] }) {
  const [active, setActive] = useState(0);
  return (
    <div>
      <div role="tablist" style={{ display: 'flex', gap: '.5rem', borderBottom: '1px solid rgba(255,255,255,.07)' }}>
        {tabs.map((t, i) => (
          <button key={i} role="tab" aria-selected={i === active}
            onClick={() => setActive(i)}
            onKeyDown={(e) => {
              if (e.key === 'ArrowRight') setActive((active + 1) % tabs.length);
              if (e.key === 'ArrowLeft')  setActive((active - 1 + tabs.length) % tabs.length);
            }}
            style={{
              padding: '.65rem 1rem',
              borderBottom: i === active ? '2px solid #a5b4fc' : '2px solid transparent',
              color: i === active ? '#fff' : 'rgba(255,255,255,.55)',
              background: 'transparent', border: 'none', cursor: 'pointer',
              fontFamily: 'inherit', fontSize: '.85rem',
            }}>
            {t.label}
          </button>
        ))}
      </div>
      <div role="tabpanel" style={{ paddingTop: '1.25rem' }}>
        {tabs[active].content}
      </div>
    </div>
  );
}
前提条件
Tailwind CSS v4TypeScript 5
USE CASES
  • 任意のダッシュボードに組み込み

タブ切替部品

:LiTarget: 用途

タブ切替。アクティブ表示・キーボード操作・コンテンツ切替。

:LiSparkle: 特徴

  • アクティブ状態管理
  • 左右キー操作
  • aria 属性
  • コンテンツ切替

:LiCode: コード(コピペ用)

'use client';
import { useState, ReactNode } from 'react';

export function Tabs({ tabs }: { tabs: { label: string; content: ReactNode }[] }) {
  const [active, setActive] = useState(0);
  return (
    <div>
      <div role="tablist" style={{ display: 'flex', gap: '.5rem', borderBottom: '1px solid rgba(255,255,255,.07)' }}>
        {tabs.map((t, i) => (
          <button key={i} role="tab" aria-selected={i === active}
            onClick={() => setActive(i)}
            onKeyDown={(e) => {
              if (e.key === 'ArrowRight') setActive((active + 1) % tabs.length);
              if (e.key === 'ArrowLeft')  setActive((active - 1 + tabs.length) % tabs.length);
            }}
            style={{
              padding: '.65rem 1rem',
              borderBottom: i === active ? '2px solid #a5b4fc' : '2px solid transparent',
              color: i === active ? '#fff' : 'rgba(255,255,255,.55)',
              background: 'transparent', border: 'none', cursor: 'pointer',
              fontFamily: 'inherit', fontSize: '.85rem',
            }}>
            {t.label}
          </button>
        ))}
      </div>
      <div role="tabpanel" style={{ paddingTop: '1.25rem' }}>
        {tabs[active].content}
      </div>
    </div>
  );
}

:LiHandPointer: 使い方

対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。

:LiAlertCircle: 注意事項

  • 依存パッケージを忘れず追加