Skip to content

Commit

Permalink
feat(sketch): add sketch package (#2720)
Browse files Browse the repository at this point in the history
* chore: check-in work

* chore: check-in work

* feat(sketch): add sketch package with color generation

* chore(project): add license banner

* chore(project): add sketch plugin to prettier ignore

* chore: check-in work

* chore: check-in work

* chore: check-in work

* fix(icons): add opacity to 32 checkmark--filled

* chore(sketch): remove tmp files

* refactor(sketch): update to shared bundle

* fix(icons): update inner-path on checkmark--filled

* feat(sketch): add sketch package

* chore(project): sync lockfile and offline mirror

* chore(project): revert change to .yarnrc

* chore(sketch): remove unused svg tool

* chore(sketch): clean-up package.json

* docs(sketch): add docs and JSDoc annotations

* docs(sketch): add additional JSDoc annotations and comments

* docs(sketch): update readme

* fix(sketch): set text color to black

* fix(sketch): no borders on generated icon layers
  • Loading branch information
joshblack authored May 28, 2019
1 parent aa47b4b commit 0a8606f
Show file tree
Hide file tree
Showing 52 changed files with 1,494 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ packages/components/css
packages/components/scss
packages/components/docs/js

# Sketch
**/*.sketchplugin/**

# Changelogs
**/CHANGELOG.md

Expand Down
Binary file added .yarn-offline-mirror/@babel-polyfill-7.4.4.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/@skpm-babel-preset-0.2.1.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/@skpm-builder-0.7.0.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/@skpm-file-loader-2.0.1.tgz
Binary file not shown.
Binary file not shown.
Binary file added .yarn-offline-mirror/@skpm-nib-loader-0.1.1.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/author-regex-1.0.0.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/cli-spinners-1.3.1.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/cocoascript-class-0.1.2.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/coscript-1.0.0.tgz
Binary file not shown.
Binary file not shown.
Binary file added .yarn-offline-mirror/fs.promised-3.0.0.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/gittar-0.1.1.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/globby-7.1.1.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/keychain-1.3.0.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/ora-1.4.0.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/parse-author-2.0.0.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/promise-polyfill-8.1.0.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/run-sketch-plugin-1.0.3.tgz
Binary file not shown.
Binary file not shown.
Binary file added .yarn-offline-mirror/skpm-1.2.0.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/webpack-4.31.0.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/webpack-merge-4.2.1.tgz
Binary file not shown.
Binary file added .yarn-offline-mirror/yesno-0.2.0.tgz
Binary file not shown.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@
"yarn lerna run lint:staged --scope carbon-components-react",
"git add"
],
"*.js,!packages/components/**/*.js,!packages/react/**/*.js": [
"yarn format:staged",
"git add"
],
"*.md": [
"yarn format:staged",
"git add"
Expand Down
2 changes: 1 addition & 1 deletion packages/icons/src/svg/16/checkmark--filled.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/icons/src/svg/32/checkmark--filled.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/sketch/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.sketchplugin
103 changes: 103 additions & 0 deletions packages/sketch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# @carbon/sketch

<!-- prettier-ignore-start -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table of Contents

- [Getting started (developing)](#getting-started-developing)
- [Overview](#overview)
- [Building sketch plugins](#building-sketch-plugins)
- [Project structure](#project-structure)
- [Reference](#reference)
- [Tips & Tricks](#tips--tricks)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->

## Getting started (developing)

When working with this package, you will need to follow a couple of steps to get
started. It's important that you have Sketch installed on your system before
attempting any of these steps.

1. Run `cd packages/sketch` to go into the package folder
2. Run `yarn build` to build out the initial plugin
3. Run `yarn skpm:link` to link the plugin to your Sketch plugin folder

Afterwards, you can continue development by running `yarn develop`.

## Overview

### Building sketch plugins

The output of `@carbon/sketch` is a plugin at
`packages/sketch/carbon-elements.sketchplugin`. This artifact is generated by
running `yarn build`. Under the hood, we make use of a tool called
[`skpm`](https://github.com/skpm/skpm) that allows us to write our Sketch
plugins using modern JavaScript language features and modules.

When using `skpm`, we add a field named `skpm` to our `package.json` so that it
knows details about our plugin, most notably the name of the plugin and a
reference to a `manifest.json` file. This file lists out the capabilities of the
sketch plugin under the `commands` field, and also defines the menu structure th
at should appear for this plugin under the Plugins menu in Sketch.

Under the `commands` field, we list out commands and define a path to a `script`
and name the `handler` that should be called when running the command. In other
words, if we have a file like:

```js
// commands/greeting.js
import sketch from 'sketch';

export function greeting() {
sketch.UI.message('Hello world!');
}
```

Then in our `manifest.json` we would create an entry under `commands` like:

```json
{
"commands": [
{
"name": "The name of the command"
"identifier": "the.command.identifier",
"script": "commands/greeting.",
"handler": "greeting"
}
]
}
```

_Note: We chose the `greeting` handler because that was what was exported in
`export function greeting() {}`._

We later use the `identifier` field in our menu to reference the command.

### Project structure

```bash
packages/sketch
├── package.json
└── src
├── commands # Implementation of commands in `manifest.json`
├── manifest.json # Define capabilities of Sketch plugin
├── sharedStyles # Methods for syncing shared layer and text styles
└── tools # Tools for interacting with the Sketch DOM and styles
```

## Reference

- [API Reference](https://developer.sketch.com/reference/api) for the `sketch`
module
- [`Sketch-Headers`](https://github.com/abynim/Sketch-Headers) to determine
methods on internal objects
- [Plugin bundle guide](https://developer.sketch.com/guides/plugin-bundles/) for
structuring a plugin and its menus

## Tips & Tricks

- Use `yarn skpm log -f` to tail logs from the Sketch plugin. Useful if you want
to debug using `console.log` layer is removed
34 changes: 34 additions & 0 deletions packages/sketch/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "@carbon/sketch",
"description": "Tooling for generating a sketch plugin to bring code to design",
"private": true,
"version": "10.2.0",
"license": "Apache-2.0",
"scripts": {
"build": "cross-env NODE_ENV=production skpm-build",
"clean": "rimraf carbon-elements.sketchplugin",
"develop": "cross-env NODE_ENV=development skpm-build --watch",
"skpm:link": "skpm-link"
},
"dependencies": {
"@babel/polyfill": "^7.4.4",
"@carbon/colors": "10.2.0",
"@carbon/icon-helpers": "10.2.0",
"@carbon/icons": "10.2.0",
"@carbon/themes": "10.2.0",
"@carbon/type": "10.2.0",
"@skpm/builder": "^0.7.0",
"color-string": "^1.5.3",
"skpm": "^1.2.0"
},
"devDependencies": {
"cross-env": "^5.2.0",
"rimraf": "^2.6.3"
},
"skpm": {
"name": "Carbon Elements",
"manifest": "src/manifest.json",
"main": "carbon-elements.sketchplugin",
"assets": []
}
}
94 changes: 94 additions & 0 deletions packages/sketch/src/commands/colors/generate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* Copyright IBM Corp. 2018, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { Document, Rectangle, ShapePath, SymbolMaster } from 'sketch/dom';
import { command } from '../command';
import { syncColorStyles } from '../../sharedStyles/colors';
import { findOrCreatePage, selectPage } from '../../tools/page';
import { groupByKey } from '../../tools/grouping';

const ARTBOARD_WIDTH = 40;
const ARTBOARD_HEIGHT = 40;
const ARTBOARD_MARGIN = 8;

export function generate() {
command('commands/colors/generate', () => {
const document = Document.getSelectedDocument();
const page = selectPage(findOrCreatePage(document, 'Color'));
const sharedStyles = syncColorStyles(document);
const { blackAndWhite, colors, support } = groupByKey(
sharedStyles,
sharedStyle => {
const { name } = sharedStyle;
const [category, swatch, grade] = name.split('/');
switch (swatch) {
case 'black':
case 'white':
return 'blackAndWhite';
case 'yellow':
case 'orange':
return 'support';
default:
return 'colors';
}
}
);

let X_OFFSET = 0;
let Y_OFFSET = 0;

for (const sharedStyle of blackAndWhite) {
createSymbolFromSharedStyle(sharedStyle, page, X_OFFSET, Y_OFFSET);
X_OFFSET = X_OFFSET + ARTBOARD_WIDTH + ARTBOARD_MARGIN;
}

X_OFFSET = 0;
Y_OFFSET = Y_OFFSET + ARTBOARD_HEIGHT + ARTBOARD_MARGIN;

const swatches = groupByKey(colors, sharedStyle => {
const [category, swatch, grade] = sharedStyle.name.split('/');
return swatch;
});

for (const swatch of Object.keys(swatches)) {
for (const sharedStyle of swatches[swatch]) {
createSymbolFromSharedStyle(sharedStyle, page, X_OFFSET, Y_OFFSET);
X_OFFSET = X_OFFSET + ARTBOARD_WIDTH + ARTBOARD_MARGIN;
}

X_OFFSET = 0;
Y_OFFSET = Y_OFFSET + ARTBOARD_HEIGHT + ARTBOARD_MARGIN;
}

for (const sharedStyle of support) {
createSymbolFromSharedStyle(sharedStyle, page, X_OFFSET, Y_OFFSET);
X_OFFSET = X_OFFSET + ARTBOARD_WIDTH + ARTBOARD_MARGIN;
}
});
}

function createSymbolFromSharedStyle(sharedStyle, parent, offsetX, offsetY) {
const [category, swatch, grade] = sharedStyle.name.split('/');

const colorName = grade ? `${swatch}/${swatch}-${grade}` : swatch;
const rectangle = new ShapePath({
name: 'Color',
frame: new Rectangle(0, 0, ARTBOARD_WIDTH, ARTBOARD_HEIGHT),
shapeType: ShapePath.ShapeType.Rectangle,
sharedStyleId: sharedStyle.id,
style: sharedStyle.style,
});

const artboard = new SymbolMaster({
parent,
name: `${category}/${colorName}`,
frame: new Rectangle(offsetX, offsetY, ARTBOARD_WIDTH, ARTBOARD_HEIGHT),
layers: [rectangle],
});

return artboard;
}
9 changes: 9 additions & 0 deletions packages/sketch/src/commands/colors/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Copyright IBM Corp. 2018, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

export { sync } from './sync';
export { generate } from './generate';
17 changes: 17 additions & 0 deletions packages/sketch/src/commands/colors/sync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright IBM Corp. 2018, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { Document } from 'sketch/dom';
import { command } from '../command';
import { syncColorStyles } from '../../sharedStyles/colors';

export function sync() {
command('commands/colors/sync', () => {
const document = Document.getSelectedDocument();
syncColorStyles(document);
});
}
26 changes: 26 additions & 0 deletions packages/sketch/src/commands/command.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright IBM Corp. 2018, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import sketch from 'sketch';

/**
* Wrap a given command function for consistent UI messages and development
* runtime logging.
* @param {string} name - the name of the command
* @param {Function} fn - the function to call to run the command
*/
export function command(name, fn) {
const start = Date.now();

sketch.UI.message('Hi 👋 We are still working on this! 🚧');
fn();
sketch.UI.message('Done! 🎉');

if (process.env.NODE_ENV === 'development') {
console.log(`[Carbon Elements] ${name}: Done in ${Date.now() - start}ms`);
}
}
Loading

0 comments on commit 0a8606f

Please sign in to comment.