Skip to content

Commit 6a5b825

Browse files
committed
feat: implemented demo page
1 parent 46369a6 commit 6a5b825

4 files changed

Lines changed: 148 additions & 10 deletions

File tree

lib/ContentEditable.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ const ContentEditable: React.FC<ContentEditableProps> = ({
3333
const divRef = useRef<HTMLDivElement | null>(null)
3434

3535
useEffect(() => {
36-
if (updatedContent) {
36+
if (updatedContent !== null && updatedContent !== undefined) {
3737
setContent(updatedContent)
38+
if (divRef.current) divRef.current.innerText = updatedContent
3839
if (onContentExternalUpdate) onContentExternalUpdate(updatedContent)
3940
}
4041
}, [updatedContent, onContentExternalUpdate])

src/App.css

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,45 @@
1+
.full-width {
2+
width: 100%;
3+
}
4+
.falsy {
5+
color: red;
6+
}
7+
.truthy {
8+
color: green;
9+
}
10+
111
.main-container {
2-
padding: 3rem;
12+
min-height: 100vh;
313
display: flex;
4-
justify-content: center;
14+
flex-direction: column;
15+
justify-content: flex-end;
516
align-items: center;
617
}
7-
.full-width {
8-
width: 100%;
18+
.message-history-container {
19+
display: flex;
20+
flex-direction: column;
21+
gap: 1rem;
22+
margin: 2rem 0;
23+
flex: 1;
24+
overflow: auto;
25+
max-height: 75vh;
26+
}
27+
.message-item {
28+
display: flex;
29+
align-self: flex-start;
30+
padding: 0.85rem 1rem;
31+
border-radius: 0.35rem;
32+
background-color: #eff1f6;
33+
letter-spacing: 0.05ch;
34+
line-height: 1.2;
35+
white-space: pre-wrap;
36+
}
37+
.message-history-container,
38+
.input-container {
39+
padding: 0 3rem;
940
}
41+
1042
.input-container {
11-
padding: 0 1rem;
1243
position: relative;
1344
}
1445
.input-element {
@@ -22,3 +53,37 @@
2253
color: #a2acb4;
2354
margin-left: 1rem;
2455
}
56+
57+
.metrics-section {
58+
display: flex;
59+
justify-content: space-between;
60+
align-items: flex-start;
61+
gap: 2rem;
62+
margin: 2rem -3rem 0;
63+
font-size: 0.875rem;
64+
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
65+
monospace;
66+
border-top: 1px solid #0b57d0;
67+
background-color: #e0e8f6;
68+
padding: 2rem 3rem;
69+
}
70+
.metrics-section__left-box {
71+
display: flex;
72+
flex: 1;
73+
flex-direction: column;
74+
gap: 0.35rem;
75+
}
76+
77+
button {
78+
cursor: pointer;
79+
appearance: none;
80+
border: none;
81+
background-color: #2f6ed3;
82+
color: white;
83+
padding: 0.875rem 1rem;
84+
border-radius: 0.35rem;
85+
letter-spacing: 0.08ch;
86+
}
87+
button:hover {
88+
background-color: #1f4aa8;
89+
}

src/App.tsx

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,89 @@
11
import ContentEditable from "../lib/ContentEditable"
22
import "./App.css"
3-
import { useState } from "react"
3+
import { useEffect, useState } from "react"
44

55
function App() {
6+
const [emptyContent, setEmptyContent] = useState<string | undefined>(
7+
undefined
8+
)
69
const [content, setContent] = useState("")
10+
const [isFocused, setIsFocused] = useState(false)
11+
const [isBlurred, setIsBlurred] = useState(false)
12+
const [keyDown, setKeyDown] = useState("")
13+
const [keyUp, setKeyUp] = useState("")
14+
const [messageHistory, setMessageHistory] = useState<string[]>([
15+
"Type something and press on 'Send' to send another message...",
16+
])
17+
18+
const truncateString = (str: string, limit: number) => {
19+
return str.length > limit ? str.slice(0, limit) + "..." : str
20+
}
21+
22+
useEffect(() => {
23+
setEmptyContent(undefined)
24+
}, [emptyContent])
25+
26+
const saveMessageInHistory = (message: string) => {
27+
setMessageHistory([...messageHistory, message])
28+
setContent("")
29+
setEmptyContent("")
30+
}
31+
732
return (
8-
<div className="main-container full-width">
9-
<div style={{ whiteSpace: "pre-wrap" }}>{content}</div>
33+
<div className="full-width main-container">
34+
<div className="full-width message-history-container">
35+
{messageHistory.map((message, index) => (
36+
<div key={index} className="message-item">
37+
{message}
38+
</div>
39+
))}
40+
</div>
1041
<ContentEditable
1142
placeholder="Type here"
1243
containerClassName="full-width input-container"
1344
contentEditableClassName="full-width input-element"
1445
placeholderClassName="input-placeholder"
46+
updatedContent={emptyContent}
1547
onChange={(content) => setContent(content)}
48+
onFocus={() => {
49+
setIsFocused(true)
50+
setIsBlurred(false)
51+
}}
52+
onBlur={() => {
53+
setIsFocused(false)
54+
setIsBlurred(true)
55+
}}
56+
onKeyDown={(e) => setKeyDown(e.key)}
57+
onKeyUp={(e) => setKeyUp(e.key)}
1658
/>
59+
<div className="full-width metrics-section">
60+
<div className="metrics-section__left-box">
61+
<div>
62+
Content: <b>{truncateString(content, 200)}</b>
63+
</div>
64+
<div>
65+
Is focused:{" "}
66+
<b className={isFocused ? "truthy" : "falsy"}>
67+
{isFocused ? "true" : "false"}
68+
</b>
69+
</div>
70+
<div>
71+
Is blurred:{" "}
72+
<b className={isBlurred ? "truthy" : "falsy"}>
73+
{isBlurred ? "true" : "false"}
74+
</b>
75+
</div>
76+
<div>
77+
Key down: <b>{keyDown}</b>
78+
</div>
79+
<div>
80+
Key up: <b>{keyUp}</b>
81+
</div>
82+
</div>
83+
<div>
84+
<button onClick={() => saveMessageInHistory(content)}>Send</button>
85+
</div>
86+
</div>
1787
</div>
1888
)
1989
}

src/index.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
-webkit-font-smoothing: antialiased;
77
-moz-osx-font-smoothing: grayscale;
88
}
9-
9+
* {
10+
box-sizing: border-box;
11+
}
1012
body {
1113
margin: 0;
1214
display: flex;

0 commit comments

Comments
 (0)