Skip to content

Commit ec6d664

Browse files
CopilotOmgRod
andcommitted
Fix TabPanels: refactor to Tab children pattern for rich content support
Co-authored-by: OmgRod <89850217+OmgRod@users.noreply.github.com> Agent-Logs-Url: https://github.com/OmgRod/MiniWiki/sessions/bede1e37-f2b4-4f66-875b-e24030741638
1 parent 41510fd commit ec6d664

3 files changed

Lines changed: 48 additions & 34 deletions

File tree

‎components/Tabs.js‎

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
import { useState } from 'react';
1+
import React, { useState } from 'react';
22

3-
export function TabPanels({ tabs = [] }) {
4-
const [active, setActive] = useState(tabs[0]?.id);
5-
const activeTab = tabs.find((tab) => tab.id === active) || tabs[0];
3+
export function Tab({ children }) {
4+
return children;
5+
}
6+
7+
export function TabPanels({ children }) {
8+
const tabs = React.Children.toArray(children).filter(
9+
(child) => React.isValidElement(child) && child.props.title != null,
10+
);
11+
const [activeIndex, setActiveIndex] = useState(0);
612

713
if (!tabs.length) {
814
return null;
@@ -11,22 +17,24 @@ export function TabPanels({ tabs = [] }) {
1117
return (
1218
<div className="my-6 overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900">
1319
<div className="flex flex-wrap gap-1 border-b border-slate-200 p-2 dark:border-slate-800">
14-
{tabs.map((tab) => (
20+
{tabs.map((tab, index) => (
1521
<button
16-
key={tab.id}
22+
key={tab.props.title}
1723
type="button"
18-
onClick={() => setActive(tab.id)}
24+
onClick={() => setActiveIndex(index)}
1925
className={`rounded-md px-3 py-1.5 text-sm transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 ${
20-
tab.id === active
26+
index === activeIndex
2127
? 'bg-blue-600 text-white'
2228
: 'text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-slate-800'
2329
}`}
2430
>
25-
{tab.label}
31+
{tab.props.title}
2632
</button>
2733
))}
2834
</div>
29-
<div className="p-4 text-sm leading-6 text-slate-700 dark:text-slate-200">{activeTab?.content}</div>
35+
<div className="p-4 text-sm leading-6 text-slate-700 dark:text-slate-200">
36+
{tabs[activeIndex]?.props.children}
37+
</div>
3038
</div>
3139
);
3240
}

‎components/mdx-components.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import PresetSearch from './PresetSearch';
2020
import SearchBar from './SearchBar';
2121
import Sidebar from './Sidebar';
2222
import Steps from './Steps';
23-
import Tabs, { TabPanels } from './Tabs';
23+
import Tabs, { Tab, TabPanels } from './Tabs';
2424
import Table, { Caption, TBody, TD, TH, THead, TR } from './WikiTable';
2525

2626
const mdxComponents = {
@@ -54,6 +54,7 @@ const mdxComponents = {
5454
THead,
5555
TR,
5656
Tabs,
57+
Tab,
5758
TabPanels,
5859
caption: (props) => <Caption {...props} />,
5960
pre: (props) => <CodeBlock {...props} />,

‎content/guides/components/tabs.mdx‎

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,43 @@ description: Tabbed content UI for grouped alternatives.
55

66
# Tabs
77

8-
`Tabs` exports `TabPanels` for rendering tab groups.
8+
`TabPanels` renders a tab group. Each `Tab` child represents one tab, with its `title` displayed as the tab button label. Tab content can be any HTML or Markdown.
99

10-
## Props (`TabPanels`)
10+
## Props
11+
12+
### `TabPanels`
1113

1214
| Prop | Type | Required | Description |
1315
| --- | --- | --- | --- |
14-
| `tabs` | `Array<{ id: string, label: string, content: ReactNode }>` | Yes | Tab definitions. |
16+
| `children` | `Tab` elements | Yes | One or more `Tab` components. |
17+
18+
### `Tab`
19+
20+
| Prop | Type | Required | Description |
21+
| --- | --- | --- | --- |
22+
| `title` | `string` | Yes | Label shown on the tab button. |
23+
| `children` | `ReactNode` | Yes | Content rendered when the tab is active. |
1524

1625
## Live examples
1726

18-
<TabPanels
19-
tabs={[
20-
{ id: 'js', label: 'JavaScript', content: 'npm run dev' },
21-
{ id: 'pnpm', label: 'pnpm', content: 'pnpm dev' },
22-
{ id: 'bun', label: 'bun', content: 'bun run dev' },
23-
]}
24-
/>
25-
26-
<TabPanels
27-
tabs={[
28-
{ id: 'docs', label: 'Docs', content: 'Markdown + MDX content pages.' },
29-
{ id: 'config', label: 'Config', content: 'JSON files for navigation and layout behavior.' },
30-
]}
31-
/>
27+
<TabPanels>
28+
<Tab title="JavaScript">npm run dev</Tab>
29+
<Tab title="pnpm">pnpm dev</Tab>
30+
<Tab title="Bun">bun run dev</Tab>
31+
</TabPanels>
32+
33+
<TabPanels>
34+
<Tab title="Docs">Markdown + MDX content pages.</Tab>
35+
<Tab title="Config">JSON files for navigation and layout behavior.</Tab>
36+
</TabPanels>
3237

3338
## Code
3439

3540
```mdx
36-
<TabPanels
37-
tabs={[
38-
{ id: 'js', label: 'JavaScript', content: 'npm run dev' },
39-
{ id: 'pnpm', label: 'pnpm', content: 'pnpm dev' },
40-
]}
41-
/>
41+
<TabPanels>
42+
<Tab title="JavaScript">npm run dev</Tab>
43+
<Tab title="pnpm">pnpm dev</Tab>
44+
<Tab title="Bun">bun run dev</Tab>
45+
</TabPanels>
4246
```
47+

0 commit comments

Comments
 (0)