1
- import { BoolCodeControl } from "comps/controls/codeControl" ;
1
+ import { BoolCodeControl , StringControl } from "comps/controls/codeControl" ;
2
2
import React , { ReactNode , useContext , useRef } from "react" ;
3
3
import { ExternalEditorContext } from "util/context/ExternalEditorContext" ;
4
4
import { Comp , CompParams , MultiBaseComp } from "lowcoder-core" ;
@@ -22,10 +22,14 @@ import {
22
22
MethodConfigsType ,
23
23
withMethodExposing ,
24
24
} from "./withMethodExposing" ;
25
+ import { Section } from "lowcoder-design" ;
26
+ import { trans } from "i18n" ;
25
27
26
28
export type NewChildren < ChildrenCompMap extends Record < string , Comp < unknown > > > =
27
29
ChildrenCompMap & {
28
30
hidden : InstanceType < typeof BoolCodeControl > ;
31
+ className : InstanceType < typeof StringControl > ;
32
+ dataTestId : InstanceType < typeof StringControl > ;
29
33
} ;
30
34
31
35
export function HidableView ( props : {
@@ -50,12 +54,51 @@ export function HidableView(props: {
50
54
}
51
55
}
52
56
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
+
53
91
export function uiChildren <
54
92
ChildrenCompMap extends Record < string , Comp < unknown > > ,
55
93
> (
56
94
childrenMap : ToConstructor < ChildrenCompMap >
57
95
) : 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 ;
59
102
}
60
103
61
104
type ViewReturn = ReactNode ;
@@ -89,10 +132,22 @@ export class UICompBuilder<
89
132
setPropertyViewFn (
90
133
propertyViewFn : PropertyViewFnTypeForComp < NewChildren < ChildrenCompMap > >
91
134
) {
92
- this . propertyViewFn = propertyViewFn ;
135
+ this . propertyViewFn = this . decoratePropertyViewFn ( propertyViewFn ) ;
93
136
return this ;
94
137
}
95
138
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
+
96
151
setExposeStateConfigs (
97
152
configs : ExposingConfig < ChildrenToComp < ChildrenCompMap > > [ ]
98
153
) {
@@ -110,8 +165,11 @@ export class UICompBuilder<
110
165
}
111
166
112
167
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
+ }
115
173
}
116
174
const newChildrenMap = uiChildren ( this . childrenMap ) ;
117
175
const builder = this ;
@@ -122,7 +180,7 @@ export class UICompBuilder<
122
180
ToNodeType < NewChildren < ChildrenCompMap > >
123
181
> {
124
182
ref : React . RefObject < HTMLDivElement > = React . createRef ( ) ;
125
-
183
+
126
184
override parseChildrenFromValue (
127
185
params : CompParams < ToDataType < NewChildren < ChildrenCompMap > > >
128
186
) : NewChildren < ChildrenCompMap > {
@@ -185,8 +243,13 @@ function UIView(props: { comp: any; viewFn: any }) {
185
243
//END ADD BY FRED
186
244
187
245
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 >
191
254
) ;
192
255
}
0 commit comments