nnuer
강희태@gmlxo9917

칩으로 쌓이는 배경 정보 입력 질문

기타 블록

질문 제목과 설명 아래에 입력한 항목이 파란 알약 칩으로 쌓이는 태그 입력과 '없음' 체크박스가 있는 단계형 질문입니다. 엔터나 더하기 버튼으로 추가하고 칩의 x로 지웁니다.

#tag-input#chips#form#wizard#korean2026. 10. 16. 업데이트

블록 신고

운영자가 확인한 뒤 필요하면 블록을 숨깁니다.

사유
Claude Code · 모름 · React (TSX)
결과 코드펼치기
import { useState } from "react";

const FONT_URL = "https://fonts.googleapis.com/css2?family=Gothic+A1:wght@400;500;600;700;800&display=swap";

export default function BackgroundInfoTagInput() {
  const [tags, setTags] = useState(["시장 분석 데이터", "경쟁사 현황"]);
  const [draft, setDraft] = useState("");
  const [none, setNone] = useState(false);

  const addTag = () => {
    const value = draft.trim();
    if (!value || tags.includes(value)) return;
    setTags([...tags, value]);
    setDraft("");
  };

  const toggleNone = () => {
    setNone((v) => !v);
  };

  return (
    <section className="w-full bg-white px-4 py-10 font-['Gothic_A1',sans-serif] sm:px-6 sm:py-16">
      <link rel="stylesheet" href={FONT_URL} precedence="default" />
      <div className="mx-auto flex w-full max-w-[672px] flex-col gap-6">
        <h2 className="text-[20px] font-bold leading-normal text-[#1a1d1f] sm:text-[24px]">미리 알아야 할 것</h2>
        <p id="bg-info-desc" className="text-[15px] font-normal leading-normal text-[#6f767e] sm:text-[16px]">
          참석자들이 회의 전에 알아야 할 배경 정보가 있나요?
        </p>

        <div className={`flex flex-col gap-4 transition-opacity duration-150 ${none ? "pointer-events-none opacity-40" : ""}`} aria-disabled={none}>
          {tags.length > 0 && (
            <ul className="flex flex-wrap gap-2" aria-label="추가된 배경 정보">
              {tags.map((tag) => (
                <li key={tag} className="flex items-center gap-2 rounded-full bg-[rgba(67,97,238,0.06)] px-4 py-2.5">
                  <span className="text-[14px] font-semibold leading-normal text-[#4361ee]">{tag}</span>
                  <button
                    type="button"
                    onClick={() => setTags(tags.filter((t) => t !== tag))}
                    disabled={none}
                    aria-label={`${tag} 삭제`}
                    className="rounded-full text-[#4361ee] transition-opacity hover:opacity-70 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#4361ee]"
                  >
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                      <circle cx="12" cy="12" r="10" />
                      <path d="m15 9-6 6M9 9l6 6" />
                    </svg>
                  </button>
                </li>
              ))}
            </ul>
          )}

          <div className="flex items-center justify-between gap-3 rounded-xl border border-[#eeeef2] px-5 py-3.5 focus-within:border-[#4361ee]">
            <label htmlFor="bg-info-input" className="sr-only">
              배경 정보 추가
            </label>
            <input
              id="bg-info-input"
              type="text"
              value={draft}
              disabled={none}
              aria-describedby="bg-info-desc"
              onChange={(e) => setDraft(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter" && !e.nativeEvent.isComposing) {
                  e.preventDefault();
                  addTag();
                }
              }}
              placeholder="배경 정보 추가..."
              className="min-w-0 flex-1 bg-transparent text-[16px] leading-normal text-[#1a1d1f] outline-none placeholder:text-[#6f767e] placeholder:opacity-60"
            />
            <button
              type="button"
              onClick={addTag}
              disabled={none}
              aria-label="배경 정보 추가하기"
              className="flex shrink-0 items-center justify-center rounded-md bg-[#4361ee] p-1 text-white transition-colors hover:bg-[#3651d4] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#4361ee] disabled:cursor-not-allowed disabled:opacity-50"
            >
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" aria-hidden="true">
                <path d="M12 5v14M5 12h14" />
              </svg>
            </button>
          </div>
        </div>

        <label className="flex cursor-pointer items-center gap-3 pt-2">
          <input type="checkbox" checked={none} onChange={toggleNone} className="peer sr-only" />
          <span
            className={`flex size-6 items-center justify-center rounded-md border-2 transition-colors peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-[#4361ee] ${
              none ? "border-[#4361ee] bg-[#4361ee]" : "border-[#eeeef2] bg-white"
            }`}
            aria-hidden="true"
          >
            {none && (
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
                <path d="M20 6 9 17l-5-5" />
              </svg>
            )}
          </span>
          <span className="text-[16px] font-medium leading-normal text-[#6f767e]">없음</span>
        </label>
      </div>
    </section>
  );
}

적용 사이트 0

이 블록이 실제로 쓰인 사이트입니다.

로그인하고 내 사이트 추가

아직 등록된 사이트가 없습니다. 이 블록을 쓴 사이트가 있다면 알려 주세요.

로그인하고 재현 결과 올리기

재현 후기

v1 · 0개

아직 이 버전의 프롬프트로 직접 만들어 본 사람이 없습니다. 첫 번째로 재현해 보세요.