@solhun/feedback-kit-web 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +172 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -2
- package/dist/index.d.ts +33 -2
- package/dist/index.js +172 -61
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -109,6 +109,18 @@ interface AnnotationPopupState {
|
|
|
109
109
|
}
|
|
110
110
|
interface PickingState {
|
|
111
111
|
active: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* 켜져 있지만 **클릭 가로채기만 잠시 끈 상태**.
|
|
114
|
+
*
|
|
115
|
+
* 왜 필요한가: 지목 모드는 페이지의 모든 클릭을 먹는다(그래야 지목하려고 누른 링크가
|
|
116
|
+
* 실제로 이동해 버리지 않는다). 그 대가로 **제보할 화면을 만들 수가 없다** — 드롭다운을
|
|
117
|
+
* 열고 그 안의 항목을 지목하고 싶어도 여는 클릭부터 막힌다. 그때 모드를 끄면 다시
|
|
118
|
+
* 켜야 하고, 사용자에겐 그게 "모드가 유지되지 않는다"로 읽힌다.
|
|
119
|
+
*
|
|
120
|
+
* 그래서 끄는 것과 멈추는 것을 나눈다. 멈춘 동안 페이지는 원래대로 동작하고, 모드는
|
|
121
|
+
* 켜진 채로 남는다.
|
|
122
|
+
*/
|
|
123
|
+
paused: boolean;
|
|
112
124
|
/** 지금 마우스가 올라가 있는 요소. 하이라이트를 그리는 근거. */
|
|
113
125
|
hovered: ElementInfo | null;
|
|
114
126
|
popup: AnnotationPopupState | null;
|
|
@@ -167,6 +179,12 @@ declare class ElementPickingController {
|
|
|
167
179
|
private readonly rankHintsFor;
|
|
168
180
|
private readonly listeners;
|
|
169
181
|
private active;
|
|
182
|
+
/**
|
|
183
|
+
* 일시중지. **저장하지 않는다** — 멈추는 목적이 대개 "링크를 눌러 다른 화면으로 가는 것"
|
|
184
|
+
* 이라, 그 이동이 끝나면 지목이 돌아와 있는 게 목적에 맞다. 같은 이유로 경로가 바뀌면
|
|
185
|
+
* 스스로 풀린다(`syncPath`) — 그래야 SPA 이동과 새로고침이 같게 동작한다.
|
|
186
|
+
*/
|
|
187
|
+
private paused;
|
|
170
188
|
private attached;
|
|
171
189
|
private hovered;
|
|
172
190
|
private popup;
|
|
@@ -179,7 +197,7 @@ declare class ElementPickingController {
|
|
|
179
197
|
/** 지금 도는 자동 캡처. Enter 가 캡처보다 빨랐을 때 기다릴 대상. */
|
|
180
198
|
private capturing;
|
|
181
199
|
/**
|
|
182
|
-
* 사용자가 [
|
|
200
|
+
* 사용자가 [이런 건가요? ▾] 를 직접 건드렸는가. 한 번이라도 건드리면 이후 타이핑에 의한 자동
|
|
183
201
|
* 접힘/펼침이 멈춘다 — 모달의 `userToggledHints` 와 같은 규칙. 팝업을 새로 열 때마다 리셋된다.
|
|
184
202
|
*/
|
|
185
203
|
private userToggledHints;
|
|
@@ -188,10 +206,23 @@ declare class ElementPickingController {
|
|
|
188
206
|
constructor(opts: ElementPickingOpts);
|
|
189
207
|
getState(): PickingState;
|
|
190
208
|
get isActive(): boolean;
|
|
209
|
+
/** 켜져 있지만 클릭을 안 먹는 상태인가. */
|
|
210
|
+
get isPaused(): boolean;
|
|
191
211
|
subscribe(listener: PickingListener): () => void;
|
|
192
212
|
start(): void;
|
|
193
213
|
/** [지목 종료]. 저장된 플래그까지 지워서 새로고침해도 다시 켜지지 않게 한다. */
|
|
194
214
|
stop(): void;
|
|
215
|
+
/**
|
|
216
|
+
* 잠시 멈춘다 — 페이지 클릭이 원래대로 동작하고, 모드는 켜진 채로 남는다.
|
|
217
|
+
*
|
|
218
|
+
* 팝업이 열려 있으면 **그대로 둔다.** 쓰던 한 줄을 여기서 지우면 「지목 켜면 모달 초안이
|
|
219
|
+
* 날아간다」와 같은 사고를 다른 자리에 만드는 셈이다. 팝업은 위젯 자신의 UI 라
|
|
220
|
+
* 리스너를 떼도 계속 눌린다.
|
|
221
|
+
*/
|
|
222
|
+
pause(): void;
|
|
223
|
+
/** 다시 지목을 받는다. */
|
|
224
|
+
resume(): void;
|
|
225
|
+
togglePause(): void;
|
|
195
226
|
/**
|
|
196
227
|
* 저장돼 있던 모드를 되살린다. 새로고침·페이지 이동 직후에 한 번 부른다.
|
|
197
228
|
* @returns 되살아났으면 true.
|
|
@@ -220,7 +251,7 @@ declare class ElementPickingController {
|
|
|
220
251
|
* 아니면 줄바꿈 뒤 이어붙인다 — 모달의 `applyHint` 와 동일한 규칙이다.
|
|
221
252
|
*/
|
|
222
253
|
applyHint(hintId: string): void;
|
|
223
|
-
/** [
|
|
254
|
+
/** [이런 건가요? ▾] 토글. 방향과 무관하게 이후 자동 접힘/펼침을 멈춘다. */
|
|
224
255
|
toggleHints(): void;
|
|
225
256
|
/**
|
|
226
257
|
* 사용자가 붙여넣기(Cmd+V)나 드래그로 넣은 그림. 자동 캡처 결과를 덮는다.
|
package/dist/index.d.ts
CHANGED
|
@@ -109,6 +109,18 @@ interface AnnotationPopupState {
|
|
|
109
109
|
}
|
|
110
110
|
interface PickingState {
|
|
111
111
|
active: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* 켜져 있지만 **클릭 가로채기만 잠시 끈 상태**.
|
|
114
|
+
*
|
|
115
|
+
* 왜 필요한가: 지목 모드는 페이지의 모든 클릭을 먹는다(그래야 지목하려고 누른 링크가
|
|
116
|
+
* 실제로 이동해 버리지 않는다). 그 대가로 **제보할 화면을 만들 수가 없다** — 드롭다운을
|
|
117
|
+
* 열고 그 안의 항목을 지목하고 싶어도 여는 클릭부터 막힌다. 그때 모드를 끄면 다시
|
|
118
|
+
* 켜야 하고, 사용자에겐 그게 "모드가 유지되지 않는다"로 읽힌다.
|
|
119
|
+
*
|
|
120
|
+
* 그래서 끄는 것과 멈추는 것을 나눈다. 멈춘 동안 페이지는 원래대로 동작하고, 모드는
|
|
121
|
+
* 켜진 채로 남는다.
|
|
122
|
+
*/
|
|
123
|
+
paused: boolean;
|
|
112
124
|
/** 지금 마우스가 올라가 있는 요소. 하이라이트를 그리는 근거. */
|
|
113
125
|
hovered: ElementInfo | null;
|
|
114
126
|
popup: AnnotationPopupState | null;
|
|
@@ -167,6 +179,12 @@ declare class ElementPickingController {
|
|
|
167
179
|
private readonly rankHintsFor;
|
|
168
180
|
private readonly listeners;
|
|
169
181
|
private active;
|
|
182
|
+
/**
|
|
183
|
+
* 일시중지. **저장하지 않는다** — 멈추는 목적이 대개 "링크를 눌러 다른 화면으로 가는 것"
|
|
184
|
+
* 이라, 그 이동이 끝나면 지목이 돌아와 있는 게 목적에 맞다. 같은 이유로 경로가 바뀌면
|
|
185
|
+
* 스스로 풀린다(`syncPath`) — 그래야 SPA 이동과 새로고침이 같게 동작한다.
|
|
186
|
+
*/
|
|
187
|
+
private paused;
|
|
170
188
|
private attached;
|
|
171
189
|
private hovered;
|
|
172
190
|
private popup;
|
|
@@ -179,7 +197,7 @@ declare class ElementPickingController {
|
|
|
179
197
|
/** 지금 도는 자동 캡처. Enter 가 캡처보다 빨랐을 때 기다릴 대상. */
|
|
180
198
|
private capturing;
|
|
181
199
|
/**
|
|
182
|
-
* 사용자가 [
|
|
200
|
+
* 사용자가 [이런 건가요? ▾] 를 직접 건드렸는가. 한 번이라도 건드리면 이후 타이핑에 의한 자동
|
|
183
201
|
* 접힘/펼침이 멈춘다 — 모달의 `userToggledHints` 와 같은 규칙. 팝업을 새로 열 때마다 리셋된다.
|
|
184
202
|
*/
|
|
185
203
|
private userToggledHints;
|
|
@@ -188,10 +206,23 @@ declare class ElementPickingController {
|
|
|
188
206
|
constructor(opts: ElementPickingOpts);
|
|
189
207
|
getState(): PickingState;
|
|
190
208
|
get isActive(): boolean;
|
|
209
|
+
/** 켜져 있지만 클릭을 안 먹는 상태인가. */
|
|
210
|
+
get isPaused(): boolean;
|
|
191
211
|
subscribe(listener: PickingListener): () => void;
|
|
192
212
|
start(): void;
|
|
193
213
|
/** [지목 종료]. 저장된 플래그까지 지워서 새로고침해도 다시 켜지지 않게 한다. */
|
|
194
214
|
stop(): void;
|
|
215
|
+
/**
|
|
216
|
+
* 잠시 멈춘다 — 페이지 클릭이 원래대로 동작하고, 모드는 켜진 채로 남는다.
|
|
217
|
+
*
|
|
218
|
+
* 팝업이 열려 있으면 **그대로 둔다.** 쓰던 한 줄을 여기서 지우면 「지목 켜면 모달 초안이
|
|
219
|
+
* 날아간다」와 같은 사고를 다른 자리에 만드는 셈이다. 팝업은 위젯 자신의 UI 라
|
|
220
|
+
* 리스너를 떼도 계속 눌린다.
|
|
221
|
+
*/
|
|
222
|
+
pause(): void;
|
|
223
|
+
/** 다시 지목을 받는다. */
|
|
224
|
+
resume(): void;
|
|
225
|
+
togglePause(): void;
|
|
195
226
|
/**
|
|
196
227
|
* 저장돼 있던 모드를 되살린다. 새로고침·페이지 이동 직후에 한 번 부른다.
|
|
197
228
|
* @returns 되살아났으면 true.
|
|
@@ -220,7 +251,7 @@ declare class ElementPickingController {
|
|
|
220
251
|
* 아니면 줄바꿈 뒤 이어붙인다 — 모달의 `applyHint` 와 동일한 규칙이다.
|
|
221
252
|
*/
|
|
222
253
|
applyHint(hintId: string): void;
|
|
223
|
-
/** [
|
|
254
|
+
/** [이런 건가요? ▾] 토글. 방향과 무관하게 이후 자동 접힘/펼침을 멈춘다. */
|
|
224
255
|
toggleHints(): void;
|
|
225
256
|
/**
|
|
226
257
|
* 사용자가 붙여넣기(Cmd+V)나 드래그로 넣은 그림. 자동 캡처 결과를 덮는다.
|
package/dist/index.js
CHANGED
|
@@ -320,6 +320,12 @@ var ElementPickingController = class {
|
|
|
320
320
|
constructor(opts) {
|
|
321
321
|
this.listeners = /* @__PURE__ */ new Set();
|
|
322
322
|
this.active = false;
|
|
323
|
+
/**
|
|
324
|
+
* 일시중지. **저장하지 않는다** — 멈추는 목적이 대개 "링크를 눌러 다른 화면으로 가는 것"
|
|
325
|
+
* 이라, 그 이동이 끝나면 지목이 돌아와 있는 게 목적에 맞다. 같은 이유로 경로가 바뀌면
|
|
326
|
+
* 스스로 풀린다(`syncPath`) — 그래야 SPA 이동과 새로고침이 같게 동작한다.
|
|
327
|
+
*/
|
|
328
|
+
this.paused = false;
|
|
323
329
|
this.attached = false;
|
|
324
330
|
this.hovered = null;
|
|
325
331
|
this.popup = null;
|
|
@@ -331,7 +337,7 @@ var ElementPickingController = class {
|
|
|
331
337
|
/** 지금 도는 자동 캡처. Enter 가 캡처보다 빨랐을 때 기다릴 대상. */
|
|
332
338
|
this.capturing = null;
|
|
333
339
|
/**
|
|
334
|
-
* 사용자가 [
|
|
340
|
+
* 사용자가 [이런 건가요? ▾] 를 직접 건드렸는가. 한 번이라도 건드리면 이후 타이핑에 의한 자동
|
|
335
341
|
* 접힘/펼침이 멈춘다 — 모달의 `userToggledHints` 와 같은 규칙. 팝업을 새로 열 때마다 리셋된다.
|
|
336
342
|
*/
|
|
337
343
|
this.userToggledHints = false;
|
|
@@ -358,6 +364,7 @@ var ElementPickingController = class {
|
|
|
358
364
|
getState() {
|
|
359
365
|
return {
|
|
360
366
|
active: this.active,
|
|
367
|
+
paused: this.paused,
|
|
361
368
|
hovered: this.hovered,
|
|
362
369
|
popup: this.popup,
|
|
363
370
|
markers: this.markers
|
|
@@ -366,6 +373,10 @@ var ElementPickingController = class {
|
|
|
366
373
|
get isActive() {
|
|
367
374
|
return this.active;
|
|
368
375
|
}
|
|
376
|
+
/** 켜져 있지만 클릭을 안 먹는 상태인가. */
|
|
377
|
+
get isPaused() {
|
|
378
|
+
return this.paused;
|
|
379
|
+
}
|
|
369
380
|
subscribe(listener) {
|
|
370
381
|
this.listeners.add(listener);
|
|
371
382
|
listener(this.getState());
|
|
@@ -377,6 +388,7 @@ var ElementPickingController = class {
|
|
|
377
388
|
start() {
|
|
378
389
|
if (this.active) return;
|
|
379
390
|
this.active = true;
|
|
391
|
+
this.paused = false;
|
|
380
392
|
this.store.setPickingActive(true);
|
|
381
393
|
this.attach();
|
|
382
394
|
this.startPathWatch();
|
|
@@ -386,6 +398,7 @@ var ElementPickingController = class {
|
|
|
386
398
|
/** [지목 종료]. 저장된 플래그까지 지워서 새로고침해도 다시 켜지지 않게 한다. */
|
|
387
399
|
stop() {
|
|
388
400
|
this.active = false;
|
|
401
|
+
this.paused = false;
|
|
389
402
|
this.store.setPickingActive(false);
|
|
390
403
|
this.detach();
|
|
391
404
|
this.stopPathWatch();
|
|
@@ -393,6 +406,31 @@ var ElementPickingController = class {
|
|
|
393
406
|
this.popup = null;
|
|
394
407
|
this.emit();
|
|
395
408
|
}
|
|
409
|
+
/**
|
|
410
|
+
* 잠시 멈춘다 — 페이지 클릭이 원래대로 동작하고, 모드는 켜진 채로 남는다.
|
|
411
|
+
*
|
|
412
|
+
* 팝업이 열려 있으면 **그대로 둔다.** 쓰던 한 줄을 여기서 지우면 「지목 켜면 모달 초안이
|
|
413
|
+
* 날아간다」와 같은 사고를 다른 자리에 만드는 셈이다. 팝업은 위젯 자신의 UI 라
|
|
414
|
+
* 리스너를 떼도 계속 눌린다.
|
|
415
|
+
*/
|
|
416
|
+
pause() {
|
|
417
|
+
if (!this.active || this.paused) return;
|
|
418
|
+
this.paused = true;
|
|
419
|
+
this.detach();
|
|
420
|
+
this.hovered = null;
|
|
421
|
+
this.emit();
|
|
422
|
+
}
|
|
423
|
+
/** 다시 지목을 받는다. */
|
|
424
|
+
resume() {
|
|
425
|
+
if (!this.active || !this.paused) return;
|
|
426
|
+
this.paused = false;
|
|
427
|
+
this.attach();
|
|
428
|
+
this.emit();
|
|
429
|
+
}
|
|
430
|
+
togglePause() {
|
|
431
|
+
if (this.paused) this.resume();
|
|
432
|
+
else this.pause();
|
|
433
|
+
}
|
|
396
434
|
/**
|
|
397
435
|
* 저장돼 있던 모드를 되살린다. 새로고침·페이지 이동 직후에 한 번 부른다.
|
|
398
436
|
* @returns 되살아났으면 true.
|
|
@@ -408,6 +446,7 @@ var ElementPickingController = class {
|
|
|
408
446
|
}
|
|
409
447
|
/** 경로가 바뀌었을 때 그 경로의 마커로 갈아 끼운다. */
|
|
410
448
|
syncPath() {
|
|
449
|
+
if (this.paused) this.resume();
|
|
411
450
|
this.lastPathname = this.getPathname();
|
|
412
451
|
this.markers = this.store.list(this.lastPathname);
|
|
413
452
|
this.reconcileMarkerOutcomes();
|
|
@@ -436,12 +475,12 @@ var ElementPickingController = class {
|
|
|
436
475
|
this.attached = false;
|
|
437
476
|
}
|
|
438
477
|
handleMouseOver(event) {
|
|
439
|
-
if (!this.active || isOwnUi(event.target)) return;
|
|
478
|
+
if (!this.active || this.paused || isOwnUi(event.target)) return;
|
|
440
479
|
this.hovered = describeElement(event.target);
|
|
441
480
|
this.emit();
|
|
442
481
|
}
|
|
443
482
|
handleClick(event) {
|
|
444
|
-
if (!this.active) return;
|
|
483
|
+
if (!this.active || this.paused) return;
|
|
445
484
|
if (isOwnUi(event.target)) return;
|
|
446
485
|
event.preventDefault();
|
|
447
486
|
event.stopPropagation();
|
|
@@ -522,7 +561,7 @@ ${hint.draft}`;
|
|
|
522
561
|
};
|
|
523
562
|
this.emit();
|
|
524
563
|
}
|
|
525
|
-
/** [
|
|
564
|
+
/** [이런 건가요? ▾] 토글. 방향과 무관하게 이후 자동 접힘/펼침을 멈춘다. */
|
|
526
565
|
toggleHints() {
|
|
527
566
|
if (!this.popup) return;
|
|
528
567
|
this.userToggledHints = true;
|
|
@@ -973,7 +1012,7 @@ import {
|
|
|
973
1012
|
} from "react";
|
|
974
1013
|
|
|
975
1014
|
// src/version.ts
|
|
976
|
-
var VERSION = true ? "0.
|
|
1015
|
+
var VERSION = true ? "0.7.0" : "dev";
|
|
977
1016
|
|
|
978
1017
|
// src/feedback-kit.tsx
|
|
979
1018
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -995,6 +1034,7 @@ var OWN_UI_PROPS = { [OWN_UI_ATTR]: "" };
|
|
|
995
1034
|
var FONT_STACK = "ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif";
|
|
996
1035
|
var INITIAL_PICKING_STATE = {
|
|
997
1036
|
active: false,
|
|
1037
|
+
paused: false,
|
|
998
1038
|
hovered: null,
|
|
999
1039
|
popup: null,
|
|
1000
1040
|
markers: []
|
|
@@ -1148,6 +1188,7 @@ var inputStyle = {
|
|
|
1148
1188
|
};
|
|
1149
1189
|
function PickToggle({
|
|
1150
1190
|
active,
|
|
1191
|
+
paused,
|
|
1151
1192
|
disabled,
|
|
1152
1193
|
variant,
|
|
1153
1194
|
focusId,
|
|
@@ -1175,14 +1216,9 @@ function PickToggle({
|
|
|
1175
1216
|
// 항상 값을 준다. 조건부로 빼면 리렌더 때 shorthand(border)와 충돌한다고 React 가 경고한다.
|
|
1176
1217
|
borderColor: active ? TOKENS.accent : TOKENS.line,
|
|
1177
1218
|
...floating ? {
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
transform: "translateX(-50%)",
|
|
1182
|
-
// 오버레이 자체는 클릭을 통과시킨다(pointerEvents:none) — 이 토글만 되살린다.
|
|
1183
|
-
pointerEvents: "auto",
|
|
1184
|
-
background: TOKENS.surface,
|
|
1185
|
-
boxShadow: TOKENS.shadow
|
|
1219
|
+
// 위치는 감싸는 `PickBar` 가 잡는다 — 옆에 [잠시 멈춤] 이 함께 서야 하는데
|
|
1220
|
+
// 토글이 스스로 fixed 면 둘을 나란히 둘 수 없다.
|
|
1221
|
+
background: TOKENS.surface
|
|
1186
1222
|
} : {
|
|
1187
1223
|
width: "100%",
|
|
1188
1224
|
justifyContent: "space-between",
|
|
@@ -1199,8 +1235,12 @@ function PickToggle({
|
|
|
1199
1235
|
/* @__PURE__ */ jsx(
|
|
1200
1236
|
"span",
|
|
1201
1237
|
{
|
|
1202
|
-
style: {
|
|
1203
|
-
|
|
1238
|
+
style: {
|
|
1239
|
+
fontSize: 12,
|
|
1240
|
+
fontWeight: 600,
|
|
1241
|
+
color: active && !paused ? TOKENS.accent : TOKENS.muted
|
|
1242
|
+
},
|
|
1243
|
+
children: active ? paused ? "\uC77C\uC2DC\uC911\uC9C0" : "\uCF1C\uC9D0" : "\uAEBC\uC9D0"
|
|
1204
1244
|
}
|
|
1205
1245
|
),
|
|
1206
1246
|
/* @__PURE__ */ jsx(
|
|
@@ -1212,7 +1252,7 @@ function PickToggle({
|
|
|
1212
1252
|
width: 38,
|
|
1213
1253
|
height: 22,
|
|
1214
1254
|
borderRadius: 11,
|
|
1215
|
-
background: active ? TOKENS.accent : TOKENS.line
|
|
1255
|
+
background: active ? paused ? TOKENS.muted : TOKENS.accent : TOKENS.line
|
|
1216
1256
|
},
|
|
1217
1257
|
children: /* @__PURE__ */ jsx(
|
|
1218
1258
|
"span",
|
|
@@ -1236,6 +1276,58 @@ function PickToggle({
|
|
|
1236
1276
|
}
|
|
1237
1277
|
);
|
|
1238
1278
|
}
|
|
1279
|
+
function PickBar({
|
|
1280
|
+
paused,
|
|
1281
|
+
onToggle,
|
|
1282
|
+
onTogglePause
|
|
1283
|
+
}) {
|
|
1284
|
+
return /* @__PURE__ */ jsxs(
|
|
1285
|
+
"div",
|
|
1286
|
+
{
|
|
1287
|
+
style: {
|
|
1288
|
+
position: "fixed",
|
|
1289
|
+
top: 16,
|
|
1290
|
+
left: "50%",
|
|
1291
|
+
transform: "translateX(-50%)",
|
|
1292
|
+
display: "flex",
|
|
1293
|
+
alignItems: "stretch",
|
|
1294
|
+
gap: 8,
|
|
1295
|
+
// 오버레이 자체는 클릭을 통과시킨다(pointerEvents:none) — 이 막대만 되살린다.
|
|
1296
|
+
pointerEvents: "auto",
|
|
1297
|
+
padding: 6,
|
|
1298
|
+
borderRadius: 12,
|
|
1299
|
+
background: TOKENS.surface,
|
|
1300
|
+
boxShadow: TOKENS.shadow
|
|
1301
|
+
},
|
|
1302
|
+
children: [
|
|
1303
|
+
/* @__PURE__ */ jsx(PickToggle, { variant: "floating", active: true, paused, onToggle }),
|
|
1304
|
+
/* @__PURE__ */ jsxs(
|
|
1305
|
+
"button",
|
|
1306
|
+
{
|
|
1307
|
+
type: "button",
|
|
1308
|
+
"aria-pressed": paused,
|
|
1309
|
+
"data-fk-pick-pause": paused ? "paused" : "running",
|
|
1310
|
+
onClick: onTogglePause,
|
|
1311
|
+
style: {
|
|
1312
|
+
...baseButton,
|
|
1313
|
+
display: "inline-flex",
|
|
1314
|
+
alignItems: "center",
|
|
1315
|
+
gap: 6,
|
|
1316
|
+
whiteSpace: "nowrap",
|
|
1317
|
+
borderColor: paused ? TOKENS.accent : TOKENS.line,
|
|
1318
|
+
color: paused ? TOKENS.accent : TOKENS.ink,
|
|
1319
|
+
fontWeight: 600
|
|
1320
|
+
},
|
|
1321
|
+
children: [
|
|
1322
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: paused ? "\u25B6" : "\u23F8" }),
|
|
1323
|
+
paused ? "\uC9C0\uBAA9 \uC7AC\uAC1C" : "\uC7A0\uC2DC \uBA48\uCDA4"
|
|
1324
|
+
]
|
|
1325
|
+
}
|
|
1326
|
+
)
|
|
1327
|
+
]
|
|
1328
|
+
}
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
1239
1331
|
function MarkerStatus({ status }) {
|
|
1240
1332
|
const presentation = status === "sending" ? { icon: "\u21BB", text: "\uC804\uC1A1 \uC911", color: TOKENS.accent } : status === "done" ? { icon: "\u2713", text: "\uC644\uB8CC", color: TOKENS.success } : { icon: "\u25F7", text: "\uB300\uAE30", color: TOKENS.warning };
|
|
1241
1333
|
return /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", gap: 4, alignItems: "center", color: presentation.color }, children: [
|
|
@@ -1259,47 +1351,7 @@ function HintChips({
|
|
|
1259
1351
|
onToggle
|
|
1260
1352
|
}) {
|
|
1261
1353
|
return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
|
|
1262
|
-
|
|
1263
|
-
/* @__PURE__ */ jsx("p", { style: { margin: "0 0 7px", color: TOKENS.muted, fontSize: 12 }, children: "\uC774\uB7F0 \uAC74\uAC00\uC694?" }),
|
|
1264
|
-
/* @__PURE__ */ jsx(
|
|
1265
|
-
"div",
|
|
1266
|
-
{
|
|
1267
|
-
role: "group",
|
|
1268
|
-
"aria-label": "\uC790\uC8FC \uB098\uC624\uB294 \uC81C\uBCF4 \uC81C\uC548",
|
|
1269
|
-
style: { display: "flex", flexWrap: "wrap", gap: 6, marginBottom: 7 },
|
|
1270
|
-
children: hints.map((hint) => {
|
|
1271
|
-
const used = usedHintIds.includes(hint.id);
|
|
1272
|
-
return /* @__PURE__ */ jsx(
|
|
1273
|
-
"button",
|
|
1274
|
-
{
|
|
1275
|
-
type: "button",
|
|
1276
|
-
"data-fk-focus-id": `hint:${hint.id}`,
|
|
1277
|
-
disabled: used || disabled,
|
|
1278
|
-
"aria-pressed": used,
|
|
1279
|
-
onClick: () => onApply(hint.id),
|
|
1280
|
-
style: {
|
|
1281
|
-
...baseButton,
|
|
1282
|
-
minHeight: 30,
|
|
1283
|
-
padding: "5px 10px",
|
|
1284
|
-
fontSize: 12,
|
|
1285
|
-
fontWeight: 600,
|
|
1286
|
-
borderRadius: 999,
|
|
1287
|
-
...used ? {
|
|
1288
|
-
background: TOKENS.subtle,
|
|
1289
|
-
color: TOKENS.muted,
|
|
1290
|
-
borderColor: TOKENS.line,
|
|
1291
|
-
cursor: "default"
|
|
1292
|
-
} : {}
|
|
1293
|
-
},
|
|
1294
|
-
children: hint.label
|
|
1295
|
-
},
|
|
1296
|
-
hint.id
|
|
1297
|
-
);
|
|
1298
|
-
})
|
|
1299
|
-
}
|
|
1300
|
-
)
|
|
1301
|
-
] }) : null,
|
|
1302
|
-
/* @__PURE__ */ jsx(
|
|
1354
|
+
/* @__PURE__ */ jsxs(
|
|
1303
1355
|
"button",
|
|
1304
1356
|
{
|
|
1305
1357
|
type: "button",
|
|
@@ -1307,10 +1359,61 @@ function HintChips({
|
|
|
1307
1359
|
"aria-expanded": hintsExpanded,
|
|
1308
1360
|
disabled,
|
|
1309
1361
|
onClick: onToggle,
|
|
1310
|
-
style: {
|
|
1311
|
-
|
|
1362
|
+
style: {
|
|
1363
|
+
display: "block",
|
|
1364
|
+
margin: "0 0 7px",
|
|
1365
|
+
padding: 0,
|
|
1366
|
+
border: "none",
|
|
1367
|
+
background: "none",
|
|
1368
|
+
font: "inherit",
|
|
1369
|
+
fontSize: 12,
|
|
1370
|
+
color: TOKENS.muted,
|
|
1371
|
+
cursor: disabled ? "default" : "pointer",
|
|
1372
|
+
textAlign: "left"
|
|
1373
|
+
},
|
|
1374
|
+
children: [
|
|
1375
|
+
"\uC774\uB7F0 \uAC74\uAC00\uC694? ",
|
|
1376
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: hintsExpanded ? "\u25B4" : "\u25BE" })
|
|
1377
|
+
]
|
|
1312
1378
|
}
|
|
1313
|
-
)
|
|
1379
|
+
),
|
|
1380
|
+
hintsExpanded ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
1381
|
+
"div",
|
|
1382
|
+
{
|
|
1383
|
+
role: "group",
|
|
1384
|
+
"aria-label": "\uC790\uC8FC \uB098\uC624\uB294 \uC81C\uBCF4 \uC81C\uC548",
|
|
1385
|
+
style: { display: "flex", flexWrap: "wrap", gap: 6, marginBottom: 7 },
|
|
1386
|
+
children: hints.map((hint) => {
|
|
1387
|
+
const used = usedHintIds.includes(hint.id);
|
|
1388
|
+
return /* @__PURE__ */ jsx(
|
|
1389
|
+
"button",
|
|
1390
|
+
{
|
|
1391
|
+
type: "button",
|
|
1392
|
+
"data-fk-focus-id": `hint:${hint.id}`,
|
|
1393
|
+
disabled: used || disabled,
|
|
1394
|
+
"aria-pressed": used,
|
|
1395
|
+
onClick: () => onApply(hint.id),
|
|
1396
|
+
style: {
|
|
1397
|
+
...baseButton,
|
|
1398
|
+
minHeight: 30,
|
|
1399
|
+
padding: "5px 10px",
|
|
1400
|
+
fontSize: 12,
|
|
1401
|
+
fontWeight: 600,
|
|
1402
|
+
borderRadius: 999,
|
|
1403
|
+
...used ? {
|
|
1404
|
+
background: TOKENS.subtle,
|
|
1405
|
+
color: TOKENS.muted,
|
|
1406
|
+
borderColor: TOKENS.line,
|
|
1407
|
+
cursor: "default"
|
|
1408
|
+
} : {}
|
|
1409
|
+
},
|
|
1410
|
+
children: hint.label
|
|
1411
|
+
},
|
|
1412
|
+
hint.id
|
|
1413
|
+
);
|
|
1414
|
+
})
|
|
1415
|
+
}
|
|
1416
|
+
) }) : null
|
|
1314
1417
|
] });
|
|
1315
1418
|
}
|
|
1316
1419
|
function FeedbackKit(props) {
|
|
@@ -1629,6 +1732,7 @@ function FeedbackKit(props) {
|
|
|
1629
1732
|
{
|
|
1630
1733
|
variant: "inline",
|
|
1631
1734
|
active: pickingActive,
|
|
1735
|
+
paused: pickingState.paused,
|
|
1632
1736
|
disabled: draftLocked,
|
|
1633
1737
|
focusId: MODAL_ACTION_PICK,
|
|
1634
1738
|
onToggle: togglePicking
|
|
@@ -1880,7 +1984,14 @@ function FeedbackKit(props) {
|
|
|
1880
1984
|
}
|
|
1881
1985
|
}
|
|
1882
1986
|
) : null,
|
|
1883
|
-
/* @__PURE__ */ jsx(
|
|
1987
|
+
/* @__PURE__ */ jsx(
|
|
1988
|
+
PickBar,
|
|
1989
|
+
{
|
|
1990
|
+
paused: pickingState.paused,
|
|
1991
|
+
onToggle: togglePicking,
|
|
1992
|
+
onTogglePause: () => activeKit.picking.togglePause()
|
|
1993
|
+
}
|
|
1994
|
+
),
|
|
1884
1995
|
pickingState.markers.map((marker, index) => /* @__PURE__ */ jsx(
|
|
1885
1996
|
"div",
|
|
1886
1997
|
{
|