@eric-skaftason/web-components 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +339 -0
- package/README.md +2 -0
- package/index.js +0 -0
- package/package.json +19 -0
- package/src/card/card.html +7 -0
- package/src/card/card.js +102 -0
- package/src/card/card_container.html +16 -0
- package/src/card/styles/default.css +12 -0
- package/src/card/styles/flat.css +7 -0
- package/src/card/styles/universal.css +65 -0
- package/src/dropdown/dropdown.js +120 -0
- package/src/dropdown/dropdown_element.html +27 -0
- package/src/dropdown/dropdown_menu.html +58 -0
- package/src/modal/list_add_element/list_add_element.html +44 -0
- package/src/modal/list_add_element/list_add_element.js +53 -0
- package/src/modal/list_element/list_element.html +42 -0
- package/src/modal/list_element/list_element.js +28 -0
- package/src/modal/list_input/list_input.html +28 -0
- package/src/modal/list_input/list_input.js +174 -0
- package/src/modal/menu_body/menu_body.html +38 -0
- package/src/modal/menu_body/menu_body.js +22 -0
- package/src/modal/menu_button/menu_button.html +32 -0
- package/src/modal/menu_button/menu_button.js +15 -0
- package/src/modal/menu_controller/menu_controller.html +22 -0
- package/src/modal/menu_controller/menu_controller.js +38 -0
- package/src/modal/menu_controls/menu_controls.html +19 -0
- package/src/modal/menu_controls/menu_controls.js +15 -0
- package/src/modal/menu_header/menu_header.html +16 -0
- package/src/modal/menu_header/menu_header.js +15 -0
- package/src/modal/menu_text/menu_text.html +18 -0
- package/src/modal/menu_text/menu_text.js +15 -0
- package/src/modal/menu_title/menu_title.html +21 -0
- package/src/modal/menu_title/menu_title.js +15 -0
- package/src/modal/modal_menu/modal_menu.html +39 -0
- package/src/modal/modal_menu/modal_menu.js +42 -0
- package/src/modal/modal_menu.js +15 -0
- package/src/modal-lite/modal_menu.css +122 -0
- package/src/nav_bar/nav_bar.html +178 -0
- package/src/nav_bar/nav_bar.js +50 -0
- package/src/progress_bar/progress_bar.html +21 -0
- package/src/progress_bar/progress_bar.js +58 -0
- package/tests/card.html +17 -0
- package/tests/dropdown.html +0 -0
- package/tests/modal.html +0 -0
- package/tests/nav_bar.html +0 -0
- package/tests/progress_bar.html +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
:host {
|
|
3
|
+
box-sizing: border-box;
|
|
4
|
+
display: flex;
|
|
5
|
+
justify-content: center;
|
|
6
|
+
align-items: center;
|
|
7
|
+
|
|
8
|
+
padding: 0 5px 0 5px;
|
|
9
|
+
min-width: 40px;
|
|
10
|
+
height: 40px;
|
|
11
|
+
|
|
12
|
+
color: #ffffff;
|
|
13
|
+
background-color: #292929;
|
|
14
|
+
cursor: pointer;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
:host(:hover) {
|
|
18
|
+
background-color: #1a1a1a;
|
|
19
|
+
}
|
|
20
|
+
</style>
|
|
21
|
+
|
|
22
|
+
<slot></slot>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Menu controller
|
|
2
|
+
class MenuController extends HTMLElement {
|
|
3
|
+
constructor() {
|
|
4
|
+
super();
|
|
5
|
+
this.attachShadow({ mode: 'open' });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async connectedCallback() {
|
|
9
|
+
const res = await fetch('/components/modal/menu_controller/menu_controller.html');
|
|
10
|
+
const html = await res.text();
|
|
11
|
+
|
|
12
|
+
this.shadowRoot.innerHTML = html;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
customElements.define('menu-controller', MenuController);
|
|
16
|
+
|
|
17
|
+
// Menu controller (close menu button)
|
|
18
|
+
class Controller_CloseMenu extends MenuController {
|
|
19
|
+
constructor() {
|
|
20
|
+
super();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async connectedCallback() {
|
|
24
|
+
await super.connectedCallback();
|
|
25
|
+
|
|
26
|
+
this.shadowRoot.host.textContent = this.shadowRoot.host.innerText || 'x';
|
|
27
|
+
|
|
28
|
+
this.addEventListener('click', () => {
|
|
29
|
+
this.dispatchEvent(new CustomEvent('close-menu', {
|
|
30
|
+
bubbles: true, // allows the event to move up the dom
|
|
31
|
+
composed: true // allows the event to move up the dom, outside any shadow dom layers
|
|
32
|
+
}));
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
customElements.define('close-menu', Controller_CloseMenu);
|
|
37
|
+
|
|
38
|
+
export default { MenuController, Controller_CloseMenu };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
:host {
|
|
3
|
+
padding: 0;
|
|
4
|
+
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
width: 100%;
|
|
7
|
+
|
|
8
|
+
user-select: none;
|
|
9
|
+
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: row-reverse;
|
|
12
|
+
align-items: center;
|
|
13
|
+
|
|
14
|
+
width: 100%;
|
|
15
|
+
background-color: #464646;
|
|
16
|
+
}
|
|
17
|
+
</style>
|
|
18
|
+
|
|
19
|
+
<slot></slot>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Menu controls (container)
|
|
2
|
+
export class MenuControls extends HTMLElement {
|
|
3
|
+
constructor() {
|
|
4
|
+
super();
|
|
5
|
+
this.attachShadow({ mode: 'open' });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async connectedCallback() {
|
|
9
|
+
const res = await fetch('/components/modal/menu_controls/menu_controls.html');
|
|
10
|
+
const html = await res.text();
|
|
11
|
+
|
|
12
|
+
this.shadowRoot.innerHTML = html;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
customElements.define('menu-controls', MenuControls);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Menu header (container)
|
|
2
|
+
export class MenuHeader extends HTMLElement {
|
|
3
|
+
constructor() {
|
|
4
|
+
super();
|
|
5
|
+
this.attachShadow({ mode: 'open' });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async connectedCallback() {
|
|
9
|
+
const res = await fetch('/components/modal/menu_header/menu_header.html');
|
|
10
|
+
const html = await res.text();
|
|
11
|
+
|
|
12
|
+
this.shadowRoot.innerHTML = html;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
customElements.define('menu-header', MenuHeader);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
:host {
|
|
3
|
+
width: 100%;
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
margin-top: 5px;
|
|
6
|
+
margin-bottom: 5px;
|
|
7
|
+
padding: 5px;
|
|
8
|
+
|
|
9
|
+
display: flex;
|
|
10
|
+
justify-content: center;
|
|
11
|
+
align-items: center;
|
|
12
|
+
text-align: center;
|
|
13
|
+
|
|
14
|
+
color: #ffffff;
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
|
|
18
|
+
<slot></slot>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Menu text
|
|
2
|
+
export class MenuText extends HTMLElement {
|
|
3
|
+
constructor() {
|
|
4
|
+
super();
|
|
5
|
+
this.attachShadow({ mode: 'open' });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async connectedCallback() {
|
|
9
|
+
const res = await fetch('/components/modal/menu_text/menu_text.html');
|
|
10
|
+
const html = await res.text();
|
|
11
|
+
|
|
12
|
+
this.shadowRoot.innerHTML = html;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
customElements.define('menu-text', MenuText);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
:host {
|
|
3
|
+
/* Fill the entire space of the menu-title html element (the element's size is defined in menu_header.html as ::slotted(menu-title){...}) */
|
|
4
|
+
width: 100%;
|
|
5
|
+
height: 70px;
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
margin-bottom: 10px;
|
|
8
|
+
|
|
9
|
+
border-bottom: #dfdfdf 1px dashed;
|
|
10
|
+
|
|
11
|
+
display: flex;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
align-items: center;
|
|
14
|
+
|
|
15
|
+
color: #ffffff;
|
|
16
|
+
font-size: 26px;
|
|
17
|
+
font-weight: bold;
|
|
18
|
+
}
|
|
19
|
+
</style>
|
|
20
|
+
|
|
21
|
+
<slot></slot>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Menu title
|
|
2
|
+
export class MenuTitle extends HTMLElement {
|
|
3
|
+
constructor() {
|
|
4
|
+
super();
|
|
5
|
+
this.attachShadow({ mode: 'open' });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async connectedCallback() {
|
|
9
|
+
const res = await fetch('/components/modal/menu_title/menu_title.html');
|
|
10
|
+
const html = await res.text();
|
|
11
|
+
|
|
12
|
+
this.shadowRoot.innerHTML = html;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
customElements.define('menu-title', MenuTitle);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
:host {
|
|
3
|
+
width: 100%;
|
|
4
|
+
height: 100%;
|
|
5
|
+
|
|
6
|
+
position: absolute;
|
|
7
|
+
top: 0;
|
|
8
|
+
left: 0;
|
|
9
|
+
|
|
10
|
+
background-color: rgba(0, 0, 0, 0.8);
|
|
11
|
+
z-index: 10000;
|
|
12
|
+
|
|
13
|
+
display: flex;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
align-items: center;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.menu_container {
|
|
19
|
+
position: relative; /* makes children with absolute position be relative to this element */
|
|
20
|
+
min-width: 250px;
|
|
21
|
+
min-height: 250px;
|
|
22
|
+
width: 80%;
|
|
23
|
+
height: 80%;
|
|
24
|
+
|
|
25
|
+
padding-bottom: 10px;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
box-sizing: border-box;
|
|
28
|
+
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
|
|
32
|
+
background-color: #303030;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
</style>
|
|
36
|
+
|
|
37
|
+
<div class="menu_container">
|
|
38
|
+
<slot></slot>
|
|
39
|
+
</div>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export class ModalMenu extends HTMLElement {
|
|
2
|
+
constructor() {
|
|
3
|
+
super();
|
|
4
|
+
this.attachShadow({ mode: 'open' });
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
setDimensions(width, height) {
|
|
8
|
+
if (width) this.shadowRoot.querySelector('.menu_container').style.width = width;
|
|
9
|
+
if (height) this.shadowRoot.querySelector('.menu_container').style.height = height;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async connectedCallback() {
|
|
13
|
+
const res = await fetch('/components/modal/modal_menu/modal_menu.html');
|
|
14
|
+
const html = await res.text();
|
|
15
|
+
|
|
16
|
+
this.shadowRoot.innerHTML = html;
|
|
17
|
+
|
|
18
|
+
// Set width/height
|
|
19
|
+
this.setDimensions(this.shadowRoot.host.getAttribute('width'), this.shadowRoot.host.getAttribute('height'));
|
|
20
|
+
|
|
21
|
+
// Opacity of BG
|
|
22
|
+
const opacity = this.shadowRoot.host.getAttribute('opacity');
|
|
23
|
+
if (opacity) {
|
|
24
|
+
this.shadowRoot.host.style.backgroundColor = `rgba(0, 0, 0, ${opacity})`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Vertical centring (center for consistency)
|
|
28
|
+
const center = this.shadowRoot.host.getAttribute('center');
|
|
29
|
+
|
|
30
|
+
const menu_body = this.shadowRoot.host.querySelector('menu-body');
|
|
31
|
+
if (menu_body && (center === '' || center)) {
|
|
32
|
+
menu_body.style.display = 'flex';
|
|
33
|
+
menu_body.style.justifyContent = 'center';
|
|
34
|
+
menu_body.style.height = '100%';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.addEventListener('close-menu', (event) => {
|
|
38
|
+
this.remove();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
customElements.define('modal-menu', ModalMenu);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import '/components/modal/modal_menu/modal_menu.js';
|
|
2
|
+
|
|
3
|
+
import '/components/modal/menu_controls/menu_controls.js';
|
|
4
|
+
import '/components/modal/menu_controller/menu_controller.js';
|
|
5
|
+
|
|
6
|
+
import '/components/modal/menu_header/menu_header.js';
|
|
7
|
+
import '/components/modal/menu_body/menu_body.js';
|
|
8
|
+
|
|
9
|
+
import '/components/modal/menu_title/menu_title.js';
|
|
10
|
+
import '/components/modal/menu_text/menu_text.js';
|
|
11
|
+
import '/components/modal/menu_button/menu_button.js';
|
|
12
|
+
|
|
13
|
+
import '/components/modal/list_input/list_input.js';
|
|
14
|
+
import '/components/modal/list_add_element/list_add_element.js';
|
|
15
|
+
import '/components/modal/list_element/list_element.js';
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
.modal * {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.modal {
|
|
6
|
+
width: 100%;
|
|
7
|
+
height: 100%;
|
|
8
|
+
|
|
9
|
+
position: absolute;
|
|
10
|
+
top: 0;
|
|
11
|
+
left: 0;
|
|
12
|
+
|
|
13
|
+
background-color: rgba(0, 0, 0, 0.8);
|
|
14
|
+
z-index: 10000;
|
|
15
|
+
|
|
16
|
+
display: flex;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
align-items: center;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.modal .menu_container {
|
|
22
|
+
position: relative; /* makes children with absolute position be relative to this element */
|
|
23
|
+
min-width: 250px;
|
|
24
|
+
min-height: 250px;
|
|
25
|
+
width: 80%;
|
|
26
|
+
height: 80%;
|
|
27
|
+
|
|
28
|
+
padding-bottom: 10px;
|
|
29
|
+
overflow: hidden;
|
|
30
|
+
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
|
|
34
|
+
background-color: #303030;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.modal .menu_container * {
|
|
38
|
+
width: 100%;
|
|
39
|
+
|
|
40
|
+
padding: 10px;
|
|
41
|
+
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
align-items: center;
|
|
46
|
+
|
|
47
|
+
border-color: #dfdfdf;
|
|
48
|
+
|
|
49
|
+
user-select: none;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.modal .menu_controls {
|
|
53
|
+
/* position: absolute; */
|
|
54
|
+
/* top: 0; */
|
|
55
|
+
/* right: 0; */
|
|
56
|
+
|
|
57
|
+
padding: 0;
|
|
58
|
+
height: 40px;
|
|
59
|
+
background-color: #464646;
|
|
60
|
+
|
|
61
|
+
display: flex;
|
|
62
|
+
flex-direction: row;
|
|
63
|
+
justify-content: flex-end;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: 5px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.modal .menu_controls .menu_control {
|
|
69
|
+
width: 40px;
|
|
70
|
+
height: 100%;
|
|
71
|
+
|
|
72
|
+
color: #ffffff;
|
|
73
|
+
background-color: #292929;
|
|
74
|
+
cursor: pointer;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.modal .menu_controls .menu_control:hover {
|
|
78
|
+
background-color: #1a1a1a;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.modal .menu_header {
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.modal .menu_body {
|
|
86
|
+
overflow-y: auto;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.modal .menu_title {
|
|
90
|
+
height: 70px;
|
|
91
|
+
margin-bottom: 10px;
|
|
92
|
+
|
|
93
|
+
color: #ffffff;
|
|
94
|
+
font-size: 26px;
|
|
95
|
+
font-weight: bold;
|
|
96
|
+
|
|
97
|
+
border-bottom: 1px solid;
|
|
98
|
+
/* text-decoration: underline; */
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.modal .menu_text {
|
|
102
|
+
color: #f5f5f5;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
.modal .menu_button {
|
|
107
|
+
height: 50px;
|
|
108
|
+
color: #f5f5f5;
|
|
109
|
+
|
|
110
|
+
background-color: #292929;
|
|
111
|
+
|
|
112
|
+
cursor: pointer;
|
|
113
|
+
transition: background-color 0.2s ease, transform 0.1s ease;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.modal .menu_button:hover {
|
|
117
|
+
background-color: #1a1a1a;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.modal .menu_button:active {
|
|
121
|
+
transform: scale(0.98);
|
|
122
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.placeholder {
|
|
3
|
+
display: block;
|
|
4
|
+
width: 100%;
|
|
5
|
+
height: 150px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.nav_bar {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
|
|
12
|
+
position: fixed;
|
|
13
|
+
top: 0;
|
|
14
|
+
left: 0;
|
|
15
|
+
background-color: rgba(255, 255, 255, 0.6);
|
|
16
|
+
backdrop-filter: blur(10px);
|
|
17
|
+
z-index: 1000;
|
|
18
|
+
backdrop-filter: blur(5px);
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 150px;
|
|
23
|
+
|
|
24
|
+
border-bottom: 1px solid black;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.row {
|
|
28
|
+
display: flex;
|
|
29
|
+
justify-content: center;
|
|
30
|
+
align-items: center;
|
|
31
|
+
|
|
32
|
+
width: 100%;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Row 1 */
|
|
36
|
+
|
|
37
|
+
#main {
|
|
38
|
+
flex: 2;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#title_container {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
align-items: center;
|
|
46
|
+
flex: 1;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#title {
|
|
50
|
+
font-family: 'Courier New', Courier, monospace;
|
|
51
|
+
font-size: 40px;
|
|
52
|
+
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
margin: 0;
|
|
55
|
+
margin-top: 5px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#title:hover {
|
|
59
|
+
text-decoration: underline;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#subtitle {
|
|
63
|
+
margin: 0;
|
|
64
|
+
|
|
65
|
+
font-family: 'Times New Roman', Times, serif;
|
|
66
|
+
font-style: italic;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
#logo {
|
|
70
|
+
position: absolute;
|
|
71
|
+
top: 0;
|
|
72
|
+
right: 0;
|
|
73
|
+
|
|
74
|
+
height: 100px;
|
|
75
|
+
width: auto;
|
|
76
|
+
aspect-ratio: 1 / 1;
|
|
77
|
+
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
|
|
80
|
+
transition: transform 0.2s;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* Row 2 */
|
|
84
|
+
|
|
85
|
+
::slotted(*) {
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: row;
|
|
88
|
+
height: 100%;
|
|
89
|
+
|
|
90
|
+
justify-content: center;
|
|
91
|
+
align-items: center;
|
|
92
|
+
|
|
93
|
+
flex: 1;
|
|
94
|
+
justify-content: space-between;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.slot_wrapper {
|
|
98
|
+
flex: 1;
|
|
99
|
+
justify-content: space-between;
|
|
100
|
+
|
|
101
|
+
display: flex;
|
|
102
|
+
flex-direction: row;
|
|
103
|
+
width: 100%;
|
|
104
|
+
|
|
105
|
+
border-top: 1px solid #00469c;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
#links * {
|
|
109
|
+
display: flex;
|
|
110
|
+
|
|
111
|
+
height: 100%;
|
|
112
|
+
|
|
113
|
+
justify-content: center;
|
|
114
|
+
align-items: center;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
a:hover {
|
|
118
|
+
background-color: rgba(255, 255, 255, 0.4);
|
|
119
|
+
border-left: 1px solid #00469c;
|
|
120
|
+
border-right: 1px solid #00469c;
|
|
121
|
+
}
|
|
122
|
+
::slotted(a:hover) {
|
|
123
|
+
background-color: rgba(255, 255, 255, 0.4);
|
|
124
|
+
border-left: 1px solid #00469c;
|
|
125
|
+
border-right: 1px solid #00469c;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.dropdown {
|
|
129
|
+
flex: 2;
|
|
130
|
+
outline: none;
|
|
131
|
+
border: none;
|
|
132
|
+
}
|
|
133
|
+
::slotted(.dropdown) {
|
|
134
|
+
flex: 2;
|
|
135
|
+
outline: none;
|
|
136
|
+
border: none;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.quick_link {
|
|
140
|
+
flex: 1;
|
|
141
|
+
}
|
|
142
|
+
::slotted(.quick_link) {
|
|
143
|
+
flex: 1;
|
|
144
|
+
|
|
145
|
+
justify-content: center;
|
|
146
|
+
align-items: center;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
</style>
|
|
150
|
+
<div class="placeholder"></div>
|
|
151
|
+
<div class="nav_bar">
|
|
152
|
+
<div class="row" id="main">
|
|
153
|
+
<div id="title_container">
|
|
154
|
+
<h1 id="title">Redmond Tech Team</h1>
|
|
155
|
+
<p id="subtitle">-</p>
|
|
156
|
+
</div>
|
|
157
|
+
<img id="logo" src="/assets/tech_logo_hd.png" alt="">
|
|
158
|
+
</div>
|
|
159
|
+
<div class="slot_wrapper">
|
|
160
|
+
<slot>
|
|
161
|
+
<nav class="row" id="links">
|
|
162
|
+
<dropdown-menu desc="Programs" openFrom="bottom" class="dropdown">
|
|
163
|
+
|
|
164
|
+
<dropdown-element link="/rfs"><p>RedFS</p></dropdown-element>
|
|
165
|
+
<dropdown-element link="/games"><p>Games</p></dropdown-element>
|
|
166
|
+
|
|
167
|
+
</dropdown-menu>
|
|
168
|
+
<a class="quick_link" href="/rfs">RedFS</a>
|
|
169
|
+
<a class="quick_link" href="/info">Fun</a>
|
|
170
|
+
<a class="quick_link" href="/contrib">Info</a>
|
|
171
|
+
<dropdown-menu desc="Authentication" openFrom="bottom" class="dropdown">
|
|
172
|
+
<dropdown-element link="/login"><p>Login</p></dropdown-element>
|
|
173
|
+
<dropdown-element link="/sign_up"><p>Create Account</p></dropdown-element>
|
|
174
|
+
</dropdown-menu>
|
|
175
|
+
</nav>
|
|
176
|
+
</slot>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
class NavBar extends HTMLElement {
|
|
2
|
+
constructor() {
|
|
3
|
+
super(); // must run super as this constructor is prioritised over the HTMLElement class constructor
|
|
4
|
+
|
|
5
|
+
// Use shadow DOM to prevetns styling conflicts between this element and the parent DOM
|
|
6
|
+
this.attachShadow({ mode: 'open' }); // mode open makes shadowRoot accessible via element.shadowRoot in JS
|
|
7
|
+
|
|
8
|
+
const tempStyle = document.createElement('style');
|
|
9
|
+
// host refers to self
|
|
10
|
+
tempStyle.textContent = `
|
|
11
|
+
:host {
|
|
12
|
+
display: block;
|
|
13
|
+
height: 150px;
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
this.shadowRoot.append(tempStyle);
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// when element is added to DOM
|
|
23
|
+
async connectedCallback() {
|
|
24
|
+
const response = await fetch('/components/nav_bar/nav_bar.html');
|
|
25
|
+
const html = await response.text(); // use text method for HTML
|
|
26
|
+
this.shadowRoot.innerHTML = html;
|
|
27
|
+
|
|
28
|
+
// Once this js file loads, the HTML dropdown elements get updated
|
|
29
|
+
await import("/components/dropdown/dropdown.js");
|
|
30
|
+
|
|
31
|
+
const subtitle_response = await fetch('/api/app_info');
|
|
32
|
+
const subtitle_json = await subtitle_response.json();
|
|
33
|
+
const subtitle = subtitle_json.data;
|
|
34
|
+
this.shadowRoot.getElementById("subtitle").innerText = `${subtitle.package} - ${subtitle["dev-phase"]} v${subtitle.version}`;
|
|
35
|
+
|
|
36
|
+
// Click on main bar to return to home
|
|
37
|
+
this.shadowRoot.addEventListener('click', (event) => {
|
|
38
|
+
const target = event.target;
|
|
39
|
+
|
|
40
|
+
if (target.id === 'title' || target.id === 'logo') document.location = '/';
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// when element is removed from DOM
|
|
45
|
+
disconnectedCallback() {
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
customElements.define('page-nav', NavBar);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.bar_container, .bar {
|
|
3
|
+
border-radius: 5px;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.bar_container {
|
|
7
|
+
width: 400px;
|
|
8
|
+
height: 20px;
|
|
9
|
+
|
|
10
|
+
background-color: rgb(168, 168, 168);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.bar_container .bar {
|
|
14
|
+
height: 100%;
|
|
15
|
+
width: 0%;
|
|
16
|
+
background-color: #1880ff;
|
|
17
|
+
}
|
|
18
|
+
</style>
|
|
19
|
+
<div class="bar_container">
|
|
20
|
+
<div class="bar"></div>
|
|
21
|
+
</div>
|