Skip to content

Commit 86538b8

Browse files
adding style changes and collapsible library
1 parent 42c52b0 commit 86538b8

8 files changed

Lines changed: 496 additions & 63 deletions

File tree

.DS_Store

6 KB
Binary file not shown.

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TOKEN = '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'

code/chart.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,45 @@
22
const ctx = document.getElementById('chart').getContext('2d')
33

44
//"Draw" the chart here 👇
5+
const drawChart = (numberOfFinishedProjects) => {
6+
config = {
7+
type: 'pie',
8+
data: {
9+
labels: ['Finished Projects', 'Left Projects'],
10+
datasets: [{
11+
label: 'Technigo Projects',
12+
data: [numberOfFinishedProjects, 20 - numberOfFinishedProjects],
13+
backgroundColor: [
14+
'rgba(255, 99, 132, 1)',
15+
'rgba(54, 162, 235, 1)',
16+
],
17+
borderColor: [
18+
'rgba(255, 99, 132, 1)',
19+
'rgba(54, 162, 235, 1)',
20+
],
21+
borderWidth: 1
22+
}]
23+
},
24+
options: {
25+
plugins: {
26+
title: {
27+
display: true,
28+
text: "Comparison Technigo Project left-projects built",
29+
position: 'top',
30+
padding: {
31+
top: 10,
32+
bottom: 20
33+
}
34+
}
35+
}
36+
37+
}
38+
39+
}
40+
const myChart = new Chart(ctx, config);
41+
}
42+
43+
44+
45+
46+

