mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 00:02:19 +00:00
fix: load lazily the app icons
This commit is contained in:
@@ -70,20 +70,32 @@
|
||||
let beforeIconComponent: any
|
||||
let afterIconComponent: any
|
||||
|
||||
$: resolvedConfig.beforeIcon && handleBeforeIcon()
|
||||
$: resolvedConfig.afterIcon && handleAfterIcon()
|
||||
$: resolvedConfig.beforeIcon && beforeIconComponent && handleBeforeIcon()
|
||||
$: resolvedConfig.afterIcon && afterIconComponent && handleAfterIcon()
|
||||
|
||||
let confirmedCallback: (() => void) | undefined = undefined
|
||||
|
||||
async function handleBeforeIcon() {
|
||||
if (resolvedConfig.beforeIcon) {
|
||||
beforeIconComponent = await loadIcon(resolvedConfig.beforeIcon)
|
||||
beforeIconComponent = await loadIcon(
|
||||
resolvedConfig.beforeIcon,
|
||||
beforeIconComponent,
|
||||
14,
|
||||
undefined,
|
||||
undefined
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleAfterIcon() {
|
||||
if (resolvedConfig.afterIcon) {
|
||||
afterIconComponent = await loadIcon(resolvedConfig.afterIcon)
|
||||
afterIconComponent = await loadIcon(
|
||||
resolvedConfig.afterIcon,
|
||||
afterIconComponent,
|
||||
14,
|
||||
undefined,
|
||||
undefined
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,17 +222,17 @@
|
||||
on:click={handleClick}
|
||||
size={resolvedConfig.size}
|
||||
color={resolvedConfig.color}
|
||||
startIcon={{
|
||||
icon: resolvedConfig.beforeIcon ? beforeIconComponent : undefined
|
||||
}}
|
||||
endIcon={{
|
||||
icon: resolvedConfig.afterIcon ? afterIconComponent : undefined
|
||||
}}
|
||||
{loading}
|
||||
>
|
||||
{#if resolvedConfig.beforeIcon}
|
||||
<div class="min-w-4" bind:this={beforeIconComponent} />
|
||||
{/if}
|
||||
{#if resolvedConfig.label?.toString() && resolvedConfig.label?.toString()?.length > 0}
|
||||
<div>{resolvedConfig.label.toString()}</div>
|
||||
{/if}
|
||||
{#if resolvedConfig.afterIcon}
|
||||
<div class="min-w-4" bind:this={afterIconComponent} />
|
||||
{/if}
|
||||
</Button>
|
||||
{/key}
|
||||
</AlignWrapper>
|
||||
|
||||
@@ -29,10 +29,12 @@
|
||||
|
||||
let iconComponent: any
|
||||
|
||||
$: handleIcon(resolvedConfig.icon)
|
||||
$: handleIcon(resolvedConfig, iconComponent)
|
||||
|
||||
async function handleIcon(i?: string) {
|
||||
iconComponent = i ? await loadIcon(i) : undefined
|
||||
async function handleIcon(conf, comp) {
|
||||
if (conf.icon && comp) {
|
||||
await loadIcon(conf.icon, iconComponent, conf.size, conf.strokeWidth, conf.color)
|
||||
}
|
||||
}
|
||||
|
||||
let css = initCss($app.css?.iconcomponent, customCss)
|
||||
@@ -66,12 +68,9 @@
|
||||
class={twMerge(css?.container?.class, 'wm-icon-container')}
|
||||
style={css?.container?.style ?? ''}
|
||||
>
|
||||
{#if resolvedConfig.icon && iconComponent}
|
||||
<svelte:component
|
||||
this={iconComponent}
|
||||
size={resolvedConfig.size || 24}
|
||||
color={resolvedConfig.color || 'currentColor'}
|
||||
strokeWidth={resolvedConfig.strokeWidth || 2}
|
||||
{#if resolvedConfig.icon}
|
||||
<div
|
||||
bind:this={iconComponent}
|
||||
class={twMerge(css?.icon?.class, 'wm-icon')}
|
||||
style={css?.icon?.style ?? ''}
|
||||
/>
|
||||
|
||||
@@ -6,21 +6,34 @@ function toKebabCase(str: string): string {
|
||||
.toLowerCase()
|
||||
}
|
||||
|
||||
export async function loadIcon(name: string): Promise<any> {
|
||||
let iconComponent: any
|
||||
export async function loadIcon(
|
||||
name: string,
|
||||
parent: HTMLElement,
|
||||
size: number | undefined,
|
||||
strokeWidth: number | undefined,
|
||||
color: string | undefined
|
||||
): Promise<any> {
|
||||
try {
|
||||
if (name) {
|
||||
iconComponent = (
|
||||
await import(
|
||||
`../../../../../node_modules/lucide-svelte/dist/svelte/icons/${toKebabCase(name)}.svelte`
|
||||
)
|
||||
).default
|
||||
return iconComponent
|
||||
await fetch(
|
||||
`https://cdn.jsdelivr.net/npm/lucide-static@0.367.0/icons/${toKebabCase(name)}.svg`
|
||||
)
|
||||
.then((response) => response.text())
|
||||
.then((svg) => (parent.innerHTML = svg))
|
||||
let elem = parent.children?.[0]
|
||||
if (elem) {
|
||||
elem.setAttribute('width', size?.toString() ?? '24')
|
||||
elem.setAttribute('height', size?.toString() ?? '24')
|
||||
if (strokeWidth) {
|
||||
elem.setAttribute('stroke-width', strokeWidth.toString())
|
||||
}
|
||||
if (color) {
|
||||
elem.setAttribute('stroke', color)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iconComponent = undefined
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
iconComponent = undefined
|
||||
}
|
||||
}
|
||||
|
||||
+10
-13
@@ -2,32 +2,26 @@
|
||||
import type { StaticInput } from '../../../inputType'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import { ClearableInput, Popup } from '../../../../common'
|
||||
|
||||
import { AllIcons } from './icons'
|
||||
export let componentInput: StaticInput<string>
|
||||
|
||||
let loading = false
|
||||
let items: { label: string; icon: any }[]
|
||||
let filteredItems: { label: string; icon: any }[]
|
||||
let items: string[]
|
||||
let filteredItems: string[]
|
||||
let search = ''
|
||||
|
||||
$: if (search) {
|
||||
filteredItems = items.filter((item) => {
|
||||
return item.label.toLowerCase().includes(search.toLowerCase())
|
||||
return item.toLowerCase().includes(search.toLowerCase())
|
||||
})
|
||||
} else {
|
||||
filteredItems = items
|
||||
}
|
||||
|
||||
async function getData() {
|
||||
if (items) {
|
||||
}
|
||||
loading = true
|
||||
// @ts-ignore
|
||||
const data = await import('lucide-svelte/icons')
|
||||
|
||||
filteredItems = items = Object.entries(data)
|
||||
.filter(([key]) => !(key.endsWith('Icon') || key.startsWith('Lucide')))
|
||||
.map(([key, icon]) => ({ label: key, icon }))
|
||||
items = AllIcons
|
||||
|
||||
loading = false
|
||||
}
|
||||
@@ -80,7 +74,7 @@
|
||||
class="col-span-4 mb-2"
|
||||
/>
|
||||
<div class="grid gap-1 grid-cols-4 max-h-[300px] overflow-auto">
|
||||
{#each filteredItems as { label, icon }}
|
||||
{#each filteredItems as label}
|
||||
<button
|
||||
type="button"
|
||||
title={label}
|
||||
@@ -92,7 +86,10 @@
|
||||
hover:bg-gray-100 focus:bg-gray-100 rounded duration-200 dark:hover:bg-frost-900 dark:focus:bg-frost-900
|
||||
{label === componentInput.value ? 'text-blue-600 bg-blue-50 pointer-events-none' : ''}"
|
||||
>
|
||||
<svelte:component this={icon} size={22} />
|
||||
<img
|
||||
loading="lazy"
|
||||
src="https://cdn.jsdelivr.net/npm/lucide-static@0.367.0/icons/{label}.svg"
|
||||
/>
|
||||
<span class="inline-block w-full text-[10px] ellipsize pt-0.5">
|
||||
{label}
|
||||
</span>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user