From 5595c0df2ccefa957d8f89ba750347ee0325482d Mon Sep 17 00:00:00 2001 From: Stefan Dietz Date: Wed, 17 Jan 2024 09:32:53 +0100 Subject: [PATCH 1/5] Touch up and extend samples for table render function --- .../src/components/table/render-cell.tsx | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/samples/react/src/components/table/render-cell.tsx b/packages/samples/react/src/components/table/render-cell.tsx index bfb1b87d54..574658045f 100644 --- a/packages/samples/react/src/components/table/render-cell.tsx +++ b/packages/samples/react/src/components/table/render-cell.tsx @@ -11,30 +11,38 @@ import { SampleDescription } from '../SampleDescription'; const HEADERS: KoliBriTableHeaders = { horizontal: [ [ - { label: '#', key: 'order', textAlign: 'center', width: '10em' }, + { + label: '#', + key: 'order', + textAlign: 'center', + width: '10em', + + /* Example 1: Simple render function using textContent */ + render: (el, cell) => { + el.textContent = `Index: ${cell.label}`; + }, + }, { label: 'Datum (string)', key: 'date', width: '20em', textAlign: 'center', - render: (el, tupel) => { - // https://reactjs.org/docs/portals.html - getRoot(el).render({DATE_FORMATTER.format(tupel.label as unknown as Date)}); + + /* Example 2: Render function using innerHTML. ⚠️Make sure to sanitize data to avoid XSS. */ + render: (el, cell) => { + el.innerHTML = `${DATE_FORMATTER.format(cell.label as unknown as Date)}`; }, - sort: (data: Data[]) => - data.sort((data0, data1) => { - if (data0.date < data1.date) return -1; - else if (data1.date < data0.date) return 1; - else return 0; - }), + sort: (data: Data[]) => data.sort((data0, data1) => data0.date.getTime() - data1.date.getTime()), }, { label: 'Aktion (react)', key: 'order', + + /* Example 3: Render function using React */ render: (el) => { el.setAttribute('role', 'presentation'); - // https://reactjs.org/docs/portals.html + /* https://react.dev/reference/react-dom/client/createRoot */ getRoot(el).render( <> From 6ba0a45e7eba01c2ea7f642938ac2fc84b9b95c6 Mon Sep 17 00:00:00 2001 From: Stefan Dietz Date: Wed, 17 Jan 2024 10:21:06 +0100 Subject: [PATCH 2/5] Add example for render return value --- .../src/components/table/render-cell.tsx | 68 +++++++++++++++---- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/packages/samples/react/src/components/table/render-cell.tsx b/packages/samples/react/src/components/table/render-cell.tsx index 574658045f..a66b217fd4 100644 --- a/packages/samples/react/src/components/table/render-cell.tsx +++ b/packages/samples/react/src/components/table/render-cell.tsx @@ -4,10 +4,32 @@ import { KolButton, KolInputText, KolTable } from '@public-ui/react'; import { getRoot } from '../../shares/react-roots'; import { KoliBriTableHeaders } from '@public-ui/components'; -import { DATA, Data } from './test-data'; import { DATE_FORMATTER } from './formatter'; import { SampleDescription } from '../SampleDescription'; +type Data = { + order: number; + date: Date; + shipped: boolean; +}; +const DATA: Data[] = [ + { + order: 0, + shipped: false, + date: new Date('1981-05-26T21:33:43.612Z'), + }, + { + order: 1, + shipped: true, + date: new Date('1971-04-25T19:44:17.014Z'), + }, + { + order: 2, + shipped: false, + date: new Date('1986-07-10T11:39:29.539Z'), + }, +]; + const HEADERS: KoliBriTableHeaders = { horizontal: [ [ @@ -17,37 +39,59 @@ const HEADERS: KoliBriTableHeaders = { textAlign: 'center', width: '10em', - /* Example 1: Simple render function using textContent */ + /* Example 1: Use render return value to format date */ + render: (_el, cell) => `Index: ${cell.label}`, + }, + { + label: 'Status', + key: 'shipped', + textAlign: 'center', + width: '10em', + + /* Example 2: Simple render function using textContent */ render: (el, cell) => { - el.textContent = `Index: ${cell.label}`; + if (cell.label) { + el.textContent = `Order has been dispatched 🚚`; + } else { + el.textContent = `Order pending 📦`; + } }, }, { - label: 'Datum (string)', + label: 'Date (string)', key: 'date', width: '20em', textAlign: 'center', - /* Example 2: Render function using innerHTML. ⚠️Make sure to sanitize data to avoid XSS. */ + /* Example 3: Render function using innerHTML. ⚠️Make sure to sanitize data to avoid XSS. */ render: (el, cell) => { el.innerHTML = `${DATE_FORMATTER.format(cell.label as unknown as Date)}`; }, sort: (data: Data[]) => data.sort((data0, data1) => data0.date.getTime() - data1.date.getTime()), }, { - label: 'Aktion (react)', + label: 'Action (react)', key: 'order', + width: '20em', - /* Example 3: Render function using React */ + /* Example 4: Render function using React */ render: (el) => { el.setAttribute('role', 'presentation'); /* https://react.dev/reference/react-dom/client/createRoot */ getRoot(el).render( - <> - - - , +
+ + +
, ); }, }, @@ -60,6 +104,6 @@ export const TableRenderCell: FC = () => (

This sample simulates the usage of React render functions for the table column contents.

- + ); From 708ed3dfcfb822a875d55e87606e45cb38d3802f Mon Sep 17 00:00:00 2001 From: Stefan Dietz Date: Wed, 17 Jan 2024 10:43:09 +0100 Subject: [PATCH 3/5] Add table render function examples without React --- packages/components/src/dev/index.ts | 3 + .../src/dev/table-render-function.html | 15 ++++ .../src/dev/table-render-function.ts | 69 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 packages/components/src/dev/table-render-function.html create mode 100644 packages/components/src/dev/table-render-function.ts diff --git a/packages/components/src/dev/index.ts b/packages/components/src/dev/index.ts index 7862ed646c..031e6ddc74 100644 --- a/packages/components/src/dev/index.ts +++ b/packages/components/src/dev/index.ts @@ -13,4 +13,7 @@ switch (location.pathname) { case '/dev/details-synced-open-state.html': import('./details-synced-open-state'); break; + case '/dev/table-render-function.html': + import('./table-render-function'); + break; } diff --git a/packages/components/src/dev/table-render-function.html b/packages/components/src/dev/table-render-function.html new file mode 100644 index 0000000000..d5e2b26fe0 --- /dev/null +++ b/packages/components/src/dev/table-render-function.html @@ -0,0 +1,15 @@ + + + + + Table Render Function | KoliBri + + + + + +
+
+
+ + diff --git a/packages/components/src/dev/table-render-function.ts b/packages/components/src/dev/table-render-function.ts new file mode 100644 index 0000000000..9b3f70811c --- /dev/null +++ b/packages/components/src/dev/table-render-function.ts @@ -0,0 +1,69 @@ +import type { KoliBriTableHeaders, KoliBriTableCell } from '@public-ui/schema'; + +type Data = { + order: number; + date: Date; + shipped: boolean; +}; +const DATA: Data[] = [ + { + order: 0, + shipped: false, + date: new Date('1981-05-26T21:33:43.612Z'), + }, + { + order: 1, + shipped: true, + date: new Date('1971-04-25T19:44:17.014Z'), + }, + { + order: 2, + shipped: false, + date: new Date('1986-07-10T11:39:29.539Z'), + }, +]; +const HEADERS: KoliBriTableHeaders = { + horizontal: [ + [ + { + label: '#', + key: 'order', + + /* Example 1: Use render return value to format date */ + render: (_el, cell: KoliBriTableCell) => `Index: ${cell.label}`, + }, + { + label: 'Status', + key: 'shipped', + + /* Example 2: Simple render function using textContent */ + render: (el, cell) => { + if (cell.label) { + el.textContent = `Order has been dispatched 🚚`; + } else { + el.textContent = `Order pending 📦`; + } + }, + }, + { + label: 'Date (string)', + key: 'date', + + /* Example 3: Render function using innerHTML. ⚠️Make sure to sanitize data to avoid XSS. */ + render: (el, cell) => { + el.innerHTML = `${Intl.DateTimeFormat('de-DE').format(cell.label as unknown as Date)}`; + }, + // @ts-ignore + sort: (data: Data[]) => data.sort((data0, data1) => data0.date.getTime() - data1.date.getTime()), + }, + ], + ], +}; + +const container = document.getElementById('table-container'); +const table = document.createElement('kol-table'); + +table._label = 'Table example with render functions'; +table._data = DATA; +table._headers = HEADERS; +container?.appendChild(table); From 100f600697d7e44105d3aa6740c09dae687467f4 Mon Sep 17 00:00:00 2001 From: Stefan Dietz Date: Wed, 17 Jan 2024 10:45:49 +0100 Subject: [PATCH 4/5] Fix typo --- packages/components/src/dev/table-render-function.ts | 2 +- packages/samples/react/src/components/table/render-cell.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/src/dev/table-render-function.ts b/packages/components/src/dev/table-render-function.ts index 9b3f70811c..9a8a8f9b84 100644 --- a/packages/components/src/dev/table-render-function.ts +++ b/packages/components/src/dev/table-render-function.ts @@ -29,7 +29,7 @@ const HEADERS: KoliBriTableHeaders = { label: '#', key: 'order', - /* Example 1: Use render return value to format date */ + /* Example 1: Use render return value to format data */ render: (_el, cell: KoliBriTableCell) => `Index: ${cell.label}`, }, { diff --git a/packages/samples/react/src/components/table/render-cell.tsx b/packages/samples/react/src/components/table/render-cell.tsx index a66b217fd4..6467a5c08f 100644 --- a/packages/samples/react/src/components/table/render-cell.tsx +++ b/packages/samples/react/src/components/table/render-cell.tsx @@ -39,7 +39,7 @@ const HEADERS: KoliBriTableHeaders = { textAlign: 'center', width: '10em', - /* Example 1: Use render return value to format date */ + /* Example 1: Use render return value to format data */ render: (_el, cell) => `Index: ${cell.label}`, }, { From 520b1b3acca18ed84cca1309e50cbcd7c3fa208f Mon Sep 17 00:00:00 2001 From: Stefan Dietz Date: Wed, 17 Jan 2024 11:08:40 +0100 Subject: [PATCH 5/5] Work around type issue --- packages/components/src/dev/table-render-function.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/components/src/dev/table-render-function.ts b/packages/components/src/dev/table-render-function.ts index 9a8a8f9b84..640b298239 100644 --- a/packages/components/src/dev/table-render-function.ts +++ b/packages/components/src/dev/table-render-function.ts @@ -1,4 +1,4 @@ -import type { KoliBriTableHeaders, KoliBriTableCell } from '@public-ui/schema'; +import type { KoliBriTableCell, KoliBriTableHeaders } from '@public-ui/schema'; type Data = { order: number; @@ -53,8 +53,7 @@ const HEADERS: KoliBriTableHeaders = { render: (el, cell) => { el.innerHTML = `${Intl.DateTimeFormat('de-DE').format(cell.label as unknown as Date)}`; }, - // @ts-ignore - sort: (data: Data[]) => data.sort((data0, data1) => data0.date.getTime() - data1.date.getTime()), + sort: (data) => data.sort((data0, data1) => (data0 as Data).date.getTime() - (data1 as Data).date.getTime()), }, ], ],