HTML 77.2%
TypeScript 10.5%
Python 9.6%
JavaScript 2.5%
1'use client';2import { Check, Plus } from 'lucide-react';3import { cn } from '@/lib/cn';4import { COMPARE_MAX, type TrayItem, trayType, useCompareTray } from './compare-store';56/**7 * Small toggle that adds/removes an entity from the compare tray (localStorage-backed, mirrored into `/compare?ids=`).8 * `size="sm"` for table rows (still a ≥ 44 px hit area through padding on touch), default for entity headers.9 * Renders a neutral placeholder before hydration so server and client markup match.10 */11export function CompareButton({ e, size = 'md', className, label = 'Compare' }: { e: TrayItem | { slug: string; name: string; entity_type: string; organization?: { name: string } | null }; size?: 'sm' | 'md'; className?: string; label?: string }) {12 const tray = useCompareTray();13 const item: TrayItem = { slug: e.slug, name: e.name, entity_type: e.entity_type, organization: typeof e.organization === 'string' || e.organization === null || e.organization === undefined ? (e.organization as string | null | undefined) : e.organization.name };14 const on = tray.ready && tray.has(item.slug);15 const otherType = tray.ready && tray.type !== null && tray.type !== trayType(item.entity_type) && !on;16 const full = tray.ready && tray.full && !on;17 const title = on ? 'Remove from comparison' : otherType ? `Start a new ${item.entity_type} comparison (replaces the current tray)` : full ? `The tray holds at most ${COMPARE_MAX} items` : 'Add to comparison';18 return (19 <button20 type="button"21 onClick={() => {22 if (full) return;23 tray.toggle(item);24 }}25 aria-pressed={on}26 title={title}27 disabled={full}28 className={cn(29 'inline-flex shrink-0 items-center gap-1 border text-xs font-medium whitespace-nowrap transition-colors disabled:cursor-not-allowed disabled:opacity-40',30 size === 'sm' ? 'h-7 px-1.5' : 'h-9 px-2.5 text-sm',31 on ? 'border-accent bg-accent-soft text-accent' : 'border-rule text-ink-2 hover:border-rule-strong hover:text-ink',32 className,33 )}34 >35 {on ? <Check className={size === 'sm' ? 'size-3' : 'size-3.5'} aria-hidden /> : <Plus className={size === 'sm' ? 'size-3' : 'size-3.5'} aria-hidden />}36 <span>{on ? 'Comparing' : label}</span>37 </button>38 );39}40