add check boxes
This commit is contained in:
parent
650570c405
commit
fb8578822e
3 changed files with 158 additions and 24 deletions
|
|
@ -15,5 +15,16 @@
|
||||||
You need to enable JavaScript to run this app.
|
You need to enable JavaScript to run this app.
|
||||||
</noscript>
|
</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
<svg viewBox="0 0 0 0" style="position: absolute; z-index: -1; opacity: 0;">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="boxGradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="25" y2="25">
|
||||||
|
<stop offset="0%" stop-color="#27FDC7"></stop>
|
||||||
|
<stop offset="100%" stop-color="#0FC0F5"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<path id="todo__box" stroke="url(#boxGradient)" d="M21 12.7v5c0 1.3-1 2.3-2.3 2.3H8.3C7 20 6 19 6 17.7V7.3C6 6 7 5 8.3 5h10.4C20 5 21 6 21 7.3v5.4"></path>
|
||||||
|
<path id="todo__check" stroke="url(#boxGradient)" d="M10 13l2 2 5-5"></path>
|
||||||
|
<circle id="todo__circle" cx="13.5" cy="12.5" r="10"></circle>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
107
src/App.css
107
src/App.css
|
|
@ -93,6 +93,9 @@
|
||||||
color: #5a5a5a;
|
color: #5a5a5a;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
margin-left: 40px;
|
||||||
|
width: 470px;
|
||||||
}
|
}
|
||||||
.todo-list-title:hover span[contenteditable="false"]:before {
|
.todo-list-title:hover span[contenteditable="false"]:before {
|
||||||
content: 'click to edit';
|
content: 'click to edit';
|
||||||
|
|
@ -123,7 +126,7 @@
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
.todo-list {
|
.todo-list {
|
||||||
padding: 20px;
|
padding: 15px;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
@ -154,7 +157,109 @@
|
||||||
/* Disable Auto Zoom in Input “Text” tag - Safari on iPhone */
|
/* Disable Auto Zoom in Input “Text” tag - Safari on iPhone */
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
.todo-item button {
|
||||||
|
padding: 4px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
.view-src {
|
.view-src {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** todo css via https://codepen.io/shshaw/pen/WXMdwE 😻 */
|
||||||
|
.todo {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
min-height: 40px;
|
||||||
|
min-width: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
.todo__state {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.todo__text {
|
||||||
|
color: #135156;
|
||||||
|
transition: all 0.4s linear 0.4s;
|
||||||
|
}
|
||||||
|
.todo__icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 280px;
|
||||||
|
height: 100%;
|
||||||
|
margin: auto;
|
||||||
|
fill: none;
|
||||||
|
stroke: #27FDC7;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-linejoin: round;
|
||||||
|
stroke-linecap: round;
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo__box,
|
||||||
|
.todo__check {
|
||||||
|
transition: stroke-dashoffset 0.5s cubic-bezier(0.9, 0, 0.5, 1);
|
||||||
|
}
|
||||||
|
.todo__state:checked ~ .todo-list-title {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
.todo__circle {
|
||||||
|
stroke: #27FDC7;
|
||||||
|
stroke-dasharray: 1 6;
|
||||||
|
stroke-width: 0;
|
||||||
|
transform-origin: 13.5px 12.5px;
|
||||||
|
transform: scale(0.4) rotate(0deg);
|
||||||
|
animation: none 0.5s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes explode {
|
||||||
|
30% {
|
||||||
|
stroke-width: 3;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
transform: scale(0.8) rotate(40deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-width: 0;
|
||||||
|
stroke-opacity: 0;
|
||||||
|
transform: scale(1.1) rotate(60deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.todo__box {
|
||||||
|
stroke-dasharray: 56.1053, 56.1053;
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
transition-delay: 0.16s;
|
||||||
|
}
|
||||||
|
.todo__check {
|
||||||
|
stroke: #27FDC7;
|
||||||
|
stroke-dasharray: 9.8995, 9.8995;
|
||||||
|
stroke-dashoffset: 9.8995;
|
||||||
|
transition-duration: 0.32s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo__circle {
|
||||||
|
animation-delay: 0.56s;
|
||||||
|
animation-duration: 0.56s;
|
||||||
|
}
|
||||||
|
.todo__state:checked + .todo__text {
|
||||||
|
transition-delay: 0s;
|
||||||
|
color: #5EBEC1;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
.todo__state:checked ~ .todo__icon .todo__box {
|
||||||
|
stroke-dashoffset: 56.1053;
|
||||||
|
transition-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo__state:checked ~ .todo__icon .todo__check {
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
transition-delay: 0.48s;
|
||||||
|
}
|
||||||
|
.todo__state:checked ~ .todo__icon .todo__circle {
|
||||||
|
animation-name: explode;
|
||||||
|
}
|
||||||
|
|
|
||||||
64
src/App.js
64
src/App.js
|
|
@ -129,6 +129,10 @@ class App extends Component {
|
||||||
console.log('An API error occurred', e)
|
console.log('An API error occurred', e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
handleTodoToggle = (e) => {
|
||||||
|
console.log('checkbox changed')
|
||||||
|
console.log(e.target.checked);
|
||||||
|
}
|
||||||
handleDataChange = (event, currentValue) => {
|
handleDataChange = (event, currentValue) => {
|
||||||
// save on change debounced?
|
// save on change debounced?
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +141,6 @@ class App extends Component {
|
||||||
const key = event.target.dataset.key
|
const key = event.target.dataset.key
|
||||||
|
|
||||||
const updatedTodos = this.state.todos.map((todo, i) => {
|
const updatedTodos = this.state.todos.map((todo, i) => {
|
||||||
const { data, ref } = todo
|
|
||||||
const id = getTodoId(todo)
|
const id = getTodoId(todo)
|
||||||
if (id === key && todo.data.title !== currentValue) {
|
if (id === key && todo.data.title !== currentValue) {
|
||||||
todo.data.title = currentValue
|
todo.data.title = currentValue
|
||||||
|
|
@ -164,21 +167,34 @@ class App extends Component {
|
||||||
let deleteButton
|
let deleteButton
|
||||||
if (ref) {
|
if (ref) {
|
||||||
deleteButton = (
|
deleteButton = (
|
||||||
<button data-id={id} onClick={this.deleteTodo}>delete</button>
|
<button data-id={id} onClick={this.deleteTodo}>
|
||||||
|
delete
|
||||||
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div key={i} className='todo-item'>
|
<div key={i} className='todo-item'>
|
||||||
<div className='todo-list-title'>
|
<label className="todo">
|
||||||
<ContentEditable
|
<input className="todo__state" type="checkbox" onChange={this.handleTodoToggle} />
|
||||||
tagName='span'
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 25" className="todo__icon">
|
||||||
editKey={id}
|
<use xlinkHref="#todo__box" className="todo__box"></use>
|
||||||
onChange={this.handleDataChange} // handle innerHTML change
|
<use xlinkHref="#todo__check" className="todo__check"></use>
|
||||||
onBlur={this.handleBlur} // handle innerHTML change
|
<use xlinkHref="#todo__circle" className="todo__circle"></use>
|
||||||
html={data.title}
|
</svg>
|
||||||
>
|
<div className='todo-list-title'>
|
||||||
</ContentEditable>
|
|
||||||
</div>
|
<ContentEditable
|
||||||
|
tagName='span'
|
||||||
|
editKey={id}
|
||||||
|
onChange={this.handleDataChange} // handle innerHTML change
|
||||||
|
onBlur={this.handleBlur} // handle innerHTML change
|
||||||
|
html={data.title}
|
||||||
|
>
|
||||||
|
</ContentEditable>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
|
||||||
{deleteButton}
|
{deleteButton}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -186,15 +202,15 @@ class App extends Component {
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="app">
|
<div className='app'>
|
||||||
<header className="app-header">
|
<header className='app-header'>
|
||||||
<div className="app-title-wrapper">
|
<div className='app-title-wrapper'>
|
||||||
<div className="app-title-wrapper">
|
<div className='app-title-wrapper'>
|
||||||
<div className='app-left-nav'>
|
<div className='app-left-nav'>
|
||||||
<img src={logo} className="app-logo" alt="logo" />
|
<img src={logo} className='app-logo' alt='logo' />
|
||||||
<div className='app-title-text'>
|
<div className='app-title-text'>
|
||||||
<h1 className="app-title">Netlify + Fauna DB</h1>
|
<h1 className='app-title'>Netlify + Fauna DB</h1>
|
||||||
<p className="app-intro">
|
<p className='app-intro'>
|
||||||
Using FaunaDB & Netlify functions
|
Using FaunaDB & Netlify functions
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -203,14 +219,16 @@ class App extends Component {
|
||||||
<div className='deploy-button-wrapper'>
|
<div className='deploy-button-wrapper'>
|
||||||
<a
|
<a
|
||||||
target='_blank'
|
target='_blank'
|
||||||
href="https://app.netlify.com/start/deploy?repository=https://github.com/netlify/netlify-faunadb-example">
|
rel='noopener noreferrer'
|
||||||
<img src={deployButton} className="deploy-button" alt="deploy to netlify" />
|
href='https://app.netlify.com/start/deploy?repository=https://github.com/netlify/netlify-faunadb-example'>
|
||||||
|
<img src={deployButton} className='deploy-button' alt='deploy to netlify' />
|
||||||
</a>
|
</a>
|
||||||
<div className='view-src'>
|
<div className='view-src'>
|
||||||
<a
|
<a
|
||||||
target='_blank'
|
target='_blank'
|
||||||
href="https://github.com/netlify/netlify-faunadb-example">
|
rel='noopener noreferrer'
|
||||||
<img className='github-icon' src={github} /> View the source Luke
|
href='https://github.com/netlify/netlify-faunadb-example'>
|
||||||
|
<img className='github-icon' src={github} alt='view repo on github' /> View the source Luke
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue