Component

Settings Tabs

Full settings page with a vertical nav tab list and content panels including general, account, appearance, integrations, and a danger zone.

  • Component
  • Tailwind
  • HTML
  • MIT

Preview

Live component

Interactive preview
Open preview
9:41 100%
devsnips.dev/library/tailwind/components/tabs/settings-tabs/
fluid · no fixed width 100%
No dependencies Production-ready

Install

Add to your project

terminal
npx devsnips add Tailwind/Components/Tabs/settings-tabs
registry path: Tailwind/Components/Tabs/settings-tabs

Source

Implementation

code.html
<div class="w-full max-w-5xl bg-white rounded-2xl border border-gray-200 shadow-sm overflow-hidden">
  <div class="grid md:grid-cols-[240px_1fr]">
    <!-- Sidebar nav -->
    <nav class="border-b md:border-b-0 md:border-r border-gray-100 p-4" aria-label="Settings">
      <h2 class="px-2 pb-2 text-xs font-semibold uppercase tracking-wider text-gray-400">Settings</h2>
      <div role="tablist" aria-orientation="vertical" aria-label="Settings panels" class="flex md:flex-col gap-1 overflow-x-auto md:overflow-visible">
        <button role="tab" id="stab-general" aria-selected="true" aria-controls="spanel-general" tabindex="0"
          class="flex items-center gap-2.5 w-full text-left px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 whitespace-nowrap md:whitespace-normal">
          <svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
          General
        </button>
        <button role="tab" id="stab-account" aria-selected="false" aria-controls="spanel-account" tabindex="-1"
          class="flex items-center gap-2.5 w-full text-left px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 rounded-lg transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 whitespace-nowrap md:whitespace-normal">
          <svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/></svg>
          Account
        </button>
        <button role="tab" id="stab-appearance" aria-selected="false" aria-controls="spanel-appearance" tabindex="-1"
          class="flex items-center gap-2.5 w-full text-left px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 rounded-lg transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 whitespace-nowrap md:whitespace-normal">
          <svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01"/></svg>
          Appearance
        </button>
        <button role="tab" id="stab-integrations" aria-selected="false" aria-controls="spanel-integrations" tabindex="-1"
          class="flex items-center gap-2.5 w-full text-left px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 rounded-lg transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 whitespace-nowrap md:whitespace-normal">
          <svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/></svg>
          Integrations
        </button>
        <button role="tab" id="stab-danger" aria-selected="false" aria-controls="spanel-danger" tabindex="-1"
          class="flex items-center gap-2.5 w-full text-left px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 rounded-lg transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 whitespace-nowrap md:whitespace-normal">
          <svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
          Danger zone
        </button>
      </div>
    </nav>

    <!-- Panels -->
    <div class="p-6 md:p-8">
      <div role="tabpanel" id="spanel-general" aria-labelledby="stab-general" tabindex="0" class="focus:outline-none">
        <h3 class="text-lg font-semibold text-gray-900">General</h3>
        <p class="text-sm text-gray-500">Workspace defaults and locale.</p>
        <div class="mt-5 space-y-4 max-w-md">
          <div><label class="block text-sm font-medium text-gray-700 mb-1" for="s-workspace">Workspace name</label><input id="s-workspace" type="text" value="Acme Inc." class="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500/30 outline-none"></div>
          <div><label class="block text-sm font-medium text-gray-700 mb-1" for="s-locale">Locale</label><select id="s-locale" class="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500/30 outline-none"><option>English (US)</option><option>Français</option><option>Deutsch</option></select></div>
        </div>
        <div class="mt-6"><button class="text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg px-4 py-2 transition-colors">Save changes</button></div>
      </div>
      <div role="tabpanel" id="spanel-account" aria-labelledby="stab-account" tabindex="0" class="hidden focus:outline-none">
        <h3 class="text-lg font-semibold text-gray-900">Account</h3>
        <p class="text-sm text-gray-500">Manage your personal information.</p>
        <div class="mt-5 flex items-center gap-4">
          <img src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=64&h=64&fit=crop&crop=faces" alt="" class="w-16 h-16 rounded-full object-cover">
          <button class="text-sm font-medium text-blue-600 hover:text-blue-700">Change avatar</button>
        </div>
      </div>
      <div role="tabpanel" id="spanel-appearance" aria-labelledby="stab-appearance" tabindex="0" class="hidden focus:outline-none">
        <h3 class="text-lg font-semibold text-gray-900">Appearance</h3>
        <p class="text-sm text-gray-500">Choose how DevSnips looks to you.</p>
        <div class="mt-5 grid grid-cols-3 gap-3 max-w-md">
          <button class="rounded-xl border-2 border-blue-500 p-3 text-left"><div class="h-10 rounded bg-white border border-gray-200"></div><p class="mt-2 text-xs font-medium text-gray-900">Light</p></button>
          <button class="rounded-xl border border-gray-200 p-3 text-left"><div class="h-10 rounded bg-slate-900"></div><p class="mt-2 text-xs font-medium text-gray-700">Dark</p></button>
          <button class="rounded-xl border border-gray-200 p-3 text-left"><div class="h-10 rounded bg-gradient-to-br from-white to-slate-900"></div><p class="mt-2 text-xs font-medium text-gray-700">System</p></button>
        </div>
      </div>
      <div role="tabpanel" id="spanel-integrations" aria-labelledby="stab-integrations" tabindex="0" class="hidden focus:outline-none">
        <h3 class="text-lg font-semibold text-gray-900">Integrations</h3>
        <p class="text-sm text-gray-500">Connect your tools.</p>
        <div class="mt-5 space-y-3 max-w-md">
          <div class="flex items-center justify-between rounded-lg border border-gray-200 p-3"><span class="text-sm font-medium text-gray-900">Slack</span><button class="text-xs font-medium text-blue-600 hover:text-blue-700">Connect</button></div>
          <div class="flex items-center justify-between rounded-lg border border-gray-200 p-3"><span class="text-sm font-medium text-gray-900">GitHub</span><span class="text-xs font-medium text-emerald-600">Connected</span></div>
        </div>
      </div>
      <div role="tabpanel" id="spanel-danger" aria-labelledby="stab-danger" tabindex="0" class="hidden focus:outline-none">
        <h3 class="text-lg font-semibold text-gray-900">Danger zone</h3>
        <p class="text-sm text-gray-500">Irreversible actions.</p>
        <div class="mt-5 rounded-lg border border-rose-200 bg-rose-50 p-4 max-w-md">
          <div class="flex items-center justify-between"><div><p class="text-sm font-medium text-rose-900">Delete workspace</p><p class="text-xs text-rose-700">All data will be permanently removed.</p></div><button class="text-sm font-medium text-white bg-rose-600 hover:bg-rose-700 rounded-lg px-3 py-2">Delete</button></div>
        </div>
      </div>
    </div>
  </div>
