Skip to content

Commit 2ee1090

Browse files
Merge pull request #567 from pattern-lab/features/376-patternorder
Features/376 patternorder
2 parents a18c3bb + c5905ec commit 2ee1090

File tree

8 files changed

+181
-40
lines changed

8 files changed

+181
-40
lines changed

core/lib/object_factory.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ var Pattern = function (relPath, data, patternlab) {
7171
this.lineageR = [];
7272
this.lineageRIndex = [];
7373
this.isPseudoPattern = false;
74+
this.order = Number.MAX_SAFE_INTEGER;
7475
this.engine = patternEngines.getEngineForPattern(this);
7576
};
7677

core/lib/patternlab.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v2.6.2 - 2016
2+
* patternlab-node - v2.7.0 - 2016
33
*
44
* Brian Muenzenmeyer, Geoff Pursell, and the web community.
55
* Licensed under the MIT license.
@@ -146,7 +146,7 @@ var patternlab_engine = function (config) {
146146
Pattern = require('./object_factory').Pattern,
147147
patternlab = {};
148148

149-
patternlab.engines = patternEngines;
149+
patternlab.engines = patternEngines;
150150

151151
var pattern_assembler = new pa(),
152152
pattern_exporter = new pe(),

core/lib/ui_builder.js

Lines changed: 74 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ var ui_builder = function () {
115115
var docPattern = patternlab.subtypePatterns[pattern.patternGroup + (isSubtypePattern ? '-' + pattern.patternSubGroup : '')];
116116
if (docPattern) {
117117
docPattern.isDocPattern = true;
118+
docPattern.order = -Number.MAX_SAFE_INTEGER;
118119
return docPattern;
119120
}
120121

@@ -130,7 +131,8 @@ var ui_builder = function () {
130131
isPattern: false,
131132
engine: null,
132133
flatPatternPath: pattern.flatPatternPath,
133-
isDocPattern: true
134+
isDocPattern: true,
135+
order: -Number.MAX_SAFE_INTEGER
134136
},
135137
patternlab
136138
);
@@ -199,16 +201,16 @@ var ui_builder = function () {
199201
* @param pattern - the pattern to register
200202
*/
201203
function addPatternSubType(patternlab, pattern) {
204+
let newSubType = {
205+
patternSubtypeLC: pattern.patternSubGroup.toLowerCase(),
206+
patternSubtypeUC: pattern.patternSubGroup.charAt(0).toUpperCase() + pattern.patternSubGroup.slice(1),
207+
patternSubtype: pattern.patternSubType,
208+
patternSubtypeDash: pattern.patternSubGroup, //todo verify
209+
patternSubtypeItems: []
210+
};
202211
var patternType = getPatternType(patternlab, pattern);
203-
patternType.patternTypeItems.push(
204-
{
205-
patternSubtypeLC: pattern.patternSubGroup.toLowerCase(),
206-
patternSubtypeUC: pattern.patternSubGroup.charAt(0).toUpperCase() + pattern.patternSubGroup.slice(1),
207-
patternSubtype: pattern.patternSubType,
208-
patternSubtypeDash: pattern.patternSubGroup, //todo verify
209-
patternSubtypeItems: []
210-
}
211-
);
212+
let insertIndex = _.sortedIndexBy(patternType.patternTypeItems, newSubType, 'patternSubtype');
213+
patternType.patternTypeItems.splice(insertIndex, 0, newSubType);
212214
}
213215

214216
/**
@@ -230,7 +232,8 @@ var ui_builder = function () {
230232
patternName: pattern.patternName,
231233
patternState: pattern.patternState,
232234
patternSrcPath: encodeURI(pattern.subdir + '/' + pattern.fileName),
233-
patternPath: patternPath
235+
patternPath: patternPath,
236+
order: pattern.order
234237
};
235238
}
236239

@@ -242,23 +245,25 @@ var ui_builder = function () {
242245
* @param createViewAllVariant - whether or not to create the special view all item
243246
*/
244247
function addPatternSubTypeItem(patternlab, pattern, createSubtypeViewAllVarient) {
245-
var patternSubType = getPatternSubType(patternlab, pattern);
248+
let newSubTypeItem;
249+
246250
if (createSubtypeViewAllVarient) {
247-
patternSubType.patternSubtypeItems.push(
248-
{
249-
patternPartial: 'viewall-' + pattern.patternGroup + '-' + pattern.patternSubGroup,
250-
patternName: 'View All',
251-
patternPath: encodeURI(pattern.flatPatternPath + '/index.html'),
252-
patternType: pattern.patternType,
253-
patternSubtype: pattern.patternSubtype
254-
}
255-
);
251+
newSubTypeItem = {
252+
patternPartial: 'viewall-' + pattern.patternGroup + '-' + pattern.patternSubGroup,
253+
patternName: 'View All',
254+
patternPath: encodeURI(pattern.flatPatternPath + '/index.html'),
255+
patternType: pattern.patternType,
256+
patternSubtype: pattern.patternSubtype,
257+
order: 0
258+
};
256259
}
257260
else {
258-
patternSubType.patternSubtypeItems.push(
259-
createPatternSubTypeItem(pattern)
260-
);
261+
newSubTypeItem = createPatternSubTypeItem(pattern);
261262
}
263+
264+
let patternSubType = getPatternSubType(patternlab, pattern);
265+
patternSubType.patternSubtypeItems.push(newSubTypeItem);
266+
patternSubType.patternSubtypeItems = _.sortBy(patternSubType.patternSubtypeItems, ['order', 'name']);
262267
}
263268

264269
/**
@@ -284,13 +289,15 @@ var ui_builder = function () {
284289
patternType.patternItems.push({
285290
patternPartial: 'viewall-' + pattern.patternGroup + '-all',
286291
patternName: 'View All',
287-
patternPath: encodeURI(pattern.patternType + '/index.html')
292+
patternPath: encodeURI(pattern.patternType + '/index.html'),
293+
order: -Number.MAX_SAFE_INTEGER
288294
});
289295
}
290296

291297
} else {
292298
patternType.patternItems.push(createPatternSubTypeItem(pattern));
293299
}
300+
patternType.patternItems = _.sortBy(patternType.patternItems, ['order', 'name']);
294301
}
295302

296303
// function getPatternItems(patternlab, patternType) {
@@ -302,20 +309,54 @@ var ui_builder = function () {
302309
// }
303310

304311
/**
305-
* Sorts patterns based on name.
306-
* Will be expanded to use explicit order in the near future
312+
* Sorts patterns based on order property found within pattern markdown, falling back on name.
307313
* @param patternsArray - patterns to sort
308314
* @returns sorted patterns
309315
*/
310316
function sortPatterns(patternsArray) {
311317
return patternsArray.sort(function (a, b) {
312318

313-
if (a.name > b.name) {
314-
return 1;
319+
let aOrder = parseInt(a.order, 10);
320+
let bOrder = parseInt(b.order, 10);
321+
322+
if (aOrder === NaN) {
323+
aOrder = Number.MAX_SAFE_INTEGER;
324+
}
325+
326+
if (bOrder === NaN) {
327+
aOrder = Number.MAX_SAFE_INTEGER;
315328
}
316-
if (a.name < b.name) {
329+
330+
//alwasy return a docPattern first
331+
if (a.isDocPattern && !b.isDocPattern) {
317332
return -1;
318333
}
334+
335+
if (!a.isDocPattern && b.isDocPattern) {
336+
return 1;
337+
}
338+
339+
//use old alphabetical ordering if we have nothing else to use
340+
//pattern.order will be Number.MAX_SAFE_INTEGER if never defined by markdown, or markdown parsing fails
341+
if (aOrder === Number.MAX_SAFE_INTEGER && bOrder === Number.MAX_SAFE_INTEGER) {
342+
343+
if (a.name > b.name) {
344+
return 1;
345+
}
346+
if (a.name < b.name) {
347+
return -1;
348+
}
349+
}
350+
351+
//if we get this far, we can sort safely
352+
if (aOrder && bOrder) {
353+
if (aOrder > bOrder) {
354+
return 1;
355+
}
356+
if (aOrder < bOrder) {
357+
return -1;
358+
}
359+
}
319360
return 0;
320361
});
321362
}
@@ -330,7 +371,7 @@ var ui_builder = function () {
330371
patternGroups: {}
331372
};
332373

333-
_.forEach(sortPatterns(patternlab.patterns), function (pattern) {
374+
_.forEach(patternlab.patterns, function (pattern) {
334375

335376
//ignore patterns we can omit from rendering directly
336377
pattern.omitFromStyleguide = isPatternExcluded(pattern, patternlab);
@@ -459,8 +500,8 @@ var ui_builder = function () {
459500
//render the footer needed for the viewall template
460501
var footerHTML = buildFooterHTML(patternlab, 'viewall-' + patternPartial);
461502

462-
//render the viewall template
463-
var subtypePatterns = _.values(patternSubtypes);
503+
//render the viewall template by finding these smallest subtype-grouped patterns
504+
var subtypePatterns = sortPatterns(_.values(patternSubtypes));
464505

465506
//determine if we should write at this time by checking if these are flat patterns or grouped patterns
466507
p = _.find(subtypePatterns, function (pat) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "patternlab-node",
33
"description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).",
4-
"version": "2.6.2",
4+
"version": "2.7.0",
55
"main": "./core/lib/patternlab.js",
66
"dependencies": {
77
"diveSync": "^0.3.0",

test/ui_builder_tests.js

Lines changed: 103 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
var tap = require('tap');
44
var rewire = require("rewire");
5+
var _ = require('lodash');
56
var eol = require('os').EOL;
67
var Pattern = require('../core/lib/object_factory').Pattern;
78
var extend = require('util')._extend;
@@ -120,8 +121,8 @@ tap.test('groupPatterns - creates pattern groups correctly', function (test) {
120121
});
121122

122123
patternlab.patterns.push(
123-
new Pattern('00-test/foo.mustache'),
124124
new Pattern('00-test/bar.mustache'),
125+
new Pattern('00-test/foo.mustache'),
125126
new Pattern('patternType1/patternSubType1/blue.mustache'),
126127
new Pattern('patternType1/patternSubType1/red.mustache'),
127128
new Pattern('patternType1/patternSubType1/yellow.mustache'),
@@ -134,22 +135,120 @@ tap.test('groupPatterns - creates pattern groups correctly', function (test) {
134135
//act
135136
var result = ui.groupPatterns(patternlab);
136137

137-
//assert
138138
test.equals(result.patternGroups.patternType1.patternSubType1.blue.patternPartial, 'patternType1-blue');
139139
test.equals(result.patternGroups.patternType1.patternSubType1.red.patternPartial, 'patternType1-red');
140140
test.equals(result.patternGroups.patternType1.patternSubType1.yellow.patternPartial, 'patternType1-yellow');
141141
test.equals(result.patternGroups.patternType1.patternSubType2.black.patternPartial, 'patternType1-black');
142142
test.equals(result.patternGroups.patternType1.patternSubType2.grey.patternPartial, 'patternType1-grey');
143143
test.equals(result.patternGroups.patternType1.patternSubType2.white.patternPartial, 'patternType1-white');
144144

145-
test.equals(patternlab.patternTypes[0].patternItems[0].patternPartial, 'test-bar');
146-
test.equals(patternlab.patternTypes[0].patternItems[1].patternPartial, 'test-foo');
145+
test.equals(patternlab.patternTypes[0].patternItems[0].patternPartial, 'test-bar', 'first pattern item should be test-bar');
146+
test.equals(patternlab.patternTypes[0].patternItems[1].patternPartial, 'test-foo', 'second pattern item should be test-foo');
147147

148148
//todo: patternlab.patternTypes[0].patternItems[1] looks malformed
149149

150150
test.end();
151151
});
152152

153+
tap.test('groupPatterns - orders patterns when provided from md', function (test) {
154+
//arrange
155+
var patternlab = createFakePatternLab({
156+
patterns: [],
157+
patternGroups: {},
158+
subtypePatterns: {}
159+
});
160+
161+
patternlab.patterns.push(
162+
new Pattern('patternType1/patternSubType1/blue.mustache'),
163+
new Pattern('patternType1/patternSubType1/red.mustache'),
164+
new Pattern('patternType1/patternSubType1/yellow.mustache')
165+
);
166+
ui.resetUIBuilderState(patternlab);
167+
168+
patternlab.patterns[1].order = 1;
169+
170+
//act
171+
ui.groupPatterns(patternlab);
172+
173+
let patternType = _.find(patternlab.patternTypes, ['patternType', 'patternType1']);
174+
let patternSubType = _.find(patternType.patternTypeItems, ['patternSubtype', 'patternSubType1']);
175+
var items = patternSubType.patternSubtypeItems;
176+
177+
//zero is viewall
178+
test.equals(items[1].patternPartial, 'patternType1-red');
179+
test.equals(items[2].patternPartial, 'patternType1-blue');
180+
test.equals(items[3].patternPartial, 'patternType1-yellow');
181+
182+
test.end();
183+
});
184+
185+
tap.test('groupPatterns - retains pattern order from name when order provided from md is malformed', function (test) {
186+
//arrange
187+
var patternlab = createFakePatternLab({
188+
patterns: [],
189+
patternGroups: {},
190+
subtypePatterns: {}
191+
});
192+
193+
patternlab.patterns.push(
194+
new Pattern('patternType1/patternSubType1/blue.mustache'),
195+
new Pattern('patternType1/patternSubType1/red.mustache'),
196+
new Pattern('patternType1/patternSubType1/yellow.mustache')
197+
);
198+
ui.resetUIBuilderState(patternlab);
199+
200+
patternlab.patterns[1].order = 'notanumber!';
201+
202+
//act
203+
ui.groupPatterns(patternlab);
204+
205+
let patternType = _.find(patternlab.patternTypes, ['patternType', 'patternType1']);
206+
let patternSubType = _.find(patternType.patternTypeItems, ['patternSubtype', 'patternSubType1']);
207+
var items = patternSubType.patternSubtypeItems;
208+
209+
//zero is viewall
210+
test.equals(items[1].patternPartial, 'patternType1-blue');
211+
test.equals(items[2].patternPartial, 'patternType1-red');
212+
test.equals(items[3].patternPartial, 'patternType1-yellow');
213+
214+
test.end();
215+
});
216+
217+
tap.test('groupPatterns - sorts viewall subtype pattern to the beginning', function (test) {
218+
//arrange
219+
var patternlab = createFakePatternLab({
220+
patterns: [],
221+
patternGroups: {},
222+
subtypePatterns: {}
223+
});
224+
225+
patternlab.patterns.push(
226+
new Pattern('patternType1/patternSubType1/blue.mustache'),
227+
new Pattern('patternType1/patternSubType1/red.mustache'),
228+
new Pattern('patternType1/patternSubType1/yellow.mustache')
229+
);
230+
ui.resetUIBuilderState(patternlab);
231+
232+
patternlab.patterns[0].order = 1;
233+
patternlab.patterns[1].order = 3;
234+
patternlab.patterns[2].order = 2;
235+
236+
//act
237+
ui.groupPatterns(patternlab);
238+
239+
let patternType = _.find(patternlab.patternTypes, ['patternType', 'patternType1']);
240+
let patternSubType = _.find(patternType.patternTypeItems, ['patternSubtype', 'patternSubType1']);
241+
var items = patternSubType.patternSubtypeItems;
242+
243+
//zero is viewall
244+
test.equals(items[0].patternPartial, 'viewall-patternType1-patternSubType1');
245+
test.equals(items[1].patternPartial, 'patternType1-blue');
246+
test.equals(items[2].patternPartial, 'patternType1-yellow');
247+
test.equals(items[3].patternPartial, 'patternType1-red');
248+
249+
test.end();
250+
});
251+
153252
tap.test('groupPatterns - creates documentation patterns for each type and subtype if not exists', function (test) {
154253
//arrange
155254
var patternlab = createFakePatternLab({

0 commit comments

Comments
 (0)