@syntrologie/adapt-nav 2.8.0-canary.31 → 2.8.0-canary.310

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 (144) hide show
  1. package/dist/NavWidgetLit.d.ts +56 -0
  2. package/dist/NavWidgetLit.d.ts.map +1 -0
  3. package/dist/NavWidgetLit.editable.d.ts +151 -0
  4. package/dist/NavWidgetLit.editable.d.ts.map +1 -0
  5. package/dist/NavWidgetLit.test.d.ts +8 -0
  6. package/dist/NavWidgetLit.test.d.ts.map +1 -0
  7. package/dist/chunk-SX36IHRC.js +640 -0
  8. package/dist/chunk-SX36IHRC.js.map +7 -0
  9. package/dist/editor.d.ts +66 -21
  10. package/dist/editor.d.ts.map +1 -1
  11. package/dist/editor.js +5627 -307
  12. package/dist/editor.js.map +7 -0
  13. package/dist/nav-item-editor.d.ts +43 -0
  14. package/dist/nav-item-editor.d.ts.map +1 -0
  15. package/dist/resolveNavTarget.d.ts +61 -0
  16. package/dist/resolveNavTarget.d.ts.map +1 -0
  17. package/dist/resolveNavTarget.test.d.ts +2 -0
  18. package/dist/resolveNavTarget.test.d.ts.map +1 -0
  19. package/dist/runtime.d.ts +22 -6
  20. package/dist/runtime.d.ts.map +1 -1
  21. package/dist/runtime.js +643 -142
  22. package/dist/runtime.js.map +7 -0
  23. package/dist/schema.d.ts +316 -174
  24. package/dist/schema.d.ts.map +1 -1
  25. package/dist/schema.js +155 -125
  26. package/dist/schema.js.map +7 -0
  27. package/dist/types.d.ts +7 -0
  28. package/dist/types.d.ts.map +1 -1
  29. package/package.json +12 -16
  30. package/dist/NavWidget.d.ts +0 -31
  31. package/dist/NavWidget.d.ts.map +0 -1
  32. package/dist/NavWidget.js +0 -491
  33. package/dist/cdn.d.ts +0 -62
  34. package/dist/cdn.d.ts.map +0 -1
  35. package/dist/cdn.js +0 -48
  36. package/dist/summarize.js +0 -51
  37. package/dist/types.js +0 -18
  38. package/node_modules/@syntro/design-system/README.md +0 -335
  39. package/node_modules/@syntro/design-system/dist/assets/syntrologie-logo.svg +0 -21
  40. package/node_modules/@syntro/design-system/dist/assets/syntrologie-logomark.svg +0 -10
  41. package/node_modules/@syntro/design-system/dist/index.d.ts +0 -8
  42. package/node_modules/@syntro/design-system/dist/index.d.ts.map +0 -1
  43. package/node_modules/@syntro/design-system/dist/index.js +0 -7
  44. package/node_modules/@syntro/design-system/dist/tailwind-preset.d.ts +0 -19
  45. package/node_modules/@syntro/design-system/dist/tailwind-preset.d.ts.map +0 -1
  46. package/node_modules/@syntro/design-system/dist/tailwind-preset.js +0 -453
  47. package/node_modules/@syntro/design-system/dist/tokens/colors.css +0 -464
  48. package/node_modules/@syntro/design-system/dist/tokens/colors.d.ts +0 -874
  49. package/node_modules/@syntro/design-system/dist/tokens/colors.d.ts.map +0 -1
  50. package/node_modules/@syntro/design-system/dist/tokens/colors.js +0 -564
  51. package/node_modules/@syntro/design-system/dist/tokens/effects.css +0 -43
  52. package/node_modules/@syntro/design-system/dist/tokens/effects.d.ts +0 -85
  53. package/node_modules/@syntro/design-system/dist/tokens/effects.d.ts.map +0 -1
  54. package/node_modules/@syntro/design-system/dist/tokens/effects.js +0 -77
  55. package/node_modules/@syntro/design-system/dist/tokens/index.d.ts +0 -10
  56. package/node_modules/@syntro/design-system/dist/tokens/index.d.ts.map +0 -1
  57. package/node_modules/@syntro/design-system/dist/tokens/index.js +0 -9
  58. package/node_modules/@syntro/design-system/package.json +0 -55
  59. package/node_modules/@syntro/design-system/src/assets/syntrologie-logo.svg +0 -21
  60. package/node_modules/@syntro/design-system/src/assets/syntrologie-logomark.svg +0 -10
  61. package/node_modules/@syntrologie/sdk-contracts/dist/index.d.ts +0 -129
  62. package/node_modules/@syntrologie/sdk-contracts/dist/index.js +0 -15
  63. package/node_modules/@syntrologie/sdk-contracts/dist/schemas.d.ts +0 -2225
  64. package/node_modules/@syntrologie/sdk-contracts/dist/schemas.js +0 -162
  65. package/node_modules/@syntrologie/sdk-contracts/package.json +0 -33
  66. package/node_modules/@syntrologie/shared-editor-ui/dist/cn.d.ts +0 -2
  67. package/node_modules/@syntrologie/shared-editor-ui/dist/cn.d.ts.map +0 -1
  68. package/node_modules/@syntrologie/shared-editor-ui/dist/cn.js +0 -3
  69. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.d.ts +0 -34
  70. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.d.ts.map +0 -1
  71. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.js +0 -158
  72. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.d.ts +0 -7
  73. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.d.ts.map +0 -1
  74. package/node_modules/@syntrologie/shared-editor-ui/dist/components/BeforeAfterToggle.js +0 -9
  75. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts +0 -23
  76. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts.map +0 -1
  77. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.js +0 -40
  78. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts +0 -7
  79. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts.map +0 -1
  80. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.js +0 -22
  81. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSection.d.ts +0 -8
  82. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSection.d.ts.map +0 -1
  83. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DismissedSection.js +0 -9
  84. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.d.ts +0 -7
  85. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.d.ts.map +0 -1
  86. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditBackButton.js +0 -4
  87. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBody.d.ts +0 -7
  88. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBody.d.ts.map +0 -1
  89. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorBody.js +0 -4
  90. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.d.ts +0 -13
  91. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.d.ts.map +0 -1
  92. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorCard.js +0 -15
  93. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.d.ts +0 -7
  94. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.d.ts.map +0 -1
  95. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorFooter.js +0 -4
  96. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeader.d.ts +0 -9
  97. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeader.d.ts.map +0 -1
  98. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorHeader.js +0 -4
  99. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.d.ts +0 -8
  100. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.d.ts.map +0 -1
  101. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorInput.js +0 -8
  102. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayout.d.ts +0 -7
  103. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayout.d.ts.map +0 -1
  104. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorLayout.js +0 -4
  105. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts +0 -25
  106. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts.map +0 -1
  107. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.js +0 -379
  108. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.d.ts +0 -8
  109. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.d.ts.map +0 -1
  110. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorSelect.js +0 -8
  111. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.d.ts +0 -8
  112. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.d.ts.map +0 -1
  113. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorTextarea.js +0 -17
  114. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.d.ts +0 -32
  115. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.d.ts.map +0 -1
  116. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.js +0 -85
  117. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyState.d.ts +0 -6
  118. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyState.d.ts.map +0 -1
  119. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EmptyState.js +0 -4
  120. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeader.d.ts +0 -8
  121. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeader.d.ts.map +0 -1
  122. package/node_modules/@syntrologie/shared-editor-ui/dist/components/GroupHeader.js +0 -5
  123. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts +0 -12
  124. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts.map +0 -1
  125. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.js +0 -40
  126. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts +0 -26
  127. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts.map +0 -1
  128. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.js +0 -202
  129. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useElementRect.d.ts +0 -8
  130. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useElementRect.d.ts.map +0 -1
  131. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useElementRect.js +0 -46
  132. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts +0 -24
  133. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts.map +0 -1
  134. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.js +0 -86
  135. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts +0 -34
  136. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts.map +0 -1
  137. package/node_modules/@syntrologie/shared-editor-ui/dist/index.js +0 -25
  138. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/elementChainRecommender.d.ts +0 -37
  139. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/elementChainRecommender.d.ts.map +0 -1
  140. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/elementChainRecommender.js +0 -52
  141. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/selectorGenerator.d.ts +0 -22
  142. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/selectorGenerator.d.ts.map +0 -1
  143. package/node_modules/@syntrologie/shared-editor-ui/dist/utils/selectorGenerator.js +0 -143
  144. package/node_modules/@syntrologie/shared-editor-ui/package.json +0 -45
