Support auto-indexing libraries that don't have any metadata
- Probably sort them at the bottom
- Possibly make this opt-out using a setting
I wrote a small script that for a given library imports all symbols to a document and creates the metadata for it. If needed I can share it with you in private?
Oh that's wonderful! Any reason to keep it private? Would be a great public resource :)
Haha. because I don't know if it is any good. And it is part of a plugin that I develop which I am not allowed to share. So some variables you would have to guess from where they are.
But here it is:
import { UI, sketchDoc, _, Text } from '../imports';
import { findPageOrCreatePage } from '../styles-overview/createStylesOverview';
import { metaData } from '../..';
export function generateStickersOverview() {
let libraries = require('sketch/dom').getLibraries();
const libraryName = metaData.libraryForStickers;
const library = libraries.find(library => library.name === libraryName);
if (!library) {
UI.message(`⚠️ ${libraryName} not found. Are you sure it is added?`);
}
const symbolReferences = library.getImportableSymbolReferencesForDocument(sketchDoc);
let stickersMetaData = [];
let symbolInstances = [];
let xIndex = 0;
let yIndex = 0;
symbolReferences.forEach((symbolReference, index) => {
const symbolMaster = symbolReference.import();
const instance = symbolMaster.createNewInstance();
instance.frame.y = (index - yIndex) * 100;
instance.frame.x = xIndex;
symbolInstances.push(instance);
const categoryName = getCategoryName(instance.name);
instance.name = `${instance.name} ${categoryName}`;
const componentName = categoryName.split('.')[0].replace(/-/g, '_');
if (!stickersMetaData.find(instance => instance.name === componentName)) {
let metadataObject = {};
metadataObject.name = componentName;
stickersMetaData.push(metadataObject);
}
const stickerNamePlusSubNAme = `${componentName}.${categoryName.split('.')[1]}`;
if (!stickersMetaData.find(instance => instance.name === stickerNamePlusSubNAme)) {
xIndex += 200;
yIndex = index;
instance.frame.y = (index - yIndex) * 100;
instance.frame.x = xIndex;
let metadataObject = {};
metadataObject.name = stickerNamePlusSubNAme;
stickersMetaData.push(metadataObject);
}
});
stickersMetaData = _.orderBy(stickersMetaData, ['name'], ['asc']);
let textLayer = textLayer = new Text({
text: getStickersMetadata(stickersMetaData)
});
const stickersMetaDataPage = findPageOrCreatePage('stickers-metadata');
stickersMetaDataPage.layers = [textLayer];
const importedSymbolsPage = findPageOrCreatePage('imported-symbols');
importedSymbolsPage.layers = symbolInstances;
}
function getStickersMetadata(stickersMetaData) {
const sectionPrefix = '!StickerSection ';
const title = 'title: ';
const hideNames = 'hideNames: true';
// const description = 'description: A description';
let yamlStickersMetadata = '';
stickersMetaData.forEach(stickerMetaData => {
yamlStickersMetadata += `${sectionPrefix}${stickerMetaData.name}\n`;
let sectionTitle = stickerMetaData.name.split('.')[1];
if (sectionTitle) {
sectionTitle = sectionTitle.replace('_', ' ');
} else {
sectionTitle = stickerMetaData.name.replace('@', '').replace('.', ' ').replace('_', ' ');
sectionTitle = upperCasefirst(sectionTitle);
}
yamlStickersMetadata += `${title}${sectionTitle}\n`;
yamlStickersMetadata += `${hideNames}\n`;
});
return yamlStickersMetadata;
}
function upperCasefirst(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function getCategoryName(name) {
name = name.replace(/\d+\./g, '');
name = name.replace(/\s/g, '');
name = name.replace(/-/g, '_');
name = name.split('/');
//TODO: maybe these should be hardcoded somewhere else? Or User input?
const listOfCategoryItems = ['small', 'medium', 'large'];
let newName = '';
name.forEach((namePart, index) => {
if (index === 0) {
newName = `@${name[0]}`;
} else if (index === 1) {
newName += `.${name[index]}`;
} else if (listOfCategoryItems.includes(name[index])) {
newName += `_${name[index]}`;
}
});
return newName;
}
You would probably need to make something like a picker from which a user can pick a library to generate the stickers file from. In my case, it is hardcoded and it is fine like that for me.
I used lodash to sort everything. Could probably be done better but gives a pretty neat result.
I am still working on optimizing the script. How can I share something with you in private? I could probably strip out the sensitive info from the plugin and then share the plugin to you.
Oh feel free to email me privately: roman at nurik dot net
Would this request allow for layers/symbols to be used with Stickers without the need to tag them? If so, this would be amazing. A feature I would definitely use.
Would be great to use it with any library without metadata as @iamhenry suggests.