├── README.md ├── _config.yml ├── flowComponentAutoLink.coffee └── flowComponentAutoLink.sketchplugin └── Contents └── Sketch ├── createBackBtn.cocoascript ├── createFooter.cocoascript ├── createHeader.cocoascript ├── createLink.cocoascript └── manifest.json /README.md: -------------------------------------------------------------------------------- 1 | ## flowComponentAutoLink 2 | The flowComponentAutoLink module for Framer.js helps you create links, headers and footers for Framer's FlowComponent without leaving Sketch. It consists of a Framer module and a Sketch plugin. The Framer module adds the autoLink() method to your FlowComponents. It will automatically set up links, headers and footers based on your layer names. 3 | 4 | [Download latest version here](https://github.com/awt2542/flowComponentAutoLink/archive/master.zip) 5 | 6 | ![sketchdemo](https://cl.ly/0X0i443b0f44/Screen%20Shot%202016-12-03%20at%2013.36.22.png) 7 | 8 | ## How to set it up 9 | 1. Include the flowComponentAutoLink module to your Framer project 10 | 4. Open Sketch and select the two layers you want to link together (a button layer and page layer) 11 | 5. Create a link using the Sketch plugin and select a transition. Notice how the button layer will change its name 12 | 6. Import your changes to Framer 13 | 7. Call flowComponent.autoLink() after you've defined your FlowComponent and your start screen. 14 | 15 | ### Supported layer names 16 | 17 | * showNext_layerB 18 | * showOverlayTop_layerB 19 | * showOverlayRight_layerB 20 | * showOverlayBottom_layerB 21 | * showOverlayLeft_layerB 22 | * showPrevious 23 | * header 24 | * footer 25 | 26 | Replace layerB with the name of the layer you want to link to. The Sketch plugin will generate these names for you but you can write them yourself, too. 27 | 28 | ## Example project 29 | 30 | ```coffeescript 31 | flowComponentAutoLink = require 'flowComponentAutoLink' 32 | sketch = Framer.Importer.load("imported/project@1x") 33 | flow = new FlowComponent 34 | flow.showNext sketch.pageA 35 | flow.autoLink() 36 | ``` 37 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /flowComponentAutoLink.coffee: -------------------------------------------------------------------------------- 1 | transitions = [ 2 | "showNext" 3 | "showOverlayTop" 4 | "showOverlayRight" 5 | "showOverlayBottom" 6 | "showOverlayLeft" 7 | "showOverlayCenter" 8 | ] 9 | 10 | FlowComponent::autoLink = -> 11 | separator = "_" 12 | layers = Framer.CurrentContext._layers 13 | layers.forEach (l) => 14 | l.name = l._info.originalName if l._info?.originalName 15 | switch l.name 16 | when "showPrevious" then l.onClick => @showPrevious() 17 | when "header" then @header = l 18 | when "footer" then @footer = l 19 | transition = l.name.split(separator)[0] 20 | if _.includes transitions, transition 21 | destination = l.name.replace(transition+separator,'') 22 | l.onClick => 23 | linkedLayer = _.find(layers, (l) -> l.name is destination) 24 | @[transition] linkedLayer 25 | -------------------------------------------------------------------------------- /flowComponentAutoLink.sketchplugin/Contents/Sketch/createBackBtn.cocoascript: -------------------------------------------------------------------------------- 1 | var onRun = function(context) { 2 | for (var i=0; i < context.selection.count(); i++){ 3 | var item = context.selection[i] 4 | item.setName("showPrevious"); 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /flowComponentAutoLink.sketchplugin/Contents/Sketch/createFooter.cocoascript: -------------------------------------------------------------------------------- 1 | var onRun = function(context) { 2 | for (var i=0; i < context.selection.count(); i++){ 3 | var item = context.selection[i] 4 | item.setName("footer"); 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /flowComponentAutoLink.sketchplugin/Contents/Sketch/createHeader.cocoascript: -------------------------------------------------------------------------------- 1 | var onRun = function(context) { 2 | for (var i=0; i < context.selection.count(); i++){ 3 | var item = context.selection[i] 4 | item.setName("header"); 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /flowComponentAutoLink.sketchplugin/Contents/Sketch/createLink.cocoascript: -------------------------------------------------------------------------------- 1 | var onRun = function(context) { 2 | 3 | function createSelect(first,second,selectIndex){ 4 | var options = ['Show Next ⬅️','Show Overlay Bottom ⬆️','Show Overlay Right ⬅️','Show Overlay Top ⬇️','Show Overlay Left ➡️','Show Overlay Center ⏺'] 5 | var keywords = ['showNext','showOverlayBottom','showOverlayRight','showOverlayTop','showOverlayLeft', 'showOverlayCenter'] 6 | var accessory = NSComboBox.alloc().initWithFrame(NSMakeRect(0,0,200,25)) 7 | accessory.addItemsWithObjectValues(options) 8 | accessory.selectItemAtIndex(selectIndex) // pre-select first item 9 | 10 | var button = first 11 | var view = second 12 | 13 | var alert = NSAlert.alloc().init() 14 | alert.setMessageText('Choose a transition') 15 | alert.setInformativeText('"'+button.name()+'" to "'+view.name()+'"') 16 | 17 | alert.addButtonWithTitle('Create link') // 1000 18 | alert.addButtonWithTitle('Cancel') // 1001 19 | alert.addButtonWithTitle('Reverse ↔') // 1002 20 | alert.setAccessoryView(accessory) 21 | 22 | var responseCode = alert.runModal() 23 | var sel = accessory.indexOfSelectedItem() 24 | 25 | if (responseCode == 1000){ 26 | context.document.showMessage("FlowComponentLinks: Renamed 1 layer. Open Framer to import the changes") 27 | button.setName(keywords[sel]+"_"+view.name()); 28 | } else if (responseCode == 1002) { 29 | createSelect(view,button,sel) 30 | } 31 | 32 | } 33 | 34 | function selectArtboard(first){ 35 | var artboards = context.document.currentPage().artboards() 36 | var artboardNames = [] 37 | if (artboards.count() == 0){ 38 | context.document.showMessage("FlowComponentLinks: Add an artboard to your document before trying to create a link") 39 | } 40 | for(var i=0; i < artboards.count(); i++){ 41 | artboardNames.push(artboards[i].name()) 42 | } 43 | 44 | var accessory = NSComboBox.alloc().initWithFrame(NSMakeRect(0,0,200,25)) 45 | accessory.addItemsWithObjectValues(artboardNames) 46 | accessory.selectItemAtIndex(0) // pre-select first item 47 | 48 | var button = first 49 | 50 | var alert = NSAlert.alloc().init() 51 | 52 | alert.setMessageText('Choose an artboard') 53 | alert.setInformativeText('Where should '+button.name()+' link to?') 54 | 55 | alert.addButtonWithTitle('Select Artboard') // 1000 56 | alert.addButtonWithTitle('Cancel') // 1001 57 | alert.setAccessoryView(accessory) 58 | 59 | var responseCode = alert.runModal() 60 | var sel = accessory.indexOfSelectedItem() 61 | 62 | if (responseCode == 1000){ 63 | createSelect(button,artboards[sel],0) 64 | } 65 | 66 | } 67 | 68 | if (context.selection.count() == 2){ 69 | var one = context.selection[0] 70 | var second = context.selection[1] 71 | if (second.class() == "MSArtboardGroup"){ 72 | createSelect(one,second,0) 73 | } else { 74 | createSelect(second,one,0) 75 | } 76 | } else if (context.selection.count() == 1) { 77 | var button = context.selection[0]; 78 | selectArtboard(button); 79 | } else { 80 | context.document.showMessage("FlowComponentLinks: You need to select at least one layer") 81 | } 82 | }; 83 | -------------------------------------------------------------------------------- /flowComponentAutoLink.sketchplugin/Contents/Sketch/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "author" : "Andreas", 3 | "commands" : [ 4 | { 5 | "script" : "createLink.cocoascript", 6 | "handler" : "onRun", 7 | "shortcut" : "", 8 | "name" : "Create a link", 9 | "identifier" : "createLink" 10 | }, 11 | { 12 | "script" : "createBackBtn.cocoascript", 13 | "handler" : "onRun", 14 | "shortcut" : "", 15 | "name" : "Create back button", 16 | "identifier" : "createBackBtn" 17 | }, 18 | { 19 | "script" : "createHeader.cocoascript", 20 | "handler" : "onRun", 21 | "shortcut" : "", 22 | "name" : "Create header", 23 | "identifier" : "createHeader" 24 | }, 25 | { 26 | "script" : "createFooter.cocoascript", 27 | "handler" : "onRun", 28 | "shortcut" : "", 29 | "name" : "Create footer", 30 | "identifier" : "createFooter" 31 | } 32 | ], 33 | "menu" : { 34 | "items" : [ 35 | "createLink", 36 | "createBackBtn", 37 | "createHeader", 38 | "createFooter" 39 | ], 40 | "title" : "flowComponentAutoLink" 41 | }, 42 | "identifier" : "com.sketchapp.flowcomponentautolink", 43 | "version" : "1.0", 44 | "description" : "", 45 | "authorEmail" : "", 46 | "name" : "flowComponentAutoLink" 47 | } --------------------------------------------------------------------------------