1+ import { useState } from "react" ;
12import type { SchemaObject } from "../../../oas/parser/index.js" ;
23import { Badge } from "../../../ui/Badge.js" ;
34import { Card } from "../../../ui/Card.js" ;
4- import { Tabs , TabsContent , TabsList , TabsTrigger } from "../../../ui/Tabs .js" ;
5+ import { cn } from "../../../util/cn .js" ;
56import { SchemaView } from "./SchemaView.js" ;
67import {
78 decideExclusivity ,
@@ -13,9 +14,13 @@ import {
1314const DecisionTable = ( {
1415 variants,
1516 schema,
17+ selectedVariant,
18+ onSelectVariant,
1619} : {
1720 variants : SchemaObject [ ] ;
1821 schema : SchemaObject ;
22+ selectedVariant : string ;
23+ onSelectVariant : ( label : string ) => void ;
1924} ) => {
2025 const rows = variants . map ( ( v , i ) => ( {
2126 label : labelForVariant ( i , v ) ,
@@ -36,7 +41,18 @@ const DecisionTable = ({
3641 < tbody className = "divide-y" >
3742 { rows . map ( ( row ) => (
3843 < tr key = { row . label } className = "hover:bg-muted/30" >
39- < td className = "p-2 font-medium" > { row . label } </ td >
44+ < td className = "p-2 font-medium" >
45+ < button
46+ type = "button"
47+ className = { cn (
48+ "hover:underline" ,
49+ selectedVariant === row . label && "text-primary" ,
50+ ) }
51+ onClick = { ( ) => onSelectVariant ( row . label ) }
52+ >
53+ { row . label }
54+ </ button >
55+ </ td >
4056 < td className = "p-2 text-muted-foreground text-xs" >
4157 { row . guards . length > 0
4258 ? row . guards . join ( " · " )
@@ -51,14 +67,16 @@ const DecisionTable = ({
5167 ) ;
5268} ;
5369
54- const VariantPanel = ( { variant } : { variant : SchemaObject } ) => (
55- < div className = "my-4" >
56- { variant . description && (
57- < p className = "text-sm text-muted-foreground" > { variant . description } </ p >
58- ) }
59- < SchemaView schema = { variant } />
60- </ div >
61- ) ;
70+ const VariantPanel = ( { variant } : { variant : SchemaObject } ) => {
71+ return (
72+ < div className = "space-y-2" >
73+ { variant . description && (
74+ < p className = "text-sm text-muted-foreground" > { variant . description } </ p >
75+ ) }
76+ < SchemaView schema = { variant } />
77+ </ div >
78+ ) ;
79+ } ;
6280
6381export const UnionView = ( { schema } : { schema : SchemaObject } ) => {
6482 const mode = Array . isArray ( schema . oneOf )
@@ -67,10 +85,14 @@ export const UnionView = ({ schema }: { schema: SchemaObject }) => {
6785 ? "anyOf"
6886 : undefined ;
6987
88+ const variants = mode ? unionVariants ( schema ) : [ ] ;
89+ const [ selectedVariant , setSelectedVariant ] = useState ( ( ) =>
90+ variants [ 0 ] ? labelForVariant ( 0 , variants [ 0 ] ) : "" ,
91+ ) ;
92+
7093 if ( ! mode ) return null ;
7194
7295 const exclusivity = decideExclusivity ( schema ) ;
73- const variants = unionVariants ( schema ) ;
7496
7597 const semanticsMessage =
7698 exclusivity === "exactly-one" ? (
@@ -84,8 +106,14 @@ export const UnionView = ({ schema }: { schema: SchemaObject }) => {
84106 </ >
85107 ) ;
86108
109+ const currentVariantIndex = variants . findIndex (
110+ ( v , i ) => labelForVariant ( i , v ) === selectedVariant ,
111+ ) ;
112+ const currentVariant =
113+ currentVariantIndex >= 0 ? variants [ currentVariantIndex ] : null ;
114+
87115 return (
88- < Card className = "overflow-hidden" >
116+ < Card className = "overflow-hidden text-sm " >
89117 < div className = "flex flex-col gap-4 p-4" >
90118 < div className = "flex items-center gap-2" >
91119 < Badge variant = "outline" > { mode } </ Badge >
@@ -94,30 +122,15 @@ export const UnionView = ({ schema }: { schema: SchemaObject }) => {
94122 </ div >
95123 </ div >
96124
97- < DecisionTable variants = { variants } schema = { schema } />
125+ < DecisionTable
126+ variants = { variants }
127+ schema = { schema }
128+ selectedVariant = { selectedVariant }
129+ onSelectVariant = { setSelectedVariant }
130+ />
131+ < strong > Properties for { selectedVariant } :</ strong >
132+ { currentVariant && < VariantPanel variant = { currentVariant } /> }
98133 </ div >
99- < Tabs defaultValue = "0" className = "w-full px-4" >
100- < TabsList className = "flex w-full" >
101- { variants . map ( ( v , i ) => (
102- < TabsTrigger
103- key = { labelForVariant ( i , v ) }
104- value = { String ( i ) }
105- className = "flex-1"
106- >
107- { labelForVariant ( i , v ) }
108- </ TabsTrigger >
109- ) ) }
110- </ TabsList >
111- { variants . map ( ( v , i ) => (
112- < TabsContent
113- key = { labelForVariant ( i , v ) }
114- value = { String ( i ) }
115- className = "px-2"
116- >
117- < VariantPanel variant = { v } />
118- </ TabsContent >
119- ) ) }
120- </ Tabs >
121134 </ Card >
122135 ) ;
123136} ;
0 commit comments