forked from MapComplete/MapComplete
More refactoring, stuff kindoff works
This commit is contained in:
parent
62f471df1e
commit
3943100e54
52 changed files with 635 additions and 1010 deletions
|
@ -1,9 +1,10 @@
|
|||
import {UIElement} from "../UIElement";
|
||||
import Locale from "../i18n/Locale";
|
||||
import Translations from "../i18n/Translations";
|
||||
import BaseUIElement from "../BaseUIElement";
|
||||
|
||||
export class Button extends UIElement {
|
||||
private _text: UIElement;
|
||||
private _text: BaseUIElement;
|
||||
private _onclick: () => void;
|
||||
private _clss: string;
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
import {UIElement} from "../UIElement";
|
||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
|
||||
export default class FeatureSwitched extends UIElement{
|
||||
private readonly _upstream: UIElement;
|
||||
private readonly _swtch: UIEventSource<boolean>;
|
||||
|
||||
constructor(upstream :UIElement,
|
||||
swtch: UIEventSource<boolean>) {
|
||||
super(swtch);
|
||||
this._upstream = upstream;
|
||||
this._swtch = swtch;
|
||||
}
|
||||
|
||||
InnerRender(): UIElement | string {
|
||||
if(this._swtch.data){
|
||||
return this._upstream.Render();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
import BaseUIElement from "../BaseUIElement";
|
||||
import {InputElement} from "../Input/InputElement";
|
||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
|
||||
export default class FileSelectorButton extends InputElement<FileList> {
|
||||
|
||||
IsSelected: UIEventSource<boolean>;
|
||||
private readonly _value = new UIEventSource(undefined);
|
||||
private readonly _label: BaseUIElement;
|
||||
private readonly _acceptType: string;
|
||||
|
||||
constructor(label: BaseUIElement, acceptType: string = "image/*") {
|
||||
super();
|
||||
this._label = label;
|
||||
this._acceptType = acceptType;
|
||||
}
|
||||
|
||||
GetValue(): UIEventSource<FileList> {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
IsValid(t: FileList): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected InnerConstructElement(): HTMLElement {
|
||||
const self = this;
|
||||
const el = document.createElement("form")
|
||||
{
|
||||
const label = document.createElement("label")
|
||||
label.appendChild(this._label.ConstructElement())
|
||||
el.appendChild(label)
|
||||
}
|
||||
{
|
||||
const actualInputElement = document.createElement("input");
|
||||
actualInputElement.style.cssText = "display:none";
|
||||
actualInputElement.type = "file";
|
||||
actualInputElement.accept = this._acceptType;
|
||||
actualInputElement.name = "picField";
|
||||
actualInputElement.multiple = true;
|
||||
|
||||
actualInputElement.onchange = () => {
|
||||
if (actualInputElement.files !== null) {
|
||||
self._value.setData(actualInputElement.files)
|
||||
}
|
||||
}
|
||||
|
||||
el.addEventListener('submit', e => {
|
||||
if (actualInputElement.files !== null) {
|
||||
self._value.setData(actualInputElement.files)
|
||||
}
|
||||
e.preventDefault()
|
||||
})
|
||||
|
||||
el.appendChild(actualInputElement)
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
import {UIElement} from "../UIElement";
|
||||
import BaseUIElement from "../BaseUIElement";
|
||||
|
||||
export class FixedUiElement extends UIElement {
|
||||
export class FixedUiElement extends BaseUIElement {
|
||||
private _html: string;
|
||||
|
||||
constructor(html: string) {
|
||||
super(undefined);
|
||||
super();
|
||||
this._html = html ?? "";
|
||||
}
|
||||
|
||||
|
@ -12,4 +13,10 @@ export class FixedUiElement extends UIElement {
|
|||
return this._html;
|
||||
}
|
||||
|
||||
protected InnerConstructElement(): HTMLElement {
|
||||
const e = document.createElement("span")
|
||||
e.innerHTML = this._html
|
||||
return e;
|
||||
}
|
||||
|
||||
}
|
|
@ -23,6 +23,9 @@ export default class Img extends BaseUIElement {
|
|||
protected InnerConstructElement(): HTMLElement {
|
||||
const el = document.createElement("img")
|
||||
el.src = this._src;
|
||||
el.onload = () => {
|
||||
el.style.opacity = "1"
|
||||
}
|
||||
return el;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
import {UIElement} from "../UIElement";
|
||||
|
||||
export default class LazyElement extends UIElement {
|
||||
|
||||
|
||||
public Activate: () => void;
|
||||
private _content: UIElement = undefined;
|
||||
private readonly _loadingContent: string;
|
||||
|
||||
constructor(content: (() => UIElement), loadingContent = "Rendering...") {
|
||||
super();
|
||||
this._loadingContent = loadingContent;
|
||||
this.dumbMode = false;
|
||||
const self = this;
|
||||
this.Activate = () => {
|
||||
if (this._content === undefined) {
|
||||
self._content = content();
|
||||
}
|
||||
self.Update();
|
||||
// @ts-ignore
|
||||
if (this._content.Activate) {
|
||||
// THis is ugly - I know
|
||||
// @ts-ignore
|
||||
this._content.Activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InnerRender(): string {
|
||||
if (this._content === undefined) {
|
||||
return this._loadingContent;
|
||||
}
|
||||
return this._content.Render();
|
||||
}
|
||||
|
||||
}
|
|
@ -6,18 +6,18 @@ import {UIEventSource} from "../../Logic/UIEventSource";
|
|||
export default class Link extends BaseUIElement {
|
||||
private readonly _element: HTMLElement;
|
||||
|
||||
constructor(embeddedShow: BaseUIElement | string, target: string | UIEventSource<string>, newTab: boolean = false) {
|
||||
constructor(embeddedShow: BaseUIElement | string, href: string | UIEventSource<string>, newTab: boolean = false) {
|
||||
super();
|
||||
const _embeddedShow = Translations.W(embeddedShow);
|
||||
|
||||
|
||||
const el = document.createElement("a")
|
||||
|
||||
if(typeof target === "string"){
|
||||
el.href = target
|
||||
if(typeof href === "string"){
|
||||
el.href = href
|
||||
}else{
|
||||
target.addCallbackAndRun(target => {
|
||||
el.target = target;
|
||||
href.addCallbackAndRun(href => {
|
||||
el.href = href;
|
||||
})
|
||||
}
|
||||
if (newTab) {
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import {UIElement} from "../UIElement";
|
||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
import Svg from "../../Svg";
|
||||
import State from "../../State";
|
||||
|
||||
export default class Ornament extends UIElement {
|
||||
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
import {UIElement} from "../UIElement";
|
||||
|
||||
export default class PageSplit extends UIElement{
|
||||
private _left: UIElement;
|
||||
private _right: UIElement;
|
||||
private _leftPercentage: number;
|
||||
|
||||
constructor(left: UIElement, right:UIElement,
|
||||
leftPercentage: number = 50) {
|
||||
super();
|
||||
this._left = left;
|
||||
this._right = right;
|
||||
this._leftPercentage = leftPercentage;
|
||||
}
|
||||
|
||||
InnerRender(): string {
|
||||
return `<span class="page-split" style="height: min-content"><span style="flex:0 0 ${this._leftPercentage}%">${this._left.Render()}</span><span style="flex: 0 0 ${100-this._leftPercentage}%">${this._right.Render()}</span></span>`;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,18 +4,21 @@ import BaseUIElement from "../BaseUIElement";
|
|||
import Link from "./Link";
|
||||
import Img from "./Img";
|
||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
import {UIElement} from "../UIElement";
|
||||
|
||||
|
||||
export class SubtleButton extends Combine {
|
||||
export class SubtleButton extends UIElement {
|
||||
|
||||
private readonly _element: BaseUIElement
|
||||
|
||||
constructor(imageUrl: string | BaseUIElement, message: string | BaseUIElement, linkTo: { url: string | UIEventSource<string>, newTab?: boolean } = undefined) {
|
||||
super(SubtleButton.generateContent(imageUrl, message, linkTo));
|
||||
|
||||
super();
|
||||
this._element = SubtleButton.generateContent(imageUrl, message, linkTo)
|
||||
this.SetClass("block flex p-3 my-2 bg-blue-100 rounded-lg hover:shadow-xl hover:bg-blue-200 link-no-underline")
|
||||
|
||||
}
|
||||
|
||||
private static generateContent(imageUrl: string | BaseUIElement, messageT: string | BaseUIElement, linkTo: { url: string | UIEventSource<string>, newTab?: boolean } = undefined): (BaseUIElement )[] {
|
||||
private static generateContent(imageUrl: string | BaseUIElement, messageT: string | BaseUIElement, linkTo: { url: string | UIEventSource<string>, newTab?: boolean } = undefined): BaseUIElement {
|
||||
const message = Translations.W(messageT);
|
||||
let img;
|
||||
if ((imageUrl ?? "") === "") {
|
||||
|
@ -28,26 +31,27 @@ export class SubtleButton extends Combine {
|
|||
img?.SetClass("block flex items-center justify-center h-11 w-11 flex-shrink0")
|
||||
const image = new Combine([img])
|
||||
.SetClass("flex-shrink-0");
|
||||
|
||||
|
||||
if (linkTo == undefined) {
|
||||
return [
|
||||
return new Combine([
|
||||
image,
|
||||
message,
|
||||
];
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
new Link(
|
||||
new Combine([
|
||||
image,
|
||||
message?.SetClass("block ml-4 overflow-ellipsis")
|
||||
]).SetClass("flex group"),
|
||||
linkTo.url,
|
||||
linkTo.newTab ?? false
|
||||
)
|
||||
];
|
||||
|
||||
|
||||
return new Link(
|
||||
new Combine([
|
||||
image,
|
||||
message?.SetClass("block ml-4 overflow-ellipsis")
|
||||
]).SetClass("flex group"),
|
||||
linkTo.url,
|
||||
linkTo.newTab ?? false
|
||||
)
|
||||
}
|
||||
|
||||
protected InnerRender(): string | BaseUIElement {
|
||||
return this._element;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,41 +1,33 @@
|
|||
import {UIElement} from "../UIElement";
|
||||
import Translations from "../i18n/Translations";
|
||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
import Combine from "./Combine";
|
||||
import BaseUIElement from "../BaseUIElement";
|
||||
import {VariableUiElement} from "./VariableUIElement";
|
||||
|
||||
export class TabbedComponent extends UIElement {
|
||||
export class TabbedComponent extends Combine {
|
||||
|
||||
private readonly header: UIElement;
|
||||
private content: UIElement[] = [];
|
||||
|
||||
constructor(elements: { header: UIElement | string, content: UIElement | string }[], openedTab: (UIEventSource<number> | number) = 0) {
|
||||
super(typeof (openedTab) === "number" ? new UIEventSource(openedTab) : (openedTab ?? new UIEventSource<number>(0)));
|
||||
const self = this;
|
||||
const tabs: UIElement[] = []
|
||||
constructor(elements: { header: BaseUIElement | string, content: BaseUIElement | string }[], openedTab: (UIEventSource<number> | number) = 0) {
|
||||
|
||||
const openedTabSrc = typeof (openedTab) === "number" ? new UIEventSource(openedTab) : (openedTab ?? new UIEventSource<number>(0))
|
||||
|
||||
const tabs: BaseUIElement[] = []
|
||||
const contentElements: BaseUIElement[] = [];
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let element = elements[i];
|
||||
const header = Translations.W(element.header).onClick(() => self._source.setData(i))
|
||||
const header = Translations.W(element.header).onClick(() => openedTabSrc.setData(i))
|
||||
const content = Translations.W(element.content)
|
||||
this.content.push(content);
|
||||
if (!this.content[i].IsEmpty()) {
|
||||
const tab = header.SetClass("block tab-single-header")
|
||||
tabs.push(tab)
|
||||
}
|
||||
content.SetClass("tab-content")
|
||||
contentElements.push(content);
|
||||
const tab = header.SetClass("block tab-single-header")
|
||||
tabs.push(tab)
|
||||
}
|
||||
|
||||
this.header = new Combine(tabs).SetClass("block tabs-header-bar")
|
||||
const header = new Combine(tabs).SetClass("block tabs-header-bar")
|
||||
const actualContent = new VariableUiElement(
|
||||
openedTabSrc.map(i => contentElements[i])
|
||||
)
|
||||
super([header, actualContent])
|
||||
|
||||
|
||||
}
|
||||
|
||||
InnerRender(): UIElement {
|
||||
|
||||
const content = this.content[this._source.data];
|
||||
return new Combine([
|
||||
this.header,
|
||||
content.SetClass("tab-content"),
|
||||
])
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue