@syntrologie/adapt-content 2.1.0 → 2.2.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.
Files changed (148) hide show
  1. package/dist/cdn.d.ts +1 -1
  2. package/dist/components/AnchorPicker.d.ts +5 -20
  3. package/dist/components/AnchorPicker.d.ts.map +1 -1
  4. package/dist/components/AnchorPicker.js +4 -181
  5. package/dist/editor.d.ts.map +1 -1
  6. package/dist/editor.js +51 -27
  7. package/dist/runtime.d.ts +1 -1
  8. package/dist/runtime.d.ts.map +1 -1
  9. package/dist/schema.d.ts +28 -28
  10. package/dist/types.d.ts +5 -15
  11. package/dist/types.d.ts.map +1 -1
  12. package/dist/utils/selectorGenerator.d.ts +3 -19
  13. package/dist/utils/selectorGenerator.d.ts.map +1 -1
  14. package/dist/utils/selectorGenerator.js +2 -119
  15. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/BeforeAfterToggle.test.d.ts +2 -0
  16. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/BeforeAfterToggle.test.d.ts.map +1 -0
  17. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/BeforeAfterToggle.test.js +28 -0
  18. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DetectionBadge.test.d.ts +2 -0
  19. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DetectionBadge.test.d.ts.map +1 -0
  20. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DetectionBadge.test.js +18 -0
  21. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DismissedSection.test.d.ts +2 -0
  22. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DismissedSection.test.d.ts.map +1 -0
  23. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DismissedSection.test.js +22 -0
  24. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditBackButton.test.d.ts +2 -0
  25. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditBackButton.test.d.ts.map +1 -0
  26. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditBackButton.test.js +20 -0
  27. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorBody.test.d.ts +2 -0
  28. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorBody.test.d.ts.map +1 -0
  29. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorBody.test.js +12 -0
  30. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorCard.test.d.ts +2 -0
  31. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorCard.test.d.ts.map +1 -0
  32. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorCard.test.js +25 -0
  33. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorFooter.test.d.ts +2 -0
  34. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorFooter.test.d.ts.map +1 -0
  35. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorFooter.test.js +23 -0
  36. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorHeader.test.d.ts +2 -0
  37. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorHeader.test.d.ts.map +1 -0
  38. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorHeader.test.js +24 -0
  39. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorInput.test.d.ts +2 -0
  40. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorInput.test.d.ts.map +1 -0
  41. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorInput.test.js +26 -0
  42. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorLayout.test.d.ts +2 -0
  43. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorLayout.test.d.ts.map +1 -0
  44. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorLayout.test.js +13 -0
  45. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorSelect.test.d.ts +2 -0
  46. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorSelect.test.d.ts.map +1 -0
  47. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorSelect.test.js +22 -0
  48. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorTextarea.test.d.ts +2 -0
  49. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorTextarea.test.d.ts.map +1 -0
  50. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorTextarea.test.js +20 -0
  51. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ElementHighlight.test.d.ts +2 -0
  52. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ElementHighlight.test.d.ts.map +1 -0
  53. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ElementHighlight.test.js +100 -0
  54. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EmptyState.test.d.ts +2 -0
  55. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EmptyState.test.d.ts.map +1 -0
  56. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EmptyState.test.js +10 -0
  57. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/GroupHeader.test.d.ts +2 -0
  58. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/GroupHeader.test.d.ts.map +1 -0
  59. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/GroupHeader.test.js +14 -0
  60. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/TriggerJourney.test.d.ts +2 -0
  61. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/TriggerJourney.test.d.ts.map +1 -0
  62. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/TriggerJourney.test.js +126 -0
  63. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/cn.test.d.ts +2 -0
  64. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/cn.test.d.ts.map +1 -0
  65. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/cn.test.js +16 -0
  66. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/formatConditionLabel.test.d.ts +2 -0
  67. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/formatConditionLabel.test.d.ts.map +1 -0
  68. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/formatConditionLabel.test.js +329 -0
  69. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useElementRect.test.d.ts +2 -0
  70. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useElementRect.test.d.ts.map +1 -0
  71. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useElementRect.test.js +112 -0
  72. package/node_modules/@syntrologie/shared-editor-ui/dist/cn.d.ts +2 -0
  73. package/node_modules/@syntrologie/shared-editor-ui/dist/cn.d.ts.map +1 -0
  74. package/node_modules/@syntrologie/shared-editor-ui/dist/cn.js +3 -0
  75. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.d.ts +31 -0
  76. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.d.ts.map +1 -0
  77. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.js +152 -0
  78. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.d.ts +7 -0
  79. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.d.ts.map +1 -0
  80. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.js +9 -0
  81. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts +23 -0
  82. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts.map +1 -0
  83. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.js +40 -0
  84. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts +6 -0
  85. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts.map +1 -0
  86. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.js +5 -0
  87. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSection.d.ts +8 -0
  88. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSection.d.ts.map +1 -0
  89. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSection.js +9 -0
  90. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.d.ts +7 -0
  91. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.d.ts.map +1 -0
  92. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.js +4 -0
  93. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBody.d.ts +7 -0
  94. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBody.d.ts.map +1 -0
  95. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBody.js +4 -0
  96. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.d.ts +13 -0
  97. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.d.ts.map +1 -0
  98. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.js +6 -0
  99. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.d.ts +7 -0
  100. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.d.ts.map +1 -0
  101. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.js +4 -0
  102. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeader.d.ts +9 -0
  103. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeader.d.ts.map +1 -0
  104. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeader.js +4 -0
  105. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.d.ts +8 -0
  106. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.d.ts.map +1 -0
  107. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.js +5 -0
  108. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayout.d.ts +7 -0
  109. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayout.d.ts.map +1 -0
  110. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayout.js +4 -0
  111. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts +23 -0
  112. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts.map +1 -0
  113. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.js +116 -0
  114. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.d.ts +8 -0
  115. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.d.ts.map +1 -0
  116. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.js +5 -0
  117. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.d.ts +8 -0
  118. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.d.ts.map +1 -0
  119. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.js +15 -0
  120. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.d.ts +32 -0
  121. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.d.ts.map +1 -0
  122. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.js +75 -0
  123. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyState.d.ts +6 -0
  124. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyState.d.ts.map +1 -0
  125. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyState.js +4 -0
  126. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeader.d.ts +8 -0
  127. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeader.d.ts.map +1 -0
  128. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeader.js +5 -0
  129. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts +12 -0
  130. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts.map +1 -0
  131. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.js +40 -0
  132. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts +26 -0
  133. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts.map +1 -0
  134. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.js +207 -0
  135. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useElementRect.d.ts +8 -0
  136. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useElementRect.d.ts.map +1 -0
  137. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useElementRect.js +46 -0
  138. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useShowWhenStatus.d.ts +24 -0
  139. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useShowWhenStatus.d.ts.map +1 -0
  140. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useShowWhenStatus.js +215 -0
  141. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts +33 -0
  142. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts.map +1 -0
  143. package/node_modules/@syntrologie/shared-editor-ui/dist/index.js +24 -0
  144. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/selectorGenerator.d.ts +22 -0
  145. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/selectorGenerator.d.ts.map +1 -0
  146. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/selectorGenerator.js +143 -0
  147. package/node_modules/@syntrologie/shared-editor-ui/package.json +45 -0
  148. package/package.json +17 -12
