Horizontal and vertical alignment with Scriptable

While I am a huge fan of widgets on iOS, most apps miss the mark in terms of
what they offer via their widgets. Because I’m not one to settle, I have been on
a quest to build my own widgets so that I can get exactly what I desire.

Fortunately, I happened upon Scriptable (thanks Geoff!),
which makes it extremely easy to write your own iOS widgets with good ol’
JavaScript!

Sadly, the documentation kinda sucks, at least in terms of providing examples.
There is a gallery of scripts other folks have written, but it was pretty thin.
The content available was more in line with existing scripts that you could
leverage, and not clean examples of how to do things.

While writing my own widget, I had to figure out how to get things to align the
way I wanted them. Specifically, I wanted to be able to utilize the entire
widget area, and have everything space itself out accordingly. Essentially, I
wanted things to function like they do when using the flexible box (flexbox)
in CSS.

Fortunately, Scriptable provides an addSpacer() method, that you can pass in a
length value to. If you omit the length argument, or pass it a null value, the
spacer will become flexible, and will consume any left over space.

Armed with this, you can center text or build out a grid system that will span
the entirety of the widget!

For demonstration purposes, I put together a script that creates a 9 by 9 grid,
that will stretch both horizontally and vertically to full the widget. Each area
has text that tells you which part of the widget it is (like a compass):

async function createWidget() {
  const widget = new ListWidget

  const layoutStack = widget.addStack
  layoutStack.layoutVertically

  const topStack = layoutStack.addStack
  const northWestEl = topStack.addText('NW'
  topStack.addSpacer
  const northEL = topStack.addText('N'
  topStack.addSpacer
  const northEastEl = topStack.addText('NE'

  layoutStack.addSpacer

  const middleStack = layoutStack.addStack
  const westEl = middleStack.addText('W'
  middleStack.addSpacer
  const centerEl = middleStack.addText('Center'
  middleStack.addSpacer
  const eastEl = middleStack.addText('E'

  layoutStack.addSpacer

  const bottomStack = layoutStack.addStack
  const southWestEl = bottomStack.addText('SW'
  bottomStack.addSpacer
  const southEl = bottomStack.addText('S'
  bottomStack.addSpacer
  const southEastEl = bottomStack.addText('SE'

  return widget
}

const widget = await createWidget

if (config.runsInWidget) {
  Script.setWidget(widget
} else {
  widget.presentLarge
}

Script.complete

The resulting widget looks like this (captured from the Scriptable macOS beta
app):

Scriptable.app alignment demo

Josh Sherman - The Man, The Myth, The Avatar

About Josh

Husband. Father. Pug dad. Musician. Founder of Holiday API, Head of Engineering and Emoji Specialist at Mailshake, and author of the best damn Lorem Ipsum Library for PHP.


If you found this article helpful, please consider buying me a coffee.