singularity-forge/web/lib/use-editor-font-size.ts
ace-pm 6b0ac484ba refactor: update log prefixes and string values from gsd- to sf- namespace
Updates channel prefixes, log messages, comments, and configuration values
across daemon, mcp-server, and related packages to complete the rebrand from
gsd to sf-run naming.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:37:12 +02:00

70 lines
2.3 KiB
TypeScript

"use client"
import { useState, useEffect, useCallback } from "react"
const STORAGE_KEY = "sf-editor-font-size"
const DEFAULT_SIZE = 14
const CHANGE_EVENT = "editor-font-size-changed"
/**
* Persists editor font size to localStorage and syncs across components/tabs.
*
* Observability:
* - `localStorage.getItem('sf-editor-font-size')` → current persisted value
* - Window event `editor-font-size-changed` fires on every local change
* - `storage` events sync across tabs
*/
export function useEditorFontSize(): [number, (size: number) => void] {
const [fontSize, setFontSizeState] = useState<number>(() => {
if (typeof window === "undefined") return DEFAULT_SIZE
try {
const stored = localStorage.getItem(STORAGE_KEY)
if (stored) {
const parsed = Number(stored)
if (Number.isFinite(parsed) && parsed >= 8 && parsed <= 24) return parsed
}
} catch {
// localStorage may be unavailable
}
return DEFAULT_SIZE
})
const setFontSize = useCallback((size: number) => {
const clamped = Math.max(8, Math.min(24, Math.round(size)))
setFontSizeState(clamped)
try {
localStorage.setItem(STORAGE_KEY, String(clamped))
} catch {
// localStorage may be unavailable
}
// Notify other hook instances within the same tab
window.dispatchEvent(new CustomEvent(CHANGE_EVENT, { detail: clamped }))
}, [])
// Sync from other tabs via storage event
useEffect(() => {
const handleStorage = (e: StorageEvent) => {
if (e.key !== STORAGE_KEY) return
const parsed = Number(e.newValue)
if (Number.isFinite(parsed) && parsed >= 8 && parsed <= 24) {
setFontSizeState(parsed)
}
}
window.addEventListener("storage", handleStorage)
return () => window.removeEventListener("storage", handleStorage)
}, [])
// Sync from other hook instances in the same tab via custom event
useEffect(() => {
const handleChange = (e: Event) => {
const detail = (e as CustomEvent<number>).detail
if (Number.isFinite(detail) && detail >= 8 && detail <= 24) {
setFontSizeState(detail)
}
}
window.addEventListener(CHANGE_EVENT, handleChange)
return () => window.removeEventListener(CHANGE_EVENT, handleChange)
}, [])
return [fontSize, setFontSize]
}