@@ -0,0 +1,116 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState } from 'react';
3
+ import { createPortal } from 'react-dom';
4
+ import { cn } from '../cn';
5
+ // =============================================================================
6
+ // Logo
7
+ // =============================================================================
8
+ /**
9
+ * Syntrologie logo mark — from Figma design system.
10
+ * Rendered as inline SVG to avoid CSP issues with data: URIs on injected pages.
11
+ */
12
+ function SyntroLogo() {
13
+ return (_jsxs("svg", { width: "28", height: "18", viewBox: "0 0 101 63", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("g", { clipPath: "url(#syntro-fab-clip)", children: _jsx("path", { d: "M51.989 0.284C52.386 0.29 52.808 0.341 53.192 0.443C53.769 0.596 54.362 0.983 54.745 1.442C55.895 2.822 56.767 4.782 57.669 6.357C59.947 10.334 62.152 14.372 64.498 18.307C64.671 18.597 65.127 19.343 65.475 19.411C66.654 19.641 79.278 11.523 81.123 10.317C80.704 8.6 80.624 7.21 81.334 5.525C82.014 3.916 83.317 2.651 84.946 2.019C86.593 1.366 88.286 1.42 89.902 2.123C91.486 2.795 92.733 4.076 93.363 5.677C95.111 10.218 91.347 15.013 86.561 14.442C85.392 14.302 84.649 13.927 83.6 13.441C76.542 18.247 69.094 22.597 61.207 25.907C60.153 26.349 59.42 26.6 58.519 27.328C60.583 27.43 87.034 24.236 87.878 23.781C87.926 23.755 88.048 23.697 88.08 23.652C88.244 23.421 88.277 23.007 88.376 22.735C88.819 21.511 89.563 20.379 90.604 19.586C91.887 18.608 93.6 18.093 95.208 18.324C96.992 18.581 98.67 19.55 99.74 21.005C100.733 22.364 101.141 24.064 100.875 25.726C100.607 27.394 99.692 28.888 98.329 29.887C96.02 31.573 92.641 31.613 90.392 29.789C89.579 29.13 89.177 28.535 88.566 27.692C86.692 28.103 83.447 28.463 81.472 28.73C76.577 29.399 71.671 29.99 66.756 30.504C65.752 30.608 59.279 31.013 58.779 31.24L58.781 31.387C59.106 31.577 66.974 33.025 68.328 33.358C72.475 34.405 76.572 35.64 80.606 37.06C82.709 37.818 84.721 38.686 86.814 39.457C88.505 38.051 89.243 36.875 91.925 36.841C93.665 36.833 95.339 37.506 96.589 38.717C97.986 40.087 98.415 41.541 98.429 43.422C98.417 44.842 98.099 45.978 97.229 47.137C96.168 48.531 94.597 49.447 92.86 49.682C91.161 49.922 89.437 49.472 88.073 48.431C86.201 47.02 85.795 45.462 85.488 43.323C85.255 43.193 85.018 43.071 84.776 42.958C83.907 42.553 78.511 40.359 77.911 40.577C77.837 41.147 78.926 42.592 79.243 43.155L84.336 52.073C85.165 53.529 86.027 54.991 86.789 56.483C87.253 57.391 87.414 58.355 87.056 59.343C86.557 60.722 85.014 61.408 83.626 61.438C81.429 61.427 79.228 61.427 77.029 61.427L62.967 61.427L35.549 61.435C33.337 61.436 20.693 61.626 19.579 61.199C18.758 60.889 18.093 60.265 17.732 59.465C17.455 58.844 17.335 57.994 17.577 57.361C18.242 55.623 19.5 53.659 20.438 52.043L28.119 39.028C28.9 37.701 31.213 33.891 31.7 32.634C25.671 32.936 18.736 32.547 12.6 32.721C11.75 34.138 10.992 35.281 9.368 35.935C7.744 36.588 5.704 36.604 4.097 35.922C2.546 35.272 1.319 34.028 0.69 32.468C0.053 30.839 0.086 29.025 0.781 27.42C2.812 22.739 9.259 22.202 12.05 26.464C12.555 27.235 12.774 27.84 13.104 28.703L26.462 28.711C28.926 28.713 31.729 28.779 34.17 28.668C35.279 26.892 36.442 24.733 37.515 22.901L45.376 9.375C46.797 6.902 48.214 4.368 49.685 1.924C50.222 1.032 50.962 0.493 51.989 0.284ZM22.119 57.31C23.512 57.503 26.045 57.431 27.526 57.429L36.661 57.42L68.412 57.422C73.113 57.421 77.994 57.351 82.68 57.438L75.664 45.098C74.562 43.171 73.093 40.773 72.104 38.827C71.245 38.351 70.291 38.109 69.335 37.848C59.189 35.076 48.669 33.421 38.172 32.796C37.642 32.764 36.994 32.766 36.469 32.794L25.855 50.865C24.634 52.935 23.364 55.302 22.119 57.31ZM52.216 5.513C49.384 10.611 46.473 15.665 43.484 20.673C42.193 22.878 40.862 25.071 39.63 27.31C39.46 27.618 39.36 27.782 39.453 28.133C40.522 28.342 45.866 26.973 47.112 26.644C49.169 26.137 60.135 22.684 61.174 21.436C61.248 21.163 61.287 21.069 61.125 20.762C60.279 19.163 59.326 17.527 58.435 15.958L53.592 7.329C53.355 6.915 52.677 5.599 52.216 5.513ZM96.18 26.494C96.963 25.713 97.12 24.502 96.563 23.547C96.005 22.592 94.872 22.133 93.807 22.432C92.972 22.666 92.324 23.327 92.108 24.167C91.892 25.007 92.14 25.899 92.758 26.507C93.396 27.134 94.327 27.361 95.182 27.096C95.558 26.98 95.901 26.773 96.18 26.494ZM87.871 10.399C89.147 10.087 89.941 8.813 89.659 7.529C89.377 6.246 88.122 5.422 86.832 5.673C85.97 5.841 85.266 6.463 84.994 7.298C84.722 8.133 84.923 9.05 85.52 9.694C86.118 10.339 87.017 10.608 87.871 10.399ZM91.505 40.879C90.185 41.122 89.31 42.388 89.55 43.709C89.791 45.03 91.055 45.907 92.377 45.669C93.22 45.517 93.921 44.933 94.223 44.131C94.525 43.329 94.383 42.428 93.85 41.758C93.29 41.055 92.389 40.717 91.505 40.879ZM9.138 29.557C9.005 28.88 8.592 28.292 8.001 27.937C7.409 27.583 6.696 27.495 6.036 27.697C5.665 27.81 5.326 28.011 5.048 28.282C4.24 29.07 4.079 30.31 4.66 31.278C5.241 32.247 6.411 32.688 7.487 32.346C8.666 31.97 9.376 30.771 9.138 29.557Z", fill: "currentColor" }) }), _jsx("defs", { children: _jsx("clipPath", { id: "syntro-fab-clip", children: _jsx("rect", { width: "101", height: "63", fill: "white" }) }) })] }));
14
+ }
15
+ // =============================================================================
16
+ // Draggable FAB
17
+ // =============================================================================
18
+ const FAB_SIZE = 56;
19
+ const DRAG_THRESHOLD = 5; // px movement before we consider it a drag
20
+ function DraggableFab({ isOpen, onToggle, initialRight, zIndex, portalTarget }) {
21
+ // Position state — bottom-right or bottom-left by default
22
+ const [pos, setPos] = useState({
23
+ x: initialRight ? window.innerWidth - FAB_SIZE - 40 : 40,
24
+ y: window.innerHeight - FAB_SIZE - 40,
25
+ });
26
+ // Drag tracking refs (non-reactive for perf)
27
+ const dragging = useRef(false);
28
+ const hasMoved = useRef(false);
29
+ const offset = useRef({ x: 0, y: 0 });
30
+ const posRef = useRef(pos);
31
+ posRef.current = pos;
32
+ // Keep FAB within viewport on resize
33
+ useEffect(() => {
34
+ const handleResize = () => {
35
+ setPos((prev) => ({
36
+ x: Math.min(prev.x, window.innerWidth - FAB_SIZE),
37
+ y: Math.min(prev.y, window.innerHeight - FAB_SIZE),
38
+ }));
39
+ };
40
+ window.addEventListener('resize', handleResize);
41
+ return () => window.removeEventListener('resize', handleResize);
42
+ }, []);
43
+ const handlePointerDown = useCallback((e) => {
44
+ dragging.current = true;
45
+ hasMoved.current = false;
46
+ offset.current = {
47
+ x: e.clientX - posRef.current.x,
48
+ y: e.clientY - posRef.current.y,
49
+ };
50
+ e.target.setPointerCapture(e.pointerId);
51
+ e.preventDefault();
52
+ }, []);
53
+ const handlePointerMove = useCallback((e) => {
54
+ if (!dragging.current)
55
+ return;
56
+ const newX = e.clientX - offset.current.x;
57
+ const newY = e.clientY - offset.current.y;
58
+ // Check if we've moved past the threshold
59
+ const dx = Math.abs(newX - posRef.current.x);
60
+ const dy = Math.abs(newY - posRef.current.y);
61
+ if (!hasMoved.current && dx < DRAG_THRESHOLD && dy < DRAG_THRESHOLD)
62
+ return;
63
+ hasMoved.current = true;
64
+ setPos({
65
+ x: Math.max(0, Math.min(newX, window.innerWidth - FAB_SIZE)),
66
+ y: Math.max(0, Math.min(newY, window.innerHeight - FAB_SIZE)),
67
+ });
68
+ }, []);
69
+ const handlePointerUp = useCallback((e) => {
70
+ e.target.releasePointerCapture(e.pointerId);
71
+ const wasDragging = hasMoved.current;
72
+ dragging.current = false;
73
+ hasMoved.current = false;
74
+ // Only toggle if it was a click, not a drag
75
+ if (!wasDragging) {
76
+ onToggle();
77
+ }
78
+ }, [onToggle]);
79
+ return createPortal(_jsx("div", { className: "syntro-editor-scope", style: { display: 'contents' }, children: _jsx("button", { "data-syntro-fab": true, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, style: {
80
+ position: 'fixed',
81
+ left: pos.x,
82
+ top: pos.y,
83
+ zIndex,
84
+ width: FAB_SIZE,
85
+ height: FAB_SIZE,
86
+ borderRadius: '50%',
87
+ border: '2px solid #b72e2a',
88
+ cursor: dragging.current ? 'grabbing' : 'grab',
89
+ display: 'flex',
90
+ alignItems: 'center',
91
+ justifyContent: 'center',
92
+ background: '#000000',
93
+ color: '#ffffff',
94
+ boxShadow: isOpen
95
+ ? '0 4px 24px rgba(0,0,0,0.6), 0 0 0 2px rgba(255,255,255,0.08)'
96
+ : '0 4px 24px rgba(0,0,0,0.6)',
97
+ transition: 'box-shadow 150ms ease',
98
+ touchAction: 'none',
99
+ userSelect: 'none',
100
+ WebkitUserSelect: 'none',
101
+ }, title: isOpen ? 'Close panel' : 'Open panel', children: _jsx(SyntroLogo, {}) }) }), portalTarget);
102
+ }
103
+ // =============================================================================
104
+ // Component
105
+ // =============================================================================
106
+ export function EditorPanelShell({ isOpen, onToggle, position = 'right', panelId, zIndex = 2147483647, portalTarget, children, }) {
107
+ const isRight = position === 'right';
108
+ const resolvedPortalTarget = portalTarget ?? (typeof document !== 'undefined' ? document.body : null);
109
+ return (_jsxs(_Fragment, { children: [resolvedPortalTarget && (_jsx(DraggableFab, { isOpen: isOpen, onToggle: onToggle, initialRight: isRight, zIndex: zIndex + 1, portalTarget: resolvedPortalTarget })), isOpen && (_jsx("div", { ...(panelId ? { id: panelId } : {}), "data-syntro-editor-panel": true, className: cn('syntro-editor-scope se-fixed se-top-0 se-w-[390px] se-h-screen se-flex se-flex-col se-text-text-primary se-backdrop-blur-xl se-font-sans', isRight
110
+ ? 'se-right-0 se-border-l se-border-border-primary'
111
+ : 'se-left-0 se-border-r se-border-border-primary'), style: {
112
+ zIndex,
113
+ background: 'linear-gradient(160deg, rgba(7,8,10,0.78) 0%, rgba(14,17,20,0.82) 45%, rgba(15,19,24,0.78) 100%)',
114
+ boxShadow: isRight ? '-20px 0 60px rgba(0,0,0,0.5)' : '20px 0 60px rgba(0,0,0,0.5)',
115
+ }, children: children }))] }));
116
+ }
@@ -0,0 +1,8 @@
1
+ import type React from 'react';
2
+ interface EditorSelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
3
+ label?: string;
4
+ className?: string;
5
+ }
6
+ export declare function EditorSelect({ label, className, children, ...props }: EditorSelectProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=EditorSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditorSelect.d.ts","sourceRoot":"","sources":["../../src/components/EditorSelect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,UAAU,iBAAkB,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,2CAqBvF"}
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../cn';
3
+ export function EditorSelect({ label, className, children, ...props }) {
4
+ return (_jsxs("div", { children: [label && (_jsx("label", { className: "se-text-sm se-font-medium se-text-input-field-text-label se-mb-1 se-block", children: label })), _jsx("select", { ...props, className: cn('se-w-full se-py-2 se-px-3 se-rounded-lg se-border se-border-input-field-border se-bg-slate-grey-3 se-text-text-primary se-text-sm se-mb-2', 'focus:se-border-input-field-border-selected focus:se-outline-none focus:se-shadow-focus-primary', 'disabled:se-bg-input-field-bg-disabled disabled:se-cursor-not-allowed disabled:se-opacity-50', className), children: children })] }));
5
+ }
@@ -0,0 +1,8 @@
1
+ import type React from 'react';
2
+ interface EditorTextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
3
+ label?: string;
4
+ className?: string;
5
+ }
6
+ export declare function EditorTextarea({ label, className, value, ...props }: EditorTextareaProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=EditorTextarea.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditorTextarea.d.ts","sourceRoot":"","sources":["../../src/components/EditorTextarea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,UAAU,mBAAoB,SAAQ,KAAK,CAAC,sBAAsB,CAAC,mBAAmB,CAAC;IACrF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,2CAgCxF"}
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from 'react';
3
+ import { cn } from '../cn';
4
+ export function EditorTextarea({ label, className, value, ...props }) {
5
+ const ref = useRef(null);
6
+ // Auto-resize to fit content
7
+ useEffect(() => {
8
+ const el = ref.current;
9
+ if (!el)
10
+ return;
11
+ el.style.height = 'auto';
12
+ el.style.height = `${el.scrollHeight}px`;
13
+ }, [value]);
14
+ return (_jsxs("div", { children: [label && (_jsx("label", { className: "se-text-sm se-font-medium se-text-input-field-text-label se-mb-1 se-block", children: label })), _jsx("textarea", { ref: ref, value: value, ...props, className: cn('se-w-full se-py-2 se-px-3 se-rounded-lg se-border se-border-input-field-border se-bg-slate-grey-3 se-text-text-primary se-text-sm se-font-[inherit] se-mb-2 se-resize-y se-min-h-[60px] se-max-h-[50vh] se-overflow-y-auto se-box-border', 'placeholder:se-text-input-field-text-placeholder', 'focus:se-border-input-field-border-selected focus:se-outline-none focus:se-shadow-focus-primary', 'disabled:se-bg-input-field-bg-disabled disabled:se-cursor-not-allowed disabled:se-opacity-50', className) })] }));
15
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * ElementHighlight — Shared overlay highlight for DOM elements.
3
+ *
4
+ * Tracks element position via useElementRect (scroll/resize-aware).
5
+ * Renders via createPortal to document.body with position: fixed.
6
+ *
7
+ * EXCEPTION: This component MUST stay on document.body (not in shadow root).
8
+ * It tracks and highlights host page elements, and needs same-tree visual
9
+ * stacking context. Uses inline styles exclusively (no CSS leaking concerns).
10
+ *
11
+ * Replaces: InspectHighlight, HighlightOverlay, DiscoveryHighlightOverlay,
12
+ * ReviewHighlightOverlay.
13
+ */
14
+ import type React from 'react';
15
+ export interface ElementHighlightProps {
16
+ element: HTMLElement;
17
+ color: string;
18
+ bgColor?: string;
19
+ borderStyle?: 'solid' | 'dashed';
20
+ borderWidth?: number;
21
+ label?: string;
22
+ labelIcon?: React.ReactNode;
23
+ showRemove?: boolean;
24
+ onRemove?: () => void;
25
+ onClick?: () => void;
26
+ zIndex?: number;
27
+ padding?: number;
28
+ showDimensions?: boolean;
29
+ className?: string;
30
+ }
31
+ export declare function ElementHighlight({ element, color, bgColor, borderStyle, borderWidth, label, labelIcon, showRemove, onRemove, onClick, zIndex, padding, showDimensions, className, }: ElementHighlightProps): React.ReactPortal | null;
32
+ //# sourceMappingURL=ElementHighlight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementHighlight.d.ts","sourceRoot":"","sources":["../../src/components/ElementHighlight.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,KAAK,EACL,OAAuB,EACvB,WAAqB,EACrB,WAAe,EACf,KAAK,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,OAAO,EACP,MAAmB,EACnB,OAAW,EACX,cAAc,EACd,SAAS,GACV,EAAE,qBAAqB,4BAsGvB"}
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createPortal } from 'react-dom';
3
+ import { useElementRect } from '../hooks/useElementRect';
4
+ export function ElementHighlight({ element, color, bgColor = 'transparent', borderStyle = 'solid', borderWidth = 2, label, labelIcon, showRemove, onRemove, onClick, zIndex = 2147483646, padding = 2, showDimensions, className, }) {
5
+ const rect = useElementRect(element);
6
+ if (!rect)
7
+ return null;
8
+ // Build dimensions label from element metadata
9
+ const dimensionsLabel = showDimensions
10
+ ? (() => {
11
+ const tag = element.tagName.toLowerCase();
12
+ const id = element.id ? `#${element.id}` : '';
13
+ const cls = element.className && typeof element.className === 'string'
14
+ ? `.${element.className.split(' ').filter(Boolean).slice(0, 2).join('.')}`
15
+ : '';
16
+ return `${tag}${id}${cls} \u2014 ${Math.round(rect.width)}\u00d7${Math.round(rect.height)}`;
17
+ })()
18
+ : null;
19
+ const displayLabel = label || dimensionsLabel;
20
+ return createPortal(_jsx("div", { "data-syntro-highlight": true, className: className, onClick: (e) => {
21
+ e.stopPropagation();
22
+ e.preventDefault();
23
+ onClick?.();
24
+ }, style: {
25
+ position: 'fixed',
26
+ top: rect.top - padding,
27
+ left: rect.left - padding,
28
+ width: rect.width + padding * 2,
29
+ height: rect.height + padding * 2,
30
+ border: `${borderWidth}px ${borderStyle} ${color}`,
31
+ backgroundColor: bgColor,
32
+ borderRadius: '4px',
33
+ zIndex,
34
+ pointerEvents: onClick || onRemove ? 'auto' : 'none',
35
+ cursor: onClick ? 'pointer' : 'default',
36
+ transition: 'all 0.05s ease-out',
37
+ boxSizing: 'border-box',
38
+ }, children: displayLabel && (_jsxs("div", { "data-syntro-highlight-label": true, style: {
39
+ position: 'absolute',
40
+ top: '-22px',
41
+ left: 0,
42
+ background: showDimensions
43
+ ? `${color.replace(')', ',0.85)').replace('rgb(', 'rgba(')}`
44
+ : color,
45
+ color: '#fff',
46
+ fontSize: showDimensions ? '9px' : '10px',
47
+ fontWeight: 600,
48
+ fontFamily: showDimensions ? 'monospace' : 'inherit',
49
+ padding: '1px 6px',
50
+ borderRadius: '4px',
51
+ whiteSpace: 'nowrap',
52
+ display: 'flex',
53
+ alignItems: 'center',
54
+ gap: '6px',
55
+ pointerEvents: 'auto',
56
+ }, children: [labelIcon, displayLabel, showRemove && onRemove && (_jsx("button", { "data-syntro-highlight-remove": true, onClick: (e) => {
57
+ e.stopPropagation();
58
+ e.preventDefault();
59
+ onRemove();
60
+ }, style: {
61
+ background: 'rgba(0,0,0,0.3)',
62
+ border: 'none',
63
+ color: '#fff',
64
+ borderRadius: '50%',
65
+ width: '14px',
66
+ height: '14px',
67
+ fontSize: '10px',
68
+ cursor: 'pointer',
69
+ display: 'flex',
70
+ alignItems: 'center',
71
+ justifyContent: 'center',
72
+ padding: 0,
73
+ lineHeight: 1,
74
+ }, children: "\u00D7" }))] })) }), document.body);
75
+ }
@@ -0,0 +1,6 @@
1
+ interface EmptyStateProps {
2
+ message: string;
3
+ }
4
+ export declare function EmptyState({ message }: EmptyStateProps): import("react/jsx-runtime").JSX.Element;
5
+ export {};
6
+ //# sourceMappingURL=EmptyState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmptyState.d.ts","sourceRoot":"","sources":["../../src/components/EmptyState.tsx"],"names":[],"mappings":"AAAA,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,eAAe,2CAMtD"}
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export function EmptyState({ message }) {
3
+ return (_jsx("div", { className: "se-text-center se-py-8 se-px-4 se-text-text-secondary se-text-sm", children: message }));
4
+ }
@@ -0,0 +1,8 @@
1
+ interface GroupHeaderProps {
2
+ label: string;
3
+ count: number;
4
+ className?: string;
5
+ }
6
+ export declare function GroupHeader({ label, count, className }: GroupHeaderProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=GroupHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupHeader.d.ts","sourceRoot":"","sources":["../../src/components/GroupHeader.tsx"],"names":[],"mappings":"AAEA,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CAcxE"}
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../cn';
3
+ export function GroupHeader({ label, count, className }) {
4
+ return (_jsxs("div", { className: cn('se-text-xs se-font-bold se-text-text-primary se-uppercase se-tracking-wide se-py-1 se-pb-2 se-flex se-items-center se-justify-between', className), children: [_jsx("span", { children: label }), _jsx("span", { className: "se-text-xs se-text-text-secondary se-bg-badge-slate-bg se-px-1.5 se-py-0.5 se-rounded-lg", children: count })] }));
5
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * TriggerJourney — compact horizontal node graph for showWhen conditions.
3
+ *
4
+ * Displays each condition as a small circle node connected by lines.
5
+ * Nodes light up green as conditions are met.
6
+ */
7
+ import type { ShowWhenStatus } from './ConditionStatusLine';
8
+ export interface TriggerJourneyProps {
9
+ status: ShowWhenStatus | null;
10
+ }
11
+ export declare function TriggerJourney({ status }: TriggerJourneyProps): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=TriggerJourney.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TriggerJourney.d.ts","sourceRoot":"","sources":["../../src/components/TriggerJourney.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE7E,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;CAC/B;AA4FD,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,EAAE,mBAAmB,2CA6B7D"}
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * TriggerJourney — compact horizontal node graph for showWhen conditions.
4
+ *
5
+ * Displays each condition as a small circle node connected by lines.
6
+ * Nodes light up green as conditions are met.
7
+ */
8
+ import { Check } from 'lucide-react';
9
+ import { cn } from '../cn';
10
+ /* ------------------------------------------------------------------ */
11
+ /* Internal: small progress bar for event_count nodes */
12
+ /* ------------------------------------------------------------------ */
13
+ function ProgressBar({ current, target }) {
14
+ const pct = Math.min(100, Math.round((current / Math.max(target, 1)) * 100));
15
+ return (_jsxs("div", { className: "se-flex se-items-center se-gap-0.5", children: [_jsx("span", { className: "se-inline-block se-w-8 se-h-1 se-rounded-full se-bg-white/10", title: `${current}/${target} (${pct}%)`, children: _jsx("span", { className: cn('se-block se-h-full se-rounded-full se-transition-all', pct >= 100 ? 'se-bg-green-4' : 'se-bg-blue-4'), style: { width: `${pct}%` } }) }), _jsxs("span", { className: "se-text-[9px] se-text-text-tertiary", children: [current, "/", target] })] }));
16
+ }
17
+ /* ------------------------------------------------------------------ */
18
+ /* Internal: single journey node with label + optional connection */
19
+ /* ------------------------------------------------------------------ */
20
+ function JourneyNode({ cs, isLast }) {
21
+ const hasProgress = !!cs.formatted.progress;
22
+ const inProgress = !cs.passed && hasProgress && cs.formatted.progress.current > 0;
23
+ return (_jsxs("div", { className: "se-flex se-items-center se-gap-0", children: [_jsxs("div", { className: "se-flex se-flex-col se-items-center se-min-w-0", children: [_jsx("div", { "data-journey-node": true, "data-passed": cs.passed ? 'true' : 'false', className: cn('se-w-4 se-h-4 se-rounded-full se-border-2 se-flex se-items-center se-justify-center se-shrink-0', cs.passed
24
+ ? 'se-bg-green-4 se-border-green-4'
25
+ : inProgress
26
+ ? 'se-bg-blue-4 se-border-blue-4'
27
+ : 'se-bg-transparent se-border-white/20'), children: cs.passed && _jsx(Check, { className: "se-w-2.5 se-h-2.5 se-text-white" }) }), _jsx("span", { className: "se-text-[9px] se-text-text-tertiary se-truncate se-max-w-[60px] se-text-center se-mt-0.5", title: cs.formatted.instruction, children: cs.formatted.shortLabel }), hasProgress && (_jsx(ProgressBar, { current: cs.formatted.progress.current, target: cs.formatted.progress.target }))] }), !isLast && (_jsx("div", { "data-journey-line": true, className: cn('se-h-0.5 se-w-4 se-self-start se-mt-2 se-shrink-0', cs.passed ? 'se-bg-green-4' : 'se-bg-white/10') }))] }));
28
+ }
29
+ /* ------------------------------------------------------------------ */
30
+ /* Main component */
31
+ /* ------------------------------------------------------------------ */
32
+ export function TriggerJourney({ status }) {
33
+ if (!status || status.conditions.length === 0) {
34
+ return (_jsx("div", { className: "se-mt-1 se-text-[10px] se-text-text-tertiary se-italic", children: "Always Present" }));
35
+ }
36
+ const { conditions } = status;
37
+ const allPassed = conditions.every((c) => c.passed);
38
+ const isMulti = conditions.length > 1;
39
+ return (_jsxs("div", { className: "se-mt-1", children: [_jsx("div", { className: "se-flex se-items-start", children: conditions.map((cs, i) => (_jsx(JourneyNode, { cs: cs, isLast: i === conditions.length - 1 }, i))) }), allPassed && isMulti && (_jsxs("div", { className: "se-flex se-items-center se-gap-1 se-mt-1 se-text-[10px] se-text-green-4", children: [_jsx(Check, { className: "se-w-3 se-h-3" }), _jsx("span", { children: "All conditions met" })] }))] }));
40
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Format a showWhen condition into a human-readable label.
3
+ * Pure function — no runtime dependency.
4
+ */
5
+ interface ConditionLike {
6
+ type: string;
7
+ [key: string]: unknown;
8
+ }
9
+ export interface ConditionProgress {
10
+ current: number;
11
+ target: number;
12
+ operator: string;
13
+ }
14
+ export interface FormattedCondition {
15
+ label: string;
16
+ instruction: string;
17
+ shortLabel: string;
18
+ progress?: ConditionProgress;
19
+ }
20
+ /**
21
+ * Convert a Condition object into a human-readable label.
22
+ * For event_count conditions, also returns progress data.
23
+ */
24
+ export declare function formatConditionLabel(condition: ConditionLike, accumulatorCount?: number): FormattedCondition;
25
+ export {};
26
+ //# sourceMappingURL=formatConditionLabel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatConditionLabel.d.ts","sourceRoot":"","sources":["../src/formatConditionLabel.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAgDD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,aAAa,EACxB,gBAAgB,CAAC,EAAE,MAAM,GACxB,kBAAkB,CAsKpB"}
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Format a showWhen condition into a human-readable label.
3
+ * Pure function — no runtime dependency.
4
+ */
5
+ /**
6
+ * Format match criteria as a parenthetical string.
7
+ * { tagName: 'a' } → '(tagName: a)'
8
+ */
9
+ function formatMatch(match) {
10
+ if (!match || Object.keys(match).length === 0)
11
+ return '';
12
+ const parts = Object.entries(match).map(([k, v]) => `${k}: ${v}`);
13
+ return ` (${parts.join(', ')})`;
14
+ }
15
+ /**
16
+ * Format an operator for display.
17
+ */
18
+ function formatOperator(op) {
19
+ switch (op) {
20
+ case 'gte':
21
+ return '\u2265'; // ≥
22
+ case 'lte':
23
+ return '\u2264'; // ≤
24
+ case 'gt':
25
+ return '>';
26
+ case 'lt':
27
+ return '<';
28
+ case 'eq':
29
+ return '=';
30
+ default:
31
+ return op;
32
+ }
33
+ }
34
+ /**
35
+ * Convert a hyphenated or underscored key into human-readable lowercase text.
36
+ * e.g. "fine-arts-page-views" → "fine arts page views"
37
+ */
38
+ function humanizeKey(key) {
39
+ return key.replace(/[-_]/g, ' ').toLowerCase();
40
+ }
41
+ /**
42
+ * Strip trailing wildcard segments from a URL path.
43
+ * e.g. "/fine-arts/**" → "/fine-arts/"
44
+ */
45
+ function cleanUrl(url) {
46
+ return url.replace(/\/?\*+$/, '/').replace(/\/\/$/, '/');
47
+ }
48
+ // Pre-compiled regexes for event_count classification
49
+ const PAGE_VIEW_RE = /page.?view/i;
50
+ const CLICK_RE = /click/i;
51
+ /**
52
+ * Convert a Condition object into a human-readable label.
53
+ * For event_count conditions, also returns progress data.
54
+ */
55
+ export function formatConditionLabel(condition, accumulatorCount) {
56
+ switch (condition.type) {
57
+ case 'event_count': {
58
+ const key = condition.key;
59
+ const op = condition.operator;
60
+ const target = condition.count;
61
+ const current = accumulatorCount ?? 0;
62
+ const humanized = humanizeKey(key);
63
+ let instruction;
64
+ let shortLabel;
65
+ if (PAGE_VIEW_RE.test(humanized)) {
66
+ // Extract the topic by removing "page view(s)" from the humanized key
67
+ const topic = humanized.replace(/\s*page\s*views?\s*/i, '').trim();
68
+ instruction = topic
69
+ ? `View ${topic} pages ${target}+ times`
70
+ : `View pages ${target}+ times`;
71
+ shortLabel = `View ${target}+ times`;
72
+ }
73
+ else if (CLICK_RE.test(humanized)) {
74
+ const topic = humanized.replace(/\s*clicks?\s*/i, '').trim();
75
+ instruction = topic
76
+ ? `Click ${topic} ${target}+ times`
77
+ : `Click ${target}+ times`;
78
+ shortLabel = `${target}+ clicks`;
79
+ }
80
+ else {
81
+ // Generic event
82
+ const lastWord = humanized.trim().split(' ').filter(w => w).pop() || 'events';
83
+ instruction = `Reach ${target}+ ${humanized} events`;
84
+ shortLabel = `${target}+ ${lastWord}s`;
85
+ }
86
+ return {
87
+ label: `${key} ${formatOperator(op)} ${target}`,
88
+ instruction,
89
+ shortLabel,
90
+ progress: { current, target, operator: op },
91
+ };
92
+ }
93
+ case 'page_url': {
94
+ const url = condition.url;
95
+ const cleaned = cleanUrl(url);
96
+ const hasWildcard = url !== cleaned;
97
+ const instruction = hasWildcard
98
+ ? `Visit a ${cleaned} page`
99
+ : `Visit ${cleaned}`;
100
+ return {
101
+ label: `${url}`,
102
+ instruction,
103
+ shortLabel: cleaned,
104
+ };
105
+ }
106
+ case 'anchor_visible': {
107
+ const anchorId = condition.anchorId;
108
+ const state = condition.state;
109
+ return {
110
+ label: `${anchorId} (${state})`,
111
+ instruction: `Scroll until ${anchorId} is ${state}`,
112
+ shortLabel: `${anchorId}`,
113
+ };
114
+ }
115
+ case 'event_occurred': {
116
+ const eventName = condition.eventName;
117
+ return {
118
+ label: `${eventName}`,
119
+ instruction: `Trigger a ${eventName} event`,
120
+ shortLabel: `${eventName}`,
121
+ };
122
+ }
123
+ case 'state_equals': {
124
+ const key = condition.key;
125
+ const val = condition.value === undefined ? 'undefined' : JSON.stringify(condition.value);
126
+ return {
127
+ label: `${key} = ${val}`,
128
+ instruction: `${key} equals ${val}`,
129
+ shortLabel: `${key}`,
130
+ };
131
+ }
132
+ case 'viewport': {
133
+ const parts = [];
134
+ if (condition.minWidth !== undefined)
135
+ parts.push(`w ${formatOperator('gte')} ${condition.minWidth}px`);
136
+ if (condition.maxWidth !== undefined)
137
+ parts.push(`w ${formatOperator('lte')} ${condition.maxWidth}px`);
138
+ if (condition.minHeight !== undefined)
139
+ parts.push(`h ${formatOperator('gte')} ${condition.minHeight}px`);
140
+ if (condition.maxHeight !== undefined)
141
+ parts.push(`h ${formatOperator('lte')} ${condition.maxHeight}px`);
142
+ const label = parts.join(', ') || 'any viewport';
143
+ const instruction = parts.length > 0
144
+ ? `Use a viewport ${parts.join(' and ')}`
145
+ : 'Use a viewport of any size';
146
+ const shortLabel = parts.length > 0 ? parts[0] : 'Any size';
147
+ return { label, instruction, shortLabel };
148
+ }
149
+ case 'session_metric': {
150
+ const key = condition.key;
151
+ const op = condition.operator;
152
+ const threshold = condition.threshold;
153
+ return {
154
+ label: `${key} ${formatOperator(op)} ${threshold}`,
155
+ instruction: `${key} reaches ${threshold}+`,
156
+ shortLabel: `${key} ${threshold}+`,
157
+ };
158
+ }
159
+ case 'dismissed': {
160
+ const inverted = condition.inverted;
161
+ const key = condition.key;
162
+ const target = key || 'this';
163
+ return {
164
+ label: inverted ? 'not dismissed' : 'dismissed',
165
+ instruction: inverted
166
+ ? `Do not dismiss ${target}`
167
+ : `Dismiss ${target}`,
168
+ shortLabel: inverted ? 'Not dismissed' : 'Dismissed',
169
+ };
170
+ }
171
+ case 'cooldown_active': {
172
+ const inverted = condition.inverted;
173
+ return {
174
+ label: inverted ? 'cooldown inactive' : 'cooldown active',
175
+ instruction: inverted
176
+ ? 'Wait for cooldown to expire'
177
+ : 'Cooldown is active',
178
+ shortLabel: inverted ? 'Cooldown done' : 'Cooldown active',
179
+ };
180
+ }
181
+ case 'frequency_limit': {
182
+ const inverted = condition.inverted;
183
+ const limit = condition.limit;
184
+ return {
185
+ label: `shown ${formatOperator(inverted ? 'lt' : 'gte')} ${limit} times`,
186
+ instruction: inverted
187
+ ? `Shown fewer than ${limit} times`
188
+ : `Shown ${limit}+ times`,
189
+ shortLabel: inverted ? `< ${limit} views` : `${limit}+ views`,
190
+ };
191
+ }
192
+ case 'route': {
193
+ const routeId = condition.routeId;
194
+ return {
195
+ label: `${routeId}`,
196
+ instruction: `Navigate to ${routeId} route`,
197
+ shortLabel: `${routeId}`,
198
+ };
199
+ }
200
+ default:
201
+ return {
202
+ label: `${condition.type}`,
203
+ instruction: `${condition.type}`,
204
+ shortLabel: `${condition.type}`,
205
+ };
206
+ }
207
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Returns a live DOMRect for an element, updating on scroll, resize,
3
+ * and element size changes.
4
+ *
5
+ * Uses requestAnimationFrame to batch updates and avoid layout thrashing.
6
+ */
7
+ export declare function useElementRect(element: HTMLElement | null): DOMRect | null;
8
+ //# sourceMappingURL=useElementRect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useElementRect.d.ts","sourceRoot":"","sources":["../../src/hooks/useElementRect.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CA6C1E"}