@contember/echo 0.0.27 → 0.0.29
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/dist/components/Echo.d.ts +3 -0
- package/dist/components/atoms/Button.d.ts +7 -0
- package/dist/components/atoms/Shape.d.ts +8 -0
- package/dist/components/atoms/index.d.ts +1 -0
- package/dist/components/atoms/inputs/CheckboxGroup.d.ts +9 -0
- package/dist/components/atoms/inputs/InputWrapper.d.ts +8 -0
- package/dist/components/atoms/inputs/RadioGroup.d.ts +9 -0
- package/dist/components/atoms/inputs/Select.d.ts +9 -0
- package/dist/components/atoms/inputs/TextArea.d.ts +9 -0
- package/dist/components/atoms/inputs/TextInput.d.ts +9 -0
- package/dist/components/icons/CheckCircleIcon.d.ts +3 -0
- package/dist/components/icons/ChevronRightIcon.d.ts +3 -0
- package/dist/components/icons/ContemberIcon.d.ts +3 -0
- package/dist/components/icons/ExternalLinkIcon.d.ts +3 -0
- package/dist/components/icons/HighlightIcon.d.ts +3 -0
- package/dist/components/icons/PenIcon.d.ts +3 -0
- package/dist/components/icons/TrashIcon.d.ts +3 -0
- package/dist/components/icons/XCircleIcon.d.ts +3 -0
- package/dist/components/icons/XIcon.d.ts +3 -0
- package/dist/components/icons/index.d.ts +8 -0
- package/dist/components/molecules/ColorSelector.d.ts +2 -0
- package/dist/components/molecules/CustomInput.d.ts +9 -0
- package/dist/components/molecules/DrawingToolbar.d.ts +2 -0
- package/dist/components/molecules/DrawingTooltip.d.ts +2 -0
- package/dist/components/molecules/LauncherButton.d.ts +2 -0
- package/dist/components/molecules/Notification.d.ts +2 -0
- package/dist/components/molecules/ShapeActions.d.ts +2 -0
- package/dist/components/molecules/StoredFeedback.d.ts +2 -0
- package/dist/components/molecules/WelcomeMessage.d.ts +2 -0
- package/dist/components/molecules/index.d.ts +8 -0
- package/dist/components/organisms/DrawingLayer.d.ts +2 -0
- package/dist/components/organisms/FeedbackForm.d.ts +2 -0
- package/dist/components/organisms/index.d.ts +2 -0
- package/dist/config/defaultText.d.ts +2 -0
- package/dist/config/drawingConfig.d.ts +13 -0
- package/dist/contexts/EchoContext.d.ts +9 -0
- package/dist/contexts/index.d.ts +1 -0
- package/dist/echo.es.js +1743 -1174
- package/dist/echo.umd.js +8 -9
- package/dist/hooks/useInputHandler.d.ts +7 -0
- package/dist/hooks/usePageHeight.d.ts +4 -0
- package/dist/hooks/usePageStateSync.d.ts +4 -0
- package/dist/index.d.ts +41 -2
- package/dist/stores/drawingStore.d.ts +39 -0
- package/dist/stores/echoStore.d.ts +15 -0
- package/dist/stores/feedbackStore.d.ts +17 -0
- package/dist/stores/index.d.ts +4 -0
- package/dist/stores/widgetStore.d.ts +21 -0
- package/dist/style.css +1 -1
- package/dist/types.d.ts +151 -0
- package/dist/utils/color.d.ts +2 -0
- package/dist/utils/common.d.ts +2 -0
- package/dist/utils/console.d.ts +4 -0
- package/dist/utils/device.d.ts +1 -0
- package/dist/utils/events.d.ts +5 -0
- package/dist/utils/format.d.ts +1 -0
- package/dist/utils/geometry.d.ts +8 -0
- package/dist/utils/index.d.ts +12 -0
- package/dist/utils/listeners.d.ts +24 -0
- package/dist/utils/metadata.d.ts +2 -0
- package/dist/utils/monkeyPatch.d.ts +4 -0
- package/dist/utils/notifications.d.ts +6 -0
- package/dist/utils/screenshot.d.ts +2 -0
- package/dist/utils/stateManagement.d.ts +8 -0
- package/dist/utils/storage.d.ts +30 -0
- package/dist/utils/svg.d.ts +13 -0
- package/dist/utils/validators.d.ts +2 -0
- package/package.json +1 -1
- package/dist/echo.es.js.map +0 -1
- package/dist/echo.umd.js.map +0 -1
@@ -0,0 +1,21 @@
|
|
1
|
+
import type { CustomInputConfig, FullEchoConfig, Notification, Position, TextConfig } from '~/types';
|
2
|
+
export type WidgetState = {
|
3
|
+
text: TextConfig;
|
4
|
+
isOpen: boolean;
|
5
|
+
primaryColor: string;
|
6
|
+
notification: Notification;
|
7
|
+
dimensions: {
|
8
|
+
width: number;
|
9
|
+
height: number;
|
10
|
+
};
|
11
|
+
isStoredFeedbackOpen: boolean;
|
12
|
+
pagesCount: number;
|
13
|
+
welcomeMessageIsClosing: boolean;
|
14
|
+
position: Position;
|
15
|
+
customInputs?: CustomInputConfig[];
|
16
|
+
};
|
17
|
+
export type WidgetStore = {
|
18
|
+
state: WidgetState;
|
19
|
+
setState: (state: Partial<WidgetState>) => void;
|
20
|
+
};
|
21
|
+
export declare const createWidgetStore: (config: FullEchoConfig, currentPageKey: string) => WidgetStore;
|
package/dist/style.css
CHANGED
@@ -1 +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}}
|
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;top:0;left:0;margin:0;padding:0;max-width:none;max-height:none;border:3px solid var(--primary-color);background:transparent}.echo-overlay::backdrop{background:transparent}[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%;padding:.5rem;border:1px solid var(--border-color);border-radius:var(--radius-md);background-color:#fff;color:var(--text-medium);font-size:var(--font-sm);transition:all var(--duration-base) var(--ease-default);min-height:120px;resize:vertical;font-family:inherit}.echo-feedback-form-textarea:focus{outline:none;border-color:var(--primary-color);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}}.echo-inputs{display:flex;flex-direction:column;gap:1rem;margin-bottom:1rem}.echo-input{display:flex;flex-direction:column;gap:.5rem}.echo-input-label{font-size:.875rem;font-weight:500;color:var(--text-color)}.echo-input-required{color:#dc2626;margin-left:.25rem}.echo-input-field{width:100%;padding:.5rem;border:1px solid var(--border-color);border-radius:var(--radius-md);background-color:#fff;color:var(--text-medium);font-size:var(--font-sm);transition:all var(--duration-base) var(--ease-default)}.echo-input-field:focus{outline:none;border-color:var(--primary-color);box-shadow:0 0 0 3px color-mix(in srgb,var(--primary-color) 15%,transparent)}.echo-input-field::placeholder{color:var(--text-lighter)}select.echo-input-field{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .5rem center;padding-right:2.5rem;cursor:pointer}.echo-input-options{display:flex;flex-direction:column;gap:var(--spacing-sm);border:none;margin:0;padding:0}.echo-input-option{display:flex;align-items:center;gap:.5rem;cursor:pointer;padding:var(--spacing-xs);border-radius:var(--radius-sm);transition:all var(--duration-base) var(--ease-default)}.echo-input-option:hover{background:var(--primary-color-lightest)}.echo-input-option input[type=radio],.echo-input-option input[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;width:18px;height:18px;border:1px solid var(--border-color);background-color:#fff;display:grid;place-content:center;cursor:pointer;transition:all var(--duration-base) var(--ease-default)}.echo-input-option input[type=radio]{border-radius:50%}.echo-input-option input[type=radio]:before{content:"";width:10px;height:10px;border-radius:50%;transform:scale(0);transition:transform var(--duration-base) var(--ease-default);background-color:var(--primary-color)}.echo-input-option input[type=radio]:checked:before{transform:scale(1)}.echo-input-option input[type=checkbox]{border-radius:var(--radius-sm)}.echo-input-option input[type=checkbox]:before{content:"";width:12px;height:12px;transform:scale(0);transition:all var(--duration-base) var(--ease-default);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");background-size:contain;background-repeat:no-repeat;background-position:center}.echo-input-option input[type=checkbox]:checked{background-color:var(--primary-color-lighter);border-color:var(--primary-color-lighter)}.echo-input-option input[type=checkbox]:checked:before{transform:scale(1)}.echo-input-option input[type=radio]:hover,.echo-input-option input[type=checkbox]:hover{border-color:var(--primary-color-lighter)}.echo-input-option input[type=radio]:focus,.echo-input-option input[type=checkbox]:focus{outline:none;border-color:var(--primary-color-lighter);box-shadow:0 0 0 3px color-mix(in srgb,var(--primary-color) 15%,transparent)}.echo-input-option input[type=radio]:checked,.echo-input-option input[type=checkbox]:checked{border-color:var(--primary-color-lighter)}.echo-input-option span{font-size:var(--font-sm);color:var(--text-medium);-webkit-user-select:none;user-select:none}.echo-select{position:relative;width:100%}.echo-select-trigger{width:100%;padding:.5rem;border:1px solid var(--border-color);border-radius:var(--radius-md);background-color:#fff;color:var(--text-medium);font-size:var(--font-sm);transition:all var(--duration-base) var(--ease-default);cursor:pointer;text-align:left;display:flex;align-items:center;justify-content:space-between;gap:.5rem;outline:none}.echo-select-trigger[data-placeholder=true]{color:var(--text-lighter)}.echo-select-trigger:hover{border-color:var(--border-color-medium)}.echo-select-trigger:focus,.echo-select-trigger[data-open=true]{border-color:var(--primary-color);box-shadow:0 0 0 3px color-mix(in srgb,var(--primary-color) 15%,transparent)}.echo-select-arrow{flex-shrink:0;transition:transform var(--duration-base) var(--ease-default)}.echo-select-trigger[data-open=true] .echo-select-arrow{transform:rotate(180deg)}.echo-select-dropdown{position:absolute;top:calc(100% + .25rem);left:0;right:0;background:#fff;border:1px solid var(--border-color-medium);border-radius:var(--radius-md);box-shadow:var(--shadow-black-lightened-md);max-height:15rem;overflow-y:auto;z-index:10;animation:slideDownFade var(--duration-base) var(--ease-default);padding:var(--spacing-xs)}.echo-select-option{width:100%;padding:.5rem .75rem;background:none;border:none;text-align:left;color:var(--text-medium);font-size:var(--font-sm);cursor:pointer;transition:all var(--duration-base) var(--ease-default);outline:none;border-radius:var(--radius-sm)}.echo-select-option:hover{background:var(--primary-color-lightest)}.echo-select-option:focus{background:var(--primary-color-lightest);box-shadow:0 0 0 1px var(--primary-color) inset}.echo-select-option[data-selected=true]{background:var(--primary-color-lightest);color:var(--primary-color);font-weight:500}select.echo-input-field{display:none}.visually-hidden{position:absolute;left:50%;bottom:0;transform:translate(-50%);width:1px;height:1px;padding:0;margin:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
|
package/dist/types.d.ts
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
export type Screenshot = `data:image/png;base64,${string}`;
|
2
|
+
export type BrowserInfo = {
|
3
|
+
width: number;
|
4
|
+
height: number;
|
5
|
+
screenWidth: number;
|
6
|
+
screenHeight: number;
|
7
|
+
language: string;
|
8
|
+
languages: readonly string[];
|
9
|
+
doNotTrack: string | null;
|
10
|
+
cookiesEnabled: boolean;
|
11
|
+
hardwareConcurrency: number;
|
12
|
+
deviceMemory?: number;
|
13
|
+
maxTouchPoints: number;
|
14
|
+
colorDepth: number;
|
15
|
+
pixelRatio: number;
|
16
|
+
availableWidth: number;
|
17
|
+
availableHeight: number;
|
18
|
+
};
|
19
|
+
export type NetworkInfo = {
|
20
|
+
effectiveType?: string;
|
21
|
+
downlink?: number;
|
22
|
+
rtt?: number;
|
23
|
+
saveData?: boolean;
|
24
|
+
};
|
25
|
+
export type LocationInfo = {
|
26
|
+
url: string;
|
27
|
+
origin: string;
|
28
|
+
pathname: string;
|
29
|
+
searchParams: Record<string, string>;
|
30
|
+
referrer: string;
|
31
|
+
};
|
32
|
+
export type TimeInfo = {
|
33
|
+
timezone: string;
|
34
|
+
localDateTime: string;
|
35
|
+
};
|
36
|
+
export type Metadata = {
|
37
|
+
userAgent: string;
|
38
|
+
browserInfo: BrowserInfo;
|
39
|
+
networkInfo: NetworkInfo;
|
40
|
+
locationInfo: LocationInfo;
|
41
|
+
timeInfo: TimeInfo;
|
42
|
+
console: ConsoleEntry[];
|
43
|
+
};
|
44
|
+
export type ConsoleEntry = {
|
45
|
+
type: 'log' | 'warn' | 'error';
|
46
|
+
message: string;
|
47
|
+
timestamp: string;
|
48
|
+
};
|
49
|
+
export type FeedbackPayload = {
|
50
|
+
message: string;
|
51
|
+
screenshot?: Screenshot;
|
52
|
+
metadata: Metadata;
|
53
|
+
customInputs?: Record<string, CustomInputValue>;
|
54
|
+
};
|
55
|
+
export type Position = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
56
|
+
export type TextConfig = {
|
57
|
+
welcomeMessage: {
|
58
|
+
text: string;
|
59
|
+
closeAriaLabel: string;
|
60
|
+
};
|
61
|
+
feedbackForm: {
|
62
|
+
title: string;
|
63
|
+
placeholder: string;
|
64
|
+
screenshotAlt: string;
|
65
|
+
submitButton: string;
|
66
|
+
minimizeTitle: string;
|
67
|
+
expandTitle: string;
|
68
|
+
closeTitle: string;
|
69
|
+
showFormTitle: string;
|
70
|
+
};
|
71
|
+
notification: {
|
72
|
+
successTitle: string;
|
73
|
+
errorTitle: string;
|
74
|
+
errorMessage: string;
|
75
|
+
hideTitle: string;
|
76
|
+
};
|
77
|
+
drawingTooltip: {
|
78
|
+
text: string;
|
79
|
+
};
|
80
|
+
};
|
81
|
+
export type CustomInputValue = string | string[];
|
82
|
+
export type CustomInputBase = {
|
83
|
+
id: string;
|
84
|
+
label?: string;
|
85
|
+
required?: boolean;
|
86
|
+
defaultValue?: CustomInputValue;
|
87
|
+
};
|
88
|
+
export type TextInputConfig = CustomInputBase & {
|
89
|
+
type: 'text';
|
90
|
+
placeholder?: string;
|
91
|
+
};
|
92
|
+
export type TextAreaConfig = CustomInputBase & {
|
93
|
+
type: 'textarea';
|
94
|
+
placeholder?: string;
|
95
|
+
};
|
96
|
+
export type SelectOption = {
|
97
|
+
value: string;
|
98
|
+
label: string;
|
99
|
+
};
|
100
|
+
export type SelectInputConfig = CustomInputBase & {
|
101
|
+
type: 'select';
|
102
|
+
options: SelectOption[];
|
103
|
+
placeholder?: string;
|
104
|
+
};
|
105
|
+
export type RadioInputConfig = CustomInputBase & {
|
106
|
+
type: 'radio';
|
107
|
+
options: SelectOption[];
|
108
|
+
};
|
109
|
+
export type CheckboxInputConfig = CustomInputBase & {
|
110
|
+
type: 'checkbox';
|
111
|
+
options: SelectOption[];
|
112
|
+
};
|
113
|
+
export type CustomInputConfig = TextInputConfig | TextAreaConfig | SelectInputConfig | RadioInputConfig | CheckboxInputConfig;
|
114
|
+
export type EchoConfig = {
|
115
|
+
onSubmit: (data: FeedbackPayload) => Promise<Response | void>;
|
116
|
+
position?: Position;
|
117
|
+
primaryColor?: `#${string}`;
|
118
|
+
textConfig?: Partial<TextConfig>;
|
119
|
+
customInputs?: CustomInputConfig[];
|
120
|
+
};
|
121
|
+
export type FullEchoConfig = Required<EchoConfig> & {
|
122
|
+
textConfig: TextConfig;
|
123
|
+
};
|
124
|
+
export declare const POSITIONS: Record<Position, {
|
125
|
+
[key: string]: string;
|
126
|
+
}>;
|
127
|
+
export type Point = {
|
128
|
+
x: number;
|
129
|
+
y: number;
|
130
|
+
};
|
131
|
+
export type ShapeType = 'rectangle' | 'path';
|
132
|
+
export type DrawingTool = 'rectangle' | 'path';
|
133
|
+
export type Shape = {
|
134
|
+
id: string;
|
135
|
+
type: ShapeType;
|
136
|
+
color: string;
|
137
|
+
points: Point[];
|
138
|
+
};
|
139
|
+
export type IconProps = {
|
140
|
+
size?: number;
|
141
|
+
stroke?: string;
|
142
|
+
strokeWidth?: number;
|
143
|
+
class?: string;
|
144
|
+
style?: any;
|
145
|
+
fill?: string;
|
146
|
+
};
|
147
|
+
export type Notification = {
|
148
|
+
show: boolean;
|
149
|
+
type: 'success' | 'error' | null;
|
150
|
+
message: string | null;
|
151
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const isMobileDevice: () => boolean;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const formatPath: (path: string) => string;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
export * from './color';
|
2
|
+
export * from './common';
|
3
|
+
export * from './console';
|
4
|
+
export * from './device';
|
5
|
+
export * from './events';
|
6
|
+
export * from './format';
|
7
|
+
export * from './geometry';
|
8
|
+
export * from './listeners';
|
9
|
+
export * from './screenshot';
|
10
|
+
export * from './storage';
|
11
|
+
export * from './svg';
|
12
|
+
export * from './validators';
|
@@ -0,0 +1,24 @@
|
|
1
|
+
export declare const registerWindowEventListener: {
|
2
|
+
<K extends keyof WindowEventMap>(props: {
|
3
|
+
event: K;
|
4
|
+
callback: (e: WindowEventMap[K]) => void;
|
5
|
+
onMount?: () => void;
|
6
|
+
onCleanup?: () => void;
|
7
|
+
useOriginal?: boolean;
|
8
|
+
}): void;
|
9
|
+
(props: {
|
10
|
+
event: string;
|
11
|
+
callback: (e: Event) => void;
|
12
|
+
onMount?: () => void;
|
13
|
+
onCleanup?: () => void;
|
14
|
+
useOriginal?: boolean;
|
15
|
+
}): void;
|
16
|
+
};
|
17
|
+
export declare const registerMutationObserver: (props: {
|
18
|
+
target: Node;
|
19
|
+
options?: MutationObserverInit;
|
20
|
+
callback: (mutations: MutationRecord[]) => void;
|
21
|
+
onMount?: () => void;
|
22
|
+
onCleanup?: () => void;
|
23
|
+
}) => void;
|
24
|
+
export declare const createWrappedListener: (originalListener: EventListenerOrEventListenerObject, callback: (event: Event) => void) => (this: EventTarget, event: Event) => void;
|
@@ -0,0 +1,4 @@
|
|
1
|
+
export declare const registerOriginalListener: (target: EventTarget, type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => void;
|
2
|
+
export declare const removeOriginalListener: (target: EventTarget, type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions) => void;
|
3
|
+
export declare const patchEventTarget: (callback: (event: Event) => void) => void;
|
4
|
+
export declare const unpatchEventTarget: () => void;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { DrawingState } from '~/stores/drawingStore';
|
2
|
+
import type { FeedbackState } from '~/stores/feedbackStore';
|
3
|
+
import type { WidgetStore } from '~/stores/widgetStore';
|
4
|
+
export type PageState = {
|
5
|
+
feedback: FeedbackState;
|
6
|
+
drawing: DrawingState;
|
7
|
+
};
|
8
|
+
export declare const createDebouncedStateSaver: (widget: WidgetStore) => (pageKey: string, state: PageState, isClearing?: any) => void;
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { DrawingState, FeedbackState } from '~/stores';
|
2
|
+
import type { CustomInputValue, Shape } from '~/types';
|
3
|
+
type StoredPageState = {
|
4
|
+
feedback: {
|
5
|
+
message: string;
|
6
|
+
customInputValues?: Record<string, CustomInputValue>;
|
7
|
+
};
|
8
|
+
drawing: {
|
9
|
+
shapes: Shape[];
|
10
|
+
};
|
11
|
+
latestQuery?: string;
|
12
|
+
};
|
13
|
+
export declare const formatPagePath: (path: string | undefined) => string;
|
14
|
+
export declare const dispatchStorageChange: () => void;
|
15
|
+
export declare const getStorageKey: (key: string) => string;
|
16
|
+
export declare const getFromStorage: <T>(key: string, defaultValue: T) => T;
|
17
|
+
export declare const setToStorage: <T>(key: string, value: T) => void;
|
18
|
+
export declare const getPageKey: () => string;
|
19
|
+
export declare const savePageState: (pageKey: string, state: {
|
20
|
+
feedback: FeedbackState;
|
21
|
+
drawing: DrawingState;
|
22
|
+
}) => void;
|
23
|
+
export declare const loadPageState: (pageKey: string) => StoredPageState | undefined;
|
24
|
+
export declare const clearPageState: (pageKey: string) => void;
|
25
|
+
export declare const getStoredPagesCount: () => number;
|
26
|
+
export declare const getStoredPages: () => {
|
27
|
+
path: string;
|
28
|
+
state: StoredPageState;
|
29
|
+
}[];
|
30
|
+
export {};
|