hypercrm 1.0.4 → 1.0.5
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/assets/widget.js +91 -6
- package/dist/index.d.ts +38 -0
- package/dist/index.js +15 -0
- package/dist/react.js +27 -5
- package/package.json +1 -1
package/assets/widget.js
CHANGED
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
const styles = `
|
|
54
54
|
.hypercrm-widget-container {
|
|
55
55
|
position: fixed;
|
|
56
|
-
bottom: 24px;
|
|
57
|
-
right: 24px;
|
|
56
|
+
bottom: calc(24px + var(--hypercrm-offset-bottom, 0px));
|
|
57
|
+
right: calc(24px + var(--hypercrm-offset-side, 0px));
|
|
58
58
|
z-index: 2147483000;
|
|
59
59
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
60
60
|
color: var(--hypercrm-text-primary, #111827);
|
|
@@ -78,13 +78,17 @@
|
|
|
78
78
|
--hypercrm-radius-lg: 20px;
|
|
79
79
|
--hypercrm-radius-md: 16px;
|
|
80
80
|
--hypercrm-radius-sm: 12px;
|
|
81
|
+
--hypercrm-offset-bottom: 0px;
|
|
82
|
+
--hypercrm-offset-side: 0px;
|
|
83
|
+
--hypercrm-offset-bottom-mobile: 0px;
|
|
84
|
+
--hypercrm-offset-side-mobile: 0px;
|
|
81
85
|
color-scheme: light;
|
|
82
86
|
-webkit-font-smoothing: antialiased;
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
.hypercrm-widget-container.hypercrm-position-left {
|
|
86
90
|
right: auto;
|
|
87
|
-
left: 24px;
|
|
91
|
+
left: calc(24px + var(--hypercrm-offset-side, 0px));
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
.hypercrm-widget-container.hypercrm-position-left .hypercrm-widget-panel {
|
|
@@ -1291,15 +1295,19 @@
|
|
|
1291
1295
|
|
|
1292
1296
|
@media (max-width: 640px) {
|
|
1293
1297
|
.hypercrm-widget-container {
|
|
1294
|
-
bottom: 16px;
|
|
1295
|
-
right: 16px;
|
|
1298
|
+
bottom: calc(16px + var(--hypercrm-offset-bottom-mobile, 0px));
|
|
1299
|
+
right: calc(16px + var(--hypercrm-offset-side-mobile, 0px));
|
|
1296
1300
|
}
|
|
1297
1301
|
|
|
1298
1302
|
.hypercrm-widget-container.hypercrm-position-left {
|
|
1299
|
-
left: 16px;
|
|
1303
|
+
left: calc(16px + var(--hypercrm-offset-side-mobile, 0px));
|
|
1300
1304
|
right: auto;
|
|
1301
1305
|
}
|
|
1302
1306
|
|
|
1307
|
+
.hypercrm-widget-container.hypercrm-mobile-disabled {
|
|
1308
|
+
display: none;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1303
1311
|
.hypercrm-toggle-btn {
|
|
1304
1312
|
width: 56px;
|
|
1305
1313
|
height: 56px;
|
|
@@ -1331,6 +1339,10 @@
|
|
|
1331
1339
|
this.theme = { ...DEFAULT_THEME, ...(this.options.theme || {}) };
|
|
1332
1340
|
this.colorModePreference = this.options.colorMode || 'light';
|
|
1333
1341
|
this.position = this.normalizePosition(this.options.position);
|
|
1342
|
+
this.offset = this.normalizeOffsets(this.options.offset);
|
|
1343
|
+
const mobileOptions = this.options && typeof this.options.mobile === 'object' ? this.options.mobile : {};
|
|
1344
|
+
this.mobileEnabled = mobileOptions?.enabled !== false;
|
|
1345
|
+
this.mobileOffset = this.normalizeOffsets(mobileOptions?.offset);
|
|
1334
1346
|
this.mediaColorQuery = null;
|
|
1335
1347
|
this.systemColorListener = null;
|
|
1336
1348
|
this.systemColorListenerAttached = false;
|
|
@@ -1401,6 +1413,22 @@
|
|
|
1401
1413
|
return value === 'left' ? 'left' : 'right';
|
|
1402
1414
|
}
|
|
1403
1415
|
|
|
1416
|
+
normalizeOffsetValue(value) {
|
|
1417
|
+
if (value === null || value === undefined || value === '') return 0;
|
|
1418
|
+
const num = Number(value);
|
|
1419
|
+
return Number.isFinite(num) ? num : 0;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
normalizeOffsets(value) {
|
|
1423
|
+
if (!value || typeof value !== 'object') {
|
|
1424
|
+
return { bottom: 0, side: 0 };
|
|
1425
|
+
}
|
|
1426
|
+
return {
|
|
1427
|
+
bottom: this.normalizeOffsetValue(value.bottom),
|
|
1428
|
+
side: this.normalizeOffsetValue(value.side),
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1404
1432
|
applyPosition() {
|
|
1405
1433
|
if (!this.container) return;
|
|
1406
1434
|
const position = this.normalizePosition(this.position || this.options.position);
|
|
@@ -1414,6 +1442,41 @@
|
|
|
1414
1442
|
this.applyPosition();
|
|
1415
1443
|
}
|
|
1416
1444
|
|
|
1445
|
+
applyOffsets() {
|
|
1446
|
+
if (!this.container) return;
|
|
1447
|
+
const offset = this.offset || { bottom: 0, side: 0 };
|
|
1448
|
+
const mobileOffset = this.mobileOffset || { bottom: 0, side: 0 };
|
|
1449
|
+
this.container.style.setProperty('--hypercrm-offset-bottom', `${offset.bottom}px`);
|
|
1450
|
+
this.container.style.setProperty('--hypercrm-offset-side', `${offset.side}px`);
|
|
1451
|
+
this.container.style.setProperty('--hypercrm-offset-bottom-mobile', `${mobileOffset.bottom}px`);
|
|
1452
|
+
this.container.style.setProperty('--hypercrm-offset-side-mobile', `${mobileOffset.side}px`);
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
applyMobileVisibility() {
|
|
1456
|
+
if (!this.container) return;
|
|
1457
|
+
this.container.classList.toggle('hypercrm-mobile-disabled', this.mobileEnabled === false);
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
setOffset(offset) {
|
|
1461
|
+
this.offset = this.normalizeOffsets(offset);
|
|
1462
|
+
this.options.offset = this.offset;
|
|
1463
|
+
this.applyOffsets();
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
setMobileOffset(offset) {
|
|
1467
|
+
this.mobileOffset = this.normalizeOffsets(offset);
|
|
1468
|
+
const current = this.options.mobile && typeof this.options.mobile === 'object' ? this.options.mobile : {};
|
|
1469
|
+
this.options.mobile = { ...current, offset: this.mobileOffset };
|
|
1470
|
+
this.applyOffsets();
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
setMobileEnabled(enabled) {
|
|
1474
|
+
this.mobileEnabled = enabled !== false;
|
|
1475
|
+
const current = this.options.mobile && typeof this.options.mobile === 'object' ? this.options.mobile : {};
|
|
1476
|
+
this.options.mobile = { ...current, enabled: this.mobileEnabled };
|
|
1477
|
+
this.applyMobileVisibility();
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1417
1480
|
absUrl(url) {
|
|
1418
1481
|
if (!url) return url;
|
|
1419
1482
|
if (/^https?:/i.test(url)) return url;
|
|
@@ -1618,6 +1681,8 @@
|
|
|
1618
1681
|
document.body.appendChild(container);
|
|
1619
1682
|
this.container = container;
|
|
1620
1683
|
this.applyPosition();
|
|
1684
|
+
this.applyOffsets();
|
|
1685
|
+
this.applyMobileVisibility();
|
|
1621
1686
|
|
|
1622
1687
|
// Lightbox overlay
|
|
1623
1688
|
const lightbox = document.createElement('div');
|
|
@@ -2371,6 +2436,17 @@
|
|
|
2371
2436
|
if (!this.options.position && this.orgInfo?.widget?.position) {
|
|
2372
2437
|
this.setPosition(this.orgInfo.widget.position);
|
|
2373
2438
|
}
|
|
2439
|
+
const orgOffset = this.orgInfo?.widget?.offset;
|
|
2440
|
+
if (!this.options.offset && orgOffset) {
|
|
2441
|
+
this.setOffset(orgOffset);
|
|
2442
|
+
}
|
|
2443
|
+
const orgMobile = this.orgInfo?.widget?.mobile || {};
|
|
2444
|
+
if (typeof this.options.mobile?.enabled !== 'boolean' && typeof orgMobile.enabled === 'boolean') {
|
|
2445
|
+
this.setMobileEnabled(orgMobile.enabled);
|
|
2446
|
+
}
|
|
2447
|
+
if (!this.options.mobile?.offset && orgMobile.offset) {
|
|
2448
|
+
this.setMobileOffset(orgMobile.offset);
|
|
2449
|
+
}
|
|
2374
2450
|
const iconUrl = this.orgInfo?.widget?.iconUrl;
|
|
2375
2451
|
this.orgIconUrl = iconUrl ? this.absUrl(iconUrl) : null;
|
|
2376
2452
|
this.updateHeaderIcons();
|
|
@@ -2954,6 +3030,15 @@
|
|
|
2954
3030
|
setPosition(position) {
|
|
2955
3031
|
if (activeWidget) activeWidget.setPosition(position);
|
|
2956
3032
|
},
|
|
3033
|
+
setOffset(offset) {
|
|
3034
|
+
if (activeWidget) activeWidget.setOffset(offset);
|
|
3035
|
+
},
|
|
3036
|
+
setMobileOffset(offset) {
|
|
3037
|
+
if (activeWidget) activeWidget.setMobileOffset(offset);
|
|
3038
|
+
},
|
|
3039
|
+
setMobileEnabled(enabled) {
|
|
3040
|
+
if (activeWidget) activeWidget.setMobileEnabled(enabled);
|
|
3041
|
+
},
|
|
2957
3042
|
open() {
|
|
2958
3043
|
if (activeWidget) activeWidget.openWidget();
|
|
2959
3044
|
},
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,17 @@ export interface WidgetOptions {
|
|
|
6
6
|
theme?: Record<string, string>;
|
|
7
7
|
colorMode?: 'light' | 'dark' | 'auto';
|
|
8
8
|
position?: 'left' | 'right';
|
|
9
|
+
offset?: {
|
|
10
|
+
bottom?: number;
|
|
11
|
+
side?: number;
|
|
12
|
+
};
|
|
13
|
+
mobile?: {
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
offset?: {
|
|
16
|
+
bottom?: number;
|
|
17
|
+
side?: number;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
9
20
|
autoOpen?: boolean;
|
|
10
21
|
debug?: boolean;
|
|
11
22
|
scriptUrl?: string;
|
|
@@ -15,12 +26,30 @@ export declare const destroyWidget: () => void;
|
|
|
15
26
|
export declare const setWidgetTheme: (theme: Record<string, string>) => Promise<void>;
|
|
16
27
|
export declare const setWidgetColorMode: (mode: "light" | "dark" | "auto") => Promise<void>;
|
|
17
28
|
export declare const setWidgetPosition: (position: "left" | "right") => Promise<void>;
|
|
29
|
+
export declare const setWidgetOffset: (offset: {
|
|
30
|
+
bottom?: number;
|
|
31
|
+
side?: number;
|
|
32
|
+
}) => Promise<void>;
|
|
33
|
+
export declare const setWidgetMobileOffset: (offset: {
|
|
34
|
+
bottom?: number;
|
|
35
|
+
side?: number;
|
|
36
|
+
}) => Promise<void>;
|
|
37
|
+
export declare const setWidgetMobileEnabled: (enabled: boolean) => Promise<void>;
|
|
18
38
|
declare const _default: {
|
|
19
39
|
init: (options?: WidgetOptions) => Promise<any>;
|
|
20
40
|
destroy: () => void;
|
|
21
41
|
setTheme: (theme: Record<string, string>) => Promise<void>;
|
|
22
42
|
setColorMode: (mode: "light" | "dark" | "auto") => Promise<void>;
|
|
23
43
|
setPosition: (position: "left" | "right") => Promise<void>;
|
|
44
|
+
setOffset: (offset: {
|
|
45
|
+
bottom?: number;
|
|
46
|
+
side?: number;
|
|
47
|
+
}) => Promise<void>;
|
|
48
|
+
setMobileOffset: (offset: {
|
|
49
|
+
bottom?: number;
|
|
50
|
+
side?: number;
|
|
51
|
+
}) => Promise<void>;
|
|
52
|
+
setMobileEnabled: (enabled: boolean) => Promise<void>;
|
|
24
53
|
};
|
|
25
54
|
export default _default;
|
|
26
55
|
declare global {
|
|
@@ -31,6 +60,15 @@ declare global {
|
|
|
31
60
|
setTheme: (theme?: Record<string, string>) => void;
|
|
32
61
|
setColorMode: (mode: 'light' | 'dark' | 'auto') => void;
|
|
33
62
|
setPosition: (position: 'left' | 'right') => void;
|
|
63
|
+
setOffset: (offset: {
|
|
64
|
+
bottom?: number;
|
|
65
|
+
side?: number;
|
|
66
|
+
}) => void;
|
|
67
|
+
setMobileOffset: (offset: {
|
|
68
|
+
bottom?: number;
|
|
69
|
+
side?: number;
|
|
70
|
+
}) => void;
|
|
71
|
+
setMobileEnabled: (enabled: boolean) => void;
|
|
34
72
|
open: () => void;
|
|
35
73
|
close: () => void;
|
|
36
74
|
toggle: () => void;
|
package/dist/index.js
CHANGED
|
@@ -95,10 +95,25 @@ export const setWidgetPosition = async (position) => {
|
|
|
95
95
|
await ensureScriptLoaded();
|
|
96
96
|
window.HyperCRMWidget.setPosition(position);
|
|
97
97
|
};
|
|
98
|
+
export const setWidgetOffset = async (offset) => {
|
|
99
|
+
await ensureScriptLoaded();
|
|
100
|
+
window.HyperCRMWidget.setOffset(offset || {});
|
|
101
|
+
};
|
|
102
|
+
export const setWidgetMobileOffset = async (offset) => {
|
|
103
|
+
await ensureScriptLoaded();
|
|
104
|
+
window.HyperCRMWidget.setMobileOffset(offset || {});
|
|
105
|
+
};
|
|
106
|
+
export const setWidgetMobileEnabled = async (enabled) => {
|
|
107
|
+
await ensureScriptLoaded();
|
|
108
|
+
window.HyperCRMWidget.setMobileEnabled(enabled);
|
|
109
|
+
};
|
|
98
110
|
export default {
|
|
99
111
|
init: initWidget,
|
|
100
112
|
destroy: destroyWidget,
|
|
101
113
|
setTheme: setWidgetTheme,
|
|
102
114
|
setColorMode: setWidgetColorMode,
|
|
103
115
|
setPosition: setWidgetPosition,
|
|
116
|
+
setOffset: setWidgetOffset,
|
|
117
|
+
setMobileOffset: setWidgetMobileOffset,
|
|
118
|
+
setMobileEnabled: setWidgetMobileEnabled,
|
|
104
119
|
};
|
package/dist/react.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
|
-
import { initWidget, destroyWidget, setWidgetTheme, setWidgetColorMode, setWidgetPosition, } from './index';
|
|
2
|
+
import { initWidget, destroyWidget, setWidgetTheme, setWidgetColorMode, setWidgetPosition, setWidgetOffset, setWidgetMobileOffset, setWidgetMobileEnabled, } from './index';
|
|
3
3
|
export const useHyperCRMWidget = (options = {}) => {
|
|
4
|
-
const { apiUrl, apiKey, orgId, mount, theme, colorMode, position, autoOpen, debug, scriptUrl, } = options;
|
|
4
|
+
const { apiUrl, apiKey, orgId, mount, theme, colorMode, position, offset, mobile, autoOpen, debug, scriptUrl, } = options;
|
|
5
5
|
const readyRef = useRef(false);
|
|
6
|
-
const latestRef = useRef({ theme, colorMode, position });
|
|
6
|
+
const latestRef = useRef({ theme, colorMode, position, offset, mobile });
|
|
7
7
|
useEffect(() => {
|
|
8
|
-
latestRef.current = { theme, colorMode, position };
|
|
9
|
-
}, [theme, colorMode, position]);
|
|
8
|
+
latestRef.current = { theme, colorMode, position, offset, mobile };
|
|
9
|
+
}, [theme, colorMode, position, offset, mobile]);
|
|
10
10
|
useEffect(() => {
|
|
11
11
|
let cancelled = false;
|
|
12
12
|
readyRef.current = false;
|
|
@@ -18,11 +18,14 @@ export const useHyperCRMWidget = (options = {}) => {
|
|
|
18
18
|
theme: latestRef.current.theme,
|
|
19
19
|
colorMode: latestRef.current.colorMode,
|
|
20
20
|
position: latestRef.current.position,
|
|
21
|
+
offset: latestRef.current.offset,
|
|
22
|
+
mobile: latestRef.current.mobile,
|
|
21
23
|
autoOpen,
|
|
22
24
|
debug,
|
|
23
25
|
scriptUrl,
|
|
24
26
|
})
|
|
25
27
|
.then(() => {
|
|
28
|
+
var _a, _b;
|
|
26
29
|
if (cancelled)
|
|
27
30
|
return;
|
|
28
31
|
readyRef.current = true;
|
|
@@ -32,6 +35,12 @@ export const useHyperCRMWidget = (options = {}) => {
|
|
|
32
35
|
setWidgetColorMode(latest.colorMode);
|
|
33
36
|
if (latest.position)
|
|
34
37
|
setWidgetPosition(latest.position);
|
|
38
|
+
if (latest.offset)
|
|
39
|
+
setWidgetOffset(latest.offset);
|
|
40
|
+
if ((_a = latest.mobile) === null || _a === void 0 ? void 0 : _a.offset)
|
|
41
|
+
setWidgetMobileOffset(latest.mobile.offset);
|
|
42
|
+
if (typeof ((_b = latest.mobile) === null || _b === void 0 ? void 0 : _b.enabled) === 'boolean')
|
|
43
|
+
setWidgetMobileEnabled(latest.mobile.enabled);
|
|
35
44
|
})
|
|
36
45
|
.catch((err) => {
|
|
37
46
|
if (debug)
|
|
@@ -58,6 +67,19 @@ export const useHyperCRMWidget = (options = {}) => {
|
|
|
58
67
|
return;
|
|
59
68
|
setWidgetPosition(position);
|
|
60
69
|
}, [position]);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
if (!readyRef.current || !offset)
|
|
72
|
+
return;
|
|
73
|
+
setWidgetOffset(offset);
|
|
74
|
+
}, [offset]);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (!readyRef.current)
|
|
77
|
+
return;
|
|
78
|
+
if (mobile === null || mobile === void 0 ? void 0 : mobile.offset)
|
|
79
|
+
setWidgetMobileOffset(mobile.offset);
|
|
80
|
+
if (typeof (mobile === null || mobile === void 0 ? void 0 : mobile.enabled) === 'boolean')
|
|
81
|
+
setWidgetMobileEnabled(mobile.enabled);
|
|
82
|
+
}, [mobile]);
|
|
61
83
|
};
|
|
62
84
|
export const HyperCRMWidget = (props) => {
|
|
63
85
|
useHyperCRMWidget(props);
|