Compare commits
2 commits
fbc78b78e9
...
9e6158ed45
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e6158ed45 | ||
|
|
0c36b516fa |
3 changed files with 22 additions and 8 deletions
|
|
@ -509,7 +509,6 @@ export default function AnnotationSelectionLayer({
|
||||||
value={Number((strokeData.strokeWidth * 10).toFixed(2))}
|
value={Number((strokeData.strokeWidth * 10).toFixed(2))}
|
||||||
options={[1, 2, 4, 8, 12]}
|
options={[1, 2, 4, 8, 12]}
|
||||||
min={1}
|
min={1}
|
||||||
max={30}
|
|
||||||
step={1}
|
step={1}
|
||||||
onChange={(v) => commitStrokeWidth(v / 10)}
|
onChange={(v) => commitStrokeWidth(v / 10)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -2578,7 +2578,6 @@ export default function PDFViewer({
|
||||||
value={Number((drawWidthPct * 10).toFixed(2))}
|
value={Number((drawWidthPct * 10).toFixed(2))}
|
||||||
options={[1, 2, 4, 8, 12]}
|
options={[1, 2, 4, 8, 12]}
|
||||||
min={1}
|
min={1}
|
||||||
max={30}
|
|
||||||
step={1}
|
step={1}
|
||||||
onChange={(v) => setDrawWidthPct(v / 10)}
|
onChange={(v) => setDrawWidthPct(v / 10)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -2658,7 +2657,6 @@ export default function PDFViewer({
|
||||||
value={Number((shapeWidthPct * 10).toFixed(2))}
|
value={Number((shapeWidthPct * 10).toFixed(2))}
|
||||||
options={[1, 2, 4, 8, 12]}
|
options={[1, 2, 4, 8, 12]}
|
||||||
min={1}
|
min={1}
|
||||||
max={30}
|
|
||||||
step={1}
|
step={1}
|
||||||
onChange={(v) => setShapeWidthPct(v / 10)}
|
onChange={(v) => setShapeWidthPct(v / 10)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -2856,8 +2854,8 @@ export default function PDFViewer({
|
||||||
{/* F8: hint ความปลอดภัยของ redaction (PLAN-FEAT.md §5 — บนจอบังเท่านั้น) */}
|
{/* F8: hint ความปลอดภัยของ redaction (PLAN-FEAT.md §5 — บนจอบังเท่านั้น) */}
|
||||||
{tool === "redact" && (
|
{tool === "redact" && (
|
||||||
<p className="hidden max-w-xs text-[11px] leading-tight text-amber-600 lg:block">
|
<p className="hidden max-w-xs text-[11px] leading-tight text-amber-600 lg:block">
|
||||||
ปิดพรางบนจอเท่านั้น — ข้อความใต้กรอบยังเลือกได้ ต้องกด "Export PDF" เพื่อ
|
เป็นการปกปิดข้อมูลบนหน้าจอชั่วคราวเท่านั้น (ข้อความดั้งเดิมยังสามารถคัดลอกได้)
|
||||||
ปิดพรางจริงในไฟล์ที่แจกจ่าย
|
กรุณากด 'Export PDF' เพื่อปกปิดข้อมูลอย่างถาวรก่อนนำไปเผยแพร่
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,8 @@ export function NumberCombo({
|
||||||
value: number;
|
value: number;
|
||||||
options: number[];
|
options: number[];
|
||||||
min: number;
|
min: number;
|
||||||
max: number;
|
/** ขอบบนตอน clamp — ไม่ส่ง = ไม่จำกัด (เช่น ความหนาเส้นวาด) */
|
||||||
|
max?: number;
|
||||||
step: number;
|
step: number;
|
||||||
/** ละขั้นของปุ่ม ▲▼ (default 1 — เช่น fontSize ใช้ 0.1) */
|
/** ละขั้นของปุ่ม ▲▼ (default 1 — เช่น fontSize ใช้ 0.1) */
|
||||||
stepBy?: number;
|
stepBy?: number;
|
||||||
|
|
@ -103,6 +104,22 @@ export function NumberCombo({
|
||||||
|
|
||||||
useEffect(() => setDraft(String(value)), [value]);
|
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(() => {
|
useEffect(() => {
|
||||||
if (!open) return;
|
if (!open) return;
|
||||||
const onMouseDown = (e: MouseEvent) => {
|
const onMouseDown = (e: MouseEvent) => {
|
||||||
|
|
@ -117,7 +134,7 @@ export function NumberCombo({
|
||||||
function commitDraft() {
|
function commitDraft() {
|
||||||
const v = Number(draft);
|
const v = Number(draft);
|
||||||
if (draft.trim() !== "" && Number.isFinite(v)) {
|
if (draft.trim() !== "" && Number.isFinite(v)) {
|
||||||
const clamped = Math.min(max, Math.max(min, Number(v.toFixed(2))));
|
const clamped = Math.min(max ?? Infinity, Math.max(min, Number(v.toFixed(2))));
|
||||||
setDraft(String(clamped));
|
setDraft(String(clamped));
|
||||||
if (clamped !== value) onChange(clamped);
|
if (clamped !== value) onChange(clamped);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -130,7 +147,7 @@ export function NumberCombo({
|
||||||
function stepValue(dir: 1 | -1) {
|
function stepValue(dir: 1 | -1) {
|
||||||
const by = stepBy ?? 1;
|
const by = stepBy ?? 1;
|
||||||
const base = draft.trim() !== "" && Number.isFinite(Number(draft)) ? Number(draft) : value;
|
const base = draft.trim() !== "" && Number.isFinite(Number(draft)) ? Number(draft) : value;
|
||||||
const next = Math.min(max, Math.max(min, Number((base + dir * by).toFixed(2))));
|
const next = Math.min(max ?? Infinity, Math.max(min, Number((base + dir * by).toFixed(2))));
|
||||||
setDraft(String(next));
|
setDraft(String(next));
|
||||||
if (next !== value) onChange(next);
|
if (next !== value) onChange(next);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue