Last active
January 4, 2017 22:18
-
-
Save zzarcon/cad6e94c103f0f6912e2d269647c38ce to your computer and use it in GitHub Desktop.
Component: behavior + events
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** @jsx h */ | |
import 'skatejs-web-components'; | |
import { Component, h } from 'skatejs'; | |
import styles from './styles'; | |
class SKTags extends Component { | |
static props = { | |
delimiter: prop.string({attribute: true, default: ' '}), | |
tags: prop.array({attribute: true}), | |
} | |
renderCallback() { | |
const tagElements = this.tags.map(t => <span class="tag">{t}</span>); | |
return <div> | |
<style>{styles}</style> | |
<div class='wrapper' onclick={this.onWrapperClick}> | |
<span class='tags'>{tagElements}</span> | |
<input type="text" oninput={this.onInput} onkeydown={this.onKeydown} autofocus="true" class= 'input'/> | |
</div> | |
</div> | |
} | |
onWrapperClick = e => { | |
this.focusInput(); | |
} | |
focusInput() { | |
this.shadowRoot.querySelector('.input').focus(); | |
} | |
onKeydown = e => { | |
const value = e.target.value; | |
const isDel = e.keyCode === deleteCode; | |
if (isDel && value.length <= 0) { | |
this.removeTag(); | |
} | |
} | |
onInput = e => { | |
const lastChar = e.target.value.substr(-1); | |
const value = e.target.value.slice(0, -1).trim(); | |
const isDelimiter = lastChar === this.delimiter; | |
if (value && isDelimiter) { | |
this.addTag(value); | |
e.target.value = ''; | |
} | |
this.adjustInputSize(e.target.value.length); | |
} | |
adjustInputSize(textLength) { | |
const input = this.shadowRoot.querySelector('.input'); | |
const width = (textLength * 13) + 6; | |
input.style.width = `${width}px`; | |
} | |
addTag(value) { | |
this.tags = this.tags.concat(value); | |
} | |
} | |
customElements.define('sk-tags', SKTags); |
You can clean up the code if you're willing to use some ES2016 features such as property initialisers. For example, you can simplify props
and all your event handlers:
class SKTags extends Component {
// So you don't have to do a getter.
static props = {}
// Auto-binds the method to `this` so it can be passed off
// as `oninput={this.onInput}`.
onInput = e => {
const lastChar = this.value.substr(-1);
const value = this.value.slice(0, -1).trim();
const isDelimiter = lastChar === component.delimiter;
if (value && isDelimiter) {
component.addTag(value);
this.value = '';
}
component.adjustInputSize(this.value.length);
}
}
@treshugart your suggestions make a lot of sense, already applied the changes, it looks easier to read now.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I would make use of the built-in props where possible. For
delimiter
you can useprop.string({ attribute: true, default: ' ' })
. Fortags
you can useprop.array({ attribute: true })
. However, that assumes a JSON array. If you don't want that, then your custom prop is fine, but usingprop.array()
would simplify the example for the readers.