The Edit app’s layout engine lets users select a layout, toggle blocks on/off, resize them and drag them.
Layouts are stored in public/config.json
for now, but will eventually become cloud assets.
Data structure
{ LayoutName : { t: FreePane or TabbedPane ( can use either in the root block) blocks: { BlockName: { t: TabbedPane, visible: true, style: { l, t, w, h, z }, blocks: { BlockName : { t: SomeComponent, visible: true, style: { l, t, w, h, z } }, BlockName : { t: SomeComponent, visible: false, style: { l, t, w, h, z } } } } } } }
React structure overview
Here are the React structures for two different layouts, which cover all scenarios.
SimpleEdit layout
<EditorApp>
<FreePane>
<MenuBar/>
<Block>
<DragResizer>
<Preview>
</DragResizer>
</Block>
<Block>
<DragResizer>
<TabbedPane>
<TabSelector/>
<Block>
<Preset/>
</Block>
<Block>
<Monitor/>
</Block>
<Block>
<Screenshotter/>
</Block>
</TabbedPane>
</DragResizer>
</Block>
</FreePane>
</EditorApp>
Code layout
<EditorApp> <FreePane> <MenuBar/> <Block> <DragResizer> <Preview> </DragResizer> </Block> <Block> <TabbedPane> <TabSelector/> <Block> <Preset/> </Block> <Block> <Monitor/> </Block> <Block> <Screenshotter/> </Block> </TabbedPane> </Block> </FreePane> </EditorApp>
Dragging / resizing
Dragging / resizing a block is handled by the DragResizer component. DragResizer receives a preset prop which contains its initial style:
{ left, top, width, height }
We store this style in the state and pass it to the DragResizer’s container div, and modify it when the user drags / resizes the component.
Layout components
We use 3 components to layout our app components:
- FreePane
- TabbedPane
- Block
They are all defined in the same file, src/components/Panes/Panes.js
(we can’t have them in separate files, as these components can render each other that would introduce dependency loops).
Block
A Block renders a component (eg Preset, Monitor…) or a Pane wrapped inside a DragResizer, with an optional header containing controls for the DragResizer.
FreePane
A FreePane renders one or more blocks with all of them visible by default.
TabbedPane
A TabbedPane renders multiple Blocks + a header. Only one block is visible at a time. Clicking on the header tabs lets us toggle between blocks.