Skip to content

Commit d11dfd9

Browse files
authored
Merge pull request #21 from jzuniga206/feature
Added Component Panel Expansion
2 parents 1688c1f + 5a67b07 commit d11dfd9

File tree

2 files changed

+114
-65
lines changed

2 files changed

+114
-65
lines changed

src/components/LeftColExpansionPanel.tsx

Lines changed: 66 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ import InputLabel from '@material-ui/core/InputLabel'; // labeling of state/clas
1515

1616
// import { ComponentInt, ComponentsInt, ChildInt } from '../utils/Interfaces'; // unused
1717

18+
interface TypographyProps {
19+
type: string;
20+
}
21+
1822
// TODO: ASSIGN SPECIFIC TYPING TO INCOMING PROPS (REMOVE ANY)
1923
const LeftColExpansionPanel = (props: any) => {
2024
const {
@@ -36,6 +40,10 @@ const LeftColExpansionPanel = (props: any) => {
3640
return focusComponent.id === id ? 'focused' : '';
3741
}
3842

43+
// boolean flag to determine if the component card is focused or not
44+
// state/class toggles will be displayed when a component is focused
45+
const focusedToggle = isFocused() === 'focused' ? true : false;
46+
3947
return (
4048
<Grid
4149
container
@@ -48,13 +56,15 @@ const LeftColExpansionPanel = (props: any) => {
4856
<div
4957
className={classes.root}
5058
style={
51-
!isFocused() ? {} : { boxShadow: '0 10px 10px rgba(0,0,0,0.25)' }
59+
// shadow to highlight the focused component card
60+
focusedToggle ? { boxShadow: '4px 4px 4px rgba(0, 0, 0, .4)' } : {}
5261
}
5362
>
63+
{/* NOT SURE WHY COLOR: RED IS USED, TRIED REMOVING IT AND NO VISIBLE CHANGE OCCURED */}
5464
<Grid item xs={12} style={{ color: 'red', backgroundColor: color }}>
5565
<List style={{ color: 'red' }}>
5666
<ListItem
57-
button
67+
// button // commented out to disable materialUI hover shading effect. TBD if any adverse effects occur
5868
style={{ color: 'red' }}
5969
onClick={() => {
6070
changeFocusComponent({ title });
@@ -75,40 +85,16 @@ const LeftColExpansionPanel = (props: any) => {
7585
>
7686
{title}
7787
</Typography>
78-
{/* TOGGLE FOR STATEFULNESS */}
79-
<InputLabel
80-
htmlFor='stateful'
81-
style={{
82-
color: '#fff',
83-
marginBottom: '10px',
84-
marginTop: '0px',
85-
marginLeft: '11px',
86-
padding: '0px',
87-
fontSize: '18px'
88-
}}
89-
>
90-
State?
91-
</InputLabel>
92-
{/*
93-
Have to change focus component after toggling state
94-
in order to properly change the code that appears in the code
95-
peview
88+
89+
{/* ALL OF THE STATE/CLASS TOGGLES AND LABELS ARE ONLY RENDERED IF THEIR COMPONENT IS THE FOCUSED COMPONENT
90+
91+
TO DO : IMPROVE DRYNESS OF CODE BY RENDERING ALL FOUR MATERIAL ELEMENTS (LABELS/SWITCH) IN ONE CONDITIONAL
9692
*/}
97-
<Switch
98-
checked={stateful}
99-
onChange={e => {
100-
toggleComponentState(id);
101-
changeFocusComponent(title);
102-
}}
103-
value='stateful'
104-
color='primary'
105-
id={props.id.toString()}
106-
// id={props.index.toString()}
107-
/>
108-
<div>
109-
{/* TOGGLE FOR CLASS BASED */}
93+
94+
{/* LABEL AND TOGGLE(SWITCH) FOR STATEFULNESS */}
95+
{focusedToggle ? (
11096
<InputLabel
111-
htmlFor='classBased'
97+
htmlFor='stateful'
11298
style={{
11399
color: '#fff',
114100
marginBottom: '10px',
@@ -118,17 +104,58 @@ const LeftColExpansionPanel = (props: any) => {
118104
fontSize: '18px'
119105
}}
120106
>
121-
Class?
107+
State?
122108
</InputLabel>
109+
) : (
110+
''
111+
)}
112+
113+
{focusedToggle ? (
123114
<Switch
124-
checked={classBased}
115+
checked={stateful}
125116
onChange={e => {
126-
toggleComponentClass(id);
117+
toggleComponentState(id);
127118
changeFocusComponent(title);
128119
}}
129-
value='classBased'
120+
value='stateful'
130121
color='primary'
122+
id={props.id.toString()}
131123
/>
124+
) : (
125+
''
126+
)}
127+
<div>
128+
{/* LABEL/TOGGLE(SWITCH) FOR CLASS BASED */}
129+
{focusedToggle ? (
130+
<InputLabel
131+
htmlFor='classBased'
132+
style={{
133+
color: '#fff',
134+
marginBottom: '10px',
135+
marginTop: '0px',
136+
marginLeft: '11px',
137+
padding: '0px',
138+
fontSize: '18px'
139+
}}
140+
>
141+
Class?
142+
</InputLabel>
143+
) : (
144+
''
145+
)}
146+
{focusedToggle ? (
147+
<Switch
148+
checked={classBased}
149+
onChange={e => {
150+
toggleComponentClass(id);
151+
changeFocusComponent(title);
152+
}}
153+
value='classBased'
154+
color='primary'
155+
/>
156+
) : (
157+
''
158+
)}
132159
</div>
133160
</div>
134161
}
@@ -162,7 +189,7 @@ const LeftColExpansionPanel = (props: any) => {
162189
}}
163190
>
164191
<DeleteIcon style={{ color: '#D3D3D3' }} />
165-
Delete Component
192+
<span style={{ marginTop: '3px' }}>Delete Component</span>
166193
</Button>
167194
</Fragment>
168195
)}

src/components/Rectangle.tsx

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import TransformerComponent from './TransformerComponent';
55
import GrandchildRectangle from './GrandchildRectangle';
66
import { ComponentsInt, ChildInt } from '../utils/Interfaces';
77
import { ComponentInt } from '../utils/Interfaces';
8+
import KonvaStage from './KonvaStage';
89

910
interface PropsInt {
1011
x: number;
@@ -27,8 +28,10 @@ interface PropsInt {
2728
image: HTMLImageElement;
2829
}
2930

30-
3131
class Rectangle extends Component<PropsInt> {
32+
rect: Konva.Rect;
33+
group: Konva.Group;
34+
3235
//This assigns the color to the Rect based on componentId's color in the state
3336
getComponentColor(componentId: number) {
3437
const color = this.props.components.find(
@@ -46,7 +49,12 @@ class Rectangle extends Component<PropsInt> {
4649
}
4750

4851
//resize function
49-
handleResize(componentId: number, childId: number, target: Konva.Group, blockSnapSize: number) {
52+
handleResize(
53+
componentId: number,
54+
childId: number,
55+
target: Konva.Group,
56+
blockSnapSize: number
57+
) {
5058
//find the id of the component where the componentID in the state equals the currently focused component
5159
//and then find the numberID for that component
5260
//So, this would be assigning "Container 1", with component ID being whatever the ID for "Container" is
@@ -65,15 +73,15 @@ class Rectangle extends Component<PropsInt> {
6573

6674
//The math here is easier than it looks
6775
//Basically, the height and width is first rounded up to a whole number (behind the whole snapping phenomenon)
68-
//after scaling it by multiplying it by scaleX/Y (height and width are the original height and width, the scale is the CHANGE in w/h),
76+
//after scaling it by multiplying it by scaleX/Y (height and width are the original height and width, the scale is the CHANGE in w/h),
6977
//dividing it by the 'snapsize' or grid unit area (which is 10x10 for this entire application) and re-multiplied by
7078
//that same snapsize. I'm not entirely sure why this had to be divided before the rounding, and re-multiplied,
71-
//since having positions that aren't a whole number doesn't seem to be that big of a deal.
79+
//since having positions that aren't a whole number doesn't seem to be that big of a deal.
7280

7381
//So there's a bit of redundancy in the x and y info. target.x() or y() only log the CHANGE of position of the Rect component.
74-
//Since when you change the width or height of the component you do not change the actual position, the
82+
//Since when you change the width or height of the component you do not change the actual position, the
7583
//value for x an y dispatched to the action creator will always be the same as the current x,y position, unless you can somehow
76-
//resize AND reposition at the same time.
84+
//resize AND reposition at the same time.
7785
const transformation = {
7886
width:
7987
Math.round((target.width() * target.scaleX()) / blockSnapSize) *
@@ -87,9 +95,14 @@ class Rectangle extends Component<PropsInt> {
8795
this.props.handleTransform(componentId, childId, transformation);
8896
}
8997

90-
//mostly the same logic as above, just grabbing the change in position for the focused child and sending it
98+
//mostly the same logic as above, just grabbing the change in position for the focused child and sending it
9199
//to the action creator.
92-
handleDrag(componentId: number, childId: number, target: Konva.Group, blockSnapSize: number) {
100+
handleDrag(
101+
componentId: number,
102+
childId: number,
103+
target: Konva.Group,
104+
blockSnapSize: number
105+
) {
93106
const transformation = {
94107
x: Math.round(target.x() / blockSnapSize) * blockSnapSize,
95108
y: Math.round(target.y() / blockSnapSize) * blockSnapSize
@@ -131,7 +144,8 @@ class Rectangle extends Component<PropsInt> {
131144
onDragEnd={event =>
132145
this.handleDrag(componentId, childId, event.target, blockSnapSize)
133146
}
134-
ref={node => { //this refference actually isn't doing anything since it isn't within the transformer component
147+
ref={node => {
148+
//this refference actually isn't doing anything since it isn't within the transformer component
135149
this.group = node;
136150
}}
137151
tabIndex='0' // required for keypress event to be heard by this.group
@@ -161,18 +175,22 @@ class Rectangle extends Component<PropsInt> {
161175
onTransformEnd={event =>
162176
this.handleResize(componentId, childId, event.target, blockSnapSize)
163177
}
164-
strokeWidth={childType === 'COMP' ? 4 : 2}
178+
strokeWidth={childType === 'COMP' ? 4 : 2}
165179
strokeScaleEnabled={false}
166180
draggable={false}
167181
fill={null}
168182
shadowBlur={childId === -1 ? 6 : null}
169-
fillPatternImage={childId === -1 ? this.props.image : null} //spooky addition, image if uploaded will only be background of App component
170-
fillPatternScaleX={this.props.image ? width / this.props.image.width : 1} //here we are making sure the width of the image will stretch of shrink
171-
fillPatternScaleY={this.props.image? height / this.props.image.height : 1} //based on the width or height of the App component
183+
fillPatternImage={childId === -1 ? this.props.image : null} //spooky addition, image if uploaded will only be background of App component
184+
fillPatternScaleX={
185+
this.props.image ? width / this.props.image.width : 1
186+
} //here we are making sure the width of the image will stretch of shrink
187+
fillPatternScaleY={
188+
this.props.image ? height / this.props.image.height : 1
189+
} //based on the width or height of the App component
172190
_useStrictMode
173191
/>
174192
<Label>
175-
<Text //this is just the text that goes above each Rect,
193+
<Text //this is just the text that goes above each Rect,
176194
fontStyle={'bold'}
177195
fontVariant={'small-caps'}
178196
// pseudochild's label should look different than normal children:
@@ -189,12 +207,12 @@ class Rectangle extends Component<PropsInt> {
189207
</Label>
190208
{// for all children other than the pseudoChild, find their component's children array and recursively render the children found there
191209
childId !== -1 && //inline conditional to check if a child exists
192-
childType === 'COMP' && //inline conditional to see if the child is a component, not an HTML element
210+
childType === 'COMP' && //inline conditional to see if the child is a component, not an HTML element
193211
components //map all 'grandchildren' in the child on display to this new component
194212
.find((comp: ComponentInt) => comp.title === childComponentName)
195213
.childrenArray.filter((child: ChildInt) => child.childId !== -1)
196214
.map((grandchild: ChildInt, i: number) => (
197-
<GrandchildRectangle
215+
<GrandchildRectangle
198216
key={i}
199217
components={components}
200218
componentId={componentId}
@@ -204,15 +222,17 @@ class Rectangle extends Component<PropsInt> {
204222
childComponentId={grandchild.childComponentId}
205223
focusChild={focusChild}
206224
childId={childId} // scary addition, grandchildren rects default to childId of "direct" children
207-
width={ //this is the logic used to display the grandchildren with proper scaling based on the parent (technically child) h/w
225+
width={
226+
//this is the logic used to display the grandchildren with proper scaling based on the parent (technically child) h/w
208227
grandchild.position.width *
209228
(width / this.getPseudoChild().position.width)
210229
}
211230
height={
212231
grandchild.position.height *
213232
(height / this.getPseudoChild().position.height)
214233
}
215-
x={ //similar logic to above
234+
x={
235+
//similar logic to above
216236
(grandchild.position.x - this.getPseudoChild().position.x) *
217237
(width / this.getPseudoChild().position.width)
218238
}
@@ -222,14 +242,16 @@ class Rectangle extends Component<PropsInt> {
222242
}
223243
/>
224244
))}
225-
{focusChild && focusChild.childId === childId && draggable && ( //this conditional logic binds the transformer to the focused child, and Draggable is checked to make sure grandchildren can't be selected
226-
<TransformerComponent //This is the component that binds the Rect nodes to the Transformer node so they can be resized.
227-
focusChild={focusChild}
228-
rectClass={'childRect'}
229-
anchorSize={8}
230-
color={'grey'}
231-
/>
232-
)}
245+
{focusChild &&
246+
focusChild.childId === childId &&
247+
draggable && ( //this conditional logic binds the transformer to the focused child, and Draggable is checked to make sure grandchildren can't be selected
248+
<TransformerComponent //This is the component that binds the Rect nodes to the Transformer node so they can be resized.
249+
focusChild={focusChild}
250+
rectClass={'childRect'}
251+
anchorSize={8}
252+
color={'grey'}
253+
/>
254+
)}
233255
</Group>
234256
);
235257
}

0 commit comments

Comments
 (0)