Skip to content

Commit 9c5d32f

Browse files
committed
feat: make title editable
1 parent 77b962e commit 9c5d32f

8 files changed

+155
-13
lines changed

src/components/BitButton.component.module.css

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
margin-left: .25rem;
55
margin-right: .25rem;
66
margin-bottom: 1rem;
7-
background-color: #61dafb;
7+
background-color: var(--secondary-color);
88
border: none;
99
border-radius: 5px;
1010
cursor: pointer;
1111
font-size: 3rem;
1212
font-family: 'Montserrat', sans-serif;
1313
overflow: hidden;
14-
transition: background-color 0.3s, border-color 0.3s;
14+
transition: .2s linear;
1515

16-
& > .text {
16+
&>.text {
1717
display: inline-block;
1818
}
1919
}
@@ -32,5 +32,5 @@
3232

3333
.hovered,
3434
.selected {
35-
background-color: #21a1f1;
36-
}
35+
background-color: var(--primary-color);
36+
}

src/components/Button.component.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
font-family: inherit;
1313
cursor: pointer;
1414
width: fit-content;
15-
transition: background-color 0.3s, border-color 0.3s;
15+
transition: .2s linear;
1616
}
1717

1818
.button:disabled {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
input {
2+
color: var(--text-color);
3+
text-transform: uppercase;
4+
background-color: var(--background-color);
5+
outline: none;
6+
margin: 1rem;
7+
padding: 1rem;
8+
width: 80%;
9+
border: none;
10+
border: .5px solid var(--text-color);
11+
border-radius: .25rem;
12+
transition: .2s linear;
13+
14+
&:focus {
15+
box-shadow: -5px -5px 0px whitesmoke;
16+
}
17+
}
18+
19+
@media (prefers-color-scheme: light) {
20+
input {
21+
color: var(--background-color);
22+
background-color: var(--text-color);
23+
border: .5px solid var(--background-color);
24+
25+
&:focus {
26+
box-shadow: -5px -5px 0px black;
27+
}
28+
}
29+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { useEffect, useMemo, useState } from "react";
2+
import { IconButton } from "./IconButton.component";
3+
4+
import styles from "./EditableTitle.component.module.css";
5+
6+
const EditableTitle = () => {
7+
const countdownTitleSettingKey = "title";
8+
const [displayText, setDisplayText] = useState("Please stand by");
9+
const [newText, setNewText] = useState("Please stand by");
10+
const [isEditVisible, setEditVisible] = useState(false);
11+
const [isEditMode, setEditMode] = useState(false);
12+
13+
useEffect(() => {
14+
const titleSettingValue = localStorage.getItem(countdownTitleSettingKey);
15+
if (titleSettingValue) {
16+
setDisplayText(titleSettingValue);
17+
}
18+
}, []);
19+
20+
useEffect(() => {
21+
localStorage.setItem(countdownTitleSettingKey, displayText);
22+
}, [displayText]);
23+
24+
const editButton = useMemo(
25+
() => (
26+
<IconButton
27+
text="✏️"
28+
tooltip="Edit text"
29+
onClick={() => setEditMode(true)}
30+
/>
31+
),
32+
[]
33+
);
34+
35+
const confirmDiscardButtons = useMemo(
36+
() => (
37+
<>
38+
<IconButton
39+
text="✅"
40+
tooltip="Accept"
41+
onClick={() => {
42+
setDisplayText(newText);
43+
setEditMode(false);
44+
}}
45+
/>
46+
<IconButton
47+
text="❌"
48+
tooltip="Discard"
49+
onClick={() => {
50+
setEditMode(false);
51+
setEditVisible(false);
52+
}}
53+
/>
54+
</>
55+
),
56+
[newText]
57+
);
58+
59+
return (
60+
<div
61+
className="flex flex-row flex-wrap items-center justify-center mb-8 w-full"
62+
onMouseOver={() => setEditVisible(true)}
63+
onMouseOut={() => setEditVisible(false)}
64+
>
65+
{!isEditMode && (
66+
<>
67+
<h1 className="text-5xl uppercase">{displayText}</h1>
68+
{isEditVisible && editButton}
69+
</>
70+
)}
71+
{isEditMode && (
72+
<>
73+
<input
74+
type="text"
75+
style={styles}
76+
defaultValue={newText}
77+
autoFocus
78+
size={newText.length}
79+
onChange={(e) => {
80+
const text = e.target.value;
81+
if (text.length > 1) {
82+
setNewText(e.target.value);
83+
}
84+
}}
85+
onKeyDown={(e) => {
86+
switch (e.key) {
87+
case "Escape":
88+
setEditMode(false);
89+
break;
90+
case "Enter":
91+
setDisplayText(newText);
92+
setEditMode(false);
93+
break;
94+
default:
95+
break;
96+
}
97+
}}
98+
/>
99+
{confirmDiscardButtons}
100+
</>
101+
)}
102+
</div>
103+
);
104+
};
105+
106+
export default EditableTitle;

src/components/IconButton.component.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
font-family: inherit;
1313
cursor: pointer;
1414
width: fit-content;
15-
transition: background-color 0.3s, border-color 0.3s;
15+
transition: .2s linear;
1616
}
1717

1818
.button {

src/components/MuteButton.component.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useMuteContext } from "../hooks/useMuteContext.hook";
33
import { IconButton } from "./IconButton.component";
44

55
const MuteButton = () => {
6-
const IsMutedSettingKey = "isMuted";
6+
const IsMutedSettingKey = "mute";
77
const { isMuted, toggleMute } = useMuteContext();
88

99
useEffect(() => {

src/index.css

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
@import 'tailwindcss';
22

33
:root {
4+
--primary-color: #21a1f1;
5+
--secondary-color: #61dafb;
6+
--background-color: #242424;
7+
--text-color: rgba(255, 255, 255, 0.87);
8+
49
color-scheme: light dark;
5-
color: rgba(255, 255, 255, 0.87);
6-
background-color: #242424;
10+
color: var(--text-color);
11+
background-color: var(--background-color);
712

813
font-size: 1em;
914
font-synthesis: none;
@@ -19,6 +24,7 @@ body {
1924
a {
2025
text-decoration: none;
2126
color: #3498dbcc;
27+
transition: .2s linear;
2228

2329
&:hover {
2430
text-decoration: underline;
@@ -28,8 +34,8 @@ a {
2834

2935
@media (prefers-color-scheme: light) {
3036
:root {
31-
color: #242424;
32-
background-color: rgba(255, 255, 255, 0.87);
37+
color: var(--background-color);
38+
background-color: var(--text-color);
3339
}
3440
}
3541

src/pages/TimerCountdown.page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useLocation, useNavigate } from "react-router-dom";
55
import routes from "../routes";
66
import BitButton from "../components/BitButton.component";
77
import BitCounter from "../BitCounter";
8+
import EditableTitle from "../components/EditableTitle.component";
89
import { Button, ButtonType } from "../components/Button.component";
910
import { useMuteContext } from "../hooks/useMuteContext.hook";
1011

@@ -120,7 +121,7 @@ function TimerCountdown() {
120121
/>
121122
<div className="flex flex-col items-center justify-center text-center">
122123
<div className="flex flex-col items-center justify-center text-center">
123-
<h1 className="text-5xl uppercase mb-8">Please stand by</h1>
124+
<EditableTitle />
124125
<div className="flex flex-row justify-center align-center flex-wrap mt-8">
125126
{refs.map((_, index) => (
126127
<BitButton

0 commit comments

Comments
 (0)