-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
Addon-docs: Add opt-in table of contents #23142
Merged
Merged
Changes from 12 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
4a49745
Docs: Add opt-in Table of Contents
shilman bd15fe7
make changes
ndelangen c7ec591
Merge branch 'next' into shilman/toc-proof-of-concept
ndelangen 0546301
Fix build
shilman 71e9188
Merge branch 'next' into shilman/toc-proof-of-concept
ndelangen d07ad74
Merge branch 'next' into shilman/toc-proof-of-concept
shilman 3d69572
Merge branch 'next' into shilman/toc-proof-of-concept
shilman fe01f47
Addon-docs: Fix bug where TOC is always showing
shilman 43a5531
Remove spurious console.log
shilman e09f436
Addon-docs: Add TOC stories
shilman 90c9929
Addon-docs: Fix TOC context bug
shilman 76ca248
Cleanup
shilman 995732e
Update code/ui/blocks/src/components/TableOfContents.tsx
shilman d8c8eb8
Merge branch 'next' into shilman/toc-proof-of-concept
shilman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { global as globalThis } from '@storybook/global'; | ||
|
||
export default { | ||
component: globalThis.Components.Button, | ||
tags: ['autodocs'], | ||
parameters: { | ||
chromatic: { disable: true }, | ||
docs: { toc: {} }, | ||
}, | ||
}; | ||
|
||
export const One = { | ||
args: { label: 'One' }, | ||
}; | ||
|
||
export const Two = { | ||
args: { label: 'Two' }, | ||
}; | ||
|
||
export const Three = { | ||
args: { label: 'Two' }, | ||
}; |
14 changes: 14 additions & 0 deletions
14
code/addons/docs/template/stories/toc/custom-selector.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { global as globalThis } from '@storybook/global'; | ||
import { One, Two, Three } from './basic.stories'; | ||
|
||
export default { | ||
component: globalThis.Components.Button, | ||
tags: ['autodocs'], | ||
parameters: { | ||
chromatic: { disable: true }, | ||
// Select all the headings in the document | ||
docs: { toc: { headingSelector: 'h1, h2, h3' } }, | ||
}, | ||
}; | ||
|
||
export { One, Two, Three }; |
14 changes: 14 additions & 0 deletions
14
code/addons/docs/template/stories/toc/custom-title.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { global as globalThis } from '@storybook/global'; | ||
import { One, Two, Three } from './basic.stories'; | ||
|
||
export default { | ||
component: globalThis.Components.Button, | ||
tags: ['autodocs'], | ||
parameters: { | ||
chromatic: { disable: true }, | ||
// Custom title label | ||
docs: { toc: { title: 'Contents' } }, | ||
}, | ||
}; | ||
|
||
export { One, Two, Three }; |
14 changes: 14 additions & 0 deletions
14
code/addons/docs/template/stories/toc/ignore-selector.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { global as globalThis } from '@storybook/global'; | ||
import { One, Two, Three } from './basic.stories'; | ||
|
||
export default { | ||
component: globalThis.Components.Button, | ||
tags: ['autodocs'], | ||
parameters: { | ||
chromatic: { disable: true }, | ||
// Skip the first story in the TOC | ||
docs: { toc: { ignoreSelector: '#one' } }, | ||
}, | ||
}; | ||
|
||
export { One, Two, Three }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
import React, { useEffect } from 'react'; | ||
import type { FC, ReactElement } from 'react'; | ||
import { styled } from '@storybook/theming'; | ||
import tocbot from 'tocbot'; | ||
|
||
export interface TocParameters { | ||
/** CSS selector for the container to search for headings. */ | ||
contentsSelector?: string; | ||
|
||
/** | ||
* When true, hide the TOC. We still show the empty container | ||
* (as opposed to showing nothing at all) because it affects the | ||
* page layout and we want to preserve the layout across pages. | ||
*/ | ||
disable?: boolean; | ||
|
||
/** CSS selector to match headings to list in the TOC. */ | ||
headingSelector?: string; | ||
|
||
/** Headings that match the ignoreSelector will be skipped. */ | ||
ignoreSelector?: string; | ||
|
||
/** Custom title ReactElement or string to display above the TOC. */ | ||
title?: ReactElement | string | null; | ||
|
||
/** | ||
* TocBot options, not guaranteed to be available in future versions. | ||
* See [tocbot docs](https://tscanlin.github.io/tocbot/#usage) | ||
shilman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
unsafeTocbotOptions?: tocbot.IStaticOptions; | ||
} | ||
|
||
const Wrapper = styled.div(({ theme }) => ({ | ||
width: '10rem', | ||
|
||
'@media (max-width: 768px)': { | ||
display: 'none', | ||
}, | ||
})); | ||
|
||
const Content = styled.div(({ theme }) => ({ | ||
position: 'fixed', | ||
top: 0, | ||
width: '10rem', | ||
paddingTop: '4rem', | ||
|
||
fontFamily: theme.typography.fonts.base, | ||
fontSize: theme.typography.size.s2, | ||
|
||
WebkitFontSmoothing: 'antialiased', | ||
MozOsxFontSmoothing: 'grayscale', | ||
WebkitTapHighlightColor: 'rgba(0, 0, 0, 0)', | ||
WebkitOverflowScrolling: 'touch', | ||
|
||
'& *': { | ||
boxSizing: 'border-box', | ||
}, | ||
|
||
'& > .toc-wrapper > .toc-list': { | ||
paddingLeft: 0, | ||
borderLeft: `solid 2px ${theme.color.mediumlight}`, | ||
|
||
'.toc-list': { | ||
paddingLeft: 0, | ||
borderLeft: `solid 2px ${theme.color.mediumlight}`, | ||
|
||
'.toc-list': { | ||
paddingLeft: 0, | ||
borderLeft: `solid 2px ${theme.color.mediumlight}`, | ||
}, | ||
}, | ||
}, | ||
'& .toc-list-item': { | ||
position: 'relative', | ||
listStyleType: 'none', | ||
marginLeft: 20, | ||
paddingTop: 3, | ||
paddingBottom: 3, | ||
}, | ||
'& .toc-list-item::before': { | ||
content: '""', | ||
position: 'absolute', | ||
height: '100%', | ||
top: 0, | ||
left: 0, | ||
transform: `translateX(calc(-2px - 20px))`, | ||
borderLeft: `solid 2px ${theme.color.mediumdark}`, | ||
opacity: 0, | ||
transition: 'opacity 0.2s', | ||
}, | ||
'& .toc-list-item.is-active-li::before': { | ||
opacity: 1, | ||
}, | ||
'& .toc-list-item > a': { | ||
color: theme.color.defaultText, | ||
textDecoration: 'none', | ||
}, | ||
'& .toc-list-item.is-active-li > a': { | ||
fontWeight: 600, | ||
color: theme.color.secondary, | ||
textDecoration: 'none', | ||
}, | ||
})); | ||
|
||
const Heading = styled.p(({ theme }) => ({ | ||
fontWeight: 600, | ||
fontSize: '0.875em', | ||
color: theme.textColor, | ||
textTransform: 'uppercase', | ||
marginBottom: 10, | ||
})); | ||
|
||
type TableOfContentsProps = React.PropsWithChildren< | ||
TocParameters & { | ||
className?: string; | ||
} | ||
>; | ||
|
||
const OptionalTitle: FC<{ title: TableOfContentsProps['title'] }> = ({ title }) => { | ||
if (title === null) { | ||
return null; | ||
} | ||
if (typeof title === 'string') { | ||
return <Heading>{title}</Heading>; | ||
} | ||
return title; | ||
}; | ||
|
||
export const TableOfContents = ({ | ||
title, | ||
disable, | ||
headingSelector, | ||
contentsSelector, | ||
ignoreSelector, | ||
unsafeTocbotOptions, | ||
}: TableOfContentsProps) => { | ||
useEffect(() => { | ||
const configuration = { | ||
tocSelector: '.toc-wrapper', | ||
contentSelector: contentsSelector ?? '.sbdocs-content', | ||
headingSelector: headingSelector ?? 'h3', | ||
ignoreSelector: ignoreSelector ?? '.skip-toc', | ||
headingsOffset: 40, | ||
scrollSmoothOffset: -40, | ||
/** | ||
* Ignore headings that did not | ||
* come from the main markdown code. | ||
*/ | ||
// ignoreSelector: ':not(.sbdocs), .hide-from-toc', | ||
orderedList: false, | ||
/** | ||
* Prevent default linking behavior, | ||
* leaving only the smooth scrolling. | ||
*/ | ||
onClick: () => false, | ||
...unsafeTocbotOptions, | ||
}; | ||
|
||
/** | ||
* Wait for the DOM to be ready. | ||
*/ | ||
const timeout = setTimeout(() => tocbot.init(configuration), 100); | ||
return () => { | ||
clearTimeout(timeout); | ||
tocbot.destroy(); | ||
}; | ||
}, [disable]); | ||
|
||
return ( | ||
<> | ||
<Wrapper> | ||
{!disable ? ( | ||
<Content> | ||
<OptionalTitle title={title || null} /> | ||
<div className="toc-wrapper" /> | ||
</Content> | ||
) : null} | ||
</Wrapper> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand this correctly, that if a user has
toc
in project annotations, and for a single component havedisable
, we always show the TOC container (but sometimes empty), so that layout won't shift?But if the user doesn't have
toc
set global, but just for a single story, then we'll have layout shifts?I think this is a good solution, I just want to make sure my understanding is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe so. This is @cdedreuille 's comment I believe.