mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Implement fit-mode rendering contract with container sizing and pane re-fit
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { loadUiTheme, saveUiTheme } from './settings-store';
|
||||
import { loadPreviewFitMode, loadUiTheme, savePreviewFitMode, saveUiTheme } from './settings-store';
|
||||
|
||||
const KEY = 'astrolabe:settings';
|
||||
|
||||
@@ -84,3 +84,29 @@ describe('settings-store · ui.theme', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('settings-store · preview.fitMode', () => {
|
||||
beforeEach(() => vi.stubGlobal('localStorage', makeStorageStub()));
|
||||
afterEach(() => vi.unstubAllGlobals());
|
||||
|
||||
it('defaults to Original (default) when nothing is stored', () => {
|
||||
expect(loadPreviewFitMode()).toBe('default');
|
||||
});
|
||||
|
||||
it('returns a stored valid fit mode', () => {
|
||||
localStorage.setItem(KEY, JSON.stringify({ preview: { fitMode: 'full' } }));
|
||||
expect(loadPreviewFitMode()).toBe('full');
|
||||
});
|
||||
|
||||
it('falls back to default for an unrecognized value', () => {
|
||||
localStorage.setItem(KEY, JSON.stringify({ preview: { fitMode: 'cover' } }));
|
||||
expect(loadPreviewFitMode()).toBe('default');
|
||||
});
|
||||
|
||||
it('round-trips through load and preserves the theme slice', () => {
|
||||
saveUiTheme('dark');
|
||||
savePreviewFitMode('height');
|
||||
expect(loadPreviewFitMode()).toBe('height');
|
||||
expect(loadUiTheme()).toBe('dark'); // the other slice survives the merge
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* `localStorage`; everything else goes through these typed functions.
|
||||
*/
|
||||
|
||||
import type { FitMode } from '@core/rendering';
|
||||
import type { UiTheme } from '@core/theme';
|
||||
|
||||
const KEY = 'astrolabe:settings';
|
||||
@@ -20,9 +21,13 @@ const KEY = 'astrolabe:settings';
|
||||
/** Spec §07 Appearance default. */
|
||||
const DEFAULT_THEME: UiTheme = 'light';
|
||||
|
||||
/** Spec §04 — the Fit control defaults to Original. */
|
||||
const DEFAULT_FIT_MODE: FitMode = 'default';
|
||||
|
||||
/** Loose view of the stored record — M5 will give this its full typed shape. */
|
||||
interface StoredSettings {
|
||||
ui?: { theme?: unknown; [k: string]: unknown };
|
||||
preview?: { fitMode?: unknown; [k: string]: unknown };
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
@@ -61,6 +66,10 @@ function isUiTheme(v: unknown): v is UiTheme {
|
||||
return v === 'light' || v === 'dark';
|
||||
}
|
||||
|
||||
function isFitMode(v: unknown): v is FitMode {
|
||||
return v === 'default' || v === 'width' || v === 'height' || v === 'full';
|
||||
}
|
||||
|
||||
/** The persisted UI theme, or the default — unknown/legacy values fall back. */
|
||||
export function loadUiTheme(): UiTheme {
|
||||
const stored = readRaw().ui?.theme;
|
||||
@@ -74,3 +83,15 @@ export function saveUiTheme(theme: UiTheme): void {
|
||||
const current = readRaw();
|
||||
writeRaw({ ...current, ui: { ...current.ui, theme } });
|
||||
}
|
||||
|
||||
/** The persisted preview fit mode, or the default — unknown values fall back. */
|
||||
export function loadPreviewFitMode(): FitMode {
|
||||
const stored = readRaw().preview?.fitMode;
|
||||
return isFitMode(stored) ? stored : DEFAULT_FIT_MODE;
|
||||
}
|
||||
|
||||
/** Persist the preview fit mode, preserving every other key already in the record. */
|
||||
export function savePreviewFitMode(fitMode: FitMode): void {
|
||||
const current = readRaw();
|
||||
writeRaw({ ...current, preview: { ...current.preview, fitMode } });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user