@changebot/widgets-vue 0.0.4 → 0.0.7

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.
Files changed (2) hide show
  1. package/README.md +684 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,684 @@
1
+ # @changebot/widgets-vue
2
+
3
+ Vue wrapper components for [Changebot](https://www.changebot.ai) - beautiful, customizable widgets for displaying product updates and changelogs to your users.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @changebot/widgets-vue
9
+ ```
10
+
11
+ ### Peer Dependencies
12
+
13
+ This package requires Vue 3.0.0 or later:
14
+
15
+ ```bash
16
+ npm install vue
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```vue
22
+ <script setup>
23
+ import {
24
+ ChangebotProvider,
25
+ ChangebotBadge,
26
+ ChangebotPanel
27
+ } from '@changebot/widgets-vue';
28
+ </script>
29
+
30
+ <template>
31
+ <ChangebotProvider slug="your-team-slug">
32
+ <header>
33
+ <h1>My App</h1>
34
+ <ChangebotBadge />
35
+ </header>
36
+
37
+ <ChangebotPanel mode="drawer-right" />
38
+ </ChangebotProvider>
39
+ </template>
40
+ ```
41
+
42
+ ## Components
43
+
44
+ ### ChangebotProvider
45
+
46
+ The provider component manages state and data fetching for all child Changebot components. Wrap your components with this provider to enable automatic updates and state synchronization.
47
+
48
+ #### Props
49
+
50
+ | Prop | Type | Default | Description |
51
+ |------|------|---------|-------------|
52
+ | `slug` | `string` | required | Your Changebot team slug (from your Changebot dashboard) |
53
+ | `scope` | `string` | `"default"` | Scope identifier for isolating multiple instances |
54
+
55
+ #### Example
56
+
57
+ ```vue
58
+ <template>
59
+ <ChangebotProvider slug="acme-corp">
60
+ <!-- Your components -->
61
+ </ChangebotProvider>
62
+ </template>
63
+ ```
64
+
65
+ #### Multiple Instances
66
+
67
+ Use different scopes to run multiple independent instances:
68
+
69
+ ```vue
70
+ <template>
71
+ <div>
72
+ <ChangebotProvider slug="team-a" scope="team-a">
73
+ <ChangebotBadge scope="team-a" />
74
+ <ChangebotPanel scope="team-a" />
75
+ </ChangebotProvider>
76
+
77
+ <ChangebotProvider slug="team-b" scope="team-b">
78
+ <ChangebotBadge scope="team-b" />
79
+ <ChangebotPanel scope="team-b" />
80
+ </ChangebotProvider>
81
+ </div>
82
+ </template>
83
+ ```
84
+
85
+ ---
86
+
87
+ ### ChangebotBadge
88
+
89
+ A badge component that displays the count of new, unread updates. Clicking the badge opens the associated panel.
90
+
91
+ #### Props
92
+
93
+ | Prop | Type | Default | Description |
94
+ |------|------|---------|-------------|
95
+ | `scope` | `string` | `"default"` | Scope to connect to (must match provider scope) |
96
+ | `show-count` | `boolean` | `true` | Whether to display the numeric count |
97
+ | `theme` | `Theme` | - | Fixed theme (see Theming section) |
98
+ | `light` | `Theme` | - | Theme for light mode (auto-switches based on system preference) |
99
+ | `dark` | `Theme` | - | Theme for dark mode (auto-switches based on system preference) |
100
+
101
+ #### Example
102
+
103
+ ```vue
104
+ <template>
105
+ <!-- Basic usage -->
106
+ <ChangebotBadge />
107
+
108
+ <!-- With theme -->
109
+ <ChangebotBadge theme="catppuccin-mocha" />
110
+
111
+ <!-- Auto-switching theme -->
112
+ <ChangebotBadge
113
+ light="catppuccin-latte"
114
+ dark="catppuccin-mocha"
115
+ />
116
+
117
+ <!-- Hidden count (shows dot only) -->
118
+ <ChangebotBadge :show-count="false" />
119
+ </template>
120
+ ```
121
+
122
+ ---
123
+
124
+ ### ChangebotPanel
125
+
126
+ A panel component that displays your product updates. Can be displayed as a drawer (left/right) or centered modal.
127
+
128
+ #### Props
129
+
130
+ | Prop | Type | Default | Description |
131
+ |------|------|---------|-------------|
132
+ | `scope` | `string` | `"default"` | Scope to connect to (must match provider scope) |
133
+ | `mode` | `"drawer-left"` \| `"drawer-right"` \| `"modal"` | `"drawer-right"` | Display mode |
134
+ | `theme` | `Theme` | - | Fixed theme (see Theming section) |
135
+ | `light` | `Theme` | - | Theme for light mode (auto-switches based on system preference) |
136
+ | `dark` | `Theme` | - | Theme for dark mode (auto-switches based on system preference) |
137
+
138
+ #### Methods
139
+
140
+ Use template refs to access methods:
141
+
142
+ ```vue
143
+ <script setup>
144
+ import { ref } from 'vue';
145
+ import { ChangebotPanel } from '@changebot/widgets-vue';
146
+
147
+ const panelRef = ref(null);
148
+
149
+ const openPanel = async () => {
150
+ await panelRef.value?.open();
151
+ };
152
+
153
+ const closePanel = async () => {
154
+ await panelRef.value?.close();
155
+ };
156
+
157
+ // Set updates programmatically (for standalone usage)
158
+ const setUpdates = async (updates) => {
159
+ await panelRef.value?.setUpdates(updates);
160
+ };
161
+ </script>
162
+
163
+ <template>
164
+ <button @click="openPanel">Show Updates</button>
165
+ <ChangebotPanel
166
+ ref="panelRef"
167
+ mode="drawer-right"
168
+ theme="nord"
169
+ />
170
+ </template>
171
+ ```
172
+
173
+ #### Example
174
+
175
+ ```vue
176
+ <script setup>
177
+ import { ref } from 'vue';
178
+ import { ChangebotPanel } from '@changebot/widgets-vue';
179
+
180
+ const panelRef = ref(null);
181
+
182
+ const handleOpenPanel = async () => {
183
+ await panelRef.value?.open();
184
+ };
185
+ </script>
186
+
187
+ <template>
188
+ <button @click="handleOpenPanel">Show Updates</button>
189
+ <ChangebotPanel
190
+ ref="panelRef"
191
+ mode="drawer-right"
192
+ theme="nord"
193
+ />
194
+ </template>
195
+ ```
196
+
197
+ ---
198
+
199
+ ### ChangebotBanner
200
+
201
+ A banner component that displays a highlighted update at the top of your page. Automatically shows the most recent update marked with `highlight_target="banner"`.
202
+
203
+ #### Props
204
+
205
+ | Prop | Type | Default | Description |
206
+ |------|------|---------|-------------|
207
+ | `scope` | `string` | `"default"` | Scope to connect to (must match provider scope) |
208
+ | `theme` | `Theme` | - | Fixed theme (see Theming section) |
209
+ | `light` | `Theme` | - | Theme for light mode (auto-switches based on system preference) |
210
+ | `dark` | `Theme` | - | Theme for dark mode (auto-switches based on system preference) |
211
+
212
+ #### Methods
213
+
214
+ ```vue
215
+ <script setup>
216
+ import { ref } from 'vue';
217
+
218
+ const bannerRef = ref(null);
219
+
220
+ // Show banner with specific update
221
+ const showBanner = async (update) => {
222
+ await bannerRef.value?.show(update);
223
+ };
224
+
225
+ // Dismiss the banner
226
+ const dismissBanner = async () => {
227
+ await bannerRef.value?.dismiss();
228
+ };
229
+
230
+ // Toggle expanded state
231
+ const toggleBanner = async () => {
232
+ await bannerRef.value?.toggle();
233
+ };
234
+ </script>
235
+
236
+ <template>
237
+ <ChangebotBanner ref="bannerRef" theme="dracula" />
238
+ </template>
239
+ ```
240
+
241
+ #### Example
242
+
243
+ ```vue
244
+ <template>
245
+ <ChangebotBanner theme="dracula" />
246
+ </template>
247
+ ```
248
+
249
+ ---
250
+
251
+ ### ChangebotToast
252
+
253
+ A toast notification component that displays brief update notifications. Automatically shows the most recent update marked with `highlight_target="toast"`.
254
+
255
+ #### Props
256
+
257
+ | Prop | Type | Default | Description |
258
+ |------|------|---------|-------------|
259
+ | `scope` | `string` | `"default"` | Scope to connect to (must match provider scope) |
260
+ | `position` | `"top-left"` \| `"top-right"` \| `"bottom-left"` \| `"bottom-right"` | `"bottom-right"` | Screen position for the toast |
261
+ | `auto-dismiss` | `number` | - | Auto-dismiss after N seconds (optional) |
262
+ | `theme` | `Theme` | - | Fixed theme (see Theming section) |
263
+ | `light` | `Theme` | - | Theme for light mode (auto-switches based on system preference) |
264
+ | `dark` | `Theme` | - | Theme for dark mode (auto-switches based on system preference) |
265
+
266
+ #### Methods
267
+
268
+ ```vue
269
+ <script setup>
270
+ import { ref } from 'vue';
271
+
272
+ const toastRef = ref(null);
273
+
274
+ // Show toast with specific update
275
+ const showToast = async (update) => {
276
+ await toastRef.value?.show(update);
277
+ };
278
+
279
+ // Dismiss the toast
280
+ const dismissToast = async () => {
281
+ await toastRef.value?.dismiss();
282
+ };
283
+ </script>
284
+
285
+ <template>
286
+ <ChangebotToast
287
+ ref="toastRef"
288
+ position="bottom-right"
289
+ :auto-dismiss="5"
290
+ theme="tokyo-night"
291
+ />
292
+ </template>
293
+ ```
294
+
295
+ #### Example
296
+
297
+ ```vue
298
+ <template>
299
+ <ChangebotToast
300
+ position="bottom-right"
301
+ :auto-dismiss="5"
302
+ theme="tokyo-night"
303
+ />
304
+ </template>
305
+ ```
306
+
307
+ ---
308
+
309
+ ## Theming
310
+
311
+ Changebot widgets include 15 beautiful pre-built themes:
312
+
313
+ ### Available Themes
314
+
315
+ - **Catppuccin**: `catppuccin-latte` (light), `catppuccin-frappe`, `catppuccin-macchiato`, `catppuccin-mocha` (dark)
316
+ - **Gruvbox**: `gruvbox-light`, `gruvbox-dark`
317
+ - **Popular**: `dracula`, `nord`, `tokyo-night`, `cyberpunk`
318
+ - **Solarized**: `solarized-light`, `solarized-dark`
319
+ - **Everforest**: `everforest-light`, `everforest-dark`
320
+ - **Modern**: `baremetrics` (clean, professional light theme)
321
+
322
+ ### Using Themes
323
+
324
+ #### Fixed Theme
325
+
326
+ Use the `theme` prop for a theme that never changes:
327
+
328
+ ```vue
329
+ <template>
330
+ <ChangebotPanel theme="catppuccin-mocha" />
331
+ </template>
332
+ ```
333
+
334
+ #### Auto-Switching Theme
335
+
336
+ Use `light` and `dark` props to automatically switch based on user's system preference:
337
+
338
+ ```vue
339
+ <template>
340
+ <ChangebotPanel
341
+ light="catppuccin-latte"
342
+ dark="catppuccin-mocha"
343
+ />
344
+ </template>
345
+ ```
346
+
347
+ #### Apply to All Components
348
+
349
+ ```vue
350
+ <template>
351
+ <ChangebotProvider slug="acme">
352
+ <ChangebotBadge
353
+ light="gruvbox-light"
354
+ dark="gruvbox-dark"
355
+ />
356
+ <ChangebotPanel
357
+ light="gruvbox-light"
358
+ dark="gruvbox-dark"
359
+ />
360
+ <ChangebotBanner
361
+ light="gruvbox-light"
362
+ dark="gruvbox-dark"
363
+ />
364
+ <ChangebotToast
365
+ light="gruvbox-light"
366
+ dark="gruvbox-dark"
367
+ />
368
+ </ChangebotProvider>
369
+ </template>
370
+ ```
371
+
372
+ ---
373
+
374
+ ## Display Modes
375
+
376
+ The `ChangebotPanel` component supports three display modes:
377
+
378
+ ### drawer-right (default)
379
+
380
+ Slides in from the right side of the screen. Great for most applications.
381
+
382
+ ```vue
383
+ <template>
384
+ <ChangebotPanel mode="drawer-right" />
385
+ </template>
386
+ ```
387
+
388
+ ### drawer-left
389
+
390
+ Slides in from the left side of the screen. Useful when your navigation is on the right.
391
+
392
+ ```vue
393
+ <template>
394
+ <ChangebotPanel mode="drawer-left" />
395
+ </template>
396
+ ```
397
+
398
+ ### modal
399
+
400
+ Displays as a centered modal dialog with backdrop overlay. Best for focused, important updates.
401
+
402
+ ```vue
403
+ <template>
404
+ <ChangebotPanel mode="modal" />
405
+ </template>
406
+ ```
407
+
408
+ ---
409
+
410
+ ## Advanced Usage
411
+
412
+ ### Standalone Usage (Without Provider)
413
+
414
+ Components can work independently without a provider for simple use cases:
415
+
416
+ #### Standalone Badge
417
+
418
+ ```vue
419
+ <script setup>
420
+ import { ref } from 'vue';
421
+ import { ChangebotBadge } from '@changebot/widgets-vue';
422
+
423
+ const count = ref(3);
424
+ </script>
425
+
426
+ <template>
427
+ <ChangebotBadge :count="count" :show-count="true" />
428
+ </template>
429
+ ```
430
+
431
+ #### Standalone Panel
432
+
433
+ ```vue
434
+ <script setup>
435
+ import { ref } from 'vue';
436
+ import { ChangebotPanel } from '@changebot/widgets-vue';
437
+
438
+ const panelRef = ref(null);
439
+
440
+ const openWithUpdates = async () => {
441
+ await panelRef.value?.setUpdates([
442
+ {
443
+ id: 1,
444
+ title: 'New Feature',
445
+ content: '<p>Check out our new feature!</p>',
446
+ display_date: '2024-01-15',
447
+ published_at: '2024-01-15T10:00:00Z',
448
+ expires_on: null,
449
+ highlight_target: null,
450
+ hosted_url: null,
451
+ tags: [{ id: 1, name: 'Feature', color: '#3b82f6' }]
452
+ }
453
+ ]);
454
+ await panelRef.value?.open();
455
+ };
456
+ </script>
457
+
458
+ <template>
459
+ <button @click="openWithUpdates">Show Updates</button>
460
+ <ChangebotPanel ref="panelRef" />
461
+ </template>
462
+ ```
463
+
464
+ ---
465
+
466
+ ## Complete Examples
467
+
468
+ ### Basic Setup with All Components
469
+
470
+ ```vue
471
+ <script setup>
472
+ import {
473
+ ChangebotProvider,
474
+ ChangebotBadge,
475
+ ChangebotPanel,
476
+ ChangebotBanner,
477
+ ChangebotToast
478
+ } from '@changebot/widgets-vue';
479
+ </script>
480
+
481
+ <template>
482
+ <ChangebotProvider slug="acme-corp">
483
+ <!-- Banner appears automatically for banner-highlighted updates -->
484
+ <ChangebotBanner theme="catppuccin-mocha" />
485
+
486
+ <header>
487
+ <h1>ACME Corp</h1>
488
+ <!-- Badge shows count of new updates -->
489
+ <ChangebotBadge theme="catppuccin-mocha" />
490
+ </header>
491
+
492
+ <main>
493
+ <!-- Your app content -->
494
+ </main>
495
+
496
+ <!-- Panel opens when badge is clicked -->
497
+ <ChangebotPanel
498
+ mode="drawer-right"
499
+ theme="catppuccin-mocha"
500
+ />
501
+
502
+ <!-- Toast appears for toast-highlighted updates -->
503
+ <ChangebotToast
504
+ position="bottom-right"
505
+ :auto-dismiss="5"
506
+ theme="catppuccin-mocha"
507
+ />
508
+ </ChangebotProvider>
509
+ </template>
510
+ ```
511
+
512
+ ### Responsive Theme Example
513
+
514
+ ```vue
515
+ <script setup>
516
+ import {
517
+ ChangebotProvider,
518
+ ChangebotBadge,
519
+ ChangebotPanel
520
+ } from '@changebot/widgets-vue';
521
+ </script>
522
+
523
+ <template>
524
+ <!-- Automatically switches between light/dark based on system preference -->
525
+ <ChangebotProvider slug="acme-corp">
526
+ <header>
527
+ <h1>My App</h1>
528
+ <ChangebotBadge
529
+ light="catppuccin-latte"
530
+ dark="catppuccin-mocha"
531
+ />
532
+ </header>
533
+
534
+ <ChangebotPanel
535
+ mode="drawer-right"
536
+ light="catppuccin-latte"
537
+ dark="catppuccin-mocha"
538
+ />
539
+ </ChangebotProvider>
540
+ </template>
541
+ ```
542
+
543
+ ### Multiple Scopes Example
544
+
545
+ ```vue
546
+ <script setup>
547
+ import {
548
+ ChangebotProvider,
549
+ ChangebotBadge,
550
+ ChangebotPanel
551
+ } from '@changebot/widgets-vue';
552
+ </script>
553
+
554
+ <template>
555
+ <div>
556
+ <!-- Product Updates -->
557
+ <ChangebotProvider slug="product-updates" scope="product">
558
+ <section>
559
+ <h2>
560
+ Product News
561
+ <ChangebotBadge scope="product" theme="nord" />
562
+ </h2>
563
+ <ChangebotPanel scope="product" mode="drawer-right" theme="nord" />
564
+ </section>
565
+ </ChangebotProvider>
566
+
567
+ <!-- Company Announcements -->
568
+ <ChangebotProvider slug="company-news" scope="company">
569
+ <section>
570
+ <h2>
571
+ Company Announcements
572
+ <ChangebotBadge scope="company" theme="dracula" />
573
+ </h2>
574
+ <ChangebotPanel scope="company" mode="drawer-left" theme="dracula" />
575
+ </section>
576
+ </ChangebotProvider>
577
+ </div>
578
+ </template>
579
+ ```
580
+
581
+ ### Programmatic Control Example
582
+
583
+ ```vue
584
+ <script setup>
585
+ import { ref } from 'vue';
586
+ import {
587
+ ChangebotProvider,
588
+ ChangebotPanel
589
+ } from '@changebot/widgets-vue';
590
+
591
+ const panelRef = ref(null);
592
+
593
+ const showUpdates = async () => {
594
+ await panelRef.value?.open();
595
+ };
596
+
597
+ const hideUpdates = async () => {
598
+ await panelRef.value?.close();
599
+ };
600
+ </script>
601
+
602
+ <template>
603
+ <ChangebotProvider slug="acme-corp">
604
+ <div>
605
+ <button @click="showUpdates">Show Updates</button>
606
+ <button @click="hideUpdates">Hide Updates</button>
607
+ </div>
608
+
609
+ <ChangebotPanel ref="panelRef" mode="modal" />
610
+ </ChangebotProvider>
611
+ </template>
612
+ ```
613
+
614
+ ### Composition API Example
615
+
616
+ ```vue
617
+ <script setup>
618
+ import { ref, onMounted } from 'vue';
619
+ import {
620
+ ChangebotProvider,
621
+ ChangebotPanel
622
+ } from '@changebot/widgets-vue';
623
+
624
+ const panelRef = ref(null);
625
+ const isOpen = ref(false);
626
+
627
+ const togglePanel = async () => {
628
+ if (isOpen.value) {
629
+ await panelRef.value?.close();
630
+ } else {
631
+ await panelRef.value?.open();
632
+ }
633
+ isOpen.value = !isOpen.value;
634
+ };
635
+
636
+ // Auto-open on mount
637
+ onMounted(async () => {
638
+ await panelRef.value?.open();
639
+ isOpen.value = true;
640
+ });
641
+ </script>
642
+
643
+ <template>
644
+ <ChangebotProvider slug="acme-corp">
645
+ <button @click="togglePanel">
646
+ {{ isOpen ? 'Close' : 'Open' }} Updates
647
+ </button>
648
+
649
+ <ChangebotPanel
650
+ ref="panelRef"
651
+ mode="drawer-right"
652
+ theme="nord"
653
+ />
654
+ </ChangebotProvider>
655
+ </template>
656
+ ```
657
+
658
+ ---
659
+
660
+ ## TypeScript Support
661
+
662
+ This package includes TypeScript definitions out of the box. All components are fully typed.
663
+
664
+ ```vue
665
+ <script setup lang="ts">
666
+ import { ref } from 'vue';
667
+ import type { HTMLChangebotPanelElement } from '@changebot/widgets-vue';
668
+
669
+ const panelRef = ref<HTMLChangebotPanelElement | null>(null);
670
+ </script>
671
+ ```
672
+
673
+ ---
674
+
675
+ ## License
676
+
677
+ Apache-2.0
678
+
679
+ ## Links
680
+
681
+ - [Changebot Website](https://www.changebot.ai)
682
+ - [Documentation](https://docs.changebot.ai)
683
+ - [GitHub Repository](https://github.com/changebot-ai/widgets)
684
+ - [NPM Package](https://www.npmjs.com/package/@changebot/widgets-vue)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@changebot/widgets-vue",
3
- "version": "0.0.4",
3
+ "version": "0.0.7",
4
4
  "description": "Vue wrapper components for Changebot widgets",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@stencil/vue-output-target": "^0.11.8",
16
- "@changebot/core": "^0.0.4"
16
+ "@changebot/core": "^0.0.7"
17
17
  },
18
18
  "devDependencies": {
19
19
  "vue": "^3.3.0",