← back to kdsplus__test002

Function bodies 63 total

All specs Real LLM only Function bodies
PUT function · typescript · L4-L32 (29 LOC)
src/app/api/prompts/[id]/route.ts
export async function PUT(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  if (!supabase) {
    return NextResponse.json({ error: 'Supabase가 설정되지 않았습니다.' }, { status: 503 });
  }

  const { id } = await params;
  const body = await request.json();

  const { data: prompt, error } = await supabase
    .from('prompt_templates')
    .update({
      name: body.name,
      description: body.description,
      prompt_text: body.prompt_text,
      updated_at: new Date().toISOString(),
    })
    .eq('id', id)
    .select()
    .single();

  if (error) {
    return NextResponse.json({ error: error.message }, { status: 500 });
  }

  return NextResponse.json({ prompt });
}
GET function · typescript · L4-L20 (17 LOC)
src/app/api/prompts/route.ts
export async function GET() {
  if (!supabase) {
    return NextResponse.json({ prompts: [] });
  }

  const { data: prompts, error } = await supabase
    .from('prompt_templates')
    .select('*')
    .order('is_default', { ascending: false })
    .order('created_at', { ascending: false });

  if (error) {
    return NextResponse.json({ error: error.message }, { status: 500 });
  }

  return NextResponse.json({ prompts });
}
POST function · typescript · L22-L45 (24 LOC)
src/app/api/prompts/route.ts
export async function POST(request: NextRequest) {
  if (!supabase) {
    return NextResponse.json({ error: 'Supabase가 설정되지 않았습니다.' }, { status: 503 });
  }

  const body = await request.json();

  const { data: prompt, error } = await supabase
    .from('prompt_templates')
    .insert({
      name: body.name,
      description: body.description || null,
      prompt_text: body.prompt_text,
      is_default: false,
    })
    .select()
    .single();

  if (error) {
    return NextResponse.json({ error: error.message }, { status: 500 });
  }

  return NextResponse.json({ prompt });
}
POST function · typescript · L6-L82 (77 LOC)
src/app/api/proposals/generate/route.ts
export async function POST(request: NextRequest) {
  try {
    if (!supabase) {
      return NextResponse.json(
        { error: 'Supabase가 설정되지 않았습니다. .env.local 파일을 확인해주세요.' },
        { status: 503 }
      );
    }

    const { url, session_id, prompt_id, custom_prompt } = await request.json();

    if (!url || !session_id) {
      return NextResponse.json({ error: 'URL과 세션 ID가 필요합니다.' }, { status: 400 });
    }

    // 1. URL 스크래핑
    let scrapedContent: string;
    try {
      scrapedContent = await scrapeUrl(url);
    } catch {
      return NextResponse.json({ error: '해당 URL의 내용을 가져올 수 없습니다.' }, { status: 400 });
    }

    // 2. 프롬프트 가져오기
    let promptText = custom_prompt;
    if (!promptText && prompt_id) {
      const { data: prompt } = await supabase
        .from('prompt_templates')
        .select('prompt_text')
        .eq('id', prompt_id)
        .single();
      promptText = prompt?.prompt_text;
    }
    if (!promptText) {
      const { data: defaultPrompt } = await su
getDefaultPrompt function · typescript · L84-L96 (13 LOC)
src/app/api/proposals/generate/route.ts
function getDefaultPrompt(): string {
  return `당신은 전문 비즈니스 컨설턴트입니다. 아래 웹사이트의 내용을 분석하여 전문적인 제안서를 작성해주세요.

제안서는 다음 구조를 따라주세요:
1. 프로젝트 개요
2. 현황 분석
3. 제안 내용
4. 기대 효과
5. 실행 계획
6. 예산 및 일정

마크다운 형식으로 작성하고, 전문적이고 설득력 있는 톤을 유지해주세요.`;
}
GET function · typescript · L4-L25 (22 LOC)
src/app/api/proposals/[id]/route.ts
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  if (!supabase) {
    return NextResponse.json({ error: 'Supabase가 설정되지 않았습니다.' }, { status: 503 });
  }

  const { id } = await params;

  const { data: proposal, error } = await supabase
    .from('proposals')
    .select('*')
    .eq('id', id)
    .single();

  if (error || !proposal) {
    return NextResponse.json({ error: '제안서를 찾을 수 없습니다.' }, { status: 404 });
  }

  return NextResponse.json({ proposal });
}
DELETE function · typescript · L27-L47 (21 LOC)
src/app/api/proposals/[id]/route.ts
export async function DELETE(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  if (!supabase) {
    return NextResponse.json({ error: 'Supabase가 설정되지 않았습니다.' }, { status: 503 });
  }

  const { id } = await params;

  const { error } = await supabase
    .from('proposals')
    .delete()
    .eq('id', id);

  if (error) {
    return NextResponse.json({ error: error.message }, { status: 500 });
  }

  return NextResponse.json({ success: true });
}
Same scanner, your repo: https://repobility.com — Repobility
GET function · typescript · L4-L27 (24 LOC)
src/app/api/proposals/route.ts
export async function GET(request: NextRequest) {
  if (!supabase) {
    return NextResponse.json({ proposals: [] });
  }

  const { searchParams } = new URL(request.url);
  const sessionId = searchParams.get('session_id');

  if (!sessionId) {
    return NextResponse.json({ error: '세션 ID가 필요합니다.' }, { status: 400 });
  }

  const { data: proposals, error } = await supabase
    .from('proposals')
    .select('id, session_id, source_url, title, status, created_at')
    .eq('session_id', sessionId)
    .order('created_at', { ascending: false });

  if (error) {
    return NextResponse.json({ error: error.message }, { status: 500 });
  }

  return NextResponse.json({ proposals });
}
RootLayout function · typescript · L24-L44 (21 LOC)
src/app/layout.tsx
export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ko" className="dark">
      <body
        className={`${inter.variable} ${geistMono.variable} antialiased`}
      >
        <div className="flex h-dvh">
          <Sidebar />
          <main className="flex-1 overflow-y-auto p-6 lg:p-8">
            {children}
          </main>
        </div>
        <Toaster theme="dark" />
      </body>
    </html>
  );
}
HomePage function · typescript · L9-L32 (24 LOC)
src/app/page.tsx
export default function HomePage() {
  const [generatedProposal, setGeneratedProposal] = useState<Proposal | null>(null);

  return (
    <div className="mx-auto max-w-4xl space-y-6">
      {/* 인사 헤더 */}
      <div className="mb-2">
        <h1 className="text-2xl font-bold text-white">AI 제안서 생성기</h1>
        <p className="text-white/50 mt-1">URL을 입력하면 AI가 전문적인 제안서를 만들어 드립니다</p>
      </div>

      {/* URL 입력 */}
      <UrlInputCard onGenerated={setGeneratedProposal} />

      {/* 생성된 제안서 */}
      {generatedProposal && (
        <GeneratedProposalCard proposal={generatedProposal} />
      )}

      {/* 최근 제안서 목록 */}
      <RecentProposalsList />
    </div>
  );
}
ProposalDetailPage function · typescript · L12-L141 (130 LOC)
src/app/proposals/[id]/page.tsx
export default function ProposalDetailPage() {
  const params = useParams();
  const router = useRouter();
  const [proposal, setProposal] = useState<Proposal | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchProposal = async () => {
      try {
        const res = await fetch(`/api/proposals/${params.id}`);
        const data = await res.json();
        setProposal(data.proposal);
      } catch {
        console.error('Failed to fetch');
      } finally {
        setLoading(false);
      }
    };
    fetchProposal();
  }, [params.id]);

  const handleDownload = () => {
    if (!proposal) return;
    const blob = new Blob([proposal.content], { type: 'text/markdown' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${proposal.title || 'proposal'}.md`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleDelete = async () => {
    if (!proposal) return;
ProposalsPage function · typescript · L11-L113 (103 LOC)
src/app/proposals/page.tsx
export default function ProposalsPage() {
  const [proposals, setProposals] = useState<Proposal[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchProposals = async () => {
      try {
        const sessionId = getSessionId();
        if (!sessionId) return;
        const res = await fetch(`/api/proposals?session_id=${sessionId}`);
        const data = await res.json();
        setProposals(data.proposals || []);
      } catch {
        console.error('Failed to fetch');
      } finally {
        setLoading(false);
      }
    };
    fetchProposals();
  }, []);

  const handleDelete = async (id: string) => {
    await fetch(`/api/proposals/${id}`, { method: 'DELETE' });
    setProposals(prev => prev.filter(p => p.id !== id));
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center py-20">
        <Loader2 className="h-6 w-6 animate-spin text-white/40" />
      </div>
    );
  }

  return (
    <div className="mx
SettingsPage function · typescript · L4-L22 (19 LOC)
src/app/settings/page.tsx
export default function SettingsPage() {
  return (
    <div className="mx-auto max-w-3xl space-y-6">
      <div className="flex items-center gap-3">
        <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-white/10">
          <Settings className="h-5 w-5 text-white" />
        </div>
        <div>
          <h1 className="text-2xl font-bold text-white">프롬프트 설정</h1>
          <p className="text-white/50 mt-1">AI 제안서 생성에 사용되는 프롬프트를 관리합니다</p>
        </div>
      </div>

      <div className="glass rounded-2xl p-6">
        <PromptEditor />
      </div>
    </div>
  );
}
GeneratedProposalCard function · typescript · L15-L68 (54 LOC)
src/components/features/GeneratedProposalCard.tsx
export function GeneratedProposalCard({ proposal }: GeneratedProposalCardProps) {
  const handleDownload = () => {
    const blob = new Blob([proposal.content], { type: 'text/markdown' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${proposal.title || 'proposal'}.md`;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div className="glass rounded-2xl p-6">
      <div className="mb-4 flex items-center justify-between">
        <div className="flex items-center gap-3">
          <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-white/10">
            <FileText className="h-5 w-5 text-white" />
          </div>
          <div>
            <h2 className="text-lg font-semibold text-white">
              {proposal.title || '생성된 제안서'}
            </h2>
            <p className="text-sm text-white/50">{proposal.source_url}</p>
          </div>
        </div>
        <div classN
PromptEditor function · typescript · L12-L154 (143 LOC)
src/components/features/PromptEditor.tsx
export function PromptEditor() {
  const [prompts, setPrompts] = useState<PromptTemplate[]>([]);
  const [selected, setSelected] = useState<PromptTemplate | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);

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

  const fetchPrompts = async () => {
    try {
      const res = await fetch('/api/prompts');
      const data = await res.json();
      const promptList = data.prompts || [];
      setPrompts(promptList);
      if (promptList.length > 0) {
        setSelected(promptList[0]);
      }
    } catch {
      toast.error('프롬프트를 불러올 수 없습니다.');
    } finally {
      setLoading(false);
    }
  };

  const handleSave = async () => {
    if (!selected) return;
    setSaving(true);
    try {
      const res = await fetch(`/api/prompts/${selected.id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: selected
If a scraper extracted this row, it came from Repobility (https://repobility.com)
RecentProposalsList function · typescript · L10-L105 (96 LOC)
src/components/features/RecentProposalsList.tsx
export function RecentProposalsList() {
  const [proposals, setProposals] = useState<Proposal[]>([]);
  const [loading, setLoading] = useState(true);

  const fetchProposals = async () => {
    try {
      const sessionId = getSessionId();
      if (!sessionId) return;

      const res = await fetch(`/api/proposals?session_id=${sessionId}`);
      const data = await res.json();
      setProposals(data.proposals || []);
    } catch {
      console.error('Failed to fetch proposals');
    } finally {
      setLoading(false);
    }
  };

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

  const handleDelete = async (id: string) => {
    try {
      await fetch(`/api/proposals/${id}`, { method: 'DELETE' });
      setProposals(prev => prev.filter(p => p.id !== id));
    } catch {
      console.error('Failed to delete proposal');
    }
  };

  if (loading) {
    return (
      <div className="glass rounded-2xl p-6">
        <div className="flex items-center gap-3 mb-4">
          <Clock cl
UrlInputCard function · typescript · L14-L101 (88 LOC)
src/components/features/UrlInputCard.tsx
export function UrlInputCard({ onGenerated }: UrlInputCardProps) {
  const [url, setUrl] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!url.trim()) return;

    setLoading(true);
    setError('');

    try {
      const response = await fetch('/api/proposals/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          url: url.trim(),
          session_id: getSessionId(),
        }),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || '제안서 생성에 실패했습니다.');
      }

      onGenerated(data.proposal);
      setUrl('');
    } catch (err) {
      setError(err instanceof Error ? err.message : '오류가 발생했습니다.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="glass rounded-2xl p
MobileNav function · typescript · L14-L38 (25 LOC)
src/components/layout/MobileNav.tsx
export function MobileNav() {
  const pathname = usePathname();

  return (
    <nav className="glass-strong fixed bottom-0 left-0 right-0 z-50 flex border-t border-white/5 lg:hidden">
      {navItems.map((item) => {
        const isActive = pathname === item.href ||
          (item.href !== '/' && pathname.startsWith(item.href));
        return (
          <Link
            key={item.href}
            href={item.href}
            className={cn(
              'flex flex-1 flex-col items-center gap-1 py-3 text-xs transition-colors',
              isActive ? 'text-white' : 'text-white/40'
            )}
          >
            <item.icon className="h-5 w-5" />
            {item.label}
          </Link>
        );
      })}
    </nav>
  );
}
Sidebar function · typescript · L14-L65 (52 LOC)
src/components/layout/Sidebar.tsx
export function Sidebar() {
  const pathname = usePathname();

  return (
    <aside className="glass-strong hidden w-64 flex-col border-r border-white/5 lg:flex">
      {/* 로고 */}
      <div className="flex items-center gap-3 px-6 py-5">
        <div className="flex h-9 w-9 items-center justify-center rounded-lg bg-white/10">
          <Sparkles className="h-5 w-5 text-white" />
        </div>
        <div>
          <h1 className="text-sm font-semibold text-white">AI 제안서</h1>
          <p className="text-xs text-white/50">생성기</p>
        </div>
      </div>

      {/* 구분선 */}
      <div className="mx-4 h-px bg-white/5" />

      {/* 네비게이션 */}
      <nav className="flex-1 space-y-1 px-3 py-4">
        {navItems.map((item) => {
          const isActive = pathname === item.href ||
            (item.href !== '/' && pathname.startsWith(item.href));
          return (
            <Link
              key={item.href}
              href={item.href}
              className={cn(
               
Badge function · typescript · L30-L50 (21 LOC)
src/components/ui/badge.tsx
function Badge({
  className,
  variant = "default",
  render,
  ...props
}: useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>) {
  return useRender({
    defaultTagName: "span",
    props: mergeProps<"span">(
      {
        className: cn(badgeVariants({ variant }), className),
      },
      props
    ),
    render,
    state: {
      slot: "badge",
      variant,
    },
  })
}
Button function · typescript · L45-L58 (14 LOC)
src/components/ui/button.tsx
function Button({
  className,
  variant = "default",
  size = "default",
  ...props
}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {
  return (
    <ButtonPrimitive
      data-slot="button"
      className={cn(buttonVariants({ variant, size, className }))}
      {...props}
    />
  )
}
Card function · typescript · L5-L21 (17 LOC)
src/components/ui/card.tsx
function Card({
  className,
  size = "default",
  ...props
}: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
  return (
    <div
      data-slot="card"
      data-size={size}
      className={cn(
        "group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
        className
      )}
      {...props}
    />
  )
}
CardHeader function · typescript · L23-L34 (12 LOC)
src/components/ui/card.tsx
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-header"
      className={cn(
        "group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3",
        className
      )}
      {...props}
    />
  )
}
Repobility · code-quality intelligence · https://repobility.com
CardTitle function · typescript · L36-L47 (12 LOC)
src/components/ui/card.tsx
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-title"
      className={cn(
        "text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
        className
      )}
      {...props}
    />
  )
}
CardDescription function · typescript · L49-L57 (9 LOC)
src/components/ui/card.tsx
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-description"
      className={cn("text-sm text-muted-foreground", className)}
      {...props}
    />
  )
}
CardAction function · typescript · L59-L70 (12 LOC)
src/components/ui/card.tsx
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-action"
      className={cn(
        "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
        className
      )}
      {...props}
    />
  )
}
CardContent function · typescript · L72-L80 (9 LOC)
src/components/ui/card.tsx
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-content"
      className={cn("px-4 group-data-[size=sm]/card:px-3", className)}
      {...props}
    />
  )
}
CardFooter function · typescript · L82-L93 (12 LOC)
src/components/ui/card.tsx
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-footer"
      className={cn(
        "flex items-center rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/card:p-3",
        className
      )}
      {...props}
    />
  )
}
Dialog function · typescript · L10-L12 (3 LOC)
src/components/ui/dialog.tsx
function Dialog({ ...props }: DialogPrimitive.Root.Props) {
  return <DialogPrimitive.Root data-slot="dialog" {...props} />
}
DialogTrigger function · typescript · L14-L16 (3 LOC)
src/components/ui/dialog.tsx
function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
  return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
}
DialogPortal function · typescript · L18-L20 (3 LOC)
src/components/ui/dialog.tsx
function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {
  return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
}
Repobility · code-quality intelligence platform · https://repobility.com
DialogClose function · typescript · L22-L24 (3 LOC)
src/components/ui/dialog.tsx
function DialogClose({ ...props }: DialogPrimitive.Close.Props) {
  return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
}
DialogOverlay function · typescript · L26-L40 (15 LOC)
src/components/ui/dialog.tsx
function DialogOverlay({
  className,
  ...props
}: DialogPrimitive.Backdrop.Props) {
  return (
    <DialogPrimitive.Backdrop
      data-slot="dialog-overlay"
      className={cn(
        "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
        className
      )}
      {...props}
    />
  )
}
DialogContent function · typescript · L42-L81 (40 LOC)
src/components/ui/dialog.tsx
function DialogContent({
  className,
  children,
  showCloseButton = true,
  ...props
}: DialogPrimitive.Popup.Props & {
  showCloseButton?: boolean
}) {
  return (
    <DialogPortal>
      <DialogOverlay />
      <DialogPrimitive.Popup
        data-slot="dialog-content"
        className={cn(
          "fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-background p-4 text-sm ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
          className
        )}
        {...props}
      >
        {children}
        {showCloseButton && (
          <DialogPrimitive.Close
            data-slot="dialog-close"
            render={
              <Button
                variant="ghost"
                className="absolute top-2 right-2"
                size="icon-sm"
              />
  
DialogHeader function · typescript · L83-L91 (9 LOC)
src/components/ui/dialog.tsx
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="dialog-header"
      className={cn("flex flex-col gap-2", className)}
      {...props}
    />
  )
}
DialogFooter function · typescript · L93-L118 (26 LOC)
src/components/ui/dialog.tsx
function DialogFooter({
  className,
  showCloseButton = false,
  children,
  ...props
}: React.ComponentProps<"div"> & {
  showCloseButton?: boolean
}) {
  return (
    <div
      data-slot="dialog-footer"
      className={cn(
        "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end",
        className
      )}
      {...props}
    >
      {children}
      {showCloseButton && (
        <DialogPrimitive.Close render={<Button variant="outline" />}>
          Close
        </DialogPrimitive.Close>
      )}
    </div>
  )
}
DialogTitle function · typescript · L120-L128 (9 LOC)
src/components/ui/dialog.tsx
function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
  return (
    <DialogPrimitive.Title
      data-slot="dialog-title"
      className={cn("text-base leading-none font-medium", className)}
      {...props}
    />
  )
}
DialogDescription function · typescript · L130-L144 (15 LOC)
src/components/ui/dialog.tsx
function DialogDescription({
  className,
  ...props
}: DialogPrimitive.Description.Props) {
  return (
    <DialogPrimitive.Description
      data-slot="dialog-description"
      className={cn(
        "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
        className
      )}
      {...props}
    />
  )
}
Input function · typescript · L6-L18 (13 LOC)
src/components/ui/input.tsx
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
  return (
    <InputPrimitive
      type={type}
      data-slot="input"
      className={cn(
        "h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
        className
      )}
      {...props}
    />
  )
}
Same scanner, your repo: https://repobility.com — Repobility
Label function · typescript · L7-L18 (12 LOC)
src/components/ui/label.tsx
function Label({ className, ...props }: React.ComponentProps<"label">) {
  return (
    <label
      data-slot="label"
      className={cn(
        "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
        className
      )}
      {...props}
    />
  )
}
ScrollArea function · typescript · L8-L29 (22 LOC)
src/components/ui/scroll-area.tsx
function ScrollArea({
  className,
  children,
  ...props
}: ScrollAreaPrimitive.Root.Props) {
  return (
    <ScrollAreaPrimitive.Root
      data-slot="scroll-area"
      className={cn("relative", className)}
      {...props}
    >
      <ScrollAreaPrimitive.Viewport
        data-slot="scroll-area-viewport"
        className="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1"
      >
        {children}
      </ScrollAreaPrimitive.Viewport>
      <ScrollBar />
      <ScrollAreaPrimitive.Corner />
    </ScrollAreaPrimitive.Root>
  )
}
ScrollBar function · typescript · L31-L53 (23 LOC)
src/components/ui/scroll-area.tsx
function ScrollBar({
  className,
  orientation = "vertical",
  ...props
}: ScrollAreaPrimitive.Scrollbar.Props) {
  return (
    <ScrollAreaPrimitive.Scrollbar
      data-slot="scroll-area-scrollbar"
      data-orientation={orientation}
      orientation={orientation}
      className={cn(
        "flex touch-none p-px transition-colors select-none data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent",
        className
      )}
      {...props}
    >
      <ScrollAreaPrimitive.Thumb
        data-slot="scroll-area-thumb"
        className="relative flex-1 rounded-full bg-border"
      />
    </ScrollAreaPrimitive.Scrollbar>
  )
}
Separator function · typescript · L7-L23 (17 LOC)
src/components/ui/separator.tsx
function Separator({
  className,
  orientation = "horizontal",
  ...props
}: SeparatorPrimitive.Props) {
  return (
    <SeparatorPrimitive
      data-slot="separator"
      orientation={orientation}
      className={cn(
        "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
        className
      )}
      {...props}
    />
  )
}
Sheet function · typescript · L10-L12 (3 LOC)
src/components/ui/sheet.tsx
function Sheet({ ...props }: SheetPrimitive.Root.Props) {
  return <SheetPrimitive.Root data-slot="sheet" {...props} />
}
SheetTrigger function · typescript · L14-L16 (3 LOC)
src/components/ui/sheet.tsx
function SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {
  return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
}
SheetClose function · typescript · L18-L20 (3 LOC)
src/components/ui/sheet.tsx
function SheetClose({ ...props }: SheetPrimitive.Close.Props) {
  return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
}
SheetPortal function · typescript · L22-L24 (3 LOC)
src/components/ui/sheet.tsx
function SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {
  return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
}
If a scraper extracted this row, it came from Repobility (https://repobility.com)
SheetOverlay function · typescript · L26-L37 (12 LOC)
src/components/ui/sheet.tsx
function SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {
  return (
    <SheetPrimitive.Backdrop
      data-slot="sheet-overlay"
      className={cn(
        "fixed inset-0 z-50 bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs",
        className
      )}
      {...props}
    />
  )
}
SheetContent function · typescript · L39-L81 (43 LOC)
src/components/ui/sheet.tsx
function SheetContent({
  className,
  children,
  side = "right",
  showCloseButton = true,
  ...props
}: SheetPrimitive.Popup.Props & {
  side?: "top" | "right" | "bottom" | "left"
  showCloseButton?: boolean
}) {
  return (
    <SheetPortal>
      <SheetOverlay />
      <SheetPrimitive.Popup
        data-slot="sheet-content"
        data-side={side}
        className={cn(
          "fixed z-50 flex flex-col gap-4 bg-background bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starti
SheetHeader function · typescript · L83-L91 (9 LOC)
src/components/ui/sheet.tsx
function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="sheet-header"
      className={cn("flex flex-col gap-0.5 p-4", className)}
      {...props}
    />
  )
}
page 1 / 2next ›