feat(WIP, unstable): 自定义输入框
This commit is contained in:
@@ -14,6 +14,8 @@ import './ui/chat-elements/chat-text.ts'
|
|||||||
import './ui/chat-elements/chat-mention.ts'
|
import './ui/chat-elements/chat-mention.ts'
|
||||||
import './ui/chat-elements/chat-text-container.ts'
|
import './ui/chat-elements/chat-text-container.ts'
|
||||||
import './ui/chat-elements/chat-quote.ts'
|
import './ui/chat-elements/chat-quote.ts'
|
||||||
|
import './ui/InputElement.ts'
|
||||||
|
import './ui/InnerTextContainerElement.ts'
|
||||||
import Main from "./ui/Main.tsx"
|
import Main from "./ui/Main.tsx"
|
||||||
|
|
||||||
import performAuth from './performAuth.ts'
|
import performAuth from './performAuth.ts'
|
||||||
|
|||||||
58
client/ui/InputElement.ts
Normal file
58
client/ui/InputElement.ts
Normal file
@@ -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(`
|
||||||
|
<div contentEditable="true" style="outline: none !important; color: rgb(var(--mdui-color-on-surface-variant)); display: inline-block; word-wrap: break-word; white-space: pre-wrap;"></div>
|
||||||
|
`, '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)
|
||||||
4
mdui_patched/components/text-field/index.js
vendored
4
mdui_patched/components/text-field/index.js
vendored
@@ -398,9 +398,9 @@ let TextField = class TextField extends FocusableMixin(MduiElement) {
|
|||||||
'is-firefox': navigator.userAgent.includes('Firefox'),
|
'is-firefox': navigator.userAgent.includes('Firefox'),
|
||||||
...invalidClassNameObj,
|
...invalidClassNameObj,
|
||||||
});
|
});
|
||||||
return html `<div part="container" class="${className}">${this.renderPrefix()}<div class="input-container">${this.renderLabel()} ${this.isTextarea
|
return html `<div part="container" class="${className}">${this.renderPrefix()}<div class="input-container">${this.renderLabel()} ${!hasInputSlot ? (this.isTextarea
|
||||||
? this.renderTextArea(hasInputSlot)
|
? this.renderTextArea(hasInputSlot)
|
||||||
: this.renderInput(hasInputSlot)} ${when(hasInputSlot, () => html `<slot name="input" class="input"></slot>`)}</div>${this.renderSuffix()}${this.renderClearButton(hasClearButton)} ${this.renderTogglePasswordButton(hasTogglePasswordButton)} ${this.renderRightIcon(hasErrorIcon)}</div>${when(hasError || hasHelper || hasCounter, () => html `<div part="supporting" class="${classMap({ supporting: true, ...invalidClassNameObj })}">${this.renderHelper(hasError, hasHelper)} ${this.renderCounter(hasCounter)}</div>`)}`;
|
: this.renderInput(hasInputSlot)) : ''} ${when(hasInputSlot, () => html `<slot name="input" class="input"></slot>`)}</div>${this.renderSuffix()}${this.renderClearButton(hasClearButton)} ${this.renderTogglePasswordButton(hasTogglePasswordButton)} ${this.renderRightIcon(hasErrorIcon)}</div>${when(hasError || hasHelper || hasCounter, () => html `<div part="supporting" class="${classMap({ supporting: true, ...invalidClassNameObj })}">${this.renderHelper(hasError, hasHelper)} ${this.renderCounter(hasCounter)}</div>`)}`;
|
||||||
}
|
}
|
||||||
setCustomValidityInternal(message) {
|
setCustomValidityInternal(message) {
|
||||||
this.inputRef.value.setCustomValidity(message);
|
this.inputRef.value.setCustomValidity(message);
|
||||||
|
|||||||
Reference in New Issue
Block a user