@product7/product7-js 0.3.2 → 0.3.5
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/README.md +53 -29
- package/dist/README.md +53 -29
- package/dist/product7-js.js +515 -141
- package/dist/product7-js.js.map +1 -1
- package/dist/product7-js.min.js +1 -1
- package/dist/product7-js.min.js.map +1 -1
- package/package.json +1 -1
- package/src/api/services/MessengerService.js +1 -30
- package/src/core/APIService.js +87 -1
- package/src/core/BaseAPIService.js +128 -11
- package/src/core/Product7.js +183 -19
- package/src/docs/api.md +253 -89
- package/src/docs/example.md +203 -153
- package/src/docs/framework-integrations.md +236 -358
- package/src/docs/installation.md +171 -143
- package/src/index.js +48 -41
- package/src/widgets/MessengerWidget.js +30 -30
- package/src/widgets/SurveyWidget.js +20 -0
- package/src/widgets/messenger/views/ChatView.js +14 -8
- package/src/widgets/messenger/views/HomeView.js +5 -2
- package/types/index.d.ts +34 -0
package/src/docs/example.md
CHANGED
|
@@ -5,67 +5,66 @@
|
|
|
5
5
|
### Simple Setup
|
|
6
6
|
|
|
7
7
|
```javascript
|
|
8
|
-
import Product7 from '@product7/product7-js';
|
|
8
|
+
import { Product7 } from '@product7/product7-js';
|
|
9
9
|
|
|
10
10
|
const sdk = new Product7({
|
|
11
11
|
workspace: 'my-workspace',
|
|
12
|
-
|
|
13
|
-
user_id: 'user_123',
|
|
14
|
-
email: 'user@example.com',
|
|
15
|
-
},
|
|
12
|
+
boardName: 'feature-requests',
|
|
16
13
|
});
|
|
17
14
|
|
|
18
15
|
await sdk.init();
|
|
16
|
+
await sdk.identify({
|
|
17
|
+
user_id: 'user_123',
|
|
18
|
+
email: 'user@example.com',
|
|
19
|
+
name: 'John Doe',
|
|
20
|
+
});
|
|
19
21
|
|
|
20
|
-
const widget = sdk.
|
|
22
|
+
const widget = sdk.createFeedbackWidget();
|
|
21
23
|
widget.mount();
|
|
22
24
|
```
|
|
23
25
|
|
|
24
26
|
---
|
|
25
27
|
|
|
26
|
-
## User
|
|
28
|
+
## User Identity
|
|
27
29
|
|
|
28
|
-
### Basic
|
|
30
|
+
### Basic Identify Call
|
|
29
31
|
|
|
30
32
|
```javascript
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
email: 'user@example.com',
|
|
36
|
-
name: 'John Doe',
|
|
37
|
-
},
|
|
33
|
+
await sdk.identify({
|
|
34
|
+
user_id: 'user_123',
|
|
35
|
+
email: 'user@example.com',
|
|
36
|
+
name: 'John Doe',
|
|
38
37
|
});
|
|
39
38
|
```
|
|
40
39
|
|
|
41
40
|
### With Custom Fields
|
|
42
41
|
|
|
43
42
|
```javascript
|
|
44
|
-
|
|
43
|
+
await sdk.identify({
|
|
45
44
|
user_id: 'user_123',
|
|
46
45
|
email: 'user@example.com',
|
|
47
46
|
name: 'John Doe',
|
|
48
47
|
custom_fields: {
|
|
49
48
|
role: 'admin',
|
|
50
49
|
plan: 'pro',
|
|
51
|
-
signup_date: '2024-01-01'
|
|
52
|
-
}
|
|
53
|
-
}
|
|
50
|
+
signup_date: '2024-01-01',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
54
53
|
```
|
|
55
54
|
|
|
56
55
|
### With Company Data
|
|
57
56
|
|
|
58
57
|
```javascript
|
|
59
|
-
|
|
58
|
+
await sdk.identify({
|
|
60
59
|
user_id: 'user_123',
|
|
61
60
|
email: 'user@example.com',
|
|
62
61
|
name: 'John Doe',
|
|
63
62
|
company: {
|
|
64
63
|
id: 'company_456',
|
|
65
64
|
name: 'Acme Corp',
|
|
66
|
-
monthly_spend: 1000
|
|
67
|
-
}
|
|
68
|
-
}
|
|
65
|
+
monthly_spend: 1000,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
69
68
|
```
|
|
70
69
|
|
|
71
70
|
### Extract from Auth
|
|
@@ -80,36 +79,29 @@ const authData = {
|
|
|
80
79
|
|
|
81
80
|
const metadata = Product7.extractMetadataFromAuth(authData);
|
|
82
81
|
|
|
83
|
-
|
|
84
|
-
workspace: 'my-workspace',
|
|
85
|
-
metadata,
|
|
86
|
-
});
|
|
82
|
+
await sdk.identify(metadata);
|
|
87
83
|
```
|
|
88
84
|
|
|
89
85
|
---
|
|
90
86
|
|
|
91
|
-
## Widget
|
|
87
|
+
## Feedback Widget
|
|
92
88
|
|
|
93
89
|
### Different Positions
|
|
94
90
|
|
|
95
91
|
```javascript
|
|
96
|
-
|
|
97
|
-
const widget1 = sdk.createWidget('button', {
|
|
92
|
+
const widget1 = sdk.createFeedbackWidget({
|
|
98
93
|
position: 'bottom-right',
|
|
99
94
|
});
|
|
100
95
|
|
|
101
|
-
|
|
102
|
-
const widget2 = sdk.createWidget('button', {
|
|
96
|
+
const widget2 = sdk.createFeedbackWidget({
|
|
103
97
|
position: 'bottom-left',
|
|
104
98
|
});
|
|
105
99
|
|
|
106
|
-
|
|
107
|
-
const widget3 = sdk.createWidget('button', {
|
|
100
|
+
const widget3 = sdk.createFeedbackWidget({
|
|
108
101
|
position: 'top-right',
|
|
109
102
|
});
|
|
110
103
|
|
|
111
|
-
|
|
112
|
-
const widget4 = sdk.createWidget('button', {
|
|
104
|
+
const widget4 = sdk.createFeedbackWidget({
|
|
113
105
|
position: 'top-left',
|
|
114
106
|
});
|
|
115
107
|
```
|
|
@@ -117,7 +109,7 @@ const widget4 = sdk.createWidget('button', {
|
|
|
117
109
|
### Dark Theme
|
|
118
110
|
|
|
119
111
|
```javascript
|
|
120
|
-
const widget = sdk.
|
|
112
|
+
const widget = sdk.createFeedbackWidget({
|
|
121
113
|
theme: 'dark',
|
|
122
114
|
});
|
|
123
115
|
widget.mount();
|
|
@@ -126,24 +118,37 @@ widget.mount();
|
|
|
126
118
|
### Custom Board
|
|
127
119
|
|
|
128
120
|
```javascript
|
|
129
|
-
const widget = sdk.
|
|
121
|
+
const widget = sdk.createFeedbackWidget({
|
|
122
|
+
boardName: 'bug-reports',
|
|
123
|
+
});
|
|
124
|
+
widget.mount();
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Headless Feedback
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
const widget = sdk.createFeedbackWidget({
|
|
131
|
+
headless: true,
|
|
130
132
|
boardName: 'feature-requests',
|
|
131
133
|
});
|
|
134
|
+
|
|
132
135
|
widget.mount();
|
|
136
|
+
|
|
137
|
+
document
|
|
138
|
+
.querySelector('#feedback-trigger')
|
|
139
|
+
?.addEventListener('click', () => widget.open());
|
|
133
140
|
```
|
|
134
141
|
|
|
135
|
-
### Multiple Widgets
|
|
142
|
+
### Multiple Feedback Widgets
|
|
136
143
|
|
|
137
144
|
```javascript
|
|
138
|
-
|
|
139
|
-
const feedbackWidget = sdk.createWidget('button', {
|
|
145
|
+
const feedbackWidget = sdk.createFeedbackWidget({
|
|
140
146
|
position: 'bottom-right',
|
|
141
147
|
boardName: 'general',
|
|
142
148
|
});
|
|
143
149
|
feedbackWidget.mount();
|
|
144
150
|
|
|
145
|
-
|
|
146
|
-
const bugWidget = sdk.createWidget('button', {
|
|
151
|
+
const bugWidget = sdk.createFeedbackWidget({
|
|
147
152
|
position: 'bottom-left',
|
|
148
153
|
boardName: 'bug-reports',
|
|
149
154
|
});
|
|
@@ -151,177 +156,221 @@ bugWidget.updateText('Report Bug');
|
|
|
151
156
|
bugWidget.mount();
|
|
152
157
|
```
|
|
153
158
|
|
|
154
|
-
### Update Widget
|
|
159
|
+
### Update the Widget
|
|
155
160
|
|
|
156
161
|
```javascript
|
|
157
|
-
const widget = sdk.
|
|
162
|
+
const widget = sdk.createFeedbackWidget();
|
|
158
163
|
widget.mount();
|
|
159
164
|
|
|
160
|
-
// Update text
|
|
161
165
|
widget.updateText('Send Feedback');
|
|
162
|
-
|
|
163
|
-
// Update position
|
|
164
166
|
widget.updatePosition('top-right');
|
|
165
|
-
|
|
166
|
-
// Show/hide
|
|
167
167
|
widget.hide();
|
|
168
168
|
widget.show();
|
|
169
169
|
```
|
|
170
170
|
|
|
171
171
|
---
|
|
172
172
|
|
|
173
|
-
##
|
|
173
|
+
## Survey Widget
|
|
174
174
|
|
|
175
|
-
###
|
|
175
|
+
### Create and Open a Survey
|
|
176
176
|
|
|
177
177
|
```javascript
|
|
178
|
-
sdk.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
board: feedback.board,
|
|
185
|
-
});
|
|
178
|
+
const survey = sdk.createSurveyWidget({
|
|
179
|
+
surveyType: 'nps',
|
|
180
|
+
position: 'center',
|
|
181
|
+
title: 'Quick question',
|
|
182
|
+
description: 'How likely are you to recommend us?',
|
|
183
|
+
showSubmitButton: true,
|
|
186
184
|
});
|
|
185
|
+
|
|
186
|
+
survey.mount();
|
|
187
|
+
survey.open();
|
|
187
188
|
```
|
|
188
189
|
|
|
189
|
-
###
|
|
190
|
+
### Show Active Surveys
|
|
190
191
|
|
|
191
192
|
```javascript
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
// Show custom error notification
|
|
196
|
-
toast.error('Failed to submit feedback. Please try again.');
|
|
193
|
+
const surveys = await sdk.getActiveSurveys({
|
|
194
|
+
includeEligibility: true,
|
|
197
195
|
});
|
|
196
|
+
|
|
197
|
+
if (surveys.length > 0) {
|
|
198
|
+
await sdk.showSurveyById(surveys[0].surveyId, {
|
|
199
|
+
position: 'center',
|
|
200
|
+
});
|
|
201
|
+
}
|
|
198
202
|
```
|
|
199
203
|
|
|
200
|
-
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Messenger Widget
|
|
207
|
+
|
|
208
|
+
### Basic Messenger
|
|
201
209
|
|
|
202
210
|
```javascript
|
|
203
|
-
sdk.
|
|
204
|
-
|
|
211
|
+
const messenger = sdk.createMessengerWidget({
|
|
212
|
+
position: 'bottom-right',
|
|
213
|
+
teamName: 'Support Team',
|
|
214
|
+
enableHelp: true,
|
|
215
|
+
enableChangelog: true,
|
|
205
216
|
});
|
|
206
217
|
|
|
207
|
-
|
|
208
|
-
|
|
218
|
+
messenger.mount();
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Headless Messenger
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
const messenger = sdk.createMessengerWidget({
|
|
225
|
+
headless: true,
|
|
226
|
+
enableHelp: true,
|
|
209
227
|
});
|
|
228
|
+
|
|
229
|
+
messenger.mount();
|
|
230
|
+
|
|
231
|
+
document
|
|
232
|
+
.querySelector('#support-link')
|
|
233
|
+
?.addEventListener('click', () => messenger.open());
|
|
210
234
|
```
|
|
211
235
|
|
|
212
|
-
###
|
|
236
|
+
### Programmatic Messenger Navigation
|
|
213
237
|
|
|
214
238
|
```javascript
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
239
|
+
messenger.open();
|
|
240
|
+
messenger.navigateTo('help');
|
|
241
|
+
messenger.close();
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Changelog Widget
|
|
247
|
+
|
|
248
|
+
### Basic Changelog
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
const changelog = sdk.createChangelogWidget({
|
|
252
|
+
position: 'bottom-left',
|
|
253
|
+
triggerText: "What's New",
|
|
254
|
+
showBadge: true,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
changelog.mount();
|
|
219
258
|
```
|
|
220
259
|
|
|
221
|
-
###
|
|
260
|
+
### Open Changelog Programmatically
|
|
222
261
|
|
|
223
262
|
```javascript
|
|
224
|
-
sdk.
|
|
225
|
-
|
|
263
|
+
const changelog = sdk.createChangelogWidget({
|
|
264
|
+
headless: true,
|
|
226
265
|
});
|
|
266
|
+
|
|
267
|
+
changelog.mount();
|
|
268
|
+
changelog.open();
|
|
227
269
|
```
|
|
228
270
|
|
|
229
271
|
---
|
|
230
272
|
|
|
231
|
-
##
|
|
273
|
+
## Event Handling
|
|
232
274
|
|
|
233
|
-
###
|
|
275
|
+
### Track Feedback Submissions
|
|
234
276
|
|
|
235
277
|
```javascript
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
// Create widget after login
|
|
241
|
-
const widget = sdk.createWidget('button');
|
|
242
|
-
widget.mount();
|
|
243
|
-
}
|
|
278
|
+
sdk.on('feedback:submitted', ({ feedback }) => {
|
|
279
|
+
console.log('Feedback submitted:', feedback);
|
|
280
|
+
});
|
|
244
281
|
```
|
|
245
282
|
|
|
246
|
-
###
|
|
283
|
+
### Track Survey Events
|
|
247
284
|
|
|
248
285
|
```javascript
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
286
|
+
sdk.on('survey:submitted', ({ response }) => {
|
|
287
|
+
console.log('Survey submitted:', response);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
sdk.on('survey:questionAnswered', (data) => {
|
|
291
|
+
console.log('Question answered:', data.pageId, data.answer);
|
|
292
|
+
});
|
|
253
293
|
```
|
|
254
294
|
|
|
255
|
-
###
|
|
295
|
+
### SDK Lifecycle
|
|
256
296
|
|
|
257
297
|
```javascript
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
298
|
+
sdk.on('sdk:initialized', (data) => {
|
|
299
|
+
console.log('SDK ready:', data.sessionToken);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
sdk.on('sdk:identified', (data) => {
|
|
303
|
+
console.log('User identified:', data.metadata);
|
|
304
|
+
});
|
|
261
305
|
```
|
|
262
306
|
|
|
263
307
|
---
|
|
264
308
|
|
|
265
|
-
##
|
|
309
|
+
## Authentication Flows
|
|
266
310
|
|
|
267
|
-
###
|
|
311
|
+
### On Login
|
|
268
312
|
|
|
269
313
|
```javascript
|
|
270
|
-
|
|
314
|
+
async function handleLogin(authResponse) {
|
|
315
|
+
const metadata = Product7.extractMetadataFromAuth(authResponse);
|
|
316
|
+
|
|
317
|
+
await sdk.init();
|
|
318
|
+
await sdk.identify(metadata);
|
|
319
|
+
|
|
320
|
+
const widget = sdk.createFeedbackWidget();
|
|
321
|
+
widget.mount();
|
|
322
|
+
}
|
|
271
323
|
```
|
|
272
324
|
|
|
273
|
-
###
|
|
325
|
+
### On User Change
|
|
274
326
|
|
|
275
327
|
```javascript
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
328
|
+
async function handleUserChanged(user) {
|
|
329
|
+
await sdk.identify({
|
|
330
|
+
user_id: user.id,
|
|
331
|
+
email: user.email,
|
|
332
|
+
name: user.name,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
281
335
|
```
|
|
282
336
|
|
|
283
|
-
###
|
|
337
|
+
### On Logout
|
|
284
338
|
|
|
285
339
|
```javascript
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
});
|
|
340
|
+
function handleLogout() {
|
|
341
|
+
sdk.destroyAllWidgets();
|
|
342
|
+
sdk.destroy();
|
|
343
|
+
}
|
|
291
344
|
```
|
|
292
345
|
|
|
293
346
|
---
|
|
294
347
|
|
|
295
348
|
## Programmatic Control
|
|
296
349
|
|
|
297
|
-
### Open
|
|
350
|
+
### Open Feedback from Code
|
|
298
351
|
|
|
299
352
|
```javascript
|
|
300
|
-
const widget = sdk.
|
|
353
|
+
const widget = sdk.createFeedbackWidget({
|
|
354
|
+
headless: true,
|
|
355
|
+
});
|
|
356
|
+
|
|
301
357
|
widget.mount();
|
|
302
358
|
|
|
303
|
-
// Open panel from code
|
|
304
359
|
setTimeout(() => {
|
|
305
|
-
widget.
|
|
360
|
+
widget.open();
|
|
306
361
|
}, 3000);
|
|
307
362
|
```
|
|
308
363
|
|
|
309
|
-
###
|
|
310
|
-
|
|
311
|
-
```javascript
|
|
312
|
-
widget.closePanel();
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
### Trigger from Custom Button
|
|
364
|
+
### Toggle Survey
|
|
316
365
|
|
|
317
366
|
```javascript
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
if (widget) {
|
|
322
|
-
widget.openPanel();
|
|
323
|
-
}
|
|
367
|
+
const survey = sdk.createSurveyWidget({
|
|
368
|
+
surveyType: 'csat',
|
|
369
|
+
showSubmitButton: true,
|
|
324
370
|
});
|
|
371
|
+
|
|
372
|
+
survey.mount();
|
|
373
|
+
survey.toggle();
|
|
325
374
|
```
|
|
326
375
|
|
|
327
376
|
---
|
|
@@ -333,16 +382,15 @@ customButton.addEventListener('click', () => {
|
|
|
333
382
|
```javascript
|
|
334
383
|
try {
|
|
335
384
|
await sdk.init();
|
|
336
|
-
|
|
385
|
+
await sdk.identify({
|
|
386
|
+
user_id: 'user_123',
|
|
387
|
+
email: 'user@example.com',
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const widget = sdk.createFeedbackWidget();
|
|
337
391
|
widget.mount();
|
|
338
392
|
} catch (error) {
|
|
339
|
-
|
|
340
|
-
console.error('Config error:', error.message);
|
|
341
|
-
} else if (error instanceof APIError) {
|
|
342
|
-
console.error('API error:', error.status);
|
|
343
|
-
} else {
|
|
344
|
-
console.error('Unexpected error:', error);
|
|
345
|
-
}
|
|
393
|
+
console.error('Product7 error:', error);
|
|
346
394
|
}
|
|
347
395
|
```
|
|
348
396
|
|
|
@@ -395,39 +443,39 @@ const widget = sdk.createWidget('custom');
|
|
|
395
443
|
widget.mount();
|
|
396
444
|
```
|
|
397
445
|
|
|
398
|
-
### Conditional
|
|
446
|
+
### Conditional Loading
|
|
399
447
|
|
|
400
448
|
```javascript
|
|
401
|
-
// Only show feedback for authenticated users
|
|
402
449
|
if (user.isAuthenticated) {
|
|
403
450
|
const sdk = new Product7({
|
|
404
451
|
workspace: 'my-workspace',
|
|
405
|
-
metadata: {
|
|
406
|
-
user_id: user.id,
|
|
407
|
-
email: user.email,
|
|
408
|
-
},
|
|
409
452
|
});
|
|
410
453
|
|
|
411
454
|
await sdk.init();
|
|
412
|
-
|
|
455
|
+
await sdk.identify({
|
|
456
|
+
user_id: user.id,
|
|
457
|
+
email: user.email,
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
const widget = sdk.createFeedbackWidget();
|
|
413
461
|
widget.mount();
|
|
414
462
|
}
|
|
415
463
|
```
|
|
416
464
|
|
|
417
|
-
### Environment-
|
|
465
|
+
### Environment-Based Config
|
|
418
466
|
|
|
419
467
|
```javascript
|
|
420
|
-
const
|
|
468
|
+
const sdk = new Product7({
|
|
421
469
|
workspace: 'my-workspace',
|
|
422
|
-
metadata: getMetadata(),
|
|
423
470
|
apiUrl:
|
|
424
471
|
process.env.NODE_ENV === 'production'
|
|
425
472
|
? 'https://api.product7.io/api/v1'
|
|
426
473
|
: 'https://staging.api.product7.io/api/v1',
|
|
427
474
|
debug: process.env.NODE_ENV === 'development',
|
|
428
|
-
};
|
|
475
|
+
});
|
|
429
476
|
|
|
430
|
-
|
|
477
|
+
await sdk.init();
|
|
478
|
+
await sdk.identify(getMetadata());
|
|
431
479
|
```
|
|
432
480
|
|
|
433
481
|
---
|
|
@@ -437,15 +485,17 @@ const sdk = new Product7(config);
|
|
|
437
485
|
### Mock SDK
|
|
438
486
|
|
|
439
487
|
```javascript
|
|
440
|
-
// In tests
|
|
441
488
|
jest.mock('@product7/product7-js');
|
|
442
489
|
|
|
443
490
|
test('should initialize SDK', async () => {
|
|
444
491
|
const sdk = new Product7({
|
|
445
492
|
workspace: 'test',
|
|
446
|
-
|
|
493
|
+
mock: true,
|
|
447
494
|
});
|
|
495
|
+
|
|
448
496
|
await sdk.init();
|
|
497
|
+
await sdk.identify({ user_id: '123' });
|
|
498
|
+
|
|
449
499
|
expect(sdk.initialized).toBe(true);
|
|
450
500
|
});
|
|
451
501
|
```
|
|
@@ -453,7 +503,7 @@ test('should initialize SDK', async () => {
|
|
|
453
503
|
### Check Widget Exists
|
|
454
504
|
|
|
455
505
|
```javascript
|
|
456
|
-
const widget = sdk.
|
|
506
|
+
const widget = sdk.createFeedbackWidget();
|
|
457
507
|
widget.mount();
|
|
458
508
|
|
|
459
509
|
const found = sdk.getWidget(widget.id);
|