Tabs
Tabbed panels in <mo-tabs> with roving-tabindex arrows and hash deep-linking. Panels toggle via hidden.
INSTALL
1pnpm dlx @sayagodev/mo add tabsOr import the files from the package (no copy):
1import "@sayagodev/mo/css/tabs.css";2import "@sayagodev/mo/js/tabs.js";
EXAMPLES
Make changes to your account here. Arrow keys move between tabs.
Change your password here. Panels toggle through the hidden attribute.
Configure how you get notified.
1<mo-tabs>2 <div role="tablist">3 <button role="tab">Account</button>4 <button role="tab">Password</button>5 <button role="tab">Notifications</button>6 </div>7 <div role="tabpanel">8 <p class="text-light">9 Make changes to your account here. Arrow keys move between tabs.10 </p>11 </div>12 <div role="tabpanel">13 <p class="text-light">14 Change your password here. Panels toggle through the hidden attribute.15 </p>16 </div>17 <div role="tabpanel">18 <p class="text-light">19 Configure how you get notified.20 </p>21 </div>22</mo-tabs>23
Rendered output of your component.
Source code of your component.
1<mo-tabs>2 <div role="tablist">3 <button role="tab">4 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">5 <rect width="20" height="14" x="2" y="3" rx="2"></rect>6 <line x1="2" x2="22" y1="9" y2="9"></line>7 </svg>8 Preview9 </button>10 <button role="tab">11 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">12 <polyline points="16 18 22 12 16 6"></polyline>13 <polyline points="8 6 2 12 8 18"></polyline>14 </svg>15 Code16 </button>17 </div>18 <div role="tabpanel">19 <p class="text-light">Rendered output of your component.</p>20 </div>21 <div role="tabpanel">22 <p class="text-light">Source code of your component.</p>23 </div>24</mo-tabs>25
Welcome home. The disabled tab cannot be activated.
1<mo-tabs>2 <div role="tablist">3 <button role="tab">Home</button>4 <button role="tab" disabled>Disabled</button>5 </div>6 <div role="tabpanel">7 <p class="text-light">Welcome home. The disabled tab cannot be activated.</p>8 </div>9</mo-tabs>10
Overview panel. data-variant="line" swaps the pill for a 2px underline.
Analytics panel. Arrow keys still move between tabs.
Reports panel.
1<mo-tabs>2 <div role="tablist" data-variant="line">3 <button role="tab">Overview</button>4 <button role="tab">Analytics</button>5 <button role="tab">Reports</button>6 </div>7 <div role="tabpanel">8 <p class="text-light">9 Overview panel. data-variant="line" swaps the pill for a 2px underline.10 </p>11 </div>12 <div role="tabpanel">13 <p class="text-light">14 Analytics panel. Arrow keys still move between tabs.15 </p>16 </div>17 <div role="tabpanel">18 <p class="text-light">19 Reports panel.20 </p>21 </div>22</mo-tabs>23
Make changes to your account here. ArrowUp and ArrowDown move between tabs.
Change your password here. Panels toggle through the hidden attribute.
Configure how you get notified.
1<mo-tabs data-orientation="vertical">2 <div role="tablist">3 <button role="tab">Account</button>4 <button role="tab">Password</button>5 <button role="tab">Notifications</button>6 </div>7 <div role="tabpanel">8 <p class="text-light">9 Make changes to your account here. ArrowUp and ArrowDown move between tabs.10 </p>11 </div>12 <div role="tabpanel">13 <p class="text-light">14 Change your password here. Panels toggle through the hidden attribute.15 </p>16 </div>17 <div role="tabpanel">18 <p class="text-light">19 Configure how you get notified.20 </p>21 </div>22</mo-tabs>23
USAGE
1<mo-tabs>2 <div role="tablist">3 <button role="tab" aria-selected="true">One</button>4 <button role="tab" aria-selected="false">Two</button>5 </div>6 <div role="tabpanel">…</div>7 <div role="tabpanel" hidden>…</div>8</mo-tabs>
API
FILES
src/css/tabs.csssrc/js/tabs.jsmo add tabsTHEMING · PLAYGROUND
This is the exact component from the examples above, wearing a completely different theme. Edit the tokens and --mo-* hooks in the editor — autocomplete knows them all — and the preview obeys in real time. Your CSS always wins.
--background--foreground--input--muted--muted-foreground--radius--ring--mo-tabs-active-bg--mo-tabs-height--mo-tabs-list-bg--mo-tabs-radius--mo-tabs-vertical-gapPreview
Your CSS
Try it: type --mo- for the component hooks, or edit any value — the preview obeys in real time.