├── .gitignore ├── Archives ├── PuzzleTokens.sketchplugin.6.1.0.zip ├── PuzzleTokens.sketchplugin.6.12.0.zip ├── PuzzleTokens.sketchplugin.6.2.1.zip ├── PuzzleTokens.sketchplugin.6.3.2.zip ├── PuzzleTokens.sketchplugin.6.3.3.zip ├── PuzzleTokens.sketchplugin.6.4.0.zip ├── PuzzleTokens.sketchplugin.6.5.2.zip ├── PuzzleTokens.sketchplugin.6.6.1.zip ├── PuzzleTokens.sketchplugin.6.6.2.zip ├── PuzzleTokens.sketchplugin.6.6.3.zip └── PuzzleTokens.sketchplugin.6.7.0.zip ├── CHANGELOG.md ├── DEBUG.md ├── LICENSE ├── PuzzleTokens.sketchplugin.zip ├── PuzzleTokens.sketchplugin └── Contents │ ├── Resources │ └── icon.png │ └── Sketch │ ├── classes │ ├── DSApp.js │ ├── DSExporter.js │ └── DSPreviewer.js │ ├── cmd-actions.js │ ├── cmd-apply-less.js │ ├── cmd-config.js │ ├── cmd-export.js │ ├── cmd-generate-preview.js │ ├── cmd-other.js │ ├── cmdline-functions.js │ ├── constants.js │ ├── lib │ ├── ga.js │ ├── gradient-parser │ │ └── parser.js │ ├── uidialog.js │ ├── uipanel.js │ └── utils.js │ ├── manifest.json │ └── scripts │ ├── nsconvert_less.js │ └── nsconvert_sass.js ├── README.md ├── Scripts ├── SketchScrips.txt └── run-pt.sh ├── Styles ├── Releases │ ├── 6.10.0 │ │ ├── sketch-styles.less │ │ ├── test-inspector.json │ │ ├── test-vars.json │ │ └── test.sketch │ ├── 6.11.0 │ │ ├── styles.less │ │ ├── test-inspector.json │ │ ├── test-vars.json │ │ └── test.sketch │ ├── 6.12.0 │ │ ├── styles.less │ │ ├── test-inspector.json │ │ ├── test-vars.json │ │ └── test.sketch │ ├── 6.14.0 │ │ ├── _pt-assets │ │ │ └── test │ │ │ │ ├── inspector.json │ │ │ │ ├── vars.json │ │ │ │ └── vars.scss │ │ ├── styles.less │ │ └── test.sketch │ ├── 6.7.0 │ │ ├── styles.less │ │ ├── test-inspector.json │ │ ├── test-vars.json │ │ └── test.sketch │ ├── 6.8.0 │ │ ├── sketch-styles.less │ │ ├── test-inspector.json │ │ ├── test-vars.json │ │ └── test.sketch │ ├── 6.9.0 │ │ ├── _pt-assets │ │ │ └── test │ │ │ │ ├── inspector.json │ │ │ │ ├── vars.json │ │ │ │ └── vars.scss │ │ ├── sketch-styles.less │ │ ├── test-inspector.json │ │ ├── test-vars.json │ │ └── test.sketch │ ├── 8.1.1 │ │ ├── test.less │ │ └── test.sketch │ ├── 8.13.0 │ │ ├── Blend-Mode-Test.sketch │ │ └── test.sass │ ├── 8.14.0 │ │ ├── Test.sketch │ │ └── test.less │ ├── 8.15.0 │ │ ├── puzzle-tokens.less │ │ └── puzzle-tokens.scss │ ├── 8.16.1 │ │ ├── one.less │ │ └── two.less │ ├── 8.16.3 │ │ ├── Test.sketch │ │ ├── bad.less │ │ └── good.less │ ├── 8.17.0 │ │ ├── gradient-test.less │ │ └── gradient-test.sketch │ ├── 8.3.0 │ │ ├── ResizeArtboard.less │ │ ├── ResizeArtboard.sketch │ │ └── _pt-assets │ │ │ └── ResizeArtboard │ │ │ ├── inspector.json │ │ │ ├── vars.json │ │ │ └── vars.scss │ ├── 8.3.2 │ │ ├── Test.less │ │ ├── Test.sketch │ │ └── test-lib.sketch │ ├── 8.3.3 │ │ ├── New.less │ │ ├── Old.less │ │ ├── Test.sketch │ │ └── _pt-assets │ │ │ └── Test │ │ │ ├── inspector.json │ │ │ ├── vars.json │ │ │ └── vars.scss │ ├── 8.3.4 │ │ └── Test.less │ └── 8.5.0 │ │ ├── Test.scss │ │ └── Test.sketch ├── Set-Text │ ├── _pt-assets │ │ └── set-text │ │ │ ├── inspector.json │ │ │ ├── vars.json │ │ │ └── vars.scss │ ├── set-text.less │ └── set-text.sketch ├── Tests │ ├── Buttons │ │ ├── Illustration.png │ │ ├── Test-All-In-One.less │ │ ├── Test-Blue.less │ │ ├── Test-Blue.scss │ │ ├── Test-Green.less │ │ ├── Test-Green.scss │ │ ├── Test.sketch │ │ ├── _Styles.less │ │ ├── _Styles.scss │ │ ├── _pt-assets │ │ │ └── Test │ │ │ │ ├── inspector.json │ │ │ │ ├── vars.json │ │ │ │ ├── vars.scss │ │ │ │ └── viewer.css │ │ └── images │ │ │ ├── image.svg │ │ │ ├── new-logo.jpg │ │ │ └── old-logo.png │ ├── Gradients │ │ ├── linear-gradients-inspector.json │ │ ├── linear-gradients.less │ │ └── linear-gradients.sketch │ ├── Opacity │ │ ├── Opacity-inspector.json │ │ ├── Opacity.sketch │ │ └── styles.less │ └── SM-Kit │ │ ├── _constants.scss │ │ ├── _functions.scss │ │ ├── sm-kit-simple-inspector.json │ │ ├── sm-kit-simple-vars.json │ │ ├── sm-kit-simple-vars.scss │ │ ├── sm-kit-simple.sketch │ │ ├── sm-tokens-simple-1.less │ │ ├── sm-tokens-simple.less │ │ └── sm-tokens-simple.scss ├── Two Brands │ ├── Start-Dark.less │ ├── Start-Light.less │ ├── functions.less │ └── mybrand.less └── material-palettes │ ├── _pt-assets │ └── palettes │ │ ├── inspector.json │ │ ├── vars.json │ │ └── vars.scss │ ├── palettes-inspector.json │ ├── palettes.sketch │ └── scss │ ├── _constants.scss │ ├── _functions.scss │ └── palettes.scss ├── appcast.xml └── archives ├── PuzzleTokens.sketchplugin.3.0.0.zip ├── PuzzleTokens.sketchplugin.3.0.1.zip ├── PuzzleTokens.sketchplugin.3.0.2.zip ├── PuzzleTokens.sketchplugin.3.1.0.zip ├── PuzzleTokens.sketchplugin.3.1.1.zip ├── PuzzleTokens.sketchplugin.3.1.2.zip ├── PuzzleTokens.sketchplugin.3.1.3.zip ├── PuzzleTokens.sketchplugin.4.1.0.zip ├── PuzzleTokens.sketchplugin.4.1.1.zip ├── PuzzleTokens.sketchplugin.4.1.2.zip ├── PuzzleTokens.sketchplugin.5.0.0.zip ├── PuzzleTokens.sketchplugin.5.1.0.zip ├── PuzzleTokens.sketchplugin.5.1.1.zip ├── PuzzleTokens.sketchplugin.5.2.0.zip ├── PuzzleTokens.sketchplugin.5.3.0.zip ├── PuzzleTokens.sketchplugin.5.3.1.zip ├── PuzzleTokens.sketchplugin.5.3.2.zip ├── PuzzleTokens.sketchplugin.6.0.0.zip ├── PuzzleTokens.sketchplugin.6.0.1.zip ├── PuzzleTokens.sketchplugin.6.1.1.zip ├── PuzzleTokens.sketchplugin.6.10.0.zip ├── PuzzleTokens.sketchplugin.6.11.0.zip ├── PuzzleTokens.sketchplugin.6.12.1.zip ├── PuzzleTokens.sketchplugin.6.13.0.zip ├── PuzzleTokens.sketchplugin.6.14.0.zip ├── PuzzleTokens.sketchplugin.6.2.0.zip ├── PuzzleTokens.sketchplugin.6.2.2.zip ├── PuzzleTokens.sketchplugin.6.3.0.zip ├── PuzzleTokens.sketchplugin.6.5.0.zip ├── PuzzleTokens.sketchplugin.6.5.1.zip ├── PuzzleTokens.sketchplugin.6.6.0.zip ├── PuzzleTokens.sketchplugin.6.7.1.zip ├── PuzzleTokens.sketchplugin.6.8.0.zip ├── PuzzleTokens.sketchplugin.6.9.0.zip ├── PuzzleTokens.sketchplugin.7.0.0.zip ├── PuzzleTokens.sketchplugin.8.0.1.zip ├── PuzzleTokens.sketchplugin.8.1.0.zip ├── PuzzleTokens.sketchplugin.8.1.1.zip ├── PuzzleTokens.sketchplugin.8.1.2.zip ├── PuzzleTokens.sketchplugin.8.10.0.zip ├── PuzzleTokens.sketchplugin.8.11.0.zip ├── PuzzleTokens.sketchplugin.8.12.0.zip ├── PuzzleTokens.sketchplugin.8.12.1.zip ├── PuzzleTokens.sketchplugin.8.13.0.zip ├── PuzzleTokens.sketchplugin.8.14.0.zip ├── PuzzleTokens.sketchplugin.8.14.1.zip ├── PuzzleTokens.sketchplugin.8.14.4.zip ├── PuzzleTokens.sketchplugin.8.15.0.zip ├── PuzzleTokens.sketchplugin.8.16.0.zip ├── PuzzleTokens.sketchplugin.8.16.1.zip ├── PuzzleTokens.sketchplugin.8.16.2.zip ├── PuzzleTokens.sketchplugin.8.16.3.zip ├── PuzzleTokens.sketchplugin.8.16.4.zip ├── PuzzleTokens.sketchplugin.8.17.0.zip ├── PuzzleTokens.sketchplugin.8.17.1.zip ├── PuzzleTokens.sketchplugin.8.17.2.zip ├── PuzzleTokens.sketchplugin.8.17.3.zip ├── PuzzleTokens.sketchplugin.8.17.4.zip ├── PuzzleTokens.sketchplugin.8.17.5.zip ├── PuzzleTokens.sketchplugin.8.18.0.zip ├── PuzzleTokens.sketchplugin.8.18.1.zip ├── PuzzleTokens.sketchplugin.8.18.2.zip ├── PuzzleTokens.sketchplugin.8.19.0.zip ├── PuzzleTokens.sketchplugin.8.19.1.zip ├── PuzzleTokens.sketchplugin.8.19.2.zip ├── PuzzleTokens.sketchplugin.8.19.3.zip ├── PuzzleTokens.sketchplugin.8.19.4.zip ├── PuzzleTokens.sketchplugin.8.19.5.zip ├── PuzzleTokens.sketchplugin.8.19.6.zip ├── PuzzleTokens.sketchplugin.8.19.7.zip ├── PuzzleTokens.sketchplugin.8.2.0.zip ├── PuzzleTokens.sketchplugin.8.20.0.zip ├── PuzzleTokens.sketchplugin.8.3.0.zip ├── PuzzleTokens.sketchplugin.8.3.1.zip ├── PuzzleTokens.sketchplugin.8.3.2.zip ├── PuzzleTokens.sketchplugin.8.3.3.zip ├── PuzzleTokens.sketchplugin.8.3.4.zip ├── PuzzleTokens.sketchplugin.8.3.5.zip ├── PuzzleTokens.sketchplugin.8.4.0.zip ├── PuzzleTokens.sketchplugin.8.4.1.zip ├── PuzzleTokens.sketchplugin.8.5.0.zip ├── PuzzleTokens.sketchplugin.8.5.1.zip ├── PuzzleTokens.sketchplugin.8.6.0.zip ├── PuzzleTokens.sketchplugin.8.7.0.zip ├── PuzzleTokens.sketchplugin.8.7.1.zip ├── PuzzleTokens.sketchplugin.8.7.2.zip ├── PuzzleTokens.sketchplugin.8.7.3.zip ├── PuzzleTokens.sketchplugin.8.7.4.zip ├── PuzzleTokens.sketchplugin.8.8.0.zip ├── PuzzleTokens.sketchplugin.8.8.1.zip ├── PuzzleTokens.sketchplugin.8.8.2.zip ├── PuzzleTokens.sketchplugin.8.8.3.zip ├── PuzzleTokens.sketchplugin.8.8.4.zip └── PuzzleTokens.sketchplugin.8.9.0.zip /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.1.0.zip -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.12.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.12.0.zip -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.2.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.2.1.zip -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.3.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.3.2.zip -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.3.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.3.3.zip -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.4.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.4.0.zip -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.5.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.5.2.zip -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.6.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.6.1.zip -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.6.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.6.2.zip -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.6.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.6.3.zip -------------------------------------------------------------------------------- /Archives/PuzzleTokens.sketchplugin.6.7.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Archives/PuzzleTokens.sketchplugin.6.7.0.zip -------------------------------------------------------------------------------- /DEBUG.md: -------------------------------------------------------------------------------- 1 | 1) Run Pluggins > Puzzle Tokens > Configure > Enable debug logging 2 | 2) Execute Apply Tokens 3 | 3) Open Terminal and execute 4 | ``cat ~/Library/Logs/com.bohemiancoding.sketch3/Plugin\ Log.log`` 5 | 4) See the last lines to find a problem 6 | -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/PuzzleTokens.sketchplugin.zip -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/PuzzleTokens.sketchplugin/Contents/Resources/icon.png -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/cmd-actions.js: -------------------------------------------------------------------------------- 1 | @import "lib/ga.js"; 2 | @import "lib/utils.js"; 3 | @import "constants.js"; 4 | 5 | function onStartup(context) { 6 | const installedBefore = Settings.settingForKey(SettingKeys.PLUGIN_INSTALLED) 7 | if (!installedBefore) { 8 | track(TRACK_INSTALLED) 9 | Settings.setSettingForKey(SettingKeys.PLUGIN_INSTALLED, 1) 10 | } else { 11 | track(TRACK_STARTED) 12 | } 13 | } -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/cmd-apply-less.js: -------------------------------------------------------------------------------- 1 | @import "lib/uidialog.js"; 2 | @import "lib/utils.js"; 3 | @import "classes/DSApp.js"; 4 | @import "constants.js"; 5 | 6 | 7 | var onRunDialog = function (context) { 8 | UIDialog.setUp(context); 9 | var myless = new DSApp(context) 10 | myless.init() 11 | myless.runDialog() 12 | } 13 | 14 | var onRunDialogOnlyStyles = function (context) { 15 | UIDialog.setUp(context); 16 | var myless = new DSApp(context) 17 | myless.onlyUpdateStyles = true 18 | myless.init() 19 | myless.runDialog() 20 | } 21 | 22 | var onRunQuick = function (context) { 23 | UIDialog.setUp(context); 24 | var myless = new DSApp(context) 25 | myless.onlyUpdateStyles = Settings.settingForKey(SettingKeys.PLUGIN_LAST_ONLY_UPDATE) === true 26 | myless.init() 27 | myless.runQuick() 28 | } -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/cmd-config.js: -------------------------------------------------------------------------------- 1 | @import "lib/uidialog.js"; 2 | @import "lib/utils.js"; 3 | @import "constants.js"; 4 | 5 | 6 | var onRun = function (context) { 7 | const sketch = require('sketch') 8 | const Settings = require('sketch/settings') 9 | const document = sketch.fromNative(context.document) 10 | const UI = require('sketch/ui') 11 | 12 | UIDialog.setUp(context); 13 | 14 | // Read settings 15 | let logDebug = Settings.settingForKey(SettingKeys.PLUGIN_LOGDEBUG_ENABLED) == 1 16 | let showJSON = Settings.settingForKey(SettingKeys.PLUGIN_SHOW_JSON) == 1 17 | let showDoubleStyle = Settings.settingForKey(SettingKeys.PLUGIN_SHOW_DOUBLESTYLES) == 1 18 | let ignoreMissed = Settings.settingForKey(SettingKeys.PLUGIN_APPLY_IGNORE_MISSED) == 1 19 | let skipSizes = Settings.settingForKey(SettingKeys.PLUGIN_APPLY_SKIP_SIZES) == 1 20 | let genSymbTokens = Settings.settingForKey(SettingKeys.PLUGIN_GENERATE_SYMBOLTOKENS) == 1 21 | let gaEnabled = !Settings.settingForKey(SettingKeys.PLUGIN_GA_DISABLED) 22 | let nodeJSPAth = Settings.settingForKey(SettingKeys.PLUGIN_NODEJS_PATH) 23 | if (undefined == nodeJSPAth) nodeJSPAth = "" 24 | let sassModulePath = Settings.settingForKey(SettingKeys.PLUGIN_SASSMODULE_PATH) 25 | if (undefined == sassModulePath) sassModulePath = "" 26 | let lesscPath = Settings.settingForKey(SettingKeys.PLUGIN_LESSC_PATH) 27 | if (undefined == lesscPath) lesscPath = "" 28 | 29 | // Build dialog 30 | const dialog = new UIDialog("Configure", NSMakeRect(0, 0, 450, 400), "Save", "Edit Puzzle Tokens common configuration settings.") 31 | 32 | dialog.addLeftLabel("", "Apply Options") 33 | dialog.addCheckbox("showDoubleStyle", "Warn about style name duplicates", showDoubleStyle) 34 | dialog.addCheckbox("ignoreMissed", "Don't create new styles and ignore missed symbols", ignoreMissed) 35 | dialog.addCheckbox("skipSizes", "Don't apply sizes and margins", skipSizes) 36 | dialog.addCheckbox("showJSON", "Show internal JSON data", showJSON) 37 | dialog.addCheckbox("logDebug", "Enable debug logging", logDebug) 38 | 39 | dialog.addDivider() 40 | dialog.addLeftLabel("", "Path to Node.js") 41 | dialog.addTextInput("nodeJSPAth", "", nodeJSPAth, Constants.NODEJS_PATH, 350) 42 | dialog.addLeftLabel("", "Path to SASS Module", 40) 43 | dialog.addTextInput("sassModulePath", "", sassModulePath, Constants.DEF_SASSMODULE_PATH, 350) 44 | dialog.addLeftLabel("", "Path to lessc", 40) 45 | dialog.addTextInput("lesscPath", "", lesscPath, Constants.DEF_LESSC_PATH, 350) 46 | 47 | dialog.y -= 20 48 | 49 | dialog.addDivider() 50 | dialog.addLeftLabel("", "Integration with Puzzle Publisher", 40) 51 | dialog.addCheckbox("genSymbTokens", "Generate symbols & styles file", genSymbTokens) 52 | dialog.y -= 20 53 | 54 | dialog.addDivider() 55 | dialog.addLeftLabel("", "Privacy", 40) 56 | dialog.addCheckbox("gaEnabled", "Share analytics with PT developer", gaEnabled) 57 | dialog.addHint("gaEnabledHint", "Help improve Puzzle Tokens by automatically sending usage data. Usage data is collected anonymously and cannot be used to identify you.", 40) 58 | 59 | // Run event loop 60 | while (true) { 61 | const result = dialog.run() 62 | if (!result) { 63 | dialog.finish() 64 | return false 65 | } 66 | showDoubleStyle = dialog.views['showDoubleStyle'].state() == 1 67 | ignoreMissed = dialog.views['ignoreMissed'].state() == 1 68 | skipSizes = dialog.views['skipSizes'].state() == 1 69 | logDebug = dialog.views['logDebug'].state() == 1 70 | showJSON = dialog.views['showJSON'].state() == 1 71 | genSymbTokens = dialog.views['genSymbTokens'].state() == 1 72 | gaEnabled = dialog.views['gaEnabled'].state() == 1 73 | nodeJSPAth = dialog.views['nodeJSPAth'].stringValue() + "" 74 | sassModulePath = dialog.views['sassModulePath'].stringValue() + "" 75 | lesscPath = dialog.views['lesscPath'].stringValue() + "" 76 | 77 | break 78 | } 79 | dialog.finish() 80 | 81 | // Save updated settings 82 | Settings.setSettingForKey(SettingKeys.PLUGIN_LOGDEBUG_ENABLED, logDebug) 83 | Settings.setSettingForKey(SettingKeys.PLUGIN_SHOW_DOUBLESTYLES, showDoubleStyle) 84 | Settings.setSettingForKey(SettingKeys.PLUGIN_APPLY_IGNORE_MISSED, ignoreMissed) 85 | Settings.setSettingForKey(SettingKeys.PLUGIN_APPLY_SKIP_SIZES, skipSizes) 86 | Settings.setSettingForKey(SettingKeys.PLUGIN_SHOW_JSON, showJSON) 87 | Settings.setSettingForKey(SettingKeys.PLUGIN_GENERATE_SYMBOLTOKENS, genSymbTokens) 88 | Settings.setSettingForKey(SettingKeys.PLUGIN_GA_DISABLED, !gaEnabled) 89 | Settings.setSettingForKey(SettingKeys.PLUGIN_NODEJS_PATH, nodeJSPAth) 90 | Settings.setSettingForKey(SettingKeys.PLUGIN_SASSMODULE_PATH, sassModulePath) 91 | Settings.setSettingForKey(SettingKeys.PLUGIN_LESSC_PATH, lesscPath) 92 | 93 | return true 94 | 95 | }; 96 | 97 | -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/cmd-export.js: -------------------------------------------------------------------------------- 1 | @import "lib/uidialog.js"; 2 | @import "lib/utils.js"; 3 | @import "classes/DSExporter.js"; 4 | @import "constants.js"; 5 | 6 | var onRun = function (context) { 7 | const document = Sketch.fromNative(context.document) 8 | 9 | UIDialog.setUp(context); 10 | 11 | var app = new DSExporter(context) 12 | app.init() 13 | app.run() 14 | 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/cmd-generate-preview.js: -------------------------------------------------------------------------------- 1 | @import "lib/uidialog.js"; 2 | @import "lib/utils.js"; 3 | @import "classes/DSPreviewer.js"; 4 | @import "constants.js"; 5 | 6 | var onRun = function (context) { 7 | const sketch = require('sketch') 8 | const Settings = require('sketch/settings') 9 | const document = sketch.fromNative(context.document) 10 | const UI = require('sketch/ui') 11 | 12 | UIDialog.setUp(context); 13 | 14 | var app = new DSPreviewer(context) 15 | app.run() 16 | 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/cmd-other.js: -------------------------------------------------------------------------------- 1 | @import("constants.js") 2 | 3 | var showChangeLog = function (context) { 4 | NSWorkspace.sharedWorkspace().openURL(NSURL.URLWithString(Constants.SITE_CHANGELOG_URL)) 5 | }; -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/cmdline-functions.js: -------------------------------------------------------------------------------- 1 | @import "classes/DSApp.js"; 2 | @import "classes/DSApp.js" 3 | 4 | // See example here: https://github.com/ingrammicro/puzzle-tokens/blob/master/README.md#command-line-api 5 | 6 | 7 | function applyStyles(context, runOptions) 8 | { 9 | var myless = new DSApp(context) 10 | if (DEBUG) log(" APPLY STYLES...") 11 | myless.runFromCmd(context.styles) 12 | } 13 | 14 | function showError(error) 15 | { 16 | log(error + "\n") 17 | log("Command line example:") 18 | log(example + "\n") 19 | } 20 | 21 | function saveDocument(document) 22 | { 23 | if (DEBUG) log(" SAVING DOCUMENT...") 24 | document.save(err => 25 | { 26 | if (err) 27 | { 28 | log(" Failed to save a document. Error: " + err) 29 | } 30 | }) 31 | } 32 | 33 | function saveDocumentAs(document, filePath) 34 | { 35 | if (DEBUG) log(" SAVING DOCUMENT TO " + filePath) 36 | /*document.save(filePath, { 37 | saveMode: Document.SaveMode.SaveTo, 38 | })*/ 39 | 40 | var newFileURL = NSURL.fileURLWithPath(filePath) 41 | // document.sketchObject.writeToURL_ofType_forSaveOperation_originalContentsURL_error_(newFileURL, "com.bohemiancoding.sketch.drawing", 42 | // NSSaveOperation, nil, nil); 43 | document.sketchObject.saveToURL_ofType_forSaveOperation_delegate_didSaveSelector_contextInfo(newFileURL, "com.bohemiancoding.sketch.drawing", NSSaveAsOperation, nil, nil, nil); 44 | } 45 | 46 | 47 | function closeDocument(document) 48 | { 49 | if (DEBUG) log(" CLOSING DOCUMENT...") 50 | document.close() 51 | } 52 | 53 | var cmdRun = function (context) 54 | { 55 | 56 | // Parse command line arguments 57 | let path = context.file + "" 58 | if ('' == path) 59 | { 60 | return showError("context.file is not specified") 61 | } 62 | 63 | if (DEBUG) log("PROCESS " + path) 64 | 65 | let styles = context.styles + "" 66 | if ('' == styles) 67 | { 68 | return showError("context.styles is not specified") 69 | } 70 | 71 | let argCommands = context.commands + "" 72 | if ('' == argCommands) 73 | { 74 | return showError("context.commands is not specified") 75 | } 76 | 77 | const commandsList = argCommands.split(',') 78 | const allCommands = ['save', 'apply', 'close'] 79 | const cmds = {} 80 | for (var cmd of allCommands) 81 | { 82 | cmds[cmd] = commandsList.includes(cmd) 83 | } 84 | // Open Sketch document 85 | Document.open(path, (err, document) => 86 | { 87 | if (err || !document) 88 | { 89 | log("ERROR: Can't open " + path) 90 | return 91 | } 92 | const runOptions = { 93 | cmd: "applyStyles", 94 | fromCmd: true, 95 | sDoc: document, 96 | nDoc: document.sketchObject 97 | } 98 | context.document = document.sketchObject 99 | if (cmds.apply) applyStyles(context, runOptions) 100 | if (cmds.save) 101 | { 102 | if (context.saveAs) 103 | saveDocumentAs(document, context.saveAs) 104 | else 105 | saveDocument(document) 106 | } 107 | if (cmds.close) closeDocument(document) 108 | }) 109 | 110 | }; 111 | 112 | 113 | -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/constants.js: -------------------------------------------------------------------------------- 1 | var Constants = { 2 | DOCUMENT_VERSION: "docVersion", 3 | TAB_SIZE: 2, 4 | HOTSPOT_PADDING: 0, 5 | LOGGING: false, 6 | RESOURCES_FOLDER: "scripts", 7 | ASSETS_FOLDER_PREFIX: "_pt-assets", 8 | SYMBOLTOKENFILE_POSTFIX: "inspector.json", 9 | CSSFILE_POSTFIX: "viewer.css", 10 | VARSFILE_POSTFIX: "vars.json", 11 | SASSFILE_POSTFIX: "vars.scss", 12 | SYMBOLPAGE_NAME: "Symbols", 13 | EXPORT_FORMAT_LESS: 0, 14 | EXPORT_FORMAT_SCSS: 1, 15 | 16 | SITE_CHANGELOG_URL: "https://github.com/ingrammicro/puzzle-tokens/blob/master/CHANGELOG.md", 17 | NODEJS_PATH: "/usr/local/bin/node", 18 | DEF_SASSMODULE_PATH: "/usr/local/lib/node_modules", 19 | DEF_LESSC_PATH:"/usr/local/bin/lessc", 20 | 21 | GA_ID: "UA-84277242-4" 22 | }; 23 | 24 | var SettingKeys = { 25 | PLUGIN_PREVIEWER_DEF: "pluginPreviewerDef", 26 | PLUGIN_LAST_ONLY_UPDATE: "PLUGIN_LAST_ONLY_UPDATE", 27 | PLUGIN_PATH_TO_TOKENS_LESS: "pluginPathToTokensLess", 28 | PLUGIN_PATH_TO_TOKENS_LESS_LIST: "pluginPathToTokensLessList", 29 | PLUGIN_PATH_TO_TOKENS: "PLUGIN_PATH_TO_TOKENS", 30 | PLUGIN_PATH_TO_TOKENS_LIST: "PLUGIN_PATH_TO_TOKENS_LIST", 31 | PLUGIN_GENERATE_SYMBOLTOKENS: "pluginGenSymbTokens", 32 | PLUGIN_APPLY_CLEAR: "pluginApplyClear", 33 | PLUGIN_SHOW_JSON: "pluginDebug", 34 | PLUGIN_SHOW_DOUBLESTYLES: "pluginDoubleStyles", 35 | PLUGIN_APPLY_IGNORE_MISSED: "PLUGIN_APPLY_IGNORE_MISSED", 36 | PLUGIN_APPLY_SKIP_SIZES: "PLUGIN_APPLY_SKIP_SIZES", 37 | PLUGIN_APPLY_ONLY_UPDATE_STYLES: "PLUGIN_APPLY_ONLY_UPDATE_STYLES", 38 | PLUGIN_CREATE_SYMBOLS: "pluginCreateSymbols", 39 | PLUGIN_EXPORT_PATH_TO: "pluginExportPathTo", 40 | PLUGIN_EXPORT_OPEN_FINDER: "PLUGIN_EXPORT_OPEN_FINDER", 41 | PLUGIN_EXPORT_FORMAT: "pluginExportFormat", 42 | PLUGIN_EXPORT_OPTS: "pluginExportOpts", 43 | PLUGIN_EXPORT_LIB_STYLES: "pluginExportLibStyles", 44 | 45 | PLUGIN_NODEJS_PATH: "pluginNodeJSPath0", 46 | PLUGIN_SASSMODULE_PATH: "pluginSassModulePath", 47 | PLUGIN_LESSC_PATH: "PLUGIN_LESSC_PATH", 48 | 49 | PLUGIN_INSTALLED: "pluginInstalled", 50 | PLUGIN_GA_DISABLED: "pluginGADisabled", 51 | PLUGIN_LOGDEBUG_ENABLED: "pluginLogDebugEnabled", 52 | }; 53 | 54 | const TRACK_INSTALLED = "installed" 55 | const TRACK_STARTED = "started" 56 | const TRACK_APPLY_DIALOG_SHOWN = "apply-dialog-shown" 57 | const TRACK_APPLY_DIALOG_CLOSED = "apply-dialog-closed" // cmd:ok,cancel 58 | const TRACK_APPLY_COMPLETED = "apply-completed" // num_cs: created styles, num_us: updated styles, num_l: updated layers, quick: yes/no 59 | const TRACK_APPLY_COMPLETED_LESS = "apply-completed-less" 60 | const TRACK_APPLY_COMPLETED_SCSS = "apply-completed-scss" 61 | const TRACK_EXPORT_COMPLETED = "export-completed" 62 | 63 | var Sketch = require('sketch/dom') 64 | var Settings = require('sketch/settings') 65 | var Style = require('sketch/dom').Style 66 | var Image = require('sketch/dom').Image 67 | const Group = require('sketch/dom').Group 68 | var SharedStyle = require('sketch/dom').SharedStyle 69 | var UI = require('sketch/ui') 70 | const path = require('path'); 71 | const Text = require('sketch/dom').Text 72 | const Shape = require('sketch/dom').Shape 73 | const Page = require('sketch/dom').Page 74 | const SmartLayout = require('sketch').SmartLayout 75 | const Artboard = require('sketch/dom').Artboard 76 | const Document = require('sketch/dom').Document 77 | const SymbolMaster = require('sketch/dom').SymbolMaster 78 | const Rectangle = require('sketch/dom').Rectangle 79 | 80 | 81 | const SKLAYER_STYLE = "sklayer-style" 82 | const SKTEXT_STYLE = "sktext-style" 83 | const PT_TEXT = "pt-text" 84 | const PT_RESIZE_SYMBOL = "-pt-resize-symbol" 85 | const PT_PARAGRAPH_SPACING = "pt-paragraph-spacing" 86 | const PT_LAYER_TYPE = "-pt-layer-type" 87 | const PT_SMARTLAYOUT = "-pt-smartlayout" 88 | const PT_FIX_SIZE_HEIGHT = "-pt-fix-size-height" 89 | const PT_FIX_SIZE_WIDTH = "-pt-fix-size-width" 90 | const PT_SIZE_BEHAVIOUR = "-pt-text-size-behaviour" 91 | const PT_PIN_LEFT = "-pt-pin-left" 92 | const PT_PIN_RIGHT = "-pt-pin-right" 93 | const PT_PIN_TOP = "-pt-pin-top" 94 | const PT_PIN_BOTTOM = "-pt-pin-bottom" 95 | const PT_BORDER_UPDATE = "-pt-border-update" 96 | const PT_FILL_UPDATE = "-pt-fill-update" 97 | const PT_SKIP_MISSED = "-pt-skip-missed" 98 | const PT_SHADOW_UPDATE = "-pt-shadow-update" 99 | const PT_MARGIN_RELATIVE_TO = "-pt-margin-relative-to" 100 | const PT_MARGIN_RESIZE = "-pt-margin-resize" 101 | const PT_VERTICAL_ALIGN = "-pt-valign" 102 | const PT_FIT_CONTENT = "-pt-fit-content" 103 | const PT_RESIZE_INSTANCES = "-pt-resize-instances" 104 | const PT_OVERRIDE_SYMBOL = "-pt-override-symbol" 105 | const PT_ATTR = "-pt-attr" 106 | 107 | const SPACE_COLORS = ".--COLORS-" 108 | 109 | const THIS_NAME = "_This" 110 | 111 | 112 | // source: https://sketchplugins.com/d/956-set-fix-height-layer-property 113 | const edgeFixdMap = { 114 | '-pt-pin-right': 1, 115 | '-pt-fix-size-width': 2, 116 | '-pt-pin-left': 4, 117 | '-pt-pin-bottom': 8, 118 | '-pt-fix-size-height': 16, 119 | '-pt-pin-top': 32, 120 | } 121 | 122 | const FIXED_SIZE_BEHAVIOUR_MAP = { 123 | 'auto-width': 0, 124 | 'auto-height': 1, 125 | 'fixed-size': 2 126 | } 127 | 128 | 129 | const BLENDING_MODE_CSS_TO_SKETCH = { 130 | "normal": Style.BlendingMode.Normal, 131 | "darken": Style.BlendingMode.Darken, 132 | "multiply": Style.BlendingMode.Multiply, 133 | "color-burn": Style.BlendingMode.ColorBurn, 134 | "lighten": Style.BlendingMode.Lighten, 135 | "screen": Style.BlendingMode.Screen, 136 | "color-dodge": Style.BlendingMode.ColorDodge, 137 | "overlay": Style.BlendingMode.Overlay, 138 | //"darken": Style.BlendingMode.SoftLight, // Not supported in CSS 139 | //"darken": Style.BlendingMode.HardLight, // Not supported in CSS 140 | "difference": Style.BlendingMode.Difference, 141 | "exclusion": Style.BlendingMode.Exclusion, 142 | "hue": Style.BlendingMode.Hue, 143 | "saturation": Style.BlendingMode.Saturation, 144 | "color": Style.BlendingMode.Color, 145 | "luminosity": Style.BlendingMode.Luminosity, 146 | } 147 | 148 | 149 | const alignMap = { 150 | left: Text.Alignment.left, 151 | center: Text.Alignment.center, 152 | right: Text.Alignment.right, 153 | justify: Text.Alignment.justify 154 | } 155 | const alignMap2 = { 156 | [Text.Alignment.left]: "left", 157 | [Text.Alignment.center]: "center", 158 | [Text.Alignment.right]: "right", 159 | [Text.Alignment.justify]: "justify" 160 | } 161 | const vertAlignMap = { 162 | "top": Text.VerticalAlignment.top, 163 | "middle": Text.VerticalAlignment.center, 164 | "bottom": Text.VerticalAlignment.bottom 165 | } 166 | const vertAlignMap2 = { 167 | [Text.VerticalAlignment.top]: "top", 168 | [Text.VerticalAlignment.center]: "middle", 169 | [Text.VerticalAlignment.bottom]: "bottom", 170 | } 171 | const bordedLineEndMap = { 172 | "butt": Style.LineEnd.Butt, 173 | "round": Style.LineEnd.Round, 174 | "projecting": Style.LineEnd.Projecting 175 | } 176 | 177 | const bordedLineJoinMap = { 178 | "miter": Style.LineJoin.Miter, 179 | "round": Style.LineJoin.Round, 180 | "bevel": Style.LineJoin.Bevel 181 | } 182 | 183 | const smartLayoutMap = { 184 | "none": null, 185 | "left": SmartLayout.LeftToRight, 186 | "lefttoright": SmartLayout.LeftToRight, 187 | "center": SmartLayout.HorizontallyCenter, 188 | "horizontallycenter": SmartLayout.HorizontallyCenter, 189 | "right": SmartLayout.RightToLeft, 190 | "righttoleft": SmartLayout.RightToLeft, 191 | "toptobottom": SmartLayout.TopToBottom, 192 | "verticallycenter": SmartLayout.VerticallyCenter, 193 | "bottomtotop": SmartLayout.BottomToTop, 194 | } 195 | 196 | const bordedArrowheadMap = { 197 | "none": Style.Arrowhead.None, 198 | "openarrow": Style.Arrowhead.OpenArrow, 199 | "filledarrow": Style.Arrowhead.FilledArrow, 200 | "opencircle": Style.Arrowhead.OpenCircle, 201 | "filledcircle": Style.Arrowhead.FilledCircle, 202 | "opensquare": Style.Arrowhead.OpenSquare, 203 | "filledsquare": Style.Arrowhead.FilledSquare, 204 | } 205 | 206 | 207 | const weights = [ 208 | { label: 'thin', sketch: 2, css: 100, title: "Thin" }, 209 | { label: 'extra-light', sketch: 3, css: 200, title: "Extra Light" }, 210 | { label: 'light', sketch: 4, css: 300, title: "Light" }, 211 | { label: 'regular', sketch: 5, css: 400, title: "Regular" }, 212 | { label: 'medium', sketch: 6, css: 500, title: "Medium" }, 213 | { label: 'semi-bold', sketch: 8, css: 600, title: "Semi Bold" }, 214 | { label: 'semibold', sketch: 8, css: 600, title: "Semi Bold#2" }, 215 | { label: 'bold', sketch: 9, css: 700, title: "Bold" }, 216 | { label: 'extra-bold', sketch: 10, css: 800, title: "Extra Bold" }, 217 | { label: 'black', sketch: 12, css: 900, title: "Black" }, 218 | { label: 'fa-solid', sketch: 14, css: "fa-solid", title: "Font Awesome Solid" }, 219 | ] 220 | 221 | // source: https://github.com/bahamas10/css-color-names/blob/master/css-color-names.json 222 | const COLOR_NAMES = { 223 | "aliceblue": "#f0f8ff", 224 | "antiquewhite": "#faebd7", 225 | "aqua": "#00ffff", 226 | "aquamarine": "#7fffd4", 227 | "azure": "#f0ffff", 228 | "beige": "#f5f5dc", 229 | "bisque": "#ffe4c4", 230 | "black": "#000000", 231 | "blanchedalmond": "#ffebcd", 232 | "blue": "#0000ff", 233 | "blueviolet": "#8a2be2", 234 | "brown": "#a52a2a", 235 | "burlywood": "#deb887", 236 | "cadetblue": "#5f9ea0", 237 | "chartreuse": "#7fff00", 238 | "chocolate": "#d2691e", 239 | "coral": "#ff7f50", 240 | "cornflowerblue": "#6495ed", 241 | "cornsilk": "#fff8dc", 242 | "crimson": "#dc143c", 243 | "cyan": "#00ffff", 244 | "darkblue": "#00008b", 245 | "darkcyan": "#008b8b", 246 | "darkgoldenrod": "#b8860b", 247 | "darkgray": "#a9a9a9", 248 | "darkgreen": "#006400", 249 | "darkgrey": "#a9a9a9", 250 | "darkkhaki": "#bdb76b", 251 | "darkmagenta": "#8b008b", 252 | "darkolivegreen": "#556b2f", 253 | "darkorange": "#ff8c00", 254 | "darkorchid": "#9932cc", 255 | "darkred": "#8b0000", 256 | "darksalmon": "#e9967a", 257 | "darkseagreen": "#8fbc8f", 258 | "darkslateblue": "#483d8b", 259 | "darkslategray": "#2f4f4f", 260 | "darkslategrey": "#2f4f4f", 261 | "darkturquoise": "#00ced1", 262 | "darkviolet": "#9400d3", 263 | "deeppink": "#ff1493", 264 | "deepskyblue": "#00bfff", 265 | "dimgray": "#696969", 266 | "dimgrey": "#696969", 267 | "dodgerblue": "#1e90ff", 268 | "firebrick": "#b22222", 269 | "floralwhite": "#fffaf0", 270 | "forestgreen": "#228b22", 271 | "fuchsia": "#ff00ff", 272 | "gainsboro": "#dcdcdc", 273 | "ghostwhite": "#f8f8ff", 274 | "goldenrod": "#daa520", 275 | "gold": "#ffd700", 276 | "gray": "#808080", 277 | "green": "#008000", 278 | "greenyellow": "#adff2f", 279 | "grey": "#808080", 280 | "honeydew": "#f0fff0", 281 | "hotpink": "#ff69b4", 282 | "indianred": "#cd5c5c", 283 | "indigo": "#4b0082", 284 | "ivory": "#fffff0", 285 | "khaki": "#f0e68c", 286 | "lavenderblush": "#fff0f5", 287 | "lavender": "#e6e6fa", 288 | "lawngreen": "#7cfc00", 289 | "lemonchiffon": "#fffacd", 290 | "lightblue": "#add8e6", 291 | "lightcoral": "#f08080", 292 | "lightcyan": "#e0ffff", 293 | "lightgoldenrodyellow": "#fafad2", 294 | "lightgray": "#d3d3d3", 295 | "lightgreen": "#90ee90", 296 | "lightgrey": "#d3d3d3", 297 | "lightpink": "#ffb6c1", 298 | "lightsalmon": "#ffa07a", 299 | "lightseagreen": "#20b2aa", 300 | "lightskyblue": "#87cefa", 301 | "lightslategray": "#778899", 302 | "lightslategrey": "#778899", 303 | "lightsteelblue": "#b0c4de", 304 | "lightyellow": "#ffffe0", 305 | "lime": "#00ff00", 306 | "limegreen": "#32cd32", 307 | "linen": "#faf0e6", 308 | "magenta": "#ff00ff", 309 | "maroon": "#800000", 310 | "mediumaquamarine": "#66cdaa", 311 | "mediumblue": "#0000cd", 312 | "mediumorchid": "#ba55d3", 313 | "mediumpurple": "#9370db", 314 | "mediumseagreen": "#3cb371", 315 | "mediumslateblue": "#7b68ee", 316 | "mediumspringgreen": "#00fa9a", 317 | "mediumturquoise": "#48d1cc", 318 | "mediumvioletred": "#c71585", 319 | "midnightblue": "#191970", 320 | "mintcream": "#f5fffa", 321 | "mistyrose": "#ffe4e1", 322 | "moccasin": "#ffe4b5", 323 | "navajowhite": "#ffdead", 324 | "navy": "#000080", 325 | "oldlace": "#fdf5e6", 326 | "olive": "#808000", 327 | "olivedrab": "#6b8e23", 328 | "orange": "#ffa500", 329 | "orangered": "#ff4500", 330 | "orchid": "#da70d6", 331 | "palegoldenrod": "#eee8aa", 332 | "palegreen": "#98fb98", 333 | "paleturquoise": "#afeeee", 334 | "palevioletred": "#db7093", 335 | "papayawhip": "#ffefd5", 336 | "peachpuff": "#ffdab9", 337 | "peru": "#cd853f", 338 | "pink": "#ffc0cb", 339 | "plum": "#dda0dd", 340 | "powderblue": "#b0e0e6", 341 | "purple": "#800080", 342 | "rebeccapurple": "#663399", 343 | "red": "#ff0000", 344 | "rosybrown": "#bc8f8f", 345 | "royalblue": "#4169e1", 346 | "saddlebrown": "#8b4513", 347 | "salmon": "#fa8072", 348 | "sandybrown": "#f4a460", 349 | "seagreen": "#2e8b57", 350 | "seashell": "#fff5ee", 351 | "sienna": "#a0522d", 352 | "silver": "#c0c0c0", 353 | "skyblue": "#87ceeb", 354 | "slateblue": "#6a5acd", 355 | "slategray": "#708090", 356 | "slategrey": "#708090", 357 | "snow": "#fffafa", 358 | "springgreen": "#00ff7f", 359 | "steelblue": "#4682b4", 360 | "tan": "#d2b48c", 361 | "teal": "#008080", 362 | "thistle": "#d8bfd8", 363 | "tomato": "#ff6347", 364 | "turquoise": "#40e0d0", 365 | "violet": "#ee82ee", 366 | "wheat": "#f5deb3", 367 | "white": "#ffffff", 368 | "whitesmoke": "#f5f5f5", 369 | "yellow": "#ffff00", 370 | "yellowgreen": "#9acd32" 371 | } 372 | 373 | function degToRad (deg) { 374 | return deg * Math.PI / 180; 375 | } -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/lib/ga.js: -------------------------------------------------------------------------------- 1 | @import "lib/utils.js"; 2 | @import "constants.js"; 3 | 4 | function jsonToQueryString(json) { 5 | return Object.keys(json) 6 | .map(function (key) { 7 | return encodeURIComponent(key) + "=" + encodeURIComponent(json[key]); 8 | }) 9 | .join("&"); 10 | } 11 | 12 | function _completeGA(d, r, e) { 13 | if (DEBUG) log("Completed GA") 14 | } 15 | 16 | 17 | 18 | function track(page, props = undefined) { 19 | coscript.scheduleWithInterval_jsFunction(1, function () { 20 | 21 | var trackingId = Constants.GA_ID 22 | 23 | var Settings = require("sketch/settings"); 24 | var kUUIDKey = "google.analytics.uuid"; 25 | var uuid = null 26 | var uuid = NSUserDefaults.standardUserDefaults().objectForKey(kUUIDKey); 27 | if (!uuid) { 28 | uuid = NSUUID.UUID().UUIDString(); 29 | NSUserDefaults.standardUserDefaults().setObject_forKey(uuid, kUUIDKey) 30 | } 31 | 32 | var variant = "" // MSApplicationMetadata.metadata().variant; 33 | var source = 34 | "Sketch " + 35 | (variant == "NONAPPSTORE" ? "" : variant + " ") + 36 | Settings.version.sketch; 37 | 38 | 39 | if (Settings.settingForKey(SettingKeys.PLUGIN_GA_DISABLED)) { 40 | // the user didn't enable sharing analytics 41 | return 'the user didn\'t enable sharing analytics'; 42 | } 43 | 44 | var payload = { 45 | v: 1, 46 | tid: trackingId, 47 | ds: source, 48 | cid: uuid, 49 | t: "pageview", 50 | dp: page 51 | }; 52 | 53 | if (typeof __command !== "undefined") { 54 | payload.an = __command.pluginBundle().name(); 55 | payload.aid = __command.pluginBundle().identifier(); 56 | payload.av = __command.pluginBundle().version(); 57 | } 58 | 59 | if (props) { 60 | Object.keys(props).forEach(function (key) { 61 | payload[key] = props[key]; 62 | }); 63 | } 64 | 65 | var nURL = NSURL.URLWithString( 66 | "https://www.google-analytics.com/collect?payload_data&" + 67 | jsonToQueryString(payload) + 68 | "&z=" + 69 | NSUUID.UUID().UUIDString() 70 | ); 71 | if (DEBUG) log("Started GA " + nURL) 72 | //NSData.dataWithContentsOfURL(nURL); 73 | let session = NSURLSession.sharedSession() 74 | //let task = [session dataTaskWithURL: nURL completionHandler: _completeGA]//, _completeGA) 75 | //let task = session.dataTaskWithURL_completionHandler_(nURL, _completeGA) 76 | let task = session.dataTaskWithURL(nURL) 77 | task.resume() 78 | }) 79 | } 80 | -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/lib/gradient-parser/parser.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Rafael Caricio. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | var GradientParser = (GradientParser || {}); 6 | 7 | GradientParser.parse = (function () { 8 | 9 | var tokens = { 10 | linearGradient: /^(\-(webkit|o|ms|moz)\-)?(linear\-gradient)/i, 11 | repeatingLinearGradient: /^(\-(webkit|o|ms|moz)\-)?(repeating\-linear\-gradient)/i, 12 | radialGradient: /^(\-(webkit|o|ms|moz)\-)?(radial\-gradient)/i, 13 | repeatingRadialGradient: /^(\-(webkit|o|ms|moz)\-)?(repeating\-radial\-gradient)/i, 14 | sideOrCorner: /^to (left (top|bottom)|right (top|bottom)|left|right|top|bottom)/i, 15 | extentKeywords: /^(closest\-side|closest\-corner|farthest\-side|farthest\-corner|contain|cover)/, 16 | positionKeywords: /^(left|center|right|top|bottom)/i, 17 | pixelValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))px/, 18 | percentageValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))\%/, 19 | emValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))em/, 20 | angleValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))deg/, 21 | startCall: /^\(/, 22 | endCall: /^\)/, 23 | comma: /^,/, 24 | hexColor: /^\#([0-9a-fA-F]+)/, 25 | literalColor: /^([a-zA-Z]+)/, 26 | rgbColor: /^rgb/i, 27 | rgbaColor: /^rgba/i, 28 | number: /^(([0-9]*\.[0-9]+)|([0-9]+\.?))/ 29 | }; 30 | 31 | var input = ''; 32 | 33 | function error(msg) { 34 | var err = new Error(input + ': ' + msg); 35 | err.source = input; 36 | throw err; 37 | } 38 | 39 | function getAST() { 40 | var ast = matchListDefinitions(); 41 | 42 | if (input.length > 0) { 43 | error('Invalid input not EOF'); 44 | } 45 | 46 | return ast; 47 | } 48 | 49 | function matchListDefinitions() { 50 | return matchListing(matchDefinition); 51 | } 52 | 53 | function matchDefinition() { 54 | return matchGradient( 55 | 'linear-gradient', 56 | tokens.linearGradient, 57 | matchLinearOrientation) || 58 | 59 | matchGradient( 60 | 'repeating-linear-gradient', 61 | tokens.repeatingLinearGradient, 62 | matchLinearOrientation) || 63 | 64 | matchGradient( 65 | 'radial-gradient', 66 | tokens.radialGradient, 67 | matchListRadialOrientations) || 68 | 69 | matchGradient( 70 | 'repeating-radial-gradient', 71 | tokens.repeatingRadialGradient, 72 | matchListRadialOrientations); 73 | } 74 | 75 | function matchGradient(gradientType, pattern, orientationMatcher) { 76 | return matchCall(pattern, function (captures) { 77 | 78 | var orientation = orientationMatcher(); 79 | if (orientation) { 80 | if (!scan(tokens.comma)) { 81 | error('Missing comma before color stops'); 82 | } 83 | } 84 | 85 | return { 86 | type: gradientType, 87 | orientation: orientation, 88 | colorStops: matchListing(matchColorStop) 89 | }; 90 | }); 91 | } 92 | 93 | function matchCall(pattern, callback) { 94 | var captures = scan(pattern); 95 | 96 | if (captures) { 97 | if (!scan(tokens.startCall)) { 98 | error('Missing ('); 99 | } 100 | 101 | var result = callback(captures); 102 | 103 | if (!scan(tokens.endCall)) { 104 | error('Missing )'); 105 | } 106 | 107 | return result; 108 | } 109 | } 110 | 111 | function matchLinearOrientation() { 112 | return matchSideOrCorner() || 113 | matchAngle(); 114 | } 115 | 116 | function matchSideOrCorner() { 117 | return match('directional', tokens.sideOrCorner, 1); 118 | } 119 | 120 | function matchAngle() { 121 | return match('angular', tokens.angleValue, 1); 122 | } 123 | 124 | function matchListRadialOrientations() { 125 | var radialOrientations, 126 | radialOrientation = matchRadialOrientation(), 127 | lookaheadCache; 128 | 129 | if (radialOrientation) { 130 | radialOrientations = []; 131 | radialOrientations.push(radialOrientation); 132 | 133 | lookaheadCache = input; 134 | if (scan(tokens.comma)) { 135 | radialOrientation = matchRadialOrientation(); 136 | if (radialOrientation) { 137 | radialOrientations.push(radialOrientation); 138 | } else { 139 | input = lookaheadCache; 140 | } 141 | } 142 | } 143 | 144 | return radialOrientations; 145 | } 146 | 147 | function matchRadialOrientation() { 148 | var radialType = matchCircle() || 149 | matchEllipse(); 150 | 151 | if (radialType) { 152 | radialType.at = matchAtPosition(); 153 | } else { 154 | var extent = matchExtentKeyword(); 155 | if (extent) { 156 | radialType = extent; 157 | var positionAt = matchAtPosition(); 158 | if (positionAt) { 159 | radialType.at = positionAt; 160 | } 161 | } else { 162 | var defaultPosition = matchPositioning(); 163 | if (defaultPosition) { 164 | radialType = { 165 | type: 'default-radial', 166 | at: defaultPosition 167 | }; 168 | } 169 | } 170 | } 171 | 172 | return radialType; 173 | } 174 | 175 | function matchCircle() { 176 | var circle = match('shape', /^(circle)/i, 0); 177 | 178 | if (circle) { 179 | circle.style = matchLength() || matchExtentKeyword(); 180 | } 181 | 182 | return circle; 183 | } 184 | 185 | function matchEllipse() { 186 | var ellipse = match('shape', /^(ellipse)/i, 0); 187 | 188 | if (ellipse) { 189 | ellipse.style = matchDistance() || matchExtentKeyword(); 190 | } 191 | 192 | return ellipse; 193 | } 194 | 195 | function matchExtentKeyword() { 196 | return match('extent-keyword', tokens.extentKeywords, 1); 197 | } 198 | 199 | function matchAtPosition() { 200 | if (match('position', /^at/, 0)) { 201 | var positioning = matchPositioning(); 202 | 203 | if (!positioning) { 204 | error('Missing positioning value'); 205 | } 206 | 207 | return positioning; 208 | } 209 | } 210 | 211 | function matchPositioning() { 212 | var location = matchCoordinates(); 213 | 214 | if (location.x || location.y) { 215 | return { 216 | type: 'position', 217 | value: location 218 | }; 219 | } 220 | } 221 | 222 | function matchCoordinates() { 223 | return { 224 | x: matchDistance(), 225 | y: matchDistance() 226 | }; 227 | } 228 | 229 | function matchListing(matcher) { 230 | var captures = matcher(), 231 | result = []; 232 | 233 | if (captures) { 234 | result.push(captures); 235 | while (scan(tokens.comma)) { 236 | captures = matcher(); 237 | if (captures) { 238 | result.push(captures); 239 | } else { 240 | error('One extra comma'); 241 | } 242 | } 243 | } 244 | 245 | return result; 246 | } 247 | 248 | function matchColorStop() { 249 | var color = matchColor(); 250 | 251 | if (!color) { 252 | error('Expected color definition'); 253 | } 254 | 255 | color.length = matchDistance(); 256 | return color; 257 | } 258 | 259 | function matchColor() { 260 | return matchHexColor() || 261 | matchRGBAColor() || 262 | matchRGBColor() || 263 | matchLiteralColor(); 264 | } 265 | 266 | function matchLiteralColor() { 267 | return match('literal', tokens.literalColor, 0); 268 | } 269 | 270 | function matchHexColor() { 271 | return match('hex', tokens.hexColor, 1); 272 | } 273 | 274 | function matchRGBColor() { 275 | return matchCall(tokens.rgbColor, function () { 276 | return { 277 | type: 'rgb', 278 | value: matchListing(matchNumber) 279 | }; 280 | }); 281 | } 282 | 283 | function matchRGBAColor() { 284 | return matchCall(tokens.rgbaColor, function () { 285 | return { 286 | type: 'rgba', 287 | value: matchListing(matchNumber) 288 | }; 289 | }); 290 | } 291 | 292 | function matchNumber() { 293 | return scan(tokens.number)[1]; 294 | } 295 | 296 | function matchDistance() { 297 | return match('%', tokens.percentageValue, 1) || 298 | matchPositionKeyword() || 299 | matchLength(); 300 | } 301 | 302 | function matchPositionKeyword() { 303 | return match('position-keyword', tokens.positionKeywords, 1); 304 | } 305 | 306 | function matchLength() { 307 | return match('px', tokens.pixelValue, 1) || 308 | match('em', tokens.emValue, 1); 309 | } 310 | 311 | function match(type, pattern, captureIndex) { 312 | var captures = scan(pattern); 313 | if (captures) { 314 | return { 315 | type: type, 316 | value: captures[captureIndex] 317 | }; 318 | } 319 | } 320 | 321 | function scan(regexp) { 322 | var captures, 323 | blankCaptures; 324 | 325 | blankCaptures = /^[\n\r\t\s]+/.exec(input); 326 | if (blankCaptures) { 327 | consume(blankCaptures[0].length); 328 | } 329 | 330 | captures = regexp.exec(input); 331 | if (captures) { 332 | consume(captures[0].length); 333 | } 334 | 335 | return captures; 336 | } 337 | 338 | function consume(size) { 339 | input = input.substr(size); 340 | } 341 | 342 | return function (code) { 343 | input = code.toString(); 344 | return getAST(); 345 | }; 346 | })(); -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/lib/uidialog.js: -------------------------------------------------------------------------------- 1 | var UIDialog_iconImage = null 2 | const TAB_HEIGHT = 55 3 | 4 | function Class(className, BaseClass, selectorHandlerDict) { 5 | var uniqueClassName = className + NSUUID.UUID().UUIDString(); 6 | var delegateClassDesc = MOClassDescription.allocateDescriptionForClassWithName_superclass_(uniqueClassName, BaseClass); 7 | for (var selectorString in selectorHandlerDict) { 8 | delegateClassDesc.addInstanceMethodWithSelector_function_(selectorString, selectorHandlerDict[selectorString]); 9 | } 10 | delegateClassDesc.registerClass(); 11 | return NSClassFromString(uniqueClassName); 12 | }; 13 | 14 | class UIAbstractWindow { 15 | 16 | constructor(window, intRect) { 17 | this.window = window 18 | 19 | var container = NSView.alloc().initWithFrame(intRect) 20 | this.container = container 21 | this.topContainer = container 22 | this.views = [] 23 | 24 | this.leftOffset = 0 25 | 26 | this.rect = intRect 27 | this.y = NSHeight(this.rect) 28 | 29 | this.leftColumn = true 30 | this.leftColWidth = 120 31 | this.textOffset = 2 32 | } 33 | 34 | removeLeftColumn() { 35 | this.leftColumn = false 36 | this.leftColWidth = 0 37 | this.textOffset = 0 38 | } 39 | 40 | initTabs(tabs) { 41 | const intRect = this.rect 42 | 43 | this.tabs = tabs.map(function (tab) { return { label: tab } }) 44 | 45 | var tabView = NSTabView.alloc().initWithFrame(intRect) 46 | 47 | this.tabs.forEach(function (tab, index) { 48 | 49 | let viewController = NSViewController.alloc().init() 50 | viewController.originalSize = intRect 51 | 52 | var view = NSView.alloc().initWithFrame(intRect) 53 | view.wantsLayer = false 54 | viewController.view = view 55 | 56 | let tabViewIem = NSTabViewItem.alloc().init() 57 | tabViewIem.viewController = viewController 58 | tabViewIem.label = tab.label 59 | tabViewIem.initialFirstResponder = view 60 | 61 | tabView.addTabViewItem(tabViewIem) 62 | 63 | tab.container = view 64 | 65 | }, this) 66 | 67 | this.tabView = tabView 68 | this.container = this.tabs[0].container 69 | this.topContainer = tabView 70 | 71 | this.leftOffset = 20 72 | this.y = NSHeight(this.rect) - TAB_HEIGHT 73 | } 74 | 75 | setTabForViewsCreating(tabIndex) { 76 | this.container = this.tabs[tabIndex].container 77 | 78 | this.y = NSHeight(this.rect) - TAB_HEIGHT 79 | } 80 | 81 | 82 | enableTextByID(id, enabled) { 83 | if (!(id in dialog.views)) return 84 | 85 | var text = dialog.views[id] 86 | if (!enabled) 87 | text.textColor = NSColor.disabledControlTextColor() 88 | else 89 | text.textColor = NSColor.controlTextColor() 90 | 91 | } 92 | 93 | enableHintByID(id, enabled) { 94 | if (!(id in dialog.views)) return 95 | 96 | var text = dialog.views[id] 97 | if (!enabled) 98 | text.textColor = NSColor.disabledControlTextColor() 99 | else 100 | text.textColor = NSColor.secondaryLabelColor() 101 | 102 | } 103 | 104 | enableControlByID(id, enabled) { 105 | var control = dialog.views[id] 106 | control.enabled = enabled 107 | 108 | this.enableTextByID(id + 'Label', enabled) 109 | this.enableHintByID(id + 'Hint', enabled) 110 | 111 | } 112 | 113 | getNewFrame(height = 25, width = -1, yinc = -1) { 114 | var frame = NSMakeRect(this.leftColWidth, this.y - height, width == -1 ? NSWidth(this.rect) - 10 - this.leftColWidth : width, height) 115 | this.y -= height + (yinc >= 0 ? yinc : 10) 116 | return frame 117 | } 118 | 119 | addSpace() { 120 | this.getNewFrame(0) 121 | } 122 | 123 | addLeftLabel(id, text, height = 40) { 124 | var frame = null 125 | 126 | if (this.leftColumn) 127 | frame = NSMakeRect(0, this.y - height - this.textOffset, this.leftColWidth - 10, height) 128 | else 129 | frame = this.getNewFrame(height) 130 | 131 | const label = NSTextField.alloc().initWithFrame(frame); 132 | label.setStringValue(text); 133 | label.setBezeled(false); 134 | label.setDrawsBackground(false); 135 | label.setEditable(false); 136 | label.setSelectable(false); 137 | if (this.leftColumn) { 138 | label.setFont(NSFont.boldSystemFontOfSize(12)) 139 | label.setAlignment(NSTextAlignmentRight) 140 | } 141 | 142 | if ('' != id) this.views[id] = label 143 | 144 | this.container.addSubview(label) 145 | return label 146 | } 147 | 148 | addLabel(id, text, height = 25, frame = undefined) { 149 | const myframe = frame ? Utils.copyRect(frame) : undefined 150 | if (myframe) myframe.size.height = height 151 | const label = NSTextField.alloc().initWithFrame(myframe ? myframe : this.getNewFrame(height)); 152 | label.setStringValue(text); 153 | label.setBezeled(false); 154 | label.setDrawsBackground(false); 155 | label.setEditable(false); 156 | label.setSelectable(false); 157 | 158 | if ('' != id) this.views[id] = label 159 | 160 | this.container.addSubview(label) 161 | this.y += 5 162 | return label 163 | } 164 | 165 | // required: id:, options: 166 | // opional: label: "", width: 220, frame: undefined 167 | addComboBox(opt) { 168 | if (undefined == opt.label) opt.label = "" 169 | if (undefined == opt.width) opt.width = 220 170 | 171 | if (opt.label != '') 172 | this.addLabel(id + "Label", opt.label, 17) 173 | 174 | const v = NSComboBox.alloc().initWithFrame(opt.frame ? opt.frame : this.getNewFrame(20, opt.width)) 175 | if (opt.options.length > 0) { 176 | v.addItemsWithObjectValues(opt.options) 177 | v.setNumberOfVisibleItems(opt.options.length); 178 | v.selectItemAtIndex(0) 179 | } 180 | v.setCompletes(1); 181 | 182 | this.container.addSubview(v) 183 | this.views[opt.id] = v 184 | 185 | return v 186 | } 187 | 188 | addCheckbox(id, label, checked, height = 18) { 189 | checked = (checked == false) ? NSOffState : NSOnState; 190 | 191 | const checkbox = NSButton.alloc().initWithFrame(this.getNewFrame(height, -1, 6)); 192 | checkbox.setButtonType(NSSwitchButton); 193 | checkbox.setBezelStyle(0); 194 | checkbox.setTitle(label); 195 | checkbox.setState(checked); 196 | 197 | this.container.addSubview(checkbox) 198 | this.views[id] = checkbox 199 | return checkbox 200 | } 201 | 202 | addTextBox(id, label, textValue, inlineHint = "", height = 120) { 203 | if (label != '') this.addLabel(id + "Label", label, 17) 204 | 205 | const textBox = NSTextField.alloc().initWithFrame(this.getNewFrame(height)) 206 | textBox.setEditable(true) 207 | textBox.setBordered(true) 208 | textBox.setStringValue(textValue) 209 | if (inlineHint != "") { 210 | textBox.setPlaceholderString(inlineHint) 211 | } 212 | 213 | this.container.addSubview(textBox) 214 | this.views[id] = textBox 215 | 216 | return textBox 217 | } 218 | 219 | 220 | addTextViewBox(id, label, textValue, height = 120) { 221 | if (label != '') this.addLabel(id + "Label", label, 17) 222 | 223 | const frame = this.getNewFrame(height) 224 | const scrollView = NSScrollView.alloc().initWithFrame(frame) 225 | scrollView.setHasVerticalScroller(true) 226 | scrollView.setHasHorizontalScroller(true) 227 | 228 | const textView = NSTextView.alloc().initWithFrame(frame) 229 | textView.setEditable(false) 230 | textView.setString(textValue + "") 231 | 232 | scrollView.addSubview(textView) 233 | scrollView.setDocumentView(textView) 234 | this.container.addSubview(scrollView) 235 | 236 | 237 | this.views[id] = textView 238 | 239 | return textView 240 | } 241 | 242 | addTextInput(id, label, textValue, inlineHint = "", width = 220, frame = undefined) { 243 | if (label != '') this.addLabel(id + "Label", label, 17, frame) 244 | 245 | const input = NSTextField.alloc().initWithFrame(frame ? frame : this.getNewFrame(20, width)) 246 | input.setEditable(true) 247 | input.setBordered(true) 248 | input.setStringValue(textValue + "") 249 | if (inlineHint != "") { 250 | input.setPlaceholderString(inlineHint) 251 | } 252 | 253 | this.container.addSubview(input) 254 | this.views[id] = input 255 | 256 | return input 257 | } 258 | 259 | // opt: required: id, label, labelSelect, textValue 260 | // optional: inlineHint = "", width = 220, widthSelect = 50), askFilePath=false 261 | // comboBoxOptions: string array 262 | addPathInput(opt) { 263 | if (!('width' in opt)) opt.width = 220 264 | if (!('widthSelect' in opt)) opt.widthSelect = 50 265 | if (!('inlineHint' in opt)) opt.inlineHint = "" 266 | if (!('askFilePath' in opt)) opt.askFilePath = false 267 | 268 | if (opt.label != '') this.addLabel(opt.id + "Label", opt.label, 17) 269 | 270 | const frame = this.getNewFrame(28, opt.width - opt.widthSelect - 5) 271 | const frame2 = Utils.copyRect(frame) 272 | frame2.origin.x = frame2.origin.x + opt.width - opt.widthSelect 273 | frame2.origin.y -= 3 274 | 275 | const input = 'comboBoxOptions' in opt ? 276 | this.addComboBox({ id: opt.id, options: opt.comboBoxOptions, width: 0, frame: frame }) 277 | : this.addTextInput(opt.id, "", opt.textValue, opt.inlineHint, 0, frame) 278 | 279 | this.addButton(opt.id + "Select", opt.labelSelect, function () { 280 | const newPath = opt.askFilePath 281 | ? Utils.askFilePath(input.stringValue() + "") 282 | : Utils.askPath(input.stringValue() + "") 283 | if (newPath != null) { 284 | input.setStringValue(newPath) 285 | } 286 | return 287 | }, 0, frame2) 288 | return input 289 | } 290 | addSelect(id, label, selectItem, options, width = 100) { 291 | if (label != '') this.addLabel(id + "Label", label, 15) 292 | 293 | const v = NSPopUpButton.alloc().initWithFrame(this.getNewFrame(23, width)); 294 | v.addItemsWithTitles(options) 295 | v.selectItemAtIndex(selectItem) 296 | 297 | this.container.addSubview(v) 298 | this.views[id] = v 299 | return v 300 | } 301 | 302 | 303 | addRadioButtons(id, label, selectItem, options, width = 100) { 304 | if (label != '') this.addLabel(id + "Label", label, 15) 305 | 306 | // pre-select the first item 307 | if (selectItem < 0) selectItem = 0 308 | 309 | let group = this.startRadioButtions(id, selectItem) 310 | 311 | for (var item of options) { 312 | const index = group.btns.length 313 | 314 | const btn = NSButton.alloc().initWithFrame(this.getNewFrame(18, width)) 315 | btn.setButtonType(NSRadioButton) 316 | btn.setTitle(item) 317 | btn.setState(index != selectItem ? NSOffState : NSOnState) 318 | btn.myGroup = group 319 | btn.myIndex = index 320 | btn.setCOSJSTargetFunction(group.radioTargetFunction) 321 | 322 | this.container.addSubview(btn) 323 | group.btns.push(btn) 324 | } 325 | 326 | return group 327 | } 328 | 329 | startRadioButtions(idGroup, selectedIndex) { 330 | const groups = { 331 | id: idGroup, 332 | btns: [], 333 | selectedIndex: selectedIndex, 334 | radioTargetFunction: (sender) => { 335 | sender.myGroup.selectedIndex = sender.myIndex 336 | } 337 | 338 | } 339 | this._buttonsGroups = groups 340 | this.views[idGroup] = this._buttonsGroups 341 | return this._buttonsGroups 342 | } 343 | 344 | addRadioButton(id, title, index, frame) { 345 | const selected = this._buttonsGroups.selectedIndex == index 346 | 347 | const btn = NSButton.alloc().initWithFrame(frame) 348 | btn.setButtonType(NSRadioButton) 349 | if (title != '') btn.setTitle(title) 350 | btn.setState(!selected ? NSOffState : NSOnState) 351 | btn.myGroup = this._buttonsGroups 352 | btn.myIndex = index 353 | btn.setCOSJSTargetFunction(this._buttonsGroups.radioTargetFunction) 354 | 355 | this.views[id] = btn 356 | this.container.addSubview(btn) 357 | this._buttonsGroups.btns.push(btn) 358 | 359 | return btn 360 | } 361 | 362 | addButton(id, label, func, width = 100, frame = undefined) { 363 | // create OK button 364 | var btn = NSButton.alloc().initWithFrame(frame ? frame : this.getNewFrame(20, width)); 365 | btn.setTitle(label) 366 | btn.setBezelStyle(NSRoundedBezelStyle) 367 | btn.sizeToFit() 368 | btn.setCOSJSTargetFunction(func) 369 | 370 | this.container.addSubview(btn) 371 | this.views[id] = btn 372 | return btn 373 | 374 | } 375 | 376 | addHint(id, label, height = 23) { 377 | this.y += 3 378 | 379 | const hint = NSTextField.alloc().initWithFrame(this.getNewFrame(height, -1, 3)); 380 | hint.setStringValue(label); 381 | hint.setColor = NSColor.secondaryLabelColor() 382 | hint.setBezeled(false); 383 | hint.setDrawsBackground(false); 384 | hint.setEditable(false); 385 | hint.setSelectable(false); 386 | hint.setFont(NSFont.systemFontOfSize(10)) 387 | 388 | this.container.addSubview(hint) 389 | if ('' != id) this.views[id] = hint 390 | return hint 391 | } 392 | 393 | addDivider() { 394 | 395 | const height = 1 396 | var frame = NSMakeRect(0, this.y - height, NSWidth(this.rect) - 10, height) 397 | this.y -= height + 10 398 | 399 | var divider = NSView.alloc().initWithFrame(frame); 400 | 401 | divider.setWantsLayer(1); 402 | divider.layer().setBackgroundColor(CGColorCreateGenericRGB(204 / 255, 204 / 255, 204 / 255, 1)); 403 | 404 | this.container.addSubview(divider) 405 | 406 | return divider; 407 | } 408 | 409 | // image: NSImage 410 | 411 | addImage(id, image, frame) { 412 | var nImageView = NSImageView.alloc().initWithFrame(frame) 413 | nImageView.setImage(image) 414 | this.container.addSubview(nImageView) 415 | this.views[id] = nImageView 416 | return nImageView 417 | } 418 | 419 | 420 | finish() { 421 | this.window = null 422 | } 423 | 424 | } 425 | 426 | class UIDialog extends UIAbstractWindow { 427 | 428 | static setUp(context) { 429 | UIDialog_iconImage = NSImage.alloc().initByReferencingFile(context.plugin.urlForResourceNamed("icon.png").path()) 430 | } 431 | 432 | constructor(title, rect, okButtonTitle, description = '', cancelButtonTitle = "Cancel",thirdButtonTitle=undefined) { 433 | var window = NSAlert.alloc().init() 434 | window.setIcon(UIDialog_iconImage) 435 | window.setMessageText(title) 436 | if (description != '') { 437 | window.setInformativeText(description) 438 | } 439 | if (okButtonTitle) window.addButtonWithTitle(okButtonTitle) 440 | if (cancelButtonTitle) window.addButtonWithTitle(cancelButtonTitle) 441 | if (thirdButtonTitle) window.addButtonWithTitle(thirdButtonTitle) 442 | 443 | 444 | super(window, rect) 445 | } 446 | 447 | 448 | 449 | run() { 450 | this.window.setAccessoryView(this.topContainer) 451 | const res = this.window.runModal() 452 | this.userClickedOk = res == '1000' 453 | this.userClickedCancel = res == '1001' 454 | this.userClickedThird = res == '1002' 455 | return this.userClickedOk 456 | } 457 | 458 | } 459 | -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/lib/uipanel.js: -------------------------------------------------------------------------------- 1 | class UIPanel extends UIAbstractWindow { 2 | 3 | constructor(title) { 4 | let winRect = NSMakeRect(300, 500, 400, 270) 5 | let window = NSWindow.alloc().initWithContentRect_styleMask_backing_defer(winRect, NSWindowStyleMaskTitled | NSWindowStyleMaskFullSizeContentView, NSBackingStoreBuffered, true) 6 | window.title = title 7 | 8 | let contRect = window.contentLayoutRect() 9 | 10 | super(window, contRect) 11 | window.setContentView(this.container) 12 | 13 | window.ReleasedWhenClosed = true; 14 | } 15 | 16 | 17 | show() { 18 | this.window.makeKeyAndOrderFront(this.window) 19 | } 20 | 21 | finish() { 22 | log('closing...') 23 | this.window.orderOut(null) 24 | 25 | //this.window.close() // close() crashes Sketch 26 | log('closed') 27 | this.window = null 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Puzzle Tokens", 3 | "description": "Apply design tokens to Sketch styles", 4 | "author": "Maxim Bazarov", 5 | "homepage": "", 6 | "identifier": "com.cloudblue.sketch.ds", 7 | "appcast": "https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/master/appcast.xml", 8 | "compatibleVersion": 3, 9 | "bundleVersion": 1, 10 | "version": "8.20.0", 11 | "icon": "icon.png", 12 | "commands": [ 13 | { 14 | "script": "cmd-actions.js", 15 | "name": "My Action Listener", 16 | "handlers": { 17 | "actions": { 18 | "Startup": "onStartup" 19 | } 20 | }, 21 | "identifier": "my-action-listener-identifier" 22 | }, 23 | { 24 | "script": "cmdline-functions.js", 25 | "handler": "cmdRun", 26 | "name": "Run from command line", 27 | "identifier": "cmdRun" 28 | }, 29 | { 30 | "script": "cmd-apply-less.js", 31 | "handler": "onRunDialog", 32 | "name": "Apply Design Tokens", 33 | "shortcut": "command alt a", 34 | "identifier": "cmApplyLess" 35 | }, 36 | { 37 | "script": "cmd-apply-less.js", 38 | "handler": "onRunDialogOnlyStyles", 39 | "name": "Apply to existing styles only", 40 | "identifier": "cmApplyOnlyUpdateLess" 41 | }, 42 | { 43 | "script": "cmd-apply-less.js", 44 | "handler": "onRunQuick", 45 | "name": "Repeat last applying in headless mode", 46 | "shortcut": "command alt k", 47 | "identifier": "cmQuickApply" 48 | }, 49 | { 50 | "script": "cmd-generate-preview.js", 51 | "handler": "onRun", 52 | "name": "Generate Styles Overview", 53 | "identifier": "cmdGeneratePreview" 54 | }, 55 | { 56 | "script": "cmd-export.js", 57 | "handler": "onRun", 58 | "name": "Export Styles", 59 | "identifier": "cmdExport" 60 | }, 61 | { 62 | "script": "cmd-config.js", 63 | "handler": "onRun", 64 | "name": "Configure", 65 | "identifier": "cmConfig" 66 | }, 67 | { 68 | "script": "cmd-other.js", 69 | "handler": "showChangeLog", 70 | "shortcut": "", 71 | "name": "Show Change Log", 72 | "identifier": "showChangeLog" 73 | } 74 | ], 75 | "menu": { 76 | "title": "📦 Puzzle Tokens", 77 | "items": [ 78 | "cmApplyLess", 79 | "cmApplyOnlyUpdateLess", 80 | "-", 81 | "cmQuickApply", 82 | "-", 83 | "cmdGeneratePreview", 84 | "cmdExport", 85 | "-", 86 | "cmConfig", 87 | "-", 88 | "showChangeLog" 89 | ] 90 | } 91 | } -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/scripts/nsconvert_less.js: -------------------------------------------------------------------------------- 1 | const DEBUG = false; 2 | 3 | var fs = require('fs'); 4 | var nodePath = require('path'); 5 | 6 | const args = parseArgs(process.argv.slice(2)) 7 | var pathToLess = args['-styles'] 8 | var pathToJSON = args['-json'] 9 | var pathToResultSASS = args['-sass'] 10 | var pathToLessc = args['-lessc'] 11 | var pathToResultCSS = args['-css'] 12 | var pathToResultVars = args['-vars'] 13 | var pluginNamesSrc = args['-plugins'] 14 | var pluginNames = pluginNamesSrc != undefined ? pluginNamesSrc.split(',') : undefined 15 | var less; 16 | var lessPath = '' 17 | var lessVars = {} 18 | var sketchRules = [] 19 | var parseOptions = null 20 | var _lookups = {} 21 | 22 | ///////////////////////////////////////////// 23 | if (DEBUG) console.log("Started") 24 | 25 | // INIT DATA 26 | if (!initPaths()) process.exit(0) 27 | 28 | // LOAD LESS 29 | var strSrcLess = loadLessFromFiles(pathToLess) 30 | if (null == strSrcLess) process.exit(-1) 31 | 32 | // SAVE TOKENS AS COMMENTS IN LESS 33 | var strLess = injectTokensIntoLess(strSrcLess) 34 | 35 | // RENDER LESS TO JSON 36 | transformLESStoJSON(strLess) 37 | 38 | // RENDER CUSTOM LESS TO RAW CSS 39 | if (undefined != pathToResultCSS) 40 | transformCustomLESStoCSS(pathToLess, pathToResultCSS) 41 | 42 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 43 | function parseArgs(args) 44 | { 45 | let list = [] 46 | args.forEach(function (arg) 47 | { 48 | const v = arg.split("=") 49 | if (0 == v.length) return 50 | list[v[0]] = v[1] 51 | }) 52 | return list 53 | } 54 | 55 | function initPaths() 56 | { 57 | if (undefined == pathToLess) 58 | { 59 | console.log("nsconvert_less.js -styles= -json= -css= -vars= -plugins=[plugin1,plugin2]") 60 | return false 61 | } 62 | 63 | // REMOVE OLD RESULTS 64 | if (pathToJSON && fs.existsSync(pathToJSON)) 65 | { 66 | fs.unlinkSync(pathToJSON) 67 | } 68 | 69 | // CHANGE CURRENT PATH TO LESS FOLDER TO ENABLE IMPORTS 70 | lessPath = nodePath.dirname(pathToLess) 71 | process.chdir(lessPath) 72 | 73 | return true 74 | } 75 | 76 | function injectTokensIntoLess(srcData, lastPath = null) 77 | { 78 | var lessLines = srcData.split("\n") 79 | var newData = "" 80 | 81 | lessLines.forEach(function (line) 82 | { 83 | line = line.trim() 84 | 85 | // import file manually 86 | if (line.startsWith("@import") && !line.includes("{")) 87 | { 88 | // cut file name 89 | let parts = line.split("\"") 90 | if (!parts.length) parts = line.split("\'") 91 | const importFileName = parts[1] 92 | if (DEBUG) console.log("importFileName=" + importFileName) 93 | // construct path to imported filed 94 | let importPath = "" 95 | if (importFileName.startsWith("/")) 96 | { 97 | importPath = importFileName 98 | // 99 | const dirInfo = nodePath.parse(importPath) 100 | if (!dirInfo) 101 | { 102 | console.log("Failed to scan path:" + importPath) 103 | process.exit(-1) 104 | } 105 | lastPath = dirInfo.dir 106 | } else 107 | { 108 | if (null != lastPath) 109 | { 110 | importPath = lastPath + "/" + importFileName 111 | } else 112 | { 113 | const dirInfo = nodePath.parse(pathToLess) 114 | if (!dirInfo) 115 | { 116 | console.log("Failed to scan path:" + pathToLess) 117 | process.exit(-1) 118 | } 119 | importPath = dirInfo.dir + "/" + importFileName 120 | } 121 | } 122 | // load file 123 | if (DEBUG) console.log("importFilePath=" + importPath) 124 | const strSrcLess = loadLessFromFiles(importPath) 125 | if (null == strSrcLess) 126 | { 127 | console.log("Failed to load import by path:" + importPath) 128 | process.exit(-1) 129 | } 130 | const strLess = injectTokensIntoLess(strSrcLess, lastPath) 131 | newData += strLess 132 | return 133 | } 134 | 135 | // drop comment lines 136 | line = line.trim() 137 | if (line.startsWith("//")) return 138 | 139 | if (line.includes("@")) 140 | { 141 | var commentPos = line.indexOf("//") 142 | if (commentPos > 0) 143 | { 144 | line = line.substring(0, commentPos) 145 | } 146 | 147 | var found = line.split(":") 148 | if (found && found.length > 1 && (found[1].includes("+") || found[1].includes("/") || found[1].includes("*") || found.includes("/") || found[1].includes(" - "))) 149 | { 150 | var s = found[1].trim().replace(";", "") 151 | line += " //!" + s + "!" 152 | } else 153 | { 154 | var tokenInfo = line.match(/@{1}([\w-]*)\w{0,};/) 155 | if (null != tokenInfo && tokenInfo.length >= 1) 156 | { 157 | var token = tokenInfo[1] 158 | line += " //!" + token + "!" 159 | if (token.includes("--token")) 160 | { 161 | line += `\n-pt-${found[0].replace("@", "")}--token: @${token};` 162 | //console.log(`\n-pt-${found[0]}--token: @${token};\n`) 163 | } 164 | } 165 | } 166 | } 167 | newData += line + "\n" 168 | }) 169 | return newData 170 | } 171 | 172 | function loadLessFromFiles(fileName1, fileName2) 173 | { 174 | if (DEBUG) console.log("Read LESS: running...") 175 | 176 | var data = '' 177 | const data1 = fs.readFileSync(fileName1, 'utf8'); 178 | if (null == data1) 179 | { 180 | console.log("Can't open file by path:" + fileName1) 181 | return null 182 | } 183 | data = data + data1; 184 | if (fileName2 != undefined) 185 | { 186 | data = data + "\n" + fs.readFileSync(fileName2, 'utf8'); 187 | } 188 | 189 | return data 190 | } 191 | 192 | function transformLESStoJSON(data) 193 | { 194 | 195 | var passToNodeModules = _getPathToNodeModules() 196 | less = require(passToNodeModules + "/less") 197 | 198 | var pluginModules = [] 199 | if (undefined != pluginNames) 200 | { 201 | pluginNames.forEach(function (pluginName) 202 | { 203 | const pluginModule = require(passToNodeModules + "/" + pluginName); 204 | pluginModules.push(pluginModule) 205 | }) 206 | } 207 | 208 | var options1 = { 209 | async: false, 210 | fileAsync: false, 211 | plugins: pluginModules, 212 | } 213 | 214 | process.on('unhandledRejection', error => 215 | { 216 | // Will print "unhandledRejection err is not defined" 217 | console.log('Failed to parse LESS with error message:', error.message); 218 | process.exit(-1) 219 | }); 220 | 221 | 222 | try 223 | { 224 | less.parse(data, options1, function (err, root, imports, options) 225 | { 226 | parseOptions = options 227 | //console.log(options.pluginManagermixin) 228 | if (undefined != err) console.log(err) 229 | 230 | var evalEnv = new less.contexts.Eval(options); 231 | var evaldRoot = root.eval(evalEnv); 232 | var ruleset = evaldRoot.rules; 233 | 234 | ruleset.forEach(function (rule) 235 | { 236 | if (rule.isLineComment) 237 | { 238 | return 239 | } else if (rule.variable === true) 240 | { 241 | // var name; 242 | let name = rule.name.substr(1); 243 | 244 | var value = rule.value; 245 | lessVars["@" + name] = value.toCSS(options); 246 | 247 | //console.log(name + " : " + value.toCSS(options)) 248 | } else 249 | { 250 | parseSketchRule(rule, null, []) 251 | } 252 | }); 253 | //console.log(lessVars) 254 | 255 | // completed 256 | if (DEBUG) console.log("Completed") 257 | saveData(sketchRules, pathToJSON) 258 | if (DEBUG) console.log("Saved JSON") 259 | if (pathToResultSASS != null) 260 | { 261 | saveVarsToSASS(lessVars, pathToResultSASS) 262 | if (DEBUG) console.log("Saved SASS") 263 | } 264 | if (pathToResultVars != undefined) 265 | { 266 | saveData(lessVars, pathToResultVars) 267 | } 268 | }); 269 | } catch (e) 270 | { 271 | console.log("Failed to parse LESS with error message:\n") 272 | console.log(e.message) 273 | process.exit(-1) 274 | } 275 | 276 | if (DEBUG) console.log(sketchRules) 277 | if (DEBUG) console.log("Read LESS: done") 278 | } 279 | 280 | 281 | function parseSketchRule(rule, elements, path) 282 | { 283 | 284 | // save info about enabled mixins to ignore them 285 | if (rule._lookups && Object.keys(rule._lookups).length > 0) 286 | { 287 | Object.keys(rule._lookups).forEach(function (s) 288 | { 289 | _lookups[s.trim()] = true 290 | }) 291 | } 292 | 293 | if (null != elements) 294 | { 295 | var foundMixin = false 296 | elements.forEach(function (el) 297 | { 298 | path = path.concat([el.value]) 299 | if (el.value in _lookups) 300 | { 301 | foundMixin = true 302 | return 303 | } 304 | }) 305 | if (foundMixin) return 306 | } else 307 | { 308 | if (rule.selectors != null && rule.selectors.length > 0) 309 | { 310 | rule.selectors.forEach(function (sel) 311 | { 312 | parseSketchRule(rule, sel.elements, path) 313 | }) 314 | return 315 | } 316 | } 317 | /// 318 | if (rule.rules && rule.rules.length > 0) 319 | { 320 | if (!(rule.rules[0].rules)) 321 | { 322 | saveSketchRule(rule, path) 323 | } else 324 | { 325 | rule.rules.forEach(function (oneRule) 326 | { 327 | parseSketchRule(oneRule, null, path) 328 | }) 329 | } 330 | } 331 | } 332 | 333 | function saveSketchRule(rule, path) 334 | { 335 | if (DEBUG) console.log("-----saveSketchRule") 336 | 337 | //var sketchPath = path.join("*") 338 | //sketchPath = sketchPath.replace(/(\.)/g, '').replace(/^\./,'') 339 | 340 | // detect mixin by keyword and skip it 341 | if (path.length > 0 && path[0].startsWith(".mixin-")) return 342 | if (path.length == 1 && "&" == path[0]) return 343 | 344 | const sketchRule = { 345 | path: path.join("*"), 346 | props: { 347 | __tokens: [] 348 | } 349 | } 350 | rule.rules.forEach(function (oneRule, index) 351 | { 352 | // drop comment 353 | if (oneRule.isLineComment) return 354 | 355 | if (null != oneRule.selectors) 356 | { 357 | parseSketchRule(oneRule, null, path) 358 | return 359 | } 360 | 361 | // skip mixin 362 | if (null == oneRule.value || null == oneRule.name) return 363 | 364 | var value = oneRule.value.toCSS(parseOptions); 365 | 366 | // drop comment and unparsed variables 367 | const s = typeof oneRule.name + "" 368 | if ("object" == s) return 369 | if (oneRule.name.startsWith("@")) return 370 | if (oneRule.name.includes("--token")) return 371 | 372 | // Try to get token from special next line. Example: 373 | // font-size: @@tag-text-font-size--token; 374 | // -pt-font-size--token: @tag-text-font-size--token; 375 | const calcTokenName = `-pt-${oneRule.name}--token` 376 | const nextNextRule = rule.rules[index + 2] 377 | if (nextNextRule && nextNextRule.name != null && nextNextRule.name === calcTokenName && nextNextRule.value != null && nextNextRule.value.value != null) 378 | { 379 | token = "@" + nextNextRule.value.value 380 | } else 381 | { 382 | // get token from rule comment 383 | var token = '' 384 | var nextRule = rule.rules[index + 1] 385 | if (nextRule != null && nextRule.isLineComment) 386 | { 387 | var res = nextRule.value.match(/!{1}([\s\w-+\*//@]*)!{1}/) 388 | if (null != res && null != res[1]) 389 | { 390 | token = res[1] 391 | } 392 | } 393 | } 394 | sketchRule.props[String(oneRule.name)] = value 395 | if (token != '') 396 | { 397 | if (!token.startsWith('@')) token = "@" + token 398 | sketchRule.props.__tokens.push([ 399 | oneRule.name, token 400 | ]) 401 | } 402 | }) 403 | // we need more properties then only "__tokens" 404 | if (Object.keys(sketchRule.props).length > 1) sketchRules.push(sketchRule) 405 | } 406 | 407 | 408 | 409 | function saveData(data, pathToJSON) 410 | { 411 | var json = JSON.stringify(data, null) //, ' ') 412 | 413 | if (pathToJSON && pathToJSON != '') 414 | { 415 | fs.writeFileSync(pathToJSON, json, 'utf8'); 416 | } else 417 | { 418 | //console.log(json) 419 | } 420 | 421 | return true 422 | } 423 | 424 | function saveVarsToSASS(data, pathToSASS) 425 | { 426 | var json = "" 427 | Object.keys(data).sort().filter(propName=>!propName.startsWith("@_")).forEach(propName => 428 | { 429 | //for (let propName in data) { 430 | let value = data[propName] 431 | if (value.indexOf("/") >= 0) 432 | { 433 | // quote file name 434 | value = '"' + value + '"' 435 | } 436 | json += '$' + propName.slice(1) + ": " + value + ";\n" 437 | }) 438 | 439 | if (pathToSASS && pathToSASS != '') 440 | { 441 | fs.writeFileSync(pathToSASS, json, 'utf8'); 442 | } else 443 | { 444 | //console.log(json) 445 | } 446 | 447 | return true 448 | } 449 | 450 | 451 | function _getPathToNodeModules() 452 | { 453 | var result = require('child_process').execSync("node /usr/local/bin/npm -g root", { env: process.env.PATH }) 454 | var path = result.toString().replace("\n", "") 455 | return path 456 | } 457 | 458 | 459 | function transformCustomLESStoCSS(pathToOrgLess, pathToCSS) 460 | { 461 | const pathToCustomLess = pathToOrgLess.replace(".less", ".css.less") 462 | 463 | // Check file existing 464 | if (!fs.existsSync(pathToCustomLess)) 465 | { 466 | // no file with name .css.less 467 | return true 468 | } 469 | 470 | // Convert LESS to pure CSS and save it to CSS file 471 | pathToCSS = pathToCSS.replace(/\s/g, "\\ ") 472 | const pathToCompiler = pathToLessc!=undefined && pathToLessc!=""?pathToLessc:"/usr/local/bin/lessc" 473 | 474 | const result = require('child_process').execSync("node " + pathToCompiler+ " " + pathToCustomLess + " > " + pathToCSS, { env: process.env.PATH }) 475 | if (DEBUG) console.log("Rendered CSS LESS to CSS: " + pathToCSS) 476 | } -------------------------------------------------------------------------------- /PuzzleTokens.sketchplugin/Contents/Sketch/scripts/nsconvert_sass.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var nodePath = require('path'); 3 | const DEBUG = false 4 | 5 | const args = parseArgs(process.argv.slice(2)) 6 | var pathToSass = args['-styles'] 7 | var pathToJSON = args['-json'] 8 | var argsPathToSassModule = args['-sassmodule'] 9 | var sassPath = '' 10 | var sketchRules = [] 11 | 12 | ///////////////////////////////////////////// 13 | if (DEBUG) console.log("Started") 14 | 15 | // INIT DATA 16 | if (!initPaths()) process.exit(0) 17 | 18 | // LOAD LESS 19 | var strSrcSass = loadSassFromFiles(pathToSass) 20 | if (null == strSrcSass) process.exit(-1) 21 | 22 | // SAVE TOKENS AS COMMENTS IN SASS 23 | var strSass = injectTokensIntoSass(strSrcSass) 24 | 25 | // RENDER SASS TO JSON 26 | transformSASStoJSON(strSass) 27 | 28 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 29 | 30 | function parseArgs(args) 31 | { 32 | let list = [] 33 | args.forEach(function (arg) 34 | { 35 | const v = arg.split("=") 36 | if (0 == v.length) return 37 | list[v[0]] = v[1] 38 | }) 39 | return list 40 | } 41 | 42 | function initPaths() 43 | { 44 | if (undefined == pathToSass) 45 | { 46 | console.log("nsconvert_sass.js PATH_TO_SAAS_FILE PATH_TO_JSON_FILE") 47 | return false 48 | } 49 | 50 | // REMOVE OLD RESULTS 51 | if (pathToJSON && fs.existsSync(pathToJSON)) 52 | { 53 | fs.unlinkSync(pathToJSON) 54 | } 55 | 56 | // CHANGE CURRENT PATH TO LESS FOLDER TO ENABLE IMPORTS 57 | sassPath = nodePath.dirname(pathToSass) 58 | process.chdir(sassPath) 59 | 60 | return true 61 | } 62 | 63 | function injectTokensIntoSass(srcData) 64 | { 65 | var sassLines = srcData.split("\n") 66 | var newData = "" 67 | 68 | sassLines.forEach(function (line) 69 | { 70 | 71 | // drop comment lines 72 | line = line.trim() 73 | if (line.startsWith("//")) return 74 | 75 | var found = line.match(/\${1}([\w-]*)\w{0,};/) 76 | if (null != found && found.length >= 1) 77 | { 78 | var token = found[1] 79 | var commentPos = line.indexOf("//") 80 | if (commentPos > 0) 81 | { 82 | line = line.substring(0, commentPos) 83 | } 84 | line += " //!" + token + "!" 85 | } 86 | newData += line + "\n" 87 | }) 88 | 89 | return newData 90 | } 91 | 92 | function loadSassFromFiles(fileName1, fileName2) 93 | { 94 | if (DEBUG) console.log("Read SASS: running...") 95 | 96 | var data = '' 97 | const data1 = fs.readFileSync(fileName1, 'utf8'); 98 | if (null == data1) 99 | { 100 | console.log("Can't open file by path:" + fileName1) 101 | return null 102 | } 103 | data = data + data1; 104 | if (fileName2 != undefined) 105 | { 106 | data = data + "\n" + fs.readFileSync(fileName2, 'utf8'); 107 | } 108 | 109 | return data 110 | } 111 | 112 | function transformSASStoJSON(data) 113 | { 114 | var pathToSassModule = _getpathToSassModule() 115 | if (DEBUG) console.log(pathToSassModule) 116 | var sass = require(pathToSassModule) 117 | 118 | process.on('unhandledRejection', error => 119 | { 120 | // Will print "unhandledRejection err is not defined" 121 | console.log('Failed to parse SASS with error message:', error.message); 122 | process.exit(-1) 123 | }); 124 | 125 | 126 | try 127 | { 128 | result = sass.renderSync({ 129 | data: data, 130 | outputStyle: "expanded" 131 | }) 132 | if (DEBUG) console.log("Completed") 133 | saveData(result.css.toString(), pathToJSON) 134 | if (DEBUG) console.log("Saved") 135 | 136 | } catch (e) 137 | { 138 | console.log("Failed to parse SASS with error message:\n") 139 | console.log(e.message) 140 | process.exit(-1) 141 | } 142 | 143 | //console.log(sketchRules) 144 | 145 | 146 | if (DEBUG) console.log("Read SASS: done") 147 | } 148 | 149 | 150 | function saveData(strCSS, pathToJSON) 151 | { 152 | var data = [] 153 | if (DEBUG) console.log("CSS:") 154 | //console.log(strCSS) 155 | //console.log("-------------------") 156 | 157 | // 158 | var sassLines = strCSS.split("\n") 159 | var node = null 160 | var inComments = false 161 | sassLines.forEach(function (line) 162 | { 163 | //console.log(line) 164 | if (line.startsWith("/*") && line.endsWith("*/")) 165 | { 166 | } else if (line.startsWith("/*")) 167 | { 168 | inComments = true 169 | } else if (line.startsWith("*/")) 170 | { 171 | inComments = false 172 | } else if (inComments) 173 | { 174 | // skip comment 175 | } else if (line.endsWith("{")) 176 | { 177 | // start node declaration 178 | const paths = line.replace(" {", "").split(' ').join("*") 179 | node = { 180 | path: paths, 181 | props: { 182 | "__tokens": { 183 | } 184 | } 185 | } 186 | } else if (line.endsWith("}")) 187 | { 188 | // complete node declaration 189 | data.push(node) 190 | } else if (node) 191 | { 192 | // save css rule 193 | line = line.replace(/^(\s*)/, "") 194 | var ruleName = line.replace(/(:+\s+.+;+)/, "") 195 | var ruleValue = line.replace(/(\S+\s+)/, "").replace(/(;+)$/, "") 196 | node.props[ruleName] = ruleValue 197 | } 198 | }) 199 | // 200 | 201 | var json = JSON.stringify(data, null, ' ') 202 | 203 | if (pathToJSON && pathToJSON != '') 204 | { 205 | fs.writeFileSync(pathToJSON, json, 'utf8'); 206 | } else 207 | { 208 | //console.log(json) 209 | } 210 | 211 | return true 212 | } 213 | 214 | function _getpathToSassModule() 215 | { 216 | var path = "" 217 | if (argsPathToSassModule !== undefined && argsPathToSassModule != "") 218 | path = argsPathToSassModule 219 | else 220 | { 221 | var result = require('child_process').execSync("node /usr/local/bin/npm -g root", { env: process.env.PATH }) 222 | path = result.toString().replace("\n", "") 223 | } 224 | return path + "/sass" 225 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Puzzle Tokens 2 | Puzzle Tokens is a Sketch plugin to specify and apply design tokens (in LESS or SCSS format) to Sketch layers (with shared styles) with auto styles preview generation. 3 | 4 | ### [Check this article](https://medium.com/@akalenyuk/bringing-styles-preprocessing-to-sketch-9cdf0d0c49bd) to get a detailed overview with examples and join [Discussions](https://github.com/ingrammicro/puzzle-tokens/discussions) for live talk 5 | 6 | ## Installation 7 | 1. Download [zip file](https://github.com/ingrammicro/puzzle-tokens/raw/master/PuzzleTokens.sketchplugin.zip) 8 | 2. Unarchive and install 9 | 3. Download and install [Node.js](https://nodejs.org/en/download/) 10 | 4. Instal _less_ or _sass_ using the following Terminal commands: 11 | ``` 12 | sudo -s 13 | npm i less -g 14 | npm i sass -g 15 | ``` 16 | 5. Now you're good to go! 17 | 18 | ## Usage 19 | 1. Download [Example 1](https://github.com/ingrammicro/puzzle-tokens/tree/master/Styles/Tests/Buttons). 20 | 2. Open Library.sketch file in Sketch.app 21 | 3. Run Plugins > Puzzle Tokens > Apply Design Tokens menu command 22 | 4. Specify LESS file according to screenshot 23 | 24 | 25 | 26 | 5. Repeat the same operation, but select "tokens-blue.less" file. See how styles and widgets look now. 27 | 28 | 29 | ## Features 30 | The following CSS styles are supporting. 31 | ```css 32 | // Text Layers 33 | 34 | .TextStyle { 35 | // Sketch only styles 36 | pt-paragraph-spacing: 23.33; 37 | pt-text: "New text content"; 38 | -pt-text-size-behaviour: fixed-size; // or "auto-height" or "auto-width" 39 | 40 | // CSS native styles 41 | font-size: 12px; 42 | font-family: "Open Sans"; // or "Open Sans","Times New Roman" 43 | font-weight: bold; // or extra-light, light, regular, medium, semibold, bold OR fa-solid (special trick to define FontAwesome solid icon) 44 | font-style: italic; // or normal 45 | line-height: 1.0; // or 1.2 or 1.5 or any other mulitplier for font-size OR 10px 46 | color: #FFFFFF; // HEX value OR any other CSS-compatible color values, such as red or black OR color variable name in double quotes 47 | opacity: 63%; // supported "63%" or "0.42" 48 | text-transform: uppercase; // "uppercase", "lowercase", "none" 49 | text-decoration: underline; // "underline", "line-through" 50 | text-align: left; // "left", center", "right", "justify" 51 | vertical-align: top; // "top", "middle", "bottom" 52 | letter-spacing: 10px; // px OR "normal" 53 | } 54 | 55 | // Shape layers 56 | 57 | .ShapeStyle { 58 | // SKETCH only properties 59 | border-position: center; // center OR inside OR outside 60 | border-line-end: butt; // butt / round / projecting 61 | border-line-join: miter; // miter / round / bevel 62 | border-start-arrowhead: openarrow; // none / openarrow / filledarrow / opencircle / filledcircle / opensquare / filledsquare 63 | border-end-arrowhead: openarrow; // none / openarrow / filledarrow / opencircle / filledcircle / opensquare / filledsquare 64 | -pt-border-update: true; // Use it if you want to replace an existing border, instead of adding a new one. 65 | -pt-fill-update: true; // Use it if you want to replace an existing fill, instead of adding a new one. 66 | 67 | /// CSS native properties 68 | background-color: #B0AFB1; 69 | background-color: linear-gradient(45deg, #000000,#B0AFB4); 70 | background-color: linear-gradient(134deg, #004B3A 0%, #2D8B61 51%, #9BD77E 100%); 71 | background-color: "mycolors/color01"; // assign color variable 72 | opacity: 63%; // "63%" or "0.42" 73 | border-color: #000000; 74 | border-color: linear-gradient(45deg, #000000,#B0AFB4); 75 | border-color: linear-gradient(134deg, #004B3A 0%, #2D8B61 51%, #9BD77E 100%); 76 | border-color: "mycolors/color01"; // assign color variable 77 | border-width: 2px; 78 | border-style: dotted; // dotted OR dashed 79 | 80 | box-shadow: none; // Clear any existing shadows from the layer style. 81 | box-shadow: 0 10px 20px 2 #FF00FF; 82 | box-shadow: inset 0 10px 20px 2 rgba(0,0,0,0.1); 83 | box-shadow: 0 10px 20px 2 rgba(0,0,0,0.1), inset 0 10px 20px 2 rgba(0,0,0,0.1); 84 | -pt-shadow-update: true; // Use it if you want to replace any previous shadows, instead of adding a new one. 85 | 86 | mix-blend-mode: normal; // normal / darken / multiply / color-burn / lighten / screen / color-dodge / overlay / difference 87 | // exclusion / hue / saturation / color / luminosity 88 | 89 | // !!ATTENTION!! 90 | // Shared styles don't include radius property, 91 | // still you can set the radius-border for a style. 92 | // Border radius will be reapplied to layers 93 | // through style assigned to it. You can also 94 | // apply it to the layers or symbols directly. 95 | 96 | border-radius: 5px; 97 | border-radius: 5px 5px 0 0; 98 | } 99 | 100 | // Text & Shape Layer Common Properties 101 | .Style{ 102 | // Sketch only styles 103 | -pt-layer-type: text; // "layer" or "text" // Usefull to help PT to understnand the type of the layer 104 | -pt-pin-left: true; // "true" or "false 105 | -pt-pin-right: true; // "true" or "false 106 | -pt-pin-top: true; // "true" or "false 107 | -pt-pin-bottom: true; // "true" or "false 108 | -pt-fix-size-height: true; // "true" or "false 109 | -pt-fix-size-width: true; // "true" or "false 110 | -pt-skip-missed: true: // "true" or "false // Usefull to skip style if no layer 111 | // found without an error 112 | -pt-resize-symbol: true: // resize layer owner (symbol master) to a layer size 113 | 114 | // The following properties are not a part of shared styles. 115 | // Bu you can set these properties for a shared style. 116 | // These properties will be reapplied to layers 117 | // through style assigned to it. You can also 118 | // apply it to the layers or symbols directly. 119 | 120 | width: 100px; 121 | height: 100px; 122 | 123 | margin-top: 10px; 124 | margin-left: 20px; 125 | margin-right: 20px; 126 | margin-bottom: 10px; 127 | 128 | // By default, margin is set relative to the layer's containing artboard or page. 129 | // (Specifically, the layer is moved so that it is positioned inside the artboard/ 130 | // page at the specified margin. In the example above, the top-left corner of the 131 | // layer is set to x:10 and y:20 of the containing artboard.) 132 | // 133 | // If you prefer to set the margin relative to another layer (for example, to set 134 | // the text layer of a button within the boundaries of the button's background 135 | // layer style), use the "-pt-margin-relative-to" property shown below. 136 | 137 | -pt-margin-relative-to: "layer name"; // set margin values relative to the specified 138 | // layer. The specified layer must be a sibling 139 | // (at the same level in a group, artboard, or 140 | // symbol) of the layer to which you are 141 | // applying the margin styles. If not specified, 142 | // margin will be set relative to the artboard 143 | // or page 144 | -pt-margin-resize: true; // if true, resize the "margin-relative-to" 145 | // layer to "fit" the size of the current layer, 146 | // plus the specified margin. This will make 147 | // the "margin-relative-to" layer surround 148 | // the current layer at exactly the requested 149 | // margin. 150 | 151 | 152 | -pt-valign: middle; // middle / top / bottom : align vertically inside a parent 153 | } 154 | 155 | // Group & SymbolMaster Properties 156 | #Group{ 157 | -pt-smartlayout: LeftToRight; // LeftToRight OR HorizontallyCenter OR RightToLeft OR TopToBottom 158 | // OR VerticallyCenter OR BottomToTop OR None 159 | } 160 | 161 | // Group, SymbolMaster and Artboard Properties 162 | #Symbol{ 163 | -pt-fit-content: true; // Resize to fit content 164 | } 165 | 166 | // SymbolMaster properties 167 | #Symbol{ 168 | -pt-resize-instances: true; // Resize all instances of a symbol; the same as 169 | // clicking Sketch's "Shrink instance to fit 170 | // content" button in the Overrides section of 171 | // the instance. (This reapplies SmartLayout, 172 | // useful when you change the size of a symbol.) 173 | } 174 | 175 | // Symbol Instance Properties 176 | #Card .IconButton { // Path to a symbol-instance layer 177 | 178 | // You can change the symbol source for a symbol override (for example, to switch 179 | // the icon displayed in a symbol instance). Usage is: 180 | // -pt-override-symbol: ('AffectedLayerName', '#Path #To #New #Symbol'); 181 | // 182 | // In the example shown here, the Card symbol has a symbol instance in a layer named 183 | // IconButton. If that IconButton instance has a symbol override in layer RightIcon, 184 | // you can set the icon to a new icon by sharing its Puzzle Tokens path like so: 185 | 186 | -pt-override-symbol: ('RightIcon ', '#Icons #Arrows #RightArrow'); 187 | 188 | // Set the path to 'none' to disable the symbol override and show nothing at all. 189 | } 190 | 191 | #Image{ 192 | // Required Properties 193 | image: ~"images/new-logo.jpg"; // OR transparent 194 | // Optional Properties 195 | border-color: white; 196 | border-width: 3px; 197 | box-shadow: 0 10px 20px 2 #FF00FF; 198 | width: 100px; // OR 50 % 199 | height: 100px; // OR 50 % 200 | top: 11px; 201 | bottom: 22px; 202 | left: 2px; 203 | right: 33px; 204 | } 205 | ``` 206 | 207 | 208 | You can [look into more examples](https://github.com/ingrammicro/puzzle-tokens/tree/master/Styles/Tests) to get familiar with the plugin. 209 | 210 | ## Supported Targets 211 | You can update the following Sketch objects. 212 | 213 | ```css 214 | // Update shared style 215 | .MyStyles .Group .Style1{ 216 | color: #FFFFFF; 217 | } 218 | 219 | // Update symbol child style properties 220 | #MySymbols #Buttons #Submit{ 221 | .Text{ 222 | color: #FFFFFF; 223 | } 224 | } 225 | 226 | // Update artboard child style properties 227 | #MyArtboard #Group1{ 228 | .Rectangle{ 229 | color: #FFFFFF; 230 | } 231 | } 232 | 233 | // Assign shared style to artboard/symbol child 234 | #MySymbols #Buttons #Submit{ 235 | .Text{ 236 | sktext-style: "MyStyle/Group/Style1"; 237 | } 238 | .Back{ 239 | sklayer-style: "MyStyle/Group/Back"; 240 | } 241 | } 242 | 243 | // Update color variables !!!!!!!! DONT USE GRADIENTS FOR COLOR VARIABLES. SKETCH WILL CRASH !!!!! 244 | .--COLORS-{ 245 | .primary{ 246 | color: black; 247 | } 248 | .secondary{ 249 | color: grey; 250 | } 251 | } 252 | 253 | ``` 254 | ## Special Tricks for Selector Names 255 | - To start a style or symbol name from a number just add --PT- prefix. So, "--PT-1 Style" will be transformed to "1 Style". 256 | - To start a style or symbol name from a dot just use -DOT- special keyword. So, "-DOT-Style" will be transformed to ".Style" 257 | - To use a space inside a style or symbol name you can uses a space (but formally it will not be a CSS compartible notation) or replace space by __ .So "My__First__Style" wil be transformed to "My First Style 258 | 259 | ## Required Style Properties 260 | To apply _text_ style you need to defined at least one of the following properites: 261 | - color 262 | - font-family 263 | - font-size 264 | - font-weight 265 | - text-transform 266 | - text-align 267 | - vertical-align 268 | - pt-paragraph-spacing 269 | 270 | For _layer_ style: 271 | - background-color 272 | - border-color 273 | - box-shadow 274 | - border-radius 275 | - opacity 276 | 277 | To create _image: 278 | - image 279 | 280 | To assign shared style to layer: 281 | - sklayer-style 282 | - sktext-style 283 | 284 | ## Sketch versions supported 285 | Some styles, such as text font/transformation/etc require Sketch 53 or later. You're safe using the latest stable Sketch version to get the plugin working. 286 | 287 | 288 | ## Demos 289 | https://www.dropbox.com/s/f25cfsm26vgeu62/Recording1.mov?dl=0 290 | 291 | ## Command line API 292 | ``` 293 | #!/bin/bash 294 | context="{\"file\":\"${HOME}/GitHub/puzzle-tokens/Styles/material-palettes/palettes.sketch\"" 295 | # The following line is optional 296 | context="${context},\"saveAs\":\"${HOME}/GitHub/puzzle-tokens/Styles/material-palettes/palettes_new.sketch\"" 297 | context="${context},\"styles\":\"${HOME}/GitHub/puzzle-tokens/Styles/material-palettes/scss/palettes.scss\"" 298 | context="${context},\"commands\":\"apply,save,close\"}" 299 | echo $context 300 | /Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool --without-activating=YES --new-instance=No run ~/Library/Application\ Support/com.bohemiancoding.sketch3/Plugins/PuzzleTokens.sketchplugin "cmdRun" --context=$context 301 | ``` 302 | 303 | Compact variant: 304 | ``` 305 | /Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool --without-activating=YES --new-instance=No run ~/Library/Application\ Support/com.bohemiancoding.sketch3/Plugins/PuzzleTokens.sketchplugin "cmdRun" --context="{\"file\":\"${HOME}/GitHub/puzzle-tokens/Styles/material-palettes/palettes.sketch\",\"styles\":\"${HOME}/GitHub/puzzle-tokens/Styles/material-palettes/scss/palettes.scss\",\"commands\":\"apply,save,close\"}" 306 | ``` 307 | -------------------------------------------------------------------------------- /Scripts/SketchScrips.txt: -------------------------------------------------------------------------------- 1 | ////////////////////////////////// RENAME TEXT STYLES 2 | // Argument 3 | var search = "OLDNAME" 4 | var replace = "NEWNAME" 5 | 6 | //Get the current document 7 | var sketch = require('sketch') 8 | var document = sketch.getSelectedDocument() 9 | 10 | //Get the shared text styles of this document 11 | var textStyles = document.sharedTextStyles; 12 | 13 | textStyles.forEach(function(style){ 14 | style.name = style.name.replaceAll(search,replace) 15 | }) 16 | 17 | 18 | //////////////////////////////////////////////////////////// 19 | -------------------------------------------------------------------------------- /Scripts/run-pt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sketchFile="$1" 4 | stylesFile="$2" 5 | commands="$3" 6 | saveAs="$4" 7 | 8 | 9 | help="./run-pt.sh path_to_sketch_file path_to_styles_file commands(apply,save,close) path_to_NEW_sketch_file(optional)" 10 | 11 | if [ "$commands" == "" ]; then 12 | echo $help 13 | exit -1 14 | fi 15 | 16 | 17 | context='"file":"' 18 | context+=$sketchFile 19 | context+='","styles":"' 20 | context+=$stylesFile 21 | context+='","commands":"' 22 | context+=$commands 23 | context+='"' 24 | if [ "$saveAs" != "" ]; then 25 | context+=',"saveAs":"' 26 | context+=$saveAs 27 | context+='"' 28 | fi 29 | 30 | qc="{" 31 | qc+=$context 32 | qc+="}" 33 | 34 | 35 | /Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool --without-activating=YES --new-instance=No run ~/Library/Application\ Support/com.bohemiancoding.sketch3/Plugins/PuzzleTokens.sketchplugin "cmdRun" --context=$qc 36 | -------------------------------------------------------------------------------- /Styles/Releases/6.10.0/sketch-styles.less: -------------------------------------------------------------------------------- 1 | @font-x-small: 10.7px; 2 | @font-x-small-spacing: 40 * @font-x-small / 1000; 3 | @font-medium: 13.3px; 4 | @font-medium-spacing: 40 * @font-medium / 1000; 5 | 6 | @font-face-regular: "Arial"; 7 | @font-face-icons: "Font Awesome 5 Free"; 8 | 9 | @color-text-success: green; 10 | @color-text-warning: orange; 11 | @color-text-primary: #32272F; 12 | 13 | 14 | .Views .Status{ 15 | .Icon{ 16 | .Success, .Warning{ 17 | letter-spacing: @font-x-small-spacing; 18 | font-family: @font-face-icons; 19 | font-size: 9px; 20 | line-height: 20px; 21 | font-weight: bold; 22 | margin-top: 0px; 23 | margin-left: 0px; 24 | height: 20px; 25 | } 26 | .Success{ 27 | color: @color-text-success; 28 | } 29 | .Warning{ 30 | color: @color-text-warning; 31 | } 32 | } 33 | Text{ 34 | color: @color-text-primary; 35 | font-size: @font-medium; 36 | letter-spacing: @font-medium-spacing; 37 | font-family: @font-face-regular; 38 | line-height: 20px; 39 | } 40 | .Tile .Text{ 41 | color: @color-text-primary; 42 | font-size: @font-x-small; 43 | letter-spacing: @font-x-small-spacing; 44 | font-family: @font-face-regular; 45 | line-height: 20px; 46 | margin-top: 0px; 47 | } 48 | } -------------------------------------------------------------------------------- /Styles/Releases/6.10.0/test-inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{"Views/Status/Icon/Success":{"tokens":{"@font-x-small-spacing":true,"@font-face-icons":true,"@color-text-success":true}},"Views/Status/Icon/Warning":{"tokens":{"@font-x-small-spacing":true,"@font-face-icons":true,"@color-text-warning":true}},"Views/Status/Text":{"tokens":{"@color-text-primary":true,"@font-medium":true,"@font-medium-spacing":true,"@font-face-regular":true}},"Views/Status/Tile/Text":{"tokens":{"@color-text-primary":true,"@font-x-small":true,"@font-x-small-spacing":true,"@font-face-regular":true}}},"Views / Status / Success":{"layers":{"Symbol":{"tokens":{"@font-x-small-spacing":true,"@font-face-icons":true,"@color-text-success":true}},"Label":{"tokens":{"@color-text-primary":true,"@font-medium":true,"@font-medium-spacing":true,"@font-face-regular":true}}}},"Views / Status / Tile Status / Success":{"layers":{"Symbol":{"tokens":{"@font-x-small-spacing":true,"@font-face-icons":true,"@color-text-success":true}},"Label":{"tokens":{"@color-text-primary":true,"@font-x-small":true,"@font-x-small-spacing":true,"@font-face-regular":true}}}},"Views / Status / Warning":{"layers":{"Symbol":{"tokens":{"@font-x-small-spacing":true,"@font-face-icons":true,"@color-text-warning":true}},"Label":{"tokens":{"@color-text-primary":true,"@font-medium":true,"@font-medium-spacing":true,"@font-face-regular":true}}}},"Views / Status / Tile Status / Warning ":{"layers":{"Symbol":{"tokens":{"@font-x-small-spacing":true,"@font-face-icons":true,"@color-text-warning":true}},"Label":{"tokens":{"@color-text-primary":true,"@font-x-small":true,"@font-x-small-spacing":true,"@font-face-regular":true}}}}} -------------------------------------------------------------------------------- /Styles/Releases/6.10.0/test-vars.json: -------------------------------------------------------------------------------- 1 | { 2 | "@font-x-small": "10.7px", 3 | "@font-x-small-spacing": "0.428px", 4 | "@font-medium": "13.3px", 5 | "@font-medium-spacing": "0.532px", 6 | "@font-face-regular": "\"Arial\"", 7 | "@font-face-icons": "\"Font Awesome 5 Free\"", 8 | "@color-text-success": "green", 9 | "@color-text-warning": "orange", 10 | "@color-text-primary": "#32272F" 11 | } -------------------------------------------------------------------------------- /Styles/Releases/6.10.0/test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/6.10.0/test.sketch -------------------------------------------------------------------------------- /Styles/Releases/6.11.0/styles.less: -------------------------------------------------------------------------------- 1 | @button-width: 200; 2 | @button-height: 80; 3 | @button-label-margin: 25; 4 | 5 | #Controls #Buttons #DefaultSubmit{ 6 | .Back{ 7 | height: @button-height; 8 | width: @button-width; 9 | background-color: lightgray; 10 | border-width: 1px; 11 | border-color: gray; 12 | } 13 | .Top{ 14 | height: 2px; 15 | width: @button-width; 16 | background-color: black; 17 | border-width: 0px; 18 | } 19 | .Label{ 20 | margin-left: @button-label-margin; 21 | margin-top: @button-label-margin; 22 | height: 20px; 23 | width: @button-width - @button-label-margin*2; 24 | pt-text: Submit Button; 25 | color: white; 26 | } 27 | ._This{ 28 | height: @button-height; 29 | width: @button-width; 30 | } 31 | } -------------------------------------------------------------------------------- /Styles/Releases/6.11.0/test-inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{}} -------------------------------------------------------------------------------- /Styles/Releases/6.11.0/test-vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/Releases/6.11.0/test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/6.11.0/test.sketch -------------------------------------------------------------------------------- /Styles/Releases/6.12.0/styles.less: -------------------------------------------------------------------------------- 1 | 2 | .Style{ 3 | color: black; 4 | pt-paragraph-spacing: 40; 5 | line-height: 10px; 6 | font-size: 13.3px; 7 | } -------------------------------------------------------------------------------- /Styles/Releases/6.12.0/test-inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{"Style":{"tokens":{}}}} -------------------------------------------------------------------------------- /Styles/Releases/6.12.0/test-vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/Releases/6.12.0/test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/6.12.0/test.sketch -------------------------------------------------------------------------------- /Styles/Releases/6.14.0/_pt-assets/test/inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{"Style1":{"tokens":{}},"Style2":{"tokens":{}}}} -------------------------------------------------------------------------------- /Styles/Releases/6.14.0/_pt-assets/test/vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/Releases/6.14.0/_pt-assets/test/vars.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/6.14.0/_pt-assets/test/vars.scss -------------------------------------------------------------------------------- /Styles/Releases/6.14.0/styles.less: -------------------------------------------------------------------------------- 1 | 2 | .Style1{ 3 | color: hsla(240,100%,50%,0.5); 4 | font-size: 20px; 5 | } 6 | .Style2{ 7 | color: hsl(240,100%,50%); 8 | font-size: 20px; 9 | } -------------------------------------------------------------------------------- /Styles/Releases/6.14.0/test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/6.14.0/test.sketch -------------------------------------------------------------------------------- /Styles/Releases/6.7.0/styles.less: -------------------------------------------------------------------------------- 1 | .Shape{ 2 | background: rgba(255,255,255,0.00); 3 | box-shadow: 0 7px 40px 0 rgba(0,0,0,0.13),inset 0 2px 8px 0 rgba(0,0,0,0.24); 4 | border-radius: 4px; 5 | border-style: dotted; 6 | border-width: 5px; 7 | } 8 | 9 | #Artboard .Rectangle{ 10 | sklayer-style: Shape; 11 | } -------------------------------------------------------------------------------- /Styles/Releases/6.7.0/test-inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{"Shape":{"tokens":{}}}} -------------------------------------------------------------------------------- /Styles/Releases/6.7.0/test-vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/Releases/6.7.0/test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/6.7.0/test.sketch -------------------------------------------------------------------------------- /Styles/Releases/6.8.0/sketch-styles.less: -------------------------------------------------------------------------------- 1 | .Lines{ 2 | .Line{ 3 | border-width: 10px; 4 | border-color: red; 5 | border-line-end: round; 6 | border-line-join: miter; 7 | } 8 | } 9 | 10 | #Page__1{ 11 | Line{ 12 | sklayer-style: "Lines/Line"; 13 | } 14 | } -------------------------------------------------------------------------------- /Styles/Releases/6.8.0/test-inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{"Lines/Line":{"tokens":{}}}} -------------------------------------------------------------------------------- /Styles/Releases/6.8.0/test-vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/Releases/6.8.0/test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/6.8.0/test.sketch -------------------------------------------------------------------------------- /Styles/Releases/6.9.0/_pt-assets/test/inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{"Lines/Line":{"tokens":{}}}} -------------------------------------------------------------------------------- /Styles/Releases/6.9.0/_pt-assets/test/vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/Releases/6.9.0/_pt-assets/test/vars.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/6.9.0/_pt-assets/test/vars.scss -------------------------------------------------------------------------------- /Styles/Releases/6.9.0/sketch-styles.less: -------------------------------------------------------------------------------- 1 | .Lines{ 2 | .Line{ 3 | border-width: 10px; 4 | border-color: red; 5 | border-start-arrowhead: openarrow; 6 | border-end-arrowhead: filledarrow; 7 | } 8 | } 9 | 10 | #Artboard{ 11 | .Line{ 12 | sklayer-style: "Lines/Line"; 13 | } 14 | } -------------------------------------------------------------------------------- /Styles/Releases/6.9.0/test-inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{"Lines/Line":{"tokens":{}}}} -------------------------------------------------------------------------------- /Styles/Releases/6.9.0/test-vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/Releases/6.9.0/test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/6.9.0/test.sketch -------------------------------------------------------------------------------- /Styles/Releases/8.1.1/test.less: -------------------------------------------------------------------------------- 1 | .Back1{ 2 | background-color: linear-gradient(134deg, #004B3A 0%, #2D8B61 81%, #9BD77E 100%); 3 | } 4 | .Back2{ 5 | background-color: linear-gradient(134deg, #004B3A, #2D8B61, #9BD77E); 6 | } -------------------------------------------------------------------------------- /Styles/Releases/8.1.1/test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.1.1/test.sketch -------------------------------------------------------------------------------- /Styles/Releases/8.13.0/Blend-Mode-Test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.13.0/Blend-Mode-Test.sketch -------------------------------------------------------------------------------- /Styles/Releases/8.13.0/test.sass: -------------------------------------------------------------------------------- 1 | .Overlay { 2 | mix-blend-mode: lighten; 3 | background-color: #FF03F8; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /Styles/Releases/8.14.0/Test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.14.0/Test.sketch -------------------------------------------------------------------------------- /Styles/Releases/8.14.0/test.less: -------------------------------------------------------------------------------- 1 | .--COLORS-{ 2 | .primary{ 3 | color: black; 4 | } 5 | .secondary{ 6 | color: grey; 7 | } 8 | } -------------------------------------------------------------------------------- /Styles/Releases/8.15.0/puzzle-tokens.less: -------------------------------------------------------------------------------- 1 | //////////// COLOR VARS ////////// 2 | 3 | .--COLORS-{ 4 | .Red-Colors{ 5 | .red01{ 6 | color: green; 7 | } 8 | } 9 | } 10 | 11 | ///////////////// Text Styles ///////////////// 12 | ///////////////// Layer Styles ///////////////// 13 | ///////////////Rectangle Style 14 | .Rectangle Style{ 15 | background-color: "Red-Colors/red01"; 16 | } 17 | -------------------------------------------------------------------------------- /Styles/Releases/8.15.0/puzzle-tokens.scss: -------------------------------------------------------------------------------- 1 | //////////// COLOR VARS ////////// 2 | .--COLORS-{ 3 | .Red-Colors{ 4 | .red01{ 5 | color: red; 6 | } 7 | } 8 | } 9 | 10 | ///////////////// Text Styles ///////////////// 11 | ///////////////// Layer Styles ///////////////// 12 | ///////////////Rectangle Style 13 | .Rectangle Style{ 14 | background-color: "Red-Colors/red01"; 15 | border-width: 1px; 16 | } 17 | -------------------------------------------------------------------------------- /Styles/Releases/8.16.1/one.less: -------------------------------------------------------------------------------- 1 | @brand: two; 2 | @import "@{brand}.less"; -------------------------------------------------------------------------------- /Styles/Releases/8.16.1/two.less: -------------------------------------------------------------------------------- 1 | .Neutral{ 2 | background-color: black; 3 | } -------------------------------------------------------------------------------- /Styles/Releases/8.16.3/Test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.16.3/Test.sketch -------------------------------------------------------------------------------- /Styles/Releases/8.16.3/bad.less: -------------------------------------------------------------------------------- 1 | .--COLORS-{ 2 | .primary{ 3 | color: black; 4 | } 5 | .secondary{ 6 | color: linear-gradient(45deg, #000000,#B0AFB4);; 7 | } 8 | } -------------------------------------------------------------------------------- /Styles/Releases/8.16.3/good.less: -------------------------------------------------------------------------------- 1 | .--COLORS-{ 2 | .primary{ 3 | color: blue; 4 | } 5 | .secondary{ 6 | color: red; 7 | } 8 | } -------------------------------------------------------------------------------- /Styles/Releases/8.17.0/gradient-test.less: -------------------------------------------------------------------------------- 1 | // Creating a gradient trying to add opacity 2 | 3 | @token: { 4 | colourA: fade(#20CC20,0.5); 5 | colourB: #CC2020; 6 | } 7 | 8 | .gradients .linear-gradient-opacity { 9 | background-color: linear-gradient(20deg,@token[colourA] 10%, @token[colourB] 80%); 10 | } 11 | 12 | .gradients .radial-gradient-opacity { 13 | background-color: radial-gradient(red 10px,@token[colourA] 10%, @token[colourB] 80%); 14 | } -------------------------------------------------------------------------------- /Styles/Releases/8.17.0/gradient-test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.17.0/gradient-test.sketch -------------------------------------------------------------------------------- /Styles/Releases/8.3.0/ResizeArtboard.less: -------------------------------------------------------------------------------- 1 | #Artboard{ 2 | height:500px; 3 | width:500px; 4 | } -------------------------------------------------------------------------------- /Styles/Releases/8.3.0/ResizeArtboard.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.3.0/ResizeArtboard.sketch -------------------------------------------------------------------------------- /Styles/Releases/8.3.0/_pt-assets/ResizeArtboard/inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{}} -------------------------------------------------------------------------------- /Styles/Releases/8.3.0/_pt-assets/ResizeArtboard/vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/Releases/8.3.0/_pt-assets/ResizeArtboard/vars.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.3.0/_pt-assets/ResizeArtboard/vars.scss -------------------------------------------------------------------------------- /Styles/Releases/8.3.2/Test.less: -------------------------------------------------------------------------------- 1 | @import "/Users/baza/Ingram/Git/ingram-micro-cloud/cb-modern-ui/design-tokens.less"; 2 | .test{ 3 | background-color: blue; 4 | } -------------------------------------------------------------------------------- /Styles/Releases/8.3.2/Test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.3.2/Test.sketch -------------------------------------------------------------------------------- /Styles/Releases/8.3.2/test-lib.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.3.2/test-lib.sketch -------------------------------------------------------------------------------- /Styles/Releases/8.3.3/New.less: -------------------------------------------------------------------------------- 1 | #Buttons{ 2 | #Button-Label,#Button-LabelActions{ 3 | .Group{ 4 | .Label,.ActionsIcon{ 5 | color: green; 6 | -pt-skip-missed: true; 7 | } 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Styles/Releases/8.3.3/Old.less: -------------------------------------------------------------------------------- 1 | #Buttons{ 2 | #Button-Label,#Button-LabelActions{ 3 | .Group{ 4 | .Label,.ActionsIcon{ 5 | color: green; 6 | } 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /Styles/Releases/8.3.3/Test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.3.3/Test.sketch -------------------------------------------------------------------------------- /Styles/Releases/8.3.3/_pt-assets/Test/inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{}} -------------------------------------------------------------------------------- /Styles/Releases/8.3.3/_pt-assets/Test/vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/Releases/8.3.3/_pt-assets/Test/vars.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.3.3/_pt-assets/Test/vars.scss -------------------------------------------------------------------------------- /Styles/Releases/8.3.4/Test.less: -------------------------------------------------------------------------------- 1 | .colors-blue(){ 2 | BLUE-1: blue; 3 | } 4 | 5 | .colors-red(){ 6 | RED-1: red; 7 | } 8 | 9 | #colors(){ 10 | .colors-blue(); 11 | .colors-red(); 12 | } 13 | 14 | 15 | .colors{ 16 | .blue{ 17 | each(.colors-blue(), { 18 | .@{key}{ 19 | color: @value; 20 | } 21 | }) 22 | } 23 | .red{ 24 | each(.colors-red(), { 25 | .@{key}{ 26 | color: @value; 27 | } 28 | }) 29 | } 30 | } -------------------------------------------------------------------------------- /Styles/Releases/8.5.0/Test.scss: -------------------------------------------------------------------------------- 1 | $linear-direction: 45deg; 2 | $palette-height: 160px; 3 | $palette-width: 160px; 4 | $palette-radius: 80px; 5 | 6 | $gradients-colors-coolors: ( 7 | Gradient__Coolor__001: linear-gradient($linear-direction, rgb(0, 97, 255) 0%, rgb(96, 239, 255) 100%), 8 | Gradient__Coolor__002: linear-gradient($linear-direction, rgb(0, 255, 135) 0%, rgb(96, 239, 255) 100%), 9 | ); 10 | 11 | .Gradients Coolors { 12 | .Linear { 13 | @each $key, $value in $gradients-colors-coolors { 14 | .#{$key} { 15 | background-color: $value; 16 | } 17 | } 18 | } 19 | } 20 | 21 | #Gradients Coolors { 22 | @each $key, $value in $gradients-colors-coolors { 23 | .#{$key}{ 24 | -pt-layer-type: layer; 25 | sklayer-style: "Gradients Coolors/Linear/#{$key}"; 26 | border-radius: $palette-radius; 27 | width: $palette-width; 28 | height: $palette-height; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Styles/Releases/8.5.0/Test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Releases/8.5.0/Test.sketch -------------------------------------------------------------------------------- /Styles/Set-Text/_pt-assets/set-text/inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{},"colors__":{},"attrs":{}} -------------------------------------------------------------------------------- /Styles/Set-Text/_pt-assets/set-text/vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/Set-Text/_pt-assets/set-text/vars.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Set-Text/_pt-assets/set-text/vars.scss -------------------------------------------------------------------------------- /Styles/Set-Text/set-text.less: -------------------------------------------------------------------------------- 1 | #Artboard .text { 2 | pt-text: "OK!"; 3 | } 4 | 5 | #Artboard .Group .text2 { 6 | pt-text: "OK #2!"; 7 | } -------------------------------------------------------------------------------- /Styles/Set-Text/set-text.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Set-Text/set-text.sketch -------------------------------------------------------------------------------- /Styles/Tests/Buttons/Illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Tests/Buttons/Illustration.png -------------------------------------------------------------------------------- /Styles/Tests/Buttons/Test-All-In-One.less: -------------------------------------------------------------------------------- 1 | //////////// COLOR TOKENS TOKENS ////////// 2 | @color-000: #ffffff00; 3 | @color-001: #ffffff; 4 | @color-002: #f56565; 5 | @color-003: #0071ba; 6 | @color-004: #ffffff80; 7 | @color-005: #00000080; 8 | @color-006: #ff0000; 9 | 10 | //////////// FONT SIZE TOKENS TOKENS ////////// 11 | @font-size-000: 12px; 12 | 13 | //////////// FONT WEIGHTS TOKENS TOKENS ////////// 14 | @font-weight-001: 400; 15 | @font-weight-000: 700; 16 | 17 | //////////// FONTS TOKENS ////////// 18 | @font-family-000: Verdana; 19 | 20 | ///////////////// Text Styles ///////////////// 21 | ///////////////Controls/Buttons/Submit/Cancel/Text 22 | .Controls .Buttons .Submit .Cancel .Text{ 23 | font-family: @font-family-000; 24 | font-size: @font-size-000; 25 | color: @color-000; 26 | text-align: center; 27 | vertical-align: top; 28 | font-weight: @font-weight-000; 29 | font-style: italic; 30 | text-transform: uppercase; 31 | text-decoration: underline; 32 | pt-paragraph-spacing: 0; 33 | } 34 | ///////////////Controls/Buttons/Submit/Ok Button/Text 35 | .Controls .Buttons .Submit .Ok__Button .Text{ 36 | font-family: @font-family-000; 37 | font-size: @font-size-000; 38 | color: @color-001; 39 | text-align: center; 40 | vertical-align: bottom; 41 | font-weight: @font-weight-001; 42 | line-height: 30px; 43 | text-transform: none; 44 | letter-spacing: 5px; 45 | pt-paragraph-spacing: 0; 46 | } 47 | ///////////////Controls/Buttons/Submit/Ok Button/Text/Me 48 | .Controls .Buttons .Submit .Ok__Button .Text .Me{ 49 | font-family: @font-family-000; 50 | font-size: @font-size-000; 51 | color: @color-001; 52 | text-align: center; 53 | vertical-align: bottom; 54 | font-weight: @font-weight-001; 55 | line-height: 30px; 56 | text-transform: none; 57 | pt-paragraph-spacing: 0; 58 | } 59 | ///////////////// Layer Styles ///////////////// 60 | ///////////////Controls/Buttons/Submit/Cancel/Back 61 | .Controls .Buttons .Submit .Cancel .Back{ 62 | border-color: @color-002; 63 | border-position: inside; 64 | border-width: 3px; 65 | } 66 | /////// Additional borders for Controls/Buttons/Submit/Cancel/Back 67 | .Controls .Buttons .Submit .Cancel .Back{ 68 | border-color: @color-001; 69 | border-position: inside; 70 | border-width: 5px; 71 | } 72 | .Controls .Buttons .Submit .Cancel .Back{ 73 | border-color: @color-002; 74 | border-position: inside; 75 | border-width: 8px; 76 | } 77 | ///////////////Controls/Buttons/Submit/Ok Button/Back 78 | .Controls .Buttons .Submit .Ok__Button .Back{ 79 | background-color: @color-003; 80 | } 81 | /////// Additional fills for Controls/Buttons/Submit/Ok Button/Back 82 | .Controls .Buttons .Submit .Ok__Button .Back{ 83 | background-color: linear-gradient(@color-004 ,@color-005); 84 | } 85 | ///////////////Opacities/25 86 | .Opacities .--PT-25{ 87 | opacity: 0.25; 88 | } 89 | ///////////////Opacities/0 90 | .Opacities .--PT-0{ 91 | opacity: 0; 92 | } 93 | ///////////////Opacities/50 94 | .Opacities .--PT-50{ 95 | opacity: 0.5; 96 | } 97 | ///////////////Opacities/75 98 | .Opacities .--PT-75{ 99 | opacity: 0.75; 100 | } 101 | ///////////////Opacities/100 102 | .Opacities .--PT-100{ 103 | } 104 | ///////////////Buttons/Disabled 105 | .Buttons .Disabled{ 106 | background-color: @color-006; 107 | } 108 | ///////////////Buttons/Lined 109 | .Buttons .Lined{ 110 | border-color: @color-001; 111 | border-width: 10px; 112 | border-line-end: round; 113 | } 114 | -------------------------------------------------------------------------------- /Styles/Tests/Buttons/Test-Blue.less: -------------------------------------------------------------------------------- 1 | @btn-back-color: #0071ba; 2 | @btn-text-color: white; 3 | @btn-shadow: 0px 5px 10px rgba(0,0,0,0.5); 4 | @btn-radius: 5px; 5 | @btn-border-style: dashed; 6 | @btn-font-size: 12px; 7 | 8 | @import "_Styles.less"; -------------------------------------------------------------------------------- /Styles/Tests/Buttons/Test-Blue.scss: -------------------------------------------------------------------------------- 1 | $btn-back-color: #0071ba; 2 | $btn-text-color: white; 3 | $btn-shadow: 0px 5px 10px rgba(0,0,0,0.5); 4 | $btn-radius: 5px; 5 | $btn-border-style: dashed; 6 | $btn-font-size: 12px; 7 | 8 | @import "_Styles.scss"; -------------------------------------------------------------------------------- /Styles/Tests/Buttons/Test-Green.less: -------------------------------------------------------------------------------- 1 | @btn-back-color: lightgreen; 2 | @btn-text-color: black; 3 | @btn-shadow: none; 4 | @btn-radius: 0px; 5 | @btn-border-style: none; 6 | @btn-font-size: 10px; 7 | 8 | @import "_Styles.less"; -------------------------------------------------------------------------------- /Styles/Tests/Buttons/Test-Green.scss: -------------------------------------------------------------------------------- 1 | $btn-back-color: lightgreen; 2 | $btn-text-color: black; 3 | $btn-shadow: none; 4 | $btn-radius: 0px; 5 | $btn-border-style: none; 6 | $btn-font-size: 10px; 7 | 8 | @import "_Styles.scss"; -------------------------------------------------------------------------------- /Styles/Tests/Buttons/Test.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Tests/Buttons/Test.sketch -------------------------------------------------------------------------------- /Styles/Tests/Buttons/_Styles.less: -------------------------------------------------------------------------------- 1 | // Test styles 2 | .Controls .Buttons .Submit { 3 | .Ok__Button { 4 | Text{ 5 | color : @btn-text-color; 6 | font-size: @btn-font-size; 7 | font-family: Verdana; 8 | font-style: normal; 9 | text-align: center; 10 | vertical-align: bottom; 11 | line-height: 30px; 12 | kerning: 2.5; 13 | } 14 | Back{ 15 | background-color: @btn-back-color; 16 | border-color: contrast(@btn-back-color); 17 | border-radius: @btn-radius; 18 | border-width: 1px; 19 | box-shadow: @btn-shadow; 20 | border-style: @btn-border-style; 21 | } 22 | } 23 | } 24 | /// Other technics 25 | 26 | @base-path: "images/"; 27 | #Artboard__1 .Logo{ 28 | image: ~"@{base-path}/old-logo.png"; 29 | width: 100px; 30 | bottom: 22px; 31 | left: 2px; 32 | right: 33px; 33 | border-width: 2px; 34 | border-color: blue; 35 | } 36 | 37 | @base-path: "images/"; 38 | #Artboard__2 .Image{ 39 | image: ~"@{base-path}/image.svg"; 40 | //width: 100px; 41 | //height: 100px; 42 | //bottom: 22px; 43 | //left: 2px; 44 | } 45 | 46 | .Buttons{ 47 | .Disabled{ 48 | background-color: red; 49 | } 50 | .Lined{ 51 | border-width: 10px; 52 | border-color: white; 53 | border-line-end: round; 54 | border-line-join: miter; 55 | } 56 | } 57 | 58 | #Buttons{ 59 | #Disabled{ 60 | .Rectangle{ 61 | border-radius: 2px; 62 | sklayer-style: "Buttons/Disabled"; 63 | //sklayer-style: "Controls/Buttons/Raised/Default/Back"; 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /Styles/Tests/Buttons/_Styles.scss: -------------------------------------------------------------------------------- 1 | // Test styles 2 | 3 | .Controls .Buttons .Submit { 4 | .Ok__Button { 5 | .Text{ 6 | color : $btn-text-color; 7 | font-size: $btn-font-size; 8 | font-family: Verdana; 9 | font-style: normal; 10 | text-align: center; 11 | vertical-align: bottom; 12 | line-height: 30px; 13 | kerning: 2.5; 14 | } 15 | .Back{ 16 | background-color: $btn-back-color; 17 | border-color: grey; 18 | border-radius: $btn-radius; 19 | border-width: 1px; 20 | box-shadow: $btn-shadow; 21 | border-style: $btn-border-style; 22 | } 23 | } 24 | } 25 | /// Other technics 26 | 27 | #Artboard__1 .Logo{ 28 | image: "images/old-logo.png"; 29 | width: 100px; 30 | bottom: 22px; 31 | left: 2px; 32 | right: 33px; 33 | border-width: 2px; 34 | border-color: blue; 35 | } 36 | 37 | #Artboard__2 .Image{ 38 | image: "images/image.svg"; 39 | //width: 100px; 40 | //height: 100px; 41 | //bottom: 22px; 42 | //left: 2px; 43 | } 44 | 45 | 46 | .Buttons{ 47 | .Disabled{ 48 | background-color: red; 49 | } 50 | .Lined{ 51 | border-width: 10px; 52 | border-color: white; 53 | border-line-end: round; 54 | border-line-join: miter; 55 | } 56 | } 57 | 58 | #Buttons{ 59 | #Disabled{ 60 | .Rectangle{ 61 | border-radius: 2px; 62 | sklayer-style: "Buttons/Disabled"; 63 | //sklayer-style: "Controls/Buttons/Raised/Default/Back"; 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /Styles/Tests/Buttons/_pt-assets/Test/inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{"Controls/Buttons/Submit/Ok Button Text":{"tokens":[["color","@btn-text-color"],["font-size","@btn-font-size"]]},"Controls/Buttons/Submit/Ok Button Back":{"tokens":[["background-color","@btn-back-color"],["border-radius","@btn-radius"],["box-shadow","@btn-shadow"],["border-style","@btn-border-style"]]}}} -------------------------------------------------------------------------------- /Styles/Tests/Buttons/_pt-assets/Test/vars.json: -------------------------------------------------------------------------------- 1 | {"@btn-back-color":"#0071ba","@btn-text-color":"white","@btn-shadow":"0px 5px 10px rgba(0, 0, 0, 0.5)","@btn-radius":"5px","@btn-border-style":"dashed","@btn-font-size":"12px","@base-path":"\"images/\""} -------------------------------------------------------------------------------- /Styles/Tests/Buttons/_pt-assets/Test/vars.scss: -------------------------------------------------------------------------------- 1 | $btn-back-color: #0071ba; 2 | $btn-text-color: white; 3 | $btn-shadow: 0px 5px 10px rgba(0, 0, 0, 0.5); 4 | $btn-radius: 5px; 5 | $btn-border-style: dashed; 6 | $btn-font-size: 12px; 7 | $base-path: ""images/""; 8 | -------------------------------------------------------------------------------- /Styles/Tests/Buttons/_pt-assets/Test/viewer.css: -------------------------------------------------------------------------------- 1 | /* MOD FOR VARIANT B WAS @color-background-primary*/ 2 | @keyframes fadeIn { 3 | from { 4 | opacity: 0; 5 | } 6 | to { 7 | opacity: 1; 8 | } 9 | } 10 | @keyframes fadeOut { 11 | from { 12 | opacity: 1; 13 | } 14 | to { 15 | opacity: 0; 16 | } 17 | } 18 | @keyframes slideInDown { 19 | from { 20 | transform: translate3d(0, 100%, 0); 21 | visibility: visible; 22 | } 23 | to { 24 | transform: translate3d(0, 0, 0); 25 | } 26 | } 27 | @keyframes slideInLeft { 28 | from { 29 | transform: translate3d(-100%, 0, 0); 30 | visibility: visible; 31 | } 32 | to { 33 | transform: translate3d(0, 0, 0); 34 | } 35 | } 36 | @keyframes slideInRight { 37 | from { 38 | transform: translate3d(100%, 0, 0); 39 | visibility: visible; 40 | } 41 | to { 42 | transform: translate3d(0, 0, 0); 43 | } 44 | } 45 | @keyframes slideInUp { 46 | from { 47 | transform: translate3d(0, -100%, 0); 48 | visibility: visible; 49 | } 50 | to { 51 | transform: translate3d(0, 0, 0); 52 | } 53 | } 54 | @keyframes slideOutDown { 55 | from { 56 | transform: translate3d(0, 0, 0); 57 | } 58 | to { 59 | visibility: hidden; 60 | transform: translate3d(0, 100%, 0); 61 | } 62 | } 63 | @keyframes slideOutLeft { 64 | from { 65 | transform: translate3d(0, 0, 0); 66 | } 67 | to { 68 | visibility: hidden; 69 | transform: translate3d(-100%, 0, 0); 70 | } 71 | } 72 | @keyframes slideOutRight { 73 | from { 74 | transform: translate3d(0, 0, 0); 75 | } 76 | to { 77 | visibility: hidden; 78 | transform: translate3d(100%, 0, 0); 79 | } 80 | } 81 | @keyframes slideOutUp { 82 | from { 83 | transform: translate3d(0, 0, 0); 84 | } 85 | to { 86 | visibility: hidden; 87 | transform: translate3d(0, -100%, 0); 88 | } 89 | } 90 | .fadeIn { 91 | animation-name: fadeIn; 92 | } 93 | .fadeOut { 94 | animation-name: fadeOut; 95 | } 96 | .slideInDown { 97 | animation-name: slideInDown; 98 | } 99 | .slideInLeft { 100 | animation-name: slideInLeft; 101 | } 102 | .slideInRight { 103 | animation-name: slideInRight; 104 | } 105 | .slideInUp { 106 | animation-name: slideInUp; 107 | } 108 | .slideOutDown { 109 | animation-name: slideOutDown; 110 | } 111 | .slideOutLeft { 112 | animation-name: slideOutLeft; 113 | } 114 | .slideOutRight { 115 | animation-name: slideOutRight; 116 | } 117 | .slideOutUp { 118 | animation-name: slideOutUp; 119 | } 120 | .transit { 121 | animation-duration: all 0.2s easy; 122 | animation-fill-mode: both; 123 | } 124 | -------------------------------------------------------------------------------- /Styles/Tests/Buttons/images/image.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Styles/Tests/Buttons/images/new-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Tests/Buttons/images/new-logo.jpg -------------------------------------------------------------------------------- /Styles/Tests/Buttons/images/old-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Tests/Buttons/images/old-logo.png -------------------------------------------------------------------------------- /Styles/Tests/Gradients/linear-gradients-inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{"Controls/Button/Large.We/Regular-You/Primary Me/Text":{"tokens":{}},"Controls/Button/Large/Regular/Primary/Back":{"tokens":{}},"Back-0":{"tokens":{}},"Back-1":{"tokens":{}},"Back-2":{"tokens":{}},"Back-3":{"tokens":{}},"Back-4":{"tokens":{}},"Back-5":{"tokens":{}},"Back-6":{"tokens":{}},"Back-7":{"tokens":{}},"Back-8":{"tokens":{}},"Back-9":{"tokens":{}},"Back-10":{"tokens":{}},"Back-11":{"tokens":{}},"Back-12":{"tokens":{}},"Back-13":{"tokens":{}},"Back-14":{"tokens":{}},"Back-15":{"tokens":{}},"Back-16":{"tokens":{}},"Back-17":{"tokens":{}},"Back-18":{"tokens":{}},"Back-19":{"tokens":{}},"Back-20":{"tokens":{}},"Back-21":{"tokens":{}},"Back-22":{"tokens":{}},"Back-23":{"tokens":{}},"Back-24":{"tokens":{}},"Back-25":{"tokens":{}},"Back-26":{"tokens":{}},"Back-27":{"tokens":{}},"Back-28":{"tokens":{}},"Back-29":{"tokens":{}},"Back-30":{"tokens":{}},"Back-31":{"tokens":{}},"Back-32":{"tokens":{}},"Back-33":{"tokens":{}},"Back-34":{"tokens":{}},"Back-35":{"tokens":{}},"Back-36":{"tokens":{}}}} -------------------------------------------------------------------------------- /Styles/Tests/Gradients/linear-gradients.less: -------------------------------------------------------------------------------- 1 | 2 | each(range(1,37),{ 3 | @temp: @index - 1; 4 | @deg: @temp * 10; 5 | Back-@{temp}{ 6 | background-color: linear-gradient( ~"@{deg}deg", black,white,red); 7 | } 8 | } 9 | ) 10 | -------------------------------------------------------------------------------- /Styles/Tests/Gradients/linear-gradients.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Tests/Gradients/linear-gradients.sketch -------------------------------------------------------------------------------- /Styles/Tests/Opacity/Opacity-inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{}} -------------------------------------------------------------------------------- /Styles/Tests/Opacity/Opacity.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Tests/Opacity/Opacity.sketch -------------------------------------------------------------------------------- /Styles/Tests/Opacity/styles.less: -------------------------------------------------------------------------------- 1 | // Opacity 2 | @opacity-disabed: 0.5; 3 | 4 | // Apply opacity to symbol childs 5 | #Controls{ 6 | #Raised__Buttons, #Raised__Free__Buttons, #Raised__Right__Buttons{ 7 | #Primary, #Primary__Actions, #Default, #Default__Actions, #Delete, #Delete, #Warning, #Warning{ 8 | #Disabled .Button{ 9 | opacity: @opacity-disabed; 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Styles/Tests/SM-Kit/_constants.scss: -------------------------------------------------------------------------------- 1 | // Thanks to Sérgio Gomes for precalculating those values 2 | // https://medium.com/dev-channel/using-sass-to-automatically-pick-text-colors-4ba7645d2796 3 | 4 | $channel-values: 5 | 0 6 | .0003035269835488375 7 | .000607053967097675 8 | .0009105809506465125 9 | .00121410793419535 10 | .0015176349177441874 11 | .001821161901293025 12 | .0021246888848418626 13 | .0024282158683907 14 | .0027317428519395373 15 | .003035269835488375 16 | .003346535763899161 17 | .003676507324047436 18 | .004024717018496307 19 | .004391442037410293 20 | .004776953480693729 21 | .005181516702338386 22 | .005605391624202723 23 | .006048833022857054 24 | .006512090792594475 25 | .006995410187265387 26 | .007499032043226175 27 | .008023192985384994 28 | .008568125618069307 29 | .009134058702220787 30 | .00972121732023785 31 | .010329823029626936 32 | .010960094006488246 33 | .011612245179743885 34 | .012286488356915872 35 | .012983032342173012 36 | .013702083047289686 37 | .014443843596092545 38 | .01520851442291271 39 | .01599629336550963 40 | .016807375752887384 41 | .017641954488384078 42 | .018500220128379697 43 | .019382360956935723 44 | .0202885630566524 45 | .021219010376003555 46 | .022173884793387385 47 | .02315336617811041 48 | .024157632448504756 49 | .02518685962736163 50 | .026241221894849898 51 | .027320891639074894 52 | .028426039504420793 53 | .0295568344378088 54 | .030713443732993635 55 | .03189603307301153 56 | .033104766570885055 57 | .03433980680868217 58 | .03560131487502034 59 | .03688945040110004 60 | .0382043715953465 61 | .03954623527673284 62 | .04091519690685319 63 | .042311410620809675 64 | .043735029256973465 65 | .04518620438567554 66 | .046665086336880095 67 | .04817182422688942 68 | .04970656598412723 69 | .05126945837404324 70 | .052860647023180246 71 | .05448027644244237 72 | .05612849004960009 73 | .05780543019106723 74 | .0595112381629812 75 | .06124605423161761 76 | .06301001765316767 77 | .06480326669290577 78 | .06662593864377289 79 | .06847816984440017 80 | .07036009569659588 81 | .07227185068231748 82 | .07421356838014963 83 | .07618538148130785 84 | .07818742180518633 85 | .08021982031446832 86 | .0822827071298148 87 | .08437621154414882 88 | .08650046203654976 89 | .08865558628577294 90 | .09084171118340768 91 | .09305896284668745 92 | .0953074666309647 93 | .09758734714186246 94 | .09989872824711389 95 | .10224173308810132 96 | .10461648409110419 97 | .10702310297826761 98 | .10946171077829933 99 | .1119324278369056 100 | .11443537382697373 101 | .11697066775851084 102 | .11953842798834562 103 | .12213877222960187 104 | .12477181756095049 105 | .12743768043564743 106 | .1301364766903643 107 | .13286832155381798 108 | .13563332965520566 109 | .13843161503245183 110 | .14126329114027164 111 | .14412847085805777 112 | .14702726649759498 113 | .14995978981060856 114 | .15292615199615017 115 | .1559264637078274 116 | .1589608350608804 117 | .162029375639111 118 | .1651321945016676 119 | .16826940018969075 120 | .1714411007328226 121 | .17464740365558504 122 | .17788841598362912 123 | .18116424424986022 124 | .184474994500441 125 | .18782077230067787 126 | .19120168274079138 127 | .1946178304415758 128 | .19806931955994886 129 | .20155625379439707 130 | .20507873639031693 131 | .20863687014525575 132 | .21223075741405523 133 | .21586050011389926 134 | .2195261997292692 135 | .2232279573168085 136 | .22696587351009836 137 | .23074004852434915 138 | .23455058216100522 139 | .238397573812271 140 | .24228112246555486 141 | .24620132670783548 142 | .25015828472995344 143 | .25415209433082675 144 | .2581828529215958 145 | .26225065752969623 146 | .26635560480286247 147 | .2704977910130658 148 | .27467731206038465 149 | .2788942634768104 150 | .2831487404299921 151 | .2874408377269175 152 | .29177064981753587 153 | .2961382707983211 154 | .3005437944157765 155 | .3049873140698863 156 | .30946892281750854 157 | .31398871337571754 158 | .31854677812509186 159 | .32314320911295075 160 | .3277780980565422 161 | .33245153634617935 162 | .33716361504833037 163 | .3419144249086609 164 | .3467040563550296 165 | .35153259950043936 166 | .3564001441459435 167 | .3613067797835095 168 | .3662525955988395 169 | .3712376804741491 170 | .3762621229909065 171 | .38132601143253014 172 | .386429433787049 173 | .39157247774972326 174 | .39675523072562685 175 | .4019777798321958 176 | .4072402119017367 177 | .41254261348390375 178 | .4178850708481375 179 | .4232676699860717 180 | .4286904966139066 181 | .43415363617474895 182 | .4396571738409188 183 | .44520119451622786 184 | .45078578283822346 185 | .45641102318040466 186 | .4620769996544071 187 | .467783796112159 188 | .47353149614800955 189 | .4793201831008268 190 | .4851499400560704 191 | .4910208498478356 192 | .4969329950608704 193 | .5028864580325687 194 | .5088813208549338 195 | .5149176653765214 196 | .5209955732043543 197 | .5271151257058131 198 | .5332764040105052 199 | .5394794890121072 200 | .5457244613701866 201 | .5520114015120001 202 | .5583403896342679 203 | .5647115057049292 204 | .5711248294648731 205 | .5775804404296506 206 | .5840784178911641 207 | .5906188409193369 208 | .5972017883637634 209 | .6038273388553378 210 | .6104955708078648 211 | .6172065624196511 212 | .6239603916750761 213 | .6307571363461468 214 | .6375968739940326 215 | .6444796819705821 216 | .6514056374198242 217 | .6583748172794485 218 | .665387298282272 219 | .6724431569576875 220 | .6795424696330938 221 | .6866853124353135 222 | .6938717612919899 223 | .7011018919329731 224 | .7083757798916868 225 | .7156935005064807 226 | .7230551289219693 227 | .7304607400903537 228 | .7379104087727308 229 | .7454042095403874 230 | .7529422167760779 231 | .7605245046752924 232 | .768151147247507 233 | .7758222183174236 234 | .7835377915261935 235 | .7912979403326302 236 | .799102738014409 237 | .8069522576692516 238 | .8148465722161012 239 | .8227857543962835 240 | .8307698767746546 241 | .83879901174074 242 | .846873231509858 243 | .8549926081242338 244 | .8631572134541023 245 | .8713671191987972 246 | .8796223968878317 247 | .8879231178819663 248 | .8962693533742664 249 | .9046611743911496 250 | .9130986517934192 251 | .9215818562772946 252 | .9301108583754237 253 | .938685728457888 254 | .9473065367331999 255 | .9559733532492861 256 | .9646862478944651 257 | .9734452903984125 258 | .9822505503331171 259 | .9911020971138298 260 | 1; -------------------------------------------------------------------------------- /Styles/Tests/SM-Kit/_functions.scss: -------------------------------------------------------------------------------- 1 | //// Custom functions to get parity with Less functions 2 | 3 | @function tint($color, $value) { 4 | @return mix(#ffffff, $color, $value); 5 | } 6 | 7 | 8 | /** 9 | * Calculate the luminance for a color. 10 | * See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests 11 | */ 12 | @function luminance($color) { 13 | $red: nth($channel-values, red($color) + 1); 14 | $green: nth($channel-values, green($color) + 1); 15 | $blue: nth($channel-values, blue($color) + 1); 16 | 17 | @return .2126 * $red + .7152 * $green + .0722 * $blue; 18 | } 19 | 20 | /** 21 | * Calculate the contrast ratio between two colors. 22 | * See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests 23 | */ 24 | @function return-contrast-color($back, $front) { 25 | $backLum: luminance($back) + .05; 26 | $foreLum: luminance($front) + .05; 27 | 28 | @return max($backLum, $foreLum) / min($backLum, $foreLum); 29 | } 30 | 31 | /** 32 | * Determine whether to use dark or light text on top of given color. 33 | * Returns black for dark text and white for light text. 34 | */ 35 | 36 | @function contrast($color) { 37 | $lightContrast: return-contrast-color($color, white); 38 | $darkContrast: return-contrast-color($color, black); 39 | 40 | @if ($lightContrast > $darkContrast) { 41 | @return white; 42 | } 43 | @else { 44 | @return black; 45 | } 46 | } -------------------------------------------------------------------------------- /Styles/Tests/SM-Kit/sm-kit-simple-vars.json: -------------------------------------------------------------------------------- 1 | { 2 | "@color-000": "#db0482ff", 3 | "@color-001": "#8925f5ff", 4 | "@color-002": "#923f7bff", 5 | "@color-003": "#17062bff", 6 | "@color-004": "#ffffffff", 7 | "@color-005": "#d83a3aff", 8 | "@color-006": "#f7a436ff", 9 | "@color-007": "#0ec988ff", 10 | "@color-008": "#fff79cff", 11 | "@color-009": "#000000ff", 12 | "@font-size006": "10px", 13 | "@font-size005": "12px", 14 | "@font-size004": "14px", 15 | "@font-size003": "16px", 16 | "@font-size002": "24px", 17 | "@font-size001": "36px", 18 | "@font-size000": "56px", 19 | "@font-weight000": "700", 20 | "@font-family000": "Graphik" 21 | } -------------------------------------------------------------------------------- /Styles/Tests/SM-Kit/sm-kit-simple-vars.scss: -------------------------------------------------------------------------------- 1 | $color-000: #db0482ff; 2 | $color-001: #8925f5ff; 3 | $color-002: #923f7bff; 4 | $color-003: #17062bff; 5 | $color-004: #ffffffff; 6 | $color-005: #d83a3aff; 7 | $color-006: #f7a436ff; 8 | $color-007: #0ec988ff; 9 | $color-008: #fff79cff; 10 | $color-009: #000000ff; 11 | $font-size006: 10px; 12 | $font-size005: 12px; 13 | $font-size004: 14px; 14 | $font-size003: 16px; 15 | $font-size002: 24px; 16 | $font-size001: 36px; 17 | $font-size000: 56px; 18 | $font-weight000: 700; 19 | $font-family000: Graphik; 20 | -------------------------------------------------------------------------------- /Styles/Tests/SM-Kit/sm-kit-simple.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/Tests/SM-Kit/sm-kit-simple.sketch -------------------------------------------------------------------------------- /Styles/Tests/SM-Kit/sm-tokens-simple-1.less: -------------------------------------------------------------------------------- 1 | 2 | //// Base colors 3 | 4 | @colors: { 5 | Brand: #db0482; 6 | Primary: #8925f5; 7 | Secondary: #923F7B; 8 | Black: #17062b; 9 | White: white; 10 | Danger: #d83a3a; 11 | Warning: #f7a436; 12 | Success: #0ec988; 13 | Highlight: #fff79c; 14 | } 15 | 16 | // Fonts 17 | 18 | @font-size: { 19 | h1: 56px; 20 | h2: 36px; 21 | } 22 | 23 | @text-align: left, right; 24 | 25 | @module: 4px; 26 | 27 | // Shadows 28 | 29 | @shadow: { 30 | enormous: 0 @module*8 @module*32 fade(@colors[Black], 30%); 31 | large: 0 @module*4 @module*8 fade(@colors[Black], 20%); 32 | } 33 | 34 | //// Less to Sketch Mapping 35 | 36 | /* 37 | .Backgrounds .Brand { 38 | background-color: @colors[Brand]; 39 | } 40 | 41 | .Backgrounds .Primary { 42 | background-color: @colors[Primary]; 43 | } 44 | 45 | .Backgrounds .Secondary { 46 | background-color: @colors[Secondary]; 47 | } 48 | 49 | .Backgrounds .Black { 50 | background-color: @colors[Black]; 51 | } 52 | 53 | .Backgrounds .White { 54 | background-color: @colors[White]; 55 | } 56 | 57 | .Backgrounds .Danger { 58 | background-color: @colors[Danger]; 59 | } 60 | 61 | .Backgrounds .Warning { 62 | background-color: @colors[Warning]; 63 | } 64 | 65 | .Backgrounds .Success { 66 | background-color: @colors[Success]; 67 | } 68 | 69 | .Backgrounds .Highlight { 70 | background-color: @colors[Highlight]; 71 | } 72 | 73 | */ 74 | 75 | /* 76 | .Backgrounds { 77 | each(@colors, { 78 | .@{key} { 79 | background-color: @value; 80 | } 81 | }); 82 | } 83 | */ 84 | 85 | 86 | 87 | // Texts generation: Size/Alignment/Color 88 | 89 | each(@font-size, .(@vs, @ks, @is) { 90 | .@{ks}Size { 91 | each(@text-align, .(@va, @ka, @ia) { 92 | .@{va}Aligned { 93 | each(@colors, { 94 | .@{key} { 95 | color: @value; 96 | font-size: @vs; 97 | text-align: @va; 98 | vertical-align: middle; 99 | line-height: 1.25; 100 | } 101 | }); 102 | 103 | // Contrast text colors subset generation 104 | .ContrastTo { 105 | //Base colors 106 | each(@colors, { 107 | .@{key} { 108 | color: contrast(@value); // getting a color contrast to a given color 109 | font-size: @vs; 110 | text-align: @va; 111 | vertical-align: middle; 112 | line-height: 1.25; 113 | } 114 | }); 115 | //Neutral colors 116 | each(range(7), { 117 | .Neutral-@{index} { 118 | color: contrast(tint(@colors[Black], 45% + (@index)*50%/7)); 119 | font-size: @vs; 120 | text-align: @va; 121 | vertical-align: middle; 122 | line-height: 1.25; 123 | } 124 | }); 125 | } 126 | } 127 | }); 128 | } 129 | }); 130 | -------------------------------------------------------------------------------- /Styles/Tests/SM-Kit/sm-tokens-simple.less: -------------------------------------------------------------------------------- 1 | 2 | //// Base colors 3 | 4 | @colors: { 5 | Brand: #db0482; 6 | Primary: #8925f5; 7 | Secondary: #923F7B; 8 | Black: #17062b; 9 | White: white; 10 | Danger: #d83a3a; 11 | Warning: #f7a436; 12 | Success: #0ec988; 13 | Highlight: #fff79c; 14 | } 15 | 16 | // Fonts 17 | 18 | @font-size: { 19 | h1: 56px; 20 | h2: 36px; 21 | h3: 24px; 22 | h4: 16px; 23 | normal: 14px; 24 | small: 12px; 25 | tiny: 10px; 26 | } 27 | 28 | @text-align: left, right, center; 29 | 30 | @module: 4px; 31 | 32 | // Shadows 33 | 34 | @shadow: { 35 | enormous: 0 @module*8 @module*32 fade(@colors[Black], 30%); 36 | large: 0 @module*4 @module*8 fade(@colors[Black], 20%); 37 | medium: 0 @module @module*2 fade(@colors[Black], 10%); 38 | small: 0 @module/2 @module/4 fade(@colors[Black], 15%); 39 | } 40 | 41 | //// Less to Sketch Mapping 42 | 43 | /* 44 | .Backgrounds .Brand { 45 | background-color: @colors[Brand]; 46 | } 47 | 48 | .Backgrounds .Primary { 49 | background-color: @colors[Primary]; 50 | } 51 | 52 | .Backgrounds .Secondary { 53 | background-color: @colors[Secondary]; 54 | } 55 | 56 | .Backgrounds .Black { 57 | background-color: @colors[Black]; 58 | } 59 | 60 | .Backgrounds .White { 61 | background-color: @colors[White]; 62 | } 63 | 64 | .Backgrounds .Danger { 65 | background-color: @colors[Danger]; 66 | } 67 | 68 | .Backgrounds .Warning { 69 | background-color: @colors[Warning]; 70 | } 71 | 72 | .Backgrounds .Success { 73 | background-color: @colors[Success]; 74 | } 75 | 76 | .Backgrounds .Highlight { 77 | background-color: @colors[Highlight]; 78 | } 79 | 80 | */ 81 | 82 | /* 83 | .Backgrounds { 84 | each(@colors, { 85 | .@{key} { 86 | background-color: @value; 87 | } 88 | }); 89 | } 90 | */ 91 | 92 | .Backgrounds { 93 | // base color styles generation 94 | each(@colors, { 95 | .@{key} { 96 | background-color: @value; 97 | } 98 | }); 99 | 100 | // shades generation 101 | .Neutrals { 102 | each(range(7), { 103 | .Neutral-@{index} { 104 | background-color: tint(@colors[Black], 45% + (@index)*50%/7); 105 | } 106 | }); 107 | } 108 | 109 | // Stage background 110 | .Stage { 111 | background-color: tint(@colors[Black], 98%); 112 | } 113 | } 114 | 115 | // Elevated backgrounds w/Shadow 116 | 117 | .Backgrounds .Elevated { 118 | each(@colors, { 119 | .@{key} { 120 | background-color: @value; 121 | box-shadow: @shadow[large]; 122 | } 123 | }); 124 | // shades generation 125 | .Neutrals { 126 | each(range(7), { 127 | .Neutral-@{index} { 128 | background-color: tint(@colors[Black], 45% + (@index)*50%/7); 129 | box-shadow: @shadow[large]; 130 | } 131 | }); 132 | } 133 | } 134 | 135 | 136 | // Texts generation: Size/Alignment/Color 137 | 138 | each(@font-size, .(@vs, @ks, @is) { 139 | .@{ks}Size { 140 | each(@text-align, .(@va, @ka, @ia) { 141 | .@{va}Aligned { 142 | each(@colors, { 143 | .@{key} { 144 | color: @value; 145 | font-size: @vs; 146 | text-align: @va; 147 | vertical-align: middle; 148 | line-height: 1.25; 149 | } 150 | }); 151 | 152 | // Contrast text colors subset generation 153 | .ContrastTo { 154 | //Base colors 155 | each(@colors, { 156 | .@{key} { 157 | color: contrast(@value); // getting a color contrast to a given color 158 | font-size: @vs; 159 | text-align: @va; 160 | vertical-align: middle; 161 | line-height: 1.25; 162 | } 163 | }); 164 | //Neutral colors 165 | each(range(7), { 166 | .Neutral-@{index} { 167 | color: contrast(tint(@colors[Black], 45% + (@index)*50%/7)); 168 | font-size: @vs; 169 | text-align: @va; 170 | vertical-align: middle; 171 | line-height: 1.25; 172 | } 173 | }); 174 | } 175 | } 176 | }); 177 | } 178 | }); 179 | 180 | 181 | // Gradient Backgrounds 182 | 183 | .Gradients { 184 | .Brand-Primary { 185 | background-color: linear-gradient(45deg, @colors[Brand], @colors[Primary]); 186 | } 187 | .Brand-Secondary { 188 | background-color: linear-gradient(45deg, @colors[Brand], @colors[Secondary]); 189 | } 190 | .Brand-Highlight { 191 | background-color: linear-gradient(45deg, @colors[Brand], @colors[Highlight]); 192 | } 193 | } 194 | 195 | // Shadows Backgrounds 196 | 197 | .Shadows .Primary { 198 | each(@shadow, { 199 | .@{key}Size { 200 | background-color: @colors[White]; 201 | box-shadow: @value; 202 | } 203 | .Inner { 204 | .@{key}Size { 205 | background-color: @colors[White]; 206 | box-shadow: inset @value; 207 | } 208 | } 209 | }); 210 | 211 | } 212 | 213 | 214 | //// Symbols styles 215 | 216 | #Buttons { 217 | #PrimarySmall .Back { 218 | border-radius: @module; 219 | } 220 | #PrimaryMedium .Back { 221 | border-radius: @module*2; 222 | } 223 | #PrimaryLarge .Back { 224 | border-radius: @module*4; 225 | } 226 | } -------------------------------------------------------------------------------- /Styles/Tests/SM-Kit/sm-tokens-simple.scss: -------------------------------------------------------------------------------- 1 | @use "sass:map"; 2 | @use "sass:color"; 3 | 4 | @import "_constants.scss"; 5 | @import "functions.scss"; 6 | 7 | 8 | //// Base colors 9 | 10 | $colors: ( 11 | Brand: tomato, 12 | Primary: violet, 13 | Secondary: limegreen, 14 | Black: #17062b, 15 | White: white, 16 | Danger: #d83a3a, 17 | Warning: #f7a436, 18 | Success: #0ec988, 19 | Highlight: #fff79c 20 | ); 21 | 22 | // Fonts 23 | 24 | $font-size: ( 25 | h1: 56px, 26 | h2: 36px, 27 | h3: 24px, 28 | h4: 16px, 29 | normal: 14px, 30 | small: 12px, 31 | tiny: 10px 32 | ); 33 | 34 | $text-align: left, right, center; 35 | 36 | $module: 4px; 37 | 38 | // Shadows 39 | 40 | $shadow: ( 41 | enormous: 0 $module*8 $module*32 fade-out(map.get($colors, Black), .7), 42 | large: 0 $module*4 $module*8 fade-out(map.get($colors, Black), .8), 43 | medium: 0 $module $module*2 fade-out(map.get($colors, Black), .9), 44 | small: 0 $module/2 $module/4 fade-out(map.get($colors, Black), .95) 45 | ); 46 | 47 | 48 | // Backgrounds 49 | 50 | .Backgrounds { 51 | // base color styles generation 52 | @each $key, $value in $colors { 53 | .#{$key} { 54 | background-color: $value; 55 | } 56 | } 57 | 58 | // shades generation 59 | .Neutrals { 60 | @for $index from 1 through 7 { 61 | .Neutral-#{$index} { 62 | background-color: tint(map.get($colors, Black), 45% + ($index)*50%/7); 63 | } 64 | } 65 | } 66 | 67 | // Stage background 68 | .Stage { 69 | background-color: tint(map.get($colors, Black), 98%); 70 | } 71 | } 72 | 73 | // Elevated backgrounds w/Shadow 74 | 75 | .Backgrounds .Elevated { 76 | @each $key, $value in $colors { 77 | .#{$key} { 78 | background-color: $value; 79 | box-shadow: map.get($shadow, large); 80 | } 81 | } 82 | // shades generation 83 | .Neutrals { 84 | @for $index from 1 through 7 { 85 | .Neutral-#{$index} { 86 | background-color: tint(map.get($colors, Black), 45% + ($index)*50%/7); 87 | box-shadow: map.get($shadow, large); 88 | } 89 | } 90 | } 91 | } 92 | 93 | 94 | // Texts generation: Size/Alignment/Color 95 | 96 | @each $ks,$vs in $font-size { 97 | 98 | .#{$ks}Size { 99 | @each $va in $text-align { 100 | $ia: index(($text-align), ($va)); 101 | .#{$va}Aligned { 102 | @each $key, $value in $colors { 103 | .#{$key} { 104 | color: $value; 105 | font-size: $vs; 106 | font-family: "Open Sans"; 107 | text-align: $va; 108 | vertical-align: middle; 109 | line-height: 1.25; 110 | } 111 | } 112 | 113 | // Contrast text colors subset generation 114 | .ContrastTo { 115 | //Base colors 116 | @each $key, $value in $colors { 117 | .#{$key} { 118 | color: contrast($value); // getting a color contrast to a given color 119 | font-size: $vs; 120 | text-align: $va; 121 | vertical-align: middle; 122 | line-height: 1.25; 123 | } 124 | } 125 | //Neutral colors 126 | @for $index from 1 through 7 { 127 | .Neutral-#{$index} { 128 | color: contrast(tint(map.get($colors, Black), 45% + ($index)*50%/7)); 129 | font-size: $vs; 130 | text-align: $va; 131 | vertical-align: middle; 132 | line-height: 1.25; 133 | } 134 | } 135 | } 136 | } 137 | } 138 | } 139 | } 140 | 141 | 142 | // Gradient Backgrounds 143 | 144 | .Gradients { 145 | .Brand-Primary { 146 | background-color: linear-gradient(45deg, map.get($colors, Brand), map.get($colors, Primary)); 147 | } 148 | .Brand-Secondary { 149 | background-color: linear-gradient(45deg, map.get($colors, Brand), map.get($colors, Secondary)); 150 | } 151 | .Brand-Highlight { 152 | background-color: linear-gradient(45deg, map.get($colors, Brand), map.get($colors, Highlight)); 153 | } 154 | } 155 | 156 | // Shadows Backgrounds 157 | 158 | .Shadows .Primary { 159 | @each $key, $value in $shadow { 160 | .#{$key}Size { 161 | background-color: map.get($colors, White); 162 | box-shadow: $value; 163 | } 164 | .Inner { 165 | .#{$key}Size { 166 | background-color: map.get($colors, White); 167 | box-shadow: inset $value; 168 | } 169 | } 170 | } 171 | 172 | } 173 | 174 | 175 | //// Symbols styles 176 | 177 | #Buttons { 178 | #PrimarySmall .Back { 179 | border-radius: $module; 180 | } 181 | #PrimaryMedium .Back { 182 | border-radius: $module*2; 183 | } 184 | #PrimaryLarge .Back { 185 | border-radius: $module*4; 186 | } 187 | } 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /Styles/Two Brands/Start-Dark.less: -------------------------------------------------------------------------------- 1 | // this is just the starting file. we set the variable for the right theme and import the less functions 2 | 3 | @brand: mybrand; 4 | @theme: "dark"; 5 | 6 | @import ~"functions.less"; -------------------------------------------------------------------------------- /Styles/Two Brands/Start-Light.less: -------------------------------------------------------------------------------- 1 | // this is just the starting file. we set the variable for the right theme and import the less functions 2 | 3 | @brand: mybrand; 4 | @theme: "light"; 5 | 6 | @import ~"functions.less"; -------------------------------------------------------------------------------- /Styles/Two Brands/functions.less: -------------------------------------------------------------------------------- 1 | @import ~"@{brand}.less"; 2 | 3 | .--COLORS-{ 4 | .Colors{ 5 | .Neutral{ 6 | each(.mixin-colors-neutral(), { 7 | .@{key}{ 8 | color: @value; 9 | } 10 | }) 11 | } 12 | .Utility{ 13 | each(.mixin-colors-utility(), { 14 | .@{key}{ 15 | color: @value; 16 | } 17 | }) 18 | } 19 | .Mist{ 20 | each(.mixin-colors-mist(), { 21 | .@{key}{ 22 | color: @value; 23 | } 24 | }) 25 | } 26 | .Glass{ 27 | each(.mixin-colors-glass(), { 28 | .@{key}{ 29 | color: @value; 30 | } 31 | }) 32 | } 33 | .elevations{ 34 | each(.mixin-colors-elevations(@theme), { 35 | .@{key}{ 36 | color: @value; 37 | } 38 | }) 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Styles/Two Brands/mybrand.less: -------------------------------------------------------------------------------- 1 | .mixin-colors-neutral(){ 2 | // Neutral Colors 3 | 4 | neutral-1000: #000000; // Do we put Solid Black in the Neutral Palette? 5 | neutral-900: #040404; 6 | neutral-800: #1A1A1A; 7 | neutral-700: #2A2A2A; 8 | neutral-600: #3C3C3C; 9 | neutral-500: #4B4B4B; 10 | neutral-400: #696969; 11 | neutral-300: #A3A3A3; 12 | neutral-200: #D1D1D1; 13 | neutral-100: #E8E8E8; 14 | neutral-50: #F5F5F5; 15 | neutral-000: #FFFFFF; // Do we put Solid White in the Neutral Palette? 16 | } 17 | 18 | .mixin-colors-mist(){ 19 | // Mist: These are white opacity Overlays 20 | 21 | mist-900: rgba(255,255,255,0.90); 22 | mist-800: rgba(255,255,255,0.80); 23 | mist-700: rgba(255,255,255,0.70); 24 | mist-600: rgba(255,255,255,0.60); 25 | mist-500: rgba(255,255,255,0.50); 26 | mist-400: rgba(255,255,255,0.40); 27 | mist-300: rgba(255,255,255,0.30); 28 | mist-200: rgba(255,255,255,0.20); 29 | mist-100: rgba(255,255,255,0.10); 30 | } 31 | 32 | .mixin-colors-glass(){ 33 | // Glass: These are black opacity Overlays 34 | 35 | glass-900: rgba(0,0,0,0.90); 36 | glass-800: rgba(0,0,0,0.80); 37 | glass-700: rgba(0,0,0,0.70); 38 | glass-600: rgba(0,0,0,0.60); 39 | glass-500: rgba(0,0,0,0.50); 40 | glass-400: rgba(0,0,0,0.40); 41 | glass-300: rgba(0,0,0,0.30); 42 | glass-200: rgba(0,0,0,0.20); 43 | glass-100: rgba(0,0,0,0.10); 44 | } 45 | 46 | // Utility 47 | 48 | .mixin-colors-utility(){ 49 | utility-positive: #64A541; 50 | utility-warning: #FFCC00; 51 | utility-error: #E5931D; 52 | } 53 | 54 | .mixin-colors-elevations (@theme) when (@theme = "dark") { 55 | Elevation-0: #130D13; 56 | Elevation-1: #1C141C; 57 | Elevation-2: #2B1E2B; 58 | Elevation-3: #2D202D; 59 | Elevation-4: #453845; 60 | Elevation-5: #979097; 61 | } 62 | .mixin-colors-elevations (@theme) when (@theme = "light") { 63 | Elevation-0: #FFFFFF; 64 | Elevation-1: #FFFFFF; 65 | Elevation-2: #FFFFFF; 66 | Elevation-3: #FFFFFF; 67 | Elevation-4: #DFDFDF; 68 | Elevation-5: #FFFFFF; 69 | } -------------------------------------------------------------------------------- /Styles/material-palettes/_pt-assets/palettes/inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{},"colors__":{},"attrs":{}} -------------------------------------------------------------------------------- /Styles/material-palettes/_pt-assets/palettes/vars.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Styles/material-palettes/_pt-assets/palettes/vars.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/material-palettes/_pt-assets/palettes/vars.scss -------------------------------------------------------------------------------- /Styles/material-palettes/palettes-inspector.json: -------------------------------------------------------------------------------- 1 | {"styles":{"palettes/red/red-100":{"tokens":{}},"palettes/red/red-900":{"tokens":{}},"palettes/red/red-200":{"tokens":{}},"palettes/red/red-800":{"tokens":{}},"palettes/red/red-300":{"tokens":{}},"palettes/red/red-700":{"tokens":{}},"palettes/red/red-400":{"tokens":{}},"palettes/red/red-600":{"tokens":{}},"palettes/red/red-050":{"tokens":{}},"palettes/red/red-500":{"tokens":{}},"palettes/pink/pink-100":{"tokens":{}},"palettes/pink/pink-900":{"tokens":{}},"palettes/pink/pink-200":{"tokens":{}},"palettes/pink/pink-800":{"tokens":{}},"palettes/pink/pink-300":{"tokens":{}},"palettes/pink/pink-700":{"tokens":{}},"palettes/pink/pink-400":{"tokens":{}},"palettes/pink/pink-600":{"tokens":{}},"palettes/pink/pink-050":{"tokens":{}},"palettes/pink/pink-500":{"tokens":{}},"palettes/purple/purple-100":{"tokens":{}},"palettes/purple/purple-900":{"tokens":{}},"palettes/purple/purple-200":{"tokens":{}},"palettes/purple/purple-800":{"tokens":{}},"palettes/purple/purple-300":{"tokens":{}},"palettes/purple/purple-700":{"tokens":{}},"palettes/purple/purple-400":{"tokens":{}},"palettes/purple/purple-600":{"tokens":{}},"palettes/purple/purple-050":{"tokens":{}},"palettes/purple/purple-500":{"tokens":{}},"palettes/deep-purple/deep-purple-100":{"tokens":{}},"palettes/deep-purple/deep-purple-900":{"tokens":{}},"palettes/deep-purple/deep-purple-200":{"tokens":{}},"palettes/deep-purple/deep-purple-800":{"tokens":{}},"palettes/deep-purple/deep-purple-300":{"tokens":{}},"palettes/deep-purple/deep-purple-700":{"tokens":{}},"palettes/deep-purple/deep-purple-400":{"tokens":{}},"palettes/deep-purple/deep-purple-600":{"tokens":{}},"palettes/deep-purple/deep-purple-050":{"tokens":{}},"palettes/deep-purple/deep-purple-500":{"tokens":{}},"palettes/indigo/indigo-100":{"tokens":{}},"palettes/indigo/indigo-900":{"tokens":{}},"palettes/indigo/indigo-200":{"tokens":{}},"palettes/indigo/indigo-800":{"tokens":{}},"palettes/indigo/indigo-300":{"tokens":{}},"palettes/indigo/indigo-700":{"tokens":{}},"palettes/indigo/indigo-400":{"tokens":{}},"palettes/indigo/indigo-600":{"tokens":{}},"palettes/indigo/indigo-050":{"tokens":{}},"palettes/indigo/indigo-500":{"tokens":{}},"palettes/blue/blue-100":{"tokens":{}},"palettes/blue/blue-900":{"tokens":{}},"palettes/blue/blue-200":{"tokens":{}},"palettes/blue/blue-800":{"tokens":{}},"palettes/blue/blue-300":{"tokens":{}},"palettes/blue/blue-700":{"tokens":{}},"palettes/blue/blue-400":{"tokens":{}},"palettes/blue/blue-600":{"tokens":{}},"palettes/blue/blue-050":{"tokens":{}},"palettes/blue/blue-500":{"tokens":{}},"palettes/light-blue/light-blue-100":{"tokens":{}},"palettes/light-blue/light-blue-900":{"tokens":{}},"palettes/light-blue/light-blue-200":{"tokens":{}},"palettes/light-blue/light-blue-800":{"tokens":{}},"palettes/light-blue/light-blue-300":{"tokens":{}},"palettes/light-blue/light-blue-700":{"tokens":{}},"palettes/light-blue/light-blue-400":{"tokens":{}},"palettes/light-blue/light-blue-600":{"tokens":{}},"palettes/light-blue/light-blue-050":{"tokens":{}},"palettes/light-blue/light-blue-500":{"tokens":{}},"palettes/cyan/cyan-100":{"tokens":{}},"palettes/cyan/cyan-900":{"tokens":{}},"palettes/cyan/cyan-200":{"tokens":{}},"palettes/cyan/cyan-800":{"tokens":{}},"palettes/cyan/cyan-300":{"tokens":{}},"palettes/cyan/cyan-700":{"tokens":{}},"palettes/cyan/cyan-400":{"tokens":{}},"palettes/cyan/cyan-600":{"tokens":{}},"palettes/cyan/cyan-050":{"tokens":{}},"palettes/cyan/cyan-500":{"tokens":{}},"palettes/teal/teal-100":{"tokens":{}},"palettes/teal/teal-900":{"tokens":{}},"palettes/teal/teal-200":{"tokens":{}},"palettes/teal/teal-800":{"tokens":{}},"palettes/teal/teal-300":{"tokens":{}},"palettes/teal/teal-700":{"tokens":{}},"palettes/teal/teal-400":{"tokens":{}},"palettes/teal/teal-600":{"tokens":{}},"palettes/teal/teal-050":{"tokens":{}},"palettes/teal/teal-500":{"tokens":{}},"palettes/green/green-100":{"tokens":{}},"palettes/green/green-900":{"tokens":{}},"palettes/green/green-200":{"tokens":{}},"palettes/green/green-800":{"tokens":{}},"palettes/green/green-300":{"tokens":{}},"palettes/green/green-700":{"tokens":{}},"palettes/green/green-400":{"tokens":{}},"palettes/green/green-600":{"tokens":{}},"palettes/green/green-050":{"tokens":{}},"palettes/green/green-500":{"tokens":{}},"palettes/light-green/light-green-100":{"tokens":{}},"palettes/light-green/light-green-900":{"tokens":{}},"palettes/light-green/light-green-200":{"tokens":{}},"palettes/light-green/light-green-800":{"tokens":{}},"palettes/light-green/light-green-300":{"tokens":{}},"palettes/light-green/light-green-700":{"tokens":{}},"palettes/light-green/light-green-400":{"tokens":{}},"palettes/light-green/light-green-600":{"tokens":{}},"palettes/light-green/light-green-050":{"tokens":{}},"palettes/light-green/light-green-500":{"tokens":{}},"palettes/lime/lime-100":{"tokens":{}},"palettes/lime/lime-900":{"tokens":{}},"palettes/lime/lime-200":{"tokens":{}},"palettes/lime/lime-800":{"tokens":{}},"palettes/lime/lime-300":{"tokens":{}},"palettes/lime/lime-700":{"tokens":{}},"palettes/lime/lime-400":{"tokens":{}},"palettes/lime/lime-600":{"tokens":{}},"palettes/lime/lime-050":{"tokens":{}},"palettes/lime/lime-500":{"tokens":{}},"palettes/yellow/yellow-100":{"tokens":{}},"palettes/yellow/yellow-900":{"tokens":{}},"palettes/yellow/yellow-200":{"tokens":{}},"palettes/yellow/yellow-800":{"tokens":{}},"palettes/yellow/yellow-300":{"tokens":{}},"palettes/yellow/yellow-700":{"tokens":{}},"palettes/yellow/yellow-400":{"tokens":{}},"palettes/yellow/yellow-600":{"tokens":{}},"palettes/yellow/yellow-050":{"tokens":{}},"palettes/yellow/yellow-500":{"tokens":{}},"palettes/amber/amber-100":{"tokens":{}},"palettes/amber/amber-900":{"tokens":{}},"palettes/amber/amber-200":{"tokens":{}},"palettes/amber/amber-800":{"tokens":{}},"palettes/amber/amber-300":{"tokens":{}},"palettes/amber/amber-700":{"tokens":{}},"palettes/amber/amber-400":{"tokens":{}},"palettes/amber/amber-600":{"tokens":{}},"palettes/amber/amber-050":{"tokens":{}},"palettes/amber/amber-500":{"tokens":{}},"palettes/orange/orange-100":{"tokens":{}},"palettes/orange/orange-900":{"tokens":{}},"palettes/orange/orange-200":{"tokens":{}},"palettes/orange/orange-800":{"tokens":{}},"palettes/orange/orange-300":{"tokens":{}},"palettes/orange/orange-700":{"tokens":{}},"palettes/orange/orange-400":{"tokens":{}},"palettes/orange/orange-600":{"tokens":{}},"palettes/orange/orange-050":{"tokens":{}},"palettes/orange/orange-500":{"tokens":{}},"palettes/deep-orange/deep-orange-100":{"tokens":{}},"palettes/deep-orange/deep-orange-900":{"tokens":{}},"palettes/deep-orange/deep-orange-200":{"tokens":{}},"palettes/deep-orange/deep-orange-800":{"tokens":{}},"palettes/deep-orange/deep-orange-300":{"tokens":{}},"palettes/deep-orange/deep-orange-700":{"tokens":{}},"palettes/deep-orange/deep-orange-400":{"tokens":{}},"palettes/deep-orange/deep-orange-600":{"tokens":{}},"palettes/deep-orange/deep-orange-050":{"tokens":{}},"palettes/deep-orange/deep-orange-500":{"tokens":{}},"palettes/brown/brown-100":{"tokens":{}},"palettes/brown/brown-900":{"tokens":{}},"palettes/brown/brown-200":{"tokens":{}},"palettes/brown/brown-800":{"tokens":{}},"palettes/brown/brown-300":{"tokens":{}},"palettes/brown/brown-700":{"tokens":{}},"palettes/brown/brown-400":{"tokens":{}},"palettes/brown/brown-600":{"tokens":{}},"palettes/brown/brown-050":{"tokens":{}},"palettes/brown/brown-500":{"tokens":{}},"palettes/grey/grey-100":{"tokens":{}},"palettes/grey/grey-900":{"tokens":{}},"palettes/grey/grey-200":{"tokens":{}},"palettes/grey/grey-800":{"tokens":{}},"palettes/grey/grey-300":{"tokens":{}},"palettes/grey/grey-700":{"tokens":{}},"palettes/grey/grey-400":{"tokens":{}},"palettes/grey/grey-600":{"tokens":{}},"palettes/grey/grey-050":{"tokens":{}},"palettes/grey/grey-500":{"tokens":{}},"palettes/blue-grey/blue-grey-100":{"tokens":{}},"palettes/blue-grey/blue-grey-900":{"tokens":{}},"palettes/blue-grey/blue-grey-200":{"tokens":{}},"palettes/blue-grey/blue-grey-800":{"tokens":{}},"palettes/blue-grey/blue-grey-300":{"tokens":{}},"palettes/blue-grey/blue-grey-700":{"tokens":{}},"palettes/blue-grey/blue-grey-400":{"tokens":{}},"palettes/blue-grey/blue-grey-600":{"tokens":{}},"palettes/blue-grey/blue-grey-050":{"tokens":{}},"palettes/blue-grey/blue-grey-500":{"tokens":{}}},"color":{"layers":{}}} -------------------------------------------------------------------------------- /Styles/material-palettes/palettes.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/Styles/material-palettes/palettes.sketch -------------------------------------------------------------------------------- /Styles/material-palettes/scss/_constants.scss: -------------------------------------------------------------------------------- 1 | // Thanks to Sérgio Gomes for precalculating those values 2 | // https://medium.com/dev-channel/using-sass-to-automatically-pick-text-colors-4ba7645d2796 3 | 4 | $channel-values: 5 | 0 6 | .0003035269835488375 7 | .000607053967097675 8 | .0009105809506465125 9 | .00121410793419535 10 | .0015176349177441874 11 | .001821161901293025 12 | .0021246888848418626 13 | .0024282158683907 14 | .0027317428519395373 15 | .003035269835488375 16 | .003346535763899161 17 | .003676507324047436 18 | .004024717018496307 19 | .004391442037410293 20 | .004776953480693729 21 | .005181516702338386 22 | .005605391624202723 23 | .006048833022857054 24 | .006512090792594475 25 | .006995410187265387 26 | .007499032043226175 27 | .008023192985384994 28 | .008568125618069307 29 | .009134058702220787 30 | .00972121732023785 31 | .010329823029626936 32 | .010960094006488246 33 | .011612245179743885 34 | .012286488356915872 35 | .012983032342173012 36 | .013702083047289686 37 | .014443843596092545 38 | .01520851442291271 39 | .01599629336550963 40 | .016807375752887384 41 | .017641954488384078 42 | .018500220128379697 43 | .019382360956935723 44 | .0202885630566524 45 | .021219010376003555 46 | .022173884793387385 47 | .02315336617811041 48 | .024157632448504756 49 | .02518685962736163 50 | .026241221894849898 51 | .027320891639074894 52 | .028426039504420793 53 | .0295568344378088 54 | .030713443732993635 55 | .03189603307301153 56 | .033104766570885055 57 | .03433980680868217 58 | .03560131487502034 59 | .03688945040110004 60 | .0382043715953465 61 | .03954623527673284 62 | .04091519690685319 63 | .042311410620809675 64 | .043735029256973465 65 | .04518620438567554 66 | .046665086336880095 67 | .04817182422688942 68 | .04970656598412723 69 | .05126945837404324 70 | .052860647023180246 71 | .05448027644244237 72 | .05612849004960009 73 | .05780543019106723 74 | .0595112381629812 75 | .06124605423161761 76 | .06301001765316767 77 | .06480326669290577 78 | .06662593864377289 79 | .06847816984440017 80 | .07036009569659588 81 | .07227185068231748 82 | .07421356838014963 83 | .07618538148130785 84 | .07818742180518633 85 | .08021982031446832 86 | .0822827071298148 87 | .08437621154414882 88 | .08650046203654976 89 | .08865558628577294 90 | .09084171118340768 91 | .09305896284668745 92 | .0953074666309647 93 | .09758734714186246 94 | .09989872824711389 95 | .10224173308810132 96 | .10461648409110419 97 | .10702310297826761 98 | .10946171077829933 99 | .1119324278369056 100 | .11443537382697373 101 | .11697066775851084 102 | .11953842798834562 103 | .12213877222960187 104 | .12477181756095049 105 | .12743768043564743 106 | .1301364766903643 107 | .13286832155381798 108 | .13563332965520566 109 | .13843161503245183 110 | .14126329114027164 111 | .14412847085805777 112 | .14702726649759498 113 | .14995978981060856 114 | .15292615199615017 115 | .1559264637078274 116 | .1589608350608804 117 | .162029375639111 118 | .1651321945016676 119 | .16826940018969075 120 | .1714411007328226 121 | .17464740365558504 122 | .17788841598362912 123 | .18116424424986022 124 | .184474994500441 125 | .18782077230067787 126 | .19120168274079138 127 | .1946178304415758 128 | .19806931955994886 129 | .20155625379439707 130 | .20507873639031693 131 | .20863687014525575 132 | .21223075741405523 133 | .21586050011389926 134 | .2195261997292692 135 | .2232279573168085 136 | .22696587351009836 137 | .23074004852434915 138 | .23455058216100522 139 | .238397573812271 140 | .24228112246555486 141 | .24620132670783548 142 | .25015828472995344 143 | .25415209433082675 144 | .2581828529215958 145 | .26225065752969623 146 | .26635560480286247 147 | .2704977910130658 148 | .27467731206038465 149 | .2788942634768104 150 | .2831487404299921 151 | .2874408377269175 152 | .29177064981753587 153 | .2961382707983211 154 | .3005437944157765 155 | .3049873140698863 156 | .30946892281750854 157 | .31398871337571754 158 | .31854677812509186 159 | .32314320911295075 160 | .3277780980565422 161 | .33245153634617935 162 | .33716361504833037 163 | .3419144249086609 164 | .3467040563550296 165 | .35153259950043936 166 | .3564001441459435 167 | .3613067797835095 168 | .3662525955988395 169 | .3712376804741491 170 | .3762621229909065 171 | .38132601143253014 172 | .386429433787049 173 | .39157247774972326 174 | .39675523072562685 175 | .4019777798321958 176 | .4072402119017367 177 | .41254261348390375 178 | .4178850708481375 179 | .4232676699860717 180 | .4286904966139066 181 | .43415363617474895 182 | .4396571738409188 183 | .44520119451622786 184 | .45078578283822346 185 | .45641102318040466 186 | .4620769996544071 187 | .467783796112159 188 | .47353149614800955 189 | .4793201831008268 190 | .4851499400560704 191 | .4910208498478356 192 | .4969329950608704 193 | .5028864580325687 194 | .5088813208549338 195 | .5149176653765214 196 | .5209955732043543 197 | .5271151257058131 198 | .5332764040105052 199 | .5394794890121072 200 | .5457244613701866 201 | .5520114015120001 202 | .5583403896342679 203 | .5647115057049292 204 | .5711248294648731 205 | .5775804404296506 206 | .5840784178911641 207 | .5906188409193369 208 | .5972017883637634 209 | .6038273388553378 210 | .6104955708078648 211 | .6172065624196511 212 | .6239603916750761 213 | .6307571363461468 214 | .6375968739940326 215 | .6444796819705821 216 | .6514056374198242 217 | .6583748172794485 218 | .665387298282272 219 | .6724431569576875 220 | .6795424696330938 221 | .6866853124353135 222 | .6938717612919899 223 | .7011018919329731 224 | .7083757798916868 225 | .7156935005064807 226 | .7230551289219693 227 | .7304607400903537 228 | .7379104087727308 229 | .7454042095403874 230 | .7529422167760779 231 | .7605245046752924 232 | .768151147247507 233 | .7758222183174236 234 | .7835377915261935 235 | .7912979403326302 236 | .799102738014409 237 | .8069522576692516 238 | .8148465722161012 239 | .8227857543962835 240 | .8307698767746546 241 | .83879901174074 242 | .846873231509858 243 | .8549926081242338 244 | .8631572134541023 245 | .8713671191987972 246 | .8796223968878317 247 | .8879231178819663 248 | .8962693533742664 249 | .9046611743911496 250 | .9130986517934192 251 | .9215818562772946 252 | .9301108583754237 253 | .938685728457888 254 | .9473065367331999 255 | .9559733532492861 256 | .9646862478944651 257 | .9734452903984125 258 | .9822505503331171 259 | .9911020971138298 260 | 1; -------------------------------------------------------------------------------- /Styles/material-palettes/scss/_functions.scss: -------------------------------------------------------------------------------- 1 | //// Custom functions to get parity with Less functions 2 | 3 | @function tint($color, $value) { 4 | @return mix(#ffffff, $color, $value); 5 | } 6 | 7 | 8 | /** 9 | * Calculate the luminance for a color. 10 | * See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests 11 | */ 12 | @function luminance($color) { 13 | $red: nth($channel-values, red($color) + 1); 14 | $green: nth($channel-values, green($color) + 1); 15 | $blue: nth($channel-values, blue($color) + 1); 16 | 17 | @return .2126 * $red + .7152 * $green + .0722 * $blue; 18 | } 19 | 20 | /** 21 | * Calculate the contrast ratio between two colors. 22 | * See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests 23 | */ 24 | @function return-contrast-color($back, $front) { 25 | $backLum: luminance($back) + .05; 26 | $foreLum: luminance($front) + .05; 27 | 28 | @return max($backLum, $foreLum) / min($backLum, $foreLum); 29 | } 30 | 31 | /** 32 | * Determine whether to use dark or light text on top of given color. 33 | * Returns black for dark text and white for light text. 34 | */ 35 | 36 | @function contrast($color) { 37 | $lightContrast: return-contrast-color($color, white); 38 | $darkContrast: return-contrast-color($color, black); 39 | 40 | @if ($lightContrast > $darkContrast) { 41 | @return white; 42 | } 43 | @else { 44 | @return black; 45 | } 46 | } -------------------------------------------------------------------------------- /Styles/material-palettes/scss/palettes.scss: -------------------------------------------------------------------------------- 1 | // Material Design Palette Sketch Styles Generation 2 | // Using Puzzle Tokens Sketch plugin and SASS 3 | // version 1.0.1 by Marcelo Paiva (gh: mpaiva) and Juan Alvarado (gh: jalvarado91) 4 | 5 | 6 | // Required SASS modules: 7 | @use "sass:map"; // access values in arrays 8 | @use "sass:color"; // color manipulation 9 | 10 | // Dependencies: 11 | @import "_constants.scss"; 12 | @import "_functions.scss"; 13 | 14 | // BaseColors - from these colors we will generate the lighter and darker tints. 15 | $baseColors: ( 16 | red : #F44336, 17 | pink : #E91E63, 18 | purple : #9C27B0, 19 | deep-purple: #673AB7, 20 | indigo : #3F51B5, 21 | blue : #2196F3, 22 | light-blue : #03A9F4, 23 | cyan : #00BCD4, 24 | teal : #009688, 25 | green : #4CAF50, 26 | light-green: #8BC34A, 27 | lime : #CDDC39, 28 | yellow : #FFEB3B, 29 | amber : #FFC107, 30 | orange : #ff6600, 31 | deep-orange: #FF5722, 32 | brown : #795548, 33 | grey : #9E9E9E, 34 | blue-grey : #607D8B 35 | ); 36 | 37 | // Generate the the light and dark tint colors for each base color 38 | // 39 | @function colorMap($baseColors, $variations, $colorStep: 100) { 40 | $colors: (); 41 | @each $color, $value in $baseColors { 42 | $maxVar: 36; 43 | $mid : $variations / 2; 44 | $dist : $mid - 1; 45 | $step : $maxVar / $dist; 46 | // lighten and darken 47 | @for $i from 1 through $dist { 48 | $percent: $maxVar - ($step * ($i - 1)); 49 | $darken : ($variations - $i) * $colorStep; 50 | $lighten: $i * $colorStep; 51 | $colors : map-merge($colors, (#{$color}-#{$lighten}: lighten($value, $percent), #{$color}-#{$darken}: darken($value, $percent))); 52 | } 53 | // middle eg 500 54 | $colors: map-merge($colors, (#{$color}-050: lighten($value, 38.7))); 55 | $colors: map-merge($colors, (#{$color}-#{$variations/2*$colorStep}: $value)); 56 | } 57 | @return $colors; 58 | } 59 | 60 | // Let's generate some palettes and styles. 61 | 62 | // Create a folder to hold all Palettes. 63 | 64 | .palettes { 65 | @each $baseColor, $baseColorValue in $baseColors { 66 | $bColor: ( 67 | $baseColor: $baseColorValue 68 | ); 69 | 70 | // Create a sub-folder with the base color names 71 | 72 | .#{"" + $baseColor} { 73 | $paletteNumber : 10; // How many palettes you want for each base color? 74 | $paletteIncrements: 100; // Incremental for pallete names e.g.: blue-100, blue-200 75 | @each $color, $value in colorMap(($bColor), $paletteNumber, $paletteIncrements) { 76 | .#{$color} { 77 | background-color: $value; 78 | } 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /appcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Puzzle Tokens 5 | https://github.com/ingrammicro/puzzle-token/raw/master/appcast.xml 6 | Apply tokens to Sketch layers and styles 7 | en 8 | 9 | Version 8.20.9 10 | 21 Sep 2022 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.3.0.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.3.0.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.3.0.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.3.0.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.3.0.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.3.0.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.3.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.3.1.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.3.1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.3.1.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.3.1.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.3.1.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.3.1.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.3.1.3.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.4.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.4.1.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.4.1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.4.1.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.4.1.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.4.1.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.5.0.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.5.0.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.5.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.5.1.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.5.1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.5.1.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.5.2.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.5.2.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.5.3.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.5.3.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.5.3.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.5.3.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.5.3.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.5.3.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.0.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.0.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.0.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.0.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.1.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.10.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.10.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.11.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.11.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.12.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.12.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.13.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.13.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.14.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.14.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.2.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.2.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.2.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.2.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.3.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.3.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.5.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.5.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.5.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.5.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.6.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.6.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.7.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.7.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.8.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.8.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.6.9.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.6.9.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.7.0.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.7.0.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.0.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.0.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.1.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.1.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.1.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.1.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.10.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.10.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.11.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.11.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.12.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.12.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.12.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.12.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.13.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.13.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.14.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.14.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.14.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.14.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.14.4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.14.4.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.15.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.15.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.16.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.16.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.16.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.16.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.16.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.16.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.16.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.16.3.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.16.4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.16.4.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.17.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.17.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.17.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.17.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.17.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.17.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.17.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.17.3.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.17.4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.17.4.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.17.5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.17.5.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.18.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.18.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.18.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.18.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.18.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.18.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.19.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.19.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.19.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.19.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.19.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.19.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.19.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.19.3.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.19.4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.19.4.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.19.5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.19.5.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.19.6.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.19.6.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.19.7.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.19.7.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.2.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.2.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.20.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.20.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.3.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.3.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.3.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.3.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.3.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.3.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.3.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.3.3.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.3.4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.3.4.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.3.5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.3.5.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.4.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.4.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.4.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.4.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.5.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.5.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.5.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.5.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.6.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.6.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.7.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.7.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.7.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.7.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.7.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.7.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.7.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.7.3.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.7.4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.7.4.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.8.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.8.0.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.8.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.8.1.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.8.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.8.2.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.8.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.8.3.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.8.4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.8.4.zip -------------------------------------------------------------------------------- /archives/PuzzleTokens.sketchplugin.8.9.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ingrammicro/puzzle-tokens/db3d329a1eacf194105c9876d8955b0a0de4a5e9/archives/PuzzleTokens.sketchplugin.8.9.0.zip --------------------------------------------------------------------------------