Above, Below, and Beyond Tech Talk

by Rahel Lüthy

October 24, 2019

A CSS Subgrid Example

Whenever I hear about a new technology or language feature, the first question I ask myself is: Which problem does it solve? So when I learned about the addition of subgrid to the CSS Grid Layout specification, I wanted to see a simple example which showed a subgrid-based solution to an actual problem. I found helpful videos and rock-solid-but-complicated layout arrangements, but nothing simple.

This post is the 3’-intro I was looking for:

A Simple Form

Suppose you are dealing with the following HTML form:

  <label for="name" class="field">
    <span class="label-text">Name</span>
    <input type="text" id="name" />
  <label for="email" class="field">
    <span class="label-text">Email</span>
    <input type="email" id="email" />
  <label for="message" class="field">
    <span class="label-text">A Looong Label</span>
    <input type="text" id="message" />

The existing CSS Grid layout already makes it easy to arrange individual fields:

.field {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-column-gap: 1em;
    margin-bottom: 1em;

As a result, each row dynamically respects the preferred width of its label:

While this is a good start, we would like to have something better:

A two-column definition, so that

This is exactly what the new subgrid feature is for: It matches up its grid lines to lines in the parent grid. We move the two-column grid layout definition to the parent form, and tell the fields to align along these tracks:

form {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-column-gap: 1em;

.field {
    display: grid;
    grid-column: span 2;
    grid-template-columns: subgrid;
    margin-bottom: 1em;

Caution: CSS Subgrid is only supported in Firefox (v71)

November 21, 2018

How we use React/Redux with TypeScript

Our team develops visual applications in the field of medical informatics. We started using React/Redux with TypeScript a few months ago. This post is a highly opinionated summary of best practices that evolved over time:

A bit of personal background, to give certain decisions more context: I have been developing user interfaces for over 20 years. Java and OOP have been loyal companions throughout most of this time. A few years ago, I started doing more and more FP, mostly in Scala & Elm, but also in Java (hi vavr 👋).

Our team members come from all sorts of backgrounds. When deciding on a web app stack, opinions varied a lot. We finally settled on React/Redux + TypeScript as a compromise – it turned out to be a good decision.

Favor Types Over Classes

Coming from an OOP background, it was comforting that TypeScript brings familiar OOP constructs to the table. However, TypeScript is based on a structural type system, which can confuse Java developers very quickly:

class Patient {

    firstName: string
    lastName: string

    constructor(firstName: string, lastName: string) {
        this.firstName = firstName
        this.lastName = lastName

const patient: Patient = { firstName: 'Ada', lastName: 'Lovelace' }

console.log(patient instanceof Patient) // false – seriously?! 🤔

I am sure that one could get used to the TypeScript way of working with classes. However, we somehow ended up not using classes at all 🤷. Instead, we exclusively model our data with read-only types:

type Patient = Readonly<{
    id: PatientId
    caseId: CaseId
    bed: BedId
    firstName: string
    lastName: string

Super concise and very safe to use.

Don’t Fear Stringly Types

Any experienced Java programmer avoids stringly types like the plague. In Java, this makes sense, they prevent the compiler from helping us find errors. The TypeScript compiler works differently, so be ready to embrace patterns which you would avoid in Java:

type Patient = Readonly<{
    gender: 'male' | 'female' | 'non-binary'

Code completion works perfectly fine here:

And the compiler detects errors flawlessly:

const smartStringHandling = (patient: Patient) => {
    if (patient.gender === 'whatever') { // compile error

To give a more advanced example, here’s how we base our action types, actions, and reducers on simple strings:


const ADD_MESSAGE = 'message/add'
const ADD_TODO = 'todo/add'


type Action = AddMessageAction | AddTodoAction

type AddMessageAction = Readonly<{
    type: typeof ADD_MESSAGE
    message: Message

type AddTodoAction = Readonly<{
    type: typeof ADD_TODO
    todo: Todo


const reducer = (state: State, action: Action): State => {
    switch (action.type) {
        case ADD_MESSAGE:

            // 🎉 this would require a cast in Java
            const message = action.message

            return {
                messages: state.messages.push(message)
        case ADD_TODO:
            return {
                todos: state.todos.push(action.todo)

Favor Composition Over Inheritance

As mentioned above, we don’t really use TypeScript’s OOP features, so using inheritance has never been very tempting. Instead, we often use a mix of composition, union types, and intersection types to foster code re-use:

type Patient = Readonly<{
    address: Address // Composition
    gender: 'male' | 'female' | 'non-binary' // Union Type

type Displayable = Readonly<{
    displayName: string

type DisplayablePatient = Patient & Displayable // Intersection Type

Immutability FTW

We haven’t seen many runtime errors, but the ones that occurred were all caused by inconsistent mutations. That’s why we settled on using the immutable collections library to make all our state completely read-only:

import { Map } from 'immutable'

type State = Readonly<{
    bedByPatient: Map<PatientId, BedId>

Nominal Typing

Using type aliases for your identifiers seems very convenient. No need for extra wrapping, and very readable code:

type PatientId = string
type BedId = string

type State = Readonly<{
    bedByPatient: Map<PatientId, BedId>

Unfortunately, things look more type-safe than they are. Aliases are nothing more than what their name implies: they are simple synonyms. Any string can be used in place of a PatientId or BedId – and vice versa:

const state: State = {
    bedByPatient: Map<PatientId, BedId>()

// Compiles just fine, which is NOT what we want
state.bedByPatient.set('foo', 'bar')

We want to have types which can be distinguished by the compiler because they have different names, even though they share the same structure (a string). This is known as “nominal typing”. The TypeScript Deep Dive Book gives a good list of nominal typing patterns.

We are using the enum-based brand pattern to get the desired compile-time safety:

enum PatientIdBrand {}
type PatientId = PatientIdBrand & string

enum BedIdBrand {}
type BedId = BedIdBrand & string

type State = Readonly<{
    bedByPatient: Map<PatientId, BedId>

const state: State = {
    bedByPatient: Map()

// Compile error:
// Argument type '"foo"' is not assignable to parameter of type 'PatientId'
state.bedByPatient.set('foo', 'bar')

Explicit Types Enhance Readability

While it is often possible to not specify types explicitly, they still sometimes enhance code readability (and IDE completion, for that matter). Container components are a good example: they involve a lot of “plumbing”, where input/output types have to match, so explicit types are a plus here. This is how our container components tend to look:

type Props = Readonly<{
    patientId: PatientId

type FromStateProps = Readonly<{
    patient: Patient

const mapStateToProps = (state: State, props: Props): FromStateProps => {
    const patient = getPatient(state, props.patientId)
    return {

type FromDispatchProps = Readonly<{
    onMouseEnter: () => void
    onMouseOut: () => void

const mapDispatchToProps = (dispatch: Dispatch<PatientsAction>, props: Props): FromDispatchProps => {
    return {
        onMouseEnter: () => dispatch(selectPatients(ImmutableList.of(props.patientId))),
        onMouseOut: () => dispatch(selectPatients(ImmutableList()))

export default connect(mapStateToProps, mapDispatchToProps)(ExampleComponent)

TSS: CSS + TypeScript = 😍

As a developer, CSS has always been the scary corner of my applications. It uses a global namespace, you cannot use variables, and it’s almost impossible to tell which code is even in use at all. So you end up treating your CSS very differently from the rest of your code: no refactorings, no re-use, no clean-up.

We are using Material-UI in all our projects, so it did not take much convincing to also use their styling solution. It uses JSS at its core and has excellent TypeScript support. This is how a basic component looks:

import { createStyles, withStyles, WithStyles } from '@material-ui/core'
import * as React from 'react'

const styles = createStyles({
    root: {
        backgroundColor: 'steelblue'

type Props = Readonly<{
    text: string
}> & WithStyles<typeof styles>

const ExampleComponent = ({ text, classes }: Props) =>
    <div className={classes.root}>{text}</div>

export default withStyles(styles)(ExampleComponent)

Look Ma, No Semicolons!

And finally, a good practice that is not specific to React nor TypeScript: make your code prettier! We use husky to kick off code formatting before each git commit. Here’s our current configuration:


  "tabWidth": 4,
  "useTabs": false,
  "semi": false,
  "singleQuote": true,
  "printWidth": 120

Thanks for reviewing this post, Ben!

May 24, 2018

React SVG Tooltips

SVG has built-in support for tooltips through its <title> element. However, the rendered text looks very basic and cannot easily by styled:

Tooltips are an important design element when creating information-heavy, visual applications. They allow keeping the user interface clean, providing information only when needed. As Shneiderman (1996) put it in his famous visual information-seeking mantra:

Overview first, zoom and filter, then details-on-demand
Overview first, zoom and filter, then details-on-demand
Overview first, zoom and filter, then details-on-demand

Tooltips cover the details-on-demand aspect. However, in order to provide such details in an appealing way, built-in SVG tooltips are often not sufficient.

SVG Tooltips

There’s actually a pretty good technology out there to design appealing graphical UI elements: SVG! It is way superior to simple text boxes.

In an ideal SVG world, tooltips would:

  1. Be specific to an element
  2. Be visible on demand (mouse hovering)
  3. Support fully customizable SVG contents
  4. Appear always on top

Good News: If you’re using React, I have got you covered! Meet react-svg-tooltip, my npm package that addresses all SVG tooltip needs.

Intro to react-svg-tooltip

The library offers a Tooltip component which can be embedded in any SVG element hierarchy:

import * as React from 'react';
import { Tooltip } from 'react-svg-tooltip';

const App = () => {

    const circleRef = React.createRef<SVGCircleElement>();

    return (
        <div className='App'>
            <svg viewBox='0 0 100 100'>
                <circle ref={circleRef} cx={50} cy={50} r={10} fill='steelblue'/>
                <Tooltip for={circleRef}>
                    <rect x={2} y={2} width={10} height={5} rx={.5} ry={.5} fill='black'/>
                    <text x={5} y={5} fontSize={2} fill='white'>Yay!</text>

export default App;

Edit pk7p4y9v3q

The component covers all requirements listed above:

  1. Its for property accepts a reference to an element which serves as the mouse trigger
  2. All mouse listener handling is happening behind the scenes
  3. Arbitrary SVG can be used as tooltip contents. In fact, the library itself does not provide an actual tooltip. Instead, it gives you a 0-based coordinate system, so you can place your favorite SVG elements in whichever style suits your needs.
  4. Contents are attached to the root svg element (using a React portal behind the scenes). Thereby your tooltip will always be rendered last, i.e. always on top.

As usual, all code is on GitHub, feedback is very welcome, and PRs are highly appreciated!

Older Posts » Archive