@syntrologie/adapt-nav 2.16.0 → 2.17.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 (211) hide show
  1. package/dist/NavWidgetLit.d.ts.map +1 -1
  2. package/dist/chunk-HMLY7DHA.js +16 -0
  3. package/dist/chunk-HMLY7DHA.js.map +7 -0
  4. package/dist/chunk-ZYHZ6JAD.js +447 -0
  5. package/dist/chunk-ZYHZ6JAD.js.map +7 -0
  6. package/dist/editor.d.ts +42 -21
  7. package/dist/editor.d.ts.map +1 -1
  8. package/dist/editor.js +310 -313
  9. package/dist/editor.js.map +7 -0
  10. package/dist/resolveNavTarget.d.ts +61 -0
  11. package/dist/resolveNavTarget.d.ts.map +1 -0
  12. package/dist/resolveNavTarget.test.d.ts +2 -0
  13. package/dist/resolveNavTarget.test.d.ts.map +1 -0
  14. package/dist/runtime.d.ts +3 -4
  15. package/dist/runtime.d.ts.map +1 -1
  16. package/dist/runtime.js +612 -221
  17. package/dist/runtime.js.map +7 -0
  18. package/dist/schema.d.ts +182 -72
  19. package/dist/schema.d.ts.map +1 -1
  20. package/dist/schema.js +155 -125
  21. package/dist/schema.js.map +7 -0
  22. package/package.json +9 -24
  23. package/dist/NavWidget.d.ts +0 -31
  24. package/dist/NavWidget.d.ts.map +0 -1
  25. package/dist/NavWidget.js +0 -476
  26. package/dist/NavWidgetLit.js +0 -495
  27. package/dist/NavWidgetLit.test.js +0 -199
  28. package/dist/cdn.d.ts +0 -62
  29. package/dist/cdn.d.ts.map +0 -1
  30. package/dist/cdn.js +0 -48
  31. package/dist/editor-lit.d.ts +0 -49
  32. package/dist/editor-lit.d.ts.map +0 -1
  33. package/dist/editor-lit.js +0 -319
  34. package/dist/runtime-lit.d.ts +0 -108
  35. package/dist/runtime-lit.d.ts.map +0 -1
  36. package/dist/runtime-lit.js +0 -241
  37. package/dist/summarize.js +0 -51
  38. package/dist/types.js +0 -18
  39. package/node_modules/@syntro/design-system/README.md +0 -335
  40. package/node_modules/@syntro/design-system/dist/assets/syntrologie-logo.svg +0 -21
  41. package/node_modules/@syntro/design-system/dist/assets/syntrologie-logomark.svg +0 -10
  42. package/node_modules/@syntro/design-system/dist/index.d.ts +0 -8
  43. package/node_modules/@syntro/design-system/dist/index.d.ts.map +0 -1
  44. package/node_modules/@syntro/design-system/dist/index.js +0 -7
  45. package/node_modules/@syntro/design-system/dist/tailwind-preset.d.ts +0 -19
  46. package/node_modules/@syntro/design-system/dist/tailwind-preset.d.ts.map +0 -1
  47. package/node_modules/@syntro/design-system/dist/tailwind-preset.js +0 -455
  48. package/node_modules/@syntro/design-system/dist/tokens/colors.css +0 -464
  49. package/node_modules/@syntro/design-system/dist/tokens/colors.d.ts +0 -874
  50. package/node_modules/@syntro/design-system/dist/tokens/colors.d.ts.map +0 -1
  51. package/node_modules/@syntro/design-system/dist/tokens/colors.js +0 -564
  52. package/node_modules/@syntro/design-system/dist/tokens/effects.css +0 -43
  53. package/node_modules/@syntro/design-system/dist/tokens/effects.d.ts +0 -139
  54. package/node_modules/@syntro/design-system/dist/tokens/effects.d.ts.map +0 -1
  55. package/node_modules/@syntro/design-system/dist/tokens/effects.js +0 -121
  56. package/node_modules/@syntro/design-system/dist/tokens/index.d.ts +0 -12
  57. package/node_modules/@syntro/design-system/dist/tokens/index.d.ts.map +0 -1
  58. package/node_modules/@syntro/design-system/dist/tokens/index.js +0 -11
  59. package/node_modules/@syntro/design-system/dist/tokens/panel-shell.d.ts +0 -93
  60. package/node_modules/@syntro/design-system/dist/tokens/panel-shell.d.ts.map +0 -1
  61. package/node_modules/@syntro/design-system/dist/tokens/panel-shell.js +0 -72
  62. package/node_modules/@syntro/design-system/package.json +0 -55
  63. package/node_modules/@syntro/design-system/src/assets/syntrologie-logo.svg +0 -21
  64. package/node_modules/@syntro/design-system/src/assets/syntrologie-logomark.svg +0 -10
  65. package/node_modules/@syntrologie/sdk-contracts/dist/index.d.ts +0 -129
  66. package/node_modules/@syntrologie/sdk-contracts/dist/index.js +0 -17
  67. package/node_modules/@syntrologie/sdk-contracts/dist/schemas.d.ts +0 -2296
  68. package/node_modules/@syntrologie/sdk-contracts/dist/schemas.js +0 -361
  69. package/node_modules/@syntrologie/sdk-contracts/package.json +0 -33
  70. package/node_modules/@syntrologie/shared-editor-ui/dist/cn.d.ts +0 -2
  71. package/node_modules/@syntrologie/shared-editor-ui/dist/cn.d.ts.map +0 -1
  72. package/node_modules/@syntrologie/shared-editor-ui/dist/cn.js +0 -3
  73. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.d.ts +0 -34
  74. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.d.ts.map +0 -1
  75. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.js +0 -161
  76. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPickerLit.d.ts +0 -84
  77. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPickerLit.d.ts.map +0 -1
  78. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPickerLit.js +0 -323
  79. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.d.ts +0 -7
  80. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.d.ts.map +0 -1
  81. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.js +0 -9
  82. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggleLit.d.ts +0 -25
  83. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggleLit.d.ts.map +0 -1
  84. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggleLit.js +0 -55
  85. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts +0 -23
  86. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts.map +0 -1
  87. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.js +0 -40
  88. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLineLit.d.ts +0 -33
  89. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLineLit.d.ts.map +0 -1
  90. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLineLit.js +0 -118
  91. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts +0 -7
  92. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts.map +0 -1
  93. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.js +0 -22
  94. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadgeLit.d.ts +0 -32
  95. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadgeLit.d.ts.map +0 -1
  96. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadgeLit.js +0 -68
  97. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSection.d.ts +0 -8
  98. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSection.d.ts.map +0 -1
  99. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSection.js +0 -9
  100. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSectionLit.d.ts +0 -34
  101. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSectionLit.d.ts.map +0 -1
  102. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSectionLit.js +0 -57
  103. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.d.ts +0 -7
  104. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.d.ts.map +0 -1
  105. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.js +0 -4
  106. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButtonLit.d.ts +0 -13
  107. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButtonLit.d.ts.map +0 -1
  108. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButtonLit.js +0 -31
  109. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBody.d.ts +0 -7
  110. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBody.d.ts.map +0 -1
  111. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBody.js +0 -4
  112. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBodyLit.d.ts +0 -7
  113. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBodyLit.d.ts.map +0 -1
  114. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBodyLit.js +0 -15
  115. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.d.ts +0 -13
  116. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.d.ts.map +0 -1
  117. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.js +0 -15
  118. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCardLit.d.ts +0 -36
  119. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCardLit.d.ts.map +0 -1
  120. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCardLit.js +0 -102
  121. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.d.ts +0 -7
  122. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.d.ts.map +0 -1
  123. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.js +0 -4
  124. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooterLit.d.ts +0 -20
  125. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooterLit.d.ts.map +0 -1
  126. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooterLit.js +0 -48
  127. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeader.d.ts +0 -9
  128. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeader.d.ts.map +0 -1
  129. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeader.js +0 -4
  130. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeaderLit.d.ts +0 -16
  131. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeaderLit.d.ts.map +0 -1
  132. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeaderLit.js +0 -25
  133. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.d.ts +0 -8
  134. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.d.ts.map +0 -1
  135. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.js +0 -8
  136. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInputLit.d.ts +0 -66
  137. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInputLit.d.ts.map +0 -1
  138. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInputLit.js +0 -87
  139. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayout.d.ts +0 -7
  140. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayout.d.ts.map +0 -1
  141. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayout.js +0 -4
  142. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayoutLit.d.ts +0 -7
  143. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayoutLit.d.ts.map +0 -1
  144. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayoutLit.js +0 -15
  145. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts +0 -25
  146. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts.map +0 -1
  147. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.js +0 -390
  148. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShellLit.d.ts +0 -66
  149. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShellLit.d.ts.map +0 -1
  150. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShellLit.js +0 -528
  151. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.d.ts +0 -8
  152. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.d.ts.map +0 -1
  153. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.js +0 -8
  154. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelectLit.d.ts +0 -41
  155. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelectLit.d.ts.map +0 -1
  156. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelectLit.js +0 -63
  157. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.d.ts +0 -8
  158. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.d.ts.map +0 -1
  159. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.js +0 -17
  160. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextareaLit.d.ts +0 -55
  161. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextareaLit.d.ts.map +0 -1
  162. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextareaLit.js +0 -92
  163. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.d.ts +0 -32
  164. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.d.ts.map +0 -1
  165. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.js +0 -85
  166. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlightLit.d.ts +0 -90
  167. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlightLit.d.ts.map +0 -1
  168. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlightLit.js +0 -242
  169. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyState.d.ts +0 -6
  170. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyState.d.ts.map +0 -1
  171. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyState.js +0 -4
  172. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyStateLit.d.ts +0 -12
  173. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyStateLit.d.ts.map +0 -1
  174. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyStateLit.js +0 -21
  175. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeader.d.ts +0 -8
  176. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeader.d.ts.map +0 -1
  177. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeader.js +0 -5
  178. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeaderLit.d.ts +0 -21
  179. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeaderLit.d.ts.map +0 -1
  180. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeaderLit.js +0 -33
  181. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts +0 -12
  182. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts.map +0 -1
  183. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.js +0 -40
  184. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourneyLit.d.ts +0 -28
  185. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourneyLit.d.ts.map +0 -1
  186. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourneyLit.js +0 -121
  187. package/node_modules/@syntrologie/shared-editor-ui/dist/controllers/PanelShellController.d.ts +0 -110
  188. package/node_modules/@syntrologie/shared-editor-ui/dist/controllers/PanelShellController.d.ts.map +0 -1
  189. package/node_modules/@syntrologie/shared-editor-ui/dist/controllers/PanelShellController.js +0 -481
  190. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts +0 -26
  191. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts.map +0 -1
  192. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.js +0 -202
  193. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useElementRect.d.ts +0 -8
  194. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useElementRect.d.ts.map +0 -1
  195. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useElementRect.js +0 -46
  196. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts +0 -24
  197. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts.map +0 -1
  198. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.js +0 -86
  199. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts +0 -36
  200. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts.map +0 -1
  201. package/node_modules/@syntrologie/shared-editor-ui/dist/index.js +0 -26
  202. package/node_modules/@syntrologie/shared-editor-ui/dist/lit-elements.d.ts +0 -15
  203. package/node_modules/@syntrologie/shared-editor-ui/dist/lit-elements.d.ts.map +0 -1
  204. package/node_modules/@syntrologie/shared-editor-ui/dist/lit-elements.js +0 -14
  205. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/elementChainRecommender.d.ts +0 -33
  206. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/elementChainRecommender.d.ts.map +0 -1
  207. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/elementChainRecommender.js +0 -68
  208. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/selectorGenerator.d.ts +0 -22
  209. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/selectorGenerator.d.ts.map +0 -1
  210. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/selectorGenerator.js +0 -143
  211. package/node_modules/@syntrologie/shared-editor-ui/package.json +0 -55
