Skip to content

Commit

Permalink
feat: renderItem: render templates with lit-html
Browse files Browse the repository at this point in the history
This adds support to pass data-nav a `renderItem` function,
which should return a lit-html TemplateResult when invoked.
If set, this will use lit-html rendering instead of the current
Polymer template handling.

The resize-forwarding behavior of iron-resize has been disabled
when using renderItem. If resizing issues occur when migrating
to renderItem, switch to ResizeObserver in the data-nav view.
  • Loading branch information
Patrik Kullman authored and JockeCK committed Jun 25, 2020
1 parent dc59194 commit fc10bdf
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 21 deletions.
51 changes: 37 additions & 14 deletions cosmoz-data-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ class CosmozDataNav extends hauntedPolymer('haunted', useDataNav)(mixinBehaviors
value: 1
},

renderItem: {
type: Function
},

/**
* The currently selected index.
*/
Expand Down Expand Up @@ -353,7 +357,7 @@ class CosmozDataNav extends hauntedPolymer('haunted', useDataNav)(mixinBehaviors
}

_onTemplatesChange(change) {
if (!this._elementTemplate) {
if (!this._elementTemplate && !this.renderItem) {
const templates = change.addedNodes.filter(n => n.nodeType === Node.ELEMENT_NODE && n.tagName === 'TEMPLATE'),
elementTemplate = templates[0];

Expand Down Expand Up @@ -419,6 +423,11 @@ class CosmozDataNav extends hauntedPolymer('haunted', useDataNav)(mixinBehaviors
incDiv = document.createElement('div');
element.appendChild(incDiv);
element.__incomplete = incDiv;
if (this.renderItem) {
const instDiv = document.createElement('div');
element.appendChild(instDiv);
element.__instance = instDiv;
}
element.setAttribute('slot', 'items');
element.classList.add('animatable');
return element;
Expand Down Expand Up @@ -547,12 +556,13 @@ class CosmozDataNav extends hauntedPolymer('haunted', useDataNav)(mixinBehaviors
return;
}

// update instance's data-nav related props
const instance = renderedElement.__instance;
Object.entries(this._getBaseProps(index))
.forEach(([key, value]) => instance._setPendingProperty(key, value));
instance._flushProperties();

if (!this.renderItem) {
// update instance's data-nav related props
const instance = renderedElement.__instance;
Object.entries(this._getBaseProps(index))
.forEach(([key, value]) => instance._setPendingProperty(key, value));
instance._flushProperties();
}
this._elements.splice(renderedIndex, 1);
this.splice('_elements', elementIndex, 0, renderedElement);
}
Expand Down Expand Up @@ -709,7 +719,7 @@ class CosmozDataNav extends hauntedPolymer('haunted', useDataNav)(mixinBehaviors
baseProps = this._getBaseProps(index),
instance = element.__instance;

if (instance) {
if (!this.renderItem && instance) {
Object.assign(instance, baseProps);
}

Expand All @@ -727,7 +737,7 @@ class CosmozDataNav extends hauntedPolymer('haunted', useDataNav)(mixinBehaviors
return;
}

instance._showHideChildren(true);
this._toggleInstance(instance, false);
}

_removeInstance(instance) {
Expand Down Expand Up @@ -859,7 +869,7 @@ class CosmozDataNav extends hauntedPolymer('haunted', useDataNav)(mixinBehaviors
* @return {Boolean} True if the element should be notified
*/
resizerShouldNotify(resizable) {
return this._isDescendantOfElementInstance(resizable, this.selectedElement);
return !this.renderItem && this._isDescendantOfElementInstance(resizable, this.selectedElement);
}

/**
Expand Down Expand Up @@ -894,7 +904,7 @@ class CosmozDataNav extends hauntedPolymer('haunted', useDataNav)(mixinBehaviors
* @return {Boolean} True if descendant has been notified.
*/
_notifyElementResize(element = this.selectedElement) {
if (!this.isConnected || !element) {
if (this.renderItem || !this.isConnected || !element) {
return false;
}

Expand Down Expand Up @@ -942,8 +952,6 @@ class CosmozDataNav extends hauntedPolymer('haunted', useDataNav)(mixinBehaviors
instance = new this._elementCtor(props);

element.__instance = instance;
element.item = item;
element._reset = false;
element.appendChild(instance.root);
}

Expand Down Expand Up @@ -1011,19 +1019,34 @@ class CosmozDataNav extends hauntedPolymer('haunted', useDataNav)(mixinBehaviors
this._renderRan = needsRender;

if (needsRender) {
element.item = item;
element._reset = false;
if (this.renderItem) {
render(this.renderItem(item, idx, this.items), element.__instance);
this._toggleInstance(element.__instance, true);
return;
}
this._forwardItem(element, item, idx);
if (isSelected) {
return idx;
}
} else if (isSelected) {
// make sure that the instance is visible (may be a re-aligned invisible instance)
element.__instance._showHideChildren(false);
this._toggleInstance(element.__instance, true);
// resize is a expensive operation
this._renderRan = this._notifyElementResize();
this._setSelectedInstance(this._getInstance(element));
}
}

_toggleInstance(inst, show) {
if (this.renderItem) {
inst.style.display = show ? 'block' : 'none';
return;
}
inst._showHideChildren(!show);
}

_getItemId(item) {
return this.isIncompleteFn(item) ? item : this.get(this.idPath, item);
}
Expand Down
15 changes: 8 additions & 7 deletions demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ const asyncs = {},
console.log('on need data', id);
asyncs[id] = setTimeout(() => dataNav.setItemById(id, { id }), 500);
},
computeJSON = index => JSON.stringify(items[index]);
computeJSON = index => JSON.stringify(items[index]),
renderItem = (item, index, items) => html`
<cosmoz-demo-view
.item="${ item }" .index="${ index }"
.prevDisabled="${ index < 1 }" .nextDisabled="${ index > items.length - 2 }">
</cosmoz-demo-view>
`;

useEffect(() => {
if (instance?.dataset == null) {
Expand Down Expand Up @@ -65,13 +71,8 @@ const asyncs = {},
@selected-changed="${ e => setSelected(e?.detail?.value) }"
@selected-item-changed="${ e => setSelItem(e?.detail?.value) }"
@selected-instance-changed="${ e => setInstance(e?.detail?.value) }"
.renderItem="${ renderItem }"
>
<template>
<cosmoz-demo-view
item="{{ item }}" index="[[ index ]]"
prev-disabled="[[ prevDisabled ]]" next-disabled="[[ nextDisabled ]]">
</cosmoz-demo-view>
</template>
</cosmoz-data-nav>
<paper-textarea value="${ computeJSON(selected) }"></paper-textarea>
<div>Selected: ${ JSON.stringify(selItem) }</div>
Expand Down

0 comments on commit fc10bdf

Please sign in to comment.