Code Monkey home page Code Monkey logo

svelte-themer's Issues

Is global the right way to go?

This could be done with a wrapping element that does not affect the dom's structure beyond css. A mix of setProperty() and removeProperty() could be used to handle the theme transitions.

I do like your object storage for variable settings. A lot cleaner than what I was working on.

Possible benefits:
Global default variables could be defined in script to handle non-js systems. (rare to be sure)
-- global defaults also allow for partial rewrites of the variables. (i.e. no need to rewrite media breakpoints unless desired.)
Applying to a wrapping element allows for the nesting of variable settings. Perhaps modals look different.
Named wrappers could still use localStorage for defaults.
This allows for easier real-time changes with user-defined themes.
Property setters make the code cleaner since you don't have to build complex strings beyond your tiered variable names.

Listed below is a simple example. Everything in the slot would see the variable --txtColor as red.
display: contents; removes the wrapper from creating display issues (grids, etc).

<script>
	import { onMount } from 'svelte';
	let el;	
	onMount(() => {
		el.style.setProperty('--txtColor','red')
	});
	
</script>

<div bind:this={el} style="display: contents; ">
	<slot ></slot>
</div>

feat(next): themes object instead of array

// themes.js
export default {
  themer: {
    light: {},
    dark: {},
    colors: {},
  },
  forest: {
    light: {},
    dark: {},
    colors: {},
  },
  solarized: {
    light: {},
    dark: {},
    colors: {},
  },
}

per container theme?

This is super useful!

I have a very special case where I might want to theme within containers. Do you know if it's possible to add a container flag such as

.container > :global(svg)

I am not sure how one would inject the .container > :global part...

The exampIe got this from is here:

https://svelte.dev/repl/4e04a629ab934863b09c4ee3f69d99a1?version=3.8.1

I'll try to check out your code to see if I can solve it but if you have a quick idea how to do it I'd appreciate it!!

Cheers, /Jon

The following packages did not export their

Setup info

I have installed through yarn add -D svelte-themer, however I have also tried adding as a normal dependency and nothing changed.

Errors

At build time I get the following

[rollup-plugin-svelte] The following packages did not export their `package.json` file so we could not check the "svelte" field. If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.

- svelte-themer

When I try to access the website I get the following:

Error: <ThemeWrapper> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules
    at validate_component (/.../project/__sapper__/dev/server/server.js:95:15)
    at /.../project/__sapper__/dev/server/server.js:15381:3
    at Object.$$render (/.../project/__sapper__/dev/server/server.js:113:22)
    at /.../project/__sapper__/dev/server/server.js:15438:40
    at $$render (/.../project/__sapper__/dev/server/server.js:113:22)
    at Object.render (/.../project/__sapper__/dev/server/server.js:121:26)
    at /.../project/__sapper__/dev/server/server.js:20314:49
    at Generator.next (<anonymous>)
    at fulfilled (/.../project/__sapper__/dev/server/server.js:15757:58)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
Error: <ThemeWrapper> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules
    at validate_component (/.../project/__sapper__/dev/server/server.js:95:15)
    at /.../project/__sapper__/dev/server/server.js:15381:3
    at Object.$$render (/.../project/__sapper__/dev/server/server.js:113:22)
    at /.../project/__sapper__/dev/server/server.js:15438:40
    at $$render (/.../project/__sapper__/dev/server/server.js:113:22)
    at Object.render (/.../project/__sapper__/dev/server/server.js:121:26)
    at /.../project/__sapper__/dev/server/server.js:20314:49
    at Generator.next (<anonymous>)
    at fulfilled (/.../project/__sapper__/dev/server/server.js:15757:58)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
Error: <ThemeWrapper> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules
    at validate_component (/.../project/__sapper__/dev/server/server.js:95:15)
    at /.../project/__sapper__/dev/server/server.js:15381:3
    at Object.$$render (/.../project/__sapper__/dev/server/server.js:113:22)
    at /.../project/__sapper__/dev/server/server.js:15438:40
    at $$render (/.../project/__sapper__/dev/server/server.js:113:22)
    at Object.render (/.../project/__sapper__/dev/server/server.js:121:26)
    at /.../project/__sapper__/dev/server/server.js:20314:49
    at Generator.next (<anonymous>)
    at fulfilled (/.../project/__sapper__/dev/server/server.js:15757:58)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)

improve release notes and release automation

Description

Provide readable release notes with thanks to contributors.

  • fix github actions (currently the script to release is commented out, ensure versions are updated)
  • add "thank you" section for contributors

Uncaught TypeError: ThemeWrapper is not a constructor

Hi.

Using sveltejs/template with nothing modified except svelte-themer ^0.4.8 installed as a dev dependency.

// App.svelte
<script>
	import { ThemeWrapper, ThemeToggle } from 'svelte-themer'
</script>
  
<ThemeWrapper>
	<main>
		<h1>svelte themer</h1>
		<ThemeToggle />
	</main>
</ThemeWrapper>

<style>
	:global(html) {
		background-color: var(--theme-colors-background, initial);
		color: var(--theme-colors-text, initial);
	}
</style>

npm run dev

In the browser console all I get is

Uncaught TypeError: ThemeWrapper is not a constructor
    create_fragment bundle.js:2449
    init index.mjs:1500
    App bundle.js:2518
    app main.js:3
    <anonymous> bundle.js:2536

I'm a Svelte noob, am I missing something?

Thank you for your consideration.

Themer breaks page.js routing

So my problem is that when I try to use this package it somehow breaks my page.js routing but it works if I refresh the page after clicking the link for the page in the navbar. Tried it on npm run dev and npm run build

Code:

// App.svelte
<script>
  import router from "page";
  import { ThemeWrapper, ThemeToggle } from "svelte-themer";

  import Home from "./pages/Home.svelte";
  import Files from "./pages/Files.svelte";
  import ThemesPage from "./pages/Themes.svelte";
  import Account from "./pages/Account.svelte";

  import Nav from "./components/Nav.svelte";
  import Footer from "./components/Footer.svelte";

  let page;

  router("/", () => (page = Home));
  router("/files", () => (page = Files));
  router("/themes", () => (page = ThemesPage));
  router("/account", () => (page = Account));

  router.start();
</script>

<ThemeWrapper>
  <Nav />
  <svelte:component this={page} />
  <ThemeToggle />
  <Footer />
</ThemeWrapper>
// Nav.svelte
<nav class="pa3 pa4-ns">
  <div class="tc pb3">
    <a
      class="fas fa-folder-open link dim f6 f5-ns dib mr3 pointer"
      href="/">home</a>
    <a
      class="fas fa-folder-open link dim f6 f5-ns dib mr3 pointer"
      href="/files">files</a>
    <a
      class="fas fa-folder-open link dim f6 f5-ns dib mr3 pointer"
      href="/themes">themes</a>
    <a
      class="fas fa-folder-open link dim f6 f5-ns dib mr3 pointer"
      href="/account">account</a>
  </div>
</nav>

Also I get this error in the console after importing this package and I don't really know what may be causing it

Uncaught Error: Function called outside component initialization
    get_current_component index.js:119
    setContext index.js:129
    instance index.js:514
    flush index.mjs:723
    init index.mjs:1477
    App main.js:5818
    app main.js:3
    <anonymous> main.js:5835
index.js:119:18

can't reproduce it :/

using svelte basic template...

Folder structure: ⤵️

image

package.json ⤵️

image

main.js ⤵️

image

themes.js ⤵️

image

App.svelte ⤵️

image

Results:

Light ⤵️

image

Dark ⤵️

image

Is there something I'm missing?

clean up logic, remove JS consumption logic

  • move to reactive and afterUpdate for theme setter
  • switch to use theme.css file (must be linked to index.html and available)
    • would users rather feed themes.js OR feed theme.css

Uncaught TypeError: getContext(...) is undefined

Hello,

svelte-themer 0.4.9 as a dev dependency, sveltejs/template.

Getting an error because getContext('theme') is undefined when trying to implement my own theme toggle button. Note that using the provided ThemeToggle everything worked.

// App.svelte
<script>
	import { ThemeWrapper } from 'svelte-themer'
	import ThemeButton from './components/ThemeButton.svelte'
	import themes from './themes.js'
