@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
package/dist/NavWidget.js DELETED
@@ -1,476 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * Adaptive Nav - NavWidget Component
4
- *
5
- * React component that renders a collapsible navigation tips accordion
6
- * with per-item conditional visibility based on triggerWhen decision strategies.
7
- *
8
- * Demonstrates the compositional action pattern where child actions
9
- * (nav:tip) serve as configuration data for the parent widget.
10
- */
11
- import { purple, slateGrey } from '@syntro/design-system/tokens';
12
- import React, { useCallback, useEffect, useMemo, useReducer, useState } from 'react';
13
- import { createRoot } from 'react-dom/client';
14
- import { navigateWithFrameworkRouter } from './runtime';
15
- // ============================================================================
16
- // Emoji → Lucide SVG inline mapping (no lucide-react dependency)
17
- // ============================================================================
18
- const EMOJI_SVG_MAP = {
19
- '💵': '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="12" x="2" y="6" rx="2"/><circle cx="12" cy="12" r="2"/><path d="M6 12h.01M18 12h.01"/></svg>',
20
- '🏛️': '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" x2="21" y1="22" y2="22"/><line x1="6" x2="6" y1="18" y2="11"/><line x1="10" x2="10" y1="18" y2="11"/><line x1="14" x2="14" y1="18" y2="11"/><line x1="18" x2="18" y1="18" y2="11"/><polygon points="12 2 20 7 4 7"/></svg>',
21
- '⏭️': '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 4 15 12 5 20 5 4"/><line x1="19" x2="19" y1="5" y2="19"/></svg>',
22
- '➡️': '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>',
23
- '💡': '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/></svg>',
24
- '💰': '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="12" x="2" y="6" rx="2"/><circle cx="12" cy="12" r="2"/><path d="M6 12h.01M18 12h.01"/></svg>',
25
- '📋': '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M12 11h4"/><path d="M12 16h4"/><path d="M8 11h.01"/><path d="M8 16h.01"/></svg>',
26
- '✅': '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/></svg>',
27
- '⚠️': '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>',
28
- };
29
- function renderIcon(emoji) {
30
- return EMOJI_SVG_MAP[emoji] ?? escapeHtml(emoji);
31
- }
32
- // ============================================================================
33
- // Sanitization
34
- // ============================================================================
35
- function escapeHtml(str) {
36
- return str
37
- .replace(/&/g, '&amp;')
38
- .replace(/</g, '&lt;')
39
- .replace(/>/g, '&gt;')
40
- .replace(/"/g, '&quot;')
41
- .replace(/'/g, '&#39;');
42
- }
43
- // ============================================================================
44
- // Styles
45
- // ============================================================================
46
- const baseStyles = {
47
- container: {
48
- fontFamily: 'var(--sc-font-family, system-ui, -apple-system, sans-serif)',
49
- maxWidth: '100%',
50
- overflow: 'hidden',
51
- },
52
- accordion: {
53
- display: 'flex',
54
- flexDirection: 'column',
55
- gap: 'var(--sc-content-item-gap, 6px)',
56
- },
57
- item: {
58
- borderRadius: 'var(--sc-content-border-radius, 8px)',
59
- overflow: 'hidden',
60
- transition: 'box-shadow 0.2s ease',
61
- },
62
- header: {
63
- display: 'flex',
64
- alignItems: 'center',
65
- gap: '8px',
66
- width: '100%',
67
- padding: 'var(--sc-content-item-padding, 12px 16px)',
68
- border: 'none',
69
- cursor: 'pointer',
70
- fontSize: 'var(--sc-content-item-font-size, 15px)',
71
- fontWeight: 500,
72
- fontFamily: 'inherit',
73
- textAlign: 'left',
74
- transition: 'background-color 0.15s ease',
75
- },
76
- chevron: {
77
- fontSize: '20px',
78
- transition: 'transform 0.2s ease',
79
- marginLeft: 'auto',
80
- flexShrink: 0,
81
- color: 'var(--sc-content-chevron-color, currentColor)',
82
- },
83
- icon: {
84
- fontSize: '16px',
85
- flexShrink: 0,
86
- },
87
- body: {
88
- overflow: 'hidden',
89
- transition: 'max-height 0.25s ease, padding-bottom 0.25s ease',
90
- padding: 'var(--sc-content-body-padding, 0 16px 12px 16px)',
91
- },
92
- description: {
93
- fontSize: 'var(--sc-content-body-font-size, 14px)',
94
- lineHeight: '1.5',
95
- margin: 0,
96
- },
97
- linkButton: {
98
- display: 'inline-flex',
99
- alignItems: 'center',
100
- gap: '4px',
101
- marginTop: '10px',
102
- padding: '6px 12px',
103
- borderRadius: '6px',
104
- textDecoration: 'none',
105
- fontSize: '13px',
106
- fontWeight: 500,
107
- cursor: 'pointer',
108
- border: 'none',
109
- transition: 'background-color 0.15s ease',
110
- },
111
- categoryHeader: {
112
- fontSize: 'var(--sc-content-category-font-size, 12px)',
113
- fontWeight: 600,
114
- textTransform: 'uppercase',
115
- letterSpacing: '0.05em',
116
- padding: 'var(--sc-content-category-padding, 8px 4px 4px 4px)',
117
- },
118
- emptyState: {
119
- fontSize: '13px',
120
- padding: '16px',
121
- textAlign: 'center',
122
- },
123
- };
124
- const themeStyles = {
125
- light: {
126
- container: {
127
- backgroundColor: 'transparent',
128
- color: 'inherit',
129
- },
130
- item: {
131
- backgroundColor: 'var(--sc-content-background)',
132
- border: 'var(--sc-content-border)',
133
- },
134
- itemExpanded: {
135
- boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08)',
136
- },
137
- header: {
138
- backgroundColor: 'transparent',
139
- color: 'var(--sc-content-text-color)',
140
- },
141
- headerHover: {
142
- backgroundColor: 'var(--sc-content-background-hover)',
143
- },
144
- body: {
145
- color: 'var(--sc-content-text-secondary-color)',
146
- },
147
- linkButton: {
148
- // purple[4] = #6a59ce — design system primary purple, used as fallback when --sc-color-primary is not set
149
- backgroundColor: `var(--sc-color-primary, ${purple[4]})`,
150
- color: '#ffffff',
151
- },
152
- categoryHeader: {
153
- color: slateGrey[7],
154
- },
155
- emptyState: {
156
- color: slateGrey[8],
157
- },
158
- },
159
- dark: {
160
- container: {
161
- backgroundColor: 'transparent',
162
- color: 'inherit',
163
- },
164
- item: {
165
- backgroundColor: 'var(--sc-content-background)',
166
- border: 'var(--sc-content-border)',
167
- },
168
- itemExpanded: {
169
- boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
170
- },
171
- header: {
172
- backgroundColor: 'transparent',
173
- color: 'var(--sc-content-text-color)',
174
- },
175
- headerHover: {
176
- backgroundColor: 'var(--sc-content-background-hover)',
177
- },
178
- body: {
179
- color: 'var(--sc-content-text-secondary-color)',
180
- },
181
- linkButton: {
182
- // purple[4] = #6a59ce — design system primary purple, used as fallback when --sc-color-primary is not set
183
- backgroundColor: `var(--sc-color-primary, ${purple[4]})`,
184
- color: '#ffffff',
185
- },
186
- categoryHeader: {
187
- color: slateGrey[8],
188
- },
189
- emptyState: {
190
- color: slateGrey[7],
191
- },
192
- },
193
- };
194
- // ============================================================================
195
- // Helpers
196
- // ============================================================================
197
- /** Check if any of the given routes match the current page pathname */
198
- function routeMatchesCurrent(routes) {
199
- if (typeof window === 'undefined')
200
- return false;
201
- const current = window.location.pathname;
202
- return routes.some((route) => {
203
- // Strip query/hash from route if present
204
- const routePath = route.split('?')[0].split('#')[0];
205
- // Exact match or glob pattern (** suffix)
206
- if (routePath.endsWith('/**')) {
207
- return current.startsWith(routePath.slice(0, -3));
208
- }
209
- return current === routePath;
210
- });
211
- }
212
- /** Apply a brief pulse animation to an element, then remove it */
213
- function pulseElement(el) {
214
- const keyframes = [
215
- { boxShadow: '0 0 0 0 rgba(13, 148, 136, 0.5)' },
216
- { boxShadow: '0 0 0 8px rgba(13, 148, 136, 0)' },
217
- ];
218
- el.animate(keyframes, { duration: 600, iterations: 3, easing: 'ease-out' });
219
- }
220
- function NavTipItem({ item, isExpanded, isLast, onToggle, onNavigate, onFocusAnchor, theme, }) {
221
- const [isHovered, setIsHovered] = useState(false);
222
- const colors = themeStyles[theme];
223
- const { title, description, href, icon, external, anchor } = item.config;
224
- const itemStyle = {
225
- ...baseStyles.item,
226
- ...colors.item,
227
- ...(isExpanded ? colors.itemExpanded : {}),
228
- ...(!isLast ? { borderBottom: 'var(--sc-content-item-divider, none)' } : {}),
229
- };
230
- const headerStyle = {
231
- ...baseStyles.header,
232
- ...colors.header,
233
- ...(isHovered ? colors.headerHover : {}),
234
- };
235
- const chevronStyle = {
236
- ...baseStyles.chevron,
237
- transform: isExpanded ? 'rotate(90deg)' : 'rotate(0deg)',
238
- };
239
- const bodyStyle = {
240
- ...baseStyles.body,
241
- ...colors.body,
242
- maxHeight: isExpanded ? '500px' : '0',
243
- paddingBottom: isExpanded ? '16px' : '0',
244
- };
245
- // Determine the effective navigation target from anchor or legacy href
246
- const effectiveHref = anchor
247
- ? Array.isArray(anchor.route)
248
- ? anchor.route[0]
249
- : anchor.route
250
- : href;
251
- // Same-page check: anchor exists, selector is meaningful, and route matches current page
252
- const isSamePage = anchor
253
- ? routeMatchesCurrent(Array.isArray(anchor.route) ? anchor.route : [anchor.route])
254
- : effectiveHref
255
- ? routeMatchesCurrent([effectiveHref])
256
- : false;
257
- const hasSelector = anchor?.selector && anchor.selector !== '*';
258
- const isFocusAction = isSamePage && hasSelector;
259
- const hasAction = !!effectiveHref || isFocusAction;
260
- const handleLinkClick = (e) => {
261
- e.preventDefault();
262
- e.stopPropagation();
263
- if (isFocusAction && anchor) {
264
- onFocusAnchor(anchor);
265
- }
266
- else if (effectiveHref) {
267
- onNavigate(effectiveHref, external ?? false);
268
- }
269
- };
270
- // CTA label
271
- const ctaLabel = isFocusAction ? `Focus \u2192` : external ? `Go \u2197` : `Go \u2192`;
272
- return (_jsxs("div", { style: itemStyle, "data-nav-tip-id": item.config.id, children: [_jsxs("button", { type: "button", style: headerStyle, onClick: onToggle, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), "aria-expanded": isExpanded, children: [icon && (
273
- // biome-ignore lint/security/noDangerouslySetInnerHtml: renderIcon returns sanitized SVG from EMOJI_SVG_MAP or escapeHtml
274
- _jsx("span", { style: baseStyles.icon, dangerouslySetInnerHTML: { __html: renderIcon(icon) } })), _jsx("span", { children: title }), _jsx("span", { style: chevronStyle, children: '\u203A' })] }), _jsxs("div", { style: bodyStyle, "aria-hidden": !isExpanded, children: [_jsx("p", { style: baseStyles.description, children: description }), hasAction && (_jsx("a", { href: effectiveHref || '#', onClick: handleLinkClick, style: { ...baseStyles.linkButton, ...colors.linkButton }, target: external ? '_blank' : undefined, rel: external ? 'noopener noreferrer' : undefined, children: ctaLabel }))] })] }));
275
- }
276
- // ============================================================================
277
- // NavWidget Component
278
- // ============================================================================
279
- /**
280
- * NavWidget - Renders a collapsible navigation tips accordion.
281
- *
282
- * This component demonstrates the compositional action pattern:
283
- * - Parent (NavWidget) receives `config.actions` array
284
- * - Each action has optional `triggerWhen` for per-item visibility
285
- * - Parent evaluates triggerWhen and filters visible tips
286
- * - Parent manages expand state and re-rendering on context changes
287
- */
288
- export function NavWidget({ config, runtime, instanceId }) {
289
- // Force re-render when context/accumulator changes.
290
- const [renderTick, forceUpdate] = useReducer((x) => x + 1, 0);
291
- // Track expanded tip IDs
292
- const [expandedIds, setExpandedIds] = useState(new Set());
293
- // Subscribe to context changes for reactive updates
294
- useEffect(() => {
295
- const unsubscribe = runtime.context.subscribe(() => {
296
- forceUpdate();
297
- });
298
- return unsubscribe;
299
- }, [runtime.context]);
300
- // Subscribe to accumulator changes for event_count-based triggerWhen
301
- useEffect(() => {
302
- if (!runtime.accumulator?.subscribe)
303
- return;
304
- return runtime.accumulator.subscribe(() => {
305
- forceUpdate();
306
- });
307
- }, [runtime.accumulator]);
308
- // Filter visible tips based on per-item triggerWhen
309
- // biome-ignore lint/correctness/useExhaustiveDependencies: renderTick is intentionally included to force re-evaluation when the runtime's mutable context changes (subscribed above via forceUpdate)
310
- const visibleTips = useMemo(() => config.actions.filter((tip) => {
311
- if (!tip.triggerWhen)
312
- return true;
313
- try {
314
- const result = runtime.evaluateSync(tip.triggerWhen);
315
- return result.value;
316
- }
317
- catch {
318
- // If strategy evaluation fails, hide the tip (fail-closed)
319
- return false;
320
- }
321
- }), [config.actions, runtime, renderTick]);
322
- // Group by category
323
- const categoryGroups = useMemo(() => {
324
- const groups = new Map();
325
- for (const tip of visibleTips) {
326
- const cat = tip.config.category;
327
- if (!groups.has(cat)) {
328
- groups.set(cat, []);
329
- }
330
- groups.get(cat).push(tip);
331
- }
332
- return groups;
333
- }, [visibleTips]);
334
- // Check if any items have categories
335
- const hasCategories = useMemo(() => visibleTips.some((t) => t.config.category), [visibleTips]);
336
- // Resolve theme (auto → detect system preference)
337
- const resolvedTheme = useMemo(() => {
338
- if (config.theme && config.theme !== 'auto')
339
- return config.theme;
340
- if (typeof window !== 'undefined') {
341
- return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
342
- }
343
- return 'light';
344
- }, [config.theme]);
345
- // Handle tip toggle
346
- const handleToggle = useCallback((id) => {
347
- setExpandedIds((prev) => {
348
- const wasExpanded = prev.has(id);
349
- let next;
350
- if (config.expandBehavior === 'single') {
351
- // In single mode, emit collapse events for any previously-expanded tips
352
- for (const prevId of prev) {
353
- if (prevId !== id) {
354
- runtime.events.publish('nav:toggled', {
355
- instanceId,
356
- tipId: prevId,
357
- expanded: false,
358
- timestamp: Date.now(),
359
- });
360
- }
361
- }
362
- next = wasExpanded ? new Set() : new Set([id]);
363
- }
364
- else {
365
- next = new Set(prev);
366
- if (wasExpanded) {
367
- next.delete(id);
368
- }
369
- else {
370
- next.add(id);
371
- }
372
- }
373
- // Emit event for the clicked tip using fresh state from the updater
374
- runtime.events.publish('nav:toggled', {
375
- instanceId,
376
- tipId: id,
377
- expanded: !wasExpanded,
378
- timestamp: Date.now(),
379
- });
380
- return next;
381
- });
382
- }, [config.expandBehavior, runtime.events, instanceId]);
383
- // Handle navigation with event publishing
384
- const handleNavigate = useCallback((href, external) => {
385
- // Reject dangerous URIs to prevent XSS
386
- const normalizedHref = href.trim().toLowerCase();
387
- if (normalizedHref.startsWith('javascript:') || normalizedHref.startsWith('data:')) {
388
- return;
389
- }
390
- runtime.events.publish('nav:tip_clicked', {
391
- instanceId,
392
- href,
393
- external,
394
- timestamp: Date.now(),
395
- });
396
- if (external) {
397
- window.open(href, '_blank', 'noopener,noreferrer');
398
- }
399
- else {
400
- // Try the host framework's native router first (Next.js, Nuxt, etc.)
401
- // Falls back to pushState for vanilla SPAs.
402
- const url = new URL(href, window.location.origin);
403
- url.search = window.location.search;
404
- if (!navigateWithFrameworkRouter(url.toString())) {
405
- window.history.pushState(null, '', url.toString());
406
- window.dispatchEvent(new PopStateEvent('popstate'));
407
- }
408
- }
409
- }, [runtime.events, instanceId]);
410
- // Handle same-page anchor focus: scroll + pulse + focus
411
- const handleFocusAnchor = useCallback((anchor) => {
412
- const el = document.querySelector(anchor.selector);
413
- if (!(el instanceof HTMLElement))
414
- return;
415
- runtime.events.publish('nav:tip_focused', {
416
- instanceId,
417
- selector: anchor.selector,
418
- route: anchor.route,
419
- timestamp: Date.now(),
420
- });
421
- el.scrollIntoView({ behavior: 'smooth', block: 'center' });
422
- pulseElement(el);
423
- // Focus after scroll completes
424
- setTimeout(() => el.focus(), 400);
425
- }, [runtime.events, instanceId]);
426
- // Compute container styles
427
- const containerStyle = {
428
- ...baseStyles.container,
429
- ...themeStyles[resolvedTheme].container,
430
- };
431
- const categoryHeaderStyle = {
432
- ...baseStyles.categoryHeader,
433
- ...themeStyles[resolvedTheme].categoryHeader,
434
- };
435
- const emptyStateStyle = {
436
- ...baseStyles.emptyState,
437
- ...themeStyles[resolvedTheme].emptyState,
438
- };
439
- // Render a list of nav tip items
440
- const renderItems = (items) => items.map((tip, index) => (_jsx(NavTipItem, { item: tip, isExpanded: expandedIds.has(tip.config.id), isLast: index === items.length - 1, onToggle: () => handleToggle(tip.config.id), onNavigate: handleNavigate, onFocusAnchor: handleFocusAnchor, theme: resolvedTheme }, tip.config.id)));
441
- // Empty state
442
- if (visibleTips.length === 0) {
443
- return (_jsx("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-nav", children: _jsx("div", { style: emptyStateStyle, children: "You're all set for now! We'll share helpful tips here when they're relevant to what you're doing." }) }));
444
- }
445
- return (_jsx("div", { style: containerStyle, "data-adaptive-id": instanceId, "data-adaptive-type": "adaptive-nav", children: _jsx("div", { style: baseStyles.accordion, children: hasCategories
446
- ? Array.from(categoryGroups.entries()).map(([category, items]) => (_jsxs(React.Fragment, { children: [category && (_jsx("div", { style: categoryHeaderStyle, "data-category-header": category, children: category })), renderItems(items)] }, category ?? '__ungrouped')))
447
- : renderItems(visibleTips) }) }));
448
- }
449
- // ============================================================================
450
- // Mountable Widget Interface
451
- // ============================================================================
452
- /**
453
- * Mountable widget interface for the runtime's WidgetRegistry.
454
- */
455
- export const NavMountableWidget = {
456
- mount(container, config) {
457
- const { runtime, instanceId = 'nav-widget', ...navConfig } = config || {
458
- expandBehavior: 'single',
459
- theme: 'auto',
460
- actions: [],
461
- };
462
- // React rendering when runtime + ReactDOM are available
463
- if (runtime && typeof createRoot === 'function') {
464
- const root = createRoot(container);
465
- root.render(React.createElement(NavWidget, {
466
- config: navConfig,
467
- runtime: runtime,
468
- instanceId,
469
- }));
470
- return () => {
471
- root.unmount();
472
- };
473
- }
474
- },
475
- };
476
- export default NavWidget;