Code Bug Fix: How to filter a svelte store using a dynamic filter

Original Source Link

I have a derived store which has to filter an entries object using HTML selects for the filter. Now I introduced an extra filter store (observable) to force the derived store callback to run when the filter store changes.

But is it possible to trigger the callback in the derived store below without the filter store when the filter changes? Do I need this extra store here?
The below code works fine. I’am curious.

import { writable, derived } from 'svelte/store';
import { entries } from './../stores/entries.js';

export const filter = writable({
  // to update filter use: $filter.kind = ... 
  // or: filter.update(o => Object.assign(o, {kind: .., batchId: ...}));
  batchId: 'all',
  kind: 'all',

let list, total;

export const view = derived(
  [filter, entries], 
  ([$filter, $entries], set) => {

    total = 0;

    if ($entries) {
      // filter by HTML selects: kind, batchId
      list = Object.keys($, key) => {
        if ((['all', $[key].description.kind].includes($filter.kind))
          && (['all', $[key].parentId].includes($filter.batchId))) {
            total += $[key].grossValue;
        return a;  
      }, []);
      set({list, total});

    return () => {
  }, null

You could extract the logic from the derived store into a function / object you control yourself, with an API to manually trigger an update… But that would not be a good idea. That would break some encapsulation for no benefit and all.

Your writable + derived solution is, IMO, the most straightforward and elegant solution. It explicitly outlines data dependencies, and cleanly separate concerns, with no arcane code involved. It also provides Svelte what it needs to monitor changes, and manages subscriptions automatically for you, with the finest granularity.

This is a nice pattern, and it is perfectly appropriated for your use case. I would keep it like this.

Tagged : / /

Code Bug Fix: Svelte (routify) + rollup: not watching for css changes in /static

Original Source Link

I want to be able to watch for changes in /static (for example, on global.css)

I am using the following code to watch for changes on my static directory:

        watch: {
            clearScreen: false,
            include: ["static/**", "src/**"]

I also tried calling add “css” to the –extensions option in routify cli:
routify -D --extensions svelte,html,md,css

However nothing works, and I can’t seem to trigger a rebuild on changes to css files… Any advice?


Rollup watches only the files that are included in your bundle (i.e. that have been imported in a file directly or indirectly imported from your entry point — input in your Rollup config). Said otherwise, files that are not imported but merely referenced in index.html can’t rely on Rollup watcher. We would need a copy plugin with its own file watcher, but currently there are none.

If it’s just for CSS assets, you can use rollup-plugin-postcss and import './global.css' from your main.js instead of having it directly in the static directory. Here’s an article with detailed explanations on how to do just that.

Well, since I started writing this answer, there is now a copy plugin with watch capability: rollup-plugin-copy-watch.

So if you need more than just CSS, or if you don’t want to include your global.css into your build process, you can use that instead.

Install in your project:

yarn add -D rollup-plugin-copy-watch

In your rollup.config.js, change the import:

// import copy from 'rollup-plugin-copy'
import copy from 'rollup-plugin-copy-watch'

And add a watch option to the copy plugin (also added verbose in the example, to ensure it works):

        targets: [
          { src: staticDir + '/**/!(__index.html)', dest: distDir },
          { src: `${staticDir}/__index.html`, dest: distDir, rename: '__app.html', transform },
        copyOnce: true,
        flatten: false,

        watch: staticDir,
        verbose: true,

Tagged : /

Code Bug Fix: How to define a conditional transition in Svelte?

Original Source Link

In Svelte we can add transitions with:

<div in:fade={{duration: 150}}>...</div>

It’s also possible to have conditional HTML attributes with:

<input disabled={null}>

This doesn’t work with transitions:

<div in:fade={null}>...</div>

Which throws this error as it expects a config object:

Cannot read property ‘delay’ of null

So what would would be the appropriate way of adding a conditional transition in Svelte?

Other than:

{#if animate}
    <div in:fade></div>

You can pass in a configuration object to the transition with a duration of 0 (effectively instantaneously)

    import { fade } from 'svelte/transition'

    export let animate

<div in:fade={{ duration: animate ? 500 : 0 }}>

Tagged :