{
viewbound[3] === 0)
);
};
+
+function Debug({
+ infos,
+}: {
+ infos: { label: string; value: string | number | boolean }[];
+}) {
+ return (
+
+ {infos.map(({ label, value }, i) => {
+ if (value === undefined || value === null) {
+ return <>>;
+ }
+ return (
+
+ {label}: {JSON.stringify(value)}
+
+ );
+ })}
+
+ );
+}
+
+const DebugInfoContainer = styled.div`
+ position: absolute;
+ top: 12px;
+ left: 12px;
+ z-index: 9999;
+ background: rgba(0, 0, 0, 0.5);
+ border-radius: 4px;
+ color: white;
+ padding: 0.5rem;
+ font-size: 0.8rem;
+ font-family: monospace;
+ line-height: 1.2;
+ white-space: pre;
+`;
diff --git a/editor-packages/editor-canvas/math/center-of.ts b/editor-packages/editor-canvas/math/center-of.ts
index 0d8e0015d..ad357dc4d 100644
--- a/editor-packages/editor-canvas/math/center-of.ts
+++ b/editor-packages/editor-canvas/math/center-of.ts
@@ -63,6 +63,11 @@ export function centerOf(
vbcenter[1] - boxcenter[1] * scale,
];
+ // apply viewbound's offset to the translate.
+ // (this works, but not fully tested)
+ translate[0] -= viewbound[0];
+ translate[1] -= viewbound[1];
+
return {
box: box,
center: boxcenter,
diff --git a/editor-packages/editor-canvas/math/viewbound-edge-scrolling.ts b/editor-packages/editor-canvas/math/viewbound-edge-scrolling.ts
index 4146b59c4..58b56be4a 100644
--- a/editor-packages/editor-canvas/math/viewbound-edge-scrolling.ts
+++ b/editor-packages/editor-canvas/math/viewbound-edge-scrolling.ts
@@ -16,7 +16,7 @@
*
* @param cx x coordinate of the cursor
* @param cy y coordinate of the cursor
- * @param viewbound the viewbound of the canvas (l, t, b, r)
+ * @param viewbound the viewbound of the canvas (l x1, t y1, r x2, b y2)
* @param margin the margin value (default 40px)
* @param factor the returned value will be multiplied by this factor (default 1/4)
*
@@ -29,7 +29,7 @@ export function edge_scrolling(
margin = 40,
factor = 1 / 4
): [number, number] {
- const [l, t, b, r] = viewbound;
+ const [l, t, r, b] = viewbound;
let [dx, dy] = [0, 0];
if (cx < l + margin) {
diff --git a/editor-packages/editor-dashboard/components/dashbaord-grid-placement-auxilary-drop-guide.tsx b/editor-packages/editor-dashboard/components/dashbaord-grid-placement-auxilary-drop-guide.tsx
new file mode 100644
index 000000000..9d3671e72
--- /dev/null
+++ b/editor-packages/editor-dashboard/components/dashbaord-grid-placement-auxilary-drop-guide.tsx
@@ -0,0 +1,84 @@
+import React from "react";
+import styled from "@emotion/styled";
+import assert from "assert";
+
+export type AuxilaryGridDropGuideLeftOrRightSpecification = {
+ left?: boolean;
+ right?: boolean;
+};
+type AuxilaryGridDropGuide = AuxilaryGridDropGuideLeftOrRightSpecification & {
+ onClick?: () => void;
+ over?: boolean;
+};
+
+/**
+ * This is a guide placed between items
+ *
+ * Functions
+ * 1. Highlight on drop
+ * 2. Highlight on hover (if new section can be created)
+ */
+export const AuxilaryDashbaordGridPlacementGuide = React.forwardRef(function (
+ { left, right, over, onClick }: AuxilaryGridDropGuide,
+ ref: React.Ref
+) {
+ assert(left !== right, 'You can only have one of "left" or "right"');
+
+ return (
+
+ );
+});
+
+const GUIDE_MARGIN = 4;
+const GUIDE_ACCESSIBLE_WIDTH = 32;
+
+const Guide = styled.div`
+ --guide-margin-vertical: 24px;
+ --color-highlight: rgb(0, 179, 255);
+
+ position: absolute;
+ width: ${GUIDE_ACCESSIBLE_WIDTH}px;
+ top: var(--guide-margin-vertical);
+ bottom: calc(var(--guide-margin-vertical) + 44px);
+
+ &[data-left="true"] {
+ left: ${-(GUIDE_MARGIN + GUIDE_ACCESSIBLE_WIDTH)}px;
+ }
+
+ &[data-right="true"] {
+ right: ${-(GUIDE_MARGIN + GUIDE_ACCESSIBLE_WIDTH)}px;
+ }
+
+ ::after {
+ content: "";
+ position: absolute;
+ opacity: 0;
+ top: 0;
+ /* center under parent */
+ left: 50%;
+
+ width: 2px;
+ height: 100%;
+ background: var(--color-highlight);
+
+ transition: opacity 0.2s ease-in-out;
+ }
+
+ &[data-over="true"] {
+ ::after {
+ opacity: 1;
+ }
+ }
+
+ &:hover {
+ ::after {
+ opacity: 1;
+ }
+ }
+`;
diff --git a/editor-packages/editor-dashboard/components/dashboard-item-card-scene.tsx b/editor-packages/editor-dashboard/components/dashboard-item-card-scene.tsx
index a52068aa0..5080b9a4d 100644
--- a/editor-packages/editor-dashboard/components/dashboard-item-card-scene.tsx
+++ b/editor-packages/editor-dashboard/components/dashboard-item-card-scene.tsx
@@ -7,6 +7,8 @@ import {
DashboardItemCardProps,
} from "./dashboard-item-card";
+const MAX_WIDTH = 240;
+
type SceneMeta = {
id: string;
filekey: string;
@@ -34,6 +36,7 @@ function SceneCardPreview({
return (
}
- preview={}
+ preview={}
/>
);
});
diff --git a/editor-packages/editor-dashboard/components/dashboard-item-card.tsx b/editor-packages/editor-dashboard/components/dashboard-item-card.tsx
index 5a2b0f5d6..af82d0183 100644
--- a/editor-packages/editor-dashboard/components/dashboard-item-card.tsx
+++ b/editor-packages/editor-dashboard/components/dashboard-item-card.tsx
@@ -114,6 +114,7 @@ const Card = styled.div`
`;
const PreviewContainer = styled.div`
+ --color-highlight: rgb(0, 179, 255);
outline: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 2px;
overflow: hidden;
@@ -136,8 +137,14 @@ const PreviewContainer = styled.div`
transition: all 0.2s ease-in-out;
}
+ .scale-on-over {
+ overflow: hidden;
+ will-change: transform;
+ transition: all 0.2s ease-in-out;
+ }
+
&[data-selected="true"] {
- outline: 4px solid rgb(0, 179, 255);
+ outline: 4px solid var(--color-highlight);
#overlay {
display: block;
@@ -145,11 +152,16 @@ const PreviewContainer = styled.div`
}
&[data-over="true"] {
- outline: 4px solid rgb(0, 179, 255);
+ outline: 4px solid var(--color-highlight);
#view {
opacity: 0.5;
}
+
+ .scale-on-over {
+ border-radius: 5px;
+ transform: scale(0.85);
+ }
}
transition: all 0.2s ease-in-out;
diff --git a/editor-packages/editor-dashboard/components/index.ts b/editor-packages/editor-dashboard/components/index.ts
index 6c7b702e8..01740de90 100644
--- a/editor-packages/editor-dashboard/components/index.ts
+++ b/editor-packages/editor-dashboard/components/index.ts
@@ -1,6 +1,6 @@
+export * from "./dashbaord-grid-placement-auxilary-drop-guide";
export * from "./dashboard-item-card-folder";
export * from "./dashboard-item-card-scene";
export * from "./dashboard-item-card";
-export * from "./icon-button";
export * from "./hierarchy-item";
export * from "./section-header";
diff --git a/editor-packages/editor-dashboard/components/section-header.tsx b/editor-packages/editor-dashboard/components/section-header.tsx
index 05280a4c3..9514b2a16 100644
--- a/editor-packages/editor-dashboard/components/section-header.tsx
+++ b/editor-packages/editor-dashboard/components/section-header.tsx
@@ -11,7 +11,7 @@ import {
DropdownMenuContent,
DropdownMenuItem,
} from "@editor-ui/dropdown-menu";
-import { IconButton } from "../components";
+import { IconButton } from "@code-editor/ui";
import Highlighter from "react-highlight-words";
import * as Collapsible from "@radix-ui/react-collapsible";
diff --git a/editor-packages/editor-dashboard/core/provider.tsx b/editor-packages/editor-dashboard/core/provider.tsx
index f1c1a4a66..72e515d75 100644
--- a/editor-packages/editor-dashboard/core/provider.tsx
+++ b/editor-packages/editor-dashboard/core/provider.tsx
@@ -83,7 +83,17 @@ export function useDashboard() {
[editordispatch]
);
- const enterNode = useCallback(
+ const isolateNode = useCallback(
+ (node: string) => {
+ editordispatch({
+ type: "design/enter-isolation",
+ node,
+ });
+ },
+ [editordispatch]
+ );
+
+ const focusNodeOnCanvas = useCallback(
(node: string) => {
editordispatch({
type: "canvas/focus",
@@ -163,7 +173,8 @@ export function useDashboard() {
selection: editorState.selectedNodes,
dispatch,
selectNode,
- enterNode,
+ focusNodeOnCanvas,
+ isolateNode,
blurSelection,
foldAll,
unfoldAll,
diff --git a/editor-packages/editor-dashboard/scaffold/editor-dashboard-hierarchy.tsx b/editor-packages/editor-dashboard/scaffold/editor-dashboard-hierarchy.tsx
index 946ea1d96..2c71a04b7 100644
--- a/editor-packages/editor-dashboard/scaffold/editor-dashboard-hierarchy.tsx
+++ b/editor-packages/editor-dashboard/scaffold/editor-dashboard-hierarchy.tsx
@@ -10,9 +10,18 @@ export function DashboardHierarchy() {
const { hierarchy, selectNode, selection } = useDashboard();
const { sections } = hierarchy;
- // const data = sections.reduce((acc, item) => {
- // return [...acc, ...item.items];
- // }, []);
+ const items = [
+ {
+ id: "scenes",
+ name: "Scenes",
+ path: "scenes://",
+ },
+ {
+ id: "components",
+ name: "Components",
+ path: "components://",
+ },
+ ];
const renderItem = useCallback(
(item: DashboardItem, i: number) => {
@@ -50,11 +59,18 @@ export function DashboardHierarchy() {
);
return (
- item.id, [])}
- renderItem={renderItem}
- />
+
+ item.id, [])}
+ renderItem={renderItem}
+ />
+
);
}
diff --git a/editor-packages/editor-dashboard/scaffold/editor-dashboard.tsx b/editor-packages/editor-dashboard/scaffold/editor-dashboard.tsx
index 6c9b0eacc..803442e54 100644
--- a/editor-packages/editor-dashboard/scaffold/editor-dashboard.tsx
+++ b/editor-packages/editor-dashboard/scaffold/editor-dashboard.tsx
@@ -8,6 +8,8 @@ import {
DashboardItemCardProps,
DASHBOARD_ITEM_CARD_SELECTOR,
DASHBOARD_ITEM_PATH_ATTRIBUTE,
+ AuxilaryDashbaordGridPlacementGuide,
+ AuxilaryGridDropGuideLeftOrRightSpecification,
} from "../components";
import { EditorHomeHeader } from "./editor-dashboard-header";
import { DndProvider, useDrag, useDrop } from "react-dnd";
@@ -31,13 +33,15 @@ export function Dashboard() {
hierarchyFoldings,
filter,
dispatch,
- enterNode,
+ focusNodeOnCanvas: enterNode,
+ // isolateNode: enterNode,
selectNode,
blurSelection,
fold,
unfold,
foldAll,
unfoldAll,
+ mkdir,
selection,
} = useDashboard();
@@ -51,7 +55,7 @@ export function Dashboard() {
const headerActions = [
{
id: "sections/unfold-all",
- label: "Unfold All Sections",
+ label: "Expand All Sections",
handler: unfoldAll,
},
{
@@ -59,6 +63,14 @@ export function Dashboard() {
label: "Fold All Section",
handler: foldAll,
},
+ {
+ id: "sections/new",
+ label: "New Folder",
+ handler: () => {
+ // TODO:
+ mkdir("/");
+ },
+ },
];
return (
@@ -75,7 +87,7 @@ export function Dashboard() {
{hierarchy.sections.map((section, i) => {
const { name, contents } = section;
return (
-
- p !== id));
});
}}
- />
+ /> */}
);
}
-function RootDirectory({
+function Directory({
label,
contents,
query,
@@ -171,7 +183,7 @@ function RootDirectory({
}) {
return (