@syntrologie/adapt-content 2.5.1 → 2.6.0-canary.2
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/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts.map +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.js +22 -153
- package/node_modules/@syntrologie/shared-editor-ui/package.json +2 -2
- package/package.json +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.js +0 -224
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/BeforeAfterToggle.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/BeforeAfterToggle.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/BeforeAfterToggle.test.js +0 -29
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ConditionStatusLine.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ConditionStatusLine.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ConditionStatusLine.test.js +0 -260
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DetectionBadge.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DetectionBadge.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DetectionBadge.test.js +0 -70
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DismissedSection.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DismissedSection.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DismissedSection.test.js +0 -46
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditBackButton.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditBackButton.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditBackButton.test.js +0 -20
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorBody.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorBody.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorBody.test.js +0 -12
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorCard.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorCard.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorCard.test.js +0 -84
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorFooter.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorFooter.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorFooter.test.js +0 -23
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorHeader.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorHeader.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorHeader.test.js +0 -23
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorInput.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorInput.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorInput.test.js +0 -26
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorLayout.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorLayout.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorLayout.test.js +0 -13
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorPanelShell.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorPanelShell.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorPanelShell.test.js +0 -496
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorSelect.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorSelect.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorSelect.test.js +0 -22
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorTextarea.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorTextarea.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorTextarea.test.js +0 -20
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ElementHighlight.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ElementHighlight.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ElementHighlight.test.js +0 -176
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EmptyState.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EmptyState.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EmptyState.test.js +0 -10
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/GroupHeader.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/GroupHeader.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/GroupHeader.test.js +0 -14
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/TriggerJourney.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/TriggerJourney.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/TriggerJourney.test.js +0 -189
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/cn.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/cn.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/cn.test.js +0 -16
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/formatConditionLabel.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/formatConditionLabel.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/formatConditionLabel.test.js +0 -329
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.js +0 -257
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useElementRect.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useElementRect.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useElementRect.test.js +0 -112
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.d.ts +0 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.d.ts.map +0 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.js +0 -1015
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTriggerWhenStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useTriggerWhenStatus.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAmB,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAG5F;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,KAAK,CAAC;YACZ,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;YAC3C,KAAK,EAAE,OAAO,CAAC;SAChB,CAAC,CAAC;QACH,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,GAAG,IAAI,CAAC;CACV;
|
|
1
|
+
{"version":3,"file":"useTriggerWhenStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useTriggerWhenStatus.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAmB,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAG5F;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,KAAK,CAAC;YACZ,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;YAC3C,KAAK,EAAE,OAAO,CAAC;SAChB,CAAC,CAAC;QACH,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,GAAG,IAAI,CAAC;CACV;AAsED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,eAAe,EAAE,GACvB,GAAG,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC,CA0CvC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* useTriggerWhenStatus — live triggerWhen evaluation for editor diagnostics.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Delegates condition evaluation to the runtime's evaluateSync() method,
|
|
5
|
+
* eliminating duplicated logic. Subscribes to the EventAccumulator for
|
|
6
|
+
* reactive updates.
|
|
7
7
|
*
|
|
8
8
|
* NOTE: This hook accesses `window.SynOS.handle.runtime` directly
|
|
9
9
|
* because EditorPanelProps doesn't expose runtime. This is safe —
|
|
@@ -11,167 +11,36 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
13
13
|
import { formatConditionLabel } from '../formatConditionLabel';
|
|
14
|
-
function getRuntime() {
|
|
15
|
-
return window.SynOS?.handle?.runtime ?? null;
|
|
16
|
-
}
|
|
17
14
|
/**
|
|
18
|
-
*
|
|
15
|
+
* Build a RuntimeLike from the real SynOS.handle.runtime.
|
|
19
16
|
*/
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
switch (type) {
|
|
26
|
-
case 'event_count': {
|
|
27
|
-
if (!runtime.accumulator)
|
|
28
|
-
break;
|
|
29
|
-
const key = condition.key;
|
|
30
|
-
const withinMs = condition.withinMs;
|
|
31
|
-
const count = runtime.accumulator.getCount(key, withinMs);
|
|
32
|
-
accCount = count;
|
|
33
|
-
const target = condition.count;
|
|
34
|
-
const op = condition.operator;
|
|
35
|
-
switch (op) {
|
|
36
|
-
case 'gte':
|
|
37
|
-
passed = count >= target;
|
|
38
|
-
break;
|
|
39
|
-
case 'lte':
|
|
40
|
-
passed = count <= target;
|
|
41
|
-
break;
|
|
42
|
-
case 'eq':
|
|
43
|
-
passed = count === target;
|
|
44
|
-
break;
|
|
45
|
-
case 'gt':
|
|
46
|
-
passed = count > target;
|
|
47
|
-
break;
|
|
48
|
-
case 'lt':
|
|
49
|
-
passed = count < target;
|
|
50
|
-
break;
|
|
51
|
-
}
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
case 'page_url': {
|
|
55
|
-
const url = condition.url;
|
|
56
|
-
const pattern = url
|
|
57
|
-
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
58
|
-
.replace(/\*\*/g, '.*')
|
|
59
|
-
.replace(/\*/g, '[^/]*');
|
|
60
|
-
passed = new RegExp(`^${pattern}$`).test(ctx.page.url);
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
case 'route':
|
|
64
|
-
passed = ctx.page.routeId === condition.routeId;
|
|
65
|
-
break;
|
|
66
|
-
case 'anchor_visible': {
|
|
67
|
-
const anchors = ctx.anchors;
|
|
68
|
-
const condSelector = typeof condition.anchorId === 'string'
|
|
69
|
-
? condition.anchorId
|
|
70
|
-
: (condition.anchorId?.selector ?? '');
|
|
71
|
-
const anchor = anchors?.find((a) => a.anchorId === condSelector);
|
|
72
|
-
switch (condition.state) {
|
|
73
|
-
case 'visible':
|
|
74
|
-
passed = anchor?.visible === true;
|
|
75
|
-
break;
|
|
76
|
-
case 'present':
|
|
77
|
-
passed = anchor?.present === true;
|
|
78
|
-
break;
|
|
79
|
-
case 'absent':
|
|
80
|
-
passed = !anchor?.present;
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
case 'event_occurred':
|
|
86
|
-
passed =
|
|
87
|
-
runtime.events?.hasRecentEvent(condition.eventName, condition.withinMs ?? 60000) ?? false;
|
|
88
|
-
break;
|
|
89
|
-
case 'viewport': {
|
|
90
|
-
const { width, height } = ctx.viewport;
|
|
91
|
-
passed = true;
|
|
92
|
-
if (condition.minWidth !== undefined && width < condition.minWidth)
|
|
93
|
-
passed = false;
|
|
94
|
-
if (condition.maxWidth !== undefined && width > condition.maxWidth)
|
|
95
|
-
passed = false;
|
|
96
|
-
if (condition.minHeight !== undefined && height < condition.minHeight)
|
|
97
|
-
passed = false;
|
|
98
|
-
if (condition.maxHeight !== undefined && height > condition.maxHeight)
|
|
99
|
-
passed = false;
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
case 'session_metric': {
|
|
103
|
-
const val = runtime.state?.getSessionMetric(condition.key) ?? 0;
|
|
104
|
-
const threshold = condition.threshold;
|
|
105
|
-
const op = condition.operator;
|
|
106
|
-
switch (op) {
|
|
107
|
-
case 'gte':
|
|
108
|
-
passed = val >= threshold;
|
|
109
|
-
break;
|
|
110
|
-
case 'lte':
|
|
111
|
-
passed = val <= threshold;
|
|
112
|
-
break;
|
|
113
|
-
case 'eq':
|
|
114
|
-
passed = val === threshold;
|
|
115
|
-
break;
|
|
116
|
-
case 'gt':
|
|
117
|
-
passed = val > threshold;
|
|
118
|
-
break;
|
|
119
|
-
case 'lt':
|
|
120
|
-
passed = val < threshold;
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
break;
|
|
124
|
-
}
|
|
125
|
-
case 'dismissed':
|
|
126
|
-
passed = condition.inverted
|
|
127
|
-
? !(runtime.state?.isDismissed(condition.key) ?? false)
|
|
128
|
-
: (runtime.state?.isDismissed(condition.key) ?? false);
|
|
129
|
-
break;
|
|
130
|
-
case 'cooldown_active':
|
|
131
|
-
passed = condition.inverted
|
|
132
|
-
? !(runtime.state?.isCooldownActive(condition.key) ?? false)
|
|
133
|
-
: (runtime.state?.isCooldownActive(condition.key) ?? false);
|
|
134
|
-
break;
|
|
135
|
-
case 'frequency_limit': {
|
|
136
|
-
const count = runtime.state?.getFrequencyCount(condition.key) ?? 0;
|
|
137
|
-
const limitReached = count >= condition.limit;
|
|
138
|
-
passed = condition.inverted ? !limitReached : limitReached;
|
|
139
|
-
break;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
const formatted = formatConditionLabel(condition, accCount);
|
|
17
|
+
function getRuntime() {
|
|
18
|
+
// biome-ignore lint: window.SynOS is set by the runtime SDK
|
|
19
|
+
const rt = window.SynOS?.handle?.runtime;
|
|
20
|
+
if (!rt?.evaluateSync)
|
|
21
|
+
return null;
|
|
143
22
|
return {
|
|
144
|
-
|
|
145
|
-
|
|
23
|
+
evaluateSync: rt.evaluateSync.bind(rt),
|
|
24
|
+
accumulator: rt.accumulator,
|
|
146
25
|
};
|
|
147
26
|
}
|
|
148
27
|
/**
|
|
149
|
-
* Evaluate all conditions in a triggerWhen RuleStrategy.
|
|
28
|
+
* Evaluate all conditions in a triggerWhen RuleStrategy via the runtime engine.
|
|
150
29
|
*/
|
|
151
30
|
function evaluateTriggerWhen(triggerWhen, runtime) {
|
|
152
31
|
if (triggerWhen.type !== 'rules' || !triggerWhen.rules?.length) {
|
|
153
32
|
return { visible: !!triggerWhen.default, isFallback: true, conditions: [] };
|
|
154
33
|
}
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (ruleMatched) {
|
|
166
|
-
return { visible: rule.value, isFallback: false, conditions: allConditions };
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
// No rules matched — use default
|
|
170
|
-
return {
|
|
171
|
-
visible: triggerWhen.default ?? false,
|
|
172
|
-
isFallback: true,
|
|
173
|
-
conditions: allConditions,
|
|
174
|
-
};
|
|
34
|
+
const result = runtime.evaluateSync(triggerWhen);
|
|
35
|
+
const conditions = (result.matchInfo?.evaluatedConditions ?? []).map(({ condition, result: passed }) => {
|
|
36
|
+
// Get live accumulator count for event_count progress display
|
|
37
|
+
const accCount = condition.type === 'event_count' && runtime.accumulator
|
|
38
|
+
? runtime.accumulator.getCount(condition.key, condition.withinMs)
|
|
39
|
+
: undefined;
|
|
40
|
+
const formatted = formatConditionLabel(condition, accCount);
|
|
41
|
+
return { type: condition.type, passed, formatted };
|
|
42
|
+
});
|
|
43
|
+
return { visible: result.value, isFallback: result.isFallback, conditions };
|
|
175
44
|
}
|
|
176
45
|
/**
|
|
177
46
|
* Hook: live triggerWhen evaluation for a list of action items.
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"css-selector-generator": "^3.8.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
+
"lucide-react": ">=0.400.0",
|
|
31
32
|
"react": ">=18.0.0",
|
|
32
|
-
"react-dom": ">=18.0.0"
|
|
33
|
-
"lucide-react": ">=0.400.0"
|
|
33
|
+
"react-dom": ">=18.0.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@testing-library/dom": "^10.4.1",
|
package/package.json
CHANGED
package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnchorPicker.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/AnchorPicker.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { act, render } from '@testing-library/react';
|
|
3
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
-
import { AnchorPicker } from '../components/AnchorPicker';
|
|
5
|
-
// Mock ResizeObserver for jsdom
|
|
6
|
-
vi.stubGlobal('ResizeObserver', class {
|
|
7
|
-
observe() { }
|
|
8
|
-
unobserve() { }
|
|
9
|
-
disconnect() { }
|
|
10
|
-
});
|
|
11
|
-
// Mock selectorGenerator utilities
|
|
12
|
-
vi.mock('../utils/selectorGenerator', () => ({
|
|
13
|
-
generateSelector: vi.fn((el) => `mock-selector-${el.tagName.toLowerCase()}`),
|
|
14
|
-
validateSelector: vi.fn(() => true),
|
|
15
|
-
getElementDescription: vi.fn((el) => `mock-desc-${el.tagName.toLowerCase()}`),
|
|
16
|
-
}));
|
|
17
|
-
import { generateSelector, getElementDescription, validateSelector, } from '../utils/selectorGenerator';
|
|
18
|
-
describe('AnchorPicker', () => {
|
|
19
|
-
let mockElementAtPoint;
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
mockElementAtPoint = document.createElement('div');
|
|
22
|
-
mockElementAtPoint.textContent = 'Target Element';
|
|
23
|
-
document.body.appendChild(mockElementAtPoint);
|
|
24
|
-
vi.spyOn(mockElementAtPoint, 'getBoundingClientRect').mockReturnValue({
|
|
25
|
-
top: 100,
|
|
26
|
-
left: 200,
|
|
27
|
-
width: 300,
|
|
28
|
-
height: 150,
|
|
29
|
-
bottom: 250,
|
|
30
|
-
right: 500,
|
|
31
|
-
x: 200,
|
|
32
|
-
y: 100,
|
|
33
|
-
toJSON: () => ({}),
|
|
34
|
-
});
|
|
35
|
-
vi.mocked(generateSelector).mockClear();
|
|
36
|
-
vi.mocked(validateSelector).mockClear();
|
|
37
|
-
vi.mocked(getElementDescription).mockClear();
|
|
38
|
-
vi.mocked(generateSelector).mockImplementation((el) => `mock-selector-${el.tagName.toLowerCase()}`);
|
|
39
|
-
vi.mocked(validateSelector).mockReturnValue(true);
|
|
40
|
-
vi.mocked(getElementDescription).mockImplementation((el) => `mock-desc-${el.tagName.toLowerCase()}`);
|
|
41
|
-
// Stub elementFromPoint on document (jsdom does not define it)
|
|
42
|
-
if (!document.elementFromPoint) {
|
|
43
|
-
document.elementFromPoint = vi.fn(() => null);
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
vi.spyOn(document, 'elementFromPoint').mockReturnValue(null);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
afterEach(() => {
|
|
50
|
-
if (mockElementAtPoint.parentNode) {
|
|
51
|
-
mockElementAtPoint.remove();
|
|
52
|
-
}
|
|
53
|
-
vi.restoreAllMocks();
|
|
54
|
-
});
|
|
55
|
-
it('renders nothing when isActive is false', () => {
|
|
56
|
-
render(_jsx(AnchorPicker, { isActive: false, onPick: vi.fn(), onCancel: vi.fn() }));
|
|
57
|
-
const picker = document.body.querySelector('[data-syntro-anchor-picker]');
|
|
58
|
-
expect(picker).toBeNull();
|
|
59
|
-
});
|
|
60
|
-
it('renders overlay portal to document.body when active', () => {
|
|
61
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: vi.fn() }));
|
|
62
|
-
const picker = document.body.querySelector('[data-syntro-anchor-picker]');
|
|
63
|
-
expect(picker).toBeTruthy();
|
|
64
|
-
unmount();
|
|
65
|
-
});
|
|
66
|
-
it('sets crosshair cursor on overlay', () => {
|
|
67
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: vi.fn() }));
|
|
68
|
-
const picker = document.body.querySelector('[data-syntro-anchor-picker]');
|
|
69
|
-
expect(picker.style.cursor).toBe('crosshair');
|
|
70
|
-
unmount();
|
|
71
|
-
});
|
|
72
|
-
it('sets highest z-index on overlay', () => {
|
|
73
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: vi.fn() }));
|
|
74
|
-
const picker = document.body.querySelector('[data-syntro-anchor-picker]');
|
|
75
|
-
expect(picker.style.zIndex).toBe('2147483644');
|
|
76
|
-
unmount();
|
|
77
|
-
});
|
|
78
|
-
it('calls onCancel when Escape key is pressed', () => {
|
|
79
|
-
const onCancel = vi.fn();
|
|
80
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: onCancel }));
|
|
81
|
-
act(() => {
|
|
82
|
-
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
|
|
83
|
-
});
|
|
84
|
-
expect(onCancel).toHaveBeenCalledTimes(1);
|
|
85
|
-
unmount();
|
|
86
|
-
});
|
|
87
|
-
it('does not call onCancel for non-Escape keys', () => {
|
|
88
|
-
const onCancel = vi.fn();
|
|
89
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: onCancel }));
|
|
90
|
-
act(() => {
|
|
91
|
-
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
|
|
92
|
-
});
|
|
93
|
-
expect(onCancel).not.toHaveBeenCalled();
|
|
94
|
-
unmount();
|
|
95
|
-
});
|
|
96
|
-
it('highlights element on mousemove via elementFromPoint', () => {
|
|
97
|
-
document.elementFromPoint.mockReturnValue(mockElementAtPoint);
|
|
98
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: vi.fn() }));
|
|
99
|
-
act(() => {
|
|
100
|
-
document.dispatchEvent(new MouseEvent('mousemove', { clientX: 250, clientY: 150, bubbles: true }));
|
|
101
|
-
});
|
|
102
|
-
// generateSelector should have been called with the element
|
|
103
|
-
expect(generateSelector).toHaveBeenCalledWith(mockElementAtPoint);
|
|
104
|
-
unmount();
|
|
105
|
-
});
|
|
106
|
-
it('clears hover state when elementFromPoint returns null', () => {
|
|
107
|
-
document.elementFromPoint.mockReturnValue(null);
|
|
108
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: vi.fn() }));
|
|
109
|
-
act(() => {
|
|
110
|
-
document.dispatchEvent(new MouseEvent('mousemove', { clientX: 250, clientY: 150, bubbles: true }));
|
|
111
|
-
});
|
|
112
|
-
// No highlight should be shown (just the overlay container + the semi-transparent bg div)
|
|
113
|
-
const picker = document.body.querySelector('[data-syntro-anchor-picker]');
|
|
114
|
-
expect(picker.children.length).toBe(1);
|
|
115
|
-
unmount();
|
|
116
|
-
});
|
|
117
|
-
it('excludes editor panel elements from picking', () => {
|
|
118
|
-
const editorPanel = document.createElement('div');
|
|
119
|
-
editorPanel.setAttribute('data-syntro-editor-panel', '');
|
|
120
|
-
const innerEl = document.createElement('span');
|
|
121
|
-
editorPanel.appendChild(innerEl);
|
|
122
|
-
document.body.appendChild(editorPanel);
|
|
123
|
-
document.elementFromPoint.mockReturnValue(innerEl);
|
|
124
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: vi.fn() }));
|
|
125
|
-
act(() => {
|
|
126
|
-
document.dispatchEvent(new MouseEvent('mousemove', { clientX: 100, clientY: 100, bubbles: true }));
|
|
127
|
-
});
|
|
128
|
-
// Should not call generateSelector for excluded elements
|
|
129
|
-
expect(generateSelector).not.toHaveBeenCalled();
|
|
130
|
-
editorPanel.remove();
|
|
131
|
-
unmount();
|
|
132
|
-
});
|
|
133
|
-
it('excludes HTML, BODY, HEAD elements from picking', () => {
|
|
134
|
-
document.elementFromPoint.mockReturnValue(document.body);
|
|
135
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: vi.fn() }));
|
|
136
|
-
act(() => {
|
|
137
|
-
document.dispatchEvent(new MouseEvent('mousemove', { clientX: 100, clientY: 100, bubbles: true }));
|
|
138
|
-
});
|
|
139
|
-
expect(generateSelector).not.toHaveBeenCalled();
|
|
140
|
-
unmount();
|
|
141
|
-
});
|
|
142
|
-
it('calls onPick with valid selector on click after hover', () => {
|
|
143
|
-
const onPick = vi.fn();
|
|
144
|
-
document.elementFromPoint.mockReturnValue(mockElementAtPoint);
|
|
145
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: onPick, onCancel: vi.fn() }));
|
|
146
|
-
// First hover to set the hovered element
|
|
147
|
-
act(() => {
|
|
148
|
-
document.dispatchEvent(new MouseEvent('mousemove', { clientX: 250, clientY: 150, bubbles: true }));
|
|
149
|
-
});
|
|
150
|
-
// Then click
|
|
151
|
-
act(() => {
|
|
152
|
-
document.dispatchEvent(new MouseEvent('click', { clientX: 250, clientY: 150, bubbles: true }));
|
|
153
|
-
});
|
|
154
|
-
expect(onPick).toHaveBeenCalledTimes(1);
|
|
155
|
-
expect(onPick).toHaveBeenCalledWith({
|
|
156
|
-
element: mockElementAtPoint,
|
|
157
|
-
selector: 'mock-selector-div',
|
|
158
|
-
description: 'mock-desc-div',
|
|
159
|
-
});
|
|
160
|
-
unmount();
|
|
161
|
-
});
|
|
162
|
-
it('regenerates selector when validation fails on click', () => {
|
|
163
|
-
const onPick = vi.fn();
|
|
164
|
-
document.elementFromPoint.mockReturnValue(mockElementAtPoint);
|
|
165
|
-
vi.mocked(validateSelector).mockReturnValue(false);
|
|
166
|
-
vi.mocked(generateSelector).mockReturnValue('regenerated-selector');
|
|
167
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: onPick, onCancel: vi.fn() }));
|
|
168
|
-
// Hover to set element
|
|
169
|
-
act(() => {
|
|
170
|
-
document.dispatchEvent(new MouseEvent('mousemove', { clientX: 250, clientY: 150, bubbles: true }));
|
|
171
|
-
});
|
|
172
|
-
// Click
|
|
173
|
-
act(() => {
|
|
174
|
-
document.dispatchEvent(new MouseEvent('click', { clientX: 250, clientY: 150, bubbles: true }));
|
|
175
|
-
});
|
|
176
|
-
expect(onPick).toHaveBeenCalledWith(expect.objectContaining({
|
|
177
|
-
selector: 'regenerated-selector',
|
|
178
|
-
}));
|
|
179
|
-
unmount();
|
|
180
|
-
});
|
|
181
|
-
it('does not call onPick when no element is hovered on click', () => {
|
|
182
|
-
const onPick = vi.fn();
|
|
183
|
-
document.elementFromPoint.mockReturnValue(null);
|
|
184
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: onPick, onCancel: vi.fn() }));
|
|
185
|
-
act(() => {
|
|
186
|
-
document.dispatchEvent(new MouseEvent('click', { clientX: 250, clientY: 150, bubbles: true }));
|
|
187
|
-
});
|
|
188
|
-
expect(onPick).not.toHaveBeenCalled();
|
|
189
|
-
unmount();
|
|
190
|
-
});
|
|
191
|
-
it('removes event listeners when deactivated', () => {
|
|
192
|
-
const onCancel = vi.fn();
|
|
193
|
-
const { rerender, unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: onCancel }));
|
|
194
|
-
// Deactivate
|
|
195
|
-
rerender(_jsx(AnchorPicker, { isActive: false, onPick: vi.fn(), onCancel: onCancel }));
|
|
196
|
-
// Escape should not trigger onCancel after deactivation
|
|
197
|
-
act(() => {
|
|
198
|
-
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }));
|
|
199
|
-
});
|
|
200
|
-
expect(onCancel).not.toHaveBeenCalled();
|
|
201
|
-
unmount();
|
|
202
|
-
});
|
|
203
|
-
it('temporarily disables pointer events on overlay during mousemove detection', () => {
|
|
204
|
-
const overlayPointerEvents = [];
|
|
205
|
-
document.elementFromPoint.mockImplementation(() => {
|
|
206
|
-
// Capture overlay pointer events state during elementFromPoint call
|
|
207
|
-
const overlay = document.body.querySelector('[data-syntro-anchor-picker]');
|
|
208
|
-
if (overlay) {
|
|
209
|
-
overlayPointerEvents.push(overlay.style.pointerEvents);
|
|
210
|
-
}
|
|
211
|
-
return mockElementAtPoint;
|
|
212
|
-
});
|
|
213
|
-
const { unmount } = render(_jsx(AnchorPicker, { isActive: true, onPick: vi.fn(), onCancel: vi.fn() }));
|
|
214
|
-
act(() => {
|
|
215
|
-
document.dispatchEvent(new MouseEvent('mousemove', { clientX: 250, clientY: 150, bubbles: true }));
|
|
216
|
-
});
|
|
217
|
-
// During elementFromPoint, overlay pointerEvents should be 'none'
|
|
218
|
-
expect(overlayPointerEvents).toContain('none');
|
|
219
|
-
// After the call, it should be restored to 'auto'
|
|
220
|
-
const overlay = document.body.querySelector('[data-syntro-anchor-picker]');
|
|
221
|
-
expect(overlay.style.pointerEvents).toBe('auto');
|
|
222
|
-
unmount();
|
|
223
|
-
});
|
|
224
|
-
});
|
package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/BeforeAfterToggle.test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BeforeAfterToggle.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/BeforeAfterToggle.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { fireEvent, render } from '@testing-library/react';
|
|
3
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
4
|
-
import { BeforeAfterToggle } from '../components/BeforeAfterToggle';
|
|
5
|
-
describe('BeforeAfterToggle', () => {
|
|
6
|
-
it('renders Before and After buttons', () => {
|
|
7
|
-
const { getByText } = render(_jsx(BeforeAfterToggle, { mode: "before", onToggle: () => { } }));
|
|
8
|
-
expect(getByText('Before')).toBeTruthy();
|
|
9
|
-
expect(getByText('After')).toBeTruthy();
|
|
10
|
-
});
|
|
11
|
-
it('calls onToggle with "before" when Before is clicked', () => {
|
|
12
|
-
const onToggle = vi.fn();
|
|
13
|
-
const { getByText } = render(_jsx(BeforeAfterToggle, { mode: "after", onToggle: onToggle }));
|
|
14
|
-
fireEvent.click(getByText('Before'));
|
|
15
|
-
expect(onToggle).toHaveBeenCalledWith('before');
|
|
16
|
-
});
|
|
17
|
-
it('calls onToggle with "after" when After is clicked', () => {
|
|
18
|
-
const onToggle = vi.fn();
|
|
19
|
-
const { getByText } = render(_jsx(BeforeAfterToggle, { mode: "before", onToggle: onToggle }));
|
|
20
|
-
fireEvent.click(getByText('After'));
|
|
21
|
-
expect(onToggle).toHaveBeenCalledWith('after');
|
|
22
|
-
});
|
|
23
|
-
it('highlights active mode with blue class', () => {
|
|
24
|
-
const { getByText } = render(_jsx(BeforeAfterToggle, { mode: "before", onToggle: () => { } }));
|
|
25
|
-
expect(getByText('Before').className).toContain('se-text-blue-5');
|
|
26
|
-
expect(getByText('Before').className).toContain('se-bg-blue-5/30');
|
|
27
|
-
expect(getByText('After').className).toContain('se-text-text-secondary');
|
|
28
|
-
});
|
|
29
|
-
});
|
package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ConditionStatusLine.test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ConditionStatusLine.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ConditionStatusLine.test.tsx"],"names":[],"mappings":""}
|