Skip to content

Commit cf9edf8

Browse files
add layer hierarchy display
1 parent f02933f commit cf9edf8

16 files changed

Lines changed: 291 additions & 95 deletions

File tree

editor/components/clear-remote-design-session-cache/index.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
import React from "react";
22
import { RemoteDesignSessionCacheStore } from "../../store";
33

4-
export function ClearRemoteDesignSessionCache(props: { url: string }) {
4+
export function ClearRemoteDesignSessionCache(
5+
props:
6+
| { url: string }
7+
| {
8+
file: string;
9+
node: string;
10+
}
11+
) {
512
const clearCache = () => {
6-
new RemoteDesignSessionCacheStore({ url: props.url }).clear();
7-
alert("cleared - " + props.url);
13+
new RemoteDesignSessionCacheStore(props).clear();
14+
alert("cleared - " + JSON.stringify(props));
815
};
916

1017
return (

editor/components/editor/editor-layer-hierarchy/editor-layer-hierarchy-tree.tsx

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,83 @@ import styled from "@emotion/styled";
44
import { TreeView } from "@editor-ui/editor";
55
import { ListView } from "@editor-ui/listview";
66
import { LayerRow } from "./editor-layer-hierarchy-item";
7+
import { useEditorState } from "core/states";
78

89
export function EditorLayerHierarchy() {
10+
const [state] = useEditorState();
11+
const root = state.design?.current?.entry;
12+
const layers = root ? flatten(root) : [];
13+
const [selected, setSelected] = useState<string | null>(null);
14+
915
const renderItem = useCallback(
10-
({ id, name, depth }, index: number, { isDragging }: ListView.ItemInfo) => {
16+
({ id, name, depth }) => {
1117
return (
1218
<LayerRow
1319
name={name}
1420
depth={depth}
1521
id={id}
22+
expanded={haschildren(id) == true ? true : undefined}
1623
key={id}
17-
expanded={false}
18-
selected={false}
24+
selected={selected == id}
1925
onAddClick={() => {}}
2026
onMenuClick={() => {}}
2127
onDoubleClick={() => {}}
22-
onPress={() => {}}
28+
onPress={() => {
29+
setSelected(id);
30+
}}
2331
onSelectMenuItem={() => {}}
2432
onContextMenu={() => {}}
2533
/>
2634
);
2735
},
28-
[]
36+
[selected]
2937
);
3038

31-
const pageInfo = [
32-
{ id: "1", name: "Screen", depth: 0 },
33-
{ id: "2", name: "Layer 1", depth: 0 },
34-
{ id: "3", name: "Layer 2", depth: 0 },
35-
{ id: "4", name: "Layer 3", depth: 0 },
36-
{ id: "5", name: "Layer 4", depth: 0 },
37-
];
39+
const haschildren = useCallback((id: string) => {
40+
return layers.some((layer) => layer.parent === id);
41+
}, []);
42+
3843
return (
3944
<TreeView.Root
40-
sortable={true}
41-
data={pageInfo}
45+
data={layers}
4246
keyExtractor={useCallback((item: any) => item.id, [])}
43-
// onMoveItem={}
44-
acceptsDrop={() => false}
4547
renderItem={renderItem}
4648
/>
4749
);
4850
}
51+
52+
interface ITreeNode {
53+
id: string;
54+
name: string;
55+
children?: ITreeNode[];
56+
}
57+
58+
interface FlattenedNode {
59+
id: string;
60+
name: string;
61+
depth: number;
62+
parent: string;
63+
}
64+
65+
const flatten = (
66+
tree: ITreeNode,
67+
parent?: string,
68+
depth: number = 0
69+
): FlattenedNode[] => {
70+
const convert = (node: ITreeNode, depth: number, parent?: string) => {
71+
const result: FlattenedNode = {
72+
id: node.id,
73+
name: node.name,
74+
depth: depth,
75+
parent,
76+
};
77+
return result;
78+
};
79+
80+
const final = [];
81+
final.push(convert(tree, depth, parent));
82+
for (const child of tree.children || []) {
83+
final.push(...flatten(child, tree.id, depth + 1));
84+
}
85+
return final;
86+
};

editor/components/side-navigation/side-navigation.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ export function SideNavigation(props: {
99

1010
const Wrapper = styled.div`
1111
flex: 0;
12-
min-width: 200px;
12+
width: 200px;
13+
/* max-width: 320px; */
1314
display: flex;
1415
align-items: stretch;
1516
flex-direction: column;

editor/core/reducers/workspace-reducer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export function workspaceReducer(
1010
switch (action.type) {
1111
default: {
1212
return produce(state, (draft) => {
13+
// @ts-ignore
1314
draft.history = historyReducer(state.history, action);
1415
});
1516
}
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
import { EditorSnapshot, EditorState } from "./editor-state";
22

3-
export function createInitialEditorState(app: EditorSnapshot): EditorState {
3+
export function createInitialEditorState(editor: EditorSnapshot): EditorState {
44
return {
5-
selectedPage: app.selectedPage,
6-
selectedNodes: app.selectedNodes,
7-
design: app.design,
5+
selectedPage: editor.selectedPage,
6+
selectedNodes: editor.selectedNodes,
7+
design: editor.design,
8+
};
9+
}
10+
11+
export function createPendingEditorState(): EditorState {
12+
return {
13+
selectedPage: null,
14+
selectedNodes: [],
15+
design: null,
816
};
917
}

editor/core/states/editor-state.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import type { ReflectSceneNode } from "@design-sdk/figma-node";
2+
import { DesignInput } from "@designto/config/input";
3+
14
export interface EditorState {
25
selectedPage: string;
36
selectedNodes: string[];
@@ -10,7 +13,13 @@ export interface EditorSnapshot {
1013
design: ReflectRepository;
1114
}
1215

13-
// TODO:
1416
interface ReflectRepository {
17+
/**
18+
* fileid; filekey
19+
*/
20+
key: string;
21+
22+
// TODO:
1523
pages: [];
24+
current: DesignInput;
1625
}

editor/core/states/history-initial-state.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { EditorSnapshot, HistoryState } from "core/states";
2-
import { createInitialEditorState } from "./editor-initial-state";
2+
import {
3+
createInitialEditorState,
4+
createPendingEditorState,
5+
} from "./editor-initial-state";
36

47
export function createInitialHistoryState(
58
editor: EditorSnapshot
@@ -11,3 +14,12 @@ export function createInitialHistoryState(
1114
future: [],
1215
};
1316
}
17+
18+
export function createPendingHistoryState(): HistoryState {
19+
const applicationState = createPendingEditorState();
20+
return {
21+
past: [],
22+
present: applicationState,
23+
future: [],
24+
};
25+
}

editor/core/states/index.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@ export * from "./history-state";
77
export * from "./workspace-initial-state";
88
export * from "./editor-initial-state";
99
export * from "./history-initial-state";
10+
11+
//
12+
13+
export * from "./use-editor-state";
14+
export * from "./use-workspace-state";
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { useMemo } from "react";
2+
import { useWorkspaceState } from "./use-workspace-state";
3+
import { useDispatch, FlatDispatcher } from "../dispatch";
4+
import { EditorState } from "./editor-state";
5+
6+
export const useEditorState = (): [EditorState, FlatDispatcher] => {
7+
const state = useWorkspaceState();
8+
const dispatch = useDispatch();
9+
return useMemo(
10+
() => [state.history.present, dispatch],
11+
[state.history.present, dispatch]
12+
);
13+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { useContext } from "react";
2+
import { StateContext } from "./editor-context";
3+
import { WorkspaceState } from "./workspace-state";
4+
5+
export const useWorkspaceState = (): WorkspaceState => {
6+
const value = useContext(StateContext);
7+
8+
if (!value) {
9+
throw new Error(`No StateProvider: this is a logical error.`);
10+
}
11+
12+
return value;
13+
};

0 commit comments

Comments
 (0)