@@ -1,319 +0,0 @@
1
- /**
2
- * Adaptive Nav - Lit Editor Component
3
- *
4
- * Lit web component port of the React Nav editor (editor.tsx).
5
- * Displays nav tip cards with detection badges, inline editing
6
- * (Title, Description, Link URL, Icon, Category), and rationale.
7
- *
8
- * Custom events:
9
- * navigate-home — user clicked back
10
- * dirty-change — { dirty: boolean }
11
- */
12
- import { html, LitElement, nothing } from 'lit';
13
- import { describeTrigger, summarizeNavItem } from './summarize';
14
- import { isOwnAction } from './types';
15
- // ============================================================================
16
- // Targeting Extraction
17
- // ============================================================================
18
- const isRuleStrategy = (s) => typeof s === 'object' &&
19
- s !== null &&
20
- s.type === 'rules' &&
21
- Array.isArray(s.rules);
22
- const extractFirstPage = (triggerWhen) => {
23
- if (!triggerWhen || !isRuleStrategy(triggerWhen))
24
- return null;
25
- for (const rule of triggerWhen.rules) {
26
- for (const cond of rule.conditions) {
27
- const c = cond;
28
- if (c.type === 'page_url' && typeof c.url === 'string')
29
- return c.url;
30
- }
31
- }
32
- return null;
33
- };
34
- const extractFirstAnchor = (triggerWhen) => {
35
- if (!triggerWhen || !isRuleStrategy(triggerWhen))
36
- return null;
37
- for (const rule of triggerWhen.rules) {
38
- for (const cond of rule.conditions) {
39
- const c = cond;
40
- if (c.type === 'anchor_visible' && typeof c.anchorId === 'string')
41
- return c.anchorId;
42
- }
43
- }
44
- return null;
45
- };
46
- // ============================================================================
47
- // Helpers
48
- // ============================================================================
49
- const flattenItems = (config) => {
50
- const actions = (config.actions || []).filter(isOwnAction);
51
- return actions.map((tip, i) => {
52
- // Prefer the tip's own anchor (real pipeline data ships the target here).
53
- // Fall back to an `anchor_visible` condition inside triggerWhen for older configs.
54
- const tipAnchor = tip.kind === 'nav:tip' ? tip.config.anchor?.selector : undefined;
55
- const rawRoute = tip.kind === 'nav:tip' ? tip.config.anchor?.route : undefined;
56
- const tipRoute = typeof rawRoute === 'string' ? rawRoute : undefined;
57
- return {
58
- key: String(i),
59
- index: i,
60
- summary: summarizeNavItem(tip),
61
- trigger: describeTrigger(tip.triggerWhen),
62
- rationale: tip.rationale?.why,
63
- firstAnchor: tipAnchor || extractFirstAnchor(tip.triggerWhen),
64
- firstPage: tipRoute || extractFirstPage(tip.triggerWhen),
65
- tip,
66
- };
67
- });
68
- };
69
- const runDetection = (items) => {
70
- const map = new Map();
71
- const currentPath = window.location.pathname;
72
- for (const item of items) {
73
- // Page match
74
- let pageMatch = true;
75
- if (item.firstPage) {
76
- const pattern = item.firstPage;
77
- const regex = new RegExp(`^${pattern.replace(/\*\*/g, '.*').replace(/(?<!\.)(\*)/g, '[^/]*')}$`);
78
- pageMatch = regex.test(currentPath);
79
- }
80
- // Anchor match
81
- let anchorFound = false;
82
- if (item.firstAnchor) {
83
- try {
84
- anchorFound = document.querySelector(item.firstAnchor) !== null;
85
- }
86
- catch {
87
- // Invalid selector
88
- }
89
- }
90
- else {
91
- anchorFound = pageMatch;
92
- }
93
- map.set(item.key, { found: pageMatch && anchorFound });
94
- }
95
- return map;
96
- };
97
- // ============================================================================
98
- // Element
99
- // ============================================================================
100
- export class NavEditorLit extends LitElement {
101
- constructor() {
102
- super(...arguments);
103
- this.config = null;
104
- this.onChange = null;
105
- this._editingKey = null;
106
- this._detectionMap = new Map();
107
- this._detectionInterval = null;
108
- this._onPopstate = () => this._runDetection();
109
- this._runDetection = () => {
110
- if (!this.config)
111
- return;
112
- this._detectionMap = runDetection(flattenItems(this.config));
113
- };
114
- // ---- Actions ----
115
- this._handleBack = () => {
116
- if (this._editingKey !== null) {
117
- this._editingKey = null;
118
- }
119
- else {
120
- this.dispatchEvent(new CustomEvent('navigate-home', { bubbles: true }));
121
- }
122
- };
123
- this._handleItemClick = (key) => {
124
- this._editingKey = key;
125
- };
126
- this._handleFieldChange = (index, field, value) => {
127
- if (!this.config || !this.onChange)
128
- return;
129
- const ownActions = (this.config.actions || []).filter(isOwnAction).slice();
130
- const tip = { ...ownActions[index], config: { ...ownActions[index].config } };
131
- tip.config[field] = value;
132
- ownActions[index] = tip;
133
- const otherActions = (this.config.actions || []).filter((a) => !isOwnAction(a));
134
- const updated = { ...this.config, actions: [...otherActions, ...ownActions] };
135
- this.onChange(updated);
136
- this.dispatchEvent(new CustomEvent('dirty-change', { detail: { dirty: true }, bubbles: true }));
137
- };
138
- // ---- Render ----
139
- this._handleBadgeClick = (item, e) => {
140
- e.stopPropagation();
141
- const href = item.tip.config.href;
142
- if (!href)
143
- return;
144
- // SPA navigate via pushState + popstate
145
- window.history.pushState({}, '', href);
146
- window.dispatchEvent(new PopStateEvent('popstate'));
147
- };
148
- this._renderDetectionBadge = (item) => {
149
- const detection = this._detectionMap.get(item.key);
150
- const found = detection?.found ?? false;
151
- if (found) {
152
- return html `<button type="button"
153
- title="Click to scroll to element"
154
- @click=${(e) => this._handleBadgeClick(item, e)}
155
- class="se-shrink-0 se-w-2 se-h-2 se-rounded-full se-border-none se-cursor-pointer"
156
- style="background:#22c55e"
157
- ></button>`;
158
- }
159
- return html `<button type="button"
160
- title="Click to navigate to page"
161
- @click=${(e) => this._handleBadgeClick(item, e)}
162
- class="se-shrink-0 se-w-2 se-h-2 se-rounded-full se-border-none se-cursor-pointer"
163
- style="background:#ef4444"
164
- ></button>`;
165
- };
166
- this._renderEditMode = (item) => {
167
- const tip = item.tip;
168
- return html `
169
- <div class="se-py-1">
170
- <div class="se-flex se-items-center se-gap-2 se-mb-3 se-text-[13px] se-font-semibold se-text-text-primary">
171
- <span>🧭</span>
172
- <span>${item.summary}</span>
173
- </div>
174
-
175
- <div class="se-mb-3">
176
- <label class="se-text-[11px] se-font-semibold se-text-text-secondary se-mb-1 se-block">Title</label>
177
- <input type="text" .value=${tip.config.title}
178
- @input=${(e) => this._handleFieldChange(item.index, 'title', e.target.value)}
179
- class="se-w-full se-p-2 se-rounded se-border se-border-border-primary se-bg-input-field-bg se-text-text-primary se-text-sm" />
180
- </div>
181
-
182
- <div class="se-mb-3">
183
- <label class="se-text-[11px] se-font-semibold se-text-text-secondary se-mb-1 se-block">Description</label>
184
- <input type="text" .value=${tip.config.description}
185
- @input=${(e) => this._handleFieldChange(item.index, 'description', e.target.value)}
186
- class="se-w-full se-p-2 se-rounded se-border se-border-border-primary se-bg-input-field-bg se-text-text-primary se-text-sm" />
187
- </div>
188
-
189
- <div class="se-mb-3">
190
- <label class="se-text-[11px] se-font-semibold se-text-text-secondary se-mb-1 se-block">Link URL</label>
191
- <input type="text" .value=${tip.config.href || ''} placeholder="Optional"
192
- @input=${(e) => this._handleFieldChange(item.index, 'href', e.target.value)}
193
- class="se-w-full se-p-2 se-rounded se-border se-border-border-primary se-bg-input-field-bg se-text-text-primary se-text-sm" />
194
- </div>
195
-
196
- <div class="se-mb-3">
197
- <label class="se-text-[11px] se-font-semibold se-text-text-secondary se-mb-1 se-block">Icon</label>
198
- <input type="text" .value=${tip.config.icon || ''} placeholder="e.g., 🧭"
199
- @input=${(e) => this._handleFieldChange(item.index, 'icon', e.target.value)}
200
- class="se-w-full se-p-2 se-rounded se-border se-border-border-primary se-bg-input-field-bg se-text-text-primary se-text-sm" />
201
- </div>
202
-
203
- <div class="se-mb-3">
204
- <label class="se-text-[11px] se-font-semibold se-text-text-secondary se-mb-1 se-block">Category</label>
205
- <input type="text" .value=${tip.config.category || ''} placeholder="Optional"
206
- @input=${(e) => this._handleFieldChange(item.index, 'category', e.target.value)}
207
- class="se-w-full se-p-2 se-rounded se-border se-border-border-primary se-bg-input-field-bg se-text-text-primary se-text-sm" />
208
- </div>
209
-
210
- ${tip.rationale
211
- ? html `
212
- <div>
213
- <span class="se-text-[11px] se-font-semibold se-text-text-secondary se-mb-1 se-block">AI Rationale</span>
214
- <div class="se-p-2 se-rounded se-border se-border-dashed se-border-border-primary se-bg-card-bg se-text-text-secondary se-text-xs se-mb-2">
215
- ${tip.rationale.why}
216
- </div>
217
- </div>
218
- `
219
- : nothing}
220
- </div>
221
- `;
222
- };
223
- this._renderListMode = (items) => {
224
- if (items.length === 0) {
225
- return html `<div class="se-text-center se-py-8 se-px-4 se-text-text-secondary se-text-sm">
226
- No tips configured.
227
- </div>`;
228
- }
229
- return html `
230
- <div class="se-text-[11px] se-font-semibold se-uppercase se-tracking-wider se-text-text-secondary se-mb-2 se-px-1">
231
- TIPS <span class="se-text-text-tertiary se-font-normal">${items.length}</span>
232
- </div>
233
- ${items.map((item) => html `
234
- <div
235
- data-item-key=${item.key}
236
- @click=${() => this._handleItemClick(item.key)}
237
- class="se-p-3 se-rounded-lg se-border se-border-border-primary se-bg-card-bg se-cursor-pointer se-mb-2 se-transition-all hover:se-border-pink-4/40 hover:se-bg-pink-4/5"
238
- >
239
- <div class="se-flex se-items-center se-gap-2">
240
- ${this._renderDetectionBadge(item)}
241
- <span class="se-flex-1 se-overflow-hidden se-text-ellipsis se-whitespace-nowrap se-text-sm se-text-text-primary">
242
- ${item.summary}
243
- </span>
244
- </div>
245
- ${item.trigger !== 'All pages'
246
- ? html `
247
- <div class="se-text-[10px] se-text-text-tertiary se-mt-1">📍 ${item.trigger}</div>
248
- `
249
- : nothing}
250
- ${item.rationale
251
- ? html `
252
- <div class="se-text-[10px] se-text-text-tertiary se-mt-1">WHY: ${item.rationale}</div>
253
- `
254
- : nothing}
255
- </div>
256
- `)}
257
- `;
258
- };
259
- }
260
- createRenderRoot() {
261
- return this;
262
- }
263
- connectedCallback() {
264
- super.connectedCallback();
265
- window.addEventListener('popstate', this._onPopstate);
266
- // Run detection on an interval (matches React's 2s interval)
267
- this._detectionInterval = setInterval(() => this._runDetection(), 2000);
268
- }
269
- disconnectedCallback() {
270
- window.removeEventListener('popstate', this._onPopstate);
271
- if (this._detectionInterval) {
272
- clearInterval(this._detectionInterval);
273
- this._detectionInterval = null;
274
- }
275
- super.disconnectedCallback();
276
- }
277
- firstUpdated() {
278
- this._runDetection();
279
- // No auto-dirty on load — only dirty when user makes changes (matching React behavior).
280
- }
281
- render() {
282
- if (!this.config) {
283
- return html `<div class="se-p-8 se-text-center se-text-text-secondary se-text-sm">Loading...</div>`;
284
- }
285
- const items = flattenItems(this.config);
286
- const editItem = this._editingKey !== null ? items.find((it) => it.key === this._editingKey) : null;
287
- return html `
288
- <div class="se-flex se-flex-col se-h-full">
289
- <!-- Header (no Back button — panel provides that) -->
290
- <div class="se-px-4 se-pt-3 se-pb-1">
291
- <h2 class="se-m-0 se-text-base se-font-semibold se-text-text-primary">Navigation Tips</h2>
292
- <p class="se-m-0 se-mt-0.5 se-text-xs se-text-text-secondary">
293
- ${items.length} tip${items.length !== 1 ? 's' : ''}
294
- </p>
295
- </div>
296
-
297
- <div class="se-flex-1 se-overflow-auto se-p-4">
298
- ${editItem
299
- ? html `
300
- <button type="button" @click=${() => {
301
- this._editingKey = null;
302
- }}
303
- class="se-mb-3 se-py-1 se-px-2 se-rounded se-border-none se-bg-card-bg se-text-text-secondary se-text-xs se-cursor-pointer"
304
- >← Back to list</button>
305
- ${this._renderEditMode(editItem)}
306
- `
307
- : this._renderListMode(items)}
308
- </div>
309
- </div>
310
- `;
311
- }
312
- }
313
- NavEditorLit.properties = {
314
- config: { attribute: false },
315
- onChange: { attribute: false },
316
- _editingKey: { state: true },
317
- _detectionMap: { state: true },
318
- };
319
- customElements.define('se-nav-editor', NavEditorLit);
@@ -1,108 +0,0 @@
1
- /**
2
- * Adaptive Nav - Runtime Module (Lit)
3
- *
4
- * Runtime manifest for the navigation tips accordion adaptive.
5
- * Uses the Lit web component mountable instead of the React one.
6
- * Includes widget-based nav tips and navigation action executors
7
- * (scrollTo, navigate) previously in adaptive-navigation.
8
- */
9
- import type { ActionExecutor, NavConfig, NavigateAction, NavWidgetRuntime, ScrollToAction } from './types';
10
- /**
11
- * Execute a scrollTo action
12
- */
13
- export declare const executeScrollTo: ActionExecutor<ScrollToAction>;
14
- /**
15
- * Try to navigate using the host framework's native router.
16
- * Returns true if a framework router handled the navigation,
17
- * false if no framework was detected (caller should use pushState or location.href).
18
- *
19
- * Using the native router preserves SPA behavior (no full reload),
20
- * layout state, scroll position, and framework-specific features
21
- * (RSC streaming, view transitions, etc.).
22
- */
23
- export declare function navigateWithFrameworkRouter(url: string): boolean;
24
- /**
25
- * Execute a navigate action
26
- */
27
- export declare const executeNavigate: ActionExecutor<NavigateAction>;
28
- /**
29
- * NavWidgetLitMountable — Mounts the `<syntro-nav-tips>` Lit web component.
30
- *
31
- * Drop-in companion to NavMountableWidget that avoids React/ReactDOM entirely.
32
- * Self-registers the custom element on first use.
33
- */
34
- export declare const NavWidgetLitMountable: {
35
- mount(container: HTMLElement, config?: NavConfig & {
36
- runtime?: NavWidgetRuntime;
37
- instanceId?: string;
38
- }): () => void;
39
- };
40
- /**
41
- * All executors provided by this app.
42
- * These are registered with the runtime's ExecutorRegistry.
43
- */
44
- export declare const executors: readonly [{
45
- readonly kind: "navigation:scrollTo";
46
- readonly executor: ActionExecutor<ScrollToAction>;
47
- }, {
48
- readonly kind: "navigation:navigate";
49
- readonly executor: ActionExecutor<NavigateAction>;
50
- }];
51
- /**
52
- * Runtime manifest for adaptive-nav (Lit variant).
53
- *
54
- * Provides:
55
- * - Navigation action executors (scrollTo, navigate)
56
- * - Widget-based nav tips accordion using the Lit web component
57
- */
58
- export declare const runtime: {
59
- id: string;
60
- version: string;
61
- name: string;
62
- description: string;
63
- /**
64
- * Navigation action executors (scrollTo, navigate).
65
- */
66
- executors: readonly [{
67
- readonly kind: "navigation:scrollTo";
68
- readonly executor: ActionExecutor<ScrollToAction>;
69
- }, {
70
- readonly kind: "navigation:navigate";
71
- readonly executor: ActionExecutor<NavigateAction>;
72
- }];
73
- /**
74
- * Widget definitions for the runtime's WidgetRegistry.
75
- */
76
- widgets: {
77
- id: string;
78
- component: {
79
- mount(container: HTMLElement, config?: NavConfig & {
80
- runtime?: NavWidgetRuntime;
81
- instanceId?: string;
82
- }): () => void;
83
- };
84
- metadata: {
85
- name: string;
86
- description: string;
87
- icon: string;
88
- };
89
- }[];
90
- /**
91
- * Extract notify watcher entries from tile config props.
92
- * The runtime evaluates these continuously (even with drawer closed)
93
- * and publishes nav:tip_revealed when triggerWhen transitions false → true.
94
- */
95
- notifyWatchers(props: Record<string, unknown>): {
96
- id: string;
97
- strategy: import("./types").DecisionStrategy<boolean>;
98
- eventName: string;
99
- eventProps: {
100
- tipId: string;
101
- title: string | undefined;
102
- body: string | undefined;
103
- icon: string | undefined;
104
- };
105
- }[];
106
- };
107
- export default runtime;
108
- //# sourceMappingURL=runtime-lit.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtime-lit.d.ts","sourceRoot":"","sources":["../src/runtime-lit.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EACV,cAAc,EAEd,SAAS,EACT,cAAc,EAEd,gBAAgB,EAChB,cAAc,EACf,MAAM,SAAS,CAAC;AAMjB;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,cAAc,CA+B1D,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAgDhE;AAgBD;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,cAAc,CAuC1D,CAAC;AAMF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB;qBAEnB,WAAW,WACb,SAAS,GAAG;QAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;CA2B3E,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;EAGZ,CAAC;AAMX;;;;;;GAMG;AACH,eAAO,MAAM,OAAO;;;;;IAMlB;;OAEG;;;;;;;;IAGH;;OAEG;;;;6BAnEU,WAAW,WACb,SAAS,GAAG;gBAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC;gBAAC,UAAU,CAAC,EAAE,MAAM,CAAA;aAAE;;;;;;;;IA+E1E;;;;OAIG;0BACmB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;CAgB9C,CAAC;AAEF,eAAe,OAAO,CAAC"}
@@ -1,241 +0,0 @@
1
- /**
2
- * Adaptive Nav - Runtime Module (Lit)
3
- *
4
- * Runtime manifest for the navigation tips accordion adaptive.
5
- * Uses the Lit web component mountable instead of the React one.
6
- * Includes widget-based nav tips and navigation action executors
7
- * (scrollTo, navigate) previously in adaptive-navigation.
8
- */
9
- import { registerNavWidgetLit } from './NavWidgetLit';
10
- // ============================================================================
11
- // Navigation Action Executors (merged from adaptive-navigation)
12
- // ============================================================================
13
- /**
14
- * Execute a scrollTo action
15
- */
16
- export const executeScrollTo = async (action, context) => {
17
- const anchorEl = context.resolveAnchor(action.anchorId);
18
- if (!anchorEl) {
19
- console.error(`[adaptive-nav] Anchor not found for scrollTo, skipping: ${action.anchorId.selector}`);
20
- return { cleanup: () => { } };
21
- }
22
- // Scroll to element
23
- anchorEl.scrollIntoView({
24
- behavior: action.behavior ?? 'smooth',
25
- block: action.block ?? 'center',
26
- inline: action.inline ?? 'nearest',
27
- });
28
- context.publishEvent('action.applied', {
29
- id: context.generateId(),
30
- kind: 'navigation:scrollTo',
31
- anchorId: action.anchorId,
32
- behavior: action.behavior ?? 'smooth',
33
- });
34
- return {
35
- cleanup: () => {
36
- // Optionally restore scroll position on revert
37
- },
38
- };
39
- };
40
- /**
41
- * Try to navigate using the host framework's native router.
42
- * Returns true if a framework router handled the navigation,
43
- * false if no framework was detected (caller should use pushState or location.href).
44
- *
45
- * Using the native router preserves SPA behavior (no full reload),
46
- * layout state, scroll position, and framework-specific features
47
- * (RSC streaming, view transitions, etc.).
48
- */
49
- export function navigateWithFrameworkRouter(url) {
50
- if (typeof window === 'undefined')
51
- return false;
52
- const w = window;
53
- // Next.js — window.next.router.push() triggers App Router navigation
54
- // with RSC fetch, layout preservation, and loading states
55
- try {
56
- const nextRouter = w.next?.router;
57
- if (nextRouter?.push) {
58
- nextRouter.push(url);
59
- return true;
60
- }
61
- }
62
- catch {
63
- /* fall through */
64
- }
65
- // Nuxt 3 — useRouter() isn't accessible from outside Vue, but
66
- // $nuxt.$router (Nuxt 2) or window.__NUXT__?.hooks (Nuxt 3) + navigateTo
67
- // aren't reliably exposed. Nuxt 2 exposes $nuxt.$router.push().
68
- try {
69
- if (w.$nuxt?.$router?.push) {
70
- w.$nuxt.$router.push(url);
71
- return true;
72
- }
73
- }
74
- catch {
75
- /* fall through */
76
- }
77
- // Angular — Angular Router isn't exposed on window by default.
78
- // The most reliable approach is to detect Angular and use location.href.
79
- if (w.ng || w.getAllAngularRootElements || document.querySelector('[ng-version]')) {
80
- window.location.href = url;
81
- return true;
82
- }
83
- // SvelteKit — goto() isn't on window, but __SVELTEKIT_DATA__ confirms the framework.
84
- if (w.__SVELTEKIT_DATA__ || document.body?.hasAttribute('data-sveltekit')) {
85
- window.location.href = url;
86
- return true;
87
- }
88
- // Astro (View Transitions) — no client-side router API exposed
89
- if (document.querySelector('[data-astro-transition-fallback]')) {
90
- window.location.href = url;
91
- return true;
92
- }
93
- return false;
94
- }
95
- /**
96
- * Check if a URL is same-origin as the current page.
97
- * Relative URLs (e.g. "/dashboard") are always same-origin.
98
- */
99
- function isSameOrigin(url) {
100
- try {
101
- const parsed = new URL(url, window.location.origin);
102
- return parsed.origin === window.location.origin;
103
- }
104
- catch {
105
- // If URL parsing fails, fall back to full navigation
106
- return false;
107
- }
108
- }
109
- /**
110
- * Execute a navigate action
111
- */
112
- export const executeNavigate = async (action, context) => {
113
- // Validate URL to prevent javascript: URLs
114
- const url = action.url.trim();
115
- if (url.toLowerCase().startsWith('javascript:')) {
116
- throw new Error('javascript: URLs are not allowed');
117
- }
118
- const target = action.target ?? '_self';
119
- context.publishEvent('action.applied', {
120
- id: context.generateId(),
121
- kind: 'navigation:navigate',
122
- url: action.url,
123
- target,
124
- });
125
- if (target === '_blank') {
126
- // Open in new tab
127
- window.open(url, '_blank', 'noopener,noreferrer');
128
- }
129
- else if (!action.forceFullNavigation && isSameOrigin(url)) {
130
- // Try the host framework's native router first (Next.js, Nuxt, Angular, etc.)
131
- // Falls back to pushState for vanilla SPAs, or location.href as last resort.
132
- if (!navigateWithFrameworkRouter(url)) {
133
- window.history.pushState(null, '', url);
134
- window.dispatchEvent(new PopStateEvent('popstate'));
135
- }
136
- }
137
- else {
138
- // Full navigation for cross-origin URLs or when explicitly requested
139
- window.location.href = url;
140
- }
141
- return {
142
- cleanup: () => {
143
- // Navigation cannot be reverted
144
- },
145
- };
146
- };
147
- // ============================================================================
148
- // Lit Mountable Widget
149
- // ============================================================================
150
- /**
151
- * NavWidgetLitMountable — Mounts the `<syntro-nav-tips>` Lit web component.
152
- *
153
- * Drop-in companion to NavMountableWidget that avoids React/ReactDOM entirely.
154
- * Self-registers the custom element on first use.
155
- */
156
- export const NavWidgetLitMountable = {
157
- mount(container, config) {
158
- registerNavWidgetLit();
159
- const el = document.createElement('syntro-nav-tips');
160
- const { runtime, instanceId = 'nav-widget', ...navConfig } = config ?? {
161
- expandBehavior: 'single',
162
- theme: 'auto',
163
- actions: [],
164
- };
165
- // Assign structured props as JS properties (not HTML attributes)
166
- Object.assign(el, {
167
- config: navConfig,
168
- runtime,
169
- instanceId,
170
- });
171
- container.appendChild(el);
172
- return () => el.remove();
173
- },
174
- };
175
- // ============================================================================
176
- // Executor Definitions for Registration
177
- // ============================================================================
178
- /**
179
- * All executors provided by this app.
180
- * These are registered with the runtime's ExecutorRegistry.
181
- */
182
- export const executors = [
183
- { kind: 'navigation:scrollTo', executor: executeScrollTo },
184
- { kind: 'navigation:navigate', executor: executeNavigate },
185
- ];
186
- // ============================================================================
187
- // App Runtime Manifest
188
- // ============================================================================
189
- /**
190
- * Runtime manifest for adaptive-nav (Lit variant).
191
- *
192
- * Provides:
193
- * - Navigation action executors (scrollTo, navigate)
194
- * - Widget-based nav tips accordion using the Lit web component
195
- */
196
- export const runtime = {
197
- id: 'adaptive-nav',
198
- version: '2.0.0',
199
- name: 'Navigation Tips',
200
- description: 'Navigation actions and accordion-based tips with per-item conditional visibility',
201
- /**
202
- * Navigation action executors (scrollTo, navigate).
203
- */
204
- executors,
205
- /**
206
- * Widget definitions for the runtime's WidgetRegistry.
207
- */
208
- widgets: [
209
- {
210
- id: 'adaptive-nav:tips',
211
- component: NavWidgetLitMountable,
212
- metadata: {
213
- name: 'Navigation Tips',
214
- description: 'Accordion of contextual navigation tips with per-item visibility',
215
- icon: '\u{1F9ED}',
216
- },
217
- },
218
- ],
219
- /**
220
- * Extract notify watcher entries from tile config props.
221
- * The runtime evaluates these continuously (even with drawer closed)
222
- * and publishes nav:tip_revealed when triggerWhen transitions false → true.
223
- */
224
- notifyWatchers(props) {
225
- const actions = (props.actions ?? []);
226
- return actions
227
- .filter((a) => a.notify && a.triggerWhen)
228
- .map((a) => ({
229
- id: `nav:${a.config.id}`,
230
- strategy: a.triggerWhen,
231
- eventName: 'nav:tip_revealed',
232
- eventProps: {
233
- tipId: a.config.id,
234
- title: a.notify.title,
235
- body: a.notify.body,
236
- icon: a.notify.icon,
237
- },
238
- }));
239
- },
240
- };
241
- export default runtime;