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

@ -1,17 +1,20 @@
<script lang="ts">
/**
* Wrapper around 'subtleButton' with an arrow pointing to the right
* See also: NextButton
*/
import SubtleButton from "./SubtleButton.svelte";
import {ChevronLeftIcon} from "@rgossiaux/svelte-heroicons/solid";
import {createEventDispatcher} from "svelte";
/**
* Wrapper around 'subtleButton' with an arrow pointing to the right
* See also: NextButton
*/
import SubtleButton from "./SubtleButton.svelte"
import { ChevronLeftIcon } from "@rgossiaux/svelte-heroicons/solid"
import { createEventDispatcher } from "svelte"
const dispatch = createEventDispatcher<{ click }>()
export let clss = ""
const dispatch = createEventDispatcher<{ click }>()
export let clss = ""
</script>
<SubtleButton on:click={() => dispatch("click")} options={{extraClasses:clss+ " flex items-center"}}>
<ChevronLeftIcon class="w-12 h-12" slot="image"/>
<slot slot="message"/>
<SubtleButton
on:click={() => dispatch("click")}
options={{ extraClasses: clss + " flex items-center" }}
>
<ChevronLeftIcon class="w-12 h-12" slot="image" />
<slot slot="message" />
</SubtleButton>

View file

@ -1,13 +1,12 @@
<script lang="ts">
import { UIEventSource } from "../../Logic/UIEventSource.js";
import { UIEventSource } from "../../Logic/UIEventSource.js"
/**
* For some stupid reason, it is very hard to bind inputs
*/
export let selected: UIEventSource<boolean>;
let _c: boolean = selected.data ?? true;
export let selected: UIEventSource<boolean>
let _c: boolean = selected.data ?? true
$: selected.setData(_c)
</script>
<input type="checkbox" bind:checked={_c} />

View file

