@solhun/feedback-kit-web 0.2.3 → 0.4.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 +322 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -3
- package/dist/index.d.ts +58 -3
- package/dist/index.js +327 -60
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ElementInfo, FeedbackPin, FeedbackReport, SubmitOutcome, QueueStatus, ReportParts, ScreenshotCapture, ScreenshotReencode, WidgetControllerOpts, WidgetController, FeedbackStorage, ContextProviders } from '@solhun/feedback-kit-core';
|
|
1
|
+
import { ElementInfo, FeedbackPin, FeedbackScreenshot, FeedbackReport, SubmitOutcome, QueueStatus, ReportParts, ScreenshotCapture, ScreenshotReencode, WidgetControllerOpts, WidgetController, FeedbackStorage, ContextProviders } from '@solhun/feedback-kit-core';
|
|
2
2
|
export { COMMENT_MAX_CHARS, COMMENT_REQUIRED_MESSAGE, COMMENT_TOO_LONG_MESSAGE, ElementInfo, FLOATING_BUTTON_ID, FeedbackAdapter, FeedbackConfig, FeedbackContext, FeedbackPin, FeedbackReport, FeedbackStorage, FeedbackUser, MODAL_ACTION_PICK, ModalSubmitStatus, ReportModalController, ReportModalState, ResolvedConfig, SCREENSHOT_FAILED_MESSAGE, SOURCE_ATTR, SUBMIT_DONE_MESSAGE, SUBMIT_PENDING_MESSAGE, ScreenshotStatus, SubmitResult, Visibility, VisibilityEnv, VisibilityFn, WidgetController, WidgetPosition, WidgetScreen, WidgetState, denormalizePin, normalizePin, parseSourceAttr, resolveConfig, shouldShowWidget, sourceFromElement } from '@solhun/feedback-kit-core';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
|
|
@@ -76,12 +76,26 @@ interface PickingQueueLike {
|
|
|
76
76
|
subscribe?(listener: (status: QueueStatus) => void): () => void;
|
|
77
77
|
getOutcome?(clientSubmissionId: string): Pick<SubmitOutcome, "delivered" | "id"> | null;
|
|
78
78
|
}
|
|
79
|
+
/** 퀵 주석의 스크린샷 상태. 모달과 같은 어휘를 쓴다(렌더러가 둘을 같은 방식으로 그린다). */
|
|
80
|
+
type AnnotationShotStatus = "none" | "capturing" | "ready" | "failed";
|
|
79
81
|
interface AnnotationPopupState {
|
|
80
82
|
element: ElementInfo | null;
|
|
81
83
|
/** 클릭한 지점의 뷰포트 상대 좌표(0~1). */
|
|
82
84
|
point: FeedbackPin;
|
|
83
85
|
comment: string;
|
|
84
86
|
canSave: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* 이 주석에 실려 갈 그림. 클릭 직후 자동 캡처가 채우고, 사용자가 붙여넣기(Cmd+V)나
|
|
89
|
+
* 드래그로 덮을 수 있다.
|
|
90
|
+
*
|
|
91
|
+
* 왜 퀵 주석에도 그림을 싣나: 이게 없으면 **들어온 문에 따라 정보량이 달라진다.**
|
|
92
|
+
* 지목으로 남긴 제보만 화면 증거가 비는 일이 실제로 있었고(0.2.0), 그때 얻은 규칙이
|
|
93
|
+
* "같은 제보는 어느 문으로 들어와도 같은 것을 담는다" 다.
|
|
94
|
+
*/
|
|
95
|
+
screenshot: FeedbackScreenshot | null;
|
|
96
|
+
screenshotStatus: AnnotationShotStatus;
|
|
97
|
+
/** 저장 중인가. 두 번 눌러 같은 주석이 두 번 가는 것을 막는다. */
|
|
98
|
+
saving: boolean;
|
|
85
99
|
}
|
|
86
100
|
interface PickingState {
|
|
87
101
|
active: boolean;
|
|
@@ -106,8 +120,17 @@ interface ElementPickingOpts {
|
|
|
106
120
|
height: number;
|
|
107
121
|
};
|
|
108
122
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
123
|
+
* 퀵 주석에 붙일 자동 캡처. 없으면 그림 없이 코멘트만 받는다.
|
|
124
|
+
* 웹 기본 캡처는 위젯 자신의 UI 를 결과에서 빼므로(`ignoreElements`) 팝업이 찍히지 않는다.
|
|
125
|
+
*/
|
|
126
|
+
capture?: ScreenshotCapture | null;
|
|
127
|
+
reencode?: ScreenshotReencode | null;
|
|
128
|
+
screenshotLimitBytes?: number;
|
|
129
|
+
/**
|
|
130
|
+
* 요소를 고르면 호출된다. 주면 **퀵 주석 팝업 대신 이걸 부른다** —
|
|
131
|
+
* 호스트가 전체 리포트 모달을 열어 우선순위까지 받고 싶을 때의 탈출구다.
|
|
132
|
+
* 기본값은 팝업이다: 지목은 "클릭 → 한 줄 → Enter" 로 끝나는 게 목적이라,
|
|
133
|
+
* 매번 중앙 모달이 뜨면 흐름이 끊긴다.
|
|
111
134
|
*
|
|
112
135
|
* 모드는 켜진 채로 둔다. 한 번 켜고 여러 요소를 연달아 지목하는 게 이 모드의 목적이라,
|
|
113
136
|
* 요소 하나 고를 때마다 모드가 꺼지면 매번 다시 켜야 한다.
|
|
@@ -122,6 +145,9 @@ declare class ElementPickingController {
|
|
|
122
145
|
private readonly getPathname;
|
|
123
146
|
private readonly doc;
|
|
124
147
|
private readonly getViewport;
|
|
148
|
+
private readonly capture;
|
|
149
|
+
private readonly reencode;
|
|
150
|
+
private readonly screenshotLimitBytes;
|
|
125
151
|
private readonly unsubscribeQueue;
|
|
126
152
|
private readonly listeners;
|
|
127
153
|
private active;
|
|
@@ -132,6 +158,10 @@ declare class ElementPickingController {
|
|
|
132
158
|
private pathWatch;
|
|
133
159
|
private lastPathname;
|
|
134
160
|
private saving;
|
|
161
|
+
/** 늦게 끝난 캡처가 다음 주석의 그림을 덮지 못하게 하는 세대 번호. */
|
|
162
|
+
private shotGeneration;
|
|
163
|
+
/** 지금 도는 자동 캡처. Enter 가 캡처보다 빨랐을 때 기다릴 대상. */
|
|
164
|
+
private capturing;
|
|
135
165
|
private readonly onClick;
|
|
136
166
|
private readonly onMouseOver;
|
|
137
167
|
constructor(opts: ElementPickingOpts);
|
|
@@ -159,8 +189,21 @@ declare class ElementPickingController {
|
|
|
159
189
|
y: number;
|
|
160
190
|
}): void;
|
|
161
191
|
setAnnotationComment(value: string): void;
|
|
192
|
+
/**
|
|
193
|
+
* 사용자가 붙여넣기(Cmd+V)나 드래그로 넣은 그림. 자동 캡처 결과를 덮는다.
|
|
194
|
+
*
|
|
195
|
+
* 자동 캡처보다 이게 우선인 이유: 사용자가 굳이 그림을 붙였다면 그건 "지금 화면"이
|
|
196
|
+
* 아니라 **보여주고 싶은 다른 것**이다(잘라낸 부분, 다른 탭, 기대하는 디자인).
|
|
197
|
+
*/
|
|
198
|
+
attachAnnotationImage(shot: FeedbackScreenshot): Promise<void>;
|
|
199
|
+
/** 그림만 뗀다. 코멘트는 그대로 — 그림이 없어도 주석은 성립한다. */
|
|
200
|
+
removeAnnotationImage(): void;
|
|
162
201
|
/** 취소 — 마커도 제보도 남기지 않는다. 모드는 켜진 채로 둔다. */
|
|
163
202
|
cancelAnnotation(): void;
|
|
203
|
+
private isSavable;
|
|
204
|
+
/** 도는 캡처가 있으면 끝나기를 기다린다. 캡처가 던져도 저장을 막지 않는다. */
|
|
205
|
+
private settleCapture;
|
|
206
|
+
private runCapture;
|
|
164
207
|
/**
|
|
165
208
|
* 제출된 제보를 마커로 남긴다. 모달 경로에서 쓴다 — 마커 생성이 팝업 저장 안에만
|
|
166
209
|
* 있으면, 리포트 모달로 보낸 지목 제보는 화면에 흔적이 남지 않는다("보냈는지 알 수
|
|
@@ -202,6 +245,16 @@ declare function reactComponentPath(node: Element, limit?: number): string[];
|
|
|
202
245
|
/** 제보 본문에 실을 한 줄. 컴포넌트를 못 찾으면 null(빈 줄을 만들지 않는다). */
|
|
203
246
|
declare function reactComponentSummary(node: Element): string | null;
|
|
204
247
|
|
|
248
|
+
/**
|
|
249
|
+
* 요소를 고른 뒤 무엇을 띄우는가.
|
|
250
|
+
*
|
|
251
|
+
* - `popup`(기본): 클릭한 자리에 **한 줄 입력창**. Enter 로 바로 보낸다.
|
|
252
|
+
* - `modal`: 화면 중앙의 전체 리포트 모달(우선순위까지 고른다).
|
|
253
|
+
*
|
|
254
|
+
* 기본이 팝업인 이유: 지목은 "여기 이거요" 를 여러 곳에 연달아 남기는 작업이다.
|
|
255
|
+
* 클릭마다 중앙 모달이 뜨면 시선이 클릭 지점을 떠나고, 어디를 가리켰는지 잊는다.
|
|
256
|
+
*/
|
|
257
|
+
type PickTarget = "popup" | "modal";
|
|
205
258
|
interface WebWidgetOpts extends Omit<WidgetControllerOpts, "platform" | "initialPicking" | "onPickingChange"> {
|
|
206
259
|
/** 지목 모드 플래그와 마커를 담아 둘 저장소. 기본은 `localStorage`. */
|
|
207
260
|
store?: MarkerStore;
|
|
@@ -213,6 +266,8 @@ interface WebWidgetOpts extends Omit<WidgetControllerOpts, "platform" | "initial
|
|
|
213
266
|
width: number;
|
|
214
267
|
height: number;
|
|
215
268
|
};
|
|
269
|
+
/** 요소를 고른 뒤 띄울 UI. 기본은 `popup`. */
|
|
270
|
+
pickTarget?: PickTarget;
|
|
216
271
|
}
|
|
217
272
|
interface WebWidget {
|
|
218
273
|
widget: WidgetController;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ElementInfo, FeedbackPin, FeedbackReport, SubmitOutcome, QueueStatus, ReportParts, ScreenshotCapture, ScreenshotReencode, WidgetControllerOpts, WidgetController, FeedbackStorage, ContextProviders } from '@solhun/feedback-kit-core';
|
|
1
|
+
import { ElementInfo, FeedbackPin, FeedbackScreenshot, FeedbackReport, SubmitOutcome, QueueStatus, ReportParts, ScreenshotCapture, ScreenshotReencode, WidgetControllerOpts, WidgetController, FeedbackStorage, ContextProviders } from '@solhun/feedback-kit-core';
|
|
2
2
|
export { COMMENT_MAX_CHARS, COMMENT_REQUIRED_MESSAGE, COMMENT_TOO_LONG_MESSAGE, ElementInfo, FLOATING_BUTTON_ID, FeedbackAdapter, FeedbackConfig, FeedbackContext, FeedbackPin, FeedbackReport, FeedbackStorage, FeedbackUser, MODAL_ACTION_PICK, ModalSubmitStatus, ReportModalController, ReportModalState, ResolvedConfig, SCREENSHOT_FAILED_MESSAGE, SOURCE_ATTR, SUBMIT_DONE_MESSAGE, SUBMIT_PENDING_MESSAGE, ScreenshotStatus, SubmitResult, Visibility, VisibilityEnv, VisibilityFn, WidgetController, WidgetPosition, WidgetScreen, WidgetState, denormalizePin, normalizePin, parseSourceAttr, resolveConfig, shouldShowWidget, sourceFromElement } from '@solhun/feedback-kit-core';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
|
|
@@ -76,12 +76,26 @@ interface PickingQueueLike {
|
|
|
76
76
|
subscribe?(listener: (status: QueueStatus) => void): () => void;
|
|
77
77
|
getOutcome?(clientSubmissionId: string): Pick<SubmitOutcome, "delivered" | "id"> | null;
|
|
78
78
|
}
|
|
79
|
+
/** 퀵 주석의 스크린샷 상태. 모달과 같은 어휘를 쓴다(렌더러가 둘을 같은 방식으로 그린다). */
|
|
80
|
+
type AnnotationShotStatus = "none" | "capturing" | "ready" | "failed";
|
|
79
81
|
interface AnnotationPopupState {
|
|
80
82
|
element: ElementInfo | null;
|
|
81
83
|
/** 클릭한 지점의 뷰포트 상대 좌표(0~1). */
|
|
82
84
|
point: FeedbackPin;
|
|
83
85
|
comment: string;
|
|
84
86
|
canSave: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* 이 주석에 실려 갈 그림. 클릭 직후 자동 캡처가 채우고, 사용자가 붙여넣기(Cmd+V)나
|
|
89
|
+
* 드래그로 덮을 수 있다.
|
|
90
|
+
*
|
|
91
|
+
* 왜 퀵 주석에도 그림을 싣나: 이게 없으면 **들어온 문에 따라 정보량이 달라진다.**
|
|
92
|
+
* 지목으로 남긴 제보만 화면 증거가 비는 일이 실제로 있었고(0.2.0), 그때 얻은 규칙이
|
|
93
|
+
* "같은 제보는 어느 문으로 들어와도 같은 것을 담는다" 다.
|
|
94
|
+
*/
|
|
95
|
+
screenshot: FeedbackScreenshot | null;
|
|
96
|
+
screenshotStatus: AnnotationShotStatus;
|
|
97
|
+
/** 저장 중인가. 두 번 눌러 같은 주석이 두 번 가는 것을 막는다. */
|
|
98
|
+
saving: boolean;
|
|
85
99
|
}
|
|
86
100
|
interface PickingState {
|
|
87
101
|
active: boolean;
|
|
@@ -106,8 +120,17 @@ interface ElementPickingOpts {
|
|
|
106
120
|
height: number;
|
|
107
121
|
};
|
|
108
122
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
123
|
+
* 퀵 주석에 붙일 자동 캡처. 없으면 그림 없이 코멘트만 받는다.
|
|
124
|
+
* 웹 기본 캡처는 위젯 자신의 UI 를 결과에서 빼므로(`ignoreElements`) 팝업이 찍히지 않는다.
|
|
125
|
+
*/
|
|
126
|
+
capture?: ScreenshotCapture | null;
|
|
127
|
+
reencode?: ScreenshotReencode | null;
|
|
128
|
+
screenshotLimitBytes?: number;
|
|
129
|
+
/**
|
|
130
|
+
* 요소를 고르면 호출된다. 주면 **퀵 주석 팝업 대신 이걸 부른다** —
|
|
131
|
+
* 호스트가 전체 리포트 모달을 열어 우선순위까지 받고 싶을 때의 탈출구다.
|
|
132
|
+
* 기본값은 팝업이다: 지목은 "클릭 → 한 줄 → Enter" 로 끝나는 게 목적이라,
|
|
133
|
+
* 매번 중앙 모달이 뜨면 흐름이 끊긴다.
|
|
111
134
|
*
|
|
112
135
|
* 모드는 켜진 채로 둔다. 한 번 켜고 여러 요소를 연달아 지목하는 게 이 모드의 목적이라,
|
|
113
136
|
* 요소 하나 고를 때마다 모드가 꺼지면 매번 다시 켜야 한다.
|
|
@@ -122,6 +145,9 @@ declare class ElementPickingController {
|
|
|
122
145
|
private readonly getPathname;
|
|
123
146
|
private readonly doc;
|
|
124
147
|
private readonly getViewport;
|
|
148
|
+
private readonly capture;
|
|
149
|
+
private readonly reencode;
|
|
150
|
+
private readonly screenshotLimitBytes;
|
|
125
151
|
private readonly unsubscribeQueue;
|
|
126
152
|
private readonly listeners;
|
|
127
153
|
private active;
|
|
@@ -132,6 +158,10 @@ declare class ElementPickingController {
|
|
|
132
158
|
private pathWatch;
|
|
133
159
|
private lastPathname;
|
|
134
160
|
private saving;
|
|
161
|
+
/** 늦게 끝난 캡처가 다음 주석의 그림을 덮지 못하게 하는 세대 번호. */
|
|
162
|
+
private shotGeneration;
|
|
163
|
+
/** 지금 도는 자동 캡처. Enter 가 캡처보다 빨랐을 때 기다릴 대상. */
|
|
164
|
+
private capturing;
|
|
135
165
|
private readonly onClick;
|
|
136
166
|
private readonly onMouseOver;
|
|
137
167
|
constructor(opts: ElementPickingOpts);
|
|
@@ -159,8 +189,21 @@ declare class ElementPickingController {
|
|
|
159
189
|
y: number;
|
|
160
190
|
}): void;
|
|
161
191
|
setAnnotationComment(value: string): void;
|
|
192
|
+
/**
|
|
193
|
+
* 사용자가 붙여넣기(Cmd+V)나 드래그로 넣은 그림. 자동 캡처 결과를 덮는다.
|
|
194
|
+
*
|
|
195
|
+
* 자동 캡처보다 이게 우선인 이유: 사용자가 굳이 그림을 붙였다면 그건 "지금 화면"이
|
|
196
|
+
* 아니라 **보여주고 싶은 다른 것**이다(잘라낸 부분, 다른 탭, 기대하는 디자인).
|
|
197
|
+
*/
|
|
198
|
+
attachAnnotationImage(shot: FeedbackScreenshot): Promise<void>;
|
|
199
|
+
/** 그림만 뗀다. 코멘트는 그대로 — 그림이 없어도 주석은 성립한다. */
|
|
200
|
+
removeAnnotationImage(): void;
|
|
162
201
|
/** 취소 — 마커도 제보도 남기지 않는다. 모드는 켜진 채로 둔다. */
|
|
163
202
|
cancelAnnotation(): void;
|
|
203
|
+
private isSavable;
|
|
204
|
+
/** 도는 캡처가 있으면 끝나기를 기다린다. 캡처가 던져도 저장을 막지 않는다. */
|
|
205
|
+
private settleCapture;
|
|
206
|
+
private runCapture;
|
|
164
207
|
/**
|
|
165
208
|
* 제출된 제보를 마커로 남긴다. 모달 경로에서 쓴다 — 마커 생성이 팝업 저장 안에만
|
|
166
209
|
* 있으면, 리포트 모달로 보낸 지목 제보는 화면에 흔적이 남지 않는다("보냈는지 알 수
|
|
@@ -202,6 +245,16 @@ declare function reactComponentPath(node: Element, limit?: number): string[];
|
|
|
202
245
|
/** 제보 본문에 실을 한 줄. 컴포넌트를 못 찾으면 null(빈 줄을 만들지 않는다). */
|
|
203
246
|
declare function reactComponentSummary(node: Element): string | null;
|
|
204
247
|
|
|
248
|
+
/**
|
|
249
|
+
* 요소를 고른 뒤 무엇을 띄우는가.
|
|
250
|
+
*
|
|
251
|
+
* - `popup`(기본): 클릭한 자리에 **한 줄 입력창**. Enter 로 바로 보낸다.
|
|
252
|
+
* - `modal`: 화면 중앙의 전체 리포트 모달(우선순위까지 고른다).
|
|
253
|
+
*
|
|
254
|
+
* 기본이 팝업인 이유: 지목은 "여기 이거요" 를 여러 곳에 연달아 남기는 작업이다.
|
|
255
|
+
* 클릭마다 중앙 모달이 뜨면 시선이 클릭 지점을 떠나고, 어디를 가리켰는지 잊는다.
|
|
256
|
+
*/
|
|
257
|
+
type PickTarget = "popup" | "modal";
|
|
205
258
|
interface WebWidgetOpts extends Omit<WidgetControllerOpts, "platform" | "initialPicking" | "onPickingChange"> {
|
|
206
259
|
/** 지목 모드 플래그와 마커를 담아 둘 저장소. 기본은 `localStorage`. */
|
|
207
260
|
store?: MarkerStore;
|
|
@@ -213,6 +266,8 @@ interface WebWidgetOpts extends Omit<WidgetControllerOpts, "platform" | "initial
|
|
|
213
266
|
width: number;
|
|
214
267
|
height: number;
|
|
215
268
|
};
|
|
269
|
+
/** 요소를 고른 뒤 띄울 UI. 기본은 `popup`. */
|
|
270
|
+
pickTarget?: PickTarget;
|
|
216
271
|
}
|
|
217
272
|
interface WebWidget {
|
|
218
273
|
widget: WidgetController;
|