diff --git a/app.js b/app.js
index 374c9b3..6355aad 100644
--- a/app.js
+++ b/app.js
@@ -3,7 +3,64 @@ import * as TW from "https://esm.sh/@twind/core@1.0.1";
import TWPreTail from "https://esm.sh/@twind/preset-tailwind@1.0.1";
import TWPreAuto from "https://esm.sh/@twind/preset-autoprefix@1.0.1";
-const Configure = {presets: [TWPreTail(), TWPreAuto()]};
+const Configure = {
+ theme:
+ {
+ extend:
+ {
+ keyframes:
+ {
+ flash:
+ {
+ '0%': { opacity: 1.0 },
+ '50%': { opacity: 0.3 },
+ '100%': { opacity: 0.0 }
+ },
+ pulse:
+ {
+ "0%": { opacity: 0.0 },
+ "10%": { opacity: 0.0 },
+ "12%": { opacity: 1.0 },
+ "22%": { opacity: 1.0 },
+ "42%": { opacity: 0.2 },
+ "100%": { opacity: 0.0 }
+ }
+ },
+ animation:
+ {
+ flash: "flash 1s both"
+ },
+ strokeWidth:
+ {
+ "bold": "3px"
+ }
+ }
+ },
+ rules:
+ [
+ [
+ "stroke-draw",
+ {
+ "vector-effect":"non-scaling-stroke",
+ "stroke-linecap":"square"
+ },
+ ],
+ [
+ 'shadow-glow-(.*)',
+ (match, context)=>
+ {
+ return { "box-shadow": `0px 0px 5px 2px ${context.theme().colors[match[1]]}` };
+ }
+ ],
+ [
+ 'shadow-sss',
+ {
+ "box-shadow": "rgb(0 0 0 / 50%) 0px -3px 2px inset, rgb(255 255 255 / 50%) 0px 10px 10px inset"
+ }
+ ]
+ ],
+ presets: [TWPreTail(), TWPreAuto()]
+};
const ShadowDOM = document.querySelector("#app").attachShadow({mode: "open"});
const ShadowDiv = document.createElement("div");
const ShadowCSS = document.createElement("style");
@@ -11,10 +68,17 @@ ShadowDOM.append(ShadowCSS);
ShadowDOM.append(ShadowDiv);
TW.observe(TW.twind(Configure, TW.cssom(ShadowCSS)), ShadowDiv);
-import UI from "./ui.js";
+import * as UI from "./ui.js";
import {render} from "https://esm.sh/preact@10.11.3/compat";
import {html} from "https://esm.sh/htm@3.1.1/preact";
render(html`
<${UI.Button} icon="+">hey!/>
- <${UI.Chart}>
SUP
/>
+ <${UI.Button} light>Left/>
+ <${UI.Button} inactive>Right/>
+ <${UI.Button} disabled>Right/>
+ <${UI.Chart}>
+
+ />
`, ShadowDiv);
\ No newline at end of file
diff --git a/ui.js b/ui.js
index 9e7405e..994b75d 100644
--- a/ui.js
+++ b/ui.js
@@ -3,72 +3,123 @@ import React from "https://esm.sh/preact@10.11.3/compat";
///
import {html} from "https://esm.sh/htm@3.1.1/preact";
-export default {
- Button({children, icon, light, disabled})
- {
- return html`
- `;
- },
+/** @typedef {({children}:{children:React.ReactNode})=>JSX.Element} BasicElement */
- /** @type {({children}:{inset:number, children:React.ReactNode})=>JSX.Element} */
- Chart({children})
+export function Button({children, icon, light, disabled, inactive})
+{
+ const [LightGet, LightSet] = React.useState(light);
+ const [FlashGet, FlashSet] = React.useState(0);
+ const handleClick =()=>
+ {
+ if(inactive||disabled){ return; }
+ LightSet(!LightGet);
+ FlashSet(FlashGet+1);
+ };
+
+ return html`
+ `;
+}
+
+/** @type {BasicElement} */
+export function Chart({children})
+{
+ const inset = 20
+
+ const size = 1/6;
+ /** @type {Record} */
+ const rulesXMapping = {
+ "125": [size*0.0, true ],
+ "250": [size*1.0, true ],
+ "500": [size*2.0, true ],
+ "1000": [size*3.0, true ],
+ "2000": [size*4.0, true ],
+ "3000": [size*4.5, false],
+ "4000": [size*5.0, true ],
+ "6000": [size*5.5, false],
+ "8000": [size*6.0, true ]
+ };
+ const rulesX = Object.entries(rulesXMapping).map(([label, [position, normal]])=>
{
- const inset = 20
- const size = 1/6;
- /** @type {Record} */
- const mappingX = {
- "125": [size*0.0, true ],
- "250": [size*1.0, true ],
- "500": [size*2.0, true ],
- "1000": [size*3.0, true ],
- "2000": [size*4.0, true ],
- "3000": [size*4.5, false],
- "4000": [size*5.0, true ],
- "6000": [size*5.5, false],
- "8000": [size*6.0, true ],
- };
- const rulesX = Object.entries(mappingX).map(([label, [position, normal]])=>
- {
- return html`
-
- ${label}
- `;
- });
- const rulesY = [];
- const rulesYMin = -10;
- const rulesYMax = 120;
- for(let db = rulesYMin; db <= rulesYMax; db+=10)
- {
- const percent = ((db-rulesYMin) / (rulesYMax-rulesYMin))*100;
- rulesY.push(html`
-
- ${db}
-
- `);
- }
return html`
-
-
-
Frequency in Hz
-
-
- Hearing Level (dbHL)
-
+
+ ${label}
+ `;
+ });
+ const rulesY = [];
+ const rulesYMin = -10;
+ const rulesYMax = 120;
+ for(let db = rulesYMin; db <= rulesYMax; db+=10)
+ {
+ const percent = ((db-rulesYMin) / (rulesYMax-rulesYMin))*100;
+ rulesY.push(html`
+
+ ${db}
+
+ `);
+ }
+ return html`
+
+
+
Frequency in Hz
+
+
+ Hearing Level (dbHL)
-
-
- ${ rulesX }
- ${ rulesY }
+
+
+
+ ${ rulesX }
+ ${ rulesY }
+
${ children }
- `;
- }
+
+ `;
+}
+
+/** @type {Record
} */
+const Glyph = {
+ Arrow:({children})=> html`
+
+
+ `,
+
+ //style="transform: translate(50%, 50%) rotate(-15deg) scale(0.5);"
+ X: ({children})=> html`
+
+
+ ${children}`,
+
+ O: ({children})=> html`
+
+ ${children}`
+};
+
+/** @type {({right, response, x, y}:{right:boolean, response?:boolean, x:string|number, y:string|number})=>JSX.Element} */
+export function Mark({right, response, x, y})
+{
+ return html`
+
+ `;
}
\ No newline at end of file