mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Chart theming: selectable chart theme + spec↔config merge/extract
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { defaultSettings } from '@core/settings';
|
||||
import {
|
||||
loadChartTheme,
|
||||
loadPreviewFitMode,
|
||||
loadUiTheme,
|
||||
loadUserSettings,
|
||||
saveChartTheme,
|
||||
saveManagedSettings,
|
||||
savePreviewFitMode,
|
||||
saveUiTheme,
|
||||
@@ -119,6 +121,34 @@ describe('settings-store · ui.previewFitMode', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('settings-store · ui.chartTheme', () => {
|
||||
beforeEach(() => vi.stubGlobal('localStorage', makeStorageStub()));
|
||||
afterEach(() => vi.unstubAllGlobals());
|
||||
|
||||
it('defaults to astrolabe when nothing is stored', () => {
|
||||
expect(loadChartTheme()).toBe('astrolabe');
|
||||
});
|
||||
|
||||
it('returns a stored valid chart theme', () => {
|
||||
localStorage.setItem(KEY, JSON.stringify({ ui: { chartTheme: 'stock' } }));
|
||||
expect(loadChartTheme()).toBe('stock');
|
||||
});
|
||||
|
||||
it('falls back to astrolabe for an unrecognized id', () => {
|
||||
localStorage.setItem(KEY, JSON.stringify({ ui: { chartTheme: 'neon' } }));
|
||||
expect(loadChartTheme()).toBe('astrolabe');
|
||||
});
|
||||
|
||||
it('round-trips and preserves the other ui slices', () => {
|
||||
saveUiTheme('dark');
|
||||
savePreviewFitMode('height');
|
||||
saveChartTheme('powerbi');
|
||||
expect(loadChartTheme()).toBe('powerbi');
|
||||
expect(loadUiTheme()).toBe('dark');
|
||||
expect(loadPreviewFitMode()).toBe('height');
|
||||
});
|
||||
});
|
||||
|
||||
describe('settings-store · full UserSettings record', () => {
|
||||
beforeEach(() => vi.stubGlobal('localStorage', makeStorageStub()));
|
||||
afterEach(() => vi.unstubAllGlobals());
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import type { FitMode } from '@core/rendering';
|
||||
import { loadSettings, type UserSettings } from '@core/settings';
|
||||
import type { UiTheme } from '@core/theme';
|
||||
import { isChartThemeId, type ChartThemeId } from '@core/vega-themes';
|
||||
|
||||
const KEY = 'astrolabe:settings';
|
||||
|
||||
@@ -28,12 +29,15 @@ const DEFAULT_THEME: UiTheme = 'light';
|
||||
/** Spec §04 — the Fit control defaults to Original. */
|
||||
const DEFAULT_FIT_MODE: FitMode = 'default';
|
||||
|
||||
/** Spec §04 — the Chart theme picker defaults to the house style. */
|
||||
const DEFAULT_CHART_THEME: ChartThemeId = 'astrolabe';
|
||||
|
||||
/** The managed slice the per-pane settings clusters own (theme + fit live in their own slices). */
|
||||
export type ManagedSettings = Pick<UserSettings, 'editor' | 'performance' | 'formatting'>;
|
||||
|
||||
/** Loose view of the stored record for the per-slice write-through merges. */
|
||||
interface StoredSettings {
|
||||
ui?: { theme?: unknown; previewFitMode?: unknown; [k: string]: unknown };
|
||||
ui?: { theme?: unknown; previewFitMode?: unknown; chartTheme?: unknown; [k: string]: unknown };
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
@@ -118,6 +122,18 @@ export function loadPreviewFitMode(): FitMode {
|
||||
return isFitMode(stored) ? stored : DEFAULT_FIT_MODE;
|
||||
}
|
||||
|
||||
/** The persisted chart theme, or the default — unknown ids fall back. */
|
||||
export function loadChartTheme(): ChartThemeId {
|
||||
const stored = readRaw().ui?.chartTheme;
|
||||
return isChartThemeId(stored) ? stored : DEFAULT_CHART_THEME;
|
||||
}
|
||||
|
||||
/** Persist the chart theme, preserving every other key already in the record. */
|
||||
export function saveChartTheme(chartTheme: ChartThemeId): void {
|
||||
const current = readRaw();
|
||||
writeRaw({ ...current, ui: { ...current.ui, chartTheme } });
|
||||
}
|
||||
|
||||
/** Persist the preview fit mode, preserving every other key already in the record. */
|
||||
export function savePreviewFitMode(fitMode: FitMode): void {
|
||||
const current = readRaw();
|
||||
|
||||
Reference in New Issue
Block a user