- {["team-one", "team-two", "team-three"].map((key, index) => (
-
-
-
-
-
-
- {index === 1 ? (
-
- ) : null}
-
-
-
-
-
-
- ))}
+
+
+
+
);
diff --git a/desktop/src/shared/ui/identity-card-skeleton.tsx b/desktop/src/shared/ui/identity-card-skeleton.tsx
new file mode 100644
index 000000000..31d967eec
--- /dev/null
+++ b/desktop/src/shared/ui/identity-card-skeleton.tsx
@@ -0,0 +1,103 @@
+import { cn } from "@/shared/lib/cn";
+import { Skeleton } from "@/shared/ui/skeleton";
+
+type IdentityCardSkeletonProps = {
+ className?: string;
+ footerSubtitleWidthClass?: string;
+ footerTitleWidthClass?: string;
+ kind?: "single" | "stack";
+ showAction?: boolean;
+ stackCount?: number;
+};
+
+const MAX_STACK_ITEMS = 6;
+const STACK_ITEM_KEYS = [
+ "first",
+ "second",
+ "third",
+ "fourth",
+ "fifth",
+ "sixth",
+];
+
+export function IdentityCardSkeleton({
+ className,
+ footerSubtitleWidthClass = "w-16",
+ footerTitleWidthClass = "w-28",
+ kind = "single",
+ showAction = false,
+ stackCount = 3,
+}: IdentityCardSkeletonProps) {
+ return (
+
+ {showAction ? (
+
+ ) : null}
+
+ {kind === "stack" ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+
+ );
+}
+
+function SingleAvatarSkeleton() {
+ return (
+
+
+
+ );
+}
+
+function StackSkeleton({ count }: { count: number }) {
+ const visibleCount = Math.max(1, Math.min(count, MAX_STACK_ITEMS));
+ const { overlap, size } = getStackMetrics(visibleCount);
+
+ return (
+
+
+ {STACK_ITEM_KEYS.slice(0, visibleCount).map((key, index) => (
+ 0 ? -overlap : 0,
+ width: size,
+ zIndex: index + 1,
+ }}
+ />
+ ))}
+
+
+ );
+}
+
+function getStackMetrics(count: number) {
+ switch (count) {
+ case 1:
+ return { overlap: 0, size: 152 };
+ case 2:
+ return { overlap: 44, size: 124 };
+ case 3:
+ return { overlap: 46, size: 108 };
+ case 4:
+ return { overlap: 50, size: 96 };
+ case 5:
+ return { overlap: 48, size: 86 };
+ default:
+ return { overlap: 46, size: 78 };
+ }
+}