logo

Aki UI

アキ ウイ

Expandable Tabs

エクスパンダブルタブ

A row of icons where only the selected one says its name. The label animates its own width up from zero so the row reflows around it instead of jumping, and the pill behind travels between tabs on a shared layout id rather than fading in place. Icons keep their accessible names whether or not the label is showing. Built with Framer Motion shared layout and Tailwind CSS.

Installation

Install the following dependencies:1

npm install framer-motion

Copy and paste the following code into a new component file:2

"use client"

import { AnimatePresence, motion } from "framer-motion"
import { useState, type ReactNode } from "react"

export type ExpandableTab = {
id: string,
label: string,
icon: ReactNode
}

How to use it3

"use client"

import { ExpandableTabs } from "@/components/ui/expandable-tabs"

const tabs = [
{ id: "home", label: "Home", icon: <HomeIcon /> },
{ id: "search", label: "Search", icon: <SearchIcon /> },
]

export default function Page() {

Props

ExpandableTabs

NameDefaultDescription
tabs

ExpandableTab[]

The tabs to render

defaultIdfirst tab

string

Which tab starts selected

onChange

(id: string) => void

Called with the id of the tab selected

darkfalse

boolean

Render the dark palette

ExpandableTab (type)

NameDefaultDescription
id

string

Stable key for the tab

label

string

Name revealed when selected, also the accessible label

icon

ReactNode

Icon always visible