mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-20 00:17:44 +00:00
feat(grid): improve boolean checkbox styling for light and dark themes
This commit is contained in:
@@ -270,16 +270,17 @@ function alignCanvasPixel(value: number, dpr: number): number {
|
||||
return Math.round(value * dpr) / dpr;
|
||||
}
|
||||
|
||||
function drawBooleanCheckbox(ctx: CanvasRenderingContext2D, options: { drawX: number; y: number; colWidth: number; scaleX: number; scaleY: number; theme: DataGridPaintTheme; checked: boolean }): void {
|
||||
export function drawBooleanCheckbox(ctx: CanvasRenderingContext2D, options: { drawX: number; y: number; colWidth: number; scaleX: number; scaleY: number; theme: DataGridPaintTheme; checked: boolean }): void {
|
||||
const { drawX, y, colWidth, scaleX, scaleY, theme, checked } = options;
|
||||
const size = BOOLEAN_CHECKBOX_SIZE;
|
||||
const boxX = alignCanvasPixel(drawX + (colWidth - size) / 2, scaleX);
|
||||
const boxY = alignCanvasPixel(y + (CANVAS_DATA_GRID_ROW_HEIGHT - size) / 2, scaleY);
|
||||
ctx.lineWidth = 1;
|
||||
ctx.fillStyle = theme.background;
|
||||
ctx.fillRect(boxX, boxY, size, size);
|
||||
if (checked) {
|
||||
ctx.fillStyle = theme.primary;
|
||||
ctx.fillRect(boxX, boxY, size, size);
|
||||
ctx.strokeStyle = theme.background;
|
||||
ctx.strokeStyle = theme.foreground;
|
||||
ctx.strokeRect(boxX + 0.5, boxY + 0.5, size - 1, size - 1);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(boxX + 3, boxY + size / 2);
|
||||
|
||||
+76
-1
@@ -1,6 +1,6 @@
|
||||
import { strict as assert } from "node:assert";
|
||||
import { test } from "vitest";
|
||||
import { canvasDataGridActionReservedWidth, fitCanvasText, resolveCanvasCellTextLayout, resolveCanvasDataGridRowBase, resolveCanvasDataGridRowFill } from "../../apps/desktop/src/lib/dataGrid/canvasDataGridRenderer.ts";
|
||||
import { canvasDataGridActionReservedWidth, drawBooleanCheckbox, fitCanvasText, resolveCanvasCellTextLayout, resolveCanvasDataGridRowBase, resolveCanvasDataGridRowFill } from "../../apps/desktop/src/lib/dataGrid/canvasDataGridRenderer.ts";
|
||||
import { DATA_GRID_DARK_STRIPED_ROW_BG, DATA_GRID_LIGHT_STRIPED_ROW_BG, resolveDataGridPaintTheme } from "../../apps/desktop/src/lib/dataGrid/dataGridPaintTheme.ts";
|
||||
|
||||
function measureContext(charWidth = 1): CanvasRenderingContext2D {
|
||||
@@ -96,3 +96,78 @@ test("canvas row base respects stripedRows option", () => {
|
||||
assert.equal(resolveCanvasDataGridRowBase(theme, newRow, { isActive: false, stripedRows: false }), "row-new");
|
||||
assert.equal(resolveCanvasDataGridRowBase(theme, newRow, { isActive: false, stripedRows: true }), "row-new");
|
||||
});
|
||||
|
||||
test("drawBooleanCheckbox renders checked and unchecked state with clean background and border", () => {
|
||||
interface CanvasCall {
|
||||
method: string;
|
||||
args: unknown[];
|
||||
}
|
||||
const calls: CanvasCall[] = [];
|
||||
const fakeCtx = {
|
||||
lineWidth: 1,
|
||||
fillStyle: "",
|
||||
strokeStyle: "",
|
||||
fillRect: (x: number, y: number, w: number, h: number) => {
|
||||
calls.push({ method: "fillRect", args: [x, y, w, h] });
|
||||
},
|
||||
strokeRect: (x: number, y: number, w: number, h: number) => {
|
||||
calls.push({ method: "strokeRect", args: [x, y, w, h] });
|
||||
},
|
||||
beginPath: () => {
|
||||
calls.push({ method: "beginPath", args: [] });
|
||||
},
|
||||
moveTo: (x: number, y: number) => {
|
||||
calls.push({ method: "moveTo", args: [x, y] });
|
||||
},
|
||||
lineTo: (x: number, y: number) => {
|
||||
calls.push({ method: "lineTo", args: [x, y] });
|
||||
},
|
||||
stroke: () => {
|
||||
calls.push({ method: "stroke", args: [] });
|
||||
},
|
||||
} as unknown as CanvasRenderingContext2D;
|
||||
|
||||
const theme = {
|
||||
background: "#ffffff",
|
||||
foreground: "#111111",
|
||||
mutedForeground: "#888888",
|
||||
primary: "#000000",
|
||||
} as unknown as Parameters<typeof drawBooleanCheckbox>[1]["theme"];
|
||||
|
||||
// Unchecked state: clean background fill and muted border
|
||||
calls.length = 0;
|
||||
drawBooleanCheckbox(fakeCtx, {
|
||||
drawX: 0,
|
||||
y: 0,
|
||||
colWidth: 60,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
theme,
|
||||
checked: false,
|
||||
});
|
||||
assert.equal(fakeCtx.fillStyle, "#ffffff");
|
||||
assert.equal(fakeCtx.strokeStyle, "#888888");
|
||||
assert.equal(fakeCtx.lineWidth, 1);
|
||||
assert.ok(calls.some((c) => c.method === "fillRect"));
|
||||
assert.ok(calls.some((c) => c.method === "strokeRect"));
|
||||
assert.ok(!calls.some((c) => c.method === "stroke"));
|
||||
|
||||
// Checked state: clean background fill, foreground border, and checkmark stroke
|
||||
calls.length = 0;
|
||||
drawBooleanCheckbox(fakeCtx, {
|
||||
drawX: 0,
|
||||
y: 0,
|
||||
colWidth: 60,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
theme,
|
||||
checked: true,
|
||||
});
|
||||
assert.equal(fakeCtx.fillStyle, "#ffffff");
|
||||
assert.equal(fakeCtx.strokeStyle, "#111111");
|
||||
assert.equal(fakeCtx.lineWidth, 1);
|
||||
assert.ok(calls.some((c) => c.method === "fillRect"));
|
||||
assert.ok(calls.some((c) => c.method === "strokeRect"));
|
||||
assert.ok(calls.some((c) => c.method === "stroke"));
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user