@getspot/spot-widget-vue2 1.4.0 → 2.0.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/CHANGELOG.md +11 -0
- package/README.md +437 -5
- package/dist/index.d.ts +23 -0
- package/package.json +21 -4
- package/.turbo/turbo-build.log +0 -13
- package/src/Vue2SpotWidget.vue +0 -230
- package/vite.config.js +0 -24
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,12 +1,444 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @getspot/spot-widget-vue2
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Vue 2 component wrapper for the Spot refund guarantee widget.
|
|
4
|
+
|
|
5
|
+
> **Note:** This Vue 2 wrapper uses types from [@getspot/spot-widget](https://www.npmjs.com/package/@getspot/spot-widget).
|
|
6
|
+
|
|
7
|
+
### Key Types
|
|
8
|
+
- `ApiConfig` - API configuration (environment, partnerId, customEndpoint)
|
|
9
|
+
- `QuoteRequestData` - Quote request data for single items or batch requests
|
|
10
|
+
- `SelectionData` - User selection data returned in callbacks
|
|
11
|
+
- `Quote` - Quote response data with pricing and terms
|
|
12
|
+
- `Theme` - Styling customization options
|
|
13
|
+
|
|
14
|
+
For complete type definitions, see the [@getspot/spot-widget documentation](https://www.npmjs.com/package/@getspot/spot-widget).
|
|
5
15
|
|
|
6
16
|
## Installation
|
|
7
17
|
|
|
8
18
|
```bash
|
|
9
|
-
npm install
|
|
19
|
+
npm install @getspot/spot-widget-vue2
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```vue
|
|
25
|
+
<template>
|
|
26
|
+
<Vue2SpotWidget
|
|
27
|
+
:api-config="{
|
|
28
|
+
environment: 'production',
|
|
29
|
+
partnerId: 'your-partner-id'
|
|
30
|
+
}"
|
|
31
|
+
:quote-request-data="quoteData"
|
|
32
|
+
:show-table="true"
|
|
33
|
+
:opt-in-selected="false"
|
|
34
|
+
@quote-retrieved="onQuoteRetrieved"
|
|
35
|
+
@opt-in="onOptIn"
|
|
36
|
+
@opt-out="onOptOut"
|
|
37
|
+
@error="onError"
|
|
38
|
+
/>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script>
|
|
42
|
+
import Vue2SpotWidget from '@getspot/spot-widget-vue2';
|
|
43
|
+
|
|
44
|
+
export default {
|
|
45
|
+
components: {
|
|
46
|
+
Vue2SpotWidget
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
data() {
|
|
50
|
+
return {
|
|
51
|
+
quoteData: {
|
|
52
|
+
startDate: '2024-01-01T00:00:00Z',
|
|
53
|
+
endDate: '2024-01-07T23:59:59Z',
|
|
54
|
+
currencyCode: 'USD',
|
|
55
|
+
eventType: 'Ski Trip',
|
|
56
|
+
productType: 'Trip',
|
|
57
|
+
productDuration: 'Trip',
|
|
58
|
+
productPrice: 500,
|
|
59
|
+
productId: 'ski-trip-2024',
|
|
60
|
+
cartId: 'cart-123',
|
|
61
|
+
productName: 'Aspen Ski Trip 2024'
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
methods: {
|
|
67
|
+
onQuoteRetrieved(quote) {
|
|
68
|
+
console.log('Quote retrieved:', quote);
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
onOptIn(data) {
|
|
72
|
+
console.log('User opted in:', data);
|
|
73
|
+
// Handle opt-in logic
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
onOptOut(data) {
|
|
77
|
+
console.log('User opted out:', data);
|
|
78
|
+
// Handle opt-out logic
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
onError(error) {
|
|
82
|
+
console.error('Widget error:', error);
|
|
83
|
+
// Handle errors
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
</script>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## TypeScript Support
|
|
91
|
+
|
|
92
|
+
This package includes TypeScript definitions for Vue 2. To use with TypeScript:
|
|
93
|
+
|
|
94
|
+
```vue
|
|
95
|
+
<template>
|
|
96
|
+
<Vue2SpotWidget
|
|
97
|
+
:api-config="apiConfig"
|
|
98
|
+
:quote-request-data="quoteData"
|
|
99
|
+
@opt-in="onOptIn"
|
|
100
|
+
@opt-out="onOptOut"
|
|
101
|
+
@error="onError"
|
|
102
|
+
/>
|
|
103
|
+
</template>
|
|
104
|
+
|
|
105
|
+
<script lang="ts">
|
|
106
|
+
import Vue from 'vue';
|
|
107
|
+
import Vue2SpotWidget from '@getspot/spot-widget-vue2';
|
|
108
|
+
import type { Quote, SelectionData, ApiConfig, QuoteRequestData } from '@getspot/spot-widget';
|
|
109
|
+
|
|
110
|
+
interface Data {
|
|
111
|
+
apiConfig: ApiConfig;
|
|
112
|
+
quoteData: QuoteRequestData;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export default Vue.extend({
|
|
116
|
+
components: {
|
|
117
|
+
Vue2SpotWidget
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
data(): Data {
|
|
121
|
+
return {
|
|
122
|
+
apiConfig: {
|
|
123
|
+
environment: 'production',
|
|
124
|
+
partnerId: 'your-partner-id'
|
|
125
|
+
},
|
|
126
|
+
quoteData: {
|
|
127
|
+
startDate: '2024-01-01T00:00:00Z',
|
|
128
|
+
endDate: '2024-01-07T23:59:59Z',
|
|
129
|
+
currencyCode: 'USD',
|
|
130
|
+
eventType: 'Test Event',
|
|
131
|
+
productType: 'Trip',
|
|
132
|
+
productDuration: 'Trip',
|
|
133
|
+
productPrice: 100,
|
|
134
|
+
productId: 'test-product',
|
|
135
|
+
cartId: 'test-cart',
|
|
136
|
+
productName: 'Test Product'
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
methods: {
|
|
142
|
+
onOptIn(data: SelectionData) {
|
|
143
|
+
console.log('User opted in:', data);
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
onOptOut(data: SelectionData) {
|
|
147
|
+
console.log('User opted out:', data);
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
onError(error: Error) {
|
|
151
|
+
console.error('Widget error:', error);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
</script>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Props
|
|
159
|
+
|
|
160
|
+
### Required Props
|
|
161
|
+
|
|
162
|
+
| Prop | Type | Description |
|
|
163
|
+
|------|------|-------------|
|
|
164
|
+
| `apiConfig` | `ApiConfig` | Configuration for the Spot API including environment and partner ID |
|
|
165
|
+
| `quoteRequestData` | `QuoteRequestData` | Quote request data containing product and cart information |
|
|
166
|
+
|
|
167
|
+
### Optional Props
|
|
168
|
+
|
|
169
|
+
| Prop | Type | Default | Description |
|
|
170
|
+
|------|------|---------|-------------|
|
|
171
|
+
| `showTable` | `boolean` | `true` | Whether to show the payout table |
|
|
172
|
+
| `optInSelected` | `boolean` | `false` | Whether the widget should be pre-selected for opt-in |
|
|
173
|
+
| `theme` | `Theme` | `undefined` | Theme customization options for styling the widget |
|
|
174
|
+
|
|
175
|
+
## Events
|
|
176
|
+
|
|
177
|
+
The component emits the following events:
|
|
178
|
+
|
|
179
|
+
### @quote-retrieved
|
|
180
|
+
|
|
181
|
+
Emitted when a quote is successfully retrieved.
|
|
182
|
+
|
|
183
|
+
```vue
|
|
184
|
+
<Vue2SpotWidget @quote-retrieved="onQuoteRetrieved" />
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Payload:** `Quote` object
|
|
188
|
+
|
|
189
|
+
### @opt-in
|
|
190
|
+
|
|
191
|
+
Emitted when user opts in to the refund guarantee.
|
|
192
|
+
|
|
193
|
+
```vue
|
|
194
|
+
<Vue2SpotWidget @opt-in="onOptIn" />
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Payload:** `SelectionData` object with `status: 'QUOTE_ACCEPTED'`
|
|
198
|
+
|
|
199
|
+
### @opt-out
|
|
200
|
+
|
|
201
|
+
Emitted when user opts out of the refund guarantee.
|
|
202
|
+
|
|
203
|
+
```vue
|
|
204
|
+
<Vue2SpotWidget @opt-out="onOptOut" />
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**Payload:** `SelectionData` object with `status: 'QUOTE_DECLINED'`
|
|
208
|
+
|
|
209
|
+
### @error
|
|
210
|
+
|
|
211
|
+
Emitted when an error occurs during quote retrieval.
|
|
212
|
+
|
|
213
|
+
```vue
|
|
214
|
+
<Vue2SpotWidget @error="onError" />
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Payload:** Error object with `message`, `status`, and `responseBody`
|
|
218
|
+
|
|
219
|
+
### @no-matching-quote
|
|
220
|
+
|
|
221
|
+
Emitted when no matching quote is found.
|
|
222
|
+
|
|
223
|
+
```vue
|
|
224
|
+
<Vue2SpotWidget @no-matching-quote="onNoMatchingQuote" />
|
|
10
225
|
```
|
|
11
226
|
|
|
12
|
-
|
|
227
|
+
**Payload:** Object with `status: 'NO_MATCHING_QUOTE'` and original request data
|
|
228
|
+
|
|
229
|
+
### @selection-change
|
|
230
|
+
|
|
231
|
+
Emitted when user changes their selection (opt-in or opt-out).
|
|
232
|
+
|
|
233
|
+
```vue
|
|
234
|
+
<Vue2SpotWidget @selection-change="onSelectionChange" />
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Payload:** `SelectionData` object
|
|
238
|
+
|
|
239
|
+
## Exposed Methods
|
|
240
|
+
|
|
241
|
+
You can access widget methods using template refs:
|
|
242
|
+
|
|
243
|
+
```vue
|
|
244
|
+
<template>
|
|
245
|
+
<div>
|
|
246
|
+
<Vue2SpotWidget
|
|
247
|
+
ref="spotWidget"
|
|
248
|
+
v-bind="widgetProps"
|
|
249
|
+
/>
|
|
250
|
+
<button @click="updateQuote">Update Quote</button>
|
|
251
|
+
<button @click="getSelection">Get Selection</button>
|
|
252
|
+
<button @click="validateSelection">Validate Selection</button>
|
|
253
|
+
</div>
|
|
254
|
+
</template>
|
|
255
|
+
|
|
256
|
+
<script>
|
|
257
|
+
import Vue2SpotWidget from '@getspot/spot-widget-vue2';
|
|
258
|
+
|
|
259
|
+
export default {
|
|
260
|
+
components: {
|
|
261
|
+
Vue2SpotWidget
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
methods: {
|
|
265
|
+
async updateQuote() {
|
|
266
|
+
const success = await this.$refs.spotWidget.updateQuote({
|
|
267
|
+
// new quote data
|
|
268
|
+
});
|
|
269
|
+
console.log('Quote updated:', success);
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
getSelection() {
|
|
273
|
+
const selection = this.$refs.spotWidget.getSelection();
|
|
274
|
+
console.log('Current selection:', selection);
|
|
275
|
+
},
|
|
276
|
+
|
|
277
|
+
validateSelection() {
|
|
278
|
+
const isValid = this.$refs.spotWidget.validateSelection();
|
|
279
|
+
console.log('Selection is valid:', isValid);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
</script>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Available Methods
|
|
287
|
+
|
|
288
|
+
| Method | Return Type | Description |
|
|
289
|
+
|--------|-------------|-------------|
|
|
290
|
+
| `updateQuote(data)` | `Promise<boolean>` | Update the quote with new request data |
|
|
291
|
+
| `getSelection()` | `SelectionData \| null` | Get the current user selection |
|
|
292
|
+
| `validateSelection()` | `boolean` | Validate that the user has made a selection |
|
|
293
|
+
| `destroy()` | `void` | Destroy the widget instance and clean up resources |
|
|
294
|
+
|
|
295
|
+
## Configuration
|
|
296
|
+
|
|
297
|
+
### API Configuration
|
|
298
|
+
|
|
299
|
+
The `apiConfig` prop accepts the following options:
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
{
|
|
303
|
+
environment: 'production' | 'sandbox' | 'local',
|
|
304
|
+
partnerId: string,
|
|
305
|
+
customEndpoint?: string // Optional custom API endpoint
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Quote Request Data
|
|
310
|
+
|
|
311
|
+
#### Single Quote Format
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
{
|
|
315
|
+
startDate: string, // ISO 8601 date string
|
|
316
|
+
endDate: string, // ISO 8601 date string
|
|
317
|
+
currencyCode: 'USD' | 'CAD' | 'AUD',
|
|
318
|
+
eventType: string, // e.g., "Ski Trip", "Concert"
|
|
319
|
+
productType: 'Pass' | 'Trip' | 'Registration',
|
|
320
|
+
productDuration: 'Daily' | 'Seasonal' | 'Trip' | 'Event',
|
|
321
|
+
productPrice: number, // Price in specified currency
|
|
322
|
+
productId: string, // Unique product identifier
|
|
323
|
+
cartId: string, // Cart identifier
|
|
324
|
+
productName: string, // Human-readable product name
|
|
325
|
+
participantDescription?: string // Optional participant details
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
#### Batch Quote Format
|
|
330
|
+
|
|
331
|
+
For multiple items in a cart:
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
{
|
|
335
|
+
cartInfo: {
|
|
336
|
+
cartId: string,
|
|
337
|
+
cartName: string,
|
|
338
|
+
currencyCode: 'USD' | 'CAD' | 'AUD'
|
|
339
|
+
},
|
|
340
|
+
items: Array<{
|
|
341
|
+
// Same fields as single quote, minus cartId and currencyCode
|
|
342
|
+
cartItemId?: string // Optional unique identifier for cart item
|
|
343
|
+
}>
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Styling
|
|
348
|
+
|
|
349
|
+
Customize the widget appearance using the `theme` prop:
|
|
350
|
+
|
|
351
|
+
```vue
|
|
352
|
+
<template>
|
|
353
|
+
<Vue2SpotWidget
|
|
354
|
+
:theme="{
|
|
355
|
+
primaryColor: '#007bff',
|
|
356
|
+
borderRadius: '8px',
|
|
357
|
+
fontFamily: 'Arial, sans-serif'
|
|
358
|
+
}"
|
|
359
|
+
v-bind="otherProps"
|
|
360
|
+
/>
|
|
361
|
+
</template>
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Error Handling
|
|
365
|
+
|
|
366
|
+
Always implement error handling for production use:
|
|
367
|
+
|
|
368
|
+
```vue
|
|
369
|
+
<template>
|
|
370
|
+
<div>
|
|
371
|
+
<Vue2SpotWidget
|
|
372
|
+
v-bind="widgetProps"
|
|
373
|
+
@error="handleError"
|
|
374
|
+
@no-matching-quote="handleNoQuote"
|
|
375
|
+
/>
|
|
376
|
+
<div v-if="errorMessage" class="error-message">
|
|
377
|
+
{{ errorMessage }}
|
|
378
|
+
</div>
|
|
379
|
+
</div>
|
|
380
|
+
</template>
|
|
381
|
+
|
|
382
|
+
<script>
|
|
383
|
+
export default {
|
|
384
|
+
data() {
|
|
385
|
+
return {
|
|
386
|
+
errorMessage: ''
|
|
387
|
+
};
|
|
388
|
+
},
|
|
389
|
+
|
|
390
|
+
methods: {
|
|
391
|
+
handleError(error) {
|
|
392
|
+
console.error('Spot Widget Error:', error);
|
|
393
|
+
|
|
394
|
+
// Show user-friendly message
|
|
395
|
+
this.errorMessage = 'Unable to load refund options. Please try again.';
|
|
396
|
+
|
|
397
|
+
// Track error in analytics
|
|
398
|
+
if (window.analytics) {
|
|
399
|
+
window.analytics.track('spot_widget_error', {
|
|
400
|
+
message: error.message,
|
|
401
|
+
status: error.status
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
|
|
406
|
+
handleNoQuote() {
|
|
407
|
+
this.errorMessage = 'No refund guarantee available for this product.';
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
</script>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## Vue 2 Specific Notes
|
|
415
|
+
|
|
416
|
+
This package is specifically designed for Vue 2.x applications. Key differences from the Vue 3 version:
|
|
417
|
+
|
|
418
|
+
- Uses Vue 2 Options API syntax
|
|
419
|
+
- Compatible with Vue 2.6+ (requires Vue 2.7+ for full TypeScript support)
|
|
420
|
+
- Uses `beforeDestroy` lifecycle hook instead of `beforeUnmount`
|
|
421
|
+
- Function-based watchers instead of arrow functions for Vue 2 compatibility
|
|
422
|
+
|
|
423
|
+
## Compatibility
|
|
424
|
+
|
|
425
|
+
- **Vue**: 2.6+
|
|
426
|
+
- **TypeScript**: 4.x - 5.x (requires Vue 2.7+ for full TS support)
|
|
427
|
+
- **Node.js**: 16+
|
|
428
|
+
|
|
429
|
+
## Migration from Vue 2 to Vue 3
|
|
430
|
+
|
|
431
|
+
If you're migrating from Vue 2 to Vue 3, consider switching to `@getspot/spot-widget-vue` which is designed for Vue 3 and includes:
|
|
432
|
+
|
|
433
|
+
- Composition API support
|
|
434
|
+
- Better TypeScript integration
|
|
435
|
+
- Modern Vue 3 lifecycle hooks
|
|
436
|
+
- Enhanced performance
|
|
437
|
+
|
|
438
|
+
## License
|
|
439
|
+
|
|
440
|
+
See the main package for license information.
|
|
441
|
+
|
|
442
|
+
## Support
|
|
443
|
+
|
|
444
|
+
For support, please contact [support@getspot.com](mailto:support@getspot.com).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Vue from 'vue';
|
|
2
|
+
import type { SpotWidgetOptions, SelectionData, Quote } from '@getspot/spot-widget';
|
|
3
|
+
|
|
4
|
+
export interface Vue2SpotWidgetProps extends Omit<SpotWidgetOptions, 'location' | 'callbacks'> {
|
|
5
|
+
onQuoteRetrieved?: (quote: Quote) => void;
|
|
6
|
+
onOptIn?: (data: SelectionData) => void;
|
|
7
|
+
onOptOut?: (data: SelectionData) => void;
|
|
8
|
+
onError?: (error: { message: string; status?: number; responseBody?: any }) => void;
|
|
9
|
+
onNoMatchingQuote?: (data: { status: string; data: any }) => void;
|
|
10
|
+
onSelectionChange?: (data: SelectionData) => void;
|
|
11
|
+
callbacks?: SpotWidgetOptions['callbacks'];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface Vue2SpotWidgetMethods {
|
|
15
|
+
updateQuote: (newQuoteRequestData: SpotWidgetOptions['quoteRequestData']) => Promise<boolean>;
|
|
16
|
+
getSelection: () => SelectionData | null;
|
|
17
|
+
validateSelection: () => boolean;
|
|
18
|
+
destroy: () => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare const Vue2SpotWidget: Vue.Component<Vue2SpotWidgetProps, Vue2SpotWidgetMethods>;
|
|
22
|
+
|
|
23
|
+
export default Vue2SpotWidget;
|
package/package.json
CHANGED
|
@@ -1,22 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getspot/spot-widget-vue2",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
7
|
"main": "dist/index.umd.js",
|
|
8
8
|
"module": "dist/index.es.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"CHANGELOG.md"
|
|
14
|
+
],
|
|
9
15
|
"dependencies": {
|
|
10
|
-
"@getspot/spot-widget": "
|
|
16
|
+
"@getspot/spot-widget": "2.0.0"
|
|
11
17
|
},
|
|
12
18
|
"peerDependencies": {
|
|
13
19
|
"vue": "^2.6.0"
|
|
14
20
|
},
|
|
15
21
|
"devDependencies": {
|
|
16
22
|
"vite": "^4.0.0",
|
|
17
|
-
"@vitejs/plugin-vue2": "^2.0.0"
|
|
23
|
+
"@vitejs/plugin-vue2": "^2.0.0",
|
|
24
|
+
"vitest": "^0.34.0",
|
|
25
|
+
"@vitest/coverage-v8": "^0.34.0",
|
|
26
|
+
"jsdom": "^22.0.0",
|
|
27
|
+
"@vue/test-utils": "^1.3.6",
|
|
28
|
+
"vue": "^2.7.14",
|
|
29
|
+
"vue-template-compiler": "^2.7.14"
|
|
18
30
|
},
|
|
19
31
|
"scripts": {
|
|
20
|
-
"build": "vite build"
|
|
32
|
+
"build": "vite build && cp src/index.d.ts dist/index.d.ts",
|
|
33
|
+
"docs:readme": "node scripts/generate-readme.js",
|
|
34
|
+
"test": "vitest",
|
|
35
|
+
"test:watch": "vitest --watch",
|
|
36
|
+
"test:coverage": "vitest --coverage",
|
|
37
|
+
"test:ci": "vitest run --coverage"
|
|
21
38
|
}
|
|
22
39
|
}
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @getspot/spot-widget-vue2@1.4.0 build /builds/getspot/spot-widget/packages/vue2
|
|
3
|
-
> vite build
|
|
4
|
-
|
|
5
|
-
[36mvite v4.5.13 [32mbuilding for production...[36m[39m
|
|
6
|
-
transforming...
|
|
7
|
-
[32m✓[39m 2 modules transformed.
|
|
8
|
-
No name was provided for external module "@getspot/spot-widget" in "output.globals" – guessing "SpotWidget".
|
|
9
|
-
rendering chunks...
|
|
10
|
-
computing gzip size...
|
|
11
|
-
[2mdist/[22m[36mindex.umd.js [39m[1m[2m4.41 kB[22m[1m[22m[2m │ gzip: 1.47 kB[22m
|
|
12
|
-
[2mdist/[22m[36mindex.es.js [39m[1m[2m5.98 kB[22m[1m[22m[2m │ gzip: 1.66 kB[22m
|
|
13
|
-
[32m✓ built in 396ms[39m
|
package/src/Vue2SpotWidget.vue
DELETED
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div ref="container" />
|
|
3
|
-
</template>
|
|
4
|
-
|
|
5
|
-
<script>
|
|
6
|
-
import SpotWidget from "@getspot/spot-widget";
|
|
7
|
-
|
|
8
|
-
export default {
|
|
9
|
-
name: "Vue2SpotWidget",
|
|
10
|
-
props: {
|
|
11
|
-
apiConfig: {
|
|
12
|
-
type: Object,
|
|
13
|
-
default: undefined,
|
|
14
|
-
},
|
|
15
|
-
quoteRequestData: {
|
|
16
|
-
type: [Object, Array],
|
|
17
|
-
default: undefined,
|
|
18
|
-
},
|
|
19
|
-
showTable: {
|
|
20
|
-
type: Boolean,
|
|
21
|
-
default: true,
|
|
22
|
-
},
|
|
23
|
-
optInSelected: {
|
|
24
|
-
type: Boolean,
|
|
25
|
-
default: false,
|
|
26
|
-
},
|
|
27
|
-
theme: {
|
|
28
|
-
type: Object,
|
|
29
|
-
default: undefined,
|
|
30
|
-
},
|
|
31
|
-
callbacks: {
|
|
32
|
-
type: Object,
|
|
33
|
-
default: () => ({}),
|
|
34
|
-
},
|
|
35
|
-
onQuoteRetrieved: {
|
|
36
|
-
type: Function,
|
|
37
|
-
default: undefined,
|
|
38
|
-
},
|
|
39
|
-
onOptIn: {
|
|
40
|
-
type: Function,
|
|
41
|
-
default: undefined,
|
|
42
|
-
},
|
|
43
|
-
onOptOut: {
|
|
44
|
-
type: Function,
|
|
45
|
-
default: undefined,
|
|
46
|
-
},
|
|
47
|
-
onError: {
|
|
48
|
-
type: Function,
|
|
49
|
-
default: undefined,
|
|
50
|
-
},
|
|
51
|
-
onNoMatchingQuote: {
|
|
52
|
-
type: Function,
|
|
53
|
-
default: undefined,
|
|
54
|
-
},
|
|
55
|
-
onSelectionChange: {
|
|
56
|
-
type: Function,
|
|
57
|
-
default: undefined,
|
|
58
|
-
},
|
|
59
|
-
options: {
|
|
60
|
-
type: Object,
|
|
61
|
-
default: () => ({}),
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
data() {
|
|
65
|
-
return {
|
|
66
|
-
widget: null,
|
|
67
|
-
reinitTimeout: null,
|
|
68
|
-
};
|
|
69
|
-
},
|
|
70
|
-
computed: {
|
|
71
|
-
mergedCallbacks() {
|
|
72
|
-
return {
|
|
73
|
-
...this.callbacks,
|
|
74
|
-
...(this.onQuoteRetrieved && { onQuoteRetrieved: this.onQuoteRetrieved }),
|
|
75
|
-
...(this.onOptIn && {
|
|
76
|
-
onOptIn: (data) => {
|
|
77
|
-
if (this.onOptIn) this.onOptIn(data);
|
|
78
|
-
if (this.onSelectionChange) this.onSelectionChange(data);
|
|
79
|
-
}
|
|
80
|
-
}),
|
|
81
|
-
...(this.onOptOut && {
|
|
82
|
-
onOptOut: (data) => {
|
|
83
|
-
if (this.onOptOut) this.onOptOut(data);
|
|
84
|
-
if (this.onSelectionChange) this.onSelectionChange(data);
|
|
85
|
-
}
|
|
86
|
-
}),
|
|
87
|
-
...(this.onError && { onError: this.onError }),
|
|
88
|
-
...(this.onNoMatchingQuote && { onNoMatchingQuote: this.onNoMatchingQuote }),
|
|
89
|
-
};
|
|
90
|
-
},
|
|
91
|
-
widgetOptions() {
|
|
92
|
-
return {
|
|
93
|
-
apiConfig: this.apiConfig,
|
|
94
|
-
quoteRequestData: this.quoteRequestData,
|
|
95
|
-
showTable: this.showTable,
|
|
96
|
-
optInSelected: this.optInSelected,
|
|
97
|
-
theme: this.theme,
|
|
98
|
-
callbacks: this.mergedCallbacks,
|
|
99
|
-
...this.options,
|
|
100
|
-
};
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
mounted() {
|
|
104
|
-
this.initializeWidget();
|
|
105
|
-
},
|
|
106
|
-
watch: {
|
|
107
|
-
quoteRequestData: {
|
|
108
|
-
handler: function(newQuoteRequestData, oldQuoteRequestData) {
|
|
109
|
-
if (this.widget && newQuoteRequestData && JSON.stringify(newQuoteRequestData) !== JSON.stringify(oldQuoteRequestData)) {
|
|
110
|
-
// Debounce reinitialize to prevent multiple rapid updates
|
|
111
|
-
if (this.reinitTimeout) {
|
|
112
|
-
clearTimeout(this.reinitTimeout);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
this.reinitTimeout = setTimeout(() => {
|
|
116
|
-
this.reinitializeWidget();
|
|
117
|
-
this.reinitTimeout = null;
|
|
118
|
-
}, 100);
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
deep: true,
|
|
122
|
-
},
|
|
123
|
-
apiConfig: {
|
|
124
|
-
handler: function() {
|
|
125
|
-
this.reinitializeWidget();
|
|
126
|
-
},
|
|
127
|
-
deep: true,
|
|
128
|
-
},
|
|
129
|
-
showTable: function(newVal, oldVal) {
|
|
130
|
-
if (newVal !== oldVal) {
|
|
131
|
-
this.reinitializeWidget();
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
optInSelected: function(newVal, oldVal) {
|
|
135
|
-
if (newVal !== oldVal) {
|
|
136
|
-
this.reinitializeWidget();
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
theme: {
|
|
140
|
-
handler: function(newTheme, oldTheme) {
|
|
141
|
-
if (this.widget && JSON.stringify(newTheme) !== JSON.stringify(oldTheme)) {
|
|
142
|
-
this.updateTheme(newTheme);
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
deep: true,
|
|
146
|
-
},
|
|
147
|
-
mergedCallbacks: {
|
|
148
|
-
handler: function(newCallbacks, oldCallbacks) {
|
|
149
|
-
if (this.widget && JSON.stringify(newCallbacks) !== JSON.stringify(oldCallbacks)) {
|
|
150
|
-
this.updateCallbacks(newCallbacks);
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
deep: true,
|
|
154
|
-
},
|
|
155
|
-
},
|
|
156
|
-
methods: {
|
|
157
|
-
initializeWidget() {
|
|
158
|
-
// Destroy any existing widget first
|
|
159
|
-
if (this.widget) {
|
|
160
|
-
this.widget.destroy();
|
|
161
|
-
this.widget = null;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Clear the container completely
|
|
165
|
-
if (this.$refs.container) {
|
|
166
|
-
this.$refs.container.innerHTML = '';
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Add a small delay to ensure DOM is ready
|
|
170
|
-
this.$nextTick(() => {
|
|
171
|
-
try {
|
|
172
|
-
this.widget = new SpotWidget({
|
|
173
|
-
...this.widgetOptions,
|
|
174
|
-
location: this.$refs.container,
|
|
175
|
-
});
|
|
176
|
-
} catch (err) {
|
|
177
|
-
this.$emit("error", err);
|
|
178
|
-
if (this.onError) this.onError(err);
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
},
|
|
182
|
-
reinitializeWidget() {
|
|
183
|
-
if (this.widget) {
|
|
184
|
-
this.widget.destroy();
|
|
185
|
-
this.widget = null;
|
|
186
|
-
}
|
|
187
|
-
this.initializeWidget();
|
|
188
|
-
},
|
|
189
|
-
async updateQuote(newQuoteRequestData) {
|
|
190
|
-
return this.widget && this.widget.updateQuote ? this.widget.updateQuote(newQuoteRequestData) : undefined;
|
|
191
|
-
},
|
|
192
|
-
getSelection() {
|
|
193
|
-
return this.widget && this.widget.getSelection ? this.widget.getSelection() : undefined;
|
|
194
|
-
},
|
|
195
|
-
validateSelection() {
|
|
196
|
-
return this.widget && this.widget.validateSelection ? this.widget.validateSelection() : undefined;
|
|
197
|
-
},
|
|
198
|
-
updateTheme: function(newTheme) {
|
|
199
|
-
if (!this.widget || !this.widget.container) return;
|
|
200
|
-
|
|
201
|
-
var entries = Object.keys(newTheme || {});
|
|
202
|
-
for (var i = 0; i < entries.length; i++) {
|
|
203
|
-
var key = entries[i];
|
|
204
|
-
var value = newTheme[key];
|
|
205
|
-
var cssVariable = "--" + key;
|
|
206
|
-
this.widget.container.style.setProperty(cssVariable, value);
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
|
-
updateCallbacks: function(newCallbacks) {
|
|
210
|
-
if (!this.widget) return;
|
|
211
|
-
|
|
212
|
-
this.widget.options.callbacks = newCallbacks;
|
|
213
|
-
},
|
|
214
|
-
destroy() {
|
|
215
|
-
if (this.widget && typeof this.widget.destroy === "function") {
|
|
216
|
-
this.widget.destroy();
|
|
217
|
-
this.widget = null;
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
beforeDestroy() {
|
|
222
|
-
if (this.reinitTimeout) {
|
|
223
|
-
clearTimeout(this.reinitTimeout);
|
|
224
|
-
}
|
|
225
|
-
if (this.widget && typeof this.widget.destroy === "function") {
|
|
226
|
-
this.widget.destroy();
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
};
|
|
230
|
-
</script>
|
package/vite.config.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vite";
|
|
2
|
-
import vue from "@vitejs/plugin-vue2";
|
|
3
|
-
import path from "path";
|
|
4
|
-
|
|
5
|
-
export default defineConfig({
|
|
6
|
-
plugins: [vue()],
|
|
7
|
-
build: {
|
|
8
|
-
outDir: "dist",
|
|
9
|
-
lib: {
|
|
10
|
-
entry: path.resolve(__dirname, "src/Vue2SpotWidget.vue"),
|
|
11
|
-
name: "Vue2SpotWidget",
|
|
12
|
-
fileName: (format) => `index.${format}.js`,
|
|
13
|
-
formats: ["umd", "es"],
|
|
14
|
-
},
|
|
15
|
-
rollupOptions: {
|
|
16
|
-
external: ["vue", "@getspot/spot-widget"],
|
|
17
|
-
output: {
|
|
18
|
-
globals: {
|
|
19
|
-
vue: "Vue",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
});
|