1- /* eslint-disable @typescript-eslint/no-explicit-any */
2- import { renderAnyToString } from "@/lib/strings " ;
1+ import { isArray , isObject , isString } from "@/lib/type-guards" ;
2+ import { isUrl } from "@/lib/url " ;
33import { CollapsibleHeaderProps } from "@zenml-io/react-component-library" ;
44import {
55 Tooltip ,
@@ -14,7 +14,7 @@ import { KeyValue } from "./KeyValue";
1414
1515type Props = {
1616 intent ?: CollapsibleHeaderProps [ "intent" ] ;
17- data ?: { [ key : string ] : any } ;
17+ data ?: { [ key : string ] : unknown } ;
1818 title : ReactNode ;
1919 contentClassName ?: string ;
2020 className ?: string ;
@@ -30,15 +30,15 @@ export function NestedCollapsible({
3030 children,
3131 className
3232} : PropsWithChildren < Props > ) {
33- const objects : { [ key : string ] : any } = { } ;
34- const nonObjects : { [ key : string ] : any } = { } ;
35- const arrays : { [ key : string ] : any } = { } ;
33+ const objects : { [ key : string ] : Record < string , unknown > } = { } ;
34+ const nonObjects : { [ key : string ] : unknown } = { } ;
35+ const arrays : { [ key : string ] : unknown [ ] } = { } ;
3636 const regex = / ^ < c l a s s \s + ' .* ' > $ / ;
3737
3838 for ( const [ key , value ] of Object . entries ( data || { } ) ) {
39- if ( typeof value === "object" && value !== null && ! Array . isArray ( value ) ) {
40- objects [ key ] = value ;
41- } else if ( Array . isArray ( value ) ) {
39+ if ( isObject ( value ) ) {
40+ objects [ key ] = value as Record < string , unknown > ;
41+ } else if ( isArray ( value ) ) {
4242 arrays [ key ] = value ;
4343 } else {
4444 nonObjects [ key ] = value ;
@@ -74,14 +74,23 @@ export function NestedCollapsible({
7474 }
7575 value = {
7676 < >
77- { typeof value === "boolean" ? (
78- < div className = "py-1" > { JSON . stringify ( value ) } </ div >
79- ) : regex . test ( value ) ? (
77+ { isString ( value ) && regex . test ( value ) ? (
8078 < Codesnippet className = "py-1" highlightCode code = { value } />
8179 ) : value === null ? (
82- < div className = "overflow-x-auto" > null</ div >
80+ < div > null</ div >
81+ ) : isString ( value ) && isUrl ( value ) ? (
82+ < a
83+ className = "underline transition-all duration-200 hover:decoration-transparent"
84+ href = { value }
85+ target = "_blank"
86+ rel = "noopener noreferrer"
87+ >
88+ { value }
89+ </ a >
8390 ) : (
84- < div className = "overflow-x-auto py-1" > { value } </ div >
91+ < div className = "whitespace-normal" >
92+ { isString ( value ) ? value : JSON . stringify ( value ) }
93+ </ div >
8594 ) }
8695 </ >
8796 }
@@ -101,13 +110,11 @@ export function NestedCollapsible({
101110 ) ;
102111}
103112
104- function RenderArray ( { title, value } : { title : string ; value : any } ) {
105- const simpleValues : any [ ] = value . filter (
106- ( val : any ) => ( ! Array . isArray ( val ) && typeof val !== "object" ) || val === null
107- ) ;
108- const nestedValues : any [ ] = value . filter (
109- ( val : any ) => Array . isArray ( val ) || typeof val === "object"
113+ function RenderArray ( { title, value } : { title : string ; value : unknown [ ] } ) {
114+ const simpleValues : unknown [ ] = value . filter (
115+ ( val ) => ( ! isArray ( val ) && ! isObject ( val ) ) || val === null
110116 ) ;
117+ const nestedValues : unknown [ ] = value . filter ( ( val ) => isArray ( val ) || isObject ) ;
111118
112119 return (
113120 < >
@@ -125,16 +132,40 @@ function RenderArray({ title, value }: { title: string; value: any }) {
125132 </ Tooltip >
126133 </ TooltipProvider >
127134 }
128- value = { < div className = "py-1" > { renderAnyToString ( value ) } </ div > }
135+ value = {
136+ < div className = "py-1" >
137+ { value === null ? (
138+ < div > null</ div >
139+ ) : isString ( value ) && isUrl ( value ) ? (
140+ < a
141+ className = "underline transition-all duration-200 hover:decoration-transparent"
142+ href = { value }
143+ target = "_blank"
144+ rel = "noopener noreferrer"
145+ >
146+ { value }
147+ </ a >
148+ ) : (
149+ < div className = "whitespace-normal" >
150+ { isString ( value ) ? value : JSON . stringify ( value ) }
151+ </ div >
152+ ) }
153+ </ div >
154+ }
129155 />
130156 ) ) }
131157 </ dl >
132158 ) }
133159 { nestedValues . length > 0 && (
134160 < ul className = "space-y-4" >
135- { nestedValues . map ( ( val : any , index : number ) => (
161+ { nestedValues . map ( ( val , index : number ) => (
136162 < li key = { index } >
137- < NestedCollapsible intent = "secondary" key = { index } title = { index } data = { val } />
163+ < NestedCollapsible
164+ intent = "secondary"
165+ key = { index }
166+ title = { index }
167+ data = { val as Record < string , Record < string , unknown > | unknown [ ] > }
168+ />
138169 </ li >
139170 ) ) }
140171 </ ul >
0 commit comments