Skip to content

Commit 05ec9d4

Browse files
committed
Adds sort to headless CMS and site generator pages
1 parent ef29367 commit 05ec9d4

File tree

5 files changed

+162
-69
lines changed

5 files changed

+162
-69
lines changed

src/js/sort-container.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
class SortContainer extends HTMLElement {
2+
constructor() {
3+
super();
4+
this.attrs = {
5+
select: "data-sort",
6+
children: "data-sort-children",
7+
};
8+
}
9+
10+
connectedCallback() {
11+
this.select = this.querySelector(`[${this.attrs.select}]`);
12+
this.bindEvents();
13+
}
14+
15+
bindEvents() {
16+
this.select.addEventListener("change", e => {
17+
this.sort(e.target.value);
18+
}, false);
19+
}
20+
21+
sort(key) {
22+
let container = this.querySelector(`[${this.attrs.children}]`);
23+
// Thanks https://github.com/component/sort (MIT License)
24+
let arr = [].slice.call(container.children).sort((a, b) => {
25+
let aVal = a.getAttribute(`data-sort-${key}`);
26+
let bVal = b.getAttribute(`data-sort-${key}`);
27+
28+
// numeric sorts
29+
if(key.endsWith("-numeric") || key.endsWith("-numeric-ascending") || key.endsWith("-numeric-descending")) {
30+
aVal = parseFloat(aVal) || 0;
31+
bVal = parseFloat(bVal) || 0;
32+
33+
if(key.endsWith("-numeric-descending")) {
34+
[aVal, bVal] = [bVal, aVal];
35+
}
36+
return aVal - bVal;
37+
}
38+
39+
if(bVal < aVal) {
40+
return 1;
41+
} else if(aVal < bVal) {
42+
return -1;
43+
}
44+
return 0;
45+
});
46+
let frag = document.createDocumentFragment();
47+
for (let i = 0; i < arr.length; i++) {
48+
frag.appendChild(arr[i]);
49+
}
50+
container.appendChild(frag);
51+
}
52+
}
53+
54+
window.customElements.define("sort-container", SortContainer);

src/site/_includes/components/cards.njk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{% macro repo(item, loopIndex, githubData) %}
22
<div id="{{item.id}}" class="generator-card flex flex-col h-full"
3+
data-sort-name="{{ item.data.title | lower }}"
4+
{%- if githubData[item.data.repo].stars !== "" %} data-sort-githubstars-numeric-descending="{{ githubData[item.data.repo].stars }}"{% endif %}
35
{%- if item.data.typeofcms %} data-filter-typeofcms="{{ item.data.typeofcms | lower }}"{% endif %}
46
{%- if item.data.opensource %} data-filter-opensource="{{ item.data.opensource | lower }}"{% endif %}
57
{%- if item.data.templates %} data-filter-template="{{ item.data.templates | join(",") | lower }}"{% endif %}

src/site/_includes/layouts/base.njk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,5 +93,6 @@ ogimage: "/img/og/default-og-image.png"
9393
</svg>
9494
<script type="module" src="/js/details-force-state.js"></script>
9595
<script type="module" src="/js/filter-container.js"></script>
96+
<script type="module" src="/js/sort-container.js"></script>
9697
</body>
9798
</html>

src/site/generators.njk

Lines changed: 57 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,46 +13,64 @@ layout: layouts/base.njk
1313
</section>
1414

1515
<section class="cards mt-12">
16-
<filter-container>
17-
<form class="pb-4">
18-
<div class="pb-2">
19-
<strong class="pr-4">Filter</strong>
20-
<span data-filter-results></span>
16+
<sort-container>
17+
<filter-container>
18+
<form class="pb-4">
19+
<div class="flex flex-wrap">
20+
<div>
21+
<div class="pb-2">
22+
<strong class="pr-4">Filter</strong>
23+
<span data-filter-results></span>
24+
</div>
25+
<label class="inline-flex pr-4 pb-2">
26+
<span class="sr-only">Language</span>
27+
<select data-filter-bind="language" data-filter-delimiter="," class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
28+
<option selected value="">All Languages</option>
29+
{%- for language in collections.generators | select("data.language") | flatten | unique | sort(false, false) %}
30+
<option value="{{ language | lower }}">{{ language }}</option>
31+
{%- endfor %}
32+
</select>
33+
</label>
34+
<label class="inline-flex pr-4 pb-2">
35+
<span class="sr-only">Template</span>
36+
<select data-filter-bind="template" data-filter-delimiter="," class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
37+
<option selected value="">All Templates</option>
38+
{%- for template in collections.generators | select("data.templates") | flatten | unique | sort(false, false) %}
39+
<option value="{{ template | lower }}">{{ template }}</option>
40+
{%- endfor %}
41+
</select>
42+
</label>
43+
<label class="inline-flex pr-4 pb-2">
44+
<span class="sr-only">License</span>
45+
<select data-filter-bind="license" data-filter-delimiter="," class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
46+
<option selected value="">All Licenses</option>
47+
{%- for license in collections.generators | select("data.license") | flatten | unique | sort(false, false) %}
48+
<option value="{{ license | lower }}">{{ license }}</option>
49+
{%- endfor %}
50+
</select>
51+
</label>
52+
</div>
53+
<div>
54+
<div class="pb-2">
55+
<strong class="pr-4">Sort</strong>
56+
</div>
57+
<label class="inline-flex pr-4 pb-2">
58+
<span class="sr-only">Sort by</span>
59+
<select data-sort class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
60+
<option selected value="githubstars-numeric-descending">GitHub Stars</option>
61+
<option value="name">Name</option>
62+
</select>
63+
</label>
64+
</div>
65+
</div>
66+
</form>
67+
<div class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3" data-sort-children>
68+
{% for item in collections.generators | sortTools(github) %}
69+
{{ cards.repo(item, loop.index0, github) }}
70+
{% endfor %}
2171
</div>
22-
<label class="inline-flex pr-4 pb-2">
23-
<span class="sr-only">Language</span>
24-
<select data-filter-bind="language" data-filter-delimiter="," class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
25-
<option selected value="">All Languages</option>
26-
{%- for language in collections.generators | select("data.language") | flatten | unique | sort(false, false) %}
27-
<option value="{{ language | lower }}">{{ language }}</option>
28-
{%- endfor %}
29-
</select>
30-
</label>
31-
<label class="inline-flex pr-4 pb-2">
32-
<span class="sr-only">Template</span>
33-
<select data-filter-bind="template" data-filter-delimiter="," class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
34-
<option selected value="">All Templates</option>
35-
{%- for template in collections.generators | select("data.templates") | flatten | unique | sort(false, false) %}
36-
<option value="{{ template | lower }}">{{ template }}</option>
37-
{%- endfor %}
38-
</select>
39-
</label>
40-
<label class="inline-flex pr-4 pb-2">
41-
<span class="sr-only">License</span>
42-
<select data-filter-bind="license" data-filter-delimiter="," class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
43-
<option selected value="">All Licenses</option>
44-
{%- for license in collections.generators | select("data.license") | flatten | unique | sort(false, false) %}
45-
<option value="{{ license | lower }}">{{ license }}</option>
46-
{%- endfor %}
47-
</select>
48-
</label>
49-
</form>
50-
<div class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
51-
{% for item in collections.generators | sortTools(github) %}
52-
{{ cards.repo(item, loop.index0, github) }}
53-
{% endfor %}
54-
</div>
55-
</filter-container>
72+
</filter-container>
73+
</sort-container>
5674
</section>
5775

