Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

💄 ♻️ Rework Docs #2580

Merged
merged 14 commits into from
Dec 15, 2024
34 changes: 17 additions & 17 deletions components/DocumentationNavigation/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import { useRouter } from 'next/router'
import styled from 'styled-components'
import { matchActualTarget } from 'utils'
import React from 'react';
import { useRouter } from 'next/router';
import styled from 'styled-components';
import { matchActualTarget } from 'utils';

export const ChevronRightIcon = ({ ...props }) => (
<svg
Expand All @@ -14,10 +14,10 @@ export const ChevronRightIcon = ({ ...props }) => (
>
<path d="M11 24.792L12.2654 26L21.4773 17.2061C22.1747 16.5403 22.1737 15.4588 21.4773 14.7939L12.2654 6L11 7.208L20.2099 16L11 24.792Z" />
</svg>
)
);

export interface DocsNavProps {
navItems: any
navItems: any;
}

const getNestedBreadcrumbs = (
Expand All @@ -27,38 +27,38 @@ const getNestedBreadcrumbs = (
) => {
for (const listItem of listItems || []) {
if (matchActualTarget(pagePath, listItem.slug || listItem.href)) {
breadcrumbs.push(listItem)
return [listItem]
breadcrumbs.push(listItem);
return [listItem];
}
const nestedBreadcrumbs = getNestedBreadcrumbs(
listItem.items,
pagePath,
breadcrumbs
)
);
if (nestedBreadcrumbs.length) {
return [listItem, ...nestedBreadcrumbs]
return [listItem, ...nestedBreadcrumbs];
}
}
return []
}
return [];
};

export function Breadcrumbs({ navItems }: DocsNavProps) {
const router = useRouter()
const breadcrumbs = getNestedBreadcrumbs(navItems, router.asPath) || []
const router = useRouter();
const breadcrumbs = getNestedBreadcrumbs(navItems, router.asPath) || [];
return (
<>
<BreadcrumbList>
{breadcrumbs.map((breadcrumb, i) => (
<li key={breadcrumb.slug}>
{i != 0 && <ChevronRightIcon />}
<a href={breadcrumb.slug}>
<a className="hover:text-orange-500" href={breadcrumb.slug}>
{breadcrumb.title || breadcrumb.category}
</a>
</li>
))}
</BreadcrumbList>
</>
)
);
}

const BreadcrumbList = styled.ul`
Expand Down Expand Up @@ -107,4 +107,4 @@ const BreadcrumbList = styled.ul`
opacity: 1 !important;
}
}
`
`;
25 changes: 1 addition & 24 deletions components/DocumentationNavigation/DocumentationNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { searchIndices } from '../../components/search/indices';
import { VersionSelect } from './VersionSelect';
import { BiMenu } from 'react-icons/bi';
import { IoMdClose } from 'react-icons/io';
import { LeftHandSideParentContainer } from 'components/docsSearch/SearchNavigation';

export interface DocsNavProps {
navItems: any;
Expand All @@ -28,30 +29,6 @@ export function DocumentationNavigation({ navItems }: DocsNavProps) {
onClick={() => setMobileNavIsOpen(!mobileNavIsOpen)}
/>
)}

<DocsLeftSidebar open={mobileNavIsOpen}>
<DocsSidebarHeaderWrapper>
<DocsSidebarHeader>
<div className="text-2xl leading-tight mt-2.5 ml-2 font-tuner text-orange-500">
Tina Docs
</div>
<VersionSelect />
</DocsSidebarHeader>


<CloseButton mobileNavIsOpen={mobileNavIsOpen} onClick={() => setMobileNavIsOpen(false)}>
<IoMdClose className="icon text-orange-500 hover:text-orange-400" />
</CloseButton>

<Search collapse expanded={true} indices={searchIndices} />
</DocsSidebarHeaderWrapper>

{router.isFallback ? (
<FallbackPlaceholder />
) : (
<DocsNavigationList navItems={navItems} />
)}
</DocsLeftSidebar>

<Overlay
open={mobileNavIsOpen}
Expand Down
50 changes: 50 additions & 0 deletions components/docsMain/directoryOverflowButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { DocsNavigationList } from 'components/DocumentationNavigation/DocsNavigationList';
import { useState, useEffect, useRef } from 'react';
import { MdMenu } from 'react-icons/md';

const DirectoryOverflow = ({ tocData }) => {
return (
<div className="absolute z-20 bg-white mt-4 rounded-lg w-full p-6 shadow-xl animate-fade-down animate-duration-300 overflow-y-scroll h-96">
<DocsNavigationList navItems={tocData.tocData} />
</div>
);
};

const DirectoryOverflowButton = (tocData) => {
const [isTableOfContentsOpen, setIsTableOfContentsOpen] = useState(false);
const containerRef = useRef(null);

useEffect(() => {
const handleClickOutside = (event) => {
if (containerRef.current && !containerRef.current.contains(event.target)) {
setIsTableOfContentsOpen(false);
}
};

document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);

return (
<div className="pb-6 w-full" ref={containerRef}>
<div
className="py-2 px-4 border-slate-400 bg-gradient-to-r from-white/50 to-white/30 rounded-lg shadow-lg cursor-pointer"
onClick={() => setIsTableOfContentsOpen(!isTableOfContentsOpen)}
>
<span className="flex items-center space-x-2 py-1">
<MdMenu size={20} className="text-orange-500" />
<span className="text-slate-600">Topics</span>
</span>
</div>
{isTableOfContentsOpen && (
<div className="w-full relative">
<DirectoryOverflow tocData={tocData} />
</div>
)}
</div>
);
};

export default DirectoryOverflowButton;
21 changes: 21 additions & 0 deletions components/docsMain/docsMainBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Breadcrumbs } from 'components/DocumentationNavigation/Breadcrumbs';
import DocsMobileHeader from './docsMobileHeader';

