@rlse/widget 0.2.0 → 0.2.2

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 CHANGED
@@ -1,12 +1,14 @@
1
1
  # @rlse/widget
2
2
 
3
- React component for embedding [![](https://www.google.com/s2/favicons?domain=rlse.dev&sz=16) rlse.dev](https://rlse.dev) release notes directly in your application.
3
+ Multi-framework release notes widget for [![](https://www.google.com/s2/favicons?domain=rlse.dev&sz=16) rlse.dev](https://rlse.dev). Works with React, Vue, Angular, Svelte, Astro, and vanilla JavaScript.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@rlse/widget)](https://www.npmjs.com/package/@rlse/widget)
6
6
  [![Socket Badge](https://badge.socket.dev/npm/package/@rlse/widget/latest)](https://socket.dev/npm/package/@rlse/widget)
7
7
 
8
8
  ## Features
9
9
 
10
+ - **Multi-framework**: React, Vue, Angular, Svelte, Astro, Vanilla JS
11
+ - **Three variants**: Floating button, embedded panel, dropdown menu
10
12
  - **Smart triggers**: Manual button, auto-popup on new releases, or both
11
13
  - **Unread badge**: Shows count of unseen changes
12
14
  - **App filtering**: Show changes for a specific application or all
@@ -21,6 +23,8 @@ npm install @rlse/widget
21
23
 
22
24
  ## Quick Start
23
25
 
26
+ ### React / Next.js
27
+
24
28
  ```tsx
25
29
  import { RlseWidget } from '@rlse/widget';
26
30
 
@@ -34,6 +38,60 @@ function App() {
34
38
  }
35
39
  ```
36
40
 
41
+ ### Vue / Nuxt
42
+
43
+ ```vue
44
+ <script setup>
45
+ import { RlseWidget } from '@rlse/widget/vue';
46
+ </script>
47
+
48
+ <template>
49
+ <RlseWidget org-slug="your-org-slug" />
50
+ </template>
51
+ ```
52
+
53
+ ### Angular
54
+
55
+ ```ts
56
+ import { RlseWidgetComponent } from '@rlse/widget/angular';
57
+
58
+ @Component({
59
+ imports: [RlseWidgetComponent],
60
+ template: `<rlse-widget orgSlug="your-org-slug"></rlse-widget>`
61
+ })
62
+ ```
63
+
64
+ ### Svelte / SvelteKit
65
+
66
+ ```svelte
67
+ <script>
68
+ import { RlseWidget } from '@rlse/widget/svelte';
69
+ </script>
70
+
71
+ <RlseWidget orgSlug="your-org-slug" />
72
+ ```
73
+
74
+ ### Astro
75
+
76
+ ```astro
77
+ ---
78
+ import { RlseWidget } from '@rlse/widget/react'; // or vue/svelte
79
+ ---
80
+
81
+ <RlseWidget orgSlug="your-org-slug" client:load />
82
+ ```
83
+
84
+ ### Vanilla JS (CDN)
85
+
86
+ ```html
87
+ <script>
88
+ window.rlseWidgetConfig = {
89
+ orgSlug: 'your-org-slug',
90
+ };
91
+ </script>
92
+ <script async src="https://rlse.dev/widget.js"></script>
93
+ ```
94
+
37
95
  ## Configuration
38
96
 
39
97
  ### Required
@@ -56,9 +114,15 @@ function App() {
56
114
  | `primaryColor` | `string` | `#3b82f6` | Accent color (hex) |
57
115
  | `autoShowAfter` | `number` | `7` | Days before auto-popup triggers again |
58
116
 
59
- ## Full Example
117
+ ## Widget Variants
118
+
119
+ ### RlseWidget (Floating Button)
120
+
121
+ A floating trigger button that opens a modal. Best for standalone pages.
60
122
 
61
123
  ```tsx
124
+ import { RlseWidget } from '@rlse/widget';
125
+
62
126
  <RlseWidget
63
127
  orgSlug="acme-corp"
64
128
  appSlug="dashboard"
@@ -66,13 +130,43 @@ function App() {
66
130
  position="bottom-right"
67
131
  theme="auto"
68
132
  limit={5}
69
- triggerLabel="🎁 What's New"
70
- modalTitle="Acme Release Notes"
71
- primaryColor="#10b981"
72
- autoShowAfter={3}
73
- />
133
+ triggerLabel="What's New"
134
+ modalTitle="Release Notes"
135
+ primaryColor="#3b82f6"
136
+ />;
137
+ ```
138
+
139
+ ### RlseWidgetEmbed (Inline Panel)
140
+
141
+ An embeddable panel for sidebars or dedicated pages. Great for dashboards.
142
+
143
+ ```tsx
144
+ import { RlseWidgetEmbed } from '@rlse/widget';
145
+
146
+ <RlseWidgetEmbed
147
+ orgSlug="acme-corp"
148
+ appSlug="dashboard"
149
+ showHeader={true}
150
+ showFooter={true}
151
+ />;
74
152
  ```
75
153
 
154
+ ### RlseWidgetMenu (Dropdown)
155
+
156
+ A compact dropdown for navigation bars. Perfect for user menus.
157
+
158
+ ```tsx
159
+ import { RlseWidgetMenu } from '@rlse/widget';
160
+
161
+ <RlseWidgetMenu
162
+ orgSlug="acme-corp"
163
+ appSlug="dashboard"
164
+ triggerLabel="What's New"
165
+ />;
166
+ ```
167
+
168
+ ````
169
+
76
170
  ## Trigger Modes
77
171
 
78
172
  - **`manual`** — Floating button always visible; click to open. Unread badge shows unseen count.
@@ -93,7 +187,7 @@ Use `primaryColor` to match your brand:
93
187
 
94
188
  ```tsx
95
189
  <RlseWidget orgSlug="acme-corp" primaryColor="#ff6b6b" />
96
- ```
190
+ ````
97
191
 
98
192
  ## Troubleshooting
99
193
 
@@ -119,3 +213,4 @@ Use `primaryColor` to match your brand:
119
213
 
120
214
  - Email: support@rlse.dev
121
215
  - Dashboard: Settings → Widget Embed
216
+ - Full documentation: https://rlse.dev/docs/widget
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback } from 'react';
3
- import { renderDescription, formatChangeDate, getReleaseNotesUrl } from '@rlse/widget-core';
3
+ import { renderDescription, formatChangeDate, getReleaseNotesUrl, } from '@rlse/widget-core';
4
4
  import { DEFAULT_CONFIG } from './types';
5
5
  import { useWidgetData } from './useWidgetData';
6
6
  import { markAllChangesAsSeen, getUnreadCount } from './storage';
@@ -57,7 +57,10 @@ export function RlseWidgetEmbed(props) {
57
57
  borderRadius: 10,
58
58
  background: config.primaryColor || '#3b82f6',
59
59
  color: 'white',
60
- }, children: unreadCount }))] })), _jsx("div", { style: contentStyle, children: isLoading ? (_jsx("div", { style: { padding: 40, textAlign: 'center' }, children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { animation: 'spin 1s linear infinite' }, children: [_jsx("style", { children: `@keyframes spin{to{transform:rotate(360deg)}}` }), _jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })] }) })) : changes.length === 0 ? (_jsx("div", { style: { padding: 40, textAlign: 'center', color: '#64748b' }, children: _jsx("p", { children: "No release notes yet. Check back soon!" }) })) : (changes.map((change) => (_jsxs("article", { style: { padding: '16px 0', borderBottom: '1px solid var(--border, #e2e8f0)' }, children: [_jsxs("div", { style: {
60
+ }, children: unreadCount }))] })), _jsx("div", { style: contentStyle, children: isLoading ? (_jsx("div", { style: { padding: 40, textAlign: 'center' }, children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { animation: 'spin 1s linear infinite' }, children: [_jsx("style", { children: `@keyframes spin{to{transform:rotate(360deg)}}` }), _jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })] }) })) : changes.length === 0 ? (_jsx("div", { style: { padding: 40, textAlign: 'center', color: '#64748b' }, children: _jsx("p", { children: "No release notes yet. Check back soon!" }) })) : (changes.map((change) => (_jsxs("article", { style: {
61
+ padding: '16px 0',
62
+ borderBottom: '1px solid var(--border, #e2e8f0)',
63
+ }, children: [_jsxs("div", { style: {
61
64
  display: 'flex',
62
65
  alignItems: 'flex-start',
63
66
  justifyContent: 'space-between',
@@ -1,4 +1,4 @@
1
1
  export { RlseWidgetComponent } from './components/rlse-widget.component';
2
- export { WidgetDataService, type WidgetDataState } from './services/widget-data.service';
2
+ export { WidgetDataService, type WidgetDataState, } from './services/widget-data.service';
3
3
  export type { WidgetConfig, Change, WidgetChangesResponse, } from '@rlse/widget-core';
4
4
  export { DEFAULT_CONFIG } from '@rlse/widget-core';
@@ -1,5 +1,5 @@
1
1
  // Angular Components
2
2
  export { RlseWidgetComponent } from './components/rlse-widget.component';
3
3
  // Angular Services
4
- export { WidgetDataService } from './services/widget-data.service';
4
+ export { WidgetDataService, } from './services/widget-data.service';
5
5
  export { DEFAULT_CONFIG } from '@rlse/widget-core';
@@ -0,0 +1,19 @@
1
+ import type { WidgetChangesResponse } from './types';
2
+ export interface FetchChangesParams {
3
+ orgSlug: string;
4
+ appSlug?: string;
5
+ limit: number;
6
+ baseUrl: string;
7
+ signal?: AbortSignal;
8
+ }
9
+ export interface FetchChangesResult {
10
+ changes: WidgetChangesResponse['changes'];
11
+ error: Error | null;
12
+ }
13
+ export declare function fetchChanges({ orgSlug, appSlug, limit, baseUrl, signal, }: FetchChangesParams): Promise<FetchChangesResult>;
14
+ export declare class WidgetDataFetcher {
15
+ private abortController;
16
+ fetch(params: Omit<FetchChangesParams, 'signal'>): Promise<FetchChangesResult>;
17
+ abort(): void;
18
+ destroy(): void;
19
+ }
@@ -0,0 +1,64 @@
1
+ export async function fetchChanges({ orgSlug, appSlug, limit, baseUrl, signal, }) {
2
+ try {
3
+ // Validate baseUrl
4
+ if (!baseUrl || typeof baseUrl !== 'string') {
5
+ throw new Error(`Invalid baseUrl: ${baseUrl}`);
6
+ }
7
+ let url;
8
+ try {
9
+ url = new URL(`${baseUrl}/api/widget/changes`);
10
+ }
11
+ catch {
12
+ throw new Error(`Invalid baseUrl for widget API: ${baseUrl}`);
13
+ }
14
+ url.searchParams.set('orgSlug', orgSlug);
15
+ if (appSlug) {
16
+ url.searchParams.set('appSlug', appSlug);
17
+ }
18
+ url.searchParams.set('limit', limit.toString());
19
+ const response = await fetch(url.toString(), { signal });
20
+ if (!response.ok) {
21
+ throw new Error(`Failed to fetch changes: ${response.status}`);
22
+ }
23
+ const data = await response.json();
24
+ return { changes: data.changes, error: null };
25
+ }
26
+ catch (err) {
27
+ // Don't return error if request was aborted
28
+ if (err instanceof Error && err.name === 'AbortError') {
29
+ return { changes: [], error: null };
30
+ }
31
+ return {
32
+ changes: [],
33
+ error: err instanceof Error ? err : new Error('Unknown error'),
34
+ };
35
+ }
36
+ }
37
+ export class WidgetDataFetcher {
38
+ constructor() {
39
+ this.abortController = null;
40
+ }
41
+ async fetch(params) {
42
+ // Cancel any in-flight request
43
+ this.abort();
44
+ this.abortController = new AbortController();
45
+ const result = await fetchChanges({
46
+ ...params,
47
+ signal: this.abortController.signal,
48
+ });
49
+ // Clear controller after successful completion
50
+ if (this.abortController?.signal.aborted === false) {
51
+ this.abortController = null;
52
+ }
53
+ return result;
54
+ }
55
+ abort() {
56
+ if (this.abortController) {
57
+ this.abortController.abort();
58
+ this.abortController = null;
59
+ }
60
+ }
61
+ destroy() {
62
+ this.abort();
63
+ }
64
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Render a change description.
3
+ * - HTML content (new format): passed through after stripping event handlers
4
+ * and javascript: URLs as a safety net
5
+ * - Markdown content (legacy records): converted via simpleMarkdownToHtml
6
+ */
7
+ export declare function renderDescription(content: string): string;
8
+ export declare function escapeHtml(text: string): string;
9
+ export declare function formatChangeDate(timestamp: number): string;
10
+ export declare function getReleaseNotesUrl(baseUrl: string, orgSlug: string, appSlug?: string): string;
@@ -0,0 +1,92 @@
1
+ // No external imports needed
2
+ /**
3
+ * Render a change description.
4
+ * - HTML content (new format): passed through after stripping event handlers
5
+ * and javascript: URLs as a safety net
6
+ * - Markdown content (legacy records): converted via simpleMarkdownToHtml
7
+ */
8
+ export function renderDescription(content) {
9
+ if (!content)
10
+ return '';
11
+ if (content.trimStart().startsWith('<')) {
12
+ // HTML content: strip on* attributes and javascript: URLs
13
+ return content
14
+ .replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]*)/gi, '')
15
+ .replace(/href\s*=\s*"javascript:[^"]*"/gi, '')
16
+ .replace(/href\s*=\s*'javascript:[^']*'/gi, '');
17
+ }
18
+ return simpleMarkdownToHtml(content);
19
+ }
20
+ function simpleMarkdownToHtml(markdown) {
21
+ // Helper to sanitize URLs - only allow safe protocols
22
+ const isSafeUrl = (url) => {
23
+ try {
24
+ const parsed = new URL(url);
25
+ const protocol = parsed.protocol.replace(':', '');
26
+ return ['http', 'https', 'mailto', 'tel'].includes(protocol);
27
+ }
28
+ catch {
29
+ // Relative URLs are OK
30
+ return (url.startsWith('/') ||
31
+ url.startsWith('./') ||
32
+ url.startsWith('../') ||
33
+ !url.includes(':'));
34
+ }
35
+ };
36
+ return (markdown
37
+ // Escape HTML
38
+ .replace(/&/g, '&amp;')
39
+ .replace(/</g, '&lt;')
40
+ .replace(/>/g, '&gt;')
41
+ // Bold
42
+ .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
43
+ .replace(/__(.+?)__/g, '<strong>$1</strong>')
44
+ // Italic
45
+ .replace(/\*(.+?)\*/g, '<em>$1</em>')
46
+ .replace(/_(.+?)_/g, '<em>$1</em>')
47
+ // Code
48
+ .replace(/`(.+?)`/g, '<code style="background:var(--rlse-border);padding:2px 4px;border-radius:4px;font-family:monospace;font-size:90%;">$1</code>')
49
+ // Links - with URL validation
50
+ .replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_match, text, url) => {
51
+ if (isSafeUrl(url)) {
52
+ // Escape both url and text to prevent attribute injection and XSS
53
+ const safeUrl = url
54
+ .replace(/&/g, '&amp;')
55
+ .replace(/"/g, '&quot;')
56
+ .replace(/</g, '&lt;')
57
+ .replace(/>/g, '&gt;');
58
+ return `<a href="${safeUrl}" target="_blank" rel="noopener" style="color:var(--rlse-accent);text-decoration:none;">${text}</a>`;
59
+ }
60
+ return text.replace(/</g, '&lt;').replace(/>/g, '&gt;'); // Return escaped plain text for unsafe URLs
61
+ })
62
+ // Lists
63
+ .replace(/^- (.+)$/gm, '<li>$1</li>')
64
+ // Paragraphs
65
+ .split('\n\n')
66
+ .map((para) => para.startsWith('<li>') ? `<ul>${para}</ul>` : `<p>${para}</p>`)
67
+ .join(''));
68
+ }
69
+ export function escapeHtml(text) {
70
+ const div = document.createElement('div');
71
+ div.textContent = text;
72
+ return div.innerHTML;
73
+ }
74
+ export function formatChangeDate(timestamp) {
75
+ return new Date(timestamp).toLocaleDateString('en-US', {
76
+ year: 'numeric',
77
+ month: 'short',
78
+ day: 'numeric',
79
+ });
80
+ }
81
+ export function getReleaseNotesUrl(baseUrl, orgSlug, appSlug) {
82
+ try {
83
+ const parsed = new URL(baseUrl);
84
+ const base = `${parsed.protocol}//${orgSlug}.${parsed.host}`;
85
+ return appSlug ? `${base}/${appSlug}` : base;
86
+ }
87
+ catch {
88
+ return appSlug
89
+ ? `${baseUrl}/${orgSlug}/${appSlug}`
90
+ : `${baseUrl}/${orgSlug}`;
91
+ }
92
+ }
package/dist/storage.d.ts CHANGED
@@ -1 +1,11 @@
1
- export { getStorageKey, getLastVisitKey, getSeenChangesKey, getLastVisit, setLastVisit, getSeenChanges, markAllChangesAsSeen, getUnreadCount, shouldAutoShow, } from '@rlse/widget-core';
1
+ export declare function getStorageKey(orgSlug: string): string;
2
+ export declare function getLastVisitKey(orgSlug: string): string;
3
+ export declare function getSeenChangesKey(orgSlug: string): string;
4
+ export declare function getLastVisit(orgSlug: string): number | null;
5
+ export declare function setLastVisit(orgSlug: string): void;
6
+ export declare function getSeenChanges(orgSlug: string): string[];
7
+ export declare function markAllChangesAsSeen(orgSlug: string, changeIds: string[]): void;
8
+ export declare function getUnreadCount(orgSlug: string, changes: {
9
+ _id: string;
10
+ }[]): number;
11
+ export declare function shouldAutoShow(orgSlug: string, autoShowAfter: number): boolean;
package/dist/storage.js CHANGED
@@ -1,2 +1,80 @@
1
- // Re-export all storage functions from core
2
- export { getStorageKey, getLastVisitKey, getSeenChangesKey, getLastVisit, setLastVisit, getSeenChanges, markAllChangesAsSeen, getUnreadCount, shouldAutoShow, } from '@rlse/widget-core';
1
+ const STORAGE_KEY_PREFIX = 'rlse_widget_';
2
+ const LAST_VISIT_KEY_SUFFIX = '_last_visit';
3
+ const SEEN_CHANGES_KEY_SUFFIX = '_seen';
4
+ export function getStorageKey(orgSlug) {
5
+ return `${STORAGE_KEY_PREFIX}${orgSlug}`;
6
+ }
7
+ export function getLastVisitKey(orgSlug) {
8
+ return `${getStorageKey(orgSlug)}${LAST_VISIT_KEY_SUFFIX}`;
9
+ }
10
+ export function getSeenChangesKey(orgSlug) {
11
+ return `${getStorageKey(orgSlug)}${SEEN_CHANGES_KEY_SUFFIX}`;
12
+ }
13
+ export function getLastVisit(orgSlug) {
14
+ if (typeof window === 'undefined')
15
+ return null;
16
+ try {
17
+ const value = localStorage.getItem(getLastVisitKey(orgSlug));
18
+ if (!value)
19
+ return null;
20
+ const parsed = parseInt(value, 10);
21
+ return Number.isNaN(parsed) ? null : parsed;
22
+ }
23
+ catch {
24
+ return null;
25
+ }
26
+ }
27
+ export function setLastVisit(orgSlug) {
28
+ if (typeof window === 'undefined')
29
+ return;
30
+ try {
31
+ localStorage.setItem(getLastVisitKey(orgSlug), Date.now().toString());
32
+ }
33
+ catch {
34
+ // Ignore storage errors
35
+ }
36
+ }
37
+ export function getSeenChanges(orgSlug) {
38
+ if (typeof window === 'undefined')
39
+ return [];
40
+ try {
41
+ const value = localStorage.getItem(getSeenChangesKey(orgSlug));
42
+ if (!value)
43
+ return [];
44
+ const parsed = JSON.parse(value);
45
+ // Validate that parsed is an array of strings
46
+ if (!Array.isArray(parsed) ||
47
+ !parsed.every((item) => typeof item === 'string')) {
48
+ return [];
49
+ }
50
+ return parsed;
51
+ }
52
+ catch {
53
+ return [];
54
+ }
55
+ }
56
+ export function markAllChangesAsSeen(orgSlug, changeIds) {
57
+ if (typeof window === 'undefined')
58
+ return;
59
+ try {
60
+ localStorage.setItem(getSeenChangesKey(orgSlug), JSON.stringify(changeIds));
61
+ }
62
+ catch {
63
+ // Ignore storage errors
64
+ }
65
+ }
66
+ export function getUnreadCount(orgSlug, changes) {
67
+ if (typeof window === 'undefined')
68
+ return 0;
69
+ const seen = getSeenChanges(orgSlug);
70
+ return changes.filter((c) => !seen.includes(c._id)).length;
71
+ }
72
+ export function shouldAutoShow(orgSlug, autoShowAfter) {
73
+ if (typeof window === 'undefined')
74
+ return false;
75
+ const lastVisit = getLastVisit(orgSlug);
76
+ if (!lastVisit)
77
+ return true; // First visit
78
+ const daysSinceVisit = (Date.now() - lastVisit) / (1000 * 60 * 60 * 24);
79
+ return daysSinceVisit >= autoShowAfter;
80
+ }
package/dist/types.d.ts CHANGED
@@ -1,2 +1,54 @@
1
- export type { WidgetConfig, Change, WidgetChangesResponse, } from '@rlse/widget-core';
2
- export { DEFAULT_CONFIG } from '@rlse/widget-core';
1
+ export interface WidgetConfig {
2
+ /** Organization slug (required) */
3
+ orgSlug: string;
4
+ /** Optional app slug to filter changes */
5
+ appSlug?: string;
6
+ /** Trigger behavior: 'auto', 'manual', or 'both' */
7
+ trigger?: 'auto' | 'manual' | 'both';
8
+ /** Days since last visit to auto-show (for 'auto' or 'both') */
9
+ autoShowAfter?: number;
10
+ /** Maximum changes to display */
11
+ limit?: number;
12
+ /** Show status badges */
13
+ showStatus?: boolean;
14
+ /** Show creation dates */
15
+ showDates?: boolean;
16
+ /** Button position for manual trigger (floating widget only) */
17
+ position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
18
+ /** Theme: 'light', 'dark', or 'auto' */
19
+ theme?: 'light' | 'dark' | 'auto';
20
+ /** Primary accent color (hex) */
21
+ primaryColor?: string;
22
+ /** Button text (floating widget only) */
23
+ triggerLabel?: string;
24
+ /** Modal/Panel title */
25
+ modalTitle?: string;
26
+ /** Base URL for the server (optional, defaults to https://rlse.dev) */
27
+ baseUrl?: string;
28
+ }
29
+ export interface Change {
30
+ _id: string;
31
+ _creationTime: number;
32
+ changeName: string;
33
+ changeSummary: string;
34
+ changeDescription: string;
35
+ currentStatus: string;
36
+ appName?: string;
37
+ appSlug?: string;
38
+ }
39
+ export interface WidgetChangesResponse {
40
+ org: {
41
+ orgName: string;
42
+ orgSlug: string;
43
+ };
44
+ app?: {
45
+ appName: string;
46
+ appSlug: string;
47
+ };
48
+ changes: Change[];
49
+ meta: {
50
+ total: number;
51
+ limit: number;
52
+ };
53
+ }
54
+ export declare const DEFAULT_CONFIG: Partial<WidgetConfig>;
package/dist/types.js CHANGED
@@ -1 +1,12 @@
1
- export { DEFAULT_CONFIG } from '@rlse/widget-core';
1
+ export const DEFAULT_CONFIG = {
2
+ trigger: 'manual',
3
+ limit: 10,
4
+ showStatus: true,
5
+ showDates: true,
6
+ position: 'bottom-right',
7
+ theme: 'auto',
8
+ triggerLabel: "What's New",
9
+ modalTitle: 'Release Notes',
10
+ baseUrl: 'https://rlse.dev',
11
+ autoShowAfter: 7,
12
+ };
@@ -1,5 +1,5 @@
1
1
  import { ref, computed, onMounted, onUnmounted } from 'vue';
2
- import { fetchChanges, WidgetDataFetcher } from '@rlse/widget-core';
2
+ import { fetchChanges, WidgetDataFetcher, } from '@rlse/widget-core';
3
3
  export function useWidgetData(options) {
4
4
  const changes = ref([]);
5
5
  const isLoading = ref(true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rlse/widget",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Multi-framework release notes widget for rlse.dev - React, Vue, Angular, Svelte",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -87,7 +87,5 @@
87
87
  "embed"
88
88
  ],
89
89
  "license": "MIT",
90
- "dependencies": {
91
- "@rlse/widget-core": "../widget-core"
92
- }
90
+ "dependencies": {}
93
91
  }