Skip to content

Commit e2d18a9

Browse files
Merge pull request #9 from SlyPredator/main
feat: make banner reusable component
2 parents 7c5ea28 + a96c0b5 commit e2d18a9

5 files changed

Lines changed: 186 additions & 9 deletions

File tree

docs/COMPONENT-USAGE.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# How to use the components defined in `/src/components` with examples
2+
3+
This document details the process and reference for the HTML components like `navbar`, `footer` and `banner`. This document will be updated as more components are added to the codebase.
4+
5+
* [Component Documentation](#component-documentation)
6+
* [1. Navigation Bar (`components/navbar.html`)](#1-navigation-bar-componentsnavbarhtml)
7+
* [2. Site Footer (`components/footer.html`)](#2-site-footer-componentsfooterhtml)
8+
* [3. Scroll Banner (`components/banner.html`)](#3-scroll-banner-componentsbannerhtml)
9+
10+
## 1. Navigation Bar (`components/navbar.html`)
11+
12+
### Description
13+
This component provides the main site navigation, including a logo, key navigation links, and a "Sponsor US" button. It uses a `dark` class for styling.
14+
15+
### Structure and Features
16+
* **ID**: `navbar`
17+
* **Class**: `dark`
18+
* **Logo**: Links to the home page (`/`) and uses an `<img>` with an inline style for a grayscale/inverted effect.
19+
* **Main Links**: Includes links for About Us, Projects, Achievements, Activities, Team, and Contact.
20+
* **Sponsor Button**: A call-to-action button (`.btn-sponsor`) that pre-fills the `contact/` form with an example sponsorship message.
21+
22+
### Example Usage
23+
24+
```html
25+
<!DOCTYPE html>
26+
<html lang="en">
27+
<head>
28+
<!-- Previous text under <head>... -->
29+
<link rel="stylesheet" href="/src/styles/navbar.css" /> <!-- Import css file for navbar -->
30+
<!-- Rest of the text under <head> -->
31+
</head>
32+
33+
<body>
34+
<div id="navbar-placeholder"></div>
35+
<main>
36+
<!-- main body code.. -->
37+
</main>
38+
<script src="/src/scripts/mobile-navbar.js"></script> <!-- Navbar for mobile layouts -->
39+
<script src="/src/scripts/componentLoader.js"></script> <!-- Import utility for component loading -->
40+
41+
<script>
42+
loadComponent("navbar-placeholder", "/src/components/navbar.html");
43+
</script>
44+
</body>
45+
</html>
46+
```
47+
48+
49+
## 2. Site Footer (`components/footer.html`)
50+
51+
### Description
52+
A comprehensive footer component containing branding, structured links for club activities and work, social media connections, and a copyright notice.
53+
54+
### Structure and Features
55+
* **ID**: `footer-new`
56+
* **External Dependency**: Requires Font Awesome for social media icons, linked via a CDN: https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css
57+
58+
* **Footer Content**:
59+
* **Brand**: Displays the logo, name ("RIGNITC"), and tagline.
60+
* **Club Links**: Includes About Us, Team, Contact, and Sitemap.
61+
* **Work Links**: Includes Projects, Achievements, Activities, and a "Sponsor Us" link with a pre-filled sponsorship enquiry message.
62+
* **Socials**: Icons linking to Instagram, GitHub, LinkedIn, YouTube, and Blog.
63+
* **Footer Bottom**: Contains the text "No Copyrights Reserved".
64+
65+
### Example Usage
66+
67+
```html
68+
<!DOCTYPE html>
69+
<html lang="en">
70+
<head>
71+
<!-- Previous text under <head>... -->
72+
<link rel="stylesheet" href="/src/styles/footer.css" /> <!-- Import css file for footer -->
73+
<!-- Rest of the text under <head> -->
74+
</head>
75+
76+
<body>
77+
<div id="footer-placeholder"></div>
78+
<main>
79+
<!-- main body code.. -->
80+
</main>
81+
<script src="/src/scripts/componentLoader.js"></script> <!-- Import utility for component loading -->
82+
83+
<script>
84+
loadComponent("footer-placeholder", "/src/components/footer.html");
85+
</script>
86+
</body>
87+
</html>
88+
```
89+
90+
91+
## 3. Scroll Banner (`components/banner.html`)
92+
93+
### Description
94+
This component is designed to display a single, scrolling text link, typically used for site-wide announcements or page-wise notifications. It is built to be dynamically populated using placeholders.
95+
96+
### Customization and Placeholders
97+
The banner uses three primary placeholders that must be replaced by a rendering engine (like a templating language) to display content:
98+
99+
* `{{link}}`: The URL the banner text should link to.
100+
* `{{target}}`: The link's target attribute (e.g., _blank for a new tab).
101+
* Common target attribute values:
102+
* `_blank` - Opens the link in a new tab or window
103+
* `_self` - Opens the link in the same frame (default behavior)
104+
* `_parent` - Opens in the parent frame
105+
* `_top` - Opens in the full body of the window
106+
* `framename` - Opens in a named iframe
107+
* `{{text}}`: The actual text content that will scroll within the banner.
108+
109+
### Example Usage
110+
111+
```html
112+
<!DOCTYPE html>
113+
<html lang="en">
114+
<head>
115+
<!-- Previous text under <head>... -->
116+
<link rel="stylesheet" href="/src/styles/banner.css" /> <!-- Import css file for banner -->
117+
<!-- Rest of the text under <head> -->
118+
</head>
119+
120+
<body>
121+
<div id="navbar-placeholder"></div>
122+
<div id="banner-placeholder"></div> <!-- Placeholder for banner UNDER NAVBAR! -->
123+
<main>
124+
<!-- main body code.. -->
125+
</main>
126+
<script src="/src/scripts/componentLoader.js"></script> <!-- Import utility for component loading -->
127+
128+
<script>
129+
loadComponent("banner-placeholder", "/src/components/banner.html", {
130+
link: "https://rignitc.com/activities/origo/",
131+
text: "ORIGO Robotics Challenge'25 — View the Challenge Overview and Guidelines <u>here</u>",
132+
target: "_blank"
133+
});
134+
</script>
135+
</body>
136+
</html>
137+
```

src/components/banner.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<div class="banner-wrapper">
22
<div class="scroll-banner">
33
<div class="scroll-text">
4-
<a href="https://rignitc.com/activities/origo/" target="_blank">
5-
ORIGO Robotics Challenge'25 — View the Challenge Overview and Guidelines <u>here</u>
4+
<a href="{{link}}" target="{{target}}">
5+
{{text}}
66
</a>
77
</div>
88
</div>
9-
</div>
9+
</div>

src/pages/hof/index.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,12 @@ <h1>ORIGO Robotics Challenge'25</h1>
5151
<script>
5252
loadComponent("navbar-placeholder", "/src/components/navbar.html");
5353
loadComponent("footer-placeholder", "/src/components/footer.html");
54-
loadComponent("banner-placeholder", "/src/components/banner.html");
54+
loadComponent("banner-placeholder", "/src/components/banner.html", {
55+
link: "https://rignitc.com/activities/origo/",
56+
text: "ORIGO Robotics Challenge'25 — View the Challenge Overview and Guidelines <u>here</u>",
57+
target: "_blank"
58+
});
5559
</script>
5660
<script src="/src/scripts/hof.js"></script>
5761
</body>
58-
</html>
62+
</html>

src/scripts/componentLoader.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
* Handles client-side component fetching for static sites (e.g., python -m http.server).
55
* * @param {string} placeholderId - The ID of the element where the component will be inserted (e.g., 'navbar-placeholder').
66
* @param {string} componentPath - The relative path to the component's HTML file (e.g., '../components/Navbar.html').
7+
* @param {Object} data - Optional data to pass to the component.
78
* @returns {Promise<void>}
89
*/
9-
function loadComponent(placeholderId, componentPath) {
10+
function loadComponent(placeholderId, componentPath, data = null) {
1011
const placeholder = document.getElementById(placeholderId);
1112

1213
if (!placeholder) {
@@ -30,7 +31,24 @@ function loadComponent(placeholderId, componentPath) {
3031
})
3132
.then(html => {
3233
if (html) {
34+
// If data is provided, replace placeholders in the HTML
35+
if (data) {
36+
html = replacePlaceholders(html, data);
37+
}
3338
placeholder.innerHTML = html;
39+
40+
// Add 'loaded' class to scroll-text elements to trigger animation
41+
setTimeout(() => {
42+
const scrollTextElements = placeholder.querySelectorAll('.scroll-text');
43+
scrollTextElements.forEach(element => {
44+
element.classList.add('loaded');
45+
});
46+
}, 50); // Small delay to ensure DOM is updated
47+
48+
// If there's a callback function in data, execute it
49+
if (data && data.onLoad) {
50+
data.onLoad();
51+
}
3452
}
3553
})
3654
.catch(error => {
@@ -42,5 +60,18 @@ function loadComponent(placeholderId, componentPath) {
4260
});
4361
}
4462

63+
/**
64+
* Replace placeholders in HTML template with data
65+
* @param {string} html - HTML template string
66+
* @param {Object} data - Data object with key-value pairs
67+
* @returns {string} Processed HTML
68+
*/
69+
function replacePlaceholders(html, data) {
70+
return html.replace(/\{\{(\w+)\}\}/g, (match, key) => {
71+
return data[key] !== undefined ? data[key] : match;
72+
});
73+
}
74+
4575
// Optionally, expose the function globally so it can be called from HTML
46-
window.loadComponent = loadComponent;
76+
window.loadComponent = loadComponent;
77+
window.replacePlaceholders = replacePlaceholders;

src/styles/banner.css

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,16 @@
2323
.scroll-text {
2424
display: inline-block;
2525
padding-left: 100%;
26-
animation: scroll-left 25s linear infinite;
26+
/* Remove animation from initial state */
27+
animation: none;
2728
font-size: 16px;
2829
}
2930

31+
.scroll-text.loaded {
32+
animation: scroll-left 25s linear infinite;
33+
}
34+
3035
@keyframes scroll-left {
3136
0% { transform: translateX(0); }
3237
100% { transform: translateX(-100%); }
33-
}
38+
}

0 commit comments

Comments
 (0)