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

PBI 2716 & 2758 Improve Testimonials Section on Home Page #2756

Merged
merged 22 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2f00a5b
setup Marquee component from Magic UI
tino-liu Jan 15, 2025
19db75b
Implement Marquee into testimonials block
tino-liu Jan 15, 2025
c6bfb84
Fix testimony card height
tino-liu Jan 15, 2025
300d7f5
add src as tailwind config folder
tino-liu Jan 15, 2025
4e704be
Merge branch 'main' into 2716-Improve-Testimonials-Section
tino-liu Jan 15, 2025
35af9cc
changed testimonial card css
tino-liu Jan 15, 2025
fa894ae
update line clamp style
tino-liu Jan 15, 2025
7188c2b
Adjust the layout of Testimonials
ZenoWang1999 Jan 16, 2025
f197109
Keep the functionality of Testimonials unchanged
ZenoWang1999 Jan 16, 2025
0bf7c97
Merge branch 'main' into LocalEnv
ZenoWang1999 Jan 16, 2025
c74822a
fix the error in tailwind.config.js
ZenoWang1999 Jan 16, 2025
dfed98b
Updated some styles to make the gradient effect more natural
ZenoWang1999 Jan 17, 2025
62b3dfd
Merge branch 'main' into LocalEnv
ZenoWang1999 Jan 17, 2025
05839f8
Resolved the issues related to PBI2758 and optimized the correspondin…
ZenoWang1999 Jan 20, 2025
1be1f97
Merge branch 'main' into LocalEnv
ZenoWang1999 Jan 20, 2025
331aac8
Update the comments
ZenoWang1999 Jan 21, 2025
aa3dc17
Merge branch 'main' into LocalEnv
ZenoWang1999 Jan 21, 2025
1f49bef
Optimized the synchronization function
ZenoWang1999 Jan 21, 2025
a4e7139
Merge branch 'main' into 2716-Improve-Testimonials-Section
ZenoWang1999 Jan 21, 2025
1742d8d
Optimized the synchronization function
ZenoWang1999 Jan 21, 2025
39d939f
Merge branch '2716-Improve-Testimonials-Section' of https://github.co…
ZenoWang1999 Jan 21, 2025
da41bc8
Optimized the synchronization function
ZenoWang1999 Jan 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions app/docs/[...slug]/DocsPagesClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ import { TinaMarkdown } from 'tinacms/dist/rich-text';
import { useTocListener } from 'components/AppRouterMigrationComponents/Docs/toc_helper';

