can
Version:
MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.
94 lines (88 loc) • 2.55 kB
HTML
<script type='text/stache' id='demo-html'>
<my-tabs {^@add-panel}="@*addPanel">
<my-panel {add-panel}="@*addPanel" title="CanJS">CanJS Content</my-panel>
<my-panel {add-panel}="@*addPanel" title="StealJS">StealJS Content</my-panel>
</my-tabs>
</script>
<script src="../../node_modules/steal/steal.js" main="@empty">
var Component = require("can-component");
var DefineMap = require("can-define/map/map");
var DefineList = require("can-define/list/list");
var canBatch = require("can-event/batch/batch");
var stache = require("can-stache");
Component.extend({
tag: "my-tabs",
template:
stache("<ul>"+
// Create an LI for each item in the panel's viewModel object
"{{#panels}}"+
"<li {{#isActive}}class='active'{{/isActive}} "+
"($click)='makeActive(.)'>"+
"{{title}}"+
"</li>"+
"{{/panels}}"+
"</ul>"+
"<content></content>"),
ViewModel: DefineMap.extend({
// Contains a list of all panel scopes within the
// tabs element.
panels: {
value: new DefineList([])
},
active: "any",
// When a `<panel>` element is inserted into the document,
// it calls this method to add the panel's viewModel to the
// panels array.
addPanel: function(panel){
// If this is the first panel, activate it.
if(this.panels.length === 0) {
this.makeActive(panel);
}
this.panels.push(panel);
},
// When a `<panel>` element is removed from the document,
// it calls this method to remove the panel's viewModel from
// the panels array.
removePanel: function(panel){
var panels = this.panels;
canBatch.start();
panels.splice(panels.indexOf(panel),1);
// if the panel was active, make the first item active
if(panel === this.active){
if(panels.length){
this.makeActive(panels[0]);
} else {
this.active = undefined;
}
}
canBatch.stop();
},
makeActive: function(panel){
this.active = panel;
this.panels.forEach(function(panel){
panel.active = false;
});
panel.active = true;
},
// this is viewModel, not mustache
// consider removing viewModel as arg
isActive: function( panel ) {
return this.active === panel;
}
})
});
Component.extend({
template: stache("{{#if active}}<content></content>{{/if}}"),
tag:"my-panel",
ViewModel: DefineMap.extend({
active: { value: false },
addPanel: "any",
init: function(){
this.addPanel(this);
}
})
});
var el = document.getElementById("demo-html");
var frag = stache(el.innerHTML)({});
document.body.appendChild(frag);
</script>