From fa3926e2a156668d3700404e7bee25b915b51dbd Mon Sep 17 00:00:00 2001 From: Drylozu <35281350+Drylozu@users.noreply.github.com> Date: Fri, 17 Dec 2021 12:23:50 -0500 Subject: [PATCH] feat(theme-classic): allow passing additional attributes to tab headings (#6082) Co-authored-by: Joshua Chen --- .../src/theme-classic.d.ts | 7 +- .../src/theme/Tabs/index.tsx | 24 ++++-- .../markdown-features-tabs-styles.module.css | 27 +++++++ .../markdown-features-tabs.mdx | 79 ++++++++++++++++++- .../BrowserWindow/styles.module.css | 1 + 5 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 website/docs/guides/markdown-features/markdown-features-tabs-styles.module.css diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 9f578f949e..e2b95689a6 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -516,6 +516,7 @@ declare module '@theme/TabItem' { readonly label?: string; readonly hidden?: boolean; readonly className?: string; + readonly attributes?: Record; } const TabItem: (props: Props) => JSX.Element; @@ -531,7 +532,11 @@ declare module '@theme/Tabs' { readonly block?: boolean; readonly children: readonly ReactElement[]; readonly defaultValue?: string | null; - readonly values?: readonly {value: string; label?: string}[]; + readonly values?: readonly { + value: string; + label?: string; + attributes?: Record; + }[]; readonly groupId?: string; readonly className?: string; } diff --git a/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx b/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx index 343874ac09..18f46a20f1 100644 --- a/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx @@ -51,7 +51,13 @@ function TabsComponent(props: Props): JSX.Element { ); }); const values = - valuesProp ?? children.map(({props: {value, label}}) => ({value, label})); + valuesProp ?? + // We only pick keys that we recognize. MDX would inject some keys by default + children.map(({props: {value, label, attributes}}) => ({ + value, + label, + attributes, + })); const dup = duplicates(values, (a, b) => a.value === b.value); if (dup.length > 0) { throw new Error( @@ -144,19 +150,25 @@ function TabsComponent(props: Props): JSX.Element { }, className, )}> - {values.map(({value, label}) => ( + {values.map(({value, label, attributes}) => (
  • tabRefs.push(tabControl)} onKeyDown={handleKeydown} onFocus={handleTabChange} - onClick={handleTabChange}> + onClick={handleTabChange} + {...attributes} + className={clsx( + 'tabs__item', + styles.tabItem, + attributes?.className as string, + { + 'tabs__item--active': selectedValue === value, + }, + )}> {label ?? value}
  • ))} diff --git a/website/docs/guides/markdown-features/markdown-features-tabs-styles.module.css b/website/docs/guides/markdown-features/markdown-features-tabs-styles.module.css new file mode 100644 index 0000000000..9e75491e62 --- /dev/null +++ b/website/docs/guides/markdown-features/markdown-features-tabs-styles.module.css @@ -0,0 +1,27 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.red { + color: red; +} +.red[aria-selected="true"] { + border-bottom-color: red; +} + +.orange { + color: orange; +} +.orange[aria-selected="true"] { + border-bottom-color: orange; +} + +.yellow { + color: yellow; +} +.yellow[aria-selected="true"] { + border-bottom-color: yellow; +} diff --git a/website/docs/guides/markdown-features/markdown-features-tabs.mdx b/website/docs/guides/markdown-features/markdown-features-tabs.mdx index 5fc9d5acd1..031264a85a 100644 --- a/website/docs/guides/markdown-features/markdown-features-tabs.mdx +++ b/website/docs/guides/markdown-features/markdown-features-tabs.mdx @@ -9,6 +9,7 @@ slug: /markdown-features/tabs import BrowserWindow from '@site/src/components/BrowserWindow'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +import styles from './markdown-features-tabs-styles.module.css'; ``` Docusaurus provides `` components that you can use thanks to [MDX](./markdown-features-react.mdx): @@ -229,15 +230,12 @@ Tab choices with different `groupId`s will not interfere with each other: You might want to customize the appearance of certain set of tabs. To do that you can pass the string in `className` prop and the specified CSS class will be added to the `Tabs` component: ```jsx -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - // highlight-next-line This is an apple 🍎 This is an orange 🍊 This is a banana 🍌 -; + ``` ```mdx-code-block @@ -249,3 +247,76 @@ import TabItem from '@theme/TabItem'; ``` + +### Customizing tab headings + +You can also customize each tab heading independently by using the `attributes` field. The extra props can be passed to the headings either through the `values` prop in `Tabs`, or props of each `TabItem`β€”in the same way as you declare `label`. + + +```jsx title="some-doc.mdx" +import styles from './styles.module.css'; + + + + This is an apple 🍎 + + + This is an orange 🍊 + + + This is a banana 🍌 + + +``` + + +```css title="styles.module.css" +.red { + color: red; +} +.red[aria-selected='true'] { + border-bottom-color: red; +} + +.orange { + color: orange; +} +.orange[aria-selected='true'] { + border-bottom-color: orange; +} + +.yellow { + color: yellow; +} +.yellow[aria-selected='true'] { + border-bottom-color: yellow; +} +``` + +```mdx-code-block + + + + This is an apple 🍎 + + + This is an orange 🍊 + + + This is a banana 🍌 + + + +``` + +:::tip + +`className` would be merged with other default class names. You may also use a custom `data-value` field (`{'data-value': 'apple'}`) paired with CSS attribute selectors: + +```css title="styles.module.css" +li[role='tab'][data-value='apple'] { + color: red; +} +``` + +::: diff --git a/website/src/components/BrowserWindow/styles.module.css b/website/src/components/BrowserWindow/styles.module.css index c1aa5645fc..e746e7d889 100644 --- a/website/src/components/BrowserWindow/styles.module.css +++ b/website/src/components/BrowserWindow/styles.module.css @@ -10,6 +10,7 @@ border-top-left-radius: var(--ifm-global-radius); border-top-right-radius: var(--ifm-global-radius); box-shadow: var(--ifm-global-shadow-lw); + margin-bottom: var(--ifm-leading); } .browserWindowHeader {