PHANTOM
🇮🇳 IN
Skip to content

WIP: Svelte 5#1078

Draft
benjaminknox wants to merge 8 commits intobrave:mainfrom
benjaminknox:bpk/svelte5
Draft

WIP: Svelte 5#1078
benjaminknox wants to merge 8 commits intobrave:mainfrom
benjaminknox:bpk/svelte5

Conversation

@benjaminknox
Copy link
Contributor

@benjaminknox benjaminknox commented May 7, 2025

What?

WIP svelte5 branch, branched from #890

Issues:

@socket-security
Copy link

socket-security bot commented May 7, 2025

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

@benjaminknox benjaminknox force-pushed the bpk/svelte5 branch 6 times, most recently from afc9b0d to 565e004 Compare May 7, 2025 21:13
@benjaminknox benjaminknox changed the title Svelte 5 WIP: Svelte 5 May 7, 2025
export default {
extensions: ['.svelte'],
preprocess: sveltePreprocess({
preprocess: vitePreprocess({
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is vitePreprocess a valid alternative here to sveltePreprocess @fallaciousreasoning?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm it might be, seeing as its coming from vite-plugin-svelte

I think normally sveltePreprocess is for:

  1. SCSS ==> CSS
  2. TS ==> JS
    and that sort of thing, so wouldn't be surprised if Vite is handling that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As far as I can tell, it's handling it correctly so far!

Copy link

Choose a reason for hiding this comment

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

Hey there! 👋

Out of curiosity, I noticed the reference while scrolling through the issues, so I thought I might be able to help a bit with the setup of Storybook using @storybook/addon-svelte-csf with Svelte 5.

There's an answer from the Svelte maintainers team on whether you guys need svelte-preprocess.

From what I gathered from inspection of the project dependencies in package.json, you guys should be fine with using vite-preprocess.

Feel free to tag me if there are more questions! 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good to know! Yeah, seems like we're ok then, thanks for pointing it out!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sweet, thanks for chiming in with that!

Comment on lines 60 to 65
css: { code: rawCSS }
} = svelte.compile(Component, {
const svelteOutput = svelte.compile(Component, {
generate: 'ssr',
cssHash: () => 'REMOVE_ME'
})

const rawCSS = svelteOutput?.css?.code;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@AlanBreck @fallaciousreasoning

In Svelte 5, svelte.compile() returns css: null by default, which broke the destructuring here, but I've updated it to use optional chaining.

Could you confirm this is the right approach? Everything seems to work correctly in my testing.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks, @benjaminknox! When diffing the output of Tailwind plugins between this PR and the main branch, I'm seeing that :where() is being appended to almost all of the selectors. E.g.

--- tokens/tailwind/plugins/components/toggleComponent.js	2025-11-21 12:32:53
+++ tokens-svelte5/tailwind/plugins/components/toggleComponent.js	2025-11-21 12:10:56
@@ -2,7 +2,7 @@

 module.exports = plugin(function ({ addComponents, theme }) {
 addComponents({
-  ":root,:root[data-theme][data-theme=light]": {
+  ":root, :root[data-theme][data-theme=light]": {
     "--\\.leo-toggle_--foreground-color": "black"
   },
   ":root[data-theme][data-theme=dark]": {
@@ -39,7 +39,7 @@
     "--height": "24px",
     "--icon-size": "var(--leo-icon-size, 12px)"
   },
-  ".leo-toggle button": {
+  ".leo-toggle button:where()": {
     "--leo-icon-size": "var(--icon-size)",
     "all": "unset",
     "background": "var(--unchecked-color)",
@@ -50,26 +50,26 @@
     "transition": "background-color var(--duration) ease-in-out, box-shadow var(--duration) ease-in-out",
     "flexShrink": 0
   },
-  ".leo-toggle button:disabled": {
+  ".leo-toggle button:where():disabled": {
     "opacity": 0.5
   },
-  ".leo-toggle button:disabled>.thumb": {
+  ".leo-toggle button:disabled > .thumb:where()": {
     "background": "var(--thumb-disabled-color)"
   },
-  ".leo-toggle button:focus-visible": {
+  ".leo-toggle button:where():focus-visible": {
     "boxShadow": "var(--leo-effect-focus-state-offset)"
   },
-  ".leo-toggle button:hover:not(:disabled)": {
+  ".leo-toggle button:where():hover:not(:where():disabled)": {
     "--hover-bg": "var(--unchecked-color)",
     "background": "color-mix(in srgb, var(--hover-bg) 80%, var(--foreground-color))"
   },
-  ".leo-toggle button:hover:not(:disabled)[aria-checked=true]": {
+  ".leo-toggle button:hover:not(:where():disabled)[aria-checked=true]:where()": {
     "--hover-bg": "var(--checked-color)"
   },
-  ".leo-toggle button[aria-checked=false] .thumb": {
+  ".leo-toggle button[aria-checked=false]:where() .thumb:where()": {
     "--thumb-color": "var(--leo-color-white)"
   },
-  ".leo-toggle button .thumb": {
+  ".leo-toggle button:where() .thumb:where()": {
     "--unchecked-thumb-offset": "0px",
     "--checked-thumb-offset": "calc(var(--width) - var(--height))",
     "--thumb-offset": "var(--unchecked-thumb-offset)",
@@ -85,23 +85,23 @@
     "alignItems": "center",
     "justifyContent": "center"
   },
-  ".leo-toggle button .thumb.dragging": {
+  ".leo-toggle button:where() .thumb.dragging:where()": {
     "transition": "transform 0s ease-in-out, color var(--duration) ease-in-out"
   },
-  ".leo-toggle button .thumb .on-icon": {
+  ".leo-toggle button:where() .thumb:where() .on-icon:where()": {
     "transition": "opacity var(--duration) ease-in-out",
     "display": "flex",
     "opacity": 0
   },
-  ".leo-toggle button[aria-checked=true]": {
+  ".leo-toggle button[aria-checked=true]:where()": {
     "background": "var(--checked-color)"
   },
-  ".leo-toggle button[aria-checked=true] .thumb": {
+  ".leo-toggle button[aria-checked=true]:where() .thumb:where()": {
     "--thumb-offset": "var(--checked-thumb-offset)",
     "color": "var(--checked-color)",
     "--thumb-disabled-color": "var(--thumb-color)"
   },
-  ".leo-toggle button[aria-checked=true] .thumb .on-icon": {
+  ".leo-toggle button[aria-checked=true]:where() .thumb:where() .on-icon:where()": {
     "opacity": 1
   },
   "@media (prefers-color-scheme: dark)": {
diff --color -bur tokens/tailwind/plugins/components/tooltipComponent.js tokens-svelte5/tailwind/plugins/components/tooltipComponent.js
--- tokens/tailwind/plugins/components/tooltipComponent.js	2025-11-21 12:32:51
+++ tokens-svelte5/tailwind/plugins/components/tooltipComponent.js	2025-11-21 12:10:55
@@ -12,7 +12,7 @@
     "--border-width": "0px",
     "width": "fit-content"
   },
-  ".leo-tooltip .tooltip": {
+  ".leo-tooltip .tooltip:where()": {
     "background": "var(--background)",
     "color": "var(--text)",
     "boxShadow": "var(--shadow)",
@@ -21,7 +21,7 @@
     "border": "var(--border-width) solid var(--border-color)",
     "font": "var(--leo-font-default-regular)"
   },
-  ".leo-tooltip .tooltip .arrow": {
+  ".leo-tooltip .tooltip:where() .arrow:where()": {
     "position": "absolute",
     "background": "var(--background)",
     "width": "8px",
@@ -29,31 +29,31 @@
     "transform": "rotate(45deg)",
     "zIndex": -1
   },
-  ".leo-tooltip .tooltip.default .arrow": {
+  ".leo-tooltip .tooltip.default:where() .arrow:where()": {
     "border": "var(--border-width) solid var(--border-color)",
     "zIndex": 10
   },
-  ".leo-tooltip .tooltip.default .arrow.left,.leo-tooltip .tooltip.default .arrow.bottom": {
+  ".leo-tooltip .tooltip.default:where() .arrow.left:where(), .leo-tooltip .tooltip.default:where() .arrow.bottom:where()": {
     "borderBottom": "0"
   },
-  ".leo-tooltip .tooltip.default .arrow.right,.leo-tooltip .tooltip.default .arrow.bottom": {
+  ".leo-tooltip .tooltip.default:where() .arrow.right:where(), .leo-tooltip .tooltip.default:where() .arrow.bottom:where()": {
     "borderRight": "0"
   },
-  ".leo-tooltip .tooltip.default .arrow.right,.leo-tooltip .tooltip.default .arrow.top": {
+  ".leo-tooltip .tooltip.default:where() .arrow.right:where(), .leo-tooltip .tooltip.default:where() .arrow.top:where()": {
     "borderTop": "0"
   },
-  ".leo-tooltip .tooltip.default .arrow.left,.leo-tooltip .tooltip.default .arrow.top": {
+  ".leo-tooltip .tooltip.default:where() .arrow.left:where(), .leo-tooltip .tooltip.default:where() .arrow.top:where()": {
     "borderLeft": "0"
   },
-  ".leo-tooltip .tooltip.hero": {
+  ".leo-tooltip .tooltip.hero:where()": {
     "--background": "var(--leo-gradient-hero)",
     "--text": "var(--leo-color-container-background)"
   },
-  ".leo-tooltip .tooltip.info": {
+  ".leo-tooltip .tooltip.info:where()": {
     "--background": "var(--leo-color-button-background)",
     "--text": "var(--leo-color-container-background)"
   },
-  ".leo-tooltip .tooltip.mini": {
+  ".leo-tooltip .tooltip.mini:where()": {
     "--background": "var(--leo-color-neutral-60)",
     "--text": "var(--leo-color-neutral-10)",
     "--padding": "var(--leo-spacing-m)",
@@ -61,7 +61,7 @@
     "--radius": "var(--leo-radius-s)",
     "font": "var(--leo-font-x-small-regular)"
   },
-  ".leo-tooltip .tooltip.default": {
+  ".leo-tooltip .tooltip.default:where()": {
     "--border-color": "var(--leo-color-divider-subtle)",
     "--border-width": "1px"
   }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😅 Svelte5 adds :where styles to its scoped classes now!

Migration guide: Scoped CSS uses :where(...)

I just need to include that in the regex replace on line 67:
const css = rawCSS.replace(/:where\(\.REMOVE_ME\)|\.REMOVE_ME/g, '');

Awesome, thanks for testing that @AlanBreck!

@benjaminknox benjaminknox force-pushed the bpk/svelte5 branch 3 times, most recently from 28cda17 to 1004d96 Compare November 22, 2025 00:07
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

Successfully merging this pull request may close these issues.

4 participants