Chore: reformat all files with prettier

This commit is contained in:
Pieter Vander Vennet 2023-06-14 20:39:36 +02:00
parent 5757ae5dea
commit d008dcb54d
214 changed files with 8926 additions and 8196 deletions

View file

@ -2,11 +2,9 @@
/**
* Simple wrapper around the HTML-color field.
*/
import { UIEventSource } from "../../../Logic/UIEventSource";
export let value: UIEventSource<undefined | string>;
import { UIEventSource } from "../../../Logic/UIEventSource"
export let value: UIEventSource<undefined | string>
</script>
<input bind:value={$value} type="color">
<input bind:value={$value} type="color" />

View file

@ -2,11 +2,9 @@
/**
* Simple wrapper around the HTML-date field.
*/
import { UIEventSource } from "../../../Logic/UIEventSource";
export let value: UIEventSource<undefined | string>;
import { UIEventSource } from "../../../Logic/UIEventSource"
export let value: UIEventSource<undefined | string>
</script>
<input bind:value={$value} type="date">
<input bind:value={$value} type="date" />

View file

@ -1,69 +1,68 @@
<script lang="ts">
import { UIEventSource } from "../../../Logic/UIEventSource";
import type { MapProperties } from "../../../Models/MapProperties";
import { Map as MlMap } from "maplibre-gl";
import { MapLibreAdaptor } from "../../Map/MapLibreAdaptor";
import MaplibreMap from "../../Map/MaplibreMap.svelte";
import ToSvelte from "../../Base/ToSvelte.svelte";
import Svg from "../../../Svg.js";
import { UIEventSource } from "../../../Logic/UIEventSource"
import type { MapProperties } from "../../../Models/MapProperties"
import { Map as MlMap } from "maplibre-gl"
import { MapLibreAdaptor } from "../../Map/MapLibreAdaptor"
import MaplibreMap from "../../Map/MaplibreMap.svelte"
import ToSvelte from "../../Base/ToSvelte.svelte"
import Svg from "../../../Svg.js"
/**
* A visualisation to pick a direction on a map background.
*/
export let value: UIEventSource<undefined | string>;
export let mapProperties: Partial<MapProperties> & { readonly location: UIEventSource<{ lon: number; lat: number }> };
let map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined);
let mla = new MapLibreAdaptor(map, mapProperties);
export let value: UIEventSource<undefined | string>
export let mapProperties: Partial<MapProperties> & {
readonly location: UIEventSource<{ lon: number; lat: number }>
}
let map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined)
let mla = new MapLibreAdaptor(map, mapProperties)
mla.allowMoving.setData(false)
mla.allowZooming.setData(false)
let directionElem: HTMLElement | undefined;
$: value.addCallbackAndRunD(degrees => {
let directionElem: HTMLElement | undefined
$: value.addCallbackAndRunD((degrees) => {
if (directionElem === undefined) {
return;
return
}
directionElem.style.rotate = degrees + "deg";
});
directionElem.style.rotate = degrees + "deg"
})
let mainElem : HTMLElement
let mainElem: HTMLElement
function onPosChange(x: number, y: number) {
const rect = mainElem.getBoundingClientRect();
const dx = -(rect.left + rect.right) / 2 + x;
const dy = (rect.top + rect.bottom) / 2 - y;
const angle = (180 * Math.atan2(dy, dx)) / Math.PI;
const angleGeo = Math.floor((450 - angle) % 360);
value.setData(""+angleGeo);
const rect = mainElem.getBoundingClientRect()
const dx = -(rect.left + rect.right) / 2 + x
const dy = (rect.top + rect.bottom) / 2 - y
const angle = (180 * Math.atan2(dy, dx)) / Math.PI
const angleGeo = Math.floor((450 - angle) % 360)
value.setData("" + angleGeo)
}
let isDown = false;
let isDown = false
</script>
<div bind:this={mainElem} class="relative w-48 h-48 cursor-pointer overflow-hidden"
on:click={e => onPosChange(e.x, e.y)}
on:mousedown={e => {
isDown = true
onPosChange(e.clientX, e.clientY)
} }
on:mousemove={e => {
if(isDown){
<div
bind:this={mainElem}
class="relative w-48 h-48 cursor-pointer overflow-hidden"
on:click={(e) => onPosChange(e.x, e.y)}
on:mousedown={(e) => {
isDown = true
onPosChange(e.clientX, e.clientY)
}}
on:mousemove={(e) => {
if (isDown) {
onPosChange(e.clientX, e.clientY)
}}}
on:mouseup={() => {
isDown = false
} }
on:touchmove={e => onPosChange(e.touches[0].clientX, e.touches[0].clientY)}
on:touchstart={e => onPosChange(e.touches[0].clientX, e.touches[0].clientY)}>
}
}}
on:mouseup={() => {
isDown = false
}}
on:touchmove={(e) => onPosChange(e.touches[0].clientX, e.touches[0].clientY)}
on:touchstart={(e) => onPosChange(e.touches[0].clientX, e.touches[0].clientY)}
>
<div class="w-full h-full absolute top-0 left-0 cursor-pointer">
<MaplibreMap {map} attribution={false}></MaplibreMap>
<MaplibreMap {map} attribution={false} />
</div>
<div bind:this={directionElem} class="absolute w-full h-full top-0 left-0">
<ToSvelte construct={ Svg.direction_stroke_svg}>
</ToSvelte>
<ToSvelte construct={Svg.direction_stroke_svg} />
</div>
</div>

