akhaliq HF Staff commited on
Commit
2cfb5d6
·
verified ·
1 Parent(s): 150e09e

Upload src/App.svelte with huggingface_hub

Browse files
Files changed (1) hide show
  1. src/App.svelte +243 -37
src/App.svelte CHANGED
@@ -1,47 +1,253 @@
 
1
  <script lang="ts">
2
- import svelteLogo from './assets/svelte.svg'
3
- import viteLogo from '/vite.svg'
4
- import Counter from './lib/Counter.svelte'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  </script>
6
 
7
- <main>
8
- <div>
9
- <a href="https://vite.dev" target="_blank" rel="noreferrer">
10
- <img src={viteLogo} class="logo" alt="Vite Logo" />
11
- </a>
12
- <a href="https://svelte.dev" target="_blank" rel="noreferrer">
13
- <img src={svelteLogo} class="logo svelte" alt="Svelte Logo" />
14
- </a>
15
- </div>
16
- <h1>Vite + Svelte</h1>
17
-
18
- <div class="card">
19
- <Counter />
20
- </div>
21
-
22
- <p>
23
- Check out <a href="https://github.com/sveltejs/kit#readme" target="_blank" rel="noreferrer">SvelteKit</a>, the official Svelte app framework powered by Vite!
24
- </p>
25
-
26
- <p class="read-the-docs">
27
- Click on the Vite and Svelte logos to learn more
28
- </p>
29
- </main>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  <style>
32
- .logo {
33
- height: 6em;
34
- padding: 1.5em;
35
- will-change: filter;
36
- transition: filter 300ms;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
38
- .logo:hover {
39
- filter: drop-shadow(0 0 2em #646cffaa);
 
40
  }
41
- .logo.svelte:hover {
42
- filter: drop-shadow(0 0 2em #ff3e00aa);
 
43
  }
44
- .read-the-docs {
 
 
45
  color: #888;
46
  }
47
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- src/App.svelte content here -->
2
  <script lang="ts">
3
+ import { onMount } from 'svelte';
4
+
5
+ interface Todo {
6
+ id: number;
7
+ text: string;
8
+ completed: boolean;
9
+ }
10
+
11
+ let todos: Todo[] = [];
12
+ let newTodo = '';
13
+ let nextId = 1;
14
+
15
+ onMount(() => {
16
+ const savedTodos = localStorage.getItem('todos');
17
+ if (savedTodos) {
18
+ todos = JSON.parse(savedTodos);
19
+ nextId = todos.length > 0 ? Math.max(...todos.map(t => t.id)) + 1 : 1;
20
+ }
21
+ });
22
+
23
+ $: localStorage.setItem('todos', JSON.stringify(todos));
24
+
25
+ function addTodo() {
26
+ if (newTodo.trim() === '') return;
27
+
28
+ todos = [...todos, {
29
+ id: nextId++,
30
+ text: newTodo.trim(),
31
+ completed: false
32
+ }];
33
+
34
+ newTodo = '';
35
+ }
36
+
37
+ function toggleTodo(id: number) {
38
+ todos = todos.map(todo =>
39
+ todo.id === id ? { ...todo, completed: !todo.completed } : todo
40
+ );
41
+ }
42
+
43
+ function deleteTodo(id: number) {
44
+ todos = todos.filter(todo => todo.id !== id);
45
+ }
46
+
47
+ function handleKeyPress(event: KeyboardEvent) {
48
+ if (event.key === 'Enter') {
49
+ addTodo();
50
+ }
51
+ }
52
  </script>
53
 
54
+ <div class="app">
55
+ <header>
56
+ <h1>Todo App</h1>
57
+ </header>
58
+
59
+ <main>
60
+ <div class="input-container">
61
+ <input
62
+ type="text"
63
+ bind:value={newTodo}
64
+ on:keydown={handleKeyPress}
65
+ placeholder="Add a new todo..."
66
+ aria-label="Add a new todo"
67
+ />
68
+ <button on:click={addTodo} class="add-btn" disabled={!newTodo.trim()}>
69
+ Add
70
+ </button>
71
+ </div>
72
+
73
+ <div class="todos-container">
74
+ {#if todos.length === 0}
75
+ <p class="empty-state">No todos yet. Add one above!</p>
76
+ {:else}
77
+ <ul class="todos-list" role="list">
78
+ {#each todos as todo (todo.id)}
79
+ <li class="todo-item" class:completed={todo.completed}>
80
+ <input
81
+ type="checkbox"
82
+ checked={todo.completed}
83
+ on:change={() => toggleTodo(todo.id)}
84
+ aria-label={todo.completed ? `Mark ${todo.text} as incomplete` : `Mark ${todo.text} as complete`}
85
+ />
86
+ <span class="todo-text">{todo.text}</span>
87
+ <button
88
+ class="delete-btn"
89
+ on:click={() => deleteTodo(todo.id)}
90
+ aria-label={`Delete ${todo.text}`}
91
+ >
92
+ ×
93
+ </button>
94
+ </li>
95
+ {/each}
96
+ </ul>
97
+ {/if}
98
+ </div>
99
+
100
+ {#if todos.length > 0}
101
+ <div class="stats">
102
+ <span>{todos.filter(t => !t.completed).length} remaining</span>
103
+ <span>{todos.filter(t => t.completed).length} completed</span>
104
+ </div>
105
+ {/if}
106
+ </main>
107
+ </div>
108
 
109
  <style>
110
+ .app {
111
+ max-width: 600px;
112
+ margin: 0 auto;
113
+ padding: 2rem 1rem;
114
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
115
+ }
116
+
117
+ header {
118
+ text-align: center;
119
+ margin-bottom: 2rem;
120
+ }
121
+
122
+ h1 {
123
+ color: #333;
124
+ font-weight: 600;
125
+ }
126
+
127
+ .input-container {
128
+ display: flex;
129
+ gap: 0.5rem;
130
+ margin-bottom: 2rem;
131
+ }
132
+
133
+ input {
134
+ flex: 1;
135
+ padding: 0.75rem;
136
+ border: 2px solid #ddd;
137
+ border-radius: 4px;
138
+ font-size: 1rem;
139
+ }
140
+
141
+ input:focus {
142
+ outline: none;
143
+ border-color: #4a90e2;
144
+ }
145
+
146
+ .add-btn {
147
+ padding: 0.75rem 1.5rem;
148
+ background-color: #4a90e2;
149
+ color: white;
150
+ border: none;
151
+ border-radius: 4px;
152
+ font-size: 1rem;
153
+ cursor: pointer;
154
+ transition: background-color 0.2s;
155
+ }
156
+
157
+ .add-btn:hover:not(:disabled) {
158
+ background-color: #357abd;
159
+ }
160
+
161
+ .add-btn:disabled {
162
+ background-color: #ccc;
163
+ cursor: not-allowed;
164
+ }
165
+
166
+ .todos-container {
167
+ min-height: 200px;
168
+ }
169
+
170
+ .empty-state {
171
+ text-align: center;
172
+ color: #777;
173
+ font-style: italic;
174
+ padding: 2rem;
175
+ }
176
+
177
+ .todos-list {
178
+ list-style: none;
179
+ padding: 0;
180
+ margin: 0;
181
+ }
182
+
183
+ .todo-item {
184
+ display: flex;
185
+ align-items: center;
186
+ padding: 1rem;
187
+ border-bottom: 1px solid #eee;
188
+ gap: 1rem;
189
+ transition: background-color 0.2s;
190
  }
191
+
192
+ .todo-item:hover {
193
+ background-color: #f9f9f9;
194
  }
195
+
196
+ .todo-item.completed {
197
+ opacity: 0.7;
198
  }
199
+
200
+ .todo-item.completed .todo-text {
201
+ text-decoration: line-through;
202
  color: #888;
203
  }
204
+
205
+ .todo-text {
206
+ flex: 1;
207
+ font-size: 1.1rem;
208
+ }
209
+
210
+ .delete-btn {
211
+ background: none;
212
+ border: none;
213
+ color: #e74c3c;
214
+ font-size: 1.5rem;
215
+ cursor: pointer;
216
+ width: 36px;
217
+ height: 36px;
218
+ display: flex;
219
+ align-items: center;
220
+ justify-content: center;
221
+ border-radius: 50%;
222
+ transition: background-color 0.2s;
223
+ }
224
+
225
+ .delete-btn:hover {
226
+ background-color: rgba(231, 76, 60, 0.1);
227
+ }
228
+
229
+ .stats {
230
+ display: flex;
231
+ justify-content: space-between;
232
+ margin-top: 1.5rem;
233
+ padding: 1rem;
234
+ background-color: #f5f5f5;
235
+ border-radius: 4px;
236
+ font-size: 0.9rem;
237
+ color: #555;
238
+ }
239
+
240
+ @media (max-width: 600px) {
241
+ .app {
242
+ padding: 1rem;
243
+ }
244
+
245
+ .input-container {
246
+ flex-direction: column;
247
+ }
248
+
249
+ .add-btn {
250
+ padding: 0.75rem;
251
+ }
252
+ }
253
+ </style>