UNPKG

@epa-wg/custom-element

Version:

Declarative Custom Element as W3C proposal PoC with native(XSLT) based templating

219 lines (202 loc) β€’ 11.6 kB
<!DOCTYPE html> <html lang="en" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>custom-element Declarative Custom Element implementation demo</title> <link rel="icon" href="./wc-square.svg" /> <script type="module" src="../local-storage.js"></script> <script type="module" src="../custom-element.js"></script> <style> @import "./demo.css"; button{ background: forestgreen; } table{ min-width: 16rem; } td{ border-bottom: 1px solid silver; } tfoot td{ border-bottom: none; } td,th{text-align: right; } caption{ padding: 1rem; font-weight: bolder; font-family: sans-serif; } </style> <script> window.JsonSample = {a:1,b:'B'}; </script> </head> <body> <nav> <a href="../index.html"><h3><code>custom-element</code> demo</h3></a> </nav> <main> <code>local-storage</code> allows to read and write its value to the key in <code>localStorage</code>. The <code>type</code> attribute allows to place the validation constrains to the value: when the value does not match the expected type, it would not be assigned, keeping empty <code>value</code> instead. </main> <html-demo-element legend="0. read localStorage text value" description="click should set text-key slice via localStorage change."> <template> <custom-element> <template> <local-storage key="textKey" slice="text-key" type="text" live="live"></local-storage> <button onclick="localStorage.setItem('textKey','text value')">text value</button> <button onclick="localStorage.setItem('textKey','another value')">another value</button> //text-key: <code>{//text-key}</code> </template> </custom-element> </template> </html-demo-element> <html-demo-element legend="1. always override " description="value in localStorage[] should be always reset to ABC. click should set text-key slice via localStorage change."> <template> <custom-element> <template> <!-- always reset --> <local-storage slice="override-key" key="overrideKey" type="text" value="ABC"></local-storage> <button onclick="localStorage.setItem( 'overrideKey','text value')">text value</button> <button onclick="localStorage.removeItem('overrideKey' )">clear key</button> //override-key: <code>{ //override-key }</code> </template> </custom-element> </template> </html-demo-element> <html-demo-element legend="2. from storage with default " description="default overridden by button, refresh should preserve updated value"> <template> <custom-element> <template> <!-- initially set value to DEF and update by button. On reload the value picked from localStorage --> <local-storage key="attr2Key" slice="attr2-key" type="text" live="live" slice-value="@value ?? 'DEF'"></local-storage> <button onclick="localStorage.clear()">clear localStorage</button> <button onclick="localStorage.removeItem('attr2Key')">clear key</button> <button onclick="localStorage.setItem('attr2Key','text value')">updated value</button> //attr2-key: <code>{//attr2-key}</code> </template> </custom-element> </template> </html-demo-element> <html-demo-element legend="3. localStorage type" description="type validation happy path. Invalid for type value in storage would be treated as null"> <template> <custom-element> <template> <local-storage key="dateKey" slice="date-key" type="date" live="live"></local-storage> <local-storage key="timeKey" slice="time-key" type="time" live="live"></local-storage> <local-storage key="localDateTimeKey" slice="local-date-time" type="datetime-local" live="live"></local-storage> <local-storage key="numberKey" slice="number-key" type="number" live="live"></local-storage> <local-storage key="jsonKey" slice="json-key" type="json" live="live"></local-storage> <input id="typesinput" placeholder="set value" /><button onclick=" 'dateKey,timeKey,localDateTimeKey,numberKey,jsonKey'.split(',') .map( k=> localStorage.setItem(k, typesinput.value) ) "> set to all</button><br/> <hr/> date-key: <button onclick="localStorage.setItem('dateKey', '2024-04-20T03:58:42.131Z')" >2024-04-21T03:58:42.131Z </button> <button onclick="localStorage.setItem('dateKey', new Date(Date.now()).toISOString())" >now </button> <button onclick="localStorage.setItem('dateKey', 'ABC' )" >date ABC - invalid </button> <code>{//date-key }</code><br/> time-key: <button onclick="localStorage.setItem('timeKey', '13:30')" >13:30 </button> <code>{//time-key }</code><br/> local-date-time: <button onclick="localStorage.setItem('localDateTimeKey', '1977-04-01T14:00:30')" >21977-04-01T14:00:30 - local </button> <code>{//local-date-time}</code><br/> number-key: <button onclick="localStorage.setItem('numberKey', '2024' )" >2024 - number </button> <button onclick="localStorage.setItem('numberKey', '24' )" >24 - number </button> <button onclick="localStorage.setItem('numberKey', '1.23456e+5' )" >1.23456e+5 </button> <button onclick="localStorage.setItem('numberKey', '0001' )" >0001 </button> <button onclick="localStorage.setItem('numberKey', '000' )" >000 </button> <button onclick="localStorage.setItem('numberKey', '0' )" >0 </button> <button onclick="localStorage.setItem('numberKey', 'ABC' )" >ABC - invalid, NaN </button> <code>{//number-key }</code> <br/> <fieldset> <legend>json-key: </legend> <button onclick="localStorage.setItem('jsonKey', JSON.stringify('ABC'))" >'ABC' - string </button> <button onclick="localStorage.setItem('jsonKey', JSON.stringify(12.345))" >12.345 - number </button> <button onclick="localStorage.setItem('jsonKey', JSON.stringify(window.JsonSample) )" >a:1,b:'B' -json </button> <button onclick="localStorage.setItem('jsonKey', 'ABC' )" >ABC - invalid </button><br/> json-key:<code><xsl:apply-templates select="//json-key/value/@*|//json-key/text()|//json-key/value/text()" mode="json"></xsl:apply-templates></code> </fieldset> <xsl:template mode="json" match="*|@*"> <div>{name()} : {.}</div> </xsl:template> </template> </custom-element> </template> </html-demo-element> <html-demo-element legend="3. localStorage simplest" description="local-storage read only during initial and only render, does not track the changes."> <p>Has to produce 12πŸ’</p> <template> <custom-element tag="dce-1" hidden> {//slice/fruits/text()} <slot>πŸ€”</slot> <local-storage key="cherries" slice="fruits"></local-storage> </custom-element> <dce-1>πŸ’</dce-1> </template> </html-demo-element> <html-demo-element legend="2. localStorage basket JSON " description="local-storage tracks changes"> <p>Click the fruits button to add into cart </p> <template> <custom-element tag="dce-2" hidden> <template> <local-storage key="basket" slice="basket" live type="json"></local-storage> <xhtml:table xmlns:xhtml="http://www.w3.org/1999/xhtml" > <xhtml:tbody> <for-each select="//basket/value/@*"> <xhtml:tr> <xhtml:th> {name()} </xhtml:th> <xhtml:td> {.} </xhtml:td> </xhtml:tr> </for-each> </xhtml:tbody> <xhtml:tfoot> <xhtml:tr> <xhtml:td><slot>πŸ€”</slot></xhtml:td> <xhtml:th> {sum(//slice/basket/value/@*)} </xhtml:th> </xhtml:tr> </xhtml:tfoot> </xhtml:table> </template> </custom-element> <dce-2>πŸ›’total</dce-2> </template> </html-demo-element> <fieldset> <legend>localStorage content</legend> <p>The demo should display count 1πŸ‹ and 12πŸ’ initially. The value in <code>localStorage</code> is incremented when clicked on matching button </p> <button name="lemons" value="1" >πŸ‹</button> <button name="cherries" value="12" >πŸ’</button> <button name="apple" >🍏</button> <button name="banana" >🍌</button> <table> <caption> Click to add the localStorage value </caption> <thead><tr><th>key</th><th>value</th></tr></thead> <tbody id="local-storage-values"></tbody> </table> </fieldset> <script type="module"> import { localStorageSetItem } from '../local-storage.js'; import $ from 'https://unpkg.com/css-chain@1/CssChain.js'; const basket = {cherries: 12, lemons:1 }; localStorageSetItem( 'basket', JSON.stringify(basket) ); $('button[name]') .forEach( b=> localStorage.setItem( b.name, b.value ) ) .addEventListener( 'click', e => { const k = e.target.name; basket[k] || (basket[k] = 1); localStorageSetItem( k, basket[k] = 1+1*localStorage[k] ) localStorageSetItem( 'basket', JSON.stringify(basket) ); renderStorage(); } ); const renderStorage = () => window[ 'local-storage-values' ].innerHTML = [...Array(localStorage.length).keys()] .map( k => `<tr><th>${ localStorage.key(k) }</th><td>${ localStorage.getItem( localStorage.key(k) ) }</td>` ).join( '\n' ); window.addEventListener( 'storage', renderStorage ); window.addEventListener( 'local-storage', renderStorage ); renderStorage(); </script> <script type="module" src="https://unpkg.com/html-demo-element@1/html-demo-element.js"></script> </body> </html>