mirror of
https://github.com/labring/FastGPT.git
synced 2026-04-27 02:08:10 +08:00
7a6601394d
* doc * feat: Pause Recovery (#6494) * feat: Pause Recovery * agent pause * agent pause * fix:agent pause * fix:agent pause * perf: pause agent call * fix: test --------- Co-authored-by: archer <545436317@qq.com> * fix: image read and json error (Agent) (#6502) * fix: 1.image read 2.JSON parsing error * dataset cite and pause * perf: plancall second parse * add test --------- Co-authored-by: archer <545436317@qq.com> * master message * remove invalid code * fix: pause agent (#6595) * fix: ask and step result * delete console * udpate pnpm version * prettier --------- Co-authored-by: YeYuheng <57035043+YYH211@users.noreply.github.com>
107 lines
2.8 KiB
TypeScript
107 lines
2.8 KiB
TypeScript
'use client';
|
|
|
|
import { Check, Link as LinkIcon } from 'lucide-react';
|
|
import type { ComponentProps} from 'react';
|
|
import { type ReactNode, useEffect, useRef, useState } from 'react';
|
|
import { cn } from '../lib/cn';
|
|
import { useCopyButton } from 'fumadocs-ui/utils/use-copy-button';
|
|
import { buttonVariants } from './ui/button';
|
|
import { mergeRefs } from '../lib/merge-refs';
|
|
import {
|
|
Accordion as Root,
|
|
AccordionContent,
|
|
AccordionHeader,
|
|
AccordionItem,
|
|
AccordionTrigger,
|
|
} from './ui/accordion';
|
|
|
|
export function Accordions({
|
|
type = 'single',
|
|
ref,
|
|
className,
|
|
defaultValue,
|
|
...props
|
|
}: ComponentProps<typeof Root>) {
|
|
const rootRef = useRef<HTMLDivElement>(null);
|
|
const composedRef = mergeRefs(ref, rootRef);
|
|
const [value, setValue] = useState<string | string[]>(() =>
|
|
type === 'single' ? (defaultValue ?? '') : (defaultValue ?? []),
|
|
);
|
|
|
|
useEffect(() => {
|
|
const id = window.location.hash.substring(1);
|
|
const element = rootRef.current;
|
|
if (!element || id.length === 0) return;
|
|
|
|
const selected = document.getElementById(id);
|
|
if (!selected || !element.contains(selected)) return;
|
|
const value = selected.getAttribute('data-accordion-value');
|
|
|
|
if (value) setValue((prev) => (typeof prev === 'string' ? value : [value, ...prev]));
|
|
}, []);
|
|
|
|
return (
|
|
// @ts-expect-error -- Multiple types
|
|
<Root
|
|
type={type}
|
|
ref={composedRef}
|
|
value={value}
|
|
onValueChange={setValue}
|
|
collapsible={type === 'single' ? true : undefined}
|
|
className={cn(
|
|
'divide-y divide-fd-border overflow-hidden rounded-lg border bg-fd-card',
|
|
className,
|
|
)}
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function Accordion({
|
|
title,
|
|
id,
|
|
value = String(title),
|
|
children,
|
|
...props
|
|
}: Omit<ComponentProps<typeof AccordionItem>, 'value' | 'title'> & {
|
|
title: string | ReactNode;
|
|
value?: string;
|
|
}) {
|
|
return (
|
|
<AccordionItem value={value} {...props}>
|
|
<AccordionHeader id={id} data-accordion-value={value}>
|
|
<AccordionTrigger>{title}</AccordionTrigger>
|
|
{id ? <CopyButton id={id} /> : null}
|
|
</AccordionHeader>
|
|
<AccordionContent>
|
|
<div className="px-4 pb-2 text-[0.9375rem] prose-no-margin">{children}</div>
|
|
</AccordionContent>
|
|
</AccordionItem>
|
|
);
|
|
}
|
|
|
|
function CopyButton({ id }: { id: string }) {
|
|
const [checked, onClick] = useCopyButton(() => {
|
|
const url = new URL(window.location.href);
|
|
url.hash = id;
|
|
|
|
return navigator.clipboard.writeText(url.toString());
|
|
});
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
aria-label="Copy Link"
|
|
className={cn(
|
|
buttonVariants({
|
|
color: 'ghost',
|
|
className: 'text-fd-muted-foreground me-2',
|
|
}),
|
|
)}
|
|
onClick={onClick}
|
|
>
|
|
{checked ? <Check className="size-3.5" /> : <LinkIcon className="size-3.5" />}
|
|
</button>
|
|
);
|
|
}
|