hocmai-feedback-widget 0.2.2 → 0.2.4
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/LICENSE +21 -0
- package/README.md +105 -124
- package/dist/components/FeedbackWidget.d.ts +2 -1
- package/dist/context/FeedbackContext.d.ts +15 -2
- package/dist/hocmai-feedback-widget.mjs +972 -959
- package/dist/hocmai-feedback-widget.mjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/package.json +12 -4
- package/src/App.tsx +5 -1
- package/src/capture/index.ts +15 -16
- package/src/components/FeedbackWidget.tsx +16 -9
- package/src/context/FeedbackContext.tsx +50 -5
- package/src/index.ts +1 -0
- package/src/main.tsx +5 -6
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 HOCMAI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,136 +1,77 @@
|
|
|
1
1
|
# hocmai-feedback-widget
|
|
2
2
|
|
|
3
|
-
Widget
|
|
3
|
+
> Widget báo lỗi câu hỏi kèm chụp ảnh màn hình, tối ưu cho trang nhiều công thức **MathJax CHTML**.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
Bộ chụp dùng [snapdom](https://github.com/zumerlab/snapdom) + nhúng font MathJax → chụp nhanh, đủ công thức ngay lần đầu, an toàn SSR.
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
`getBoundingClientRect()` (treo khi có hàng nghìn node `<mjx-*>`) và chỉ render được math dạng **SVG**.
|
|
11
|
-
Nhưng app render công thức bằng **MathJax v3 CHTML** (HTML + web-font riêng) nên ảnh bị **treo** và
|
|
12
|
-
**trắng / mất công thức**.
|
|
12
|
+
## Mục lục
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
- [Tính năng](#tính-năng)
|
|
15
|
+
- [Cài đặt](#cài-đặt)
|
|
16
|
+
- [Sử dụng](#sử-dụng)
|
|
17
|
+
- [API](#api)
|
|
18
|
+
- [Lưu ý](#lưu-ý)
|
|
19
|
+
- [License](#license)
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
- **
|
|
21
|
+
## Tính năng
|
|
22
|
+
|
|
23
|
+
- 📸 Chụp **toàn màn hình** hoặc **chọn vùng**, render đúng công thức MathJax CHTML.
|
|
24
|
+
- 📝 Mô tả lỗi bằng **textarea** hoặc **CKEditor** (tùy chọn).
|
|
25
|
+
- 🖼️ Tự upload ảnh và trả về URL (tối đa 3 ảnh).
|
|
26
|
+
- 🔌 API gọn: `FeedbackProvider` + hook `useFeedback`.
|
|
27
|
+
- 🧩 Core **không** phụ thuộc CKEditor — chỉ cài khi cần.
|
|
20
28
|
|
|
21
29
|
## Cài đặt
|
|
22
30
|
|
|
23
31
|
```bash
|
|
24
32
|
npm install hocmai-feedback-widget
|
|
25
|
-
# hoặc
|
|
26
|
-
yarn add hocmai-feedback-widget
|
|
27
33
|
```
|
|
28
34
|
|
|
29
|
-
Peer
|
|
30
|
-
|
|
31
|
-
Peer deps **tùy chọn** (chỉ khi dùng `isCkEditor`, xem mục [CKEditor](#trình-soạn-thảo-ckeditor-isckeditor)):
|
|
32
|
-
`@ckeditor/ckeditor5-react@^41.2.0`, `hocmai-ckeditor-custom`, `ckeditor5-classic-with-mathtype@1.0.0`.
|
|
35
|
+
**Peer dependencies:** `react`, `react-dom` (>= 16.8).
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
## Dùng nhanh
|
|
37
|
+
## Sử dụng
|
|
37
38
|
|
|
38
39
|
### 1. Bọc app bằng `FeedbackProvider`
|
|
40
|
+
|
|
39
41
|
```tsx
|
|
40
42
|
import { FeedbackProvider, type FeedbackData } from 'hocmai-feedback-widget';
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
<FeedbackProvider
|
|
45
|
+
onSubmit={async (data: FeedbackData) => {
|
|
44
46
|
// data.listImage: mảng URL ảnh đã upload
|
|
45
|
-
// data.deviceInfo, data.errorType, data.errorDescription, data.idQuestion...
|
|
46
47
|
await api.post('/questionReport/studentReport', data);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<Component {...pageProps} />
|
|
52
|
-
</FeedbackProvider>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
<App />
|
|
51
|
+
</FeedbackProvider>;
|
|
55
52
|
```
|
|
56
53
|
|
|
54
|
+
> `onSubmit` **không bắt buộc** ở Provider — có thể truyền theo từng lần ở `openFeedback` (xem mục 2).
|
|
55
|
+
|
|
57
56
|
### 2. Mở form từ component con bằng `useFeedback`
|
|
57
|
+
|
|
58
58
|
```tsx
|
|
59
59
|
import { useFeedback } from 'hocmai-feedback-widget';
|
|
60
60
|
|
|
61
|
-
const
|
|
62
|
-
const { openFeedback } = useFeedback();
|
|
63
|
-
return (
|
|
64
|
-
<button onClick={() => openFeedback(question.id, { questionIdChild: question.childId })}>
|
|
65
|
-
Báo lỗi
|
|
66
|
-
</button>
|
|
67
|
-
);
|
|
68
|
-
};
|
|
69
|
-
```
|
|
61
|
+
const { openFeedback } = useFeedback();
|
|
70
62
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
import { captureScreenshot, captureScreenshotWithOptions } from 'hocmai-feedback-widget';
|
|
63
|
+
// a) Dùng onSubmit của Provider:
|
|
64
|
+
openFeedback(questionId, { questionIdChild });
|
|
74
65
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
// b) Hoặc truyền handler riêng cho lần gọi này (ghi đè Provider):
|
|
67
|
+
openFeedback(questionId, { questionIdChild }, async (data) => {
|
|
68
|
+
await api.post('/questionReport/studentReport', data);
|
|
69
|
+
});
|
|
78
70
|
```
|
|
79
71
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
### `FeedbackProvider`
|
|
83
|
-
| Prop | Kiểu | Mặc định | Mô tả |
|
|
84
|
-
|------|------|----------|-------|
|
|
85
|
-
| `onSubmit` | `(data: FeedbackData) => Promise<void>` | (bắt buộc) | Gọi khi gửi báo lỗi. |
|
|
86
|
-
| `themeColor` | `string` | `#3b82f6` | Màu chủ đạo nút/viền. |
|
|
87
|
-
| `isCkEditor` | `boolean` | `false` | Dùng CKEditor (rich-text) cho ô mô tả thay vì textarea. |
|
|
88
|
-
| `children` | `ReactNode` | — | Nội dung app. |
|
|
89
|
-
|
|
90
|
-
### `useFeedback()`
|
|
91
|
-
- `openFeedback(questionId, contextData?)` — mở form. `contextData.questionIdChild` sẽ tự điền ô "ID câu hỏi con".
|
|
92
|
-
- `closeFeedback()` — đóng form.
|
|
93
|
-
- `isOpen`, `activeQuestionId` — trạng thái hiện tại.
|
|
94
|
-
|
|
95
|
-
### `FeedbackData`
|
|
96
|
-
```ts
|
|
97
|
-
interface FeedbackData {
|
|
98
|
-
idQuestion: string | number;
|
|
99
|
-
idChildQuestion?: string | number;
|
|
100
|
-
errorType: string; // incorrect_content | display_error | missing_data | technical_issue | other
|
|
101
|
-
errorDescription: string; // text; là HTML nếu bật isCkEditor
|
|
102
|
-
listImage: string[]; // URL ảnh đã upload (tối đa 3)
|
|
103
|
-
deviceInfo: { os; osVersion; browser; browserVersion; deviceType };
|
|
104
|
-
contextData?: any;
|
|
105
|
-
}
|
|
106
|
-
```
|
|
72
|
+
### 3. Rich-text editor cho ô mô tả _(tùy chọn)_
|
|
107
73
|
|
|
108
|
-
|
|
109
|
-
| Prop | Kiểu | Mặc định | Mô tả |
|
|
110
|
-
|------|------|----------|-------|
|
|
111
|
-
| `questionId` | `string \| number` | (bắt buộc) | ID câu hỏi. |
|
|
112
|
-
| `onSubmit` | `function` | (bắt buộc) | Nhận `FeedbackData`. |
|
|
113
|
-
| `contextData` | `object` | — | Dữ liệu kèm theo (vd `questionIdChild`). |
|
|
114
|
-
| `themeColor` | `string` | `#3b82f6` | Màu chủ đạo. |
|
|
115
|
-
| `isOpen` / `onClose` / `onOpen` | — | — | Điều khiển hiển thị thủ công. |
|
|
116
|
-
| `isEnableCaptureFull` | `boolean` | `true` | Bật nút "Toàn màn hình". |
|
|
117
|
-
| `isEnableCaptureElement` | `boolean` | `true` | Bật nút "Chọn vùng". |
|
|
118
|
-
| `isCkEditor` | `boolean` | `false` | Dùng CKEditor cho ô mô tả. |
|
|
119
|
-
| `uploadUrl` | `string` | endpoint LCMS mặc định | Nơi upload ảnh `{ base64 }` → trả `{ file_url }`. |
|
|
120
|
-
|
|
121
|
-
### Tiện ích chụp
|
|
122
|
-
- `captureScreenshot(cropRect?, onProgress?) => Promise<string | null>` — trả PNG data-URL (hoặc `null` nếu thất bại).
|
|
123
|
-
- `captureScreenshotWithOptions(cropRect, options)` — `options`: `{ scale?, backgroundColor?, timeoutMs?, excludeSelectors?, onProgress? }`.
|
|
124
|
-
- `prewarmCapture()` — hâm nóng font/cache (tự gọi khi form mở).
|
|
125
|
-
- Types: `Rect`, `CaptureProgress`, `CaptureOptions`.
|
|
126
|
-
|
|
127
|
-
## Trình soạn thảo CKEditor (`isCkEditor`)
|
|
128
|
-
|
|
129
|
-
Mặc định ô mô tả là textarea. Muốn dùng **CKEditor (kèm MathType)**, bật `isCkEditor` **và truyền component
|
|
130
|
-
editor** qua prop `descriptionEditor`. Editor nằm ở **entry phụ** `hocmai-feedback-widget/ckeditor`.
|
|
131
|
-
|
|
132
|
-
> Vì sao tách rời? Để **core widget không phụ thuộc CKEditor** — app không dùng CKEditor vẫn build bình
|
|
133
|
-
> thường, không cần cài deps CKEditor. Chỉ ai dùng `descriptionEditor` mới cần cài.
|
|
74
|
+
Bật `isCkEditor` **và** truyền `descriptionEditor` (editor đóng gói sẵn ở entry phụ):
|
|
134
75
|
|
|
135
76
|
```tsx
|
|
136
77
|
import { FeedbackProvider } from 'hocmai-feedback-widget';
|
|
@@ -138,42 +79,82 @@ import CkEditor from 'hocmai-feedback-widget/ckeditor';
|
|
|
138
79
|
|
|
139
80
|
<FeedbackProvider onSubmit={handleSubmit} isCkEditor descriptionEditor={CkEditor}>
|
|
140
81
|
<App />
|
|
141
|
-
</FeedbackProvider
|
|
82
|
+
</FeedbackProvider>;
|
|
142
83
|
```
|
|
143
84
|
|
|
144
|
-
|
|
85
|
+
Cài thêm peer deps (chỉ khi dùng CKEditor):
|
|
86
|
+
|
|
145
87
|
```bash
|
|
146
|
-
yarn add @ckeditor/ckeditor5-react hocmai-ckeditor-custom ckeditor5-classic-with-mathtype
|
|
88
|
+
yarn add @ckeditor/ckeditor5-react@5.0.0 hocmai-ckeditor-custom ckeditor5-classic-with-mathtype
|
|
147
89
|
```
|
|
148
90
|
|
|
149
|
-
|
|
150
|
-
> đời cũ (v5/v6), **KHÔNG** dùng latest (v11 cần `ckeditor5>=46`). Nên **copy đúng version** của 3 package
|
|
151
|
-
> này từ project gốc đang chạy CKEditor. Build này đã chứa sẵn core nên **không cần** `@ckeditor/ckeditor5-core` riêng.
|
|
91
|
+
**Lưu ý**: `@ckeditor/ckeditor5-react` chỉ hỗ trợ version 5, `hocmai-ckeditor-custom` có thể dùng version 0.0.2 hoặc 0.0.7 trở lên.
|
|
152
92
|
|
|
153
|
-
|
|
93
|
+
### 4. Chụp màn hình trực tiếp _(tùy chọn)_
|
|
154
94
|
|
|
155
|
-
|
|
156
|
-
|
|
95
|
+
```ts
|
|
96
|
+
import { captureScreenshot } from 'hocmai-feedback-widget';
|
|
157
97
|
|
|
158
|
-
|
|
98
|
+
const png = await captureScreenshot(); // toàn viewport
|
|
99
|
+
const region = await captureScreenshot({ x, y, width, height }); // 1 vùng (toạ độ viewport)
|
|
100
|
+
```
|
|
159
101
|
|
|
160
|
-
|
|
161
|
-
- UI của chính widget tự bị loại khỏi ảnh (qua thuộc tính `data-hsa-report-ui`).
|
|
162
|
-
- `scale` mặc định theo thiết bị, bị giới hạn bởi kích thước canvas tối đa của trình duyệt (16384px/cạnh).
|
|
163
|
-
- An toàn SSR (không chạm `window`/`document` lúc import).
|
|
102
|
+
## API
|
|
164
103
|
|
|
165
|
-
|
|
104
|
+
### `FeedbackProvider`
|
|
166
105
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
106
|
+
| Prop | Kiểu | Bắt buộc | Mặc định | Mô tả |
|
|
107
|
+
| --- | --- | :---: | :---: | --- |
|
|
108
|
+
| `children` | `ReactNode` | ✓ | — | Nội dung app được bọc. |
|
|
109
|
+
| `onSubmit` | `(data: FeedbackData) => Promise<void> \| void` | — | — | Handler mặc định khi gửi báo lỗi. Có thể bỏ, truyền theo từng lần ở `openFeedback`. |
|
|
110
|
+
| `themeColor` | `string` | — | `#3b82f6` | Màu chủ đạo của nút/viền. |
|
|
111
|
+
| `isCkEditor` | `boolean` | — | `false` | Dùng rich-text editor cho ô mô tả (cần kèm `descriptionEditor`). |
|
|
112
|
+
| `descriptionEditor` | `ComponentType<CkEditorProps>` | — | — | Component editor cho ô mô tả, vd `import CkEditor from 'hocmai-feedback-widget/ckeditor'`. |
|
|
113
|
+
| `isEnableCaptureFull` | `boolean` | — | `true` | Hiện nút "Toàn màn hình". |
|
|
114
|
+
| `isEnableCaptureElement` | `boolean` | — | `true` | Hiện nút "Chọn vùng". |
|
|
115
|
+
| `uploadUrl` | `string` | — | endpoint LCMS | Nơi upload ảnh: nhận `{ base64 }`, trả `{ file_url }`. |
|
|
116
|
+
|
|
117
|
+
### `useFeedback()`
|
|
118
|
+
|
|
119
|
+
Trả về:
|
|
120
|
+
|
|
121
|
+
| Thành phần | Kiểu | Mô tả |
|
|
122
|
+
| --- | --- | --- |
|
|
123
|
+
| `openFeedback` | `(questionId, contextData?, onSubmit?) => void` | Mở form báo lỗi cho một câu hỏi. |
|
|
124
|
+
| `closeFeedback` | `() => void` | Đóng form. |
|
|
125
|
+
| `isOpen` | `boolean` | Form đang mở hay không. |
|
|
126
|
+
| `activeQuestionId` | `string \| number \| null` | ID câu hỏi đang mở form (`null` nếu đóng). |
|
|
127
|
+
|
|
128
|
+
Tham số của `openFeedback`:
|
|
129
|
+
|
|
130
|
+
| Tham số | Kiểu | Bắt buộc | Mô tả |
|
|
131
|
+
| --- | --- | :---: | --- |
|
|
132
|
+
| `questionId` | `string \| number` | ✓ | ID câu hỏi; tự điền vào ô "ID câu hỏi". |
|
|
133
|
+
| `contextData` | `object` | — | Dữ liệu kèm theo (trả lại trong `FeedbackData.contextData`). `contextData.questionIdChild` tự điền ô "ID câu hỏi con". |
|
|
134
|
+
| `onSubmit` | `(data: FeedbackData) => Promise<void> \| void` | — | Handler riêng cho lần gọi này, **ghi đè** `onSubmit` của Provider. |
|
|
135
|
+
|
|
136
|
+
### `FeedbackData`
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
interface FeedbackData {
|
|
140
|
+
idQuestion: string | number;
|
|
141
|
+
idChildQuestion?: string | number;
|
|
142
|
+
errorType: string; // incorrect_content | display_error | missing_data | technical_issue | other
|
|
143
|
+
errorDescription: string; // text; là HTML nếu dùng CKEditor
|
|
144
|
+
listImage: string[]; // URL ảnh đã upload (tối đa 3)
|
|
145
|
+
deviceInfo: { os; osVersion; browser; browserVersion; deviceType };
|
|
146
|
+
contextData?: any;
|
|
147
|
+
}
|
|
173
148
|
```
|
|
174
149
|
|
|
175
|
-
##
|
|
176
|
-
|
|
150
|
+
## Lưu ý
|
|
151
|
+
|
|
152
|
+
- **Thứ tự `onSubmit`:** handler theo lần gọi → handler ở Provider → nếu không có thì chỉ cảnh báo (không crash).
|
|
153
|
+
- **CKEditor:** `hocmai-ckeditor-custom` là build kiểu cũ → dùng `@ckeditor/ckeditor5-react` đời cũ (v5/v6), **không** dùng latest. Nên copy đúng version từ project gốc. Build này đã chứa core nên **không cần** cài `@ckeditor/ckeditor5-core`.
|
|
154
|
+
- Khi dùng CKEditor, `errorDescription` trả về là **HTML** — backend cần xử lý phù hợp.
|
|
155
|
+
- Core **không** phụ thuộc CKEditor: app không dùng `isCkEditor` vẫn build bình thường.
|
|
156
|
+
- An toàn **SSR** (không chạm `window`/`document` lúc import).
|
|
177
157
|
|
|
178
158
|
## License
|
|
179
|
-
|
|
159
|
+
|
|
160
|
+
[MIT](./LICENSE)
|
|
@@ -13,7 +13,8 @@ export interface FeedbackData {
|
|
|
13
13
|
export interface FeedbackProps {
|
|
14
14
|
questionId: string | number;
|
|
15
15
|
contextData?: Record<string, any>;
|
|
16
|
-
|
|
16
|
+
/** Submit handler. Optional — may be provided per call via openFeedback or at the Provider. */
|
|
17
|
+
onSubmit?: (data: FeedbackData) => Promise<void> | void;
|
|
17
18
|
themeColor?: string;
|
|
18
19
|
triggerComponent?: React.ReactNode;
|
|
19
20
|
isOpen?: boolean;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { default as React, ReactNode } from 'react';
|
|
2
2
|
import { FeedbackData } from '../components/FeedbackWidget';
|
|
3
3
|
import { CkEditorProps } from '../components/CkEditor';
|
|
4
|
+
export type FeedbackSubmitHandler = (data: FeedbackData) => Promise<void> | void;
|
|
4
5
|
interface FeedbackContextType {
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Open the report form.
|
|
8
|
+
* @param onSubmit optional per-call handler; overrides the Provider's onSubmit
|
|
9
|
+
* for this submission. Lets you handle submit from anywhere.
|
|
10
|
+
*/
|
|
11
|
+
openFeedback: (questionId: string | number, contextData?: any, onSubmit?: FeedbackSubmitHandler) => void;
|
|
6
12
|
closeFeedback: () => void;
|
|
7
13
|
isOpen: boolean;
|
|
8
14
|
activeQuestionId: string | number | null;
|
|
@@ -10,12 +16,19 @@ interface FeedbackContextType {
|
|
|
10
16
|
export declare const useFeedback: () => FeedbackContextType;
|
|
11
17
|
interface FeedbackProviderProps {
|
|
12
18
|
children: ReactNode;
|
|
13
|
-
|
|
19
|
+
/** Default submit handler. Optional — you can instead pass one per call via openFeedback. */
|
|
20
|
+
onSubmit?: FeedbackSubmitHandler;
|
|
14
21
|
themeColor?: string;
|
|
15
22
|
/** Use the rich-text editor for the description instead of a plain textarea. */
|
|
16
23
|
isCkEditor?: boolean;
|
|
17
24
|
/** Editor component for the description (from `hocmai-feedback-widget/ckeditor` or your own). */
|
|
18
25
|
descriptionEditor?: React.ComponentType<CkEditorProps>;
|
|
26
|
+
/** Show the "full screen" capture button. Default true. */
|
|
27
|
+
isEnableCaptureFull?: boolean;
|
|
28
|
+
/** Show the "select region" capture button. Default true. */
|
|
29
|
+
isEnableCaptureElement?: boolean;
|
|
30
|
+
/** Endpoint that accepts { base64 } and returns { file_url } for image uploads. */
|
|
31
|
+
uploadUrl?: string;
|
|
19
32
|
}
|
|
20
33
|
export declare const FeedbackProvider: React.FC<FeedbackProviderProps>;
|
|
21
34
|
export {};
|