documentation-site/components/table-of-contents.jsx (90 lines of code) (raw):

/* Copyright (c) Uber Technologies, Inc. This source code is licensed under the MIT license found in the LICENSE file in the root directory of this source tree. */ import * as React from "react"; import { useStyletron } from "baseui"; import slugify from "../helpers/slugify"; function getPadding(componentType) { const multiplier = Number(componentType.replace("h", "")); return `${multiplier * 8}px`; } const TableOfContents = (props) => { const [css, theme] = useStyletron(); const TOC = []; const content = props.content[0].props.children; content && content.forEach && content.forEach((element) => { if ( element.props && element.props.name && element.props.name.startsWith("h") && element.props.children && element.props.children.toLowerCase ) { TOC.push({ name: element.props.children, anchor: `#${slugify(element.props.children)}`, component: element.props.name, }); } if (element.props && element.props.title) { TOC.push({ name: element.props.title, anchor: `#${slugify(element.props.title)}`, component: "h3", }); } if (element.props && element.props.api && element.props.heading) { TOC.push({ name: element.props.heading, anchor: `#${slugify(element.props.heading)}`, component: "h3", }); } }); if (TOC.length === 1) { return null; } return ( <ul className={css({ [theme.direction === "rtl" ? "borderRight" : "borderLeft"]: `1px solid ${theme.colors.mono400}`, listStyle: "none", [theme.direction === "rtl" ? "marginRight" : "marginLeft"]: theme.sizing.scale400, paddingLeft: 0, paddingRight: 0, // to make sure we align vertically with the edit on github button marginTop: "-10px", marginBottom: 0, // set predictable width to avoid page relayout when table of content changes width: "160px", position: "fixed", top: "100px", })} > {TOC.map((header) => ( <li key={header.name} className={css({ ...theme.typography.font100, [theme.direction === "rtl" ? "paddingRight" : "paddingLeft"]: getPadding(header.component), })} > <a className={css({ color: theme.colors.contentSecondary })} href={header.anchor} > {header.name} </a> </li> ))} </ul> ); }; export default TableOfContents;