Repository: podman-desktop/podman-desktop
Pull request #12194: chore: migrate empty screen to svelte 5
Author: login: deboer-tim
Created: 2025-04-14T20:12:51Z | Merged: 2025-04-22T14:03:40Z

### What does this PR do?

Migrates the empty screen to Svelte 5 using patterns already established in other components. Updated usage in /renderer to Svelte 5 syntax.

One minor cleanup to default message to fix second issue.

### Screenshot / video of UI

N/A

### What issues does this PR fix or reference?

First half of #11586.
Fixes #12145.

### How to test this PR?

Check empty screens to confirm behaviour.

Linked issue #12145: Remove default empty screen message of 'Message'
### Is your enhancement related to a problem? Please describe

The default empty screen message (e.g., shown if you use a customer upper control like here: https://github.com/podman-desktop/extension-bootc/pull/1526#pullrequestreview-2756901418) is the string 'Message'.

### Describe the solution you'd like

The empty message should be blank, since you have the choice of custom upper component, message, or both. (i.e. message should truly be optional)

### Describe alternatives you've considered

_No response_

### Additional context

_No response_

Diff:
diff --git a/packages/renderer/src/lib/container/ContainerEmptyScreen.svelte b/packages/renderer/src/lib/container/ContainerEmptyScreen.svelte
index 0bc46b6b2deb6..01c6c66a9cf6f 100644
--- a/packages/renderer/src/lib/container/ContainerEmptyScreen.svelte
+++ b/packages/renderer/src/lib/container/ContainerEmptyScreen.svelte
@@ -85,8 +85,9 @@ async function runContainer(commandLine: string): Promise<void> {
   title={title}
   message={messageCommandLine}
   commandline={commandLine}
-  on:click={(): Promise<void> => window.clipboardWriteText(commandLine)}>
-  <div slot="upperContent" hidden={stoppedOnly}>
+  onclick={(): Promise<void> => window.clipboardWriteText(commandLine)}>
+  {#snippet upperContent()}
+  <div hidden={stoppedOnly}>
     <span class="text-[var(--pd-details-empty-sub-header)] max-w-[800px] text-pretty mx-2">{messageButton}</span>
     <div class="flex gap-2 justify-center p-3">
       <Button
@@ -97,4 +98,5 @@ async function runContainer(commandLine: string): Promise<void> {
     </div>
     <h1 class="text-xl text-[var(--pd-details-empty-header)]">OR</h1>
   </div>
+  {/snippet}
 </EmptyScreen>
diff --git a/packages/renderer/src/lib/image/ImageEmptyScreen.svelte b/packages/renderer/src/lib/image/ImageEmptyScreen.svelte
index cb4c6a5c35c4b..86c0890d95476 100644
--- a/packages/renderer/src/lib/image/ImageEmptyScreen.svelte
+++ b/packages/renderer/src/lib/image/ImageEmptyScreen.svelte
@@ -42,8 +42,8 @@ async function pullFirstImage(): Promise<void> {
   title="No images"
   message="Pull a first image using the following command line:"
   commandline={commandLine}
-  on:click={(): Promise<void> => window.clipboardWriteText(commandLine)}>
-  <div slot="upperContent">
+  onclick={(): Promise<void> => window.clipboardWriteText(commandLine)}>
+  {#snippet upperContent()}
     <span class="text-[var(--pd-details-empty-sub-header)] max-w-[800px] text-pretty mx-2"
       >Pull a first image by clicking on this button:</span>
     <div class="flex gap-2 justify-center p-3">
@@ -54,5 +54,5 @@ async function pullFirstImage(): Promise<void> {
         on:click={pullFirstImage}>Pull your first image</Button>
     </div>
     <h1 class="text-xl text-[var(--pd-details-empty-header)]">OR</h1>
-  </div>
+  {/snippet}
 </EmptyScreen>
diff --git a/packages/renderer/src/lib/pod/PodEmptyScreen.svelte b/packages/renderer/src/lib/pod/PodEmptyScreen.svelte
index 9bc4a3c74ce2f..973980eab8e8c 100644
--- a/packages/renderer/src/lib/pod/PodEmptyScreen.svelte
+++ b/packages/renderer/src/lib/pod/PodEmptyScreen.svelte
@@ -54,12 +54,12 @@ async function startPod(): Promise<void> {
   title="No pods"
   message="Run a first pod using the following command line:"
   commandline={commandLine}
-  on:click={(): Promise<void> => window.clipboardWriteText(commandLine)}>
-  <div slot="upperContent">
+  onclick={(): Promise<void> => window.clipboardWriteText(commandLine)}>
+  {#snippet upperContent()}
     <div class="flex gap-2 justify-center p-3">
       <Button title="Start your first pod" type="primary" inProgress={inProgress} on:click={startPod}
         >Start your first pod</Button>
     </div>
     <h1 class="text-xl text-[var(--pd-details-empty-header)]">OR</h1>
-  </div>
+  {/snippet}
 </EmptyScreen>
diff --git a/packages/renderer/src/lib/volume/VolumeEmptyScreen.svelte b/packages/renderer/src/lib/volume/VolumeEmptyScreen.svelte
index b10b791580f14..1857315282f63 100644
--- a/packages/renderer/src/lib/volume/VolumeEmptyScreen.svelte
+++ b/packages/renderer/src/lib/volume/VolumeEmptyScreen.svelte
@@ -11,4 +11,4 @@ const commandLine = 'podman volume create myFirstVolume';
   title="No volumes"
   message="Create a volume using the following command line:"
   commandline={commandLine}
-  on:click={(): Promise<void> => window.clipboardWriteText(commandLine)} />
+  onclick={(): Promise<void> => window.clipboardWriteText(commandLine)} />
diff --git a/packages/ui/src/lib/screen/EmptyScreen.spec.ts b/packages/ui/src/lib/screen/EmptyScreen.spec.ts
index 5fea77e64aa73..69a29c9bcea0b 100644
--- a/packages/ui/src/lib/screen/EmptyScreen.spec.ts
+++ b/packages/ui/src/lib/screen/EmptyScreen.spec.ts
@@ -1,5 +1,5 @@
 /**********************************************************************
- * Copyright (C) 2023 Red Hat, Inc.
+ * Copyright (C) 2023-2025 Red Hat, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,12 +23,9 @@ import { expect, test, vi } from 'vitest';
 
 import EmptyScreen from './EmptyScreen.svelte';
 
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable @typescript-eslint/no-empty-function */
-
 test('Expect copy in clipboard', async () => {
   const mock = vi.fn();
-  render(EmptyScreen, { icon: '', commandline: 'podman run hello:world', onClick: mock });
+  render(EmptyScreen, { icon: '', commandline: 'podman run hello:world', onclick: mock });
   const button = screen.getByRole('button');
   expect(button).toBeInTheDocument();
   expect(button).toBeEnabled();
diff --git a/packages/ui/src/lib/screen/EmptyScreen.svelte b/packages/ui/src/lib/screen/EmptyScreen.svelte
index 9f8132135d7a5..46dd2b7f9be21 100644
--- a/packages/ui/src/lib/screen/EmptyScreen.svelte
+++ b/packages/ui/src/lib/screen/EmptyScreen.svelte
@@ -1,26 +1,48 @@
 <script lang="ts">
 import { faPaste } from '@fortawesome/free-solid-svg-icons';
-import { createEventDispatcher, onMount } from 'svelte';
+import { createEventDispatcher, onMount, type Snippet } from 'svelte';
 import Fa from 'svelte-fa';
 
 import Button from '../button/Button.svelte';
 import { isFontAwesomeIcon } from '../utils/icon-utils';
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export let icon: any;
-export let title = 'No title';
-export let message = 'Message';
-export let detail = '';
-export let commandline = '';
-export let hidden = false;
+interface Props {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  icon: any;
+  title?: string;
+  message?: string;
+  detail?: string;
+  commandline?: string;
+  hidden?: boolean;
+  class?: string;
+  style?: string;
+  'aria-label'?: string;
+  upperContent?: Snippet;
+  children?: Snippet;
+  onclick?: (text: string) => void;
+}
+
+let {
+  icon = undefined,
+  title = 'No title',
+  message = '',
+  detail = '',
+  commandline = '',
+  hidden = false,
+  class: className,
+  style,
+  'aria-label': ariaLabel,
+  upperContent,
+  children,
+  onclick = (text): void => {
+    dispatch('click', text);
+  },
+}: Props = $props();
 
-let fontAwesomeIcon = false;
-let processed = false;
+let fontAwesomeIcon = $state(false);
+let processed = $state(false);
 
 const dispatch = createEventDispatcher<{ click: string }>();
-export let onClick: (text: string) => void = text => {
-  dispatch('click', text);
-};
 
 onMount(() => {
   if (isFontAwesomeIcon(icon)) {
@@ -32,30 +54,31 @@ onMount(() => {
 function handleClick(): void {
   const text = copyTextDivElement?.textContent;
   if (text) {
-    onClick(text);
+    onclick(text);
   }
 }
 
-let copyTextDivElement: HTMLDivElement;
+let copyTextDivElement = $state<HTMLDivElement>();
 </script>
 
 <div
-  class="flex flex-row w-full h-full justify-center {$$props.class ?? ''}"
+  class="flex flex-row w-full h-full justify-center {className}"
   class:hidden={hidden}
-  style={$$props.style}
-  aria-label={$$props['aria-label']}>
+  style={style}
+  aria-label={ariaLabel}>
   <div class="flex flex-col h-full justify-center text-center space-y-3">
     <div class="flex justify-center text-[var(--pd-details-empty-icon)] py-2">
       {#if processed}
         {#if fontAwesomeIcon}
           <Fa icon={icon} size="4x" />
         {:else}
-          <svelte:component this={icon} size="55" />
+          {@const IconComponent = icon}
+          <IconComponent size=55 />
         {/if}
       {/if}
     </div>
     <h1 class="text-xl text-[var(--pd-details-empty-header)]">{title}</h1>
-    <slot name="upperContent" slot="upperContent" />
+    {@render upperContent?.()}
     <span class="text-[var(--pd-details-empty-sub-header)] max-w-[800px] text-pretty mx-2">{message}</span>
     {#if detail}
       <span class="text-[var(--pd-details-empty-sub-header)]">{detail}</span>
@@ -73,9 +96,9 @@ let copyTextDivElement: HTMLDivElement;
           ><Fa class="h-5 w-5 cursor-pointer text-xl text-[var(--pd-button-primary-bg)]" icon={faPaste} /></Button>
       </div>
     {/if}
-    {#if $$slots}
+    {#if children}
       <div class="py-2">
-        <slot />
+        {@render children()}
       </div>
     {/if}
   </div>


Reviews:
user: login: sourcery-ai[bot]
body: Hey @deboer-tim - I've reviewed your changes - here's some feedback:

**Overall Comments**:
- The migration to Svelte 5 looks good, and the component usage is also updated correctly.

<details>
<summary>Here's what I looked at during the review</summary>

- 🟡 **General issues**: 1 issue found
- 🟢 **Security**: all looks good
- 🟢 **Testing**: all looks good
- 🟢 **Complexity**: all looks good
- 🟢 **Documentation**: all looks good
</details>

***

<details>
<summary>Sourcery is free for open source - if you like our reviews please consider sharing them ✨</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20got%20an%20instant%20code%20review%20from%20%40SourceryAI%2C%20and%20it%20was%20brilliant%21%20It%27s%20free%20for%20open%20source%20and%20has%20a%20free%20trial%20for%20private%20code.%20Check%20it%20out%20https%3A//sourcery.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20got%20an%20instant%20code%20review%20from%20%40SourceryAI%2C%20and%20it%20was%20brilliant%21%20It%27s%20free%20for%20open%20source%20and%20has%20a%20free%20trial%20for%20private%20code.%20Check%20it%20out%20https%3A//sourcery.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https://sourcery.ai)
- [Facebook](https://www.facebook.com/sharer/sharer.php?u=https://sourcery.ai)

</details>

<sub>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
</sub>
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T20:13:52Z
user: login: gastoner
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T06:06:32Z
user: login: axel7083
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T08:54:43Z
user: login: deboer-tim
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T11:52:15Z
user: login: deboer-tim
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T11:53:10Z
user: login: sourcery-ai[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T11:53:30Z
user: login: axel7083
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T11:53:35Z
user: login: deboer-tim
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T11:53:59Z
user: login: benoitf
body: rename onClick to onclick
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-17T11:50:58Z
user: login: axel7083
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T12:20:11Z
user: login: gastoner
body: Codewise LGTM
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-22T13:22:47Z

Review comments:
diff_hunk: @@ -36,26 +58,27 @@ function handleClick(): void {
   }
 }
 
-let copyTextDivElement: HTMLDivElement;
+let copyTextDivElement = $state<HTMLDivElement>();
 </script>
 
 <div
-  class="flex flex-row w-full h-full justify-center {$$props.class ?? ''}"
+  class="flex flex-row w-full h-full justify-center {className}"
path: packages/ui/src/lib/screen/EmptyScreen.svelte
user: login: sourcery-ai[bot]
body: **suggestion:** Class binding might pass undefined value.

Since 'className' is optional, if it is undefined the binding may result in an undesirable output. Consider defaulting 'className' to an empty string or using a fallback in the binding (e.g., '{className ?? ""}') to ensure stable styling.

```suggestion
  class="flex flex-row w-full h-full justify-center {className ?? ''}"
```
created_at: 2025-04-14T20:13:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -36,26 +58,27 @@ function handleClick(): void {
   }
 }
 
-let copyTextDivElement: HTMLDivElement;
+let copyTextDivElement = $state<HTMLDivElement>();
 </script>
 
 <div
-  class="flex flex-row w-full h-full justify-center {$$props.class ?? ''}"
+  class="flex flex-row w-full h-full justify-center {className}"
path: packages/ui/src/lib/screen/EmptyScreen.svelte
user: login: gastoner
body: @deboer-tim probably relevant? since the className is undefined now => add default value or this change 
created_at: 2025-04-15T06:05:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -73,9 +96,9 @@ let copyTextDivElement: HTMLDivElement;
           ><Fa class="h-5 w-5 cursor-pointer text-xl text-[var(--pd-button-primary-bg)]" icon={faPaste} /></Button>
       </div>
     {/if}
-    {#if $$slots}
+    {#if children}
       <div class="py-2">
-        <slot />
+        {@render children()}
path: packages/ui/src/lib/screen/EmptyScreen.svelte
user: login: gastoner
body: `{@render children?.()}` ?
created_at: 2025-04-15T06:06:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,26 +1,48 @@
 <script lang="ts">
 import { faPaste } from '@fortawesome/free-solid-svg-icons';
-import { createEventDispatcher, onMount } from 'svelte';
+import { createEventDispatcher, onMount, type Snippet } from 'svelte';
 import Fa from 'svelte-fa';
 
 import Button from '../button/Button.svelte';
 import { isFontAwesomeIcon } from '../utils/icon-utils';
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export let icon: any;
-export let title = 'No title';
-export let message = 'Message';
-export let detail = '';
-export let commandline = '';
-export let hidden = false;
+interface Props {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  icon: any;
+  title?: string;
+  message?: string;
+  detail?: string;
+  commandline?: string;
+  hidden?: boolean;
+  class?: string;
+  style?: string;
+  'aria-label'?: string;
+  upperContent?: Snippet;
+  children?: Snippet;
+  onClick?: (text: string) => void;
path: packages/ui/src/lib/screen/EmptyScreen.svelte
user: login: axel7083
body: onclick ? let's be consistent with how svelte do the naming ? (I don't like it, but maybe better to have a single way)
created_at: 2025-04-15T08:54:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,26 +1,48 @@
 <script lang="ts">
 import { faPaste } from '@fortawesome/free-solid-svg-icons';
-import { createEventDispatcher, onMount } from 'svelte';
+import { createEventDispatcher, onMount, type Snippet } from 'svelte';
 import Fa from 'svelte-fa';
 
 import Button from '../button/Button.svelte';
 import { isFontAwesomeIcon } from '../utils/icon-utils';
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export let icon: any;
-export let title = 'No title';
-export let message = 'Message';
-export let detail = '';
-export let commandline = '';
-export let hidden = false;
+interface Props {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  icon: any;
+  title?: string;
+  message?: string;
+  detail?: string;
+  commandline?: string;
+  hidden?: boolean;
+  class?: string;
+  style?: string;
+  'aria-label'?: string;
+  upperContent?: Snippet;
+  children?: Snippet;
+  onClick?: (text: string) => void;
path: packages/ui/src/lib/screen/EmptyScreen.svelte
user: login: deboer-tim
body: I agree it should be consistent and use the Svelte 5 pattern... but this was the Svelte 5 name picked in previous PR and we're trying to avoid forced migration? 🤷🏻‍♂️ Not sure what to do in cases like this as PR could get rejected both ways.
created_at: 2025-04-15T11:52:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -36,26 +58,27 @@ function handleClick(): void {
   }
 }
 
-let copyTextDivElement: HTMLDivElement;
+let copyTextDivElement = $state<HTMLDivElement>();
 </script>
 
 <div
-  class="flex flex-row w-full h-full justify-center {$$props.class ?? ''}"
+  class="flex flex-row w-full h-full justify-center {className}"
path: packages/ui/src/lib/screen/EmptyScreen.svelte
user: login: deboer-tim
body: I'll test again, but Svelte 5 seems to have a new check and this now works.
created_at: 2025-04-15T11:53:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -36,26 +58,27 @@ function handleClick(): void {
   }
 }
 
-let copyTextDivElement: HTMLDivElement;
+let copyTextDivElement = $state<HTMLDivElement>();
 </script>
 
 <div
-  class="flex flex-row w-full h-full justify-center {$$props.class ?? ''}"
+  class="flex flex-row w-full h-full justify-center {className}"
path: packages/ui/src/lib/screen/EmptyScreen.svelte
user: login: sourcery-ai[bot]
body: Based on the conversation, I'll provide a helpful response that acknowledges the potential concern and supports the current implementation:

The suggestion about potentially undefined `className` is a good catch, but Tim's observation is correct. In Svelte 5, the handling of undefined class bindings has been improved. The runtime now seems to handle undefined values more gracefully, which means the current implementation should work without explicitly providing a fallback.

If you want to be extra cautious, you could still use the null coalescing operator (`??`) as originally suggested, but it's not strictly necessary in this case. Tim's recommendation to test the implementation is the best approach to confirm the behavior.

I recommend:
1. Verify the styling works as expected in the UI
2. Check that no unexpected styling issues occur when `className` is undefined
3. If any issues are found, then consider adding the explicit fallback

Would you like me to elaborate on any part of this explanation?
created_at: 2025-04-15T11:53:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,26 +1,48 @@
 <script lang="ts">
 import { faPaste } from '@fortawesome/free-solid-svg-icons';
-import { createEventDispatcher, onMount } from 'svelte';
+import { createEventDispatcher, onMount, type Snippet } from 'svelte';
 import Fa from 'svelte-fa';
 
 import Button from '../button/Button.svelte';
 import { isFontAwesomeIcon } from '../utils/icon-utils';
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export let icon: any;
-export let title = 'No title';
-export let message = 'Message';
-export let detail = '';
-export let commandline = '';
-export let hidden = false;
+interface Props {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  icon: any;
+  title?: string;
+  message?: string;
+  detail?: string;
+  commandline?: string;
+  hidden?: boolean;
+  class?: string;
+  style?: string;
+  'aria-label'?: string;
+  upperContent?: Snippet;
+  children?: Snippet;
+  onClick?: (text: string) => void;
path: packages/ui/src/lib/screen/EmptyScreen.svelte
user: login: axel7083
body: if the `onClick` is for backward compatiblity, let's keep it
created_at: 2025-04-15T11:53:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -73,9 +96,9 @@ let copyTextDivElement: HTMLDivElement;
           ><Fa class="h-5 w-5 cursor-pointer text-xl text-[var(--pd-button-primary-bg)]" icon={faPaste} /></Button>
       </div>
     {/if}
-    {#if $$slots}
+    {#if children}
       <div class="py-2">
-        <slot />
+        {@render children()}
path: packages/ui/src/lib/screen/EmptyScreen.svelte
user: login: deboer-tim
body: See `{#if children}` two lines above. We don't want the div either if no children, so no need for `?.`
created_at: 2025-04-15T11:53:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,26 +1,48 @@
 <script lang="ts">
 import { faPaste } from '@fortawesome/free-solid-svg-icons';
-import { createEventDispatcher, onMount } from 'svelte';
+import { createEventDispatcher, onMount, type Snippet } from 'svelte';
 import Fa from 'svelte-fa';
 
 import Button from '../button/Button.svelte';
 import { isFontAwesomeIcon } from '../utils/icon-utils';
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export let icon: any;
-export let title = 'No title';
-export let message = 'Message';
-export let detail = '';
-export let commandline = '';
-export let hidden = false;
+interface Props {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  icon: any;
+  title?: string;
+  message?: string;
+  detail?: string;
+  commandline?: string;
+  hidden?: boolean;
+  class?: string;
+  style?: string;
+  'aria-label'?: string;
+  upperContent?: Snippet;
+  children?: Snippet;
+  onClick?: (text: string) => void;
path: packages/ui/src/lib/screen/EmptyScreen.svelte
user: login: benoitf
body: for backward compliance, we need to dispatch an event which is already the case

but yes, the callback should be named with the same logic than svelte --> onclick
created_at: 2025-04-17T11:50:48Z
author_association: COLLABORATOR

PR comments:
user: login: codecov[bot]
created_at: 2025-04-14T20:22:24Z
body: ## [Codecov](https://app.codecov.io/gh/podman-desktop/podman-desktop/pull/12194?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=podman-desktop) Report
Attention: Patch coverage is `94.73684%` with `1 line` in your changes missing coverage. Please review.
| [Files with missing lines](https://app.codecov.io/gh/podman-desktop/podman-desktop/pull/12194?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=podman-desktop) | Patch % | Lines |
|---|---|---|
| [packages/ui/src/lib/screen/EmptyScreen.svelte](https://app.codecov.io/gh/podman-desktop/podman-desktop/pull/12194?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=podman-desktop#diff-cGFja2FnZXMvdWkvc3JjL2xpYi9zY3JlZW4vRW1wdHlTY3JlZW4uc3ZlbHRl) | 92.85% | [1 Missing :warning: ](https://app.codecov.io/gh/podman-desktop/podman-desktop/pull/12194?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=podman-desktop) |

:loudspeaker: Thoughts on this report? [Let us know!](https://github.com/codecov/feedback/issues/255)
author_association: NONE
user: login: deboer-tim
created_at: 2025-04-17T18:50:35Z
body: Renamed onClick to onclick to match the Svelte 5 pattern. (it's a 'breaking' change since onClick has been there since July [https://github.com/podman-desktop/podman-desktop/commit/43db9b0a3f2b0d836619f4483da9ddfac863df35#diff-9dada4e04e82aec5969e59d18efdc17d1afdac3d264cef8ef54b67dbe93a273a], but I agree this is better/consistent and unlikely to actually break clients)
author_association: CONTRIBUTOR
user: login: deboer-tim
created_at: 2025-04-22T13:12:25Z
body: Fixed test and rebased (1h ago). @gastoner can you give a quick review?
author_association: CONTRIBUTOR