React’s new context (React 16.3.0)

One of the new things in React 16.3.0 is a new context API:

Typically, data in a React application is passed top-down (parent to child) via props. But sometimes it’s useful to pass values through multiple levels of abstraction without involving each intermediate. Examples include a locale, or a UI theme.

Context in React provides a mechanism for a child component to access a value in an ancestor component. From now on we’ll refer to the ancestor as the provider and the child as the consumer.

Below is an example on how to use it. Create a context first, and then create a Provider along with one (or more) Consumer(s) that will be able to read the data from the Provider using its own context prop.

import React from 'react';
import {render} from 'react-dom';

const styles = {
  dark: {
    backgroundColor: 'black',
    color: 'white',
  },
  light: {
    backgroundColor: 'white',
    color: 'black',
  },
};

// 1. Create a context
const ThemeContext = React.createContext();

// 2. Our app contains a provider for ThemeContext.
// Anything we store into the ThemeContext will be accessible to a consumer
class App extends React.Component {
  state = {
    theme: 'light'
  };

  toggleTheme = () => {
    this.setState(({ theme }) => ({
      theme: theme === 'light' ? 'dark' : 'light',
    }));
  }

  render() {
    return (
      <ThemeContext.Provider value={this.state}>
        <button onClick={this.toggleTheme}>toggle theme</button>
        <ThemableDiv />
      </ThemeContext.Provider>
    );
  }
}

// 3. A consumer with access to the data contained in ThemeContext
class ThemableDiv extends React.PureComponent {
  render() {
    return(
      <ThemeContext.Consumer>
        {context => <div style={styles[context.theme]}>{context.theme}</div>}
      </ThemeContext.Consumer>
    );
  }
}

render(<App />, document.getElementById('root'));

In case you want to play with the code:

Note: The example is based on an example by Kent C. Dodds.

Original Content , Leave a comment

Generate code screenshots straight from within Visual Studio Code with Polacode

Remember those really nice screenshots of code, generated with Carbon? Polacode is an extension for Visual Studio Code that offers (somewhat) the same functionality directly inside the IDE.

Polacode – Polaroid for your Code →

Elsewhere , , Leave a comment

Easily share Wifi Passwords with friends on iOS 11

When a nearby contact with an iOS device wants to connect to a hotspot you are familiar with (e.g. your device knows the password), you can easily share the password with their device:

It’s small additions like this that put a smile on my face 🙂

Elsewhere , , , Leave a comment

Ordering tabular data with only CSS thanks to CSS Variables

Neat experiment by Roman Komarov in which he orders tabular data using just HTML/CSS, thanks to the use of CSS Custom Properties (CSS Variables):

Each cell of each row is given a specific value to sort on.

<tr
  class="table-row"
  style="
    --order-by-published: 161221;
    --order-by-views: 2431;
  ">
  <th class="table-cell">
    <a href="http://kizu.ru/en/fun/controlling-the-specificity/">Controlling the Specificity</a>
  </th>
  <td class="table-cell">2016-12-21</td>
  <td class="table-cell">2 431</td>
</tr>

When selecting a specific column, that value is aliased to the --order CSS Variable

#sort-by-published:checked ~ .table > .table-body > .table-row {
  --order: var(--order-by-published);
}

#sort-by-views:checked ~ .table > .table-body > .table-row {
  --order: var(--order-by-views);
}

And that --orderorder of each row:

.table-row {
  order: var(--order);
}

Add in an extra condition to use in the calculation and you can achieve a reverse sorting:

.table-row {
  order: calc(var(--order) * var(--sort-order, -1));
}

Very nice!

As Roman notes though, this isn’t great when it comes to a11y:

This so­lu­tion is not re­ally a so­lu­tion, but an ex­per­i­ment, and can be bad for ac­ces­si­bil­ity — right now its not pos­si­ble to re­order stuff in a way it would be ac­ces­si­ble with key­board (with­out con­fus­ing tele­port­ing fo­cus) or screen read­ers.

Roman Komarov: Variable Order →

Elsewhere , , Leave a comment

PWAs are coming to iOS 11.3: Cupertino, we have a problem

Recently it was announced that iOS 11.3 and macOS 10.13.4 will include Service Workers, opening up the way for PWAs on iOS (and potentially macOS too, following lead of Microsoft here).

☝️ If you don’t want to download the macOS 10.13.4 beta you can alternatively download Safari Technology Preview (> 48) for use with your current macOS install.

