docs: redesign docs collapsible categories (#1748)

* docs: redesign docs collapsible categories

Closes #1341

* Fix people creation from People table page

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Thaïs
2023-09-29 16:22:04 +02:00
committed by GitHub
parent b52190c707
commit 1c35ccce4e
10 changed files with 194 additions and 107 deletions

View File

@ -3,5 +3,7 @@
"position": 10,
"collapsible": true,
"collapsed": true,
"className": "navbar-sub-menu"
"customProps": {
"icon": "TbPlus"
}
}

View File

@ -3,5 +3,7 @@
"position": 3,
"collapsible": true,
"collapsed": false,
"className": "navbar-sub-menu"
"customProps": {
"icon": "TbTerminal2"
}
}

View File

@ -251,8 +251,6 @@ const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => {
For React to understand that the component is a component, you need to use PascalCase, to later instanciate it with `<MyIcon>`
```tsx
## Prop Drilling: Keep It Minimal
Prop drilling, in the React context, refers to the practice of passing state variables and their setters through multiple component layers, even if intermediary components don't use them. While sometimes necessary, excessive prop drilling can lead to:

View File

@ -40,7 +40,7 @@ git clone git@github.com:twentyhq/twenty.git
### 3. PostgreSQL database
You also need to have a PosgresSQL database available. If you already have one available, you can skip this step.
You also need to have a PostgreSQL database available. If you already have one available, you can skip this step.
If you don't, you can provision one through `docker` using the following command:

View File

@ -38,6 +38,7 @@ const config = {
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
breadcrumbs: false,
sidebarPath: require.resolve('./sidebars.js'),
sidebarCollapsible: false,
routeBasePath: '/',

View File

@ -38,6 +38,11 @@
--ifm-spacing-horizontal: 2rem;
--ifm-menu-link-padding-vertical: 0.2rem;
--list-items-border-color: #ebebeb;
--category-icon-background-color: #ebebeb;
--category-icon-border-color: #d6d6d6;
--level-1-color: #B3B3B3;
}
.markdown > h1 {
@ -60,6 +65,10 @@
[data-theme='dark'] {
--ifm-color-primary: #fff;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
--list-items-border-color: #292929;
--category-icon-background-color: #292929;
--category-icon-border-color: #333333;
--level-1-color: #666666;
}
body {
@ -73,6 +82,10 @@ html {
font-size: 14px;
}
.container {
padding-top: 48px !important;
}
.DocSearch-Button {
height: 32px !important;
border-radius: 8px !important;
@ -120,6 +133,10 @@ a.menu__link, a.navbar__item {
text-decoration: none;
}
.menu__link--external {
align-items: center;
}
li.coming-soon a::after {
float: right;
content: "soon";
@ -134,33 +151,33 @@ li.coming-soon a::after {
font-size: 80%;
}
.menu__list-item-collapsible > a {
.theme-doc-sidebar-item-category-level-1 > .menu__link {
text-transform: uppercase;
font-size:11px;
color: #B3B3B3;
font-size: 12px;
color: var(--level-1-color);
}
.menu__list-item-collapsible > a:hover {
color: #B3B3B3;
}
.menu__list-item-collapsible > a {
text-transform: uppercase;
font-size:12px;
}
.menu__list-item-collapsible:hover {
.menu__list-item--level1 > .menu__link--active,
.menu__list-item--level1 > .menu__link:hover {
background: inherit;
}
.theme-doc-sidebar-item-category {
.theme-doc-sidebar-item-category-level-1 {
padding-top: 1.5rem;
}
.theme-doc-sidebar-item-category-level-2 {
cursor: pointer;
}
.theme-doc-sidebar-item-category-level-2 .menu__list {
border-left: 1px solid var(--list-items-border-color);
margin-left: var(--ifm-menu-link-padding-horizontal);
}
.sidebar-item-icon {
display: flex;
vertical-align: center;
padding-right: 0.5rem;
margin-right: 0.5rem;
}
.icon-and-text {
@ -184,15 +201,6 @@ a.table-of-contents__link:hover{
text-decoration: underline;
}
.navbar-sub-menu {
padding-top: 8px;
font-size: 13px;
}
.navbar-sub-menu .menu__link--sublist {
font-size: 11px;
}
.docs-image {
max-width: 100%;
display: flex;

View File

@ -0,0 +1,101 @@
import Link from "@docusaurus/Link";
import isInternalUrl from "@docusaurus/isInternalUrl";
import {
Collapsible,
ThemeClassNames,
useCollapsible,
} from "@docusaurus/theme-common";
import { isActiveSidebarItem } from "@docusaurus/theme-common/internal";
import DocSidebarItems from "@theme/DocSidebarItems";
import IconExternalLink from "@theme/Icon/ExternalLink";
import clsx from "clsx";
import React from "react";
import * as icons from "../../icons";
const DocSidebarItemCategory = ({
item,
onItemClick,
activePath,
level,
index,
...props
}) => {
const {
href,
label,
className,
collapsible,
autoAddBaseUrl,
customProps = {},
items,
} = item;
const isActive = isActiveSidebarItem(item, activePath);
const isInternalLink = isInternalUrl(href);
const IconComponent = customProps?.icon ? icons[customProps.icon] : undefined;
const { collapsed, setCollapsed } = useCollapsible({
initialState: () => collapsible && !isActive && item.collapsed,
});
return (
<li
className={clsx(
ThemeClassNames.docs.docSidebarItemCategory,
ThemeClassNames.docs.docSidebarItemCategoryLevel(level),
"menu__list-item",
`menu__list-item--level${level}`,
className
)}
key={label}
>
<Link
className={clsx("menu__link", {
"menu__link--active": isActive,
"menu__link--external": !!href && !isInternalLink,
})}
autoAddBaseUrl={autoAddBaseUrl}
aria-current={isActive ? "page" : undefined}
aria-expanded={collapsible ? !collapsed : undefined}
to={href}
onClick={(e) => {
onItemClick?.(item);
if (!collapsible) return;
if (href) {
setCollapsed(false);
return;
}
e.preventDefault();
setCollapsed((previousCollapsed) => !previousCollapsed);
}}
{...props}
>
{IconComponent ? (
<span className="icon-and-text">
<i className="sidebar-item-icon">
<IconComponent />
</i>
{label}
</span>
) : (
label
)}
{!!href && !isInternalLink && <IconExternalLink />}
</Link>
<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>
);
};
export default DocSidebarItemCategory;

View File

@ -1,37 +1,11 @@
import React from 'react';
import clsx from 'clsx';
import {ThemeClassNames} from '@docusaurus/theme-common';
import {isActiveSidebarItem} from '@docusaurus/theme-common/internal';
import Link from '@docusaurus/Link';
import isInternalUrl from '@docusaurus/isInternalUrl';
import IconExternalLink from '@theme/Icon/ExternalLink';
import styles from './styles.module.css';
import {
TbFaceIdError,
TbTerminal2,
TbCloud,
TbServer,
TbBolt,
TbApps,
TbTopologyStar,
TbChartDots,
TbBug,
TbVocabulary,
TbArrowBigRight,
TbDeviceDesktop,
TbBrandWindows,
TbBugOff,
TbBrandVscode,
TbFolder,
TbEyeglass,
TbZoomQuestion,
TbBrandFigma,
TbPaint,
TbChecklist,
TbKeyboard,
TbPencil,
} from "react-icons/tb";
import Link from "@docusaurus/Link";
import isInternalUrl from "@docusaurus/isInternalUrl";
import { ThemeClassNames } from "@docusaurus/theme-common";
import { isActiveSidebarItem } from "@docusaurus/theme-common/internal";
import IconExternalLink from "@theme/Icon/ExternalLink";
import clsx from "clsx";
import React from "react";
import * as icons from "../../icons";
const DocSidebarItemLink = ({
item,
@ -41,63 +15,40 @@ const DocSidebarItemLink = ({
index,
...props
}) => {
const {href, label, className, autoAddBaseUrl, customProps = {}} = item;
const { href, label, className, autoAddBaseUrl, customProps = {} } = item;
const isActive = isActiveSidebarItem(item, activePath);
const isInternalLink = isInternalUrl(href);
let icons = {
'TbTerminal2': TbTerminal2,
'TbCloud': TbCloud,
'TbArrowBigRight': TbArrowBigRight,
'TbServer': TbServer,
'TbBolt': TbBolt,
'TbApps': TbApps,
'TbTopologyStar': TbTopologyStar,
'TbChartDots': TbChartDots,
'TbBug': TbBug,
'TbVocabulary': TbVocabulary,
'TbBrandWindows': TbBrandWindows,
'TbBugOff': TbBugOff,
'TbBrandVscode': TbBrandVscode,
'TbDeviceDesktop': TbDeviceDesktop,
'TbFolder': TbFolder,
'TbEyeglass': TbEyeglass,
'TbZoomQuestion': TbZoomQuestion,
'TbBrandFigma': TbBrandFigma,
'TbPaint': TbPaint,
'TbChecklist': TbChecklist,
'TbKeyboard': TbKeyboard,
'TbChecklist': TbChecklist,
'TbPencil': TbPencil,
};
const IconComponent = customProps?.icon
? icons[customProps.icon]
: icons.TbFaceIdError;
let IconComponent = customProps && customProps.icon ? icons[customProps.icon] : TbFaceIdError;
return (
<li
className={clsx(
ThemeClassNames.docs.docSidebarItemLink,
ThemeClassNames.docs.docSidebarItemLinkLevel(level),
'menu__list-item',
className,
"menu__list-item",
`menu__list-item--level${level}`,
className
)}
key={label}>
key={label}
>
<Link
className={clsx(
'menu__link',
!isInternalLink && styles.menuExternalLink,
{
'menu__link--active': isActive,
},
)}
className={clsx("menu__link", {
"menu__link--active": isActive,
"menu__link--external": !isInternalLink,
})}
autoAddBaseUrl={autoAddBaseUrl}
aria-current={isActive ? 'page' : undefined}
aria-current={isActive ? "page" : undefined}
to={href}
{...(isInternalLink && {
onClick: onItemClick ? () => onItemClick(item) : undefined,
})}
{...props}>
{...props}
>
<span className="icon-and-text">
<i className="sidebar-item-icon">
<IconComponent />
<IconComponent size={customProps.iconSize} />
</i>
{label}
</span>
@ -105,6 +56,6 @@ const DocSidebarItemLink = ({
</Link>
</li>
);
}
};
export default DocSidebarItemLink;

View File

@ -1,3 +0,0 @@
.menuExternalLink {
align-items: center;
}

27
docs/src/theme/icons.js Normal file
View File

@ -0,0 +1,27 @@
export {
TbApps,
TbArrowBackUp,
TbArrowBigRight,
TbBolt,
TbBrandFigma,
TbBrandVscode,
TbBrandWindows,
TbBug,
TbBugOff,
TbChartDots,
TbChecklist,
TbCloud,
TbDeviceDesktop,
TbEyeglass,
TbFaceIdError,
TbFolder,
TbKeyboard,
TbPaint,
TbPencil,
TbPlus,
TbServer,
TbTerminal2,
TbTopologyStar,
TbVocabulary,
TbZoomQuestion,
} from "react-icons/tb";