diff --git a/hightable/eslint.config.js b/hightable/eslint.config.js
index d919ae6..d8e93a7 100644
--- a/hightable/eslint.config.js
+++ b/hightable/eslint.config.js
@@ -78,6 +78,13 @@ export default tseslint.config(
'@typescript-eslint/restrict-template-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'warn',
+
+ // allow using any - see row.ts - it's not easy to replace with unknown for example
+ '@typescript-eslint/no-explicit-any': 'off',
+ '@typescript-eslint/use-unknown-in-catch-callback-variable': 'off',
+ '@typescript-eslint/prefer-promise-reject-errors': 'off',
+ '@typescript-eslint/no-unsafe-assignment': 'off',
+ '@typescript-eslint/no-unsafe-return': 'off',
},
},
)
diff --git a/hightable/package.json b/hightable/package.json
index 325f31a..6cbd3ea 100644
--- a/hightable/package.json
+++ b/hightable/package.json
@@ -14,7 +14,7 @@
"typecheck": "tsc"
},
"dependencies": {
- "hightable": "0.12.1",
+ "hightable": "0.13.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-router": "7.3.0"
diff --git a/hightable/src/Basic.tsx b/hightable/src/Basic.tsx
index 9586eb1..b4cf704 100644
--- a/hightable/src/Basic.tsx
+++ b/hightable/src/Basic.tsx
@@ -5,6 +5,6 @@ import { data } from './data'
export default function Basic() {
return
-
+
}
diff --git a/hightable/src/Controlled.tsx b/hightable/src/Controlled.tsx
index 8e57c92..4222366 100644
--- a/hightable/src/Controlled.tsx
+++ b/hightable/src/Controlled.tsx
@@ -25,7 +25,8 @@ function createRandomSelection(): Selection {
function createRandomOrderBy(): OrderBy {
const columns = data.header
const column = columns[Math.floor(Math.random() * columns.length)]
- return { column }
+ const direction = Math.random() < 0.5 ? 'ascending' : 'descending'
+ return [{ column, direction }]
}
function getNumSelected(selection: Selection): number {
@@ -34,7 +35,7 @@ function getNumSelected(selection: Selection): number {
export default function Controlled() {
const [selection, setSelection] = useState({ ranges: [] })
- const [orderBy, setOrderBy] = useState({})
+ const [orderBy, setOrderBy] = useState([])
const numSelectedRows = getNumSelected(selection)
@@ -47,8 +48,8 @@ export default function Controlled() {
-
- {orderBy.column ? `Ordered by '${orderBy.column}'` : 'Unordered'}
+
+ {orderBy[0]?.column ? `Ordered by '${orderBy[0]?.column}'` : 'Unordered'}
diff --git a/hightable/src/CustomTheme.css b/hightable/src/CustomTheme.css
new file mode 100644
index 0000000..1d845f7
--- /dev/null
+++ b/hightable/src/CustomTheme.css
@@ -0,0 +1,72 @@
+.custom-hightable {
+ --mock-row-label-background: lightcoral;
+ --border-color: lightcoral;
+ --sort-indicator-background: transparent;
+ --header-background-color: lightblue;
+ --row-label-background: lightgreen;
+ --row-label-color: black;
+ --selected-row-background: lightyellow;
+ --selected-row-header-background: lightcoral;
+ --resizer-color: lightcoral;
+ --table-corner-logo-background: lightcoral;
+ --top-bar-background-color: lightcoral;
+ --table-corner-background: lightcoral;
+}
+
+.custom-hightable thead th {
+ background-color: var(--header-background-color);
+ border-bottom: 2px solid var(--border-color);
+ color: hsl(0, 100%, 27%);
+ font-family: mono;
+}
+
+.custom-hightable thead th[aria-sort="ascending"]::after,
+.custom-hightable thead th[aria-sort="descending"]::after {
+ background-color: var(--sort-indicator-background);
+}
+
+/* cells */
+.custom-hightable th,
+.custom-hightable td {
+ border-bottom: 1px solid var(--border-color);
+ border-right: 1px solid var(--border-color);
+}
+
+/* column resize */
+.custom-hightable thead [role="separator"] {
+ border-right: 1px solid var(--border-color);
+}
+.custom-hightable thead [role="separator"]:hover {
+ background-color: var(--resizer-color);
+}
+
+/* row numbers */
+.custom-hightable tbody [role="rowheader"] {
+ background-color: var(--row-label-background);
+ border-right: 1px solid var(--border-color);
+ color: var(--row-label-color);
+}
+/* highlight the selected rows */
+.custom-hightable tr[aria-selected="true"] {
+ background-color: var(--selected-row-background);
+}
+.custom-hightable tr[aria-selected="true"] [role="rowheader"] {
+ background-color: var(--selected-row-header-background);
+}
+
+/* table corner */
+/* TODO: find a better selector for the table corner */
+.custom-hightable thead td:first-child {
+ background-color: var(--table-corner-logo-background);
+ border-right: 1px solid var(--border-color);
+}
+.custom-hightable thead td:first-child[aria-disabled="false"] {
+ background: var(
+ --table-corner-background
+ ); /* redundant with td:first-child, but allows to force the background if it has been overridden with a logo */
+}
+
+/* pending table state */
+.custom-hightable thead th::before {
+ background-color: var(--top-bar-background-color);
+}
diff --git a/hightable/src/CustomTheme.tsx b/hightable/src/CustomTheme.tsx
new file mode 100644
index 0000000..a1558ed
--- /dev/null
+++ b/hightable/src/CustomTheme.tsx
@@ -0,0 +1,13 @@
+import { HighTable, Selection } from 'hightable'
+import { useState } from 'react'
+import './CustomTheme.css'
+import { data } from './data'
+import Layout from './Layout'
+
+export default function CustomTheme() {
+ const [, setSelection] = useState(undefined)
+
+ return
+
+
+}
diff --git a/hightable/src/Layout.tsx b/hightable/src/Layout.tsx
index 5d11e55..fc8aca8 100644
--- a/hightable/src/Layout.tsx
+++ b/hightable/src/Layout.tsx
@@ -12,6 +12,8 @@ export default function Layout({ children }: { children: ReactNode }) {
['Selection', '/selection'],
['Controlled', '/controlled'],
['Mirror', '/mirror'],
+ ['Unstyled', '/unstyled'],
+ ['Custom Theme', '/custom-theme'],
].map(([label, path]) => isActive ? 'link active' : 'link' }
>{label},
diff --git a/hightable/src/Mirror.tsx b/hightable/src/Mirror.tsx
index 3f0863f..92e31e7 100644
--- a/hightable/src/Mirror.tsx
+++ b/hightable/src/Mirror.tsx
@@ -5,7 +5,7 @@ import { data } from './data'
export default function App() {
const [selection, setSelection] = useState({ ranges: [] })
- const [orderBy, setOrderBy] = useState({})
+ const [orderBy, setOrderBy] = useState([])
return
diff --git a/hightable/src/Unstyled.tsx b/hightable/src/Unstyled.tsx
new file mode 100644
index 0000000..d1cb12a
--- /dev/null
+++ b/hightable/src/Unstyled.tsx
@@ -0,0 +1,12 @@
+import { HighTable, Selection } from 'hightable'
+import { useState } from 'react'
+import { data } from './data'
+import Layout from './Layout'
+
+export default function Unstyled() {
+ const [, setSelection] = useState(undefined)
+
+ return
+
+
+}
diff --git a/hightable/src/index.css b/hightable/src/index.css
index a5d1c0a..ccf6324 100644
--- a/hightable/src/index.css
+++ b/hightable/src/index.css
@@ -128,7 +128,7 @@ nav.sidebar > div {
gap: 0.5em;
}
-.table-corner {
+thead td:first-child {
align-items: center;
background: url('https://hyperparam.app/assets/table/hightable.svg') #f9f4ff no-repeat center 6px;
}
diff --git a/hightable/src/main.tsx b/hightable/src/main.tsx
index 3da6402..4438c3a 100644
--- a/hightable/src/main.tsx
+++ b/hightable/src/main.tsx
@@ -3,8 +3,10 @@ import ReactDOM from 'react-dom/client'
import { HashRouter, Route, Routes } from 'react-router'
import Basic from './Basic.js'
import Controlled from './Controlled.js'
+import CustomTheme from './CustomTheme.js'
import Mirror from './Mirror.js'
import Selection from './Selection.js'
+import Unstyled from './Unstyled.js'
import './index.css'
const app = document.getElementById('app')
@@ -15,5 +17,7 @@ ReactDOM.createRoot(app).render(
} />
} />
} />
+ } />
+ } />
)