Great news indeed, yet as Maximiliano Firtman documented there are quite a few caveats right now. Some might get fixed, yet some others won’t. One of the bigger issues I find worrying is the fact that you can end up with different versions of one and the same PWA, depending on the context you are running it in:

On Safari, on each app’s Web view, and home screen web apps, the engine doesn’t share Service Workers nor the Cache Storage, which means the user might end with several copies of all the files for the PWA on the same device.

PWAs are coming to iOS 11.3: Cupertino, we have a problem →

Elsewhere , , , Leave a comment

React Native Snoopy, a profiling tool for React Native

The React Native bridge is the hub where communication between the Javascript and the Native world happen. Optimizing and catching unexpected (bad) communications can make or break your performance. Being that central and sensitive place, it made sense to have tooling built around it.

Snoopy is a profiling tool for React Native, that lets you snoop on the React Native Bridge using the MessageQueue spy feature. With Snoopy you can tame a stream of events, using Rx and a few built-in goodies, to locate performance hogs, problems, and expose unexpected communications on the bridge.

// Snoopy
import Snoopy from 'rn-snoopy';
import filter from 'rn-snoopy/stream/filter';

import EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter';

if (__DEV__) {
    const emitter = new EventEmitter();
    const events = Snoopy.stream(emitter);

    // Show calls to createView. Filter based on method, and provide a shape to match it.
    filter({ method: 'createView' }, true)(events).subscribe();
}

React Native Snoopy →

Elsewhere , , Leave a comment

Alex Somers & Sigur Rós – End

Alex Somers, partner of Sigur Rós’ Jónsi, has created the music for the Black Mirror episode “Hang the DJ”.

I really like the album Alex has created for this episode. Next to “Into Place” and “Out There” the track “End” (featuring Sigur Rós) really stands out:

Feels like classic Sigur Rós / Jónsi.

Listen on Apple Music →
Listen on Spotify →

Elsewhere , , , Leave a comment

Counting With CSS Counters and CSS Grid

Thanks to Counting With CSS Counters and CSS Grid my attention was directed to this fact comes to using CSS Counters:

The effectiveness of counter() wanes when we realize that an element displaying the total count can only appear after all the elements to be counted in the source code. This is because the browser first needs the chance to count all the elements, before showing the total.

So how can one fix this? In said article the author resorts to CSS Grid Layout to position the counters visually above the stuff it’s counting.

.wrapper {
  display: grid;
  …
}

.counters { 
  grid-row: 1; /* places the counters on the first row */
  grid-column: 1 / 3;  /* ensures the counters span the full grid width, forcing other content below */
}

This trick can of course also be reproduced with Flexbox, by reordering the items using its order property.

.wrapper {
  display: flex;
  flex-direction: column;
  …
}

.counters { 
  order: 1; /* places the counters on the first row */
}

💁‍♂️ CSS Counters is one of the 9 Underutilized CSS Features

Elsewhere , , , , Leave a comment

WTFJS with Math (or why 0.1 + 0.2 results in 0.30000000000000004)

A few fun little Math-related wtfjs examples. A classic one is adding an empty Array and an empty Object:

[] + {}     // '[object Object]'
{} + []     // 0

If you’re looking for a hint: Coercion.

JS WTF with Math →

Elsewhere , , , Leave a comment

Implementing Instagram Filters and Image Editing in React Native

William Candillon recreated some parts of Instagram’s editing process (namely the filter, rotate, and crop steps) in React Native.

The filters are implemented with GL-React:

Gl-react offers a really efficient paradigm for integrating React and OpenGL together. The library enables you to easily build scenes using React composability. For instance, consider an image with two filters: Brannan and Valencia. It can be expressed as below. The GLImage implementation is based on gl-react-image.

import * as React from "react";
import {Surface} from "gl-react-expo";

import {GLImage, Brannan, Valencia} from "./gl-filters";

export type FilterName = "brannan" | "valencia";
type FilterProps = {
    uri: string,
    aspectRatio: number,
    name: FilterName,
    onDraw?: () => mixed
};

export default class Filter extends React.PureComponent<FilterProps> {

    render(): React.Node {
        const {style, uri, aspectRatio, name, onDraw} = this.props;
        const source = { uri };
        return (
            <Surface style={{ width: 100, height: 100 }}>
                <Brannan on={name === "brannan"}>
                    <Valencia on={name === "valencia"}>
                    <GLImage {...{source, aspectRatio, onDraw}} />
                </Valencia>
                </Brannan>
            </Surface>
        );
    }
}

A more condense writeup is also available: Implementing Instagram filters and picture editing with React Native →

Elsewhere , , , Leave a comment