diff --git a/app.py b/app.py index c9052ea..1b3203a 100644 --- a/app.py +++ b/app.py @@ -318,13 +318,6 @@ _EXAMPLE_QUESTIONS = [ ] -def _example_chips_html() -> str: - """D4-4: 예시 질문 chip 카드""" - chips = "".join( - f'' - for q in _EXAMPLE_QUESTIONS - ) - return f'
{chips}
' # ── 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,