feat: enhance onboarding
This commit is contained in:
1 parent
ece6757979
commit
775ae0147c
23 files changed
+415
-170
No files matched your search
@@ -18,6 +18,7 @@ export { LanguageIcon } from "./language-icon";
|
||||
export { LanguageCombobox } from "./language-combobox";
|
||||
export { ColorSchemeCombobox } from "./color-scheme-combobox";
|
||||
export { BoardColorInput } from "./board-color-input";
|
||||
export { IntegrationMarquee } from "./integration-marquee";
|
||||
export { Link } from "./link";
|
||||
export {
|
||||
SelectGridLayout,
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
.root {
|
||||
--integration-marquee-accent: var(--mantine-primary-color-filled);
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: var(--mantine-spacing-xl);
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
transform: rotate(10deg);
|
||||
}
|
||||
|
||||
.track {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--mantine-spacing-xl);
|
||||
animation: integrationMarquee var(--marquee-duration) linear infinite;
|
||||
}
|
||||
|
||||
.iconFrame {
|
||||
display: grid;
|
||||
flex: 0 0 4.5rem;
|
||||
width: 4.5rem;
|
||||
height: 4.5rem;
|
||||
place-items: center;
|
||||
border: 1px solid color-mix(in srgb, var(--integration-marquee-accent) 24%, transparent);
|
||||
border-radius: var(--mantine-radius-lg);
|
||||
background: color-mix(in srgb, var(--integration-marquee-accent) 8%, var(--mantine-color-body));
|
||||
box-shadow: var(--mantine-shadow-sm);
|
||||
}
|
||||
|
||||
@keyframes integrationMarquee {
|
||||
to {
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.track {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
declare const classes: Record<string, string>;
|
||||
export default classes;
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { CSSProperties } from "react";
|
||||
import { Image } from "@mantine/core";
|
||||
|
||||
import { splitToNChunks } from "@homarr/common";
|
||||
import { integrationDefs } from "@homarr/definitions";
|
||||
|
||||
import classes from "./integration-marquee.module.css";
|
||||
|
||||
const iconGroups = splitToNChunks(
|
||||
Object.values(integrationDefs)
|
||||
.filter((integration) => integration.name !== "Mock")
|
||||
.map((integration) => integration.iconUrl),
|
||||
3,
|
||||
);
|
||||
const animationDuration = iconGroups.flat().length * 2;
|
||||
|
||||
export const IntegrationMarquee = ({ className }: { className?: string }) => (
|
||||
<div className={[classes.root, className].filter(Boolean).join(" ")} aria-hidden>
|
||||
{iconGroups.map((icons, columnIndex) => (
|
||||
<div
|
||||
key={columnIndex}
|
||||
className={classes.track}
|
||||
style={{ "--marquee-duration": `${animationDuration - columnIndex * 3}s` } as CSSProperties}
|
||||
>
|
||||
{[...icons, ...icons].map((icon, iconIndex) => (
|
||||
<div key={`${icon}-${iconIndex}`} className={classes.iconFrame}>
|
||||
<Image src={icon} alt="" fit="contain" w={52} h={52} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
Reference in new issue
Block a user