diff --git a/src/interface/dashboard.ts b/src/interface/dashboard.ts
index fc4ff58..c01e0d1 100644
--- a/src/interface/dashboard.ts
+++ b/src/interface/dashboard.ts
@@ -1,16 +1,116 @@
import { FarpatchWidget, makeNavView as makeNavItem } from "../interfaces";
+class DashboardItem {
+ id: string;
+ name: string;
+ value: string;
+ constructor(id: string, name: string, value: string) {
+ this.id = id;
+ this.name = name;
+ this.value = value;
+ }
+ render(): HTMLElement {
+ var field: HTMLElement = document.createElement("div");
+ field.classList.add("fieldset-item");
+
+ var navViewIcon = document.createElement("span");
+ navViewIcon.setAttribute("aria-hidden", "true");
+ navViewIcon.classList.add("las");
+ navViewIcon.classList.add("la-3x");
+ navViewIcon.classList.add("la-" + this.id);
+ navViewIcon.classList.add("icon");
+
+ var inputStack: HTMLElement = document.createElement("div");
+ inputStack.classList.add("input-stack");
+
+ var label: HTMLElement = document.createElement("label");
+ label.setAttribute("for", this.id);
+ label.setAttribute("id", this.id);
+ label.setAttribute("aria-hidden", "true");
+ label.innerText = this.name;
+
+ var input: HTMLElement = document.createElement("input");
+ input.setAttribute("name", this.id);
+ input.setAttribute("aria-labelledby", this.id);
+ input.setAttribute("type", "range");
+ input.setAttribute("value", this.value);
+ input.setAttribute("max", "10");
+ input.setAttribute("style", "--track-fill: 30%");
+
+ inputStack.appendChild(label);
+ inputStack.appendChild(input);
+ field.appendChild(navViewIcon);
+ field.appendChild(inputStack);
+
+ return field;
+ }
+}
+
+class DashboardSection {
+ id: string;
+ name: string;
+ items: DashboardItem[];
+ constructor(id: string, name: string, items: DashboardItem[]) {
+ this.id = id;
+ this.name = name;
+ this.items = items;
+ }
+
+ render(): HTMLElement {
+ var root: HTMLElement = document.createElement("section");
+ var header: HTMLElement = document.createElement("header");
+ var h2: HTMLElement = document.createElement("h2");
+ h2.innerText = this.name;
+ header.appendChild(h2);
+ root.appendChild(header);
+
+ var fieldset: HTMLElement = document.createElement("fieldset");
+ for (var i = 0; i < this.items.length; i++) {
+ fieldset.appendChild(this.items[i].render());
+ }
+
+ root.appendChild(fieldset);
+
+ return root;
+ }
+}
+
export class DashboardWidget implements FarpatchWidget {
index: number = 0;
- view: HTMLElement = document.createElement("div");
+ view: HTMLElement = document.createElement("form");
navItem: HTMLElement;
name: string;
icon: string = "home";
title: string = "Dashboard";
+ sections: DashboardSection[];
+
constructor(name: string) {
this.name = name;
this.navItem = makeNavItem(name, this.icon, this.title);
+
+ this.sections = [
+ new DashboardSection("voltages", "Voltages", [
+ new DashboardItem("system-voltage", "System", "3.3V"),
+ new DashboardItem("target-voltage", "Target", "1.8V"),
+ new DashboardItem("usb-voltage", "USB", "5.0V"),
+ new DashboardItem("extra-voltage", "Extra", "3.8V"),
+ ]),
+ new DashboardSection("network", "Network", [
+ new DashboardItem("ip-address", "IP Address", "10.0.0.5"),
+ new DashboardItem("gdb-port", "GDB Port", "2022"),
+ new DashboardItem("uart-port", "UART Port", "2023"),
+ ]),
+ new DashboardSection("target", "Target", [
+ new DashboardItem("detected-devices", "Detected Devices", "STM32F4"),
+ new DashboardItem("flash-size", "Flash Size", "512k"),
+ new DashboardItem("ram-size", "RAM Size", "32k"),
+ ]),
+ new DashboardSection("about", "About", [
+ new DashboardItem("farpatch-version", "Farpatch Version", "5555239293"),
+ new DashboardItem("bmp-version", "Blackmagic Version", "1.10.0"),
+ ]),
+ ];
}
updateIndex(index: number): void {
@@ -18,32 +118,10 @@ export class DashboardWidget implements FarpatchWidget {
}
onInit(): void {
- this.view.innerHTML = `
-
-
-
-
-
-
-
- `;
+ for (var i = 0; i < this.sections.length; i++) {
+ this.view.appendChild(this.sections[i].render());
+ }
+
console.log("Initialized Dashboard Widget");
}
onFocus(element: HTMLElement): void {
diff --git a/static/css/fancy.css b/static/css/fancy.css
new file mode 100644
index 0000000..928b852
--- /dev/null
+++ b/static/css/fancy.css
@@ -0,0 +1,334 @@
+@custom-media --motionOK (prefers-reduced-motion: no-preference);
+
+:root {
+ --surface1: lch(10 0 0);
+ --surface2: lch(15 0 0);
+ --surface3: lch(20 0 0);
+ --surface4: lch(25 0 0);
+
+ --text1: lch(95 0 0);
+ --text2: lch(75 0 0);
+
+ --brand: lch(64 20 237);
+ --brand-bg1: lch(70 64 349);
+ --brand-bg2: lch(60 84 300);
+
+ --brand-bg-gradient: linear-gradient(
+ to bottom,
+ var(--brand-bg1),
+ var(--brand-bg2)
+ );
+
+ --thumb-highlight-color: lch(100 0 0 / 20%);
+
+ --space-xxs: .25rem;
+ --space-xs: .5rem;
+ --space-sm: 1rem;
+ --space-md: 1.5rem;
+ --space-lg: 2rem;
+ --space-xl: 3rem;
+ --space-xxl: 6rem;
+
+ --isLTR: 1;
+ --isRTL: -1;
+
+ &:dir(rtl) {
+ --isLTR: -1;
+ --isRTL: 1;
+ }
+
+ @media (prefers-color-scheme: light) {
+ & {
+ --surface1: lch(90 0 0);
+ --surface2: lch(100 0 0);
+ --surface3: lch(98 0 0);
+ --surface4: lch(85 0 0);
+
+ --text1: lch(20 0 0);
+ --text2: lch(40 0 0);
+
+ --brand: lch(64 40 237);
+ --brand-bg1: lch(50 64 349);
+ --brand-bg2: lch(40 84 300);
+
+ --thumb-highlight-color: lch(0 0 0 / 20%);
+ }
+ }
+}
+
+form {
+ max-width: 89vw;
+ display: grid;
+ gap: var(--space-xl) var(--space-xxl);
+ --repeat: auto-fit;
+ grid-template-columns:
+ repeat(var(--repeat), minmax(min(10ch, 100%), 35ch));
+ align-items: flex-start;
+
+ @media (orientation: landscape) and (width >= 640px) { & {
+ --repeat: 2;
+ }}
+ }
+
+ section {
+ display: grid;
+ gap: var(--space-md);
+ }
+
+ header {
+ display: grid;
+ gap: var(--space-xxs);
+ }
+
+ fieldset {
+ border: 1px solid var(--surface4);
+ background: var(--surface4);
+ padding: 0;
+ margin: 0;
+ display: grid;
+ gap: 1px;
+ border-radius: var(--space-sm);
+ overflow: hidden;
+ transition: box-shadow .3s ease;
+
+ &:focus-within {
+ box-shadow: 0 5px 20px -10px hsl(0 0% 0% / 50%);
+ }
+ }
+
+ input[type="range"] {
+ --track-height: .5ex;
+ --track-fill: 0%;
+ --thumb-size: 3ex;
+ --thumb-offset: -1.25ex;
+ --thumb-highlight-size: 0px;
+
+ display: block;
+ inline-size: 100%;
+ margin: 1ex 0;
+ appearance: none;
+ background: transparent;
+ outline-offset: 5px;
+
+ @media (hover: none) {
+ & {
+ --thumb-size: 30px;
+ --thumb-offset: -14px;
+ }
+ }
+
+ &::-webkit-slider-runnable-track {
+ appearance: none;
+ block-size: var(--track-height);
+ border-radius: 5ex;
+ background:
+ linear-gradient(
+ to right,
+ transparent var(--track-fill),
+ var(--surface1) 0%
+ ),
+ var(--brand-bg-gradient) fixed;
+ }
+
+ &::-moz-range-track {
+ appearance: none;
+ block-size: var(--track-height);
+ border-radius: 5ex;
+ background:
+ linear-gradient(
+ to right,
+ transparent var(--track-fill),
+ var(--surface1) 0%
+ ),
+ var(--brand-bg-gradient) fixed;
+ }
+
+ &::-webkit-slider-thumb {
+ appearance: none;
+ cursor: ew-resize;
+ border: 3px solid var(--surface3);
+ block-size: var(--thumb-size);
+ inline-size: var(--thumb-size);
+ margin-block-start: var(--thumb-offset);
+ border-radius: 50%;
+ background: var(--brand-bg-gradient) fixed;
+ box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);
+
+ @media (--motionOK) {
+ & {
+ transition: box-shadow .1s ease;
+ }
+ }
+
+ @nest .fieldset-item:focus-within & {
+ border-color: var(--surface2);
+ }
+ }
+
+ &::-moz-range-thumb {
+ appearance: none;
+ cursor: ew-resize;
+ border: 3px solid var(--surface3);
+ block-size: var(--thumb-size);
+ inline-size: var(--thumb-size);
+ margin-block-start: var(--thumb-offset);
+ border-radius: 50%;
+ background: var(--brand-bg-gradient) fixed;
+ box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);
+
+ @media (--motionOK) {
+ & {
+ transition: box-shadow .1s ease;
+ }
+ }
+
+ @nest .fieldset-item:focus-within & {
+ border-color: var(--surface2);
+ }
+ }
+
+ &:is(:hover,:active) {
+ --thumb-highlight-size: 10px;
+ }
+ }
+
+ input[type="checkbox"] {
+ inline-size: var(--space-sm);
+ block-size: var(--space-sm);
+ margin: 0;
+ outline-offset: 5px;
+ accent-color: var(--brand);
+ position: relative;
+ transform-style: preserve-3d;
+ cursor: pointer;
+
+ &:hover::before {
+ --thumb-scale: 1;
+ }
+
+ @media (hover: none) {
+ & {
+ inline-size: var(--space-md);
+ block-size: var(--space-md);
+ }
+ }
+
+ &::before {
+ --thumb-scale: .01;
+ --thumb-highlight-size: var(--space-xl);
+
+ content: "";
+ inline-size: var(--thumb-highlight-size);
+ block-size: var(--thumb-highlight-size);
+ clip-path: circle(50%);
+ position: absolute;
+ inset-block-start: 50%;
+ inset-inline-start: 50%;
+ background: var(--thumb-highlight-color);
+ transform-origin: center center;
+ transform:
+ translateX(calc(var(--isRTL) * 50%))
+ translateY(-50%)
+ translateZ(-1px)
+ scale(var(--thumb-scale))
+ ;
+ will-change: transform;
+
+ @media (--motionOK) {
+ & {
+ transition: transform .2s ease;
+ }
+ }
+ }
+ }
+
+ .fieldset-item {
+ background: var(--surface3);
+ transition: background .2s ease;
+
+ display: grid;
+ grid-template-columns: var(--space-lg) 1fr;
+ gap: var(--space-md);
+
+ padding-block: var(--space-sm);
+ padding-inline: var(--space-md);
+
+ @media (width >= 540px) {
+ grid-template-columns: var(--space-xxl) 1fr;
+ gap: var(--space-xs);
+ padding-block: var(--space-md);
+ padding-inline: 0 var(--space-xl);
+ }
+
+ &:focus-within {
+ background: var(--surface2);
+
+ & svg {
+ fill: white;
+ }
+
+ & picture {
+ clip-path: circle(50%);
+ background: var(--brand-bg-gradient) fixed;
+ }
+ }
+
+ & > :is(.input-stack, label) {
+ display: grid;
+ gap: var(--space-xs);
+ }
+
+ & > .input-stack > label {
+ display: contents;
+ }
+
+ & > picture {
+ block-size: var(--space-xl);
+ inline-size: var(--space-xl);
+ clip-path: circle(40%);
+ display: inline-grid;
+ place-content: center;
+ background: var(--surface3) fixed;
+
+ @media (--motionOK) {
+ & {
+ transition: clip-path .3s ease;
+ }
+ }
+ }
+
+ & svg {
+ fill: var(--text2);
+ block-size: var(--space-md);
+ }
+
+ & > :is(picture, input[type="checkbox"]) {
+ place-self: center;
+ }
+ }
+
+ small {
+ color: var(--text2);
+ line-height: 1.5;
+ }
+
+ .github-corner {
+ color: var(--surface1);
+ fill: var(--surface3);
+
+ &:hover .octo-arm {
+ animation: octocat-wave 560ms ease-in-out
+ }
+ }
+
+ @keyframes octocat-wave{
+ 0%,100% {
+ transform: rotate(0)
+ }
+ 20%,60% {
+ transform: rotate(-25deg)
+ }
+ 40%,80% {
+ transform: rotate(10deg)
+ }
+ }
\ No newline at end of file
diff --git a/static/index.html b/static/index.html
index d3bd96a..ac759a4 100644
--- a/static/index.html
+++ b/static/index.html
@@ -7,75 +7,13 @@
+
+ Farpatch
-
-
-
-
-