You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While exploring new ways of providing theming flexibility to a component library, I noticed there isn't an easy way to replace or unload a component's styles without adding extra steps for the developer consuming the library (described in 'alternatives' below).
I have a few unrefined ideas, and would appreciate any other novel solutions to add to this discussion.
Since the component library comes with styles, I feel the 'happy path' would be importing components onto a page and setting up a single library-provided global.css file for typography and resets. Users who want to supply their own themes would ideally only have to encounter some trivial configuration.
Proposal 1: pass module paths to compiler options
User imports component onto page. By default, it comes with CSS in its <style> and works without extra configuration.
User can 'unload' all component styles by providing a compiler options such as:
constconfig={css: [{'module-name/ComponentName.svelte': 'none'},// one component{'library-name','none'}// entire library]}
This has an all-or-nothing drawback; we cannot specify compiler options on a per-instance-of-component basis.
Proposal 2: dynamic <svelte:options>
I thought about using setContext via a wrapper component to pass context to set the css option in <svelte:options>, but I realize <svelte:options> should only accept string literals since it cannot know dynamic settings at compile time:
Here's how dynamic <svelte:options> could have looked
+page.svelte*
<script>import{Button,Theme}from'component-library'</script><ThemeoverrideCSS><Button>Do the thing</Button></Theme>
Or perhaps it can be made possible to wrap individual components with <svelte:options> so that a single instance of the component can be changed, while remaining instances use provided styles.
<svelte:optionscss="none"><Button>Button without CSS</Button></svelte:options><Button>Button with CSS</Button>
Though this would necessarily create a copy of <Button> at build time. Button styles can be overridden with selectors like :where(.btn) so that they do not impact plain usage of <Button>.
But this has the drawback of shipping all bytes of CSS whether or not they're being used.
Alternatives considered
<style> is completely unused in every component in the library, and users must either import library-supplied CSS or SCSS, or their own CSS.
Only expose certain styles via CSS variables so that users may override via --style-props. Any custom theming would have to be provided with global CSS selectors that have high specificity.
Using setContext to conditionally import() .css files; but this loads styles onto a page that would impact all instances of a component when only 1 particular instance is meant to be overridden.
Importance
nice to have
The text was updated successfully, but these errors were encountered:
Describe the problem
While exploring new ways of providing theming flexibility to a component library, I noticed there isn't an easy way to replace or unload a component's styles without adding extra steps for the developer consuming the library (described in 'alternatives' below).
Relates to #6859, #1550.
Describe the proposed solution
I have a few unrefined ideas, and would appreciate any other novel solutions to add to this discussion.
Since the component library comes with styles, I feel the 'happy path' would be importing components onto a page and setting up a single library-provided
global.css
file for typography and resets. Users who want to supply their own themes would ideally only have to encounter some trivial configuration.Proposal 1: pass module paths to compiler options
<style>
and works without extra configuration.This has an all-or-nothing drawback; we cannot specify compiler options on a per-instance-of-component basis.
Proposal 2: dynamic
<svelte:options>
I thought about using
setContext
via a wrapper component to pass context to set thecss
option in<svelte:options>
, but I realize<svelte:options>
should only accept string literals since it cannot know dynamic settings at compile time:Here's how dynamic <svelte:options> could have looked
+page.svelte*
Button.svelte
Or perhaps it can be made possible to wrap individual components with
<svelte:options>
so that a single instance of the component can be changed, while remaining instances use provided styles.Though this would necessarily create a copy of
<Button>
at build time. Button styles can be overridden with selectors like:where(.btn)
so that they do not impact plain usage of<Button>
.Proposal 3: dynamic
<style>
Have
<style>
load conditionally:But this has the drawback of shipping all bytes of CSS whether or not they're being used.
Alternatives considered
<style>
is completely unused in every component in the library, and users must either import library-supplied CSS or SCSS, or their own CSS.--style-props
. Any custom theming would have to be provided with global CSS selectors that have high specificity.setContext
to conditionallyimport()
.css files; but this loads styles onto a page that would impact all instances of a component when only 1 particular instance is meant to be overridden.Importance
nice to have
The text was updated successfully, but these errors were encountered: