Skip to content
This repository was archived by the owner on Apr 11, 2024. It is now read-only.

Commit 57bfa9b

Browse files
mxmulmarkdalgleish
authored andcommitted
feat(symbols): Add support for nested symbols (#28)
fixes #22
1 parent 4a68378 commit 57bfa9b

File tree

7 files changed

+1602
-17
lines changed

7 files changed

+1602
-17
lines changed

README.md

+14
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ Annotate symbols with `data-sketch-symbol` attributes. Note that forward slashes
4242
</div>
4343
```
4444

45+
Annotate [nested symbols](https://www.sketchapp.com/docs/symbols/nested-symbols) with `data-sketch-symbol-instance` attributes, where the attribute values reference existing symbols defined elsewhere in the document.
46+
47+
```html
48+
<div data-sketch-symbol="Icon/Reply">...</div>
49+
<div data-sketch-symbol="Icon/Retweet">...</div>
50+
<div data-sketch-symbol="Icon/Like">...</div>
51+
52+
<div data-sketch-symbol="IconRow">
53+
<div data-sketch-symbol-instance="Icon/Reply">...</div>
54+
<div data-sketch-symbol-instance="Icon/Retweet">...</div>
55+
<div data-sketch-symbol-instance="Icon/Like">...</div>
56+
</div>
57+
```
58+
4559
Annotate all text styles with `data-sketch-text` attributes.
4660

4761
```html

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
},
3636
"homepage": "https://github.com/seek-oss/html-sketchapp-cli#readme",
3737
"dependencies": {
38-
"@brainly/html-sketchapp": "^1.0.0",
38+
"@brainly/html-sketchapp": "^1.1.0",
3939
"es6-promisify": "^6.0.0",
4040
"find-up": "^2.1.0",
4141
"get-port": "^3.2.0",

script/src/generateAlmostSketch.js

+52-16
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,40 @@
11
import Page from '@brainly/html-sketchapp/html2asketch/page.js';
22
import Document from '@brainly/html-sketchapp/html2asketch/document.js';
33
import Text from '@brainly/html-sketchapp/html2asketch/text.js';
4-
import SymbolMaster from '@brainly/html-sketchapp/html2asketch/symbolMaster.js';
54
import nodeToSketchLayers from '@brainly/html-sketchapp/html2asketch/nodeToSketchLayers.js';
5+
import SymbolMaster from '@brainly/html-sketchapp/html2asketch/symbolMaster.js';
66

7-
const getAllLayers = async item => {
7+
const getAllLayers = async (item, symbolMastersByName = {}) => {
88
const itemAndChildren = [item, ...item.querySelectorAll('*')];
99

10-
const layerPromises = Array.from(itemAndChildren)
11-
.map(node => nodeToSketchLayers(node));
10+
const symbolInstanceChildren = new Set([
11+
...item.querySelectorAll('[data-sketch-symbol-instance] *')
12+
]);
13+
14+
const layerPromises = Array.from(itemAndChildren).map(node => {
15+
if (node.dataset.sketchSymbolInstance) {
16+
const symbolName = node.dataset.sketchSymbolInstance;
17+
18+
if (!(symbolName in symbolMastersByName)) {
19+
throw new Error(`Unknown symbol master: ${symbolName}`);
20+
}
21+
22+
const symbolMaster = symbolMastersByName[symbolName];
23+
24+
const { left: x, top: y, width, height } = node.getBoundingClientRect();
25+
const symbolInstance = symbolMaster.getSymbolInstance({ x, y, width, height });
26+
27+
symbolInstance.setName(symbolName);
28+
29+
return [symbolInstance];
30+
} else if (symbolInstanceChildren.has(node)) {
31+
// Anything nested under data-sketch-symbol-instance shouldn't be rendered,
32+
// otherwise it'll be included in the symbolInstance itself.
33+
return [];
34+
}
35+
36+
return nodeToSketchLayers(node);
37+
});
1238

1339
const layers = await Promise.all(layerPromises);
1440

@@ -56,22 +82,32 @@ export function setupSymbols({ name }) {
5682
}
5783

5884
export async function snapshotSymbols({ suffix = '' }) {
59-
const symbolPromises = Array.from(document.querySelectorAll('[data-sketch-symbol]'))
60-
.map(async item => {
61-
const name = item.dataset.sketchSymbol;
62-
const { left: x, top: y } = item.getBoundingClientRect();
63-
const symbol = new SymbolMaster({ x, y });
85+
const nodes = Array.from(document.querySelectorAll('[data-sketch-symbol]'));
6486

65-
symbol.setName(`${name}${suffix}`);
87+
const symbolMastersByName = nodes.reduce((obj, item) => {
88+
const name = item.dataset.sketchSymbol;
89+
const { left: x, top: y } = item.getBoundingClientRect();
6690

67-
const layers = await getAllLayers(item);
91+
const symbol = new SymbolMaster({ x, y });
92+
symbol.setName(`${name}${suffix}`);
6893

69-
layers
70-
.filter(layer => layer !== null)
71-
.forEach(layer => symbol.addLayer(layer));
94+
obj[name] = symbol;
7295

73-
return symbol;
74-
});
96+
return obj;
97+
}, {});
98+
99+
const symbolPromises = nodes.map(async item => {
100+
const name = item.dataset.sketchSymbol;
101+
const symbol = symbolMastersByName[name];
102+
103+
const layers = await getAllLayers(item, symbolMastersByName);
104+
105+
layers
106+
.filter(layer => layer !== null)
107+
.forEach(layer => symbol.addLayer(layer));
108+
109+
return symbol;
110+
});
75111

76112
const symbols = await Promise.all(symbolPromises);
77113

0 commit comments

Comments
 (0)