fix(docs): cycle integration flow icons

This commit is contained in:
ajnart committed 2026-08-13 22:21:40 +02:00
1 parent 2257fe2a08
commit e656731729
2 files changed
+44 -55

No files matched your search

@@ -1,20 +1,15 @@
import styles from "../../../../pages/index.module.css";
import { supportedIntegrations } from "../../../../constants/supported-integrations";
const featuredIntegrations = [
{ name: "Radarr", position: styles.dataflowNodeTopLeft },
{ name: "Sonarr", position: styles.dataflowNodeMiddleLeft },
{ name: "Lidarr", position: styles.dataflowNodeBottomLeft },
{ name: "SABnzbd", position: styles.dataflowNodeTopRight },
{ name: "Jellyfin", position: styles.dataflowNodeMiddleRight },
].map((node) => ({
...node,
image: supportedIntegrations.find((integration) => integration.name === node.name)?.iconUrl ?? "",
}));
const featuredNames = new Set(["Homarr", ...featuredIntegrations.map((integration) => integration.name)]);
const otherIntegrations = supportedIntegrations.filter((integration) => !featuredNames.has(integration.name));
const iconCycleStepInSeconds = 1.4;
const nodePositions = [
styles.dataflowNodeTopLeft,
styles.dataflowNodeMiddleLeft,
styles.dataflowNodeBottomLeft,
styles.dataflowNodeTopRight,
styles.dataflowNodeMiddleRight,
styles.dataflowNodeBottomRight,
];
const cyclingIntegrations = supportedIntegrations.filter((integration) => integration.name !== "Homarr");
const paths = [
"M145 82 C330 82 330 235 480 260",
@@ -39,7 +34,7 @@ export const DataflowVisualizationComponent = () => (
<div
className={styles.dataflowDiagram}
role="img"
aria-label="Information flowing both ways between Homarr, Radarr, Sonarr, Lidarr, SABnzbd, Jellyfin, and 19 more integrations"
aria-label={`Information flowing both ways between Homarr and rotating examples from ${cyclingIntegrations.length} supported integrations`}
>
<svg className={styles.dataflowLines} viewBox="0 0 960 520" preserveAspectRatio="none" aria-hidden="true">
{paths.map((path) => (
@@ -51,30 +46,35 @@ export const DataflowVisualizationComponent = () => (
))}
</svg>
{featuredIntegrations.map((integration) => (
<div className={`${styles.dataflowNode} ${integration.position}`} key={integration.name}>
<img src={integration.image} alt="" width={54} height={54} />
</div>
))}
{nodePositions.map((position, nodeIndex) => {
const cycleStepInSeconds = 1.2 + nodeIndex * 0.13;
const phaseOffsetInSeconds = nodeIndex * 2.7;
<div className={`${styles.dataflowNode} ${styles.dataflowNodeBottomRight}`}>
<div className={styles.dataflowMoreIcons} aria-hidden="true">
{otherIntegrations.map((integration, index) => (
<img
src={integration.iconUrl}
alt=""
width={54}
height={54}
key={integration.name}
style={{
animationDelay: `${-index * iconCycleStepInSeconds}s`,
animationDuration: `${otherIntegrations.length * iconCycleStepInSeconds}s`,
}}
/>
))}
</div>
<span>+{otherIntegrations.length} more</span>
</div>
return (
<div className={`${styles.dataflowNode} ${position}`} key={position}>
<div className={styles.dataflowCyclingIcons} aria-hidden="true">
{cyclingIntegrations.map((_, integrationIndex) => {
const integration =
cyclingIntegrations[(integrationIndex + nodeIndex * 4) % cyclingIntegrations.length];
return (
<img
src={integration.iconUrl}
alt=""
width={54}
height={54}
key={integration.name}
style={{
animationDelay: `${-(integrationIndex * cycleStepInSeconds + phaseOffsetInSeconds)}s`,
animationDuration: `${cyclingIntegrations.length * cycleStepInSeconds}s`,
}}
/>
);
})}
</div>
</div>
);
})}
<div className={`${styles.dataflowNode} ${styles.dataflowHub}`}>
<img src="/img/logo.png" alt="" width={86} height={86} />
+6 -17
View File
@@ -323,13 +323,13 @@ section {
object-fit: contain;
}
.dataflowMoreIcons {
.dataflowCyclingIcons {
position: relative;
width: clamp(2rem, 4.5vw, 3.4rem);
aspect-ratio: 1;
}
.dataflowMoreIcons img {
.dataflowCyclingIcons img {
position: absolute;
inset: 0;
width: 100%;
@@ -338,17 +338,6 @@ section {
animation: dataflow-icon-cycle linear infinite;
}
.dataflowNode span {
overflow: hidden;
width: 100%;
font-size: clamp(0.68rem, 1.4vw, 0.875rem);
font-weight: 700;
line-height: 1.2;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
}
.dataflowNodeTopLeft,
.dataflowNodeMiddleLeft,
.dataflowNodeBottomLeft {
@@ -398,12 +387,12 @@ section {
@keyframes dataflow-icon-cycle {
0%,
4.8% {
3.7% {
opacity: 1;
transform: scale(1);
}
5.3%,
4.2%,
99% {
opacity: 0;
transform: scale(0.82);
@@ -483,7 +472,7 @@ section {
.statusDotFailed,
.dataflowSignal,
.dataflowSignalReverse,
.dataflowMoreIcons img {
.dataflowCyclingIcons img {
animation: none;
}
@@ -492,7 +481,7 @@ section {
display: none;
}
.dataflowMoreIcons img:first-child {
.dataflowCyclingIcons img:first-child {
opacity: 1;
}
}