Skip to content

Commit 98408bd

Browse files
authored
1 parent e831d3b commit 98408bd

File tree

1 file changed

+130
-34
lines changed

1 file changed

+130
-34
lines changed

word-counter.html

+130-34
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,17 @@
2626
margin-bottom: 20px;
2727
}
2828

29+
.writing-section {
30+
margin-bottom: 30px;
31+
background: white;
32+
padding: 20px;
33+
border-radius: 4px;
34+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
35+
}
36+
2937
.writing-area {
3038
width: 100%;
31-
min-height: 400px;
39+
min-height: 200px;
3240
padding: 20px;
3341
margin-bottom: 15px;
3442
border: 1px solid #ccc;
@@ -39,6 +47,12 @@
3947
resize: vertical;
4048
}
4149

50+
.controls {
51+
display: flex;
52+
justify-content: space-between;
53+
align-items: center;
54+
}
55+
4256
.stats {
4357
color: #666;
4458
font-size: 14px;
@@ -49,68 +63,150 @@
4963
font-style: italic;
5064
margin-left: 15px;
5165
}
66+
67+
.add-btn {
68+
background-color: #4CAF50;
69+
color: white;
70+
padding: 8px 16px;
71+
border: none;
72+
border-radius: 4px;
73+
font-size: 14px;
74+
cursor: pointer;
75+
transition: background-color 0.2s;
76+
}
77+
78+
.add-btn:hover {
79+
background-color: #45a049;
80+
}
81+
82+
.remove-btn {
83+
background-color: #ff4444;
84+
color: white;
85+
padding: 8px 16px;
86+
border: none;
87+
border-radius: 4px;
88+
font-size: 14px;
89+
cursor: pointer;
90+
transition: background-color 0.2s;
91+
}
92+
93+
.remove-btn:hover {
94+
background-color: #ff6666;
95+
}
5296
</style>
5397
</head>
5498
<body>
5599
<div class="container">
56100
<h1>Word counter</h1>
57-
<textarea class="writing-area" placeholder="Start writing here..."></textarea>
58-
<div class="stats">
59-
Words: <span id="wordCount">0</span>
60-
<span class="save-status" id="saveStatus"></span>
61-
</div>
101+
<div id="writing-container"></div>
102+
<button class="add-btn" id="addSection">Add new section</button>
62103
</div>
63104

64105
<script type="module">
65-
const STORAGE_KEY = 'writing-content'
66-
const textarea = document.querySelector('.writing-area')
67-
const wordCountElement = document.getElementById('wordCount')
68-
const saveStatus = document.getElementById('saveStatus')
106+
const STORAGE_KEY = 'writing-sections'
107+
const container = document.getElementById('writing-container')
108+
const addButton = document.getElementById('addSection')
109+
110+
let saveTimeouts = new Map()
69111

70-
let saveTimeout
112+
function generateId() {
113+
return Date.now().toString(36) + Math.random().toString(36).substr(2)
114+
}
115+
116+
function createSection(id, content = '') {
117+
const section = document.createElement('div')
118+
section.className = 'writing-section'
119+
section.dataset.id = id
120+
121+
section.innerHTML = `
122+
<textarea class="writing-area" placeholder="Start writing here...">${content}</textarea>
123+
<div class="controls">
124+
<div class="stats">
125+
Words: <span class="word-count">0</span>
126+
<span class="save-status"></span>
127+
</div>
128+
<button class="remove-btn">Remove</button>
129+
</div>
130+
`
131+
132+
const textarea = section.querySelector('textarea')
133+
const wordCount = section.querySelector('.word-count')
134+
const saveStatus = section.querySelector('.save-status')
135+
const removeBtn = section.querySelector('.remove-btn')
136+
137+
updateWordCount(textarea, wordCount)
138+
139+
textarea.addEventListener('input', () => {
140+
updateWordCount(textarea, wordCount)
141+
debouncedSave()
142+
})
143+
144+
removeBtn.addEventListener('click', () => {
145+
section.remove()
146+
debouncedSave()
147+
})
148+
149+
return section
150+
}
71151

72152
function countWords(text) {
73153
return text.trim() ? text.trim().split(/\s+/).length : 0
74154
}
75155

76-
function updateWordCount() {
156+
function updateWordCount(textarea, wordCountElement) {
77157
const count = countWords(textarea.value)
78158
wordCountElement.textContent = count
79159
}
80160

81-
function showSavedStatus() {
82-
saveStatus.textContent = 'Saved'
83-
setTimeout(() => {
84-
saveStatus.textContent = ''
85-
}, 2000)
86-
}
87-
88161
function saveToLocalStorage() {
89-
localStorage.setItem(STORAGE_KEY, textarea.value)
90-
showSavedStatus()
162+
const sectionsData = Array.from(container.children).map(section => ({
163+
id: section.dataset.id,
164+
content: section.querySelector('textarea').value
165+
}))
166+
localStorage.setItem(STORAGE_KEY, JSON.stringify(sectionsData))
167+
168+
// Update save status for all sections
169+
document.querySelectorAll('.save-status').forEach(status => {
170+
status.textContent = 'Saved'
171+
setTimeout(() => {
172+
status.textContent = ''
173+
}, 2000)
174+
})
91175
}
92176

93177
function debouncedSave() {
94-
clearTimeout(saveTimeout)
95-
saveStatus.textContent = 'Saving...'
96-
saveTimeout = setTimeout(saveToLocalStorage, 1000)
178+
// Clear any existing save timeout
179+
if (saveTimeouts.has('save')) {
180+
clearTimeout(saveTimeouts.get('save'))
181+
}
182+
183+
// Show 'Saving...' status
184+
document.querySelectorAll('.save-status').forEach(status => {
185+
status.textContent = 'Saving...'
186+
})
187+
188+
// Set new save timeout
189+
saveTimeouts.set('save', setTimeout(() => {
190+
saveTimeouts.delete('save')
191+
saveToLocalStorage()
192+
}, 1000))
97193
}
98194

99195
// Load saved content
100196
const savedContent = localStorage.getItem(STORAGE_KEY)
101197
if (savedContent) {
102-
textarea.value = savedContent
103-
updateWordCount()
198+
const savedSections = JSON.parse(savedContent)
199+
savedSections.forEach(section => {
200+
const newSection = createSection(section.id, section.content)
201+
container.appendChild(newSection)
202+
})
104203
}
105204

106-
// Event listeners
107-
textarea.addEventListener('input', () => {
108-
updateWordCount()
109-
debouncedSave()
110-
})
111-
112-
textarea.addEventListener('paste', () => {
113-
setTimeout(updateWordCount, 0)
205+
// Add new section button handler
206+
addButton.addEventListener('click', () => {
207+
const newSection = createSection(generateId())
208+
container.appendChild(newSection)
209+
newSection.querySelector('textarea').focus()
114210
})
115211
</script>
116212
</body>

0 commit comments

Comments
 (0)