Migrate to a monorepo structure (#2909)
This commit is contained in:
97
packages/twenty-docs/src/theme/DocCard/index.js
Normal file
97
packages/twenty-docs/src/theme/DocCard/index.js
Normal file
@ -0,0 +1,97 @@
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import Link from '@docusaurus/Link';
|
||||
import {
|
||||
findFirstCategoryLink,
|
||||
useDocById,
|
||||
} from '@docusaurus/theme-common/internal';
|
||||
import isInternalUrl from '@docusaurus/isInternalUrl';
|
||||
import {translate} from '@docusaurus/Translate';
|
||||
import styles from './styles.module.css';
|
||||
import * as icons from "../icons";
|
||||
|
||||
|
||||
function CardContainer({href, children}) {
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={clsx('card padding--lg', styles.cardContainer)}>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
function CardLayout({href, icon, title, description}) {
|
||||
return (
|
||||
<CardContainer href={href}>
|
||||
<h2 className={clsx("text--truncate", styles.cardTitle)} title={title}>
|
||||
<span className={styles.icon}>
|
||||
{typeof icon === "function" ? icon() : icon}
|
||||
</span>{" "}
|
||||
{title}
|
||||
</h2>
|
||||
{description && (
|
||||
<p
|
||||
className={clsx("text--truncate", styles.cardDescription)}
|
||||
title={description}
|
||||
>
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
</CardContainer>
|
||||
);
|
||||
}
|
||||
|
||||
function CardCategory({item}) {
|
||||
const href = findFirstCategoryLink(item);
|
||||
// Unexpected: categories that don't have a link have been filtered upfront
|
||||
if (!href) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<CardLayout
|
||||
href={href}
|
||||
icon="🗃️"
|
||||
title={item.label}
|
||||
description={
|
||||
item.description ??
|
||||
translate(
|
||||
{
|
||||
message: '{count} items',
|
||||
id: 'theme.docs.DocCard.categoryDescription',
|
||||
description:
|
||||
'The default description for a category card in the generated index about how many items this category includes',
|
||||
},
|
||||
{count: item.items.length},
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function CardLink({ item }) {
|
||||
const customIcon = item.customProps.icon;
|
||||
const icon = icons[customIcon] || (isInternalUrl(item.href) ? "📄️" : "🔗");
|
||||
const doc = useDocById(item.docId ?? undefined);
|
||||
|
||||
return (
|
||||
<CardLayout
|
||||
href={item.href}
|
||||
icon={icon}
|
||||
title={item.label}
|
||||
description={item.description ?? doc?.description}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export default function DocCard({item}) {
|
||||
switch (item.type) {
|
||||
case 'link':
|
||||
return <CardLink item={item} />;
|
||||
case 'category':
|
||||
return <CardCategory item={item} />;
|
||||
default:
|
||||
throw new Error(`unknown item type ${JSON.stringify(item)}`);
|
||||
}
|
||||
}
|
||||
33
packages/twenty-docs/src/theme/DocCard/styles.module.css
Normal file
33
packages/twenty-docs/src/theme/DocCard/styles.module.css
Normal file
@ -0,0 +1,33 @@
|
||||
.cardContainer {
|
||||
--ifm-link-color: var(--ifm-color-emphasis-800);
|
||||
--ifm-link-hover-color: var(--ifm-color-emphasis-700);
|
||||
--ifm-link-hover-decoration: none;
|
||||
|
||||
box-shadow: 0 1.5px 3px 0 rgb(0 0 0 / 15%);
|
||||
border: 1px solid var(--ifm-color-emphasis-200);
|
||||
transition: all var(--ifm-transition-fast) ease;
|
||||
transition-property: border, box-shadow;
|
||||
}
|
||||
|
||||
.cardContainer:hover {
|
||||
border-color: var(--ifm-color-primary);
|
||||
box-shadow: 0 3px 6px 0 rgb(0 0 0 / 20%);
|
||||
}
|
||||
|
||||
.cardContainer *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: 1.2rem;
|
||||
display: flex
|
||||
}
|
||||
|
||||
.cardDescription {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 1.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
103
packages/twenty-docs/src/theme/DocSidebarItem/Category/index.js
Normal file
103
packages/twenty-docs/src/theme/DocSidebarItem/Category/index.js
Normal file
@ -0,0 +1,103 @@
|
||||
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>
|
||||
{!customProps.isSidebarRoot && (
|
||||
<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;
|
||||
62
packages/twenty-docs/src/theme/DocSidebarItem/Link/index.js
Normal file
62
packages/twenty-docs/src/theme/DocSidebarItem/Link/index.js
Normal file
@ -0,0 +1,62 @@
|
||||
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,
|
||||
onItemClick,
|
||||
activePath,
|
||||
level,
|
||||
index,
|
||||
...props
|
||||
}) => {
|
||||
const { href, label, className, autoAddBaseUrl, customProps = {} } = item;
|
||||
const isActive = isActiveSidebarItem(item, activePath);
|
||||
const isInternalLink = isInternalUrl(href);
|
||||
const IconComponent = customProps?.icon ? icons[customProps.icon] : null;
|
||||
|
||||
return (
|
||||
<li
|
||||
className={clsx(
|
||||
ThemeClassNames.docs.docSidebarItemLink,
|
||||
ThemeClassNames.docs.docSidebarItemLinkLevel(level),
|
||||
"menu__list-item",
|
||||
`menu__list-item--level${level}`,
|
||||
{ "menu__list-item--root": customProps.isSidebarRoot },
|
||||
className
|
||||
)}
|
||||
key={label}
|
||||
>
|
||||
<Link
|
||||
className={clsx("menu__link", {
|
||||
"menu__link--active": isActive,
|
||||
"menu__link--external": !isInternalLink,
|
||||
})}
|
||||
autoAddBaseUrl={autoAddBaseUrl}
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
to={href}
|
||||
{...(isInternalLink && {
|
||||
onClick: onItemClick ? () => onItemClick(item) : undefined,
|
||||
})}
|
||||
{...props}
|
||||
>
|
||||
<span className="icon-and-text">
|
||||
{IconComponent && (
|
||||
<i className="sidebar-item-icon">
|
||||
<IconComponent size={customProps.iconSize} />
|
||||
</i>
|
||||
)}
|
||||
{label}
|
||||
</span>
|
||||
{!isInternalLink && <IconExternalLink />}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
export default DocSidebarItemLink;
|
||||
11
packages/twenty-docs/src/theme/Icon/DarkMode/index.js
Normal file
11
packages/twenty-docs/src/theme/Icon/DarkMode/index.js
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import { TbMoon } from 'react-icons/tb';
|
||||
import {useColorMode} from '@docusaurus/theme-common';
|
||||
|
||||
|
||||
const IconDarkMode = (props) => {
|
||||
const { colorMode } = useColorMode();
|
||||
return colorMode === 'dark' ? <TbMoon /> : <></>;
|
||||
}
|
||||
|
||||
export default IconDarkMode
|
||||
5
packages/twenty-docs/src/theme/Icon/Home/index.js
Normal file
5
packages/twenty-docs/src/theme/Icon/Home/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
import React from "react";
|
||||
import { TbHome } from "react-icons/tb";
|
||||
const IconHome = (props) => <TbHome size={14} />;
|
||||
|
||||
export default IconHome;
|
||||
11
packages/twenty-docs/src/theme/Icon/LightMode/index.js
Normal file
11
packages/twenty-docs/src/theme/Icon/LightMode/index.js
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import { TbSun } from 'react-icons/tb';
|
||||
import {useColorMode} from '@docusaurus/theme-common';
|
||||
|
||||
|
||||
const IconLightMode = (props) => {
|
||||
const { colorMode } = useColorMode();
|
||||
return colorMode === 'light' ? <TbSun /> : <></>;
|
||||
}
|
||||
|
||||
export default IconLightMode;
|
||||
29
packages/twenty-docs/src/theme/OptionTable/index.js
Normal file
29
packages/twenty-docs/src/theme/OptionTable/index.js
Normal file
@ -0,0 +1,29 @@
|
||||
import styles from "./style.module.css";
|
||||
import React from "react";
|
||||
|
||||
export default function OptionTable({ options }) {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<table className={styles.optionsTable}>
|
||||
<thead className={styles.tableHeader}>
|
||||
<tr className={styles.tableHeaderRow}>
|
||||
<th className={styles.tableHeaderCell}>Variable</th>
|
||||
<th className={styles.tableHeaderCell}>Example</th>
|
||||
<th className={styles.tableHeaderCell}>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className={styles.tableBody}>
|
||||
{options.map(([option, example, description]) => (
|
||||
<tr key={option} className={styles.tableRow}>
|
||||
<td className={styles.tableOptionCell}>
|
||||
{option}
|
||||
</td>
|
||||
<td className={styles.tableDescriptionCell}>{example}</td>
|
||||
<td className={styles.tableDescriptionCell}>{description}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
87
packages/twenty-docs/src/theme/OptionTable/style.module.css
Normal file
87
packages/twenty-docs/src/theme/OptionTable/style.module.css
Normal file
@ -0,0 +1,87 @@
|
||||
.container {
|
||||
mask-image: linear-gradient(
|
||||
to right,
|
||||
transparent 0.8em,
|
||||
white 1.5em,
|
||||
white calc(100% - 1.5em),
|
||||
transparent calc(100% - 0.8em)
|
||||
);
|
||||
|
||||
overflow-x: auto;
|
||||
overscroll-behavior-x: contain;
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
padding-bottom: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 1.5rem;
|
||||
margin-left: -1.5rem;
|
||||
margin-right: -1.5rem;
|
||||
}
|
||||
|
||||
.container::-webkit-scrollbar {
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.optionsTable {
|
||||
width: 100%;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
border-collapse: collapse;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.tableHeader {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.tableHeaderRow {
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom-width: 1px;
|
||||
text-align: left;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.tableHeaderCell {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
font-weight: 600;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.tableBody {
|
||||
color: var(--ifm-color-content);
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.tableRow {
|
||||
border-bottom-width: 1px;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-color: var(--ifm-color-content);
|
||||
}
|
||||
|
||||
.tableOptionCell {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
|
||||
monospace;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.5rem;
|
||||
white-space: pre;
|
||||
color: var(--ifm-color-primary-light);
|
||||
border-right: none;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.tableDescriptionCell {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
padding-left: 1.5rem;
|
||||
border-right: none;
|
||||
border-left: none;
|
||||
}
|
||||
65
packages/twenty-docs/src/theme/icons.js
Normal file
65
packages/twenty-docs/src/theme/icons.js
Normal file
@ -0,0 +1,65 @@
|
||||
export {
|
||||
TbApps,
|
||||
TbArrowBackUp,
|
||||
TbArrowBigRight,
|
||||
TbArticle,
|
||||
TbBolt,
|
||||
TbBrandFigma,
|
||||
TbBrandVscode,
|
||||
TbBrandWindows,
|
||||
TbBrandZapier,
|
||||
TbBug,
|
||||
TbBugOff,
|
||||
TbChartDots,
|
||||
TbChecklist,
|
||||
TbCloud,
|
||||
TbScript,
|
||||
TbForms,
|
||||
TbTable,
|
||||
TbSlideshow,
|
||||
TbBrandDocker,
|
||||
TbDeviceDesktop,
|
||||
TbExclamationCircle,
|
||||
TbEyeglass,
|
||||
TbFaceIdError,
|
||||
TbFolder,
|
||||
TbKeyboard,
|
||||
TbPaint,
|
||||
TbPencil,
|
||||
TbPlus,
|
||||
TbServer,
|
||||
TbTerminal2,
|
||||
TbTopologyStar,
|
||||
TbVocabulary,
|
||||
TbZoomQuestion,
|
||||
TbRocket,
|
||||
TbAugmentedReality,
|
||||
TbTerminal,
|
||||
TbBrandGraphql,
|
||||
TbApi,
|
||||
TbUsers,
|
||||
TbCheck,
|
||||
TbPill,
|
||||
TbAppWindow,
|
||||
TbTooltip,
|
||||
TbTag,
|
||||
TbLayoutList,
|
||||
TbAddressBook,
|
||||
TbLoader2,
|
||||
TbInputSearch,
|
||||
TbIcons,
|
||||
TbSquareRoundedPlusFilled,
|
||||
TbLayoutGrid,
|
||||
TbColorFilter,
|
||||
TbTextSize,
|
||||
TbComponents,
|
||||
TbCheckbox,
|
||||
TbColorPicker,
|
||||
TbCircleDot,
|
||||
TbUpload,
|
||||
TbVariable,
|
||||
TbSchema,
|
||||
TbSelect,
|
||||
TbToggleRight,
|
||||
TbTextPlus,
|
||||
} from "react-icons/tb";
|
||||
Reference in New Issue
Block a user