Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
Suchita Doshi
A paradigm shiftA paradigm shift
suchitadoshi
suchitadoshi1987
suchita009
suchita009
1
When I am away from my computer...When I am away from my computer...
2
When I am away from my computer...When I am away from my computer...
2
When I am away from my computer...When I am away from my computer...
2
When I am away from my computer...When I am away from my computer...
2
When I am away from my computer...When I am away from my computer...
2
AgendaAgenda
3
AgendaAgenda
Journey Of EmberJSEmber 1.xEmber 2.xEmber 3.x
3
AgendaAgenda
Journey Of EmberJS
Ember OctaneNative ClassesGlimmer ComponentsTemplates in OctaneTracked PropertiesModifiers & Decorators
3
AgendaAgenda
Journey Of EmberJS
Ember Octane
Classic vs Octane Epiccomparison
3
AgendaAgenda
Journey Of EmberJS
Ember Octane
Classic vs Octane Epiccomparison
Migration tools &References
3
OfOf
TheThe
JOURNEYJOURNEY
4
Ember 1.xEmber 1.x
5
Convention over configuration (A new mental model)
Ember 1.xEmber 1.x
5
Convention over configuration (A new mental model)
Built-in Routing capability
Ember 1.xEmber 1.x
5
Convention over configuration (A new mental model)
Built-in Routing capability
Ember-data
Ember 1.xEmber 1.x
5
Convention over configuration (A new mental model)
Built-in Routing capability
Ember-data
View Driven architecture
Ember 1.xEmber 1.x
5
Convention over configuration (A new mental model)
Built-in Routing capability
Ember-data
View Driven architecture
Ember 1.xEmber 1.x
RouteController
+Templates
Model
View+
TemplatesModel
export default Ember.View.extend({
// Computed Property fullName: function() { return this.get('firstName') + ' ' + this.get('lastName'); }.property('firstName', 'lastName'), fullNameChanged: function() { // deal with the change }.observes('fullName')});
1 classNameBindings: ['isActive'],2 isActive: true,3 firstName: 'John',4 lastName: 'Doe',5 6
789101112131415
5
Convention over configuration (A new mental model)
Built-in Routing capability
Ember-data
View Driven architecture
Two way data bindings
Ember 1.xEmber 1.x
5
Convention over configuration (A new mental model)
Built-in Routing capability
Ember-data
View Driven architecture
Two way data bindings
Attribute bindings using {{bind-attr}}
Ember 1.xEmber 1.x
<div {{bind-attr title=post.popup}}></div>1
5
Ember 2.xEmber 2.x
6
Component driven
Ember 2.xEmber 2.x
export default Ember.Component.extend({
// Computed Property fullName: Ember.computed('firstName', 'lastName', function() { return this.get('firstName') + ' ' + this.get('lastName'); }), fullNameChanged: Ember.observer('fullName', function() { // deal with the change })});
1 classNameBindings: ['isActive'],2 isActive: true,3 firstName: 'John',4 lastName: 'Doe',5 6
789
101112131415
RouteController
+Templates
Component+
TemplatesModelModel
6
Component driven
“Glimmer rendering engine” adoption
Ember 2.xEmber 2.x
6
Component driven
“Glimmer rendering engine” adoption
Better binding with properties {{bind-attr}}
Ember 2.xEmber 2.x
// v2.x
<div title="{{post.popup}}"></div>1
<div {{bind-attr title=post.popup}}></div>1
// v1.x
6
Component driven
“Glimmer rendering engine” adoption
Better binding with properties {{bind-attr}}
Better template scoping
Ember 2.xEmber 2.x
6
Component driven
“Glimmer rendering engine” adoption
Better binding with properties {{bind-attr}}
Better template scoping
Ember 2.xEmber 2.x
6
// v1.x
{{!-- 1.x version --}}{{#each post in posts}} {{!-- `post` references the current iteration --}}{{/each}} {{#each posts}} {{!-- the outer context is no longer accessible --}}{{/each}}
123456789
1011
// v2.x
{{!-- 2.x version --}} {{#each posts as |post|}} {{!--`post` references the current iteration --}} <p>{{post.id}} {{post.title}}</p>{{/each}}
1234567
Component driven
“Glimmer rendering engine” adoption
Better binding with properties {{bind-attr}}
Better template scoping
"Data Down, Actions Up" approach
Ember 2.xEmber 2.x
6
Component driven
“Glimmer rendering engine” adoption
Better binding with properties {{bind-attr}}
Better template scoping
"Data Down, Actions Up" approach
Roadmap for a lot of further improvements:
HTML syntax for component invocation
Routes to drive Components approach
Ember 2.xEmber 2.x
6
Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)
7
Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)
Cleanup Cleanup Cleanup
7
Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)
Cleanup Cleanup Cleanup
Remove support for IE9, IE10 and PhantomJS.
7
Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)
Cleanup Cleanup Cleanup
Remove support for IE9, IE10 and PhantomJS.
Remove bower support
7
Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)
Cleanup Cleanup Cleanup
Remove support for IE9, IE10 and PhantomJS.
Remove bower support
Native Classes
7
Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)
Cleanup Cleanup Cleanup
Remove support for IE9, IE10 and PhantomJS.
Remove bower support
Native Classes
Glimmer Components
7
Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)
Cleanup Cleanup Cleanup
Remove support for IE9, IE10 and PhantomJS.
Remove bower support
Native Classes
Glimmer Components
Angle Brackets Invocation
7
Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)
Cleanup Cleanup Cleanup
Remove support for IE9, IE10 and PhantomJS.
Remove bower support
Native Classes
Glimmer Components
Angle Brackets Invocation
@tracked properties
7
Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)
Cleanup Cleanup Cleanup
Remove support for IE9, IE10 and PhantomJS.
Remove bower support
Native Classes
Glimmer Components
Angle Brackets Invocation
@tracked properties
Modifiers & Decorators
7
Ember 3.x (Road to Octane)Ember 3.x (Road to Octane)
Cleanup Cleanup Cleanup
Remove support for IE9, IE10 and PhantomJS.
Remove bower support
Native Classes
Glimmer Components
Angle Brackets Invocation
@tracked properties
Modifiers & Decorators
Lots of documentation 7
Evolution of EmberJSEvolution of EmberJS
8
Evolution of EmberJSEvolution of EmberJS
1.x
8
Evolution of EmberJSEvolution of EmberJS
2.x1.x
8
Evolution of EmberJSEvolution of EmberJS
2.x1.x 3.x
8
Evolution of EmberJSEvolution of EmberJS
Octane2.x1.x 3.x
8
9
Native ClassesNative Classes
10
Native ClassesNative Classes
ES6 Class syntax
10
Native ClassesNative Classes
ES6 Class syntax
Increased performance
10
Native ClassesNative Classes
ES6 Class syntax
Increased performance
Smooth learning curve
10
Native ClassesNative Classes
ES6 Class syntax
Increased performance
Smooth learning curve
More aligned Javascript
community
10
Native ClassesNative Classes
ES6 Class syntax
Increased performance
Smooth learning curve
More aligned Javascript
community
Ability to share code more
easily
10
Native ClassesNative Classes
ES6 Class syntax
Increased performance
Smooth learning curve
More aligned Javascript
community
Ability to share code more
easily
No more `.get`'s
10
Native ClassesNative Classes
ES6 Class syntax
Increased performance
Smooth learning curve
More aligned Javascript
community
Ability to share code more
easily
No more `.get`'s
Cleaner and easier to read
10
Native ClassesNative Classes
ES6 Class syntax
Increased performance
Smooth learning curve
More aligned Javascript
community
Ability to share code more
easily
No more `.get`'s
Cleaner and easier to read
import { computed } from '@ember/object' class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; console.log(`Created ${this.fullName}...`); } @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }} let phoenix = new Person('Jean', 'Gray');
12345678910111213141516
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ init(props) { this._super(props); console.log(`Created ${this.get('fullName')}...`); }, fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })}); let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });
1234567891011121314
// Classic Ember Object Syntax
// Native Class Syntax
10
Native ClassesNative Classes
ES6 Class syntax
Increased performance
Smooth learning curve
More aligned Javascript
community
Ability to share code more
easily
No more `.get`'s
Cleaner and easier to read
import { computed } from '@ember/object' class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; console.log(`Created ${this.fullName}...`); } @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }} let phoenix = new Person('Jean', 'Gray');
12345678910111213141516
class Person {
}
import { computed } from '@ember/object'1 2
3 constructor(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6 console.log(`Created ${this.fullName}...`);7 }8 9 @computed('firstName', 'lastName')10 get fullName() {11 return `${this.firstName} ${this.lastName}`;12 }13
14 15let phoenix = new Person('Jean', 'Gray');16
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ init(props) { this._super(props); console.log(`Created ${this.get('fullName')}...`); }, fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })}); let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });
1234567891011121314
const Person = EmberObject.extend({
});
import EmberObject, { computed } from '@ember/object';1 2
3 init(props) {4 this._super(props);5 console.log(`Created ${this.get('fullName')}...`);6 },7 8 fullName: computed('firstName', 'lastName', function() {9 return `${this.get('firstName')} ${this.get('lastName')}`;10 })11
12 13let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });14
// Classic Ember Object Syntax
// Native Class Syntax
10
Native ClassesNative Classes
ES6 Class syntax
Increased performance
Smooth learning curve
More aligned Javascript
community
Ability to share code more
easily
No more `.get`'s
Cleaner and easier to read
import { computed } from '@ember/object' class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; console.log(`Created ${this.fullName}...`); } @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }} let phoenix = new Person('Jean', 'Gray');
12345678910111213141516
class Person {
}
import { computed } from '@ember/object'1 2
3 constructor(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6 console.log(`Created ${this.fullName}...`);7 }8 9 @computed('firstName', 'lastName')10 get fullName() {11 return `${this.firstName} ${this.lastName}`;12 }13
14 15let phoenix = new Person('Jean', 'Gray');16
@computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }
import { computed } from '@ember/object'1 2class Person {3 constructor(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6 console.log(`Created ${this.fullName}...`);7 }8 9
10111213
}14 15let phoenix = new Person('Jean', 'Gray');16
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ init(props) { this._super(props); console.log(`Created ${this.get('fullName')}...`); }, fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })}); let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });
1234567891011121314
const Person = EmberObject.extend({
});
import EmberObject, { computed } from '@ember/object';1 2
3 init(props) {4 this._super(props);5 console.log(`Created ${this.get('fullName')}...`);6 },7 8 fullName: computed('firstName', 'lastName', function() {9 return `${this.get('firstName')} ${this.get('lastName')}`;10 })11
12 13let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });14
fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 init(props) {4 this._super(props);5 console.log(`Created ${this.get('fullName')}...`);6 },7 8
91011
});12 13let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });14
// Classic Ember Object Syntax
// Native Class Syntax
10
Native ClassesNative Classes
ES6 Class syntax
Increased performance
Smooth learning curve
More aligned Javascript
community
Ability to share code more
easily
No more `.get`'s
Cleaner and easier to read
import { computed } from '@ember/object' class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; console.log(`Created ${this.fullName}...`); } @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }} let phoenix = new Person('Jean', 'Gray');
12345678910111213141516
class Person {
}
import { computed } from '@ember/object'1 2
3 constructor(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6 console.log(`Created ${this.fullName}...`);7 }8 9 @computed('firstName', 'lastName')10 get fullName() {11 return `${this.firstName} ${this.lastName}`;12 }13
14 15let phoenix = new Person('Jean', 'Gray');16
@computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }
import { computed } from '@ember/object'1 2class Person {3 constructor(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6 console.log(`Created ${this.fullName}...`);7 }8 9
10111213
}14 15let phoenix = new Person('Jean', 'Gray');16
import { computed } from '@ember/object' class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; console.log(`Created ${this.fullName}...`); } @computed('firstName', 'lastName') get fullName() { return `${this.firstName} ${this.lastName}`; }} let phoenix = new Person('Jean', 'Gray');
12345678910111213141516
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ init(props) { this._super(props); console.log(`Created ${this.get('fullName')}...`); }, fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })}); let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });
1234567891011121314
const Person = EmberObject.extend({
});
import EmberObject, { computed } from '@ember/object';1 2
3 init(props) {4 this._super(props);5 console.log(`Created ${this.get('fullName')}...`);6 },7 8 fullName: computed('firstName', 'lastName', function() {9 return `${this.get('firstName')} ${this.get('lastName')}`;10 })11
12 13let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });14
fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 init(props) {4 this._super(props);5 console.log(`Created ${this.get('fullName')}...`);6 },7 8
91011
});12 13let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });14
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ init(props) { this._super(props); console.log(`Created ${this.get('fullName')}...`); }, fullName: computed('firstName', 'lastName', function() { return `${this.get('firstName')} ${this.get('lastName')}`; })}); let phoenix = Person.create({ firstName: 'Jean', lastName: 'Gray' });
1234567891011121314
// Classic Ember Object Syntax
// Native Class Syntax
10
Glimmer ComponentsGlimmer Components
11
Offers simpler, ergonomic,
and declarative approach
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
// Classic Component
// Glimmer Component
11
Offers simpler, ergonomic,
and declarative approach
Easier to understand
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";
export default class AddRsvp extends Component {
1import { tracked } from "@glimmer/tracking";2 3
4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12
Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
import Component from '@ember/component'; export default Component.extend({
123
4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
// Classic Component
// Glimmer Component
11
Offers simpler, ergonomic,
and declarative approach
Easier to understand
Fewer hooks and propertiesimport Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";
export default class AddRsvp extends Component {
1import { tracked } from "@glimmer/tracking";2 3
4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
import Component from '@ember/component'; export default Component.extend({
123
4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
// Classic Component
// Glimmer Component
11
Offers simpler, ergonomic,
and declarative approach
Easier to understand
Fewer hooks and properties
No more implicit wrappers
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";
export default class AddRsvp extends Component {
1import { tracked } from "@glimmer/tracking";2 3
4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
import Component from '@ember/component'; export default Component.extend({
123
4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
// Classic Component
// Glimmer Component
11
Offers simpler, ergonomic,
and declarative approach
Easier to understand
Fewer hooks and properties
No more implicit wrappers
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";
export default class AddRsvp extends Component {
1import { tracked } from "@glimmer/tracking";2 3
4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
import Component from '@ember/component'; export default Component.extend({
123
4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
{{noOfGuests}}1
// Classic Component
// Glimmer Component
11
Offers simpler, ergonomic,
and declarative approach
Easier to understand
Fewer hooks and properties
No more implicit wrappers
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";
export default class AddRsvp extends Component {
1import { tracked } from "@glimmer/tracking";2 3
4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
import Component from '@ember/component'; export default Component.extend({
123
4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
{{noOfGuests}}1
<label> {{this.noOfGuests}} </label>1
// Classic Component
// Glimmer Component
11
Offers simpler, ergonomic,
and declarative approach
Easier to understand
Fewer hooks and properties
No more implicit wrappers
Namespaced arguments
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";
export default class AddRsvp extends Component {
1import { tracked } from "@glimmer/tracking";2 3
4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
return this.noOfGuests > this.args.maxGuests;
import Component from "@glimmer/component";1import { tracked } from "@glimmer/tracking";2 3export default class AddRsvp extends Component {4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8
9 }10 11}12
Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
import Component from '@ember/component'; export default Component.extend({
123
4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
return this.noOfGuests > this.maxGuests;
import Component from '@ember/component';1 2export default Component.extend({3 4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9
10 }11});12
{{noOfGuests}}1
<label> {{this.noOfGuests}} </label>1
// Classic Component
// Glimmer Component
11
Offers simpler, ergonomic,
and declarative approach
Easier to understand
Fewer hooks and properties
No more implicit wrappers
Namespaced arguments
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";
export default class AddRsvp extends Component {
1import { tracked } from "@glimmer/tracking";2 3
4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8 return this.noOfGuests > this.args.maxGuests;9 }10 11}12
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
return this.noOfGuests > this.args.maxGuests;
import Component from "@glimmer/component";1import { tracked } from "@glimmer/tracking";2 3export default class AddRsvp extends Component {4 5 @tracked noOfGuests = 5;6 7 get isMaxGuestExceeded() {8
9 }10 11}12
import Component from "@glimmer/component";import { tracked } from "@glimmer/tracking"; export default class AddRsvp extends Component { @tracked noOfGuests = 5; get isMaxGuestExceeded() { return this.noOfGuests > this.args.maxGuests; } }
123456789
101112
Glimmer ComponentsGlimmer Componentsimport Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
import Component from '@ember/component'; export default Component.extend({
123
4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
tagName: 'label',
import Component from '@ember/component';1 2export default Component.extend({3 4
5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9 return this.noOfGuests > this.maxGuests;10 }11});12
return this.noOfGuests > this.maxGuests;
import Component from '@ember/component';1 2export default Component.extend({3 4 tagName: 'label',5 6 noOfGuests: 5,7 8 isMaxGuestExceeded: computed('noOfGuests') {9
10 }11});12
import Component from '@ember/component'; export default Component.extend({ tagName: 'label', noOfGuests: 5, isMaxGuestExceeded: computed('noOfGuests') { return this.noOfGuests > this.maxGuests; }});
123456789
101112
{{noOfGuests}}1
<label> {{this.noOfGuests}} </label>1
// Classic Component
// Glimmer Component
11
Templating in OctaneTemplating in Octane
12
Templating in OctaneTemplating in Octane
Angle Brackets syntax
In line with the HTML standards
Capital Case Syntax
Easy to distinguish from helpers,properties etc.
{{employee-details name=employeeName empId=employeeId addEmployee=(action 'addEmployee')}}
123456
{{employee-details
}}
1 name=employeeName2 empId=employeeId3 addEmployee=(action 'addEmployee')4
56
<EmployeeDetails @name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}/>
12345
<EmployeeDetails
/>
1 @name={{this.employeeName}}2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4
5
// Classic templating syntax
// Octane templating syntax
12
Templating in OctaneTemplating in Octane
Angle Brackets syntax
In line with the HTML standards
Capital Case Syntax
Easy to distinguish from helpers,properties etc.
Named arguments
Denoted with `@` symbol
Easy differentiation from local andexternal properties
{{employee-details name=employeeName empId=employeeId addEmployee=(action 'addEmployee')}}
123456
{{employee-details
}}
1 name=employeeName2 empId=employeeId3 addEmployee=(action 'addEmployee')4
56
name=employeeName empId=employeeId addEmployee=(action 'addEmployee')
{{employee-details1234
}}56
<EmployeeDetails @name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}/>
12345
<EmployeeDetails
/>
1 @name={{this.employeeName}}2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4
5
@name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}
<EmployeeDetails1234
/>5
// Classic templating syntax
// Octane templating syntax
12
Templating in OctaneTemplating in Octane
Angle Brackets syntax
In line with the HTML standards
Capital Case Syntax
Easy to distinguish from helpers,properties etc.
Named arguments
Denoted with `@` symbol
Easy differentiation from local andexternal properties
Required `this`
Provides clear point-of-origin
Easy to read and understand
{{employee-details name=employeeName empId=employeeId addEmployee=(action 'addEmployee')}}
123456
{{employee-details
}}
1 name=employeeName2 empId=employeeId3 addEmployee=(action 'addEmployee')4
56
name=employeeName empId=employeeId addEmployee=(action 'addEmployee')
{{employee-details1234
}}56
name=employeeName{{employee-details1
2 empId=employeeId3 addEmployee=(action 'addEmployee')4}}5
6
<EmployeeDetails @name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}/>
12345
<EmployeeDetails
/>
1 @name={{this.employeeName}}2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4
5
@name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}
<EmployeeDetails1234
/>5
@name={{this.employeeName}}<EmployeeDetails1
2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4/>5
// Classic templating syntax
// Octane templating syntax
12
Templating in OctaneTemplating in Octane
Angle Brackets syntax
In line with the HTML standards
Capital Case Syntax
Easy to distinguish from helpers,properties etc.
Named arguments
Denoted with `@` symbol
Easy differentiation from local andexternal properties
Required `this`
Provides clear point-of-origin
Easy to read and understand
{{employee-details name=employeeName empId=employeeId addEmployee=(action 'addEmployee')}}
123456
{{employee-details
}}
1 name=employeeName2 empId=employeeId3 addEmployee=(action 'addEmployee')4
56
name=employeeName empId=employeeId addEmployee=(action 'addEmployee')
{{employee-details1234
}}56
name=employeeName{{employee-details1
2 empId=employeeId3 addEmployee=(action 'addEmployee')4}}5
6
{{employee-details name=employeeName empId=employeeId addEmployee=(action 'addEmployee')}}
123456
<EmployeeDetails @name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}/>
12345
<EmployeeDetails
/>
1 @name={{this.employeeName}}2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4
5
@name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}
<EmployeeDetails1234
/>5
@name={{this.employeeName}}<EmployeeDetails1
2 @empId={{@employeeId}}3 @addEmployee={{this.addEmployee}}4/>5
<EmployeeDetails @name={{this.employeeName}} @empId={{@employeeId}} @addEmployee={{this.addEmployee}}/>
12345
// Classic templating syntax
// Octane templating syntax
12
Tracked PropertiesTracked Properties
@tracked syntax
Explicit declarations
Cleaner code
Reduces complexity
No More `.set`'s
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});
123456789101112
import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}
123456789101112
// Classic syntax
// @tracked syntax
13
Tracked PropertiesTracked Properties
@tracked syntax
Explicit declarations
Cleaner code
Reduces complexity
No More `.set`'s
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});
123456789101112
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12
import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}
123456789101112
import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12
// Classic syntax
// @tracked syntax
13
Tracked PropertiesTracked Properties
@tracked syntax
Explicit declarations
Cleaner code
Reduces complexity
No More `.set`'s
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});
123456789101112
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12
firstName: 'Tom', lastName: 'Dale', count: 0,
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3
456
7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12
import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}
123456789101112
import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12
@tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0;
import { tracked } from '@glimmer/tracking';1 2class Person {3
456
7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12
// Classic syntax
// @tracked syntax
13
Tracked PropertiesTracked Properties
@tracked syntax
Explicit declarations
Cleaner code
Reduces complexity
No More `.set`'s
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});
123456789101112
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12
firstName: 'Tom', lastName: 'Dale', count: 0,
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3
456
7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12
fullName: computed('firstName', 'lastName', function() {
}),
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7
8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10
11});12
import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}
123456789101112
import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12
@tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0;
import { tracked } from '@glimmer/tracking';1 2class Person {3
456
7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12
get fullName() {
}
import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7
8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10
11}12
// Classic syntax
// @tracked syntax
13
Tracked PropertiesTracked Properties
@tracked syntax
Explicit declarations
Cleaner code
Reduces complexity
No More `.set`'s
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});
123456789101112
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12
firstName: 'Tom', lastName: 'Dale', count: 0,
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3
456
7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12
fullName: computed('firstName', 'lastName', function() {
}),
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7
8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10
11});12
this.set('count', this.get('count') + 1);
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8
9 return `${this.firstName} ${this.lastName}`;10 }),11});12
import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}
123456789101112
import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12
@tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0;
import { tracked } from '@glimmer/tracking';1 2class Person {3
456
7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12
get fullName() {
}
import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7
8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10
11}12
this.count = this.count + 1;
import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8
9 return `${this.firstName} ${this.lastName}`;10 }11}12
// Classic syntax
// @tracked syntax
13
Tracked PropertiesTracked Properties
@tracked syntax
Explicit declarations
Cleaner code
Reduces complexity
No More `.set`'s
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});
123456789101112
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12
firstName: 'Tom', lastName: 'Dale', count: 0,
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3
456
7 fullName: computed('firstName', 'lastName', function() {8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10 }),11});12
fullName: computed('firstName', 'lastName', function() {
}),
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7
8 this.set('count', this.get('count') + 1);9 return `${this.firstName} ${this.lastName}`;10
11});12
this.set('count', this.get('count') + 1);
import EmberObject, { computed } from '@ember/object';1 2const Person = EmberObject.extend({3 firstName: 'Tom',4 lastName: 'Dale',5 count: 0,6 7 fullName: computed('firstName', 'lastName', function() {8
9 return `${this.firstName} ${this.lastName}`;10 }),11});12
import EmberObject, { computed } from '@ember/object'; const Person = EmberObject.extend({ firstName: 'Tom', lastName: 'Dale', count: 0, fullName: computed('firstName', 'lastName', function() { this.set('count', this.get('count') + 1); return `${this.firstName} ${this.lastName}`; }),});
123456789101112
import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}
123456789101112
import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12
@tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0;
import { tracked } from '@glimmer/tracking';1 2class Person {3
456
7 get fullName() {8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10 }11}12
get fullName() {
}
import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7
8 this.count = this.count + 1;9 return `${this.firstName} ${this.lastName}`;10
11}12
this.count = this.count + 1;
import { tracked } from '@glimmer/tracking';1 2class Person {3 @tracked firstName = 'Tom';4 @tracked lastName = 'Dale';5 @tracked count = 0;6 7 get fullName() {8
9 return `${this.firstName} ${this.lastName}`;10 }11}12
import { tracked } from '@glimmer/tracking'; class Person { @tracked firstName = 'Tom'; @tracked lastName = 'Dale'; @tracked count = 0; get fullName() { this.count = this.count + 1; return `${this.firstName} ${this.lastName}`; }}
123456789101112
// Classic syntax
// @tracked syntax
13
Modifiers and DecoratorsModifiers and Decorators
14
Modifiers and DecoratorsModifiers and Decorators
Modifiers:
Functions or classes useddirectly in templates
Applied directly to elements
Allows targeting specificelements more easily
Easy to reuse
<span>{{this.formattedCount}}</span> <button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>
123456
<button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>
<span>{{this.formattedCount}}</span>1 2
3456
14
Modifiers and DecoratorsModifiers and Decorators
Modifiers:
Functions or classes useddirectly in templates
Applied directly to elements
Allows targeting specificelements more easily
Easy to reuse
Decorators:
Abstracts functionality
Improved Developer experience
<span>{{this.formattedCount}}</span> <button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>
123456
<button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>
<span>{{this.formattedCount}}</span>1 2
3456
<span>{{this.formattedCount}}</span> <button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>
123456
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class Counter extends Component { @tracked count = 0; get formattedCount() { return this.count.toString().padStart(3, '0'); } @action increment() { this.count++ } @action decrement() { this.count-- }}
123456789
101112131415161718192021
@action
@action
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class Counter extends Component {5 @tracked count = 0;6 7 get formattedCount() {8 return this.count.toString().padStart(3, '0');9 }10 11
12 increment() {13 this.count++14 }15 16
17 decrement() {18 this.count--19 }20}21
14
Modifiers and DecoratorsModifiers and Decorators
Modifiers:
Functions or classes useddirectly in templates
Applied directly to elements
Allows targeting specificelements more easily
Easy to reuse
Decorators:
Abstracts functionality
Improved Developer experience
<span>{{this.formattedCount}}</span> <button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>
123456
<button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>
<span>{{this.formattedCount}}</span>1 2
3456
<span>{{this.formattedCount}}</span> <button {{on "click" this.increment}}>Increment</button> <button {{on "click" this.decrement}}>Decrement</button>
123456
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class Counter extends Component { @tracked count = 0; get formattedCount() { return this.count.toString().padStart(3, '0'); } @action increment() { this.count++ } @action decrement() { this.count-- }}
123456789
101112131415161718192021
@action
@action
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class Counter extends Component {5 @tracked count = 0;6 7 get formattedCount() {8 return this.count.toString().padStart(3, '0');9 }10 11
12 increment() {13 this.count++14 }15 16
17 decrement() {18 this.count--19 }20}21
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class Counter extends Component { @tracked count = 0; get formattedCount() { return this.count.toString().padStart(3, '0'); } @action increment() { this.count++ } @action decrement() { this.count-- }}
123456789
101112131415161718192021
14
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
// Classic Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
// Classic Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
// Classic Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
// Classic Component syntax // Octane Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
// Classic Component syntax // Octane Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1
2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
// Classic Component syntax // Octane Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1
2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
export default Component.extend({
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5
6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
export default class ToggleLabel extends Component {
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4
5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
// Classic Component syntax // Octane Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1
2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
export default Component.extend({
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5
6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
tagName: 'label',
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7
8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
export default class ToggleLabel extends Component {
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4
5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label
</label>
1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16
1718
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
// Classic Component syntax // Octane Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1
2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
export default Component.extend({
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5
6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
tagName: 'label',
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7
8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8
910111213
isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
export default class ToggleLabel extends Component {
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4
5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label
</label>
1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16
1718
for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}}
<label123456789
"10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
// Classic Component syntax // Octane Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1
2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
export default Component.extend({
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5
6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
tagName: 'label',
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7
8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8
910111213
isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13
141516171819
20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
export default class ToggleLabel extends Component {
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4
5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
@tracked isAwesome = true;
get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; }
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5
6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11
12131415
16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label
</label>
1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16
1718
for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}}
<label123456789
"10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
// Classic Component syntax // Octane Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1
2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
export default Component.extend({
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5
6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
tagName: 'label',
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7
8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8
910111213
isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13
141516171819
20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20
2122232425
26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
export default class ToggleLabel extends Component {
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4
5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
@tracked isAwesome = true;
get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; }
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5
6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11
12131415
16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
get type() { return this.args.value ? 'on' : 'off'; }
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7
89
10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label
</label>
1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16
1718
for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}}
<label123456789
"10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
// Classic Component syntax // Octane Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1
2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
export default Component.extend({
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5
6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
tagName: 'label',
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7
8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8
910111213
isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13
141516171819
20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20
2122232425
26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26
2728293031
});32
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
export default class ToggleLabel extends Component {
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4
5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
@tracked isAwesome = true;
get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; }
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5
6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11
12131415
16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
get type() { return this.args.value ? 'on' : 'off'; }
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7
89
10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
@action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16
171819202122
}23 24
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label
</label>
1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16
1718
for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}}
<label123456789
"10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
{{on 'click' this.handleClick}}
<label1 for="{{@switchId}}"2
3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
// Classic Component syntax // Octane Component syntax
15
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
import Component from '@ember/component';import { readOnly } from '@ember/object/computed';1
2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
export default Component.extend({
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5
6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
tagName: 'label',
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7
8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8
910111213
isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13
141516171819
20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }),
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20
2122232425
26 click(e) {27 e.stopPropagation();28 e.preventDefault();29 this.sendToggle(this.get('value'));30 }31});32
click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }
import { readOnly } from '@ember/object/computed';1import Component from '@ember/component';2import { computed } from '@ember/object';3import layout from './template';4 5export default Component.extend({6 layout,7 tagName: 'label',8 attributeBindings: ['for'],9 classNames: ['toggle-text', 'toggle-prefix'],10 classNameBindings: ['labelType'],11 for: readOnly('switchId'),12 isVisible: readOnly('show'),13 isAwesome: true,14 15 labelValue: computed('isAwesome', function() {16 return this.get('isAwesome') ? 17 'awesome-label' : 'lesser-awesome-label';18 }),19 20 type: computed('value', {21 get() {22 return this.get('value') ? 'on' : 'off';23 }24 }),25 26
2728293031
});32
import { readOnly } from '@ember/object/computed';import Component from '@ember/component';import { computed } from '@ember/object';import layout from './template'; export default Component.extend({ layout, tagName: 'label', attributeBindings: ['for'], classNames: ['toggle-text', 'toggle-prefix'], classNameBindings: ['labelType'], for: readOnly('switchId'), isVisible: readOnly('show'), isAwesome: true, labelValue: computed('isAwesome', function() { return this.get('isAwesome') ? 'awesome-label' : 'lesser-awesome-label'; }), type: computed('value', { get() { return this.get('value') ? 'on' : 'off'; } }), click(e) { e.stopPropagation(); e.preventDefault(); this.sendToggle(this.get('value')); }});
123456789
1011121314151617181920212223242526272829303132
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}}1 {{yield label}}2{{else}}3 {{label}}4{{/if}}5
6
{{#if hasBlock}} {{yield label}}{{else}} {{label}}{{/if}}
123456
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
export default class ToggleLabel extends Component {
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4
5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23
24
@tracked isAwesome = true;
get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; }
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5
6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11
12131415
16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
get type() { return this.args.value ? 'on' : 'off'; }
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7
89
10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16 @action17 handleClick(e) {18 e.stopPropagation();19 e.preventDefault();20 this.args.sendToggle(this.args.value);21 }22}23 24
@action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }
import Component from '@glimmer/component';1import { tracked } from '@glimmer/tracking';2import { action } from '@ember/object';3 4export default class ToggleLabel extends Component {5 @tracked isAwesome = true;6 7 get type() {8 return this.args.value ? 'on' : 'off';9 } 10 11 get labelValue() {12 return this.isAwesome ? 13 'awesome-label' : 'lesser-awesome-label';14 }15 16
171819202122
}23 24
import Component from '@glimmer/component';import { tracked } from '@glimmer/tracking';import { action } from '@ember/object'; export default class ToggleLabel extends Component { @tracked isAwesome = true; get type() { return this.args.value ? 'on' : 'off'; } get labelValue() { return this.isAwesome ? 'awesome-label' : 'lesser-awesome-label'; } @action handleClick(e) { e.stopPropagation(); e.preventDefault(); this.args.sendToggle(this.args.value); }}
123456789
101112131415161718192021222324
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label
</label>
1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16
1718
for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}}
<label123456789
"10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label1 for="{{@switchId}}"2 {{on 'click' this.handleClick}}3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
{{on 'click' this.handleClick}}
<label1 for="{{@switchId}}"2
3 4 class="5 toggle-text6 toggle-prefix7 {{this.type}}-label8 {{if @show 'is-visible' 'is-hidden'}}9 "10 >11 {{#if @hasBlock}}12 {{yield @label}}13 {{else}}14 {{@label}}15 {{/if}}16</label>17
18
<label for="{{@switchId}}" {{on 'click' this.handleClick}} class=" toggle-text toggle-prefix {{this.type}}-label {{if @show 'is-visible' 'is-hidden'}} " > {{#if @hasBlock}} {{yield @label}} {{else}} {{@label}} {{/if}}</label>
123456789
101112131415161718
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
{{x-toggle-label label=labelVal value=false sendToggle=(action 'sendToggle')}}
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
<ToggleLabel @label={{this.labelVal}} @value=false sendToggle={{this.sendToggle}}/>
12345
// Classic Component syntax // Octane Component syntax
15
Tools & GoodnessTools & Goodness
16
Tools & GoodnessTools & Goodness
Ember Codemods: https://github.com/ember-codemods
Ember Atlas: https://www.notion.so/The-Ember-Atlas-
4094f81c86c34badb4a562ed29414ae1
The Octane Edition of Ember:
https://emberjs.com/editions/octane/
Ember Blog - Octane is Here:
https://blog.emberjs.com/2019/12/20/octane-is-here.html
16
Tools & GoodnessTools & Goodness
Ember Codemods: https://github.com/ember-codemods
Ember Atlas: https://www.notion.so/The-Ember-Atlas-
4094f81c86c34badb4a562ed29414ae1
The Octane Edition of Ember:
https://emberjs.com/editions/octane/
Ember Blog - Octane is Here:
https://blog.emberjs.com/2019/12/20/octane-is-here.html
16
Thank you!Thank you!
17