@@ -21,12 +21,12 @@ type Flag = "reactive" | "template-driven" | "event";
2121type ComponentType = "goa" | "codesnippet" ;
2222type Serializer = ( el : any , properties : ComponentBinding [ ] ) => string ;
2323
24- interface SandboxProps {
24+ interface SandboxProps < T = Record < string , unknown > > {
2525 properties ?: ComponentBinding [ ] ;
2626 formItemProperties ?: ComponentBinding [ ] ;
2727 note ?: string | { type ?: GoabCalloutType ; heading ?: string ; content : string } ;
2828 fullWidth ?: boolean ;
29- onChange ?: ( bindings : ComponentBinding [ ] , props : Record < string , unknown > ) => void ;
29+ onChange ?: ( bindings : ComponentBinding [ ] , props : T ) => void ;
3030 onChangeFormItemBindings ?: ( bindings : ComponentBinding [ ] , props : Record < string , unknown > ) => void ;
3131 flags ?: Flag [ ] ;
3232 skipRender ?: boolean ; // prevent rendering the snippet, to allow custom code to be shown
@@ -41,11 +41,11 @@ interface SandboxProps {
4141
4242type SandboxViewProps = {
4343 fullWidth ?: boolean ;
44- sandboxProps : SandboxProps ;
44+ sandboxProps : SandboxProps < unknown > ;
4545 background ?: string ;
4646} ;
4747
48- export const Sandbox = ( props : SandboxProps ) => {
48+ export const Sandbox = < T = Record < string , unknown > , > ( props : SandboxProps < T > ) => {
4949 const { language : lang , version} = useContext ( LanguageVersionContext ) ;
5050 const [ formatLang , setFormatLang ] = useState < string > ( "" ) ;
5151
@@ -92,10 +92,20 @@ export const Sandbox = (props: SandboxProps) => {
9292 }
9393
9494 function onChangeFormItemBindings ( bindings : ComponentBinding [ ] ) {
95- props . onChangeFormItemBindings ?.( bindings , toKeyValue ( bindings ) ) ;
95+ props . onChangeFormItemBindings ?.( bindings , toFormItemKeyValue ( bindings ) ) ;
9696 }
9797
98- function toKeyValue ( bindings : ComponentBinding [ ] ) {
98+ function toKeyValue ( bindings : ComponentBinding [ ] ) : T {
99+ return bindings . reduce ( ( acc : Record < string , unknown > , prop : ComponentBinding ) => {
100+ if ( typeof prop . value === "string" && prop . value === "" ) {
101+ return acc ;
102+ }
103+ acc [ prop . name ] = prop . value ;
104+ return acc ;
105+ } , { } ) as unknown as T ;
106+ }
107+
108+ function toFormItemKeyValue ( bindings : ComponentBinding [ ] ) : Record < string , unknown > {
99109 return bindings . reduce ( ( acc : Record < string , unknown > , prop : ComponentBinding ) => {
100110 if ( typeof prop . value === "string" && prop . value === "" ) {
101111 return acc ;
@@ -117,7 +127,7 @@ export const Sandbox = (props: SandboxProps) => {
117127
118128 return (
119129 < >
120- { props . skipRenderDom ? null : < SandboxView fullWidth = { props . fullWidth } sandboxProps = { props } background = { props . background } /> }
130+ { props . skipRenderDom ? null : < SandboxView fullWidth = { props . fullWidth } sandboxProps = { props as SandboxProps < unknown > } background = { props . background } /> }
121131
122132 { /* Only render the GoAAccordion if props.properties is provided */ }
123133 { props . properties && props . properties . length > 0 && (
@@ -141,7 +151,7 @@ export const Sandbox = (props: SandboxProps) => {
141151 />
142152 </ GoabAccordion >
143153 ) }
144- < SandboxCode props = { props } formatLang = { formatLang } lang = { lang } serializers = { serializers } version = { version } />
154+ < SandboxCode props = { props as SandboxProps < unknown > } formatLang = { formatLang } lang = { lang } serializers = { serializers } version = { version } />
145155 { props . note &&
146156 ( typeof props . note === "string" ? (
147157 < p className = "sandbox-note" > { props . note } </ p >
@@ -162,7 +172,7 @@ export const Sandbox = (props: SandboxProps) => {
162172} ;
163173
164174type SandboxCodeProps = {
165- props : SandboxProps & { children : ReactNode } ;
175+ props : SandboxProps < unknown > & { children : ReactNode } ;
166176 lang : string ;
167177 formatLang : string ;
168178 serializers : Record < string , Serializer > ;
@@ -246,7 +256,7 @@ function SandboxCode(p: SandboxCodeProps) {
246256// to be displayed, while hiding the non-reactive ones
247257type AdditionalCodeSnippetsProps = {
248258 tags : string [ ] ;
249- sandboxProps : SandboxProps ;
259+ sandboxProps : SandboxProps < unknown > ;
250260}
251261function AdditionalCodeSnippets ( props : AdditionalCodeSnippetsProps ) {
252262 const matches = ( list : string [ ] ) : boolean => {
@@ -275,7 +285,7 @@ function AdditionalCodeSnippets(props: AdditionalCodeSnippetsProps) {
275285// Filters components from within the Sandbox children
276286// i.e. Get all the <CodeSnippet> components
277287type ComponentListProps = {
278- sandboxProps : SandboxProps ;
288+ sandboxProps : SandboxProps < unknown > ;
279289 type : ComponentType ;
280290}
281291function ComponentList ( props : ComponentListProps ) : ReactElement [ ] {
@@ -295,7 +305,7 @@ function ComponentList(props: ComponentListProps): ReactElement[] {
295305type ComponentOutputProps = {
296306 formatLang : string ;
297307 type : "angular" | "angular-reactive" | "angular-template-driven" | "react" ;
298- sandboxProps : SandboxProps ;
308+ sandboxProps : SandboxProps < unknown > ;
299309 serializer : Serializer ;
300310}
301311
0 commit comments