Component

Underline Tabs

Modern developer documentation tabs with a moving underline indicator, version badge, and embedded code samples. Built for docs sites and API references.

  • Component
  • Tailwind
  • HTML
  • MIT

Preview

Live component

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

Install

Add to your project

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

Source

Implementation

code.html
<div class="w-full max-w-4xl bg-white rounded-xl border border-gray-200 overflow-hidden">
  <div class="flex items-center justify-between px-6 pt-5">
    <div role="tablist" aria-label="Developer docs" class="flex items-center gap-6">
      <button role="tab" id="utab-quickstart" aria-selected="true" aria-controls="upanel-quickstart" tabindex="0"
        class="relative pb-3 text-sm font-medium text-gray-900 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 rounded">
        Quickstart
        <span class="absolute inset-x-0 -bottom-px h-0.5 bg-violet-600 rounded-full" aria-hidden="true"></span>
      </button>
      <button role="tab" id="utab-guides" aria-selected="false" aria-controls="upanel-guides" tabindex="-1"
        class="relative pb-3 text-sm font-medium text-gray-500 hover:text-gray-900 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 rounded">
        Guides
      </button>
      <button role="tab" id="utab-reference" aria-selected="false" aria-controls="upanel-reference" tabindex="-1"
        class="relative pb-3 text-sm font-medium text-gray-500 hover:text-gray-900 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 rounded">
        API Reference
      </button>
      <button role="tab" id="utab-changelog" aria-selected="false" aria-controls="upanel-changelog" tabindex="-1"
        class="relative pb-3 text-sm font-medium text-gray-500 hover:text-gray-900 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 rounded">
        Changelog
      </button>
    </div>
    <span class="hidden sm:inline-flex items-center gap-1.5 text-xs font-medium text-violet-700 bg-violet-50 border border-violet-100 px-2.5 py-1 rounded-full">
      <span class="w-1.5 h-1.5 rounded-full bg-violet-500"></span> v3.2.0
    </span>
  </div>
  <div class="border-b border-gray-200"></div>

  <div role="tabpanel" id="upanel-quickstart" aria-labelledby="utab-quickstart" tabindex="0" class="p-6 focus:outline-none">
    <p class="text-sm text-gray-600">Install the SDK and make your first request in under a minute.</p>
    <pre class="mt-4 rounded-lg bg-gray-900 text-gray-100 text-xs leading-6 p-4 overflow-x-auto"><code><span class="text-gray-400"># install</span>
npm install @devsnips/sdk

<span class="text-gray-400"># run</span>
npx devsnips init</code></pre>
  </div>
  <div role="tabpanel" id="upanel-guides" aria-labelledby="utab-guides" tabindex="0" class="p-6 hidden focus:outline-none">
    <p class="text-sm text-gray-600">Step-by-step guides for authentication, webhooks, and pagination.</p>
    <ul class="mt-4 space-y-2 text-sm text-gray-700">
      <li class="flex items-center gap-2"><span class="text-violet-500">→</span> Authenticate requests with API keys</li>
      <li class="flex items-center gap-2"><span class="text-violet-500">→</span> Handle webhooks reliably</li>
      <li class="flex items-center gap-2"><span class="text-violet-500">→</span> Paginate large result sets</li>
    </ul>
  </div>
  <div role="tabpanel" id="upanel-reference" aria-labelledby="utab-reference" tabindex="0" class="p-6 hidden focus:outline-none">
    <p class="text-sm text-gray-600">Complete reference for every endpoint, parameter, and response code.</p>
    <pre class="mt-4 rounded-lg bg-gray-900 text-gray-100 text-xs leading-6 p-4 overflow-x-auto"><code>POST /v1/resources
Authorization: Bearer <span class="text-emerald-300">sk_...</span></code></pre>
  </div>
  <div role="tabpanel" id="upanel-changelog" aria-labelledby="utab-changelog" tabindex="0" class="p-6 hidden focus:outline-none">
    <p class="text-sm text-gray-600">What changed in the latest releases.</p>
    <div class="mt-4 space-y-3 text-sm">
      <div class="flex gap-3"><span class="font-mono text-violet-600">3.2.0</span><span class="text-gray-600">Added streaming responses and retry support.</span></div>
      <div class="flex gap-3"><span class="font-mono text-gray-400">3.1.0</span><span class="text-gray-600">Introduced typed webhook events.</span></div>
    </div>
  </div>
</div>

<script>
  (function () {
    var list = document.querySelector('[aria-label="Developer docs"]');
    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-gray-900', s); t.classList.toggle('text-gray-500', !s);
        var ind = t.querySelector('span.absolute');
        if (s && !ind) {
          var bar = document.createElement('span');
          bar.setAttribute('aria-hidden', 'true');
          bar.className = 'absolute inset-x-0 -bottom-px h-0.5 bg-violet-600 rounded-full';
          t.appendChild(bar);
        } else if (!s && ind) { ind.remove(); }
      });
      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 === 'ArrowRight') idx = (i + 1) % tabs.length;
        if (e.key === 'ArrowLeft') idx = (i - 1 + tabs.length) % tabs.length;
        if (e.key === 'Home') idx = 0;
        if (e.key === 'End') idx = tabs.length - 1;
        if (idx !== null) { e.preventDefault(); tabs[idx].focus(); activate(tabs[idx]); }
      });
    });
  })();
</script>
93 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/underline-tabs

Continue browsing

View all