Skip to content

Instantly share code, notes, and snippets.

@funkybob
Created August 13, 2019 22:21
Show Gist options
  • Save funkybob/5d74e52feae3e2dfc3ba370172cb09c2 to your computer and use it in GitHub Desktop.
Save funkybob/5d74e52feae3e2dfc3ba370172cb09c2 to your computer and use it in GitHub Desktop.
<svelte:options tag="my-todo" />
<h1>Todos Svelte</h1>
<section>
<TodoInput on:add={addTodo}></TodoInput>
<ul id="list-container">
{#each items as item, index (item.id)}
<TodoItem
bind:checked={item.checked}
bind:text={item.text}
on:remove={() => removeTodo(index)}
></TodoItem>
{/each}
</ul>
</section>
<style>
:host {
display: block;
}
h1 {
font-size: 100px;
font-weight: 100;
text-align: center;
color: rgba(175, 47, 47, 0.15);
}
section {
background: #fff;
margin: 30px 0 40px 0;
position: relative;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
#list-container {
margin: 0;
padding: 0;
list-style: none;
border-top: 1px solid #e6e6e6;
}
</style>
<script>
import TodoInput from './TodoInput.html';
import TodoItem from './TodoItem.html';
let uid = 1;
let items = [
{ id: uid++, checked: false, text: 'my initial todo' },
{ id: uid++, checked: true, text: 'Learn about Web Components' }
];
function addTodo (evt) {
let text = evt.detail;
items = [...items, { id: uid++, text, checked: false, }];
};
function removeTodo (index) {
items = [...items.slice(0, index), ...items.slice(index + 1)];
};
</script>
<svelte:options tag="todo-input" />
<form on:submit|preventDefault={handleOnSubmit}>
<input bind:value placeholder="What needs to be done?"/>
</form>
<style>
:host {
display: block;
}
form {
position: relative;
font-size: 24px;
border-bottom: 1px solid #ededed;
}
input {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.003);
position: relative;
margin: 0;
width: 100%;
font-size: 24px;
font-family: inherit;
font-weight: inherit;
line-height: 1.4em;
border: 0;
outline: none;
color: inherit;
padding: 6px;
border: 1px solid #CCC;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
box-sizing: border-box;
}
</style>
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
let value = '';
function handleOnSubmit () {
if (!value) return;
dispatch('add', value);
value = '';
};
</script>
<svelte:options tag="todo-item" />
<li class={ checked ? 'completed' : '' }>
<input type="checkbox" bind:checked />
<label>{text}</label>
<button on:click|preventDefault={handleOnRemove}>x</button>
</li>
<style>
:host {
display: block;
}
li {
font-size: 24px;
display: block;
position: relative;
border-bottom: 1px solid #ededed;
}
li input {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 9px;
bottom: 0;
margin: auto 0;
border: none;
/* Mobile Safari */
-webkit-appearance: none;
appearance: none;
padding: 0;
box-shadow: none;
}
li input:after {
content: url('data:image/svg+xml;utf8,<svg%20xmlns%3D"http%3A//www.w3.org/2000/svg"%20width%3D"40"%20height%3D"40"%20viewBox%3D"-10%20-18%20100%20135"><circle%20cx%3D"50"%20cy%3D"50"%20r%3D"50"%20fill%3D"none"%20stroke%3D"%23ededed"%20stroke-width%3D"3"/></svg>');
}
li input:checked:after {
content: url('data:image/svg+xml;utf8,<svg%20xmlns%3D"http%3A//www.w3.org/2000/svg"%20width%3D"40"%20height%3D"40"%20viewBox%3D"-10%20-18%20100%20135"><circle%20cx%3D"50"%20cy%3D"50"%20r%3D"50"%20fill%3D"none"%20stroke%3D"%23bddad5"%20stroke-width%3D"3"/><path%20fill%3D"%235dc2af"%20d%3D"M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z"/></svg>');
}
li label {
white-space: pre;
word-break: break-word;
padding: 15px 60px 15px 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
transition: color 0.4s;
}
li.completed label {
color: #d9d9d9;
text-decoration: line-through;
}
li button,
li input[type="checkbox"] {
outline: none;
}
li button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
font-weight: inherit;
color: inherit;
-webkit-appearance: none;
appearance: none;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
font-smoothing: antialiased;
}
li button {
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 30px;
color: #cc9a9a;
margin-bottom: 11px;
transition: color 0.2s ease-out;
}
li button:hover {
color: #af5b5e;
}
</style>
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
export let checked;
export let text;
function handleOnRemove () {
dispatch('remove');
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment