npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@skypager/helpers-sketch

v1.3.1

Published

skypager sketch design document helper

Downloads

19

Readme

Sketch Helper

Turn a designer's .sketch files into JavaScript modules.

The Sketch Helper class is an abstract representation of a .sketch file produced by Sketch App. When Skypager's runtime is extended with this helper, you are able to use it as if it was a module you required.

This helper works in node, and in the browser (provided you use a webpack loader, or the helper itself to generate the sketchtool JSON metadata)

Given a path to a .sketch file, the Sketch Helper can load any level of detail about the document's internal object model, provided you can obtain it via the sketchtool CLI

It should also be able to export .png and .svg assets.

With this metadata, it is possible to use .sketch files to build an object graph that is organized the way a Designer / Sketch User
organizes their design. If the Designer uses naming conventions for their pages, artboards, and layers , this object graph can be easily navigated, making it possible to do all sorts of crazy things!

API Docs

Usage

To enable the sketch helper in the skypager runtime, just use it the way you would any other extension

const runtime = require('@skypager/node')
  .use(require('@skypager/helpers-sketch'))

If you want to build a custom runtime module which automatically has the sketch helper enabled for any consumers

import runtime from '@skypager/node'
import Sketch, { attach } from '@skypager/helpers-sketch'

export default runtime.use({ attach })

Example

The following script can run in node, you need sketchtool in your path.

// using the node runtime, we can read the sketchfiles and use sketchtool directly.
const runtime = require('@skypager/node')
// tell the runtime to use the sketch helper so that we can create modules to represent them
runtime.use(require('@skypager/helpers-sketch'))
// create an instance of the sketch helper by giving us a name for it, and telling us the path
const sketch = runtime.sketch('my-sketch-doc', { path: '/path/to/file.sketch' }) 

main()

async function main() {
  // returns an array of layer objects
  await sketch.listAllLayers().then(layers => console.log({ layers }))
  
  // returns an array of artboard objects
  await sketch.listAllArtboards().then(artboards => console.log({ artboards }))
  
  // if your names follow a naming convention, you can use a route pattern to extract them as attributes 
  await sketch.listAllArtboards({
    namePattern: ':category/:subcategory/:artboardName'
  }) // => [{ category: 'mobile', subcategory: 'darkTheme', artboardName: 'HomeScreen', ...restOfSketchToolArtboardAttributes }]
  
  await sketch.listAllLayers({
    namePattern: ':region/:layerName'
  }) // => [{ pageName: 'HomeScreen', region: 'TopNav', layerName: 'CurrentUser', ...restOfSketchToolArtboardAttributes }]
  
  // get literally everything there is about the document
  await sketch.dump()
}

In this example, we know about the path to the sketch file, and we can create it by passing it as an argument.

If you wanted to just discover all of the sketchfiles in your current project folder

main()

async function main() {
  await runtime.sketches.discover()
  console.log(runtime.sketches.available)
}

then you could access them with something like:

const webappSketch = runtime.sketch('test/fixtures/WebApplication')
const styleguideSketch = runtime.sketch('test/fixtures/StyleGuide')

Webpack Loader

@skypager/helpers-sketch/sketchtool-loader can be used to process .sketch files and turn them into JSON structures that can be used to hydrate the Sketch helper instances in the browser, with the same metadata we rely on sketchtool to provide us with directly in the node runtime.

This will enable you to build, for example, a React App whose state is powered by a Sketch Helper instance.

  • TODO: Webpack Config Example

Subclassing Example

The Sketch Helper class by itself is pretty low-level. It provides an easier way of navigating the sketchtool JSON dumps.

The real value of this helper will come through subclassing it in a way which matches the mental model of the designer who created the .sketch file.

For example, say you had a .sketch template which consisted of an artboard that had a color palette, and typography display.

If the designer names and organizes the layers in a way you both agree on, you can create a Theme subclass which might generate CSS or less files in your project.

import Sketch from '@skypager/helpers-sketch'

export default class ThemeSketch extends Sketch {
  // assuming layer names:
  //  - typography/mainHeading
  //  - typography/subHeading
  //  - typography/copy
  generateTypographyRules() {
    const { filter } = this.lodash
    const typeLayers = filter(this.layers, { category: 'typography' })
    // need to write this function to find the values in the sketch metadata
    return typeLayers.map(findFontNameSizeAndWeight)
  }  

  // assuming layer names:
  //  - color/primary
  //  - color/secondary
  generateColorRules() {
    const { filter } = this.lodash
    const colorLayers = filter(this.layers, { category: 'color' })
    // need to write this function to find the values in the sketch metadata
    return colorLayers.map(findColorNameAndValues)   
  }
}

// now your runtime can load an entire collection of themes 
export function attach(runtime) {
  const { Helper } = runtime
  Helper.registerHelper('theme', () => ThemeSketch)

  Helper.attach(runtime, ThemeSketch, {
    registryProp: 'themes',
    lookupProp: 'theme'
  }) 
}

Now let's say you have a few theme sketch files in a folder

import runtime from '@skypager/node'
import * as ThemeSketch from './ThemeSketch'

runtime.use(ThemeSketch)

const darkTheme = runtime.theme('DarkTheme', {
  path: '/path/to/dark.theme.sketch' 
})

const lightTheme = runtime.theme('LightTheme', {
  path: '/path/to/light.theme.sketch' 
})

darktheme.generateColorRules().then(writeThemToLessFilesOrSomething)
lightTheme.generateColorRules().then(writeThemToLessFilesOrSomething)

Future Plans

  • Sketch Helper instances are observable (i.e. they have a state property that is a mobx observable) which means we can keep their state in sync with Sketch App through their plugin interface, or whenever the file is saved (easiest in electron.)