fix(web): Notiz-Widget folgt dem Hell/Dunkel-Schalter von Tessera statt der Systemeinstellung
- useTheme (next-themes) + mounted-Guard wie changelog-view.tsx - data-color-mode am Wurzel-Div folgt resolvedTheme statt fest 'auto' - zwei neue Tests (dark/light) via vi.hoisted-Themenzustand Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,14 @@ vi.mock('next-intl', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
// quick-260916-j4f: gehobener Themenzustand, damit die Variable trotz
|
||||
// Hoisting der Mocks und des statischen Imports weiter unten sicher
|
||||
// initialisiert ist (Muster changelog-page.test.tsx).
|
||||
const themeMock = vi.hoisted(() => ({ resolvedTheme: 'light' as 'light' | 'dark' }));
|
||||
vi.mock('next-themes', () => ({
|
||||
useTheme: () => ({ resolvedTheme: themeMock.resolvedTheme }),
|
||||
}));
|
||||
|
||||
// Mock @uiw/react-md-editor — provide a minimal textarea-based substitute.
|
||||
// Im Modus 'preview' wird stattdessen ein Vorschau-Div gerendert, das fuer
|
||||
// jede Aufgabenzeile ein Kaestchen enthaelt (quick-260916-iex) — nutzt die
|
||||
@@ -85,6 +93,7 @@ describe('NoteWidget', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
themeMock.resolvedTheme = 'light';
|
||||
fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => ({}),
|
||||
@@ -290,4 +299,26 @@ describe('NoteWidget', () => {
|
||||
});
|
||||
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('setzt data-color-mode auf dark, wenn Tessera auf Dunkel steht', () => {
|
||||
themeMock.resolvedTheme = 'dark';
|
||||
const { container } = render(
|
||||
<NoteWidget instanceId="note-t1" config={{}} isEditMode={false} />,
|
||||
);
|
||||
|
||||
expect(container.querySelector('[data-color-mode]')?.getAttribute('data-color-mode')).toBe(
|
||||
'dark',
|
||||
);
|
||||
});
|
||||
|
||||
it('setzt data-color-mode auf light, wenn Tessera auf Hell steht', () => {
|
||||
themeMock.resolvedTheme = 'light';
|
||||
const { container } = render(
|
||||
<NoteWidget instanceId="note-t1" config={{}} isEditMode={false} />,
|
||||
);
|
||||
|
||||
expect(container.querySelector('[data-color-mode]')?.getAttribute('data-color-mode')).toBe(
|
||||
'light',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useTheme } from 'next-themes';
|
||||
import MDEditor, { commands } from '@uiw/react-md-editor';
|
||||
import rehypeSanitize from 'rehype-sanitize';
|
||||
import type { WidgetProps } from '../widget-registry';
|
||||
@@ -41,6 +42,17 @@ const NOTE_COMMANDS = [
|
||||
|
||||
export function NoteWidget({ instanceId, config }: WidgetProps) {
|
||||
const t = useTranslations('widgets');
|
||||
const { resolvedTheme } = useTheme();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
// quick-260916-j4f: folgt dem Tessera-Schalter statt der
|
||||
// Betriebssystem-Einstellung, Muster changelog-view.tsx.
|
||||
const colorMode: 'light' | 'dark' = mounted && resolvedTheme === 'dark' ? 'dark' : 'light';
|
||||
|
||||
const [title, setTitle] = useState<string>(
|
||||
(config.title as string) || t('note.defaultTitle'),
|
||||
);
|
||||
@@ -128,7 +140,7 @@ export function NoteWidget({ instanceId, config }: WidgetProps) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col overflow-hidden" data-color-mode="auto">
|
||||
<div className="flex h-full flex-col overflow-hidden" data-color-mode={colorMode}>
|
||||
{/* Header: title + pencil toggle */}
|
||||
<div className="relative flex items-center border-b border-border px-1.5 py-1.5 gap-2">
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user