@syntrologie/adapt-content 2.4.0 → 2.5.1

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.
Files changed (54) hide show
  1. package/dist/editor.d.ts.map +1 -1
  2. package/dist/editor.js +59 -3
  3. package/dist/runtime.d.ts.map +1 -1
  4. package/dist/runtime.js +67 -12
  5. package/dist/summarize.d.ts.map +1 -1
  6. package/dist/summarize.js +12 -1
  7. package/dist/types.d.ts +9 -42
  8. package/dist/types.d.ts.map +1 -1
  9. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.d.ts +2 -0
  10. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.d.ts.map +1 -0
  11. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.js +224 -0
  12. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ConditionStatusLine.test.js +102 -0
  13. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DetectionBadge.test.js +58 -6
  14. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DismissedSection.test.js +18 -0
  15. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorCard.test.js +61 -2
  16. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorPanelShell.test.js +478 -7
  17. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ElementHighlight.test.js +54 -0
  18. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.d.ts +2 -0
  19. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.d.ts.map +1 -0
  20. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.js +257 -0
  21. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.d.ts +2 -0
  22. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.d.ts.map +1 -0
  23. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.js +1015 -0
  24. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.js +1 -1
  25. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts +4 -4
  26. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts.map +1 -1
  27. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.js +2 -2
  28. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts +2 -1
  29. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts.map +1 -1
  30. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.js +20 -3
  31. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts +10 -8
  32. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts.map +1 -1
  33. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.js +350 -87
  34. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.js +1 -1
  35. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts +3 -3
  36. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts.map +1 -1
  37. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.js +1 -1
  38. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts +1 -1
  39. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts.map +1 -1
  40. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.js +5 -2
  41. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts +24 -0
  42. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts.map +1 -0
  43. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/{useShowWhenStatus.js → useTriggerWhenStatus.js} +18 -15
  44. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts +3 -3
  45. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts.map +1 -1
  46. package/node_modules/@syntrologie/shared-editor-ui/dist/index.js +1 -1
  47. package/package.json +4 -5
  48. package/node_modules/@syntrologie/sdk-contracts/dist/index.d.ts +0 -26
  49. package/node_modules/@syntrologie/sdk-contracts/dist/index.js +0 -13
  50. package/node_modules/@syntrologie/sdk-contracts/dist/schemas.d.ts +0 -1428
  51. package/node_modules/@syntrologie/sdk-contracts/dist/schemas.js +0 -142
  52. package/node_modules/@syntrologie/sdk-contracts/package.json +0 -33
  53. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useShowWhenStatus.d.ts +0 -24
  54. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useShowWhenStatus.d.ts.map +0 -1
@@ -155,4 +155,106 @@ describe('ConditionStatusLine', () => {
155
155
  expect(label.className).toContain('se-text-text-secondary');
156
156
  expect(label.className).not.toContain('se-text-text-tertiary');
157
157
  });
