Skip to content

Commit 31ad422

Browse files
author
Joshua Lawrence
authored
Updated syntax to modern standards (#328)
* Updated syntax to modern standards - Converted to classes and decorators - Replaced component lifecycle hooks with ember-render-modifiers - Use this. rather than get - Introduced some quality of life babel plugins - Implemented angle bracket components * Drop support for older Ember versions below 3.12-LTS * Upgraded eslint and resolved lint issues * update lock file * Rolled back change to version number
1 parent b5ee56b commit 31ad422

File tree

17 files changed

+1643
-530
lines changed

17 files changed

+1643
-530
lines changed

.editorconfig

+3
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@ indent_size = 2
1616
[*.hbs]
1717
insert_final_newline = false
1818

19+
[*.js]
20+
quote_type = single
21+
1922
[*.{diff,md}]
2023
trim_trailing_whitespace = false

.eslintrc.js

+19-18
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
module.exports = {
22
root: true,
3+
parser: 'babel-eslint',
34
parserOptions: {
45
ecmaVersion: 2017,
5-
sourceType: 'module'
6+
sourceType: 'module',
67
},
7-
plugins: [
8-
'ember'
9-
],
10-
extends: [
11-
'eslint:recommended',
12-
'plugin:ember/recommended'
13-
],
8+
plugins: ['ember'],
9+
extends: ['eslint:recommended', 'plugin:ember/recommended'],
1410
env: {
15-
browser: true
11+
browser: true,
1612
},
1713
rules: {
14+
'ember/classic-decorator-no-classic-methods': 'error',
1815
},
1916
overrides: [
2017
// node files
@@ -27,26 +24,30 @@ module.exports = {
2724
'testem.js',
2825
'blueprints/*/index.js',
2926
'config/**/*.js',
30-
'tests/dummy/config/**/*.js'
27+
'tests/dummy/config/**/*.js',
3128
],
3229
excludedFiles: [
3330
'addon/**',
3431
'addon-test-support/**',
3532
'app/**',
36-
'tests/dummy/app/**'
33+
'tests/dummy/app/**',
3734
],
3835
parserOptions: {
3936
sourceType: 'script',
40-
ecmaVersion: 2015
37+
ecmaVersion: 2015,
4138
},
4239
env: {
4340
browser: false,
44-
node: true
41+
node: true,
4542
},
4643
plugins: ['node'],
47-
rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, {
48-
// add your custom rules and overrides for node files here
49-
})
50-
}
51-
]
44+
rules: Object.assign(
45+
{},
46+
require('eslint-plugin-node').configs.recommended.rules,
47+
{
48+
// add your custom rules and overrides for node files here
49+
}
50+
),
51+
},
52+
],
5253
};

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
/npm-debug.log*
1919
/testem.log
2020
/yarn-error.log
21+
/.vscode
2122

2223
# ember-try
2324
/.node_modules.ember-try/

addon/components/flash-message.js

+86-103
Original file line numberDiff line numberDiff line change
@@ -2,127 +2,110 @@ import { htmlSafe, classify } from '@ember/string';
22
import Component from '@ember/component';
33
import { isPresent } from '@ember/utils';
44
import { run } from '@ember/runloop';
5-
import { computed, set, get } from '@ember/object';
5+
import { action, computed, set } from '@ember/object';
6+
import { and, bool, readOnly, not } from '@ember/object/computed';
7+
import { tagName } from '@ember-decorators/component';
68
import layout from '../templates/components/flash-message';
7-
import getWithDefault from '../utils/get-with-default';
8-
9-
const {
10-
and,
11-
bool,
12-
readOnly,
13-
not
14-
} = computed;
15-
const {
16-
next,
17-
cancel
18-
} = run;
19-
20-
export default Component.extend({
21-
layout,
22-
active: false,
23-
messageStyle: 'bootstrap',
24-
classNames: ['flash-message'],
25-
classNameBindings: ['alertType', 'active', 'exiting'],
26-
attributeBindings: ['aria-label', 'aria-describedby', 'role'],
27-
28-
showProgress: readOnly('flash.showProgress'),
29-
notExiting: not('exiting'),
30-
showProgressBar: and('showProgress', 'notExiting'),
31-
exiting: readOnly('flash.exiting'),
32-
hasBlock: bool('template').readOnly(),
33-
34-
alertType: computed('flash.type', {
35-
get() {
36-
const flashType = getWithDefault(this, 'flash.type', '');
37-
const messageStyle = getWithDefault(this, 'messageStyle', '');
38-
let prefix = 'alert alert-';
39-
40-
if (messageStyle === 'foundation') {
41-
prefix = 'alert-box ';
42-
}
43-
44-
return `${prefix}${flashType}`;
45-
}
46-
}),
479

48-
flashType: computed('flash.type', {
49-
get() {
50-
const flashType = getWithDefault(this, 'flash.type', '');
10+
const { next, cancel } = run;
5111

52-
return classify(flashType);
53-
}
54-
}),
12+
@tagName('')
13+
export default class FlashMessage extends Component {
14+
layout = layout;
15+
active = false;
16+
messageStyle = 'bootstrap';
5517

56-
didInsertElement() {
57-
this._super(...arguments);
58-
const pendingSet = next(this, () => {
59-
set(this, 'active', true);
60-
});
61-
set(this, 'pendingSet', pendingSet);
62-
this.set('_mouseEnterHandler', this._mouseEnter.bind(this));
63-
this.set('_mouseLeaveHandler', this._mouseLeave.bind(this));
64-
this.element.addEventListener('mouseenter', this._mouseEnterHandler);
65-
this.element.addEventListener('mouseleave', this._mouseLeaveHandler);
66-
},
67-
68-
willDestroyElement() {
69-
this._super(...arguments);
70-
this.element.removeEventListener('mouseenter', this._mouseEnterHandler);
71-
this.element.removeEventListener('mouseleave', this._mouseLeaveHandler);
72-
},
73-
74-
progressDuration: computed('flash.showProgress', {
75-
get() {
76-
if (!get(this, 'flash.showProgress')) {
77-
return false;
78-
}
79-
80-
const duration = getWithDefault(this, 'flash.timeout', 0);
81-
82-
return htmlSafe(`transition-duration: ${duration}ms`);
18+
@readOnly('flash.showProgress')
19+
showProgress;
20+
21+
@not('exiting')
22+
notExiting;
23+
24+
@and('showProgress', 'notExiting')
25+
showProgressBar;
26+
27+
@readOnly('flash.exiting')
28+
exiting;
29+
30+
@bool('template')
31+
hasBlock;
32+
33+
@computed('flash.type', 'messageStyle')
34+
get alertType() {
35+
const flashType = this.flash.type || '';
36+
const messageStyle = this.messageStyle || '';
37+
let prefix = 'alert alert-';
38+
39+
if (messageStyle === 'foundation') {
40+
prefix = 'alert-box ';
8341
}
84-
}),
8542

86-
click() {
87-
const destroyOnClick = getWithDefault(this, 'flash.destroyOnClick', true);
43+
return `${prefix}${flashType}`;
44+
}
8845

89-
if (destroyOnClick) {
90-
this._destroyFlashMessage();
46+
@computed('flash.type')
47+
get flashType() {
48+
return classify(this.flash.type || '');
49+
}
50+
51+
@computed('flash.{showProgress,timeout}')
52+
get progressDuration() {
53+
if (!this.flash?.showProgress) {
54+
return false;
9155
}
92-
},
56+
const duration = this.flash?.timeout || 0;
57+
return htmlSafe(`transition-duration: ${duration}ms`);
58+
}
9359

9460
_mouseEnter() {
95-
const flash = get(this, 'flash');
96-
if (isPresent(flash)) {
97-
flash.preventExit();
61+
if (isPresent(this.flash)) {
62+
this.flash.preventExit();
9863
}
99-
},
64+
}
10065

10166
_mouseLeave() {
102-
const flash = get(this, 'flash');
103-
if (isPresent(flash) && !get(flash, 'exiting')) {
104-
flash.allowExit();
67+
if (isPresent(this.flash) && !this.flash.exiting) {
68+
this.flash.allowExit();
10569
}
106-
},
107-
108-
willDestroy() {
109-
this._super(...arguments);
110-
this._destroyFlashMessage();
111-
cancel(get(this, 'pendingSet'));
112-
},
70+
}
11371

114-
// private
11572
_destroyFlashMessage() {
116-
const flash = getWithDefault(this, 'flash', false);
117-
118-
if (flash) {
119-
flash.destroyMessage();
73+
if (this.flash) {
74+
this.flash.destroyMessage();
12075
}
121-
},
76+
}
12277

123-
actions: {
124-
close() {
78+
@action
79+
onClick() {
80+
const destroyOnClick = this.flash?.destroyOnClick ?? true;
81+
82+
if (destroyOnClick) {
12583
this._destroyFlashMessage();
12684
}
12785
}
128-
});
86+
87+
@action
88+
onClose() {
89+
this._destroyFlashMessage();
90+
}
91+
92+
@action
93+
onDidInsert(element) {
94+
const pendingSet = next(this, () => {
95+
set(this, 'active', true);
96+
});
97+
set(this, 'pendingSet', pendingSet);
98+
set(this, '_mouseEnterHandler', this._mouseEnter);
99+
set(this, '_mouseLeaveHandler', this._mouseLeave);
100+
element.addEventListener('mouseenter', this._mouseEnterHandler);
101+
element.addEventListener('mouseleave', this._mouseLeaveHandler);
102+
}
103+
104+
@action
105+
onWillDestroy(element) {
106+
element.removeEventListener('mouseenter', this._mouseEnterHandler);
107+
element.removeEventListener('mouseleave', this._mouseLeaveHandler);
108+
cancel(this.pendingSet);
109+
this._destroyFlashMessage();
110+
}
111+
}

0 commit comments

Comments
 (0)