diff --git a/js/input_watcher.js b/js/input_watcher.js index 6362d11..79bccc0 100644 --- a/js/input_watcher.js +++ b/js/input_watcher.js @@ -61,6 +61,13 @@ export class Watcher { wrap.appendChild(header); wrap.appendChild(chipsEl); + // フォント・サイズを textarea に合わせる(子要素へ継承) + try { + const taCS = getComputedStyle(ta); + wrap.style.fontFamily = taCS.fontFamily; + wrap.style.fontSize = taCS.fontSize; + } catch (_) {} + const editor = new TagEditor(chipsEl, (str) => this._syncToTextarea(w, ta, str)); w.__pteEditor = editor; @@ -74,12 +81,37 @@ export class Watcher { getValue: () => "", setValue: () => {}, getHeight: () => { - const h = chipsEl.scrollHeight + 22; - return Math.max(56, Math.min(220, h)); + // 実レイアウト後の内容高さ(header + chips)にぴったり合わせる + const h = wrap.scrollHeight; + return Math.max(24, Math.min(400, h)); }, }); w.__pteDom = dom; + // 内容の高さが変わったらノードをフィット(余分な余白を出さない) + let _fitting = false; + const refit = () => { + if (_fitting) return; + // 幅が確定していない(未描画)ときは誤計測になるのでスキップ + if (chipsEl.clientWidth < 20) return; + _fitting = true; + requestAnimationFrame(() => { + try { + const cs = node.computeSize(); + if (Math.abs(cs[1] - node.size[1]) > 1) { + node.setSize([node.size[0], cs[1]]); + node.setDirtyCanvas(true, true); + } + } catch (_) {} + _fitting = false; + }); + }; + try { + const ro = new ResizeObserver(() => refit()); + ro.observe(chipsEl); + } catch (_) {} + w.__pteRefit = refit; + // 初期描画 editor.setFromString(w.value != null ? String(w.value) : ta.value || ""); @@ -94,14 +126,8 @@ export class Watcher { }; ta.addEventListener("input", onInput); - // ノードサイズを再計算してチップエリアを見えるように - requestAnimationFrame(() => { - try { - const sz = node.computeSize(); - node.setSize([Math.max(node.size[0], sz[0]), Math.max(node.size[1], sz[1])]); - node.setDirtyCanvas(true, true); - } catch (_) {} - }); + // 初期レイアウト確定後にノードをフィット + refit(); } // チップ編集結果を textarea(=真実の値)へ3行同期 diff --git a/js/style.css b/js/style.css index d141bfe..ea4b889 100644 --- a/js/style.css +++ b/js/style.css @@ -16,7 +16,7 @@ .pte-empty { color: var(--descrip-text, #888); - font-size: 11px; + font-size: 0.9em; font-style: italic; padding: 2px 4px; } @@ -29,7 +29,7 @@ background: var(--comfy-menu-bg, #353535); border: 1px solid var(--border-color, #4a4a4a); border-radius: 5px; - font-size: 12px; + font-size: inherit; line-height: 1.4; color: var(--input-text, #ddd); cursor: grab; @@ -53,7 +53,7 @@ } .pte-chip-trans { - font-size: 10px; + font-size: 0.9em; color: var(--descrip-text, #9aa); white-space: nowrap; overflow: hidden; @@ -62,7 +62,7 @@ } .pte-translate { - font-size: 10px; + font-size: 0.9em; font-weight: 700; flex: 0 0 auto; } @@ -114,10 +114,10 @@ color: inherit; opacity: 0.65; cursor: pointer; - font-size: 12px; + font-size: 1em; line-height: 1; - width: 16px; - height: 16px; + width: 1.5em; + height: 1.5em; padding: 0; border-radius: 3px; display: inline-flex; @@ -141,7 +141,7 @@ } .pte-chip-edit { - font-size: 12px; + font: inherit; background: var(--comfy-input-bg, #1a1a1a); color: var(--input-text, #fff); border: 1px solid #5a8fd0;