diff --git a/packages/devtools/src/components/layout/tools-list/form/templates.tsx b/packages/devtools/src/components/layout/tools-list/form/templates.tsx index b5bc8ecba..c34a8eac0 100644 --- a/packages/devtools/src/components/layout/tools-list/form/templates.tsx +++ b/packages/devtools/src/components/layout/tools-list/form/templates.tsx @@ -1,3 +1,8 @@ +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@alpic-ai/ui/components/tooltip"; import type { ArrayFieldItemTemplateProps, ArrayFieldTemplateProps, @@ -11,7 +16,7 @@ import type { } from "@rjsf/utils"; import { getInputProps } from "@rjsf/utils"; import { Plus, X } from "lucide-react"; -import type { CSSProperties } from "react"; +import type { CSSProperties, ReactNode } from "react"; import { cn } from "@/lib/utils.js"; import { TruncatedDescription } from "../truncated-description.js"; import { @@ -77,6 +82,55 @@ export function BaseInputTemplate(props: BaseInputTemplateProps) { ); } +// A field label whose param description is revealed in a tooltip on hover, so +// descriptions stay accessible in the panel without opening a dialog. Falls +// back to a plain label when the param has no description. +function FieldLabel({ + htmlFor, + label, + required, + description, + className, +}: { + htmlFor?: string; + label: ReactNode; + required?: boolean; + description?: string; + className?: string; +}) { + const content = ( + <> + {label} + {required && *} + + ); + const labelNode = htmlFor ? ( + + ) : ( +
+ {content} +
+ ); + + if (!description) { + return labelNode; + } + + return ( + + {labelNode} + + {description} + + + ); +} + export function FieldTemplate(props: FieldTemplateProps) { const { id, @@ -112,18 +166,19 @@ export function FieldTemplate(props: FieldTemplateProps) { style={style as CSSProperties} > {showLabel && ( - + /> )} - {!rendersOwnTitle && rawDescription ? ( + {/* No label to hang the tooltip on (e.g. array items) — keep it inline. */} + {!rendersOwnTitle && !showLabel && rawDescription ? ( {!isRoot && title && ( -
- {title} - {required && *} -
+ )} - {!isRoot && description && ( + {/* No title to hang the tooltip on — keep the description inline. */} + {!isRoot && !title && description && (

{description}

)} {properties @@ -220,12 +278,17 @@ export function ArrayFieldTemplate(props: ArrayFieldTemplateProps) { return (
{title && ( -
- {title} - {required && *} -
+ + )} + {/* No title to hang the tooltip on — keep the description inline. */} + {!title && description && ( +

{description}

)} - {description &&

{description}

} {/* rjsf v6: items is ReactElement[] (pre-rendered ArrayFieldItemTemplate). */} {items} {canAdd && (