/** * Terminal Theme Customize Modal * Left-right split design: list on left, large preview on right * Uses React Portal to render at document root for proper z-index * * Features: * - Real-time preview: changes are applied immediately to the terminal * - Save: persists the current settings * - Cancel: reverts to the original settings when modal was opened * - Custom themes: create, edit, delete, import .itermcolors */ import React, { useEffect, useMemo, useState, useCallback, useRef, memo } from 'react'; import { createPortal } from 'react-dom'; import { Check, Download, Minus, Palette, Pencil, Plus, Sparkles, Type, X } from 'lucide-react'; import { useI18n } from '../../application/i18n/I18nProvider'; import { useAvailableFonts } from '../../application/state/fontStore'; import { TERMINAL_THEMES, TerminalThemeConfig, USER_VISIBLE_TERMINAL_THEMES, isUiMatchTerminalThemeId } from '../../infrastructure/config/terminalThemes'; import { DEFAULT_FONT_SIZE, MIN_FONT_SIZE, MAX_FONT_SIZE, TerminalFont } from '../../infrastructure/config/fonts'; import { useCustomThemes, useCustomThemeActions } from '../../application/state/customThemeStore'; import { parseItermcolors } from '../../infrastructure/parsers/itermcolorsParser'; import { CustomThemeModal } from './CustomThemeModal'; import { Button } from '../ui/button'; import { cn } from '../../lib/utils'; import { TerminalTheme } from '../../domain/models'; type TabType = 'theme' | 'font' | 'custom'; // Memoized theme item component to prevent unnecessary re-renders const ThemeItem = memo(({ theme, isSelected, onSelect, onEdit, }: { theme: TerminalThemeConfig; isSelected: boolean; onSelect: (id: string) => void; onEdit?: (id: string) => void; }) => (