fix: replace example chip gr.HTML+onclick with gr.Button for reliable input fill

gr.HTML inline onclick cannot update Gradio 6 Svelte component state.
Replace _example_chips_html() with gr.Button per chip wired to msg_box
via Gradio event system. CSS updated from .example-chip to .example-chip-btn.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 17:13:36 +09:00
co-authored by Claude Sonnet 4.6
parent f987df5da5
commit a456650bc8
+31 -33
View File
@@ -318,13 +318,6 @@ _EXAMPLE_QUESTIONS = [
]
def _example_chips_html() -> str:
"""D4-4: 예시 질문 chip 카드"""
chips = "".join(
f'<button class="example-chip" onclick="fillInput({repr(q)})">{_html.escape(q)}</button>'
for q in _EXAMPLE_QUESTIONS
)
return f'<div id="example-chips" class="example-chips-wrap">{chips}</div>'
# ── JavaScript (D3 + D4) ──────────────────────────────────────────
@@ -364,14 +357,10 @@ _JS = """
if (el) el.classList.add('nav-active');
};
// D4-3/4: 예시 질문 chip 클릭 → 입력창 채우기
window.fillInput = function(text) {
// D4-3: 입력창 포커스 유틸
window.focusInput = function() {
const ta = document.querySelector('.pill-input textarea');
if (!ta) return;
const setter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set;
setter.call(ta, text);
ta.dispatchEvent(new Event('input', { bubbles: true }));
ta.focus();
if (ta) ta.focus();
};
// D4-5: 설정 패널 토글
@@ -575,22 +564,23 @@ footer { display: none !important; }
}
/* ── 예시 질문 Chip (D4-4) ── */
.example-chips-wrap { display: flex; flex-wrap: wrap; gap: 8px; padding: 8px 0 4px; }
.example-chip {
background: #fff;
border: 1.5px solid #e2e8f0;
border-radius: 20px;
padding: 8px 16px;
font-size: .875rem;
color: #374151;
cursor: pointer;
transition: all .15s;
white-space: nowrap;
.example-chips-row { padding: 6px 0 4px !important; flex-wrap: wrap !important; gap: 8px !important; }
.example-chip-btn button {
border-radius: 20px !important;
border: 1.5px solid #e2e8f0 !important;
background: #fff !important;
color: #374151 !important;
padding: 8px 18px !important;
font-size: .875rem !important;
box-shadow: none !important;
white-space: nowrap !important;
transition: all .15s !important;
font-weight: 400 !important;
}
.example-chip:hover {
background: #eff6ff;
border-color: #93c5fd;
color: #1d4ed8;
.example-chip-btn button:hover {
background: #eff6ff !important;
border-color: #93c5fd !important;
color: #1d4ed8 !important;
}
/* ── 컨트롤 패널 (D4-5) ── */
@@ -655,8 +645,8 @@ footer { display: none !important; }
.dark .message-wrap .bot { background: #1e293b !important; border-color: #334155 !important; }
.dark .nav-btn button:hover { background: #1e293b !important; }
.dark .nav-btn button.nav-active { background: #1e3a5f !important; color: #93c5fd !important; }
.dark .example-chip { background: #1e293b !important; border-color: #334155 !important; color: #cbd5e1 !important; }
.dark .example-chip:hover { background: #1e3a5f !important; border-color: #3b82f6 !important; }
.dark .example-chip-btn button { background: #1e293b !important; border-color: #334155 !important; color: #cbd5e1 !important; }
.dark .example-chip-btn button:hover { background: #1e3a5f !important; border-color: #3b82f6 !important; }
.dark #control-panel { background: #1e293b !important; border-color: #334155 !important; }
"""
@@ -756,8 +746,12 @@ with gr.Blocks(title="율봇", css=_CUSTOM_CSS, theme=_THEME, js=_JS) as demo:
)
send_btn = gr.Button("", variant="primary", scale=0, min_width=48, elem_classes=["pill-send-btn"])
# D4-4: 예시 질문 Chips
gr.HTML(_example_chips_html())
# D4-4: 예시 질문 Chips (gr.Button — Gradio 이벤트로 msg_box 직접 업데이트)
with gr.Row(elem_classes=["example-chips-row"]):
chip_btns = [
gr.Button(q, elem_classes=["example-chip-btn"], size="sm")
for q in _EXAMPLE_QUESTIONS
]
# 첨부 Accordions
with gr.Accordion("📷 이미지 첨부 (선택)", open=False):
@@ -816,6 +810,10 @@ with gr.Blocks(title="율봇", css=_CUSTOM_CSS, theme=_THEME, js=_JS) as demo:
# ── 이벤트 바인딩 ─────────────────────────────────────────────
# 예시 질문 chips → msg_box 채우기
for _q, _btn in zip(_EXAMPLE_QUESTIONS, chip_btns):
_btn.click(fn=lambda x=_q: x, outputs=[msg_box])
# 사이드바 네비게이션
_panels = [panel_chat, panel_doc_register, panel_doc_manage]
chat_nav_btn.click(show_chat_panel, outputs=_panels,