5876
<section class="mt-12">

src/site/headless-cms.njk

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,55 @@ layout: layouts/base.njk
1313
</section>
1414

1515
<section class="cards mt-12">
16-
<filter-container>
17-
<form class="pb-4">
18-
<div class="pb-2">
19-
<strong class="pr-4">Filter</strong>
20-
<span data-filter-results></span>
16+
<sort-container>
17+
<filter-container>
18+
<form class="pb-4">
19+
<div class="flex flex-wrap">
20+
<div>
21+
<div class="pb-2">
22+
<strong class="pr-4">Filter</strong>
23+
<span data-filter-results></span>
24+
</div>
25+
<label class="inline-flex pr-4 pb-2">
26+
<span class="sr-only">CMS Type</span>
27+
<select data-filter-bind="typeofcms" class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
28+
<option selected value="">Any CMS Type</option>
29+
{%- for template in collections.cms | select("data.typeofcms") | unique | sort(false, false) %}
30+
<option value="{{ template | lower }}">{{ template }}</option>
31+
{%- endfor %}
32+
</select>
33+
</label>
34+
<label class="inline-flex pr-4 pb-2">
35+
<span class="sr-only">License</span>
36+
<select data-filter-bind="opensource" class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
37+
<option selected value="">Any License</option>
38+
{%- for opensource in collections.cms | select("data.opensource") | unique | sort(true, false) %}
39+
<option value="{{ opensource | lower }}">{% if opensource == "No" %}Closed{% else %}Open{% endif %} source</option>
40+
{%- endfor %}
41+
</select>
42+
</label>
43+
</div>
44+
<div>
45+
<div class="pb-2">
46+
<strong class="pr-4">Sort</strong>
47+
</div>
48+
<label class="inline-flex pr-4 pb-2">
49+
<span class="sr-only">Sort by</span>
50+
<select data-sort class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
51+
<option selected value="githubstars-numeric-descending">GitHub Stars</option>
52+
<option value="name">Name</option>
53+
</select>
54+
</label>
55+
</div>
56+
</div>
57+
</form>
58+
<div class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3" data-sort-children>
59+
{% for item in collections.cms | sortTools(github) %}
60+
{{ cards.repo(item, loop.index0, github) }}
61+
{% endfor %}
2162
</div>
22-
<label class="inline-flex pr-4 pb-2">
23-
<span class="sr-only">CMS Type</span>
24-
<select data-filter-bind="typeofcms" class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
25-
<option selected value="">Any CMS Type</option>
26-
{%- for template in collections.cms | select("data.typeofcms") | unique | sort(false, false) %}
27-
<option value="{{ template | lower }}">{{ template }}</option>
28-
{%- endfor %}
29-
</select>
30-
</label>
31-
<label class="inline-flex pr-4 pb-2">
32-
<span class="sr-only">License</span>
33-
<select data-filter-bind="opensource" class="text-white py-1 px-2 rounded-default border border-white bg-transparent">
34-
<option selected value="">Any License</option>
35-
{%- for opensource in collections.cms | select("data.opensource") | unique | sort(true, false) %}
36-
<option value="{{ opensource | lower }}">{% if opensource == "No" %}Closed{% else %}Open{% endif %} source</option>
37-
{%- endfor %}
38-
</select>
39-
</label>
40-
</form>
41-
<div class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
42-
{% for item in collections.cms | sortTools(github) %}
43-
{{ cards.repo(item, loop.index0, github) }}
44-
{% endfor %}
45-
</div>
46-
</filter-container>
63+
</filter-container>
64+
</sort-container>
4765
</section>
4866

4967
<section class="mt-12">

0 commit comments

Comments
 (0)