diff --git a/components/pdf/AnnotationSelectionLayer.tsx b/components/pdf/AnnotationSelectionLayer.tsx index 455a1b6..2f2f4bb 100644 --- a/components/pdf/AnnotationSelectionLayer.tsx +++ b/components/pdf/AnnotationSelectionLayer.tsx @@ -509,6 +509,7 @@ export default function AnnotationSelectionLayer({ value={Number((strokeData.strokeWidth * 10).toFixed(2))} options={[1, 2, 4, 8, 12]} min={1} + max={30} step={1} onChange={(v) => commitStrokeWidth(v / 10)} /> diff --git a/components/pdf/PDFViewer.tsx b/components/pdf/PDFViewer.tsx index 263a7e4..ff9c9fb 100644 --- a/components/pdf/PDFViewer.tsx +++ b/components/pdf/PDFViewer.tsx @@ -2578,6 +2578,7 @@ export default function PDFViewer({ value={Number((drawWidthPct * 10).toFixed(2))} options={[1, 2, 4, 8, 12]} min={1} + max={30} step={1} onChange={(v) => setDrawWidthPct(v / 10)} /> @@ -2657,6 +2658,7 @@ export default function PDFViewer({ value={Number((shapeWidthPct * 10).toFixed(2))} options={[1, 2, 4, 8, 12]} min={1} + max={30} step={1} onChange={(v) => setShapeWidthPct(v / 10)} /> @@ -2854,8 +2856,8 @@ export default function PDFViewer({ {/* F8: hint ความปลอดภัยของ redaction (PLAN-FEAT.md §5 — บนจอบังเท่านั้น) */} {tool === "redact" && (

- เป็นการปกปิดข้อมูลบนหน้าจอชั่วคราวเท่านั้น (ข้อความดั้งเดิมยังสามารถคัดลอกได้) - กรุณากด 'Export PDF' เพื่อปกปิดข้อมูลอย่างถาวรก่อนนำไปเผยแพร่ + ปิดพรางบนจอเท่านั้น — ข้อความใต้กรอบยังเลือกได้ ต้องกด "Export PDF" เพื่อ + ปิดพรางจริงในไฟล์ที่แจกจ่าย

)} diff --git a/components/pdf/ToolControls.tsx b/components/pdf/ToolControls.tsx index 559e9cf..40a7143 100644 --- a/components/pdf/ToolControls.tsx +++ b/components/pdf/ToolControls.tsx @@ -87,8 +87,7 @@ export function NumberCombo({ value: number; options: number[]; min: number; - /** ขอบบนตอน clamp — ไม่ส่ง = ไม่จำกัด (เช่น ความหนาเส้นวาด) */ - max?: number; + max: number; step: number; /** ละขั้นของปุ่ม ▲▼ (default 1 — เช่น fontSize ใช้ 0.1) */ stepBy?: number; @@ -104,22 +103,6 @@ export function NumberCombo({ useEffect(() => setDraft(String(value)), [value]); - // FIX-3 (ปรับ): หยุดพิมพ์แล้ว ~0.5 วิ commit เอง — ไม่ต้องรอ Enter/blur แต่ยัง - // รวมเป็น commit เดียวต่อชุดที่พิมพ์เสร็จ (ไม่ยิง server action + version - // snapshot ต่อ keystroke — สำคัญกับแผง selection ที่ commit ทัพหลังถึง DB) - useEffect(() => { - if (draft === String(value)) return; // sync กลับจาก value ไม่นับเป็นการพิมพ์ - const t = setTimeout(() => { - const v = Number(draft); - if (draft.trim() === "" || !Number.isFinite(v)) return; // คั่นกลางพิมพ์/ลบหมด — ให้ blur จัดการ - const clamped = Math.min(max ?? Infinity, Math.max(min, Number(v.toFixed(2)))); - if (clamped !== value) onChange(clamped); // value เปลี่ยน → effect ด้านบน sync draft กลับ - else setDraft(String(clamped)); // เกินขอบแต่ clamped แล้วเท่าค่าเดิม → แสดงค่าจริง - }, 500); - return () => clearTimeout(t); - // eslint-disable-next-line react-hooks/exhaustive-deps -- draft/value/onChange ใช้ค่าล่าสุดตอน timer ยิง - }, [draft]); - useEffect(() => { if (!open) return; const onMouseDown = (e: MouseEvent) => { @@ -134,7 +117,7 @@ export function NumberCombo({ function commitDraft() { const v = Number(draft); if (draft.trim() !== "" && Number.isFinite(v)) { - const clamped = Math.min(max ?? Infinity, Math.max(min, Number(v.toFixed(2)))); + const clamped = Math.min(max, Math.max(min, Number(v.toFixed(2)))); setDraft(String(clamped)); if (clamped !== value) onChange(clamped); } else { @@ -147,7 +130,7 @@ export function NumberCombo({ function stepValue(dir: 1 | -1) { const by = stepBy ?? 1; const base = draft.trim() !== "" && Number.isFinite(Number(draft)) ? Number(draft) : value; - const next = Math.min(max ?? Infinity, Math.max(min, Number((base + dir * by).toFixed(2)))); + const next = Math.min(max, Math.max(min, Number((base + dir * by).toFixed(2)))); setDraft(String(next)); if (next !== value) onChange(next); }