@contember/echo 0.0.20 → 0.0.22
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +185 -0
- package/README.md +55 -70
- package/dist/components/Echo.d.ts +2 -2
- package/dist/components/atoms/Button.d.ts +0 -2
- package/dist/components/icons/index.d.ts +0 -1
- package/dist/components/molecules/LauncherButton.d.ts +2 -0
- package/dist/components/molecules/StoredFeedback.d.ts +2 -0
- package/dist/{features/feedback/components → components/organisms}/FeedbackForm.d.ts +1 -1
- package/dist/config/drawingConfig.d.ts +5 -10
- package/dist/contexts/EchoContext.d.ts +5 -8
- package/dist/echo.es.js +5082 -6230
- package/dist/echo.umd.js +11 -1095
- package/dist/index.d.ts +4 -3
- package/dist/stores/drawingStore.d.ts +6 -7
- package/dist/stores/echoStore.d.ts +4 -11
- package/dist/stores/feedbackStore.d.ts +6 -6
- package/dist/stores/widgetStore.d.ts +9 -8
- package/dist/style.css +1 -0
- package/dist/types.d.ts +24 -30
- package/dist/utils/common.d.ts +1 -0
- package/dist/utils/format.d.ts +1 -0
- package/dist/utils/index.d.ts +10 -1
- package/dist/utils/listeners.d.ts +22 -0
- package/dist/utils/screenshot.d.ts +2 -6
- package/dist/utils/storage.d.ts +2 -2
- package/dist/utils/validators.d.ts +2 -0
- package/package.json +4 -6
- package/dist/components/EchoLayout.d.ts +0 -7
- package/dist/components/Launcher.d.ts +0 -6
- package/dist/components/Overlay.d.ts +0 -4
- package/dist/components/icons/MessageIcon.d.ts +0 -3
- package/dist/features/drawing/components/index.d.ts +0 -5
- package/dist/features/drawing/index.d.ts +0 -2
- package/dist/features/drawing/styles/ColorSelector.styles.d.ts +0 -2
- package/dist/features/drawing/styles/DrawingLayer.styles.d.ts +0 -2
- package/dist/features/drawing/styles/DrawingToolbar.styles.d.ts +0 -2
- package/dist/features/drawing/styles/DrawingTooltip.styles.d.ts +0 -2
- package/dist/features/drawing/styles/ShapeActions.styles.d.ts +0 -2
- package/dist/features/drawing/styles/index.d.ts +0 -6
- package/dist/features/feedback/components/index.d.ts +0 -1
- package/dist/features/feedback/index.d.ts +0 -2
- package/dist/features/feedback/styles/FeedbackForm.styles.d.ts +0 -2
- package/dist/features/feedback/styles/index.d.ts +0 -1
- package/dist/features/launcher/components/EchoLauncherButton.d.ts +0 -2
- package/dist/features/launcher/components/SavedPagesDropdown.d.ts +0 -2
- package/dist/features/launcher/styles/EchoLauncherButton.styles.d.ts +0 -2
- package/dist/features/launcher/styles/Notification.styles.d.ts +0 -2
- package/dist/features/launcher/styles/SavedPagesDropdown.styles.d.ts +0 -2
- package/dist/features/launcher/styles/WelcomeMessage.styles.d.ts +0 -2
- package/dist/features/launcher/styles/index.d.ts +0 -4
- package/dist/styles/Echo.styles.d.ts +0 -2
- package/dist/styles/index.d.ts +0 -2
- package/dist/styles/zIndex.d.ts +0 -13
- /package/dist/{features/drawing/components → components/atoms}/Shape.d.ts +0 -0
- /package/dist/{features/drawing/components → components/molecules}/ColorSelector.d.ts +0 -0
- /package/dist/{features/drawing/components → components/molecules}/DrawingToolbar.d.ts +0 -0
- /package/dist/{features/drawing/components → components/molecules}/DrawingTooltip.d.ts +0 -0
- /package/dist/{features/launcher/components → components/molecules}/Notification.d.ts +0 -0
- /package/dist/{features/drawing/components → components/molecules}/ShapeActions.d.ts +0 -0
- /package/dist/{features/launcher/components → components/molecules}/WelcomeMessage.d.ts +0 -0
- /package/dist/{features/drawing/components → components/organisms}/DrawingLayer.d.ts +0 -0
package/dist/index.d.ts
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
import { type
|
1
|
+
import { type EchoConfig, type FeedbackPayload } from './types';
|
2
|
+
import './styles.css';
|
2
3
|
/**
|
3
4
|
* Initialize the Echo feedback widget.
|
4
5
|
* @throws {Error} If initialization fails or invalid options are provided
|
5
6
|
* @returns {() => void} Cleanup function to remove the widget
|
6
7
|
*/
|
7
|
-
export declare function initEcho(options:
|
8
|
-
export type {
|
8
|
+
export declare function initEcho(options: EchoConfig): () => void;
|
9
|
+
export type { FeedbackPayload, EchoConfig };
|
@@ -1,12 +1,11 @@
|
|
1
|
-
import type { DrawingTool, Point, Shape } from '~/types';
|
2
|
-
export
|
1
|
+
import type { DrawingTool, FullEchoConfig, Point, Shape } from '~/types';
|
2
|
+
export type DrawingState = {
|
3
3
|
isDrawing: boolean;
|
4
4
|
selectedShapeId: string | null;
|
5
5
|
selectedTool: DrawingTool;
|
6
6
|
selectedColor: string;
|
7
7
|
shapes: Shape[];
|
8
8
|
currentPoints: Point[];
|
9
|
-
currentPath: string;
|
10
9
|
showTooltip: boolean;
|
11
10
|
mousePosition: Point;
|
12
11
|
hasDrawn: boolean;
|
@@ -15,8 +14,8 @@ export interface DrawingState {
|
|
15
14
|
initialClickPos: Point | null;
|
16
15
|
dragOffset: Point | null;
|
17
16
|
cursor: string;
|
18
|
-
}
|
19
|
-
export
|
17
|
+
};
|
18
|
+
export type DrawingStore = {
|
20
19
|
state: DrawingState;
|
21
20
|
setState: (state: Partial<DrawingState>, isClearing?: boolean) => void;
|
22
21
|
methods: {
|
@@ -36,5 +35,5 @@ export interface DrawingStore {
|
|
36
35
|
points: Point[];
|
37
36
|
}, point: Point) => void;
|
38
37
|
};
|
39
|
-
}
|
40
|
-
export declare const createDrawingStore: (
|
38
|
+
};
|
39
|
+
export declare const createDrawingStore: (config: FullEchoConfig, currentPageKey: string, onStateChange?: (state: Partial<DrawingState>, isClearing?: boolean) => void) => DrawingStore;
|
@@ -1,20 +1,13 @@
|
|
1
|
-
import type {
|
1
|
+
import type { FullEchoConfig } from '~/types';
|
2
2
|
import { type DrawingStore } from './drawingStore';
|
3
3
|
import { type FeedbackStore } from './feedbackStore';
|
4
4
|
import { type WidgetStore } from './widgetStore';
|
5
|
-
export
|
5
|
+
export type EchoStore = {
|
6
6
|
feedback: FeedbackStore;
|
7
7
|
drawing: DrawingStore;
|
8
8
|
widget: WidgetStore;
|
9
|
-
text: TextConfig;
|
10
9
|
methods: {
|
11
10
|
reset: () => void;
|
12
11
|
};
|
13
|
-
}
|
14
|
-
|
15
|
-
primaryColor: string;
|
16
|
-
onSubmit: (data: FeedbackData) => Promise<void>;
|
17
|
-
text: TextConfig;
|
18
|
-
}
|
19
|
-
export declare const createEchoStore: (config: EchoStoreConfig) => EchoStore;
|
20
|
-
export {};
|
12
|
+
};
|
13
|
+
export declare const createEchoStore: (config: FullEchoConfig) => EchoStore;
|
@@ -1,12 +1,12 @@
|
|
1
|
-
import type { Screenshot } from '~/types';
|
2
|
-
export
|
1
|
+
import type { FullEchoConfig, Screenshot } from '~/types';
|
2
|
+
export type FeedbackState = {
|
3
3
|
comment: string;
|
4
4
|
screenshot?: Screenshot;
|
5
5
|
isCapturing: boolean;
|
6
6
|
isMinimized: boolean;
|
7
|
-
}
|
8
|
-
export
|
7
|
+
};
|
8
|
+
export type FeedbackStore = {
|
9
9
|
state: FeedbackState;
|
10
10
|
setState: (state: Partial<FeedbackState>, isClearing?: boolean) => void;
|
11
|
-
}
|
12
|
-
export declare const createFeedbackStore: (
|
11
|
+
};
|
12
|
+
export declare const createFeedbackStore: (config: FullEchoConfig, currentPageKey: string, onStateChange?: (state: Partial<FeedbackState>, isClearing?: boolean) => void) => FeedbackStore;
|
@@ -1,5 +1,6 @@
|
|
1
|
-
import type {
|
2
|
-
export
|
1
|
+
import type { FeedbackPayload, FullEchoConfig, Notification, TextConfig } from '~/types';
|
2
|
+
export type WidgetState = {
|
3
|
+
text: TextConfig;
|
3
4
|
isOpen: boolean;
|
4
5
|
primaryColor: string;
|
5
6
|
notification: Notification;
|
@@ -7,16 +8,16 @@ export interface WidgetState {
|
|
7
8
|
width: number;
|
8
9
|
height: number;
|
9
10
|
};
|
10
|
-
|
11
|
+
isStoredFeedbackOpen: boolean;
|
11
12
|
pagesCount: number;
|
12
13
|
welcomeMessageIsClosing: boolean;
|
13
|
-
}
|
14
|
-
export
|
14
|
+
};
|
15
|
+
export type WidgetStore = {
|
15
16
|
state: WidgetState;
|
16
17
|
setState: (state: Partial<WidgetState>) => void;
|
17
18
|
methods: {
|
18
19
|
postSubmit: (result: Notification) => void;
|
19
|
-
onSubmit: (data:
|
20
|
+
onSubmit: (data: FeedbackPayload) => Promise<void>;
|
20
21
|
};
|
21
|
-
}
|
22
|
-
export declare const createWidgetStore: (
|
22
|
+
};
|
23
|
+
export declare const createWidgetStore: (config: FullEchoConfig, currentPageKey: string) => WidgetStore;
|
package/dist/style.css
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*,*:before,*:after{box-sizing:border-box}.echo-root{position:absolute;top:0;left:0;z-index:var(--z-root);isolation:isolate;pointer-events:none;--z-root: 999999;--z-launcher: 2;--z-overlay: 1;--z-drawing-toolbar: 3;--z-drawing-tooltip: 3;--z-shape-actions: 3;--z-notification: 2;--z-welcome-message: 2;--z-widget-button: 2;--z-feedback-form: 4;--primary-color: #000;--primary-text-color: #fff;--error-color: #f44336;--success-color: var(--primary-color);--text-dark: #1a1a1a;--text-medium: #333;--text-light: #666;--text-lighter: #999;--border-color: rgba(0, 0, 0, .1);--border-color-light: rgba(0, 0, 0, .05);--border-color-medium: rgba(0, 0, 0, .08);--primary-color-lighter: color-mix(in srgb, var(--primary-color) 100%, white 40%);--primary-color-lightest: color-mix(in srgb, var(--primary-color) 7%, white 100%);--hover-color: color-mix(in srgb, var(--primary-color) 80%, #fff);--shadow-color-dark: rgba(0, 0, 0, .6);--shadow-color-light: rgba(255, 255, 255, .1);--shadow-color-medium: rgba(0, 0, 0, .2);--shadow-sm: 0 1px 3px;--shadow-md: 0 4px 10px;--shadow-lg: 0 10px 20px;--shadow-black-sm: var(--shadow-sm) rgba(0, 0, 0, .5);--shadow-black-md: var(--shadow-md) rgba(0, 0, 0, .5);--shadow-black-lg: var(--shadow-lg) rgba(0, 0, 0, .5);--shadow-black-lightened-sm: var(--shadow-sm) var(--shadow-color-medium);--shadow-black-lightened-md: var(--shadow-md) var(--shadow-color-medium);--shadow-black-lightened-lg: var(--shadow-lg) var(--shadow-color-medium);--shadow-primary-sm: var(--shadow-sm) color-mix(in srgb, var(--primary-color) 60%, transparent 80%);--shadow-primary-md: var(--shadow-md) color-mix(in srgb, var(--primary-color) 50%, transparent 80%);--shadow-primary-lg: var(--shadow-lg) color-mix(in srgb, var(--primary-color) 40%, transparent 80%);--shadow-primary-lighter-sm: var(--shadow-sm) color-mix(in srgb, var(--primary-color-lighter) 70%, transparent 80%);--shadow-primary-lighter-md: var(--shadow-md) color-mix(in srgb, var(--primary-color-lighter) 60%, transparent 80%);--shadow-primary-lighter-lg: var(--shadow-lg) color-mix(in srgb, var(--primary-color-lighter) 50%, transparent 80%);--shadow-primary-lightest-sm: var(--shadow-sm) color-mix(in srgb, var(--primary-color-lightest) 70%, transparent 80%);--shadow-primary-lightest-md: var(--shadow-md) color-mix(in srgb, var(--primary-color-lightest) 60%, transparent 80%);--shadow-primary-lightest-lg: var(--shadow-lg) color-mix(in srgb, var(--primary-color-lightest) 50%, transparent 80%);--shadow-combined-sm: var(--shadow-primary-sm), var(--shadow-black-lightened-sm);--shadow-combined-md: var(--shadow-primary-md), var(--shadow-black-lightened-md);--shadow-combined-lg: var(--shadow-primary-lg), var(--shadow-black-lightened-lg);--spacing-xs: 4px;--spacing-sm: 8px;--spacing-md: 12px;--spacing-lg: 16px;--spacing-xl: 20px;--spacing-2xl: 24px;--spacing-3xl: 32px;--radius-sm: 4px;--radius-md: 8px;--radius-lg: 12px;--radius-xl: 16px;--radius-full: 9999px;--font-xs: .8125rem;--font-sm: .875rem;--font-base: .9375rem;--font-md: 1rem;--font-lg: 1.125rem;--duration-fast: .1s;--duration-base: .2s;--duration-slow: .3s;--duration-slower: .4s;--duration-slowest: .6s;--ease-default: ease;--ease-in-out: ease-in-out;--ease-bounce: cubic-bezier(.34, 1.56, .64, 1);--ease-smooth: cubic-bezier(.4, 0, .2, 1);--ease-spring: cubic-bezier(.16, 1, .3, 1)}.echo-stored-feedback{position:absolute;display:flex;flex-direction:column;bottom:calc(100% + var(--spacing-lg));right:0;width:320px;background:#fff;border-radius:var(--radius-lg);box-shadow:var(--shadow-black-lightened-lg);animation:slideUpFade var(--duration-base) var(--ease-smooth);z-index:calc(var(--z-widget-button) + 1);transform-origin:bottom right;transition:all var(--duration-base) var(--ease-smooth)}.echo-stored-feedback-header{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-md) var(--spacing-lg)}.echo-stored-feedback-header h3{margin:0;font-size:var(--font-md);font-weight:600}.echo-stored-feedback-list{max-height:400px;overflow-y:auto;border-bottom-left-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.echo-stored-feedback-item{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-md) var(--spacing-lg);border-bottom:1px solid var(--border-color-light);transition:all var(--duration-base) var(--ease-smooth);background:#fff;position:relative}.echo-stored-feedback-item:hover{background:var(--primary-color-lightest)}.echo-stored-feedback-item-current{background:var(--primary-color-lightest);padding-left:calc(var(--spacing-lg) - 3px)}.echo-stored-feedback-item-current:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--primary-color);border-top-left-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.echo-stored-feedback-item:last-child{border-bottom:none;border-bottom-left-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.echo-stored-feedback-item:last-child.echo-stored-feedback-item-current:before{border-bottom-left-radius:var(--radius-lg)}.echo-stored-feedback-content{flex:1;min-width:0;margin-right:var(--spacing-md)}.echo-stored-feedback-path{font-size:var(--font-sm);font-weight:500;color:var(--text-medium);margin-bottom:var(--spacing-xs);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.echo-stored-feedback-preview{font-size:var(--font-xs);color:var(--text-light);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.echo-stored-feedback-actions{display:flex;align-items:center;gap:var(--spacing-sm)}.echo-stored-feedback-link{color:var(--text-light)}.echo-stored-feedback-link:hover{color:var(--primary-color)}.echo-stored-feedback-delete{color:var(--text-light);font-size:var(--font-xs);padding:var(--spacing-xs) var(--spacing-md)}.echo-stored-feedback-delete:hover{color:var(--error-color);background:color-mix(in srgb,var(--error-color) 10%,transparent)}.echo-stored-feedback-empty{padding:var(--spacing-3xl) var(--spacing-lg);text-align:center;color:var(--text-light);font-size:var(--font-sm);border-bottom-left-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.echo-launcher{position:fixed;z-index:var(--z-launcher);bottom:var(--spacing-xl);right:var(--spacing-xl)}.echo-overlay{position:absolute;z-index:var(--z-overlay);top:0;left:0;right:0;bottom:0;border:3px solid var(--primary-color)}[data-hidden=true],[data-hidden=false]{transition:opacity var(--duration-slow) var(--ease-in-out),visibility var(--duration-slow) var(--ease-in-out)}[data-hidden=true]{opacity:0;visibility:hidden;pointer-events:none}[data-hidden=false]{opacity:1;visibility:visible;pointer-events:auto;user-select:none;-webkit-user-select:none}.echo-launcher-button{z-index:var(--z-widget-button);position:relative;display:flex;align-items:center;justify-content:center;cursor:pointer;background:radial-gradient(circle at 40% 40%,var(--primary-color) 0%,var(--primary-color-lighter) 65%,var(--primary-color-lighter) 100%);border:none;border-radius:var(--radius-full);width:48px;height:48px;box-shadow:var(--shadow-black-md);transition:all var(--duration-slow) var(--ease-default),left var(--duration-slower) var(--ease-smooth),opacity var(--duration-slow) var(--ease-in-out)}.echo-launcher-button:hover{box-shadow:var(--shadow-black-lg);transform:translateY(-2px)}.echo-launcher-button:active{transform:scale(.95)}.echo-launcher-button-count{position:absolute;top:calc(-1 * var(--spacing-xs));right:calc(-1 * var(--spacing-xs));background:var(--primary-color-lightest);color:var(--primary-color-lighter);border-radius:var(--radius-md);min-width:20px;height:20px;display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-black-sm);padding:0 var(--spacing-xs);font-weight:600;pointer-events:auto;cursor:pointer;transform-origin:center center;animation:popIn var(--duration-slow) var(--ease-bounce);transition:transform var(--duration-base) var(--ease-default)}.echo-launcher-button-count:hover{transform:scale(1.1)}.echo-feedback{position:fixed;bottom:var(--spacing-xl);right:var(--spacing-xl);width:min(calc(100vw - var(--spacing-2xl)),24rem);z-index:var(--z-feedback-form);box-shadow:var(--shadow-black-lightened-lg);display:flex;flex-direction:column;gap:var(--spacing-lg);background:#fff;border-radius:var(--radius-lg);will-change:transform;padding:var(--spacing-lg)}.echo-feedback[data-minimized=true]{transition:transform .4s var(--ease-default),box-shadow .4s var(--ease-default);transform:translate(calc(100% - 48px),calc(100% - 48px));box-shadow:0 8px 16px #0003}.echo-feedback[data-minimized=true]:hover{cursor:pointer;transform:translate(calc(100% - 48px),calc(100% - 48px)) rotate(-2deg) scale(1.1);box-shadow:0 12px 24px #00000040}.echo-feedback[data-minimized=false]{transition:transform .4s var(--ease-smooth),box-shadow .4s var(--ease-smooth);transform:translate(0)}.echo-feedback[style*=transition]{pointer-events:none}.echo-feedback-content{display:flex;flex-direction:column;gap:var(--spacing-lg)}.echo-feedback-header{display:flex;justify-content:space-between;align-items:center}.echo-feedback-title{font-size:var(--font-lg);font-weight:600;color:var(--text-dark);margin:0}.echo-feedback-header-actions{display:flex;gap:var(--spacing-xs);margin:calc(-1 * var(--spacing-sm)) calc(-1 * var(--spacing-sm)) calc(-1 * var(--spacing-sm)) 0}.echo-feedback-form-textarea{width:100%;min-height:120px;border-radius:var(--radius-md);border:1px solid var(--border-color);padding:var(--spacing-md);font-size:var(--font-base);resize:vertical;background:#fffc;font-family:inherit}.echo-feedback-form-textarea:focus{outline:none;border-color:var(--primary-color);background:#fff;box-shadow:0 0 0 3px color-mix(in srgb,var(--primary-color) 15%,transparent)}.echo-feedback-form-textarea::placeholder{color:var(--text-lighter)}[data-hide-when-drawing=true]{opacity:1;visibility:visible;transition:opacity .3s ease-in-out,visibility .3s ease-in-out}[data-drawing=true] [data-hide-when-drawing=true]{opacity:0;visibility:hidden;pointer-events:none;user-select:none;-webkit-user-select:none}.echo-drawing-layer,.echo-drawing-layer-container{position:absolute;top:0;left:0;right:0;bottom:0;pointer-events:none;user-select:none;-webkit-user-select:none}.echo-drawing-layer-container svg{pointer-events:auto}.echo-drawing-toolbar{position:fixed;top:var(--spacing-xl);left:var(--spacing-xl);display:flex;flex-direction:column;gap:var(--spacing-sm);z-index:var(--z-drawing-toolbar);opacity:1;transition:opacity var(--duration-base) var(--ease-default)}.echo-drawing-toolbar-button{width:50px;height:50px;border-radius:var(--radius-full);border:2px solid #ddd;background:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;transition:all var(--duration-base) var(--ease-default);box-shadow:var(--shadow-black-sm);position:relative}.echo-drawing-toolbar-icon{width:25px;height:25px;color:var(--primary-color);transition:color var(--duration-base) var(--ease-default)}.echo-drawing-toolbar-button:hover{transform:scale(1.05);border-color:var(--hover-color)}.echo-drawing-toolbar-button[data-selected=true]{background:var(--primary-color-lightest);border-color:var(--primary-color)}.echo-color-selector{position:relative}.echo-color-selector:hover .echo-drawing-toolbar-button{border-top-right-radius:0;border-bottom-right-radius:0;transform:scale(1.05);border-right-color:transparent;background:rgba(var(--primary-color),.9);border-color:var(--hover-color)}.echo-color-swatch-wrapper{position:absolute;left:calc(100% - 2px);top:50%;transform:translateY(-50%);height:52.5px;padding-right:var(--spacing-sm);display:none}.echo-color-selector:hover .echo-color-swatch-wrapper{display:block}.echo-color-swatch{height:100%;background:#fff;border-radius:var(--radius-md);border-top-left-radius:0;border-bottom-left-radius:0;padding:var(--spacing-sm);padding-left:var(--spacing-md);box-shadow:var(--shadow-black-sm);display:flex;align-items:center;gap:var(--spacing-sm);border:2px solid #ddd;border-left:none}.echo-color-selector:hover .echo-color-swatch{border-color:var(--hover-color)}.echo-color-swatch-button{width:24px;height:24px;border-radius:var(--radius-full);border:2px solid transparent;cursor:pointer;padding:0;transition:transform var(--duration-base) var(--ease-default)}.echo-color-swatch-button:hover{transform:scale(1.1)}.echo-color-swatch-button[data-selected=true]{border-color:var(--primary-color)}.echo-drawing-tooltip{display:flex;text-wrap:nowrap;position:fixed;background:#fff;padding:var(--spacing-sm) var(--spacing-lg);border-radius:var(--radius-lg);box-shadow:var(--shadow-combined-sm);font-size:var(--font-sm);color:var(--primary-color);z-index:var(--z-drawing-tooltip);pointer-events:none;animation:slideDownFade var(--duration-slow) var(--ease-default);border:1px solid var(--primary-color);background:var(--primary-color-lightest)}.echo-shape-actions{position:fixed;z-index:var(--z-shape-actions);display:flex;gap:var(--spacing-xs);background:#fff;border-radius:var(--radius-lg);box-shadow:var(--shadow-combined-md);transform:translate(-50%,-100%) translateY(calc(-1 * var(--spacing-sm)));animation:popInSlideDown var(--duration-fast) var(--ease-default);cursor:default;pointer-events:auto;padding:var(--spacing-xs);border:1px solid var(--primary-color)}.echo-shape-actions-divider{width:1px;margin:var(--spacing-sm) 0;background:var(--border-color);pointer-events:none}.echo-shape-actions[hidden]{display:none}.echo-notification{position:absolute;z-index:var(--z-notification);bottom:70px;right:0;width:300px;padding:var(--spacing-2xl);border-radius:var(--radius-lg);font-size:var(--font-md);font-weight:500;box-shadow:var(--shadow-combined-md);background:#fff;border:1px solid var(--primary-color);transform-origin:bottom right;display:flex;flex-direction:column;align-items:center;gap:var(--spacing-xl);opacity:1;pointer-events:auto;transition:all var(--duration-base) var(--ease-smooth)}.echo-notification:not([data-empty=true]){animation:popInSlideUp var(--duration-slower) var(--ease-spring)}.echo-notification[data-empty=true]{opacity:0;pointer-events:none;transform:translateY(var(--spacing-sm)) scale(.95);transition:none}.echo-notification-hide{position:absolute;top:var(--spacing-lg);right:var(--spacing-lg);width:24px;height:24px;padding:var(--spacing-xs);border:none;background:transparent;color:var(--text-light);opacity:.7;cursor:pointer;border-radius:var(--radius-full);display:flex;align-items:center;justify-content:center;transition:all var(--duration-base) var(--ease-bounce);flex-shrink:0}.echo-notification-hide:hover{opacity:1;background:var(--primary-color-lightest);transform:scale(1.1);color:var(--primary-color)}.echo-notification-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;transform:scale(1.5);background:var(--primary-color-lightest);padding:var(--spacing-md);border-radius:var(--radius-full);margin-top:var(--spacing-md);transition:all var(--duration-base) var(--ease-bounce)}.echo-notification[data-type=success]{border-color:var(--success-color)}.echo-notification[data-type=success] .echo-notification-icon{color:var(--success-color)}.echo-notification[data-type=error]{border-color:var(--error-color)}.echo-notification[data-type=error] .echo-notification-icon{color:var(--error-color);background:color-mix(in srgb,var(--error-color) 10%,white)}.echo-notification-content{display:flex;flex-direction:column;align-items:center;gap:12px;text-align:center;padding:0 12px}.echo-notification-title{font-size:1rem;font-weight:600;color:#1a1a1a}.echo-notification-message{font-size:.875rem;font-weight:400;color:#666;line-height:1.4;max-width:100%}@media (max-width: 768px){.echo-notification{right:0;width:calc(100vw - 40px);height:auto;min-height:180px;-webkit-backdrop-filter:none;backdrop-filter:none;font-size:.9375rem;padding:20px;gap:16px;bottom:calc(100% + 20px)}.echo-notification-icon{transform:scale(1.3);padding:10px;margin-top:8px}.echo-notification-title{font-size:.9375rem}.echo-notification-message{font-size:.8125rem}}.echo-welcome-message{display:flex;align-items:center;gap:var(--spacing-xs);position:fixed;z-index:var(--z-welcome-message);background:var(--primary-color-lightest);border:1px solid var(--primary-color);color:var(--primary-color);padding:var(--spacing-md) var(--spacing-lg);border-radius:var(--radius-lg);font-size:var(--font-sm);font-weight:500;box-shadow:var(--shadow-combined-md);opacity:1;transform:translateY(0) scale(1);transition:all var(--duration-slow) var(--ease-smooth);animation:bounceIn var(--duration-slowest) var(--ease-bounce);user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;cursor:pointer;text-align:left}.echo-welcome-message:hover{transform:translateY(-2px) scale(1.02);background:var(--primary-color-lightest);box-shadow:var(--shadow-combined-lg)}.echo-welcome-message:active{transform:translateY(0) scale(.98)}.echo-welcome-message-close{width:20px;height:20px;padding:2px;margin-left:var(--spacing-xs);border:none;background:transparent;opacity:.7;cursor:pointer;border-radius:var(--radius-full);display:flex;align-items:center;justify-content:center;transition:all var(--duration-base) var(--ease-default)}.echo-welcome-message-close:hover{opacity:1;background:var(--shadow-color-light);transform:scale(1.1)}.echo-welcome-message-close:active{transform:scale(.95)}.echo-welcome-message:after{content:"";position:absolute;bottom:-4px;right:17px;width:16px;height:16px;background:inherit;transform:rotate(45deg);border-radius:var(--radius-xs);border:1px solid var(--primary-color);z-index:-2}.echo-welcome-message:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:var(--primary-color-lightest);z-index:-1;border-radius:var(--radius-lg)}.echo-welcome-message-pulsar{content:"";display:inline-block;width:6px;height:6px;background:var(--primary-color);border-radius:50%;margin-right:8px;animation:pulse 1.5s var(--ease-in-out) infinite}.echo-button{display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:var(--radius-md);font-weight:500;cursor:pointer;transition:all var(--duration-base) var(--ease-default);line-height:1}.echo-button:focus-visible{outline:2px solid var(--primary-color);outline-offset:2px}.echo-button-primary{background:var(--primary-color);color:#fff}.echo-button-primary:hover{background:var(--hover-color);transform:translateY(-1px)}.echo-button-primary:active{transform:translateY(0)}.echo-button-secondary{background:transparent;color:var(--text-light)}.echo-button-secondary:hover{background-color:var(--primary-color-lightest);color:var(--primary-color)}.echo-button-xs{padding:var(--spacing-xs);font-size:var(--font-xs)}.echo-button-sm{padding:var(--spacing-xs);font-size:var(--font-sm)}.echo-button-md{padding:var(--spacing-md) var(--spacing-2xl);font-size:var(--font-base)}.echo-button-lg{padding:var(--spacing-md) var(--spacing-3xl);font-size:var(--font-md)}@keyframes slideUpFade{0%{opacity:0;transform:translateY(var(--spacing-sm))}to{opacity:1;transform:translateY(0)}}@keyframes slideDownFade{0%{opacity:0;transform:translateY(calc(-1 * var(--spacing-sm)))}to{opacity:1;transform:translateY(0)}}@keyframes popIn{0%{transform:scale(0);opacity:0}to{transform:scale(1);opacity:1}}@keyframes popInSlideUp{0%{opacity:0;transform:translateY(var(--spacing-sm)) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes popInSlideDown{0%{opacity:0;transform:translate(-50%,-100%) translateY(calc(-1 * var(--spacing-xs))) scale(.95)}to{opacity:1;transform:translate(-50%,-100%) translateY(calc(-1 * var(--spacing-sm))) scale(1)}}@keyframes bounceIn{0%{opacity:0;transform:translateY(var(--spacing-xl)) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(1.5);opacity:.5}to{transform:scale(1);opacity:1}}
|
package/dist/types.d.ts
CHANGED
@@ -1,29 +1,29 @@
|
|
1
|
-
export type Screenshot = `data:image/
|
2
|
-
export
|
1
|
+
export type Screenshot = `data:image/png;base64,${string}`;
|
2
|
+
export type BrowserInfo = {
|
3
3
|
width: number;
|
4
4
|
height: number;
|
5
5
|
screenWidth: number;
|
6
6
|
screenHeight: number;
|
7
|
-
}
|
8
|
-
export
|
7
|
+
};
|
8
|
+
export type Metadata = {
|
9
9
|
url: string;
|
10
10
|
userAgent: string;
|
11
11
|
timestamp: string;
|
12
12
|
browserInfo: BrowserInfo;
|
13
|
-
}
|
14
|
-
export
|
13
|
+
};
|
14
|
+
export type ConsoleEntry = {
|
15
15
|
type: 'log' | 'warn' | 'error';
|
16
16
|
message: string;
|
17
17
|
timestamp: string;
|
18
|
-
}
|
19
|
-
export
|
18
|
+
};
|
19
|
+
export type FeedbackPayload = {
|
20
20
|
comment: string;
|
21
21
|
screenshot?: Screenshot;
|
22
22
|
metadata: Metadata;
|
23
23
|
console: ConsoleEntry[];
|
24
|
-
}
|
24
|
+
};
|
25
25
|
export type Position = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
26
|
-
export
|
26
|
+
export type TextConfig = {
|
27
27
|
welcomeMessage: {
|
28
28
|
text: string;
|
29
29
|
closeAriaLabel: string;
|
@@ -47,47 +47,41 @@ export interface TextConfig {
|
|
47
47
|
drawingTooltip: {
|
48
48
|
text: string;
|
49
49
|
};
|
50
|
-
}
|
51
|
-
export type
|
52
|
-
onSubmit: (data:
|
50
|
+
};
|
51
|
+
export type EchoConfig = {
|
52
|
+
onSubmit: (data: FeedbackPayload) => Promise<void>;
|
53
53
|
position?: Position;
|
54
54
|
primaryColor?: `#${string}`;
|
55
55
|
textConfig?: Partial<TextConfig>;
|
56
|
-
|
56
|
+
};
|
57
|
+
export type FullEchoConfig = Required<EchoConfig> & {
|
58
|
+
textConfig: TextConfig;
|
57
59
|
};
|
58
60
|
export declare const POSITIONS: Record<Position, {
|
59
61
|
[key: string]: string;
|
60
62
|
}>;
|
61
|
-
export
|
63
|
+
export type Point = {
|
62
64
|
x: number;
|
63
65
|
y: number;
|
64
|
-
}
|
66
|
+
};
|
65
67
|
export type ShapeType = 'rectangle' | 'path';
|
66
68
|
export type DrawingTool = 'rectangle' | 'path';
|
67
|
-
export
|
69
|
+
export type Shape = {
|
68
70
|
id: string;
|
69
71
|
type: ShapeType;
|
70
72
|
color: string;
|
71
73
|
points: Point[];
|
72
|
-
}
|
73
|
-
export
|
74
|
+
};
|
75
|
+
export type IconProps = {
|
74
76
|
size?: number;
|
75
77
|
stroke?: string;
|
76
78
|
strokeWidth?: number;
|
77
79
|
class?: string;
|
78
80
|
style?: any;
|
79
81
|
fill?: string;
|
80
|
-
}
|
81
|
-
export
|
82
|
-
primaryColor: string;
|
83
|
-
}
|
84
|
-
export interface EnrichedStylesConfig extends StylesConfig {
|
85
|
-
primaryTextColor: string;
|
86
|
-
primaryColorLighter: string;
|
87
|
-
primaryColorLightest: string;
|
88
|
-
}
|
89
|
-
export interface Notification {
|
82
|
+
};
|
83
|
+
export type Notification = {
|
90
84
|
show: boolean;
|
91
85
|
type: 'success' | 'error' | null;
|
92
86
|
message: string | null;
|
93
|
-
}
|
87
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const deepMerge: (target: any, source: any) => any;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const formatPath: (path: string) => string;
|
package/dist/utils/index.d.ts
CHANGED
@@ -1,4 +1,13 @@
|
|
1
|
+
export * from './color';
|
2
|
+
export * from './common';
|
3
|
+
export * from './console';
|
4
|
+
export * from './debounce';
|
1
5
|
export * from './device';
|
2
|
-
export * from './
|
6
|
+
export * from './events';
|
7
|
+
export * from './format';
|
3
8
|
export * from './geometry';
|
9
|
+
export * from './listeners';
|
10
|
+
export * from './screenshot';
|
4
11
|
export * from './storage';
|
12
|
+
export * from './svg';
|
13
|
+
export * from './validators';
|
@@ -0,0 +1,22 @@
|
|
1
|
+
export declare const registerKeyListener: (key: string, callback: () => void) => void;
|
2
|
+
export declare const registerWindowEventListener: {
|
3
|
+
<K extends keyof WindowEventMap>(props: {
|
4
|
+
event: K;
|
5
|
+
callback: (e: WindowEventMap[K]) => void;
|
6
|
+
onMount?: () => void;
|
7
|
+
onCleanup?: () => void;
|
8
|
+
}): void;
|
9
|
+
(props: {
|
10
|
+
event: string;
|
11
|
+
callback: (e: Event) => void;
|
12
|
+
onMount?: () => void;
|
13
|
+
onCleanup?: () => void;
|
14
|
+
}): void;
|
15
|
+
};
|
16
|
+
export declare const registerMutationObserver: (props: {
|
17
|
+
target: Node;
|
18
|
+
options?: MutationObserverInit;
|
19
|
+
callback: (mutations: MutationRecord[]) => void;
|
20
|
+
onMount?: () => void;
|
21
|
+
onCleanup?: () => void;
|
22
|
+
}) => void;
|
@@ -1,6 +1,2 @@
|
|
1
|
-
import type { Screenshot
|
2
|
-
|
3
|
-
annotations: Shape[];
|
4
|
-
}
|
5
|
-
export declare const captureScreenshot: ({ annotations }: CaptureScreenshotConfig) => Promise<Screenshot | undefined>;
|
6
|
-
export {};
|
1
|
+
import type { Screenshot } from '~/types';
|
2
|
+
export declare const captureScreenshot: () => Promise<Screenshot | undefined>;
|
package/dist/utils/storage.d.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { DrawingState, FeedbackState } from '~/stores';
|
2
2
|
import type { Shape } from '~/types';
|
3
|
-
|
3
|
+
type StoredPageState = {
|
4
4
|
feedback: {
|
5
5
|
comment: string;
|
6
6
|
};
|
@@ -8,7 +8,7 @@ interface StoredPageState {
|
|
8
8
|
shapes: Shape[];
|
9
9
|
};
|
10
10
|
latestQuery?: string;
|
11
|
-
}
|
11
|
+
};
|
12
12
|
export declare const dispatchStorageChange: () => void;
|
13
13
|
export declare const getStorageKey: (key: string) => string;
|
14
14
|
export declare const getFromStorage: <T>(key: string, defaultValue: T) => T;
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@contember/echo",
|
3
3
|
"license": "Apache-2.0",
|
4
|
-
"version": "0.0.
|
4
|
+
"version": "0.0.22",
|
5
5
|
"type": "module",
|
6
6
|
"author": "neumie@neumie.dev",
|
7
7
|
"keywords": [
|
@@ -16,10 +16,9 @@
|
|
16
16
|
"dist"
|
17
17
|
],
|
18
18
|
"scripts": {
|
19
|
-
"dev": "vite",
|
20
|
-
"build": "tsc && vite build && tsc --emitDeclarationOnly
|
21
|
-
"
|
22
|
-
"watch": "concurrently \"tsc --watch\" \"vite build --watch\""
|
19
|
+
"dev": "vite build --watch",
|
20
|
+
"build": "tsc && vite build && tsc --emitDeclarationOnly",
|
21
|
+
"ts:watch": "tsc --watch"
|
23
22
|
},
|
24
23
|
"dependencies": {
|
25
24
|
"html2canvas": "^1.4.1",
|
@@ -27,7 +26,6 @@
|
|
27
26
|
},
|
28
27
|
"devDependencies": {
|
29
28
|
"@types/node": "^20.17.12",
|
30
|
-
"concurrently": "^9.1.2",
|
31
29
|
"typescript": "^5.0.0",
|
32
30
|
"vite": "^5.0.0",
|
33
31
|
"vite-plugin-solid": "^2.10.1",
|
@@ -1 +0,0 @@
|
|
1
|
-
export * from './FeedbackForm';
|
@@ -1 +0,0 @@
|
|
1
|
-
export * from './FeedbackForm.styles';
|
package/dist/styles/index.d.ts
DELETED
package/dist/styles/zIndex.d.ts
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
declare const zIndex: {
|
2
|
-
readonly root: 999999;
|
3
|
-
readonly overlay: 1;
|
4
|
-
readonly launcher: 2;
|
5
|
-
readonly widgetButton: 2;
|
6
|
-
readonly notification: 2;
|
7
|
-
readonly welcomeMessage: 2;
|
8
|
-
readonly feedbackForm: 4;
|
9
|
-
readonly drawingToolbar: 3;
|
10
|
-
readonly shapeActions: 3;
|
11
|
-
readonly drawingTooltip: 3;
|
12
|
-
};
|
13
|
-
export { zIndex };
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|