forked from MapComplete/MapComplete
Refactoring: port unit picker
This commit is contained in:
parent
622df2df19
commit
2b05d79dbb
8 changed files with 188 additions and 67 deletions
|
@ -23,7 +23,7 @@ export class Denomination {
|
||||||
}
|
}
|
||||||
this._canonicalSingular = json.canonicalDenominationSingular?.trim()
|
this._canonicalSingular = json.canonicalDenominationSingular?.trim()
|
||||||
|
|
||||||
json.alternativeDenomination.forEach((v, i) => {
|
json.alternativeDenomination?.forEach((v, i) => {
|
||||||
if ((v?.trim() ?? "") === "") {
|
if ((v?.trim() ?? "") === "") {
|
||||||
throw `${context}.alternativeDenomination.${i}: invalid alternative denomination: undefined, null or only whitespace`
|
throw `${context}.alternativeDenomination.${i}: invalid alternative denomination: undefined, null or only whitespace`
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,6 @@ export class Denomination {
|
||||||
return (this._humanSingular ?? this._human).Clone()
|
return (this._humanSingular ?? this._human).Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
getToggledHuman(isSingular: Store<boolean>): BaseUIElement {
|
|
||||||
if (this._humanSingular === undefined) {
|
|
||||||
return this.human
|
|
||||||
}
|
|
||||||
return new Toggle(this.humanSingular, this.human, isSingular)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a representation of the given value
|
* Create a representation of the given value
|
||||||
|
@ -165,7 +159,7 @@ export class Denomination {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
isDefaultUnit(country: () => string) {
|
isDefaultDenomination(country: () => string) {
|
||||||
if (this.useIfNoUnitGiven === true) {
|
if (this.useIfNoUnitGiven === true) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,7 +199,7 @@ export class Unit {
|
||||||
) {
|
) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let countries: string | string[] = country()
|
let countries: string | string[] = country() ?? []
|
||||||
if (typeof countries === "string") {
|
if (typeof countries === "string") {
|
||||||
countries = countries.split(",")
|
countries = countries.split(",")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,64 +1,109 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
||||||
import { UIEventSource } from "../../Logic/UIEventSource";
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
import type { ValidatorType } from "./Validators";
|
import type {ValidatorType} from "./Validators";
|
||||||
import Validators from "./Validators";
|
import Validators from "./Validators";
|
||||||
import { ExclamationIcon } from "@rgossiaux/svelte-heroicons/solid";
|
import {ExclamationIcon} from "@rgossiaux/svelte-heroicons/solid";
|
||||||
import { Translation } from "../i18n/Translation";
|
import {Translation} from "../i18n/Translation";
|
||||||
import { createEventDispatcher, onDestroy } from "svelte";
|
import {createEventDispatcher, onDestroy} from "svelte";
|
||||||
import {Validator} from "./Validator";
|
import {Validator} from "./Validator";
|
||||||
|
import {Unit} from "../../Models/Unit";
|
||||||
|
import UnitInput from "../Popup/UnitInput.svelte";
|
||||||
|
|
||||||
export let value: UIEventSource<string>;
|
|
||||||
// Internal state, only copied to 'value' so that no invalid values leak outside
|
export let type: ValidatorType;
|
||||||
let _value = new UIEventSource(value.data ?? "");
|
export let feedback: UIEventSource<Translation> | undefined = undefined;
|
||||||
export let type: ValidatorType;
|
export let getCountry: () => string | undefined
|
||||||
export let feedback: UIEventSource<Translation> | undefined = undefined;
|
export let placeholder: string | Translation | undefined
|
||||||
export let getCountry: () => string | undefined
|
export let unit: Unit = undefined
|
||||||
export let placeholder: string | Translation | undefined
|
|
||||||
let validator : Validator = Validators.get(type)
|
export let value: UIEventSource<string>;
|
||||||
let _placeholder = placeholder ?? validator?.getPlaceholder() ?? type
|
/**
|
||||||
|
* Internal state bound to the input element.
|
||||||
$: {
|
*
|
||||||
// The type changed -> reset some values
|
* This is only copied to 'value' when appropriate so that no invalid values leak outside;
|
||||||
validator = Validators.get(type)
|
* Additionally, the unit is added when copying
|
||||||
_value.setData(value.data ?? "")
|
*/
|
||||||
feedback = feedback?.setData(validator?.getFeedback(_value.data, getCountry));
|
let _value = new UIEventSource(value.data ?? "");
|
||||||
_placeholder = placeholder ?? validator?.getPlaceholder() ?? type
|
|
||||||
}
|
let validator: Validator = Validators.get(type ?? "string")
|
||||||
|
let selectedUnit: UIEventSource<string> = new UIEventSource<string>(undefined)
|
||||||
onDestroy(_value.addCallbackAndRun(v => {
|
let _placeholder = placeholder ?? validator?.getPlaceholder() ?? type
|
||||||
if (validator.isValid(v, getCountry)) {
|
|
||||||
feedback?.setData(undefined);
|
function initValueAndDenom() {
|
||||||
value.setData(v);
|
if (unit && value.data) {
|
||||||
return;
|
const [v, denom] = unit?.findDenomination(value.data, getCountry)
|
||||||
|
if (denom) {
|
||||||
|
_value.setData(v)
|
||||||
|
selectedUnit.setData(denom.canonical)
|
||||||
|
} else {
|
||||||
|
_value.setData(value.data ?? "")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_value.setData(value.data ?? "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
value.setData(undefined);
|
|
||||||
feedback?.setData(validator.getFeedback(v, getCountry));
|
|
||||||
}))
|
|
||||||
|
|
||||||
if (validator === undefined) {
|
initValueAndDenom()
|
||||||
throw "Not a valid type for a validator:" + type;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isValid = _value.map(v => validator.isValid(v, getCountry));
|
$: {
|
||||||
|
// The type changed -> reset some values
|
||||||
|
validator = Validators.get(type ?? "string")
|
||||||
|
_placeholder = placeholder ?? validator?.getPlaceholder() ?? type
|
||||||
|
feedback = feedback?.setData(validator?.getFeedback(_value.data, getCountry));
|
||||||
|
|
||||||
let htmlElem: HTMLInputElement;
|
initValueAndDenom()
|
||||||
|
}
|
||||||
let dispatch = createEventDispatcher<{ selected }>();
|
|
||||||
$: {
|
function setValues() {
|
||||||
if (htmlElem !== undefined) {
|
// Update the value stores
|
||||||
htmlElem.onfocus = () => dispatch("selected");
|
const v = _value.data
|
||||||
|
if (!validator.isValid(v, getCountry) || v === "") {
|
||||||
|
value.setData(undefined);
|
||||||
|
feedback?.setData(validator.getFeedback(v, getCountry));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unit && isNaN(Number(v))) {
|
||||||
|
value.setData(undefined);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
feedback?.setData(undefined);
|
||||||
|
value.setData(v + (selectedUnit.data ?? ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy(_value.addCallbackAndRun(_ => setValues()))
|
||||||
|
onDestroy(selectedUnit.addCallback(_ => setValues()))
|
||||||
|
if (validator === undefined) {
|
||||||
|
throw "Not a valid type for a validator:" + type;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isValid = _value.map(v => validator.isValid(v, getCountry));
|
||||||
|
|
||||||
|
let htmlElem: HTMLInputElement;
|
||||||
|
|
||||||
|
let dispatch = createEventDispatcher<{ selected }>();
|
||||||
|
$: {
|
||||||
|
if (htmlElem !== undefined) {
|
||||||
|
htmlElem.onfocus = () => dispatch("selected");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if validator.textArea}
|
{#if validator.textArea}
|
||||||
<textarea class="w-full" bind:value={$_value} inputmode={validator.inputmode ?? "text"} placeholder={_placeholder}></textarea>
|
<textarea class="w-full" bind:value={$_value} inputmode={validator.inputmode ?? "text"}
|
||||||
|
placeholder={_placeholder}></textarea>
|
||||||
{:else }
|
{:else }
|
||||||
<span class="inline-flex">
|
<span class="inline-flex">
|
||||||
<input bind:this={htmlElem} bind:value={$_value} class="w-full" inputmode={validator.inputmode ?? "text"} placeholder={_placeholder}>
|
<input bind:this={htmlElem} bind:value={$_value} class="w-full" inputmode={validator.inputmode ?? "text"}
|
||||||
{#if !$isValid}
|
placeholder={_placeholder}>
|
||||||
|
{#if !$isValid}
|
||||||
<ExclamationIcon class="h-6 w-6 -ml-6"></ExclamationIcon>
|
<ExclamationIcon class="h-6 w-6 -ml-6"></ExclamationIcon>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if unit !== undefined}
|
||||||
|
<UnitInput {unit} {selectedUnit} textValue={_value} upstreamValue={value}/>
|
||||||
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -7,17 +7,20 @@
|
||||||
import {createEventDispatcher, onDestroy} from "svelte";
|
import {createEventDispatcher, onDestroy} from "svelte";
|
||||||
import InputHelper from "../../InputElement/InputHelper.svelte";
|
import InputHelper from "../../InputElement/InputHelper.svelte";
|
||||||
import type {Feature} from "geojson";
|
import type {Feature} from "geojson";
|
||||||
|
import {Unit} from "../../../Models/Unit";
|
||||||
|
|
||||||
export let value: UIEventSource<string>;
|
export let value: UIEventSource<string>;
|
||||||
export let config: TagRenderingConfig;
|
export let config: TagRenderingConfig;
|
||||||
export let tags: UIEventSource<Record<string, string>>;
|
export let tags: UIEventSource<Record<string, string>>;
|
||||||
|
|
||||||
export let feature: Feature = undefined;
|
export let feature: Feature = undefined;
|
||||||
|
export let unit: Unit | undefined
|
||||||
|
|
||||||
let placeholder = config.freeform?.placeholder
|
let placeholder = config.freeform?.placeholder
|
||||||
$: {
|
$: {
|
||||||
placeholder = config.freeform?.placeholder
|
placeholder = config.freeform?.placeholder
|
||||||
}
|
}
|
||||||
|
let inline = config.freeform.inline
|
||||||
|
|
||||||
export let feedback: UIEventSource<Translation> = new UIEventSource<Translation>(undefined);
|
export let feedback: UIEventSource<Translation> = new UIEventSource<Translation>(undefined);
|
||||||
|
|
||||||
|
@ -35,13 +38,14 @@
|
||||||
|
|
||||||
{#if config.freeform.inline}
|
{#if config.freeform.inline}
|
||||||
<Inline key={config.freeform.key} {tags} template={config.render}>
|
<Inline key={config.freeform.key} {tags} template={config.render}>
|
||||||
<ValidatedInput {feedback} {getCountry} on:selected={() => dispatch("selected")}
|
<ValidatedInput {feedback} {getCountry} {unit} on:selected={() => dispatch("selected")}
|
||||||
type={config.freeform.type} {placeholder} {value}></ValidatedInput>
|
type={config.freeform.type} {placeholder} {value}></ValidatedInput>
|
||||||
</Inline>
|
</Inline>
|
||||||
{:else}
|
{:else}
|
||||||
<ValidatedInput {feedback} {getCountry} on:selected={() => dispatch("selected")}
|
<ValidatedInput {feedback} {getCountry} {unit} on:selected={() => dispatch("selected")}
|
||||||
type={config.freeform.type} {placeholder} {value}></ValidatedInput>
|
type={config.freeform.type} {placeholder} {value}></ValidatedInput>
|
||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<InputHelper args={config.freeform.helperArgs} {feature} type={config.freeform.type} {value}/>
|
<InputHelper args={config.freeform.helperArgs} {feature} type={config.freeform.type} {value}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if config !== undefined && (config?.condition === undefined || config.condition.matchesProperties(_tags))}
|
{#if config !== undefined && (config?.condition === undefined || config.condition.matchesProperties(_tags))}
|
||||||
<div class={"link-underline flex flex-col w-full "+classes+" "+extraClasses}>
|
<div class={"link-underline inline-block w-full "+classes+" "+extraClasses}>
|
||||||
{#if trs.length === 1}
|
{#if trs.length === 1}
|
||||||
<TagRenderingMapping mapping={trs[0]} {tags} {state} {selectedElement} {layer}></TagRenderingMapping>
|
<TagRenderingMapping mapping={trs[0]} {tags} {state} {selectedElement} {layer}></TagRenderingMapping>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import TagRenderingMappingInput from "./TagRenderingMappingInput.svelte";
|
import TagRenderingMappingInput from "./TagRenderingMappingInput.svelte";
|
||||||
import {Translation} from "../../i18n/Translation";
|
import {Translation} from "../../i18n/Translation";
|
||||||
import Constants from "../../../Models/Constants";
|
import Constants from "../../../Models/Constants";
|
||||||
import {TagUtils} from "../../../Logic/Tags/TagUtils";
|
import {Unit} from "../../../Models/Unit";
|
||||||
|
|
||||||
export let config: TagRenderingConfig;
|
export let config: TagRenderingConfig;
|
||||||
export let tags: UIEventSource<Record<string, string>>;
|
export let tags: UIEventSource<Record<string, string>>;
|
||||||
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
let feedback: UIEventSource<Translation> = new UIEventSource<Translation>(undefined);
|
let feedback: UIEventSource<Translation> = new UIEventSource<Translation>(undefined);
|
||||||
|
|
||||||
|
let unit: Unit = layer.units?.find(unit => unit.appliesToKeys.has(config.freeform?.key))
|
||||||
|
|
||||||
// Will be bound if a freeform is available
|
// Will be bound if a freeform is available
|
||||||
let freeformInput = new UIEventSource<string>(tags?.[config.freeform?.key]);
|
let freeformInput = new UIEventSource<string>(tags?.[config.freeform?.key]);
|
||||||
let selectedMapping: number = undefined;
|
let selectedMapping: number = undefined;
|
||||||
|
@ -41,11 +43,13 @@
|
||||||
return m.hideInAnswer.matchesProperties(tags.data)
|
return m.hideInAnswer.matchesProperties(tags.data)
|
||||||
})
|
})
|
||||||
// We received a new config -> reinit
|
// We received a new config -> reinit
|
||||||
|
unit = layer.units.find(unit => unit.appliesToKeys.has(config.freeform?.key))
|
||||||
|
|
||||||
if (config.mappings?.length > 0 && (checkedMappings === undefined || checkedMappings?.length < config.mappings.length)) {
|
if (config.mappings?.length > 0 && (checkedMappings === undefined || checkedMappings?.length < config.mappings.length)) {
|
||||||
checkedMappings = [...config.mappings.map(_ => false), false /*One element extra in case a freeform value is added*/];
|
checkedMappings = [...config.mappings.map(_ => false), false /*One element extra in case a freeform value is added*/];
|
||||||
}
|
}
|
||||||
if (config.freeform?.key) {
|
if (config.freeform?.key) {
|
||||||
if(!config.multiAnswer){ // Somehow, setting multianswer freeform values is broken if this is not set
|
if (!config.multiAnswer) { // Somehow, setting multianswer freeform values is broken if this is not set
|
||||||
freeformInput.setData(tags.data[config.freeform.key]);
|
freeformInput.setData(tags.data[config.freeform.key]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -77,7 +81,7 @@
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
function onSave() {
|
function onSave() {
|
||||||
if(selectedTags === undefined){
|
if (selectedTags === undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (layer.source === null) {
|
if (layer.source === null) {
|
||||||
|
@ -152,7 +156,7 @@
|
||||||
|
|
||||||
{#if config.freeform?.key && !(mappings?.length > 0)}
|
{#if config.freeform?.key && !(mappings?.length > 0)}
|
||||||
<!-- There are no options to choose from, simply show the input element: fill out the text field -->
|
<!-- There are no options to choose from, simply show the input element: fill out the text field -->
|
||||||
<FreeformInput {config} {tags} {feedback} feature={selectedElement} value={freeformInput}/>
|
<FreeformInput {config} {tags} {feedback} {unit} feature={selectedElement} value={freeformInput}/>
|
||||||
{:else if mappings !== undefined && !config.multiAnswer}
|
{:else if mappings !== undefined && !config.multiAnswer}
|
||||||
<!-- Simple radiobuttons as mapping -->
|
<!-- Simple radiobuttons as mapping -->
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
|
@ -169,7 +173,7 @@
|
||||||
<label class="flex">
|
<label class="flex">
|
||||||
<input type="radio" bind:group={selectedMapping} name={"mappings-radio-"+config.id}
|
<input type="radio" bind:group={selectedMapping} name={"mappings-radio-"+config.id}
|
||||||
value={config.mappings?.length}>
|
value={config.mappings?.length}>
|
||||||
<FreeformInput {config} {tags} {feedback} feature={selectedElement} value={freeformInput}
|
<FreeformInput {config} {tags} {feedback} {unit} feature={selectedElement} value={freeformInput}
|
||||||
on:selected={() => selectedMapping = config.mappings?.length }/>
|
on:selected={() => selectedMapping = config.mappings?.length }/>
|
||||||
</label>
|
</label>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -188,7 +192,7 @@
|
||||||
<label class="flex">
|
<label class="flex">
|
||||||
<input type="checkbox" name={"mappings-checkbox-"+config.id+"-"+config.mappings?.length}
|
<input type="checkbox" name={"mappings-checkbox-"+config.id+"-"+config.mappings?.length}
|
||||||
bind:checked={checkedMappings[config.mappings.length]}>
|
bind:checked={checkedMappings[config.mappings.length]}>
|
||||||
<FreeformInput {config} {tags} {feedback} feature={selectedElement} value={freeformInput}
|
<FreeformInput {config} {tags} {feedback} {unit} feature={selectedElement} value={freeformInput}
|
||||||
on:selected={() => checkedMappings[config.mappings.length] = true}/>
|
on:selected={() => checkedMappings[config.mappings.length] = true}/>
|
||||||
</label>
|
</label>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -210,7 +214,8 @@
|
||||||
<!-- TagRenderingQuestion-buttons -->
|
<!-- TagRenderingQuestion-buttons -->
|
||||||
<slot name="cancel"></slot>
|
<slot name="cancel"></slot>
|
||||||
<slot name="save-button" {selectedTags}>
|
<slot name="save-button" {selectedTags}>
|
||||||
<button on:click={onSave} class={(selectedTags === undefined ? "disabled" : "button-shadow")+" primary"}>
|
<button on:click={onSave}
|
||||||
|
class={(selectedTags === undefined ? "disabled" : "button-shadow")+" primary"}>
|
||||||
<Tr t={Translations.t.general.save}/>
|
<Tr t={Translations.t.general.save}/>
|
||||||
</button>
|
</button>
|
||||||
</slot>
|
</slot>
|
||||||
|
|
67
UI/Popup/UnitInput.svelte
Normal file
67
UI/Popup/UnitInput.svelte
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<script lang="ts">
|
||||||
|
|
||||||
|
import {Unit} from "../../Models/Unit";
|
||||||
|
import {Store, UIEventSource} from "../../Logic/UIEventSource";
|
||||||
|
import Tr from "../Base/Tr.svelte";
|
||||||
|
import {onDestroy} from "svelte";
|
||||||
|
|
||||||
|
export let unit: Unit
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current value of the input field
|
||||||
|
* Not necessarily a correct number
|
||||||
|
*/
|
||||||
|
export let textValue: UIEventSource<string>
|
||||||
|
/**
|
||||||
|
* The actual _valid_ value that is upstreamed
|
||||||
|
*/
|
||||||
|
export let upstreamValue: Store<string>
|
||||||
|
|
||||||
|
let isSingle: Store<boolean> = textValue.map(v => Number(v) === 1)
|
||||||
|
|
||||||
|
export let selectedUnit: UIEventSource<string> = new UIEventSource<string>(undefined)
|
||||||
|
export let getCountry = () => "be"
|
||||||
|
console.log("Unit", unit)
|
||||||
|
onDestroy(upstreamValue.addCallbackAndRun(v => {
|
||||||
|
if (v === undefined) {
|
||||||
|
if (!selectedUnit.data) {
|
||||||
|
selectedUnit.setData(unit.getDefaultDenomination(getCountry).canonical)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const selected = unit.findDenomination(v, getCountry)
|
||||||
|
if (selected === undefined) {
|
||||||
|
selectedUnit.setData(unit.getDefaultDenomination(getCountry).canonical)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const [value, denomination] = selected
|
||||||
|
selectedUnit.setData(denomination.canonical)
|
||||||
|
return
|
||||||
|
}))
|
||||||
|
|
||||||
|
onDestroy(textValue.addCallbackAndRunD(v => {
|
||||||
|
// Fallback in case that the user manually types a denomination
|
||||||
|
const [value, denomination] = unit.findDenomination(v, getCountry)
|
||||||
|
if (value === undefined || denomination === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
textValue.setData(value)
|
||||||
|
selectedUnit.setData(denomination.canonical)
|
||||||
|
|
||||||
|
}))
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<select bind:value={$selectedUnit}>
|
||||||
|
{#each unit.denominations as denom (denom.canonical)}
|
||||||
|
<option value={denom.canonical}>
|
||||||
|
{#if $isSingle}
|
||||||
|
<Tr t={denom.humanSingular}/>
|
||||||
|
{:else }
|
||||||
|
<Tr t={denom.human}/>
|
||||||
|
{/if}
|
||||||
|
</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
8
test.ts
8
test.ts
|
@ -3,6 +3,13 @@ import * as theme from "./assets/generated/themes/bookcases.json"
|
||||||
import ThemeViewState from "./Models/ThemeViewState"
|
import ThemeViewState from "./Models/ThemeViewState"
|
||||||
import Combine from "./UI/Base/Combine"
|
import Combine from "./UI/Base/Combine"
|
||||||
import SpecialVisualizations from "./UI/SpecialVisualizations"
|
import SpecialVisualizations from "./UI/SpecialVisualizations"
|
||||||
|
import ValidatedInput from "./UI/InputElement/ValidatedInput.svelte";
|
||||||
|
import SvelteUIElement from "./UI/Base/SvelteUIElement";
|
||||||
|
import {UIEventSource} from "./Logic/UIEventSource";
|
||||||
|
import {Unit} from "./Models/Unit";
|
||||||
|
import {Denomination} from "./Models/Denomination";
|
||||||
|
import {VariableUiElement} from "./UI/Base/VariableUIElement";
|
||||||
|
import {FixedUiElement} from "./UI/Base/FixedUiElement";
|
||||||
|
|
||||||
function testspecial() {
|
function testspecial() {
|
||||||
const layout = new LayoutConfig(<any>theme, true) // qp.data === "" ? : new AllKnownLayoutsLazy().get(qp.data)
|
const layout = new LayoutConfig(<any>theme, true) // qp.data === "" ? : new AllKnownLayoutsLazy().get(qp.data)
|
||||||
|
@ -14,7 +21,6 @@ function testspecial() {
|
||||||
new Combine(all).AttachTo("maindiv")
|
new Combine(all).AttachTo("maindiv")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*/
|
/*/
|
||||||
testspecial()
|
testspecial()
|
||||||
//*/
|
//*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue