Skip to content

Commit baf7b94

Browse files
author
Brian Muenzenmeyer
committed
Merge pull request #284 from pattern-lab/203-patternstates-inheritance
Implement pattern state lowest common denominator
2 parents 029ac93 + 9ceb4ed commit baf7b94

File tree

7 files changed

+730
-445
lines changed

7 files changed

+730
-445
lines changed

README.md

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,50 @@ The current selection is as follows.
144144
}
145145
```
146146
##### Pattern States
147-
You can set the state of a pattern by including it in `patternlab-config.json` too. The out of the box styles are in progress (orange), in review (yellow), and complete (green).
148-
Pattern states should be lowercase and use hyphens where spaces are present.
147+
You can set the state of a pattern by including its key in the `patternStates` object in `patternlab-config.json`, along with a style defined inside `patternStateCascade`. The out of the box styles are in progress (orange), in review (yellow), and complete (green).
149148
```
150149
"patternStates": {
151-
"colors" : "inprogress",
152-
"fonts" : "inreview",
153-
"three-up" : "complete"
150+
"atoms-colors" : "complete",
151+
"molecules-primary-nav" : "inreview",
152+
"organisms-header" : "inprogress"
153+
}
154+
```
155+
156+
Note that patterns inherit the lowest common denominator pattern state of their lineage.
157+
Consider:
158+
```
159+
"patternStates": {
160+
"molecules-single-comment" : "complete",
161+
"organisms-sticky-comment" : "inreview",
162+
"templates-article" : "complete"
163+
}
164+
```
165+
In this case, two things are of note:
166+
167+
* templates-article will display inreview since it inherits `organisms-sticky-comment`
168+
* pages-article will not display any pattern state, as it does not define one
169+
170+
The `patternStateCascade` array is important in that the order is hierarchical.
171+
The default is below:
172+
173+
```
174+
"patternStateCascade": ["inprogress", "inreview", "complete"],
175+
```
176+
177+
which correspond to classes defined inside `./core/styleguide/css/styleguide.css`
178+
179+
```
180+
/* pattern states */
181+
.inprogress:before {
182+
color: #FF4136 !important;
183+
}
184+
185+
.inreview:before {
186+
color: #FFCC00 !important;
187+
}
188+
189+
.complete:before {
190+
color: #2ECC40 !important;
154191
}
155192
```
156193

core/lib/lineage_hunter.js

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212

1313
var lineage_hunter = function () {
1414

15+
var pa = require('./pattern_assembler');
16+
1517
function findlineage(pattern, patternlab) {
1618

17-
var pa = require('./pattern_assembler');
1819
var pattern_assembler = new pa();
1920

2021
//find the {{> template-name }} within patterns
@@ -50,7 +51,11 @@ var lineage_hunter = function () {
5051
"lineagePattern": ancestorPattern.key,
5152
"lineagePath": "../../patterns/" + ancestorPattern.patternLink
5253
};
53-
pattern.lineage.push(JSON.stringify(l));
54+
if (ancestorPattern.patternState) {
55+
l.lineageState = ancestorPattern.patternState;
56+
}
57+
58+
pattern.lineage.push(l);
5459

5560
//also, add the lineageR entry if it doesn't exist
5661
if (ancestorPattern.lineageRIndex.indexOf(pattern.key) === -1) {
@@ -61,16 +66,90 @@ var lineage_hunter = function () {
6166
"lineagePattern": pattern.key,
6267
"lineagePath": "../../patterns/" + pattern.patternLink
6368
};
64-
ancestorPattern.lineageR.push(JSON.stringify(lr));
69+
if (pattern.patternState) {
70+
lr.lineageState = pattern.patternState;
71+
}
72+
73+
ancestorPattern.lineageR.push(lr);
6574
}
6675
}
6776
});
6877
}
6978
}
7079

80+
function setPatternState(direction, pattern, targetPattern) {
81+
// if the request came from the past, apply target pattern state to current pattern lineage
82+
if (direction === 'fromPast') {
83+
for (var i = 0; i < pattern.lineageIndex.length; i++) {
84+
if (pattern.lineageIndex[i] === targetPattern.key) {
85+
pattern.lineage[i].lineageState = targetPattern.patternState;
86+
}
87+
}
88+
} else {
89+
//the request came from the future, apply target pattern state to current pattern reverse lineage
90+
for (var i = 0; i < pattern.lineageRIndex.length; i++) {
91+
if (pattern.lineageRIndex[i] === targetPattern.key) {
92+
pattern.lineageR[i].lineageState = targetPattern.patternState;
93+
}
94+
}
95+
}
96+
}
97+
98+
99+
function cascadePatternStates(patternlab) {
100+
101+
var pattern_assembler = new pa();
102+
103+
for (var i = 0; i < patternlab.patterns.length; i++) {
104+
var pattern = patternlab.patterns[i];
105+
106+
//for each pattern with a defined state
107+
if (pattern.patternState) {
108+
109+
if (pattern.lineageIndex && pattern.lineageIndex.length > 0) {
110+
111+
//find all lineage - patterns being consumed by this one
112+
for (var h = 0; h < pattern.lineageIndex.length; h++) {
113+
var lineagePattern = pattern_assembler.get_pattern_by_key(pattern.lineageIndex[h], patternlab);
114+
setPatternState('fromFuture', lineagePattern, pattern);
115+
}
116+
}
117+
118+
if (pattern.lineageRIndex && pattern.lineageRIndex.length > 0) {
119+
120+
//find all reverse lineage - that is, patterns consuming this one
121+
for (var j = 0; j < pattern.lineageRIndex.length; j++) {
122+
123+
var lineageRPattern = pattern_assembler.get_pattern_by_key(pattern.lineageRIndex[j], patternlab);
124+
125+
//only set patternState if pattern.patternState "is less than" the lineageRPattern.patternstate
126+
//this makes patternlab apply the lowest common ancestor denominator
127+
if (patternlab.config.patternStateCascade.indexOf(pattern.patternState)
128+
< patternlab.config.patternStateCascade.indexOf(lineageRPattern.patternState)) {
129+
130+
if (patternlab.config.debug) {
131+
console.log('Found a lower common denominator pattern state: ' + pattern.patternState + ' on ' + pattern.key + '. Setting reverse lineage pattern ' + lineageRPattern.key + ' from ' + lineageRPattern.patternState);
132+
}
133+
134+
lineageRPattern.patternState = pattern.patternState;
135+
136+
//take this opportunity to overwrite the lineageRPattern's lineage state too
137+
setPatternState('fromPast', lineageRPattern, pattern);
138+
} else {
139+
setPatternState('fromPast', pattern, lineageRPattern);
140+
}
141+
}
142+
}
143+
}
144+
}
145+
}
146+
71147
return {
72148
find_lineage: function (pattern, patternlab) {
73149
findlineage(pattern, patternlab);
150+
},
151+
cascade_pattern_states : function (patternlab) {
152+
cascadePatternStates(patternlab);
74153
}
75154
};
76155

core/lib/pattern_assembler.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ var pattern_assembler = function () {
3636
}
3737

3838
function setState(pattern, patternlab) {
39-
if (patternlab.config.patternStates && patternlab.config.patternStates[pattern.patternName]) {
40-
pattern.patternState = patternlab.config.patternStates[pattern.patternName];
39+
if (patternlab.config.patternStates && patternlab.config.patternStates[pattern.key]) {
40+
pattern.patternState = patternlab.config.patternStates[pattern.key];
4141
} else {
4242
pattern.patternState = "";
4343
}

core/lib/patternlab.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ var patternlab_engine = function (config) {
1818
pa = require('./pattern_assembler'),
1919
mh = require('./media_hunter'),
2020
pe = require('./pattern_exporter'),
21+
lh = require('./lineage_hunter'),
2122
he = require('html-entities').AllHtmlEntities,
2223
patternlab = {};
2324

@@ -80,6 +81,7 @@ var patternlab_engine = function (config) {
8081
var pattern_assembler = new pa(),
8182
entity_encoder = new he(),
8283
pattern_exporter = new pe(),
84+
lineage_hunter = new lh(),
8385
patterns_dir = paths.source.patterns;
8486

8587
pattern_assembler.combine_listItems(patternlab);
@@ -154,6 +156,9 @@ var patternlab_engine = function (config) {
154156
//we need to do this before expanding patterns & partials into extendedTemplates, otherwise we could lose the data -> partial reference
155157
pattern_assembler.parse_data_links(patternlab);
156158

159+
//cascade any patternStates
160+
lineage_hunter.cascade_pattern_states(patternlab);
161+
157162
//delete the contents of config.patterns.public before writing
158163
if (deletePatternDir) {
159164
fs.emptyDirSync(paths.public.patterns);
@@ -172,6 +177,19 @@ var patternlab_engine = function (config) {
172177

173178
pattern.header = head;
174179

180+
//json stringify lineage and lineageR
181+
var lineageArray = [];
182+
for (var i = 0; i < pattern.lineage.length; i++) {
183+
lineageArray.push(JSON.stringify(pattern.lineage[i]));
184+
}
185+
pattern.lineage = lineageArray;
186+
187+
var lineageRArray = [];
188+
for (var i = 0; i < pattern.lineageR.length; i++) {
189+
lineageRArray.push(JSON.stringify(pattern.lineageR[i]));
190+
}
191+
pattern.lineageR = lineageRArray;
192+
175193
//render the pattern, but first consolidate any data we may have
176194
var allData = JSON.parse(JSON.stringify(patternlab.data));
177195
allData = pattern_assembler.merge_data(allData, pattern.jsonFileData);

patternlab-config.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,11 @@
4949
"tools-shortcuts": true,
5050
"tools-docs": true
5151
},
52+
"patternStateCascade": ["inprogress", "inreview", "complete"],
5253
"patternStates": {
53-
"homepage-emergency" : "inprogress"
54+
"molecules-single-comment" : "complete",
55+
"organisms-sticky-comment" : "inreview",
56+
"templates-article" : "complete"
5457
},
5558
"patternExportKeys": [],
5659
"patternExportDirectory": "./pattern_exports/",

0 commit comments

Comments
 (0)