hypercrm 1.0.3 → 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 +92 -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 {
|
|
@@ -106,6 +110,7 @@
|
|
|
106
110
|
.hypercrm-toggle-btn {
|
|
107
111
|
width: 50px;
|
|
108
112
|
height: 50px;
|
|
113
|
+
padding: 0;
|
|
109
114
|
border-radius: 50%;
|
|
110
115
|
border: none;
|
|
111
116
|
display: flex;
|
|
@@ -1290,15 +1295,19 @@
|
|
|
1290
1295
|
|
|
1291
1296
|
@media (max-width: 640px) {
|
|
1292
1297
|
.hypercrm-widget-container {
|
|
1293
|
-
bottom: 16px;
|
|
1294
|
-
right: 16px;
|
|
1298
|
+
bottom: calc(16px + var(--hypercrm-offset-bottom-mobile, 0px));
|
|
1299
|
+
right: calc(16px + var(--hypercrm-offset-side-mobile, 0px));
|
|
1295
1300
|
}
|
|
1296
1301
|
|
|
1297
1302
|
.hypercrm-widget-container.hypercrm-position-left {
|
|
1298
|
-
left: 16px;
|
|
1303
|
+
left: calc(16px + var(--hypercrm-offset-side-mobile, 0px));
|
|
1299
1304
|
right: auto;
|
|
1300
1305
|
}
|
|
1301
1306
|
|
|
1307
|
+
.hypercrm-widget-container.hypercrm-mobile-disabled {
|
|
1308
|
+
display: none;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1302
1311
|
.hypercrm-toggle-btn {
|
|
1303
1312
|
width: 56px;
|
|
1304
1313
|
height: 56px;
|
|
@@ -1330,6 +1339,10 @@
|
|
|
1330
1339
|
this.theme = { ...DEFAULT_THEME, ...(this.options.theme || {}) };
|
|
1331
1340
|
this.colorModePreference = this.options.colorMode || 'light';
|
|
1332
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);
|
|
1333
1346
|
this.mediaColorQuery = null;
|
|
1334
1347
|
this.systemColorListener = null;
|
|
1335
1348
|
this.systemColorListenerAttached = false;
|
|
@@ -1400,6 +1413,22 @@
|
|
|
1400
1413
|
return value === 'left' ? 'left' : 'right';
|
|
1401
1414
|
}
|
|
1402
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
|
+
|
|
1403
1432
|
applyPosition() {
|
|
1404
1433
|
if (!this.container) return;
|
|
1405
1434
|
const position = this.normalizePosition(this.position || this.options.position);
|
|
@@ -1413,6 +1442,41 @@
|
|
|
1413
1442
|
this.applyPosition();
|
|
1414
1443
|
}
|
|
1415
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
|
+
|
|
1416
1480
|
absUrl(url) {
|
|
1417
1481
|
if (!url) return url;
|
|
1418
1482
|
if (/^https?:/i.test(url)) return url;
|
|
@@ -1617,6 +1681,8 @@
|
|
|
1617
1681
|
document.body.appendChild(container);
|
|
1618
1682
|
this.container = container;
|
|
1619
1683
|
this.applyPosition();
|
|
1684
|
+
this.applyOffsets();
|
|
1685
|
+
this.applyMobileVisibility();
|
|
1620
1686
|
|
|
1621
1687
|
// Lightbox overlay
|
|
1622
1688
|
const lightbox = document.createElement('div');
|
|
@@ -2370,6 +2436,17 @@
|
|
|
2370
2436
|
if (!this.options.position && this.orgInfo?.widget?.position) {
|
|
2371
2437
|
this.setPosition(this.orgInfo.widget.position);
|
|
2372
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
|
+
}
|
|
2373
2450
|
const iconUrl = this.orgInfo?.widget?.iconUrl;
|
|
2374
2451
|
this.orgIconUrl = iconUrl ? this.absUrl(iconUrl) : null;
|
|
2375
2452
|
this.updateHeaderIcons();
|
|
@@ -2953,6 +3030,15 @@
|
|
|
2953
3030
|
setPosition(position) {
|
|
2954
3031
|
if (activeWidget) activeWidget.setPosition(position);
|
|
2955
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
|
+
},
|
|
2956
3042
|
open() {
|
|
2957
3043
|
if (activeWidget) activeWidget.openWidget();
|
|
2958
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);
|