@ -3,84 +3,82 @@
* This overlay element will regularly show a hand that swipes over the underlying element.
* This element will hide as soon as the Store 'hideSignal' receives a change (which is not undefined)
*/
import { Store } from "../../Logic/UIEventSource";
import { onDestroy } from "svelte";
import { Store } from "../../Logic/UIEventSource"
import { onDestroy } from "svelte"
let mainElem: HTMLElement;
export let hideSignal: Store<any>;
function hide(){
mainElem.style.visibility = "hidden";
let mainElem: HTMLElement
export let hideSignal: Store<any>
function hide() {
mainElem.style.visibility = "hidden"
}
if (hideSignal) {
onDestroy(hideSignal.addCallbackD(() => {
console.log("Received hide signal")
hide()
return true;
}));
onDestroy(
hideSignal.addCallbackD(() => {
console.log("Received hide signal")
hide()
return true
})
)
}
$: {
mainElem?.addEventListener("click",_ => hide())
mainElem?.addEventListener("touchstart",_ => hide())
}
</script>
$: {
mainElem?.addEventListener("click", (_) => hide())
mainElem?.addEventListener("touchstart", (_) => hide())
}
</script>
<div bind:this={mainElem} class="absolute bottom-0 right-0 w-full h-full">
<div id="hand-container" class="pointer-events-none">
<img src="./assets/svg/hand.svg"/>
<img src="./assets/svg/hand.svg" />
</div>
</div>
<style>
@keyframes hand-drag-animation {
/* This is the animation on the little extra hand on the location input. If fades in, invites the user to interact/drag the map */
0% {
opacity: 0;
transform: rotate(-30deg);
}
6% {
opacity: 1;
transform: rotate(-30deg);
}
12% {
opacity: 1;
transform: rotate(-45deg);
}
24% {
opacity: 1;
transform: rotate(-00deg);
}
30% {
opacity: 1;
transform: rotate(-30deg);
}
36% {
opacity: 0;
transform: rotate(-30deg);
}
100% {
opacity: 0;
transform: rotate(-30deg);
}
@keyframes hand-drag-animation {
/* This is the animation on the little extra hand on the location input. If fades in, invites the user to interact/drag the map */
0% {
opacity: 0;
transform: rotate(-30deg);
}
6% {
opacity: 1;
transform: rotate(-30deg);
}
#hand-container {
position: absolute;
width: 2rem;
left: calc(50% + 4rem);
top: calc(50%);
opacity: 0.7;
animation: hand-drag-animation 4s ease-in-out infinite;
transform-origin: 50% 125%;
12% {
opacity: 1;
transform: rotate(-45deg);
}
24% {
opacity: 1;
transform: rotate(-00deg);
}
30% {
opacity: 1;
transform: rotate(-30deg);
}
36% {
opacity: 0;
transform: rotate(-30deg);
}
100% {
opacity: 0;
transform: rotate(-30deg);
}
}
#hand-container {
position: absolute;
width: 2rem;
left: calc(50% + 4rem);
top: calc(50%);
opacity: 0.7;
animation: hand-drag-animation 4s ease-in-out infinite;
transform-origin: 50% 125%;
}
</style>

View file

@ -1,15 +1,14 @@
<script lang="ts">
import { UIEventSource } from "../../Logic/UIEventSource.js";
import { UIEventSource } from "../../Logic/UIEventSource.js"
/**
* For some stupid reason, it is very hard to bind inputs
*/
export let value: UIEventSource<number>;
let i: number = value.data;
export let value: UIEventSource<number>
let i: number = value.data
$: value.setData(i)
</script>
<select bind:value={i} >
<slot></slot>
<select bind:value={i}>
<slot />
</select>

View file

@ -1,31 +1,36 @@
<script lang="ts">
import {createEventDispatcher} from "svelte";
import {XCircleIcon} from "@rgossiaux/svelte-heroicons/solid";
import { createEventDispatcher } from "svelte"
import { XCircleIcon } from "@rgossiaux/svelte-heroicons/solid"
/**
* The slotted element will be shown on top, with a lower-opacity border
*/
const dispatch = createEventDispatcher<{ close }>();
/**
* The slotted element will be shown on top, with a lower-opacity border
*/
const dispatch = createEventDispatcher<{ close }>()
</script>
<div class="absolute top-0 right-0 w-screen h-screen p-4 md:p-6" style="background-color: #00000088">
<div class="content normal-background">
<div class="rounded-xl h-full">
<slot></slot>
</div>
<slot name="close-button">
<!-- The close button is placed _after_ the default slot in order to always paint it on top -->
<div class="w-8 h-8 absolute right-10 top-10 cursor-pointer" on:click={() => dispatch("close")}>
<XCircleIcon/>
</div>
</slot>
<div
class="absolute top-0 right-0 w-screen h-screen p-4 md:p-6"
style="background-color: #00000088"
>
<div class="content normal-background">
<div class="rounded-xl h-full">
<slot />
</div>
<slot name="close-button">
<!-- The close button is placed _after_ the default slot in order to always paint it on top -->
<div
class="w-8 h-8 absolute right-10 top-10 cursor-pointer"
on:click={() => dispatch("close")}
>
<XCircleIcon />
</div>
</slot>
</div>
</div>
<style>
.content {
height: calc( 100vh - 2rem );
height: calc(100vh - 2rem);
border-radius: 0.5rem;
overflow-x: auto;
box-shadow: 0 0 1rem #00000088;

View file

@ -3,11 +3,11 @@
* Given an HTML string, properly shows this
*/
export let src: string;
let htmlElem: HTMLElement;
export let src: string
let htmlElem: HTMLElement
$: {
if (htmlElem) {
htmlElem.innerHTML = src;
htmlElem.innerHTML = src
}
}
@ -15,6 +15,5 @@
</script>
{#if src !== undefined}
<span bind:this={htmlElem} class={clss}></span>
<span bind:this={htmlElem} class={clss} />
{/if}

View file

@ -1,23 +1,24 @@
<script lang="ts">
import { UIEventSource } from "../../Logic/UIEventSource";
import { onDestroy } from "svelte";
import { UIEventSource } from "../../Logic/UIEventSource"
import { onDestroy } from "svelte"
/**
* For some stupid reason, it is very hard to let {#if} work together with UIEventSources, so we wrap then here
*/
export let condition: UIEventSource<boolean>;
let _c = condition.data;
onDestroy(condition.addCallback(c => {
/* Do _not_ abbreviate this as `.addCallback(c => _c = c)`. This is the same as writing `.addCallback(c => {return _c = c})`,
export let condition: UIEventSource<boolean>
let _c = condition.data
onDestroy(
condition.addCallback((c) => {
/* Do _not_ abbreviate this as `.addCallback(c => _c = c)`. This is the same as writing `.addCallback(c => {return _c = c})`,
which will _unregister_ the callback if `c = true`! */
_c = c;
return false
}))
_c = c
return false
})
)
</script>
{#if _c}
<slot></slot>
{:else}
<slot name="else"></slot>
<slot />
{:else}
<slot name="else" />
{/if}

View file

@ -1,33 +1,34 @@
<script lang="ts">
import {UIEventSource} from "../../Logic/UIEventSource";
import {onDestroy} from "svelte";
import { UIEventSource } from "../../Logic/UIEventSource"
import { onDestroy } from "svelte"
/**
* Functions as 'If', but uses 'display:hidden' instead.
*/
export let condition: UIEventSource<boolean>;
let _c = condition.data;
let hasBeenShownPositive = false
let hasBeenShownNegative = false
onDestroy(condition.addCallbackAndRun(c => {
/* Do _not_ abbreviate this as `.addCallback(c => _c = c)`. This is the same as writing `.addCallback(c => {return _c = c})`,
/**
* Functions as 'If', but uses 'display:hidden' instead.
*/
export let condition: UIEventSource<boolean>
let _c = condition.data
let hasBeenShownPositive = false
let hasBeenShownNegative = false
onDestroy(
condition.addCallbackAndRun((c) => {
/* Do _not_ abbreviate this as `.addCallback(c => _c = c)`. This is the same as writing `.addCallback(c => {return _c = c})`,
which will _unregister_ the callback if `c = true`! */
hasBeenShownPositive = hasBeenShownPositive || c
hasBeenShownNegative = hasBeenShownNegative || !c
_c = c;
return false
}))
hasBeenShownPositive = hasBeenShownPositive || c
hasBeenShownNegative = hasBeenShownNegative || !c
_c = c
return false
})
)
</script>
{#if hasBeenShownPositive}
<span class={_c ? "" : "hidden"}>
<slot/>
</span>
<span class={_c ? "" : "hidden"}>
<slot />
</span>
{/if}
{#if hasBeenShownNegative}
<span class={_c ? "hidden" : ""}>
<slot name="else"/>
</span>
<span class={_c ? "hidden" : ""}>
<slot name="else" />
</span>
{/if}

View file

@ -1,18 +1,20 @@
<script lang="ts">
import { UIEventSource } from "../../Logic/UIEventSource";
import { onDestroy } from "svelte";
import { UIEventSource } from "../../Logic/UIEventSource"
import { onDestroy } from "svelte"
/**
* For some stupid reason, it is very hard to let {#if} work together with UIEventSources, so we wrap then here
*/
export let condition: UIEventSource<boolean>;
let _c = !condition.data;
onDestroy(condition.addCallback(c => {
_c = !c;
return false
}))
export let condition: UIEventSource<boolean>
let _c = !condition.data
onDestroy(
condition.addCallback((c) => {
_c = !c
return false
})
)
</script>
{#if _c}
<slot></slot>
<slot />
{/if}

View file

@ -1,13 +1,13 @@
<script>
import ToSvelte from "./ToSvelte.svelte";
import Svg from "../../Svg";
import ToSvelte from "./ToSvelte.svelte"
import Svg from "../../Svg"
</script>
<div class="pl-2 p-1 flex">
<div class="animate-spin self-center w-6 h-6 min-w-6">
<ToSvelte construct={Svg.loading_svg()}></ToSvelte>
<ToSvelte construct={Svg.loading_svg()} />
</div>
<div class="ml-2">
<slot></slot>
<slot />
</div>
</div>

View file

@ -1,17 +1,17 @@
<script lang="ts">
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
import Translations from "../i18n/Translations.js";
import Tr from "./Tr.svelte";
import ToSvelte from "./ToSvelte.svelte";
import Svg from "../../Svg";
import { OsmConnection } from "../../Logic/Osm/OsmConnection"
import Translations from "../i18n/Translations.js"
import Tr from "./Tr.svelte"
import ToSvelte from "./ToSvelte.svelte"
import Svg from "../../Svg"
export let osmConnection: OsmConnection
export let clss = ""
export let osmConnection: OsmConnection
export let clss = ""
</script>
<button class={clss} on:click={() => osmConnection.AttemptLogin()}>
<ToSvelte construct={Svg.login_svg().SetClass("w-12 m-1")}/>
<slot name="message">
<Tr t={Translations.t.general.loginWithOpenStreetMap}/>
</slot>
<ToSvelte construct={Svg.login_svg().SetClass("w-12 m-1")} />
<slot name="message">
<Tr t={Translations.t.general.loginWithOpenStreetMap} />
</slot>
</button>

View file

@ -1,47 +1,45 @@
<script lang="ts">
import Loading from "./Loading.svelte";
import type { OsmServiceState } from "../../Logic/Osm/OsmConnection";
import { Translation } from "../i18n/Translation";
import Translations from "../i18n/Translations";
import Tr from "./Tr.svelte";
import {OsmConnection} from "../../Logic/Osm/OsmConnection";
import {ImmutableStore, UIEventSource} from "../../Logic/UIEventSource";
import Loading from "./Loading.svelte"
import type { OsmServiceState } from "../../Logic/Osm/OsmConnection"
import { Translation } from "../i18n/Translation"
import Translations from "../i18n/Translations"
import Tr from "./Tr.svelte"
import { OsmConnection } from "../../Logic/Osm/OsmConnection"
import { ImmutableStore, UIEventSource } from "../../Logic/UIEventSource"
export let state: {osmConnection: OsmConnection, featureSwitches?: { featureSwitchUserbadge?: UIEventSource<boolean>}};
export let state: {
osmConnection: OsmConnection
featureSwitches?: { featureSwitchUserbadge?: UIEventSource<boolean> }
}
/**
* If set, 'loading' will act as if we are already logged in.
*/
export let ignoreLoading: boolean = false
let loadingStatus = state.osmConnection.loadingStatus;
let badge = state.featureSwitches?.featureSwitchUserbadge ?? new ImmutableStore(true);
const t = Translations.t.general;
let loadingStatus = state.osmConnection.loadingStatus
let badge = state.featureSwitches?.featureSwitchUserbadge ?? new ImmutableStore(true)
const t = Translations.t.general
const offlineModes: Partial<Record<OsmServiceState, Translation>> = {
offline: t.loginFailedOfflineMode,
unreachable: t.loginFailedUnreachableMode,
unknown: t.loginFailedUnreachableMode,
readonly: t.loginFailedReadonlyMode
};
const apiState = state.osmConnection.apiIsOnline;
readonly: t.loginFailedReadonlyMode,
}
const apiState = state.osmConnection.apiIsOnline
</script>
{#if $badge}
{#if !ignoreLoading && $loadingStatus === "loading"}
<slot name="loading">
<Loading></Loading>
<Loading />
</slot>
{:else if $loadingStatus === "error"}
<div class="flex items-center alert max-w-64">
<img src="./assets/svg/invalid.svg" class="w-8 h-8 m-2 shrink-0">
<img src="./assets/svg/invalid.svg" class="w-8 h-8 m-2 shrink-0" />
<Tr t={offlineModes[$apiState]} />
</div>
{:else if $loadingStatus === "logged-in"}
<slot></slot>
<slot />
{:else if $loadingStatus === "not-attempted"}
<slot name="not-logged-in">
</slot>
<slot name="not-logged-in" />
{/if}
{/if}

View file

@ -1,14 +1,16 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
import { createEventDispatcher } from "svelte"
/**
* A round button with an icon and possible a small text, which hovers above the map
*/
const dispatch = createEventDispatcher()
const dispatch = createEventDispatcher()
export let cls = ""
</script>
<button on:click={e => dispatch("click", e)} class={"rounded-full h-fit w-fit m-0.5 md:m-1 p-0.5 sm:p-1 pointer-events-auto "+cls} >
<slot/>
<button
on:click={(e) => dispatch("click", e)}
class={"rounded-full h-fit w-fit m-0.5 md:m-1 p-0.5 sm:p-1 pointer-events-auto " + cls}
>
<slot />
</button>

View file

@ -1,20 +1,26 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
import { XCircleIcon } from "@rgossiaux/svelte-heroicons/solid";
import { createEventDispatcher } from "svelte"
import { XCircleIcon } from "@rgossiaux/svelte-heroicons/solid"
/**
* The slotted element will be shown on the right side
*/
const dispatch = createEventDispatcher<{ close }>();
const dispatch = createEventDispatcher<{ close }>()
</script>
<div class="absolute top-0 right-0 h-screen overflow-auto w-full md:w-6/12 lg:w-5/12 xl:w-4/12 drop-shadow-2xl" style="max-width: 100vw; max-height: 100vh">
<div
class="absolute top-0 right-0 h-screen overflow-auto w-full md:w-6/12 lg:w-5/12 xl:w-4/12 drop-shadow-2xl"
style="max-width: 100vw; max-height: 100vh"
>
<div class="flex flex-col m-0 normal-background">
<slot name="close-button">
<div class="w-8 h-8 absolute right-10 top-10 cursor-pointer" on:click={() => dispatch("close")}>
<div
class="w-8 h-8 absolute right-10 top-10 cursor-pointer"
on:click={() => dispatch("close")}
>
<XCircleIcon />
</div>
</slot>
<slot></slot>
<slot />
</div>
</div>

View file

@ -1,21 +1,24 @@
<script lang="ts">
/**
* Wrapper around 'subtleButton' with an arrow pointing to the right
* See also: BackButton
*/
import SubtleButton from "./SubtleButton.svelte";
import {ChevronRightIcon} from "@rgossiaux/svelte-heroicons/solid";
import {createEventDispatcher} from "svelte";
/**
* Wrapper around 'subtleButton' with an arrow pointing to the right
* See also: BackButton
*/
import SubtleButton from "./SubtleButton.svelte"
import { ChevronRightIcon } from "@rgossiaux/svelte-heroicons/solid"
import { createEventDispatcher } from "svelte"
const dispatch = createEventDispatcher<{ click }>()
export let clss : string= ""
const dispatch = createEventDispatcher<{ click }>()
export let clss: string = ""
</script>
<SubtleButton on:click={() => dispatch("click")} options={{extraClasses: clss+" flex items-center"}}>
<slot name="image" slot="image"/>
<div class="w-full flex justify-between items-center" slot="message">
<slot/>
<ChevronRightIcon class="w-12 h-12"/>
</div>
<SubtleButton
on:click={() => dispatch("click")}
options={{ extraClasses: clss + " flex items-center" }}
>
<slot name="image" slot="image" />
<div class="w-full flex justify-between items-center" slot="message">
<slot />
<ChevronRightIcon class="w-12 h-12" />
</div>
</SubtleButton>

View file

@ -1,33 +1,30 @@
<script lang="ts">
import ToSvelte from "./ToSvelte.svelte";
import Svg from "../../Svg";
import ToSvelte from "./ToSvelte.svelte"
import Svg from "../../Svg"
export let generateShareData: () => {
export let generateShareData: () => {
text: string
title: string
url: string
}
function share(){
}
function share() {
if (!navigator.share) {
console.log("web share not supported")
return;
console.log("web share not supported")
return
}
navigator
.share(generateShareData())
.then(() => {
console.log("Thanks for sharing!")
})
.catch((err) => {
console.log(`Couldn't share because of`, err.message)
})
}
.share(generateShareData())
.then(() => {
console.log("Thanks for sharing!")
})
.catch((err) => {
console.log(`Couldn't share because of`, err.message)
})
}
</script>
<button on:click={share} class="secondary w-8 h-8 m-0 p-0">
<slot name="content">
<ToSvelte construct={Svg.share_svg().SetClass("w-7 h-7 p-1")}/>
</slot>
<slot name="content">
<ToSvelte construct={Svg.share_svg().SetClass("w-7 h-7 p-1")} />
</slot>
</button>

View file

@ -1,7 +1,7 @@
<script lang="ts">
import {createEventDispatcher} from "svelte";
import BaseUIElement from "../BaseUIElement";
import Img from "./Img";
import { createEventDispatcher } from "svelte"
import BaseUIElement from "../BaseUIElement"
import Img from "./Img"
export let imageUrl: string | BaseUIElement = undefined
export let message: string | BaseUIElement = undefined
@ -10,22 +10,22 @@
extraClasses?: string
} = {}
let imgClasses = "block justify-center shrink-0 mr-4 " + (options?.imgSize ?? "h-11 w-11");
const dispatch = createEventDispatcher<{click}>()
let imgClasses = "block justify-center shrink-0 mr-4 " + (options?.imgSize ?? "h-11 w-11")
const dispatch = createEventDispatcher<{ click }>()
</script>
<button
class={(options.extraClasses??"") + ' secondary no-image-background'}
class={(options.extraClasses ?? "") + " secondary no-image-background"}
target={options?.newTab ? "_blank" : ""}
on:click={(e) => dispatch("click", e)}
>
<slot name="image">
{#if imageUrl !== undefined}
{#if typeof imageUrl === "string"}
<Img src={imageUrl} class={imgClasses}></Img>
<Img src={imageUrl} class={imgClasses} />
{/if}
{/if}
</slot>
<slot name="message"/>
<slot name="message" />
</button>

View file

@ -5,10 +5,10 @@ import { VariableUiElement } from "./VariableUIElement"
import Lazy from "./Lazy"
import Loading from "./Loading"
import SvelteUIElement from "./SvelteUIElement"
import SubtleLink from "./SubtleLink.svelte";
import Translations from "../i18n/Translations";
import Combine from "./Combine";
import Img from "./Img";
import SubtleLink from "./SubtleLink.svelte"
import Translations from "../i18n/Translations"
import Combine from "./Combine"
import Img from "./Img"
/**
* @deprecated
@ -40,26 +40,28 @@ export class SubtleButton extends UIElement {
}
protected InnerRender(): string | BaseUIElement {
if(this.options.url !== undefined){
return new SvelteUIElement(SubtleLink, {href: this.options.url, newTab: this.options.newTab})
if (this.options.url !== undefined) {
return new SvelteUIElement(SubtleLink, {
href: this.options.url,
newTab: this.options.newTab,
})
}
const classes = "button";
const message = Translations.W(this.message)?.SetClass("block overflow-ellipsis no-images flex-shrink");
let img;
const imgClasses = "block justify-center flex-none mr-4 " + (this.options?.imgSize ?? "h-11 w-11")
const classes = "button"
const message = Translations.W(this.message)?.SetClass(
"block overflow-ellipsis no-images flex-shrink"
)
let img
const imgClasses =
"block justify-center flex-none mr-4 " + (this.options?.imgSize ?? "h-11 w-11")
if ((this.imageUrl ?? "") === "") {
img = undefined;
} else if (typeof (this.imageUrl) === "string") {
img = undefined
} else if (typeof this.imageUrl === "string") {
img = new Img(this.imageUrl)?.SetClass(imgClasses)
} else {
img = this.imageUrl?.SetClass(imgClasses);
img = this.imageUrl?.SetClass(imgClasses)
}
const button = new Combine([
img,
message
]).SetClass("flex items-center group w-full")
const button = new Combine([img, message]).SetClass("flex items-center group w-full")
this.SetClass(classes)
return button

View file

@ -1,7 +1,7 @@
<script lang="ts">
import {onMount} from "svelte";
import BaseUIElement from "../BaseUIElement";
import Img from "./Img";
import { onMount } from "svelte"
import BaseUIElement from "../BaseUIElement"
import Img from "./Img"
export let imageUrl: string | BaseUIElement = undefined
export let href: string
@ -10,10 +10,9 @@
imgSize?: string
// extraClasses?: string
} = {}
let imgElem: HTMLElement;
let imgClasses = "block justify-center shrink-0 mr-4 " + (options?.imgSize ?? "h-11 w-11");
let imgElem: HTMLElement
let imgClasses = "block justify-center shrink-0 mr-4 " + (options?.imgSize ?? "h-11 w-11")
onMount(() => {
// Image
@ -27,24 +26,23 @@
}
if (img) imgElem.replaceWith(img.ConstructElement())
}
})
</script>
<a
class={(options.extraClasses??"") + ' button text-ellipsis'}
class={(options.extraClasses ?? "") + " button text-ellipsis"}
{href}
target={(newTab ? "_blank" : undefined) }
target={newTab ? "_blank" : undefined}
>
<slot name="image">
{#if imageUrl !== undefined}
{#if typeof imageUrl === "string"}
<Img src={imageUrl} class={imgClasses}></Img>
{:else }
<Img src={imageUrl} class={imgClasses} />
{:else}
<template bind:this={imgElem} />
{/if}
{/if}
</slot>
<slot/>
<slot />
</a>

View file

@ -1,121 +1,126 @@
<script lang="ts">
/**
* Thin wrapper around 'TabGroup' which binds the state
*/
/**
* Thin wrapper around 'TabGroup' which binds the state
*/
import {Tab, TabGroup, TabList, TabPanel, TabPanels} from "@rgossiaux/svelte-headlessui";
import {UIEventSource} from "../../Logic/UIEventSource";
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from "@rgossiaux/svelte-headlessui"
import { UIEventSource } from "../../Logic/UIEventSource"
export let tab: UIEventSource<number>;
let tabElements: HTMLElement[] = [];
$: tabElements[$tab]?.click();
$: {
if (tabElements[tab.data]) {
window.setTimeout(() => tabElements[tab.data].click(), 50)
}
export let tab: UIEventSource<number>
let tabElements: HTMLElement[] = []
$: tabElements[$tab]?.click()
$: {
if (tabElements[tab.data]) {
window.setTimeout(() => tabElements[tab.data].click(), 50)
}
}
</script>
<div class="tabbedgroup w-full h-full">
<TabGroup class="h-full w-full flex flex-col" defaultIndex={1}
on:change={(e) =>{if(e.detail >= 0){tab.setData( e.detail); }} }>
<div class="interactive flex items-center justify-between sticky top-0">
<TabList class="flex flex-wrap">
{#if $$slots.title1}
<Tab class={({selected}) => "tab "+(selected ? "primary" : "")}>
<div bind:this={tabElements[0]} class="flex">
<slot name="title0">
Tab 0
</slot>
</div>
</Tab>
{/if}
{#if $$slots.title1}
<Tab class={({selected}) => "tab "+(selected ? "primary" : "")}>
<div bind:this={tabElements[1]} class="flex">
<slot name="title1"/>
</div>
</Tab>
{/if}
{#if $$slots.title2}
<Tab class={({selected}) => "tab "+(selected ? "primary" : "")}>
<div bind:this={tabElements[2]} class="flex">
<slot name="title2"/>
</div>
</Tab>
{/if}
{#if $$slots.title3}
<Tab class={({selected}) => "tab "+(selected ? "primary" : "")}>
<div bind:this={tabElements[3]} class="flex">
<slot name="title3"/>
</div>
</Tab>
{/if}
{#if $$slots.title4}
<Tab class={({selected}) => "tab "+(selected ? "primary" : "")}>
<div bind:this={tabElements[4]} class="flex">
<slot name="title4"/>
</div>
</Tab>
{/if}
</TabList>
<slot name="post-tablist"/>
</div>
<div class="overflow-y-auto normal-background">
<TabPanels defaultIndex={$tab}>
<TabPanel>
<slot name="content0">
<div>Empty</div>
</slot>
</TabPanel>
<TabPanel>
<slot name="content1"/>
</TabPanel>
<TabPanel>
<slot name="content2"/>
</TabPanel>
<TabPanel>
<slot name="content3"/>
</TabPanel>
<TabPanel>
<slot name="content4"/>
</TabPanel>
</TabPanels>
</div>
</TabGroup>
<TabGroup
class="h-full w-full flex flex-col"
defaultIndex={1}
on:change={(e) => {
if (e.detail >= 0) {
tab.setData(e.detail)
}
}}
>
<div class="interactive flex items-center justify-between sticky top-0">
<TabList class="flex flex-wrap">
{#if $$slots.title1}
<Tab class={({ selected }) => "tab " + (selected ? "primary" : "")}>
<div bind:this={tabElements[0]} class="flex">
<slot name="title0">Tab 0</slot>
</div>
</Tab>
{/if}
{#if $$slots.title1}
<Tab class={({ selected }) => "tab " + (selected ? "primary" : "")}>
<div bind:this={tabElements[1]} class="flex">
<slot name="title1" />
</div>
</Tab>
{/if}
{#if $$slots.title2}
<Tab class={({ selected }) => "tab " + (selected ? "primary" : "")}>
<div bind:this={tabElements[2]} class="flex">
<slot name="title2" />
</div>
</Tab>
{/if}
{#if $$slots.title3}
<Tab class={({ selected }) => "tab " + (selected ? "primary" : "")}>
<div bind:this={tabElements[3]} class="flex">
<slot name="title3" />
</div>
</Tab>
{/if}
{#if $$slots.title4}
<Tab class={({ selected }) => "tab " + (selected ? "primary" : "")}>
<div bind:this={tabElements[4]} class="flex">
<slot name="title4" />
</div>
</Tab>
{/if}
</TabList>
<slot name="post-tablist" />
</div>
<div class="overflow-y-auto normal-background">
<TabPanels defaultIndex={$tab}>
<TabPanel>
<slot name="content0">
<div>Empty</div>
</slot>
</TabPanel>
<TabPanel>
<slot name="content1" />
</TabPanel>
<TabPanel>
<slot name="content2" />
</TabPanel>
<TabPanel>
<slot name="content3" />
</TabPanel>
<TabPanel>
<slot name="content4" />
</TabPanel>
</TabPanels>
</div>
</TabGroup>
</div>
<style>
.tabbedgroup {
max-height: 100vh;
height: 100%;
}
.tabbedgroup {
max-height: 100vh;
height: 100%;
}
:global(.tab) {
margin: 0.25rem;
padding: 0.25rem;
padding-left: 0.75rem;
padding-right: 0.75rem;
border-radius: 1rem;
}
:global(.tab) {
margin: 0.25rem;
padding: 0.25rem;
padding-left: 0.75rem;
padding-right: 0.75rem;
border-radius: 1rem;
}
:global(.tab .flex) {
align-items: center;
gap: 0.25rem;
}
:global(.tab .flex) {
align-items: center;
gap: 0.25rem;
}
:global(.tab span|div) {
align-items: center;
gap: 0.25rem;
display: flex;
}
:global(.tab span|div) {
align-items: center;
gap: 0.25rem;
display: flex;
}
:global(.tab-selected svg) {
fill: var(--catch-detail-color-contrast);
}
:global(.tab-selected svg) {
fill: var(--catch-detail-color-contrast);
}
:global(.tab-unselected) {
background-color: var(--background-color) !important;
color: var(--foreground-color) !important;
}
:global(.tab-unselected) {
background-color: var(--background-color) !important;
color: var(--foreground-color) !important;
}
</style>

View file

@ -78,7 +78,7 @@ export default class Table extends BaseUIElement {
for (let j = 0; j < row.length; j++) {
try {
let elem = row[j]
if(elem?.ConstructElement === undefined){
if (elem?.ConstructElement === undefined) {
continue
}
const htmlElem = elem?.ConstructElement()

View file

@ -1,23 +1,21 @@
<script lang="ts">
import BaseUIElement from "../BaseUIElement.js";
import { onDestroy, onMount } from "svelte";
import BaseUIElement from "../BaseUIElement.js"
import { onDestroy, onMount } from "svelte"
export let construct: BaseUIElement | (() => BaseUIElement);
let elem: HTMLElement;
let html: HTMLElement;
export let construct: BaseUIElement | (() => BaseUIElement)
let elem: HTMLElement
let html: HTMLElement
onMount(() => {
const uiElem = typeof construct === "function"
? construct() : construct;
html =uiElem?.ConstructElement();
const uiElem = typeof construct === "function" ? construct() : construct
html = uiElem?.ConstructElement()
if (html !== undefined) {
elem.replaceWith(html);
elem.replaceWith(html)
}
});
})
onDestroy(() => {
html?.remove();
});
html?.remove()
})
</script>
<span bind:this={elem} />

View file

@ -2,36 +2,37 @@
/**
* Properly renders a translation
*/
import { Translation } from "../i18n/Translation";
import { onDestroy } from "svelte";
import Locale from "../i18n/Locale";
import { Utils } from "../../Utils";
import FromHtml from "./FromHtml.svelte";
import WeblateLink from "./WeblateLink.svelte";
import { Translation } from "../i18n/Translation"
import { onDestroy } from "svelte"
import Locale from "../i18n/Locale"
import { Utils } from "../../Utils"
import FromHtml from "./FromHtml.svelte"
import WeblateLink from "./WeblateLink.svelte"
export let t: Translation;
export let t: Translation
export let cls: string = ""
export let tags: Record<string, string> | undefined = undefined;
export let tags: Record<string, string> | undefined = undefined
// Text for the current language
let txt: string | undefined;
$: onDestroy(Locale.language.addCallbackAndRunD(l => {
const translation = t?.textFor(l);
if (translation === undefined) {
return;
}
if (tags) {
txt = Utils.SubstituteKeys(txt, tags);
} else {
txt = translation;
}
}));
let txt: string | undefined
$: onDestroy(
Locale.language.addCallbackAndRunD((l) => {
const translation = t?.textFor(l)
if (translation === undefined) {
return
}
if (tags) {
txt = Utils.SubstituteKeys(txt, tags)
} else {
txt = translation
}
})
)
</script>
{#if t}
<span class={cls}>
<FromHtml src={txt}></FromHtml>
<WeblateLink context={t.context}></WeblateLink>
<FromHtml src={txt} />
<WeblateLink context={t.context} />
</span>
{/if}

View file

@ -1,25 +1,32 @@
<script lang="ts">
import Locale from "../i18n/Locale";
import LinkToWeblate from "./LinkToWeblate";
import Locale from "../i18n/Locale"
import LinkToWeblate from "./LinkToWeblate"
/**
* Shows a small icon which will open up weblate; a contributor can translate the item for 'context' there
*/
export let context : string
export let context: string
let linkToWeblate = Locale.showLinkToWeblate;
let linkOnMobile = Locale.showLinkOnMobile;
let language = Locale.language;
let linkToWeblate = Locale.showLinkToWeblate
let linkOnMobile = Locale.showLinkOnMobile
let language = Locale.language
</script>
{#if !!context && context.indexOf(":") > 0}
{#if $linkOnMobile}
<a href={LinkToWeblate.hrefToWeblate($language, context)} target="_blank" class="mx-1 weblate-link">
<a
href={LinkToWeblate.hrefToWeblate($language, context)}
target="_blank"
class="mx-1 weblate-link"
>
<img src="./assets/svg/translate.svg" class="font-gray" />
</a>
{:else if $linkToWeblate}
<a href={LinkToWeblate.hrefToWeblate($language, context)} class="weblate-link hidden-on-mobile mx-1" target="_blank">
<a
href={LinkToWeblate.hrefToWeblate($language, context)}
class="weblate-link hidden-on-mobile mx-1"
target="_blank"
>
<img src="./assets/svg/translate.svg" class="font-gray inline-block" />
</a>
{/if}