Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@docusaurus/core": "^3.2.1",
"@docusaurus/plugin-sitemap": "^3.2.1",
"@docusaurus/preset-classic": "^3.2.1",
"@docusaurus/theme-common": "^3.8.1",
"@mdx-js/react": "^3.0.0",
"ajv": "^6.12.6",
"ajv-keywords": "^3.5.2",
Expand Down
244 changes: 176 additions & 68 deletions src/pages/concepts/reference/glossary.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,93 @@
import React, {useState} from "react";
import React, { useState, useRef, useEffect } from "react";
import Layout from "@theme/Layout";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import Head from "@docusaurus/Head";
import clsx from "clsx";

function Glossary() {
const [state, setState] = useState(() => {
const alphabet = "ABCEFGIMRSTUW";
const initialState = {};
for (let i = 0; i < alphabet.length; i++) {
initialState[alphabet[i]] = true;
}
return initialState;
// Initialize refs for each section
const sectionRefs = useRef({});
// Track which section is in view for navbar highlight
const [activeLetter, setActiveLetter] = useState("A");

// Initialize state for toggling sections
const [expandedSections, setExpandedSections] = useState(() => {
const sections = {};
"ABCEFGIMRSTUW".split('').forEach(letter => {
sections[letter] = true;
});
return sections;
});

// Scroll to section when navbar letter is clicked
// Lock highlight on clicked letter until its section is at the top
const [scrollTargetLetter, setScrollTargetLetter] = useState(null);
const scrollToSection = (letter) => {
// Always expand the section before scroll
setExpandedSections(prev => ({ ...prev, [letter]: true }));
setScrollTargetLetter(letter);
setActiveLetter(letter);
setTimeout(() => {
if (sectionRefs.current[letter]) {
sectionRefs.current[letter].scrollIntoView({ behavior: 'instant', block: 'start' });
// Offset for sticky navbar (default 150px)
window.scrollBy({ top: -150, behavior: 'smooth' });
}
}, 0);
};




// Intersection Observer for active section
useEffect(() => {
const handleScroll = () => {
// Get all refs in DOM order
const sectionList = Object.entries(sectionRefs.current)
.filter(([letter, ref]) => !!ref && expandedSections[letter])
.map(([letter, ref]) => ({ letter, top: ref.getBoundingClientRect().top }));
// If a scroll target is set, keep highlight until its section is at the top
if (scrollTargetLetter) {
const targetSection = sectionList.find(s => s.letter === scrollTargetLetter);
if (targetSection && Math.abs(targetSection.top) < 4) {
setActiveLetter(scrollTargetLetter);
setScrollTargetLetter(null); // Unlock
} else {
setActiveLetter(scrollTargetLetter);
}
return;
}
// Find the section closest to (but not below) the top of viewport, only among expanded
let closest = null;
let minDist = Infinity;
sectionList.forEach(({ letter, top }) => {
if (top <= 150 && Math.abs(top) < minDist) {
minDist = Math.abs(top);
closest = letter;
}
});
// Fallback: if no section is visible, keep the last activeLetter
if (closest) {
setActiveLetter(closest);
}
// else do not update activeLetter, keep last clicked

};
window.addEventListener('scroll', handleScroll, { passive: true });
// Call once to set initial
handleScroll();
return () => window.removeEventListener('scroll', handleScroll);
}, [expandedSections, scrollTargetLetter]);

const toggleSection = (letter) => {
setExpandedSections(prev => ({
...prev,
[letter]: !prev[letter]
}));
};




const entries = {
A: [
{
Expand Down Expand Up @@ -105,7 +182,7 @@ function Glossary() {
S: [
{
name: "Stubs",
ink: "/docs/concepts/reference/glossary/stubs",
link: "/docs/concepts/reference/glossary/stubs",
},
{
name: "Software Testing Life Cycle",
Expand Down Expand Up @@ -139,70 +216,101 @@ function Glossary() {
},
],
};
const {siteConfig, siteMetadata} = useDocusaurusContext;
const handleClick = (index) => {
setState((state) => {
var obj = {
...state,
[index]: !state[index],
};
return obj;
});
};

return (
<Layout
title="About the docs"
title="Glossary | Keploy Documentation"
permalink="/reference/glossary"
description="User General Information about Keploy's Documentation"
description="Comprehensive glossary of testing and development terms used in Keploy documentation"
wrapperClassName="min-h-screen"
>
<main className="margin-vert--lg container flex flex-col justify-evenly">
<div className="pb-5 text-center text-4xl font-bold">Glossary</div>
<div className="flex flex-row justify-evenly">
{new Array(26).fill(0).map((x, i) => (
<button
className={`col-span-1 gap-2 rounded-sm p-3
${
state[String.fromCharCode(65 + i)]
? "text-black-200 rounded-3xl bg-orange-200 font-bold shadow-md hover:text-orange-950 dark:text-orange-900"
: entries[String.fromCharCode(65 + i)] === undefined
? "bg-transparent text-gray-400" // Modified color class
: "bg-grey-200 rounded-3xl shadow-md"
} `}
key={i}
disabled={
entries[String.fromCharCode(65 + i)] === undefined
? true
: false
}
onClick={() => handleClick(String.fromCharCode(65 + i))}
>
{String.fromCharCode(65 + i)}
</button>
))}
<Head>
<meta name="keywords" content="glossary, testing terms, development terms, Keploy, API testing, unit testing" />
</Head>

<main className="container mx-auto px-4 py-8">
<div className="text-center mb-8">
<h1 className="text-3xl md:text-4xl font-bold mb-2">
Developer Glossary
</h1>
<p className="text-gray-600 text-lg opacity-80">
Browse our comprehensive glossary of testing and development terms used throughout Keploy's documentation.
</p>
</div>
<div className="-mb-3 mt-10 flex flex-wrap justify-center gap-4 text-xl font-semibold">
{Object.entries(state).map(([key, value]) => {
return (
<div key={key} className="mb-4 w-1/4">
<div key={key}>{value ? key : ""}</div>
{value ? (
<div className="ml-4 flex flex-col justify-around text-xl">
{entries[key]?.map(({name, link}, i) => (
<a
className="text-orange-600 hover:text-orange-800 hover:underline"
key={i}
href={link}
>
{name}
</a>
))}
</div>
) : (
""
)}

{/* Alphabet Navigation */}
<div className="sticky top-16 z-10 py-4 mb-8 border-b border-gray-200 bg-white/90 backdrop-blur-sm">
<div className="flex flex-wrap justify-center gap-1 sm:gap-2">
{Array.from({ length: 26 }, (_, i) => {
const letter = String.fromCharCode(65 + i);
const hasTerms = entries[letter] !== undefined;
const isActive = expandedSections[letter];

return (
<button
key={letter}
onClick={() => scrollToSection(letter)}
disabled={!hasTerms}
className={clsx(
'w-10 h-10 flex items-center justify-center rounded-lg transition-all duration-200 font-medium',
{
'bg-orange-200 text-orange-900 font-bold shadow-md': activeLetter === letter && hasTerms,
'text-gray-400 cursor-not-allowed': !hasTerms,
'text-gray-700 hover:bg-gray-100': activeLetter !== letter && hasTerms
}
)}
aria-label={`Scroll to ${letter} section`}
>
{letter}
</button>
);
})}
</div>
</div>

{/* Glossary Terms */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{Object.entries(entries).map(([letter, terms]) =>
expandedSections[letter] && (
<div
key={letter}
ref={el => (sectionRefs.current[letter] = el)}
className="space-y-4"
>
<div className="flex items-center mb-4">
<h2 className="text-2xl font-bold text-gray-900">
{letter}
</h2>
<span className="ml-3 text-sm text-gray-500 bg-gray-100 px-2 py-1 rounded-full">
{terms.length} {terms.length === 1 ? 'term' : 'terms'}
</span>
</div>

<div className="space-y-3">
{terms.map(({ name, link }, index) => (
<a
key={index}
href={link}
className="block p-4 bg-white rounded-lg border border-gray-200 hover:border-orange-300 transition-all duration-200 hover:shadow-md"
>
<div className="flex items-center">
<div className="flex-1">
<h3 className="font-medium text-gray-900">
{name}
</h3>
</div>
<div className="ml-2 text-orange-500">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</div>
</div>
</a>
))}
</div>
</div>
);
})}
)
)}
</div>
</main>
</Layout>
Expand Down