Skip to content
Draft
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
5 changes: 5 additions & 0 deletions .changeset/fast-lights-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@liam-hq/erd-core": patch
---

- ⚡️ improve performance when selecting column element with hash
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { aColumn, aPrimaryKeyConstraint } from '@liam-hq/schema'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { NuqsTestingAdapter } from 'nuqs/adapters/testing'
import type { FC, PropsWithChildren } from 'react'
import { describe, expect, it } from 'vitest'
import { beforeEach, describe, expect, it } from 'vitest'
import {
SchemaProvider,
UserEditingProvider,
Expand All @@ -17,6 +18,10 @@ const wrapper: FC<PropsWithChildren> = ({ children }) => (
</NuqsTestingAdapter>
)

beforeEach(() => {
location.hash = ''
})

describe('id', () => {
it('renders column name as a inked heading', () => {
render(
Expand All @@ -36,6 +41,29 @@ describe('id', () => {
'#users__columns__id',
)
})

describe('interactions', () => {
it('scrolls to element when the link is clicked', async () => {
const user = userEvent.setup()
render(
<ColumnsItem
tableId="users"
column={aColumn({ name: 'id', type: 'bigserial' })}
constraints={{}}
/>,
{ wrapper },
)

await user.click(screen.getByRole('link', { name: 'id #' }))

expect(location.hash).toBe('#users__columns__id')
// TODO: check element.scrollIntoView is called
})

it.todo(
'does nothing with ⌘ + click (default browser action: open in new tab)',
)
})
})

describe('type', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,27 @@ export const ColumnsItem: FC<Props> = ({ tableId, column, constraints }) => {
return (
<div id={elementId} className={clsx(styles.wrapper, diffStyle)}>
<h3 className={styles.heading}>
<a href={`#${elementId}`}>{column.name} #</a>
<a
href={`#${elementId}`}
onClick={(event) => {
// Do not call preventDefault to allow the default link behavior when ⌘ key is pressed
if (event.metaKey || event.ctrlKey) {
return
}

event.preventDefault()

const element = document.getElementById(elementId)
element?.scrollIntoView()
// Setting location.hash = '' immediately can be slow for the transitions.
// We defer the operation using setTimeout(..., 0) to avoid blocking and ensure smooth execution of the current updates.
setTimeout(() => {
location.hash = elementId
}, 0)
}}
>
{column.name} #
</a>
</h3>
{column.comment && <Comment tableId={tableId} column={column} />}
<GridTableRoot>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@ export const UserEditingProvider: FC<Props> = ({

const setActiveTableName: typeof _setActiveTableName = useCallback(
(...args) => {
location.hash = ''
// reset location.hash when the active table changes or is removed
// Setting location.hash = '' immediately can be slow for the transitions.
// We defer the operation using setTimeout(..., 0) to avoid blocking and ensure smooth execution of the current updates.
setTimeout(() => {
location.hash = ''
}, 0)
return _setActiveTableName(...args)
},
[_setActiveTableName],
Expand Down