Sidebar Context $derived.by
Error
#1831
-
Describe the bugI keep getting the following error whenever I try to use sidebar, I used the code from the docs for testing ReproductionI am using Laravel + Inertia + Svelte and not SvelteKit. This is the code I used to test the sidebar: <script lang="ts">
import {Calendar, House, Inbox, Search, Settings} from "lucide-svelte";
import * as Sidebar from "$lib/components/ui/sidebar/index.js";
// Menu items.
const items = [
{
title: "Home",
url: "#",
icon: House,
},
{
title: "Inbox",
url: "#",
icon: Inbox,
},
{
title: "Calendar",
url: "#",
icon: Calendar,
},
{
title: "Search",
url: "#",
icon: Search,
},
{
title: "Settings",
url: "#",
icon: Settings,
},
];
let sidebarOpen = true;
</script>
<Sidebar.Provider bind:open={sidebarOpen}>
<Sidebar.Root>
<Sidebar.Content>
<Sidebar.Group>
<Sidebar.GroupLabel>Application</Sidebar.GroupLabel>
<Sidebar.GroupContent>
<Sidebar.Menu>
{#each items as item (item.title)}
<Sidebar.MenuItem>
<Sidebar.MenuButton>
{#snippet child({ props })}
<a href={item.url} {...props}>
<item.icon />
<span>{item.title}</span>
</a>
{/snippet}
</Sidebar.MenuButton>
</Sidebar.MenuItem>
{/each}
</Sidebar.Menu>
</Sidebar.GroupContent>
</Sidebar.Group>
</Sidebar.Content>
</Sidebar.Root>
</Sidebar.Provider> LogsSystem InfoSystem:
OS: Linux 6.13 Fedora Linux 41 (Workstation Edition)
CPU: (8) x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
Memory: 2.98 GB / 15.49 GB
Container: Yes
Shell: 3.7.0 - /usr/bin/fish
Binaries:
Node: 22.14.0 - /usr/bin/node
npm: 10.9.2 - /usr/bin/npm
bun: 1.2.4 - ~/.bun/bin/bun
Browsers:
Brave Browser: 135.1.77.95
npmPackages:
bits-ui: ^1.3.19 => 1.3.19
formsnap: 1.0.1 => 1.0.1
lucide-svelte: ^0.487.0 => 0.487.0
svelte: ^5.25.7 => 5.25.7
sveltekit-superforms: ^2.24.1 => 2.24.1
tailwindcss: ^3.4.17 => 3.4.17 Severityannoyance |
Beta Was this translation helpful? Give feedback.
Replies: 31 comments 23 replies
-
Related: #1711 Not sure why this is happening... In the other discussion they mention upgrading bits-ui but your's seems to be up to date so maybe there was a different dep that was problematic. Can you try this small rewrite of the class in your code to see if it makes a difference: class SidebarState {
readonly props: SidebarStateProps;
- open = $derived.by(() => this.props.open());
openMobile = $state(false);
setOpen: SidebarStateProps['setOpen'];
#isMobile: IsMobile;
- state = $derived.by(() => (this.open ? 'expanded' : 'collapsed'));
+ get open() {
+ return this.props.open;
+ }
+ get state() {
+ return this.open() ? 'expanded' : 'collapsed'
+ }
constructor(props: SidebarStateProps) {
this.setOpen = props.setOpen;
this.#isMobile = new IsMobile();
this.props = props;
} |
Beta Was this translation helpful? Give feedback.
-
Actually looking more closely I think your code is out of date. Try running the cli to add the sidebar component again. |
Beta Was this translation helpful? Give feedback.
-
I already did that like 3 times today |
Beta Was this translation helpful? Give feedback.
-
What is the code in your This is the most up to date code: import { IsMobile } from "$lib/registry/hook/is-mobile.svelte.js";
import { getContext, setContext } from "svelte";
import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js";
type Getter<T> = () => T;
export type SidebarStateProps = {
/**
* A getter function that returns the current open state of the sidebar.
* We use a getter function here to support `bind:open` on the `Sidebar.Provider`
* component.
*/
open: Getter<boolean>;
/**
* A function that sets the open state of the sidebar. To support `bind:open`, we need
* a source of truth for changing the open state to ensure it will be synced throughout
* the sub-components and any `bind:` references.
*/
setOpen: (open: boolean) => void;
};
class SidebarState {
readonly props: SidebarStateProps;
open = $derived.by(() => this.props.open());
openMobile = $state(false);
setOpen: SidebarStateProps["setOpen"];
#isMobile: IsMobile;
state = $derived.by(() => (this.open ? "expanded" : "collapsed"));
constructor(props: SidebarStateProps) {
this.setOpen = props.setOpen;
this.#isMobile = new IsMobile();
this.props = props;
}
// Convenience getter for checking if the sidebar is mobile
// without this, we would need to use `sidebar.isMobile.current` everywhere
get isMobile() {
return this.#isMobile.current;
}
// Event handler to apply to the `<svelte:window>`
handleShortcutKeydown = (e: KeyboardEvent) => {
if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
this.toggle();
}
};
setOpenMobile = (value: boolean) => {
this.openMobile = value;
};
toggle = () => {
return this.#isMobile.current
? (this.openMobile = !this.openMobile)
: this.setOpen(!this.open);
};
}
const SYMBOL_KEY = "scn-sidebar";
/**
* Instantiates a new `SidebarState` instance and sets it in the context.
*
* @param props The constructor props for the `SidebarState` class.
* @returns The `SidebarState` instance.
*/
export function setSidebar(props: SidebarStateProps): SidebarState {
return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props));
}
/**
* Retrieves the `SidebarState` instance from the context. This is a class instance,
* so you cannot destructure it.
* @returns The `SidebarState` instance.
*/
export function useSidebar(): SidebarState {
return getContext(Symbol.for(SYMBOL_KEY));
} If you aren't being updated to the latest version then maybe there are some CF issues that need to be resolved. |
Beta Was this translation helpful? Give feedback.
-
@ieedan I am used to code problems and stuff so I already updated before retrying but still same problem.
Well I tired that and now I got a problem with |
Beta Was this translation helpful? Give feedback.
-
Can you show me the full code? |
Beta Was this translation helpful? Give feedback.
-
@ieedan Which code exactly ? The code I sent in the issue is literally all the code I have unless you want the context file code. |
Beta Was this translation helpful? Give feedback.
-
Yeah just send the context file code. |
Beta Was this translation helpful? Give feedback.
-
import { IsMobile } from "$lib/hooks/is-mobile.svelte.js";
import { getContext, setContext } from "svelte";
import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js";
type Getter<T> = () => T;
export type SidebarStateProps = {
/**
* A getter function that returns the current open state of the sidebar.
* We use a getter function here to support `bind:open` on the `Sidebar.Provider`
* component.
*/
open: Getter<boolean>;
/**
* A function that sets the open state of the sidebar. To support `bind:open`, we need
* a source of truth for changing the open state to ensure it will be synced throughout
* the sub-components and any `bind:` references.
*/
setOpen: (open: boolean) => void;
};
class SidebarState {
readonly props: SidebarStateProps;
open = $derived.by(() => this.props.open());
openMobile = $state(false);
setOpen: SidebarStateProps["setOpen"];
#isMobile: IsMobile;
state = $derived.by(() => (this.open ? "expanded" : "collapsed"));
constructor(props: SidebarStateProps) {
this.setOpen = props.setOpen;
this.#isMobile = new IsMobile();
this.props = props;
}
// Convenience getter for checking if the sidebar is mobile
// without this, we would need to use `sidebar.isMobile.current` everywhere
get isMobile() {
return this.#isMobile.current;
}
// Event handler to apply to the `<svelte:window>`
handleShortcutKeydown = (e: KeyboardEvent) => {
if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
this.toggle();
}
};
setOpenMobile = (value: boolean) => {
this.openMobile = value;
};
toggle = () => {
return this.#isMobile.current
? (this.openMobile = !this.openMobile)
: this.setOpen(!this.open);
};
}
const SYMBOL_KEY = "scn-sidebar";
/**
* Instantiates a new `SidebarState` instance and sets it in the context.
*
* @param props The constructor props for the `SidebarState` class.
* @returns The `SidebarState` instance.
*/
export function setSidebar(props: SidebarStateProps): SidebarState {
return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props));
}
/**
* Retrieves the `SidebarState` instance from the context. This is a class instance,
* so you cannot destructure it.
* @returns The `SidebarState` instance.
*/
export function useSidebar(): SidebarState {
return getContext(Symbol.for(SYMBOL_KEY));
} |
Beta Was this translation helpful? Give feedback.
-
And with that code you are getting the same error message as you sent above? The source mapping suggests it's different but idk if that's an error... |
Beta Was this translation helpful? Give feedback.
-
I use different import aliases but they point to the same file as the original code |
Beta Was this translation helpful? Give feedback.
-
So if the code here is correct that is invalid placement. |
Beta Was this translation helpful? Give feedback.
-
@ieedan no actually, that's valid |
Beta Was this translation helpful? Give feedback.
-
The source map failed us there. Maybe you can try and provide a minimal reproduction? |
Beta Was this translation helpful? Give feedback.
-
@ieedan can you elaborate ? do you want me to make a new project with minimal code ? Everything else like buttons, labels, etc.. are working fine. |
Beta Was this translation helpful? Give feedback.
-
@ieedan It would be a little complicated since my components are inside my back-end project as I said I am using Laravel + Vite + Svelte. |
Beta Was this translation helpful? Give feedback.
-
You can init a project with the same structure and share it like that |
Beta Was this translation helpful? Give feedback.
-
@ieedan I tried my best to make this. It doesn't display anything but If you open it inside its own windows it will display an error in the console. |
Beta Was this translation helpful? Give feedback.
-
So if you wrap the entire thing in the |
Beta Was this translation helpful? Give feedback.
-
@ieedan The code in the docs doesn't have that 😭 I didn't use the provider, I will try it and tell you. |
Beta Was this translation helpful? Give feedback.
-
It's there https://next.shadcn-svelte.com/docs/components/sidebar#usage |
Beta Was this translation helpful? Give feedback.
-
@ieedan I didn't bother with the +layout files since I am not using svelteKit mb, again I will try it and tell you. |
Beta Was this translation helpful? Give feedback.
-
@ieedan Still the same issue, I used the provider and still
EDIT: I did mess with the sidebar's code yesterday and did manage to fix it and I got the output working the thing is I am not sure if the output I got is the correct one or not. |
Beta Was this translation helpful? Give feedback.
-
Are you able to reproduce in the stackblitz? |
Beta Was this translation helpful? Give feedback.
-
@ieedan I tried to make it as much closer to my project as I can, The thing is... why does it work ? |
Beta Was this translation helpful? Give feedback.
-
Should I send the changes I made here or should we make a discussion ? |
Beta Was this translation helpful? Give feedback.
-
@ieedan Soooo we gonna modify the sidebar's code or at least think about it ? |
Beta Was this translation helpful? Give feedback.
-
Hello, I am having the same issue now, after creating a new project. For me the issue only occurs when I am building my project, and not in dev, which would explain why StackBlitz functions fine. I am using SvelteKit, and unfortunately I don't have a solution to this issue either. |
Beta Was this translation helpful? Give feedback.
-
I found the issue 😑, Can you take a guess:
The correct guess is N°3 🎉🎉🎉 {
"compilerOptions": {
"target": "ES2022", // MAKE SURE THE TARGET IS ES2022 or Higher !!!
"baseUrl": ".",
"paths": {
"$lib": ["./resources/js"],
"$lib/*": ["./resources/js/*"],
"$$": ["./resources/js"],
}
},
"include": ["resources/js/**/*"],
"exclude": ["node_modules"]
} I will send a PR for adding the missing details to the docs 🙂 |
Beta Was this translation helpful? Give feedback.
-
Hi, I'm experiencing the same issue. I followed the official documentation to set up a fresh SvelteKit project and installed shadcn-svelte as described. However, my project is using plain JavaScript — not TypeScript. In this setup, the components fail to work properly (same error as reported). When I create a new SvelteKit project with TypeScript enabled and install shadcn-svelte, everything works fine. |
Beta Was this translation helpful? Give feedback.
I'm sorry to call you out like this, but I literally told you to check your target.. And none of the documentation here is incorrect. As you were using typescript with svelte 5, you should've checked svelte docs, where it clearly states to target
ES2022
or higher.Svelte docs for typescript
And if you create pure svelte + vite in the recommended way (also in svelte docs), it would have already added the target of
ESNext
intsconfig.app.json
. This project is not to blame for the "incorrect" documentation, but rather probably the template you were using for your project.Yes, a note could've been helpful, but honestly, it wasn't the responsibility of
shadcn-svelte
.