maquinaweb-ui 2.72.3 → 2.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytics/core.d.ts +35 -0
- package/dist/analytics/core.d.ts.map +1 -0
- package/dist/analytics/core.js +189 -0
- package/dist/analytics/core.js.map +1 -0
- package/dist/analytics/delegated-clicks.d.ts +17 -0
- package/dist/analytics/delegated-clicks.d.ts.map +1 -0
- package/dist/analytics/delegated-clicks.js +259 -0
- package/dist/analytics/delegated-clicks.js.map +1 -0
- package/dist/analytics/provider.d.ts +21 -0
- package/dist/analytics/provider.d.ts.map +1 -0
- package/dist/analytics/provider.js +74 -0
- package/dist/analytics/provider.js.map +1 -0
- package/dist/analytics/types.d.ts +59 -0
- package/dist/analytics/types.d.ts.map +1 -0
- package/dist/analytics.d.ts +5 -0
- package/dist/analytics.js +8 -0
- package/dist/container-animation/container-animation.d.ts +2 -2
- package/dist/date-field/DateField.d.ts +2 -2
- package/dist/date-hour-field/DateHourField.d.ts +2 -2
- package/dist/date-hour-field/DateHourField.d.ts.map +1 -1
- package/dist/input-suggest/input-suggest.d.ts +2 -2
- package/dist/kanban-dnd/kanban-card-item.d.ts +2 -2
- package/dist/kanban-dnd/kanban-dnd-monitor.d.ts +2 -2
- package/dist/kanban-dnd/kanban-dropzone.d.ts +2 -2
- package/dist/kanban-dnd/kanban-selector.d.ts +2 -2
- package/dist/landing-text/client-landing-text.js +1 -1
- package/dist/landing-text/client-landing-text.js.map +1 -1
- package/dist/landing-text/landing-text.d.ts +2 -2
- package/dist/landing-text/landing-text.d.ts.map +1 -1
- package/dist/landing-text/server-landing-text.d.ts +2 -2
- package/dist/page-header/page-header.d.ts +2 -2
- package/dist/remote-selector/remote-selector.d.ts +3 -3
- package/dist/remote-selector/remote-selector.d.ts.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { AnalyticsConfig, AnalyticsDeviceInfo, AnalyticsPageInfo, AnalyticsUtmInfo, TrackEventOptions } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/components/analytics/core.d.ts
|
|
4
|
+
declare function createAnalyticsId(prefix: string): string;
|
|
5
|
+
declare function parseUtmParamsFromUrl(url: string): AnalyticsUtmInfo;
|
|
6
|
+
declare function shouldRotateSession(lastActivityAt: number, now: number, timeoutMs: number): boolean;
|
|
7
|
+
declare function detectDevice(userAgent: string): AnalyticsDeviceInfo;
|
|
8
|
+
declare function getCurrentPageSnapshot(fallback?: AnalyticsPageInfo): AnalyticsPageInfo;
|
|
9
|
+
declare class AnalyticsBrowserClient {
|
|
10
|
+
private config;
|
|
11
|
+
private queue;
|
|
12
|
+
private flushTimer;
|
|
13
|
+
constructor(config: AnalyticsConfig);
|
|
14
|
+
updateConfig(config: AnalyticsConfig): void;
|
|
15
|
+
private get isEnabled();
|
|
16
|
+
private get visitorStorageKey();
|
|
17
|
+
private get sessionStorageKey();
|
|
18
|
+
private getVisitorId;
|
|
19
|
+
private getSession;
|
|
20
|
+
private updateSessionActivity;
|
|
21
|
+
private enqueue;
|
|
22
|
+
flush(): Promise<void>;
|
|
23
|
+
private buildEvent;
|
|
24
|
+
trackPageView(page?: AnalyticsPageInfo): void;
|
|
25
|
+
trackEvent(eventName: string, properties?: Record<string, unknown>, options?: TrackEventOptions): void;
|
|
26
|
+
trackConversion(conversionName: string, properties?: Record<string, unknown>, conversionValue?: number | string | null): void;
|
|
27
|
+
}
|
|
28
|
+
declare function initializeAnalytics(config: AnalyticsConfig): AnalyticsBrowserClient;
|
|
29
|
+
declare function getAnalyticsClient(): AnalyticsBrowserClient | null;
|
|
30
|
+
declare function trackPageView(page?: AnalyticsPageInfo): void;
|
|
31
|
+
declare function trackEvent(eventName: string, properties?: Record<string, unknown>, options?: TrackEventOptions): void;
|
|
32
|
+
declare function trackConversion(conversionName: string, properties?: Record<string, unknown>, conversionValue?: number | string | null): void;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { createAnalyticsId, detectDevice, getAnalyticsClient, getCurrentPageSnapshot, initializeAnalytics, parseUtmParamsFromUrl, shouldRotateSession, trackConversion, trackEvent, trackPageView };
|
|
35
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","names":[],"sources":["../../src/components/analytics/core.ts"],"sourcesContent":[],"mappings":";;;iBAsBgB,iBAAA;iBAQA,qBAAA,eAAoC;AARpC,iBAoBA,mBAAA,CApBiB,cAAA,EAAA,MAAA,EAAA,GAAA,EAAA,MAAA,EAAA,SAAA,EAAA,MAAA,CAAA,EAAA,OAAA;AAQjB,iBAoBA,YAAA,CApBqB,SAAe,EAAA,MAAA,CAAA,EAoBH,mBApBmB;AAYpD,iBA6CA,sBAAA,CA7CmB,QAAA,CAAA,EA8CtB,iBA9CsB,CAAA,EA+ChC,iBA/CgC;AAQnC,cAoDM,sBAAA,CApD2C;EAqCjC,QAAA,MAAA;EAeV,QAAA,KAAA;EAQgB,QAAA,UAAA;EAYC,WAAA,CAAA,MAAA,EAZD,eAYC;EAoGV,YAAA,CAAA,MAAA,EApGU,eAoGV,CAAA,EAAA,IAAA;EA8DU,YAAA,SAAA,CAAA;EASN,YAAA,iBAAA,CAAA;EACH,YAAA,iBAAA,CAAA;EAgBG,QAAA,YAAA;EAAM,QAAA,UAAA;EAmBP,QAAA,qBAAmB;EAUnB,QAAA,OAAA;EAIA,KAAA,CAAA,CAAA,EAzHH,OAyHgB,CAAA,IAAA,CAAA;EAIb,QAAA,UAAU;EAQV,aAAA,CAAA,IAEK,CAFU,EAvER,iBAyEF,CAAA,EAAA,IAAA;6CAhEJ,mCACH;uDAgBG;;iBAmBD,mBAAA,SAA4B,kBAAe;iBAU3C,kBAAA,CAAA,GAAkB;iBAIlB,aAAA,QAAqB;iBAIrB,UAAA,iCAED,mCACH;iBAKI,eAAA,sCAED"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
//#region src/components/analytics/core.ts
|
|
5
|
+
const DEFAULT_SESSION_TIMEOUT = 1e3 * 60 * 30;
|
|
6
|
+
function createAnalyticsId(prefix) {
|
|
7
|
+
if (typeof crypto !== "undefined" && "randomUUID" in crypto) return `${prefix}_${crypto.randomUUID()}`;
|
|
8
|
+
return `${prefix}_${Math.random().toString(36).slice(2, 10)}`;
|
|
9
|
+
}
|
|
10
|
+
function parseUtmParamsFromUrl(url) {
|
|
11
|
+
const searchParams = new URL(url, "https://placeholder.local").searchParams;
|
|
12
|
+
return {
|
|
13
|
+
source: searchParams.get("utm_source") || void 0,
|
|
14
|
+
medium: searchParams.get("utm_medium") || void 0,
|
|
15
|
+
campaign: searchParams.get("utm_campaign") || void 0,
|
|
16
|
+
term: searchParams.get("utm_term") || void 0,
|
|
17
|
+
content: searchParams.get("utm_content") || void 0
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function shouldRotateSession(lastActivityAt, now, timeoutMs) {
|
|
21
|
+
return now - lastActivityAt >= timeoutMs;
|
|
22
|
+
}
|
|
23
|
+
function detectDevice(userAgent) {
|
|
24
|
+
const ua = userAgent.toLowerCase();
|
|
25
|
+
return {
|
|
26
|
+
type: ua.includes("bot") || ua.includes("crawler") ? "bot" : /tablet|ipad/.test(ua) ? "tablet" : /mobi|android|iphone/.test(ua) ? "mobile" : "desktop",
|
|
27
|
+
browser: ua.includes("edg/") ? "Edge" : ua.includes("chrome/") ? "Chrome" : ua.includes("firefox/") ? "Firefox" : ua.includes("safari/") && !ua.includes("chrome/") ? "Safari" : "Unknown",
|
|
28
|
+
os: ua.includes("windows") ? "Windows" : ua.includes("mac os") || ua.includes("macintosh") ? "macOS" : ua.includes("iphone") || ua.includes("ipad") ? "iOS" : ua.includes("android") ? "Android" : ua.includes("linux") ? "Linux" : "Unknown"
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function getCurrentPageSnapshot(fallback) {
|
|
32
|
+
if (typeof window === "undefined") return fallback || {};
|
|
33
|
+
return {
|
|
34
|
+
path: fallback?.path || `${window.location.pathname}${window.location.search || ""}`,
|
|
35
|
+
title: fallback?.title || document.title
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
var AnalyticsBrowserClient = class {
|
|
39
|
+
config;
|
|
40
|
+
queue = [];
|
|
41
|
+
flushTimer = null;
|
|
42
|
+
constructor(config) {
|
|
43
|
+
this.config = {
|
|
44
|
+
enabled: config.enabled ?? true,
|
|
45
|
+
endpoint: config.endpoint,
|
|
46
|
+
siteKey: config.siteKey,
|
|
47
|
+
sessionTimeoutMs: config.sessionTimeoutMs ?? DEFAULT_SESSION_TIMEOUT,
|
|
48
|
+
storageKeyPrefix: config.storageKeyPrefix ?? "mw.analytics",
|
|
49
|
+
delegatedClickTracking: config.delegatedClickTracking ?? true,
|
|
50
|
+
inferClickEvents: config.inferClickEvents ?? true
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
updateConfig(config) {
|
|
54
|
+
this.config = {
|
|
55
|
+
...this.config,
|
|
56
|
+
...config,
|
|
57
|
+
enabled: config.enabled ?? this.config.enabled,
|
|
58
|
+
sessionTimeoutMs: config.sessionTimeoutMs ?? this.config.sessionTimeoutMs,
|
|
59
|
+
storageKeyPrefix: config.storageKeyPrefix ?? this.config.storageKeyPrefix,
|
|
60
|
+
delegatedClickTracking: config.delegatedClickTracking ?? this.config.delegatedClickTracking,
|
|
61
|
+
inferClickEvents: config.inferClickEvents ?? this.config.inferClickEvents
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
get isEnabled() {
|
|
65
|
+
return Boolean(this.config.enabled && this.config.endpoint && this.config.siteKey && typeof window !== "undefined");
|
|
66
|
+
}
|
|
67
|
+
get visitorStorageKey() {
|
|
68
|
+
return `${this.config.storageKeyPrefix}.visitor`;
|
|
69
|
+
}
|
|
70
|
+
get sessionStorageKey() {
|
|
71
|
+
return `${this.config.storageKeyPrefix}.session`;
|
|
72
|
+
}
|
|
73
|
+
getVisitorId() {
|
|
74
|
+
const existingVisitorId = window.localStorage.getItem(this.visitorStorageKey);
|
|
75
|
+
if (existingVisitorId) return existingVisitorId;
|
|
76
|
+
const visitorId = createAnalyticsId("visitor");
|
|
77
|
+
window.localStorage.setItem(this.visitorStorageKey, visitorId);
|
|
78
|
+
return visitorId;
|
|
79
|
+
}
|
|
80
|
+
getSession(now = Date.now()) {
|
|
81
|
+
const rawSession = window.localStorage.getItem(this.sessionStorageKey);
|
|
82
|
+
if (rawSession) try {
|
|
83
|
+
const persistedSession = JSON.parse(rawSession);
|
|
84
|
+
if (!shouldRotateSession(persistedSession.lastActivityAt, now, this.config.sessionTimeoutMs)) return persistedSession;
|
|
85
|
+
} catch {}
|
|
86
|
+
const nextSession = {
|
|
87
|
+
id: createAnalyticsId("session"),
|
|
88
|
+
startedAt: now,
|
|
89
|
+
lastActivityAt: now,
|
|
90
|
+
utm: parseUtmParamsFromUrl(window.location.href)
|
|
91
|
+
};
|
|
92
|
+
window.localStorage.setItem(this.sessionStorageKey, JSON.stringify(nextSession));
|
|
93
|
+
return nextSession;
|
|
94
|
+
}
|
|
95
|
+
updateSessionActivity(session, now = Date.now()) {
|
|
96
|
+
const nextSession = {
|
|
97
|
+
...session,
|
|
98
|
+
lastActivityAt: now,
|
|
99
|
+
utm: Object.values(session.utm || {}).some(Boolean) ? session.utm : parseUtmParamsFromUrl(window.location.href)
|
|
100
|
+
};
|
|
101
|
+
window.localStorage.setItem(this.sessionStorageKey, JSON.stringify(nextSession));
|
|
102
|
+
return nextSession;
|
|
103
|
+
}
|
|
104
|
+
enqueue(event) {
|
|
105
|
+
this.queue.push(event);
|
|
106
|
+
if (this.flushTimer) return;
|
|
107
|
+
this.flushTimer = setTimeout(() => {
|
|
108
|
+
this.flush();
|
|
109
|
+
}, 300);
|
|
110
|
+
}
|
|
111
|
+
async flush() {
|
|
112
|
+
if (!this.isEnabled || this.queue.length === 0) {
|
|
113
|
+
this.flushTimer = null;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const payload = JSON.stringify({
|
|
117
|
+
siteKey: this.config.siteKey,
|
|
118
|
+
events: [...this.queue]
|
|
119
|
+
});
|
|
120
|
+
this.queue = [];
|
|
121
|
+
this.flushTimer = null;
|
|
122
|
+
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
|
|
123
|
+
const blob = new Blob([payload], { type: "application/json" });
|
|
124
|
+
if (navigator.sendBeacon(this.config.endpoint, blob)) return;
|
|
125
|
+
}
|
|
126
|
+
await fetch(this.config.endpoint, {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: { "Content-Type": "application/json" },
|
|
129
|
+
body: payload,
|
|
130
|
+
keepalive: true
|
|
131
|
+
}).catch(() => null);
|
|
132
|
+
}
|
|
133
|
+
buildEvent(eventType, eventName, page, properties, conversion) {
|
|
134
|
+
if (!this.isEnabled) return null;
|
|
135
|
+
const now = Date.now();
|
|
136
|
+
const visitorId = this.getVisitorId();
|
|
137
|
+
const session = this.updateSessionActivity(this.getSession(now), now);
|
|
138
|
+
return {
|
|
139
|
+
visitorId,
|
|
140
|
+
sessionId: session.id,
|
|
141
|
+
eventType,
|
|
142
|
+
eventName,
|
|
143
|
+
occurredAt: new Date(now).toISOString(),
|
|
144
|
+
page: getCurrentPageSnapshot(page),
|
|
145
|
+
referrer: document.referrer || void 0,
|
|
146
|
+
utm: session.utm,
|
|
147
|
+
device: detectDevice(navigator.userAgent),
|
|
148
|
+
properties,
|
|
149
|
+
conversion
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
trackPageView(page) {
|
|
153
|
+
const event = this.buildEvent("page_view", "page_view", page);
|
|
154
|
+
if (event) this.enqueue(event);
|
|
155
|
+
}
|
|
156
|
+
trackEvent(eventName, properties, options) {
|
|
157
|
+
const event = this.buildEvent(options?.eventType ?? "custom", eventName, options?.page, properties);
|
|
158
|
+
if (event) this.enqueue(event);
|
|
159
|
+
}
|
|
160
|
+
trackConversion(conversionName, properties, conversionValue) {
|
|
161
|
+
const event = this.buildEvent("conversion", conversionName, void 0, properties, {
|
|
162
|
+
name: conversionName,
|
|
163
|
+
value: conversionValue
|
|
164
|
+
});
|
|
165
|
+
if (event) this.enqueue(event);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
let analyticsClient = null;
|
|
169
|
+
function initializeAnalytics(config) {
|
|
170
|
+
if (!analyticsClient) analyticsClient = new AnalyticsBrowserClient(config);
|
|
171
|
+
else analyticsClient.updateConfig(config);
|
|
172
|
+
return analyticsClient;
|
|
173
|
+
}
|
|
174
|
+
function getAnalyticsClient() {
|
|
175
|
+
return analyticsClient;
|
|
176
|
+
}
|
|
177
|
+
function trackPageView(page) {
|
|
178
|
+
analyticsClient?.trackPageView(page);
|
|
179
|
+
}
|
|
180
|
+
function trackEvent(eventName, properties, options) {
|
|
181
|
+
analyticsClient?.trackEvent(eventName, properties, options);
|
|
182
|
+
}
|
|
183
|
+
function trackConversion(conversionName, properties, conversionValue) {
|
|
184
|
+
analyticsClient?.trackConversion(conversionName, properties, conversionValue);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
//#endregion
|
|
188
|
+
export { createAnalyticsId, detectDevice, getAnalyticsClient, getCurrentPageSnapshot, initializeAnalytics, parseUtmParamsFromUrl, shouldRotateSession, trackConversion, trackEvent, trackPageView };
|
|
189
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","names":["nextSession: PersistedSession","analyticsClient: AnalyticsBrowserClient | null"],"sources":["../../src/components/analytics/core.ts"],"sourcesContent":["'use client';\n\nimport type {\n AnalyticsConfig,\n AnalyticsConversionPayload,\n AnalyticsDeviceInfo,\n AnalyticsEventPayload,\n AnalyticsEventType,\n AnalyticsPageInfo,\n AnalyticsUtmInfo,\n TrackEventOptions,\n} from './types';\n\ntype PersistedSession = {\n id: string;\n startedAt: number;\n lastActivityAt: number;\n utm: AnalyticsUtmInfo;\n};\n\nconst DEFAULT_SESSION_TIMEOUT = 1000 * 60 * 30;\n\nexport function createAnalyticsId(prefix: string) {\n if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n return `${prefix}_${crypto.randomUUID()}`;\n }\n\n return `${prefix}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport function parseUtmParamsFromUrl(url: string): AnalyticsUtmInfo {\n const searchParams = new URL(url, 'https://placeholder.local').searchParams;\n\n return {\n source: searchParams.get('utm_source') || undefined,\n medium: searchParams.get('utm_medium') || undefined,\n campaign: searchParams.get('utm_campaign') || undefined,\n term: searchParams.get('utm_term') || undefined,\n content: searchParams.get('utm_content') || undefined,\n };\n}\n\nexport function shouldRotateSession(\n lastActivityAt: number,\n now: number,\n timeoutMs: number\n) {\n return now - lastActivityAt >= timeoutMs;\n}\n\nexport function detectDevice(userAgent: string): AnalyticsDeviceInfo {\n const ua = userAgent.toLowerCase();\n\n const type =\n ua.includes('bot') || ua.includes('crawler')\n ? 'bot'\n : /tablet|ipad/.test(ua)\n ? 'tablet'\n : /mobi|android|iphone/.test(ua)\n ? 'mobile'\n : 'desktop';\n\n const browser = ua.includes('edg/')\n ? 'Edge'\n : ua.includes('chrome/')\n ? 'Chrome'\n : ua.includes('firefox/')\n ? 'Firefox'\n : ua.includes('safari/') && !ua.includes('chrome/')\n ? 'Safari'\n : 'Unknown';\n\n const os = ua.includes('windows')\n ? 'Windows'\n : ua.includes('mac os') || ua.includes('macintosh')\n ? 'macOS'\n : ua.includes('iphone') || ua.includes('ipad')\n ? 'iOS'\n : ua.includes('android')\n ? 'Android'\n : ua.includes('linux')\n ? 'Linux'\n : 'Unknown';\n\n return { type, browser, os };\n}\n\nexport function getCurrentPageSnapshot(\n fallback?: AnalyticsPageInfo\n): AnalyticsPageInfo {\n if (typeof window === 'undefined') {\n return fallback || {};\n }\n\n return {\n path:\n fallback?.path ||\n `${window.location.pathname}${window.location.search || ''}`,\n title: fallback?.title || document.title,\n };\n}\n\nclass AnalyticsBrowserClient {\n private config: Required<\n Pick<AnalyticsConfig, 'sessionTimeoutMs' | 'storageKeyPrefix'>\n > &\n Omit<AnalyticsConfig, 'sessionTimeoutMs' | 'storageKeyPrefix'>;\n private queue: AnalyticsEventPayload[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: AnalyticsConfig) {\n this.config = {\n enabled: config.enabled ?? true,\n endpoint: config.endpoint,\n siteKey: config.siteKey,\n sessionTimeoutMs: config.sessionTimeoutMs ?? DEFAULT_SESSION_TIMEOUT,\n storageKeyPrefix: config.storageKeyPrefix ?? 'mw.analytics',\n delegatedClickTracking: config.delegatedClickTracking ?? true,\n inferClickEvents: config.inferClickEvents ?? true,\n };\n }\n\n updateConfig(config: AnalyticsConfig) {\n this.config = {\n ...this.config,\n ...config,\n enabled: config.enabled ?? this.config.enabled,\n sessionTimeoutMs: config.sessionTimeoutMs ?? this.config.sessionTimeoutMs,\n storageKeyPrefix: config.storageKeyPrefix ?? this.config.storageKeyPrefix,\n delegatedClickTracking:\n config.delegatedClickTracking ?? this.config.delegatedClickTracking,\n inferClickEvents: config.inferClickEvents ?? this.config.inferClickEvents,\n };\n }\n\n private get isEnabled() {\n return Boolean(\n this.config.enabled &&\n this.config.endpoint &&\n this.config.siteKey &&\n typeof window !== 'undefined'\n );\n }\n\n private get visitorStorageKey() {\n return `${this.config.storageKeyPrefix}.visitor`;\n }\n\n private get sessionStorageKey() {\n return `${this.config.storageKeyPrefix}.session`;\n }\n\n private getVisitorId() {\n const existingVisitorId = window.localStorage.getItem(\n this.visitorStorageKey\n );\n if (existingVisitorId) {\n return existingVisitorId;\n }\n\n const visitorId = createAnalyticsId('visitor');\n window.localStorage.setItem(this.visitorStorageKey, visitorId);\n return visitorId;\n }\n\n private getSession(now = Date.now()) {\n const rawSession = window.localStorage.getItem(this.sessionStorageKey);\n if (rawSession) {\n try {\n const persistedSession = JSON.parse(rawSession) as PersistedSession;\n if (\n !shouldRotateSession(\n persistedSession.lastActivityAt,\n now,\n this.config.sessionTimeoutMs\n )\n ) {\n return persistedSession;\n }\n } catch {}\n }\n\n const nextSession: PersistedSession = {\n id: createAnalyticsId('session'),\n startedAt: now,\n lastActivityAt: now,\n utm: parseUtmParamsFromUrl(window.location.href),\n };\n window.localStorage.setItem(\n this.sessionStorageKey,\n JSON.stringify(nextSession)\n );\n return nextSession;\n }\n\n private updateSessionActivity(session: PersistedSession, now = Date.now()) {\n const nextSession = {\n ...session,\n lastActivityAt: now,\n utm: Object.values(session.utm || {}).some(Boolean)\n ? session.utm\n : parseUtmParamsFromUrl(window.location.href),\n };\n window.localStorage.setItem(\n this.sessionStorageKey,\n JSON.stringify(nextSession)\n );\n return nextSession;\n }\n\n private enqueue(event: AnalyticsEventPayload) {\n this.queue.push(event);\n\n if (this.flushTimer) {\n return;\n }\n\n this.flushTimer = setTimeout(() => {\n void this.flush();\n }, 300);\n }\n\n async flush() {\n if (!this.isEnabled || this.queue.length === 0) {\n this.flushTimer = null;\n return;\n }\n\n const payload = JSON.stringify({\n siteKey: this.config.siteKey,\n events: [...this.queue],\n });\n\n this.queue = [];\n this.flushTimer = null;\n\n if (\n typeof navigator !== 'undefined' &&\n typeof navigator.sendBeacon === 'function'\n ) {\n const blob = new Blob([payload], { type: 'application/json' });\n if (navigator.sendBeacon(this.config.endpoint!, blob)) {\n return;\n }\n }\n\n await fetch(this.config.endpoint!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: payload,\n keepalive: true,\n }).catch(() => null);\n }\n\n private buildEvent(\n eventType: AnalyticsEventType,\n eventName: string,\n page?: AnalyticsPageInfo,\n properties?: Record<string, unknown>,\n conversion?: AnalyticsConversionPayload\n ): AnalyticsEventPayload | null {\n if (!this.isEnabled) {\n return null;\n }\n\n const now = Date.now();\n const visitorId = this.getVisitorId();\n const session = this.updateSessionActivity(this.getSession(now), now);\n\n return {\n visitorId,\n sessionId: session.id,\n eventType,\n eventName,\n occurredAt: new Date(now).toISOString(),\n page: getCurrentPageSnapshot(page),\n referrer: document.referrer || undefined,\n utm: session.utm,\n device: detectDevice(navigator.userAgent),\n properties,\n conversion,\n };\n }\n\n trackPageView(page?: AnalyticsPageInfo) {\n const event = this.buildEvent('page_view', 'page_view', page);\n if (event) {\n this.enqueue(event);\n }\n }\n\n trackEvent(\n eventName: string,\n properties?: Record<string, unknown>,\n options?: TrackEventOptions\n ) {\n const event = this.buildEvent(\n options?.eventType ?? 'custom',\n eventName,\n options?.page,\n properties\n );\n\n if (event) {\n this.enqueue(event);\n }\n }\n\n trackConversion(\n conversionName: string,\n properties?: Record<string, unknown>,\n conversionValue?: number | string | null\n ) {\n const event = this.buildEvent(\n 'conversion',\n conversionName,\n undefined,\n properties,\n { name: conversionName, value: conversionValue }\n );\n\n if (event) {\n this.enqueue(event);\n }\n }\n}\n\nlet analyticsClient: AnalyticsBrowserClient | null = null;\n\nexport function initializeAnalytics(config: AnalyticsConfig) {\n if (!analyticsClient) {\n analyticsClient = new AnalyticsBrowserClient(config);\n } else {\n analyticsClient.updateConfig(config);\n }\n\n return analyticsClient;\n}\n\nexport function getAnalyticsClient() {\n return analyticsClient;\n}\n\nexport function trackPageView(page?: AnalyticsPageInfo) {\n analyticsClient?.trackPageView(page);\n}\n\nexport function trackEvent(\n eventName: string,\n properties?: Record<string, unknown>,\n options?: TrackEventOptions\n) {\n analyticsClient?.trackEvent(eventName, properties, options);\n}\n\nexport function trackConversion(\n conversionName: string,\n properties?: Record<string, unknown>,\n conversionValue?: number | string | null\n) {\n analyticsClient?.trackConversion(conversionName, properties, conversionValue);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AnalyticsAttributesInput } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/components/analytics/delegated-clicks.d.ts
|
|
4
|
+
type BindAnalyticsClickTrackingOptions = {
|
|
5
|
+
inferClickEvents?: boolean;
|
|
6
|
+
};
|
|
7
|
+
declare function bindAnalyticsClickTracking(options?: BindAnalyticsClickTrackingOptions): () => void;
|
|
8
|
+
declare function analyticsAttributes(input: AnalyticsAttributesInput): {
|
|
9
|
+
'data-analytics-event': string | undefined;
|
|
10
|
+
'data-analytics-event-type': "cta_click" | "custom" | undefined;
|
|
11
|
+
'data-analytics-properties': string | undefined;
|
|
12
|
+
'data-analytics-conversion': string | undefined;
|
|
13
|
+
'data-analytics-conversion-value': string | number | undefined;
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { analyticsAttributes, bindAnalyticsClickTracking };
|
|
17
|
+
//# sourceMappingURL=delegated-clicks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegated-clicks.d.ts","names":[],"sources":["../../src/components/analytics/delegated-clicks.ts"],"sourcesContent":[],"mappings":";;;KAgBK,iCAAA;;AATY,CAAA;AAkaD,iBAAA,0BAAA,CACL,OAAsC,CAAtC,EAAA,iCAAsC,CAAA,EAAA,GAAA,GAAA,IAAA;AAiBjC,iBAAA,mBAAA,CAA2B,KAAA,EAAA,wBAAwB,CAAA,EAAA"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import { getAnalyticsClient, trackConversion, trackEvent } from "./core.js";
|
|
5
|
+
|
|
6
|
+
//#region src/components/analytics/delegated-clicks.ts
|
|
7
|
+
const TRACKABLE_SELECTOR = ["[data-analytics-event]", "[data-analytics-conversion]"].join(",");
|
|
8
|
+
const CLICKABLE_ELEMENT_SELECTOR = [
|
|
9
|
+
"a",
|
|
10
|
+
"area[href]",
|
|
11
|
+
"button",
|
|
12
|
+
"summary",
|
|
13
|
+
"input[type=\"submit\"]",
|
|
14
|
+
"input[type=\"button\"]",
|
|
15
|
+
"input[type=\"reset\"]",
|
|
16
|
+
"input[type=\"image\"]",
|
|
17
|
+
"[role=\"button\"]",
|
|
18
|
+
"[role=\"link\"]",
|
|
19
|
+
"[role=\"menuitem\"]",
|
|
20
|
+
"[role=\"menuitemcheckbox\"]",
|
|
21
|
+
"[role=\"menuitemradio\"]",
|
|
22
|
+
"[role=\"tab\"]",
|
|
23
|
+
"[role=\"switch\"]",
|
|
24
|
+
"[role=\"checkbox\"]",
|
|
25
|
+
"[role=\"radio\"]",
|
|
26
|
+
"[role=\"option\"]",
|
|
27
|
+
"[role=\"treeitem\"]",
|
|
28
|
+
"[role=\"combobox\"]",
|
|
29
|
+
"[tabindex]:not([tabindex=\"-1\"])"
|
|
30
|
+
].join(",");
|
|
31
|
+
const INTERACTIVE_SELECTOR = [
|
|
32
|
+
"a[href]",
|
|
33
|
+
"area[href]",
|
|
34
|
+
"button",
|
|
35
|
+
"summary",
|
|
36
|
+
"input[type=\"submit\"]",
|
|
37
|
+
"input[type=\"button\"]",
|
|
38
|
+
"input[type=\"reset\"]",
|
|
39
|
+
"input[type=\"image\"]",
|
|
40
|
+
"[role=\"button\"]",
|
|
41
|
+
"[role=\"link\"]",
|
|
42
|
+
"[role=\"menuitem\"]",
|
|
43
|
+
"[role=\"menuitemcheckbox\"]",
|
|
44
|
+
"[role=\"menuitemradio\"]",
|
|
45
|
+
"[role=\"tab\"]",
|
|
46
|
+
"[role=\"switch\"]",
|
|
47
|
+
"[role=\"checkbox\"]",
|
|
48
|
+
"[role=\"radio\"]",
|
|
49
|
+
"[role=\"option\"]",
|
|
50
|
+
"[role=\"treeitem\"]",
|
|
51
|
+
"[role=\"combobox\"]",
|
|
52
|
+
"[tabindex]:not([tabindex=\"-1\"])",
|
|
53
|
+
"[data-analytics-event]",
|
|
54
|
+
"[data-analytics-conversion]"
|
|
55
|
+
].join(",");
|
|
56
|
+
let clickTrackingOptions = { inferClickEvents: true };
|
|
57
|
+
function parseJsonObject(value) {
|
|
58
|
+
if (!value) return;
|
|
59
|
+
try {
|
|
60
|
+
const parsed = JSON.parse(value);
|
|
61
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
62
|
+
} catch {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function parseConversion(element) {
|
|
67
|
+
const conversionName = element.dataset.analyticsConversion;
|
|
68
|
+
if (!conversionName) return;
|
|
69
|
+
return {
|
|
70
|
+
name: conversionName,
|
|
71
|
+
value: element.dataset.analyticsConversionValue || void 0
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function parseEventType(value) {
|
|
75
|
+
return value === "custom" || value === "cta_click" ? value : "cta_click";
|
|
76
|
+
}
|
|
77
|
+
function normalizeText(value, maxLength = 160) {
|
|
78
|
+
const normalized = value?.replace(/\s+/g, " ").trim();
|
|
79
|
+
if (!normalized) return;
|
|
80
|
+
return normalized.length > maxLength ? `${normalized.slice(0, maxLength - 1)}…` : normalized;
|
|
81
|
+
}
|
|
82
|
+
function resolveAriaLabelledBy(element) {
|
|
83
|
+
const ids = element.getAttribute("aria-labelledby");
|
|
84
|
+
if (!ids) return void 0;
|
|
85
|
+
return normalizeText(ids.split(/\s+/).map((id) => document.getElementById(id)?.textContent).filter(Boolean).join(" "));
|
|
86
|
+
}
|
|
87
|
+
function getInputValue(element) {
|
|
88
|
+
if (element instanceof HTMLInputElement) return normalizeText(element.value) || normalizeText(element.placeholder);
|
|
89
|
+
if (element instanceof HTMLSelectElement) return normalizeText(element.options[element.selectedIndex]?.text);
|
|
90
|
+
}
|
|
91
|
+
function getElementLabel(element) {
|
|
92
|
+
return normalizeText(element.dataset.analyticsLabel) || normalizeText(element.dataset.title) || normalizeText(element.getAttribute("aria-label")) || resolveAriaLabelledBy(element) || normalizeText(element.getAttribute("title")) || normalizeText(element.getAttribute("name")) || getInputValue(element) || normalizeText(element.innerText || element.textContent);
|
|
93
|
+
}
|
|
94
|
+
const SECTION_SELECTOR = [
|
|
95
|
+
"[data-analytics-section]",
|
|
96
|
+
"[data-section]",
|
|
97
|
+
"section",
|
|
98
|
+
"nav",
|
|
99
|
+
"header",
|
|
100
|
+
"footer",
|
|
101
|
+
"main",
|
|
102
|
+
"aside",
|
|
103
|
+
"form",
|
|
104
|
+
"[role=\"navigation\"]",
|
|
105
|
+
"[role=\"banner\"]",
|
|
106
|
+
"[role=\"contentinfo\"]",
|
|
107
|
+
"[role=\"complementary\"]",
|
|
108
|
+
"[role=\"region\"]",
|
|
109
|
+
"[role=\"search\"]",
|
|
110
|
+
"[role=\"form\"]",
|
|
111
|
+
"[role=\"tablist\"]",
|
|
112
|
+
"[role=\"menu\"]",
|
|
113
|
+
"[role=\"menubar\"]",
|
|
114
|
+
"[role=\"toolbar\"]",
|
|
115
|
+
"[role=\"listbox\"]",
|
|
116
|
+
"[role=\"tree\"]",
|
|
117
|
+
"[role=\"dialog\"]",
|
|
118
|
+
"[role=\"alertdialog\"]"
|
|
119
|
+
].join(",");
|
|
120
|
+
function getClosestSectionLabel(element) {
|
|
121
|
+
const section = element.closest(SECTION_SELECTOR);
|
|
122
|
+
if (!section) return;
|
|
123
|
+
return normalizeText(section.dataset.analyticsSection) || normalizeText(section.dataset.section) || normalizeText(section.getAttribute("aria-label")) || normalizeText(section.getAttribute("aria-roledescription")) || normalizeText(section.getAttribute("id"));
|
|
124
|
+
}
|
|
125
|
+
function getInteractionKind(element) {
|
|
126
|
+
if (element instanceof HTMLAnchorElement || element instanceof HTMLAreaElement) return "link";
|
|
127
|
+
if (element instanceof HTMLButtonElement) return "button";
|
|
128
|
+
if (element instanceof HTMLInputElement) {
|
|
129
|
+
const type = element.type?.toLowerCase();
|
|
130
|
+
if (type === "submit" || type === "button" || type === "reset" || type === "image") return "button";
|
|
131
|
+
return "input";
|
|
132
|
+
}
|
|
133
|
+
if (element.tagName === "SUMMARY") return "summary";
|
|
134
|
+
switch (element.getAttribute("role")) {
|
|
135
|
+
case "button": return "button";
|
|
136
|
+
case "link": return "link";
|
|
137
|
+
case "menuitem":
|
|
138
|
+
case "menuitemcheckbox":
|
|
139
|
+
case "menuitemradio": return "menu-item";
|
|
140
|
+
case "tab": return "tab";
|
|
141
|
+
case "switch":
|
|
142
|
+
case "checkbox":
|
|
143
|
+
case "radio": return "toggle";
|
|
144
|
+
case "option":
|
|
145
|
+
case "treeitem": return "option";
|
|
146
|
+
case "combobox": return "combobox";
|
|
147
|
+
default: return "element";
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function getHrefProperties(element) {
|
|
151
|
+
const rawHref = element instanceof HTMLAnchorElement || element instanceof HTMLAreaElement ? element.href : element.getAttribute("href");
|
|
152
|
+
if (!rawHref) return {};
|
|
153
|
+
let url = null;
|
|
154
|
+
try {
|
|
155
|
+
url = new URL(rawHref, window.location.href);
|
|
156
|
+
} catch {}
|
|
157
|
+
return {
|
|
158
|
+
href: element.getAttribute("href") || void 0,
|
|
159
|
+
href_host: url?.host || void 0,
|
|
160
|
+
href_path: url ? `${url.pathname}${url.search || ""}` : void 0,
|
|
161
|
+
is_external: url ? url.origin !== window.location.origin : void 0,
|
|
162
|
+
target: element.getAttribute("target") || void 0
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function getAriaState(element) {
|
|
166
|
+
const state = {};
|
|
167
|
+
const expanded = element.getAttribute("aria-expanded");
|
|
168
|
+
if (expanded) state.aria_expanded = expanded === "true";
|
|
169
|
+
const pressed = element.getAttribute("aria-pressed");
|
|
170
|
+
if (pressed) state.aria_pressed = pressed === "true";
|
|
171
|
+
const selected = element.getAttribute("aria-selected");
|
|
172
|
+
if (selected) state.aria_selected = selected === "true";
|
|
173
|
+
const checked = element.getAttribute("aria-checked");
|
|
174
|
+
if (checked) state.aria_checked = checked === "true" ? true : checked;
|
|
175
|
+
if (element.hasAttribute("disabled") || element.getAttribute("aria-disabled") === "true") state.disabled = true;
|
|
176
|
+
return state;
|
|
177
|
+
}
|
|
178
|
+
function inferElementProperties(element) {
|
|
179
|
+
return {
|
|
180
|
+
label: getElementLabel(element),
|
|
181
|
+
title: normalizeText(element.getAttribute("title")),
|
|
182
|
+
aria_label: normalizeText(element.getAttribute("aria-label")),
|
|
183
|
+
data_title: normalizeText(element.dataset.title),
|
|
184
|
+
id: normalizeText(element.id),
|
|
185
|
+
name: normalizeText(element.getAttribute("name")),
|
|
186
|
+
role: normalizeText(element.getAttribute("role")),
|
|
187
|
+
element_type: getInteractionKind(element),
|
|
188
|
+
tag_name: element.tagName.toLowerCase(),
|
|
189
|
+
section: getClosestSectionLabel(element),
|
|
190
|
+
...getHrefProperties(element),
|
|
191
|
+
...getAriaState(element)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const INFERRED_EVENT_NAMES = {
|
|
195
|
+
link: "link_click",
|
|
196
|
+
tab: "tab_click",
|
|
197
|
+
"menu-item": "menu_item_click",
|
|
198
|
+
toggle: "toggle_click",
|
|
199
|
+
option: "option_click",
|
|
200
|
+
summary: "summary_click",
|
|
201
|
+
combobox: "combobox_click"
|
|
202
|
+
};
|
|
203
|
+
function getInferredEventName(element) {
|
|
204
|
+
return INFERRED_EVENT_NAMES[getInteractionKind(element)] || "button_click";
|
|
205
|
+
}
|
|
206
|
+
function getDelegatedAnalyticsData(element, interactiveElement) {
|
|
207
|
+
const explicitProperties = parseJsonObject(element.dataset.analyticsProperties);
|
|
208
|
+
return {
|
|
209
|
+
eventName: element.dataset.analyticsEvent || (clickTrackingOptions.inferClickEvents ? getInferredEventName(interactiveElement) : void 0),
|
|
210
|
+
eventType: parseEventType(element.dataset.analyticsEventType),
|
|
211
|
+
properties: {
|
|
212
|
+
...inferElementProperties(interactiveElement),
|
|
213
|
+
...explicitProperties
|
|
214
|
+
},
|
|
215
|
+
conversion: parseConversion(element)
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function findTrackableElement(target) {
|
|
219
|
+
if (!(target instanceof Element)) return null;
|
|
220
|
+
const explicitElement = target.closest(TRACKABLE_SELECTOR);
|
|
221
|
+
if (explicitElement) return explicitElement;
|
|
222
|
+
if (!clickTrackingOptions.inferClickEvents) return null;
|
|
223
|
+
return target.closest(INTERACTIVE_SELECTOR);
|
|
224
|
+
}
|
|
225
|
+
function handleDelegatedClick(event) {
|
|
226
|
+
const element = findTrackableElement(event.target);
|
|
227
|
+
if (!element || event.defaultPrevented || element.dataset.analyticsDisabled === "true") return;
|
|
228
|
+
const interactiveElement = (event.target instanceof Element ? event.target : null)?.closest(CLICKABLE_ELEMENT_SELECTOR);
|
|
229
|
+
if (!interactiveElement || !element.contains(interactiveElement) && !interactiveElement.contains(element)) return;
|
|
230
|
+
const data = getDelegatedAnalyticsData(element, interactiveElement);
|
|
231
|
+
if (data.eventName) trackEvent(data.eventName, data.properties, { eventType: data.eventType });
|
|
232
|
+
if (data.conversion) trackConversion(data.conversion.name, data.properties, data.conversion.value);
|
|
233
|
+
getAnalyticsClient()?.flush();
|
|
234
|
+
}
|
|
235
|
+
function bindAnalyticsClickTracking(options = {}) {
|
|
236
|
+
if (typeof document === "undefined") return () => {};
|
|
237
|
+
clickTrackingOptions = { inferClickEvents: options.inferClickEvents ?? true };
|
|
238
|
+
document.addEventListener("click", handleDelegatedClick);
|
|
239
|
+
return () => {
|
|
240
|
+
document.removeEventListener("click", handleDelegatedClick);
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
function analyticsAttributes(input) {
|
|
244
|
+
const conversion = typeof input.conversion === "string" ? {
|
|
245
|
+
name: input.conversion,
|
|
246
|
+
value: input.conversionValue
|
|
247
|
+
} : input.conversion;
|
|
248
|
+
return {
|
|
249
|
+
"data-analytics-event": input.event,
|
|
250
|
+
"data-analytics-event-type": input.eventType,
|
|
251
|
+
"data-analytics-properties": input.properties ? JSON.stringify(input.properties) : void 0,
|
|
252
|
+
"data-analytics-conversion": conversion?.name,
|
|
253
|
+
"data-analytics-conversion-value": conversion?.value ?? void 0
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
//#endregion
|
|
258
|
+
export { analyticsAttributes, bindAnalyticsClickTracking };
|
|
259
|
+
//# sourceMappingURL=delegated-clicks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegated-clicks.js","names":["clickTrackingOptions: Required<BindAnalyticsClickTrackingOptions>","url: URL | null","state: Record<string, string | boolean | undefined>","INFERRED_EVENT_NAMES: Record<string, string>"],"sources":["../../src/components/analytics/delegated-clicks.ts"],"sourcesContent":["'use client';\n\nimport { getAnalyticsClient, trackConversion, trackEvent } from './core';\nimport type {\n AnalyticsAttributesInput,\n AnalyticsConversionPayload,\n AnalyticsEventType,\n} from './types';\n\ntype DelegatedAnalyticsData = {\n eventName?: string;\n eventType: Exclude<AnalyticsEventType, 'conversion' | 'page_view'>;\n properties?: Record<string, unknown>;\n conversion?: AnalyticsConversionPayload;\n};\n\ntype BindAnalyticsClickTrackingOptions = {\n inferClickEvents?: boolean;\n};\n\nconst TRACKABLE_SELECTOR = [\n '[data-analytics-event]',\n '[data-analytics-conversion]',\n].join(',');\n\nconst CLICKABLE_ELEMENT_SELECTOR = [\n // Native HTML interactive elements\n 'a',\n 'area[href]',\n 'button',\n 'summary',\n 'input[type=\"submit\"]',\n 'input[type=\"button\"]',\n 'input[type=\"reset\"]',\n 'input[type=\"image\"]',\n // ARIA widget roles\n '[role=\"button\"]',\n '[role=\"link\"]',\n '[role=\"menuitem\"]',\n '[role=\"menuitemcheckbox\"]',\n '[role=\"menuitemradio\"]',\n '[role=\"tab\"]',\n '[role=\"switch\"]',\n '[role=\"checkbox\"]',\n '[role=\"radio\"]',\n '[role=\"option\"]',\n '[role=\"treeitem\"]',\n '[role=\"combobox\"]',\n // Custom focusable elements\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',');\n\nconst INTERACTIVE_SELECTOR = [\n 'a[href]',\n 'area[href]',\n 'button',\n 'summary',\n 'input[type=\"submit\"]',\n 'input[type=\"button\"]',\n 'input[type=\"reset\"]',\n 'input[type=\"image\"]',\n '[role=\"button\"]',\n '[role=\"link\"]',\n '[role=\"menuitem\"]',\n '[role=\"menuitemcheckbox\"]',\n '[role=\"menuitemradio\"]',\n '[role=\"tab\"]',\n '[role=\"switch\"]',\n '[role=\"checkbox\"]',\n '[role=\"radio\"]',\n '[role=\"option\"]',\n '[role=\"treeitem\"]',\n '[role=\"combobox\"]',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[data-analytics-event]',\n '[data-analytics-conversion]',\n].join(',');\n\nlet clickTrackingOptions: Required<BindAnalyticsClickTrackingOptions> = {\n inferClickEvents: true,\n};\n\nfunction parseJsonObject(value: string | undefined) {\n if (!value) {\n return undefined;\n }\n\n try {\n const parsed = JSON.parse(value);\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction parseConversion(element: HTMLElement) {\n const conversionName = element.dataset.analyticsConversion;\n if (!conversionName) {\n return undefined;\n }\n\n return {\n name: conversionName,\n value: element.dataset.analyticsConversionValue || undefined,\n };\n}\n\nfunction parseEventType(value: string | undefined) {\n return value === 'custom' || value === 'cta_click' ? value : 'cta_click';\n}\n\nfunction normalizeText(value: string | null | undefined, maxLength = 160) {\n const normalized = value?.replace(/\\s+/g, ' ').trim();\n if (!normalized) {\n return undefined;\n }\n\n return normalized.length > maxLength\n ? `${normalized.slice(0, maxLength - 1)}…`\n : normalized;\n}\n\nfunction resolveAriaLabelledBy(element: HTMLElement) {\n const ids = element.getAttribute('aria-labelledby');\n if (!ids) return undefined;\n\n const text = ids\n .split(/\\s+/)\n .map((id) => document.getElementById(id)?.textContent)\n .filter(Boolean)\n .join(' ');\n\n return normalizeText(text);\n}\n\nfunction getInputValue(element: HTMLElement) {\n if (element instanceof HTMLInputElement) {\n return normalizeText(element.value) || normalizeText(element.placeholder);\n }\n\n if (element instanceof HTMLSelectElement) {\n return normalizeText(element.options[element.selectedIndex]?.text);\n }\n\n return undefined;\n}\n\nfunction getElementLabel(element: HTMLElement) {\n return (\n normalizeText(element.dataset.analyticsLabel) ||\n normalizeText(element.dataset.title) ||\n normalizeText(element.getAttribute('aria-label')) ||\n resolveAriaLabelledBy(element) ||\n normalizeText(element.getAttribute('title')) ||\n normalizeText(element.getAttribute('name')) ||\n getInputValue(element) ||\n normalizeText(element.innerText || element.textContent)\n );\n}\n\nconst SECTION_SELECTOR = [\n '[data-analytics-section]',\n '[data-section]',\n // HTML5 semantic elements\n 'section',\n 'nav',\n 'header',\n 'footer',\n 'main',\n 'aside',\n 'form',\n // ARIA landmark roles\n '[role=\"navigation\"]',\n '[role=\"banner\"]',\n '[role=\"contentinfo\"]',\n '[role=\"complementary\"]',\n '[role=\"region\"]',\n '[role=\"search\"]',\n '[role=\"form\"]',\n // ARIA container/widget roles\n '[role=\"tablist\"]',\n '[role=\"menu\"]',\n '[role=\"menubar\"]',\n '[role=\"toolbar\"]',\n '[role=\"listbox\"]',\n '[role=\"tree\"]',\n '[role=\"dialog\"]',\n '[role=\"alertdialog\"]',\n].join(',');\n\nfunction getClosestSectionLabel(element: HTMLElement) {\n const section = element.closest<HTMLElement>(SECTION_SELECTOR);\n\n if (!section) {\n return undefined;\n }\n\n return (\n normalizeText(section.dataset.analyticsSection) ||\n normalizeText(section.dataset.section) ||\n normalizeText(section.getAttribute('aria-label')) ||\n normalizeText(section.getAttribute('aria-roledescription')) ||\n normalizeText(section.getAttribute('id'))\n );\n}\n\nfunction getInteractionKind(element: HTMLElement) {\n if (\n element instanceof HTMLAnchorElement ||\n element instanceof HTMLAreaElement\n ) {\n return 'link';\n }\n\n if (element instanceof HTMLButtonElement) {\n return 'button';\n }\n\n if (element instanceof HTMLInputElement) {\n const type = element.type?.toLowerCase();\n if (\n type === 'submit' ||\n type === 'button' ||\n type === 'reset' ||\n type === 'image'\n ) {\n return 'button';\n }\n return 'input';\n }\n\n if (element.tagName === 'SUMMARY') {\n return 'summary';\n }\n\n const role = element.getAttribute('role');\n switch (role) {\n case 'button':\n return 'button';\n case 'link':\n return 'link';\n case 'menuitem':\n case 'menuitemcheckbox':\n case 'menuitemradio':\n return 'menu-item';\n case 'tab':\n return 'tab';\n case 'switch':\n case 'checkbox':\n case 'radio':\n return 'toggle';\n case 'option':\n case 'treeitem':\n return 'option';\n case 'combobox':\n return 'combobox';\n default:\n return 'element';\n }\n}\n\nfunction getHrefProperties(element: HTMLElement) {\n const rawHref =\n element instanceof HTMLAnchorElement ||\n element instanceof HTMLAreaElement\n ? element.href\n : element.getAttribute('href');\n\n if (!rawHref) {\n return {};\n }\n\n let url: URL | null = null;\n try {\n url = new URL(rawHref, window.location.href);\n } catch {}\n\n return {\n href: element.getAttribute('href') || undefined,\n href_host: url?.host || undefined,\n href_path: url ? `${url.pathname}${url.search || ''}` : undefined,\n is_external: url ? url.origin !== window.location.origin : undefined,\n target: element.getAttribute('target') || undefined,\n };\n}\n\nfunction getAriaState(element: HTMLElement) {\n const state: Record<string, string | boolean | undefined> = {};\n\n const expanded = element.getAttribute('aria-expanded');\n if (expanded) state.aria_expanded = expanded === 'true';\n\n const pressed = element.getAttribute('aria-pressed');\n if (pressed) state.aria_pressed = pressed === 'true';\n\n const selected = element.getAttribute('aria-selected');\n if (selected) state.aria_selected = selected === 'true';\n\n const checked = element.getAttribute('aria-checked');\n if (checked) state.aria_checked = checked === 'true' ? true : checked;\n\n if (\n element.hasAttribute('disabled') ||\n element.getAttribute('aria-disabled') === 'true'\n ) {\n state.disabled = true;\n }\n\n return state;\n}\n\nfunction inferElementProperties(element: HTMLElement) {\n return {\n label: getElementLabel(element),\n title: normalizeText(element.getAttribute('title')),\n aria_label: normalizeText(element.getAttribute('aria-label')),\n data_title: normalizeText(element.dataset.title),\n id: normalizeText(element.id),\n name: normalizeText(element.getAttribute('name')),\n role: normalizeText(element.getAttribute('role')),\n element_type: getInteractionKind(element),\n tag_name: element.tagName.toLowerCase(),\n section: getClosestSectionLabel(element),\n ...getHrefProperties(element),\n ...getAriaState(element),\n };\n}\n\nconst INFERRED_EVENT_NAMES: Record<string, string> = {\n link: 'link_click',\n tab: 'tab_click',\n 'menu-item': 'menu_item_click',\n toggle: 'toggle_click',\n option: 'option_click',\n summary: 'summary_click',\n combobox: 'combobox_click',\n};\n\nfunction getInferredEventName(element: HTMLElement) {\n const kind = getInteractionKind(element);\n return INFERRED_EVENT_NAMES[kind] || 'button_click';\n}\n\nfunction getDelegatedAnalyticsData(\n element: HTMLElement,\n interactiveElement: HTMLElement\n): DelegatedAnalyticsData {\n const explicitProperties = parseJsonObject(\n element.dataset.analyticsProperties\n );\n\n return {\n eventName:\n element.dataset.analyticsEvent ||\n (clickTrackingOptions.inferClickEvents\n ? getInferredEventName(interactiveElement)\n : undefined),\n eventType: parseEventType(element.dataset.analyticsEventType),\n properties: {\n ...inferElementProperties(interactiveElement),\n ...explicitProperties,\n },\n conversion: parseConversion(element),\n };\n}\n\nfunction findTrackableElement(target: EventTarget | null) {\n if (!(target instanceof Element)) {\n return null;\n }\n\n const explicitElement = target.closest<HTMLElement>(TRACKABLE_SELECTOR);\n if (explicitElement) {\n return explicitElement;\n }\n\n if (!clickTrackingOptions.inferClickEvents) {\n return null;\n }\n\n return target.closest<HTMLElement>(INTERACTIVE_SELECTOR);\n}\n\nfunction handleDelegatedClick(event: MouseEvent) {\n const element = findTrackableElement(event.target);\n if (\n !element ||\n event.defaultPrevented ||\n element.dataset.analyticsDisabled === 'true'\n ) {\n return;\n }\n\n const target = event.target instanceof Element ? event.target : null;\n const interactiveElement = target?.closest<HTMLElement>(\n CLICKABLE_ELEMENT_SELECTOR\n );\n if (\n !interactiveElement ||\n (!element.contains(interactiveElement) &&\n !interactiveElement.contains(element))\n ) {\n return;\n }\n\n const data = getDelegatedAnalyticsData(element, interactiveElement);\n if (data.eventName) {\n trackEvent(data.eventName, data.properties, {\n eventType: data.eventType,\n });\n }\n\n if (data.conversion) {\n trackConversion(\n data.conversion.name,\n data.properties,\n data.conversion.value\n );\n }\n\n void getAnalyticsClient()?.flush();\n}\n\nexport function bindAnalyticsClickTracking(\n options: BindAnalyticsClickTrackingOptions = {}\n) {\n if (typeof document === 'undefined') {\n return () => {};\n }\n\n clickTrackingOptions = {\n inferClickEvents: options.inferClickEvents ?? true,\n };\n\n document.addEventListener('click', handleDelegatedClick);\n\n return () => {\n document.removeEventListener('click', handleDelegatedClick);\n };\n}\n\nexport function analyticsAttributes(input: AnalyticsAttributesInput) {\n const conversion =\n typeof input.conversion === 'string'\n ? { name: input.conversion, value: input.conversionValue }\n : input.conversion;\n\n return {\n 'data-analytics-event': input.event,\n 'data-analytics-event-type': input.eventType,\n 'data-analytics-properties': input.properties\n ? JSON.stringify(input.properties)\n : undefined,\n 'data-analytics-conversion': conversion?.name,\n 'data-analytics-conversion-value': conversion?.value ?? undefined,\n } satisfies Record<string, string | number | undefined | null>;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AnalyticsConfig } from "./types.js";
|
|
2
|
+
import { trackConversion, trackEvent, trackPageView } from "./core.js";
|
|
3
|
+
import * as react_jsx_runtime11 from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/components/analytics/provider.d.ts
|
|
6
|
+
declare function AnalyticsProvider({
|
|
7
|
+
children,
|
|
8
|
+
config: configOverride
|
|
9
|
+
}: {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
config?: AnalyticsConfig;
|
|
12
|
+
}): react_jsx_runtime11.JSX.Element;
|
|
13
|
+
declare function useAnalytics(): {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
trackPageView: typeof trackPageView;
|
|
16
|
+
trackEvent: typeof trackEvent;
|
|
17
|
+
trackConversion: typeof trackConversion;
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
export { AnalyticsProvider, useAnalytics };
|
|
21
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","names":[],"sources":["../../src/components/analytics/provider.tsx"],"sourcesContent":[],"mappings":";;;;;iBAgCgB,iBAAA;;UAEN;AAFV;YAIY,KAAA,CAAM;WACP;AALX,CAAA,CAAA,EAMC,mBAAA,CAAA,GAAA,CAAA,OANgC;AAC/B,iBA2Dc,YAAA,CAAA,CA3Dd,EAAA;EACQ,OAAA,EAAA,OAAA;EAEE,aAAM,EAAA,oBAAA;EACP,UAAA,EAAA,iBAAA;EACV,eAAA,EAAA,sBAAA;CAAA"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import { initializeAnalytics, trackConversion, trackEvent, trackPageView } from "./core.js";
|
|
5
|
+
import { bindAnalyticsClickTracking } from "./delegated-clicks.js";
|
|
6
|
+
import { createContext, useContext, useEffect, useMemo, useRef } from "react";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
import { usePathname, useSearchParams } from "next/navigation";
|
|
9
|
+
|
|
10
|
+
//#region src/components/analytics/provider.tsx
|
|
11
|
+
function getEnvConfig() {
|
|
12
|
+
const siteKey = process.env.NEXT_PUBLIC_ANALYTICS_SITE_KEY;
|
|
13
|
+
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;
|
|
14
|
+
return {
|
|
15
|
+
enabled: Boolean(siteKey),
|
|
16
|
+
endpoint: baseUrl ? `${baseUrl}/public/analytics/collect/` : void 0,
|
|
17
|
+
siteKey: siteKey || void 0
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const AnalyticsContext = createContext({
|
|
21
|
+
enabled: false,
|
|
22
|
+
trackPageView,
|
|
23
|
+
trackEvent,
|
|
24
|
+
trackConversion
|
|
25
|
+
});
|
|
26
|
+
function AnalyticsProvider({ children, config: configOverride }) {
|
|
27
|
+
const config = useMemo(() => ({
|
|
28
|
+
...getEnvConfig(),
|
|
29
|
+
...configOverride
|
|
30
|
+
}), [configOverride]);
|
|
31
|
+
const pathname = usePathname();
|
|
32
|
+
const searchParams = useSearchParams();
|
|
33
|
+
const routeKey = `${pathname}${searchParams.toString() ? `?${searchParams.toString()}` : ""}`;
|
|
34
|
+
const lastRouteRef = useRef("");
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
initializeAnalytics(config);
|
|
37
|
+
}, [config]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (config.delegatedClickTracking === false) return;
|
|
40
|
+
return bindAnalyticsClickTracking({ inferClickEvents: config.inferClickEvents });
|
|
41
|
+
}, [config.delegatedClickTracking, config.inferClickEvents]);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (!config.enabled || !config.endpoint || !config.siteKey) return;
|
|
44
|
+
if (lastRouteRef.current === routeKey) return;
|
|
45
|
+
lastRouteRef.current = routeKey;
|
|
46
|
+
trackPageView();
|
|
47
|
+
}, [
|
|
48
|
+
config.enabled,
|
|
49
|
+
config.endpoint,
|
|
50
|
+
config.siteKey,
|
|
51
|
+
routeKey
|
|
52
|
+
]);
|
|
53
|
+
const value = useMemo(() => ({
|
|
54
|
+
enabled: Boolean(config.enabled && config.endpoint && config.siteKey),
|
|
55
|
+
trackPageView,
|
|
56
|
+
trackEvent,
|
|
57
|
+
trackConversion
|
|
58
|
+
}), [
|
|
59
|
+
config.enabled,
|
|
60
|
+
config.endpoint,
|
|
61
|
+
config.siteKey
|
|
62
|
+
]);
|
|
63
|
+
return /* @__PURE__ */ jsx(AnalyticsContext.Provider, {
|
|
64
|
+
value,
|
|
65
|
+
children
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function useAnalytics() {
|
|
69
|
+
return useContext(AnalyticsContext);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
export { AnalyticsProvider, useAnalytics };
|
|
74
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","names":["trackPageViewCore","trackEventCore","trackConversionCore"],"sources":["../../src/components/analytics/provider.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, useEffect, useMemo, useRef } from 'react';\nimport { usePathname, useSearchParams } from 'next/navigation';\n\nimport {\n initializeAnalytics,\n trackConversion as trackConversionCore,\n trackEvent as trackEventCore,\n trackPageView as trackPageViewCore,\n} from './core';\nimport { bindAnalyticsClickTracking } from './delegated-clicks';\nimport type { AnalyticsConfig, TrackEventOptions } from './types';\n\nfunction getEnvConfig(): AnalyticsConfig {\n const siteKey = process.env.NEXT_PUBLIC_ANALYTICS_SITE_KEY;\n const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;\n\n return {\n enabled: Boolean(siteKey),\n endpoint: baseUrl ? `${baseUrl}/public/analytics/collect/` : undefined,\n siteKey: siteKey || undefined,\n };\n}\n\nconst AnalyticsContext = createContext({\n enabled: false,\n trackPageView: trackPageViewCore,\n trackEvent: trackEventCore,\n trackConversion: trackConversionCore,\n});\n\nexport function AnalyticsProvider({\n children,\n config: configOverride,\n}: {\n children: React.ReactNode;\n config?: AnalyticsConfig;\n}) {\n const config = useMemo(\n () => ({ ...getEnvConfig(), ...configOverride }),\n [configOverride]\n );\n const pathname = usePathname();\n const searchParams = useSearchParams();\n const routeKey = `${pathname}${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;\n const lastRouteRef = useRef('');\n\n useEffect(() => {\n initializeAnalytics(config);\n }, [config]);\n\n useEffect(() => {\n if (config.delegatedClickTracking === false) {\n return;\n }\n\n return bindAnalyticsClickTracking({\n inferClickEvents: config.inferClickEvents,\n });\n }, [config.delegatedClickTracking, config.inferClickEvents]);\n\n useEffect(() => {\n if (!config.enabled || !config.endpoint || !config.siteKey) {\n return;\n }\n\n if (lastRouteRef.current === routeKey) {\n return;\n }\n\n lastRouteRef.current = routeKey;\n trackPageViewCore();\n }, [config.enabled, config.endpoint, config.siteKey, routeKey]);\n\n const value = useMemo(\n () => ({\n enabled: Boolean(config.enabled && config.endpoint && config.siteKey),\n trackPageView: trackPageViewCore,\n trackEvent: trackEventCore,\n trackConversion: trackConversionCore,\n }),\n [config.enabled, config.endpoint, config.siteKey]\n );\n\n return (\n <AnalyticsContext.Provider value={value}>\n {children}\n </AnalyticsContext.Provider>\n );\n}\n\nexport function useAnalytics() {\n return useContext(AnalyticsContext);\n}\n\nexport type AnalyticsHook = {\n enabled: boolean;\n trackPageView: (page?: { path?: string; title?: string }) => void;\n trackEvent: (\n eventName: string,\n properties?: Record<string, unknown>,\n options?: TrackEventOptions\n ) => void;\n trackConversion: (\n conversionName: string,\n properties?: Record<string, unknown>,\n conversionValue?: number | string | null\n ) => void;\n};\n"],"mappings":";;;;;;;;;;AAcA,SAAS,eAAgC;CACvC,MAAM,UAAU,QAAQ,IAAI;CAC5B,MAAM,UAAU,QAAQ,IAAI;AAE5B,QAAO;EACL,SAAS,QAAQ,QAAQ;EACzB,UAAU,UAAU,GAAG,QAAQ,8BAA8B;EAC7D,SAAS,WAAW;EACrB;;AAGH,MAAM,mBAAmB,cAAc;CACrC,SAAS;CACMA;CACHC;CACKC;CAClB,CAAC;AAEF,SAAgB,kBAAkB,EAChC,UACA,QAAQ,kBAIP;CACD,MAAM,SAAS,eACN;EAAE,GAAG,cAAc;EAAE,GAAG;EAAgB,GAC/C,CAAC,eAAe,CACjB;CACD,MAAM,WAAW,aAAa;CAC9B,MAAM,eAAe,iBAAiB;CACtC,MAAM,WAAW,GAAG,WAAW,aAAa,UAAU,GAAG,IAAI,aAAa,UAAU,KAAK;CACzF,MAAM,eAAe,OAAO,GAAG;AAE/B,iBAAgB;AACd,sBAAoB,OAAO;IAC1B,CAAC,OAAO,CAAC;AAEZ,iBAAgB;AACd,MAAI,OAAO,2BAA2B,MACpC;AAGF,SAAO,2BAA2B,EAChC,kBAAkB,OAAO,kBAC1B,CAAC;IACD,CAAC,OAAO,wBAAwB,OAAO,iBAAiB,CAAC;AAE5D,iBAAgB;AACd,MAAI,CAAC,OAAO,WAAW,CAAC,OAAO,YAAY,CAAC,OAAO,QACjD;AAGF,MAAI,aAAa,YAAY,SAC3B;AAGF,eAAa,UAAU;AACvB,iBAAmB;IAClB;EAAC,OAAO;EAAS,OAAO;EAAU,OAAO;EAAS;EAAS,CAAC;CAE/D,MAAM,QAAQ,eACL;EACL,SAAS,QAAQ,OAAO,WAAW,OAAO,YAAY,OAAO,QAAQ;EACtDF;EACHC;EACKC;EAClB,GACD;EAAC,OAAO;EAAS,OAAO;EAAU,OAAO;EAAQ,CAClD;AAED,QACE,oBAAC,iBAAiB;EAAgB;EAC/B;GACyB;;AAIhC,SAAgB,eAAe;AAC7B,QAAO,WAAW,iBAAiB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//#region src/components/analytics/types.d.ts
|
|
2
|
+
type AnalyticsEventType = 'page_view' | 'cta_click' | 'custom' | 'conversion';
|
|
3
|
+
type AnalyticsDeviceInfo = {
|
|
4
|
+
type?: string;
|
|
5
|
+
browser?: string;
|
|
6
|
+
os?: string;
|
|
7
|
+
};
|
|
8
|
+
type AnalyticsUtmInfo = {
|
|
9
|
+
source?: string;
|
|
10
|
+
medium?: string;
|
|
11
|
+
campaign?: string;
|
|
12
|
+
term?: string;
|
|
13
|
+
content?: string;
|
|
14
|
+
};
|
|
15
|
+
type AnalyticsPageInfo = {
|
|
16
|
+
path?: string;
|
|
17
|
+
title?: string;
|
|
18
|
+
};
|
|
19
|
+
type AnalyticsConversionPayload = {
|
|
20
|
+
name: string;
|
|
21
|
+
value?: number | string | null;
|
|
22
|
+
};
|
|
23
|
+
type AnalyticsEventPayload = {
|
|
24
|
+
visitorId: string;
|
|
25
|
+
sessionId: string;
|
|
26
|
+
eventType: AnalyticsEventType;
|
|
27
|
+
eventName: string;
|
|
28
|
+
occurredAt: string;
|
|
29
|
+
page: AnalyticsPageInfo;
|
|
30
|
+
referrer?: string;
|
|
31
|
+
utm?: AnalyticsUtmInfo;
|
|
32
|
+
device?: AnalyticsDeviceInfo;
|
|
33
|
+
properties?: Record<string, unknown>;
|
|
34
|
+
conversion?: AnalyticsConversionPayload;
|
|
35
|
+
};
|
|
36
|
+
type AnalyticsConfig = {
|
|
37
|
+
endpoint?: string;
|
|
38
|
+
siteKey?: string;
|
|
39
|
+
enabled?: boolean;
|
|
40
|
+
sessionTimeoutMs?: number;
|
|
41
|
+
storageKeyPrefix?: string;
|
|
42
|
+
delegatedClickTracking?: boolean;
|
|
43
|
+
inferClickEvents?: boolean;
|
|
44
|
+
};
|
|
45
|
+
type TrackEventOptions = {
|
|
46
|
+
eventType?: Exclude<AnalyticsEventType, 'conversion'>;
|
|
47
|
+
page?: AnalyticsPageInfo;
|
|
48
|
+
properties?: Record<string, unknown>;
|
|
49
|
+
};
|
|
50
|
+
type AnalyticsAttributesInput = {
|
|
51
|
+
event?: string;
|
|
52
|
+
eventType?: Exclude<AnalyticsEventType, 'conversion' | 'page_view'>;
|
|
53
|
+
properties?: Record<string, unknown>;
|
|
54
|
+
conversion?: AnalyticsConversionPayload | string;
|
|
55
|
+
conversionValue?: number | string | null;
|
|
56
|
+
};
|
|
57
|
+
//#endregion
|
|
58
|
+
export { AnalyticsAttributesInput, AnalyticsConfig, AnalyticsConversionPayload, AnalyticsDeviceInfo, AnalyticsEventPayload, AnalyticsPageInfo, AnalyticsUtmInfo, TrackEventOptions };
|
|
59
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/components/analytics/types.ts"],"sourcesContent":[],"mappings":";KAAY,kBAAA;AAAA,KAMA,mBAAA,GANkB;EAMlB,IAAA,CAAA,EAAA,MAAA;EAMA,OAAA,CAAA,EAAA,MAAA;EAQA,EAAA,CAAA,EAAA,MAAA;AAKZ,CAAA;AAKY,KAlBA,gBAAA,GAkBqB;EAGpB,MAAA,CAAA,EAAA,MAAA;EAGL,MAAA,CAAA,EAAA,MAAA;EAEA,QAAA,CAAA,EAAA,MAAA;EACG,IAAA,CAAA,EAAA,MAAA;EACI,OAAA,CAAA,EAAA,MAAA;CACA;AAA0B,KArB7B,iBAAA,GAqB6B;EAG7B,IAAA,CAAA,EAAA,MAAA;EAUA,KAAA,CAAA,EAAA,MAAA;CACU;AAAR,KA9BF,0BAAA,GA8BE;EACL,IAAA,EAAA,MAAA;EACM,KAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,IAAA;CAAM;AAGT,KA9BA,qBAAA,GA8BwB;EAEd,SAAA,EAAA,MAAA;EAAR,SAAA,EAAA,MAAA;EACC,SAAA,EA9BF,kBA8BE;EACA,SAAA,EAAA,MAAA;EAA0B,UAAA,EAAA,MAAA;QA5BjC;;QAEA;WACG;eACI;eACA;;KAGH,eAAA;;;;;;;;;KAUA,iBAAA;cACE,QAAQ;SACb;eACM;;KAGH,wBAAA;;cAEE,QAAQ;eACP;eACA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { AnalyticsAttributesInput, AnalyticsConfig, AnalyticsConversionPayload, AnalyticsEventPayload, TrackEventOptions } from "./analytics/types.js";
|
|
2
|
+
import { createAnalyticsId, detectDevice, getAnalyticsClient, getCurrentPageSnapshot, initializeAnalytics, parseUtmParamsFromUrl, shouldRotateSession, trackConversion, trackEvent, trackPageView } from "./analytics/core.js";
|
|
3
|
+
import { analyticsAttributes, bindAnalyticsClickTracking } from "./analytics/delegated-clicks.js";
|
|
4
|
+
import { AnalyticsProvider, useAnalytics } from "./analytics/provider.js";
|
|
5
|
+
export { type AnalyticsAttributesInput, type AnalyticsConfig, type AnalyticsConversionPayload, type AnalyticsEventPayload, AnalyticsProvider, type TrackEventOptions, analyticsAttributes, bindAnalyticsClickTracking, createAnalyticsId, detectDevice, getAnalyticsClient, getCurrentPageSnapshot, initializeAnalytics, parseUtmParamsFromUrl, shouldRotateSession, trackConversion, trackEvent, trackPageView, useAnalytics };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import { createAnalyticsId, detectDevice, getAnalyticsClient, getCurrentPageSnapshot, initializeAnalytics, parseUtmParamsFromUrl, shouldRotateSession, trackConversion, trackEvent, trackPageView } from "./analytics/core.js";
|
|
5
|
+
import { analyticsAttributes, bindAnalyticsClickTracking } from "./analytics/delegated-clicks.js";
|
|
6
|
+
import { AnalyticsProvider, useAnalytics } from "./analytics/provider.js";
|
|
7
|
+
|
|
8
|
+
export { AnalyticsProvider, analyticsAttributes, bindAnalyticsClickTracking, createAnalyticsId, detectDevice, getAnalyticsClient, getCurrentPageSnapshot, initializeAnalytics, parseUtmParamsFromUrl, shouldRotateSession, trackConversion, trackEvent, trackPageView, useAnalytics };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentProps, ElementType } from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/container-animation/container-animation.d.ts
|
|
5
5
|
type ContainerAnimationProps<T extends ElementType = 'div'> = ComponentProps<'div'> & ComponentProps<T> & {
|
|
@@ -23,7 +23,7 @@ declare const ContainerAnimation: <T extends ElementType = "div">({
|
|
|
23
23
|
distance,
|
|
24
24
|
hideNotInView,
|
|
25
25
|
...props
|
|
26
|
-
}: ContainerAnimationProps<T>) =>
|
|
26
|
+
}: ContainerAnimationProps<T>) => react_jsx_runtime0.JSX.Element;
|
|
27
27
|
//#endregion
|
|
28
28
|
export { ContainerAnimation, ContainerAnimationProps };
|
|
29
29
|
//# sourceMappingURL=container-animation.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FieldPath, FieldValues, UseControllerProps } from "react-hook-form";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime5 from "react/jsx-runtime";
|
|
3
3
|
import { Matcher } from "react-day-picker";
|
|
4
4
|
|
|
5
5
|
//#region src/components/date-field/DateField.d.ts
|
|
@@ -29,7 +29,7 @@ declare function DateField<TFieldValues extends FieldValues = FieldValues, TFiel
|
|
|
29
29
|
required,
|
|
30
30
|
help,
|
|
31
31
|
dateOnly
|
|
32
|
-
}: DateFieldProps<TFieldValues, TFieldName>):
|
|
32
|
+
}: DateFieldProps<TFieldValues, TFieldName>): react_jsx_runtime5.JSX.Element;
|
|
33
33
|
//#endregion
|
|
34
34
|
export { DateField, DateFieldProps };
|
|
35
35
|
//# sourceMappingURL=DateField.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FieldPath, FieldValues, UseControllerProps } from "react-hook-form";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime14 from "react/jsx-runtime";
|
|
3
3
|
import { Matcher } from "react-day-picker";
|
|
4
4
|
|
|
5
5
|
//#region src/components/date-hour-field/DateHourField.d.ts
|
|
@@ -29,7 +29,7 @@ declare function DateHourField<TFieldValues extends FieldValues = FieldValues, T
|
|
|
29
29
|
help,
|
|
30
30
|
hourPlaceholder,
|
|
31
31
|
valueType
|
|
32
|
-
}: DateHourFieldProps<TFieldValues, TFieldName>):
|
|
32
|
+
}: DateHourFieldProps<TFieldValues, TFieldName>): react_jsx_runtime14.JSX.Element;
|
|
33
33
|
//#endregion
|
|
34
34
|
export { DateHourField, DateHourFieldProps };
|
|
35
35
|
//# sourceMappingURL=DateHourField.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateHourField.d.ts","names":[],"sources":["../../src/components/date-hour-field/DateHourField.tsx"],"sourcesContent":[],"mappings":";;;;;UA4CiB,wCACM,cAAc,gCAChB,UAAU,gBAAgB,UAAU,uBAC/C,KAAK,mBAAmB,cAAc;;;EAH/B,SAAA,CAAA,EAAA,MAAA;EACM,QAAA,CAAA,EAMV,OANU,GAMA,OANA,EAAA,GAAA,SAAA;EAAc,aAAA,CAAA,EAAA,OAAA;EACN,YAAA,CAAA,EAOd,IAPc;EAAV,QAAA,CAAA,EAQR,IARQ;EAAoC,QAAA,CAAA,EAAA,OAAA;EAAV,IAAA,CAAA,EAAA,MAAA;EACb,eAAA,CAAA,EAAA,MAAA;EAAc,SAAA,CAAA,EAAA,MAAA,GAAA,cAAA;;iBAcvC,aAVI,CAAA,qBAWU,WAXV,GAWwB,WAXxB,EAAA,mBAYQ,SAZR,CAYkB,YAZlB,CAAA,GAYkC,SAZlC,CAY4C,YAZ5C,CAAA,CAAA,CAAA;EAAA,IAAA;EAAA,KAAA;EAAA,WAAA;EAAA,aAAA;EAAA,QAAA;EAAA,SAAA;EAAA,QAAA;EAAA,YAAA;EAAA,QAAA;EAAA,IAAA;EAAA,eAAA;EAAA;AAAA,CAAA,EA0BV,kBA1BU,CA0BS,YA1BT,EA0BuB,UA1BvB,CAAA,CAAA,EA0BkC,
|
|
1
|
+
{"version":3,"file":"DateHourField.d.ts","names":[],"sources":["../../src/components/date-hour-field/DateHourField.tsx"],"sourcesContent":[],"mappings":";;;;;UA4CiB,wCACM,cAAc,gCAChB,UAAU,gBAAgB,UAAU,uBAC/C,KAAK,mBAAmB,cAAc;;;EAH/B,SAAA,CAAA,EAAA,MAAA;EACM,QAAA,CAAA,EAMV,OANU,GAMA,OANA,EAAA,GAAA,SAAA;EAAc,aAAA,CAAA,EAAA,OAAA;EACN,YAAA,CAAA,EAOd,IAPc;EAAV,QAAA,CAAA,EAQR,IARQ;EAAoC,QAAA,CAAA,EAAA,OAAA;EAAV,IAAA,CAAA,EAAA,MAAA;EACb,eAAA,CAAA,EAAA,MAAA;EAAc,SAAA,CAAA,EAAA,MAAA,GAAA,cAAA;;iBAcvC,aAVI,CAAA,qBAWU,WAXV,GAWwB,WAXxB,EAAA,mBAYQ,SAZR,CAYkB,YAZlB,CAAA,GAYkC,SAZlC,CAY4C,YAZ5C,CAAA,CAAA,CAAA;EAAA,IAAA;EAAA,KAAA;EAAA,WAAA;EAAA,aAAA;EAAA,QAAA;EAAA,SAAA;EAAA,QAAA;EAAA,YAAA;EAAA,QAAA;EAAA,IAAA;EAAA,eAAA;EAAA;AAAA,CAAA,EA0BV,kBA1BU,CA0BS,YA1BT,EA0BuB,UA1BvB,CAAA,CAAA,EA0BkC,mBAAA,CAAA,GAAA,CAAA,OA1BlC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Mask, Options } from "../src/hooks/with-mask.js";
|
|
2
2
|
import { FieldPath, FieldValues, UseControllerProps } from "react-hook-form";
|
|
3
3
|
import { Dispatch, SetStateAction } from "react";
|
|
4
|
-
import * as
|
|
4
|
+
import * as react_jsx_runtime6 from "react/jsx-runtime";
|
|
5
5
|
import { PopoverProps } from "@radix-ui/react-popover";
|
|
6
6
|
|
|
7
7
|
//#region src/components/input-suggest/input-suggest.d.ts
|
|
@@ -71,7 +71,7 @@ declare function InputSuggest<TFieldValues extends FieldValues = FieldValues, TF
|
|
|
71
71
|
debounceTime,
|
|
72
72
|
maxWait,
|
|
73
73
|
...props
|
|
74
|
-
}: InputSuggestProps<TFieldValues, TFieldName> & PopoverProps):
|
|
74
|
+
}: InputSuggestProps<TFieldValues, TFieldName> & PopoverProps): react_jsx_runtime6.JSX.Element;
|
|
75
75
|
//#endregion
|
|
76
76
|
export { InputSuggest, InputSuggestProps };
|
|
77
77
|
//# sourceMappingURL=input-suggest.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { KanbanCardItemProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime17 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/kanban-dnd/kanban-card-item.d.ts
|
|
5
5
|
declare function KanbanCardItem({
|
|
@@ -8,7 +8,7 @@ declare function KanbanCardItem({
|
|
|
8
8
|
className,
|
|
9
9
|
getSelectedCardIds,
|
|
10
10
|
getSelectableItems
|
|
11
|
-
}: KanbanCardItemProps):
|
|
11
|
+
}: KanbanCardItemProps): react_jsx_runtime17.JSX.Element;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { KanbanCardItem };
|
|
14
14
|
//# sourceMappingURL=kanban-card-item.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { KanbanDndMonitorProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime18 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/kanban-dnd/kanban-dnd-monitor.d.ts
|
|
5
5
|
declare function KanbanDndMonitor<TColumn>({
|
|
@@ -23,7 +23,7 @@ declare function KanbanDndMonitor<TColumn>({
|
|
|
23
23
|
isAutoScrollEnabled,
|
|
24
24
|
renderIdleLayer,
|
|
25
25
|
className
|
|
26
|
-
}: KanbanDndMonitorProps<TColumn>):
|
|
26
|
+
}: KanbanDndMonitorProps<TColumn>): react_jsx_runtime18.JSX.Element;
|
|
27
27
|
//#endregion
|
|
28
28
|
export { KanbanDndMonitor };
|
|
29
29
|
//# sourceMappingURL=kanban-dnd-monitor.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { KanbanDropZoneProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime19 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/kanban-dnd/kanban-dropzone.d.ts
|
|
5
5
|
declare function KanbanDropZone({
|
|
@@ -7,7 +7,7 @@ declare function KanbanDropZone({
|
|
|
7
7
|
id,
|
|
8
8
|
className,
|
|
9
9
|
isOverClassName
|
|
10
|
-
}: KanbanDropZoneProps):
|
|
10
|
+
}: KanbanDropZoneProps): react_jsx_runtime19.JSX.Element;
|
|
11
11
|
//#endregion
|
|
12
12
|
export { KanbanDropZone };
|
|
13
13
|
//# sourceMappingURL=kanban-dropzone.d.ts.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { KanbanSelectorProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime20 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/kanban-dnd/kanban-selector.d.ts
|
|
5
5
|
declare function KanbanSelector({
|
|
6
6
|
dragAreaId,
|
|
7
7
|
autoScrollMargin,
|
|
8
8
|
ignoredSlots
|
|
9
|
-
}: KanbanSelectorProps):
|
|
9
|
+
}: KanbanSelectorProps): react_jsx_runtime20.JSX.Element | null;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { KanbanSelector };
|
|
12
12
|
//# sourceMappingURL=kanban-selector.d.ts.map
|
|
@@ -147,7 +147,7 @@ function ClientLandingText({ item, editable = false, children }) {
|
|
|
147
147
|
variant: "outline",
|
|
148
148
|
children: /* @__PURE__ */ jsx(X, {})
|
|
149
149
|
}), /* @__PURE__ */ jsx(Button, {
|
|
150
|
-
className: "size-6 rounded-none p-0 border border-
|
|
150
|
+
className: "size-6 rounded-none p-0 border dark:border-input",
|
|
151
151
|
disabled: isSaving,
|
|
152
152
|
onClick: handleSave,
|
|
153
153
|
size: "icon",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-landing-text.js","names":[],"sources":["../../src/components/landing-text/client-landing-text.tsx"],"sourcesContent":["'use client';\n\nimport { useRef, useState } from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { Button } from '../ui/button';\n\nimport { Check, Loader2, X } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { flushSync } from 'react-dom';\nimport { refreshTag } from '../actions';\nimport type { LandingTextItem } from './types';\n\ninterface ClientLandingTextProps {\n item: LandingTextItem;\n editable?: boolean;\n children: React.ReactNode;\n}\n\nfunction labelFromKey(value: string) {\n if (!value) {\n return '';\n }\n\n return value\n .split(/[-_\\.]/g)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n}\n\nfunction parseCookies(cookieHeader: string): Record<string, string> {\n return cookieHeader\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .reduce<Record<string, string>>((acc, part) => {\n const separatorIndex = part.indexOf('=');\n if (separatorIndex < 0) {\n return acc;\n }\n\n const name = decodeURIComponent(part.slice(0, separatorIndex));\n const value = decodeURIComponent(part.slice(separatorIndex + 1));\n acc[name] = value;\n return acc;\n }, {});\n}\n\nfunction getTokenCookieValue(): string | undefined {\n if (typeof document === 'undefined' || !document.cookie) {\n return undefined;\n }\n\n const rawToken = parseCookies(document.cookie).token;\n if (!rawToken) {\n return undefined;\n }\n\n const withoutQuotes = rawToken.trim().replace(/^\"|\"$/g, '');\n return withoutQuotes.replace(/^Token\\s+/i, '');\n}\n\nasync function persistLandingContent(item: LandingTextItem, value: string) {\n const baseUrl = String(process.env.NEXT_PUBLIC_BASE_URL || '');\n const organization = String(\n process.env.NEXT_PUBLIC_ORGANIZATION_ID || ''\n ).trim();\n\n if (!baseUrl) {\n return;\n }\n\n const token = getTokenCookieValue();\n\n if (!token || !organization) {\n throw new Error(\n 'Credenciais de edição indisponíveis para salvar conteúdo.'\n );\n }\n\n const endpoint = '/landing-page-contents/upsert/';\n const response = await fetch(`${normalizeBaseUrl(baseUrl)}${endpoint}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Token ${token}`,\n 'X-Organization': organization,\n },\n body: JSON.stringify({\n page_key: item.pageKey,\n page_title: labelFromKey(item.pageKey),\n section_key: item.sectionKey,\n section_title: labelFromKey(item.sectionKey),\n content_key: item.contentKey,\n content_title: labelFromKey(item.contentKey),\n value,\n default_value: item.defaultValue,\n metadata: item.metadata,\n }),\n credentials: 'include',\n });\n\n if (!response.ok) {\n throw new Error('Nao foi possivel salvar o conteudo.');\n }\n\n await refreshTag(`landing-page-content-${item.pageKey}`);\n}\n\nfunction normalizeEditableText(value: string): string {\n return value\n .replace(/\\u00a0/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction suppressNextDocumentClick() {\n if (typeof document === 'undefined') {\n return;\n }\n\n document.addEventListener(\n 'click',\n (event) => {\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n },\n { capture: true, once: true }\n );\n}\n\nfunction ClientLandingText({\n item,\n editable = false,\n children,\n}: ClientLandingTextProps) {\n const [isEditing, setIsEditing] = useState(false);\n const [isSaving, setIsSaving] = useState(false);\n const [currentValue, setCurrentValue] = useState(item.value);\n const [draftValue, setDraftValue] = useState(item.value);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const ref = useRef<HTMLElement | null>(null);\n\n const closeEditing = (value: string) => {\n if (ref.current) {\n ref.current.innerText = value;\n }\n setDraftValue(value);\n setIsEditing(false);\n };\n\n const handleEdit = (event: React.PointerEvent<HTMLElement>) => {\n event.stopPropagation();\n suppressNextDocumentClick();\n if (!editable || isSaving || isEditing) {\n return;\n }\n\n const element = event.currentTarget;\n ref.current = element;\n\n const nextDraft = element.innerText || currentValue;\n flushSync(() => {\n setDraftValue(nextDraft);\n setIsEditing(true);\n });\n };\n\n const handleCancel = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n closeEditing(currentValue);\n };\n\n const handleSave = async (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n try {\n setIsSaving(true);\n await persistLandingContent(item, draftValue);\n setCurrentValue(draftValue);\n closeEditing(draftValue);\n } finally {\n setIsSaving(false);\n }\n };\n\n const handleInput = (event: React.FormEvent<HTMLElement>) => {\n if (!isEditing) {\n return;\n }\n ref.current = event.currentTarget;\n setDraftValue(event.currentTarget.innerText);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLElement>) => {\n if (!isEditing || isSaving) {\n return;\n }\n\n const container = containerRef.current;\n const nextFocused = event.relatedTarget;\n\n if (\n container &&\n nextFocused instanceof Node &&\n container.contains(nextFocused)\n ) {\n return;\n }\n\n const liveValue = event.currentTarget.innerText;\n if (\n normalizeEditableText(liveValue) !== normalizeEditableText(currentValue)\n ) {\n if (liveValue !== draftValue) {\n setDraftValue(liveValue);\n }\n return;\n }\n\n closeEditing(currentValue);\n };\n\n return (\n <div className=\"relative\" ref={containerRef}>\n {editable && isEditing && (\n <div className=\"absolute right-0 z-10 h-fit -top-7 flex\">\n <Button\n className=\"size-6 rounded-none p-0 text-foreground!\"\n disabled={isSaving}\n onClick={handleCancel}\n size=\"icon\"\n type=\"button\"\n variant=\"outline\"\n >\n <X />\n </Button>\n <Button\n className=\"size-6 rounded-none p-0 border border-primary-foreground\"\n disabled={isSaving}\n onClick={handleSave}\n size=\"icon\"\n type=\"button\"\n >\n {isSaving ? <Loader2 className=\"animate-spin size-3\" /> : <Check />}\n </Button>\n </div>\n )}\n\n <Slot\n className={cn(\n 'relative',\n 'after:pointer-events-none after:z-10 after:w-full after:h-full after:absolute after:left-1/2 after:-translate-x-1/2 after:top-1/2 after:-translate-y-1/2 after:box-content after:p-1',\n editable && 'hover:after:border hover:after:border-input',\n isEditing && 'after:border after:border-input',\n isEditing && 'outline-none cursor-text before:bg-red-500',\n !editable && 'after:hidden'\n )}\n contentEditable={editable && isEditing}\n onBlur={handleBlur}\n onInput={handleInput}\n onPointerDownCapture={handleEdit}\n ref={ref}\n suppressContentEditableWarning\n >\n {children}\n </Slot>\n </div>\n );\n}\n\nexport { ClientLandingText };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client-landing-text.js","names":[],"sources":["../../src/components/landing-text/client-landing-text.tsx"],"sourcesContent":["'use client';\n\nimport { useRef, useState } from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { Button } from '../ui/button';\n\nimport { Check, Loader2, X } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { flushSync } from 'react-dom';\nimport { refreshTag } from '../actions';\nimport type { LandingTextItem } from './types';\n\ninterface ClientLandingTextProps {\n item: LandingTextItem;\n editable?: boolean;\n children: React.ReactNode;\n}\n\nfunction labelFromKey(value: string) {\n if (!value) {\n return '';\n }\n\n return value\n .split(/[-_\\.]/g)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n}\n\nfunction parseCookies(cookieHeader: string): Record<string, string> {\n return cookieHeader\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .reduce<Record<string, string>>((acc, part) => {\n const separatorIndex = part.indexOf('=');\n if (separatorIndex < 0) {\n return acc;\n }\n\n const name = decodeURIComponent(part.slice(0, separatorIndex));\n const value = decodeURIComponent(part.slice(separatorIndex + 1));\n acc[name] = value;\n return acc;\n }, {});\n}\n\nfunction getTokenCookieValue(): string | undefined {\n if (typeof document === 'undefined' || !document.cookie) {\n return undefined;\n }\n\n const rawToken = parseCookies(document.cookie).token;\n if (!rawToken) {\n return undefined;\n }\n\n const withoutQuotes = rawToken.trim().replace(/^\"|\"$/g, '');\n return withoutQuotes.replace(/^Token\\s+/i, '');\n}\n\nasync function persistLandingContent(item: LandingTextItem, value: string) {\n const baseUrl = String(process.env.NEXT_PUBLIC_BASE_URL || '');\n const organization = String(\n process.env.NEXT_PUBLIC_ORGANIZATION_ID || ''\n ).trim();\n\n if (!baseUrl) {\n return;\n }\n\n const token = getTokenCookieValue();\n\n if (!token || !organization) {\n throw new Error(\n 'Credenciais de edição indisponíveis para salvar conteúdo.'\n );\n }\n\n const endpoint = '/landing-page-contents/upsert/';\n const response = await fetch(`${normalizeBaseUrl(baseUrl)}${endpoint}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Token ${token}`,\n 'X-Organization': organization,\n },\n body: JSON.stringify({\n page_key: item.pageKey,\n page_title: labelFromKey(item.pageKey),\n section_key: item.sectionKey,\n section_title: labelFromKey(item.sectionKey),\n content_key: item.contentKey,\n content_title: labelFromKey(item.contentKey),\n value,\n default_value: item.defaultValue,\n metadata: item.metadata,\n }),\n credentials: 'include',\n });\n\n if (!response.ok) {\n throw new Error('Nao foi possivel salvar o conteudo.');\n }\n\n await refreshTag(`landing-page-content-${item.pageKey}`);\n}\n\nfunction normalizeEditableText(value: string): string {\n return value\n .replace(/\\u00a0/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction suppressNextDocumentClick() {\n if (typeof document === 'undefined') {\n return;\n }\n\n document.addEventListener(\n 'click',\n (event) => {\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n },\n { capture: true, once: true }\n );\n}\n\nfunction ClientLandingText({\n item,\n editable = false,\n children,\n}: ClientLandingTextProps) {\n const [isEditing, setIsEditing] = useState(false);\n const [isSaving, setIsSaving] = useState(false);\n const [currentValue, setCurrentValue] = useState(item.value);\n const [draftValue, setDraftValue] = useState(item.value);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const ref = useRef<HTMLElement | null>(null);\n\n const closeEditing = (value: string) => {\n if (ref.current) {\n ref.current.innerText = value;\n }\n setDraftValue(value);\n setIsEditing(false);\n };\n\n const handleEdit = (event: React.PointerEvent<HTMLElement>) => {\n event.stopPropagation();\n suppressNextDocumentClick();\n if (!editable || isSaving || isEditing) {\n return;\n }\n\n const element = event.currentTarget;\n ref.current = element;\n\n const nextDraft = element.innerText || currentValue;\n flushSync(() => {\n setDraftValue(nextDraft);\n setIsEditing(true);\n });\n };\n\n const handleCancel = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n closeEditing(currentValue);\n };\n\n const handleSave = async (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n try {\n setIsSaving(true);\n await persistLandingContent(item, draftValue);\n setCurrentValue(draftValue);\n closeEditing(draftValue);\n } finally {\n setIsSaving(false);\n }\n };\n\n const handleInput = (event: React.FormEvent<HTMLElement>) => {\n if (!isEditing) {\n return;\n }\n ref.current = event.currentTarget;\n setDraftValue(event.currentTarget.innerText);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLElement>) => {\n if (!isEditing || isSaving) {\n return;\n }\n\n const container = containerRef.current;\n const nextFocused = event.relatedTarget;\n\n if (\n container &&\n nextFocused instanceof Node &&\n container.contains(nextFocused)\n ) {\n return;\n }\n\n const liveValue = event.currentTarget.innerText;\n if (\n normalizeEditableText(liveValue) !== normalizeEditableText(currentValue)\n ) {\n if (liveValue !== draftValue) {\n setDraftValue(liveValue);\n }\n return;\n }\n\n closeEditing(currentValue);\n };\n\n return (\n <div className=\"relative\" ref={containerRef}>\n {editable && isEditing && (\n <div className=\"absolute right-0 z-10 h-fit -top-7 flex\">\n <Button\n className=\"size-6 rounded-none p-0 text-foreground!\"\n disabled={isSaving}\n onClick={handleCancel}\n size=\"icon\"\n type=\"button\"\n variant=\"outline\"\n >\n <X />\n </Button>\n <Button\n className=\"size-6 rounded-none p-0 border dark:border-input\"\n disabled={isSaving}\n onClick={handleSave}\n size=\"icon\"\n type=\"button\"\n >\n {isSaving ? <Loader2 className=\"animate-spin size-3\" /> : <Check />}\n </Button>\n </div>\n )}\n\n <Slot\n className={cn(\n 'relative',\n 'after:pointer-events-none after:z-10 after:w-full after:h-full after:absolute after:left-1/2 after:-translate-x-1/2 after:top-1/2 after:-translate-y-1/2 after:box-content after:p-1',\n editable && 'hover:after:border hover:after:border-input',\n isEditing && 'after:border after:border-input',\n isEditing && 'outline-none cursor-text before:bg-red-500',\n !editable && 'after:hidden'\n )}\n contentEditable={editable && isEditing}\n onBlur={handleBlur}\n onInput={handleInput}\n onPointerDownCapture={handleEdit}\n ref={ref}\n suppressContentEditableWarning\n >\n {children}\n </Slot>\n </div>\n );\n}\n\nexport { ClientLandingText };\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { LandingTextProps } from "./types.js";
|
|
2
2
|
import { ElementType } from "react";
|
|
3
|
-
import * as
|
|
3
|
+
import * as react_jsx_runtime10 from "react/jsx-runtime";
|
|
4
4
|
|
|
5
5
|
//#region src/components/landing-text/landing-text.d.ts
|
|
6
|
-
declare function LandingText<TAs extends ElementType = 'span'>(props: LandingTextProps<TAs>): Promise<
|
|
6
|
+
declare function LandingText<TAs extends ElementType = 'span'>(props: LandingTextProps<TAs>): Promise<react_jsx_runtime10.JSX.Element>;
|
|
7
7
|
//#endregion
|
|
8
8
|
export { LandingText };
|
|
9
9
|
//# sourceMappingURL=landing-text.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"landing-text.d.ts","names":[],"sources":["../../src/components/landing-text/landing-text.tsx"],"sourcesContent":[],"mappings":";;;;;iBAOe,wBAAwB,6BAC9B,iBAAiB,OAAI,QAAA,
|
|
1
|
+
{"version":3,"file":"landing-text.d.ts","names":[],"sources":["../../src/components/landing-text/landing-text.tsx"],"sourcesContent":[],"mappings":";;;;;iBAOe,wBAAwB,6BAC9B,iBAAiB,OAAI,QAAA,mBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ServerLandingTextProps } from "./types.js";
|
|
2
2
|
import { ElementType } from "react";
|
|
3
|
-
import * as
|
|
3
|
+
import * as react_jsx_runtime4 from "react/jsx-runtime";
|
|
4
4
|
|
|
5
5
|
//#region src/components/landing-text/server-landing-text.d.ts
|
|
6
6
|
declare function ServerLandingText<TAs extends ElementType = 'span'>({
|
|
@@ -9,7 +9,7 @@ declare function ServerLandingText<TAs extends ElementType = 'span'>({
|
|
|
9
9
|
className,
|
|
10
10
|
registration,
|
|
11
11
|
...props
|
|
12
|
-
}: ServerLandingTextProps<TAs>):
|
|
12
|
+
}: ServerLandingTextProps<TAs>): react_jsx_runtime4.JSX.Element;
|
|
13
13
|
//#endregion
|
|
14
14
|
export { ServerLandingText };
|
|
15
15
|
//# sourceMappingURL=server-landing-text.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime9 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/components/page-header/page-header.d.ts
|
|
4
4
|
interface PageHeaderProps {
|
|
@@ -10,7 +10,7 @@ declare function PageHeader({
|
|
|
10
10
|
title,
|
|
11
11
|
help,
|
|
12
12
|
description
|
|
13
|
-
}: PageHeaderProps):
|
|
13
|
+
}: PageHeaderProps): react_jsx_runtime9.JSX.Element;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { PageHeader, PageHeaderProps };
|
|
16
16
|
//# sourceMappingURL=page-header.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SelectorProps } from "../ui/selector.js";
|
|
2
2
|
import { FieldPath, FieldPathValue, FieldValues, UseControllerProps } from "react-hook-form";
|
|
3
|
-
import * as
|
|
3
|
+
import * as react_jsx_runtime7 from "react/jsx-runtime";
|
|
4
4
|
import { Options } from "nuqs";
|
|
5
5
|
|
|
6
6
|
//#region src/components/remote-selector/remote-selector.d.ts
|
|
@@ -38,7 +38,7 @@ declare function RemoteSelectorField<T, TFieldValues extends FieldValues = Field
|
|
|
38
38
|
...props
|
|
39
39
|
}: RemoteSelectorFieldProps<TFieldValues, TFieldName> & BaseRemoteSelectorProps<T> & {
|
|
40
40
|
withPortal?: boolean;
|
|
41
|
-
}):
|
|
41
|
+
}): react_jsx_runtime7.JSX.Element;
|
|
42
42
|
interface RemoteSelectorQueryProps<T> extends BaseRemoteSelectorProps<T> {
|
|
43
43
|
name: string;
|
|
44
44
|
defaultValue?: string;
|
|
@@ -58,7 +58,7 @@ declare function RemoteSelectorQuery<T>({
|
|
|
58
58
|
fieldLabel,
|
|
59
59
|
type,
|
|
60
60
|
...props
|
|
61
|
-
}: RemoteSelectorQueryProps<T>):
|
|
61
|
+
}: RemoteSelectorQueryProps<T>): react_jsx_runtime7.JSX.Element;
|
|
62
62
|
//#endregion
|
|
63
63
|
export { BaseRemoteSelectorProps, RemoteSelectorField, RemoteSelectorFieldProps, RemoteSelectorQuery, RemoteSelectorQueryProps, TUseData };
|
|
64
64
|
//# sourceMappingURL=remote-selector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-selector.d.ts","names":[],"sources":["../../src/components/remote-selector/remote-selector.tsx"],"sourcesContent":[],"mappings":";;;;;;KAwBY;QAKJ;;EALI,OAAA,CAAA,EAAA,OAAQ;EAWR,SAAA,CAAA,EAAA,OAAA;CACQ;AAAT,KADC,uBACD,CAAA,CAAA,CAAA,GAAA;EAC2B,OAAA,EAD3B,QAC2B,CADlB,CACkB,CAAA;EAAT,aAAA,CAAA,EAAX,UAAW,CAAA,QAAA,CAAS,CAAT,CAAA,CAAA,CAAA,CAAA,CAAA;EAAX,cAAA,CAAA,EAAA,OAAA;EAIF,WAAA,CAAA,EAAA,OAAA;CAAd,GADE,IACF,CAAA,aAAA,CAAc,CAAd,CAAA,EAAA,OAAA,GAAA,OAAA,GAAA,UAAA,GAAA,QAAA,GAAA,UAAA,GAAA,MAAA,GAAA,SAAA,GAAA,UAAA,GAAA,SAAA,GAAA,WAAA,CAAA;AADE,UAKa,wBALb,CAAA,qBAMmB,WANnB,GAMiC,WANjC,EAAA,mBAOiB,SAPjB,CAO2B,YAP3B,CAAA,GAO2C,SAP3C,CAOqD,YAPrD,CAAA,CAAA,SAQM,kBARN,CAQyB,YARzB,EAQuC,UARvC,CAAA,CAAA;EAAI,QAAA,CAAA,EAAA,OAAA;EAKS,QAAA,CAAA,EAAA,OAAA;EACM,YAAA,CAAA,EAKN,cALM,CAKS,YALT,EAKuB,UALvB,CAAA;EAAc,QAAA,CAAA,EAAA,CAAA,KAAA,EAAA,GAAA,EAAA,GAMR,OANQ,CAAA,IAAA,CAAA,GAAA,IAAA;EACN,SAAA,CAAA,EAAA,MAAA;;AAA0B,iBASzC,mBATyC,CAAA,CAAA,EAAA,qBAWlC,WAXkC,GAWpB,WAXoB,EAAA,mBAYpC,SAZoC,CAY1B,YAZ0B,CAAA,GAYV,SAZU,CAYA,YAZA,CAAA,CAAA,CAAA;EAAA,IAAA;EAAA,SAAA;EAAA,SAAA;EAAA,QAAA;EAAA,YAAA;EAAA,QAAA,EAmB7C,gBAnB6C;EAAA,OAAA;EAAA,aAAA;EAAA,UAAA;EAAA,cAAA;EAAA,WAAA;EAAA,GAAA;CAAA,EA0BtD,wBA1BsD,CA0B7B,YA1B6B,EA0Bf,UA1Be,CAAA,GA2BvD,uBA3BuD,CA2B/B,CA3B+B,CAAA,GAAA;EAAV,UAAA,CAAA,EAAA,OAAA;CAClB,CAAA,EA4B1B,
|
|
1
|
+
{"version":3,"file":"remote-selector.d.ts","names":[],"sources":["../../src/components/remote-selector/remote-selector.tsx"],"sourcesContent":[],"mappings":";;;;;;KAwBY;QAKJ;;EALI,OAAA,CAAA,EAAA,OAAQ;EAWR,SAAA,CAAA,EAAA,OAAA;CACQ;AAAT,KADC,uBACD,CAAA,CAAA,CAAA,GAAA;EAC2B,OAAA,EAD3B,QAC2B,CADlB,CACkB,CAAA;EAAT,aAAA,CAAA,EAAX,UAAW,CAAA,QAAA,CAAS,CAAT,CAAA,CAAA,CAAA,CAAA,CAAA;EAAX,cAAA,CAAA,EAAA,OAAA;EAIF,WAAA,CAAA,EAAA,OAAA;CAAd,GADE,IACF,CAAA,aAAA,CAAc,CAAd,CAAA,EAAA,OAAA,GAAA,OAAA,GAAA,UAAA,GAAA,QAAA,GAAA,UAAA,GAAA,MAAA,GAAA,SAAA,GAAA,UAAA,GAAA,SAAA,GAAA,WAAA,CAAA;AADE,UAKa,wBALb,CAAA,qBAMmB,WANnB,GAMiC,WANjC,EAAA,mBAOiB,SAPjB,CAO2B,YAP3B,CAAA,GAO2C,SAP3C,CAOqD,YAPrD,CAAA,CAAA,SAQM,kBARN,CAQyB,YARzB,EAQuC,UARvC,CAAA,CAAA;EAAI,QAAA,CAAA,EAAA,OAAA;EAKS,QAAA,CAAA,EAAA,OAAA;EACM,YAAA,CAAA,EAKN,cALM,CAKS,YALT,EAKuB,UALvB,CAAA;EAAc,QAAA,CAAA,EAAA,CAAA,KAAA,EAAA,GAAA,EAAA,GAMR,OANQ,CAAA,IAAA,CAAA,GAAA,IAAA;EACN,SAAA,CAAA,EAAA,MAAA;;AAA0B,iBASzC,mBATyC,CAAA,CAAA,EAAA,qBAWlC,WAXkC,GAWpB,WAXoB,EAAA,mBAYpC,SAZoC,CAY1B,YAZ0B,CAAA,GAYV,SAZU,CAYA,YAZA,CAAA,CAAA,CAAA;EAAA,IAAA;EAAA,SAAA;EAAA,SAAA;EAAA,QAAA;EAAA,YAAA;EAAA,QAAA,EAmB7C,gBAnB6C;EAAA,OAAA;EAAA,aAAA;EAAA,UAAA;EAAA,cAAA;EAAA,WAAA;EAAA,GAAA;CAAA,EA0BtD,wBA1BsD,CA0B7B,YA1B6B,EA0Bf,UA1Be,CAAA,GA2BvD,uBA3BuD,CA2B/B,CA3B+B,CAAA,GAAA;EAAV,UAAA,CAAA,EAAA,OAAA;CAClB,CAAA,EA4B1B,kBAAA,CAAA,GAAA,CAAA,OA5B0B;AAAc,UAoG1B,wBApG0B,CAAA,CAAA,CAAA,SAqGjC,uBArGiC,CAqGT,CArGS,CAAA,CAAA;EAGX,IAAA,EAAA,MAAA;EAAc,YAAA,CAAA,EAAA,MAAA;EAA7B,OAAA,CAAA,EAqGL,OArGK;EACY,QAAA,CAAA,EAAA,CAAA,KAAA,EAqGR,CArGQ,GAqGJ,CArGI,EAAA,GAAA,IAAA,EAAA,GAAA,IAAA;;AAJD,iBA4GZ,mBA5GY,CAAA,CAAA,CAAA,CAAA;EAAA,IAAA;EAAA,YAAA;EAAA,OAAA;EAAA,OAAA;EAAA,aAAA;EAAA,cAAA;EAAA,WAAA;EAAA,QAAA,EAoHhB,gBApHgB;EAAA,QAAA;EAAA,UAAA;EAAA,IAAA;EAAA,GAAA;AAAA,CAAA,EAyHzB,wBAzHyB,CAyHA,CAzHA,CAAA,CAAA,EAyHE,kBAAA,CAAA,GAAA,CAAA,OAzHF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maquinaweb-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.73.0",
|
|
4
4
|
"description": "A minimal React component library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
"import": "./dist/page-header.js",
|
|
10
10
|
"types": "./dist/page-header.d.ts"
|
|
11
11
|
},
|
|
12
|
+
"./analytics": {
|
|
13
|
+
"import": "./dist/analytics.js",
|
|
14
|
+
"types": "./dist/analytics.d.ts"
|
|
15
|
+
},
|
|
12
16
|
"./kanban-dnd": {
|
|
13
17
|
"import": "./dist/kanban-dnd.js",
|
|
14
18
|
"types": "./dist/kanban-dnd.d.ts"
|