Including a cell when imported

(cross-posted from Slack)

Is there a way to automatically include a specific cell when a notebook is imported? I currently have a mutable isDesktop cell that is set in a separate cell so anything that uses isDesktop is only rerendered when the width passes the breakpoint rather than on every resize. However, this doesn’t work when cells that use isDesktop are imported into another notebook. My notebook:

1 Like

The problem isn’t the mutable per se, but the use of side-effects in an anonymous cell to assign the mutable:

{
  const newVal = width > 700;
  if (newVal !== isDesktop) {
    mutable isDesktop = newVal;
  }
}

Since this cell is anonymous, it can’t be imported into another notebook, so isDesktop will always be true on import. You could fix this by giving the cell a name, but then every notebook that wants to use these sidenotes will also need to embed the anonymous cell that applies the side-effect in order to run it (because imports are lazy).

I recommend not using a mutable here, and defining isDesktop as a generator instead. This way, your module can depend on isDesktop having the correct value, and anyone who imports your notebook won’t need to care about how it works internally.

The simplest thing to do would be:

isDesktop = width > 700

But if you don’t want isDesktop changing as the window is resized, you can optimize it using Generators.observe (which is exactly how the built-in width is implemented):

isDesktop = Generators.observe(notify => {
  let wide = notify(document.body.clientWidth > 700);
  function resized() {
    const w = document.body.clientWidth > 700;
    if (w !== wide) notify(wide = w);
  }
  addEventListener("resize", resized);
  return () => removeEventListener("resize", resized);
})
2 Likes

there are some width thingums here:

1 Like