diff --git a/packages/csx/.npmignore b/packages/csx/.npmignore index 1353eac..b15d472 100644 --- a/packages/csx/.npmignore +++ b/packages/csx/.npmignore @@ -1,4 +1,5 @@ # Don't publish the src containing ESNext proposal's code. Only publish the bundled output in dist/ and the ES6-transpiled src from lib/ src/* +node_modules/* rollup.config.js yarn.lock \ No newline at end of file diff --git a/packages/csx/package.json b/packages/csx/package.json index afc65b8..4c08111 100644 --- a/packages/csx/package.json +++ b/packages/csx/package.json @@ -1,6 +1,6 @@ { "name": "@cerxes/csx", - "version": "0.0.7", + "version": "0.0.8", "author": "Miel Truyen ", "description": "CSX is a minimalistic UI-framework inspired by React+JSX for usage with WebComponents.", "repository": { diff --git a/packages/csx/src/vdom/renderers/nodetree.js b/packages/csx/src/vdom/renderers/nodetree.js index 18c4603..3c4ab30 100644 --- a/packages/csx/src/vdom/renderers/nodetree.js +++ b/packages/csx/src/vdom/renderers/nodetree.js @@ -88,7 +88,12 @@ export const NodeTreeRenderer = { if(!newVal){ host.removeEventListener(eventName, oldVal); }else{ - host.addEventListener(eventName, newVal); + if (oldVal && oldVal !== newVal){ + host.removeEventListener(eventName, oldVal); + } + if(newVal !== oldVal){ + host.addEventListener(eventName, newVal); + } } }else{ // Assumed to be just an attribute diff --git a/tests/index.html b/tests/index.html index d8abe6b..5029a86 100644 --- a/tests/index.html +++ b/tests/index.html @@ -24,6 +24,9 @@
  • Todos MVC
  • +
  • + Tables (arrow functions) +
  • \ No newline at end of file diff --git a/tests/table/index.html b/tests/table/index.html new file mode 100644 index 0000000..a2aa127 --- /dev/null +++ b/tests/table/index.html @@ -0,0 +1,10 @@ + + + + + Cerxes - CustomElements - SVG + + + + + \ No newline at end of file diff --git a/tests/table/index.jsx b/tests/table/index.jsx new file mode 100644 index 0000000..0b01452 --- /dev/null +++ b/tests/table/index.jsx @@ -0,0 +1,108 @@ +import {render, CustomElement, defineElement, Host, prop, state} from "../../packages/csx"; +import style from "./index.scss"; +import {TableComponent} from "./table-component"; + +@defineElement("table-tester") +class TableTester extends CustomElement{ + + + /** + * + * @type {({[headerRender]: (function(): string), render: (function(User): *), [size]: number})[]} + */ + #columnDefinitions = [ + { + headerRender: () => "Id", + render: (u) => u.userId, + size: 110 + }, + { + headerRender: () => "Email", + render: (u) => u.identity?.email, + }, + { + headerRender: () => "FirstName", + render: (u) => u.identity?.firstName, + size: 160 + }, + { + headerRender: () => "LastName", + render: (u) => u.identity?.lastName, + size: 160 + }, + { + headerRender: () => "...", + render: (u) => { + let d = new Date(); + return () + }, + size: 110 + }, + ]; + + @state() + users = []; + + render(){ + + return + } + + connectedCallback() { + super.connectedCallback(); + + setTimeout(()=>this.load(), 0); + setTimeout(()=>this.load(), 50); + setTimeout(()=>this.load(), 100); + setTimeout(()=>this.load(), 150); + setTimeout(()=>this.load(), 200); + setTimeout(()=>this.load(), 250); + + this.interval = setInterval(()=>this.load(), 3000); + } + + interval; + disconnectedCallback() { + super.disconnectedCallback(); + if(this.interval) { + clearInterval(this.interval); + } + } + + load(){ + let users = []; + + let rndFirstNames = ['Loes', 'Johnny', 'Maria', 'Jezus', 'Philippe', 'Filip', 'Annie']; + let rndLastNames = ['Peeters', 'Wachters', 'Jannsens', 'De Schaetzen', 'Becks', 'Konings', 'De Clerk']; + + for(let i = 0; i < 5; ++i){ + let first = rndFirstNames[Math.floor(rndFirstNames.length*Math.random())]; + let last = rndLastNames[Math.floor(rndLastNames.length*Math.random())]; + users.push({ + userId: (Math.random()*99999).toString(36).slice(-6).toUpperCase(), + identity: { + firstName: first, + lastName: last, + email: `${first}.${last}@example.com`.toLocaleLowerCase() + } + }) + } + + this.users = users; + } + + lastClear = new Date(); + testMe = (ev, u, d)=>{ + if((new Date()).getTime() - this.lastClear.getTime() > 20){ + console.log("\n\n"); + this.lastClear = new Date(); + } + console.log("I should only show up once per click:", d.getTime()); + } +} + +document.body.appendChild(render()); +document.body.appendChild(render()); diff --git a/tests/table/index.scss b/tests/table/index.scss new file mode 100644 index 0000000..1229903 --- /dev/null +++ b/tests/table/index.scss @@ -0,0 +1,19 @@ +html{ + width: 100%; + height: 100%; +} + +body{ + display: flex; + flex-direction: column; + overflow: auto; + + width: 100%; + height: 100%; + padding: 0; + margin: 0; +} + +.center-me{ + align-self: center; +} \ No newline at end of file diff --git a/tests/table/table-component.jsx b/tests/table/table-component.jsx new file mode 100644 index 0000000..8d2d7eb --- /dev/null +++ b/tests/table/table-component.jsx @@ -0,0 +1,61 @@ +import {CustomElement, defineElement, Host, prop, state} from "../../packages/csx"; +import TableComponentStyle from "./table-component.scss"; + +let tableId = 0; + +@defineElement("tripto-table") +export class TableComponent extends CustomElement { + + #columnDefinitions; + + @prop() + set columns(value) { + this.#columnDefinitions = value; + } + + @state() data; + + @prop() + set data(value) { + this.data = value; + } + + #tableId = tableId++; + render() { + console.log(`Table render at for ${this.data?.length??0} rows: ${Date.now()}`); + return ( + + + +
    +
    +
    + {this.#columnDefinitions.map((col, idx) => ( +
    + {col.headerRender()} +
    + ))} +
    +
    +
    + {this.data?.map(dataRow => ( +
    + {this.#columnDefinitions.map((col, idx) => ( +
    + {col.render(dataRow)} +
    + ))} +
    + ))} +
    +
    +
    + ); + } +} \ No newline at end of file diff --git a/tests/table/table-component.scss b/tests/table/table-component.scss new file mode 100644 index 0000000..d3c2895 --- /dev/null +++ b/tests/table/table-component.scss @@ -0,0 +1,32 @@ + +.table { + --box-color: #a0a0a0; + --primary-color: #5f74ff; + --table-background: #e4e4f0; + --box-border: 1px solid #7d7d7d; + + border: var(--box-border); + display: block; + + header { + color: var(--primary-color); + } + + header > .row, + main > .row { + background: var(--table-background); + display: flex; + width: 100%; + line-height: 3em; + border-bottom: var(--box-border); + + .cell { + padding: 0 15px; + } + } + main > .row { + &:last-child { + border-bottom: 0; + } + } +} \ No newline at end of file