diff --git a/.postcssrc b/.postcssrc
index 3f3c53d..01dbf5d 100644
--- a/.postcssrc
+++ b/.postcssrc
@@ -1,5 +1,8 @@
{
"plugins": {
+ "postcss-modules": {
+ generateScopedName: "[name]_[local]_[hash:base64:5]"
+ },
"autoprefixer": {
"grid": true
}
diff --git a/src/index.html b/src/index.html
index ba51871..5c4bc10 100644
--- a/src/index.html
+++ b/src/index.html
@@ -7,31 +7,53 @@
-
+
+
The UAM Times
+
-
-
+
+
We won versus some other team.
-
+
diff --git a/src/index.scss b/src/index.scss
index f44f553..47005f9 100644
--- a/src/index.scss
+++ b/src/index.scss
@@ -3,26 +3,185 @@
padding: 0;
box-sizing: border-box;
}
+$secondary: green;
+
+body {
+ font-family: 'Lato', sans-serif;
+ padding: 2rem 2rem 2rem 2rem;
+
+ #click-catcher {
+ display: none;
+ position: fixed;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 2;
+
+ &.active {
+ display: block;
+ }
+ }
+}
+
+.hover-pointer {
+ &:hover {
+ cursor: pointer;
+ }
+}
+
+nav {
+ $bg-color: white;
+ position: fixed;
+ top: 0;
+ left: 0;
+ transform: translateX(-100%);
+ transition: transform 500ms ease-in-out;
+ background-color: $bg-color;
+ min-height: 100vh;
+ padding: 1rem;
+ z-index: 10;
+
+ ul {
+ overflow-y: auto;
+ li {
+ list-style-type: none;
+ padding: 5px;
+ margin-top: 0.2rem;
+ font-weight: 500;
+ border-radius: 0.5rem;
+ &.active {
+ font-weight: 600;
+ }
+ &:hover {
+ cursor: pointer;
+ background-color: mix($secondary, darken($bg-color, 10%), 10%);
+ }
+ }
+ }
+
+ &.active {
+ transform: translateX(0);
+ }
+}
header#main-header {
display: flex;
- flex-direction: column;
width: 100%;
+ flex-direction: row;
+ align-items: center;
+ border-bottom: 2px solid mix(black, $secondary, 50%);
+ padding-bottom: 1rem;
+ margin-bottom: 1rem;
- #top {
- height: 10rem;
+ $input-width: 10rem;
- #hamburger {
- width: 1.5rem;
- height: 3rem;
+ #date {
+ align-self: end;
+ small {
+ font-style: italic;
+ color: $secondary;
+ }
+ }
- &:after {
- content: '';
- display: block;
- width: 100%;
- height: 2px;
- background-color: black;
+ h1 {
+ $font-size: 4rem;
+ font-weight: 100;
+ font-size: $font-size;
+ font-family: 'Bungee Inline', serif;
+ transform: translateX(-#{$input-width/2});
+ margin-left: auto;
+ user-select: none;
+ width: 100%;
+ //text-align: center;
+ height: $font-size;
+ display: flex;
+ //align-items: ;
+justify-content: center;
+ align-items: center;
+
+ span {
+ &:hover {
+ transform: translateY(5px);
+ transition-duration: 0.2s;
}
+ &.empty {
+ width: $font-size/4;
+ }
+ //height: $font-size;
+ display: inline-block;
+ //height: $font-size;
+ transform: translateY(0px);
+ transition: 0.3s transform ease-in-out;
+ }
+ }
+
+ div#search {
+ color: $secondary;
+ display: inline-flex;
+ flex-direction: row;
+
+ &.active {
+ input.hidden-input {
+ transform: scaleX(1) translateX(-2px) !important;
+ transition-duration: 0.2s;
+ border: 2px solid black !important;
+ }
+ }
+
+ input.hidden-input {
+ margin-left: 1rem;
+ transform: scaleX(0);
+ transform-origin: left;
+ width: $input-width;
+ height: 1rem;
+ padding: 10px 12px;
+ border-width: 0;
+ transition-property: transform, border-width;
+ transition-duration: 1s;
+ transition-timing-function: ease-in-out;
+ }
+
+ i {
+ margin-left: 1rem;
+ }
+ }
+
+ #hamburger {
+ $gap: 4px;
+ $size: 4px;
+ $width: 2rem;
+
+ width: $width;
+ display: flex;
+ flex-direction: column;
+
+ &:hover {
+ #top {
+ transform: translateX(-3px);
+ }
+
+ #bottom {
+ transform: translateX(3px);
+ }
+ }
+
+
+ & > div {
+ width: 100%;
+ background-color: black;
+ height: $size;
+ border-radius: 3px;
+ }
+
+ #top {
+ transition: transform 1s cubic-bezier(0.2, -2, 0.2, 2);
+ margin-bottom: $gap;
+ }
+
+ #bottom {
+ transition: transform 1s cubic-bezier(0.2, -2, 0.2, 2);
+ margin-top: $gap;
}
}
}
diff --git a/src/index.ts b/src/index.ts
index 7148a9d..40f90ea 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,93 @@
-window.onload = function() {
- console.log("Hello world")
-};
\ No newline at end of file
+let search = {
+ icon: document.querySelector("div#search i"),
+ input: document.querySelector("div#search input") as HTMLInputElement,
+ onInputClick: () => search.active(search.icon.parentElement),
+ isActive: false,
+ active: (elem: HTMLElement) => {
+ search.isActive = !search.isActive;
+ if(search.isActive) {
+ elem.classList.add("active");
+ } else {
+ search.input.value = "";
+ elem.classList.remove("active");
+ }
+ }
+};
+
+search.icon.addEventListener("click", search.onInputClick);
+
+let nav = {
+ clickCatcher: document.querySelector("div#click-catcher"),
+ nav: document.querySelector("body > nav"),
+ hamburger: document.querySelector("#hamburger"),
+ isActive: false,
+ listItems: null as NodeListOf,
+ activeListItem: null as HTMLLIElement,
+ active: () => {
+ nav.isActive = !nav.isActive;
+ if(nav.isActive) {
+ [nav.nav, nav.clickCatcher]
+ .forEach(
+ (x) => x.classList.remove("active"));
+ } else {
+ [nav.nav, nav.clickCatcher]
+ .forEach(
+ (x) => x.classList.add("active"));
+ }
+ },
+ onClickCatcherClick: (e: Event) => {
+ console.log("Click catcher click");
+ e.stopPropagation();
+ nav.active();
+ },
+ hamburgerOnClick: () => {
+ nav.active();
+ console.log("hamburgerOnClick");
+ },
+ navOnClick: () => {
+ nav.active();
+ },
+ setActiveListItem: (elem: HTMLLIElement) => {
+ nav.activeListItem.classList.remove("active");
+ nav.activeListItem = elem;
+ nav.activeListItem.classList.add("active");
+ },
+ listItemClick: (e: Event) => {
+ nav.setActiveListItem(e.target as HTMLLIElement);
+ }
+};
+nav.listItems = nav.nav.querySelectorAll("ul > li");
+nav.listItems.forEach(
+ (x) => x.addEventListener("click", nav.listItemClick)
+);
+
+nav.activeListItem = nav.listItems[0];
+nav.activeListItem.classList.add("active");
+
+nav.hamburger.addEventListener("click", nav.hamburgerOnClick);
+nav.nav.addEventListener("click", nav.navOnClick);
+nav.clickCatcher.addEventListener("click", nav.onClickCatcherClick);
+
+let header = {
+ h1: document.querySelector("header > h1") as HTMLHeadingElement,
+ makeHeaderAnimatable: () => {
+ const text = header.h1.innerText.trim();
+ header.h1.innerHTML = "";
+ for(const letter of text) {
+ const span = document.createElement("span");
+ span.innerText = letter;
+ if(letter === " ") {
+ span.classList.add("empty");
+ }
+ header.h1.appendChild(span);
+ }
+ },
+ date: document.querySelector("header > div#date"),
+ setDate: () => {
+ header.date.innerHTML = `
+ Today is
+ ${new Date().toISOString()}`;
+ }
+};
+header.makeHeaderAnimatable();
+header.setDate();
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..9c34d8b
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["esnext", "dom", "dom.iterable"]
+ }
+}
\ No newline at end of file