feat(v2): bootstrap theme, preset, template, CI previews (#2981)

* fix(v2): doc sidebar

* chore(v2): prettier

* fix(v2): docs navbar path

* fix(v2): fix error about activepath

* chore(v2): prettier

* feat(v2): change active color

* feat(v2): Add bootstrap doc

* docs(v2): Update preset

* doc(v2): finish bootstrap documentation

* chore(v2): run lint

* doc(v2): update hook

* fix theme bootstrap layout (far from perfect)

* Try to fix bootstrap theme and deploy it!

* fix netlify error

Co-authored-by: slorber <lorber.sebastien@gmail.com>
This commit is contained in:
Fanny 2020-08-17 15:18:37 -03:00 committed by GitHub
parent 5fdf96c552
commit 8c05aa8e94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 561 additions and 67 deletions

View file

@ -14,34 +14,45 @@ import Layout from '@theme/Layout';
import {MDXProvider} from '@mdx-js/react';
import {matchPath} from '@docusaurus/router';
function DocPage(props) {
const {route: baseRoute, docsMetadata, location} = props;
// case-sensitive route such as it is defined in the sidebar
const currentRoute =
baseRoute.routes.find((route) => {
return matchPath(location.pathname, route);
}) || {};
const {permalinkToSidebar, docsSidebars} = docsMetadata;
const sidebar = permalinkToSidebar[currentRoute.path];
if (Object.keys(currentRoute).length === 0) {
return <NotFound {...props} />;
}
function DocPageContent({currentDocRoute, versionMetadata, children}) {
const {permalinkToSidebar, docsSidebars} = versionMetadata;
const sidebarName = permalinkToSidebar[currentDocRoute.path];
const sidebar = docsSidebars[sidebarName];
return (
<Layout title="Doc page" description="My Doc page">
<DocSidebar
docsSidebars={docsSidebars}
path={currentRoute.path}
sidebar={sidebar}
/>
<section className="offset-1 mr-4 mt-4 col-xl-6 offset-xl-4 p-0 justify-content-center align-self-center overflow-hidden">
<MDXProvider components={MDXComponents}>
{renderRoutes(baseRoute.routes)}
</MDXProvider>
</section>
<div className="d-flex vh-100 overflow-hidden">
{sidebar && (
<div className="vh-100" role="complementary">
<DocSidebar path={currentDocRoute.path} sidebar={sidebar} />
</div>
)}
<main className="vh-100 w-100 d-flex flex-column align-items-center overflow-auto p-5">
<MDXProvider components={MDXComponents}>{children}</MDXProvider>
</main>
</div>
</Layout>
);
}
function DocPage(props) {
const {
route: {routes: docRoutes},
versionMetadata,
location,
} = props;
const currentDocRoute = docRoutes.find((docRoute) =>
matchPath(location.pathname, docRoute),
);
if (!currentDocRoute) {
return <NotFound {...props} />;
}
return (
<DocPageContent
currentDocRoute={currentDocRoute}
versionMetadata={versionMetadata}>
{renderRoutes(docRoutes)}
</DocPageContent>
);
}
export default DocPage;

View file

@ -61,9 +61,7 @@ const DocSidebarItem = ({item, onItemClick, ...props}) => {
}
};
const DocSidebar = (props) => {
const {docsSidebars, sidebar: currentSidebar} = props;
const DocSidebar = ({sidebar, path}) => {
const [sidebarShown, setSidebarShown] = useState(false);
const handleSidebarToggle = useCallback(() => {
setSidebarShown(!sidebarShown);
@ -71,18 +69,6 @@ const DocSidebar = (props) => {
useLockBodyScroll(sidebarShown);
if (!currentSidebar) {
return null;
}
const sidebarData = docsSidebars[currentSidebar];
if (!sidebarData) {
throw new Error(
`Cannot find the sidebar "${currentSidebar}" in the sidebar config!`,
);
}
return (
<div className={classNames('bg-info', styles.sidebar)}>
<div
@ -115,7 +101,7 @@ const DocSidebar = (props) => {
</div>
<div className={classNames(styles.sideMenu)}>
<Nav vertical className="list-unstyled p-3 mr-auto">
{sidebarData.map((item) => (
{sidebar.map((item) => (
<DocSidebarItem
key={item.label}
item={item}

View file

@ -0,0 +1,32 @@
/**
* 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 from 'react';
import Layout from '@theme/Layout';
import {MDXProvider} from '@mdx-js/react';
import MDXComponents from '@theme/MDXComponents';
function MDXPage(props) {
const {content: MDXPageContent} = props;
const {frontMatter, metadata} = MDXPageContent;
const {title, description} = frontMatter;
const {permalink} = metadata;
return (
<Layout title={title} description={description} permalink={permalink}>
<main>
<div className="container margin-vert--lg padding-vert--lg">
<MDXProvider components={MDXComponents}>
<MDXPageContent />
</MDXProvider>
</div>
</main>
</Layout>
);
}
export default MDXPage;

View file

@ -0,0 +1,14 @@
/**
* 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 from 'react';
function TabItem(props) {
return <div>{props.children}</div>;
}
export default TabItem;

View file

@ -0,0 +1,154 @@
/**
* 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, {useState, Children, useEffect} from 'react';
import clsx from 'clsx';
import styles from './styles.module.css';
const keys = {
left: 37,
right: 39,
tab: 9,
};
// TODO quick fix to make bootstrap theme work
function useUserPreferencesContext() {
const [state, setState] = useState({});
return {
tabGroupChoices: state,
setTabGroupChoices: (id, value) => {
setState((s) => ({...s, [id]: value}));
},
};
}
function Tabs(props) {
const {block, children, defaultValue, values, groupId} = props;
const {tabGroupChoices, setTabGroupChoices} = useUserPreferencesContext();
const [selectedValue, setSelectedValue] = useState(defaultValue);
const [keyboardPress, setKeyboardPress] = useState(false);
if (groupId != null) {
const relevantTabGroupChoice = tabGroupChoices[groupId];
if (
relevantTabGroupChoice != null &&
relevantTabGroupChoice !== selectedValue &&
values.some((value) => value.value === relevantTabGroupChoice)
) {
setSelectedValue(relevantTabGroupChoice);
}
}
const changeSelectedValue = (newValue) => {
setSelectedValue(newValue);
if (groupId != null) {
setTabGroupChoices(groupId, newValue);
}
};
const tabRefs = [];
const focusNextTab = (tabs, target) => {
const next = tabs.indexOf(target) + 1;
if (!tabs[next]) {
tabs[0].focus();
} else {
tabs[next].focus();
}
};
const focusPreviousTab = (tabs, target) => {
const prev = tabs.indexOf(target) - 1;
if (!tabs[prev]) {
tabs[tabs.length - 1].focus();
} else {
tabs[prev].focus();
}
};
const handleKeydown = (tabs, target, event) => {
switch (event.keyCode) {
case keys.right:
focusNextTab(tabs, target);
break;
case keys.left:
focusPreviousTab(tabs, target);
break;
default:
break;
}
};
const handleKeyboardEvent = (event) => {
if (event.metaKey || event.altKey || event.ctrlKey) {
return;
}
setKeyboardPress(true);
};
const handleMouseEvent = () => {
setKeyboardPress(false);
};
useEffect(() => {
window.addEventListener('keydown', handleKeyboardEvent);
window.addEventListener('mousedown', handleMouseEvent);
}, []);
return (
<div>
<ul
role="tablist"
aria-orientation="horizontal"
className={clsx('tabs', {
'tabs--block': block,
})}>
{values.map(({value, label}) => (
<li
role="tab"
tabIndex={0}
aria-selected={selectedValue === value}
className={clsx('tabs__item', styles.tabItem, {
'tabs__item--active': selectedValue === value,
})}
style={keyboardPress ? {} : {outline: 'none'}}
key={value}
ref={(tabControl) => tabRefs.push(tabControl)}
onKeyDown={(event) => {
handleKeydown(tabRefs, event.target, event);
handleKeyboardEvent(event);
}}
onFocus={() => changeSelectedValue(value)}
onClick={() => {
changeSelectedValue(value);
setKeyboardPress(false);
}}
onPointerDown={() => setKeyboardPress(false)}>
{label}
</li>
))}
</ul>
<div role="tabpanel" className="margin-vert--md">
{
Children.toArray(children).filter(
(child) => child.props.value === selectedValue,
)[0]
}
</div>
</div>
);
}
export default Tabs;

View file

@ -0,0 +1,11 @@
/**
* 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.
*/
.tabItem {
margin-top: 0 !important;
}

View file

@ -0,0 +1,14 @@
/**
* 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 defaultTheme from 'prism-react-renderer/themes/palenight';
const usePrismTheme = () => {
return defaultTheme;
};
export default usePrismTheme;