@@ -11,6 +11,15 @@ interface FormBuilderProps {
1111 onChange : ( source : string ) => void ;
1212}
1313
14+ const COMPONENT_PALETTE : { type : string ; icon : string ; name : string ; description : string } [ ] = [
15+ { type : 'LABEL' , icon : '📝' , name : 'Label' , description : 'Informational text' } ,
16+ { type : 'INPUT' , icon : '✏️' , name : 'Text Field' , description : 'Text input' } ,
17+ { type : 'DROPDOWN' , icon : '📋' , name : 'Dropdown' , description : 'List of options' } ,
18+ { type : 'TOGGLE' , icon : '🔘' , name : 'Toggle' , description : 'True/False' } ,
19+ { type : 'SLIDER' , icon : '🎚️' , name : 'Slider' , description : 'Numeric value' } ,
20+ { type : 'STEPSLIDER' , icon : '📊' , name : 'Step Slider' , description : 'Preset steps' } ,
21+ ] ;
22+
1423const FORM_TYPES : { value : string ; label : string } [ ] = [
1524 { value : 'SIMPLE' , label : 'SIMPLE - Button List' } ,
1625 { value : 'MODAL' , label : 'MODAL - Dialog (2 Buttons)' } ,
@@ -48,6 +57,12 @@ export function FormBuilder({ source, onChange }: FormBuilderProps) {
4857 const isCustom = menu . type . toUpperCase ( ) === 'CUSTOM' ;
4958 const atModalLimit = menu . type . toUpperCase ( ) === 'MODAL' && Object . keys ( menu . buttons ) . length >= 2 ;
5059
60+ const addComponent = ( type : string ) : void => {
61+ const key = nextKey ( menu . components , 'component' ) ;
62+ commit ( { ...menu , components : { ...menu . components , [ key ] : { type, text : '' } } } ) ;
63+ setSelected ( { kind : 'component' , key } ) ;
64+ } ;
65+
5166 const addElement = ( ) : void => {
5267 if ( isCustom ) {
5368 const key = nextKey ( menu . components , 'component' ) ;
@@ -64,9 +79,9 @@ export function FormBuilder({ source, onChange }: FormBuilderProps) {
6479
6580 return (
6681 < div className = "bedrock-form-builder" >
67- < div className = "bedrock-form -preview-main " >
68- < div className = "bedrock-form -screen" >
69- < div className = "bedrock-screen -content" >
82+ < div className = "bedrock-mobile -preview" >
83+ < div className = "bedrock-mobile -screen" >
84+ < div className = "bedrock-mobile -content" >
7085 < div
7186 className = "bedrock-form-title"
7287 dangerouslySetInnerHTML = { { __html : parseMiniMessage ( menu . menuName || 'Form Title' ) } }
@@ -82,7 +97,7 @@ export function FormBuilder({ source, onChange }: FormBuilderProps) {
8297 ) ) }
8398 </ div >
8499
85- < div className = " bedrock-form-elements" >
100+ < div className = { isCustom ? ' bedrock-form-components' : 'bedrock-form-buttons' } >
86101 { isCustom
87102 ? Object . entries ( menu . components ) . map ( ( [ key , component ] ) => (
88103 < div
@@ -187,17 +202,42 @@ export function FormBuilder({ source, onChange }: FormBuilderProps) {
187202 />
188203 </ div >
189204
190- < div className = "bedrock-setting-section" >
191- < button
192- type = "button"
193- className = "btn btn-primary"
194- style = { { width : '100%' } }
195- disabled = { atModalLimit }
196- onClick = { addElement }
197- >
198- + Add { isCustom ? 'Component' : 'Button' }
199- </ button >
200- { atModalLimit && < p className = "empty-note" > A modal form shows exactly two buttons.</ p > }
205+ < div className = "bedrock-palette-section" >
206+ { isCustom ? (
207+ COMPONENT_PALETTE . map ( entry => (
208+ < div
209+ key = { entry . type }
210+ className = "bedrock-palette-item"
211+ role = "button"
212+ tabIndex = { 0 }
213+ onClick = { ( ) => addComponent ( entry . type ) }
214+ onKeyDown = { event => event . key === 'Enter' && addComponent ( entry . type ) }
215+ >
216+ < div className = "bedrock-palette-icon" > { entry . icon } </ div >
217+ < div className = "bedrock-palette-info" >
218+ < div className = "bedrock-palette-label" > { entry . name } </ div >
219+ < div className = "empty-note" > { entry . description } </ div >
220+ </ div >
221+ </ div >
222+ ) )
223+ ) : (
224+ < div
225+ className = "bedrock-palette-item"
226+ role = "button"
227+ tabIndex = { 0 }
228+ aria-disabled = { atModalLimit }
229+ onClick = { ( ) => ! atModalLimit && addElement ( ) }
230+ onKeyDown = { event => event . key === 'Enter' && ! atModalLimit && addElement ( ) }
231+ >
232+ < div className = "bedrock-palette-icon" > 🔘</ div >
233+ < div className = "bedrock-palette-info" >
234+ < div className = "bedrock-palette-label" > Add Empty Button</ div >
235+ < div className = "empty-note" >
236+ { atModalLimit ? 'A modal form shows exactly two buttons.' : 'A button that closes the form' }
237+ </ div >
238+ </ div >
239+ </ div >
240+ ) }
201241 </ div >
202242 </ div >
203243
0 commit comments