code/collapsible.js

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
/**
2+
* Collapsible - A plug and play plugin for expanding and
3+
* collapsing elements (i.e. accordion) on a website.
4+
*
5+
* @author Murtada al Mousawy (https://murtada.nl)
6+
*/
7+
(function() {
8+
'use strict';
9+
10+
/**
11+
* Creates an instance of Collapsible.
12+
*
13+
* @constructor
14+
* @param {Object} options
15+
* @param {(HTMLElement|NodeList)} options.node The HTML elements that will be manipulated.
16+
* @param {HTMLElement} [options.eventNode] The HTML element on which the eventListener will be attached.
17+
* @param {Boolean} [options.isCollapsed] Assign the state of the node element.
18+
* @param {Boolean} [options.observe] Assign a MutationObserver to observe child DOM changes.
19+
* @param {Function} [options.expandCallback] Assign a callback for the [{@link Collapsible.prototype.expand} event.
20+
* @param {Function} [options.collapseCallback] Assign a callback for the {@link Collapsible.prototype.collapse} event.
21+
* @param {Function} [options.observeCallback] Assign a callback for the {@link Collapsible.prototype.initObserver} event.
22+
*/
23+
var Collapsible = function(options) {
24+
// Initialize HTML nodes
25+
if (NodeList.prototype.isPrototypeOf(options.node)) {
26+
options.node.forEach(function(nodeItem) {
27+
var singleNodeOptions = options;
28+
singleNodeOptions.node = nodeItem;
29+
new Collapsible(singleNodeOptions);
30+
});
31+
return;
32+
} else if (options.node instanceof HTMLElement) {
33+
this.node = options.node;
34+
this.eventNode = (options.eventNode ? this.node.querySelector(options.eventNode) : this.node);
35+
this.isCollapsed = (typeof this.node.dataset.collapsibleCollapsed !== 'undefined'
36+
? true
37+
: null);
38+
39+
if (!this.isCollapsed) {
40+
this.isCollapsed = ((options.isCollapsed
41+
&& typeof options.isCollapsed === 'boolean')
42+
? options.isCollapsed
43+
: false);
44+
}
45+
46+
this.observe = (typeof options.observe === 'boolean' ? options.observe : false);
47+
this.expandCallback = (typeof options.expandCallback === 'function' ? options.expandCallback : null);
48+
this.collapseCallback = (typeof options.collapseCallback === 'function' ? options.collapseCallback : null);
49+
this.observeCallback = (typeof options.observeCallback === 'function' ? options.observeCallback : null);
50+
this.mutationCallback = (typeof options.mutationCallback === 'function' ? options.mutationCallback : null);
51+
52+
this.init();
53+
} else {
54+
console.error(options.node, 'is not a NodeList or an instance of HTMLElement');
55+
}
56+
};
57+
58+
/**
59+
* Initialize the collapsing and expanding events.
60+
*/
61+
Collapsible.prototype.init = function() {
62+
this.updateHeights();
63+
64+
if (this.isCollapsed) {
65+
this.node.style.height = this.collapsedHeight + 'px';
66+
this.node.classList.add('is-collapsed');
67+
} else {
68+
this.node.classList.add('is-expanded');
69+
}
70+
71+
this.eventNode.addEventListener('click', function() {
72+
this.toggleCollapse();
73+
}.bind(this));
74+
75+
window.addEventListener('resize', this.updateHeights.bind(this, null));
76+
77+
// Observe children of the node
78+
if (this.observe) {
79+
this.initObserver();
80+
}
81+
82+
// Attach the prototype instance to the node
83+
this.node.collapsible = this;
84+
};
85+
86+
/**
87+
* Update the collapsed and expanded heights on page resize.
88+
*
89+
* @param {int} [heightDifference] Height value to add or subtract from the parent.
90+
*/
91+
Collapsible.prototype.updateHeights = function(heightDifference) {
92+
heightDifference = heightDifference || 0;
93+
94+
// Calculate the collapsed height
95+
this.collapsedHeight = Collapsible.parseNumber(
96+
window.getComputedStyle(this.eventNode)['height']
97+
);
98+
99+
// Calculate the expanded height
100+
this.node.style.height = 'auto';
101+
102+
this.expandedHeight = Collapsible.parseNumber(
103+
window.getComputedStyle(this.node)['height']
104+
);
105+
106+
// Add or subtract the childNode's height difference
107+
this.expandedHeight += heightDifference;
108+
this.expandedHeight = Math.max(this.expandedHeight, this.collapsedHeight);
109+
110+
// Reset height to what it was before
111+
if (this.isCollapsed) {
112+
this.node.style.height = this.collapsedHeight + 'px';
113+
}
114+
115+
this.updateParentNode(this.expandedHeight - this.collapsedHeight);
116+
};
117+
118+
/**
119+
* Toggle the node state and calls the appropriate function.
120+
*/
121+
Collapsible.prototype.toggleCollapse = function() {
122+
if (this.isCollapsed) {
123+
this.expand();
124+
} else {
125+
this.collapse();
126+
}
127+
};
128+
129+
/**
130+
* Expand the node.
131+
*/
132+
Collapsible.prototype.expand = function() {
133+
this.updateHeights();
134+
135+
void this.node.offsetWidth;
136+
137+
this.node.style.height = 'auto';
138+
this.node.style.height = this.expandedHeight + 'px';
139+
this.node.classList.remove('is-collapsed');
140+
this.node.classList.add('is-expanded');
141+
142+
this.isCollapsed = false;
143+
144+
// Create a custom event
145+
var expandEvent = new CustomEvent('toggle', {
146+
bubbles: true,
147+
detail: {
148+
action: 'expand',
149+
origin: this.eventNode
150+
}
151+
});
152+
153+
this.node.dispatchEvent(expandEvent);
154+
155+
// Run callback if it exists
156+
if (this.expandCallback) {
157+
this.expandCallback.bind(this, expandEvent)();
158+
}
159+
160+
this.updateParentNode(this.expandedHeight - this.collapsedHeight);
161+
};
162+
163+
/**
164+
* Collapse the node.
165+
*/
166+
Collapsible.prototype.collapse = function() {
167+
this.node.style.height = window.getComputedStyle(this.node)['height'];
168+
169+
void this.node.offsetWidth;
170+
171+
this.node.style.height = this.collapsedHeight + 'px';
172+
this.node.classList.remove('is-expanded');
173+
this.node.classList.add('is-collapsed');
174+
175+
this.isCollapsed = true;
176+
177+
// Create a custom event
178+
var collapseEvent = new CustomEvent('toggle', {
179+
bubbles: true,
180+
detail: {
181+
action: 'collapse',
182+
origin: this.eventNode
183+
}
184+
});
185+
186+
this.node.dispatchEvent(collapseEvent);
187+
188+
// Run callback if it exists
189+
if (this.collapseCallback) {
190+
this.collapseCallback.bind(this, collapseEvent)();
191+
}
192+
193+
this.updateParentNode(-(this.expandedHeight - this.collapsedHeight));
194+
};
195+
196+
/**
197+
* Update parent heights if collapsible.
198+
*
199+
* @see {@link Collapsible.prototype.updateHeights}
200+
*/
201+
Collapsible.prototype.updateParentNode = function(heightDifference) {
202+
if (this.node.parentNode && this.node.parentNode.collapsible) {
203+
this.node.parentNode.collapsible.updateHeights(heightDifference);
204+
}
205+
};
206+
207+
/**
208+
* Observe the direct children list of the node.
209+
* Will adjust the expanded height automatically if necessary.
210+
*/
211+
Collapsible.prototype.initObserver = function() {
212+
this.mutationObserver = new window.MutationObserver(function(mutationsList) {
213+
var mutatedNode,
214+
mutationAction;
215+
216+
if (mutationsList[0]['addedNodes'].length > 0) {
217+
mutationAction = 'add';
218+
mutatedNode = mutationsList[0]['addedNodes'][0];
219+
} else {
220+
mutationAction = 'remove';
221+
mutatedNode = mutationsList[0]['removedNodes'][0];
222+
}
223+
224+
if (!this.isCollapsed) {
225+
var mutatedNodeStyle = window.getComputedStyle(mutatedNode);
226+
227+
var mutatedNodeHeight =
228+
Collapsible.parseNumber(
229+
mutatedNodeStyle['height']) +
230+
Collapsible.parseNumber(
231+
mutatedNodeStyle['margin-top']) +
232+
Collapsible.parseNumber(
233+
mutatedNodeStyle['margin-bottom']);
234+
235+
this.node.style.height = 'auto';
236+
237+
var currentHeight = Collapsible.parseNumber(
238+
window.getComputedStyle(this.node)['height']
239+
);
240+
241+
if (mutationAction == 'add') {
242+
this.node.style.height = (currentHeight - mutatedNodeHeight) + 'px';
243+
void this.node.offsetWidth;
244+
this.node.style.height = currentHeight + 'px';
245+
} else {
246+
this.node.style.height = this.expandedHeight + 'px';
247+
void this.node.offsetWidth;
248+
this.node.style.height = currentHeight + 'px';
249+
}
250+
}
251+
252+
this.expandedHeight = currentHeight;
253+
254+
// Create a custom event
255+
var mutationEvent = new CustomEvent('mutate', {
256+
bubbles: true,
257+
detail: {
258+
action: mutationAction,
259+
node: mutatedNode
260+
}
261+
});
262+
263+
this.node.dispatchEvent(mutationEvent);
264+
265+
// Run callback if it exists
266+
if (this.mutationCallback) {
267+
this.mutationCallback.bind(this, mutationEvent)();
268+
}
269+
}.bind(this));
270+
271+
this.mutationObserver.observe(this.node, {
272+
childList: true
273+
});
274+
};
275+
276+
// Helper functions
277+
Collapsible.parseNumber = function(numberString) {
278+
return Number.parseInt(numberString.slice(0, -2));
279+
};
280+
281+
// Expose the prototype function to the global scope
282+
window.Collapsible = Collapsible;
283+
})();

code/index.html

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<meta name="viewport" content="width=device-width, initial-scale=1.0">
88
<title>Project GitHub Tracker</title>
99
<link rel="stylesheet" href="./style.css" />
10+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
1011
</head>
1112

1213
<body>
@@ -26,13 +27,25 @@ <h3>User name: <span id="user-name"></span></h3>
2627

2728
<section class="projects-info">
2829

29-
3030
</section>
31+
3132
</main>
3233

3334
<!-- This will be used to draw the chart 👇 -->
34-
<canvas id="chart"></canvas>
35-
35+
<section class="chart">
36+
<canvas id="chart"></canvas>
37+
</section>
38+
39+
<footer class="footer">
40+
<a href="mailto: priscila24n@hotmail.com" target="_blank" alt="email">
41+
<p>Contact us</p>
42+
</a>
43+
<a href="#" target="_blank" alt="email">
44+
<p>GitHub Tracker</p>
45+
</a>
46+
<p>Copyright @2021 | Designed by PAS | Stockholm, Sweden. 2021</p>
47+
</footer>
48+
<script src="./collapsible.js"></script>
3649
<script src="./script.js"></script>
3750
<script src="./chart.js"></script>
3851
</body>

0 commit comments

Comments
 (0)