ComponentsNavigation
Tide Tabs
Tabs over a shallow channel whose indicator is a pool of water that flows to the chosen tab, stretching on the way and gathering when it arrives.
Forecast
"use client";
import { TideTab, TideTabList, TideTabPanel, TideTabs } from "@/components/miyuki-ui/tide-tabs";
const forecast = [
{
id: "today",
label: "Today",
text: "Snow until early afternoon, then clearing from the west.",
stats: [
["High", "−4°"],
["Low", "−11°"],
["New snow", "18 cm"],
],
},
{
id: "tomorrow",
label: "Tomorrow",
text: "Clear and cold. First lift at 08:00, wind below 20 km/h all day.",
stats: [
["High", "−6°"],
["Low", "−14°"],
["New snow", "0 cm"],
],
},
{
id: "week",
label: "Week",
text: "Two more storms, on Wednesday night and again on Saturday.",
stats: [
["Storms", "2"],
["Coldest", "−17°"],
["New snow", "46 cm"],
],
},
{
id: "season",
label: "Season",
text: "Deeper than usual for mid February at the top station.",
stats: [
["Base", "284 cm"],
["Average", "+31 cm"],
["Powder days", "23"],
],
},
];
export default function TideTabsDemo() {
return (
<TideTabs className="w-full max-w-md" defaultSelectedKey="today">
<TideTabList aria-label="Hakuba forecast">
{forecast.map((day) => (
<TideTab key={day.id} id={day.id}>
{day.label}
</TideTab>
))}
</TideTabList>
{forecast.map((day) => (
<TideTabPanel key={day.id} id={day.id} className="min-h-28">
<p className="text-muted-foreground">{day.text}</p>
<dl className="mt-4 grid grid-cols-3 gap-4">
{day.stats.map(([term, value]) => (
<div key={term}>
<dt className="text-xs text-muted-foreground">{term}</dt>
<dd className="mt-1 font-display text-2xl leading-none font-semibold tracking-[-0.02em] tabular-nums">
{value}
</dd>
</div>
))}
</dl>
</TideTabPanel>
))}
</TideTabs>
);
}Vertical
"use client";
import { TideTab, TideTabList, TideTabPanel, TideTabs } from "@/components/miyuki-ui/tide-tabs";
const lifts = [
{
id: "gondola",
label: "Gondola",
status: "Running",
text: "Every 40 seconds from the base station. Last ride up at 16:30.",
},
{
id: "chair-4",
label: "Chair 4",
status: "Wind hold",
text: "Stopped for gusts above 60 km/h at the top station. Next check at 11:00.",
},
{
id: "summit",
label: "Summit T-bar",
status: "Closed",
text: "Closed for avalanche control this morning. Patrol expects to open it after lunch.",
},
];
export default function TideTabsVerticalDemo() {
return (
<TideTabs orientation="vertical" className="w-full max-w-lg">
<TideTabList aria-label="Lifts">
{lifts.map((lift) => (
<TideTab key={lift.id} id={lift.id}>
{lift.label}
</TideTab>
))}
</TideTabList>
{lifts.map((lift) => (
<TideTabPanel key={lift.id} id={lift.id} className="pt-1">
<p className="font-medium">{lift.status}</p>
<p className="mt-1 text-muted-foreground">{lift.text}</p>
</TideTabPanel>
))}
</TideTabs>
);
}Install
npx shadcn@latest add @miyuki-ui/tide-tabsThis needs the @miyuki-ui registry in your components.json. See Using the shadcn CLI.
Props
TideTabs
Prop
Type
TideTabList
Prop
Type
TideTab
Prop
Type
TideTabPanel
Prop
Type