`;
}
/**
* Handle file upload button click
*/
private _handleUploadClick() {
const fileInput = this.shadowRoot?.querySelector(
'input[type="file"]',
) as HTMLInputElement;
fileInput?.click();
}
/**
* Handle file selection
*/
private _handleFileSelect(event: Event) {
const input = event.target as HTMLInputElement;
const files = input.files;
if (!files || files.length === 0) return;
for (const file of Array.from(files)) {
const id = this._generateAttachmentId();
const attachment: PromptAttachment = {
id,
name: file.name,
type: "file",
data: file,
};
this.addAttachment(attachment);
}
// Reset the input so the same file can be selected again
input.value = "";
}
/**
* Handle model selection change
*/
private _handleModelChange(event: Event) {
const select = event.target as HTMLSelectElement;
const newValue = select.value;
this._modelController.setValue(newValue);
// When model is a plain string (not bound to Cell), update it directly
if (typeof this.model === "string") {
this.model = newValue;
}
}
/**
* Apply the current model value to the DOM select element
* This ensures the select element shows the correct selected option
*/
private _applyModelValueToDom() {
// Re-query if we don't have a reference (e.g., model picker appeared after first render)
if (!this._modelSelectElement) {
this._modelSelectElement = this.shadowRoot?.querySelector(
".model-select",
) as HTMLSelectElement;
}
if (!this._modelSelectElement) return;
const currentValue = this._modelController.getValue();
if (currentValue != null) {
this._modelSelectElement.value = String(currentValue);
}
}
/**
* Mount the mentions overlay in the document body
*/
private _mountMentionsOverlay() {
if (this._mentionsOverlay) return;
const el = document.createElement("div");
el.style.position = "fixed";
el.style.inset = "0 auto auto 0";
el.style.zIndex = "1000";
el.style.pointerEvents = "auto";
el.dataset.ctPromptInputMentionsOverlay = "";
document.body.appendChild(el);
this._mentionsOverlay = el;
applyThemeToElement(el, this.theme ?? defaultTheme);
}
/**
* Unmount the mentions overlay from the document body
*/
private _unmountMentionsOverlay() {
if (this._mentionsOverlay) {
render(nothing, this._mentionsOverlay);
this._mentionsOverlay.remove();
this._mentionsOverlay = null;
}
if (this._raf) cancelAnimationFrame(this._raf);
this._raf = undefined;
}
/**
* Render the mentions dropdown into the overlay
*/
private _renderMentionsOverlay() {
if (!this._mentionsOverlay) return;
const filteredMentions = this.mentionController.getFilteredMentions();
if (filteredMentions.length === 0) {
this._unmountMentionsOverlay();
return;
}
// Inline styles so overlay has its own styling
const tpl = html`