Skip to content
Permalink
Browse files

feat(template-strategy-default): walk up the DOM tree and determine w…

…hat element will be scroller for virtual repeat
  • Loading branch information...
jorgenskogas committed Mar 26, 2019
1 parent d32c05d commit 6ebf90752bbf3d798e24af795c7346d7260424e8
@@ -0,0 +1,61 @@
<template>
<div class="scroller" style="overflow-y: scroll">
<div class="grid-force-size">
<div class="d-flex grid-header">
<div class="p-2 grid-column-index" style="width: 50px;">#</div>
<div class="p-2" style="width: 200px;">First Name</div>
<div class="p-2" style="width: 200px;">Last Name</div>
<div class="p-2 flex-fill">Action</div>
</div>
<div
virtual-repeat.for="person of people"
infinite-scroll-next.call="push30($scrollContext)"
class="d-flex grid-row">
<div class="p-2 grid-column-index" style="width: 50px;">${$index}</div>
<div class="p-2" style="width: 200px;">${person.fname}</div>
<div class="p-2" style="width: 200px;">${person.lname}</div>
<div class="flex-fill">
<button type="button" class="btn btn-link"><i class="far fa-edit"></i></button>
<button type="button" class="btn btn-link"><i class="far fa-trash-alt"></i></button>
</div>
</div>
</div>
</div>
<style>
.scroller {
position: relative;
height: 500px;
width: 400px;
overflow: scroll;
}
.grid-force-size {
border-right: 3px solid #ff00ff;
border-bottom: 3px solid #ff00ff;
width: 600px;
}
.grid-header {
position: sticky;
top: 0px;
background-color: #f0f0f0;
border-top: 3px solid #ff00ff;
z-index: 2;
}
.grid-row:nth-child(even) {
background-color: #fff;
}
.grid-row:nth-child(odd) {
background-color: #f1a3f1;
}
.grid-column-index {
position: sticky;
left: 0px;
border-left: 3px solid #ff00ff;
z-index: 1;
background-color: aqua;
text-align: center;
}
.grid-header .grid-column-index {
background-color: #f0f0f0;
}
</style>
</template>
@@ -0,0 +1,44 @@
interface IScrollContext {
isAtTop: boolean;
isAtBottom: boolean;
topIndex: number;
}

export interface Person {
fname: string;
lname: string;
}

const fNames = [
// tslint:disable-next-line:max-line-length
'Ford', 'Arthur', 'Trillian', 'Sneezy', 'Sleepy', 'Dopey', 'Doc', 'Happy', 'Bashful', 'Grumpy', 'Mufasa', 'Jørgen', 'Simba', 'Nala', 'Kiara', 'Kovu', 'Timon', 'Pumbaa', 'Rafiki', 'Shenzi'
];
const lNames = [
// tslint:disable-next-line:max-line-length
'Prefect', 'Dent', 'Astra', 'Adams', 'Baker', 'Clark', 'Davis', 'Evans', 'Frank', 'Ghosh', 'Hills', 'Irwin', 'Jones', 'Klein', 'Lopez', 'Mason', 'Nalty', 'Ochoa', 'Patel', 'Quinn', 'Reily', 'Smith', 'Trott', 'Usman', 'Valdo', 'White', 'Xiang', 'Yakub', 'Zafar'
];
export class PromiseGetMoreApp {
private people: Person[];

constructor() {
this.people = [
{ fname: fNames[0], lname: lNames[0] },
{ fname: fNames[1], lname: lNames[1] },
{ fname: fNames[2], lname: lNames[2] }
];
this.push30(undefined, 0);
}

public async push30(scrollContext?: IScrollContext, count = 30) {
console.log('scrollContext: ', scrollContext);
if (this.people.length < 200 && (!scrollContext || scrollContext.isAtBottom)) {
for (let i = 0; i < count; i++) {
this.people.push({
fname: fNames[Math.floor(Math.random() * fNames.length)],
lname: lNames[Math.floor(Math.random() * lNames.length)]
});
}
}
console.log('Population size:', this.people.length);
}
}
@@ -31,6 +31,12 @@ export class PromiseGetMoreApp {
moduleId: PLATFORM.moduleName('./scroller-table-multiple-repeats/sub-app'),
nav: true,
title: 'Scroller + Table + Position Relative + Multiple Repeats'
},
{
route: 'scroller-not-first-parent-div',
moduleId: PLATFORM.moduleName('./scroller-not-first-parent-div/sub-app'),
nav: true,
title: 'Scroller (not first parent) + Div'
}
]).mapUnknownRoutes({
redirect: '',
@@ -1,11 +1,11 @@
import { IView, ITemplateStrategy } from './interfaces';
import { insertBeforeNode } from './utilities-dom';
import { insertBeforeNode, getScrollContainer } from './utilities-dom';
import { DOM } from 'aurelia-pal';

export class DefaultTemplateStrategy implements ITemplateStrategy {

getScrollContainer(element: Element): HTMLElement {
return element.parentNode as HTMLElement;
return getScrollContainer(element);
}

moveViewFirst(view: IView, topBuffer: Element): void {
@@ -9,7 +9,7 @@ import { IView } from './interfaces';
export const getScrollContainer = (element: Node): HTMLElement => {
let current = element.parentNode as HTMLElement;
while (current !== null) {
if (this.hasOverflowScroll(current)) {
if (hasOverflowScroll(current)) {
return current;
}
current = current.parentNode as HTMLElement;
@@ -34,7 +34,7 @@ export const getElementDistanceToTopOfDocument = (element: Element): number => {
*/
export const hasOverflowScroll = (element: HTMLElement): boolean => {
let style = element.style;
return style.overflowY === 'scroll' || style.overflow === 'scroll' || style.overflowY === 'auto' || style.overflow === 'auto';
return style && (style.overflowY === 'scroll' || style.overflow === 'scroll' || style.overflowY === 'auto' || style.overflow === 'auto');
};

/**

0 comments on commit 6ebf907

Please sign in to comment.
You can’t perform that action at this time.