Repository: preactjs/preact-devtools
Pull request #423 (2022-08-28 04:03:41)

Print Preact render version in sidebar


Patch:
diff --git a/src/adapter/adapter/adapter.ts b/src/adapter/adapter/adapter.ts
index e7106c2..a2bde60 100644
--- a/src/adapter/adapter/adapter.ts
+++ b/src/adapter/adapter/adapter.ts
@@ -38,6 +38,8 @@ export interface InspectData {
 	canSuspend: boolean;
 	/** Only Suspense components have this */
 	suspended: boolean;
+	/** Preact version that rendered this VNode */
+	version: string;
 }
 
 export function createAdapter(
diff --git a/src/adapter/hook.ts b/src/adapter/hook.ts
index 99fa9da..4470b48 100644
--- a/src/adapter/hook.ts
+++ b/src/adapter/hook.ts
@@ -237,6 +237,7 @@ export function createHook(port: PortPageHook): DevtoolsHook {
 					idMapper,
 					bindingsV10,
 					roots,
+					version,
 				);
 				setupOptionsV10(options, renderer, roots, config as any);
 				return attachRenderer(renderer, supports);
@@ -256,6 +257,7 @@ export function createHook(port: PortPageHook): DevtoolsHook {
 					idMapper,
 					bindingsV11,
 					roots,
+					version,
 				);
 				setupOptionsV11(options as any, renderer, roots, config, profiler);
 				return attachRenderer(renderer, {
diff --git a/src/adapter/shared/inspectVNode.ts b/src/adapter/shared/inspectVNode.ts
index 21035ef..dd05610 100644
--- a/src/adapter/shared/inspectVNode.ts
+++ b/src/adapter/shared/inspectVNode.ts
@@ -20,6 +20,7 @@ export function inspectVNode<T extends SharedVNode>(
 	options: Options,
 	id: ID,
 	supportsHooks: boolean,
+	version: string,
 ): InspectData | null {
 	const vnode = getVNodeById(ids, id);
 	if (!vnode) return null;
@@ -74,5 +75,6 @@ export function inspectVNode<T extends SharedVNode>(
 		// TODO: We're not using this information anywhere yet
 		type: getDevtoolsType(vnode, bindings),
 		suspended,
+		version,
 	};
 }
diff --git a/src/adapter/shared/renderer.ts b/src/adapter/shared/renderer.ts
index 57fc728..134b84e 100644
--- a/src/adapter/shared/renderer.ts
+++ b/src/adapter/shared/renderer.ts
@@ -67,6 +67,7 @@ export function createRenderer<T extends SharedVNode>(
 	ids: IdMappingState<T>,
 	bindings: PreactBindings<T>,
 	roots: Map<T, Node>,
+	version: string,
 ): Renderer<T> {
 	let currentUnmounts: number[] = [];
 	let prevOwners = new Map<T, T>();
@@ -108,7 +109,15 @@ export function createRenderer<T extends SharedVNode>(
 	}
 
 	const inspect = (id: ID) => {
-		return inspectVNode(ids, config, bindings, options, id, supports.hooks);
+		return inspectVNode(
+			ids,
+			config,
+			bindings,
+			options,
+			id,
+			supports.hooks,
+			version,
+		);
 	};
 
 	return {
diff --git a/src/view/components/Devtools.module.css b/src/view/components/Devtools.module.css
index c3b21da..e1e642e 100644
--- a/src/view/components/Devtools.module.css
+++ b/src/view/components/Devtools.module.css
@@ -24,8 +24,8 @@ input {
 	padding: 0;
 }
 
-.root p {
-	margin-top: 0;
+p {
+	margin: 0;
 }
 
 .theme {
diff --git a/src/view/components/devtools.css b/src/view/components/devtools.css
index 928d792..78ebce2 100644
--- a/src/view/components/devtools.css
+++ b/src/view/components/devtools.css
@@ -423,6 +423,10 @@
 /**
  * RenderedAt panel
  */
+.rendered-by-wrapper {
+	margin-left: 0.3rem;
+}
+
 .rendered-at-item {
 	background: none;
 	border: none;
@@ -432,7 +436,7 @@
 	display: flex;
 	align-items: center;
 	font-size: var(--font-small);
-	padding: 0.25rem 0.5rem;
+	padding: 0.25rem 1rem;
 	cursor: pointer;
 	border-radius: 0.1875rem;
 }
@@ -448,6 +452,14 @@
 	display: block;
 }
 
+.sidebar-preact-version {
+	color: var(--color-text);
+	font-size: var(--font-small);
+	margin-top: 0.5rem;
+	margin-left: 1rem;
+	display: block;
+}
+
 /**
  * HOC panel
  */
@@ -619,10 +631,6 @@
 	padding: 0.25rem 0 0 0.25rem;
 }
 
-.sidebar-panel-empty {
-	padding-left: 1.4rem;
-}
-
 .sidebar-nav-panel-content {
 	padding-left: 0.4rem;
 }
@@ -1096,6 +1104,10 @@
 	font-weight: lighter;
 }
 
+.settings-tab p {
+	margin-top: 0;
+}
+
 .settings-tab-message {
 	margin-left: 1.25rem;
 	margin-top: 0.5rem;
diff --git a/src/view/components/elements/OwnerInfo.tsx b/src/view/components/elements/OwnerInfo.tsx
index be6f2b4..2f2541b 100644
--- a/src/view/components/elements/OwnerInfo.tsx
+++ b/src/view/components/elements/OwnerInfo.tsx
@@ -33,23 +33,27 @@ export function OwnerInfo() {
 
 	return (
 		<SidebarPanel title="Rendered by">
-			<nav data-testid="owners">
-				{data.length === 0 && <p class="sidebar-panel-empty">-</p>}
-				{data.map(node => {
-					return (
-						<button
-							key={node.id}
-							class="rendered-at-item"
-							data-active={selectedId === node.id}
-							onClick={() => {
-								store.selection.selectById(node.id);
-							}}
-						>
-							{node.name}
-						</button>
-					);
-				})}
-			</nav>
+			<div class="rendered-by-wrapper">
+				<nav data-testid="owners">
+					{data.map(node => {
+						return (
+							<button
+								key={node.id}
+								class="rendered-at-item"
+								data-active={selectedId === node.id}
+								onClick={() => {
+									store.selection.selectById(node.id);
+								}}
+							>
+								{node.name}
+							</button>
+						);
+					})}
+				</nav>
+				<p class="sidebar-preact-version">
+					Preact@{store.inspectData.value?.version || ""}
+				</p>
+			</div>
 		</SidebarPanel>
 	);
 }


Test patch:
diff --git a/src/adapter/protocol/events.test.ts b/src/adapter/protocol/events.test.ts
index aa7948c..0457c15 100644
--- a/src/adapter/protocol/events.test.ts
+++ b/src/adapter/protocol/events.test.ts
@@ -232,6 +232,7 @@ describe("applyEvent", () => {
 			type: "asd",
 			canSuspend: false,
 			suspended: false,
+			version: "",
 		};
 
 		const data = fromSnapshot([
@@ -259,6 +260,7 @@ describe("applyEvent", () => {
 			type: "asd",
 			canSuspend: false,
 			suspended: false,
+			version: "",
 		};
 
 		store.sidebar.props.uncollapsed.value = ["a", "b", "c"];
diff --git a/src/adapter/shared/renderer.test.tsx b/src/adapter/shared/renderer.test.tsx
index 832a7cd..7f62e73 100644
--- a/src/adapter/shared/renderer.test.tsx
+++ b/src/adapter/shared/renderer.test.tsx
@@ -33,6 +33,7 @@ export function setupMockHook(options: Options) {
 		createIdMappingState(1, bindingsV10.getInstance),
 		bindingsV10,
 		roots,
+		"",
 	);
 	const destroy = setupOptionsV10(options, renderer, roots, {
 		Fragment: Fragment as any,
diff --git a/src/adapter/store.test.ts b/src/adapter/store.test.ts
index 4a6e349..5de5b04 100644
--- a/src/adapter/store.test.ts
+++ b/src/adapter/store.test.ts
@@ -85,6 +85,7 @@ describe("Store", () => {
 			state: null,
 			suspended: false,
 			type: 1,
+			version: "",
 		};
 		store.clear();
 		expect(store.inspectData.value).to.equal(null);