export default function DocsClient(props) {

const { PageTableOfContents, NavigationDocsData } = props.props;
const DocumentationData = props.tinaProps.data.doc;

const allData = [DocumentationData, PageTableOfContents, NavigationDocsData];

const allData = [DocumentationData, PageTableOfContents, NavigationDocsData];

const isScreenSmallerThan1200 = screenResizer().isScreenSmallerThan1200;
const isScreenSmallerThan840 = screenResizer().isScreenSmallerThan840;
Expand All @@ -32,8 +30,6 @@ export default function DocsClient(props) {
title: DocumentationData?.next?.title,
};



const lastEdited = DocumentationData?.last_edited;
const date = lastEdited === null ? null : new Date(lastEdited);
const formattedDate = date
Expand All @@ -49,9 +45,7 @@ export default function DocsClient(props) {
? 'grid-cols-[1.25fr_3fr]'
: 'grid-cols-[1.25fr_3fr_0.75fr]';



return (
return (
<div className="relative my-6 lg:my-16 flex justify-center items-start">
<div className={`lg:px-16 px-3 w-full max-w-[2000px] grid ${gridClass}`}>
{/* LEFT COLUMN */}
Expand Down
21 changes: 21 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "styles/tailwind.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
192 changes: 103 additions & 89 deletions components/AppRouterMigrationComponents/Docs/toc/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
'use client';

import { useState, useEffect } from 'react';
import { useState, useEffect, useRef } from 'react';
import ReactMarkdown from 'react-markdown';
import styled, { css } from 'styled-components';
import RightArrowSvg from 'public/svg/right-arrow.svg';
import { getDocId } from 'utils/docs/getDocIds';

interface TocProps {
tocItems: Array<{ type: string; text: string }>;
activeIds: string[];
}

export const generateMarkdown = (tocItems: Array<{ type: string; text: string }>) => {
export const generateMarkdown = (
tocItems: Array<{ type: string; text: string }>
) => {
return tocItems
.map((item) => {
const anchor = getDocId(item.text);
Expand All @@ -23,55 +24,118 @@ export const generateMarkdown = (tocItems: Array<{ type: string; text: string }>

const ToC = ({ tocItems, activeIds }: TocProps) => {
const [isOpen, setIsOpen] = useState(false);
const tocWrapperRef = useRef<HTMLDivElement>(null);

useEffect(() => {
const close = () => setIsOpen(false);
const allLinks = document.querySelectorAll('a');
allLinks.forEach((a) => a.addEventListener('click', close));
return () => allLinks.forEach((a) => a.removeEventListener('click', close));

return () => {
allLinks.forEach((a) => a.removeEventListener('click', close));
};
}, []);

useEffect(() => {
if (tocWrapperRef.current && activeIds.length > 0) {
const tocList = tocWrapperRef.current;

const lastActiveId = activeIds[activeIds.length - 1];
const activeLink = tocList.querySelector(`a[href="#${lastActiveId}"]`);

if (activeLink) {
const activeTop = (activeLink as HTMLElement).offsetTop;
const activeHeight = (activeLink as HTMLElement).offsetHeight;
const listHeight = tocList.clientHeight;

tocList.scrollTo({
top: activeTop - listHeight / 2 + activeHeight / 2,
behavior: 'smooth',
});
}
}
}, [activeIds]);

if (!tocItems || tocItems.length === 0) {
return null;
}

const tocMarkdown = generateMarkdown(tocItems);



return (
<TocWrapper>
<TocContent activeIds={activeIds} isOpen={isOpen}>
<TocDesktopHeader>Table of Contents</TocDesktopHeader>
<ReactMarkdown
components={{
li: ({ children }) => (
<li className="hover:text-orange-500 transition-colors">{children}</li>
),
a: ({ children, ...props }) => {
const isActive = activeIds.includes(props.href?.slice(1)); // Match href with activeIds
return (
<a
{...props}
className={`${
isActive ? 'text-orange-500 font-bold no-underline' : 'hover:text-orange-500 underline transition-colors'
}`}
>
{children}
</a>
);
},
}}
>
{tocMarkdown}
</ReactMarkdown>
</TocContent>
</TocWrapper>
<>
<TocWrapper>
<TocContent activeIds={activeIds} isOpen={isOpen}>
<TocDesktopHeader>Table of Contents</TocDesktopHeader>
<TocTitleList
ref={tocWrapperRef}
className="max-h-[70vh] 2xl:max-h-[75vh] p-4 overflow-y-auto"
>
<ReactMarkdown
components={{
ul: ({ children }) => (
<ul className="space-y-1 pt-1">{children}</ul>
),
li: ({ children }) => (
<li className="leading-relaxed">{children}</li>
),
a: ({ children, ...props }) => {
const isActive = activeIds.includes(props.href?.slice(1)); // Match href with activeIds
return (
<a
{...props}
className={`
block py-1 px-2 rounded-md hover:bg-gray-50/75 transition-colors duration-150
${
isActive
? 'text-orange-500 font-medium no-underline'
: 'text-gray-600 hover:text-orange-500'
}`}
>
{children}
</a>
);
},
}}
>
{tocMarkdown}
</ReactMarkdown>
</TocTitleList>
</TocContent>
</TocWrapper>
</>
);
};

export default ToC;

const TocTitleList = styled.div<{ ref: React.RefObject<HTMLDivElement> }>`
scrollbar-width: none;
::-webkit-scrollbar {
display: none;
}
-ms-overflow-style: none;
word-wrap: break-word;
white-space: normal;
overflow-wrap: break-word;
-webkit-mask-image: linear-gradient(
to bottom,
transparent,
black 5%,
black 95%,
transparent
);
mask-image: linear-gradient(
to bottom,
transparent,
black 5%,
black 95%,
transparent
);
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
`;
const TocDesktopHeader = styled.span`
display: none;
font-size: 1rem;
Expand All @@ -89,67 +153,17 @@ const TocDesktopHeader = styled.span`
const TocWrapper = styled.div`
margin-bottom: -0.375rem;
flex: 0 0 auto;
width: 300px; /* fix width */
word-wrap: break-word; /* break the long word */
white-space: normal;
overflow-wrap: break-word; /* suppport Chrome */
@media (min-width: 1200px) {
position: sticky;
top: 8rem;
}
`;

const TocButton = styled.button<{ isOpen: boolean }>`
display: block;
padding: 0;
outline: none;
border: none;
color: var(--color-secondary);
opacity: 0.65;
background: transparent;
cursor: pointer;
transition: opacity 185ms ease-out;
display: flex;
align-items: center;
line-height: 1;
margin-bottom: 1.125rem;
span {
margin-right: 0.5rem;
}
svg {
position: relative;
width: 1.25rem;
height: auto;
fill: var(--color-grey);
transform-origin: 50% 50%;
transition: opacity 180ms ease-out, transform 180ms ease-out;
opacity: 0.5;
}
:hover,
:focus {
opacity: 1;
svg {
opacity: 1;
}
}
${(props) =>
props.isOpen &&
css`
color: var(--color-orange);
svg {
transform: rotate(90deg);
opacity: 1;
}
`}
@media (min-width: 1200px) {
display: none;
}
`;

const TocContent = styled.div<{ isOpen: boolean; activeIds: string[] }>`
display: block;
width: 100%;
Expand All @@ -176,14 +190,14 @@ const TocContent = styled.div<{ isOpen: boolean; activeIds: string[] }>`
margin: 0;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
li {
margin: 0;
padding: 0.375rem 0;
}
ul ul {
padding-left: 0.75rem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export function useTocListener(data: any) {

React.useEffect(() => {
if (!contentRef.current) return;

const tocListener = createTocListener(contentRef, setActiveIds);
const handleScroll = () => tocListener(); // Define scroll handler

Expand Down
Loading
Loading