</div>

<script>
  (function () {
    var list = document.querySelector('[aria-label="Settings panels"]');
    if (!list) return;
    var tabs = Array.prototype.slice.call(list.querySelectorAll('[role="tab"]'));
    var panels = tabs.map(function (t) { return document.getElementById(t.getAttribute('aria-controls')); });
    function activate(tab) {
      tabs.forEach(function (t) {
        var s = t === tab;
        t.setAttribute('aria-selected', s); t.tabIndex = s ? 0 : -1;
        t.classList.toggle('text-white', s); t.classList.toggle('bg-gray-900', s);
        t.classList.toggle('text-gray-700', !s); t.classList.toggle('hover:bg-gray-100', !s);
      });
      panels.forEach(function (p) { if (p) p.classList.add('hidden'); });
      var panel = document.getElementById(tab.getAttribute('aria-controls'));
      if (panel) panel.classList.remove('hidden');
    }
    tabs.forEach(function (tab, i) {
      tab.addEventListener('click', function () { activate(tab); });
      tab.addEventListener('keydown', function (e) {
        var idx = null;
        if (e.key === 'ArrowDown') idx = (i + 1) % tabs.length;
        if (e.key === 'ArrowUp') idx = (i - 1 + tabs.length) % tabs.length;
        if (idx !== null) { e.preventDefault(); tabs[idx].focus(); activate(tabs[idx]); }
      });
    });
  })();
</script>
109 lines UTF-8 · LF · Spaces: 2

AI-ready

Available to your agent.

This component is reachable through the DevSnips CLI, MCP server and Skills integrations — one registry, one resource path.

Resource path

devsnips://components/tabs/settings-tabs

Continue browsing

View all