158
+ it('renders progress bar for single condition with progress data', () => {
159
+ const status = {
160
+ visible: false,
161
+ isFallback: false,
162
+ conditions: [
163
+ {
164
+ type: 'event_count',
165
+ passed: false,
166
+ formatted: {
167
+ label: 'views >= 5',
168
+ instruction: 'View pages 5+ times',
169
+ shortLabel: 'View 5+ times',
170
+ progress: { current: 2, target: 5, operator: 'gte' },
171
+ },
172
+ },
173
+ ],
174
+ };
175
+ const { container } = render(_jsx(ConditionStatusLine, { status: status }));
176
+ // Progress bar has a title with current/target
177
+ const progressBar = container.querySelector('[title]');
178
+ expect(progressBar).toBeTruthy();
179
+ expect(progressBar.title).toContain('2/5');
180
+ // Also shows numeric progress
181
+ expect(screen.getByText('2/5')).toBeTruthy();
182
+ });
183
+ it('renders progress bar at 100% with green color', () => {
184
+ const status = {
185
+ visible: true,
186
+ isFallback: false,
187
+ conditions: [
188
+ {
189
+ type: 'event_count',
190
+ passed: true,
191
+ formatted: {
192
+ label: 'clicks >= 3',
193
+ instruction: 'Click 3+ times',
194
+ shortLabel: '3+ clicks',
195
+ progress: { current: 5, target: 3, operator: 'gte' },
196
+ },
197
+ },
198
+ ],
199
+ };
200
+ const { container } = render(_jsx(ConditionStatusLine, { status: status }));
201
+ const progressBar = container.querySelector('[title]');
202
+ expect(progressBar).toBeTruthy();
203
+ // 100% cap
204
+ expect(progressBar.title).toContain('100%');
205
+ // The inner bar should have green background
206
+ const innerBar = progressBar.firstElementChild;
207
+ expect(innerBar.className).toContain('se-bg-green-4');
208
+ });
209
+ it('renders progress bar with blue color when not at 100%', () => {
210
+ const status = {
211
+ visible: false,
212
+ isFallback: false,
213
+ conditions: [
214
+ {
215
+ type: 'event_count',
216
+ passed: false,
217
+ formatted: {
218
+ label: 'clicks >= 10',
219
+ instruction: 'Click 10+ times',
220
+ shortLabel: '10+ clicks',
221
+ progress: { current: 3, target: 10, operator: 'gte' },
222
+ },
223
+ },
224
+ ],
225
+ };
226
+ const { container } = render(_jsx(ConditionStatusLine, { status: status }));
227
+ const progressBar = container.querySelector('[title]');
228
+ const innerBar = progressBar.firstElementChild;
229
+ expect(innerBar.className).toContain('se-bg-blue-4');
230
+ expect(innerBar.className).not.toContain('se-bg-green-4');
231
+ });
232
+ it('renders progress bar in expanded multi-condition rows', () => {
233
+ const status = {
234
+ visible: false,
235
+ isFallback: false,
236
+ conditions: [
237
+ {
238
+ type: 'page_url',
239
+ passed: true,
240
+ formatted: { label: '/p', instruction: 'A', shortLabel: 'A' },
241
+ },
242
+ {
243
+ type: 'event_count',
244
+ passed: false,
245
+ formatted: {
246
+ label: 'views >= 5',
247
+ instruction: 'B',
248
+ shortLabel: 'B',
249
+ progress: { current: 2, target: 5, operator: 'gte' },
250
+ },
251
+ },
252
+ ],
253
+ };
254
+ render(_jsx(ConditionStatusLine, { status: status }));
255
+ // Expand
256
+ fireEvent.click(screen.getByText('1 of 2 conditions met'));
257
+ // Progress bar should appear in the expanded section
258
+ expect(screen.getByText('2/5')).toBeTruthy();
259
+ });
158
260
  });
@@ -1,18 +1,70 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { render } from '@testing-library/react';
3
- import { describe, expect, it } from 'vitest';
2
+ import { fireEvent, render } from '@testing-library/react';
3
+ import { describe, expect, it, vi } from 'vitest';
4
4
  import { DetectionBadge } from '../components/DetectionBadge';
