Skip to content

Commit

Permalink
feat: show type badge in DataGrid header (#144)
Browse files Browse the repository at this point in the history
* feat: show type badge in DataGrid header

* chore: feedback

* fix: minor fix

* fix: feedback

* fix: text color
  • Loading branch information
keita-determined authored Oct 17, 2024
1 parent 09548a8 commit 922affe
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 5 deletions.
11 changes: 8 additions & 3 deletions src/kit/DataGrid/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
LinkCell,
LOADING_CELL,
} from './custom-renderers';
import { drawTypeBadge } from './custom-renderers/utils';
import css from './DataGrid.module.scss';
import { getHeaderIcons } from './icons';
import { HeaderMenu, HeaderMenuProps } from './menu';
Expand Down Expand Up @@ -489,7 +490,7 @@ export function DataGrid<T, ContextAction = void | string, ContextActionData = v
}, [sorts]);

const drawHeader: DrawHeaderCallback = useCallback(
({ ctx, column, rect, theme, spriteManager }) => {
({ ctx, column, columnIndex, rect, theme, spriteManager }) => {
const sortDirection = column.id && sortMap[column.id];
if (sortDirection) {
const arrowDirection = sortDirection === 'asc' ? 'up' : 'down';
Expand Down Expand Up @@ -520,10 +521,14 @@ export function DataGrid<T, ContextAction = void | string, ContextActionData = v
const y = rect.y + rect.height / 2 + middleCenterBias;
const maxWidth = rect.width - (sortDirection ? 12 : 0) - 2 * theme.cellHorizontalPadding;
ctx.fillStyle = theme.textHeader;
drawTextWithEllipsis(ctx, column.title, x, y, maxWidth);
const textMetrics = drawTextWithEllipsis(ctx, column.title, x, y, maxWidth);
const typeName = columns[columnIndex].type;
if (typeName !== undefined) {
drawTypeBadge(ctx, theme, typeName, x + textMetrics.width + 10, y);
}
}
},
[sortMap],
[columns, sortMap],
);

useImperativeHandle(
Expand Down
7 changes: 6 additions & 1 deletion src/kit/DataGrid/columns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const MULTISELECT = 'selected';

export type ColumnDef<T> = SizedGridColumn & {
id: string;
isNumerical?: boolean;
type?: 'number' | 'text' | 'date' | 'array' | 'unspecified';
renderer: (record: T, idx: number) => GridCell;
tooltip: (record: T) => string | undefined;
};
Expand Down Expand Up @@ -52,6 +52,7 @@ export function defaultTextColumn<T extends RawJson>(
},
title: columnTitle,
tooltip: () => undefined,
type: 'text',
width: columnWidth ?? DEFAULT_COLUMN_WIDTH,
};
}
Expand Down Expand Up @@ -103,6 +104,7 @@ export function defaultNumberColumn<T extends RawJson>(
},
title: columnTitle,
tooltip: () => undefined,
type: 'number',
width: columnWidth ?? DEFAULT_COLUMN_WIDTH,
};
}
Expand All @@ -127,6 +129,7 @@ export function defaultSelectionColumn<T>(
themeOverride: { cellHorizontalPadding: 10 },
title: '',
tooltip: () => undefined,
type: 'unspecified',
width: 40,
};
}
Expand All @@ -151,6 +154,7 @@ export function defaultDateColumn<T extends RawJson>(
},
title: columnTitle,
tooltip: () => undefined,
type: 'date',
width: columnWidth ?? DEFAULT_COLUMN_WIDTH,
};
}
Expand All @@ -175,6 +179,7 @@ export function defaultArrayColumn<T extends RawJson>(
},
title: columnTitle,
tooltip: () => undefined,
type: 'array',
width: columnWidth ?? DEFAULT_COLUMN_WIDTH,
};
}
34 changes: 33 additions & 1 deletion src/kit/DataGrid/custom-renderers/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { getMiddleCenterBias, measureTextCached, type Theme } from '@glideapps/glide-data-grid';

import { hsl2str, str2hsl } from 'kit/internal/functions';

interface CornerRadius {
tl: number;
tr: number;
Expand Down Expand Up @@ -105,7 +109,35 @@ export function drawTextWithEllipsis(
x: number,
y: number,
maxWidth: number,
): void {
): TextMetrics {
const ellipsisText = truncate(ctx, text, x, maxWidth);
ctx.fillText(ellipsisText, x, y);
return ctx.measureText(ellipsisText);
}

export function drawTypeBadge(
ctx: CanvasRenderingContext2D,
theme: Theme,
typeName: 'number' | 'text' | 'date' | 'array' | 'unspecified',
x: number,
y: number,
): void {
const tagFont = `bold 10px ${theme.fontFamily}`;
const bgColor = str2hsl(getComputedStyle(ctx.canvas).getPropertyValue('--theme-surface'));
const backgroundColor = hsl2str({
...bgColor,
s: bgColor.s > 0 ? 70 : 0,
});
const textColor = theme.textDark;
ctx.beginPath();
ctx.font = tagFont;
ctx.fillStyle = backgroundColor;
ctx.strokeStyle = textColor;
ctx.lineWidth = 1;
roundedRect(ctx, x, y - 9, measureTextCached(typeName, ctx, tagFont).width + 16, 18, 4);
ctx.stroke();
ctx.fill();
ctx.fillStyle = textColor;
ctx.fillText(typeName.toUpperCase(), x + 4, y - 9 + 18 / 2 + getMiddleCenterBias(ctx, tagFont));
ctx.closePath();
}

0 comments on commit 922affe

Please sign in to comment.