Make ui components more chainable

main
Talon 2024-08-24 20:23:10 +02:00
parent 612d9bf2cc
commit bf1719d75d
27 changed files with 105 additions and 4 deletions

View File

@ -61,11 +61,13 @@ export class AudioRecorder extends UINode {
const customEvent = event as CustomEvent;
callback(customEvent.detail.audioUrl);
});
return this;
}
protected triggerRecordingComplete(audioUrl: string) {
const event = new CustomEvent("recording-complete", { detail: { audioUrl } });
this.element.dispatchEvent(event);
return this;
}
public getRecording() {

View File

@ -26,33 +26,41 @@ export class Audio extends UINode {
} else if (src instanceof MediaStream) {
this.audioElement.srcObject = src;
}
return this;
}
public play() {
this.audioElement.play();
return this;
}
public pause() {
this.audioElement.pause();
return this;
}
public setControls(show: boolean) {
this.audioElement.controls = show;
return this;
}
public setLoop(loop: boolean) {
this.audioElement.loop = loop;
return this;
}
public setMuted(muted: boolean) {
this.audioElement.muted = muted;
return this;
}
public setAutoplay(autoplay: boolean) {
this.audioElement.autoplay = autoplay;
return this;
}
public setVolume(volume: number) {
this.audioElement.volume = volume;
return this;
}
}

View File

