DeltaComponent

Description

A component that animates changes

DeltaComponent updates its DOM tree to match a new component's DOM tree using a diff algorithm. It detects text appends and adds them as new spans to avoid full re-rendering.

This DeltaComponent renders its content inside a Shadow DOM root.

Samples

Basic Delta Animation

Shadow DOM

API reference

class

DeltaComponent

public class DeltaComponent : IComponent

A small inline metric showing the change between two values (with up/down arrow and tone for positive / negative / neutral deltas).

Namespace
Tesserae
Implements
IComponent

Constructors

NameDescription
DeltaComponentInitializes a new instance of this class.
Constructor
DeltaComponent
public DeltaComponent(IComponent initial, bool useShadowDom = false)

Initializes a new instance of this class.

Methods

NameDescription
AnimatedConfigures the component to animated.
ReplaceContentReconciles what is on screen with newContent, in place: the nodes that match are kept and patched, and only what genuinely differs is swapped. That is the point of this component - a streamed reply re-rendered per frame keeps its scroll position, its selection and its text nodes instead of flickering - but it also means a node that stays keeps the event listeners its component gave it, so nodes are only ever reconciled with nodes of the same component (see CanReconcile).
DiffAndPatchPatches current into next, or swaps it out when the two cannot be reconciled. Returns the node that is on screen afterwards, which is current for a patch and next for a swap.
CanReconcileWhether two nodes may be reconciled with each other rather than swapped: the same kind of node, and the same component. A node carries the event listeners its component attached to it and no patch can move those, so re-purposing a node from one component to another leaves it answering to a component nobody can reach any more: the symptom is a control that looks right and does what its predecessor did - a tool call that became a "tools used" group mid-stream opening the chip it used to be instead of the group it is now.
RootClassOfThe first class on element that its component put there, skipping the ones the toolkit adds from outside.
MarkAsReapplyingPuts this component on the element it currently renders, so that the fluent helpers can tell in one property read whether what they are applying needs remembering.
RememberStylingRecords something just applied to this component, so it can be applied again to the element the component renders next. Ignored while a replay is in progress, so a replayed call does not record itself a second time.
ReapplyStylingApplies everything recorded through RememberStyling to the element this component renders now, in the order it was originally applied.
RenderRenders the component's root HTML element.
Method
DeltaComponent.Animated
public DeltaComponent Animated()

Configures the component to animated.

Method
DeltaComponent.ReplaceContent
public void ReplaceContent(IComponent newContent)

Reconciles what is on screen with newContent, in place: the nodes that match are kept and patched, and only what genuinely differs is swapped. That is the point of this component - a streamed reply re-rendered per frame keeps its scroll position, its selection and its text nodes instead of flickering - but it also means a node that stays keeps the event listeners its component gave it, so nodes are only ever reconciled with nodes of the same component (see CanReconcile).

Method
DeltaComponent.DiffAndPatch
private Node DiffAndPatch(Node current, Node next)

Patches current into next, or swaps it out when the two cannot be reconciled. Returns the node that is on screen afterwards, which is current for a patch and next for a swap.

Method
DeltaComponent.CanReconcile
private static bool CanReconcile(Node current, Node next)

Whether two nodes may be reconciled with each other rather than swapped: the same kind of node, and the same component. A node carries the event listeners its component attached to it and no patch can move those, so re-purposing a node from one component to another leaves it answering to a component nobody can reach any more: the symptom is a control that looks right and does what its predecessor did - a tool call that became a "tools used" group mid-stream opening the chip it used to be instead of the group it is now.

Method
DeltaComponent.RootClassOf
private static string RootClassOf(HTMLElement element)

The first class on element that its component put there, skipping the ones the toolkit adds from outside.

Remarks

tss-fade-in is added by this component to every node it inserts, and tss-stack-item by the container that took the element in. Both go on the node that is on screen and never on the freshly rendered one it is compared with, and on an element with no class of its own they are the first class. Counting them made the two sides of every classless element disagree: each <strong>, <code>, <p> and <table> of a streamed Markdown reply was swapped - and faded in again - on every chunk after the one that inserted it.

Method
DeltaComponent.MarkAsReapplying
private void MarkAsReapplying()

Puts this component on the element it currently renders, so that the fluent helpers can tell in one property read whether what they are applying needs remembering.

Remarks

The alternative, testing the component's type in each helper, was measured at a fifth of the cost of .Class() itself - which a page calls thousands of times, virtually never on a DeltaComponent. A missing property on an element is a plain read.

Method
DeltaComponent.RememberStyling
internal void RememberStyling(Action reapply, bool replayAfterPatch)

Records something just applied to this component, so it can be applied again to the element the component renders next. Ignored while a replay is in progress, so a replayed call does not record itself a second time.

Parameters

reapply
Applies the same thing again to whatever the component renders.
replayAfterPatch
Whether replaying it after a patch - which happens on every content change, not only on the rarer swap - is free of side effects. True for a call that writes an attribute and nothing else, which is exactly what a patch overwrites. False for anything that also attaches something the patch leaves alone: a tooltip's listener and tippy instance survive a patch, and calling for another one per frame would stack them up.
Method
DeltaComponent.ReapplyStyling
private void ReapplyStyling(bool afterPatch)

Applies everything recorded through RememberStyling to the element this component renders now, in the order it was originally applied.

Method
DeltaComponent.Render
public HTMLElement Render()

Renders the component's root HTML element.

See also