@syntrologie/adapt-overlays 2.4.1 → 2.5.1
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.
- package/dist/WorkflowTracker.d.ts +10 -0
- package/dist/WorkflowTracker.d.ts.map +1 -0
- package/dist/WorkflowTracker.js +19 -0
- package/dist/WorkflowWidget.d.ts +70 -0
- package/dist/WorkflowWidget.d.ts.map +1 -0
- package/dist/WorkflowWidget.js +329 -0
- package/dist/cdn.d.ts +2 -2
- package/dist/celebrations/__tests__/engine.test.d.ts +2 -0
- package/dist/celebrations/__tests__/engine.test.d.ts.map +1 -0
- package/dist/celebrations/__tests__/engine.test.js +130 -0
- package/dist/celebrations/__tests__/executor.test.d.ts +2 -0
- package/dist/celebrations/__tests__/executor.test.d.ts.map +1 -0
- package/dist/celebrations/__tests__/executor.test.js +102 -0
- package/dist/celebrations/effects/__tests__/confetti.test.d.ts +2 -0
- package/dist/celebrations/effects/__tests__/confetti.test.d.ts.map +1 -0
- package/dist/celebrations/effects/__tests__/confetti.test.js +89 -0
- package/dist/celebrations/effects/__tests__/emoji-rain.test.d.ts +2 -0
- package/dist/celebrations/effects/__tests__/emoji-rain.test.d.ts.map +1 -0
- package/dist/celebrations/effects/__tests__/emoji-rain.test.js +88 -0
- package/dist/celebrations/effects/__tests__/fireworks.test.d.ts +2 -0
- package/dist/celebrations/effects/__tests__/fireworks.test.d.ts.map +1 -0
- package/dist/celebrations/effects/__tests__/fireworks.test.js +87 -0
- package/dist/celebrations/effects/__tests__/sparkles.test.d.ts +2 -0
- package/dist/celebrations/effects/__tests__/sparkles.test.d.ts.map +1 -0
- package/dist/celebrations/effects/__tests__/sparkles.test.js +79 -0
- package/dist/celebrations/effects/confetti.d.ts +3 -0
- package/dist/celebrations/effects/confetti.d.ts.map +1 -0
- package/dist/celebrations/effects/confetti.js +80 -0
- package/dist/celebrations/effects/emoji-rain.d.ts +3 -0
- package/dist/celebrations/effects/emoji-rain.d.ts.map +1 -0
- package/dist/celebrations/effects/emoji-rain.js +73 -0
- package/dist/celebrations/effects/fireworks.d.ts +3 -0
- package/dist/celebrations/effects/fireworks.d.ts.map +1 -0
- package/dist/celebrations/effects/fireworks.js +69 -0
- package/dist/celebrations/effects/sparkles.d.ts +3 -0
- package/dist/celebrations/effects/sparkles.d.ts.map +1 -0
- package/dist/celebrations/effects/sparkles.js +83 -0
- package/dist/celebrations/engine.d.ts +16 -0
- package/dist/celebrations/engine.d.ts.map +1 -0
- package/dist/celebrations/engine.js +89 -0
- package/dist/celebrations/index.d.ts +3 -0
- package/dist/celebrations/index.d.ts.map +1 -0
- package/dist/celebrations/index.js +73 -0
- package/dist/celebrations/types.d.ts +34 -0
- package/dist/celebrations/types.d.ts.map +1 -0
- package/dist/celebrations/types.js +1 -0
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +59 -5
- package/dist/executors/tour.d.ts +20 -0
- package/dist/executors/tour.d.ts.map +1 -0
- package/dist/executors/tour.js +335 -0
- package/dist/modal.d.ts +2 -0
- package/dist/modal.d.ts.map +1 -1
- package/dist/modal.js +18 -8
- package/dist/runtime.d.ts +25 -2
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +141 -24
- package/dist/schema.d.ts +684 -4
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +36 -0
- package/dist/summarize.d.ts.map +1 -1
- package/dist/summarize.js +15 -4
- package/dist/tooltip.d.ts.map +1 -1
- package/dist/tooltip.js +26 -12
- package/dist/tour-types.d.ts +34 -0
- package/dist/tour-types.d.ts.map +1 -0
- package/dist/tour-types.js +7 -0
- package/dist/types.d.ts +20 -85
- package/dist/types.d.ts.map +1 -1
- package/dist/workflow-types.d.ts +15 -0
- package/dist/workflow-types.d.ts.map +1 -0
- package/dist/workflow-types.js +1 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.d.ts +2 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.d.ts.map +1 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.js +224 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ConditionStatusLine.test.js +102 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DetectionBadge.test.js +58 -6
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DismissedSection.test.js +18 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorCard.test.js +61 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorPanelShell.test.js +478 -7
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ElementHighlight.test.js +54 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.d.ts +2 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.d.ts.map +1 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.js +257 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.d.ts +2 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.d.ts.map +1 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.js +1015 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.js +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts +4 -4
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts.map +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.js +2 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts +2 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts.map +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.js +20 -3
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts +10 -8
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts.map +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.js +350 -87
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.js +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts +3 -3
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts.map +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.js +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts.map +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.js +5 -2
- package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts +24 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts.map +1 -0
- package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/{useShowWhenStatus.js → useTriggerWhenStatus.js} +18 -15
- package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts +3 -3
- package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts.map +1 -1
- package/node_modules/@syntrologie/shared-editor-ui/dist/index.js +1 -1
- package/package.json +3 -2
- package/node_modules/@syntrologie/sdk-contracts/dist/index.d.ts +0 -26
- package/node_modules/@syntrologie/sdk-contracts/dist/index.js +0 -13
- package/node_modules/@syntrologie/sdk-contracts/dist/schemas.d.ts +0 -1428
- package/node_modules/@syntrologie/sdk-contracts/dist/schemas.js +0 -142
- package/node_modules/@syntrologie/sdk-contracts/package.json +0 -33
- package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useShowWhenStatus.d.ts +0 -24
- package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useShowWhenStatus.d.ts.map +0 -1
package/dist/runtime.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Adaptive Overlays - Runtime Module
|
|
3
3
|
*
|
|
4
|
-
* Visual overlay actions: highlight, pulse, badge, tooltip.
|
|
4
|
+
* Visual overlay actions: highlight, pulse, badge, tooltip, celebrations.
|
|
5
5
|
*/
|
|
6
|
+
import { executeCelebrate } from './celebrations';
|
|
7
|
+
import { executeTour } from './executors/tour';
|
|
6
8
|
import { showHighlight } from './highlight';
|
|
7
9
|
import { executeModal } from './modal';
|
|
8
10
|
import { sanitizeHtml } from './sanitizer';
|
|
9
11
|
import { showTooltip } from './tooltip';
|
|
10
|
-
|
|
11
|
-
export
|
|
12
|
+
import { WorkflowMountableWidget } from './WorkflowWidget';
|
|
13
|
+
// Re-export executeModal and executeTour for use by other packages
|
|
14
|
+
export { executeModal, executeTour };
|
|
12
15
|
// ============================================================================
|
|
13
16
|
// Executors
|
|
14
17
|
// ============================================================================
|
|
@@ -16,15 +19,41 @@ export { executeModal };
|
|
|
16
19
|
* Execute a highlight action
|
|
17
20
|
*/
|
|
18
21
|
export const executeHighlight = async (action, context) => {
|
|
19
|
-
|
|
22
|
+
let anchorEl = context.resolveAnchor(action.anchorId);
|
|
23
|
+
if (!anchorEl && context.waitForAnchor) {
|
|
24
|
+
anchorEl = await context.waitForAnchor(action.anchorId, 3000);
|
|
25
|
+
}
|
|
20
26
|
if (!anchorEl) {
|
|
21
|
-
|
|
27
|
+
console.warn(`[adaptive-overlays] Anchor not found after waiting: ${action.anchorId.selector}`);
|
|
28
|
+
return { cleanup: () => { } };
|
|
29
|
+
}
|
|
30
|
+
// Self-guard: destroy any existing highlight on this anchor to prevent duplicates
|
|
31
|
+
// (batch re-apply on navigation can call this executor multiple times for the same anchor)
|
|
32
|
+
const existing = anchorEl.getAttribute('data-syntro-highlight');
|
|
33
|
+
if (existing) {
|
|
34
|
+
const prev = context.overlayRoot.querySelectorAll('.syntro-spotlight-scrim, .syntro-spotlight-ring');
|
|
35
|
+
prev.forEach((el) => el.remove());
|
|
36
|
+
}
|
|
37
|
+
anchorEl.setAttribute('data-syntro-highlight', 'true');
|
|
38
|
+
// Resolve ring color: action override → theme primary → host page var → fallback
|
|
39
|
+
let ringColor = action.style?.color;
|
|
40
|
+
if (!ringColor) {
|
|
41
|
+
try {
|
|
42
|
+
const primary = getComputedStyle(context.overlayRoot)
|
|
43
|
+
.getPropertyValue('--sc-color-primary')
|
|
44
|
+
?.trim();
|
|
45
|
+
if (primary)
|
|
46
|
+
ringColor = primary;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
/* fallback to showHighlight default */
|
|
50
|
+
}
|
|
22
51
|
}
|
|
23
52
|
const handle = showHighlight(anchorEl, context.overlayRoot, {
|
|
24
53
|
paddingPx: action.style?.paddingPx ?? 12,
|
|
25
54
|
radiusPx: action.style?.radiusPx ?? 12,
|
|
26
55
|
scrimOpacity: action.style?.scrimOpacity ?? 0.55,
|
|
27
|
-
ringColor
|
|
56
|
+
ringColor,
|
|
28
57
|
blocking: action.blocking ?? false,
|
|
29
58
|
onClickOutside: action.onClickOutside ?? true,
|
|
30
59
|
onEsc: action.onEsc ?? true,
|
|
@@ -37,6 +66,7 @@ export const executeHighlight = async (action, context) => {
|
|
|
37
66
|
return {
|
|
38
67
|
cleanup: () => {
|
|
39
68
|
handle.destroy();
|
|
69
|
+
anchorEl.removeAttribute('data-syntro-highlight');
|
|
40
70
|
},
|
|
41
71
|
};
|
|
42
72
|
};
|
|
@@ -44,30 +74,83 @@ export const executeHighlight = async (action, context) => {
|
|
|
44
74
|
* Execute a pulse action
|
|
45
75
|
*/
|
|
46
76
|
export const executePulse = async (action, context) => {
|
|
47
|
-
|
|
77
|
+
let anchorEl = context.resolveAnchor(action.anchorId);
|
|
78
|
+
if (!anchorEl && context.waitForAnchor) {
|
|
79
|
+
anchorEl = await context.waitForAnchor(action.anchorId, 3000);
|
|
80
|
+
}
|
|
48
81
|
if (!anchorEl) {
|
|
49
|
-
|
|
82
|
+
console.warn(`[adaptive-overlays] Anchor not found after waiting: ${action.anchorId.selector}`);
|
|
83
|
+
return { cleanup: () => { } };
|
|
84
|
+
}
|
|
85
|
+
const duration = action.duration ?? 4000;
|
|
86
|
+
// Wait one frame so ThemeProvider's useEffect has injected CSS vars
|
|
87
|
+
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
88
|
+
// Read primary + secondary colors from theme (shadow DOM overlay root has --sc-* vars)
|
|
89
|
+
const parseHex = (hex) => ({
|
|
90
|
+
r: parseInt(hex.slice(1, 3), 16),
|
|
91
|
+
g: parseInt(hex.slice(3, 5), 16),
|
|
92
|
+
b: parseInt(hex.slice(5, 7), 16),
|
|
93
|
+
});
|
|
94
|
+
const fallback = { r: 79, g: 70, b: 229 }; // indigo-600
|
|
95
|
+
let primary = fallback;
|
|
96
|
+
let secondary = null;
|
|
97
|
+
try {
|
|
98
|
+
const styles = getComputedStyle(context.overlayRoot);
|
|
99
|
+
const pHex = styles.getPropertyValue('--sc-color-primary')?.trim();
|
|
100
|
+
const sHex = styles.getPropertyValue('--sc-color-primary-hover')?.trim();
|
|
101
|
+
if (pHex?.startsWith('#') && pHex.length >= 7) {
|
|
102
|
+
primary = parseHex(pHex);
|
|
103
|
+
}
|
|
104
|
+
if (sHex?.startsWith('#') && sHex.length >= 7) {
|
|
105
|
+
secondary = parseHex(sHex);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
/* fallback to default */
|
|
110
|
+
}
|
|
111
|
+
// Inject/update pulse animation with theme colors
|
|
112
|
+
// Two-tone pulse when both primary and secondary are available
|
|
113
|
+
const existing = document.querySelector('[data-syntro-pulse-styles]');
|
|
114
|
+
if (existing)
|
|
115
|
+
existing.remove();
|
|
116
|
+
const style = document.createElement('style');
|
|
117
|
+
style.setAttribute('data-syntro-pulse-styles', '');
|
|
118
|
+
const { r: pr, g: pg, b: pb } = primary;
|
|
119
|
+
if (secondary) {
|
|
120
|
+
const { r: sr, g: sg, b: sb } = secondary;
|
|
121
|
+
style.textContent = `
|
|
122
|
+
@keyframes syntro-pulse-anim {
|
|
123
|
+
0%, 100% {
|
|
124
|
+
box-shadow: 0 0 0 0 rgba(${pr}, ${pg}, ${pb}, 0.35);
|
|
125
|
+
}
|
|
126
|
+
25% {
|
|
127
|
+
box-shadow: 0 0 0 12px rgba(${pr}, ${pg}, ${pb}, 0);
|
|
128
|
+
}
|
|
129
|
+
50% {
|
|
130
|
+
box-shadow: 0 0 0 0 rgba(${sr}, ${sg}, ${sb}, 0.35);
|
|
131
|
+
}
|
|
132
|
+
75% {
|
|
133
|
+
box-shadow: 0 0 0 12px rgba(${sr}, ${sg}, ${sb}, 0);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
`;
|
|
50
137
|
}
|
|
51
|
-
|
|
52
|
-
// Inject scoped pulse animation (no global styles)
|
|
53
|
-
if (!document.querySelector('[data-syntro-pulse-styles]')) {
|
|
54
|
-
const style = document.createElement('style');
|
|
55
|
-
style.setAttribute('data-syntro-pulse-styles', '');
|
|
138
|
+
else {
|
|
56
139
|
style.textContent = `
|
|
57
140
|
@keyframes syntro-pulse-anim {
|
|
58
141
|
0%, 100% {
|
|
59
|
-
box-shadow: 0 0 0 0 rgba(
|
|
142
|
+
box-shadow: 0 0 0 0 rgba(${pr}, ${pg}, ${pb}, 0.35);
|
|
60
143
|
}
|
|
61
144
|
50% {
|
|
62
|
-
box-shadow: 0 0 0
|
|
145
|
+
box-shadow: 0 0 0 12px rgba(${pr}, ${pg}, ${pb}, 0);
|
|
63
146
|
}
|
|
64
147
|
}
|
|
65
148
|
`;
|
|
66
|
-
document.head.appendChild(style);
|
|
67
149
|
}
|
|
150
|
+
document.head.appendChild(style);
|
|
68
151
|
// Apply pulse animation via inline style (scoped to this element)
|
|
69
152
|
const originalAnimation = anchorEl.style.animation;
|
|
70
|
-
anchorEl.style.animation = 'syntro-pulse-anim
|
|
153
|
+
anchorEl.style.animation = 'syntro-pulse-anim 2.5s cubic-bezier(0.4, 0, 0.6, 1) infinite';
|
|
71
154
|
anchorEl.setAttribute('data-syntro-pulse', 'true');
|
|
72
155
|
// Set up auto-remove timeout
|
|
73
156
|
const timeoutId = setTimeout(() => {
|
|
@@ -92,14 +175,31 @@ export const executePulse = async (action, context) => {
|
|
|
92
175
|
* Execute a badge action
|
|
93
176
|
*/
|
|
94
177
|
export const executeBadge = async (action, context) => {
|
|
95
|
-
|
|
178
|
+
let anchorEl = context.resolveAnchor(action.anchorId);
|
|
179
|
+
if (!anchorEl && context.waitForAnchor) {
|
|
180
|
+
anchorEl = await context.waitForAnchor(action.anchorId, 3000);
|
|
181
|
+
}
|
|
96
182
|
if (!anchorEl) {
|
|
97
|
-
|
|
183
|
+
console.warn(`[adaptive-overlays] Anchor not found after waiting: ${action.anchorId.selector}`);
|
|
184
|
+
return { cleanup: () => { } };
|
|
185
|
+
}
|
|
186
|
+
// Read primary color from theme (overlay root has --sc-* vars from shadow DOM)
|
|
187
|
+
let badgeColor = '#4f46e5';
|
|
188
|
+
try {
|
|
189
|
+
const primary = getComputedStyle(context.overlayRoot)
|
|
190
|
+
.getPropertyValue('--sc-color-primary')
|
|
191
|
+
?.trim();
|
|
192
|
+
if (primary?.startsWith('#') && primary.length >= 7) {
|
|
193
|
+
badgeColor = primary;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
/* fallback to default */
|
|
98
198
|
}
|
|
99
199
|
// Create badge element with inline styles (no global style injection)
|
|
100
200
|
const badge = document.createElement('div');
|
|
101
201
|
badge.textContent = action.content;
|
|
102
|
-
badge.setAttribute('data-syntro-badge', action.anchorId);
|
|
202
|
+
badge.setAttribute('data-syntro-badge', action.anchorId.selector);
|
|
103
203
|
// Apply styles directly to element
|
|
104
204
|
Object.assign(badge.style, {
|
|
105
205
|
position: 'absolute',
|
|
@@ -108,7 +208,7 @@ export const executeBadge = async (action, context) => {
|
|
|
108
208
|
fontWeight: '600',
|
|
109
209
|
lineHeight: '1',
|
|
110
210
|
color: 'white',
|
|
111
|
-
background:
|
|
211
|
+
background: badgeColor,
|
|
112
212
|
borderRadius: '9999px',
|
|
113
213
|
pointerEvents: 'none',
|
|
114
214
|
zIndex: '2147483646',
|
|
@@ -163,9 +263,13 @@ export const executeBadge = async (action, context) => {
|
|
|
163
263
|
* Execute a tooltip action
|
|
164
264
|
*/
|
|
165
265
|
export const executeTooltip = async (action, context) => {
|
|
166
|
-
|
|
266
|
+
let anchorEl = context.resolveAnchor(action.anchorId);
|
|
267
|
+
if (!anchorEl && context.waitForAnchor) {
|
|
268
|
+
anchorEl = await context.waitForAnchor(action.anchorId, 3000);
|
|
269
|
+
}
|
|
167
270
|
if (!anchorEl) {
|
|
168
|
-
|
|
271
|
+
console.warn(`[adaptive-overlays] Anchor not found after waiting: ${action.anchorId.selector}`);
|
|
272
|
+
return { cleanup: () => { } };
|
|
169
273
|
}
|
|
170
274
|
// Build tooltip HTML
|
|
171
275
|
const { content } = action;
|
|
@@ -252,6 +356,8 @@ export const executors = [
|
|
|
252
356
|
{ kind: 'overlays:badge', executor: executeBadge },
|
|
253
357
|
{ kind: 'overlays:tooltip', executor: executeTooltip },
|
|
254
358
|
{ kind: 'overlays:modal', executor: executeModal },
|
|
359
|
+
{ kind: 'core:tour', executor: executeTour },
|
|
360
|
+
{ kind: 'overlays:celebrate', executor: executeCelebrate },
|
|
255
361
|
];
|
|
256
362
|
/**
|
|
257
363
|
* App runtime manifest.
|
|
@@ -260,6 +366,17 @@ export const runtime = {
|
|
|
260
366
|
id: 'adaptive-overlays',
|
|
261
367
|
version: '1.0.0',
|
|
262
368
|
name: 'Overlays',
|
|
263
|
-
description: 'Tooltips, highlights, badges, modals,
|
|
369
|
+
description: 'Tooltips, highlights, badges, modals, celebrations, visual overlays, and workflow tracking',
|
|
264
370
|
executors,
|
|
371
|
+
widgets: [
|
|
372
|
+
{
|
|
373
|
+
id: 'adaptive-overlays:workflow-tracker',
|
|
374
|
+
component: WorkflowMountableWidget,
|
|
375
|
+
metadata: {
|
|
376
|
+
name: 'Workflow Tracker',
|
|
377
|
+
icon: '📋',
|
|
378
|
+
description: 'Tracks multi-step workflow progress across tours',
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
],
|
|
265
382
|
};
|