1- import { BoolCodeControl } from "comps/controls/codeControl" ;
1+ import { BoolCodeControl , StringControl } from "comps/controls/codeControl" ;
22import React , { ReactNode , useContext , useRef } from "react" ;
33import { ExternalEditorContext } from "util/context/ExternalEditorContext" ;
44import { Comp , CompParams , MultiBaseComp } from "lowcoder-core" ;
@@ -22,10 +22,14 @@ import {
2222 MethodConfigsType ,
2323 withMethodExposing ,
2424} from "./withMethodExposing" ;
25+ import { Section } from "lowcoder-design" ;
26+ import { trans } from "i18n" ;
2527
2628export type NewChildren < ChildrenCompMap extends Record < string , Comp < unknown > > > =
2729 ChildrenCompMap & {
2830 hidden : InstanceType < typeof BoolCodeControl > ;
31+ className : InstanceType < typeof StringControl > ;
32+ dataTestId : InstanceType < typeof StringControl > ;
2933 } ;
3034
3135export function HidableView ( props : {
@@ -50,12 +54,51 @@ export function HidableView(props: {
5054 }
5155}
5256
57+ export function ExtendedComponentView ( props : {
58+ children : JSX . Element | React . ReactNode ;
59+ className : string ;
60+ dataTestId : string ;
61+ } ) {
62+ if ( ! props . className && ! props . dataTestId ) {
63+ return < > { props . children } </ > ;
64+ }
65+
66+ return (
67+ < div className = { props . className } data-testid = { props . dataTestId } >
68+ { props . children }
69+ </ div >
70+ ) ;
71+ }
72+
73+ export function ExtendedPropertyView <
74+ ChildrenCompMap extends Record < string , Comp < unknown > > ,
75+ > ( props : {
76+ children : JSX . Element | React . ReactNode ,
77+ childrenMap : NewChildren < ChildrenCompMap >
78+ }
79+ ) {
80+ return (
81+ < >
82+ { props . children }
83+ < Section name = { trans ( "prop.component" ) } >
84+ { props . childrenMap . className ?. propertyView ( { label : trans ( "prop.className" ) } ) }
85+ { props . childrenMap . dataTestId ?. propertyView ( { label : trans ( "prop.dataTestId" ) } ) }
86+ </ Section >
87+ </ >
88+ ) ;
89+ }
90+
5391export function uiChildren <
5492 ChildrenCompMap extends Record < string , Comp < unknown > > ,
5593> (
5694 childrenMap : ToConstructor < ChildrenCompMap >
5795) : ToConstructor < NewChildren < ChildrenCompMap > > {
58- return { ...childrenMap , hidden : BoolCodeControl } as any ;
96+ return {
97+ ...childrenMap ,
98+ hidden : BoolCodeControl ,
99+ className : StringControl ,
100+ dataTestId : StringControl
101+ } as any ;
59102}
60103
61104type ViewReturn = ReactNode ;
@@ -89,10 +132,22 @@ export class UICompBuilder<
89132 setPropertyViewFn (
90133 propertyViewFn : PropertyViewFnTypeForComp < NewChildren < ChildrenCompMap > >
91134 ) {
92- this . propertyViewFn = propertyViewFn ;
135+ this . propertyViewFn = this . decoratePropertyViewFn ( propertyViewFn ) ;
93136 return this ;
94137 }
95138
139+ decoratePropertyViewFn (
140+ propertyViewFn : PropertyViewFnTypeForComp < NewChildren < ChildrenCompMap > >
141+ ) : PropertyViewFnTypeForComp < NewChildren < ChildrenCompMap > > {
142+ return ( childrenMap , dispatch ) => {
143+ return (
144+ < ExtendedPropertyView childrenMap = { childrenMap } >
145+ { propertyViewFn ( childrenMap , dispatch ) }
146+ </ ExtendedPropertyView >
147+ ) ;
148+ } ;
149+ }
150+
96151 setExposeStateConfigs (
97152 configs : ExposingConfig < ChildrenToComp < ChildrenCompMap > > [ ]
98153 ) {
@@ -110,8 +165,11 @@ export class UICompBuilder<
110165 }
111166
112167 build ( ) {
113- if ( this . childrenMap . hasOwnProperty ( "hidden" ) ) {
114- throw new Error ( "already has hidden" ) ;
168+ const reservedProps = [ "hidden" , "className" , "dataTestId" ] ;
169+ for ( const reservedProp of reservedProps ) {
170+ if ( this . childrenMap . hasOwnProperty ( reservedProp ) ) {
171+ throw new Error ( `Property »${ reservedProp } « is reserved and must not be implemented in components!` ) ;
172+ }
115173 }
116174 const newChildrenMap = uiChildren ( this . childrenMap ) ;
117175 const builder = this ;
@@ -122,7 +180,7 @@ export class UICompBuilder<
122180 ToNodeType < NewChildren < ChildrenCompMap > >
123181 > {
124182 ref : React . RefObject < HTMLDivElement > = React . createRef ( ) ;
125-
183+
126184 override parseChildrenFromValue (
127185 params : CompParams < ToDataType < NewChildren < ChildrenCompMap > > >
128186 ) : NewChildren < ChildrenCompMap > {
@@ -185,8 +243,13 @@ function UIView(props: { comp: any; viewFn: any }) {
185243 //END ADD BY FRED
186244
187245 return (
188- < HidableView hidden = { childrenProps . hidden as boolean } >
189- { props . viewFn ( childrenProps , comp . dispatch ) }
190- </ HidableView >
246+ < ExtendedComponentView
247+ className = { childrenProps . className as string }
248+ dataTestId = { childrenProps . dataTestId as string }
249+ >
250+ < HidableView hidden = { childrenProps . hidden as boolean } >
251+ { props . viewFn ( childrenProps , comp . dispatch ) }
252+ </ HidableView >
253+ </ ExtendedComponentView >
191254 ) ;
192255}
0 commit comments