@@ -512,6 +512,7 @@ export default function VisualBuilder({ initialContent, onChange }) {
512512 < div className = "vb-sidebar" >
513513 < div className = "vb-sidebar-header" >
514514 Elements
515+ < span className = "vb-drag-hint" > Drag or click to add</ span >
515516 </ div >
516517 < div className = "vb-elements" >
517518 { [
@@ -537,6 +538,152 @@ export default function VisualBuilder({ initialContent, onChange }) {
537538 ) ) }
538539 </ div >
539540
541+ { selectedBlock && (
542+ < div className = "vb-properties" >
543+ < div className = "vb-sidebar-header" > Properties</ div >
544+
545+ < div className = "vb-properties-content" >
546+ < div className = "prop-group" >
547+ < label > Position</ label >
548+ < div className = "prop-row" >
549+ < div className = "prop-field" >
550+ < span > X</ span >
551+ < input
552+ type = "number"
553+ value = { Math . round ( selectedBlock . position . x ) }
554+ onChange = { ( e ) => updateBlockPosition ( selectedBlock . id , {
555+ ...selectedBlock . position ,
556+ x : parseInt ( e . target . value ) || 0
557+ } ) }
558+ />
559+ </ div >
560+ < div className = "prop-field" >
561+ < span > Y</ span >
562+ < input
563+ type = "number"
564+ value = { Math . round ( selectedBlock . position . y ) }
565+ onChange = { ( e ) => updateBlockPosition ( selectedBlock . id , {
566+ ...selectedBlock . position ,
567+ y : parseInt ( e . target . value ) || 0
568+ } ) }
569+ />
570+ </ div >
571+ </ div >
572+ </ div >
573+
574+ < div className = "prop-group" >
575+ < label > Size</ label >
576+ < div className = "prop-row" >
577+ < div className = "prop-field" >
578+ < span > W</ span >
579+ < input
580+ type = "number"
581+ value = { Math . round ( selectedBlock . size . width ) }
582+ onChange = { ( e ) => updateBlockSize ( selectedBlock . id , {
583+ width : parseInt ( e . target . value ) || 100
584+ } ) }
585+ />
586+ </ div >
587+ < div className = "prop-field" >
588+ < span > H</ span >
589+ < input
590+ type = "number"
591+ value = { Math . round ( selectedBlock . size . height ) }
592+ onChange = { ( e ) => updateBlockSize ( selectedBlock . id , {
593+ height : parseInt ( e . target . value ) || 24
594+ } ) }
595+ />
596+ </ div >
597+ </ div >
598+ </ div >
599+
600+ < div className = "prop-group" >
601+ < label > Text Align</ label >
602+ < div className = "btn-group" >
603+ < button
604+ type = "button"
605+ className = { selectedBlock . styles . textAlign === 'left' ? 'active' : '' }
606+ onClick = { ( ) => updateBlockStyle ( selectedBlock . id , 'textAlign' , 'left' ) }
607+ >
608+ Left
609+ </ button >
610+ < button
611+ type = "button"
612+ className = { selectedBlock . styles . textAlign === 'center' ? 'active' : '' }
613+ onClick = { ( ) => updateBlockStyle ( selectedBlock . id , 'textAlign' , 'center' ) }
614+ >
615+ Center
616+ </ button >
617+ < button
618+ type = "button"
619+ className = { selectedBlock . styles . textAlign === 'right' ? 'active' : '' }
620+ onClick = { ( ) => updateBlockStyle ( selectedBlock . id , 'textAlign' , 'right' ) }
621+ >
622+ Right
623+ </ button >
624+ </ div >
625+ </ div >
626+
627+ < div className = "prop-group" >
628+ < label > Color</ label >
629+ < input
630+ type = "color"
631+ value = { selectedBlock . styles . color === 'inherit' ? '#000000' : selectedBlock . styles . color }
632+ onChange = { ( e ) => updateBlockStyle ( selectedBlock . id , 'color' , e . target . value ) }
633+ />
634+ </ div >
635+
636+ { selectedBlock . type === 'table' && (
637+ < >
638+ < div className = "prop-group" >
639+ < label > Columns</ label >
640+ < div className = "table-controls" >
641+ < button
642+ type = "button"
643+ className = "btn btn-sm btn-secondary"
644+ onClick = { ( ) => removeTableColumn ( selectedBlock . id ) }
645+ disabled = { getTableInfo ( selectedBlock ) ?. cols <= 1 }
646+ >
647+ −
648+ </ button >
649+ < span className = "table-count" > { getTableInfo ( selectedBlock ) ?. cols || 0 } </ span >
650+ < button
651+ type = "button"
652+ className = "btn btn-sm btn-secondary"
653+ onClick = { ( ) => addTableColumn ( selectedBlock . id ) }
654+ >
655+ +
656+ </ button >
657+ </ div >
658+ </ div >
659+
660+ < div className = "prop-group" >
661+ < label > Rows</ label >
662+ < div className = "table-controls" >
663+ < button
664+ type = "button"
665+ className = "btn btn-sm btn-secondary"
666+ onClick = { ( ) => removeTableRow ( selectedBlock . id ) }
667+ disabled = { getTableInfo ( selectedBlock ) ?. rows <= 2 }
668+ >
669+ −
670+ </ button >
671+ < span className = "table-count" > { ( getTableInfo ( selectedBlock ) ?. rows || 1 ) - 1 } </ span >
672+ < button
673+ type = "button"
674+ className = "btn btn-sm btn-secondary"
675+ onClick = { ( ) => addTableRow ( selectedBlock . id ) }
676+ >
677+ +
678+ </ button >
679+ </ div >
680+ </ div >
681+ </ >
682+ ) }
683+ </ div >
684+ </ div >
685+ ) }
686+
540687 < div className = "vb-sidebar-footer" >
541688 < button type = "button" className = "btn btn-danger w-full" onClick = { handleClear } >
542689 Clear All
@@ -661,150 +808,6 @@ export default function VisualBuilder({ initialContent, onChange }) {
661808 ) ;
662809 } ) }
663810 </ div >
664-
665- { selectedBlock && (
666- < div className = "vb-properties" >
667- < h4 > Properties</ h4 >
668-
669- < div className = "prop-group" >
670- < label > Position</ label >
671- < div className = "prop-row" >
672- < div className = "prop-field" >
673- < span > X</ span >
674- < input
675- type = "number"
676- value = { Math . round ( selectedBlock . position . x ) }
677- onChange = { ( e ) => updateBlockPosition ( selectedBlock . id , {
678- ...selectedBlock . position ,
679- x : parseInt ( e . target . value ) || 0
680- } ) }
681- />
682- </ div >
683- < div className = "prop-field" >
684- < span > Y</ span >
685- < input
686- type = "number"
687- value = { Math . round ( selectedBlock . position . y ) }
688- onChange = { ( e ) => updateBlockPosition ( selectedBlock . id , {
689- ...selectedBlock . position ,
690- y : parseInt ( e . target . value ) || 0
691- } ) }
692- />
693- </ div >
694- </ div >
695- </ div >
696-
697- < div className = "prop-group" >
698- < label > Size</ label >
699- < div className = "prop-row" >
700- < div className = "prop-field" >
701- < span > W</ span >
702- < input
703- type = "number"
704- value = { Math . round ( selectedBlock . size . width ) }
705- onChange = { ( e ) => updateBlockSize ( selectedBlock . id , {
706- width : parseInt ( e . target . value ) || 100
707- } ) }
708- />
709- </ div >
710- < div className = "prop-field" >
711- < span > H</ span >
712- < input
713- type = "number"
714- value = { Math . round ( selectedBlock . size . height ) }
715- onChange = { ( e ) => updateBlockSize ( selectedBlock . id , {
716- height : parseInt ( e . target . value ) || 24
717- } ) }
718- />
719- </ div >
720- </ div >
721- </ div >
722-
723- < div className = "prop-group" >
724- < label > Text Align</ label >
725- < div className = "btn-group" >
726- < button
727- type = "button"
728- className = { selectedBlock . styles . textAlign === 'left' ? 'active' : '' }
729- onClick = { ( ) => updateBlockStyle ( selectedBlock . id , 'textAlign' , 'left' ) }
730- >
731- Left
732- </ button >
733- < button
734- type = "button"
735- className = { selectedBlock . styles . textAlign === 'center' ? 'active' : '' }
736- onClick = { ( ) => updateBlockStyle ( selectedBlock . id , 'textAlign' , 'center' ) }
737- >
738- Center
739- </ button >
740- < button
741- type = "button"
742- className = { selectedBlock . styles . textAlign === 'right' ? 'active' : '' }
743- onClick = { ( ) => updateBlockStyle ( selectedBlock . id , 'textAlign' , 'right' ) }
744- >
745- Right
746- </ button >
747- </ div >
748- </ div >
749-
750- < div className = "prop-group" >
751- < label > Color</ label >
752- < input
753- type = "color"
754- value = { selectedBlock . styles . color === 'inherit' ? '#000000' : selectedBlock . styles . color }
755- onChange = { ( e ) => updateBlockStyle ( selectedBlock . id , 'color' , e . target . value ) }
756- />
757- </ div >
758-
759- { selectedBlock . type === 'table' && (
760- < >
761- < div className = "prop-group" >
762- < label > Columns</ label >
763- < div className = "table-controls" >
764- < button
765- type = "button"
766- className = "btn btn-sm btn-secondary"
767- onClick = { ( ) => removeTableColumn ( selectedBlock . id ) }
768- disabled = { getTableInfo ( selectedBlock ) ?. cols <= 1 }
769- >
770- − Remove
771- </ button >
772- < span className = "table-count" > { getTableInfo ( selectedBlock ) ?. cols || 0 } </ span >
773- < button
774- type = "button"
775- className = "btn btn-sm btn-secondary"
776- onClick = { ( ) => addTableColumn ( selectedBlock . id ) }
777- >
778- + Add
779- </ button >
780- </ div >
781- </ div >
782-
783- < div className = "prop-group" >
784- < label > Rows</ label >
785- < div className = "table-controls" >
786- < button
787- type = "button"
788- className = "btn btn-sm btn-secondary"
789- onClick = { ( ) => removeTableRow ( selectedBlock . id ) }
790- disabled = { getTableInfo ( selectedBlock ) ?. rows <= 2 }
791- >
792- − Remove
793- </ button >
794- < span className = "table-count" > { ( getTableInfo ( selectedBlock ) ?. rows || 1 ) - 1 } </ span >
795- < button
796- type = "button"
797- className = "btn btn-sm btn-secondary"
798- onClick = { ( ) => addTableRow ( selectedBlock . id ) }
799- >
800- + Add
801- </ button >
802- </ div >
803- </ div >
804- </ >
805- ) }
806- </ div >
807- ) }
808811 </ div >
809812
810813 < Modal
0 commit comments