Skip to content

I can't migrate my component to Svelte 5 #15125

Closed
@Enes5519

Description

@Enes5519

Discussed in #15117

Originally posted by Enes5519 January 27, 2025
The svelte 4 component I will share below is the wrapper version of a custom element from a different library on the Svelte side. The code below was working perfectly with the use of slots, but now I cannot achieve the same perfection because the slot rules are very strict. At the first stage, I was going to update it only by upgrading the version, can you help me at this stage?

<script lang="ts">
  import type { BlDialog } from "@trendyol/baklava";
  import { onDestroy } from "svelte";

  interface $$Props extends Partial<BlDialog> {
    class?: string;
    "data-testid"?: string;
    fullWidthAction?: boolean;
  }

  export let open = false;
  export let fullWidthAction = false;

  function handleDialogOpen() {
    open = true;
  }

  function handleDialogClose() {
    open = false;
  }

  onDestroy(() => {
    // @see https://github.com/Trendyol/baklava/issues/778
    document.body.style.overflow = "auto";
  });
</script>

<bl-dialog
  on:bl-dialog-open={handleDialogOpen}
  on:bl-dialog-open
  on:bl-dialog-close={handleDialogClose}
  on:bl-dialog-close
  on:bl-dialog-request-close
  class:full={fullWidthAction}
  {open}
  polyfilled={true}
  {...$$restProps}
>
  <slot />
  <slot name="primary-action" slot="primary-action" />
  <slot name="secondary-action" slot="secondary-action" />
  <slot name="tertiary-action" slot="tertiary-action" />
</bl-dialog>

<style>
  .full bl-button {
    --bl-button-display: block;
    flex: 1;
  }
</style>

Normally I translated it as below, but do I need to create a separate prop for each component to pass the slot attribute? For example, I made the bl-button custom element a component and I cannot use them under each other.

<script lang="ts">
  import type { BlDialog } from "@trendyol/baklava";
  import { onDestroy, type Snippet } from "svelte";

  interface Props extends Omit<Partial<BlDialog>, "children"> {
    "data-testid"?: string;
    fullWidthAction?: boolean;
    children?: Snippet;
    onOpen?: (e: CustomEvent<{ isOpen: boolean }>) => void;
    onClose?: (e: CustomEvent<{ isOpen: boolean }>) => void;
    onRequestClose?: (
      e: CustomEvent<{
        source: "close-button" | "keyboard" | "backdrop";
      }>
    ) => void;
  }

  let {
    open = $bindable(false),
    fullWidthAction = false,
    children,
    onOpen,
    onClose,
    onRequestClose,
    ...rest
  }: Props = $props();

  function handleDialogOpen(e: CustomEvent<{ isOpen: boolean }>) {
    open = true;
    onOpen?.(e);
  }

  function handleDialogClose(e: CustomEvent<{ isOpen: boolean }>) {
    open = false;
    onClose?.(e);
  }

  onDestroy(() => {
    // @see https://github.com/Trendyol/baklava/issues/778
    document.body.style.overflow = "auto";
  });
</script>

<bl-dialog
  onbl-dialog-open={handleDialogOpen}
  onbl-dialog-close={handleDialogClose}
  onbl-dialog-request-close={onRequestClose}
  class:full={fullWidthAction}
  {open}
  polyfilled={true}
  {...rest}
>
  {@render children?.()}
</bl-dialog>

<style>
  .full bl-button {
    --bl-button-display: block;
    flex: 1;
  }
</style>

Problematic usage

<DialogV5 bind:open {onRequestClose} {...rest}>
  <div class="container">
    <AssetImage name="{variant}-illustration.svg" alt={variant} />
    <div class="caption">{caption}</div>
    <div class="description">
      {@render children?.()}
    </div>
  </div>

  {#if primaryButtonText}
    <Button slot="primary-action" class="button" size="large" onClick={onClickPrimary}>
      {primaryButtonText}
    </Button>
  {/if}
  {#if secondaryButtonText}
    <Button slot="secondary-action" class="button" size="large" variant="secondary" onClick={onClickSecondary}>
      {secondaryButtonText}
    </Button>
  {/if}
</DialogV5>
```</div>

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions