mirror of https://github.com/mkrhere/pw2
Compare commits
4 Commits
cab162ff97
...
a1d9a25bed
Author | SHA1 | Date |
---|---|---|
Muthu Kumar | a1d9a25bed | 5 months ago |
Muthu Kumar | feb6a4c485 | 5 months ago |
Muthu Kumar | f4b3ad8102 | 5 months ago |
Muthu Kumar | d7bddd37ad | 5 months ago |
15 changed files with 344 additions and 104 deletions
@ -1,13 +0,0 @@ |
|||
import React from "react"; |
|||
import { css } from "@emotion/css"; |
|||
|
|||
const Dashed: React.FC<{ children: React.ReactNode }> = ({ children }) => ( |
|||
<span |
|||
className={css` |
|||
border-bottom: 1px dashed var(--text-colour); |
|||
`}>
|
|||
{children} |
|||
</span> |
|||
); |
|||
|
|||
export default Dashed; |
@ -0,0 +1,145 @@ |
|||
import React from "react"; |
|||
import { css, cx } from "@emotion/css"; |
|||
import { intersperse, sleep } from "../util"; |
|||
|
|||
const tripleBlink = async (el: HTMLElement) => { |
|||
const delay = 150; |
|||
|
|||
await sleep(1000); |
|||
el.style.opacity = "0.5"; |
|||
await sleep(delay); |
|||
el.style.opacity = "1"; |
|||
await sleep(delay); |
|||
el.style.opacity = "0.5"; |
|||
await sleep(delay); |
|||
el.style.opacity = "1"; |
|||
await sleep(delay); |
|||
el.style.opacity = "0.5"; |
|||
await sleep(delay * 2); |
|||
el.style.opacity = "1"; |
|||
}; |
|||
|
|||
const Flicker: React.FC<{ |
|||
children: React.ReactNode; |
|||
index: number; |
|||
description: string; |
|||
}> = ({ children, index, description }) => { |
|||
return ( |
|||
<span |
|||
className={css` |
|||
position: relative; |
|||
|
|||
& button:focus ~ .tooltip, |
|||
& button:hover ~ .tooltip { |
|||
opacity: 1; |
|||
} |
|||
|
|||
& button:focus, |
|||
& button:hover { |
|||
opacity: 1 !important; |
|||
} |
|||
`}>
|
|||
<button |
|||
className={css` |
|||
border-bottom: 1px dashed var(--text-colour); |
|||
opacity: 0; |
|||
background-color: transparent; |
|||
border: none; |
|||
color: inherit; |
|||
position: relative; |
|||
`}
|
|||
ref={async el => { |
|||
if (!el) return; |
|||
|
|||
await sleep(150); |
|||
await sleep(250 * index); |
|||
el.style.opacity = "1"; |
|||
|
|||
await sleep(1000 + Math.random() * 1000); |
|||
tripleBlink(el); |
|||
|
|||
while (true) { |
|||
await sleep(5000 + Math.random() * 10000); |
|||
el.style.opacity = String(0.5 + Math.random() * 0.5); |
|||
await sleep(2000); |
|||
tripleBlink(el); |
|||
} |
|||
}}> |
|||
{children} |
|||
</button> |
|||
<span |
|||
className={cx( |
|||
"tooltip", |
|||
css` |
|||
/* tooltip */ |
|||
position: absolute; |
|||
top: 150%; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
background: var(--card-tags); |
|||
color: var(--text-colour); |
|||
border-radius: 0.5rem; |
|||
padding: 0.5rem 0.8rem; |
|||
font-size: 0.8rem; |
|||
min-width: 20rem; |
|||
width: fit-content; |
|||
max-width: 80vw; |
|||
opacity: 0; |
|||
transition: opacity 0.2s; |
|||
user-select: none; |
|||
text-align: left; |
|||
|
|||
@media screen and (max-width: 65rem) { |
|||
position: fixed; |
|||
top: unset; |
|||
left: 1rem; |
|||
transform: translateY(2rem); |
|||
} |
|||
`,
|
|||
)}> |
|||
{description} |
|||
</span> |
|||
</span> |
|||
); |
|||
}; |
|||
|
|||
const FlickerList: React.FC<{ |
|||
list: { text: string; description: string }[]; |
|||
}> = ({ list }) => { |
|||
return ( |
|||
<ul |
|||
className={css` |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
gap: 0.5rem; |
|||
margin: 0; |
|||
padding: 0; |
|||
list-style: none; |
|||
|
|||
&:has(> li > span > button:focus) li > span > button:not(:focus), |
|||
&:has(> li > span > button:hover) li > span > button:not(:hover) |
|||
/* */ { |
|||
opacity: 0.5 !important; |
|||
} |
|||
`}>
|
|||
{[ |
|||
...intersperse( |
|||
list.map((item, index) => ( |
|||
<li |
|||
key={item.text} |
|||
className={css` |
|||
display: inline-block; |
|||
`}>
|
|||
<Flicker index={index} description={item.description}> |
|||
{item.text} |
|||
</Flicker> |
|||
</li> |
|||
)), |
|||
<li>·</li>, |
|||
), |
|||
]} |
|||
</ul> |
|||
); |
|||
}; |
|||
|
|||
export default FlickerList; |
@ -0,0 +1,54 @@ |
|||
export const projects = [ |
|||
{ |
|||
title: window.location.hostname, |
|||
description: "This website.", |
|||
url: "https://github.com/MKRhere/pw2", |
|||
cat: "web", |
|||
tags: ["react", "vite"], |
|||
}, |
|||
{ |
|||
title: "hyperactive", |
|||
description: "Suite of web-app development libraries.", |
|||
url: "https://github.com/codefeathers/hyperactive", |
|||
cat: "lib", |
|||
tags: ["reactive", "ui-framework"], |
|||
}, |
|||
{ |
|||
title: "denoland/node_shims", |
|||
description: |
|||
"Node shims for Deno’s runtime API. Contributed repo into official denoland.", |
|||
url: "https://github.com/denoland/node_shims", |
|||
cat: "lib", |
|||
tags: ["deno", "shims"], |
|||
}, |
|||
{ |
|||
title: "Telegraf", |
|||
description: |
|||
"Active maintainer of one of the most popular Telegram Bot API libraries for Node.", |
|||
url: "https://github.com/telegraf/telegraf", |
|||
cat: "lib", |
|||
tags: ["typescript", "telegram", "bot-api"], |
|||
}, |
|||
{ |
|||
title: "runtype", |
|||
description: "Safely bring runtime values into TypeScript.", |
|||
url: "https://codefeathers.github.io/runtype", |
|||
cat: "lib", |
|||
tags: ["typescript", "runtime"], |
|||
}, |
|||
{ |
|||
title: "Telecraft", |
|||
description: "Pluggable Minecraft server administration toolkit.", |
|||
url: "https://github.com/MadrasMC/telecraft", |
|||
cat: "tool", |
|||
tags: ["minecraft", "node"], |
|||
}, |
|||
{ |
|||
title: "Storymap (WIP)", |
|||
description: |
|||
"Reverse-engineered thirdparty map renderer for Vintage Story in Zig ⚡️", |
|||
// url: "https://github.com/MadrasMC/storymap",
|
|||
cat: "tool", |
|||
tags: ["vintage-story", "zig", "wip"], |
|||
}, |
|||
]; |
Loading…
Reference in new issue