</script>
  
<ThemeWrapper themes="{themes}">
	<main>
		<p>Hello</p>
		<ThemeButton />
	</main>
</ThemeWrapper>

<style>
	:global(html) {
		background-color: var(--theme-colors-background, initial);
		color: var(--theme-colors-text, initial);
	}
</style>
// components/ThemeButton.svelte
<script>
    import { getContext } from 'svelte'
    let { toggle, current, theme } = getContext('theme')
</script>

<button on:click="{toggle}">
    <slot>{$current}</slot>
</button>

Am I doing anything wrong?

Thanks

add preprocessor

Description

Add a preprocessor (ref #32) to generate CSS file for external consumption or preprocess into the ThemeWrapper style block (with global styles), negating the need for the current JS-based solution to load on mount.

Thoughts

  • how do we determine whether preprocessor is in use (e.g. when do we not execute the onMount behavior)?
  • do we add styles to ThemeWrapper style block with :global(html) or :root? Does this have unintended behaviors with initial load?
  • add an option to "eject" the created stylesheet for external consumption

feat: support nested theme keys

Support nested theme keys for supplied theme.

When supplied:

const themes = [{
  name: 'light',
  colors: {
    grey: {
      _: '#8b868c',
      dark: '#5a535b',
    },
  },
}]

CSS Variables should generate as

--theme-light-grey: #d46a6a;
--theme-light-grey-dark: #5a535b; 

This should not change the functionality of supplying underscores in keys (i.e. primary_dark) as this is more for added flexibility and plans of adding base theme props.

feat: support `prefers-color-scheme`

Support prefers-color-scheme with window.matchMedia() to determine user theme on first visit.

Current Behavior:

on visit, active theme choice is decided by

  1. local storage (if exists)
  2. fallback to first theme in themes array

Proposed Behavior:

on visit, active theme choice is decided by

  1. local storage (if exists)
  2. prefers-color-scheme choice (will be light or dark and themes should have a palette with one of these names)
  3. fallback to first theme in themes array

Changes

  • add new prop to disable proposed behavior, something like disablePrefersColorScheme? Forcing the new behavior may cause unwanted UX adjustments
  • add test to prove new behavior and prop are working as intended

Dependence on window

Hello Jose,

Great writeup on svelte theming! I came here after I failed to persist the themes myself, but it looks like I'll face the same issue here. If I'm using Sapper, or any other kind of SSR, then I won't have access to the window variable in my code (or localStorage or sessionStorage ...). Is there any way to remove that dependency? I see you use it to check the preferred mode of the browser. I noticed your localStorage is properly set inside onMount however!

Dark mode on per theme basis

First off, nice job on the theme provider 👏 I like the linear approach to themes, but I was curious about your thoughts on having dark mode styling on a per theme basis v. independent themes (i.e., "light" and "dark")?

Instead of doing this:

[{
  name: 'light',
  colors: {
    text: '#282230',
    background: '#f1f1f1',
    primary: '#01796f',
    primary_dark: '#016159',
    secondary: '#562931',
  }
}]

You could do something like this:

[{
  name: 'forest',
  defaults: {
    colors: {
      text: '#282230',
      background: '#f1f1f1',
      primary: '#01796f',
      primary_dark: '#016159',
      secondary: '#562931',
    }
  },
  dark: {
    colors: {
      background: '#000'
    }
  }
}]

The defaults would contain all of theme variables, and dark would contain only the values you would want to override/modify.

You could expose a new mode toggle and allow each theme to control it's own dark mode presentation.

I'll create a PR with these changes.

feat: support custom prefix for CSS variables

Support using a custom prefix for CSS variables through a prefix prop on ThemeWrapper

  • add PREFIX constant with value of theme in module scope of ThemeWrapper
  • add prefix prop with default PREFIX
  • add tests

Behavior:

  • if prefix={"vendor"}, CSS variables will look like --vendor-...
  • if prefix={null}, CSS variables will look like --...
  • if prefix={""}, ThemeWrapper should throw an error "Invalid prefix string supplied"
  • if prefix={" "}, ThemeWrapper should throw an error "Invalid prefix string supplied" (be sure to .trim() prefix string)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.