Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add markdown tabs #2914

Merged
merged 3 commits into from
Oct 12, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions content/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ Data Version Control, or DVC, is a data and ML
advantage of the existing engineering toolset that you're already familiar with
(Git, CI/CD, etc.).

<toggle>

<tab title="Tab 1">

```dvc
$ git status
Changes to be committed:
new file: .dvc/.gitignore
new file: .dvc/config
...
$ git commit -m "Initialize DVC"
```

</tab>

<tab title="Tab 2">

```dvc
$ dvc init
```

</tab>

<tab title="Tab 3">

```dvc
$ dvc exp run --set-param featurize.max_features=3000
```

</tab>

</toggle>

<cards>

<card href="/doc/start" heading="Get Started">
Expand All @@ -25,6 +58,41 @@ advantage of the existing engineering toolset that you're already familiar with

</cards>

<toggle>

<tab title="Tab 1">

- nd ligula lacus sed mi. Proin hendrerit molestie est vitae tempor. Nulla
ultrices, tortor sed convallis molestie, sed sapien varius pharetra ut id
justo.
- Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Phasellus ac aliquet risus. Vestibulum ut felis nec erat
accumsan
- risus mauris porta ipsum, vitae suscipit eros felis at risus. Duis in nunc et
quam mattis porta. Fusce eget fermentum velit. Nullam id lectus

</tab>

<tab title="Tab 2">

- Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Phasellus ac aliquet risus. Vestibulum ut felis nec erat
accumsan

</tab>

<tab title="Tab 3">

- Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Phasellus ac aliquet risus. Vestibulum ut felis nec erat
accumsan
- risus mauris porta ipsum, vitae suscipit eros felis at risus. Duis in nunc et
quam mattis porta. Fusce eget fermentum velit. Nullam id lectus

</tab>

</toggle>

✅ Please join our [community](/community) or use the [support](/support)
channels if you have any questions or need specific help. We are very responsive
⚡.
Expand All @@ -34,3 +102,19 @@ us a ⭐ if you like the project!

