mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-10-18 17:40:26 -05:00
fix(widget): fill the inline container and keep typing keys in the widget (#15211)
This commit is contained in:
1 parent
0b8dbbb911
commit
a18fc1a652
5 files changed
+41
-3
No files matched your search
+16
-1
@@ -123,6 +123,7 @@ That's it! The widget will appear as a floating button in the bottom-right corne
|
||||
| `text-color` | string | `#000000bf` | Text color (75% opacity black) |
|
||||
| `mode` | string | `"launcher"` | Display mode: `"launcher"` or `"inline"` |
|
||||
| `include-citations`| boolean | `false` | Include citation markers in responses |
|
||||
| `start-expanded` | boolean | `false` | Inline mode: show the full chat panel before the first message, instead of the compact input bar |
|
||||
|
||||
**Note**: These attributes must be provided as HTML attributes. Only `backend-url` and `api-key` can optionally be set via environment variables for self-hosted builds.
|
||||
|
||||
@@ -232,7 +233,21 @@ The widget is embedded directly in your page layout. Perfect for dedicated suppo
|
||||
</div>
|
||||
```
|
||||
|
||||
**CSS Tip**: The widget will fill its container's dimensions in inline mode.
|
||||
**CSS Tip**: The widget will fill its container's dimensions in inline mode. Give the container an explicit height; otherwise the panel grows with the conversation.
|
||||
|
||||
Before the first message, inline mode shows a compact input bar. Add `start-expanded` to show the full chat panel at the container's size from the start:
|
||||
|
||||
```html
|
||||
<div style="height: 600px;">
|
||||
<onyx-chat-widget mode="inline" start-expanded></onyx-chat-widget>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Keyboard Events
|
||||
|
||||
Key presses typed into the widget do not propagate to the host page (except Escape). The widget uses Shadow DOM, so a page-level handler sees `event.target` as `<onyx-chat-widget>`, not the text field. Without this, handlers that block Backspace outside text fields would also block it in the widget.
|
||||
|
||||
Handlers registered in the capture phase still run first. If such a handler blocks keys outside text fields, check `event.composedPath()[0]` instead of `event.target`.
|
||||
|
||||
## Development
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ export function resolveConfig(attributes: Partial<WidgetConfig>): WidgetConfig {
|
||||
logo: attributes.logo,
|
||||
mode: attributes.mode || "launcher",
|
||||
includeCitations: attributes.includeCitations ?? false,
|
||||
startExpanded: attributes.startExpanded ?? false,
|
||||
};
|
||||
|
||||
if (!config.backendUrl) {
|
||||
|
||||
@@ -10,6 +10,12 @@ export const widgetStyles = css`
|
||||
font-family: var(--onyx-font-family);
|
||||
}
|
||||
|
||||
/* Without a host height, the inline container's height: 100% resolves to
|
||||
auto and the panel grows with its content instead of filling the parent. */
|
||||
:host([mode="inline"]) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.launcher {
|
||||
position: fixed;
|
||||
background: var(--background-neutral-00);
|
||||
|
||||
@@ -29,6 +29,8 @@ export interface WidgetConfig {
|
||||
|
||||
// Optional - Display
|
||||
mode?: "launcher" | "inline";
|
||||
// Inline mode: show the full chat panel before the first message.
|
||||
startExpanded?: boolean;
|
||||
|
||||
// Optional - Citations
|
||||
includeCitations?: boolean;
|
||||
|
||||
+16
-2
@@ -35,9 +35,12 @@ export class OnyxChatWidget extends LitElement {
|
||||
@property({ attribute: "text-color" }) textColor?: string;
|
||||
@property({ attribute: "agent-name" }) agentName?: string;
|
||||
@property({ attribute: "logo" }) logo?: string;
|
||||
@property() mode?: "launcher" | "inline";
|
||||
// Reflected so `:host([mode="inline"])` also matches when set as a property.
|
||||
@property({ reflect: true }) mode?: "launcher" | "inline";
|
||||
@property({ attribute: "include-citations", type: Boolean })
|
||||
includeCitations?: boolean;
|
||||
@property({ attribute: "start-expanded", type: Boolean })
|
||||
startExpanded?: boolean;
|
||||
|
||||
// Assigned as a JS property, since a function cannot ride an HTML attribute.
|
||||
// Takes precedence over `api-key` and keeps the credential out of the markup.
|
||||
@@ -113,6 +116,7 @@ export class OnyxChatWidget extends LitElement {
|
||||
logo: this.logo,
|
||||
mode: this.mode,
|
||||
includeCitations: this.includeCitations,
|
||||
startExpanded: this.startExpanded,
|
||||
});
|
||||
|
||||
// Apply custom colors
|
||||
@@ -358,6 +362,13 @@ export class OnyxChatWidget extends LitElement {
|
||||
}
|
||||
|
||||
private handleKeyDown(e: KeyboardEvent) {
|
||||
// Shadow DOM retargets `e.target` to the host element, so page-level
|
||||
// handlers that let keys through only for text fields (e.g. ones that
|
||||
// block Backspace navigation) would cancel typing here. Escape still
|
||||
// propagates so the host page can close its overlays.
|
||||
if (e.key !== "Escape") {
|
||||
e.stopPropagation();
|
||||
}
|
||||
if (e.key === "Enter" && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
this.sendMessage();
|
||||
@@ -538,7 +549,10 @@ export class OnyxChatWidget extends LitElement {
|
||||
render() {
|
||||
const showContainer = this.config.mode === "inline" || this.isOpen;
|
||||
const hasMessages = this.messages.length > 0 || this.isStreaming;
|
||||
const isCompactInline = this.config.mode === "inline" && !hasMessages;
|
||||
const isCompactInline =
|
||||
this.config.mode === "inline" &&
|
||||
!this.config.startExpanded &&
|
||||
!hasMessages;
|
||||
|
||||
return html`
|
||||
${this.config.mode === "launcher"
|
||||
|
||||
Reference in new issue
Block a user