Skip to content
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

Svelte Adapter is broken for DatePicker component #2179

Open
codercms opened this issue Jan 17, 2025 · 0 comments
Open

Svelte Adapter is broken for DatePicker component #2179

codercms opened this issue Jan 17, 2025 · 0 comments

Comments

@codercms
Copy link

codercms commented Jan 17, 2025

🐛 Bug report

Since the Svelte adapter relies on the $state.snapshot rune, it leads to unexpected behavior:

const contextSnapshot = $state.snapshot(options?.context)
//@ts-expect-error - svelte typing issue
service.setContext(contextSnapshot)

$effect(() => {
const contextSnapshot = $state.snapshot(options?.context)
// @ts-expect-error - svelte typing issue
service.setContext(contextSnapshot)
})

The issue arises because $state.snapshot creates a recursive copy of the passed value using the window.structuredClone API, which removes private properties from objects and, most importantly, their prototype.
Here is issue in Svelte project with extensive description - sveltejs/svelte#15022

But actually $state.snapshot doesn't work in cases when an external library expects to receive an instance of certain class, not just a regular object. Cause $state.snapshot actually makes a copy of object using window.structuredClone API which doesn't keep object prototype, nor private properties: Things that don't work with structured clone .

Which makes usage of $state.snapshot completely broken with libraries that actually work with classes, not an "anonymous" objects.

So, the DatePicker component expects the value prop to contain an array of CalendarDate class instances. However, the $state.snapshot rune effectively removes the object prototype from the items in the "value" array, causing ZagJS to throw an error like:
Uncaught TypeError: start.toDate is not a function.

💥 Steps to reproduce

See Stackblitz repro, it fails immediately

💻 Link to reproduction

https://stackblitz.com/edit/vitejs-vite-imndkpws?file=src%2FApp.svelte

🧐 Expected behavior

DatePicker component still work with Svelte

🧭 Possible Solution

Probably it's better to not wrap component's context prop with $state.snapshot rune at all
Here's how Skeleton UI project uses Zag with Svelte: https://github.com/skeletonlabs/skeleton/blob/24f798f95017b557898583dee0d4897d321e9433/packages/skeleton-svelte/src/lib/components/Combobox/Combobox.svelte#L79

🌍 System information

Software Version(s)
Zag Version 0.81.2
Browser Chrome 131.0.6778.265
Operating System Win 11

📝 Additional information

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant