Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions hightable/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
},
},
)
2 changes: 1 addition & 1 deletion hightable/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion hightable/src/Basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ import { data } from './data'

export default function Basic() {
return <Layout>
<HighTable data={data} />
<HighTable data={data} cacheKey="demo" />
</Layout>
}
9 changes: 5 additions & 4 deletions hightable/src/Controlled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -34,7 +35,7 @@ function getNumSelected(selection: Selection): number {

export default function Controlled() {
const [selection, setSelection] = useState<Selection>({ ranges: [] })
const [orderBy, setOrderBy] = useState<OrderBy>({})
const [orderBy, setOrderBy] = useState<OrderBy>([])

const numSelectedRows = getNumSelected(selection)

Expand All @@ -47,8 +48,8 @@ export default function Controlled() {
</section>
<section>
<button onClick={() => { setOrderBy(createRandomOrderBy()) }}>Order by a random column</button>
<button onClick={() => { setOrderBy({}) }}>Clear order</button>
<span>{orderBy.column ? `Ordered by '${orderBy.column}'` : 'Unordered'}</span>
<button onClick={() => { setOrderBy([]) }}>Clear order</button>
<span>{orderBy[0]?.column ? `Ordered by '${orderBy[0]?.column}'` : 'Unordered'}</span>
</section>
</div>
<HighTable data={data} selection={selection} onSelectionChange={setSelection} orderBy={orderBy} onOrderByChange={setOrderBy} />
Expand Down
72 changes: 72 additions & 0 deletions hightable/src/CustomTheme.css
Original file line number Diff line number Diff line change
@@ -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);
}
13 changes: 13 additions & 0 deletions hightable/src/CustomTheme.tsx
Original file line number Diff line number Diff line change
@@ -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<Selection | undefined>(undefined)

return <Layout>
<HighTable data={data} cacheKey="demo" styled={true} onSelectionChange={setSelection} className="custom-hightable" />
</Layout>
}
2 changes: 2 additions & 0 deletions hightable/src/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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]) => <NavLink key={path} to={path}
className={ ({ isActive }) => isActive ? 'link active' : 'link' }
>{label}</NavLink>,
Expand Down
2 changes: 1 addition & 1 deletion hightable/src/Mirror.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { data } from './data'

export default function App() {
const [selection, setSelection] = useState<Selection>({ ranges: [] })
const [orderBy, setOrderBy] = useState<OrderBy>({})
const [orderBy, setOrderBy] = useState<OrderBy>([])

return <Layout>
<HighTable data={data} cacheKey='demo' onSelectionChange={setSelection} onOrderByChange={setOrderBy} />
Expand Down
12 changes: 12 additions & 0 deletions hightable/src/Unstyled.tsx
Original file line number Diff line number Diff line change
@@ -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<Selection | undefined>(undefined)

return <Layout>
<HighTable data={data} cacheKey="demo" styled={false} onSelectionChange={setSelection} />
</Layout>
}
2 changes: 1 addition & 1 deletion hightable/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
4 changes: 4 additions & 0 deletions hightable/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -15,5 +17,7 @@ ReactDOM.createRoot(app).render(<HashRouter>
<Route path="/selection" element={<Selection />} />
<Route path="/controlled" element={<Controlled />} />
<Route path="/mirror" element={<Mirror />} />
<Route path="/unstyled" element={<Unstyled />} />
<Route path="/custom-theme" element={<CustomTheme />} />
</Routes>
</HashRouter>)