>({});
+
+ return (
+
+ {ITEMS.map((label, index) => {
+ const uniqueId = `checklist-${index}`;
+
+ return (
+
+ setChecked((prev) => ({ ...prev, [label]: e.target.checked }))}
+ />
+
+
+
+ );
+ })}
+
+ );
+}
diff --git a/src/components/search/ElementList/ElementList.tsx b/src/components/search/ElementList/ElementList.tsx
new file mode 100644
index 0000000..dd6a478
--- /dev/null
+++ b/src/components/search/ElementList/ElementList.tsx
@@ -0,0 +1,64 @@
+"use client";
+
+import PlusIcon from "@/components/icons/icon-plus.svg";
+import { LoadingIndicator } from "./LoadingIndicator";
+import { ElementRow } from "./ElementRow";
+
+export interface Element {
+ id: string;
+ name: string;
+ description: string;
+}
+
+interface ElementListProps {
+ elements: Element[];
+ isLoading?: boolean;
+ onAdd: () => void;
+ onDelete: (id: string) => void;
+ onChange: (id: string, field: "name" | "description", value: string) => void;
+}
+
+export function ElementList({
+ elements,
+ isLoading = false,
+ onAdd,
+ onDelete,
+ onChange,
+}: ElementListProps) {
+ return (
+
+
+
+ {isLoading ? (
+
+ ) : (
+ <>
+ {elements.map((el, index) => (
+
onDelete(el.id)}
+ onChangeName={(value) => onChange(el.id, "name", value)}
+ onChangeDescription={(value) => onChange(el.id, "description", value)}
+ />
+ ))}
+
+
+ >
+ )}
+
+ );
+}
diff --git a/src/components/search/ElementList/ElementRow.tsx b/src/components/search/ElementList/ElementRow.tsx
new file mode 100644
index 0000000..df1b33f
--- /dev/null
+++ b/src/components/search/ElementList/ElementRow.tsx
@@ -0,0 +1,46 @@
+import TrashIcon from "@/components/icons/icon-trashcan.svg";
+import { ElementTitle } from "./ElementTitle";
+
+interface ElementRowProps {
+ index: number;
+ name: string;
+ description: string;
+ onDelete: () => void;
+ onChangeName: (value: string) => void;
+ onChangeDescription: (value: string) => void;
+}
+
+export function ElementRow({
+ index,
+ name,
+ description,
+ onDelete,
+ onChangeName,
+ onChangeDescription,
+}: ElementRowProps) {
+ return (
+
+
+
+
+ );
+}
diff --git a/src/components/search/ElementList/ElementTitle.tsx b/src/components/search/ElementList/ElementTitle.tsx
new file mode 100644
index 0000000..e845874
--- /dev/null
+++ b/src/components/search/ElementList/ElementTitle.tsx
@@ -0,0 +1,23 @@
+interface ElementTitleProps {
+ index: number;
+ value: string;
+ onChange: (value: string) => void;
+}
+
+export function ElementTitle({ index, value, onChange }: ElementTitleProps) {
+ return (
+
+
+ {String.fromCharCode(65 + index)}
+
+
+ onChange(e.target.value)}
+ placeholder="구성요소 명칭"
+ className="w-full bg-transparent text-title-secondary text-label-emphasis-17 placeholder:text-caption-label placeholder:text-label-emphasis-17 focus:outline-none"
+ />
+
+ );
+}
diff --git a/src/components/search/ElementList/LoadingIndicator.tsx b/src/components/search/ElementList/LoadingIndicator.tsx
new file mode 100644
index 0000000..ad4cf15
--- /dev/null
+++ b/src/components/search/ElementList/LoadingIndicator.tsx
@@ -0,0 +1,12 @@
+type LoadingIndicatorProps = {
+ label: string;
+};
+
+export function LoadingIndicator({ label }: LoadingIndicatorProps) {
+ return (
+
+ );
+}
diff --git a/src/components/search/Footer.tsx b/src/components/search/Footer.tsx
new file mode 100644
index 0000000..7ecfb08
--- /dev/null
+++ b/src/components/search/Footer.tsx
@@ -0,0 +1,18 @@
+import { Button } from "@/components/ui/Button";
+import { ResultCountButton } from "./ResultCountButton";
+
+export function Footer() {
+ return (
+
+
+ 탐색 결과 개수
+
+
+
+
+ {/* api 연동 이후 disabled 해제 관련 조건 추가 예정 */}
+
+ );
+}
diff --git a/src/components/search/PatentImportModal.tsx b/src/components/search/PatentImportModal.tsx
new file mode 100644
index 0000000..8042940
--- /dev/null
+++ b/src/components/search/PatentImportModal.tsx
@@ -0,0 +1,49 @@
+"use client";
+
+import { useState } from "react";
+import CancelIcon from "@/components/icons/icon-cancel.svg";
+import { TextField } from "@/components/ui/TextField";
+import { Button } from "@/components/ui/Button";
+
+interface PatentImportModalProps {
+ initialPatentNumber: string;
+ onClose: () => void;
+ onSubmit: (data: { patentNumber: string }) => void;
+}
+
+export function PatentImportModal({ onClose, onSubmit }: PatentImportModalProps) {
+ const [patentNumber, setPatentNumber] = useState("");
+
+ return (
+
+
e.stopPropagation()}
+ >
+
+
특허번호로 기술 불러오기
+
+
+
+
setPatentNumber(e.target.value)}
+ placeholder="특허번호를 입력해주세요"
+ />
+
+
+
+
+ );
+}
diff --git a/src/components/search/ResultCountButton.tsx b/src/components/search/ResultCountButton.tsx
new file mode 100644
index 0000000..259369b
--- /dev/null
+++ b/src/components/search/ResultCountButton.tsx
@@ -0,0 +1,33 @@
+"use client";
+
+import { useState } from "react";
+import MinusIcon from "@/components/icons/icon-minus.svg";
+import PlusIcon from "@/components/icons/icon-plus.svg";
+
+export function ResultCountButton() {
+ const [count, setCount] = useState(10);
+
+ return (
+
+
+
+
+ {count}개
+
+
+
+
+ );
+}
diff --git a/src/components/search/SearchTitle.tsx b/src/components/search/SearchTitle.tsx
new file mode 100644
index 0000000..37138b1
--- /dev/null
+++ b/src/components/search/SearchTitle.tsx
@@ -0,0 +1,20 @@
+type TitleProps = {
+ stepnum: number;
+ title: string;
+ label?: string;
+};
+
+export default function Title({ stepnum, title, label }: TitleProps) {
+ return (
+
+ );
+}
diff --git a/src/components/searchlist/Checkbox.tsx b/src/components/searchlist/Checkbox.tsx
index 0cb9db5..0460b12 100644
--- a/src/components/searchlist/Checkbox.tsx
+++ b/src/components/searchlist/Checkbox.tsx
@@ -30,7 +30,7 @@ export const Checkbox = forwardRef(
return (