@ -13,10 +13,12 @@ export class Button extends UINode {
public focus() {
this.buttonElement.focus();
return this;
}
public click() {
this.buttonElement.click();
return this;
}
public getElement(): HTMLElement {
@ -27,9 +29,11 @@ export class Button extends UINode {
this.title = text;
this.buttonElement.innerText = text;
this.element.setAttribute("aria-label", this.title);
return this;
}
public setDisabled(val: boolean) {
this.buttonElement.disabled = val;
return this;
}
}

View File

@ -12,10 +12,12 @@ export class Canvas extends UINode {
public focus() {
this.canvasElement.focus();
return this;
}
public click() {
this.canvasElement.click();
return this;
}
public getElement(): HTMLElement {

View File

@ -19,10 +19,12 @@ export class Checkbox extends UINode {
public focus() {
this.checkboxElement.focus();
return this;
}
public click() {
this.checkboxElement.click();
return this;
}
public getElement(): HTMLElement {
@ -34,6 +36,7 @@ export class Checkbox extends UINode {
this.titleElement.innerText = text;
this.element.setAttribute("aria-label", this.title);
this.element.setAttribute("aria-roledescription", "checkbox");
return this;
}
public isChecked(): boolean {
@ -42,5 +45,6 @@ export class Checkbox extends UINode {
public setChecked(value: boolean) {
this.checkboxElement.checked = value;
return this;
}
}

View File

@ -21,9 +21,10 @@ export class CollapsableContainer extends Container {
return this.wrapperElement;
}
public setTitle(text: string): void {
public setTitle(text: string) {
this.title = text;
this.summaryElement.innerText = text;
return this;
}
public isCollapsed(): boolean {
@ -36,5 +37,6 @@ export class CollapsableContainer extends Container {
} else {
this.detailsElement.removeAttribute("open");
}
return this;
}
}

View File

@ -15,6 +15,7 @@ export class Container extends UINode {
public focus() {
this.containerElement.focus();
return this;
}
public _onFocus() {
@ -45,7 +46,8 @@ export class Container extends UINode {
return this.containerElement;
}
public setAriaLabel(text: string): void {
public setAriaLabel(text: string) {
this.containerElement.setAttribute("aria-label", text);
return this;
}
}

View File

@ -20,6 +20,7 @@ export class DatePicker extends UINode {
public focus() {
this.inputElement.focus();
return this;
}
public getElement(): HTMLElement {
@ -29,6 +30,7 @@ export class DatePicker extends UINode {
public setText(text: string) {
this.title = text;
this.titleElement.innerText = text;
return this;
}
public getValue(): string {
@ -37,5 +39,6 @@ export class DatePicker extends UINode {
public setValue(value: string) {
this.inputElement.value = value;
return this;
}
}

View File

@ -31,20 +31,22 @@ export class Dialog<T> extends UIWindow {
}
}
public setOkAction(action: () => T): void {
public setOkAction(action: () => T) {
if (!this.okButton) return;
this.okButton.onClick(() => {
const result = action();
this.choose(result);
});
return this;
}
public setCancelAction(action: () => void): void {
public setCancelAction(action: () => void) {
if (!this.cancelButton) return;
this.cancelButton.onClick(() => {
action();
this.cancel();
});
return this;
}
public choose(item: T | undefined) {

View File

@ -21,6 +21,7 @@ export class Dropdown extends UINode {
public focus() {
this.selectElement.focus();
return this;
}
public getElement(): HTMLElement {
@ -30,6 +31,7 @@ export class Dropdown extends UINode {
public setText(text: string) {
this.title = text;
this.titleElement.innerText = text;
return this;
}
public getSelectedValue(): string {
@ -38,6 +40,7 @@ export class Dropdown extends UINode {
public setSelectedValue(value: string) {
this.selectElement.value = value;
return this;
}
public setOptions(options: { key: string; value: string }[]) {
@ -45,6 +48,7 @@ export class Dropdown extends UINode {
options.forEach((option) => {
this.addOption(option.key, option.value);
});
return this;
}
public addOption(key: string, value: string) {
@ -52,6 +56,7 @@ export class Dropdown extends UINode {
optionElement.value = key;
optionElement.innerText = value;
this.selectElement.appendChild(optionElement);
return this;
}
public removeOption(key: string) {
@ -60,11 +65,13 @@ export class Dropdown extends UINode {
if (optionToRemove) {
this.selectElement.removeChild(optionToRemove);
}
return this;
}
public clearOptions() {
while (this.selectElement.firstChild) {
this.selectElement.removeChild(this.selectElement.firstChild);
}
return this
}
}

View File

@ -23,6 +23,7 @@ export class FileInput extends UINode {
public focus() {
this.inputElement.focus();
return this;
}
public getElement(): HTMLElement {
@ -32,6 +33,7 @@ export class FileInput extends UINode {
public setText(text: string) {
this.title = text;
this.titleElement.innerText = text;
return this;
}
public getFiles(): FileList | null {
@ -40,5 +42,6 @@ export class FileInput extends UINode {
public setAccept(accept: string) {
this.inputElement.accept = accept;
return this;
}
}

View File

@ -18,13 +18,16 @@ export class Image extends UINode {
public setText(text: string) {
this.title = text;
this.element.setAttribute("aria-label", text);
return this;
}
public setSource(src: string) {
this.imgElement.src = src;
return this;
}
public setAltText(altText: string) {
this.imgElement.alt = altText;
return this;
}
}

View File

@ -15,10 +15,12 @@ export class ListItem extends UINode {
public focus() {
this.listElement.focus();
return this;
}
public click() {
this.listElement.click();
return this;
}
public getElement(): HTMLElement {
@ -30,5 +32,6 @@ export class ListItem extends UINode {
this.listElement.innerText = text;
this.element.setAttribute("aria-label", this.title);
this.listElement.setAttribute("aria-label", this.title);
return this;
}
}

View File

@ -23,6 +23,7 @@ export class List extends UINode {
this.listElement.appendChild(node.render());
if (this.children.length === 1) this.calculateTabIndex();
node.onFocus(() => this.calculateFocused(node));
return this;
}
public addNodeAtIndex(node: UINode, index: number) {
@ -32,6 +33,7 @@ export class List extends UINode {
this.listElement.insertBefore(node.render(), this.listElement.children[index]);
if (this.children.length === 1) this.calculateTabIndex();
node.onFocus(() => this.calculateFocused(node));
return this;
}
public remove(node: UINode) {
@ -43,11 +45,13 @@ export class List extends UINode {
if (this.focused > 0) this.focused--;
this.calculateTabIndex();
}
return this;
}
public _onFocus() {
super._onFocus();
this.children[this.focused].focus();
return this;
}
public _onClick() {
@ -133,6 +137,7 @@ export class List extends UINode {
this.children = [];
this.listElement.innerHTML = '';
this.focused = 0;
return this;
}
public getFocusedChild() {
@ -145,6 +150,7 @@ export class List extends UINode {
public onSelect(f: (id: number) => void) {
this.selectCallback = f;
return this;
}
protected calculateFocused(node: UINode) {
@ -160,5 +166,6 @@ export class List extends UINode {
// set the focused element for tab index without focusing directly.
this.focused = this.children.length - 1;
this.children[this.focused].setTabbable(true);
return this;
}
}

View File

@ -18,10 +18,12 @@ export class MultilineInput extends UINode {
public focus() {
this.textareaElement.focus();
return this;
}
public click() {
this.textareaElement.click();
return this;
}
public getElement(): HTMLElement {
@ -31,6 +33,7 @@ export class MultilineInput extends UINode {
public setText(text: string) {
this.title = text;
this.titleElement.innerText = text;
return this;
}
public getValue(): string {
@ -39,5 +42,6 @@ export class MultilineInput extends UINode {
public setValue(value: string) {
this.textareaElement.value = value;
return this;
}
}

View File

@ -100,6 +100,7 @@ export class UINode {
this.positionType = type;
this.calculateOwnStyle = true;
this.calculateStyle();
return this;
}
public onClick(f: () => void) {
@ -131,14 +132,17 @@ export class UINode {
this.getElement().setAttribute("tabindex",
(val === true) ? "0" :
"-1");
return this;
}
public setAriaLabel(text: string) {
this.element.setAttribute("aria-label", text);
return this;
}
public setRole(role: string) {
this.getElement().setAttribute("role", role);
return this;
}
public getUserData(): any {
@ -147,9 +151,11 @@ export class UINode {
public setUserData(obj: any) {
this.userdata = obj;
return this;
}
public setAccessKey(key: string) {
this.getElement().accessKey = key;
return this;
}
}

View File

@ -17,6 +17,7 @@ export class ProgressBar extends UINode {
public setText(text: string) {
this.title = text;
this.element.setAttribute("aria-label", text);
return this;
}
public getValue(): number {
@ -25,6 +26,7 @@ export class ProgressBar extends UINode {
public setValue(value: number) {
this.progressElement.value = value;
return this;
}
public getMax(): number {
@ -33,5 +35,6 @@ export class ProgressBar extends UINode {
public setMax(max: number) {
this.progressElement.max = max;
return this;
}
}

View File

@ -47,6 +47,7 @@ export class RadioGroup extends UINode {
if (firstRadioElement) {
firstRadioElement.focus();
}
return this;
}
public getElement(): HTMLElement {
@ -56,6 +57,7 @@ export class RadioGroup extends UINode {
public setText(text: string) {
this.title = text;
this.titleElement.innerText = text;
return this;
}
public getSelectedValue(): string | null {
@ -72,5 +74,6 @@ export class RadioGroup extends UINode {
if (radioElement) {
radioElement.checked = true;
}
return this;
}
}

View File

@ -22,10 +22,12 @@ export class Slider extends UINode {
public focus() {
this.sliderElement.focus();
return this;
}
public click() {
this.sliderElement.click();
return this;
}
public getElement(): HTMLElement {
@ -35,6 +37,7 @@ export class Slider extends UINode {
public setText(text: string) {
this.title = text;
this.titleElement.innerText = text;
return this;
}
public getValue(): number {
@ -43,5 +46,6 @@ export class Slider extends UINode {
public setValue(value: number) {
this.sliderElement.value = value.toString();
return this;
}
}

View File

@ -23,10 +23,12 @@ export class TabBar extends UINode {
public _onFocus() {
this.tabs[this.focused].focus();
return this;
}
public focus() {
this.tabs[this.focused].focus();
return this;
}
public add(title: string) {
@ -39,10 +41,12 @@ export class TabBar extends UINode {
this.tabBarContainer.appendChild(elem.render());
elem._onConnect();
if (this.tabs.length === 1) this.calculateTabIndex();
return this;
}
public onTabChange(f: (index: number) => void) {
this.onTabChangeCallback = f;
return this;
}
private selectTab(idx: number) {
@ -93,5 +97,6 @@ export class TabBar extends UINode {
public calculateTabIndex() {
this.tabs[this.focused].setTabbable(true);
return this;
}
}

View File

@ -18,10 +18,12 @@ export class UITab extends UINode {
public focus() {
this.textElement.focus();
return this;
}
public click() {
this.textElement.click();
return this;
}
public getElement(): HTMLElement {
@ -31,10 +33,12 @@ export class UITab extends UINode {
public setText(text: string) {
this.title = text;
this.textElement.innerText = text;
return this;
}
public setSelected(val: boolean) {
this.selected = val;
this.textElement.setAttribute("aria-selected", this.selected.toString());
return this;
}
}

View File

@ -26,6 +26,7 @@ export class TabbedView extends UINode {
this.bar.add(name);
container.setRole("tabpanel");
this.containers.push(container);
return this;
}
private onTabChanged(idx: number) {

View File

@ -19,10 +19,12 @@ export class TextInput extends UINode {
public focus() {
this.inputElement.focus();
return this;
}
public click() {
this.inputElement.click();
return this;
}
public getElement(): HTMLElement {
@ -32,6 +34,7 @@ export class TextInput extends UINode {
public setText(text: string) {
this.title = text;
this.titleElement.innerText = text;
return this;
}
public getValue(): string {
@ -40,5 +43,6 @@ export class TextInput extends UINode {
public setValue(value: string) {
this.inputElement.value = value;
return this;
}
}

View File

@ -12,10 +12,12 @@ export class Text extends UINode {
public focus() {
this.textElement.focus();
return this;
}
public click() {
this.textElement.click();
return this;
}
public getElement(): HTMLElement {
@ -25,5 +27,6 @@ export class Text extends UINode {
public setText(text: string) {
this.title = text;
this.textElement.innerText = text;
return this;
}
}

View File

@ -19,6 +19,7 @@ export class TimePicker extends UINode {
public focus() {
this.inputElement.focus();
return this;
}
public getElement(): HTMLElement {
@ -28,6 +29,7 @@ export class TimePicker extends UINode {
public setText(text: string) {
this.title = text;
this.titleElement.innerText = text;
return this;
}
public getValue(): string {
@ -36,5 +38,6 @@ export class TimePicker extends UINode {
public setValue(value: string) {
this.inputElement.value = value;
return this;
}
}

View File

@ -26,29 +26,36 @@ export class Video extends UINode {
} else if (src instanceof MediaStream) {
this.videoElement.srcObject = src;
}
return this;
}
public play() {
this.videoElement.play();
return this;
}
public pause() {
this.videoElement.pause();
return this;
}
public setControls(show: boolean) {
this.videoElement.controls = show;
return this;
}
public setLoop(loop: boolean) {
this.videoElement.loop = loop;
return this;
}
public setMuted(muted: boolean) {
this.videoElement.muted = muted;
return this;
}
public setAutoplay(autoplay: boolean) {
this.videoElement.autoplay = autoplay;
return this;
}
}

View File

@ -30,10 +30,12 @@ export class UIWindow {
public add(node: UINode) {
this.container.add(node);
return this;
}
public remove(node: UINode) {
if (this.container.children.includes(node)) this.container.remove(node);
return this;
}
public show(): HTMLElement|undefined {