@syntrologie/adapt-nav 2.2.0-canary.9 → 2.2.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.
Files changed (56) hide show
  1. package/dist/NavWidget.js +1 -1
  2. package/dist/cdn.d.ts.map +1 -1
  3. package/dist/editor.js +2 -2
  4. package/dist/runtime.d.ts.map +1 -1
  5. package/dist/runtime.js +20 -1
  6. package/dist/types.d.ts +2 -0
  7. package/dist/types.d.ts.map +1 -1
  8. package/node_modules/@syntro/design-system/dist/tailwind-preset.d.ts.map +1 -1
  9. package/node_modules/@syntro/design-system/dist/tailwind-preset.js +23 -2
  10. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/BeforeAfterToggle.test.js +1 -0
  11. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ConditionStatusLine.test.d.ts +2 -0
  12. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ConditionStatusLine.test.d.ts.map +1 -0
  13. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ConditionStatusLine.test.js +158 -0
  14. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DismissedSection.test.js +6 -0
  15. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorCard.test.js +1 -1
  16. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorHeader.test.js +4 -5
  17. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorPanelShell.test.d.ts +2 -0
  18. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorPanelShell.test.d.ts.map +1 -0
  19. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorPanelShell.test.js +25 -0
  20. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ElementHighlight.test.js +22 -0
  21. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/TriggerJourney.test.js +77 -14
  22. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/formatConditionLabel.test.js +1 -1
  23. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.d.ts +1 -2
  24. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.d.ts.map +1 -1
  25. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.js +4 -4
  26. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.d.ts.map +1 -1
  27. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.js +4 -4
  28. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.js +5 -5
  29. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSection.js +1 -1
  30. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.d.ts.map +1 -1
  31. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.js +1 -1
  32. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.d.ts.map +1 -1
  33. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.js +10 -1
  34. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.d.ts.map +1 -1
  35. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.js +1 -1
  36. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.d.ts +1 -1
  37. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.d.ts.map +1 -1
  38. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.js +5 -2
  39. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts.map +1 -1
  40. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.js +4 -4
  41. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.d.ts +1 -1
  42. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.d.ts.map +1 -1
  43. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.js +5 -2
  44. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.d.ts +1 -1
  45. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.d.ts.map +1 -1
  46. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.js +6 -4
  47. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.d.ts.map +1 -1
  48. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.js +24 -12
  49. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts.map +1 -1
  50. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.js +4 -4
  51. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts.map +1 -1
  52. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.js +12 -20
  53. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts +1 -1
  54. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts.map +1 -1
  55. package/node_modules/@syntrologie/shared-editor-ui/dist/index.js +1 -1
  56. package/package.json +1 -1
