UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

112 lines (100 loc) 2.6 kB
<div id="out"></div> <script src="../../node_modules/steal/steal.js" dev-bundle main="@empty"> import { Component, stache, DefineMap, DefineList, viewModel} from "can"; const demoHTML = `<my-accordion> <my-panel makeActive:from="makeActive" title:from="'Contacts'"> <button>Change title attribute to "Users"</button> <ul> <li>Justin</li> <li>Brian</li> </ul> </my-panel> <my-panel makeActive:from="makeActive" title:from="'Libraries'"> <ul> <li>CanJS</li> <li>JavaScriptMVC</li> </ul> </my-panel> </my-accordion>`; const Panel = DefineMap.extend({ active: "boolean", title: "string" }); const AccordionViewModel = DefineMap.extend({ active: Panel, // Contains a list of all panel scopes within the // tabs element. panels: { Default: DefineList }, // When a `<panel>` element is inserted into the document, // it calls this method to add the panel's scope 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 scope from // the panels array. removePanel: function(panel){ var panels = this.panels; 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; } } }, makeActive: function(panel){ this.active = panel; this.panels.forEach(function(panel){ panel.active = false; }); panel.active = true; } }); Component.extend({ tag: "my-accordion", ViewModel: AccordionViewModel, leakScope: true }); Component.extend({ tag:"my-panel", view: ` <h2 on:click='makeActive(this)'>{{ title }}</h2> {{# if(active) }}<content></content>{{/ if }}`, ViewModel: DefineMap.extend('MyPanelVM', { active: { type: "boolean", default: false }, title: "string", connectedCallback: function(element) { var panel = this; var parentViewModel = element.parentNode.viewModel; parentViewModel.addPanel(panel); return function() { parentViewModel.removePanel(panel); }; } }) }); var out = document.getElementById("out"); var template = stache(demoHTML); out.appendChild(template({})); out.addEventListener("click", function(ev){ var el = ev.target; var parent = el.parentNode.viewModel; if (el.nodeName === "BUTTON") { parent.title = "Users"; } }); window.canViewModel = viewModel; </script>