@squeletteapp/widget 0.1.0 → 0.3.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.
Files changed (34) hide show
  1. package/README.md +112 -0
  2. package/dist/app-BpPatA6a.js +42 -0
  3. package/dist/index-B0eQqkb_.js +7951 -0
  4. package/dist/types/app/app.d.ts +15 -0
  5. package/dist/types/banner/banner-modal.d.ts +15 -0
  6. package/dist/types/banner/banner.d.ts +14 -0
  7. package/dist/types/banner/element.d.ts +7 -0
  8. package/dist/types/banner/index.d.ts +19 -0
  9. package/dist/types/index.d.ts +10 -0
  10. package/dist/types/utils.d.ts +2 -0
  11. package/dist/types/widget/__tests__/widget.test.d.ts +1 -0
  12. package/dist/types/widget/components/widget-shell.d.ts +8 -0
  13. package/dist/types/widget/constants.d.ts +9 -0
  14. package/dist/types/widget/core/custom-element.d.ts +142 -0
  15. package/dist/types/widget/core/global-api.d.ts +97 -0
  16. package/dist/types/widget/core/identity.d.ts +73 -0
  17. package/dist/types/widget/core/panel-dimensions.d.ts +36 -0
  18. package/dist/types/widget/core/positioning.d.ts +63 -0
  19. package/dist/types/widget/core/scroll-lock.d.ts +28 -0
  20. package/dist/types/widget/element.d.ts +90 -0
  21. package/dist/types/widget/events.d.ts +13 -0
  22. package/dist/types/widget/factories.d.ts +41 -0
  23. package/dist/types/widget/styles.d.ts +8 -0
  24. package/dist/types/widget/types.d.ts +79 -0
  25. package/dist/types/widget/utils.d.ts +12 -0
  26. package/dist/widget.es.js +14 -0
  27. package/dist/widget.js +168 -15
  28. package/package.json +32 -18
  29. package/dist/button-component.d.ts +0 -2
  30. package/dist/button-component.js +0 -158
  31. package/dist/index.d.ts +0 -26
  32. package/dist/index.js +0 -230
  33. package/dist/styles.css +0 -567
  34. package/dist/widget.d.ts +0 -42
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Minimal Preact component responsible for rendering the sandboxed iframe. By
3
+ * keeping the widget UI in an isolated module we can lazy-load it only when the
4
+ * launcher opens, keeping the initial footprint tiny.
5
+ */
6
+ import type { JSX } from "preact";
7
+ export interface WidgetFrameProps {
8
+ src: string;
9
+ title: string;
10
+ onLoaded?: () => void;
11
+ onClose: () => void;
12
+ }
13
+ export declare function WidgetFrame({ src, title, onLoaded, onClose, }: WidgetFrameProps): JSX.Element;
14
+ export declare const stylesText: string;
15
+ export default WidgetFrame;
@@ -0,0 +1,15 @@
1
+ type Ticket = {
2
+ title: string;
3
+ id: number;
4
+ workspace: {
5
+ slug: string;
6
+ };
7
+ created_at: string;
8
+ };
9
+ export declare const showModal: import("@preact/signals").Signal<boolean>;
10
+ export declare const modalTicket: import("@preact/signals").Signal<Ticket | null>;
11
+ export declare function BannerModal({ workspaceSlug, theme, }: {
12
+ workspaceSlug: string;
13
+ theme: "light" | "dark";
14
+ }): import("preact").VNode<any> | null;
15
+ export {};
@@ -0,0 +1,14 @@
1
+ type SqueletteBannerWidgetProps = {
2
+ workspaceSlug: string;
3
+ theme: "light" | "dark";
4
+ };
5
+ export declare function Banner({ workspaceSlug, theme, }: SqueletteBannerWidgetProps): import("preact").JSX.Element | null;
6
+ type MarqueeSpanProps = {
7
+ children: string;
8
+ duration?: number;
9
+ gap?: number;
10
+ className?: string;
11
+ delay?: number;
12
+ };
13
+ export declare function MarqueeSpan({ children, duration, gap, className, delay, }: MarqueeSpanProps): import("preact").JSX.Element;
14
+ export {};
@@ -0,0 +1,7 @@
1
+ declare class SqueletteBannerElement extends HTMLElement {
2
+ private shadow;
3
+ constructor();
4
+ connectedCallback(): void;
5
+ disconnectedCallback(): void;
6
+ }
7
+ export { SqueletteBannerElement };
@@ -0,0 +1,19 @@
1
+ import { SqueletteBannerElement } from "./element";
2
+ export { SqueletteBannerElement };
3
+ type BannerInitPayload = {
4
+ slug: string;
5
+ contentTheme?: "light" | "dark";
6
+ theme?: BannerTheme;
7
+ };
8
+ export type BannerTheme = {
9
+ bg?: string;
10
+ border?: string;
11
+ text?: string;
12
+ badgeBg?: string;
13
+ badgeText?: string;
14
+ buttonHover?: string | number;
15
+ };
16
+ export declare const SqueletteBanner: {
17
+ init({ slug, theme, contentTheme, }: BannerInitPayload): SqueletteBannerElement | null;
18
+ setTheme(theme: BannerTheme): void;
19
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Public entry-point that re-exports the custom element and typings. Consumers
3
+ * importing via ESM or CommonJS land here after bundling.
4
+ */
5
+ export * from "./widget/element";
6
+ export { type WidgetTheme, type WidgetEventName, type WidgetEventListener, type WidgetEventDetailMap, type WidgetSubmitPayload, type CreateWidgetOptions, type WidgetView, type WidgetIdentityPayload, type WidgetPosition, type WidgetFloatingPosition, type WidgetFixedPosition, } from "./widget/types";
7
+ export { identify, clearIdentity } from "./widget/element";
8
+ export { createWidget, createFeedbackWidget, createRoadmapWidget, createChangelogWidget, } from "./widget/factories";
9
+ export * from "./banner";
10
+ export type { BannerTheme } from "./banner";
@@ -0,0 +1,2 @@
1
+ import { type ClassValue } from "clsx";
2
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Presentational shell rendered inside the widget's shadow root. It hosts the
3
+ * launcher button, overlay, and the lazy-loaded iframe container while keeping
4
+ * the custom element class free of JSX and rendering concerns.
5
+ */
6
+ import type { JSX } from "preact";
7
+ import type { WidgetShellProps } from "../types";
8
+ export declare function WidgetShell({ open, label, iframeSrc, FrameComponent, ensureFrame, onOpen, onClose, onFrameLoaded, }: WidgetShellProps): JSX.Element;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Centralised constants that define the public identity of the widget bundle.
3
+ * These values are relied upon across the element implementation and by the
4
+ * CDN embed snippet, so keep them in one place to avoid drift.
5
+ */
6
+ export declare const TAG_NAME = "squelette-widget";
7
+ export declare const API_BASE: string;
8
+ export declare const CDN_BASE = "https://cdn.squelette.app/widget.js";
9
+ export declare const DEFAULT_LABEL = "Feedback";
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Custom Element Implementation
3
+ *
4
+ * Defines the `<squelette-widget>` custom element that powers the widget system.
5
+ * This class extends HTMLElement to create a fully-featured web component with:
6
+ *
7
+ * **Core Features:**
8
+ * - Shadow DOM encapsulation for style isolation
9
+ * - Lazy loading of iframe renderer (loaded only when widget opens)
10
+ * - Reactive attribute system using observed attributes
11
+ * - Event emitter for widget lifecycle events (open, close, submit)
12
+ * - Theme management with auto/light/dark modes
13
+ * - Internationalization support
14
+ *
15
+ * **State Management:**
16
+ * - Tracks open/closed state
17
+ * - Manages iframe loading state
18
+ * - Handles user identity forwarding to iframe
19
+ * - Coordinates scroll locking when panel is open
20
+ *
21
+ * **Communication:**
22
+ * - PostMessage API for iframe communication
23
+ * - CustomEvent system for host application integration
24
+ * - Event emitter pattern for programmatic access
25
+ *
26
+ * The element is designed to be used both declaratively (HTML attributes)
27
+ * and programmatically (JavaScript API), making it flexible for different
28
+ * integration patterns.
29
+ *
30
+ * @example
31
+ * ```html
32
+ * <!-- Declarative usage -->
33
+ * <squelette-widget
34
+ * project="my-project"
35
+ * board="feedback"
36
+ * theme="auto"
37
+ * locale="en"
38
+ * ></squelette-widget>
39
+ * ```
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * // Programmatic usage
44
+ * const widget = document.querySelector('squelette-widget');
45
+ * await widget.open();
46
+ * widget.on('submit', (event) => {
47
+ * console.log('Feedback submitted:', event.payload);
48
+ * });
49
+ * ```
50
+ */
51
+ import { type WidgetEventListener, type WidgetEventName } from "../types";
52
+ /**
53
+ * Custom element class for `<squelette-widget>`.
54
+ *
55
+ * This is the main widget component that handles all widget functionality
56
+ * including rendering, state management, event handling, and iframe coordination.
57
+ */
58
+ export declare class SqueletteWidgetElement extends HTMLElement {
59
+ #private;
60
+ /**
61
+ * Attributes that trigger attributeChangedCallback when modified.
62
+ */
63
+ static get observedAttributes(): string[];
64
+ constructor();
65
+ /**
66
+ * Called when element is inserted into the DOM.
67
+ * Initializes configuration from attributes and sets up event listeners.
68
+ */
69
+ connectedCallback(): void;
70
+ /**
71
+ * Called when element is removed from the DOM.
72
+ * Cleans up all event listeners and restores page state.
73
+ */
74
+ disconnectedCallback(): void;
75
+ /**
76
+ * Called when observed attributes change.
77
+ * Updates internal configuration and triggers re-render.
78
+ */
79
+ attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
80
+ /**
81
+ * Opens the widget panel.
82
+ * @public
83
+ */
84
+ open(): Promise<void>;
85
+ /**
86
+ * Closes the widget panel.
87
+ * @public
88
+ */
89
+ close(): Promise<void>;
90
+ /**
91
+ * Toggles the widget panel open/closed state.
92
+ * @public
93
+ */
94
+ toggle(): Promise<void>;
95
+ /**
96
+ * Registers an event listener for widget events.
97
+ * @public
98
+ * @returns Cleanup function to remove the listener
99
+ */
100
+ on<K extends WidgetEventName>(event: K, handler: WidgetEventListener<K>): () => void;
101
+ /**
102
+ * Destroys the widget and removes it from the DOM.
103
+ * Cleans up all resources and event listeners.
104
+ * @public
105
+ */
106
+ destroy(): Promise<void>;
107
+ /**
108
+ * Renders the widget UI using Preact.
109
+ * @private
110
+ */
111
+ private render;
112
+ /**
113
+ * Lazy loads the iframe frame module when needed.
114
+ * @private
115
+ */
116
+ private ensureFrameModule;
117
+ /**
118
+ * Called when iframe finishes loading.
119
+ * @private
120
+ */
121
+ private handleFrameLoaded;
122
+ /**
123
+ * Updates the open/closed state and manages side effects.
124
+ * @private
125
+ */
126
+ private setOpen;
127
+ /**
128
+ * Applies theme and sets up theme change listeners.
129
+ * @private
130
+ */
131
+ private applyTheme;
132
+ /**
133
+ * Posts identity payload to iframe via postMessage.
134
+ * @private
135
+ */
136
+ private postIdentityToFrame;
137
+ }
138
+ /**
139
+ * Registers the custom element if not already registered.
140
+ * @internal
141
+ */
142
+ export declare function registerSqueletteWidget(): void;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Global API Helper
3
+ *
4
+ * Creates and exposes the `window.SqueletteWidget` global API for widget integrations.
5
+ * This module provides convenient factory functions and utilities that make
6
+ * it easy to create and configure widgets without using the custom element directly.
7
+ *
8
+ * **Available API Methods:**
9
+ *
10
+ * 1. `create()` - Flexible widget factory
11
+ * 2. `createFeedbackWidget()` - Specialized feedback widget factory
12
+ * 3. `createRoadmapWidget()` - Specialized roadmap widget factory
13
+ * 4. `createChangelogWidget()` - Specialized changelog widget factory
14
+ * 5. `identify()` - Set user identity across all widgets
15
+ * 6. `clearIdentity()` - Clear user identity
16
+ *
17
+ * **Specialized Options:**
18
+ * The specialized factories support advanced positioning options including:
19
+ * - Button-anchored positioning with collision detection
20
+ * - Fixed viewport positioning (9 preset positions)
21
+ * - Overlay blur effects
22
+ * - Custom event callbacks
23
+ * - Click-outside-to-close behavior
24
+ *
25
+ * This API maintains backward compatibility with existing integrations while
26
+ * internally using the modern custom element system.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * // Modern API
31
+ * const widget = SqueletteWidget.create({
32
+ * project: 'my-project',
33
+ * board: 'feedback',
34
+ * view: 'feedback'
35
+ * });
36
+ *
37
+ * // Specialized API
38
+ * const widget = SqueletteWidget.createFeedbackWidget('my-project', 'feedback', {
39
+ * buttonSelector: '#feedback-btn',
40
+ * position: 'bottom'
41
+ * });
42
+ *
43
+ * // Identity management
44
+ * SqueletteWidget.identify({
45
+ * userId: '123',
46
+ * email: 'user@example.com',
47
+ * signature: 'hmac-sig'
48
+ * });
49
+ * ```
50
+ */
51
+ import type { CreateWidgetOptions } from "../types";
52
+ import { SqueletteWidgetElement } from "./custom-element";
53
+ import { type PositioningOptions } from "./positioning";
54
+ import { identify as identityIdentify, clearIdentity as identityClearIdentity } from "./identity";
55
+ import { SqueletteBanner } from "../../banner";
56
+ /**
57
+ * Widget options that extend positioning options.
58
+ * Omits project/board/view as these are passed separately in some factory APIs.
59
+ */
60
+ type WidgetFactoryOptions = Omit<CreateWidgetOptions, "project" | "board" | "view"> & PositioningOptions;
61
+ /**
62
+ * Global API interface exposed on window.SqueletteWidget
63
+ */
64
+ export interface GlobalSqueletteWidget {
65
+ /** Modern widget factory */
66
+ create: (options: CreateWidgetOptions) => SqueletteWidgetElement;
67
+ /** Specialized feedback widget factory */
68
+ createFeedbackWidget: (project: string, board?: string | null, options?: WidgetFactoryOptions) => SqueletteWidgetElement;
69
+ /** Specialized roadmap widget factory */
70
+ createRoadmapWidget: (project: string, board?: string | null, options?: WidgetFactoryOptions) => SqueletteWidgetElement;
71
+ /** Specialized changelog widget factory */
72
+ createChangelogWidget: (project: string, options?: WidgetFactoryOptions) => SqueletteWidgetElement;
73
+ /** Set user identity */
74
+ identify: typeof identityIdentify;
75
+ /** Clear user identity */
76
+ clearIdentity: typeof identityClearIdentity;
77
+ /** Banner API */
78
+ banner: typeof SqueletteBanner;
79
+ /** Widget version */
80
+ version: string;
81
+ /** CDN base URL */
82
+ cdn: string;
83
+ }
84
+ /**
85
+ * Initializes and exposes the global SqueletteWidget API.
86
+ * This function is called once during module initialization.
87
+ *
88
+ * If the API already exists (e.g., from a previous script load),
89
+ * this function does nothing to avoid conflicts.
90
+ */
91
+ export declare function ensureGlobalHelper(): void;
92
+ declare global {
93
+ interface Window {
94
+ SqueletteWidget?: GlobalSqueletteWidget;
95
+ }
96
+ }
97
+ export {};
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Identity Management Module
3
+ *
4
+ * Handles user identification for the widget system. This module provides:
5
+ * - A global identity store accessible across all widget instances
6
+ * - Event-based identity updates using CustomEvents
7
+ * - Type-safe identity payload validation
8
+ * - Centralized identity state management
9
+ *
10
+ * The identity system works by:
11
+ * 1. Storing identity payload in module-level state
12
+ * 2. Broadcasting changes via 'squelette:identity' CustomEvent
13
+ * 3. Widget instances listen to this event and forward to iframes
14
+ *
15
+ * This allows multiple widget instances to share the same user identity
16
+ * without prop drilling or complex state management.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * // Set user identity
21
+ * identify({
22
+ * userId: '123',
23
+ * email: 'user@example.com',
24
+ * signature: 'hmac-signature'
25
+ * });
26
+ *
27
+ * // Clear identity
28
+ * clearIdentity();
29
+ * ```
30
+ */
31
+ import type { WidgetIdentityPayload } from '../types';
32
+ /**
33
+ * Sets the user identity for all widget instances.
34
+ *
35
+ * This function validates the payload and broadcasts the identity
36
+ * to all active widget instances via a CustomEvent. Each widget
37
+ * will then forward this information to its iframe.
38
+ *
39
+ * @param payload - User identification data including userId, email, and HMAC signature
40
+ * @throws {Error} Logs an error if payload is invalid (missing required fields)
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * identify({
45
+ * userId: 'user_123',
46
+ * email: 'john@example.com',
47
+ * signature: 'hmac_abc123',
48
+ * name: 'John Doe', // optional
49
+ * avatar: 'https://...', // optional
50
+ * });
51
+ * ```
52
+ */
53
+ export declare function identify(payload: WidgetIdentityPayload): void;
54
+ /**
55
+ * Clears the current user identity for all widget instances.
56
+ *
57
+ * This removes the stored identity and notifies all widgets
58
+ * to clear their identity state, typically used on logout.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * // On user logout
63
+ * clearIdentity();
64
+ * ```
65
+ */
66
+ export declare function clearIdentity(): void;
67
+ /**
68
+ * Gets the current identity payload.
69
+ *
70
+ * @internal This is used internally by widget instances
71
+ * @returns The current identity payload, or null if no user is identified
72
+ */
73
+ export declare function getIdentityPayload(): WidgetIdentityPayload | null;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Panel Dimensions Configuration
3
+ *
4
+ * Defines the default dimensions for different widget views (feedback, roadmap, changelog).
5
+ * Each view has optimized width and height values based on its content requirements:
6
+ *
7
+ * - Feedback: Compact form for quick feedback submission
8
+ * - Roadmap: Medium height for displaying planned features
9
+ * - Changelog: Taller panel for scrolling through updates
10
+ *
11
+ * These dimensions are applied as CSS custom properties (--sq-panel-width, --sq-panel-height)
12
+ * to the custom element, allowing the widget to adapt its size based on the active view.
13
+ */
14
+ import type { WidgetView } from "../types";
15
+ /**
16
+ * Default dimensions for each widget view type.
17
+ * Values are in pixels and represent the ideal size for each view's content.
18
+ */
19
+ export declare const PANEL_DIMENSIONS: Record<WidgetView, {
20
+ width: number;
21
+ height: number;
22
+ }>;
23
+ /**
24
+ * Fallback dimensions when view type is unknown or not specified.
25
+ */
26
+ export declare const DEFAULT_PANEL_DIMENSIONS: {
27
+ width: number;
28
+ height: number;
29
+ };
30
+ /**
31
+ * Applies panel dimensions to the widget element as CSS custom properties.
32
+ *
33
+ * @param element - The widget element to apply dimensions to
34
+ * @param view - The widget view type (feedback, roadmap, or changelog)
35
+ */
36
+ export declare function applyPanelDimensions(element: HTMLElement, view: WidgetView): void;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Widget Positioning System
3
+ *
4
+ * Handles advanced positioning logic for the widget.
5
+ * This module supports two positioning modes:
6
+ *
7
+ * 1. **Button-anchored positioning**: Widget appears relative to a trigger button
8
+ * - Dynamically calculates optimal placement (top/bottom/left/right)
9
+ * - Automatically repositions on scroll/resize
10
+ * - Ensures widget stays within viewport bounds
11
+ * - Supports collision detection and smart fallback positioning
12
+ *
13
+ * 2. **Fixed positioning**: Widget appears at a fixed viewport location
14
+ * - Supports 9 preset positions (fixed-top-left, fixed-center-center, etc.)
15
+ * - Maintains position regardless of page scroll
16
+ * - Respects viewport margins and responsive layouts
17
+ *
18
+ * This module also handles:
19
+ * - Click-outside detection to close the widget
20
+ * - Overlay blur effects
21
+ * - Custom button selector binding
22
+ * - Lifecycle cleanup for event listeners
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const cleanup = applyPositioning(element, {
27
+ * buttonSelector: '#feedback-button',
28
+ * position: 'bottom',
29
+ * overlayBlur: true
30
+ * });
31
+ *
32
+ * // Later: cleanup all event listeners
33
+ * cleanup();
34
+ * ```
35
+ */
36
+ import type { SqueletteWidgetElement } from "./custom-element";
37
+ import type { WidgetPosition } from "../types";
38
+ /**
39
+ * Widget positioning and binding options.
40
+ */
41
+ export interface PositioningOptions {
42
+ /** CSS selector for the button that triggers the widget */
43
+ buttonSelector?: string;
44
+ /** Preferred position relative to button or fixed viewport position */
45
+ position?: WidgetPosition;
46
+ /** Whether to apply blur effect to the overlay backdrop */
47
+ overlayBlur?: boolean;
48
+ /** Callback when widget open state changes */
49
+ onOpenChange?: (open: boolean) => void;
50
+ /** Callback when widget iframe finishes loading */
51
+ onLoad?: () => void;
52
+ }
53
+ /**
54
+ * Applies positioning and event bindings to a widget element.
55
+ *
56
+ * This function sets up all the positioning logic, event listeners, and
57
+ * custom behaviors needed for the widget.
58
+ *
59
+ * @param element - The widget element to enhance
60
+ * @param options - Positioning and behavior options
61
+ * @returns Array of cleanup functions to remove all applied behaviors
62
+ */
63
+ export declare function applyPositioning(element: SqueletteWidgetElement, options: PositioningOptions): Array<() => void>;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Body Scroll Lock Utility
3
+ *
4
+ * Manages the locking and unlocking of body scroll when the widget panel is open.
5
+ * This prevents the underlying page from scrolling while the user interacts with
6
+ * the widget overlay.
7
+ *
8
+ * Key behaviors:
9
+ * - Locks body scroll by setting `overflow: hidden`
10
+ * - Calculates and compensates for scrollbar width to prevent layout shift
11
+ * - Returns a cleanup function to restore original scroll state
12
+ * - Preserves original overflow and padding-right values
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const restoreScroll = toggleBodyScroll(true);
17
+ * // ... widget is open, body cannot scroll
18
+ * restoreScroll(); // restore original scroll behavior
19
+ * ```
20
+ */
21
+ /**
22
+ * Toggles body scroll lock and compensates for scrollbar width
23
+ * to prevent layout shift.
24
+ *
25
+ * @param lock - Whether to lock (true) or unlock (false) body scroll
26
+ * @returns A cleanup function that restores the original scroll state
27
+ */
28
+ export declare function toggleBodyScroll(lock: boolean): () => void;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Widget Element Module
3
+ *
4
+ * This is the main entry point for the widget's custom element implementation.
5
+ * It has been refactored into smaller, focused modules for better maintainability:
6
+ *
7
+ * **Module Structure:**
8
+ *
9
+ * - `core/custom-element.ts` - The `<squelette-widget>` custom element class
10
+ * - Handles Shadow DOM, lifecycle methods, attribute observation
11
+ * - Manages widget state (open/closed, loading, theme)
12
+ * - Coordinates iframe loading and communication
13
+ *
14
+ * - `core/identity.ts` - User identity management
15
+ * - Global identity store for all widget instances
16
+ * - `identify()` and `clearIdentity()` functions
17
+ * - Event-based identity synchronization
18
+ *
19
+ * - `core/scroll-lock.ts` - Body scroll management
20
+ * - Locks page scroll when widget is open
21
+ * - Compensates for scrollbar width to prevent layout shift
22
+ *
23
+ * - `core/panel-dimensions.ts` - Widget panel dimensions
24
+ * - Default dimensions for each view type (feedback, roadmap, changelog)
25
+ * - CSS custom property application
26
+ *
27
+ * - `core/positioning.ts` - Advanced positioning system
28
+ * - Button-anchored positioning with collision detection
29
+ * - Fixed viewport positioning (9 preset positions)
30
+ * - Click-outside-to-close behavior
31
+ * - Responsive viewport tracking
32
+ *
33
+ * - `core/global-api.ts` - Global `window.SqueletteWidget` API
34
+ * - Factory functions for creating widgets
35
+ * - Convenient JavaScript API layer
36
+ * - Version and CDN information
37
+ *
38
+ * **Usage:**
39
+ *
40
+ * Declarative (HTML):
41
+ * ```html
42
+ * <squelette-widget
43
+ * project="my-project"
44
+ * board="feedback"
45
+ * theme="auto"
46
+ * locale="en"
47
+ * ></squelette-widget>
48
+ * ```
49
+ *
50
+ * Programmatic (JavaScript):
51
+ * ```js
52
+ * const widget = SqueletteWidget.create({
53
+ * project: 'my-project',
54
+ * board: 'feedback',
55
+ * view: 'feedback'
56
+ * });
57
+ *
58
+ * await widget.open();
59
+ * widget.on('submit', (e) => console.log(e.payload));
60
+ * ```
61
+ *
62
+ * Alternative API:
63
+ * ```js
64
+ * const widget = SqueletteWidget.createFeedbackWidget('my-project', 'feedback', {
65
+ * buttonSelector: '#feedback-button',
66
+ * position: 'bottom',
67
+ * overlayBlur: true
68
+ * });
69
+ * ```
70
+ *
71
+ * Identity Management:
72
+ * ```js
73
+ * SqueletteWidget.identify({
74
+ * userId: '123',
75
+ * email: 'user@example.com',
76
+ * signature: 'hmac-signature',
77
+ * name: 'John Doe' // optional
78
+ * });
79
+ *
80
+ * SqueletteWidget.clearIdentity(); // on logout
81
+ * ```
82
+ */
83
+ export { SqueletteWidgetElement, registerSqueletteWidget, } from "./core/custom-element";
84
+ export { identify, clearIdentity } from "./core/identity";
85
+ export { ensureGlobalHelper, type GlobalSqueletteWidget, } from "./core/global-api";
86
+ declare global {
87
+ interface HTMLElementTagNameMap {
88
+ "squelette-widget": import("./core/custom-element").SqueletteWidgetElement;
89
+ }
90
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Lightweight event emitter dedicated to the widget element. It keeps
3
+ * allocation pressure low while offering an ergonomic `.on()` API for clients
4
+ * embedding the widget and for internal coordination between the shell and the
5
+ * custom element lifecycle.
6
+ */
7
+ import type { WidgetEventListener, WidgetEventName, WidgetEventDetailMap } from './types';
8
+ export declare class WidgetEventEmitter {
9
+ private listeners;
10
+ on<K extends WidgetEventName>(event: K, handler: WidgetEventListener<K>): () => void;
11
+ off<K extends WidgetEventName>(event: K, handler: WidgetEventListener<K>): void;
12
+ emit<K extends WidgetEventName>(event: K, payload: WidgetEventDetailMap[K]): void;
13
+ }