fix(b01): 챗봇 창 블랙 · 화이트 테마 색 맞춤 · Enter 보내기 · Shift+Enter 줄바꿈 (275-1·2)
- 없는 색 변수(--color-text-primary · --color-background) 걷고 테마 변수로 — 어두운 테마 제목 · 말풍선 글자 안 보임 해소 - 단추 · 내 말풍선 = primary 색 짝 · 답 말풍선 = 떠 있는 표면 + 테두리 · 입력칸 바탕 · 글자 - Enter = 보내기 · Shift+Enter = 줄바꿈 · 한글 조합 중 Enter 무시 - 화면 시험 ui_checks/275 추가 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KjUPRxjDxULvh5VA7kX5py
This commit is contained in:
@@ -58,11 +58,17 @@ export function buildKnowledgeChat(): HTMLElement {
|
||||
input.rows = 2;
|
||||
input.required = true;
|
||||
input.maxLength = 500;
|
||||
input.placeholder = "메시지를 입력하세요";
|
||||
input.placeholder = "메시지를 입력하세요 (Shift+Enter 줄바꿈)";
|
||||
input.setAttribute("aria-label", "질문");
|
||||
const submit = document.createElement("button");
|
||||
submit.type = "submit";
|
||||
submit.textContent = "보내기";
|
||||
input.addEventListener("keydown", (event) => {
|
||||
if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
|
||||
event.preventDefault();
|
||||
submit.click();
|
||||
}
|
||||
});
|
||||
form.append(input, submit);
|
||||
panel.append(header, messages, form);
|
||||
wrap.append(toggle, panel);
|
||||
|
||||
@@ -536,8 +536,8 @@
|
||||
.b01-knowledge-chat__toggle,
|
||||
.b01-knowledge-chat__form button {
|
||||
border: 0;
|
||||
background: var(--color-royal-amethyst, #6843a7);
|
||||
color: #fff;
|
||||
background: var(--color-primary);
|
||||
color: var(--color-primary-text);
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -565,7 +565,7 @@
|
||||
border-radius: 12px;
|
||||
background: var(--color-surface, #fff);
|
||||
box-shadow: 0 8px 28px #0003;
|
||||
color: var(--color-text-primary, #222);
|
||||
color: var(--color-text-body);
|
||||
overflow: hidden;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
@@ -588,8 +588,8 @@
|
||||
height: 34px;
|
||||
place-items: center;
|
||||
border-radius: 50%;
|
||||
background: var(--color-royal-amethyst, #6843a7);
|
||||
color: #fff;
|
||||
background: var(--color-primary);
|
||||
color: var(--color-primary-text);
|
||||
}
|
||||
|
||||
.b01-knowledge-chat__avatar svg {
|
||||
@@ -631,14 +631,15 @@
|
||||
.b01-knowledge-chat__user {
|
||||
align-self: flex-end;
|
||||
border-bottom-right-radius: 4px;
|
||||
background: var(--color-royal-amethyst, #6843a7);
|
||||
color: #fff;
|
||||
background: var(--color-primary);
|
||||
color: var(--color-primary-text);
|
||||
}
|
||||
|
||||
.b01-knowledge-chat__reply {
|
||||
align-self: flex-start;
|
||||
border: 1px solid var(--color-border);
|
||||
border-bottom-left-radius: 4px;
|
||||
background: var(--color-background, #f4f4f4);
|
||||
background: var(--color-surface-raised);
|
||||
}
|
||||
|
||||
.b01-knowledge-chat__reply details {
|
||||
@@ -722,7 +723,7 @@
|
||||
.b01-knowledge-source-modal__content code {
|
||||
padding: 0.1em 0.35em;
|
||||
border-radius: 4px;
|
||||
background: var(--color-background, #f4f4f4);
|
||||
background: var(--color-surface);
|
||||
}
|
||||
|
||||
.b01-knowledge-source-modal__content .ui-markdown-table {
|
||||
@@ -746,7 +747,7 @@
|
||||
}
|
||||
|
||||
.b01-knowledge-source-modal__content th {
|
||||
background: var(--color-background, #f4f4f4);
|
||||
background: var(--color-surface);
|
||||
}
|
||||
|
||||
.b01-knowledge-chat__form {
|
||||
@@ -765,11 +766,17 @@
|
||||
padding: 8px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 6px;
|
||||
background: var(--color-canvas);
|
||||
color: var(--color-text-body);
|
||||
font: inherit;
|
||||
resize: vertical;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.b01-knowledge-chat__form textarea::placeholder {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.b01-knowledge-chat__form button {
|
||||
padding: 9px 14px;
|
||||
border-radius: 8px;
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/* 275 · 대시보드 챗봇 — 블랙 · 화이트 테마 색 · 엔터 보내기
|
||||
* 시작 화면: B01 대시보드(#/b01-account) · 로그인
|
||||
* 부르는 법: orca eval --expression "$(cat 이 파일)" (async 식 · JSON 글을 돌려줌)
|
||||
* 기대 수치:
|
||||
* - 밝음 · 어두움 모두 글자 대비 ≥ 4.5(제목 · 답 말풍선 · 내 말풍선 · 보내기 · 입력칸 · 열기 단추 · 머리 아이콘)
|
||||
* - Enter = 보냄(내 말풍선 +1 · 입력칸 빔) · Shift+Enter · 한글 조합 중 Enter = 안 보냄
|
||||
* - 서버로 안 나감(fetch 가로챔) · 끝나면 테마 · 말풍선 · fetch 되돌림
|
||||
* ⚠ 대화 기록(화면 메모리)에 시험 한 줄이 남음 — 끝나면 새로고침
|
||||
*/
|
||||
(async () => {
|
||||
const w = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
const rgb = (s) => (s.match(/[\d.]+/g) || []).map(Number);
|
||||
const lum = ([r, g, b]) => {
|
||||
const f = (v) => ((v /= 255) <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4);
|
||||
return 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b);
|
||||
};
|
||||
/** 실제로 보이는 바탕 — 투명이면 조상으로 */
|
||||
const bgOf = (el) => {
|
||||
for (let e = el; e; e = e.parentElement) {
|
||||
const c = rgb(getComputedStyle(e).backgroundColor);
|
||||
if (c.length >= 3 && (c.length < 4 || c[3] > 0.5)) return c.slice(0, 3);
|
||||
}
|
||||
return [255, 255, 255];
|
||||
};
|
||||
const ratio = (a, b) => {
|
||||
const [x, y] = [lum(a), lum(b)];
|
||||
return +((Math.max(x, y) + 0.05) / (Math.min(x, y) + 0.05)).toFixed(2);
|
||||
};
|
||||
const text = (el) => ratio(rgb(getComputedStyle(el).color).slice(0, 3), bgOf(el));
|
||||
|
||||
const root = document.documentElement;
|
||||
const startTheme = root.getAttribute("data-theme");
|
||||
const chat = document.querySelector(".b01-knowledge-chat");
|
||||
if (!chat) return JSON.stringify({ error: "챗봇 없음 — 대시보드에서 부를 것" });
|
||||
const panel = chat.querySelector(".b01-knowledge-chat__panel");
|
||||
const input = chat.querySelector("textarea");
|
||||
const messages = chat.querySelector(".b01-knowledge-chat__messages");
|
||||
const users = () => messages.querySelectorAll(".b01-knowledge-chat__user").length;
|
||||
const wasHidden = panel.hidden;
|
||||
if (wasHidden) chat.querySelector(".b01-knowledge-chat__toggle").click();
|
||||
const before = messages.children.length;
|
||||
const realFetch = window.fetch;
|
||||
window.fetch = async (url, init) =>
|
||||
String(url).endsWith("/knowledge-chat")
|
||||
? new Response(JSON.stringify({ answer: "시험 답", sources: [] }), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
: realFetch(url, init);
|
||||
const press = (opts) => {
|
||||
const event = new KeyboardEvent("keydown", {
|
||||
key: "Enter",
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
...opts,
|
||||
});
|
||||
input.dispatchEvent(event);
|
||||
return event.defaultPrevented;
|
||||
};
|
||||
const out = {};
|
||||
try {
|
||||
input.value = "시험 질문";
|
||||
const start = users();
|
||||
out.shiftEnter = { sent: press({ shiftKey: true }) || users() > start };
|
||||
out.composing = { sent: press({ isComposing: true }) || users() > start };
|
||||
out.enter = { handled: press({}) };
|
||||
await w(300);
|
||||
out.enter.userBubbles = users() - start;
|
||||
out.enter.inputEmpty = input.value === "";
|
||||
for (const theme of ["light", "dark"]) {
|
||||
root.setAttribute("data-theme", theme);
|
||||
await w(50);
|
||||
const reply = messages.querySelector(".b01-knowledge-chat__reply");
|
||||
out[theme] = {
|
||||
title: text(panel.querySelector("header strong")),
|
||||
avatar: text(chat.querySelector(".b01-knowledge-chat__avatar")),
|
||||
reply: text(reply),
|
||||
user: text(messages.querySelector(".b01-knowledge-chat__user")),
|
||||
send: text(chat.querySelector(".b01-knowledge-chat__form button")),
|
||||
input: text(input),
|
||||
toggle: text(chat.querySelector(".b01-knowledge-chat__toggle")),
|
||||
panelBg: getComputedStyle(panel).backgroundColor,
|
||||
replyBg: getComputedStyle(reply).backgroundColor,
|
||||
inputBg: getComputedStyle(input).backgroundColor,
|
||||
};
|
||||
}
|
||||
} finally {
|
||||
window.fetch = realFetch;
|
||||
if (startTheme === null) root.removeAttribute("data-theme");
|
||||
else root.setAttribute("data-theme", startTheme);
|
||||
[...messages.children].slice(before).forEach((node) => node.remove());
|
||||
if (wasHidden) chat.querySelector(".b01-knowledge-chat__close").click();
|
||||
}
|
||||
out.themeRestored = root.getAttribute("data-theme") === startTheme;
|
||||
return JSON.stringify(out);
|
||||
})();
|
||||
Reference in New Issue
Block a user