Skip to content

Instantly share code, notes, and snippets.

@lukesargeant
Last active October 18, 2018 08:19
Show Gist options
  • Save lukesargeant/139702651a39c88bdb03edd824b3b6ff to your computer and use it in GitHub Desktop.
Save lukesargeant/139702651a39c88bdb03edd824b3b6ff to your computer and use it in GitHub Desktop.
Ember 3.4 Trans-Y helper for simplifying add/remove animations in lists and tables
html, body {
margin: 0;
padding: 0;
background: #2C2C2C;
font-family: "Helvetica Neue";
font-size: 12px;
}
.grid_header {
height: 30px;
background: #f3f3f3;
font-weight: bold;
width: 500px;
padding: 0 10px;
box-sizing: border-box;
display: flex;
align-items: center;
}
.grid_body {
position: absolute;
overflow: auto;
width: 500px;
top: 30px;
bottom: 0;
left: 0;
background: #f3f3f3;
}
.grid_row {
width: 100%;
padding: 0 10px;
box-sizing: border-box;
background-color: #fff;
overflow: hidden;
display: flex;
align-items: center;
transition: transform 300ms ease-out; /* controls speed of add/remove row */
}
.grid_row > div, .grid_header > div {
flex: 1;
}
.grid_row > button, .grid_header > button {
flex: 0 0 100px;
margin: 2px 0;
}
<header class="grid_header">
<div>Name</div>
<div>Data</div>
<div>Data2</div>
<button {{action "addItem"}}>Add</button>
</header>
<div class="grid_body">
{{~#each items key="name" as |item index|}}
<div class="grid_row" style={{trans-y index rowHeight}}>
<div>{{item.name}}</div>
<div>{{item.data}}</div>
<div>{{item.data2}}</div>
<button {{action "removeItem" item}}>Remove</button>
</div>
{{/each~}}
</div>
import Controller from '@ember/controller';
import { get, set } from '@ember/object';
let counter = 0;
function generateItem() {
return {
name: `Item ${counter++}`,
data: Math.random().toFixed(2),
data2: Math.random().toFixed(2),
};
}
function generateItems(num) {
let items = [];
for (let i = 0; i < num; i++) {
items.push(generateItem());
}
return items;
}
export default Controller.extend({
rowHeight: 42,
init() {
set(this, 'items', generateItems(200));
},
actions: {
removeItem(toRemove) {
set(this, 'items', get(this, 'items').filter(item => item !== toRemove));
},
addItem() {
set(this, 'items', [generateItem(), ...get(this, 'items')]);
},
}
});
import { helper } from '@ember/component/helper';
import { htmlSafe } from '@ember/template';
export function transY([index, rawHeight = 25, unit = 'px', spacing = 1]/*, hash*/) {
let height = rawHeight + unit;
let translateY = `${index * (+rawHeight + spacing)}${unit}`;
return htmlSafe(`
position: absolute;
transform: translateY(${translateY});
height: ${height};
line-height: ${height};
`);
}
export default helper(transY);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment