Skip to content
← Chat Interface
Edit Chat Interface
Name
Also known as (comma separated)
Brief definition
Conversational UI.
Notes
Tier
Core
Useful
Reference
Deleted
Controls schema (JSON array)
[ { "id": "placeholder", "type": "text", "label": "Input placeholder", "default": "Ask a question…" }, { "id": "assistantName", "type": "text", "label": "Assistant name", "default": "Assistant" }, { "id": "accent", "type": "color", "label": "Accent colour", "default": "#D9C8F0", "presets": [ "#D9C8F0", "#A8E6C1", "#F5C2E0", "#BFD9F2", "#E8A020", "#241430" ] }, { "id": "showTyping", "type": "toggle", "label": "Show typing indicator", "default": true } ]
Templates (JSON object keyed by format)
{ "html": "<section class=\"chat-interface\" style=\"--accent:{{accent}};\">\n <header class=\"chat-interface__header\">\n <span class=\"chat-interface__avatar\" aria-hidden=\"true\"></span>\n <span class=\"chat-interface__name\">{{assistantName}}</span>\n </header>\n <div class=\"chat-interface__messages\">\n <p class=\"chat-interface__msg chat-interface__msg--user\">Can you summarise this document?</p>\n <p class=\"chat-interface__msg chat-interface__msg--assistant\">Here is a three-line summary of the key points.</p>\n {{#if showTyping}}\n <div class=\"chat-interface__typing\" role=\"status\" aria-live=\"polite\">\n <span class=\"chat-interface__typing-dots\" aria-hidden=\"true\"><span></span><span></span><span></span></span>\n <span class=\"chat-interface__srtext\">{{assistantName}} is typing</span>\n </div>\n {{/if}}\n </div>\n <div class=\"chat-interface__composer\">\n <input class=\"chat-interface__input\" type=\"text\" placeholder=\"{{placeholder}}\" aria-label=\"Message\" />\n <button class=\"chat-interface__send\" type=\"button\">Send</button>\n </div>\n</section>\n<style>\n.chat-interface { font: 14px/1.5 system-ui, sans-serif; color: #241430; background: #FAF7F2; max-width: 360px; padding: 14px; border-radius: 14px; border: 1px solid #24143014; box-sizing: border-box; }\n.chat-interface__header { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }\n.chat-interface__avatar { width: 22px; height: 22px; border-radius: 50%; background: var(--accent); flex: none; }\n.chat-interface__name { font-weight: 600; font-size: 13px; }\n.chat-interface__messages { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }\n.chat-interface__msg { margin: 0; padding: 8px 12px; border-radius: 12px; max-width: 82%; font-size: 13.5px; }\n.chat-interface__msg--user { align-self: flex-end; background: var(--accent); color: #241430; }\n.chat-interface__msg--assistant { align-self: flex-start; background: #24143010; }\n.chat-interface__typing { display: flex; align-items: center; gap: 6px; align-self: flex-start; padding: 8px 12px; }\n.chat-interface__typing-dots { display: inline-flex; gap: 3px; }\n.chat-interface__typing-dots span { width: 5px; height: 5px; border-radius: 50%; background: #24143066; display: inline-block; }\n@media (prefers-reduced-motion: no-preference) {\n.chat-interface__typing-dots span { animation: chat-interface-bounce .2s ease-in-out infinite; }\n.chat-interface__typing-dots span:nth-child(2) { animation-delay: .03s; }\n.chat-interface__typing-dots span:nth-child(3) { animation-delay: .06s; }\n}\n@keyframes chat-interface-bounce { 0%, 60%, 100% { transform: translateY(0); opacity: .5; } 30% { transform: translateY(-3px); opacity: 1; } }\n.chat-interface__srtext { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }\n.chat-interface__composer { display: flex; gap: 8px; }\n.chat-interface__input { flex: 1; padding: 8px 10px; border: 1.5px solid #24143026; border-radius: 8px; font: inherit; color: #241430; background: #fff; box-sizing: border-box; }\n.chat-interface__input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }\n.chat-interface__send { background: var(--accent); color: #241430; border: none; padding: 8px 14px; border-radius: 8px; font: 600 13px system-ui, sans-serif; cursor: pointer; }\n.chat-interface__send:focus-visible { outline: 2px solid #241430; outline-offset: 2px; }\n</style>", "tailwind": "<section class=\"font-sans text-sm leading-relaxed text-[#241430] bg-[#FAF7F2] max-w-[360px] p-3.5 rounded-2xl border border-[#24143014] box-border\" style=\"--accent:{{accent}};\">\n <header class=\"flex items-center gap-2 mb-2.5\">\n <span class=\"w-[22px] h-[22px] rounded-full flex-none\" style=\"background:var(--accent)\" aria-hidden=\"true\"></span>\n <span class=\"font-semibold text-[13px]\">{{assistantName}}</span>\n </header>\n <div class=\"flex flex-col gap-2 mb-2.5\">\n <p class=\"m-0 self-end px-3 py-2 rounded-xl max-w-[82%] text-[13.5px]\" style=\"background:var(--accent);color:#241430;\">Can you summarise this document?</p>\n <p class=\"m-0 self-start px-3 py-2 rounded-xl max-w-[82%] text-[13.5px] bg-[#24143010]\">Here is a three-line summary of the key points.</p>\n {{#if showTyping}}\n <div class=\"chat-interface-tw__typing flex items-center gap-1.5 self-start px-3 py-2\" role=\"status\" aria-live=\"polite\">\n <span class=\"inline-flex gap-[3px]\" aria-hidden=\"true\"><span></span><span></span><span></span></span>\n <span class=\"sr-only\">{{assistantName}} is typing</span>\n </div>\n {{/if}}\n </div>\n <div class=\"flex gap-2\">\n <input class=\"flex-1 px-2.5 py-2 border-[1.5px] border-[#24143026] rounded-lg bg-white text-[#241430] box-border\" type=\"text\" placeholder=\"{{placeholder}}\" aria-label=\"Message\" />\n <button class=\"px-3.5 py-2 rounded-lg text-[13px] font-semibold border-none cursor-pointer\" style=\"background:var(--accent);color:#241430;\" type=\"button\">Send</button>\n </div>\n</section>\n<style>\n.chat-interface-tw__typing span span { width: 5px; height: 5px; border-radius: 50%; background: #24143066; display: inline-block; }\n@media (prefers-reduced-motion: no-preference) {\n.chat-interface-tw__typing span span { animation: chat-interface-tw-bounce .2s ease-in-out infinite; }\n.chat-interface-tw__typing span span:nth-child(2) { animation-delay: .03s; }\n.chat-interface-tw__typing span span:nth-child(3) { animation-delay: .06s; }\n}\n@keyframes chat-interface-tw-bounce { 0%, 60%, 100% { transform: translateY(0); opacity: .5; } 30% { transform: translateY(-3px); opacity: 1; } }\n</style>", "react": "export function ChatInterface({\n placeholder = \"{{placeholder}}\",\n assistantName = \"{{assistantName}}\",\n accent = \"{{accent}}\",\n showTyping = {{showTyping}},\n}) {\n return (\n <section style={{ fontFamily: \"system-ui, sans-serif\", fontSize: 14, lineHeight: 1.5, color: \"#241430\",\n background: \"#FAF7F2\", maxWidth: 360, padding: 14, borderRadius: 14, border: \"1px solid #24143014\", boxSizing: \"border-box\" }}>\n <header style={{ display: \"flex\", alignItems: \"center\", gap: 8, marginBottom: 10 }}>\n <span aria-hidden=\"true\" style={{ width: 22, height: 22, borderRadius: \"50%\", background: accent, flex: \"none\" }} />\n <span style={{ fontWeight: 600, fontSize: 13 }}>{assistantName}</span>\n </header>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8, marginBottom: 10 }}>\n <p style={{ margin: 0, alignSelf: \"flex-end\", padding: \"8px 12px\", borderRadius: 12, maxWidth: \"82%\",\n fontSize: 13.5, background: accent, color: \"#241430\" }}>Can you summarise this document?</p>\n <p style={{ margin: 0, alignSelf: \"flex-start\", padding: \"8px 12px\", borderRadius: 12, maxWidth: \"82%\",\n fontSize: 13.5, background: \"#24143010\" }}>Here is a three-line summary of the key points.</p>\n {showTyping && (\n <div role=\"status\" aria-live=\"polite\" style={{ display: \"flex\", alignItems: \"center\", gap: 6, alignSelf: \"flex-start\", padding: \"8px 12px\" }}>\n <span aria-hidden=\"true\" style={{ display: \"inline-flex\", gap: 3 }}>\n <span className=\"ci-dot ci-dot--1\" style={{ width: 5, height: 5, borderRadius: \"50%\", background: \"#24143066\" }} />\n <span className=\"ci-dot ci-dot--2\" style={{ width: 5, height: 5, borderRadius: \"50%\", background: \"#24143066\" }} />\n <span className=\"ci-dot ci-dot--3\" style={{ width: 5, height: 5, borderRadius: \"50%\", background: \"#24143066\" }} />\n </span>\n <span style={{ position: \"absolute\", width: 1, height: 1, overflow: \"hidden\", clip: \"rect(0 0 0 0)\" }}>{assistantName} is typing</span>\n </div>\n )}\n </div>\n <div style={{ display: \"flex\", gap: 8 }}>\n <input type=\"text\" placeholder={placeholder} aria-label=\"Message\" style={{ flex: 1, padding: \"8px 10px\",\n border: \"1.5px solid #24143026\", borderRadius: 8, font: \"inherit\", color: \"#241430\", background: \"#fff\", boxSizing: \"border-box\" }} />\n <button type=\"button\" style={{ background: accent, color: \"#241430\", border: \"none\", padding: \"8px 14px\",\n borderRadius: 8, fontSize: 13, fontWeight: 600, cursor: \"pointer\" }}>Send</button>\n </div>\n <style>{`\n @media (prefers-reduced-motion: no-preference) {\n .ci-dot--1 { animation: chat-interface-react-bounce 1s ease-in-out infinite; }\n .ci-dot--2 { animation: chat-interface-react-bounce 1s ease-in-out .15s infinite; }\n .ci-dot--3 { animation: chat-interface-react-bounce 1s ease-in-out .3s infinite; }\n @keyframes chat-interface-react-bounce { 0%, 60%, 100% { transform: translateY(0); opacity: .5; } 30% { transform: translateY(-3px); opacity: 1; } }\n }\n `}</style>\n </section>\n );\n}" }
Save
History