const MainDocsBodyHeader = (docData) => {
const DocumentTitle = docData.data.new.results.data.doc.title;

return (
<div>
{docData.screenSizing && (
<DocsMobileHeader data={docData}></DocsMobileHeader>
)}

<Breadcrumbs navItems={docData.data.navDocData.data} />
<div className="pt-4 font-tuner text-4xl bg-gradient-to-r from-orange-400 via-orange-500 to-orange-600 bg-clip-text text-transparent">
{DocumentTitle}
</div>
</div>
);
};

export default MainDocsBodyHeader;
77 changes: 77 additions & 0 deletions components/docsMain/docsMobileHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { DocsSearchBarHeader } from 'components/docsSearch/SearchNavigation';
import { useState } from 'react';
import { FaChevronRight } from 'react-icons/fa';
import DirectoryOverflowButton from './directoryOverflowButton';

export const MobileVersionSelect = () => {
const versions = [
['v.Latest', ''],
[
'v.0.68.13',
'https://tinacms-site-next-i08bcbicy-tinacms.vercel.app/docs/',
],
['v.0.67.3', 'https://tinacms-site-next-pu1t2v9y4-tinacms.vercel.app/'],
['v.Pre-Beta', 'https://pre-beta.tina.io/'],
];
const [versionSelected, setVersionSelected] = useState(versions[0][0]);
const [isOverflowOpen, setIsOverflowOpen] = useState(false);

const handleVersionClick = (version) => {
setVersionSelected(version[0]);
setIsOverflowOpen(false);

if (version[0] !== 'v.Latest') {
window.location.href = version[1];
}
};

return (
<div className="relative">
{/* VERSION SELECT PILL BUTTON */}
<div
className="bg-white cursor-pointer px-4 py-1 rounded-2xl shadow-sm flex justify-center text-center items-center text-stone-600"
onClick={() => setIsOverflowOpen(!isOverflowOpen)}
>
<div>{versionSelected}</div>
<div>
<FaChevronRight
className={`ml-2 transform transition-transform duration-300 ${
isOverflowOpen ? 'rotate-90' : ''
}`}
/>
</div>
</div>
{/* VERSION SELECT OVERFLOW */}
{isOverflowOpen && (
<div className="absolute bg-white shadow-lg mt-2 right-1 rounded-lg w-full z-10 animate-fade-down animate-duration-300">
{versions.map((version, index) => (
<div
key={index}
className="px-4 py-2 hover:bg-stone-100 cursor-pointer text-stone-600"
onClick={() => handleVersionClick(version)}
>
{version[0]}
</div>
))}
</div>
)}
</div>
);
};

const DocsMobileHeader = (data) => {
return (
<div className="relative pb-20">
<DocsSearchBarHeader
paddingGlobal="pb-4"
headerColour="orange"
headerPadding=""
searchMargin=""
searchBarPadding="py-3"
/>
<DirectoryOverflowButton tocData={data.data.data.navDocData.data} />
</div>
);
};

export default DocsMobileHeader;
66 changes: 66 additions & 0 deletions components/docsMain/tocOverflowButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Link from 'next/link';
import { useState, useEffect, useRef } from 'react';
import { MdMenu } from 'react-icons/md';
import { getDocId } from 'utils/docs/getDocIds';

const TocOverflow = ({ tocData }) => {
return (
<div className="absolute z-10 bg-white mt-4 rounded-lg w-full p-6 shadow-lg animate-fade-down animate-duration-300 max-h-96 overflow-y-scroll">
{tocData.tocData.map((item, index) => {
const textIndentation =
item.type === 'h3' ? 'ml-4' : item.type === 'h4' ? 'ml-8' : '';

const linkHref = `#${item.text.replace(/\s+/g, '-').toLowerCase()}`;
joshbermanssw marked this conversation as resolved.
Show resolved Hide resolved

return (
<Link
key={index}
href={linkHref}
className={`block hover:text-orange-500 transition-colors pl-6 ${textIndentation} pb-1`}
>
{item.text}
</Link>
);
})}
</div>
);
};

const TocOverflowButton = (tocData) => {
const [isTableOfContentsOpen, setIsTableOfContentsOpen] = useState(false);
const containerRef = useRef(null);

useEffect(() => {
const handleClickOutside = (event) => {
if (containerRef.current && !containerRef.current.contains(event.target)) {
setIsTableOfContentsOpen(false);
}
};

document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);

return (
<div className="py-6 w-full" ref={containerRef}>
<div
className="py-2 px-4 border-slate-400 bg-gradient-to-r from-white/50 to-white/30 rounded-lg shadow-lg cursor-pointer"
onClick={() => setIsTableOfContentsOpen(!isTableOfContentsOpen)}
>
<span className="flex items-center space-x-2">
<MdMenu size={20} className="text-orange-500" />
<span className="text-slate-600 py-1">Table of Contents</span>
</span>
</div>
{isTableOfContentsOpen && (
<div className="w-full relative">
<TocOverflow tocData={tocData} />
</div>
)}
</div>
);
};

export default TocOverflowButton;
Loading
Loading