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( } /> } /> } /> + } /> + } /> )