Skip to content

Commit 98bd855

Browse files
Bellianitsdouges
andauthored
UI changes (#382)
* Added subcomponent indicator. * fixed: resizable surface got interrupted by iframe * removed messy typings * removed italic * reverted pretier changes * reduce complexity accessing the body * revorked icons * chore: refactor to use css * chore: style tweaks * chore: nits * docs(changeset): Imported components now show a "link" icon in the element tree to more easily find them against local components / elements. * docs(changeset): Resizing the element tree panel no longer gets stuck on the editor when moving very fast. --------- Co-authored-by: Michael Dougall <6801309+itsdouges@users.noreply.github.com>
1 parent 5b4e347 commit 98bd855

7 files changed

Lines changed: 127 additions & 31 deletions

File tree

.changeset/flat-rivers-move.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@triplex/editor-next": patch
3+
---
4+
5+
Resizing the element tree panel no longer gets stuck on the editor when moving very fast.

.changeset/twelve-papayas-laugh.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@triplex/editor-next": patch
3+
---
4+
5+
Imported components now show a "link" icon in the element tree to more easily find them against local components / elements.

packages/@triplex/editor-next/src/components/resizable-surface.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export function ResizableSurface({
7979
"--local-resizing-width",
8080
`${getProposedWidth({ initialWidth, location, splitterPosition })}px`,
8181
);
82+
document.body.style.setProperty("--canvas-pointer-events", `none`);
8283
},
8384
onDragStart() {
8485
telemetry.event(actionId.resizeStart);
@@ -94,6 +95,7 @@ export function ResizableSurface({
9495
getProposedWidth({ initialWidth, location, splitterPosition }),
9596
);
9697
containerRef.current?.style.removeProperty("--local-resizing-width");
98+
document.body.style.removeProperty("--canvas-pointer-events");
9799
},
98100
onGenerateDragPreview({ nativeSetDragImage }) {
99101
disableNativeDragPreview({ nativeSetDragImage });
@@ -133,7 +135,7 @@ export function ResizableSurface({
133135
state === "drag" && "opacity-100",
134136
splitterPosition === "end" && "-right-1.5 border-l-4",
135137
splitterPosition === "start" && "-left-1.5 border-r-4",
136-
"absolute bottom-0 top-0 z-10 w-2 cursor-col-resize border-[var(--vscode-sash-hoverBorder)] opacity-0 delay-0 duration-100 hover:opacity-100 hover:transition-opacity hover:delay-200 hover:duration-150",
138+
"group absolute bottom-0 top-0 z-10 w-2 cursor-col-resize border-[var(--vscode-sash-hoverBorder)] opacity-0 delay-0 duration-100 hover:opacity-100 hover:transition-opacity hover:delay-200 hover:duration-150",
137139
])}
138140
data-testid="panel-drag-handle"
139141
ref={ref}

packages/@triplex/editor-next/src/features/app-root/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export function AppRoot() {
3131
data-testid="scene"
3232
id="scene"
3333
src={`http://localhost:${window.triplex.env.ports.client}/scene`}
34+
style={{ pointerEvents: "var(--canvas-pointer-events, auto)" /* can be used to disable pointer events on iframe */ }}
3435
/>
3536
</div>
3637
{fg("ai_chat") && <AIChat />}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Copyright (c) 2022—present Michael Dougall. All rights reserved.
3+
*
4+
* This repository utilizes multiple licenses across different directories. To
5+
* see this files license find the nearest LICENSE file up the source tree.
6+
*/
7+
import {
8+
ChevronDownIcon,
9+
ChevronRightIcon,
10+
Link2Icon,
11+
} from "@radix-ui/react-icons";
12+
import { cn } from "@triplex/lib";
13+
import { Pressable } from "../../components/pressable";
14+
15+
export function ShowElementChildrenButton({
16+
hasChildren,
17+
id,
18+
isCustomComponent,
19+
isExpanded,
20+
isImportedComponent,
21+
setExpanded,
22+
}: {
23+
hasChildren: boolean;
24+
id: string;
25+
isCustomComponent: boolean;
26+
isExpanded: boolean;
27+
isImportedComponent: boolean;
28+
setExpanded: (value: (prev: boolean) => boolean) => void;
29+
}) {
30+
const shouldShow = isCustomComponent || hasChildren;
31+
const shouldShowExternalComponentIcon =
32+
isCustomComponent && isImportedComponent;
33+
34+
if (!shouldShow) {
35+
return <div className="w-[0.5px]" />;
36+
}
37+
38+
return (
39+
<Pressable
40+
actionId={
41+
isExpanded ? "scenepanel_element_collapse" : "scenepanel_element_expand"
42+
}
43+
className="z-10 -ml-[5px] grid grid-cols-1 grid-rows-1 items-center justify-center px-0.5"
44+
describedBy={id}
45+
onClick={() => setExpanded((state) => !state)}
46+
>
47+
{shouldShowExternalComponentIcon && (
48+
<Link2Icon className="col-start-1 row-start-1 opacity-100 transition-opacity group-focus-within:opacity-0 group-hover:opacity-0" />
49+
)}
50+
51+
{isExpanded ? (
52+
<ChevronDownIcon
53+
aria-label="Hide Children"
54+
className={cn([
55+
"col-start-1 row-start-1",
56+
shouldShowExternalComponentIcon &&
57+
"opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100",
58+
])}
59+
/>
60+
) : (
61+
<ChevronRightIcon
62+
aria-label="Show Children"
63+
className={cn([
64+
"col-start-1 row-start-1",
65+
shouldShowExternalComponentIcon &&
66+
"opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100",
67+
])}
68+
/>
69+
)}
70+
</Pressable>
71+
);
72+
}

packages/@triplex/editor-next/src/features/panels/element.tsx

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ import {
99
dropTargetForElements,
1010
monitorForElements,
1111
} from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
12-
import {
13-
ChevronDownIcon,
14-
ChevronRightIcon,
15-
ComponentInstanceIcon,
16-
} from "@radix-ui/react-icons";
1712
import { compose, on, send } from "@triplex/bridge/host";
1813
import { cn } from "@triplex/lib";
1914
import { fg } from "@triplex/lib/fg";
@@ -43,6 +38,7 @@ import {
4338
} from "../../util/dnd";
4439
import { useSceneEvents, useSceneSelected } from "../app-root/context";
4540
import { ChildSelectedContext } from "./context";
41+
import { ShowElementChildrenButton } from "./element-children-button";
4642

4743
const blockAll: InstructionType[] = [
4844
"make-child",
@@ -82,7 +78,7 @@ export function SceneElement(
8278
const [_isActive, setIsActive] = useState(false);
8379
const [isForciblyHovered, setForciblyHovered] = useState(false);
8480
const isCustomComponent =
85-
props.type === "custom" && props.exportName && props.path;
81+
props.type === "custom" && !!props.exportName && !!props.path;
8682
const hasChildren = props.children.length > 0;
8783
const [isUserExpanded, setExpanded] = useState(
8884
!isCustomComponent && hasChildren,
@@ -105,6 +101,12 @@ export function SceneElement(
105101
const isExpanded = isUserExpanded || !!filter;
106102
const notifyParentSelected = use(ChildSelectedContext);
107103

104+
// a component is considered "imported" if it is a custom type but its children do not include the components own AST path OR its path is different from its parent's path
105+
const isImportedComponent =
106+
props.type === "custom" &&
107+
((props.path && props.path !== props.parentPath) ||
108+
!props.children.some((child) => child.astPath.includes(props.astPath)));
109+
108110
interface DragData {
109111
astPath: string;
110112
column: number;
@@ -291,7 +293,12 @@ export function SceneElement(
291293
}, [dropState]);
292294

293295
return (
294-
<li className="relative">
296+
<li
297+
className={cn([
298+
"relative",
299+
isExpanded && isImportedComponent && "bg-overlay",
300+
])}
301+
>
295302
{(hasChildren || isCustomComponent) && (
296303
<div
297304
className={cn([
@@ -332,29 +339,14 @@ export function SceneElement(
332339
])}
333340
/>
334341
)}
335-
{(isCustomComponent || hasChildren) && (
336-
<Pressable
337-
actionId={
338-
isExpanded
339-
? "scenepanel_element_collapse"
340-
: "scenepanel_element_expand"
341-
}
342-
className="z-10 -ml-[5px] px-0.5"
343-
describedBy={id}
344-
onClick={() => setExpanded((state) => !state)}
345-
>
346-
{isExpanded ? (
347-
<ChevronDownIcon aria-label="Hide Children" />
348-
) : (
349-
<ChevronRightIcon aria-label="Show Children" />
350-
)}
351-
</Pressable>
352-
)}
353-
{!isCustomComponent && !hasChildren && (
354-
<div className="-ml-[5px] flex flex-shrink-0 items-center px-0.5 opacity-0">
355-
<ComponentInstanceIcon />
356-
</div>
357-
)}
342+
<ShowElementChildrenButton
343+
hasChildren={hasChildren}
344+
id={id}
345+
isCustomComponent={isCustomComponent}
346+
isExpanded={isExpanded}
347+
isImportedComponent={isImportedComponent}
348+
setExpanded={setExpanded}
349+
/>
358350
<Pressable
359351
actionId="scenepanel_element_focus"
360352
className="outline-offset-inset absolute inset-0"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Copyright (c) 2022—present Michael Dougall. All rights reserved.
3+
*
4+
* This repository utilizes multiple licenses across different directories. To
5+
* see this files license find the nearest LICENSE file up the source tree.
6+
*/
7+
import "react";
8+
9+
declare module "react" {
10+
11+
interface HTMLAttributes {
12+
inert?: boolean;
13+
}
14+
15+
interface CSSProperties {
16+
[key: `--${string}`]: string | number | null | undefined;
17+
pointerEvents?: string;
18+
}
19+
}

0 commit comments

Comments
 (0)