This package contains a suite of web components, depending on the placement of the dash -- i-bid, ib-id[TODO], ibi-d[TODO].
Each of them provide a simple, 1-dimensional list generating web component*. They generate lists of (Custom) DOM elements from JSON, but can complement server-side rendering.
Often, an API will provide a JSON list (array of items) that is purely devoted to describing the business entities it represents (tailored somewhat, perhaps, for the particular view to be presented). (Let's park the important question of SSR for the time being).
Most repeater web components (there aren't that many, thanks to ES Modules greatly preceding HTML Modules), including grid web components, provide a helpful mapping mechanism between what the API provides, vs what the UI requires, via some form of moustache-style syntax, for the light children.
However, ibid's focus is on a different use case than other repeating web components:
- It has full, first-class support for enumerated tag names[WIP].
- It can complement server-side (initial) rendering[WIP].
- It does not provide any support for moustache-style template binding of the light children within each element. It is rooting for the platform to support this feature natively. It does, however, provide "binding from a distance" via transform syntax similar to non-inline css styling. If and when the platform adds support for binding the light children via moustache-style template binding, this component will support said binding, but will continue to provide support for the currently supported transform-like binding as a complementary mechanism, giving developers a choice depending on what works best.
- It renders its content (near-) adjacent to itself, so that it can insert content inside built-in list elements, or table elements, without violating proper HTML decorum.
Why provide support for different tags? Consider a few scenarios:
- Lists of repeating elements that alternate between a few tags - like the Description List Element
- "Higher order" lists of entities, where the entities take a variety of forms -- Cells of a Jupyter Notebook, for example
<ul>
<li>Head Item</li>
<li data-from=li-gen>...</li>
<li>Footer Item</li>
</ul>
<i-bid
id=li-gen
list='["hello", "world"]',
transform='{"li": "."}'
></i-bid>
Generates:
<ul>
<li>Head Item</li>
<li>hello</li>
<li>world</li>
<li>Footer</li>
</ul>
<i-bid
id=li-gen
list='["hello", "world"]',
transform='{"li": "."}'
></i-bid>
<ul>
<li>Head Item</li>
<li data-from=li-gen>...</li>
<li>Footer Item</li>
</ul>
<i-bid
id=li-gen
list='["hello", "world"]'
transform='{"li": ["."]}'
updatable>
</i-bid>
Generates:
<ul>
<li>Head Item</li>
<template data-ref=li-gen data-idx=0></template>
<li>hello</li>
<template data-ref=li-gen data-idx=1></template>
<li>world</li>
<li>Footer</li>
</ul>
<i-bid id=li-gen list='["hello", "world"]' updatable></i-bid>
So the only difference is the presence of the updatable attribute. The presence of that attribute helps to provide master / detail binding, and also is required for nested ibid's.
<dl>
<dt>Definition</dt>
<dd>Meaning of the word</dd>
<template data-from=dl-gen>
<dt></dt>
<dd></dd>
</template>
</dl>
<i-bid id=dl-gen
list='[{"term": "nah", "def": "not so"}, {"term":"goo", "def": "a viscid or sticky substance"}]'
updatable
transform='
{
"dtElements": ["term"],
"ddElements": ["def"]
}
'
>
</i-bid>
generates
<dl>
<dt>Definition</dt>
<dd>Meaning of the word</dd>
<template data-ref=dl-gen data-idx=0></template>
<dt>nah</dt><dd>not so</dd>
<template data-ref=dl-gen data-idx=1></template>
<dt>goo</dt><dd>a viscid or sticky substance</dd>
</dl>
<i-bid id=dl-gen list='[{"term": "nah", "def": "not so"}, {"term":"goo", "def": "a viscid or sticky substance"}]' updatable></i-bid>
<ul>
<template>
<li>
<span class=description></span>
<ul>
<li>
<span class=name></span>
</li>
</ul>
<i-bid updatable auto-nest -list-src list-prop=innerList from-previous=ul search-for=li transform='{".name": "name"}'></i-bid>
</li>
</template>
</ul>
<i-bid
updatable
list='[
{"description": "first item", "innerList": [{"name": "a"}, {"name": "b"}]},
{"description": "second item", "innerList": [{"name": "c"}, {"name": "b"}]}
]
'
transform='{".description": "description"}'
from-previous=ul
search-for=template
>
</i-bid>
In examples I and II, we demonstrated that wrapping the content that needs to repeat in a template is optional. Example III showed use of the template wrapper.
However, if nested ibid's are required, then wrapping outer ibid's in templates becomes required. The outer ibid's also have to have updatable set.
Note also our use of from-previous, search-for attributes. These allow for an alternative to specifying the id's.
<i-bid tag-list='[
{"localName": "tag-1", "prop1": "val1"},
{"localName": "tag-2", "prop1": "val2"}
]'>
Generates
<tag-1>hello 1</tag-1>
<tag-2>hello 2</tag-2>
<my-notebook>
<template data-from=notebook-gen>
<template itemprop=searchbox>
<label></label>
<input type=search>
</template>
<template itemprop=grid>
<my-grid></my-grid>
</template>
</template>
</my-notebook>
<i-bid id=notebook-gen list='
[
{"type": "searchbox", "hint": "Enter SSN", "label": },
{"type": "grid", "data": {}}
]
'
templ-match-on=type
transform='
"searchbox":{
},
"grid":{
}
'
updatable>
</i-bid >
generates
<my-notebook>
<template data-ref=notebook-gen data-idx=0 data-templ-idx=0></template>
<input placeholder="Enter Name">
<template data-ref=notebook-gen data-idx=1 data-templ-idx=1></template>
<my-grid></my-grid>
</my-notebook>
<i-bid>
<!--In memory -->
<template if-all-of=[]>
</i-bid>