diff --git a/client/init.ts b/client/init.ts index 235093a..ec44a64 100644 --- a/client/init.ts +++ b/client/init.ts @@ -14,6 +14,8 @@ import './ui/chat-elements/chat-text.ts' import './ui/chat-elements/chat-mention.ts' import './ui/chat-elements/chat-text-container.ts' import './ui/chat-elements/chat-quote.ts' +import './ui/InputElement.ts' +import './ui/InnerTextContainerElement.ts' import Main from "./ui/Main.tsx" import performAuth from './performAuth.ts' diff --git a/client/ui/InputElement.ts b/client/ui/InputElement.ts new file mode 100644 index 0000000..63ef0c1 --- /dev/null +++ b/client/ui/InputElement.ts @@ -0,0 +1,58 @@ +import { $ } from "mdui" + +export default class InputElement extends HTMLElement { + static observedAttributes = ['user-id'] + declare inputDiv: HTMLDivElement + constructor() { + super() + + this.attachShadow({ mode: 'open' }) + } + + _lastValue = '' + connectedCallback() { + const shadow = this.shadowRoot as ShadowRoot + + this.inputDiv = new DOMParser().parseFromString(` +
+ `, 'text/html').body.firstChild as HTMLDivElement + this.inputDiv.contentEditable = 'true' + + this.inputDiv.addEventListener('blur', () => { + if (this._lastValue !== this.value) { + this._lastValue = this.value || '' + this.dispatchEvent(new Event('change', { bubbles: true })) + } + }) + this.inputDiv.addEventListener('paste', (e: ClipboardEvent) => { + e.preventDefault() + document.execCommand('insertText', false, e.clipboardData?.getData("text/plain") || '') + }) + + this.inputDiv.style.width = '100%' + + shadow.appendChild(this.inputDiv) + } + attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) { + switch (name) { + case 'value': { + this.value = newValue || '' + break + } + } + } + focus() { + this.inputDiv.focus() + } + blur() { + this.inputDiv.blur() + } + get value() { + return this.inputDiv.textContent + } + set value(v) { + this.inputDiv.textContent = v + } +} + +customElements.define('input-element', InputElement) diff --git a/mdui_patched/components/text-field/index.js b/mdui_patched/components/text-field/index.js index ec87b5e..0e51a31 100644 --- a/mdui_patched/components/text-field/index.js +++ b/mdui_patched/components/text-field/index.js @@ -398,9 +398,9 @@ let TextField = class TextField extends FocusableMixin(MduiElement) { 'is-firefox': navigator.userAgent.includes('Firefox'), ...invalidClassNameObj, }); - return html `
${this.renderPrefix()}
${this.renderLabel()} ${this.isTextarea + return html `
${this.renderPrefix()}
${this.renderLabel()} ${!hasInputSlot ? (this.isTextarea ? this.renderTextArea(hasInputSlot) - : this.renderInput(hasInputSlot)} ${when(hasInputSlot, () => html ``)}
${this.renderSuffix()}${this.renderClearButton(hasClearButton)} ${this.renderTogglePasswordButton(hasTogglePasswordButton)} ${this.renderRightIcon(hasErrorIcon)}
${when(hasError || hasHelper || hasCounter, () => html `
${this.renderHelper(hasError, hasHelper)} ${this.renderCounter(hasCounter)}
`)}`; + : this.renderInput(hasInputSlot)) : ''} ${when(hasInputSlot, () => html ``)}
${this.renderSuffix()}${this.renderClearButton(hasClearButton)} ${this.renderTogglePasswordButton(hasTogglePasswordButton)} ${this.renderRightIcon(hasErrorIcon)}
${when(hasError || hasHelper || hasCounter, () => html `
${this.renderHelper(hasError, hasHelper)} ${this.renderCounter(hasCounter)}
`)}`; } setCustomValidityInternal(message) { this.inputRef.value.setCustomValidity(message);