Skip to content

Commit d6d330e

Browse files
committed
feat: add branding header component
1 parent 90f3f33 commit d6d330e

File tree

5 files changed

+81
-11
lines changed

5 files changed

+81
-11
lines changed

src/components/Header.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const HEADER_LOGO = `
2+
<svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
3+
{/* Leaf */}
4+
<path
5+
d="M16 4C20 4 24 7 26 12C24 18 20 22 16 24C12 22 8 18 6 12C8 7 12 4 16 4Z"
6+
fill="rgb(34, 197, 94)"
7+
className="drop-shadow-sm"
8+
/>
9+
{/* Leaf vein */}
10+
<path
11+
d="M16 6L16 22"
12+
stroke="rgb(21, 128, 61)"
13+
strokeWidth="1"
14+
className="opacity-60"
15+
/>
16+
{/* Small bar chart at bottom */}
17+
<g transform="translate(10, 25)">
18+
<rect x="0" y="2" width="2" height="4" fill="rgb(34, 197, 94)" />
19+
<rect x="3" y="0" width="2" height="6" fill="rgb(234, 179, 8)" />
20+
<rect x="6" y="1" width="2" height="5" fill="rgb(239, 68, 68)" />
21+
<rect x="9" y="3" width="2" height="3" fill="rgb(34, 197, 94)" />
22+
</g>
23+
</svg>
24+
`;
25+
26+
export const createHeader = () => {
27+
const header = document.createElement("header");
28+
header.classList.add("cv-header");
29+
30+
header.innerHTML = HEADER_LOGO;
31+
const logo = header.querySelector("svg");
32+
logo.classList.add("cv-header__logo");
33+
34+
const title = document.createElement("h1");
35+
title.classList.add("cv-header__title");
36+
title.innerText = "Carbon Visualizer";
37+
header.append(title);
38+
39+
return header;
40+
}

src/core/Panel.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ class Panel {
4747

4848
// Load panel-specific JavaScript
4949
await this.loadPanelJS();
50+
51+
// Load universal components
52+
await this.loadHeader();
5053
}
5154

5255
async loadPanelCSS() {
@@ -116,6 +119,20 @@ class Panel {
116119
}
117120
}
118121

122+
async loadHeader() {
123+
try {
124+
// Import component module and insert onto the page
125+
const componentUrl = this.browserAPI.runtime.getURL('src/components/Header.js');
126+
const componentModule = await import(componentUrl);
127+
128+
const header = componentModule.createHeader();
129+
const fallbackHeader = this.container.querySelector('header.cv-header');
130+
fallbackHeader.replaceWith(header);
131+
} catch (error) {
132+
console.error(error);
133+
}
134+
}
135+
119136
async waitForElements() {
120137
// Wait a small amount for DOM to be ready
121138
await new Promise(resolve => setTimeout(resolve, 50));
@@ -140,8 +157,8 @@ class Panel {
140157

141158
getFallbackHTML() {
142159
return `
143-
<header class="cv-panel__header">
144-
<h2 class="cv-panel__title">Carbon Visualizer - ${this.type}</h2>
160+
<header class="cv-header">
161+
<h1 class="cv-header__title">Carbon Visualizer - ${this.type}</h1>
145162
</header>
146163
<main class="cv-panel__content">
147164
<p>Panel content for ${this.type}</p>

src/panels/results/results.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
</head>
77
<body>
88
<div id="cv-panel-content">
9-
<header class="cv-panel__header">
10-
<h1 class="cv-panel__title">Carbon Visualizer</h1>
9+
<header class="cv-header">
10+
<h1 class="cv-header__title">Carbon Visualizer</h1>
1111
</header>
1212

1313
<main class="cv-panel__content">

src/panels/welcome/welcome.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
</head>
77
<body>
88
<div id="cv-panel-content">
9-
<header class="cv-panel__header">
10-
<h1 class="cv-panel__title">Carbon Visualizer</h1>
9+
<header class="cv-header">
10+
<h1 class="cv-header__title">Carbon Visualizer</h1>
1111
</header>
1212

1313
<main class="cv-panel__content">

src/styles/core.css

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
/* neutrals */
2323
--cv-black: hsl(0deg 0% 0%);
2424
--cv-white: hsl(0deg 0% 100%);
25+
--cv-grey: hsl(0deg 0% 50%);
2526
}
2627

2728
.cv-panel {
@@ -43,16 +44,28 @@
4344
}
4445

4546
/* Panel header */
46-
.cv-panel__header {
47-
padding: 1rem 1.5rem 0.5rem;
48-
border-bottom: 1px solid var(--cv-white);
47+
.cv-header {
48+
display: flex;
49+
gap: 1rem;
50+
align-items: center;
51+
padding: 1rem 1.5rem;
52+
/* TODO: The `border-bottom` color is equal to `--cv-color-gray-50` and should be replaced with the variable when implemented */
53+
border-bottom: 1px solid oklch(from oklch(50.0% 0.000 0) 50% calc(0 + (sin(0.6 * pi) * c)) h);
54+
background-color: var(--cv-white);
55+
}
56+
57+
.cv-header__logo {
58+
--header-logo-dimensions: 2rem;
59+
60+
width: var(--header-logo-dimensions);
61+
height: var(--header-logo-dimensions);
4962
}
5063

51-
.cv-panel__title {
64+
.cv-header__title {
5265
margin: 0;
5366
font-size: 1.125rem;
5467
font-weight: 600;
55-
color: var(--cv-white);
68+
color: var(--cv-black);
5669
}
5770

5871
/* Panel content */

0 commit comments

Comments
 (0)