View file

@ -1,139 +1,150 @@
<script lang="ts">
import { Store, Stores, UIEventSource } from "../../../Logic/UIEventSource";
import { Store, Stores, UIEventSource } from "../../../Logic/UIEventSource"
/**
* Given the available floors, shows an elevator to pick a single one
*
*
* This is but the input element, the logic of handling the filter is in 'LevelSelector'
*/
export let floors: Store<string[]>;
export let value: UIEventSource<string>;
export let floors: Store<string[]>
export let value: UIEventSource<string>
const HEIGHT = 40;
const HEIGHT = 40
let initialIndex = Math.max(0, floors?.data?.findIndex(f => f === value?.data) ?? 0);
let index: UIEventSource<number> = new UIEventSource<number>(initialIndex);
let forceIndex: number | undefined = undefined;
let top = Math.max(0, initialIndex) * HEIGHT;
let elevator: HTMLImageElement;
let initialIndex = Math.max(0, floors?.data?.findIndex((f) => f === value?.data) ?? 0)
let index: UIEventSource<number> = new UIEventSource<number>(initialIndex)
let forceIndex: number | undefined = undefined
let top = Math.max(0, initialIndex) * HEIGHT
let elevator: HTMLImageElement
let mouseDown = false;
let mouseDown = false
let container: HTMLElement;
let container: HTMLElement
$:{
$: {
if (top > 0 || forceIndex !== undefined) {
index.setData(closestFloorIndex());
value.setData(floors.data[forceIndex ?? closestFloorIndex()]);
index.setData(closestFloorIndex())
value.setData(floors.data[forceIndex ?? closestFloorIndex()])
}
}
function unclick() {
mouseDown = false;
mouseDown = false
}
function click() {
mouseDown = true;
mouseDown = true
}
function closestFloorIndex() {
return Math.min(floors.data.length - 1, Math.max(0, Math.round(top / HEIGHT)));
return Math.min(floors.data.length - 1, Math.max(0, Math.round(top / HEIGHT)))
}
function onMove(e: { movementY: number }) {
if (mouseDown) {
forceIndex = undefined;
const containerY = container.clientTop;
const containerMax = containerY + (floors.data.length - 1) * HEIGHT;
top = Math.min(Math.max(0, top + e.movementY), containerMax);
forceIndex = undefined
const containerY = container.clientTop
const containerMax = containerY + (floors.data.length - 1) * HEIGHT
top = Math.min(Math.max(0, top + e.movementY), containerMax)
}
}
let momentum = 0;
let momentum = 0
function stabilize() {
// Automatically move the elevator to the closes floor
if (mouseDown) {
return;
return
}
const target = (forceIndex ?? index.data) * HEIGHT;
let diff = target - top;
const target = (forceIndex ?? index.data) * HEIGHT
let diff = target - top
if (diff > 1) {
diff /= 3;
diff /= 3
}
const sign = Math.sign(diff);
momentum = momentum + sign;
let diffR = Math.min(Math.abs(momentum), forceIndex !== undefined ? 9 : 3, Math.abs(diff));
momentum = Math.sign(momentum) * Math.min(diffR, Math.abs(momentum));
top += sign * diffR;
const sign = Math.sign(diff)
momentum = momentum + sign
let diffR = Math.min(Math.abs(momentum), forceIndex !== undefined ? 9 : 3, Math.abs(diff))
momentum = Math.sign(momentum) * Math.min(diffR, Math.abs(momentum))
top += sign * diffR
if (index.data === forceIndex) {
forceIndex = undefined;
forceIndex = undefined
}
top = Math.max(top, 0)
}
Stores.Chronic(50).addCallback(_ => stabilize());
floors.addCallback(floors => {
forceIndex = floors.findIndex(s => s === value.data)
Stores.Chronic(50).addCallback((_) => stabilize())
floors.addCallback((floors) => {
forceIndex = floors.findIndex((s) => s === value.data)
})
let image: HTMLImageElement;
$:{
let image: HTMLImageElement
$: {
if (image) {
let lastY = 0;
let lastY = 0
image.ontouchstart = (e: TouchEvent) => {
mouseDown = true;
lastY = e.changedTouches[0].clientY;
};
image.ontouchmove = e => {
const y = e.changedTouches[0].clientY;
mouseDown = true
lastY = e.changedTouches[0].clientY
}
image.ontouchmove = (e) => {
const y = e.changedTouches[0].clientY
console.log(y)
const movementY = y - lastY;
lastY = y;
onMove({ movementY });
};
image.ontouchend = unclick;
const movementY = y - lastY
lastY = y
onMove({ movementY })
}
image.ontouchend = unclick
}
}
</script>
<div bind:this={container} class="relative"
style={`height: calc(${HEIGHT}px * ${$floors.length}); width: 96px`}>
<div
bind:this={container}
class="relative"
style={`height: calc(${HEIGHT}px * ${$floors.length}); width: 96px`}
>
<div class="h-full absolute w-min right-0">
{#each $floors as floor, i}
<button style={`height: ${HEIGHT}px; width: ${HEIGHT}px`}
class={"m-0 border-2 border-gray-300 flex content-box justify-center items-center "+(i === (forceIndex ?? $index) ? "selected": "" )
}
on:click={() => {forceIndex = i}}
> {floor}</button>
<button
style={`height: ${HEIGHT}px; width: ${HEIGHT}px`}
class={"m-0 border-2 border-gray-300 flex content-box justify-center items-center " +
(i === (forceIndex ?? $index) ? "selected" : "")}
on:click={() => {
forceIndex = i
}}
>
{floor}
</button>
{/each}
</div>
<div style={`width: ${HEIGHT}px`}>
<img bind:this={image} class="draggable" draggable="false" on:mousedown={click} src="./assets/svg/elevator.svg"
style={" top: "+top+"px;"} />
<img
bind:this={image}
class="draggable"
draggable="false"
on:mousedown={click}
src="./assets/svg/elevator.svg"
style={" top: " + top + "px;"}
/>
</div>
</div>
<svelte:window on:mousemove={onMove} on:mouseup={unclick} />
<style>
.draggable {
user-select: none;
cursor: move;
position: absolute;
user-drag: none;
.draggable {
user-select: none;
cursor: move;
position: absolute;
user-drag: none;
height: 72px;
margin-top: -15px;
margin-bottom: -15px;
margin-left: -18px;
-webkit-user-drag: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
height: 72px;
margin-top: -15px;
margin-bottom: -15px;
margin-left: -18px;
-webkit-user-drag: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>

View file

@ -1,82 +1,91 @@
<script lang="ts">
import {Store, UIEventSource} from "../../../Logic/UIEventSource";
import type {MapProperties} from "../../../Models/MapProperties";
import {Map as MlMap} from "maplibre-gl";
import {MapLibreAdaptor} from "../../Map/MapLibreAdaptor";
import MaplibreMap from "../../Map/MaplibreMap.svelte";
import DragInvitation from "../../Base/DragInvitation.svelte";
import {GeoOperations} from "../../../Logic/GeoOperations";
import ShowDataLayer from "../../Map/ShowDataLayer";
import * as boundsdisplay from "../../../assets/layers/range/range.json"
import StaticFeatureSource from "../../../Logic/FeatureSource/Sources/StaticFeatureSource";
import * as turf from "@turf/turf"
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig";
import {onDestroy} from "svelte";
import { Store, UIEventSource } from "../../../Logic/UIEventSource"
import type { MapProperties } from "../../../Models/MapProperties"
import { Map as MlMap } from "maplibre-gl"
import { MapLibreAdaptor } from "../../Map/MapLibreAdaptor"
import MaplibreMap from "../../Map/MaplibreMap.svelte"
import DragInvitation from "../../Base/DragInvitation.svelte"
import { GeoOperations } from "../../../Logic/GeoOperations"
import ShowDataLayer from "../../Map/ShowDataLayer"
import * as boundsdisplay from "../../../assets/layers/range/range.json"
import StaticFeatureSource from "../../../Logic/FeatureSource/Sources/StaticFeatureSource"
import * as turf from "@turf/turf"
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
import { onDestroy } from "svelte"
/**
* A visualisation to pick a location on a map background
*/
export let value: UIEventSource<{ lon: number, lat: number }>;
export let initialCoordinate : {lon: number, lat :number}
initialCoordinate = initialCoordinate ?? value.data
export let maxDistanceInMeters: number = undefined
export let mapProperties: Partial<MapProperties> & {
readonly location: UIEventSource<{ lon: number; lat: number }>
} = undefined;
/**
* Called when setup is done, can be used to add more layers to the map
*/
export let onCreated: (value: Store<{
lon: number,
lat: number
}>, map: Store<MlMap>, mapProperties: MapProperties) => void = undefined
/**
* A visualisation to pick a location on a map background
*/
export let value: UIEventSource<{ lon: number; lat: number }>
export let initialCoordinate: { lon: number; lat: number }
initialCoordinate = initialCoordinate ?? value.data
export let maxDistanceInMeters: number = undefined
export let mapProperties: Partial<MapProperties> & {
readonly location: UIEventSource<{ lon: number; lat: number }>
} = undefined
/**
* Called when setup is done, can be used to add more layers to the map
*/
export let onCreated: (
value: Store<{
lon: number
lat: number
}>,
map: Store<MlMap>,
mapProperties: MapProperties
) => void = undefined
export let map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined);
let mla = new MapLibreAdaptor(map, mapProperties);
mapProperties.location.syncWith(value)
if (onCreated) {
onCreated(value, map, mla)
}
export let map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined)
let mla = new MapLibreAdaptor(map, mapProperties)
mapProperties.location.syncWith(value)
if (onCreated) {
onCreated(value, map, mla)
}
let rangeIsShown = false
if (maxDistanceInMeters) {
onDestroy(mla.location.addCallbackD(newLocation => {
const l = [newLocation.lon, newLocation.lat]
const c: [number, number] = [initialCoordinate.lon, initialCoordinate.lat]
const d = GeoOperations.distanceBetween(l, c)
let rangeIsShown = false
if (maxDistanceInMeters) {
onDestroy(
mla.location.addCallbackD((newLocation) => {
const l = [newLocation.lon, newLocation.lat]
const c: [number, number] = [initialCoordinate.lon, initialCoordinate.lat]
const d = GeoOperations.distanceBetween(l, c)
console.log("distance is", d, l, c)
if (d <= maxDistanceInMeters) {
return
}
// This is too far away - let's move back
const correctLocation = GeoOperations.along(c, l, maxDistanceInMeters - 10)
window.setTimeout(() => {
mla.location.setData({lon: correctLocation[0], lat: correctLocation[1]})
}, 25)
if (d <= maxDistanceInMeters) {
return
}
// This is too far away - let's move back
const correctLocation = GeoOperations.along(c, l, maxDistanceInMeters - 10)
window.setTimeout(() => {
mla.location.setData({ lon: correctLocation[0], lat: correctLocation[1] })
}, 25)
if (!rangeIsShown) {
new ShowDataLayer(map, {
layer: new LayerConfig(boundsdisplay),
features: new StaticFeatureSource(
[turf.circle(c, maxDistanceInMeters, {units: "meters", properties: {"range":"yes", id: "0"}}, )]
)
})
rangeIsShown = true
}
}))
}
if (!rangeIsShown) {
new ShowDataLayer(map, {
layer: new LayerConfig(boundsdisplay),
features: new StaticFeatureSource([
turf.circle(c, maxDistanceInMeters, {
units: "meters",
properties: { range: "yes", id: "0" },
}),
]),
})
rangeIsShown = true
}
})
)
}
</script>
<div class="relative h-full min-h-32 cursor-pointer overflow-hidden">
<div class="w-full h-full absolute top-0 left-0 cursor-pointer">
<MaplibreMap {map}/>
</div>
<div class="w-full h-full absolute top-0 left-0 cursor-pointer">
<MaplibreMap {map} />
</div>
<div class="w-full h-full absolute top-0 left-0 p-8 pointer-events-none opacity-50 flex items-center">
<img class="h-full max-h-24" src="./assets/svg/move-arrows.svg"/>
</div>
<DragInvitation hideSignal={mla.location.stabilized(3000)}></DragInvitation>
<div
class="w-full h-full absolute top-0 left-0 p-8 pointer-events-none opacity-50 flex items-center"
>
<img class="h-full max-h-24" src="./assets/svg/move-arrows.svg" />
</div>
<DragInvitation hideSignal={mla.location.stabilized(3000)} />
</div>

View file

@ -1,32 +1,33 @@
<script lang="ts">
/**
* Constructs an input helper element for the given type.
* Note that all values are stringified
*/
/**
* Constructs an input helper element for the given type.
* Note that all values are stringified
*/
import {UIEventSource} from "../../Logic/UIEventSource";
import type {ValidatorType} from "./Validators";
import InputHelpers from "./InputHelpers";
import ToSvelte from "../Base/ToSvelte.svelte";
import type {Feature} from "geojson";
import BaseUIElement from "../BaseUIElement";
import {VariableUiElement} from "../Base/VariableUIElement";
import { UIEventSource } from "../../Logic/UIEventSource"
import type { ValidatorType } from "./Validators"
import InputHelpers from "./InputHelpers"
import ToSvelte from "../Base/ToSvelte.svelte"
import type { Feature } from "geojson"
import BaseUIElement from "../BaseUIElement"
import { VariableUiElement } from "../Base/VariableUIElement"
export let type: ValidatorType;
export let value: UIEventSource<string>;
export let feature: Feature;
export let args: (string | number | boolean)[] = undefined;
let properties = {feature, args: args ?? []};
let construct = new UIEventSource<(value, extraProperties) => BaseUIElement>(undefined)
$: {
construct.setData(InputHelpers.AvailableInputHelpers[type])
}
export let type: ValidatorType
export let value: UIEventSource<string>
export let feature: Feature
export let args: (string | number | boolean)[] = undefined
let properties = { feature, args: args ?? [] }
let construct = new UIEventSource<(value, extraProperties) => BaseUIElement>(undefined)
$: {
construct.setData(InputHelpers.AvailableInputHelpers[type])
}
</script>
{#if construct !== undefined}
<ToSvelte construct={() => new VariableUiElement(construct.mapD(construct => construct(value, properties)))}/>
<ToSvelte
construct={() =>
new VariableUiElement(construct.mapD((construct) => construct(value, properties)))}
/>
{/if}

View file

@ -1,109 +1,116 @@
<script lang="ts">
import { UIEventSource } from "../../Logic/UIEventSource"
import type { ValidatorType } from "./Validators"
import Validators from "./Validators"
import { ExclamationIcon } from "@rgossiaux/svelte-heroicons/solid"
import { Translation } from "../i18n/Translation"
import { createEventDispatcher, onDestroy } from "svelte"
import { Validator } from "./Validator"
import { Unit } from "../../Models/Unit"
import UnitInput from "../Popup/UnitInput.svelte"
import {UIEventSource} from "../../Logic/UIEventSource";
import type {ValidatorType} from "./Validators";
import Validators from "./Validators";
import {ExclamationIcon} from "@rgossiaux/svelte-heroicons/solid";
import {Translation} from "../i18n/Translation";
import {createEventDispatcher, onDestroy} from "svelte";
import {Validator} from "./Validator";
import {Unit} from "../../Models/Unit";
import UnitInput from "../Popup/UnitInput.svelte";
export let type: ValidatorType
export let feedback: UIEventSource<Translation> | undefined = undefined
export let getCountry: () => string | undefined
export let placeholder: string | Translation | undefined
export let unit: Unit = undefined
export let value: UIEventSource<string>
/**
* Internal state bound to the input element.
*
* This is only copied to 'value' when appropriate so that no invalid values leak outside;
* Additionally, the unit is added when copying
*/
let _value = new UIEventSource(value.data ?? "")
export let type: ValidatorType;
export let feedback: UIEventSource<Translation> | undefined = undefined;
export let getCountry: () => string | undefined
export let placeholder: string | Translation | undefined
export let unit: Unit = undefined
let validator: Validator = Validators.get(type ?? "string")
let selectedUnit: UIEventSource<string> = new UIEventSource<string>(undefined)
let _placeholder = placeholder ?? validator?.getPlaceholder() ?? type
export let value: UIEventSource<string>;
/**
* Internal state bound to the input element.
*
* This is only copied to 'value' when appropriate so that no invalid values leak outside;
* Additionally, the unit is added when copying
*/
let _value = new UIEventSource(value.data ?? "");
let validator: Validator = Validators.get(type ?? "string")
let selectedUnit: UIEventSource<string> = new UIEventSource<string>(undefined)
let _placeholder = placeholder ?? validator?.getPlaceholder() ?? type
function initValueAndDenom() {
if (unit && value.data) {
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 ?? "")
}
function initValueAndDenom() {
if (unit && value.data) {
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 ?? "")
}
}
initValueAndDenom()
$: {
// The type changed -> reset some values
validator = Validators.get(type ?? "string")
_placeholder = placeholder ?? validator?.getPlaceholder() ?? type
feedback = feedback?.setData(validator?.getFeedback(_value.data, getCountry))
initValueAndDenom()
}
$: {
// The type changed -> reset some values
validator = Validators.get(type ?? "string")
_placeholder = placeholder ?? validator?.getPlaceholder() ?? type
feedback = feedback?.setData(validator?.getFeedback(_value.data, getCountry));
initValueAndDenom()
function setValues() {
// Update the value stores
const v = _value.data
if (!validator.isValid(v, getCountry) || v === "") {
value.setData(undefined)
feedback?.setData(validator.getFeedback(v, getCountry))
return
}
function setValues() {
// Update the value stores
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 ?? ""));
if (unit && isNaN(Number(v))) {
value.setData(undefined)
return
}
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");
}
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>
{#if validator.textArea}
<textarea class="w-full" bind:value={$_value} inputmode={validator.inputmode ?? "text"}
placeholder={_placeholder}></textarea>
{:else }
<textarea
class="w-full"
bind:value={$_value}
inputmode={validator.inputmode ?? "text"}
placeholder={_placeholder}
/>
{:else}
<span class="inline-flex">
<input bind:this={htmlElem} bind:value={$_value} class="w-full" inputmode={validator.inputmode ?? "text"}
placeholder={_placeholder}>
{#if !$isValid}
<ExclamationIcon class="h-6 w-6 -ml-6"></ExclamationIcon>
<input
bind:this={htmlElem}
bind:value={$_value}
class="w-full"
inputmode={validator.inputmode ?? "text"}
placeholder={_placeholder}
/>
{#if !$isValid}
<ExclamationIcon class="h-6 w-6 -ml-6" />
{/if}
{#if unit !== undefined}
<UnitInput {unit} {selectedUnit} textValue={_value} upstreamValue={value}/>
<UnitInput {unit} {selectedUnit} textValue={_value} upstreamValue={value} />
{/if}
</span>
{/if}

View file

@ -48,7 +48,7 @@ export abstract class Validator {
* Returns 'undefined' if the element is valid
*/
public getFeedback(s: string, _?: () => string): Translation | undefined {
if(this.isValid(s)){
if (this.isValid(s)) {
return undefined
}
const tr = Translations.t.validation[this.name]
@ -57,7 +57,7 @@ export abstract class Validator {
}
}
public getPlaceholder(){
public getPlaceholder() {
return Translations.t.validation[this.name].description
}

View file

@ -1,7 +1,7 @@
import {Translation} from "../../i18n/Translation.js"
import { Translation } from "../../i18n/Translation.js"
import Translations from "../../i18n/Translations.js"
import * as emailValidatorLibrary from "email-validator"
import {Validator} from "../Validator"
import { Validator } from "../Validator"
export default class EmailValidator extends Validator {
constructor() {

View file

@ -1,24 +1,23 @@
import {parsePhoneNumberFromString} from "libphonenumber-js"
import {Validator} from "../Validator"
import {Translation} from "../../i18n/Translation";
import Translations from "../../i18n/Translations";
import { parsePhoneNumberFromString } from "libphonenumber-js"
import { Validator } from "../Validator"
import { Translation } from "../../i18n/Translation"
import Translations from "../../i18n/Translations"
export default class PhoneValidator extends Validator {
constructor() {
super("phone", "A phone number", "tel")
}
getFeedback(s: string, requestCountry?: () => string): Translation {
if(this.isValid(s, requestCountry)){
if (this.isValid(s, requestCountry)) {
return undefined
}
const tr = Translations.t.validation.phone
const generic = tr.feedback
if(requestCountry){
const country = requestCountry()
if(country){
return tr.feedbackCountry.Subs({country})
if (requestCountry) {
const country = requestCountry()
if (country) {
return tr.feedbackCountry.Subs({ country })
}
}
@ -44,7 +43,7 @@ export default class PhoneValidator extends Validator {
str = str.substring("tel:".length)
}
let countryCode = undefined
if(country){
if (country) {
countryCode = country()
}
return parsePhoneNumberFromString(

View file

@ -2,6 +2,11 @@ import { Validator } from "../Validator"
export default class TextValidator extends Validator {
constructor() {
super("text", "A longer piece of text. Uses an textArea instead of a textField", "text", true)
super(
"text",
"A longer piece of text. Uses an textArea instead of a textField",
"text",
true
)
}
}