Skip to content

Breaking: Svelte 5 #295

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
May 15, 2025
Merged

Breaking: Svelte 5 #295

merged 47 commits into from
May 15, 2025

Conversation

Antosik
Copy link
Contributor

@Antosik Antosik commented Dec 15, 2024

Work in progress

Breaking changes

  1. The svelte dependency has been moved to peer dependencies.
  2. svelte@^5.8.0 is now required
  3. Events and slot names have been updated to align with the new Svelte paradigm (see below). However, there are some breaking changes:
    3.1. The onchange event now triggers only on the component itself, not on the input element (to avoid event overlap)
    3.2. selected slot was renamed to selectedItem

Events

Events are now divided into two categories: native events - MultiSelectNativeEvents (triggered on the input element) and generated events - MultiSelectComponentEvents (triggered on the component itself).
Event naming conventions have been slightly adjusted (e.g., on:addonadd), and custom event details are no longer required (e.g., e.detail.typee.type).

Example

Before (svelte4):

<MultiSelect
  options={[1, 2, 3]}
  on:keyup={(event) => console.log('key', event.target.value)}
  on:change={(e) => alert(`You ${e.detail.type} ${e.detail.option}`)}
/>

After (svelte5):

<MultiSelect
  options={[1, 2, 3]}
  onkeyup={(event) => console.log('key', event.target.value)}
  onchange={(e) => alert(`You ${e.type} ${e.option}`)}
/>

Slots Snippets

Slot names have been slightly adjusted (e.g., expand-iconexpandIcon, etc.).

Example

Before (svelte4):

<MultiSelect
  options={languages}
  maxSelect={5}
  placeholder="What languages do you know?"
  selected={['Python', 'TypeScript', 'Julia']}
  let:option
>
  <LanguageSlot {option} />
  <Icon slot="expand-icon" let:open icon={open ? 'Collapse' : 'Expand'} />
  <MinusIcon slot="remove-icon" width="1em" />
</MultiSelect>

After (svelte5):

<MultiSelect
  options={languages}
  maxSelect={5}
  placeholder="What languages do you know?"
  selected={['Python', 'TypeScript', 'Julia']}
>
  {#snippet children({ option })}
    <LanguageSlot {option} />
  {/snippet}
  {#snippet expandIcon({ open })}
    <Icon icon={open ? 'Collapse' : 'Expand'} />
  {/snippet}
  {#snippet removeIcon()}
    <MinusIcon width="1em" />
  {/snippet}
</MultiSelect>

Minor changes

  • Dependencies were updated to latest versions
  • MultiSelectEvents were removed in favor of MultiSelectComponentEvents & MultiSelectNativeEvents
  • Little code optimizations

Todos

  1. Migrate remaining events to svelte5 (remove legacy code)
  2. Migrate routes directory to svelte5
  3. Update docs
  4. Update tests (using @testing-library/svelte (?))
  5. Wait until Feat/ svelte 5 upgrade mattjennings/mdsvexamples#32 is merged (before that dependencies can be installed only by using --legacy-peer-deps flag)
  6. Update css-classes example to use :where
  7. Update repl links on examples

Checklist

[ ] has tests (only needed if any new functionality was added or bugs fixed)
[ ] has examples/docs (only needed if any new functionality was added)

Useful links

@Antosik Antosik marked this pull request as draft December 15, 2024 13:58
Copy link
Owner

@janosh janosh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks so much @Antosik for taking of this big migration effort! 👍

i've been meaning to tackle this as well but haven't gotten to it yet so really appreciated 🙏

contributing.md Outdated
@@ -12,6 +12,7 @@ To submit a pull request, clone the repo, install dependencies and start the dev
git clone https://github.com/janosh/svelte-multiselect
cd svelte-multiselect
npm install
npm run package
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think contributors need to run npm run package?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running npm run dev requires calling npm run package first. Without it, SvelteKit can’t load the library from the dist folder, resulting in an error like:

[plugin:vite:import-analysis] Failed to resolve entry for package "svelte-multiselect". The package may have incorrect main/module/exports specified in its package.json.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, good call! i think having the package import itself may be an antipattern. i mainly did it so that the mdsvexample code fences show the package name as users would write it instead of $lib

- import MultiSelect from '$lib'
+ import MultiSelect from 'svelte-multiselect'

package.json Outdated
Comment on lines 35 to 36
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/svelte": "^5.2.6",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally, i would like to stick to pure vitest unit testing. can we do without @testing-library

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I referenced @testing-library based on the docs:

While the process is very straightforward, it is also low level and somewhat brittle, as the precise structure of your component may change frequently. Tools like @testing-library/svelte can help streamline your tests.

That said, I’m ready to revert to pure Vitest if you prefer it.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes please. i've been using pure vitest on several different projects and so far it's been great. haven't felt the need for additional testing packages and like to keep things lean.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can get rid of this file entirely now with runes? never liked this hacky workaround for testing 2-way binding...

Copy link
Contributor Author

@Antosik Antosik Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not entirely sure about that. The docs mention:

When writing component tests that involve two-way bindings, context, or snippet props, it’s best to create a wrapper component for your specific test and interact with that. @testing-library/svelte contains some examples.

Looks like we still need to keep it for now…

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah bummer! thanks for digging this up! 👍

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file contains a lot of boilerplate. many of the functions are 1-liners so probably better to inline them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are purely utility functions to improve test readability and keep things consistent. But if you’d prefer, I can inline them instead.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, please inline. thank you!

@janosh janosh added dx Developer experience refactor Refactor breaking Breaking change deps Dependency version bumps labels Dec 15, 2024
@janosh
Copy link
Owner

janosh commented Jan 10, 2025

great news! 🎉 mdsvexamples just added Svelte 5 support so no longer blocked from updating by the docs

…yntax

- add bubble, stopPropagation, preventDefault event modifier functions in MultiSelect.svelte
- skip readme tests (no longer work due to different code structure not matching Svelte 4 specific regexes)
- fix lint and typescript errors
@janosh janosh mentioned this pull request Feb 6, 2025
@janosh janosh marked this pull request as ready for review May 14, 2025 00:24
@janosh
Copy link
Owner

janosh commented May 14, 2025

did some more work. getting close to ready to merge. all unit tests now passing. some playwright tests still failing and some docs still need updating (like renaming slots to snippets)

@janosh janosh changed the title WIP: Breaking: Svelte 5 Breaking: Svelte 5 May 14, 2025
janosh added 6 commits May 14, 2025 09:56
- MultiSelect.svelte CSS: replace `:where` with `:is` for less recessive button styles
- single Toc component in +layout.svelte for /, /changelog, /contributing
- remove redundant Toc imports and instances from +page.svelte, changelog, and contributing pages
- fix async loading of changelog in +page.server.ts
Copy link
Owner

@janosh janosh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was a big lift! thanks for all your hard work @Antosik 👍 and sorry for the long delay in getting this over the finish line

@janosh janosh merged commit 816865f into janosh:main May 15, 2025
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Breaking change deps Dependency version bumps dx Developer experience refactor Refactor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants