This Confluence user macro lets users add a customizable tile to a page. You can configure the tile's title, subtitle, icon, icon color, and background color theme. An optional external link can be added to the top-right corner, opening in a new tab when clicked.
The tile supports light styling, hover effects, and color filtering for icons using CSS.
More icons can be found at Iconoir.
#*
This user macro renders a single visual tile with customizable icon, title, subtitle, link, and color theme.
*#
#set($title = $parameters["title"])
#set($subtitle = $parameters["subtitle"])
#set($imageUrl = $parameters["imageUrl"])
#set($link = $parameters["link"])
#set($iconColor = $parameters["iconColor"])
#set($tileTheme = $parameters["tileTheme"])
<div id="tiles-container" style="display: flex; gap: 1rem; padding: 10px;"></div>
<script>
const title = "$title" || "Your title";
const subtitle = "$subtitle" || "Your subtitle";
const imgUrl = "$imageUrl" || "https://cdn.jsdelivr.net/npm/iconoir@6/icons/book.svg";
const link = "$link";
const iconColor = "$iconColor";
const tileTheme = "$tileTheme";
const colorFilters = {
blue: "invert(31%) sepia(99%) saturate(3489%) hue-rotate(216deg) brightness(94%) contrast(102%)",
green: "invert(52%) sepia(42%) saturate(723%) hue-rotate(75deg) brightness(92%) contrast(85%)",
red: "invert(25%) sepia(92%) saturate(1818%) hue-rotate(348deg) brightness(89%) contrast(100%)",
yellow: "invert(93%) sepia(89%) saturate(1021%) hue-rotate(360deg) brightness(102%) contrast(104%)",
purple: "invert(20%) sepia(75%) saturate(1383%) hue-rotate(250deg) brightness(90%) contrast(96%)",
orange: "invert(64%) sepia(94%) saturate(1234%) hue-rotate(5deg) brightness(101%) contrast(100%)",
gray: "invert(53%) sepia(0%) saturate(0%) hue-rotate(179deg) brightness(90%) contrast(92%)"
};
const themes = {
sky: {
background: "#E9F2FF",
text: "#0c4a6e",
meta: "#1e3a8a"
},
blush: {
background: "#FFECF8",
text: "#831843",
meta: "#9d174d"
},
mint: {
background: "#DCFFF1",
text: "#064e3b",
meta: "#065f46"
},
gray: {
background: "#091E4208",
text: "#101214",
meta: "#091E427D"
}
};
const theme = themes[tileTheme] || {};
const container = document.getElementById("tiles-container");
const div = document.createElement("div");
div.style.cssText =
"position: relative;" +
"display: flex;" +
"flex-direction: column;" +
"align-items: flex-start;" +
"width: 100vw;" +
"box-sizing: border-box;" +
"padding: 1rem;" +
"border: 1px solid #ccc;" +
"border-radius: 6px;" +
"transition: box-shadow 0.3s ease;" +
"cursor: pointer;" +
"background: " + theme.background + ";";
if (link) {
const icon = document.createElement("div");
icon.innerHTML = `
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"
viewBox="0 0 24 24" fill="none" stroke="#666" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M18 13v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
<polyline points="15 3 21 3 21 9" />
<line x1="10" y1="14" x2="21" y2="3" />
</svg>
`;
icon.style.cssText =
"position: absolute;" +
"top: 0.5rem;" +
"right: 0.5rem;" +
"opacity: 0;" +
"transition: opacity 0.2s, transform 0.2s, stroke 0.2s;" +
"cursor: pointer;";
icon.title = "Open in a new tab";
icon.onclick = () => {
window.open(link, "_blank");
setTimeout(() => {
div.style.boxShadow = "none";
icon.style.opacity = "0";
icon.querySelector("svg").style.stroke = "#666";
}, 50);
};
div.addEventListener("mouseenter", () => {
div.style.boxShadow = "0 8px 24px rgba(0, 0, 0, 0.2)";
icon.style.opacity = "1";
});
div.addEventListener("mouseleave", () => {
div.style.boxShadow = "none";
icon.style.opacity = "0";
});
icon.addEventListener("mouseenter", () => {
const svg = icon.querySelector("svg");
svg.style.stroke = "#1d4ed8";
svg.style.transform = "scale(1.1)";
});
icon.addEventListener("mouseleave", () => {
const svg = icon.querySelector("svg");
svg.style.stroke = "#666";
svg.style.transform = "scale(1)";
});
div.appendChild(icon);
}
const img = document.createElement("img");
img.src = imgUrl;
img.alt = title;
img.style.cssText = "width: 40px; height: 40px; object-fit: contain; margin-bottom: 0.5rem;";
if (colorFilters[iconColor]) {
img.style.filter = colorFilters[iconColor];
}
const titleDiv = document.createElement("div");
titleDiv.textContent = title;
titleDiv.style.cssText = "font-weight: bold;" + "margin-bottom: 1.5rem;" + "color: " + theme.text + ";";
const subtitleDiv = document.createElement("div");
subtitleDiv.textContent = subtitle;
subtitleDiv.style.cssText = "font-size: 0.85rem;" + "color: " + theme.meta + ";";
div.appendChild(img);
div.appendChild(titleDiv);
div.appendChild(subtitleDiv);
container.appendChild(div);
</script>Show confetti bursts and a motivational message upon saving an edited page
Create dropdown menus in Confluence Cloud with predefined sets of options, multiselect features, and permission gates
Content that is hidden only if a user is in a particular group
Show filtered issues and their relations
Shows page creation date
Add a configurable floating panel to a Confluence page
Get the latest cryptocurrency rates for major coins.
Space Information macro by space Id
Add a floating scroll-to-top arrow button in pages. Always visible, lightweight, and improves navigation for long documents.
Generate a list of labels from all spaces leading to corresponding content pages, organized in alphabetical order.