diff --git a/apps/hightable-demo/package.json b/apps/hightable-demo/package.json index ebd7b60c..e680f2f3 100644 --- a/apps/hightable-demo/package.json +++ b/apps/hightable-demo/package.json @@ -14,7 +14,7 @@ "typecheck": "tsc" }, "dependencies": { - "hightable": "0.7.3", + "hightable": "../../../hightable", "react": "18.3.1", "react-dom": "18.3.1" } diff --git a/apps/hightable-demo/src/HighTable.css b/apps/hightable-demo/src/HighTable.css index fe02831b..88f5b81a 100644 --- a/apps/hightable-demo/src/HighTable.css +++ b/apps/hightable-demo/src/HighTable.css @@ -102,6 +102,26 @@ min-width: 32px; max-width: none; width: 32px; + cursor: pointer; +} +.table td:first-child span { + display: inline; +} +.table td:first-child input { + display: none; +} +.selectable td:first-child:hover span, .selectable tr.selected td:first-child span { + display: none; +} +.selectable td:first-child:hover input, .selectable tr.selected td:first-child input { + display: inline; + cursor: pointer; +} +.selectable tr.selected { + background-color: #fbf7bf; +} +.selectable tr.selected td:first-child { + background-color: #f1edbb; } /* cells */ @@ -193,7 +213,6 @@ /* table corner */ .table-corner { - background-color: #e4e4e6; border-right: 1px solid #ccc; position: absolute; height: 33px; @@ -201,9 +220,28 @@ top: 0; left: 0; z-index: 15; - box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.2); + box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.2); background: url('https://hyperparam.app/assets/table/hightable.svg') #e4e4e6 no-repeat center 6px; + cursor: default; + display: flex; + justify-content: center; +} +.selectable .table-corner { + background: #e4e4e6; + cursor: pointer; +} +.table-corner input { + display: none; +} +.selectable .table-corner span { + display: none; } +.selectable .table-corner input { + display: inline; + cursor: pointer; + text-align: center; +} + /* mock row numbers */ .mock-row-label { content: ""; diff --git a/apps/hightable-demo/src/main.tsx b/apps/hightable-demo/src/main.tsx index e90e4d7b..f3829d97 100644 --- a/apps/hightable-demo/src/main.tsx +++ b/apps/hightable-demo/src/main.tsx @@ -1,5 +1,5 @@ -import { HighTable } from 'hightable' -import { StrictMode } from 'react' +import { createTableControl, HighTable, Selection } from 'hightable' +import { StrictMode, useState } from 'react' import ReactDOM from 'react-dom/client' import { data } from './data' import './HighTable.css' @@ -8,6 +8,84 @@ import './index.css' const app = document.getElementById('app') if (!app) throw new Error('missing app element') -ReactDOM.createRoot(app).render( - -) +function App() { + const tableControl = createTableControl() + const columns = data.header + + const [columnId, setColumnId] = useState() + const [selection, setSelection] = useState([]) + + function onOrderByChange(orderBy: string | undefined) { + console.log("New value for orderBy: " + orderBy) + if (!orderBy) { + setColumnId(undefined) + return + } + const id = columns.indexOf(orderBy) + if (id === -1) { + setColumnId(undefined) + } + setColumnId(id) + } + function onSelectionChange(selection: Selection) { + setSelection(selection) + } + + function onSortClick() { + const nextId = ((columnId ?? -1) + 1) % columns.length + tableControl.setOrderBy(columns[nextId]) + } + function onSelectionClick() { + const newSelection = selection.map(({start, end}) => ({start: start + 1, end: end + 1})) + tableControl.setSelection(newSelection) + } + function getSelectionCount(selection: Selection) { + return selection.reduce((acc: number, {start, end}) => acc + end - start, 0) + } + function getFirstRows(selection: Selection, max = 5) { + const indexes: string[] = [] + let rangeIdx = 0 + while (indexes.length < max && rangeIdx < selection.length) { + const {start, end} = selection[rangeIdx] + let rowIdx = start + while (indexes.length < max && rowIdx < end) { + indexes.push(rowIdx.toString()) + rowIdx++ + } + rangeIdx++ + } + if (indexes.length === max) { + indexes.pop() + indexes.push('...') + } + return indexes + } + + return ( +
+
+

Hightable demo

+ +
+
+

Order by

+

Click the button to sort the table by the next column

+ +

Column ID: {columnId}

+

{columnId === undefined ? 'No sorted column': ('Column name: "' + columns[columnId] + '"')}

+
+
+

Rows selection

+

Click the button to delete the selected rows

+ +

selection: {JSON.stringify(selection)}

+

{getSelectionCount(selection)} selected rows: {getFirstRows(selection).map(index => {index})}

+
+
+
+ +
+
) +} + +ReactDOM.createRoot(app).render()