Self-review

This commit is contained in:
Peter White
2026-03-24 14:37:06 +01:00
parent 14d61b8f46
commit 5d26e8bc96
4 changed files with 42 additions and 47 deletions
@@ -13,10 +13,11 @@ interface StickyViewGridProps {
export function StickyViewGrid({ className, header, children }: StickyViewGridProps) {
const rootRef = useRef<HTMLDivElement>(null);
const stickyHeaderRef = useRef<HTMLDivElement>(null);
const bodyScrollRef = useRef<HTMLDivElement>(null);
const bodyTableRef = useRef<HTMLDivElement>(null);
const onStickyHeaderWheel = useCallback((event: React.WheelEvent<HTMLDivElement>) => {
const onStickyHeaderWheel = useCallback((event: WheelEvent) => {
const bodyScrollElement = bodyScrollRef.current;
if (!bodyScrollElement) {
return;
@@ -31,6 +32,19 @@ export function StickyViewGrid({ className, header, children }: StickyViewGridPr
event.preventDefault();
}, []);
useEffect(() => {
const stickyHeaderElement = stickyHeaderRef.current;
if (!stickyHeaderElement) {
return;
}
stickyHeaderElement.addEventListener('wheel', onStickyHeaderWheel, { passive: false });
return () => {
stickyHeaderElement.removeEventListener('wheel', onStickyHeaderWheel);
};
}, [onStickyHeaderWheel]);
const syncStickyLayout = useCallback(() => {
const rootElement = rootRef.current;
const bodyScrollElement = bodyScrollRef.current;
@@ -85,11 +99,11 @@ export function StickyViewGrid({ className, header, children }: StickyViewGridPr
data-scrollable="false"
>
<div
ref={stickyHeaderRef}
className={tcls(
'-mx-px sticky z-10 w-full min-w-0 max-w-full overflow-hidden px-px',
'-mx-px sticky z-10 w-full min-w-0 max-w-full overflow-hidden rounded-t-[inherit] px-px',
'[top:var(--toc-top-offset,var(--outline-top-offset,0px))]'
)}
onWheel={onStickyHeaderWheel}
>
<div
className={tcls(
@@ -53,23 +53,21 @@ export function Table(props: BlockProps<DocumentBlockTable>) {
<StickyViewGrid
className={tcls(style, 'relative mx-auto grid w-full min-w-0')}
header={
<div aria-hidden="true">
<ViewGridHeader
{...gridProps}
className={tcls(
'mb-0 rounded-b-none border-t border-r border-l',
'group-data-[scrollable=false]/table:mb-1',
'group-data-[scrollable=false]/table:rounded-b-lg',
'group-data-[scrollable=true]/table:border-t-0',
'group-data-[scrollable=true]/table:border-r-0',
'group-data-[scrollable=true]/table:border-l-0',
'group-data-[scrollable=true]/table:rounded-t-none'
)}
/>
</div>
<ViewGridHeader
{...gridProps}
className={tcls(
'mb-0 rounded-b-none border-t border-r border-l',
'group-data-[scrollable=false]/table:mb-1',
'group-data-[scrollable=false]/table:rounded-b-lg',
'group-data-[scrollable=true]/table:border-t-0',
'group-data-[scrollable=true]/table:border-r-0',
'group-data-[scrollable=true]/table:border-l-0',
'group-data-[scrollable=true]/table:rounded-t-none'
)}
/>
}
>
<ViewGrid {...gridProps} headerClassName="sr-only" />
<ViewGrid {...gridProps} />
</StickyViewGrid>
);
}
@@ -82,7 +80,10 @@ export function Table(props: BlockProps<DocumentBlockTable>) {
'w-full min-w-0 overflow-x-auto overflow-y-hidden border-tint-subtle'
)}
>
<ViewGrid {...gridProps} />
<div className={tcls('flex', 'flex-col', 'w-fit')}>
{withHeader ? <ViewGridHeader {...gridProps} /> : null}
<ViewGrid {...gridProps} />
</div>
</div>
</div>
);
@@ -7,9 +7,11 @@ import type { TableViewProps } from './Table';
import { getColumnWidth, getViewGridLayout } from './layout';
import { getColumnAlignment } from './utils';
export function ViewGridHeader(
props: TableViewProps<DocumentTableViewGrid> & { className?: string }
) {
interface ViewGridHeaderProps extends TableViewProps<DocumentTableViewGrid> {
className?: string;
}
export function ViewGridHeader(props: ViewGridHeaderProps) {
const { block, view, context, className } = props;
const { tableWidth, columnWidths, autoSizedColumns, fixedColumns } = getViewGridLayout({
block,
@@ -61,13 +63,9 @@ export function ViewGridHeader(
);
}
export interface ViewGridProps extends TableViewProps<DocumentTableViewGrid> {
headerClassName?: string;
}
export function ViewGrid(props: ViewGridProps) {
const { block, view, records, context, headerClassName } = props;
const { withHeader, tableWidth, autoSizedColumns, fixedColumns } = getViewGridLayout({
export function ViewGrid(props: TableViewProps<DocumentTableViewGrid>) {
const { block, view, records, context } = props;
const { tableWidth, autoSizedColumns, fixedColumns } = getViewGridLayout({
block,
view,
mode: context.mode,
@@ -89,7 +87,6 @@ export function ViewGrid(props: ViewGridProps) {
return (
<div role="table" className={tcls('flex', 'flex-col', 'w-fit')}>
{withHeader ? <ViewGridHeader {...props} className={headerClassName} /> : null}
{body}
</div>
);
@@ -1,24 +1,7 @@
@reference "../../RootLayout/globals.css";
/* Detect whether a scrollbar exists on the table */
@keyframes detect-scroll {
from,
to {
--can-scroll: ;
}
}
/* Apply styles to the Table if scrollbar exists */
.tableScrollArea {
animation: detect-scroll linear;
animation-timeline: scroll(self x);
overscroll-behavior-x: none;
--border-radius-if-can-scroll: var(--can-scroll) 0.375rem;
--border-radius-if-cant-scroll: 0;
border-radius: var(--border-radius-if-can-scroll, var(--border-radius-if-cant-scroll));
--border-width-if-can-scroll: var(--can-scroll) 1px;
--border-width-if-cant-scroll: 0;
border-width: var(--border-width-if-can-scroll, var(--border-width-if-cant-scroll));
}