website: add sidebar structure

This commit is contained in:
Yangshun
2022-04-06 09:27:36 +08:00
parent 6e47fceef4
commit 7eccc0db17
63 changed files with 3892 additions and 153 deletions

View File

@ -56,7 +56,32 @@ html[data-theme='dark'] {
}
.markdown h1 {
margin-top: 1rem;
font-size: 2.25em;
margin-top: 1em;
}
.markdown h2 {
font-size: 1.5em;
margin-top: 2em;
margin-bottom: 1em;
}
.markdown h3 {
font-size: 1.25em;
font-weight: 600;
margin-top: 1.6em;
margin-bottom: 0.6em;
}
.markdown blockquote {
border-left-color: var(--ifm-color-emphasis-200);
border-left-width: 0.5rem;
color: var(--ifm-color-emphasis-600);
}
.markdown ul blockquote {
font-size: 0.9em;
margin-top: 0.5em;
}
@media screen and (max-width: 767px) {
@ -163,4 +188,3 @@ html[data-theme='dark'] .navbar-icon-telegram:before {
height: 28px;
width: 24px;
}

View File

@ -11,7 +11,7 @@ export default [
wasn't sure what to expect and where to start. This handbook together
with the{' '}
<a
href="https://frontendinterviewhandbook.com"
href="https://www.frontendinterviewhandbook.com"
target="_blank"
rel="noreferrer noopener">
Front End Interview Handbook

View File

@ -23,7 +23,7 @@ const FEATURES = [
interview experience needed.
</>
),
link: '/introduction',
link: '/software-engineering-interview-guide/',
},
{
title: <>📝 Curated practice questions</>,
@ -36,17 +36,17 @@ const FEATURES = [
to tell you which the best questions are.
</>
),
link: '/best-practice-questions',
link: '/coding-interview-study-plan/',
},
{
title: <>📋 Interview cheatsheet</>,
title: <>📋 Interview best practices</>,
description: (
<>
Straight-to-the-point Do's and Don'ts during an interview. The battle is
already half won.
</>
),
link: '/cheatsheet',
link: '/coding-interview-best-practices/',
},
{
title: <>💁 Practical algorithm tips</>,
@ -56,7 +56,7 @@ const FEATURES = [
cases to look out for.
</>
),
link: '/algorithms/introduction',
link: '/algorithms/study-cheatsheet/',
},
{
title: <>💬 Behavioral questions</>,
@ -66,7 +66,7 @@ const FEATURES = [
prepare your answers ahead of time.
</>
),
link: '/behavioral-questions',
link: '/behavioral-interview-questions/',
},
{
title: <>🧪 Tested and proven</>,
@ -145,7 +145,7 @@ function HeroSection() {
<div className={styles.buttons}>
<Link
className={classnames('button button--primary button--lg')}
to="/introduction">
to="/software-engineering-interview-guide/">
Start reading now&nbsp;&nbsp;
</Link>
</div>
@ -324,7 +324,7 @@ function HowToUseSection() {
<>Software engineering specific resume content</>,
<>Optimizing and and testing your resume</>,
]}
ctaLink="/resume/guide"
ctaLink="/resume/"
/>
</div>
<div
@ -342,7 +342,7 @@ function HowToUseSection() {
<>System design interview preparation</>,
<>Behavioral interview preparation</>,
]}
ctaLink="/interview-formats"
ctaLink="/coding-interview-prep/"
/>
</div>
<div
@ -358,7 +358,7 @@ function HowToUseSection() {
<>Negotiation strategies for software engineers</>,
<>Guide on how compensation works for software engineers</>,
]}
ctaLink="/understanding-compensation"
ctaLink="/understanding-compensation/"
/>
</div>
<div
@ -818,7 +818,7 @@ function PreFooterSection() {
</p>
<Link
className={classnames('button button--primary button--lg')}
to="/introduction">
to="/software-engineering-interview-guide/">
Start reading now&nbsp;&nbsp;
</Link>
</div>

View File

@ -107,7 +107,7 @@ function DocItemContent(props) {
</div>
</div>
{renderTocDesktop && (
<div className="col col--4">
<div className="col col--3">
<TOC
toc={DocContent.toc}
minHeadingLevel={tocMinHeadingLevel}

View File

@ -0,0 +1,265 @@
/**
* 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.
*/
import React, {useEffect, useMemo} from 'react';
import clsx from 'clsx';
import {
isActiveSidebarItem,
usePrevious,
Collapsible,
useCollapsible,
findFirstCategoryLink,
ThemeClassNames,
useThemeConfig,
useDocSidebarItemsExpandedState,
isSamePath,
} from '@docusaurus/theme-common';
import Link from '@docusaurus/Link';
import isInternalUrl from '@docusaurus/isInternalUrl';
import {translate} from '@docusaurus/Translate';
import IconExternalLink from '@theme/IconExternalLink';
import DocSidebarItems from '@theme/DocSidebarItems';
import styles from './styles.module.css';
import useIsBrowser from '@docusaurus/useIsBrowser';
export default function DocSidebarItem({item, ...props}) {
switch (item.type) {
case 'category':
return <DocSidebarItemCategory item={item} {...props} />;
case 'html':
return <DocSidebarItemHtml item={item} {...props} />;
case 'link':
default:
return <DocSidebarItemLink item={item} {...props} />;
}
} // If we navigate to a category and it becomes active, it should automatically
// expand itself
function useAutoExpandActiveCategory({isActive, collapsed, setCollapsed}) {
const wasActive = usePrevious(isActive);
useEffect(() => {
const justBecameActive = isActive && !wasActive;
if (justBecameActive && collapsed) {
setCollapsed(false);
}
}, [isActive, wasActive, collapsed, setCollapsed]);
}
/**
* When a collapsible category has no link, we still link it to its first child
* during SSR as a temporary fallback. This allows to be able to navigate inside
* the category even when JS fails to load, is delayed or simply disabled
* React hydration becomes an optional progressive enhancement
* see https://github.com/facebookincubator/infima/issues/36#issuecomment-772543188
* see https://github.com/facebook/docusaurus/issues/3030
*/
function useCategoryHrefWithSSRFallback(item) {
const isBrowser = useIsBrowser();
return useMemo(() => {
if (item.href) {
return item.href;
} // In these cases, it's not necessary to render a fallback
// We skip the "findFirstCategoryLink" computation
if (isBrowser || !item.collapsible) {
return undefined;
}
return findFirstCategoryLink(item);
}, [item, isBrowser]);
}
function DocSidebarItemCategory({
item,
onItemClick,
activePath,
level,
index,
...props
}) {
const {items, label, collapsible, className, href} = item;
const hrefWithSSRFallback = useCategoryHrefWithSSRFallback(item);
const isActive = isActiveSidebarItem(item, activePath);
const isCurrentPage = isSamePath(href, activePath);
const {collapsed, setCollapsed} = useCollapsible({
// active categories are always initialized as expanded
// the default (item.collapsed) is only used for non-active categories
initialState: () => {
if (!collapsible) {
return false;
}
return isActive ? false : item.collapsed;
},
});
useAutoExpandActiveCategory({
isActive,
collapsed,
setCollapsed,
});
const {expandedItem, setExpandedItem} = useDocSidebarItemsExpandedState();
function updateCollapsed(toCollapsed = !collapsed) {
setExpandedItem(toCollapsed ? null : index);
setCollapsed(toCollapsed);
}
const {autoCollapseSidebarCategories} = useThemeConfig();
useEffect(() => {
if (
collapsible &&
expandedItem &&
expandedItem !== index &&
autoCollapseSidebarCategories
) {
setCollapsed(true);
}
}, [
collapsible,
expandedItem,
index,
setCollapsed,
autoCollapseSidebarCategories,
]);
return (
<li
className={clsx(
ThemeClassNames.docs.docSidebarItemCategory,
ThemeClassNames.docs.docSidebarItemCategoryLevel(level),
'menu__list-item',
{
'menu__list-item--collapsed': collapsed,
},
className,
)}>
<div
className={clsx('menu__list-item-collapsible', {
'menu__list-item-collapsible--active': isCurrentPage,
})}>
<Link
className={clsx('menu__link', {
'menu__link--sublist': collapsible,
'menu__link--sublist-caret': !href && collapsible,
'menu__link--active': isActive,
})}
onClick={
collapsible
? (e) => {
onItemClick?.(item);
if (href) {
updateCollapsed(false);
} else {
e.preventDefault();
updateCollapsed();
}
}
: () => {
onItemClick?.(item);
}
}
aria-current={isCurrentPage ? 'page' : undefined}
aria-expanded={collapsible ? !collapsed : undefined}
href={collapsible ? hrefWithSSRFallback ?? '#' : hrefWithSSRFallback}
{...props}>
{label}
</Link>
{href && collapsible && (
<button
aria-label={translate(
{
id: 'theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel',
message: "Toggle the collapsible sidebar category '{label}'",
description:
'The ARIA label to toggle the collapsible sidebar category',
},
{
label,
},
)}
type="button"
className="clean-btn menu__caret"
onClick={(e) => {
e.preventDefault();
updateCollapsed();
}}
/>
)}
</div>
<Collapsible lazy as="ul" className="menu__list" collapsed={collapsed}>
<DocSidebarItems
items={items}
tabIndex={collapsed ? -1 : 0}
onItemClick={onItemClick}
activePath={activePath}
level={level + 1}
/>
</Collapsible>
</li>
);
}
function DocSidebarItemHtml({item, level, index}) {
const {value, defaultStyle, className} = item;
return (
<li
className={clsx(
ThemeClassNames.docs.docSidebarItemLink,
ThemeClassNames.docs.docSidebarItemLinkLevel(level),
defaultStyle && `${styles.menuHtmlItem} menu__list-item`,
className,
)}
key={index} // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{
__html: value,
}}
/>
);
}
function DocSidebarItemLink({
item,
onItemClick,
activePath,
level,
index,
...props
}) {
const {href, label, className} = item;
const isActive = isActiveSidebarItem(item, activePath);
const isInternalLink = isInternalUrl(href);
return (
<li
className={clsx(
ThemeClassNames.docs.docSidebarItemLink,
ThemeClassNames.docs.docSidebarItemLinkLevel(level),
'menu__list-item',
className,
)}
key={label}>
<Link
className={clsx(
'menu__link',
!isInternalLink && styles.menuExternalLink,
{
'menu__link--active': isActive,
},
)}
aria-current={isActive ? 'page' : undefined}
to={href}
{...(isInternalLink && {
onClick: onItemClick ? () => onItemClick(item) : undefined,
})}
{...props}>
{label}
{!isInternalLink && <IconExternalLink />}
</Link>
</li>
);
}

View File

@ -0,0 +1,17 @@
/**
* 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.
*/
@media (min-width: 997px) {
.menuHtmlItem {
padding: var(--ifm-menu-link-padding-vertical)
var(--ifm-menu-link-padding-horizontal);
}
}
.menuExternalLink {
align-items: center;
}

View File

@ -14,7 +14,14 @@ function TOC({className, ...props}) {
<div className="margin--md">
<SidebarAd position="table_of_contents" />
</div>
<h3 className="padding-left--md padding-top--md margin-bottom--none">
<h3
className="padding-left--md padding-top--md margin-bottom--none"
style={{
textTransform: 'uppercase',
fontSize: '0.75em',
color: 'var(--ifm-color-emphasis-700)',
letterSpacing: '0.5px',
}}>
Table of Contents
</h3>
<TOCItems