Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@runspired
Last active December 11, 2019 10:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save runspired/b7ed2ada28015f6425ffe8894701a151 to your computer and use it in GitHub Desktop.
Save runspired/b7ed2ada28015f6425ffe8894701a151 to your computer and use it in GitHub Desktop.
Named Blocks w/Defaults
import Ember from 'ember';
export default Ember.Component.extend({
tagName: ''
});
import Ember from 'ember';
const InElementComponent = Ember.Component.extend({
tagName: '',
});
InElementComponent.reopenClass({
positionalParams: ['target']
});
export default InElementComponent;
import Ember from 'ember';
const LetComponent = Ember.Component.extend({
tagName: '',
});
LetComponent.reopenClass({
positionalParams: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
});
export default LetComponent;
import Ember from 'ember';
const NamedBlock = Ember.Component.extend({
tagName: '',
didInsertElement() {
Ember.set(this.state, this.name, true);
},
willDestroyElement() {
Ember.set(this.state, this.name, false);
}
});
NamedBlock.reopenClass({
positionalParams: ['state', 'name', 'target', 'defaultComponent']
});
export default NamedBlock;
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle'
});
import Ember from 'ember';
export function hasChild([ref]/*, hash*/) {
return ref.childNodes.length > 0;
}
export default Ember.Helper.helper(hasChild);
import Ember from 'ember';
export function ref(params/*, hash*/) {
return document.createElement(params[0]);
}
export default Ember.Helper.helper(ref);
<h2>About</h2>
This version of this example uses curly-component invocation and a polyfilled let helper to have compatibility with Ember 2.12
<br><br>
If your compatibility is >= 3.2 you do not need the let polyfill.
<br><br>
If your compatibility is >= 3.4 you do not need to use curly-components.
<br><br>
The named blocks in this example are intentionally invoked in a crazy order to show that they are still slotted back into position appropriately.
<br><br>
Enjoy :)
<hr>
{{#hero-table as |t|}}
{{!--
{{#t.foot}}
<th>Custom</th>
<th>Footer</th>
{{/t.foot}}
--}}
{{t.foot}}
{{#t.title}}
<h2>Named Blocks Table</h2>
{{/t.title}}
{{#t.description}}
This example shows how to compose the following features to achieve NamedBlocks.
{{/t.description}}
{{#t.source}}
<span>National Panel on Ember Features</span>
{{/t.source}}
{{#t.body}}
<tr>
<td>-in-element helper</td>
<td>✅</td>
</tr>
<tr>
<td>Contextual Components</td>
<td>✅</td>
</tr>
<tr>
<td>Hash Helper</td>
<td>✅</td>
</tr>
<tr>
<td>Component Helper</td>
<td>✅</td>
</tr>
<tr>
<td>Let Helper</td>
<td>✅</td>
</tr>
<tr>
<td>DOM Helper</td>
<td>✅</td>
</tr>
{{/t.body}}
{{#t.head}}
<th>Feature</th>
<th>3.0 Compat</th>
{{/t.head}}
{{/hero-table}}
{{#let-polyfill (hash) (ref 'thead') (ref 'tbody') (ref 'tfoot') (ref 'HeroTableTitle') (ref 'HeroTableDescription') (ref 'HeroTableSource') as |state thead tbody tfooter title description source|}}
<hero-table-wrapper>
{{title}}
{{description}}
<table class="hero-table">
{{thead}}
{{tbody}}
{{tfooter}}
{{#unless state.tfooter}}
<tfoot>
<th>Fallback</th>
<th>Footer</th>
</tfoot>
{{/unless}}
</table>
{{source}}
</hero-table-wrapper>
{{yield (hash
head=(component 'in-element' thead)
body=(component 'in-element' tbody)
foot=(component 'named-block' state 'tfooter' tfooter 'default-footer')
title=(component 'in-element' title)
description=(component 'in-element' description)
source=(component 'in-element' source)
)}}
{{/let-polyfill}}
<style>
hero-table-wrapper {
display: block;
position: relative;
margin: 1rem;
padding: 1rem;
box-sizing: content-box;
background: #f5f5f5;
border: 1px solid #e0e0e0;
font-family: "Helvetica Neue";
font-weight: 300;
border-radius: 2px;
box-shadow: 1px 2px 3px 0px rgba(0,0, 0, 0.5);
}
HeroTableTitle h2 {
font-size: 1.2rem;
color: #444499;
font-weight: 400;
margin: 0 0 .5rem;
width: 100%;
border: 0 0 2px 0 solid #e0e0e0;
}
HeroTableDescription {
padding: 0.5rem;
font-size: .8rem;
background: #fff;
display: block;
position: relative;
line-height: 1.6em;
border: 1px solid orange;
}
HeroTableSource {
font-size: .7rem;
font-style: italic;
width: 100%;
display: block;
text-align: right;
}
table.hero-table {
border: 0;
width: 100%;
background: #eee;
margin: 1rem 0;
padding: .5rem;
}
table.hero-table td {
border: 0;
border-top: 1px;
border-right: 1px;
border-left: 1px;
border-color: black;
border-style: solid;
padding: 5px;
margin: 0;
}
</style>
{{#-in-element target}}{{yield}}{{/-in-element}}
{{#-in-element target~}}
{{~#if (has-block)~}}
{{~yield~}}
{{~else~}}
{{~component defaultComponent~}}
{{~/if~}}
{{~/-in-element}}
{
"version": "0.15.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js",
"ember": "3.4.3",
"ember-template-compiler": "3.4.3",
"ember-testing": "3.4.3"
},
"addons": {
"ember-data": "3.4.2"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment