@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.
Files changed (118) hide show
  1. package/dist/WorkflowTracker.d.ts +10 -0
  2. package/dist/WorkflowTracker.d.ts.map +1 -0
  3. package/dist/WorkflowTracker.js +19 -0
  4. package/dist/WorkflowWidget.d.ts +70 -0
  5. package/dist/WorkflowWidget.d.ts.map +1 -0
  6. package/dist/WorkflowWidget.js +329 -0
  7. package/dist/cdn.d.ts +2 -2
  8. package/dist/celebrations/__tests__/engine.test.d.ts +2 -0
  9. package/dist/celebrations/__tests__/engine.test.d.ts.map +1 -0
  10. package/dist/celebrations/__tests__/engine.test.js +130 -0
  11. package/dist/celebrations/__tests__/executor.test.d.ts +2 -0
  12. package/dist/celebrations/__tests__/executor.test.d.ts.map +1 -0
  13. package/dist/celebrations/__tests__/executor.test.js +102 -0
  14. package/dist/celebrations/effects/__tests__/confetti.test.d.ts +2 -0
  15. package/dist/celebrations/effects/__tests__/confetti.test.d.ts.map +1 -0
  16. package/dist/celebrations/effects/__tests__/confetti.test.js +89 -0
  17. package/dist/celebrations/effects/__tests__/emoji-rain.test.d.ts +2 -0
  18. package/dist/celebrations/effects/__tests__/emoji-rain.test.d.ts.map +1 -0
  19. package/dist/celebrations/effects/__tests__/emoji-rain.test.js +88 -0
  20. package/dist/celebrations/effects/__tests__/fireworks.test.d.ts +2 -0
  21. package/dist/celebrations/effects/__tests__/fireworks.test.d.ts.map +1 -0
  22. package/dist/celebrations/effects/__tests__/fireworks.test.js +87 -0
  23. package/dist/celebrations/effects/__tests__/sparkles.test.d.ts +2 -0
  24. package/dist/celebrations/effects/__tests__/sparkles.test.d.ts.map +1 -0
  25. package/dist/celebrations/effects/__tests__/sparkles.test.js +79 -0
  26. package/dist/celebrations/effects/confetti.d.ts +3 -0
  27. package/dist/celebrations/effects/confetti.d.ts.map +1 -0
  28. package/dist/celebrations/effects/confetti.js +80 -0
  29. package/dist/celebrations/effects/emoji-rain.d.ts +3 -0
  30. package/dist/celebrations/effects/emoji-rain.d.ts.map +1 -0
  31. package/dist/celebrations/effects/emoji-rain.js +73 -0
  32. package/dist/celebrations/effects/fireworks.d.ts +3 -0
  33. package/dist/celebrations/effects/fireworks.d.ts.map +1 -0
  34. package/dist/celebrations/effects/fireworks.js +69 -0
  35. package/dist/celebrations/effects/sparkles.d.ts +3 -0
  36. package/dist/celebrations/effects/sparkles.d.ts.map +1 -0
  37. package/dist/celebrations/effects/sparkles.js +83 -0
  38. package/dist/celebrations/engine.d.ts +16 -0
  39. package/dist/celebrations/engine.d.ts.map +1 -0
  40. package/dist/celebrations/engine.js +89 -0
  41. package/dist/celebrations/index.d.ts +3 -0
  42. package/dist/celebrations/index.d.ts.map +1 -0
  43. package/dist/celebrations/index.js +73 -0
  44. package/dist/celebrations/types.d.ts +34 -0
  45. package/dist/celebrations/types.d.ts.map +1 -0
  46. package/dist/celebrations/types.js +1 -0
  47. package/dist/editor.d.ts.map +1 -1
  48. package/dist/editor.js +59 -5
  49. package/dist/executors/tour.d.ts +20 -0
  50. package/dist/executors/tour.d.ts.map +1 -0
  51. package/dist/executors/tour.js +335 -0
  52. package/dist/modal.d.ts +2 -0
  53. package/dist/modal.d.ts.map +1 -1
  54. package/dist/modal.js +18 -8
  55. package/dist/runtime.d.ts +25 -2
  56. package/dist/runtime.d.ts.map +1 -1
  57. package/dist/runtime.js +141 -24
  58. package/dist/schema.d.ts +684 -4
  59. package/dist/schema.d.ts.map +1 -1
  60. package/dist/schema.js +36 -0
  61. package/dist/summarize.d.ts.map +1 -1
  62. package/dist/summarize.js +15 -4
  63. package/dist/tooltip.d.ts.map +1 -1
  64. package/dist/tooltip.js +26 -12
  65. package/dist/tour-types.d.ts +34 -0
  66. package/dist/tour-types.d.ts.map +1 -0
  67. package/dist/tour-types.js +7 -0
  68. package/dist/types.d.ts +20 -85
  69. package/dist/types.d.ts.map +1 -1
  70. package/dist/workflow-types.d.ts +15 -0
  71. package/dist/workflow-types.d.ts.map +1 -0
  72. package/dist/workflow-types.js +1 -0
  73. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.d.ts +2 -0
  74. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.d.ts.map +1 -0
  75. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/AnchorPicker.test.js +224 -0
  76. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ConditionStatusLine.test.js +102 -0
  77. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DetectionBadge.test.js +58 -6
  78. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/DismissedSection.test.js +18 -0
  79. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorCard.test.js +61 -2
  80. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/EditorPanelShell.test.js +478 -7
  81. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/ElementHighlight.test.js +54 -0
  82. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.d.ts +2 -0
  83. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.d.ts.map +1 -0
  84. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/selectorGenerator.test.js +257 -0
  85. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.d.ts +2 -0
  86. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.d.ts.map +1 -0
  87. package/node_modules/@syntrologie/shared-editor-ui/dist/__tests__/useTriggerWhenStatus.test.js +1015 -0
  88. package/node_modules/@syntrologie/shared-editor-ui/dist/components/AnchorPicker.js +1 -1
  89. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts +4 -4
  90. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.d.ts.map +1 -1
  91. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ConditionStatusLine.js +2 -2
  92. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts +2 -1
  93. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.d.ts.map +1 -1
  94. package/node_modules/@syntrologie/shared-editor-ui/dist/components/DetectionBadge.js +20 -3
  95. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts +10 -8
  96. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.d.ts.map +1 -1
  97. package/node_modules/@syntrologie/shared-editor-ui/dist/components/EditorPanelShell.js +350 -87
  98. package/node_modules/@syntrologie/shared-editor-ui/dist/components/ElementHighlight.js +1 -1
  99. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts +3 -3
  100. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.d.ts.map +1 -1
  101. package/node_modules/@syntrologie/shared-editor-ui/dist/components/TriggerJourney.js +1 -1
  102. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts +1 -1
  103. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.d.ts.map +1 -1
  104. package/node_modules/@syntrologie/shared-editor-ui/dist/formatConditionLabel.js +5 -2
  105. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts +24 -0
  106. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useTriggerWhenStatus.d.ts.map +1 -0
  107. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/{useShowWhenStatus.js → useTriggerWhenStatus.js} +18 -15
  108. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts +3 -3
  109. package/node_modules/@syntrologie/shared-editor-ui/dist/index.d.ts.map +1 -1
  110. package/node_modules/@syntrologie/shared-editor-ui/dist/index.js +1 -1
  111. package/package.json +3 -2
  112. package/node_modules/@syntrologie/sdk-contracts/dist/index.d.ts +0 -26
  113. package/node_modules/@syntrologie/sdk-contracts/dist/index.js +0 -13
  114. package/node_modules/@syntrologie/sdk-contracts/dist/schemas.d.ts +0 -1428
  115. package/node_modules/@syntrologie/sdk-contracts/dist/schemas.js +0 -142
  116. package/node_modules/@syntrologie/sdk-contracts/package.json +0 -33
  117. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useShowWhenStatus.d.ts +0 -24
  118. package/node_modules/@syntrologie/shared-editor-ui/dist/hooks/useShowWhenStatus.d.ts.map +0 -1
@@ -0,0 +1,335 @@
1
+ /**
2
+ * Tour Executor
3
+ *
4
+ * Orchestrates sequential tour steps with cross-page state persistence.
5
+ * Tours can span multiple pages and resume after navigation.
6
+ *
7
+ * Each step contains an inner action (modal, tooltip) that gets executed.
8
+ * The tour listens for CTA click events to advance to the next step.
9
+ */
10
+ /** Storage key for active tour state */
11
+ const ACTIVE_TOUR_KEY = 'syntro_active_tour';
12
+ /** Track active tour executors to prevent duplicates */
13
+ const activeTours = new Map();
14
+ /**
15
+ * Get active tour state from localStorage
16
+ */
17
+ function getTourState(tourId) {
18
+ try {
19
+ const data = localStorage.getItem(ACTIVE_TOUR_KEY);
20
+ if (!data)
21
+ return null;
22
+ const state = JSON.parse(data);
23
+ // Only return if it matches the requested tour
24
+ if (state.tourId !== tourId)
25
+ return null;
26
+ return state;
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
32
+ /**
33
+ * Save tour state to localStorage
34
+ */
35
+ function saveTourState(state) {
36
+ try {
37
+ localStorage.setItem(ACTIVE_TOUR_KEY, JSON.stringify(state));
38
+ }
39
+ catch {
40
+ // Storage may be full or unavailable
41
+ }
42
+ }
43
+ /**
44
+ * Clear tour state from localStorage
45
+ */
46
+ function clearTourState() {
47
+ try {
48
+ localStorage.removeItem(ACTIVE_TOUR_KEY);
49
+ }
50
+ catch {
51
+ // Ignore errors
52
+ }
53
+ }
54
+ /**
55
+ * Get current route/path
56
+ */
57
+ function getCurrentRoute() {
58
+ return window.location.pathname;
59
+ }
60
+ /**
61
+ * Check if a step matches the current route
62
+ */
63
+ function stepMatchesRoute(step) {
64
+ if (!step.route)
65
+ return true;
66
+ const currentRoute = getCurrentRoute();
67
+ // Simple pattern matching - step.route can be exact path or glob pattern
68
+ if (step.route.includes('*')) {
69
+ const pattern = new RegExp(`^${step.route.replace(/\*/g, '.*')}$`);
70
+ return pattern.test(currentRoute);
71
+ }
72
+ return currentRoute === step.route;
73
+ }
74
+ /**
75
+ * Execute a tour action
76
+ *
77
+ * Tours orchestrate a sequence of steps, persisting state to localStorage
78
+ * to support cross-page navigation. Each step contains an action to execute
79
+ * and optionally defines transitions based on action events.
80
+ */
81
+ export const executeTour = async (action, context) => {
82
+ const { tourId, steps, startStep, autoStart = true } = action;
83
+ if (steps.length === 0) {
84
+ throw new Error(`Tour "${tourId}" has no steps`);
85
+ }
86
+ // Self-guard: if this tour is already running, return no-op
87
+ // This prevents duplicate modals when applyBatch is called multiple times
88
+ if (activeTours.has(tourId)) {
89
+ return {
90
+ cleanup: async () => {
91
+ // Delegate to the original tour's cleanup
92
+ const existing = activeTours.get(tourId);
93
+ if (existing) {
94
+ await existing.cleanup();
95
+ }
96
+ },
97
+ };
98
+ }
99
+ // Check if we can execute inner actions
100
+ if (!context.applyAction) {
101
+ throw new Error('Tour executor requires applyAction in context');
102
+ }
103
+ // Get or initialize tour state
104
+ let state = getTourState(tourId);
105
+ const isResumingTour = !!state;
106
+ // If not resuming and autoStart is false, don't start the tour
107
+ if (!isResumingTour && !autoStart) {
108
+ return {
109
+ cleanup: () => { },
110
+ };
111
+ }
112
+ if (!state) {
113
+ state = {
114
+ tourId,
115
+ currentStepId: startStep || steps[0].id,
116
+ startedAt: Date.now(),
117
+ };
118
+ saveTourState(state);
119
+ }
120
+ // Find the current step
121
+ let currentStepIndex = steps.findIndex((s) => s.id === state.currentStepId);
122
+ if (currentStepIndex === -1) {
123
+ // Step not found, use startStep or first step
124
+ const initialStepId = startStep || steps[0].id;
125
+ currentStepIndex = steps.findIndex((s) => s.id === initialStepId);
126
+ if (currentStepIndex === -1)
127
+ currentStepIndex = 0;
128
+ state.currentStepId = steps[currentStepIndex].id;
129
+ saveTourState(state);
130
+ }
131
+ const currentStep = steps[currentStepIndex];
132
+ // Check if current step matches the route
133
+ if (!stepMatchesRoute(currentStep)) {
134
+ // Current page doesn't match this step's route
135
+ // Tour is "waiting" for navigation to the correct page
136
+ context.publishEvent('tour.waiting_for_route', {
137
+ tourId,
138
+ stepId: currentStep.id,
139
+ expectedRoute: currentStep.route,
140
+ currentRoute: getCurrentRoute(),
141
+ });
142
+ // Return a no-op that cleans up when tour ends
143
+ return {
144
+ cleanup: () => { },
145
+ };
146
+ }
147
+ // Track state
148
+ let isDestroyed = false;
149
+ let currentActionHandle = null;
150
+ let eventUnsubscribe = null;
151
+ let routeWatcher = null;
152
+ /**
153
+ * Clean up current step
154
+ */
155
+ const cleanupCurrentStep = async () => {
156
+ if (eventUnsubscribe) {
157
+ eventUnsubscribe();
158
+ eventUnsubscribe = null;
159
+ }
160
+ if (currentActionHandle?.isApplied()) {
161
+ await currentActionHandle.revert();
162
+ currentActionHandle = null;
163
+ }
164
+ };
165
+ /**
166
+ * Advance to the next step
167
+ */
168
+ const advanceToStep = async (nextStepId) => {
169
+ if (isDestroyed)
170
+ return;
171
+ // Clean up current step
172
+ await cleanupCurrentStep();
173
+ if (nextStepId === 'end') {
174
+ // Tour complete
175
+ clearTourState();
176
+ context.publishEvent('tour.completed', {
177
+ tourId,
178
+ totalSteps: steps.length,
179
+ });
180
+ isDestroyed = true;
181
+ return;
182
+ }
183
+ // Find next step
184
+ const nextStep = steps.find((s) => s.id === nextStepId);
185
+ if (!nextStep) {
186
+ console.error(`[Tour] Step "${nextStepId}" not found`);
187
+ return;
188
+ }
189
+ // Update state
190
+ state.currentStepId = nextStepId;
191
+ saveTourState(state);
192
+ context.publishEvent('tour.step_changed', {
193
+ tourId,
194
+ previousStepId: currentStep.id,
195
+ nextStepId,
196
+ });
197
+ // If the next step has a different route, let navigation happen
198
+ if (nextStep.route && nextStep.route !== getCurrentRoute()) {
199
+ context.publishEvent('tour.awaiting_navigation', {
200
+ tourId,
201
+ stepId: nextStepId,
202
+ targetRoute: nextStep.route,
203
+ });
204
+ // Tour will resume when page reloads and this executor runs again
205
+ return;
206
+ }
207
+ // Execute the next step's action
208
+ await executeStep(nextStep);
209
+ };
210
+ /**
211
+ * Execute a step's inner action and set up event listeners
212
+ */
213
+ const executeStep = async (step) => {
214
+ if (isDestroyed)
215
+ return;
216
+ context.publishEvent('tour.step_started', {
217
+ tourId,
218
+ stepId: step.id,
219
+ stepIndex: steps.findIndex((s) => s.id === step.id),
220
+ totalSteps: steps.length,
221
+ });
222
+ // Execute the inner action
223
+ try {
224
+ currentActionHandle = await context.applyAction(step.action);
225
+ }
226
+ catch (error) {
227
+ console.error(`[Tour] Failed to execute step "${step.id}":`, error);
228
+ context.publishEvent('tour.step_failed', {
229
+ tourId,
230
+ stepId: step.id,
231
+ error: String(error),
232
+ });
233
+ return;
234
+ }
235
+ // Subscribe to CTA click events if there are transitions defined
236
+ if (step.onAction && context.subscribeEvent) {
237
+ eventUnsubscribe = context.subscribeEvent('action.modal_cta_clicked', (props) => {
238
+ const actionId = props?.actionId;
239
+ if (actionId && step.onAction) {
240
+ const nextStepId = step.onAction[actionId];
241
+ if (nextStepId) {
242
+ advanceToStep(nextStepId);
243
+ }
244
+ }
245
+ });
246
+ // Also listen for tooltip CTA clicks
247
+ const tooltipUnsubscribe = context.subscribeEvent('action.tooltip_cta_clicked', (props) => {
248
+ const actionId = props?.actionId;
249
+ if (actionId && step.onAction) {
250
+ const nextStepId = step.onAction[actionId];
251
+ if (nextStepId) {
252
+ advanceToStep(nextStepId);
253
+ }
254
+ }
255
+ });
256
+ // Combine unsubscribes
257
+ const originalUnsubscribe = eventUnsubscribe;
258
+ eventUnsubscribe = () => {
259
+ originalUnsubscribe();
260
+ tooltipUnsubscribe();
261
+ };
262
+ }
263
+ };
264
+ // Set up route change watcher for SPAs
265
+ const setupRouteWatcher = () => {
266
+ let lastPath = getCurrentRoute();
267
+ const checkRoute = () => {
268
+ const currentPath = getCurrentRoute();
269
+ if (currentPath !== lastPath) {
270
+ lastPath = currentPath;
271
+ context.publishEvent('tour.route_changed', {
272
+ tourId,
273
+ newRoute: currentPath,
274
+ });
275
+ }
276
+ };
277
+ // Use NavigationMonitor if available (single patch point),
278
+ // otherwise fall back to direct History API patching (legacy)
279
+ if (context.subscribeNavigation) {
280
+ return context.subscribeNavigation(() => checkRoute());
281
+ }
282
+ // Legacy: direct History API patching
283
+ window.addEventListener('popstate', checkRoute);
284
+ const origPushState = history.pushState.bind(history);
285
+ const origReplaceState = history.replaceState.bind(history);
286
+ history.pushState = (...args) => {
287
+ origPushState(...args);
288
+ queueMicrotask(checkRoute);
289
+ };
290
+ history.replaceState = (...args) => {
291
+ origReplaceState(...args);
292
+ queueMicrotask(checkRoute);
293
+ };
294
+ return () => {
295
+ window.removeEventListener('popstate', checkRoute);
296
+ history.pushState = origPushState;
297
+ history.replaceState = origReplaceState;
298
+ };
299
+ };
300
+ routeWatcher = setupRouteWatcher();
301
+ // Publish tour started/resumed event
302
+ if (!isResumingTour) {
303
+ context.publishEvent('tour.started', {
304
+ tourId,
305
+ totalSteps: steps.length,
306
+ startStepId: state.currentStepId,
307
+ });
308
+ }
309
+ else {
310
+ context.publishEvent('tour.resumed', {
311
+ tourId,
312
+ stepId: state.currentStepId,
313
+ });
314
+ }
315
+ // Execute the current step
316
+ await executeStep(currentStep);
317
+ // Create cleanup function
318
+ const cleanup = async () => {
319
+ isDestroyed = true;
320
+ // Remove from active tours
321
+ activeTours.delete(tourId);
322
+ await cleanupCurrentStep();
323
+ if (routeWatcher) {
324
+ routeWatcher();
325
+ }
326
+ // Don't clear tour state on cleanup - allow resume
327
+ context.publishEvent('tour.paused', {
328
+ tourId,
329
+ stepId: state.currentStepId,
330
+ });
331
+ };
332
+ // Register this tour as active
333
+ activeTours.set(tourId, { cleanup });
334
+ return { cleanup };
335
+ };
package/dist/modal.d.ts CHANGED
@@ -2,6 +2,8 @@
2
2
  * Modal Executor
3
3
  *
4
4
  * Displays a centered modal dialog with optional CTA buttons.
5
+ * Uses CSS custom properties (var()) directly in inline styles so theming
6
+ * is live — no timing dependency on when ThemeProvider injects vars.
5
7
  */
6
8
  import type { ActionExecutor, ModalAction } from './types';
7
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../src/modal.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAkB,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,WAAW,CAyNpD,CAAC"}
1
+ {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../src/modal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAkB,WAAW,EAAE,MAAM,SAAS,CAAC;AAW3E;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,WAAW,CA0NpD,CAAC"}
package/dist/modal.js CHANGED
@@ -2,9 +2,18 @@
2
2
  * Modal Executor
3
3
  *
4
4
  * Displays a centered modal dialog with optional CTA buttons.
5
+ * Uses CSS custom properties (var()) directly in inline styles so theming
6
+ * is live — no timing dependency on when ThemeProvider injects vars.
5
7
  */
6
- import { base } from '@syntro/design-system/tokens';
7
8
  import { sanitizeHtml } from './sanitizer';
9
+ // CSS var shorthands with fallbacks (mirrors tooltip/toast pattern)
10
+ const V = {
11
+ bg: 'var(--sc-overlay-background, #ffffff)',
12
+ title: 'var(--sc-overlay-title-color, var(--sc-overlay-text-color, #111827))',
13
+ text: 'var(--sc-overlay-text-color, #4b5563)',
14
+ accent: 'var(--sc-color-primary, #4f46e5)',
15
+ radius: 'var(--sc-border-radius, 12px)',
16
+ };
8
17
  /**
9
18
  * Execute a modal action
10
19
  */
@@ -36,8 +45,8 @@ export const executeModal = async (action, context) => {
36
45
  transform: translate(-50%, -50%) scale(0.95);
37
46
  max-width: ${sizeMap[size]};
38
47
  width: 90%;
39
- background: ${base.white};
40
- border-radius: 12px;
48
+ background: ${V.bg};
49
+ border-radius: ${V.radius};
41
50
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
42
51
  z-index: 2147483646;
43
52
  opacity: 0;
@@ -47,9 +56,9 @@ export const executeModal = async (action, context) => {
47
56
  // Build modal HTML content
48
57
  let html = '';
49
58
  if (content.title) {
50
- html += `<h2 class="syntro-modal-title" style="margin: 0 0 12px 0; font-size: 18px; font-weight: 600; color: #111827;">${sanitizeHtml(content.title)}</h2>`;
59
+ html += `<h2 class="syntro-modal-title" style="margin: 0 0 12px 0; font-size: 18px; font-weight: 600; color: ${V.title};">${sanitizeHtml(content.title)}</h2>`;
51
60
  }
52
- html += `<div class="syntro-modal-body" style="color: #4b5563; line-height: 1.5;">${sanitizeHtml(content.body)}</div>`;
61
+ html += `<div class="syntro-modal-body" style="color: ${V.text}; line-height: 1.5;">${sanitizeHtml(content.body)}</div>`;
53
62
  // Add close button if enabled
54
63
  if (dismiss?.closeButton !== false) {
55
64
  html += `
@@ -61,7 +70,8 @@ export const executeModal = async (action, context) => {
61
70
  border: none;
62
71
  cursor: pointer;
63
72
  padding: 4px;
64
- color: #6b7280;
73
+ color: ${V.text};
74
+ opacity: 0.6;
65
75
  " aria-label="Close">
66
76
  <svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor">
67
77
  <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
@@ -86,8 +96,8 @@ export const executeModal = async (action, context) => {
86
96
  cursor: pointer;
87
97
  transition: background 150ms ease;
88
98
  ${isPrimary
89
- ? 'background: #4f46e5; color: white; border: none;'
90
- : 'background: white; color: #374151; border: 1px solid #d1d5db;'}
99
+ ? `background: ${V.accent}; color: white; border: none;`
100
+ : `background: transparent; color: ${V.accent}; border: 1px solid currentColor; opacity: 0.7;`}
91
101
  "
92
102
  >
93
103
  ${sanitizeHtml(btn.label)}
package/dist/runtime.d.ts CHANGED
@@ -1,11 +1,13 @@
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 { executeTour } from './executors/tour';
6
7
  import { executeModal } from './modal';
7
8
  import type { ActionExecutor, BadgeAction, HighlightAction, PulseAction, TooltipAction } from './types';
8
- export { executeModal };
9
+ export { executeModal, executeTour };
10
+ export type { TourAction, TourStep, WorkflowMeta } from './tour-types';
9
11
  /**
10
12
  * Execute a highlight action
11
13
  */
@@ -41,6 +43,12 @@ export declare const executors: readonly [{
41
43
  }, {
42
44
  readonly kind: "overlays:modal";
43
45
  readonly executor: ActionExecutor<import("./types").ModalAction>;
46
+ }, {
47
+ readonly kind: "core:tour";
48
+ readonly executor: ActionExecutor<import("./tour-types").TourAction>;
49
+ }, {
50
+ readonly kind: "overlays:celebrate";
51
+ readonly executor: ActionExecutor<import("./types").CelebrateAction>;
44
52
  }];
45
53
  /**
46
54
  * App runtime manifest.
@@ -65,6 +73,21 @@ export declare const runtime: {
65
73
  }, {
66
74
  readonly kind: "overlays:modal";
67
75
  readonly executor: ActionExecutor<import("./types").ModalAction>;
76
+ }, {
77
+ readonly kind: "core:tour";
78
+ readonly executor: ActionExecutor<import("./tour-types").TourAction>;
79
+ }, {
80
+ readonly kind: "overlays:celebrate";
81
+ readonly executor: ActionExecutor<import("./types").CelebrateAction>;
68
82
  }];
83
+ widgets: {
84
+ id: string;
85
+ component: import("./WorkflowWidget").MountableWidget;
86
+ metadata: {
87
+ name: string;
88
+ icon: string;
89
+ description: string;
90
+ };
91
+ }[];
69
92
  };
70
93
  //# sourceMappingURL=runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EAEX,eAAe,EACf,WAAW,EACX,aAAa,EACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,YAAY,EAAE,CAAC;AAMxB;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,eAAe,CA8B5D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,WAAW,CAqDpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,WAAW,CA8EpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,aAAa,CAoFxD,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;EAMZ,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;CAMnB,CAAC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EAEX,eAAe,EACf,WAAW,EACX,aAAa,EACd,MAAM,SAAS,CAAC;AAIjB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;AAGrC,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAMvE;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,eAAe,CA2D5D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,WAAW,CAyGpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,WAAW,CA+FpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,aAAa,CAwFxD,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;EAQZ,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkBnB,CAAC"}