Skip to content

Commit 1aed382

Browse files
committed
fix: tutorial no longer dismisses on overlay click; hidden panel warning replaced with Show Panel button
- Set overlayClickBehavior to no-op so clicking the overlay doesn't destroy the tour (users can still close via the X button) - Replace "Element not visible" warning with "Panel hidden" label, an animated SVG cursor, and a "Show {Panel}" button that programmatically opens the required panel - Add delegated click handler for [data-open-panel] buttons - Bump to 1.1.2 Made-with: Cursor
1 parent 081df4f commit 1aed382

5 files changed

Lines changed: 98 additions & 27 deletions

File tree

flexfoil-ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "flexfoil-ui",
33
"private": true,
44
"license": "MIT",
5-
"version": "1.1.1",
5+
"version": "1.1.2",
66
"type": "module",
77
"scripts": {
88
"dev": "vite",

flexfoil-ui/src/App.css

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -717,30 +717,25 @@ button.primary:hover {
717717
color: #ffc107;
718718
}
719719

720-
/* Element not visible warning (when tour element is hidden behind a tab) */
720+
/* Panel-hidden warning (when tour element is behind a closed/inactive tab) */
721721
.tour-element-warning {
722722
margin-bottom: 12px;
723-
padding: 12px;
724-
background: rgba(255, 152, 0, 0.15);
725-
border: 1px solid rgba(255, 152, 0, 0.4);
726-
border-radius: 6px;
723+
padding: 12px 14px;
724+
background: rgba(255, 152, 0, 0.12);
725+
border: 1px solid rgba(255, 152, 0, 0.35);
726+
border-radius: 8px;
727727
border-left: 3px solid #ff9800;
728728
}
729729

730730
[data-theme="light"] .tour-element-warning {
731-
background: rgba(255, 152, 0, 0.1);
731+
background: rgba(255, 152, 0, 0.08);
732732
}
733733

734734
.tour-element-warning__header {
735735
display: flex;
736736
align-items: center;
737737
gap: 8px;
738-
margin-bottom: 8px;
739-
}
740-
741-
.tour-element-warning__icon {
742-
font-size: 16px;
743-
color: #ff9800;
738+
margin-bottom: 6px;
744739
}
745740

746741
.tour-element-warning__label {
@@ -755,19 +750,60 @@ button.primary:hover {
755750
font-size: 13px;
756751
color: var(--text-secondary);
757752
line-height: 1.5;
753+
margin-bottom: 10px;
758754
}
759755

760756
.tour-element-warning__message strong {
761757
color: var(--text-primary);
762758
}
763759

764-
.tour-element-warning__message ul {
765-
margin: 8px 0 0 0;
766-
padding-left: 20px;
760+
/* Animated cursor SVG inside the warning header */
761+
.tour-animated-cursor {
762+
color: #ff9800;
763+
animation: tour-cursor-click 1.6s ease-in-out infinite;
764+
flex-shrink: 0;
767765
}
768766

769-
.tour-element-warning__message li {
770-
margin-bottom: 4px;
767+
@keyframes tour-cursor-click {
768+
0%, 100% { transform: translate(0, 0) scale(1); opacity: 1; }
769+
40% { transform: translate(2px, 3px) scale(0.92); opacity: 0.8; }
770+
55% { transform: translate(2px, 3px) scale(0.92); opacity: 0.8; }
771+
70% { transform: translate(0, 0) scale(1); opacity: 1; }
772+
}
773+
774+
/* "Show Panel" button */
775+
.tour-show-panel-btn {
776+
display: flex;
777+
align-items: center;
778+
justify-content: center;
779+
gap: 6px;
780+
width: 100%;
781+
padding: 8px 14px;
782+
font-size: 13px;
783+
font-weight: 600;
784+
color: #fff;
785+
background: #e68a00;
786+
border: none;
787+
border-radius: 6px;
788+
cursor: pointer;
789+
transition: background 0.15s, transform 0.1s;
790+
}
791+
792+
.tour-show-panel-btn:hover {
793+
background: #cc7a00;
794+
}
795+
796+
.tour-show-panel-btn:active {
797+
transform: scale(0.97);
798+
}
799+
800+
[data-theme="light"] .tour-show-panel-btn {
801+
background: #f59e0b;
802+
color: #1a1a1a;
803+
}
804+
805+
[data-theme="light"] .tour-show-panel-btn:hover {
806+
background: #d97706;
771807
}
772808

773809
/* ── Command Palette ───────────────────────────────── */

flexfoil-ui/src/lib/version.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ export interface ChangelogEntry {
2828
}
2929

3030
export const CHANGELOG: ChangelogEntry[] = [
31+
{
32+
version: '1.1.2',
33+
date: '2026-03-20',
34+
items: [
35+
{ category: 'fixed', text: 'Tutorial no longer dismisses when clicking on panels or the overlay' },
36+
{ category: 'changed', text: 'Hidden panel warning in tutorials replaced with a "Show Panel" button and animated cursor' },
37+
],
38+
},
3139
{
3240
version: '1.1.1',
3341
date: '2026-03-19',

flexfoil-ui/src/onboarding/OnboardingProvider.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ export function OnboardingProvider({ children }: OnboardingProviderProps) {
130130
doneBtnText: 'Done',
131131
progressText: '{{current}} of {{total}}',
132132
allowClose: true,
133+
overlayClickBehavior: () => {},
133134
overlayColor: isDark ? 'rgba(0, 0, 0, 0.75)' : 'rgba(0, 0, 0, 0.5)',
134135
stagePadding: 8,
135136
stageRadius: 8,
@@ -308,6 +309,27 @@ export function OnboardingProvider({ children }: OnboardingProviderProps) {
308309
return driverRef.current;
309310
}, [clearChallengePolling, buildChallengeHTML, openPanel]);
310311

312+
// Delegated click handler for "Show Panel" buttons injected into tour popovers.
313+
// Active only while a tour is running so it doesn't interfere otherwise.
314+
useEffect(() => {
315+
if (!isActive) return;
316+
317+
const handleShowPanel = (e: MouseEvent) => {
318+
const btn = (e.target as HTMLElement).closest<HTMLButtonElement>('[data-open-panel]');
319+
if (!btn) return;
320+
e.stopPropagation();
321+
const panelId = btn.dataset.openPanel;
322+
if (panelId) {
323+
openPanel(panelId);
324+
// After opening, give layout a moment to settle then refresh the highlight
325+
setTimeout(() => driverRef.current?.refresh(), 150);
326+
}
327+
};
328+
329+
document.addEventListener('click', handleShowPanel, true);
330+
return () => document.removeEventListener('click', handleShowPanel, true);
331+
}, [isActive, openPanel]);
332+
311333
// Cleanup on unmount
312334
useEffect(() => {
313335
return () => {

flexfoil-ui/src/onboarding/challenges.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,24 +159,29 @@ export function getParentPanel(selector: string): string | null {
159159
}
160160

161161
/**
162-
* Build HTML for element not visible warning
162+
* Build HTML for element not visible warning with actionable "Show Panel" button
163+
* and an animated cursor to draw attention.
163164
*/
164165
export function buildElementNotVisibleHTML(panelId: string | null): string {
165166
const panelName = panelId ? getPanelDisplayName(panelId) : 'the required panel';
166-
167+
const dataAttr = panelId ? ` data-open-panel="${panelId}"` : '';
168+
169+
const cursorSvg = `<svg class="tour-animated-cursor" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
170+
<path d="M5 3l14 8-6.5 1.5L11 19z" fill="currentColor" stroke="var(--bg-primary, #1a1a1a)" stroke-width="1.2" stroke-linejoin="round"/>
171+
</svg>`;
172+
167173
return `
168174
<div class="tour-element-warning">
169175
<div class="tour-element-warning__header">
170-
<span class="tour-element-warning__icon">⚠</span>
171-
<span class="tour-element-warning__label">Element not visible</span>
176+
${cursorSvg}
177+
<span class="tour-element-warning__label">Panel hidden</span>
172178
</div>
173179
<div class="tour-element-warning__message">
174-
The element for this step is hidden. Please open the <strong>${panelName}</strong> panel:
175-
<ul style="margin: 8px 0 0 0; padding-left: 20px;">
176-
<li>Click on the <strong>${panelName}</strong> tab if you see it</li>
177-
<li>Or use <strong>Window</strong> menu → <strong>${panelName}</strong></li>
178-
</ul>
180+
The <strong>${panelName}</strong> panel needs to be visible for this step.
179181
</div>
182+
<button class="tour-show-panel-btn"${dataAttr}>
183+
Show ${panelName}
184+
</button>
180185
</div>
181186
`;
182187
}

0 commit comments

Comments
 (0)