Skip to content

Commit 8657e7b

Browse files
authored
feat(todo): better handle (sub)tasks update; revamp styling (#74)
1 parent 0ec94f8 commit 8657e7b

16 files changed

Lines changed: 245 additions & 65 deletions

src/examples/purity-todo/components/app-style.ts

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,45 @@ export const appStyle = (): string => render`
88
--background-color: #f0f0f0;
99
--text-color: #555;
1010
--shadow-color: #555;
11+
--border-color: lightgrey;
12+
--accent-color: #4a90e2;
13+
--completed-color: lightgrey;
14+
--subtask-color: lightgrey;
15+
--button-active-bg: grey;
16+
--header-bg: lightgrey;
17+
--header-border: none;
18+
--input-bg: #303030;
19+
--input-color: #eee;
20+
--input-border: none;
21+
--input-focus-outline: none;
22+
--modal-overlay-bg: #50505030;
23+
--task-item-hover-bg: transparent;
24+
--completed-image-opacity: 1;
25+
--control-button-bg: #555;
26+
--control-button-opacity: 0.75;
1127
}
1228
1329
@media (prefers-color-scheme: dark) {
1430
:root {
15-
--background-color: #484848;
16-
--text-color: #f0f0f0;
17-
--shadow-color: #000;
31+
--background-color: #1a1a2e;
32+
--text-color: #e0e0e0;
33+
--shadow-color: rgba(0, 0, 0, 0.5);
34+
--border-color: #2d2d44;
35+
--accent-color: #4a90e2;
36+
--completed-color: #6b7280;
37+
--subtask-color: #9ca3af;
38+
--button-active-bg: var(--accent-color);
39+
--header-bg: #2d2d44;
40+
--header-border: 1px solid var(--border-color);
41+
--input-bg: var(--header-bg);
42+
--input-color: var(--text-color);
43+
--input-border: 1px solid var(--border-color);
44+
--input-focus-outline: 2px solid var(--accent-color);
45+
--modal-overlay-bg: rgba(0, 0, 0, 0.7);
46+
--task-item-hover-bg: rgba(74, 144, 226, 0.1);
47+
--completed-image-opacity: 0.5;
48+
--control-button-bg: var(--accent-color);
49+
--control-button-opacity: 0.9;
1850
}
1951
}
2052
@@ -63,16 +95,22 @@ export const appStyle = (): string => render`
6395
}
6496
6597
.${ACTION_BUTTON}:active {
66-
background-color: grey;
67-
color: white;
98+
background-color: var(--button-active-bg);
6899
}
69100
70101
.${ACTION_BUTTON}.hidden {
71102
display: none;
72103
}
73104
74-
.${ACTION_BUTTON}.chosen {
75-
color: var(--background-color);
105+
.header {
106+
.${ACTION_BUTTON} {
107+
color: var(--background-color);
108+
}
109+
110+
.${ACTION_BUTTON}:active,
111+
.${ACTION_BUTTON}.chosen {
112+
color: var(--text-color);
113+
}
76114
}
77115
78116
</style>

src/examples/purity-todo/components/header.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@ import {ACTION_BUTTON} from "./app-style.js"
55

66
const headerStyle = (): string => render`
77
<style id="header-style">
8-
#header {
9-
background-color: lightgrey;
8+
.header {
9+
background-color: var(--header-bg);
10+
border-bottom: var(--header-border);
1011
height: 3rem;
1112
min-height: 3rem;
1213
max-width: 100%;
1314
z-index: 1;
14-
}
1515
16-
#header ul {
17-
display: flex;
18-
justify-content: space-around;
19-
user-select: none;
16+
ul {
17+
display: flex;
18+
justify-content: space-around;
19+
user-select: none;
20+
}
2021
}
21-
2222
</style>
2323
`
2424

2525
export const header = (): string => render`
26-
<nav id="header">
26+
<nav id="header" class="header">
2727
<ul>
2828
${navItem({value: "active", label: "⊡"})}
2929
${navItem({value: "completed", label: "⊠"})}

src/examples/purity-todo/components/input-form.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@ const inputFormStyle = () => render`
1919
form#task-form input {
2020
width: 100%;
2121
height: 100%;
22-
background-color: #303030;
23-
color: #eee;
22+
background-color: var(--input-bg);
23+
color: var(--input-color);
24+
border: var(--input-border);
2425
border-radius: 0;
2526
}
2627
28+
form#task-form input:focus {
29+
outline: var(--input-focus-outline);
30+
outline-offset: -2px;
31+
}
32+
2733
</style>
2834
`
2935

src/examples/purity-todo/components/modal-style.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const modalStyle = (): string => render`
88
right: 0;
99
bottom: 0;
1010
left: 0;
11-
background-color: #50505030;
11+
background-color: var(--modal-overlay-bg);
1212
z-index: 1;
1313
display: flex;
1414
align-items: center;
@@ -30,7 +30,7 @@ export const modalStyle = (): string => render`
3030
}
3131
3232
.modal .modal-header {
33-
background-color: lightgrey;
33+
background-color: var(--header-bg);
3434
font-weight: bold;
3535
position: relative;
3636
${lineContainerCSS}

src/examples/purity-todo/components/subtask-item.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,28 @@ const toggleSubtask =
1111
(subtaskIndex: number): EventHandler =>
1212
({target: {checked}}) => {
1313
const {id, subtasks} = selectDetailedTask()
14-
patchTask({
15-
id: id,
16-
subtasks: subtasks?.map((subtask, i) =>
17-
i === subtaskIndex ? {...subtask, checked: !subtask.checked} : subtask
18-
),
19-
})
14+
const newSubtasks = subtasks?.map((s, i) =>
15+
i === subtaskIndex ? {...s, checked: !s.checked} : s
16+
)
17+
patchTask({id: id, subtasks: newSubtasks})
2018
}
2119

2220
const handleSubtaskChange =
2321
(subtaskIndex: number): EventHandler =>
2422
({target: {value}}) => {
2523
const task = selectDetailedTask()
26-
patchTask({
27-
id: task.id,
28-
subtasks: task.subtasks?.map((subtask, i) =>
29-
i === subtaskIndex
30-
? {...subtask, description: sanitize(value)}
31-
: subtask
32-
),
33-
})
24+
const newSubtasks = task.subtasks?.map((s, i) =>
25+
i === subtaskIndex ? {...s, description: sanitize(value)} : s
26+
)
27+
patchTask({id: task.id, subtasks: newSubtasks})
3428
}
3529

3630
const deleteSubtask =
3731
(subtaskIndex: number): EventHandler =>
3832
() => {
3933
const {id, subtasks} = selectDetailedTask()
40-
patchTask({id, subtasks: subtasks?.filter((_, i) => i !== subtaskIndex)})
34+
const newSubtasks = subtasks?.filter((_, i) => i !== subtaskIndex)
35+
patchTask({id, subtasks: newSubtasks})
4136
}
4237

4338
export const subtaskItem = (

src/examples/purity-todo/components/task-details-style.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ export const taskDetailsStyle = (): string => render`
3636
.task-details--image .controls button,
3737
.task-details--image .controls label {
3838
padding: 4px 16px;
39-
background: #555;
39+
background: var(--control-button-bg);
4040
color: white;
41-
opacity: 0.75;
41+
opacity: var(--control-button-opacity);
4242
border-radius: 8px;
4343
}
4444
@@ -69,6 +69,9 @@ export const taskDetailsStyle = (): string => render`
6969
padding: 4px 8px;
7070
color: var(--text-color);
7171
opacity: 0.6;
72+
overflow: hidden;
73+
text-overflow: ellipsis;
74+
white-space: nowrap;
7275
}
7376
7477
.${SMALL_BUTTON} {

src/examples/purity-todo/components/task-details.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ export const taskDetails = (): string => {
8888
style="background-image: url('${
8989
task.isImageLoading ? IMAGES.LOADING : task?.image.link
9090
}');"
91-
>
91+
>
9292
<div class="controls" id="controls">
9393
<button ::click=${makeChangeImage("current")}>
9494
9595
</button>
96-
96+
9797
${
9898
task?.image.queries.previousPage?.startIndex !== undefined &&
9999
render`
@@ -102,7 +102,7 @@ export const taskDetails = (): string => {
102102
</button>
103103
`
104104
}
105-
105+
106106
${
107107
task?.image.queries.nextPage?.startIndex !== undefined &&
108108
render`
@@ -124,7 +124,6 @@ export const taskDetails = (): string => {
124124
</label>
125125
</div>
126126
</div>
127-
128127
</section>
129128
130129
<section class="task-details--description">
@@ -141,7 +140,7 @@ export const taskDetails = (): string => {
141140
${task.subtasks?.map(subtaskItem)}
142141
</div>
143142
<div style="padding: 4px 8px; ">
144-
<button
143+
<button
145144
class="${ACTION_BUTTON} ${SMALL_BUTTON}"
146145
::click=${handleAddSubtask}
147146
>

src/examples/purity-todo/components/task-item.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ describe("task-item", () => {
3939
onerror="this.onerror = null; this.src = './assets/images/icon-pack/forbidden.svg'"
4040
loading="lazy"
4141
/><div
42+
id="item-description-test"
4243
class="item-description"
4344
data-id="test"
4445
data-purity_click_0 data-purity_flag
@@ -73,6 +74,7 @@ describe("task-item", () => {
7374
onerror="this.onerror = null; this.src = './assets/images/icon-pack/forbidden.svg'"
7475
loading="lazy"
7576
/><div
77+
id="item-description-test"
7678
class="item-description"
7779
data-id="test"
7880
data-purity_click_0 data-purity_flag
@@ -110,6 +112,7 @@ describe("task-item", () => {
110112
onerror="this.onerror = null; this.src = './assets/images/icon-pack/forbidden.svg'"
111113
loading="lazy"
112114
/><div
115+
id="item-description-test"
113116
class="item-description"
114117
data-id="test"
115118
data-purity_click_0 data-purity_flag

src/examples/purity-todo/components/task-item.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export const taskItem = ({
5959
loading="lazy"
6060
/>
6161
<div
62+
id="item-description-${id}"
6263
class="${ITEM_DESCRIPTION}"
6364
data-id="${id}"
6465
::click=${openTaskDetails}

src/examples/purity-todo/components/task-list-style.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const taskListStyle = (): string => render`
3232
3333
ol#task-list .task-item {
3434
display: flex;
35-
border-bottom: 1px solid lightgrey;
35+
border-bottom: 1px solid var(--border-color);
3636
align-items: center;
3737
padding: 0;
3838
}
@@ -47,18 +47,18 @@ export const taskListStyle = (): string => render`
4747
}
4848
4949
ol#task-list .task-item.completed .${ITEM_DESCRIPTION} {
50-
color: lightgrey;
50+
color: var(--completed-color);
5151
}
5252
5353
.${ITEM_DESCRIPTION} .subtask-inline {
54-
color: lightgrey;
54+
color: var(--subtask-color);
5555
}
5656
5757
.${ITEM_DESCRIPTION} .subtask-inline::before {
5858
content: "⊡";
5959
margin-right: 0.5rem;
6060
margin-left: 0.5rem;
61-
color: lightgrey;
61+
color: var(--subtask-color);
6262
}
6363
6464
ol#task-list .task-item > img {
@@ -70,19 +70,16 @@ export const taskListStyle = (): string => render`
7070
z-index: -1;
7171
}
7272
73+
ol#task-list .task-item:hover {
74+
background-color: var(--task-item-hover-bg);
75+
}
76+
7377
ol#task-list .task-item.completed > img {
7478
filter: grayscale(1);
79+
opacity: var(--completed-image-opacity);
7580
}
7681
7782
ol#task-list .task-item.stale {
78-
opacity: 0.4;
79-
filter: grayscale(0.3);
80-
transition: opacity 0.3s ease-in-out, filter 0.3s ease-in-out;
81-
}
82-
83-
ol#task-list .task-item.stale:hover {
84-
opacity: 0.7;
85-
filter: grayscale(0.1);
8683
}
8784
8885
</style>

0 commit comments

Comments
 (0)