add tabs component

This commit is contained in:
Jeff Escalante 2020-05-08 16:42:08 -04:00
parent 2859a4dc39
commit a58ac39562
10 changed files with 121 additions and 3 deletions

View File

@ -141,6 +141,7 @@ There are several custom markdown plugins that are available by default that enh
There are also a couple of custom components that can be used within markdown, see the list below for documentation and details: There are also a couple of custom components that can be used within markdown, see the list below for documentation and details:
- [Enterprise Alert](components/enterprise-alert/README.md) - [Enterprise Alert](components/enterprise-alert/README.md)
- [Tabs](components/tabs/README.md)
### Redirects ### Redirects

View File

@ -0,0 +1,49 @@
# Tabs Component
> An MDX-compatible Tabs component
This React component renders tabbed content. [Example](https://p176.p0.n0.cdn.getcloudapp.com/items/E0ubRrlq/Screen%20Recording%202020-05-08%20at%2004.40%20PM.gif?v=a1f576d2c207f4312ca14adbce8a53ac)
## Usage
- Use the `<Tabs>` tag in your markdown file to begin a tabbed content section.
- Use the `<Tab>` tag with a `heading` prop to separate your markdown
### Important
A line must be skipped between the `<Tab>` and your markdown (for both above and below said markdown). [This is a limitation of MDX also pointed out by the Docusaurus folks 🔗 ](https://v2.docusaurus.io/docs/markdown-features/#multi-language-support-code-blocks). There is work currently happening with the mdx parser to eliminate this issue.
### Example
```jsx
<Tabs>
<Tab heading="CLI command">
{/* Intentionally skipped line.. */}
### Content
{/* Intentionally skipped line.. */}
</Tab>
<Tab heading="API call using cURL">### Content</Tab>
</Tabs>
```
### Component Props
`<Tabs>` can be provided any arbitrary `children` so long as the `heading` prop is present the React or HTML tag used to wrap markdown, that said, we provide the `<Tab>` component to separate your tab content without rendering extra, unnecessary markup.
This works:
```jsx
<Tabs>
<Tab heading="CLI command">### Content</Tab>
....
</Tabs>
```
This _does not_ work, as the `<Tab>` element is missing a `heading` prop:
```jsx
<Tabs>
<Tab>### Content</Tab>
....
</Tabs>
```

View File

@ -0,0 +1,20 @@
import ReactTabs from '@hashicorp/react-tabs'
export function Tabs({ children }) {
if (!Array.isArray(children))
throw new Error('Multiple <Tab> elements required')
return (
<ReactTabs
items={children.map((Block) => ({
heading: Block.props.heading,
// eslint-disable-next-line react/display-name
tabChildren: () => Block,
}))}
/>
)
}
export function Tab({ children }) {
return <>{children}</>
}

View File

@ -0,0 +1,8 @@
/* This is a CSS overwrite on top of the existing component styles to accommodate the Learn layout */
.g-tabs {
& .g-grid-container,
& > .g-grid-container {
padding-left: 0;
padding-right: 0;
}
}

View File

@ -3,10 +3,11 @@ import order from '../data/api-navigation.js'
import { frontMatter as data } from '../pages/api-docs/**/*.mdx' import { frontMatter as data } from '../pages/api-docs/**/*.mdx'
import { MDXProvider } from '@mdx-js/react' import { MDXProvider } from '@mdx-js/react'
import EnterpriseAlert from '../components/enterprise-alert' import EnterpriseAlert from '../components/enterprise-alert'
import { Tabs, Tab } from '../components/tabs'
import Head from 'next/head' import Head from 'next/head'
import Link from 'next/link' import Link from 'next/link'
const DEFAULT_COMPONENTS = { EnterpriseAlert } const DEFAULT_COMPONENTS = { EnterpriseAlert, Tabs, Tab }
function ApiDocsLayoutWrapper(pageMeta) { function ApiDocsLayoutWrapper(pageMeta) {
function ApiDocsLayout(props) { function ApiDocsLayout(props) {

View File

@ -3,10 +3,11 @@ import order from '../data/docs-navigation.js'
import { frontMatter as data } from '../pages/docs/**/*.mdx' import { frontMatter as data } from '../pages/docs/**/*.mdx'
import { MDXProvider } from '@mdx-js/react' import { MDXProvider } from '@mdx-js/react'
import EnterpriseAlert from '../components/enterprise-alert' import EnterpriseAlert from '../components/enterprise-alert'
import { Tabs, Tab } from '../components/tabs'
import Head from 'next/head' import Head from 'next/head'
import Link from 'next/link' import Link from 'next/link'
const DEFAULT_COMPONENTS = { EnterpriseAlert } const DEFAULT_COMPONENTS = { EnterpriseAlert, Tabs, Tab }
function DocsLayoutWrapper(pageMeta) { function DocsLayoutWrapper(pageMeta) {
function DocsLayout(props) { function DocsLayout(props) {

View File

@ -3,10 +3,11 @@ import order from '../data/intro-navigation.js'
import { frontMatter as data } from '../pages/intro/**/*.mdx' import { frontMatter as data } from '../pages/intro/**/*.mdx'
import { MDXProvider } from '@mdx-js/react' import { MDXProvider } from '@mdx-js/react'
import EnterpriseAlert from '../components/enterprise-alert' import EnterpriseAlert from '../components/enterprise-alert'
import { Tabs, Tab } from '../components/tabs'
import Head from 'next/head' import Head from 'next/head'
import Link from 'next/link' import Link from 'next/link'
const DEFAULT_COMPONENTS = { EnterpriseAlert } const DEFAULT_COMPONENTS = { EnterpriseAlert, Tabs, Tab }
function IntroLayoutWrapper(pageMeta) { function IntroLayoutWrapper(pageMeta) {
function IntroLayout(props) { function IntroLayout(props) {

View File

@ -1447,6 +1447,40 @@
} }
} }
}, },
"@hashicorp/react-tabs": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@hashicorp/react-tabs/-/react-tabs-0.4.0.tgz",
"integrity": "sha512-KSkd3akWC9843ybMEw1Ahga/yCfiG2BWLvjb1Hl1qVWrYIHPAYQ+W+mLvMRKJrGPlCMCTqpiNR5bK8iBvcDC/Q==",
"requires": {
"@hashicorp/react-global-styles": "^4.4.0",
"@hashicorp/react-inline-svg": "^1.0.0",
"@tippy.js/react": "^3.1.1"
},
"dependencies": {
"@hashicorp/react-global-styles": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@hashicorp/react-global-styles/-/react-global-styles-4.4.0.tgz",
"integrity": "sha512-lv6XR2plm2m3+qO6VE+RYquTzOODIt3mQ/1fBT1bn7wsR0qxFiuryW4JfsF94oCGk++LkDkRt/8V742HiT+fHw=="
},
"@tippy.js/react": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@tippy.js/react/-/react-3.1.1.tgz",
"integrity": "sha512-KF45vW/jKh/nBXk/2zzTFslv/T46zOMkIoDJ56ymZ+M00yHttk58J5wZ29oqGqDIUnobWSZD+cFpbR4u/UUvgw==",
"requires": {
"prop-types": "^15.6.2",
"tippy.js": "^5.1.1"
}
},
"tippy.js": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-5.2.1.tgz",
"integrity": "sha512-66UT6JRVn3dXNCORE+0UvUK3JZqV/VhLlU6HTDm3FmrweUUFUxUGvT8tUQ7ycMp+uhuLAwQw6dBabyC+iKf/MA==",
"requires": {
"popper.js": "^1.16.0"
}
}
}
},
"@hashicorp/react-text-and-content": { "@hashicorp/react-text-and-content": {
"version": "4.0.9", "version": "4.0.9",
"resolved": "https://registry.npmjs.org/@hashicorp/react-text-and-content/-/react-text-and-content-4.0.9.tgz", "resolved": "https://registry.npmjs.org/@hashicorp/react-text-and-content/-/react-text-and-content-4.0.9.tgz",

View File

@ -31,6 +31,7 @@
"@hashicorp/react-product-downloader": "^3.1.2", "@hashicorp/react-product-downloader": "^3.1.2",
"@hashicorp/react-section-header": "^2.0.0", "@hashicorp/react-section-header": "^2.0.0",
"@hashicorp/react-subnav": "^3.1.1", "@hashicorp/react-subnav": "^3.1.1",
"@hashicorp/react-tabs": "^0.4.0",
"@hashicorp/react-text-and-content": "^4.0.9", "@hashicorp/react-text-and-content": "^4.0.9",
"@hashicorp/react-text-split": "^0.2.6", "@hashicorp/react-text-split": "^0.2.6",
"@hashicorp/react-text-split-with-code": "0.0.9", "@hashicorp/react-text-split-with-code": "0.0.9",

View File

@ -34,12 +34,14 @@
@import '~@hashicorp/react-section-header/dist/style.css'; @import '~@hashicorp/react-section-header/dist/style.css';
@import '~@hashicorp/react-call-to-action/dist/style.css'; @import '~@hashicorp/react-call-to-action/dist/style.css';
@import '~@hashicorp/react-case-study-slider/dist/style.css'; @import '~@hashicorp/react-case-study-slider/dist/style.css';
@import '~@hashicorp/react-tabs/dist/style.css';
@import '~@hashicorp/react-code-block/dist/style.css'; @import '~@hashicorp/react-code-block/dist/style.css';
@import '~@hashicorp/react-alert-banner/dist/style.css'; @import '~@hashicorp/react-alert-banner/dist/style.css';
/* Local Components */ /* Local Components */
@import '../components/footer/style.css'; @import '../components/footer/style.css';
@import '../components/before-after/style.css'; @import '../components/before-after/style.css';
@import '../components/tabs/style.css';
/* Local Pages */ /* Local Pages */
@import './downloads/style.css'; @import './downloads/style.css';