Skip to content

Instantly share code, notes, and snippets.

@leandrohsilveira
Last active December 17, 2018 13:28
Show Gist options
  • Save leandrohsilveira/8b2b314bd93916da7e71b919a6bc601a to your computer and use it in GitHub Desktop.
Save leandrohsilveira/8b2b314bd93916da7e71b919a6bc601a to your computer and use it in GitHub Desktop.
Make riot.js observables more friendly
import './trigger.tag';
import './message.tag';
<app>
<trigger />
<message />
</app>
import riot from 'riot';
import './app.tag';
document.addEventListener('DOMContentLoaded', () => {
riot.mount('*');
});
import Observable from './observable';
const messageObservable = new Observable();
export default messageObservable;
import messageObservable from './message';
<message>
<div class={'message': true, 'show': !!description}>
<div class="description">{description}</div>
<button type="button" onclick={handleDismissClick}>Dismiss</button>
</div>
<script>
this.description = null;
this.timeout = null;
this.handleDismissClick = () => {
messageObservable.next();
}
messageObservable.subscribe(this, description => {
if(this.timeout) {
clearTimeout(this.timeout);
}
this.update({
description,
timeout: description && setTimeout(() => this.handleDismissClick(), opts.dismissTime || 5000)
});
});
</script>
<style>
:scope * {
box-sizing: border-box;
}
:scope > .message {
display: flex;
align-items: center;
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 0;
background-color: black;
color: #9A46C5;
transition: height 0.5s;
}
:scope > .message > * {
display: none;
}
:scope > .message.show {
height: 7rem;
padding: 0 3rem;
}
:scope > .message.show > * {
display: block;
}
:scope > .message > button {
margin-bottom: 0;
padding: 0 1rem;
}
:scope > .message > .description {
color: white;
flex: 1;
}
</style>
</message>
import riot from 'riot';
function Observable(initialValue) {
riot.observable(this);
this.value = initialValue;
this.next = (value) => {
this.value = value;
this.trigger('next', this.value);
};
this.subscribe = (instance, fn) => {
instance.on('mount', () => {
this.on('next', onNext);
fn(this.value)
});
instance.on('unmount', () => {
this.off('next', onNext);
});
function onNext(value) {
fn(value);
}
}
}
export default Observable;
import messageObservable from './message';
<trigger>
<div>
<form onsubmit={showMessage}>
<input type="text" ref="message" value="I'm a default message!">
<button type="submit">Display the message!</button>
</form>
</div>
<script>
this.showMessage = (e) => {
e.preventDefault();
messageObservable.next(this.refs.message.value);
};
</script>
</trigger>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment