diff options
| author | Marin Ivanov <[email protected]> | 2024-08-19 21:45:55 +0300 |
|---|---|---|
| committer | Marin Ivanov <[email protected]> | 2024-08-19 22:08:24 +0300 |
| commit | 58ffb8d601910055c3618d41cdbf559925aa6742 (patch) | |
| tree | 7f0b53609da07c3078cb20c7bf74c52d5b760285 | |
| parent | 1a3127c01590422a3899f482b477d132ffbfdccd (diff) | |
v1
| -rw-r--r-- | index.html | 160 | ||||
| -rw-r--r-- | ka.js | 48 | ||||
| -rw-r--r-- | style.css | 117 |
3 files changed, 225 insertions, 100 deletions
@@ -1,100 +1,60 @@ -<div class="container"> - - <header><big>🛠️ WebIF 2.0</big></header> - <main> - <nav> - <label for="showmenu"><big>≡ Меню</big></label> - <input type="checkbox" id="showmenu" /> - - <a class="active" href="#home">Начало</a> - <a href="#network">Мрежа</a> - <a href="#config">Настройки</a> - <a href="#tools">Инструменти</a> - </nav> - - <section> - <h2>Lorem Ipsum</h2> - <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p> - <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> - <h3>Ipsum Lorem</h3> - <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p> - <p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> - <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> - <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p> - </section> - </main> -</div> - - -<style> -body { - margin: 0; - font-family: "Lato", sans-serif; -} - -.container { - width: 900px; - margin: 0 auto; -} - -main, nav, section, nav a, nav label { - box-sizing: border-box; -} - -header, section, footer { - padding: 0.5em; -} - -main { - display: flex; -} - -nav { - display: inline-block; - background-color: #f1f1f1; - width: 250px; -} - -nav a, nav label { - width: 100%; - display: block; - color: #000; - padding: 16px; - text-decoration: none; - user-select: none; -} - -nav label { - font-size: 1.2em; - background-color: #000; - color: #fff; - cursor: pointer; -} - -nav input, nav label { - display: none; -} - -nav a.active { - background-color: #07a2a0; - color: #fff; -} - -nav a:hover:not(.active) { - background-color: #555; - color: white; -} - -@media screen and (max-width: 900px) { - .container, nav {width: 100%} - main { - flex-direction: column; - } - nav label {display: block; } - nav, nav a, nav label {width:100%;} - nav > input:not(:checked) ~ a:not(.active) { - display: none; - } -} -</style> - +<!DOCTYPE html> +<html lang="en"> +<head> + <title>WebIF 2.0</title> + <link rel="stylesheet" href="style.css"> +</head> +<body> + <div class="container"> + <header><big>🛠️ WebIF 2.0</big></header> + <main> + <nav> + <label for="showmenu"><big>≡ Меню</big></label> + <input type="checkbox" id="showmenu" /> + + <a class="active" href="#">Данни</a> + <a href="#/network">Мрежа</a> + <a href="#/config">Настройки</a> + <a href="#/tools">Инструменти</a> + <a href="#/waiting">Пуйчи</a> + </nav> + <section id="app"> + <div class="grid center middle"> + <div> + <div class="loadspin"></div> + <p>Зарежда...</p> + </div> + </div> + </section> + </main> + </div> + <script src="ka.js"></script> + <script> + const waiting = app.children[0]; + const routes = { + "/": () => div( + h2("Lorem Ipsum"), + p("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "), + p("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."), + + h2("Ipsum Lorem"), + p("Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."), + p("Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."), + p("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."), + p("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "), + ), + //"/network": () => div(), + //"/config": () => div(), + "/waiting": () => waiting, + "": () => div( + h1("Несъществуваща страница"), + p("Страницата не е намерена.") + ), + }; + const onchange = () => { + doc.querySelectorAll('nav a').forEach(x => x.setAttribute('class',(location.href===x.href)?"active":"")); + }; + router(app, routes, onchange); + </script> +</body> +</html> @@ -0,0 +1,48 @@ +var doc = document; +var elAttr = (tag, name) => tag.getAttribute(name); +function el$Attr(name, value) { + this.setAttribute(name, value); + return this; +} +function el$OnClick(callback) { + this.onclick = callback; + return this; +} +function tag(name, attrs, ...children) { + const el = doc.createElement(name); + el.attr = elAttr; + el.$attr = el$Attr; + el.$onclick = el$OnClick; + for (const child of children) { + el.appendChild((typeof(child) === 'string') ? doc.createTextNode(child) : child); + } + for (const [attr, value] of Object.entries(attrs||{})) { + el.$attr(attr, value); + } + return el; +} + +const TRIVIAL = "h1,h2,h3,p,a,div,span,select"; +for (let name of TRIVIAL.split(",")) { + window[name] = (...children) => tag(name, null, ...children); +} + +var ahref = (href, ...children) => tag("a", {href}, ...children); +var divcls = (klass, ...children) => tag("div", {class: klass}, ...children); +var img = (src) => tag("img", {src}); +var input = (type) => tag("input", {type}); + +function router(root, routes, onreload) { + function reload() { + let h = doc.location.hash.substr(1) || "/"; + if (!(h in routes)) { + h = ""; + } + root.replaceChildren(routes[h]()); + onreload && onreload(h); + }; + reload(); + window.addEventListener("hashchange", reload); + root.reload = reload; +} + diff --git a/style.css b/style.css new file mode 100644 index 0000000..825dc15 --- /dev/null +++ b/style.css @@ -0,0 +1,117 @@ +body { + margin: 0; + font-family: system-ui; +} + +h1, h2, h3 { + margin: 0.3em 0 0.3em 0; +} + +.container { + width: 900px; + margin: 0 auto; +} + +main, nav, section, nav a, nav label { + box-sizing: border-box; +} + +header { + padding: 1em; +} +section { + padding: 0 0.5em 0 0.5em ; +} + +main { + display: flex; +} +section { + flex: 1; +} +section > div { + height: 100%; +} + +nav { + display: inline-block; + background-color: #f1f1f1; + width: 250px; +} + +nav a, nav label { + width: 100%; + display: block; + color: #000; + padding: 16px; + text-decoration: none; + user-select: none; +} + +nav label { + font-size: 1.2em; + background-color: #000; + color: #fff; + cursor: pointer; +} + +nav input, nav label { + display: none; +} + +nav a.active { + background-color: #07a2a0; + color: #fff; +} + +nav a:hover:not(.active) { + background-color: #555; + color: white; +} + +@media (max-width: 900px) { + .container, nav { + width: 100%; + } + main { + flex-direction: column; + } + nav label { + display: block; + } + nav, nav a, nav label { + width:100%; + } + nav > input:not(:checked) ~ a:not(.active) { + display: none; + } +} + +.grid { + display: grid; +} +.center { + text-align: center; +} +.middle { + align-content: center; +} + +.loadspin { + display: inline-block; + pointer-events: none; + width: 2.5em; + height: 2.5em; + border: 0.4em solid transparent; + border-color: #eee; + border-top-color: #07a2a0; + border-radius: 50%; + animation: loadingspin 1s linear infinite; +} + +@keyframes loadingspin { + 100% { + transform: rotate(360deg) + } +} + |
