tangled
alpha
login
or
join now
bwc9876.dev
/
silly-tracker
0
fork
atom
Silly task tracker to track silly things for silly friend
silly.bwc9876.dev
0
fork
atom
overview
issues
3
pulls
pipelines
Layout for mobile
bwc9876.dev
3 days ago
4c244aa0
6fb0db88
verified
This commit was signed with the committer's
known signature
.
bwc9876.dev
SSH Key Fingerprint:
SHA256:DanMEP/RNlSC7pAVbnXO6wzQV00rqyKj053tz4uH5gQ=
+42
-36
3 changed files
expand all
collapse all
unified
split
src
App.tsx
Entry.tsx
index.css
+8
-3
src/App.tsx
···
3
3
import silly from "./assets/silly.png";
4
4
import Entry from "./Entry";
5
5
6
6
-
export type Entry = { id: number, name: string; progress: number };
6
6
+
export type Entry = { id: number; name: string; progress: number };
7
7
type State = Entry[];
8
8
9
9
const current = JSON.parse(window.localStorage.getItem("state") ?? "[]") as State;
···
13
13
const [state, setState] = useState<State>(current);
14
14
15
15
const addGuy = () => {
16
16
-
setState(s => {
16
16
+
setState((s) => {
17
17
const newId = Math.random() * Number.MAX_SAFE_INTEGER;
18
18
const newState = [{ id: newId, name: guyVal, progress: 0 }, ...s];
19
19
return newState.sort((a, b) => {
···
65
65
</button>
66
66
<div className="list">
67
67
{state.map((e, i) => (
68
68
-
<Entry key={e.id} onDelete={() => setState(s => s.filter((_, j) => j !== i))} onChange={(newVal) => setState(s => s.with(i, { ...e, progress: newVal }))} {...e} />
68
68
+
<Entry
69
69
+
key={e.id}
70
70
+
onDelete={() => setState((s) => s.filter((_, j) => j !== i))}
71
71
+
onChange={(newVal) => setState((s) => s.with(i, { ...e, progress: newVal }))}
72
72
+
{...e}
73
73
+
/>
69
74
))}
70
75
</div>
71
76
</>
+15
-15
src/Entry.tsx
···
1
1
import type { Entry } from "./App";
2
2
3
3
-
export type Props = Entry & { onChange: (newVal: number) => void, onDelete: () => void, };
3
3
+
export type Props = Entry & { onChange: (newVal: number) => void; onDelete: () => void };
4
4
5
5
export default function Entry({ name, progress, onChange, onDelete }: Props) {
6
6
-
return <label className={progress === 100 ? "done" : undefined}>
7
7
-
<span>{name}</span>
8
8
-
<input
9
9
-
type="range"
10
10
-
value={progress}
11
11
-
min={0}
12
12
-
max={100}
13
13
-
onChange={(ev) => onChange(parseInt(ev.target.value))}
14
14
-
/>
15
15
-
<small>
16
16
-
{progress}%
17
17
-
</small>
18
18
-
<button onClick={onDelete}>X</button>
19
19
-
</label>;
6
6
+
return (
7
7
+
<label className={progress === 100 ? "done" : undefined}>
8
8
+
<span>{name}</span>
9
9
+
<input
10
10
+
type="range"
11
11
+
value={progress}
12
12
+
min={0}
13
13
+
max={100}
14
14
+
onChange={(ev) => onChange(parseInt(ev.target.value))}
15
15
+
/>
16
16
+
<small>{progress}%</small>
17
17
+
<button onClick={onDelete}>X</button>
18
18
+
</label>
19
19
+
);
20
20
}
+19
-18
src/index.css
···
4
4
5
5
--level: 65%;
6
6
--saturation-offset: 20%;
7
7
-
--rainbow: linear-gradient(90deg,
8
8
-
hsl(0, calc(100% - var(--saturation-offset)), var(--level)) 0%,
9
9
-
hsl(36, calc(100% - var(--saturation-offset)), var(--level)) 10%,
10
10
-
hsl(64, calc(74% - var(--saturation-offset)), var(--level)) 20%,
11
11
-
hsl(118, calc(68% - var(--saturation-offset)), var(--level)) 30%,
12
12
-
hsl(179, calc(68% - var(--saturation-offset)), var(--level)) 40%,
13
13
-
hsl(188, calc(76% - var(--saturation-offset)), var(--level)) 50%,
14
14
-
hsl(212, calc(86% - var(--saturation-offset)), var(--level)) 60%,
15
15
-
hsl(260, calc(89% - var(--saturation-offset)), var(--level)) 70%,
16
16
-
hsl(284, calc(94% - var(--saturation-offset)), var(--level)) 80%,
17
17
-
hsl(308, calc(97% - var(--saturation-offset)), var(--level)) 90%,
18
18
-
hsl(0, calc(100% - var(--saturation-offset)), var(--level)) 100%);
7
7
+
--rainbow: linear-gradient(
8
8
+
90deg,
9
9
+
hsl(0, calc(100% - var(--saturation-offset)), var(--level)) 0%,
10
10
+
hsl(36, calc(100% - var(--saturation-offset)), var(--level)) 10%,
11
11
+
hsl(64, calc(74% - var(--saturation-offset)), var(--level)) 20%,
12
12
+
hsl(118, calc(68% - var(--saturation-offset)), var(--level)) 30%,
13
13
+
hsl(179, calc(68% - var(--saturation-offset)), var(--level)) 40%,
14
14
+
hsl(188, calc(76% - var(--saturation-offset)), var(--level)) 50%,
15
15
+
hsl(212, calc(86% - var(--saturation-offset)), var(--level)) 60%,
16
16
+
hsl(260, calc(89% - var(--saturation-offset)), var(--level)) 70%,
17
17
+
hsl(284, calc(94% - var(--saturation-offset)), var(--level)) 80%,
18
18
+
hsl(308, calc(97% - var(--saturation-offset)), var(--level)) 90%,
19
19
+
hsl(0, calc(100% - var(--saturation-offset)), var(--level)) 100%
20
20
+
);
19
21
}
20
22
21
23
@keyframes scroll {
···
73
75
font-size: 18pt;
74
76
}
75
77
76
76
-
&>button {
78
78
+
& > button {
77
79
transition: background-color 100ms linear;
78
80
background-color: #6c7;
79
81
font-size: 18pt;
···
89
91
flex-direction: column;
90
92
gap: 0.5em;
91
93
92
92
-
&>label {
94
94
+
& > label {
93
95
display: grid;
94
94
-
position: relative;
95
95
-
grid-template-columns: 1fr 3fr .6fr .2fr;
96
96
+
grid: row / 1fr 3fr 0.6fr 0.2fr;
96
97
align-items: center;
97
98
gap: 0.5em;
98
99
margin: 0;
99
99
-
transition: scale .2s cubic-bezier(.68, -0.55, .27, 1.55);
100
100
+
transition: scale 0.2s cubic-bezier(0.68, -0.55, 0.27, 1.55);
100
101
border: solid 2px black;
101
102
padding: 1em;
102
103
103
104
@starting-style {
104
104
-
scale: .2;
105
105
+
scale: 0.2;
105
106
}
106
107
107
108
&.done {