Skip to content

Instantly share code, notes, and snippets.

@krukid
Last active September 26, 2019 00:07
Show Gist options
  • Save krukid/909b5af87ffcd91e0faa3a53469faa79 to your computer and use it in GitHub Desktop.
Save krukid/909b5af87ffcd91e0faa3a53469faa79 to your computer and use it in GitHub Desktop.
mint-toast-v2
import Component from '@ember/component';
import { computed } from '@ember/object';
import { later, next } from '@ember/runloop';
import $ from 'jquery';
const TEMP_DELAY = 3000;
const SLIDE_DELAY = 300;
const FADE_IN_DELAY = SLIDE_DELAY * 1.3;
const FADE_OUT_DELAY = SLIDE_DELAY * 0.7;
const TYPE_CLASS = {
success: 'mint-toast__item--success',
failure: 'mint-toast__item--failure',
warning: 'mint-toast__item--warning',
default: 'mint-toast__item--default',
};
// @prop item
// @prop onResolve(item, result)
export default Component.extend({
classNames: ['mint-toast__item-outer'],
typeClass: computed('item.type', function() {
return TYPE_CLASS[this.item.type] || TYPE_CLASS.default;
}),
fadeIn() {
$(this.element)
.animate({opacity: 1}, {
duration: FADE_IN_DELAY,
queue: false,
})
.slideDown(SLIDE_DELAY);
},
fadeOut(result) {
$(this.element)
.animate({opacity: 0}, {
duration: FADE_OUT_DELAY,
queue: false,
})
.slideUp(SLIDE_DELAY, () => {
next(() => this.onResolve(this.item, result));
});
},
didInsertElement() {
this.fadeIn();
if (!this.item.performLabel) {
later(() => this.fadeOut('expire'), TEMP_DELAY);
}
},
actions: {
dismiss() {
this.fadeOut('dismiss');
},
perform() {
this.fadeOut('perform');
},
},
});
import Component from '@ember/component';
import { inject as service } from '@ember/service';
export default Component.extend({
classNames: ['mint-toast'],
mintToast: service(),
actions: {
onResolve(item, result) {
this.mintToast.resolveItem(item, result);
},
},
});
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default Controller.extend({
mintToast: service(),
actions: {
// @note random contextual toast from about page
async pushItem() {
const result = await this.mintToast.pushRandomItem();
console.log('[about] item has closed with result', result);
},
},
});
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default Controller.extend({
appName: 'Ember Twiddle',
// @note only needed for toast debug counter
mintToast: service(),
});
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default Controller.extend({
mintToast: service(),
actions: {
// @note random contextual toast from home page
async pushItem() {
const result = await this.mintToast.pushRandomItem();
console.log('[home] item has closed with result', result);
},
// @note complex action toast with follow-up
async dummyCreate() {
const result = await this.mintToast.pushItem({
text: 'Are you sure you want to create blah blah?',
type: 'warning',
performLabel: 'Yes',
});
console.log('[home] item has closed with result', result);
if (result === 'perform') {
return this.mintToast.pushItem({
text: 'Blah blah was created successfully! 🤪',
type: 'success',
});
}
return this.mintToast.pushItem({
text: 'You have changed your mind about creating blah blah! 😱',
type: 'failure',
});
},
},
});
import EmberRouter from '@ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: 'none',
rootURL: config.rootURL,
});
Router.map(function() {
this.route('about');
});
export default Router;
import Service from '@ember/service';
export default Service.extend({
items: null,
id: 0,
init() {
this._super(...arguments);
this.set('items', []);
},
// @note for debugging only
pushRandomItem() {
const performLabel = Math.random() < 0.5 && 'Reload';
const typeSeed = Math.random();
const type =
typeSeed < 0.25 ? 'success' :
typeSeed < 0.50 ? 'failure' :
typeSeed < 0.75 ? 'warning' : 'default';
const text = `${type} item ${this.id}`;
return this.pushItem({text, type, performLabel});
},
// @required item
// @required .text string
// @optional .type enum {success|failure|warning|default}
// @optional .action string
//
pushItem(item) {
return new Promise(resolve => {
const id = this.incrementProperty('id');
this.items.pushObject({...item, id, resolve});
});
},
resolveItem(item, result) {
this.items.removeObject(item);
item.resolve(result);
},
});
@import 'https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/css/uikit.min.css';
body {
margin: 0;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
}
.mint-toast {
position: fixed;
bottom: 0;
left: 0;
right: 0;
}
.mint-toast__item-outer {
padding: 0 10px 10px;
display: none;
opacity: 0;
}
.mint-toast__item-inner {
padding: 4px 10px;
}
.mint-toast__item--default {
background: rgba(0,0,0,0.8);
color: white;
}
.mint-toast__item--success {
background: rgba(0,255,0,0.8);
color: white;
}
.mint-toast__item--warning {
background: rgba(255,192,0,0.8);
color: white;
}
.mint-toast__item--failure {
background: rgba(255,0,0,0.8);
color: white;
}
<h1 class="uk-heading-small">About this Demo</h1>
<p>
<button {{action "pushItem"}} class="uk-button uk-button-default uk-width-medium">
Push from About
</button>
</p>
{{mint-toast}}
<nav class="uk-navbar-container">
<div class="uk-navbar-left">
<ul class="uk-navbar-nav">
{{#link-to "index" tagName="li" activeClass="uk-active"}}<a>Home</a>{{/link-to}}
{{#link-to "about" tagName="li" activeClass="uk-active"}}<a>About</a>{{/link-to}}
</ul>
<div class="uk-navbar-item">
Toasts: {{mintToast.items.length}}
</div>
</div>
</nav>
<div class="uk-container uk-padding">
{{outlet}}
</div>
<div class="mint-toast__item-inner {{typeClass}}">
{{item.text}}
{{#if item.performLabel}}
<a {{action "perform"}}>{{item.performLabel}}</a>
<a {{action "dismiss"}}>Dismiss</a>
{{/if}}
</div>
{{#each mintToast.items key="id" as |item|}}
{{mint-toast-item
item=item
onResolve=(action "onResolve")
}}
{{/each}}
<h1 class="uk-heading-small">Welcome to Demo</h1>
<p>
<button {{action "pushItem"}} class="uk-button uk-button-default uk-width-medium">
Push from Home
</button>
</p>
<p>
<button {{action "dummyCreate"}} class="uk-button uk-button-danger uk-width-medium">
Dummy Create
</button>
</p>
{
"version": "0.15.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js",
"ember": "3.4.3",
"ember-template-compiler": "3.4.3",
"ember-testing": "3.4.3"
},
"addons": {
"ember-data": "3.4.2"
}
}
@krukid
Copy link
Author

krukid commented Sep 25, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment