From 1ebc2b1b9d0f849861817088d7e8f3aa418590c1 Mon Sep 17 00:00:00 2001 From: Seungjun Jeong Date: Tue, 27 Oct 2026 21:51:20 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20style:=20improve=20editor=20layo?= =?UTF-8?q?ut=20and=20view=20controls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/WriteEditor.tsx | 78 ++++++++++++++++++++++----------- src/components/write-editor.css | 26 ++++++----- 2 files changed, 66 insertions(+), 38 deletions(-) diff --git a/src/components/WriteEditor.tsx b/src/components/WriteEditor.tsx index b2e48a2..cfb8757 100644 --- a/src/components/WriteEditor.tsx +++ b/src/components/WriteEditor.tsx @@ -1,4 +1,11 @@ -import { useEffect, useEffectEvent, useMemo, useRef, useState } from 'react'; +import { + useEffect, + useEffectEvent, + useLayoutEffect, + useMemo, + useRef, + useState, +} from 'react'; import { editorRequest as editorApi } from '../lib/editor-api'; import DOMPurify from 'dompurify'; import { toast } from 'sonner'; @@ -113,6 +120,31 @@ export default function WriteEditor() { const [uploads, setUploads] = useState(0); const [dragging, setDragging] = useState(false); const [view, setView] = useState<'editor' | 'preview' | 'both'>('both'); + const titleInput = useRef(null); + useLayoutEffect(() => { + const input = titleInput.current; + if (!input?.parentElement) return; + const container = input.parentElement; + const fit = () => { + input.style.fontSize = ''; + const style = getComputedStyle(input); + const maxSize = parseFloat(style.fontSize); + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + if (!context) return; + context.font = `${style.fontWeight} ${String(maxSize)}px ${style.fontFamily}`; + const width = context.measureText(input.value || input.placeholder).width; + const spacing = parseFloat(style.letterSpacing) || 0; + const textWidth = width + spacing * Math.max(0, input.value.length - 1); + input.style.fontSize = `${String(Math.max(20, Math.min(maxSize, (maxSize * input.clientWidth) / Math.max(textWidth, 1))))}px`; + input.style.height = 'auto'; + input.style.height = `${String(input.scrollHeight)}px`; + }; + fit(); + const observer = new ResizeObserver(fit); + observer.observe(container); + return () => observer.disconnect(); + }, [title, authorized, view]); const editor = useRef(null); const imageInput = useRef(null); const openedDeepLink = useRef(false); @@ -641,34 +673,9 @@ export default function WriteEditor() { return (
-
- {( - [ - ['editor', '에디터 보기'], - ['preview', '미리보기'], - ['both', '둘 다 보기'], - ] as const - ).map(([value, label]) => ( - - ))} -
-