diff --git a/core/client.js b/core/client.js
index dd7cc2a4..52d66d8a 100644
--- a/core/client.js
+++ b/core/client.js
@@ -207,6 +207,62 @@ class TfFilesElement extends LitElement {
 }
 customElements.define('tf-files', TfFilesElement);
 
+class TfFilesPaneElement extends LitElement {
+	static get properties() {
+		return {
+			expanded: {type: Boolean},
+			current: {type: String},
+			files: {type: Object},
+		};
+	}
+
+	constructor() {
+		super();
+		this.expanded = window.localStorage.getItem('files') == '1';
+		this.files = {};
+	}
+
+	set_expanded(expanded) {
+		this.expanded = expanded;
+		window.localStorage.setItem('files', expanded ? '1' : '0');
+	}
+
+	render() {
+		let self = this;
+		let expander = this.expanded ?
+			html` self.set_expanded(false)} class="expander">«` :
+			html` self.set_expanded(true)} class="expander">»`;
+		let content = html`
+			
+				
 openFile(event.detail.file)}>
+				
+				
+				
+			
 
+		`;
+		return html`
+			
+			
+				
+					${this.expanded ? html`Files` : undefined}
+					${expander}
+				
+				${this.expanded ? content : undefined}
+			
 
+		`;
+	}
+}
+customElements.define('tf-files-pane', TfFilesPaneElement);
+
 class TfSparkLineElement extends LitElement {
 	static get properties() {
 		return {
@@ -362,16 +418,6 @@ function edit() {
 	});
 }
 
-function hideFiles() {
-	window.localStorage.setItem('files', '0');
-	document.getElementById('filesPane').classList.add('collapsed');
-}
-
-function showFiles() {
-	window.localStorage.setItem('files', '1');
-	document.getElementById('filesPane').classList.remove('collapsed');
-}
-
 function trace() {
 	window.open(`/speedscope/#profileURL=${encodeURIComponent('/trace')}`);
 }
@@ -1058,11 +1104,13 @@ function openFile(name) {
 }
 
 function updateFiles() {
-	let files = document.getElementById("files_list");
-	files.files = Object.fromEntries(Object.keys(gFiles).map(file => [file, {
-		clean: gFiles[file].doc.isClean(gFiles[file].generation),
-	}]));
-	files.current = gCurrentFile;
+	let files = document.getElementsByTagName("tf-files-pane")[0];
+	if (files) {
+		files.files = Object.fromEntries(Object.keys(gFiles).map(file => [file, {
+			clean: gFiles[file].doc.isClean(gFiles[file].generation),
+		}]));
+		files.current = gCurrentFile;
+	}
 
 	gEditor.focus();
 }
@@ -1096,8 +1144,6 @@ window.addEventListener("load", function() {
 	window.addEventListener("message", message, false);
 	window.addEventListener("online", connectSocket);
 	document.getElementById("name").value = window.location.pathname;
-	document.getElementById('files_hide').addEventListener('click', () => hideFiles());
-	document.getElementById('files_show').addEventListener('click', () => showFiles());
 	document.getElementById('closeStats').addEventListener('click', () => closeStats());
 	document.getElementById('closeEditor').addEventListener('click', () => closeEditor());
 	document.getElementById('save').addEventListener('click', () => save());
@@ -1111,8 +1157,6 @@ window.addEventListener("load", function() {
 		event.preventDefault();
 		toggleStats();
 	});
-	document.getElementById('new_file_button').addEventListener('click', () => newFile());
-	document.getElementById('remove_file_button').addEventListener('click', () => removeFile());
 	for (let tag of document.getElementsByTagName('a')) {
 		if (tag.accessKey) {
 			tag.classList.add('tooltip_parent');
@@ -1145,15 +1189,9 @@ window.addEventListener("load", function() {
 	} else {
 		closeEditor();
 	}
-	if (window.localStorage.getItem('files') == '1') {
-		showFiles();
-	} else {
-		hideFiles();
-	}
 	if (window.localStorage.getItem('stats') == '1') {
 		stats();
 	} else {
 		closeStats();
 	}
-	document.getElementById('files_list').addEventListener('file_click', event => openFile(event.detail.file));
 });
diff --git a/core/index.html b/core/index.html
index bdbd69b1..9b9d1c77 100644
--- a/core/index.html
+++ b/core/index.html
@@ -26,19 +26,7 @@