Skip to content

Instantly share code, notes, and snippets.

@simonw
Created December 19, 2024 20:11
Show Gist options
  • Save simonw/e27409c6ca86a68dba7aae9a3fc65a88 to your computer and use it in GitHub Desktop.
Save simonw/e27409c6ca86a68dba7aae9a3fc65a88 to your computer and use it in GitHub Desktop.

Distraction-free Writing Interface with Auto-Save

human (Dec 19, 2024, 12:09 PM)

artifact that gives me a large textarea for writing in which constantly saves what I have entered to localStorage (restoring when I reload the page) and displays a word counter

assistant (Dec 19, 2024, 12:10 PM)

I'll create a simple but effective writing interface with auto-save and word count functionality.

create Writing interface with auto-save

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Writing interface</title>
<style>
* {
  box-sizing: border-box;
}

body {
  font-family: Helvetica, Arial, sans-serif;
  margin: 0;
  padding: 20px;
  background: #f5f5f5;
}

.container {
  max-width: 800px;
  margin: 0 auto;
}

h1 {
  color: #333;
  margin-bottom: 20px;
}

.writing-area {
  width: 100%;
  min-height: 400px;
  padding: 20px;
  margin-bottom: 15px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: white;
  font-size: 16px;
  line-height: 1.5;
  resize: vertical;
}

.stats {
  color: #666;
  font-size: 14px;
}

.save-status {
  color: #888;
  font-style: italic;
  margin-left: 15px;
}
</style>
</head>
<body>
<div class="container">
  <h1>Writing space</h1>
  <textarea class="writing-area" placeholder="Start writing here..."></textarea>
  <div class="stats">
    Words: <span id="wordCount">0</span>
    <span class="save-status" id="saveStatus"></span>
  </div>
</div>

<script type="module">
const STORAGE_KEY = 'writing-content'
const textarea = document.querySelector('.writing-area')
const wordCountElement = document.getElementById('wordCount')
const saveStatus = document.getElementById('saveStatus')

let saveTimeout

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

function updateWordCount() {
  const count = countWords(textarea.value)
  wordCountElement.textContent = count
}

function showSavedStatus() {
  saveStatus.textContent = 'Saved'
  setTimeout(() => {
    saveStatus.textContent = ''
  }, 2000)
}

function saveToLocalStorage() {
  localStorage.setItem(STORAGE_KEY, textarea.value)
  showSavedStatus()
}

function debouncedSave() {
  clearTimeout(saveTimeout)
  saveStatus.textContent = 'Saving...'
  saveTimeout = setTimeout(saveToLocalStorage, 1000)
}

// Load saved content
const savedContent = localStorage.getItem(STORAGE_KEY)
if (savedContent) {
  textarea.value = savedContent
  updateWordCount()
}

// Event listeners
textarea.addEventListener('input', () => {
  updateWordCount()
  debouncedSave()
})

textarea.addEventListener('paste', () => {
  setTimeout(updateWordCount, 0)
})
</script>
</body>
</html>

I've created a clean and simple writing interface with the following features:

  1. A large textarea that automatically saves to localStorage after 1 second of inactivity
  2. Word counter that updates in real-time
  3. Save status indicator that shows when content is being saved or has been saved
  4. Content restoration on page reload
  5. Mobile-friendly design with proper font sizing
  6. Clean, minimal styling with good contrast

The interface uses vanilla JavaScript with no dependencies and follows the requested styling conventions. Let me know if you'd like any adjustments to the layout or functionality!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment