feat(wip): 自定义编辑框

This commit is contained in:
CrescentLeaf
2026-01-04 23:28:09 +08:00
parent 3bada7c431
commit 82de2eff42
4 changed files with 100 additions and 44 deletions

View File

@@ -1,8 +1,10 @@
import { $ } from "mdui"
export default class MduiPatchedTextAreaElement extends HTMLElement {
static observedAttributes = ['user-id']
declare inputDiv: HTMLDivElement
static observedAttributes = ['value', 'placeholder']
declare inputDiv?: HTMLDivElement
declare inputPlaceHolderDiv?: HTMLDivElement
declare inputContainerDiv?: HTMLDivElement
constructor() {
super()
@@ -13,11 +15,51 @@ export default class MduiPatchedTextAreaElement extends HTMLElement {
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.inputContainerDiv = new DOMParser().parseFromString(`
<div style="overflow-y: auto; height: 100%;">
<div role="textbox" aria-multiline="true" aria-labelledby="txtboxMultilineLabel" contentEditable="true" style="outline: none !important; color: rgb(var(--mdui-color-on-surface-variant)); display: inline-block; word-break: break-word; white-space: pre-wrap;"></div>
<div style="display: none;"></div>
<style>
*::-webkit-scrollbar {
width: 7px;
height: 10px;
}
*::-webkit-scrollbar-track {
width: 6px;
background: rgba(#101f1c, 0.1);
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}
*::-webkit-scrollbar-thumb {
background-color: rgba(144, 147, 153, 0.5);
background-clip: padding-box;
min-height: 28px;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
transition: background-color 0.3s;
cursor: pointer;
}
*::-webkit-scrollbar-thumb:hover {
background-color: rgba(144, 147, 153, 0.3);
}
</style>
</div>
`, 'text/html').body.firstChild as HTMLDivElement
console.log(this.inputContainerDiv.children)
this.inputDiv = this.inputContainerDiv.children[0] as HTMLDivElement
this.inputPlaceHolderDiv = this.inputContainerDiv.children[1] as HTMLDivElement
this.inputDiv.addEventListener('input', () => {
// TODO: 修复 placeholder
this.inputPlaceHolderDiv!.style.display = this.value == '' ? '' : 'none'
this.inputDiv!.style.display = this.value == '' ? 'none' : ''
})
this.inputDiv.addEventListener('blur', () => {
if (this._lastValue !== this.value) {
this._lastValue = this.value || ''
@@ -31,7 +73,7 @@ export default class MduiPatchedTextAreaElement extends HTMLElement {
this.inputDiv.style.width = '100%'
shadow.appendChild(this.inputDiv)
shadow.appendChild(this.inputContainerDiv)
}
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {
switch (name) {
@@ -39,19 +81,27 @@ export default class MduiPatchedTextAreaElement extends HTMLElement {
this.value = newValue || ''
break
}
case 'placeholder': {
this.inputPlaceHolderDiv && (this.inputPlaceHolderDiv.innerText = newValue || '')
break
}
}
}
focus() {
this.inputDiv.focus()
this.inputDiv?.focus()
}
blur() {
this.inputDiv.blur()
this.inputDiv?.blur()
}
checkValidity() {
// TODO: implment this method
return true
}
get value() {
return this.inputDiv.textContent
return this.inputDiv?.textContent || ''
}
set value(v) {
this.inputDiv.textContent = v
this.inputDiv && (this.inputDiv.textContent = v)
}
}