Skip to content

Commit f97fe89

Browse files
authored
readability: fixes a few minor annoyances when reading code | chore: update deps (jbetancur#1379)
1 parent 1facd5c commit f97fe89

13 files changed

Lines changed: 1629 additions & 1478 deletions

apps/docs/package-lock.json

Lines changed: 1037 additions & 904 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 470 additions & 514 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/DataTable.css

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
color-scheme: var(--rdt-color-scheme, light);
2020
/* Sort icon scales with the theme's icon size */
2121
--rdt-sort-icon-size: calc(var(--rdt-icon-size, 18px) * 0.8);
22+
/* Expander open/close animation length. Mirrors EXPAND_DURATION in
23+
constants.ts, which keeps the closing row mounted for exactly this long
24+
before unmounting it — keep the two in sync. */
25+
--rdt-expand-duration: 220ms;
2226
}
2327

2428
.rdt_tableDisabled {
@@ -1619,11 +1623,11 @@
16191623
/* Expander row — grid-row trick gives a true height animation without JS measurement */
16201624
.rdt_expanderRowAnimated {
16211625
display: grid;
1622-
animation: rdt_expandIn 0.22s cubic-bezier(0.2, 0, 0, 1) forwards;
1626+
animation: rdt_expandIn var(--rdt-expand-duration, 220ms) cubic-bezier(0.2, 0, 0, 1) forwards;
16231627
}
16241628

16251629
.rdt_expanderRowClosing {
1626-
animation: rdt_expandOut 0.22s cubic-bezier(0.2, 0, 0, 1) forwards;
1630+
animation: rdt_expandOut var(--rdt-expand-duration, 220ms) cubic-bezier(0.2, 0, 0, 1) forwards;
16271631
}
16281632

16291633
@keyframes rdt_expandIn {
@@ -1671,6 +1675,4 @@
16711675
.rdt_spinner {
16721676
animation: none !important;
16731677
}
1674-
1675-
/* Column reorder FLIP animations are skipped via JS matchMedia check */
16761678
}

src/components/ColumnFilter.tsx

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { FilterState, FilterCondition, FilterOperator, FilterType, Localiza
44

55
type ColumnFilterOptions = NonNullable<Localization['filter']>;
66
import { emptyFilterState, isFilterActive } from '../hooks/useColumnFilter';
7+
import FilterIcon from '../icons/FilterIcon';
78

89
type OperatorOption = { value: FilterOperator; label: string; noInput?: boolean; twoInputs?: boolean };
910

@@ -39,13 +40,14 @@ const DEFAULT_DATE_OPERATORS: OperatorOption[] = [
3940
{ value: 'notBlank', label: 'Not blank', noInput: true },
4041
];
4142

43+
function baseOperators(filterType: FilterType): OperatorOption[] {
44+
if (filterType === 'number') return DEFAULT_NUMBER_OPERATORS;
45+
if (filterType === 'date' || filterType === 'datetime' || filterType === 'time') return DEFAULT_DATE_OPERATORS;
46+
return DEFAULT_TEXT_OPERATORS;
47+
}
48+
4249
function operatorsFor(filterType: FilterType, overrides?: ColumnFilterOptions['operators']): OperatorOption[] {
43-
const base =
44-
filterType === 'number'
45-
? DEFAULT_NUMBER_OPERATORS
46-
: filterType === 'date' || filterType === 'datetime' || filterType === 'time'
47-
? DEFAULT_DATE_OPERATORS
48-
: DEFAULT_TEXT_OPERATORS;
50+
const base = baseOperators(filterType);
4951
if (!overrides) return base;
5052
return base.map(op => (overrides[op.value] ? { ...op, label: overrides[op.value]! } : op));
5153
}
@@ -54,6 +56,14 @@ function defaultOperator(filterType: FilterType): FilterOperator {
5456
return filterType === 'text' ? 'contains' : 'equals';
5557
}
5658

59+
function inputTypeFor(filterType: FilterType): string {
60+
if (filterType === 'number') return 'number';
61+
if (filterType === 'date') return 'date';
62+
if (filterType === 'datetime') return 'datetime-local';
63+
if (filterType === 'time') return 'time';
64+
return 'text';
65+
}
66+
5767
function emptyCondition(filterType: FilterType): FilterCondition {
5868
return { operator: defaultOperator(filterType) };
5969
}
@@ -75,16 +85,7 @@ type ConditionRowProps = {
7585
function ConditionRow({ condition, filterType, options, onChange, onRemove }: ConditionRowProps): JSX.Element {
7686
const operators = operatorsFor(filterType, options.operators);
7787
const selected = operators.find(o => o.value === condition.operator) ?? operators[0];
78-
const inputType =
79-
filterType === 'number'
80-
? 'number'
81-
: filterType === 'date'
82-
? 'date'
83-
: filterType === 'datetime'
84-
? 'datetime-local'
85-
: filterType === 'time'
86-
? 'time'
87-
: 'text';
88+
const inputType = inputTypeFor(filterType);
8889
// Time inputs default to minute precision; step=1 exposes a seconds field so
8990
// logs can be filtered to the second.
9091
const inputStep = filterType === 'time' ? 1 : undefined;
@@ -301,9 +302,7 @@ export default function ColumnFilter({
301302
toggleOpen();
302303
}}
303304
>
304-
<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor" aria-hidden="true">
305-
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" />
306-
</svg>
305+
<FilterIcon />
307306
{isActive && <span className="rdt_filterDot" />}
308307
</button>
309308

src/components/DataTable.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ import useSortFlipAnimation from '../hooks/useSortFlipAnimation';
3838
import useContextMenu from '../hooks/useContextMenu';
3939
import ContextMenu from './ContextMenu';
4040

41+
function getHeadSepClass(headerSeparator: boolean | 'subtle' | 'full'): string | undefined {
42+
if (headerSeparator === false) return undefined;
43+
if (headerSeparator === 'full') return 'rdt_headSeparatorFull';
44+
return 'rdt_headSeparator';
45+
}
46+
4147
function DataTableInner<T>(props: TableProps<T>, ref: React.ForwardedRef<DataTableHandle>): JSX.Element {
4248
const {
4349
data = defaultProps.data,
@@ -516,12 +522,7 @@ function DataTableInner<T>(props: TableProps<T>, ref: React.ForwardedRef<DataTab
516522
const effectiveHeaderSep = headerSeparator !== undefined ? headerSeparator : (themeObj.headerSeparator ?? true);
517523
const sepClass =
518524
effectiveColumnSep === 'full' ? 'rdt_colSeparatorFull' : effectiveColumnSep ? 'rdt_colSeparator' : undefined;
519-
const headSepClass =
520-
effectiveHeaderSep === false
521-
? undefined
522-
: effectiveHeaderSep === 'full'
523-
? 'rdt_headSeparatorFull'
524-
: 'rdt_headSeparator';
525+
const headSepClass = getHeadSepClass(effectiveHeaderSep);
525526

526527
return (
527528
<StylesContext.Provider value={tableStyles}>

src/components/ResponsiveWrapper.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ type ResponsiveWrapperProps = React.HTMLAttributes<HTMLDivElement> & {
1010
$animateRows?: boolean;
1111
};
1212

13+
// fixedHeader needs a scroll container even when responsive is off — maxHeight
14+
// without overflow lets rows spill over whatever renders below the table.
15+
function getScrollClass($fixedHeader?: boolean, $responsive?: boolean): string | undefined {
16+
if ($fixedHeader) return 'rdt_responsiveWrapperFixed';
17+
if ($responsive) return 'rdt_responsiveWrapperScroll';
18+
return undefined;
19+
}
20+
1321
const ResponsiveWrapper = React.forwardRef<HTMLDivElement, ResponsiveWrapperProps>(function ResponsiveWrapper(
1422
{
1523
$responsive,
@@ -24,13 +32,7 @@ const ResponsiveWrapper = React.forwardRef<HTMLDivElement, ResponsiveWrapperProp
2432
ref,
2533
) {
2634
const customStyles = useStyles();
27-
// fixedHeader needs a scroll container even when responsive is off — maxHeight
28-
// without overflow lets rows spill over whatever renders below the table.
29-
const scrollClass = $fixedHeader
30-
? 'rdt_responsiveWrapperFixed'
31-
: $responsive
32-
? 'rdt_responsiveWrapperScroll'
33-
: undefined;
35+
const scrollClass = getScrollClass($fixedHeader, $responsive);
3436
return (
3537
<div
3638
ref={ref}

src/components/TableCol.tsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import '../DataTable.css';
33
import { useStyles } from '../context/StylesContext';
44
import { CellExtended } from './Cell';
55
import NativeSortIcon from '../icons/NativeSortIcon';
6+
import MenuIcon from '../icons/MenuIcon';
67
import ColumnFilter from './ColumnFilter';
78
import { equalizeId, getPinnedCellMeta } from '../util';
89
import type { PinnedOffsets } from '../util';
@@ -16,6 +17,16 @@ import type { SortingSlice } from '../hooks/useSorting';
1617

1718
type FilterLocalization = NonNullable<Localization['filter']>;
1819

20+
function getAriaSort(
21+
disableSort: boolean,
22+
sortActive: boolean,
23+
columnSortDirection: SortOrder,
24+
): React.AriaAttributes['aria-sort'] {
25+
if (disableSort) return undefined;
26+
if (!sortActive) return 'none';
27+
return columnSortDirection === SortOrder.ASC ? 'ascending' : 'descending';
28+
}
29+
1930
type TableColProps<T> = {
2031
column: TableColumn<T>;
2132
disabled: boolean;
@@ -146,6 +157,7 @@ function TableCol<T>({
146157

147158
const sortActive = !!(column.sortable && sortIndex !== -1);
148159
const disableSort = !column.sortable || disabled;
160+
const ariaSort = getAriaSort(disableSort, sortActive, columnSortDirection);
149161
const isNavActive = !!cellNavigation && activeCell?.row === -1 && activeCell?.col === navCol;
150162
// With cellNavigation the whole grid is one Tab stop (roving tabindex); otherwise
151163
// only sortable headers are tabbable.
@@ -228,15 +240,7 @@ function TableCol<T>({
228240
.join(' ')}
229241
onClick={!disableSort ? handleClick : undefined}
230242
onKeyDown={!disableSort ? handleKeyDown : undefined}
231-
aria-sort={
232-
!disableSort
233-
? sortActive
234-
? columnSortDirection === SortOrder.ASC
235-
? 'ascending'
236-
: 'descending'
237-
: 'none'
238-
: undefined
239-
}
243+
aria-sort={ariaSort}
240244
>
241245
{!disableSort && customSortIconRight && renderCustomSortIcon()}
242246
{!disableSort && nativeSortIconRight && renderNativeSortIcon(sortActive)}
@@ -283,9 +287,7 @@ function TableCol<T>({
283287
}}
284288
onPointerDown={e => e.stopPropagation()}
285289
>
286-
<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor" aria-hidden="true">
287-
<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
288-
</svg>
290+
<MenuIcon />
289291
</button>
290292
)}
291293
{onResizeStart && column.id != null && (

src/components/TableRow.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import TableCellCheckbox from './TableCellCheckbox';
77
import TableCellExpander from './TableCellExpander';
88
import ExpanderRow from './ExpanderRow';
99
import RightPinSpacer from './RightPinSpacer';
10+
import MenuIcon from '../icons/MenuIcon';
1011
import { prop, equalizeId, getConditionalStyle, getFirstRightPinnedId, getPrefixColCount, isEven } from '../util';
1112
import { STOP_PROP_TAG } from '../constants';
1213
import useRowExpander from '../hooks/useRowExpander';
@@ -279,9 +280,7 @@ function Row<T>({
279280
rowMenu.onMenuButtonClick(row, rowIndex, e);
280281
}}
281282
>
282-
<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor" aria-hidden="true">
283-
<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
284-
</svg>
283+
<MenuIcon />
285284
</button>
286285
</div>
287286
)}

src/constants.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ export const STOP_PROP_TAG = 'allowRowEvents';
99
*/
1010
export const SYSTEM_COL_WIDTH = 48;
1111

12+
/**
13+
* Duration (in ms) of the expander row open/close animation. The close handler
14+
* keeps the row mounted for this long so the exit animation can finish before
15+
* unmount. Mirrored in DataTable.css as --rdt-expand-duration, which drives the
16+
* rdt_expandIn / rdt_expandOut animations — keep the two in sync.
17+
*/
18+
export const EXPAND_DURATION = 220;
19+
1220
export enum Direction {
1321
LTR = 'ltr',
1422
RTL = 'rtl',

src/hooks/useRowExpander.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as React from 'react';
2-
3-
const EXPAND_DURATION = 220;
2+
import { EXPAND_DURATION } from '../constants';
43

54
type ExpanderState = { expanded: boolean; mounted: boolean; closing: boolean };
65
type ExpanderAction = { type: 'open' } | { type: 'close' } | { type: 'unmount' } | { type: 'sync'; value: boolean };

0 commit comments

Comments
 (0)