oscarotero / node-sketch

💎 Javascript library to manipulate sketch files
https://oscarotero.github.io/node-sketch/
MIT License
304 stars 23 forks source link

Swapping styles from different libraries #16

Closed lucaorio closed 5 years ago

lucaorio commented 5 years ago

This is probably loosely related to #4 .

I have two libraries (A, and B), and a Sketch file that currently uses some foreignStyles from A.

What's the most efficient way to swap every foreignStyle used in the Sketch file to point from library A, to B?

The IDs of the styles to match in the two different libraries are exactly the same, if that helps.

Thanks a lot, and keep up the great work! 👋

lucaorio commented 5 years ago

It seems that, assuming the shared styles living in-within the different libraries have the same ID, updating libraryID, and sourceLibraryName on every foreignStyle is enough!

@oscarotero Is this good practice? Or in the future I could encounter some issues?

oscarotero commented 5 years ago

I never had that need but I guess this is the best way to address it.

lucaorio commented 5 years ago

Thanks, Oscar! For whoever is looking to do the same:

lucaorio commented 5 years ago

@oscarotero All good with the layer styles, but I'm having some problems in replacing the text ones!

Let's set aside the shared style for a moment: how to simply apply a style to a text layer? The example below doesn't work, am I missing anything?

for (let page of sketch.pages) {
  const textOne = page.get('text', layer => layer.name === 'textOne');
  const textTwo = page.get('text', layer => layer.name === 'textTwo');

  textTwo.style.replaceWith(textOne.style.clone());
}
oscarotero commented 5 years ago

To replace text and layer styles you could do something like this:

//Get a layer named 'block'
const block = sketch.pages[0].get('shapeGroup', 'block');

//Get the shared style
const sharedStyle = block.style.sharedStyle;

//Get a shared style named 'red'
const redStyle = sketch.layerStyles.find(style => style.name === 'red');

//Assign a different shared style
block.style.sharedStyle = redStyle;

This is because all instances of "style" use the Style class (https://github.com/oscarotero/node-sketch/blob/master/src/Style.js) instead the default Node class.

BUT, I just made some tests and seems like the old way to change or apply a text/layout style does not work any more, so this should be fixed.

Not sure if I have the enough time actually, so if you want to work on this, that would be great. I'm working with this example: https://github.com/oscarotero/node-sketch/blob/feature/replace-styles/demos/replace-styles/index.js

I try to search and replace all sharedStyles but once the file is saved, the file cannot be opened by sketch app.

oscarotero commented 5 years ago

@lucaorio Finally I've released a new version (v0.14.0) fixing this issue.

To replace the shared layer/text style of any element:

//Get the new shared style to apply
const newStyle = sketch.textStyles.find(style => style.name === 'New Style');

//Search the element to apply the new style
const element = sketch.pages[0].get('text');

//Get the style used by this element
const style = element.style;

//Apply the shared style
style.applySharedStyle(newStyle);