Skip to content

Instantly share code, notes, and snippets.

@Bluscream
Last active November 3, 2025 10:37
Show Gist options
  • Select an option

  • Save Bluscream/c8d075d014d600126b9683bbb4f302bb to your computer and use it in GitHub Desktop.

Select an option

Save Bluscream/c8d075d014d600126b9683bbb4f302bb to your computer and use it in GitHub Desktop.
HomeAssistant Hide My calendars pane userscript
// ==UserScript==
// @name HomeAssistant Hide/Shrink My calendars Pane
// @namespace http://tampermonkey.net/
// @version 3.2
// @description Hide empty "My Calendars" pane, make it 50% narrower if has content
// @author Bluscream, Cursor.AI
// @homepage https://gist.github.com/Bluscream/c8d075d014d600126b9683bbb4f302bb
// @downloadURL https://gist.github.com/Bluscream/c8d075d014d600126b9683bbb4f302bb/raw/hass-hide-calendars-pane.user.js
// @updateURL https://gist.github.com/Bluscream/c8d075d014d600126b9683bbb4f302bb/raw/hass-hide-calendars-pane.user.js
// @match *://homeassistant.local*/calendar*
// @match *://192.168.2.4:*/calendar*
// @match *://192.168.2.4/calendar*
// @match *://100.100.1.4:*/calendar*
// @match *://100.100.1.4/calendar*
// @grant none
// @run-at document-end
// ==/UserScript==
(function () {
"use strict";
console.log("πŸš€ Hide Meine Kalender userscript starting...");
// Function to navigate through shadow DOM and find empty panes
function hideEmptyPane() {
try {
const homeAssistant = document.querySelector("home-assistant");
if (!homeAssistant?.shadowRoot) return false;
const main = homeAssistant.shadowRoot.querySelector(
"home-assistant-main"
);
if (!main?.shadowRoot) return false;
const drawer = main.shadowRoot.querySelector("ha-drawer");
if (!drawer) return false;
const panelResolver = drawer.querySelector("partial-panel-resolver");
if (!panelResolver) return false;
const calendar = panelResolver.querySelector("ha-panel-calendar");
if (!calendar?.shadowRoot) return false;
const topBar = calendar.shadowRoot.querySelector(
"ha-two-pane-top-app-bar-fixed"
);
if (!topBar?.shadowRoot) return false;
// Find all div.pane elements
const panes = topBar.shadowRoot.querySelectorAll("div.pane");
console.log(`πŸ“Š Found ${panes.length} pane(s)`);
let foundPane = false;
for (const pane of panes) {
// Check if this pane has calendar items
const items = pane.querySelectorAll("ha-check-list-item");
console.log(`Pane has ${items.length} calendar items`);
if (items.length === 0) {
// Hide if empty
console.log("🎯 Found empty pane, hiding it...");
pane.style.display = "none";
console.log("βœ… Empty Meine Kalender pane hidden!");
foundPane = true;
} else {
// Make 50% narrower if has content
console.log("πŸ“ Making pane 50% narrower...");
pane.style.width = "50%";
pane.style.maxWidth = "250px";
console.log("βœ… Pane width reduced!");
foundPane = true;
}
}
if (foundPane) {
return true;
}
console.log("ℹ️ No panes found");
return false;
} catch (e) {
console.error("❌ Error:", e);
return false;
}
}
// Initialize with retry logic
function init() {
let attempts = 0;
const maxAttempts = 30; // Try for up to 15 seconds
const interval = setInterval(() => {
attempts++;
if (hideEmptyPane() || attempts >= maxAttempts) {
clearInterval(interval);
if (attempts >= maxAttempts) {
console.log("⚠️ Max attempts reached");
}
}
}, 500);
}
// Observe DOM changes
const observer = new MutationObserver(() => {
hideEmptyPane();
});
// Start when ready
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => {
init();
observer.observe(document.body, { childList: true, subtree: true });
});
} else {
init();
observer.observe(document.body, { childList: true, subtree: true });
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment