more typescript type safety tricks
This commit is contained in:
@@ -11,8 +11,8 @@
|
||||
import { loadIcon } from '../icon'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { goto } from '$app/navigation'
|
||||
import { initOutput } from '../../editor/appUtils'
|
||||
import { configurationKeys } from '../../editor/component'
|
||||
import { initConfig, initOutput } from '../../editor/appUtils'
|
||||
import { components, configurationKeys } from '../../editor/component'
|
||||
|
||||
export let id: string
|
||||
export let componentInput: AppInput | undefined
|
||||
@@ -38,32 +38,10 @@
|
||||
|
||||
let runnableComponent: RunnableComponent
|
||||
|
||||
// let labelValue: string
|
||||
// let color: ButtonType.Color
|
||||
// let size: ButtonType.Size
|
||||
// let disabled: boolean | undefined = undefined
|
||||
// let fillContainer: boolean | undefined = undefined
|
||||
// let gotoUrl: string | undefined = undefined
|
||||
// let gotoNewTab: boolean | undefined = undefined
|
||||
|
||||
let isLoading: boolean = false
|
||||
let ownClick: boolean = false
|
||||
|
||||
// let beforeIcon: undefined | string = undefined
|
||||
// let afterIcon: undefined | string = undefined
|
||||
|
||||
let resolvedConfig = {} as {
|
||||
beforeIcon?: string
|
||||
afterIcon?: string
|
||||
label?: string
|
||||
color?: ButtonType.Color
|
||||
size?: ButtonType.Size
|
||||
disabled?: boolean
|
||||
fillContainer?: boolean
|
||||
gotoUrl?: string
|
||||
gotoNewTab?: boolean
|
||||
triggerOnAppLoad?: boolean
|
||||
}
|
||||
let resolvedConfig = initConfig(components['buttoncomponent'].initialData.configuration)
|
||||
|
||||
$: initializing = resolvedConfig?.label == undefined
|
||||
|
||||
@@ -123,11 +101,11 @@
|
||||
ownClick = true
|
||||
|
||||
if (!runnableComponent) {
|
||||
if (resolvedConfig.gotoUrl) {
|
||||
if (resolvedConfig.goto) {
|
||||
if (resolvedConfig.gotoNewTab) {
|
||||
window.open(resolvedConfig.gotoUrl, '_blank')
|
||||
window.open(resolvedConfig.goto, '_blank')
|
||||
} else {
|
||||
goto(resolvedConfig.gotoUrl)
|
||||
goto(resolvedConfig.goto)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -147,7 +125,7 @@
|
||||
{id}
|
||||
{extraQueryParams}
|
||||
autoRefresh={false}
|
||||
goto={resolvedConfig.gotoUrl}
|
||||
goto={resolvedConfig.goto}
|
||||
gotoNewTab={resolvedConfig.gotoNewTab}
|
||||
{render}
|
||||
>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { initConfig } from '../../editor/appUtils'
|
||||
import { components, configurationKeys } from '../../editor/component'
|
||||
import type { staticValues } from '../../editor/componentsPanel/componentStaticValues'
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import { concatCustomCss } from '../../utils'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
import Loader from '../helpers/Loader.svelte'
|
||||
|
||||
type FitOption = (typeof staticValues)['objectFitOptions'][number]
|
||||
|
||||
@@ -20,23 +23,26 @@
|
||||
fill: 'object-fill'
|
||||
}
|
||||
|
||||
let source: string | undefined = undefined
|
||||
let imageFit: FitOption | undefined = undefined
|
||||
let altText: string | undefined = undefined
|
||||
let resolvedConfig = initConfig(components['imagecomponent'].initialData.configuration)
|
||||
|
||||
$: css = concatCustomCss($app.css?.imagecomponent, customCss)
|
||||
</script>
|
||||
|
||||
<InputValue {id} input={configuration.source} bind:value={source} />
|
||||
<InputValue {id} input={configuration.imageFit} bind:value={imageFit} />
|
||||
<InputValue {id} input={configuration.altText} bind:value={altText} />
|
||||
{#each configurationKeys['imagecomponent'] as key (key)}
|
||||
<InputValue {key} {id} input={configuration[key]} bind:value={resolvedConfig[key]} />
|
||||
{/each}
|
||||
|
||||
{#if render}
|
||||
<img
|
||||
on:pointerdown|preventDefault
|
||||
src={source}
|
||||
alt={altText}
|
||||
style={css?.image?.style ?? ''}
|
||||
class={twMerge(`w-full h-full ${fit[imageFit || 'cover']}`, css?.image?.class ?? '')}
|
||||
/>
|
||||
<Loader loading={resolvedConfig.source == undefined}>
|
||||
<img
|
||||
on:pointerdown|preventDefault
|
||||
src={resolvedConfig.source}
|
||||
alt={resolvedConfig.altText}
|
||||
style={css?.image?.style ?? ''}
|
||||
class={twMerge(
|
||||
`w-full h-full ${fit[resolvedConfig.imageFit || 'cover']}`,
|
||||
css?.image?.class ?? ''
|
||||
)}
|
||||
/>
|
||||
</Loader>
|
||||
{/if}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import { fade } from 'svelte/transition'
|
||||
|
||||
export let loading: boolean
|
||||
</script>
|
||||
|
||||
{#if !loading}
|
||||
<slot />
|
||||
{:else}
|
||||
<div class="w-full h-full">
|
||||
<div
|
||||
out:fade|local={{ duration: 50 }}
|
||||
class="absolute inset-0 center-center flex-col bg-white text-gray-600 border"
|
||||
>
|
||||
<Loader2 class="animate-spin" size={16} />
|
||||
<span class="text-xs mt-1">Loading</span>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -34,13 +34,5 @@
|
||||
{#if render}
|
||||
<slot />
|
||||
{:else}
|
||||
<div class="w-full h-full">
|
||||
<div
|
||||
out:fade|local={{ duration: 50 }}
|
||||
class="absolute inset-0 center-center flex-col bg-white text-gray-600 border"
|
||||
>
|
||||
<Loader2 class="animate-spin" size={16} />
|
||||
<span class="text-xs mt-1">Loading</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full h-full" />
|
||||
{/if}
|
||||
|
||||
@@ -21,6 +21,7 @@ import { allItems } from '../utils'
|
||||
import type { Output, World } from '../rx'
|
||||
import gridHelp from '../svelte-grid/utils/helper'
|
||||
import type { FilledItem } from '../svelte-grid/types'
|
||||
import type { EvalAppInput, StaticAppInput } from '../inputType'
|
||||
|
||||
function findGridItemById(
|
||||
root: GridItem[],
|
||||
@@ -366,6 +367,19 @@ export function initOutput<I extends Record<string, any>>(
|
||||
Object.entries(init).map(([key, value]) => [key, world.newOutput(id, key, value)])
|
||||
) as Outputtable<I>
|
||||
}
|
||||
|
||||
export function initConfig<T extends Record<string, StaticAppInput | EvalAppInput>>(
|
||||
r: T
|
||||
): {
|
||||
[Property in keyof T]: T[Property] extends StaticAppInput ? T[Property]['value'] | undefined : any
|
||||
} {
|
||||
return Object.fromEntries(
|
||||
Object.entries(r).map(([key, value]) =>
|
||||
value.type == 'static' ? [key, undefined] : [key, undefined]
|
||||
)
|
||||
) as any
|
||||
}
|
||||
|
||||
export function expandGriditem(
|
||||
grid: GridItem[],
|
||||
gridComponent: GridItem,
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
noBackend={false}
|
||||
/>
|
||||
{#if can_write}
|
||||
<div class="absolute bottom-4 z-20 right-4">
|
||||
<div class="absolute bottom-4 z-50 right-4">
|
||||
<Button
|
||||
size="sm"
|
||||
startIcon={{ icon: faPen }}
|
||||
|
||||
Reference in New Issue
Block a user