package/dist/runtime.js CHANGED
@@ -1,154 +1,655 @@
1
- /**
2
- * Adaptive Nav - Runtime Module
3
- *
4
- * Runtime manifest for the navigation tips accordion adaptive.
5
- * Includes widget-based nav tips and navigation action executors
6
- * (scrollTo, navigate) previously in adaptive-navigation.
7
- */
8
- import { NavMountableWidget } from './NavWidget';
9
- // ============================================================================
10
- // Navigation Action Executors (merged from adaptive-navigation)
11
- // ============================================================================
12
- /**
13
- * Execute a scrollTo action
14
- */
15
- export const executeScrollTo = async (action, context) => {
16
- const anchorEl = context.resolveAnchor(action.anchorId);
17
- if (!anchorEl) {
18
- console.error(`[adaptive-nav] Anchor not found for scrollTo, skipping: ${action.anchorId.selector}`);
19
- return { cleanup: () => { } };
1
+ import {
2
+ __privateAdd,
3
+ __privateGet,
4
+ __privateMethod,
5
+ __privateSet,
6
+ normalizeRoute,
7
+ renderIcon,
8
+ routesMatch,
9
+ stripMountPlumbing
10
+ } from "./chunk-SX36IHRC.js";
11
+
12
+ // src/NavWidgetLit.ts
13
+ import { html, LitElement, nothing } from "lit";
14
+ import { styleMap } from "lit/directives/style-map.js";
15
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
16
+
17
+ // src/resolveNavTarget.ts
18
+ function resolveNavTarget(args) {
19
+ const { href, external, windowOrigin, isIframe } = args;
20
+ const isOpaqueOrigin = windowOrigin === "null";
21
+ if (isIframe || isOpaqueOrigin) {
22
+ return { kind: "open", url: href };
23
+ }
24
+ if (external) {
25
+ return { kind: "open", url: href };
26
+ }
27
+ let url;
28
+ try {
29
+ url = new URL(href, windowOrigin);
30
+ } catch {
31
+ return { kind: "fullnav", url: href };
32
+ }
33
+ if (url.origin !== windowOrigin) {
34
+ return { kind: "fullnav", url: url.toString() };
35
+ }
36
+ return { kind: "spa", url };
37
+ }
38
+ function detectIsIframe() {
39
+ if (typeof window === "undefined") return false;
40
+ try {
41
+ return window !== window.top;
42
+ } catch {
43
+ return true;
44
+ }
45
+ }
46
+
47
+ // src/NavWidgetLit.ts
48
+ var TOKEN_PURPLE_4 = "#6a59ce";
49
+ var TOKEN_SLATE_GREY_7 = "#677384";
50
+ var TOKEN_SLATE_GREY_8 = "#87919f";
51
+ function escapeHtml(str) {
52
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
53
+ }
54
+ function renderIcon2(emoji) {
55
+ return renderIcon(emoji) || escapeHtml(emoji);
56
+ }
57
+ function routeMatchesCurrent(routes) {
58
+ if (typeof window === "undefined") return false;
59
+ let canonicalCurrent;
60
+ try {
61
+ canonicalCurrent = normalizeRoute(window.location.pathname);
62
+ } catch {
63
+ return false;
64
+ }
65
+ return routes.some((route) => {
66
+ if (route.endsWith("/**")) {
67
+ const prefix = route.slice(0, -3);
68
+ try {
69
+ const canonicalPrefix = prefix ? normalizeRoute(prefix) : "";
70
+ return canonicalCurrent.toLowerCase().startsWith(canonicalPrefix.toLowerCase());
71
+ } catch {
72
+ return false;
73
+ }
74
+ }
75
+ try {
76
+ return routesMatch(normalizeRoute(route), canonicalCurrent);
77
+ } catch {
78
+ return false;
79
+ }
80
+ });
81
+ }
82
+ function pulseElement(el) {
83
+ const keyframes = [
84
+ { boxShadow: "0 0 0 0 rgba(13, 148, 136, 0.5)" },
85
+ { boxShadow: "0 0 0 8px rgba(13, 148, 136, 0)" }
86
+ ];
87
+ el.animate(keyframes, { duration: 600, iterations: 3, easing: "ease-out" });
88
+ }
89
+ function resolveTheme(theme) {
90
+ if (theme === "dark") return "dark";
91
+ if (theme === "light") return "light";
92
+ if (typeof window !== "undefined") {
93
+ return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
94
+ }
95
+ return "light";
96
+ }
97
+ var _contextUnsub, _accumulatorUnsub, _NavWidgetLit_instances, subscribeRuntime_fn, unsubscribeRuntime_fn, getVisibleTips_fn, getResolvedTheme_fn, handleToggle_fn, handleNavigate_fn, handleFocusAnchor_fn, publishEvent_fn, renderTipItem_fn;
98
+ var NavWidgetLit = class extends LitElement {
99
+ constructor() {
100
+ super(...arguments);
101
+ __privateAdd(this, _NavWidgetLit_instances);
102
+ // ---------- Public properties --------------------------------------------
103
+ this.config = { expandBehavior: "single", theme: "auto", actions: [] };
104
+ this.runtime = void 0;
105
+ this.instanceId = "nav-widget";
106
+ // ---------- Internal state -----------------------------------------------
107
+ /** @internal */
108
+ this._expandedIds = /* @__PURE__ */ new Set();
109
+ /** @internal */
110
+ this._renderTick = 0;
111
+ /** @internal */
112
+ this._hoveredId = null;
113
+ // ---------- Private subscriptions ----------------------------------------
114
+ __privateAdd(this, _contextUnsub, null);
115
+ __privateAdd(this, _accumulatorUnsub, null);
116
+ }
117
+ // ---------- No shadow DOM — inherit host CSS variables --------------------
118
+ createRenderRoot() {
119
+ return this;
120
+ }
121
+ // ---------- Lifecycle: connectedCallback ---------------------------------
122
+ connectedCallback() {
123
+ super.connectedCallback();
124
+ __privateMethod(this, _NavWidgetLit_instances, subscribeRuntime_fn).call(this);
125
+ }
126
+ // ---------- Lifecycle: disconnectedCallback ------------------------------
127
+ disconnectedCallback() {
128
+ super.disconnectedCallback();
129
+ __privateMethod(this, _NavWidgetLit_instances, unsubscribeRuntime_fn).call(this);
130
+ }
131
+ // ---------- Lifecycle: updated -------------------------------------------
132
+ updated(changed) {
133
+ if (changed.has("runtime")) {
134
+ __privateMethod(this, _NavWidgetLit_instances, unsubscribeRuntime_fn).call(this);
135
+ __privateMethod(this, _NavWidgetLit_instances, subscribeRuntime_fn).call(this);
20
136
  }
21
- // Scroll to element
22
- anchorEl.scrollIntoView({
23
- behavior: action.behavior ?? 'smooth',
24
- block: action.block ?? 'center',
25
- inline: action.inline ?? 'nearest',
137
+ }
138
+ // ---------- Render --------------------------------------------------------
139
+ render() {
140
+ const visibleTips = __privateMethod(this, _NavWidgetLit_instances, getVisibleTips_fn).call(this);
141
+ const theme = __privateMethod(this, _NavWidgetLit_instances, getResolvedTheme_fn).call(this);
142
+ const containerStyle = styleMap({
143
+ fontFamily: "var(--sc-font-family, system-ui, -apple-system, sans-serif)",
144
+ maxWidth: "100%",
145
+ overflow: "hidden",
146
+ backgroundColor: "transparent",
147
+ color: "inherit"
26
148
  });
27
- context.publishEvent('action.applied', {
28
- id: context.generateId(),
29
- kind: 'navigation:scrollTo',
30
- anchorId: action.anchorId,
31
- behavior: action.behavior ?? 'smooth',
149
+ const accordionStyle = styleMap({
150
+ display: "flex",
151
+ flexDirection: "column",
152
+ gap: "var(--sc-content-item-gap, 6px)"
32
153
  });
33
- return {
34
- cleanup: () => {
35
- // Optionally restore scroll position on revert
36
- },
37
- };
38
- };
39
- /**
40
- * Check if a URL is same-origin as the current page.
41
- * Relative URLs (e.g. "/dashboard") are always same-origin.
42
- */
43
- function isSameOrigin(url) {
154
+ const categoryHeaderStyle = styleMap({
155
+ fontSize: "var(--sc-content-category-font-size, 12px)",
156
+ fontWeight: "600",
157
+ textTransform: "uppercase",
158
+ letterSpacing: "0.05em",
159
+ padding: "var(--sc-content-category-padding, 8px 4px 4px 4px)",
160
+ color: theme === "dark" ? TOKEN_SLATE_GREY_8 : TOKEN_SLATE_GREY_7
161
+ });
162
+ const emptyStateStyle = styleMap({
163
+ fontSize: "13px",
164
+ padding: "16px",
165
+ textAlign: "center",
166
+ color: theme === "dark" ? TOKEN_SLATE_GREY_7 : TOKEN_SLATE_GREY_8
167
+ });
168
+ if (visibleTips.length === 0) {
169
+ return html`
170
+ <div
171
+ style=${containerStyle}
172
+ data-adaptive-id=${this.instanceId}
173
+ data-adaptive-type="adaptive-nav"
174
+ >
175
+ <div style=${emptyStateStyle}>
176
+ You're all set for now! We'll share helpful tips here when they're relevant to what
177
+ you're doing.
178
+ </div>
179
+ </div>
180
+ `;
181
+ }
182
+ const categoryGroups = /* @__PURE__ */ new Map();
183
+ for (const tip of visibleTips) {
184
+ const cat = tip.config.category;
185
+ if (!categoryGroups.has(cat)) {
186
+ categoryGroups.set(cat, []);
187
+ }
188
+ categoryGroups.get(cat).push(tip);
189
+ }
190
+ const hasCategories = visibleTips.some((t) => t.config.category);
191
+ return html`
192
+ <div
193
+ style=${containerStyle}
194
+ data-adaptive-id=${this.instanceId}
195
+ data-adaptive-type="adaptive-nav"
196
+ >
197
+ <div style=${accordionStyle}>
198
+ ${hasCategories ? Array.from(categoryGroups.entries()).map(
199
+ ([category, items]) => html`
200
+ ${category ? html`<div style=${categoryHeaderStyle} data-category-header=${category}>${category}</div>` : nothing}
201
+ ${items.map((tip, idx) => __privateMethod(this, _NavWidgetLit_instances, renderTipItem_fn).call(this, tip, idx, items.length))}
202
+ `
203
+ ) : visibleTips.map((tip, idx) => __privateMethod(this, _NavWidgetLit_instances, renderTipItem_fn).call(this, tip, idx, visibleTips.length))}
204
+ </div>
205
+ </div>
206
+ `;
207
+ }
208
+ };
209
+ _contextUnsub = new WeakMap();
210
+ _accumulatorUnsub = new WeakMap();
211
+ _NavWidgetLit_instances = new WeakSet();
212
+ // ---------- Runtime subscriptions ----------------------------------------
213
+ subscribeRuntime_fn = function() {
214
+ if (!this.runtime) return;
215
+ __privateSet(this, _contextUnsub, this.runtime.context.subscribe(() => {
216
+ this._renderTick += 1;
217
+ }));
218
+ if (this.runtime.accumulator?.subscribe) {
219
+ __privateSet(this, _accumulatorUnsub, this.runtime.accumulator.subscribe(() => {
220
+ this._renderTick += 1;
221
+ }));
222
+ }
223
+ };
224
+ unsubscribeRuntime_fn = function() {
225
+ var _a, _b;
226
+ (_a = __privateGet(this, _contextUnsub)) == null ? void 0 : _a.call(this);
227
+ __privateSet(this, _contextUnsub, null);
228
+ (_b = __privateGet(this, _accumulatorUnsub)) == null ? void 0 : _b.call(this);
229
+ __privateSet(this, _accumulatorUnsub, null);
230
+ };
231
+ // ---------- Computed helpers (called on each render) ---------------------
232
+ getVisibleTips_fn = function() {
233
+ void this._renderTick;
234
+ if (!this.runtime) return this.config.actions;
235
+ return this.config.actions.filter((tip) => {
236
+ if (!tip.triggerWhen) return true;
44
237
  try {
45
- const parsed = new URL(url, window.location.origin);
46
- return parsed.origin === window.location.origin;
238
+ const result = this.runtime.evaluateSync(tip.triggerWhen);
239
+ return result.value;
240
+ } catch {
241
+ return false;
47
242
  }
48
- catch {
49
- // If URL parsing fails, fall back to full navigation
50
- return false;
243
+ });
244
+ };
245
+ getResolvedTheme_fn = function() {
246
+ return resolveTheme(this.config.theme);
247
+ };
248
+ // ---------- Event handlers -----------------------------------------------
249
+ handleToggle_fn = function(id) {
250
+ const wasExpanded = this._expandedIds.has(id);
251
+ let next;
252
+ if (this.config.expandBehavior === "single") {
253
+ for (const prevId of this._expandedIds) {
254
+ if (prevId !== id) {
255
+ __privateMethod(this, _NavWidgetLit_instances, publishEvent_fn).call(this, "nav:toggled", {
256
+ tipId: prevId,
257
+ expanded: false
258
+ });
259
+ }
51
260
  }
52
- }
53
- /**
54
- * Execute a navigate action
55
- */
56
- export const executeNavigate = async (action, context) => {
57
- // Validate URL to prevent javascript: URLs
58
- const url = action.url.trim();
59
- if (url.toLowerCase().startsWith('javascript:')) {
60
- throw new Error('javascript: URLs are not allowed');
261
+ next = wasExpanded ? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set([id]);
262
+ } else {
263
+ next = new Set(this._expandedIds);
264
+ if (wasExpanded) {
265
+ next.delete(id);
266
+ } else {
267
+ next.add(id);
268
+ }
269
+ }
270
+ __privateMethod(this, _NavWidgetLit_instances, publishEvent_fn).call(this, "nav:toggled", {
271
+ tipId: id,
272
+ expanded: !wasExpanded
273
+ });
274
+ this._expandedIds = next;
275
+ };
276
+ handleNavigate_fn = function(href, external) {
277
+ const normalized = href.trim().toLowerCase();
278
+ if (normalized.startsWith("javascript:") || normalized.startsWith("data:")) return;
279
+ __privateMethod(this, _NavWidgetLit_instances, publishEvent_fn).call(this, "nav:tip_clicked", { href, external });
280
+ this.dispatchEvent(
281
+ new CustomEvent("nav-tip-clicked", {
282
+ bubbles: true,
283
+ detail: { href, external, instanceId: this.instanceId }
284
+ })
285
+ );
286
+ const target = resolveNavTarget({
287
+ href,
288
+ external,
289
+ windowOrigin: typeof window !== "undefined" ? window.location.origin : "",
290
+ isIframe: detectIsIframe()
291
+ });
292
+ if (target.kind === "open") {
293
+ window.open(target.url, "_blank", "noopener,noreferrer");
294
+ return;
295
+ }
296
+ if (target.kind === "fullnav") {
297
+ window.location.href = target.url;
298
+ return;
299
+ }
300
+ target.url.search = window.location.search;
301
+ if (!navigateWithFrameworkRouter(target.url.toString())) {
302
+ window.history.pushState(null, "", target.url.toString());
303
+ window.dispatchEvent(new PopStateEvent("popstate"));
304
+ }
305
+ };
306
+ handleFocusAnchor_fn = function(anchor) {
307
+ const el = document.querySelector(anchor.selector);
308
+ if (!(el instanceof HTMLElement)) return;
309
+ __privateMethod(this, _NavWidgetLit_instances, publishEvent_fn).call(this, "nav:tip_focused", {
310
+ selector: anchor.selector,
311
+ route: anchor.route
312
+ });
313
+ this.dispatchEvent(
314
+ new CustomEvent("nav-tip-focused", {
315
+ bubbles: true,
316
+ detail: { selector: anchor.selector, instanceId: this.instanceId }
317
+ })
318
+ );
319
+ el.scrollIntoView({ behavior: "smooth", block: "center" });
320
+ pulseElement(el);
321
+ setTimeout(() => el.focus(), 400);
322
+ };
323
+ publishEvent_fn = function(name, props) {
324
+ this.runtime?.events.publish(name, {
325
+ instanceId: this.instanceId,
326
+ timestamp: Date.now(),
327
+ ...props
328
+ });
329
+ };
330
+ // ---------- Tip item rendering -------------------------------------------
331
+ renderTipItem_fn = function(tip, index, total) {
332
+ const { id, title, description, href, icon, external, anchor, category: _cat } = tip.config;
333
+ const isExpanded = this._expandedIds.has(id);
334
+ const isLast = index === total - 1;
335
+ const isHovered = this._hoveredId === id;
336
+ const theme = __privateMethod(this, _NavWidgetLit_instances, getResolvedTheme_fn).call(this);
337
+ const effectiveHref = anchor ? Array.isArray(anchor.route) ? anchor.route[0] : anchor.route : href;
338
+ const isSamePage = anchor ? routeMatchesCurrent(Array.isArray(anchor.route) ? anchor.route : [anchor.route]) : effectiveHref ? routeMatchesCurrent([effectiveHref]) : false;
339
+ const hasSelector = anchor?.selector && anchor.selector !== "*";
340
+ const isFocusAction = isSamePage && hasSelector;
341
+ const hasAction = !!effectiveHref || isFocusAction;
342
+ const ctaLabel = isFocusAction ? "Focus \u2192" : external ? "Go \u2197" : "Go \u2192";
343
+ const itemStyle = styleMap({
344
+ borderRadius: "var(--sc-content-border-radius, 8px)",
345
+ overflow: "hidden",
346
+ transition: "box-shadow 0.2s ease",
347
+ backgroundColor: "var(--sc-content-background)",
348
+ border: "var(--sc-content-border)",
349
+ ...isExpanded ? {
350
+ boxShadow: theme === "dark" ? "0 4px 12px rgba(0, 0, 0, 0.15)" : "0 4px 12px rgba(0, 0, 0, 0.08)"
351
+ } : {},
352
+ ...!isLast ? { borderBottom: "var(--sc-content-item-divider, none)" } : {}
353
+ });
354
+ const headerStyle = styleMap({
355
+ display: "flex",
356
+ alignItems: "center",
357
+ gap: "8px",
358
+ width: "100%",
359
+ padding: "var(--sc-content-item-padding, 12px 16px)",
360
+ border: "none",
361
+ cursor: "pointer",
362
+ fontSize: "var(--sc-content-item-font-size, 15px)",
363
+ fontWeight: "500",
364
+ fontFamily: "inherit",
365
+ textAlign: "left",
366
+ transition: "background-color 0.15s ease",
367
+ backgroundColor: isHovered ? "var(--sc-content-background-hover)" : "transparent",
368
+ color: "var(--sc-content-text-color)"
369
+ });
370
+ const chevronStyle = styleMap({
371
+ fontSize: "20px",
372
+ transition: "transform 0.2s ease",
373
+ marginLeft: "auto",
374
+ flexShrink: "0",
375
+ color: "var(--sc-content-chevron-color, currentColor)",
376
+ transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
377
+ });
378
+ const bodyStyle = styleMap({
379
+ overflow: "hidden",
380
+ transition: "max-height 0.25s ease, padding-bottom 0.25s ease",
381
+ padding: "var(--sc-content-body-padding, 0 16px 12px 16px)",
382
+ color: "var(--sc-content-text-secondary-color)",
383
+ maxHeight: isExpanded ? "500px" : "0",
384
+ paddingBottom: isExpanded ? "16px" : "0"
385
+ });
386
+ const descriptionStyle = styleMap({
387
+ fontSize: "var(--sc-content-body-font-size, 14px)",
388
+ lineHeight: "1.5",
389
+ margin: "0"
390
+ });
391
+ const linkButtonStyle = styleMap({
392
+ display: "inline-flex",
393
+ alignItems: "center",
394
+ gap: "4px",
395
+ marginTop: "10px",
396
+ padding: "6px 12px",
397
+ borderRadius: "6px",
398
+ textDecoration: "none",
399
+ fontSize: "13px",
400
+ fontWeight: "500",
401
+ cursor: "pointer",
402
+ border: "none",
403
+ transition: "background-color 0.15s ease",
404
+ backgroundColor: `var(--sc-color-primary, ${TOKEN_PURPLE_4})`,
405
+ color: "#ffffff"
406
+ });
407
+ const iconStyle = styleMap({
408
+ fontSize: "16px",
409
+ flexShrink: "0"
410
+ });
411
+ const onLinkClick = (e) => {
412
+ e.preventDefault();
413
+ e.stopPropagation();
414
+ if (isFocusAction && anchor) {
415
+ __privateMethod(this, _NavWidgetLit_instances, handleFocusAnchor_fn).call(this, anchor);
416
+ } else if (effectiveHref) {
417
+ __privateMethod(this, _NavWidgetLit_instances, handleNavigate_fn).call(this, effectiveHref, external ?? false);
61
418
  }
62
- const target = action.target ?? '_self';
63
- context.publishEvent('action.applied', {
64
- id: context.generateId(),
65
- kind: 'navigation:navigate',
66
- url: action.url,
67
- target,
419
+ };
420
+ return html`
421
+ <div
422
+ style=${itemStyle}
423
+ data-nav-tip-id=${id}
424
+ >
425
+ <button
426
+ type="button"
427
+ style=${headerStyle}
428
+ aria-expanded=${isExpanded}
429
+ @click=${() => __privateMethod(this, _NavWidgetLit_instances, handleToggle_fn).call(this, id)}
430
+ @mouseenter=${() => {
431
+ this._hoveredId = id;
432
+ }}
433
+ @mouseleave=${() => {
434
+ this._hoveredId = null;
435
+ }}
436
+ >
437
+ ${icon ? html`<span style=${iconStyle}>${unsafeHTML(renderIcon2(icon))}</span>` : nothing}
438
+ <span>${title}</span>
439
+ <span style=${chevronStyle}>${"\u203A"}</span>
440
+ </button>
441
+ <div style=${bodyStyle} aria-hidden=${!isExpanded}>
442
+ <p style=${descriptionStyle}>${description}</p>
443
+ ${hasAction ? html`
444
+ <a
445
+ href=${effectiveHref || "#"}
446
+ style=${linkButtonStyle}
447
+ target=${external ? "_blank" : nothing}
448
+ rel=${external ? "noopener noreferrer" : nothing}
449
+ @click=${onLinkClick}
450
+ >${ctaLabel}</a>
451
+ ` : nothing}
452
+ </div>
453
+ </div>
454
+ `;
455
+ };
456
+ // ---------- Reactive properties (no decorators) --------------------------
457
+ NavWidgetLit.properties = {
458
+ // Public inputs
459
+ config: { attribute: false },
460
+ runtime: { attribute: false },
461
+ instanceId: { type: String },
462
+ // Internal reactive state
463
+ _expandedIds: { state: true },
464
+ _renderTick: { state: true },
465
+ _hoveredId: { state: true }
466
+ };
467
+ var TAG_NAME = "syntro-nav-tips";
468
+ function registerNavWidgetLit() {
469
+ if (typeof window === "undefined") return;
470
+ if (!customElements.get(TAG_NAME)) {
471
+ customElements.define(TAG_NAME, NavWidgetLit);
472
+ }
473
+ }
474
+
475
+ // src/runtime.ts
476
+ var executeScrollTo = async (action, context) => {
477
+ const anchorEl = context.resolveAnchor(action.anchorId);
478
+ if (!anchorEl) {
479
+ console.error(
480
+ `[adaptive-nav] Anchor not found for scrollTo, skipping: ${action.anchorId.selector}`
481
+ );
482
+ return { cleanup: () => {
483
+ } };
484
+ }
485
+ anchorEl.scrollIntoView({
486
+ behavior: action.behavior ?? "smooth",
487
+ block: action.block ?? "center",
488
+ inline: action.inline ?? "nearest"
489
+ });
490
+ context.publishEvent("action.applied", {
491
+ id: context.generateId(),
492
+ kind: "navigation:scrollTo",
493
+ anchorId: action.anchorId,
494
+ behavior: action.behavior ?? "smooth"
495
+ });
496
+ if (action.pulse !== false && typeof context.applyAction === "function") {
497
+ void context.applyAction({
498
+ kind: "overlays:pulse",
499
+ anchorId: action.anchorId
500
+ }).catch(() => {
68
501
  });
69
- if (target === '_blank') {
70
- // Open in new tab
71
- window.open(url, '_blank', 'noopener,noreferrer');
502
+ }
503
+ return {
504
+ cleanup: () => {
505
+ }
506
+ };
507
+ };
508
+ function navigateWithFrameworkRouter(url) {
509
+ if (typeof window === "undefined") return false;
510
+ const w = window;
511
+ try {
512
+ const nextRouter = w.next?.router;
513
+ if (nextRouter?.push) {
514
+ nextRouter.push(url);
515
+ return true;
72
516
  }
73
- else if (!action.forceFullNavigation && isSameOrigin(url)) {
74
- // SPA-aware: use pushState for same-origin URLs to avoid full page reload
75
- window.history.pushState(null, '', url);
76
- window.dispatchEvent(new PopStateEvent('popstate'));
517
+ } catch {
518
+ }
519
+ try {
520
+ if (w.$nuxt?.$router?.push) {
521
+ w.$nuxt.$router.push(url);
522
+ return true;
77
523
  }
78
- else {
79
- // Full navigation for cross-origin URLs or when explicitly requested
80
- window.location.href = url;
524
+ } catch {
525
+ }
526
+ if (w.ng || w.getAllAngularRootElements || document.querySelector("[ng-version]")) {
527
+ window.location.href = url;
528
+ return true;
529
+ }
530
+ if (w.__SVELTEKIT_DATA__ || document.body?.hasAttribute("data-sveltekit")) {
531
+ window.location.href = url;
532
+ return true;
533
+ }
534
+ if (document.querySelector("[data-astro-transition-fallback]")) {
535
+ window.location.href = url;
536
+ return true;
537
+ }
538
+ return false;
539
+ }
540
+ function isSameOrigin(url) {
541
+ try {
542
+ const parsed = new URL(url, window.location.origin);
543
+ return parsed.origin === window.location.origin;
544
+ } catch {
545
+ return false;
546
+ }
547
+ }
548
+ var executeNavigate = async (action, context) => {
549
+ const url = action.url.trim();
550
+ if (url.toLowerCase().startsWith("javascript:")) {
551
+ throw new Error("javascript: URLs are not allowed");
552
+ }
553
+ const target = action.target ?? "_self";
554
+ context.publishEvent("action.applied", {
555
+ id: context.generateId(),
556
+ kind: "navigation:navigate",
557
+ url: action.url,
558
+ target
559
+ });
560
+ if (target === "_blank") {
561
+ window.open(url, "_blank", "noopener,noreferrer");
562
+ } else if (!action.forceFullNavigation && isSameOrigin(url)) {
563
+ if (!navigateWithFrameworkRouter(url)) {
564
+ window.history.pushState(null, "", url);
565
+ window.dispatchEvent(new PopStateEvent("popstate"));
81
566
  }
82
- return {
83
- cleanup: () => {
84
- // Navigation cannot be reverted
85
- },
86
- };
87
- };
88
- // ============================================================================
89
- // Executor Definitions for Registration
90
- // ============================================================================
91
- /**
92
- * All executors provided by this app.
93
- * These are registered with the runtime's ExecutorRegistry.
94
- */
95
- export const executors = [
96
- { kind: 'navigation:scrollTo', executor: executeScrollTo },
97
- { kind: 'navigation:navigate', executor: executeNavigate },
567
+ } else {
568
+ window.location.href = url;
569
+ }
570
+ return {
571
+ cleanup: () => {
572
+ }
573
+ };
574
+ };
575
+ var DEFAULT_NAV_CONFIG = {
576
+ expandBehavior: "single",
577
+ theme: "auto",
578
+ actions: []
579
+ };
580
+ var NavWidgetLitMountable = {
581
+ mount(container, config) {
582
+ registerNavWidgetLit();
583
+ const el = document.createElement("syntro-nav-tips");
584
+ const incoming = config ?? null;
585
+ const stripped = stripMountPlumbing(incoming);
586
+ const runtime2 = incoming?.runtime;
587
+ const instanceId = incoming?.instanceId ?? "nav-widget";
588
+ const navConfig = incoming ? stripped : { ...DEFAULT_NAV_CONFIG };
589
+ Object.assign(el, {
590
+ config: navConfig,
591
+ runtime: runtime2,
592
+ instanceId
593
+ });
594
+ container.appendChild(el);
595
+ return () => el.remove();
596
+ }
597
+ };
598
+ var executors = [
599
+ { kind: "navigation:scrollTo", executor: executeScrollTo },
600
+ { kind: "navigation:navigate", executor: executeNavigate }
98
601
  ];
99
- // ============================================================================
100
- // App Runtime Manifest
101
- // ============================================================================
102
- /**
103
- * Runtime manifest for adaptive-nav.
104
- *
105
- * Provides:
106
- * - Navigation action executors (scrollTo, navigate)
107
- * - Widget-based nav tips accordion (compositional nav:tip actions)
108
- */
109
- export const runtime = {
110
- id: 'adaptive-nav',
111
- version: '2.0.0',
112
- name: 'Navigation Tips',
113
- description: 'Navigation actions and accordion-based tips with per-item conditional visibility',
114
- /**
115
- * Navigation action executors (scrollTo, navigate).
116
- */
117
- executors,
118
- /**
119
- * Widget definitions for the runtime's WidgetRegistry.
120
- */
121
- widgets: [
122
- {
123
- id: 'adaptive-nav:tips',
124
- component: NavMountableWidget,
125
- metadata: {
126
- name: 'Navigation Tips',
127
- description: 'Accordion of contextual navigation tips with per-item visibility',
128
- icon: '\u{1F9ED}',
129
- },
130
- },
131
- ],
132
- /**
133
- * Extract notify watcher entries from tile config props.
134
- * The runtime evaluates these continuously (even with drawer closed)
135
- * and publishes nav:tip_revealed when triggerWhen transitions false → true.
136
- */
137
- notifyWatchers(props) {
138
- const actions = (props.actions ?? []);
139
- return actions
140
- .filter((a) => a.notify && a.triggerWhen)
141
- .map((a) => ({
142
- id: `nav:${a.config.id}`,
143
- strategy: a.triggerWhen,
144
- eventName: 'nav:tip_revealed',
145
- eventProps: {
146
- tipId: a.config.id,
147
- title: a.notify.title,
148
- body: a.notify.body,
149
- icon: a.notify.icon,
150
- },
151
- }));
152
- },
153
- };
154
- export default runtime;
602
+ var runtime = {
603
+ id: "adaptive-nav",
604
+ version: "2.0.0",
605
+ name: "Navigation Tips",
606
+ description: "Navigation actions and accordion-based tips with per-item conditional visibility",
607
+ /**
608
+ * Navigation action executors (scrollTo, navigate).
609
+ */
610
+ executors,
611
+ /**
612
+ * Widget definitions for the runtime's WidgetRegistry.
613
+ */
614
+ widgets: [
615
+ {
616
+ id: "adaptive-nav:tips",
617
+ component: NavWidgetLitMountable,
618
+ metadata: {
619
+ name: "Navigation Tips",
620
+ description: "Accordion of contextual navigation tips with per-item visibility",
621
+ icon: "\u{1F9ED}"
622
+ }
623
+ }
624
+ ],
625
+ /**
626
+ * Extract notify watcher entries from tile config props.
627
+ * The runtime evaluates these continuously (even with drawer closed)
628
+ * and publishes nav:tip_revealed when triggerWhen transitions false → true.
629
+ */
630
+ notifyWatchers(props) {
631
+ const actions = props.actions ?? [];
632
+ return actions.filter((a) => a.notify && a.triggerWhen).map((a) => ({
633
+ id: `nav:${a.config.id}`,
634
+ strategy: a.triggerWhen,
635
+ eventName: "nav:tip_revealed",
636
+ eventProps: {
637
+ tipId: a.config.id,
638
+ title: a.notify.title,
639
+ body: a.notify.body,
640
+ icon: a.notify.icon
641
+ }
642
+ }));
643
+ }
644
+ };
645
+ var runtime_default = runtime;
646
+ export {
647
+ NavWidgetLitMountable,
648
+ runtime_default as default,
649
+ executeNavigate,
650
+ executeScrollTo,
651
+ executors,
652
+ navigateWithFrameworkRouter,
653
+ runtime
654
+ };
655
+ //# sourceMappingURL=runtime.js.map