diff --git a/src/App.jsx b/src/App.jsx index 068a08b..5f49d4c 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -3,6 +3,8 @@ import "./App.css"; import Navbar from "./Components/Navbar/Navbar"; import challenges from "./challenges"; import Card from "./Components/Card/Card"; +import Accordian from "./Components/Accordian/Accordian"; +import { faqs } from "./Components/Accordian/accordianDummyArray"; const App = () => { const [component, setComponent] = useState(null); @@ -25,7 +27,7 @@ const App = () => { onClick={(component, source, name) => { setComponent(component); setSourceLink(source); - setChallengeName(name) + setChallengeName(name); }} component={value.component} /> @@ -34,7 +36,11 @@ const App = () => {
{component}
- {component && {challengeName} Source Code} + {component && ( + + {challengeName} Source Code + + )} {component && (
+ +
+ +
); }; diff --git a/src/Components/Accordian/Accordian.css b/src/Components/Accordian/Accordian.css new file mode 100644 index 0000000..fc659cc --- /dev/null +++ b/src/Components/Accordian/Accordian.css @@ -0,0 +1,53 @@ +.Accordian-container{ + width: 100%; + background-color: #f0f0f0; + + + .AccordianItem-container{ + border-bottom: 1px solid black; + overflow: hidden; + } + + .AccordianItem-container .question-container { + width: 100%; + text-align: left; + padding: 20px 10px; + display: flex; + align-items: center; + justify-content: space-between; + font-weight: 500; + font-size: 20px; + background: transparent; + border: none; + cursor: pointer; + } + + .question-container.active { + background-image: linear-gradient(90deg,transparent,rgba(0,0,0,0.04),transparent); + } + + .AccordianItem-container .question-container:hover { + background-image: linear-gradient(90deg,transparent,rgba(0,0,0,0.04),transparent); + } + + .AccordianItem-container .arrow { + width: 25px; + height: 25px; + transition: .5s ease-in-out; + } + + .arrow.active { + rotate: 180deg; + } + + .AccordianItem-container .answer-container { + padding: 0 1rem; + transition: height .4s ease-in-out; + } + + .AccordianItem-container .answer-content { + padding: 1rem 0; + font-size: 20px; + } +} + diff --git a/src/Components/Accordian/Accordian.jsx b/src/Components/Accordian/Accordian.jsx new file mode 100644 index 0000000..a38287c --- /dev/null +++ b/src/Components/Accordian/Accordian.jsx @@ -0,0 +1,50 @@ +import React, { useRef, useState } from "react"; +import "./Accordian.css"; +import DownArrow from "../../assets/downArrow.svg"; +const AccordianItem = ({ question, answer, isOpen, onClick }) => { + const contentHeight = useRef(); + return ( +
+ +
+
{answer}
+
+
+ ); +}; + +const Accordian = ({ accordianContent }) => { + const [activeIndex, setActiveIndex] = useState(null); + + const handleItemClick = (index) => { + setActiveIndex((prevIndex) => (prevIndex === index ? null : index)); + }; + return ( +
+ {accordianContent.map((item, index) => ( + handleItemClick(index)} + /> + ))} +
+ ); +}; + +export default Accordian; diff --git a/src/Components/Accordian/AccordianContext.js b/src/Components/Accordian/AccordianContext.js new file mode 100644 index 0000000..9ce08ff --- /dev/null +++ b/src/Components/Accordian/AccordianContext.js @@ -0,0 +1,68 @@ +import userEvent from "@testing-library/user-event"; +import { createContext, useEffect, useRef, useState } from "react"; + +export const AccordianContext = createContext({}); + +const AccordianContextProvider = ({ key, defaultValue, content, children }) => { + const [isCollapsed, setIsCollapsed] = useState(false); + const [maxHeight, setMaxHeight] = useState(); + const collapseContentDivRef = useRef(); + const isProcessingRef = useRef(false); + + useEffect(() => { + setMaxHeight(collapseContentDivRef.current.clientHeight); + toggleCollapse(); + }, []); + + useEffect(() => { + _toggleCollapse(defaultValue); + }, [defaultValue]); + + const toggleCollapse = () => { + _toggleCollapse(isCollapsed); + }; + + const _toggleCollapse = (value) => { + if (isProcessingRef.current) return; + if (!content) return; + setIsCollapsed(!value); + isProcessingRef.current = true; + + if (value) { + // is expand. need to transition to collapse + // save maxHeight when full content is expanded + // height is unset + // set height to max height + // after timeout set height to 0 + setMaxHeight(collapseContentDivRef.current.clientHeight); + collapseContentDivRef.current.style.maxHeight = + collapseContentDivRef.current.clientHeight + "px"; + setTimeout(() => { + collapseContentDivRef.current.style.maxHeight = 0 + "px"; + isProcessingRef.current = false; + }, 100); + } else { + // is collapsed. need to transition to expand. + // height is 0 + // set height to max height + // after settimout set height to unset + collapseContentDivRef.current.style.maxHeight = maxHeight + "px"; + setMaxHeight(collapseContentDivRef.current.clientHeight); + setTimeout(() => { + collapseContentDivRef.current.style.maxHeight = "unset"; + isProcessingRef.current = false; + }, 100); + } + }; + + return ( + + {children} + + ); +}; + +export default AccordianContextProvider diff --git a/src/Components/Accordian/accordianDummyArray.js b/src/Components/Accordian/accordianDummyArray.js new file mode 100644 index 0000000..6eebfad --- /dev/null +++ b/src/Components/Accordian/accordianDummyArray.js @@ -0,0 +1,14 @@ +export const faqs = [ + { + question: "What is your name", + answer: `Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore vel vitae, illo ducimus eius, ut eos dolorum earum aut officiis ratione nemo libero dolores asperiores accusantium veritatis voluptatem provident minus.`, + }, + { + question: "What is your fathers name", + answer: `Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore vel vitae, illo ducimus eius, ut eos dolorum earum aut officiis ratione nemo libero dolores asperiores accusantium veritatis voluptatem provident minus.`, + }, + { + question: "What is your mothers name", + answer: `Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore vel vitae, illo ducimus eius, ut eos dolorum earum aut officiis ratione nemo libero dolores asperiores accusantium veritatis voluptatem provident minus.`, + }, +]; diff --git a/src/assets/downArrow.svg b/src/assets/downArrow.svg new file mode 100644 index 0000000..a272fb5 --- /dev/null +++ b/src/assets/downArrow.svg @@ -0,0 +1 @@ + \ No newline at end of file