Skip to content

Commit

Permalink
5870 table render samples (#5907)
Browse files Browse the repository at this point in the history
  • Loading branch information
deleonio authored Jan 17, 2024
2 parents 8f0955f + 520b1b3 commit a1fc786
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 19 deletions.
3 changes: 3 additions & 0 deletions packages/components/src/dev/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
15 changes: 15 additions & 0 deletions packages/components/src/dev/table-render-function.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html dir="ltr" lang="de">
<head>
<meta charset="utf-8" />
<title>Table Render Function | KoliBri</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="module" src="/build/kolibri.esm.js"></script>
<link rel="stylesheet" href="/assets/codicons/codicon.css" />
</head>
<body data-theme="demo">
<main class="container">
<div id="table-container"></div>
</main>
</body>
</html>
68 changes: 68 additions & 0 deletions packages/components/src/dev/table-render-function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import type { KoliBriTableCell, KoliBriTableHeaders } 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 data */
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 = `<strong>${Intl.DateTimeFormat('de-DE').format(cell.label as unknown as Date)}</strong>`;
},
sort: (data) => data.sort((data0, data1) => (data0 as Data).date.getTime() - (data1 as Data).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);
90 changes: 71 additions & 19 deletions packages/samples/react/src/components/table/render-cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,94 @@ 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: [
[
{ label: '#', key: 'order', textAlign: 'center', width: '10em' },
{
label: 'Datum (string)',
label: '#',
key: 'order',
textAlign: 'center',
width: '10em',

/* Example 1: Use render return value to format data */
render: (_el, cell) => `Index: ${cell.label}`,
},
{
label: 'Status',
key: 'shipped',
textAlign: 'center',
width: '10em',

/* 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',
width: '20em',
textAlign: 'center',
render: (el, tupel) => {
// https://reactjs.org/docs/portals.html
getRoot(el).render(<strong>{DATE_FORMATTER.format(tupel.label as unknown as Date)}</strong>);

/* Example 3: Render function using innerHTML. ⚠️Make sure to sanitize data to avoid XSS. */
render: (el, cell) => {
el.innerHTML = `<strong>${DATE_FORMATTER.format(cell.label as unknown as Date)}</strong>`;
},
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)',
label: 'Action (react)',
key: 'order',
width: '20em',

/* Example 4: 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(
<>
<KolButton _label={'Speichern'} />
<KolInputText _label="Eingabe" />
</>,
<div
style={{
display: `grid`,
gridAutoFlow: `column`,
alignItems: `end`,
gap: `1rem`,
maxWidth: `400px`,
}}
>
<KolInputText _label="Input" />
<KolButton _label={'Save'} />
</div>,
);
},
},
Expand All @@ -52,6 +104,6 @@ export const TableRenderCell: FC = () => (
<SampleDescription>
<p>This sample simulates the usage of React render functions for the table column contents.</p>
</SampleDescription>
<KolTable _label="Sort a date column" _data={DATA} _headers={HEADERS} className="block min-w-75em" />
<KolTable _label="Sort by date column" _data={DATA} _headers={HEADERS} className="block min-w-75em" />
</>
);

0 comments on commit a1fc786

Please sign in to comment.