✅ Contribute to DVC [on GitHub](https://github.com/iterative/dvc) or help us
improve this [documentation](https://github.com/iterative/dvc.org) 🙏.

<toggle>

<tab title="Tab 4">
nd ligula lacus sed mi. Proin hendrerit molestie est vitae tempor. Nulla ultrices, tortor sed convallis molestie, risus mauris porta ipsum, vitae suscipit eros felis at risus. Duis in nunc et quam mattis porta. Fusce eget fermentum velit. Nullam id lectus sed sapien varius pharetra ut id justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus ac aliquet risus. Vestibulum ut felis nec erat accumsan
</tab>

<tab title="Tab 5">
da quis vel est. Sed at varius lectus, ac tincidunt diam. Donec eu convallis sem, ac scelerisque risus. Aliquam eu turpis tristique, fermentum justo in, ultricies arcu. Nulla mi quam, ultricies sed tincidunt sed, tristique at quam. Etiam tellus enim, ullamcorper a velit et, euismod lobortis diam. Maecenas commodo auctor metus efficitur ornare. Quisque ut est fermentum, viverra augue a, dignissim tellus. Sed et vulputate lorem, sollicitudin tempus ante. Aenean sed nunc vel metus euismo
</tab>

<tab title="Tab 6">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce leo nisi, scelerisque non molestie dapibus, rhoncus eu lorem. Aenean luctus diam mauris, non aliquam urna interdum ac. Suspendisse pellentesque neque ipsum, id pharetra nisi tincidunt eget. Duis auctor enim nisl, vel vestibulum mi feugiat quis. Nulla volutpat turpis non gravida dictum. Suspendisse venenatis lacus vitae nisl bibendum rhoncus. Fusce justo sapien, rhoncus vitae congue quis, porttitor at dui. Aenean rhoncus egestas enim, at accumsan enim molestie quis. Etiam aliquam tincidunt sem vel tempor. Integer sollicitudin dictum maximus. Vestibulum ornare leo quis tortor bibendum, sed fri
</tab>

</toggle>
48 changes: 48 additions & 0 deletions src/components/Documentation/Markdown/ToggleProvider/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { createContext, useState } from 'react'

interface ITogglesData {
[key: string]: { texts: string[]; checkedInd: number }
}

interface ITogglesContext {
addNewToggle?: (id: string, texts: string[]) => void
updateToggleInd?: (id: string, newInd: number) => void
togglesData?: ITogglesData
}

export const TogglesContext = createContext<ITogglesContext>({})

export const TogglesProvider: React.FC = ({ children }) => {
const [togglesData, setTogglesData] = useState({})

const addNewToggle = (id: string, texts: string[]): void => {
const togglesDataCopy: ITogglesData = { ...togglesData }
togglesDataCopy[id] = { texts, checkedInd: 0 }
setTogglesData(togglesDataCopy)
}

const updateToggleInd = (id: string, newInd: number): void => {
const togglesDataCopy: ITogglesData = { ...togglesData }
const selectedTabText = togglesDataCopy[id].texts[newInd]
togglesDataCopy[id] = { ...togglesDataCopy[id], checkedInd: newInd }

for (const [toggleId, { texts }] of Object.entries(togglesDataCopy)) {
if (texts.includes(selectedTabText)) {
togglesDataCopy[toggleId] = {
...togglesDataCopy[toggleId],
checkedInd: togglesDataCopy[id].texts.indexOf(selectedTabText)
}
}
}

setTogglesData(togglesDataCopy)
}

return (
<TogglesContext.Provider
value={{ addNewToggle, updateToggleInd, togglesData }}
>
{children}
</TogglesContext.Provider>
)
}
94 changes: 91 additions & 3 deletions src/components/Documentation/Markdown/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import React, { ReactNode, ReactElement } from 'react'
import React, {
useEffect,
useState,
ReactNode,
ReactElement,
useContext
} from 'react'
import { nanoid } from 'nanoid'
import rehypeReact from 'rehype-react'
import Collapsible from 'react-collapsible'

Expand All @@ -7,6 +14,7 @@ import Link from '../../Link'
import Tooltip from './Tooltip'

import styles from './styles.module.css'
import { TogglesContext, TogglesProvider } from './ToggleProvider'

const Details: React.FC<{
children: Array<{ props: { children: ReactNode } } | string>
Expand Down Expand Up @@ -95,6 +103,84 @@ const Card: React.FC<{
)
}

const ToggleTab: React.FC<{
id: string
title: string
ind: number
onChange: () => void
checked: boolean
}> = ({ children, id, checked, ind, onChange, title }) => {
const inputId = `tab-${id}-${ind}`

return (
<>
<input
id={inputId}
type="radio"
name={`toggle-${id}`}
onChange={onChange}
checked={checked}
/>
<label className={styles.tabHeading} htmlFor={inputId}>
{title}
</label>
{children}
</>
)
}

const Toggle: React.FC<{
children: Array<{ props: { title: string } } | string>
}> = ({ children }) => {
const [toggleId, setToggleId] = useState('')
const {
addNewToggle = (): null => null,
updateToggleInd = (): null => null,
togglesData = {}
} = useContext(TogglesContext)
const tabs: Array<{ props: { title: string } } | string> = children.filter(
child => child !== '\n'
)
const tabsTitles = tabs.map(tab =>
typeof tab === 'object' ? tab.props.title : ''
)

useEffect(() => {
if (toggleId === '') {
const newId = nanoid()
addNewToggle(newId, tabsTitles)
setToggleId(newId)
}

if (toggleId && !togglesData[toggleId]) {
addNewToggle(toggleId, tabsTitles)
}
}, [togglesData])

return (
<div className={styles.toggle}>
{tabs.map((tab, i) => (
<ToggleTab
ind={i}
key={i}
title={tabsTitles[i]}
id={toggleId}
checked={
i === (togglesData[toggleId] ? togglesData[toggleId].checkedInd : 0)
}
onChange={(): void => updateToggleInd(toggleId, i)}
>
{tab}
</ToggleTab>
))}
</div>
)
}

const Tab: React.FC = ({ children }) => (
<div className={styles.tab}>{children}</div>
)

const renderAst = new rehypeReact({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
createElement: React.createElement as any,
Expand All @@ -104,7 +190,9 @@ const renderAst = new rehypeReact({
abbr: Abbr,
a: Link,
card: Card,
cards: Cards
cards: Cards,
toggle: Toggle,
tab: Tab
}
}).Compiler

Expand All @@ -125,7 +213,7 @@ const Markdown: React.FC<IMarkdownProps> = ({
}) => {
return (
<Main prev={prev} next={next} tutorials={tutorials} githubLink={githubLink}>
{renderAst(htmlAst)}
<TogglesProvider>{renderAst(htmlAst)}</TogglesProvider>
</Main>
)
}
Expand Down
50 changes: 50 additions & 0 deletions src/components/Documentation/Markdown/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,53 @@ a.card {
background-color: var(--color-light-blue);
}
}

.toggle {
display: flex;
flex-wrap: wrap;

input {
height: 0;
opacity: 0;
position: absolute;
width: 0;
overflow: hidden;
}

input:checked + label {
color: var(--color-azure);
border-color: var(--color-azure);
}

input:checked + label + .tab {
height: initial;
opacity: initial;
position: static;
width: 100%;
overflow: visible;
}

.tabHeading {
padding: 12px 16px 10px;
background-color: transparent;
border: none;
border-bottom: 2px solid transparent;
font-weight: bold;
font-size: 16px;
font-family: var(--font-brandon);
order: -1;

&:hover {
cursor: pointer;
}
}
}

.tab {
margin: 10px 0 0;
height: 0;
opacity: 0;
position: absolute;
overflow: hidden;
width: 0;
}