package/dist/NavWidget.js CHANGED
@@ -303,7 +303,7 @@ export function NavWidget({ config, runtime, instanceId }) {
303
303
  const hasCategories = useMemo(() => visibleTips.some((t) => t.config.category), [visibleTips]);
304
304
  // Resolve theme (auto → detect system preference)
305
305
  const resolvedTheme = useMemo(() => {
306
- if (config.theme !== 'auto')
306
+ if (config.theme && config.theme !== 'auto')
307
307
  return config.theme;
308
308
  if (typeof window !== 'undefined') {
309
309
  return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
package/dist/cdn.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,SAA0B,MAAM,UAAU,CAAC;AAGlD;;;GAGG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;2BAsC06Z,CAAC;8BAA8B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAtBp8Z,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;CAQjD,CAAC;AAaF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,SAA0B,MAAM,UAAU,CAAC;AAGlD;;;GAGG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;2BAsC07Z,CAAC;8BAA8B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAtBp9Z,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;CAQjD,CAAC;AAaF,eAAe,QAAQ,CAAC"}
package/dist/editor.js CHANGED
@@ -124,7 +124,7 @@ export function NavEditor({ config, onChange, editor }) {
124
124
  const typedConfig = config;
125
125
  const [dismissedKeys, setDismissedKeys] = useState(() => editor.getDismissedKeys?.() ?? new Set());
126
126
  const [editingKey, setEditingKey] = useState(null);
127
- const [previewMode, setPreviewMode] = useState('after');
127
+ const [_previewMode, setPreviewMode] = useState('after');
128
128
  const [_hoveredKey, setHoveredKey] = useState(null);
129
129
  // Sync dismissed keys back to navigation context on every change
130
130
  useEffect(() => {
@@ -209,7 +209,7 @@ export function NavEditor({ config, onChange, editor }) {
209
209
  editor.setBackHandler?.(editingKey !== null ? handleBackToList : null);
210
210
  return () => editor.setBackHandler?.(null);
211
211
  }, [editingKey, handleBackToList, editor]);
212
- const handleBeforeAfter = useCallback((mode) => {
212
+ const _handleBeforeAfter = useCallback((mode) => {
213
213
  setPreviewMode(mode);
214
214
  if (mode === 'before') {
215
215
  const filtered = filterConfig(typedConfig, new Set([editingKey]));
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,cAAc,EAEd,cAAc,EAEd,cAAc,EACf,MAAM,SAAS,CAAC;AAMjB;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,cAAc,CA4B1D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,cAAc,CAgC1D,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;EAGZ,CAAC;AAMX;;;;;;GAMG;AACH,eAAO,MAAM,OAAO;;;;;IAMlB;;OAEG;;;;;;;;IAGH;;OAEG;;;;;uBAqCs+T,CAAC;0BAA8B,CAAC;;;;;;;;;IAxBzgU;;;;OAIG;0BACmB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;CAgB9C,CAAC;AAEF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,cAAc,EAEd,cAAc,EAEd,cAAc,EACf,MAAM,SAAS,CAAC;AAMjB;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,cAAc,CA4B1D,CAAC;AAgBF;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,cAAc,CAoC1D,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;EAGZ,CAAC;AAMX;;;;;;GAMG;AACH,eAAO,MAAM,OAAO;;;;;IAMlB;;OAEG;;;;;;;;IAGH;;OAEG;;;;;uBAqCu1S,CAAC;0BAA8B,CAAC;;;;;;;;;IAxB13S;;;;OAIG;0BACmB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;CAgB9C,CAAC;AAEF,eAAe,OAAO,CAAC"}
package/dist/runtime.js CHANGED
@@ -35,6 +35,20 @@ export const executeScrollTo = async (action, context) => {
35
35
  },
36
36
  };
37
37
  };
38
+ /**
39
+ * Check if a URL is same-origin as the current page.
40
+ * Relative URLs (e.g. "/dashboard") are always same-origin.
41
+ */
42
+ function isSameOrigin(url) {
43
+ try {
44
+ const parsed = new URL(url, window.location.origin);
45
+ return parsed.origin === window.location.origin;
46
+ }
47
+ catch {
48
+ // If URL parsing fails, fall back to full navigation
49
+ return false;
50
+ }
51
+ }
38
52
  /**
39
53
  * Execute a navigate action
40
54
  */
@@ -55,8 +69,13 @@ export const executeNavigate = async (action, context) => {
55
69
  // Open in new tab
56
70
  window.open(url, '_blank', 'noopener,noreferrer');
57
71
  }
72
+ else if (!action.forceFullNavigation && isSameOrigin(url)) {
73
+ // SPA-aware: use pushState for same-origin URLs to avoid full page reload
74
+ window.history.pushState(null, '', url);
75
+ window.dispatchEvent(new PopStateEvent('popstate'));
76
+ }
58
77
  else {
59
- // Navigate in current tab
78
+ // Full navigation for cross-origin URLs or when explicitly requested
60
79
  window.location.href = url;
61
80
  }
62
81
  return {
package/dist/types.d.ts CHANGED
@@ -159,6 +159,8 @@ export interface NavigateAction extends BaseAction {
159
159
  kind: 'navigation:navigate';
160
160
  url: string;
161
161
  target?: '_self' | '_blank';
162
+ /** When true, always use full page navigation (window.location.href) even for same-origin URLs. */
163
+ forceFullNavigation?: boolean;
162
164
  }
163
165
  export declare const ACTION_NAMESPACES: readonly ["nav", "navigation"];
164
166
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tailwind-preset.d.ts","sourceRoot":"","sources":["../src/tailwind-preset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAI1C,eAAO,MAAM,YAAY,EAAE,OAAO,CAAC,MAAM,CA2bxC,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"tailwind-preset.d.ts","sourceRoot":"","sources":["../src/tailwind-preset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAI1C,eAAO,MAAM,YAAY,EAAE,OAAO,CAAC,MAAM,CAgdxC,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -147,29 +147,34 @@ export const syntroPreset = {
147
147
  DEFAULT: colors.pink[4],
148
148
  },
149
149
  // Semantic tokens
150
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
150
151
  text: {
151
152
  primary: colors.text.primary,
152
153
  secondary: colors.text.secondary,
153
154
  tertiary: colors.text.tertiary,
154
155
  DEFAULT: colors.text.primary,
155
156
  },
157
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
156
158
  background: {
157
159
  primary: colors.background.primary,
158
160
  secondary: colors.background.secondary,
159
161
  DEFAULT: colors.background.primary,
160
162
  },
163
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
161
164
  border: {
162
165
  primary: colors.border.primary,
163
166
  secondary: colors.border.secondary,
164
167
  DEFAULT: colors.border.primary,
165
168
  },
166
169
  // Component tokens - Button
170
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
167
171
  'btn-primary': {
168
172
  DEFAULT: colors.button.primary.backgroundDefault,
169
173
  hover: colors.button.primary.backgroundHover,
170
174
  text: colors.button.primary.text,
171
175
  border: colors.button.primary.border,
172
176
  },
177
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
173
178
  'btn-neutral': {
174
179
  DEFAULT: colors.button.neutral.background,
175
180
  text: colors.button.neutral.text,
@@ -189,12 +194,14 @@ export const syntroPreset = {
189
194
  hover: colors.button.success.hover,
190
195
  },
191
196
  // Component tokens - Card
197
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
192
198
  card: {
193
199
  bg: colors.card.background,
194
200
  content: colors.card.content,
195
201
  border: colors.card.border,
196
202
  },
197
203
  // Component tokens - Modal
204
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
198
205
  modal: {
199
206
  bg: colors.modal.background,
200
207
  content: colors.modal.content,
@@ -211,6 +218,7 @@ export const syntroPreset = {
211
218
  'content-tertiary': colors.sidebar.contentTertiary,
212
219
  },
213
220
  // Component tokens - Tab
221
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
214
222
  tab: {
215
223
  'active-bg': colors.tab.activeBackground,
216
224
  'active-content': colors.tab.activeContent,
@@ -218,15 +226,17 @@ export const syntroPreset = {
218
226
  border: colors.tab.border,
219
227
  },
220
228
  // Component tokens - Table
229
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
221
230
  'table-header': {
222
231
  text: colors.table.header.textDefault,
223
232
  'text-hover': colors.table.header.textHover,
224
233
  bg: colors.table.header.backgroundDefault,
225
234
  },
235
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
226
236
  'table-cell': {
227
- // biome-ignore lint/plugin: These define semantic token names, not usage of shadcn color classes
237
+ // biome-ignore lint: Tailwind preset defines semantic token names, not usage of shadcn color classes
228
238
  'text-primary': colors.table.cell.textPrimary,
229
- // biome-ignore lint/plugin: These define semantic token names, not usage of shadcn color classes
239
+ // biome-ignore lint: Tailwind preset defines semantic token names, not usage of shadcn color classes
230
240
  'text-secondary': colors.table.cell.textSecondary,
231
241
  bg: colors.table.cell.backgroundDefault,
232
242
  'bg-hover': colors.table.cell.backgroundHover,
@@ -245,54 +255,63 @@ export const syntroPreset = {
245
255
  'border-error': colors.inputField.borderError,
246
256
  },
247
257
  // Component tokens - Badge (9 variants)
258
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
248
259
  'badge-slate': {
249
260
  content: colors.badge.slateGrey.content,
250
261
  outline: colors.badge.slateGrey.pillOutline,
251
262
  border: colors.badge.slateGrey.borderPrimary,
252
263
  bg: colors.badge.slateGrey.background,
253
264
  },
265
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
254
266
  'badge-brand': {
255
267
  content: colors.badge.brand.content,
256
268
  outline: colors.badge.brand.pillOutline,
257
269
  border: colors.badge.brand.borderPrimary,
258
270
  bg: colors.badge.brand.background,
259
271
  },
272
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
260
273
  'badge-green': {
261
274
  content: colors.badge.green.content,
262
275
  outline: colors.badge.green.pillOutline,
263
276
  border: colors.badge.green.borderPrimary,
264
277
  bg: colors.badge.green.background,
265
278
  },
279
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
266
280
  'badge-yellow': {
267
281
  content: colors.badge.yellow.content,
268
282
  outline: colors.badge.yellow.pillOutline,
269
283
  border: colors.badge.yellow.borderPrimary,
270
284
  bg: colors.badge.yellow.background,
271
285
  },
286
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
272
287
  'badge-red': {
273
288
  content: colors.badge.red.content,
274
289
  outline: colors.badge.red.pillOutline,
275
290
  border: colors.badge.red.borderPrimary,
276
291
  bg: colors.badge.red.background,
277
292
  },
293
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
278
294
  'badge-blue': {
279
295
  content: colors.badge.blue.content,
280
296
  outline: colors.badge.blue.pillOutline,
281
297
  border: colors.badge.blue.borderPrimary,
282
298
  bg: colors.badge.blue.background,
283
299
  },
300
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
284
301
  'badge-purple': {
285
302
  content: colors.badge.purple.content,
286
303
  outline: colors.badge.purple.pillOutline,
287
304
  border: colors.badge.purple.borderPrimary,
288
305
  bg: colors.badge.purple.background,
289
306
  },
307
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
290
308
  'badge-orange': {
291
309
  content: colors.badge.orange.content,
292
310
  outline: colors.badge.orange.pillOutline,
293
311
  border: colors.badge.orange.borderPrimary,
294
312
  bg: colors.badge.orange.background,
295
313
  },
314
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
296
315
  'badge-pink': {
297
316
  content: colors.badge.pink.content,
298
317
  outline: colors.badge.pink.pillOutline,
@@ -309,6 +328,7 @@ export const syntroPreset = {
309
328
  'on-bg-hover': colors.toggle.on.backgroundHover,
310
329
  },
311
330
  // Component tokens - Menu
331
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
312
332
  menu: {
313
333
  DEFAULT: colors.menu.backgroundDefault,
314
334
  hover: colors.menu.backgroundHover,
@@ -380,6 +400,7 @@ export const syntroPreset = {
380
400
  'focus-error': focusRings.error,
381
401
  },
382
402
  // Backdrop blur — Figma scale
403
+ // biome-ignore lint: Tailwind preset intentionally maps design tokens from source
383
404
  backdropBlur: {
384
405
  sm: backdropBlur.sm,
385
406
  md: backdropBlur.md,
@@ -23,6 +23,7 @@ describe('BeforeAfterToggle', () => {
23
23
  it('highlights active mode with blue class', () => {
24
24
  const { getByText } = render(_jsx(BeforeAfterToggle, { mode: "before", onToggle: () => { } }));
25
25
  expect(getByText('Before').className).toContain('se-text-blue-5');
26
+ expect(getByText('Before').className).toContain('se-bg-blue-5/30');
26
27
  expect(getByText('After').className).toContain('se-text-text-secondary');
27
28
  });
28
29
  });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ConditionStatusLine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConditionStatusLine.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ConditionStatusLine.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,158 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { fireEvent, render, screen } from '@testing-library/react';
3
+ import { describe, expect, it } from 'vitest';
4
+ import { ConditionStatusLine } from '../components/ConditionStatusLine';
5
+ describe('ConditionStatusLine', () => {
6
+ it('returns null when status is null', () => {
7
+ const { container } = render(_jsx(ConditionStatusLine, { status: null }));
8
+ expect(container.innerHTML).toBe('');
9
+ });
10
+ it('renders single condition inline', () => {
11
+ const status = {
12
+ visible: true,
13
+ isFallback: false,
14
+ conditions: [
15
+ {
16
+ type: 'page_url',
17
+ passed: true,
18
+ formatted: { label: '/pricing', instruction: 'Visit /pricing', shortLabel: '/pricing' },
19
+ },
20
+ ],
21
+ };
22
+ render(_jsx(ConditionStatusLine, { status: status }));
23
+ expect(screen.getByText('page_url:')).toBeTruthy();
24
+ expect(screen.getByText('/pricing')).toBeTruthy();
25
+ });
26
+ it('uses at least 12px font size for condition rows', () => {
27
+ const status = {
28
+ visible: true,
29
+ isFallback: false,
30
+ conditions: [
31
+ {
32
+ type: 'page_url',
33
+ passed: true,
34
+ formatted: { label: '/pricing', instruction: 'Visit /pricing', shortLabel: '/pricing' },
35
+ },
36
+ ],
37
+ };
38
+ const { container } = render(_jsx(ConditionStatusLine, { status: status }));
39
+ const row = container.firstElementChild;
40
+ expect(row.className).toContain('se-text-[12px]');
41
+ expect(row.className).not.toContain('se-text-[10px]');
42
+ });
43
+ it('uses secondary text color for readability', () => {
44
+ const status = {
45
+ visible: true,
46
+ isFallback: false,
47
+ conditions: [
48
+ {
49
+ type: 'page_url',
50
+ passed: true,
51
+ formatted: { label: '/pricing', instruction: 'Visit /pricing', shortLabel: '/pricing' },
52
+ },
53
+ ],
54
+ };
55
+ const { container } = render(_jsx(ConditionStatusLine, { status: status }));
56
+ const row = container.firstElementChild;
57
+ expect(row.className).toContain('se-text-text-secondary');
58
+ });
59
+ it('uses medium font weight for small text', () => {
60
+ const status = {
61
+ visible: true,
62
+ isFallback: false,
63
+ conditions: [
64
+ {
65
+ type: 'page_url',
66
+ passed: true,
67
+ formatted: { label: '/pricing', instruction: 'Visit /pricing', shortLabel: '/pricing' },
68
+ },
69
+ ],
70
+ };
71
+ const { container } = render(_jsx(ConditionStatusLine, { status: status }));
72
+ const row = container.firstElementChild;
73
+ expect(row.className).toContain('se-font-medium');
74
+ });
75
+ it('renders multi-condition summary with expand button', () => {
76
+ const status = {
77
+ visible: false,
78
+ isFallback: false,
79
+ conditions: [
80
+ {
81
+ type: 'page_url',
82
+ passed: true,
83
+ formatted: { label: '/p', instruction: 'A', shortLabel: 'A' },
84
+ },
85
+ {
86
+ type: 'event_count',
87
+ passed: false,
88
+ formatted: { label: 'views >= 2', instruction: 'B', shortLabel: 'B' },
89
+ },
90
+ ],
91
+ };
92
+ render(_jsx(ConditionStatusLine, { status: status }));
93
+ expect(screen.getByText('1 of 2 conditions met')).toBeTruthy();
94
+ });
95
+ it('uses at least 11px for expand indicator', () => {
96
+ const status = {
97
+ visible: false,
98
+ isFallback: false,
99
+ conditions: [
100
+ {
101
+ type: 'a',
102
+ passed: true,
103
+ formatted: { label: 'a', instruction: 'A', shortLabel: 'A' },
104
+ },
105
+ {
106
+ type: 'b',
107
+ passed: false,
108
+ formatted: { label: 'b', instruction: 'B', shortLabel: 'B' },
109
+ },
110
+ ],
111
+ };
112
+ const { container } = render(_jsx(ConditionStatusLine, { status: status }));
113
+ // The expand indicator is the last span in the button
114
+ const button = container.querySelector('button');
115
+ const indicator = button.querySelector('span:last-child');
116
+ expect(indicator.className).toContain('se-text-[11px]');
117
+ expect(indicator.className).not.toContain('se-text-[8px]');
118
+ });
119
+ it('expands to show individual condition rows on click', () => {
120
+ const status = {
121
+ visible: false,
122
+ isFallback: false,
123
+ conditions: [
124
+ {
125
+ type: 'page_url',
126
+ passed: true,
127
+ formatted: { label: '/p', instruction: 'A', shortLabel: 'A' },
128
+ },
129
+ {
130
+ type: 'event_count',
131
+ passed: false,
132
+ formatted: { label: 'views >= 2', instruction: 'B', shortLabel: 'B' },
133
+ },
134
+ ],
135
+ };
136
+ render(_jsx(ConditionStatusLine, { status: status }));
137
+ fireEvent.click(screen.getByText('1 of 2 conditions met'));
138
+ expect(screen.getByText('page_url:')).toBeTruthy();
139
+ expect(screen.getByText('event_count:')).toBeTruthy();
140
+ });
141
+ it('uses secondary color (not tertiary) for condition detail labels', () => {
142
+ const status = {
143
+ visible: true,
144
+ isFallback: false,
145
+ conditions: [
146
+ {
147
+ type: 'page_url',
148
+ passed: true,
149
+ formatted: { label: '/pricing', instruction: 'Visit /pricing', shortLabel: '/pricing' },
150
+ },
151
+ ],
152
+ };
153
+ render(_jsx(ConditionStatusLine, { status: status }));
154
+ const label = screen.getByText('/pricing');
155
+ expect(label.className).toContain('se-text-text-secondary');
156
+ expect(label.className).not.toContain('se-text-text-tertiary');
157
+ });
158
+ });
@@ -12,6 +12,12 @@ describe('DismissedSection', () => {
12
12
  fireEvent.click(getByText('Dismissed (2)'));
13
13
  expect(queryByText('revealed')).toBeTruthy();
14
14
  });
15
+ it('uses secondary text color for readability', () => {
16
+ const { getByText } = render(_jsx(DismissedSection, { count: 2, children: _jsx("span", { children: "child" }) }));
17
+ const button = getByText('Dismissed (2)').closest('[role="button"]');
18
+ expect(button.className).toContain('se-text-text-secondary');
19
+ expect(button.className).not.toContain('se-text-text-tertiary');
20
+ });
15
21
  it('collapses again on second click', () => {
16
22
  const { getByText, queryByText } = render(_jsx(DismissedSection, { count: 1, children: _jsx("span", { children: "content" }) }));
17
23
  fireEvent.click(getByText('Dismissed (1)'));
@@ -15,7 +15,7 @@ describe('EditorCard', () => {
15
15
  it('applies green border class when validated is true', () => {
16
16
  const { container } = render(_jsx(EditorCard, { itemKey: "k", validated: true, children: "child" }));
17
17
  const card = container.firstElementChild;
18
- expect(card.className).toContain('se-border-green-4/40');
18
+ expect(card.className).toContain('se-border-green-4/50');
19
19
  });
20
20
  it('applies default border class when validated is false', () => {
21
21
  const { container } = render(_jsx(EditorCard, { itemKey: "k", validated: false, children: "child" }));
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { fireEvent, render } from '@testing-library/react';
2
+ import { render } from '@testing-library/react';
3
3
  import { describe, expect, it, vi } from 'vitest';
4
4
  import { EditorHeader } from '../components/EditorHeader';
5
5
  describe('EditorHeader', () => {
@@ -15,10 +15,9 @@ describe('EditorHeader', () => {
15
15
  const { queryByText } = render(_jsx(EditorHeader, { title: "T", onBack: () => { } }));
16
16
  expect(queryByText('Sub')).toBeNull();
17
17
  });
18
- it('calls onBack when back button is clicked', () => {
18
+ it('accepts deprecated onBack prop without rendering a back button', () => {
19
19
  const onBack = vi.fn();
20
- const { getByText } = render(_jsx(EditorHeader, { title: "T", onBack: onBack }));
21
- fireEvent.click(getByText('← Back'));
22
- expect(onBack).toHaveBeenCalledOnce();
20
+ const { queryByText } = render(_jsx(EditorHeader, { title: "T", onBack: onBack }));
21
+ expect(queryByText('← Back')).toBeNull();
23
22
  });
24
23
  });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=EditorPanelShell.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditorPanelShell.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/EditorPanelShell.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render } from '@testing-library/react';
3
+ import { describe, expect, it, vi } from 'vitest';
4
+ import { EditorPanelShell } from '../components/EditorPanelShell';
5
+ // Mock ResizeObserver and pointer capture for jsdom
6
+ vi.stubGlobal('ResizeObserver', class {
7
+ observe() { }
8
+ unobserve() { }
9
+ disconnect() { }
10
+ });
11
+ Element.prototype.setPointerCapture = vi.fn();
12
+ Element.prototype.releasePointerCapture = vi.fn();
13
+ describe('EditorPanelShell', () => {
14
+ it('applies antialiased font smoothing to the panel', () => {
15
+ const { container } = render(_jsx(EditorPanelShell, { isOpen: true, onToggle: () => { }, position: "right", children: _jsx("div", { children: "Content" }) }));
16
+ const panel = container.querySelector('[data-syntro-editor-panel]');
17
+ expect(panel).toBeTruthy();
18
+ expect(panel.className).toContain('se-antialiased');
19
+ });
20
+ it('does not render panel when closed', () => {
21
+ const { container } = render(_jsx(EditorPanelShell, { isOpen: false, onToggle: () => { }, children: _jsx("div", { children: "Content" }) }));
22
+ const panel = container.querySelector('[data-syntro-editor-panel]');
23
+ expect(panel).toBeNull();
24
+ });
25
+ });
@@ -92,6 +92,28 @@ describe('ElementHighlight', () => {
92
92
  expect(label.textContent).toContain('300');
93
93
  expect(label.textContent).toContain('150');
94
94
  });
95
+ it('uses at least 11px font for highlight labels', () => {
96
+ render(_jsx(ElementHighlight, { element: mockElement, color: "rgba(99,102,241,0.6)", showDimensions: true }));
97
+ const label = document.body.querySelector('[data-syntro-highlight-label]');
98
+ expect(label).toBeTruthy();
99
+ // showDimensions uses the smaller size (11px); non-dimensions uses 12px
100
+ expect(label.style.fontSize).toBe('11px');
101
+ });
102
+ it('uses 12px font for non-dimensions labels', () => {
103
+ render(_jsx(ElementHighlight, { element: mockElement, color: "#ef4444", label: "Test Label" }));
104
+ const label = document.body.querySelector('[data-syntro-highlight-label]');
105
+ expect(label).toBeTruthy();
106
+ expect(label.style.fontSize).toBe('12px');
107
+ });
108
+ it('uses 12px font for remove button', () => {
109
+ const onRemove = vi.fn();
110
+ render(_jsx(ElementHighlight, { element: mockElement, color: "#ef4444", label: "Test", showRemove: true, onRemove: onRemove }));
111
+ const removeBtn = document.body.querySelector('[data-syntro-highlight-remove]');
112
+ expect(removeBtn).toBeTruthy();
113
+ expect(removeBtn.style.fontSize).toBe('12px');
114
+ expect(removeBtn.style.width).toBe('16px');
115
+ expect(removeBtn.style.height).toBe('16px');
116
+ });
95
117
  it('does not show remove button when showRemove is false', () => {
96
118
  render(_jsx(ElementHighlight, { element: mockElement, color: "#3b82f6", label: "Test" }));
97
119
  const removeBtn = document.body.querySelector('[data-syntro-highlight-remove]');