mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
Fix sketch default color in dark mode (#2488)
Co-authored-by: Ghxst <200635707+GHX5T-SOL@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useT } from '../i18n';
|
||||
import { readDefaultSketchToolColor } from './sketch-colors';
|
||||
import type { SketchItem } from './sketch-model';
|
||||
|
||||
export type Tool = 'select' | 'pen' | 'text' | 'rect' | 'arrow' | 'eraser';
|
||||
@@ -34,7 +35,7 @@ export function SketchEditor({
|
||||
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
||||
const wrapRef = useRef<HTMLDivElement | null>(null);
|
||||
const [tool, setTool] = useState<Tool>('pen');
|
||||
const [color, setColor] = useState('#1c1b1a');
|
||||
const [color, setColor] = useState(() => readDefaultSketchToolColor());
|
||||
const [size, setSize] = useState(2);
|
||||
const drawingRef = useRef<SketchItem | null>(null);
|
||||
const [, force] = useState(0);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
export const DEFAULT_SKETCH_LIGHT_TOOL_COLOR = '#1c1b1a';
|
||||
export const DEFAULT_SKETCH_DARK_TOOL_COLOR = '#ffffff';
|
||||
|
||||
export function resolveDefaultSketchToolColor(
|
||||
theme: string | null,
|
||||
prefersDark: boolean,
|
||||
): string {
|
||||
if (theme === 'dark') return DEFAULT_SKETCH_DARK_TOOL_COLOR;
|
||||
if (theme === 'light') return DEFAULT_SKETCH_LIGHT_TOOL_COLOR;
|
||||
return prefersDark ? DEFAULT_SKETCH_DARK_TOOL_COLOR : DEFAULT_SKETCH_LIGHT_TOOL_COLOR;
|
||||
}
|
||||
|
||||
export function readDefaultSketchToolColor(): string {
|
||||
if (typeof document === 'undefined') return DEFAULT_SKETCH_LIGHT_TOOL_COLOR;
|
||||
const theme = document.documentElement.getAttribute('data-theme');
|
||||
const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)').matches === true;
|
||||
return resolveDefaultSketchToolColor(theme, prefersDark);
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { cleanup, render } from '@testing-library/react';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { SketchEditor } from '../../src/components/SketchEditor';
|
||||
import { I18nProvider } from '../../src/i18n';
|
||||
|
||||
class ResizeObserverMock {
|
||||
observe() {}
|
||||
disconnect() {}
|
||||
}
|
||||
|
||||
function renderEditor() {
|
||||
return render(
|
||||
<I18nProvider initial="en">
|
||||
<SketchEditor
|
||||
items={[]}
|
||||
onItemsChange={vi.fn()}
|
||||
onSave={vi.fn()}
|
||||
fileName="scratch.sketch.json"
|
||||
/>
|
||||
</I18nProvider>,
|
||||
);
|
||||
}
|
||||
|
||||
describe('SketchEditor default color', () => {
|
||||
beforeEach(() => {
|
||||
vi.stubGlobal('ResizeObserver', ResizeObserverMock);
|
||||
vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue({
|
||||
setTransform: vi.fn(),
|
||||
clearRect: vi.fn(),
|
||||
save: vi.fn(),
|
||||
fillRect: vi.fn(),
|
||||
restore: vi.fn(),
|
||||
beginPath: vi.fn(),
|
||||
moveTo: vi.fn(),
|
||||
lineTo: vi.fn(),
|
||||
stroke: vi.fn(),
|
||||
strokeRect: vi.fn(),
|
||||
fillText: vi.fn(),
|
||||
} as unknown as CanvasRenderingContext2D);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
document.documentElement.removeAttribute('data-theme');
|
||||
vi.restoreAllMocks();
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
it('starts with a light pen color under the dark theme', () => {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
|
||||
const { container } = renderEditor();
|
||||
|
||||
const colorInput = container.querySelector<HTMLInputElement>('input[type="color"]');
|
||||
expect(colorInput?.value).toBe('#ffffff');
|
||||
});
|
||||
|
||||
it('keeps the existing default pen color under the light theme', () => {
|
||||
document.documentElement.setAttribute('data-theme', 'light');
|
||||
|
||||
const { container } = renderEditor();
|
||||
|
||||
const colorInput = container.querySelector<HTMLInputElement>('input[type="color"]');
|
||||
expect(colorInput?.value).toBe('#1c1b1a');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
DEFAULT_SKETCH_DARK_TOOL_COLOR,
|
||||
DEFAULT_SKETCH_LIGHT_TOOL_COLOR,
|
||||
resolveDefaultSketchToolColor,
|
||||
} from '../../src/components/sketch-colors';
|
||||
|
||||
describe('sketch-colors', () => {
|
||||
it('uses a light tool color for an explicit dark theme', () => {
|
||||
expect(resolveDefaultSketchToolColor('dark', false)).toBe(DEFAULT_SKETCH_DARK_TOOL_COLOR);
|
||||
});
|
||||
|
||||
it('keeps the existing dark tool color for an explicit light theme', () => {
|
||||
expect(resolveDefaultSketchToolColor('light', true)).toBe(DEFAULT_SKETCH_LIGHT_TOOL_COLOR);
|
||||
});
|
||||
|
||||
it('follows the system dark preference when no explicit theme is set', () => {
|
||||
expect(resolveDefaultSketchToolColor(null, true)).toBe(DEFAULT_SKETCH_DARK_TOOL_COLOR);
|
||||
});
|
||||
|
||||
it('keeps the light-mode default when system mode is not dark', () => {
|
||||
expect(resolveDefaultSketchToolColor(null, false)).toBe(DEFAULT_SKETCH_LIGHT_TOOL_COLOR);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user