5
5
  describe('DetectionBadge', () => {
6
- it('shows green dot class when found is true', () => {
6
+ it('displays "GoTo" text', () => {
7
+ const { container } = render(_jsx(DetectionBadge, { found: true }));
8
+ expect(container.textContent).toBe('GoTo');
9
+ });
10
+ it('uses green text color when found is true', () => {
7
11
  const { container } = render(_jsx(DetectionBadge, { found: true }));
8
12
  const badge = container.firstElementChild;
9
- expect(badge.className).toContain('se-bg-green-4');
13
+ expect(badge.className).toContain('se-text-green-4');
10
14
  expect(badge.title).toBe('Found on this page');
11
15
  });
12
- it('shows gray dot class when found is false', () => {
16
+ it('uses muted text color when found is false', () => {
13
17
  const { container } = render(_jsx(DetectionBadge, { found: false }));
14
18
  const badge = container.firstElementChild;
15
- expect(badge.className).toContain('se-bg-text-tertiary');
19
+ expect(badge.className).toContain('se-text-text-tertiary');
16
20
  expect(badge.title).toBe('Not found on this page');
17
21
  });
22
+ it('renders a <span> when no onClick is provided', () => {
23
+ const { container } = render(_jsx(DetectionBadge, { found: true }));
24
+ const badge = container.firstElementChild;
25
+ expect(badge.tagName).toBe('SPAN');
26
+ });
27
+ it('renders a <button> when onClick is provided', () => {
28
+ const { container } = render(_jsx(DetectionBadge, { found: true, onClick: () => { } }));
29
+ const badge = container.firstElementChild;
30
+ expect(badge.tagName).toBe('BUTTON');
31
+ });
32
+ it('calls onClick when clicked', () => {
33
+ const onClick = vi.fn();
34
+ const { container } = render(_jsx(DetectionBadge, { found: true, onClick: onClick }));
35
+ const badge = container.firstElementChild;
36
+ fireEvent.click(badge);
37
+ expect(onClick).toHaveBeenCalledTimes(1);
38
+ });
39
+ it('calls stopPropagation so clicks do not bubble to parent card', () => {
40
+ const onClick = vi.fn();
41
+ const parentClick = vi.fn();
42
+ const { container } = render(
43
+ // biome-ignore lint/a11y/useKeyWithClickEvents: test wrapper
44
+ _jsx("div", { onClick: parentClick, children: _jsx(DetectionBadge, { found: false, onClick: onClick }) }));
45
+ const badge = container.querySelector('button');
46
+ fireEvent.click(badge);
47
+ expect(onClick).toHaveBeenCalledTimes(1);
48
+ expect(parentClick).not.toHaveBeenCalled();
49
+ });
50
+ it('shows "Click to scroll to element" title when onClick + found', () => {
51
+ const { container } = render(_jsx(DetectionBadge, { found: true, onClick: () => { } }));
52
+ const badge = container.firstElementChild;
53
+ expect(badge.title).toBe('Click to scroll to element');
54
+ });
55
+ it('shows "Click to navigate to page" title when onClick + not found', () => {
56
+ const { container } = render(_jsx(DetectionBadge, { found: false, onClick: () => { } }));
57
+ const badge = container.firstElementChild;
58
+ expect(badge.title).toBe('Click to navigate to page');
59
+ });
60
+ it('has green indicator dot when found', () => {
61
+ const { container } = render(_jsx(DetectionBadge, { found: true }));
62
+ const dot = container.querySelector('[data-indicator]');
63
+ expect(dot.className).toContain('se-bg-green-4');
64
+ });
65
+ it('has muted indicator dot when not found', () => {
66
+ const { container } = render(_jsx(DetectionBadge, { found: false }));
67
+ const dot = container.querySelector('[data-indicator]');
68
+ expect(dot.className).toContain('se-bg-text-tertiary');
69
+ });
18
70
  });
@@ -25,4 +25,22 @@ describe('DismissedSection', () => {
25
25
  fireEvent.click(getByText('Dismissed (1)'));
26
26
  expect(queryByText('content')).toBeNull();
27
27
  });
28
+ it('expands on Enter keydown', () => {
29
+ const { getByText, queryByText } = render(_jsx(DismissedSection, { count: 2, children: _jsx("span", { children: "keyboard content" }) }));
30
+ const button = getByText('Dismissed (2)').closest('[role="button"]');
31
+ fireEvent.keyDown(button, { key: 'Enter' });
32
+ expect(queryByText('keyboard content')).toBeTruthy();
33
+ });
34
+ it('expands on Space keydown', () => {
35
+ const { getByText, queryByText } = render(_jsx(DismissedSection, { count: 2, children: _jsx("span", { children: "space content" }) }));
36
+ const button = getByText('Dismissed (2)').closest('[role="button"]');
37
+ fireEvent.keyDown(button, { key: ' ' });
38
+ expect(queryByText('space content')).toBeTruthy();
39
+ });
40
+ it('does not expand on other key presses', () => {
41
+ const { getByText, queryByText } = render(_jsx(DismissedSection, { count: 2, children: _jsx("span", { children: "other key content" }) }));
42
+ const button = getByText('Dismissed (2)').closest('[role="button"]');
43
+ fireEvent.keyDown(button, { key: 'Tab' });
44
+ expect(queryByText('other key content')).toBeNull();
45
+ });
28
46
  });
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { render } from '@testing-library/react';
3
- import { describe, expect, it } from 'vitest';
2
+ import { fireEvent, render } from '@testing-library/react';
3
+ import { describe, expect, it, vi } from 'vitest';
4
4
  import { EditorCard } from '../components/EditorCard';
5
5
  describe('EditorCard', () => {
6
6
  it('renders children', () => {
@@ -22,4 +22,63 @@ describe('EditorCard', () => {
22
22
  const card = container.firstElementChild;
23
23
  expect(card.className).toContain('se-border-border-primary');
24
24
  });
25
+ it('calls onClick when Enter key is pressed', () => {
26
+ const onClick = vi.fn();
27
+ const { container } = render(_jsx(EditorCard, { itemKey: "k", onClick: onClick, children: "child" }));
28
+ const card = container.firstElementChild;
29
+ fireEvent.keyDown(card, { key: 'Enter' });
30
+ expect(onClick).toHaveBeenCalledTimes(1);
31
+ });
32
+ it('calls onClick when Space key is pressed', () => {
33
+ const onClick = vi.fn();
34
+ const { container } = render(_jsx(EditorCard, { itemKey: "k", onClick: onClick, children: "child" }));
35
+ const card = container.firstElementChild;
36
+ fireEvent.keyDown(card, { key: ' ' });
37
+ expect(onClick).toHaveBeenCalledTimes(1);
38
+ });
39
+ it('does not call onClick on other key presses', () => {
40
+ const onClick = vi.fn();
41
+ const { container } = render(_jsx(EditorCard, { itemKey: "k", onClick: onClick, children: "child" }));
42
+ const card = container.firstElementChild;
43
+ fireEvent.keyDown(card, { key: 'Tab' });
44
+ expect(onClick).not.toHaveBeenCalled();
45
+ });
46
+ it('has role="button" and tabIndex when onClick is provided', () => {
47
+ const { container } = render(_jsx(EditorCard, { itemKey: "k", onClick: () => { }, children: "child" }));
48
+ const card = container.firstElementChild;
49
+ expect(card.getAttribute('role')).toBe('button');
50
+ expect(card.getAttribute('tabindex')).toBe('0');
51
+ });
52
+ it('does not have role or tabIndex when onClick is not provided', () => {
53
+ const { container } = render(_jsx(EditorCard, { itemKey: "k", children: "child" }));
54
+ const card = container.firstElementChild;
55
+ expect(card.getAttribute('role')).toBeNull();
56
+ expect(card.getAttribute('tabindex')).toBeNull();
57
+ });
58
+ it('applies cursor-pointer and hover classes when onClick is provided', () => {
59
+ const { container } = render(_jsx(EditorCard, { itemKey: "k", onClick: () => { }, children: "child" }));
60
+ const card = container.firstElementChild;
61
+ expect(card.className).toContain('se-cursor-pointer');
62
+ expect(card.className).toContain('hover:se-bg-sidebar-hover');
63
+ });
64
+ it('does not apply cursor-pointer when onClick is not provided', () => {
65
+ const { container } = render(_jsx(EditorCard, { itemKey: "k", children: "child" }));
66
+ const card = container.firstElementChild;
67
+ expect(card.className).not.toContain('se-cursor-pointer');
68
+ });
69
+ it('calls onMouseEnter and onMouseLeave', () => {
70
+ const onMouseEnter = vi.fn();
71
+ const onMouseLeave = vi.fn();
72
+ const { container } = render(_jsx(EditorCard, { itemKey: "k", onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, children: "child" }));
73
+ const card = container.firstElementChild;
74
+ fireEvent.mouseEnter(card);
75
+ expect(onMouseEnter).toHaveBeenCalledTimes(1);
76
+ fireEvent.mouseLeave(card);
77
+ expect(onMouseLeave).toHaveBeenCalledTimes(1);
78
+ });
79
+ it('merges custom className', () => {
80
+ const { container } = render(_jsx(EditorCard, { itemKey: "k", className: "custom-class", children: "child" }));
81
+ const card = container.firstElementChild;
82
+ expect(card.className).toContain('custom-class');
83
+ });
25
84
  });