← back to kbarnoski__melody-memo

Function bodies 245 total

All specs Real LLM only Function bodies
formatTime function · typescript · L26-L30 (5 LOC)
src/components/markers/markers-panel.tsx
function formatTime(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = Math.floor(seconds % 60);
  return `${m}:${s.toString().padStart(2, "0")}`;
}
MarkersPanel function · typescript · L32-L210 (179 LOC)
src/components/markers/markers-panel.tsx
export function MarkersPanel({
  recordingId,
  currentTime,
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  duration,
  onSeek,
  onMarkersChange,
}: MarkersPanelProps) {
  const [markers, setMarkers] = useState<Marker[]>([]);
  const [isAdding, setIsAdding] = useState(false);
  const [newLabel, setNewLabel] = useState("");

  const updateParent = useCallback(
    (updated: Marker[]) => {
      setMarkers(updated);
      onMarkersChange?.(updated);
    },
    [onMarkersChange]
  );

  useEffect(() => {
    async function loadMarkers() {
      const supabase = createClient();
      const { data } = await supabase
        .from("markers")
        .select("id, time, label, color")
        .eq("recording_id", recordingId)
        .order("time");
      if (data) {
        updateParent(data);
      }
    }
    loadMarkers();
  }, [recordingId, updateParent]);

  async function addMarker() {
    const label = newLabel.trim();
    if (!label) return;

    const supabase = cr
loadMarkers function · typescript · L53-L63 (11 LOC)
src/components/markers/markers-panel.tsx
    async function loadMarkers() {
      const supabase = createClient();
      const { data } = await supabase
        .from("markers")
        .select("id, time, label, color")
        .eq("recording_id", recordingId)
        .order("time");
      if (data) {
        updateParent(data);
      }
    }
addMarker function · typescript · L67-L97 (31 LOC)
src/components/markers/markers-panel.tsx
  async function addMarker() {
    const label = newLabel.trim();
    if (!label) return;

    const supabase = createClient();
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) return;

    const { data, error } = await supabase
      .from("markers")
      .insert({
        recording_id: recordingId,
        user_id: user.id,
        time: currentTime,
        label,
        color: "#primary",
      })
      .select("id, time, label, color")
      .single();

    if (error) {
      toast.error("Failed to add marker");
      return;
    }

    const updated = [...markers, data].sort((a, b) => a.time - b.time);
    updateParent(updated);
    setNewLabel("");
    setIsAdding(false);
    toast.success("Marker added");
  }
deleteMarker function · typescript · L99-L113 (15 LOC)
src/components/markers/markers-panel.tsx
  async function deleteMarker(id: string) {
    const supabase = createClient();
    const { error } = await supabase
      .from("markers")
      .delete()
      .eq("id", id);

    if (error) {
      toast.error("Failed to delete marker");
      return;
    }

    const updated = markers.filter((m) => m.id !== id);
    updateParent(updated);
  }
Sidebar function · typescript · L31-L190 (160 LOC)
src/components/nav/sidebar.tsx
export function Sidebar() {
  const pathname = usePathname();
  const router = useRouter();
  const [mobileOpen, setMobileOpen] = useState(false);
  const [mounted, setMounted] = useState(false);
  const { setTheme, resolvedTheme } = useTheme();

  useEffect(() => setMounted(true), []);

  // Close mobile sidebar on route change
  useEffect(() => {
    setMobileOpen(false);
  }, [pathname]);

  // Prevent body scroll when mobile sidebar is open
  useEffect(() => {
    if (mobileOpen) {
      document.body.style.overflow = "hidden";
    } else {
      document.body.style.overflow = "";
    }
    return () => {
      document.body.style.overflow = "";
    };
  }, [mobileOpen]);

  async function handleSignOut() {
    const supabase = createClient();
    await supabase.auth.signOut();
    router.push("/login");
    router.refresh();
  }

  const logo = (
    <div className="flex items-center gap-2.5">
      <svg
        viewBox="0 0 24 24"
        fill="none"
        className="h-6 w-6 te
handleSignOut function · typescript · L57-L62 (6 LOC)
src/components/nav/sidebar.tsx
  async function handleSignOut() {
    const supabase = createClient();
    await supabase.auth.signOut();
    router.push("/login");
    router.refresh();
  }
Repobility analyzer · published findings · https://repobility.com
Providers function · typescript · L5-L11 (7 LOC)
src/components/providers.tsx
export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <ThemeProvider attribute="class" defaultTheme="light" disableTransitionOnChange>
      {children}
    </ThemeProvider>
  );
}
formatDateDisplay function · typescript · L14-L21 (8 LOC)
src/components/recordings/editable-date.tsx
function formatDateDisplay(dateString: string): string {
  const d = new Date(dateString);
  return d.toLocaleDateString("en-US", {
    month: "long",
    day: "numeric",
    year: "numeric",
  });
}
toInputValue function · typescript · L23-L29 (7 LOC)
src/components/recordings/editable-date.tsx
function toInputValue(dateString: string): string {
  const d = new Date(dateString);
  const year = d.getFullYear();
  const month = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${month}/${day}/${year}`;
}
parseInput function · typescript · L31-L40 (10 LOC)
src/components/recordings/editable-date.tsx
function parseInput(value: string): Date | null {
  // Accept MM/DD/YYYY
  const parts = value.split("/");
  if (parts.length !== 3) return null;
  const [m, d, y] = parts.map(Number);
  if (!m || !d || !y || m < 1 || m > 12 || d < 1 || d > 31 || y < 2000) return null;
  const date = new Date(y, m - 1, d);
  if (isNaN(date.getTime())) return null;
  return date;
}
EditableDate function · typescript · L42-L118 (77 LOC)
src/components/recordings/editable-date.tsx
export function EditableDate({ recordingId, recordedAt, createdAt }: EditableDateProps) {
  const [editing, setEditing] = useState(false);
  const [currentDate, setCurrentDate] = useState(recordedAt || createdAt);
  const [inputValue, setInputValue] = useState("");
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (editing && inputRef.current) {
      inputRef.current.select();
    }
  }, [editing]);

  function startEditing() {
    setInputValue(toInputValue(currentDate));
    setEditing(true);
  }

  async function handleSubmit() {
    const parsed = parseInput(inputValue);
    if (!parsed) {
      toast.error("Invalid date — use MM/DD/YYYY");
      return;
    }

    setEditing(false);
    const newDate = parsed.toISOString();
    if (newDate === currentDate) return;

    const supabase = createClient();
    const { error } = await supabase
      .from("recordings")
      .update({ recorded_at: newDate })
      .eq("id", recordingId);

    if (error) {
 
startEditing function · typescript · L54-L57 (4 LOC)
src/components/recordings/editable-date.tsx
  function startEditing() {
    setInputValue(toInputValue(currentDate));
    setEditing(true);
  }
handleSubmit function · typescript · L59-L82 (24 LOC)
src/components/recordings/editable-date.tsx
  async function handleSubmit() {
    const parsed = parseInput(inputValue);
    if (!parsed) {
      toast.error("Invalid date — use MM/DD/YYYY");
      return;
    }

    setEditing(false);
    const newDate = parsed.toISOString();
    if (newDate === currentDate) return;

    const supabase = createClient();
    const { error } = await supabase
      .from("recordings")
      .update({ recorded_at: newDate })
      .eq("id", recordingId);

    if (error) {
      toast.error("Failed to update date");
    } else {
      setCurrentDate(newDate);
      toast.success("Date updated");
    }
  }
handleKeyDown function · typescript · L84-L92 (9 LOC)
src/components/recordings/editable-date.tsx
  function handleKeyDown(e: React.KeyboardEvent) {
    if (e.key === "Enter") {
      e.preventDefault();
      handleSubmit();
    }
    if (e.key === "Escape") {
      setEditing(false);
    }
  }
Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
LibraryClient function · typescript · L34-L212 (179 LOC)
src/components/recordings/library-client.tsx
export function LibraryClient({ recordings, allTags }: LibraryClientProps) {
  const [search, setSearch] = useState("");
  const [selectedTagIds, setSelectedTagIds] = useState<Set<string>>(new Set());

  const toggleTag = (tagId: string) => {
    setSelectedTagIds((prev) => {
      const next = new Set(prev);
      if (next.has(tagId)) {
        next.delete(tagId);
      } else {
        next.add(tagId);
      }
      return next;
    });
  };

  const clearFilters = () => {
    setSearch("");
    setSelectedTagIds(new Set());
  };

  // Derive which tags are actually used by recordings
  const usedTagIds = useMemo(() => {
    const ids = new Set<string>();
    for (const rec of recordings) {
      for (const tag of rec.tags) {
        ids.add(tag.id);
      }
    }
    return ids;
  }, [recordings]);

  const visibleTags = useMemo(
    () => allTags.filter((t) => usedTagIds.has(t.id)),
    [allTags, usedTagIds]
  );

  const filtered = useMemo(() => {
    const q = search.toLowerCase(
formatDuration function · typescript · L37-L41 (5 LOC)
src/components/recordings/recording-card.tsx
function formatDuration(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = Math.floor(seconds % 60);
  return `${m}:${s.toString().padStart(2, "0")}`;
}
formatDate function · typescript · L43-L49 (7 LOC)
src/components/recordings/recording-card.tsx
function formatDate(dateString: string): string {
  return new Date(dateString).toLocaleDateString("en-US", {
    month: "short",
    day: "numeric",
    year: "numeric",
  });
}
RecordingCard function · typescript · L51-L184 (134 LOC)
src/components/recordings/recording-card.tsx
export function RecordingCard({
  id,
  title,
  duration,
  createdAt,
  recordedAt,
  fileName,
  description,
  hasAnalysis,
  tags,
  keySignature,
  tempo,
}: RecordingCardProps) {
  const router = useRouter();
  const [deleting, setDeleting] = useState(false);

  async function handleDelete() {
    setDeleting(true);
    const supabase = createClient();

    const { error: storageError } = await supabase.storage
      .from("recordings")
      .remove([fileName]);

    if (storageError) {
      toast.error(`Failed to delete file: ${storageError.message}`);
      setDeleting(false);
      return;
    }

    const { error: dbError } = await supabase
      .from("recordings")
      .delete()
      .eq("id", id);

    if (dbError) {
      toast.error(`Failed to delete recording: ${dbError.message}`);
      setDeleting(false);
      return;
    }

    toast.success("Recording deleted");
    router.refresh();
  }

  return (
    <Link href={`/recording/${id}`} className="block">
    <C
handleDelete function · typescript · L67-L94 (28 LOC)
src/components/recordings/recording-card.tsx
  async function handleDelete() {
    setDeleting(true);
    const supabase = createClient();

    const { error: storageError } = await supabase.storage
      .from("recordings")
      .remove([fileName]);

    if (storageError) {
      toast.error(`Failed to delete file: ${storageError.message}`);
      setDeleting(false);
      return;
    }

    const { error: dbError } = await supabase
      .from("recordings")
      .delete()
      .eq("id", id);

    if (dbError) {
      toast.error(`Failed to delete recording: ${dbError.message}`);
      setDeleting(false);
      return;
    }

    toast.success("Recording deleted");
    router.refresh();
  }
RecordingDetail function · typescript · L62-L308 (247 LOC)
src/components/recordings/recording-detail.tsx
export function RecordingDetail({
  recording,
  analysis: initialAnalysis,
  initialMessages,
}: RecordingDetailProps) {
  const router = useRouter();
  const [analysis, setAnalysis] = useState(initialAnalysis);
  const [currentTime, setCurrentTime] = useState(0);
  const [deleting, setDeleting] = useState(false);
  const [markers, setMarkers] = useState<Marker[]>([]);
  const [showVisualizer, setShowVisualizer] = useState(false);
  const [description, setDescription] = useState(recording.description ?? "");
  const [shareToken, setShareToken] = useState(recording.share_token);
  const [shareDialogOpen, setShareDialogOpen] = useState(false);
  const [sharing, setSharing] = useState(false);
  const [copied, setCopied] = useState(false);
  const playerRef = useRef<WaveformPlayerHandle>(null);

  const handleSeek = useCallback((time: number) => {
    playerRef.current?.seekTo(time);
  }, []);

  async function handleDelete() {
    setDeleting(true);
    const supabase = createClient();

handleDelete function · typescript · L84-L103 (20 LOC)
src/components/recordings/recording-detail.tsx
  async function handleDelete() {
    setDeleting(true);
    const supabase = createClient();

    await supabase.storage.from("recordings").remove([recording.file_name]);

    const { error } = await supabase
      .from("recordings")
      .delete()
      .eq("id", recording.id);

    if (error) {
      toast.error(`Failed to delete: ${error.message}`);
      setDeleting(false);
      return;
    }

    toast.success("Recording deleted");
    router.push("/library");
  }
saveDescription function · typescript · L105-L113 (9 LOC)
src/components/recordings/recording-detail.tsx
  async function saveDescription() {
    const trimmed = description.trim();
    if (trimmed === (recording.description ?? "")) return;
    const supabase = createClient();
    await supabase
      .from("recordings")
      .update({ description: trimmed || null })
      .eq("id", recording.id);
  }
Repobility — the code-quality scanner for AI-generated software · https://repobility.com
handleShare function · typescript · L115-L135 (21 LOC)
src/components/recordings/recording-detail.tsx
  async function handleShare() {
    if (shareToken) {
      setShareDialogOpen(true);
      return;
    }
    setSharing(true);
    const token = crypto.randomUUID();
    const supabase = createClient();
    const { error } = await supabase
      .from("recordings")
      .update({ share_token: token })
      .eq("id", recording.id);
    if (error) {
      toast.error(`Failed to create share link: ${error.message}`);
      setSharing(false);
      return;
    }
    setShareToken(token);
    setSharing(false);
    setShareDialogOpen(true);
  }
getShareUrl function · typescript · L137-L140 (4 LOC)
src/components/recordings/recording-detail.tsx
  function getShareUrl() {
    if (typeof window === "undefined") return "";
    return `${window.location.origin}/share/${shareToken}`;
  }
copyShareUrl function · typescript · L142-L151 (10 LOC)
src/components/recordings/recording-detail.tsx
  async function copyShareUrl() {
    try {
      await navigator.clipboard.writeText(getShareUrl());
      setCopied(true);
      toast.success("Link copied to clipboard");
      setTimeout(() => setCopied(false), 2000);
    } catch {
      toast.error("Failed to copy link");
    }
  }
TagBadge function · typescript · L25-L38 (14 LOC)
src/components/tags/tag-badge.tsx
export function TagBadge({ name, color, onRemove }: TagBadgeProps) {
  const colorClass = color && TAG_COLORS[color] ? TAG_COLORS[color] : DEFAULT_COLOR;

  return (
    <Badge variant="secondary" className={`gap-1 ${colorClass}`}>
      {name}
      {onRemove && (
        <button onClick={onRemove} className="ml-0.5 hover:opacity-70">
          <X className="h-3 w-3" />
        </button>
      )}
    </Badge>
  );
}
TagPicker function · typescript · L17-L136 (120 LOC)
src/components/tags/tag-picker.tsx
export function TagPicker({ recordingId, initialTags = [] }: TagPickerProps) {
  const [open, setOpen] = useState(false);
  const [tags, setTags] = useState(initialTags);
  const [allTags, setAllTags] = useState<{ id: string; name: string; color: string }[]>([]);
  const [search, setSearch] = useState("");

  useEffect(() => {
    loadAllTags();
  }, []);

  async function loadAllTags() {
    const supabase = createClient();
    const { data } = await supabase.from("tags").select("*").order("name");
    if (data) setAllTags(data);
  }

  async function addTag(tagId: string) {
    const supabase = createClient();
    const { error } = await supabase
      .from("recording_tags")
      .insert({ recording_id: recordingId, tag_id: tagId });

    if (error) {
      toast.error("Failed to add tag");
      return;
    }

    const tag = allTags.find((t) => t.id === tagId);
    if (tag) setTags((prev) => [...prev, tag]);
    setOpen(false);
  }

  async function removeTag(tagId: string) {
   
loadAllTags function · typescript · L27-L31 (5 LOC)
src/components/tags/tag-picker.tsx
  async function loadAllTags() {
    const supabase = createClient();
    const { data } = await supabase.from("tags").select("*").order("name");
    if (data) setAllTags(data);
  }
addTag function · typescript · L33-L47 (15 LOC)
src/components/tags/tag-picker.tsx
  async function addTag(tagId: string) {
    const supabase = createClient();
    const { error } = await supabase
      .from("recording_tags")
      .insert({ recording_id: recordingId, tag_id: tagId });

    if (error) {
      toast.error("Failed to add tag");
      return;
    }

    const tag = allTags.find((t) => t.id === tagId);
    if (tag) setTags((prev) => [...prev, tag]);
    setOpen(false);
  }
removeTag function · typescript · L49-L58 (10 LOC)
src/components/tags/tag-picker.tsx
  async function removeTag(tagId: string) {
    const supabase = createClient();
    await supabase
      .from("recording_tags")
      .delete()
      .eq("recording_id", recordingId)
      .eq("tag_id", tagId);

    setTags((prev) => prev.filter((t) => t.id !== tagId));
  }
Hi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
createAndAddTag function · typescript · L60-L84 (25 LOC)
src/components/tags/tag-picker.tsx
  async function createAndAddTag() {
    if (!search.trim()) return;

    const supabase = createClient();
    const colors = ["red", "blue", "green", "purple", "orange", "pink", "cyan", "yellow"];
    const color = colors[Math.floor(Math.random() * colors.length)];

    const { data: { user } } = await supabase.auth.getUser();
    if (!user) return;

    const { data: newTag, error } = await supabase
      .from("tags")
      .insert({ name: search.trim(), color, user_id: user.id })
      .select()
      .single();

    if (error) {
      toast.error("Failed to create tag");
      return;
    }

    await addTag(newTag.id);
    setAllTags((prev) => [...prev, newTag]);
    setSearch("");
  }
AlertDialog function · typescript · L9-L13 (5 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialog({
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
  return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />
}
AlertDialogTrigger function · typescript · L15-L21 (7 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogTrigger({
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
  return (
    <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
  )
}
AlertDialogPortal function · typescript · L23-L29 (7 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogPortal({
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
  return (
    <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
  )
}
AlertDialogOverlay function · typescript · L31-L45 (15 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogOverlay({
  className,
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
  return (
    <AlertDialogPrimitive.Overlay
      data-slot="alert-dialog-overlay"
      className={cn(
        "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
        className
      )}
      {...props}
    />
  )
}
AlertDialogContent function · typescript · L47-L68 (22 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogContent({
  className,
  size = "default",
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Content> & {
  size?: "default" | "sm"
}) {
  return (
    <AlertDialogPortal>
      <AlertDialogOverlay />
      <AlertDialogPrimitive.Content
        data-slot="alert-dialog-content"
        data-size={size}
        className={cn(
          "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg",
          className
        )}
        {...props}
      />
    </AlertDialogPortal>
  )
}
AlertDialogHeader function · typescript · L70-L84 (15 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogHeader({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-dialog-header"
      className={cn(
        "grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",
        className
      )}
      {...props}
    />
  )
}
AlertDialogFooter function · typescript · L86-L100 (15 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogFooter({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-dialog-footer"
      className={cn(
        "flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",
        className
      )}
      {...props}
    />
  )
}
Repobility analyzer · published findings · https://repobility.com
AlertDialogTitle function · typescript · L102-L116 (15 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogTitle({
  className,
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
  return (
    <AlertDialogPrimitive.Title
      data-slot="alert-dialog-title"
      className={cn(
        "text-lg font-semibold sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
        className
      )}
      {...props}
    />
  )
}
AlertDialogDescription function · typescript · L118-L129 (12 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogDescription({
  className,
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
  return (
    <AlertDialogPrimitive.Description
      data-slot="alert-dialog-description"
      className={cn("text-muted-foreground text-sm", className)}
      {...props}
    />
  )
}
AlertDialogMedia function · typescript · L131-L145 (15 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogMedia({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-dialog-media"
      className={cn(
        "bg-muted mb-2 inline-flex size-16 items-center justify-center rounded-md sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-8",
        className
      )}
      {...props}
    />
  )
}
AlertDialogAction function · typescript · L147-L163 (17 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogAction({
  className,
  variant = "default",
  size = "default",
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Action> &
  Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
  return (
    <Button variant={variant} size={size} asChild>
      <AlertDialogPrimitive.Action
        data-slot="alert-dialog-action"
        className={cn(className)}
        {...props}
      />
    </Button>
  )
}
AlertDialogCancel function · typescript · L165-L181 (17 LOC)
src/components/ui/alert-dialog.tsx
function AlertDialogCancel({
  className,
  variant = "outline",
  size = "default",
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel> &
  Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
  return (
    <Button variant={variant} size={size} asChild>
      <AlertDialogPrimitive.Cancel
        data-slot="alert-dialog-cancel"
        className={cn(className)}
        {...props}
      />
    </Button>
  )
}
Avatar function · typescript · L8-L26 (19 LOC)
src/components/ui/avatar.tsx
function Avatar({
  className,
  size = "default",
  ...props
}: React.ComponentProps<typeof AvatarPrimitive.Root> & {
  size?: "default" | "sm" | "lg"
}) {
  return (
    <AvatarPrimitive.Root
      data-slot="avatar"
      data-size={size}
      className={cn(
        "group/avatar relative flex size-8 shrink-0 overflow-hidden rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
        className
      )}
      {...props}
    />
  )
}
AvatarImage function · typescript · L28-L39 (12 LOC)
src/components/ui/avatar.tsx
function AvatarImage({
  className,
  ...props
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
  return (
    <AvatarPrimitive.Image
      data-slot="avatar-image"
      className={cn("aspect-square size-full", className)}
      {...props}
    />
  )
}
AvatarFallback function · typescript · L41-L55 (15 LOC)
src/components/ui/avatar.tsx
function AvatarFallback({
  className,
  ...props
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
  return (
    <AvatarPrimitive.Fallback
      data-slot="avatar-fallback"
      className={cn(
        "bg-muted text-muted-foreground flex size-full items-center justify-center rounded-full text-sm group-data-[size=sm]/avatar:text-xs",
        className
      )}
      {...props}
    />
  )
}
Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
AvatarBadge function · typescript · L57-L71 (15 LOC)
src/components/ui/avatar.tsx
function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
  return (
    <span
      data-slot="avatar-badge"
      className={cn(
        "bg-primary text-primary-foreground ring-background absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full ring-2 select-none",
        "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
        "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
        "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
        className
      )}
      {...props}
    />
  )
}
AvatarGroup function · typescript · L73-L84 (12 LOC)
src/components/ui/avatar.tsx
function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="avatar-group"
      className={cn(
        "*:data-[slot=avatar]:ring-background group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2",
        className
      )}
      {...props}
    />
  )
}
AvatarGroupCount function · typescript · L86-L100 (15 LOC)
src/components/ui/avatar.tsx
function AvatarGroupCount({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="avatar-group-count"
      className={cn(
        "bg-muted text-muted-foreground ring-background relative flex size-8 shrink-0 items-center justify-center rounded-full text-sm ring-2 group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
        className
      )}
      {...props}
    />
  )
}
‹ prevpage 3 / 5next ›