refactor: Migrate documentation content, rebuild UI components, and update core architecture.
This commit is contained in:
@@ -1,62 +1,61 @@
|
||||
"use client";
|
||||
"use client"
|
||||
|
||||
import { ReactNode, useState, useContext } from 'react';
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
import * as Icons from "lucide-react";
|
||||
import { cn } from '@/lib/utils';
|
||||
import { AccordionGroupContext } from '@/components/contexts/AccordionContext';
|
||||
import { ReactNode, useContext, useState } from "react"
|
||||
import { ChevronRight } from "lucide-react"
|
||||
import * as Icons from "lucide-react"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { AccordionGroupContext } from "@/components/markdown/AccordionContext"
|
||||
|
||||
type AccordionProps = {
|
||||
title: string;
|
||||
children?: ReactNode;
|
||||
defaultOpen?: boolean;
|
||||
icon?: keyof typeof Icons;
|
||||
};
|
||||
title: string
|
||||
children?: ReactNode
|
||||
icon?: keyof typeof Icons
|
||||
}
|
||||
|
||||
const Accordion: React.FC<AccordionProps> = ({
|
||||
title,
|
||||
children,
|
||||
defaultOpen = false,
|
||||
icon,
|
||||
}: AccordionProps) => {
|
||||
const groupContext = useContext(AccordionGroupContext);
|
||||
const isInGroup = groupContext?.inGroup === true;
|
||||
const [isOpen, setIsOpen] = useState(defaultOpen);
|
||||
const Icon = icon ? (Icons[icon] as React.FC<{ className?: string }>) : null;
|
||||
const Accordion: React.FC<AccordionProps> = ({ title, children, icon }: AccordionProps) => {
|
||||
const groupContext = useContext(AccordionGroupContext)
|
||||
const isInGroup = groupContext?.inGroup === true
|
||||
const groupOpen = groupContext?.openTitle === title
|
||||
const setGroupOpen = groupContext?.setOpenTitle
|
||||
const [localOpen, setLocalOpen] = useState(false)
|
||||
|
||||
// The main wrapper div for the accordion.
|
||||
// All styling logic for the accordion container is handled here.
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
// Style for STANDALONE: full card with border & shadow
|
||||
!isInGroup && "border rounded-lg shadow-sm",
|
||||
// Style for IN GROUP: only a bottom border separator
|
||||
isInGroup && "border-b last:border-b-0 border-border"
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
className="flex items-center gap-2 w-full px-4 h-12 transition-colors bg-muted/40 dark:bg-muted/20 hover:bg-muted/70 dark:hover:bg-muted/70"
|
||||
>
|
||||
<ChevronRight
|
||||
className={cn(
|
||||
"w-4 h-4 text-muted-foreground transition-transform duration-200 flex-shrink-0",
|
||||
isOpen && "rotate-90"
|
||||
)}
|
||||
/>
|
||||
{Icon && <Icon className="text-foreground w-4 h-4 flex-shrink-0" />}
|
||||
<h3 className="font-medium text-base text-foreground !m-0 leading-none">{title}</h3>
|
||||
</button>
|
||||
const isOpen = isInGroup ? groupOpen : localOpen
|
||||
|
||||
{isOpen && (
|
||||
<div className="px-4 py-3 dark:bg-muted/10 bg-muted/15">
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
const handleToggle = () => {
|
||||
if (isInGroup && setGroupOpen) {
|
||||
setGroupOpen(groupOpen ? null : title)
|
||||
} else {
|
||||
setLocalOpen(!localOpen)
|
||||
}
|
||||
}
|
||||
|
||||
export default Accordion;
|
||||
const Icon = icon ? (Icons[icon] as React.FC<{ className?: string }>) : null
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
!isInGroup && "rounded-lg border shadow-sm",
|
||||
isInGroup && "border-border border-b last:border-b-0"
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleToggle}
|
||||
className="bg-muted/40 dark:bg-muted/20 hover:bg-muted/70 dark:hover:bg-muted/70 flex w-full cursor-pointer items-center gap-2 px-4 py-3 text-start transition-colors"
|
||||
>
|
||||
<ChevronRight
|
||||
className={cn(
|
||||
"text-muted-foreground h-4 w-4 shrink-0 transition-transform duration-200",
|
||||
isOpen && "rotate-90"
|
||||
)}
|
||||
/>
|
||||
{Icon && <Icon className="text-foreground h-4 w-4 shrink-0" />}
|
||||
<h3 className="text-foreground m-0! text-base font-medium">{title}</h3>
|
||||
</button>
|
||||
|
||||
{isOpen && <div className="dark:bg-muted/10 bg-muted/15 px-4 py-3">{children}</div>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Accordion
|
||||
|
||||
Reference in New Issue
Block a user