Svelte

@NZZ Editorial Tech

Agenda

Who are we?

What is Svelte?

Why and how do we use it?

NZZ Editorial Tech Team

Sharon Funke

Manuel Roth

Philip Küng

Roman Karavia

What do we do?

Toolbox Q

  • allows reporters and editors to create simple graphics and interactive elements for their stories. 

What do we do?

  • custom made dataviz
  • interactive stories

Svelte

Component framework like Vue, React

Vue

  • declarative state-driven code
  • browser converts statements to DOM operations

Svelte

  • runs at build time
  • converts components into imperative code that updates DOM

Svelte introduction

Svelte @ Editorial Tech

Requirements for our custom elements

  • Work efficiently on projects that are completed within a few weeks

  • Decent page/visualization load performance

  • Integration with CSS of embedding page

  • Limit dependency on embedding page
    (e.g. Javascript-Framework)

  • 2-3 different versions depending on embedding width

 

Embedding page: The page that contains the custom element

Parenthesis: Why not iframe?

  • Dynamic height depending on content

  • Content is not always a rectangle
    (e.g. scrollytelling, popover)

  • Share resources (fonts, CSS) with embedding page

  • Content of iframes is loaded last

Example: Overview

React to input

Switch component

<style>
  .switch-container {
    display: flex;
    justify-content: center;
  }
</style>

<div class="switch-container">
  <div class="s-input-switch s-input-switch--secondary">
    <input
      type="checkbox"
      bind:checked={onlySwingStates} />
    <label>alle Staaten</label>
    <label>nur «Swing States»</label>
  </div>
</div>

Switch component

.switch-container.svelte-fv6lk3 {
  display: flex;
  justify-content: center;
}

Hexagon bar component

<svg viewBox={viewBox}>
  {#each getHexagons(onlySwingStates)
   as { color, width, type, x, y }}
    <Hexagon
      {color}
      {width}
      {type}
      {x}
      {y} />
  {/each}
</svg>

Hexagon bar DOM

Adapt to container width

Adapt to container width

<div bind:clientWidth={containerWidth}>
  <svg viewBox={viewBox}>
    {#each getHexagons(onlySwingStates, containerWidth)
     as { color, width, type, x, y }}
      <Hexagon
        {color}
        {width}
        {type}
        {x}
        {y} />
    {/each}
  </svg>
</div>

Example: Conclusion

  • Interactive visual element thanks to input/width bindings and reactive updates

  • Custom CSS + style guide

  • Compressed Javascript bundle size: 30 KiB

  • No Javascript-dependency on embedding page

 

See full example on nzz.ch/visuals

Thanks!

👩‍💻

📊

Copy of Svelte @ Editorial Tech

By rkaravia

Copy of Svelte @ Editorial Tech

  • 208