Skip to content

Commit

Permalink
Add ability to choose way to load tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
lex111 committed Nov 9, 2020
1 parent 251c060 commit 47d91f6
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 11 deletions.
4 changes: 2 additions & 2 deletions packages/docusaurus-theme-classic/src/theme/TabItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import React from 'react';
import type {Props} from '@theme/TabItem';

function TabItem({children, hidden}: Props): JSX.Element {
function TabItem({children, hidden, className}: Props): JSX.Element {
return (
<div role="tabpanel" {...{hidden}}>
<div role="tabpanel" {...{hidden, className}}>
{children}
</div>
);
Expand Down
36 changes: 27 additions & 9 deletions packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@ const keys = {
};

function Tabs(props: Props): JSX.Element {
const {block, children, defaultValue, values, groupId, className} = props;
const {
lazy,
block,
children,
defaultValue,
values,
groupId,
className,
} = props;
const {tabGroupChoices, setTabGroupChoices} = useUserPreferencesContext();
const [selectedValue, setSelectedValue] = useState(defaultValue);

Expand Down Expand Up @@ -109,14 +117,24 @@ function Tabs(props: Props): JSX.Element {
</li>
))}
</ul>
<div className="margin-vert--md">
{children.map((tabItem, i) =>
cloneElement(tabItem, {
key: i,
hidden: tabItem.props.value !== selectedValue,
}),
)}
</div>

{lazy ? (
cloneElement(
children.filter(
(tabItem) => tabItem.props.value === selectedValue,
)[0],
{className: 'margin-vert--md'},
)
) : (
<div className="margin-vert--md">
{children.map((tabItem, i) =>
cloneElement(tabItem, {
key: i,
hidden: tabItem.props.value !== selectedValue,
}),
)}
</div>
)}
</div>
);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/docusaurus-theme-classic/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ declare module '@theme/TabItem' {
readonly children: ReactNode;
readonly value: string;
readonly hidden: boolean;
readonly className: string;
};

const TabItem: () => JSX.Element;
Expand All @@ -389,6 +390,7 @@ declare module '@theme/Tabs' {
import type {Props as TabItemProps} from '@theme/TabItem';

export type Props = {
readonly lazy?: boolean;
readonly block?: boolean;
readonly children: readonly ReactElement<TabItemProps>[];
readonly defaultValue?: string;
Expand Down
6 changes: 6 additions & 0 deletions website/docs/markdown-features.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,12 @@ And you will get the following:
<TabItem value="banana">This is a banana 🍌</TabItem>
</Tabs>

:::info

By default, tabs are rendered eagerly, but it is possible to load them lazily by passing the `lazy` prop to the `Tabs` component.

:::

### Syncing tab choices

You may want choices of the same kind of tabs to sync with each other. For example, you might want to provide different instructions for users on Windows vs users on macOS, and you want to changing all OS-specific instructions tabs in one click. To achieve that, you can give all related tabs the same `groupId` prop. Note that doing this will persist the choice in `localStorage` and all `<Tab>` instances with the same `groupId` will update automatically when the value of one of them is changed. Not that `groupID` are globally-namespaced.
Expand Down

0 comments on commit 47d91f6

Please sign in to comment.