Simple, highly configurable flash messages for ember.
This ember addon adds a flash message service and component to your app.
ember install ember-cli-flash
This addon is tested against the Ember release
, beta
and canary
channels, back to Ember v3.16
.
Usage is very simple. First, add one of the template examples to your app. Then, inject the flashMessages
service and use one of its convenience methods:
import Component from '@ember/component';
import { inject } from '@ember/service';
export default Component.extend({
flashMessages: inject()
});
You can quickly add flash messages using these methods from the service:
.success
.warning
.info
.danger
.success
.warning
.info
.alert
.secondary
These will add the appropriate classes to the flash message component for styling in Bootstrap or Foundation. For example:
// Bootstrap: the flash message component will have 'alert alert-success' classes
// Foundation: the flash message component will have 'alert-box success' classes
this.flashMessages.success('Success!');
You can take advantage of Promises, and their .then
and .catch
methods. To add a flash message after saving a model (or when it fails):
actions: {
saveFoo() {
const flashMessages = this.flashMessages;
this.model
.save()
.then((res) => {
flashMessages.success('Successfully saved!');
doSomething(res);
})
.catch((err) => {
flashMessages.danger('Something went wrong!');
handleError(err);
});
}
}
If the convenience methods don't fit your needs, you can add custom messages with add
:
this.flashMessages.add({
message: 'Custom message'
});
You can also pass in options to custom messages:
this.flashMessages.add({
message: 'I like alpacas',
type: 'alpaca',
timeout: 500,
priority: 200,
sticky: true,
showProgress: true,
extendedTimeout: 500,
destroyOnClick: false,
onDestroy() {
// behavior triggered when flash is destroyed
}
});
this.flashMessages.success('This is amazing', {
timeout: 100,
priority: 100,
sticky: false,
showProgress: true
});
message: string
Required when preventDuplicates
is enabled. The message that the flash message displays.
type?: string
Default: info
This is mainly used for styling. The flash message's type
is set as a class name on the rendered component, together with a prefix. The rendered class name depends on the message type that was passed into the component.
timeout?: number
Default: 3000
Number of milliseconds before a flash message is automatically removed.
priority?: number
Default: 100
Higher priority messages appear before low priority messages. The best practise is to use priority values in multiples of 100
(100
being the lowest priority). Note that you will need modify your template for this work.
sticky?: boolean
Default: false
By default, flash messages disappear after a certain amount of time. To disable this and make flash messages permanent (they can still be dismissed by click), set sticky
to true.
showProgress?: boolean
Default: false
To show a progress bar in the flash message, set this to true.
extendedTimeout?: number
Default: 0
Number of milliseconds before a flash message is removed to add the class 'exiting' to the element. This can be used to animate the removal of messages with a transition.
destroyOnClick?: boolean
Default: true
By default, flash messages will be destroyed on click. Disabling this can be useful if the message supports user interaction.
onDestroy: function
Default: undefined
A function to be called when the flash message is destroyed.
To animate messages, set extendedTimeout
to something higher than zero. Here we've chosen 500ms.
module.exports = function(environment) {
var ENV = {
flashMessageDefaults: {
extendedTimeout: 500
}
}
}
Then animate using CSS transitions, using the .active
and .active.exiting
classes.
.alert {
opacity: 0;
position: relative;
left: 100px;
transition: all 700ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
&.active {
opacity: 1;
left: 0px;
&.exiting {
opacity: 0;
left: 100px;
}
}
}
You can also add arbitrary options to messages:
this.flashMessages.success('Cool story bro', {
someOption: 'hello'
});
this.flashMessages.add({
message: 'hello',
type: 'foo',
componentName: 'some-component',
content: customContent
});
This makes use of the component helper, allowing the template that ultimately renders the flash to be dynamic:
It's best practice to use flash messages sparingly, only when you need to notify the user of something. If you're sending too many messages, and need a way for your users to clear all messages from screen, you can use this method:
this.flashMessages.clearMessages();
The flash message service is designed to be Fluent, allowing you to chain methods on the service easily. The service should handle most cases but if you want to access the flash object directly, you can use the getFlashObject
method:
const flashObject = this.flashMessages.add({
message: 'hola',
type: 'foo'
}).getFlashObject();
You can then manipulate the flashObject
directly. Note that getFlashObject
must be the last method in your chain as it returns the flash object directly.
In config/environment.js
, you can override service defaults in the flashMessageDefaults
object:
module.exports = function(environment) {
var ENV = {
flashMessageDefaults: {
// flash message defaults
timeout: 5000,
extendedTimeout: 0,
priority: 200,
sticky: true,
showProgress: true,
// service defaults
type: 'alpaca',
types: [ 'alpaca', 'notice', 'foobar' ],
preventDuplicates: false
}
}
}
See the options section for information about flash message specific options.
type?: string
Default: info
When adding a custom message with add
, if no type
is specified, this default is used.
types?: array
Default: [ 'success', 'info', 'warning', 'danger', 'alert', 'secondary' ]
This option lets you specify exactly what types you need, which means in the above example, you can do this.flashMessages.{alpaca,notice,foobar}
.
preventDuplicates?: boolean
Default: false
If true
, only 1 instance of a flash message (based on its message
) can be added at a time. For example, adding two flash messages with the message "Great success!"
would only add the first instance into the queue, and the second is ignored.
Then, to display somewhere in your app, add this to your template:
It also accepts your own template:
close
actionThe close
action is always passed to the component whether it is used or not. It can be used to implement your own close button, such as an x
in the top-right corner.
When using a custom close
action, you will want to set destroyOnClick=false
to override the default (destroyOnClick=true
). You could do this globally in flashMessageDefaults
.
By default, flash messages will have Bootstrap style class names. If you want to use Foundation, simply specify the messageStyle
on the component:
If you don't wish to use the class names associated with Bootstrap / Foundation, specify the messageStylePrefix
on the component. This will override the class name prefixes with your own. For example, messageStylePrefix='special-alert-'
would create flash messages with the class special-alert-succcess
To display messages sorted by priority, add this to your template:
To add radius
or round
type corners in Foundation:
If the provided component isn't to your liking, you can easily create your own. All you need to do is pass in the flash
object to that component:
When you install the addon, it should automatically generate a helper located at tests/helpers/flash-message.js
. You can do this manually as well:
$ ember generate ember-cli-flash
This also adds the helper to tests/test-helper.js
. You won't actually need to import this into your tests, but it's good to know what the blueprint does. Basically, the helper overrides a method used to initialise the flash-message's class, so that it behaves intuitively in a testing environment.
Some example tests below, based on qunit.
An example acceptance test:
// tests/acceptance/foo-page-test.js
import { module, test } from 'qunit'
import { setupApplicationTest } from 'ember-qunit'
import { click, visit } from '@ember/test-helpers'
module('Application | Component | foo-page', function (hooks) {
setupApplicationTest(hooks)
test('flash message is rendered', async function(assert) {
assert.expect(1);
await visit('/');
await click('.button-that-opens-alert')
assert.dom('.alert.alert-success').exists({ count: 1 });
});
});
An example integration test:
// tests/integration/components/x-foo-test.js
import { module, test } from 'qunit'
import { setupRenderingTest } from 'ember-qunit'
import { render } from '@ember/test-helpers'
import { hbs } from 'ember-cli-htmlbars'
module('Integration | Component | x-foo', function (hooks) {
setupRenderingTest(hooks)
hooks.beforeEach(function() {
// We have to register any types we expect to use in this component
const typesUsed = ['info', 'warning', 'success'];
this.owner.lookup('service:flash-messages').registerTypes(typesUsed);
})
test('it renders', function(assert) {
await render(hbs`<XFoo/>`)
...
})
});
For unit tests that require the flashMessages
service, you'll need to do a small bit of setup:
import { module, test } from 'qunit'
import { setupTest } from 'ember-qunit'
module('Container | Route | foo', function (hooks) {
setupTest(hooks)
hooks.beforeEach(function() {
// We have to register any types we expect to use in this component
const typesUsed = ['info', 'warning', 'success'];
this.owner.lookup('service:flash-messages').registerTypes(typesUsed);
})
test('it does the thing it should do', function(assert) {
const subject = this.owner.lookup('route:foo')
...
})
});
This addon is minimal and does not currently ship with a stylesheet. You can style flash messages by targeting the appropriate alert classes in your CSS.
We're grateful to these wonderful contributors who've contributed to ember-cli-flash
:
Ember CLI 是一个 Ember.js 命令行工具,提供了由 broccoli 提供的快速的资源管道和项目结构。 Ember CLI 基于 Ember App Kit Project 目前已经废弃。 Assets Compilation Ember CLI asset compilation is based on broccoli. Broccoli has support for: Ha
This repository is no longer maintained. As a replacement check out: https://github.com/sir-dunxalot/ember-tooltips Ember CLI Tooltipster An Ember CLI add-on that wraps Tooltipster into an ember compo
ember-cli-updater This ember-cli addon helps you update your ember-cli application or addon. The idea of this addon is to automate some parts of the upgrade process so it's simplified. Not every chang
Ember-cli-yadda This Ember CLI addon facilitates writing BDD tests in the Gherkin language and executing them against your Ember app. @mschinis (Micheal Schinis) Did a great talk at @emberlondon BDD a
Ember-cli-simditor Ember component wrapper for simditor. Changes 0.0.7 Different from previous version, you must wrap content in object. See issue 6 for why. Getting Started Installation In your ember
ember-cli-chai Chai assertions for Ember.js. Deprecated This package is deprecated. Please use ember-auto-import to use chai and chai plugins directly. If you'd like to use chai, or were previously us