/
lizardking
/
react_project
Обзор
Документация
Войти
/
lizardking
/
react_project
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
react19
src/features/console/ui/ConsoleViewer.tsx
83 строки
3 KB
LizardKing
Task 5 - styles
17 окт 2025, 14:23
17 окт 2025, 14:23
4ba1ff3
Код
Авторство
О чём код?
import React, { useCallback, useEffect, useRef, useState } from 'react' import { SecondaryButton } from 'shared/ui/SecondaryButton' import { Section } from 'shared/ui/Section' export const ConsoleViewer = () => { const [printedLines, setPrintedLines] = useState<string[]>([]) const originalMethodsRef = useRef<Map<string, unknown> | null>(null) useEffect(() => { const originalMethods = new Map<string, unknown>() originalMethodsRef.current = originalMethods const consoleObject = window.console as unknown as Record<string, unknown> const methodNames = Object.keys(consoleObject).filter( (name) => typeof consoleObject[name] === 'function', ) const serialize = (value: unknown): string => { if ( value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint' || typeof value === 'undefined' ) { return String(value) } if (value instanceof Error) { return `${value.name}: ${value.message}${ value.stack ? '\n' + value.stack : '' }` } try { return JSON.stringify(value, null, 2) } catch { return '[Unserializable]' } } const appendLine = (...values: unknown[]) => { const text = values.map(serialize).join(' ') setPrintedLines((previous) => [...previous, text]) } methodNames.forEach((name) => { const original = consoleObject[name] as (...args: unknown[]) => void originalMethods.set(name, original); (consoleObject[name] as (...args: unknown[]) => void) = (...args) => { appendLine(...args) original(...args) } }) return () => { if (originalMethodsRef.current) { for (const [name, original] of originalMethodsRef.current.entries()) { (consoleObject[name] as unknown) = original } } } }, []) const handleClearClick = useCallback(() => setPrintedLines([]), []) return ( <Section title="Console Viewer" actions={<SecondaryButton onClick={handleClearClick}>Очистить</SecondaryButton>}> <div className="h-72 overflow-y-auto rounded-lg border border-slate-800/70 bg-slate-900/70' p-2 font-mono text-xs text-slate-200 whitespace-pre-wrap break-words"> {printedLines.length === 0 ? ( <div className="text-slate-500">Пока пусто…</div> ) : ( printedLines.map((line, index) => ( <div key={index} className="truncate">{line}</div> )) )} </div> </Section> ) }