mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
ui: domain_group management
This commit is contained in:
1 parent
8144e85c14
commit
b1c63ddd6c
17 files changed
+270
-58
No files matched your search
@@ -0,0 +1,112 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { assign } from 'lodash';
|
||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||
import AutoCompleteFC from './components/AutoComplete';
|
||||
|
||||
export interface AutoCompleteOptions<Multi extends boolean = boolean> {
|
||||
multi?: Multi;
|
||||
defaultItems?: string;
|
||||
width?: string;
|
||||
height?: string;
|
||||
listStyle?: any;
|
||||
allowEmptyQuery?: boolean;
|
||||
freeSolo?: boolean;
|
||||
freeSoloConverter?: any;
|
||||
onChange?: (value) => any;
|
||||
items?: () => Promise<any[]>;
|
||||
render?: () => string;
|
||||
text?: () => string;
|
||||
}
|
||||
|
||||
export default class AutoComplete extends DOMAttachedObject {
|
||||
static DOMAttachKey = 'ucwAutoCompleteInstance';
|
||||
ref = null;
|
||||
container = document.createElement('div');
|
||||
options: AutoCompleteOptions;
|
||||
changeListener = [
|
||||
(val) => this.$dom.val(val),
|
||||
];
|
||||
|
||||
constructor($dom, options = {}) {
|
||||
super($dom);
|
||||
this.options = {
|
||||
items: async () => [],
|
||||
render: () => '',
|
||||
text: () => null,
|
||||
multi: false,
|
||||
...options,
|
||||
};
|
||||
this.clear = this.clear.bind(this);
|
||||
this.onChange = this.onChange.bind(this);
|
||||
this.attach = this.attach.bind(this);
|
||||
this.open = this.open.bind(this);
|
||||
this.close = this.close.bind(this);
|
||||
this.value = this.value.bind(this);
|
||||
this.detach = this.detach.bind(this);
|
||||
this.focus = this.focus.bind(this);
|
||||
this.$dom.addClass('autocomplete-dummy').after(this.container);
|
||||
// Note: use `setTimeout(fn, 0)` to ensure that code is executed after browser autofill
|
||||
// also see https://stackoverflow.com/a/779785/13553984
|
||||
setTimeout(() => this.attach(), 0);
|
||||
}
|
||||
|
||||
clear(clearValue = true) {
|
||||
if (!this.ref) return;
|
||||
if (clearValue) this.ref.clear();
|
||||
else this.ref.closeList();
|
||||
}
|
||||
|
||||
onChange(val: string | ((v: string) => any)) {
|
||||
if (typeof val === 'string') this.changeListener.forEach((f) => f(val));
|
||||
else this.changeListener.push(val);
|
||||
}
|
||||
|
||||
attach() {
|
||||
const value = this.$dom.val();
|
||||
ReactDOM.render(
|
||||
<AutoCompleteFC
|
||||
ref={(ref) => { this.ref = ref; }}
|
||||
height="34px"
|
||||
itemsFn={this.options.items}
|
||||
renderItem={this.options.render}
|
||||
itemText={this.options.text}
|
||||
defaultItems={value}
|
||||
onChange={this.onChange}
|
||||
multi={this.options.multi}
|
||||
freeSolo={this.options.multi}
|
||||
/>,
|
||||
this.container,
|
||||
);
|
||||
}
|
||||
|
||||
open() {
|
||||
if (!this.ref) return;
|
||||
this.ref.triggerQuery();
|
||||
}
|
||||
|
||||
close() {
|
||||
if (!this.ref) return;
|
||||
this.ref.closeList();
|
||||
}
|
||||
|
||||
value(): any {
|
||||
if (this.options.multi) return this.$dom.val();
|
||||
return this.ref?.getSelectedItems()[0] ?? null;
|
||||
}
|
||||
|
||||
detach() {
|
||||
if (this.detached) return;
|
||||
super.detach();
|
||||
ReactDOM.unmountComponentAtNode(this.container);
|
||||
this.$dom.removeClass('autocomplete-dummy');
|
||||
this.container.parentNode.removeChild(this.container);
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.ref.focus();
|
||||
}
|
||||
}
|
||||
|
||||
assign(AutoComplete, DOMAttachedObject);
|
||||
window.Hydro.components.autocomplete = AutoComplete;
|
||||
Reference in new issue
Block a user