From fd0ccaefd86ce950fd3b2eceb9f78184d80f2c5e Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Wed, 10 Dec 2025 10:56:10 +0100 Subject: [PATCH 1/6] Ensure body never scrolls out of the viewport --- code/core/src/theming/global.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/core/src/theming/global.ts b/code/core/src/theming/global.ts index 3a28c75f86d1..190dad605bad 100644 --- a/code/core/src/theming/global.ts +++ b/code/core/src/theming/global.ts @@ -99,9 +99,12 @@ export const createGlobal = memoize(1)(({ ...resetStyles, body: { ...resetStyles.body, + position: 'fixed', + width: '100vw', + height: '100vh', + overflow: 'hidden', color: color.defaultText, background: background.app, - overflow: 'hidden', }, hr: { From d26a688ebf7eec32725e859bd1c95a08eaee2b48 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Wed, 10 Dec 2025 11:14:15 +0100 Subject: [PATCH 2/6] Reset panel height so guided tour tooltip can render correctly --- code/addons/onboarding/src/Onboarding.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/code/addons/onboarding/src/Onboarding.tsx b/code/addons/onboarding/src/Onboarding.tsx index 0c667320a118..8cc95a92ead7 100644 --- a/code/addons/onboarding/src/Onboarding.tsx +++ b/code/addons/onboarding/src/Onboarding.tsx @@ -119,6 +119,7 @@ export default function Onboarding({ api.togglePanel(true); api.togglePanelPosition('bottom'); api.setSelectedPanel(ADDON_CONTROLS_ID); + api.setSizes({ bottomPanelHeight: 300 }); }, [api, selectStory]); useEffect(() => { From 77aee15e3d348718e5fd59f62df87f0e47b267dc Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Wed, 10 Dec 2025 12:06:00 +0100 Subject: [PATCH 3/6] Tweak controls panel styling to fix overflow issue and design consistent with other panels --- .../src/controls/components/ControlsPanel.tsx | 38 ++++++++++--------- .../src/controls/components/SaveStory.tsx | 4 +- code/core/src/controls/manager.tsx | 2 +- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/code/core/src/controls/components/ControlsPanel.tsx b/code/core/src/controls/components/ControlsPanel.tsx index c7af9a12b688..e5c863122f29 100644 --- a/code/core/src/controls/components/ControlsPanel.tsx +++ b/code/core/src/controls/components/ControlsPanel.tsx @@ -1,6 +1,5 @@ import React, { useEffect, useMemo, useState } from 'react'; -import { ScrollArea } from 'storybook/internal/components'; import type { ArgTypes } from 'storybook/internal/types'; import { global } from '@storybook/global'; @@ -31,11 +30,16 @@ const clean = (obj: { [key: string]: any }) => {} as typeof obj ); -const AddonWrapper = styled.div<{ showSaveFromUI: boolean }>(({ showSaveFromUI }) => ({ - display: 'grid', - gridTemplateRows: showSaveFromUI ? '1fr 41px' : '1fr', +const AddonWrapper = styled.div<{ showSaveFromUI: boolean }>(({ showSaveFromUI, theme }) => ({ height: '100%', maxHeight: '100vh', + paddingBottom: showSaveFromUI ? 41 : 0, + backgroundColor: theme.background.content, + + thead: { + backgroundColor: theme.background.app, + lineHeight: '19px', + }, })); interface ControlsParameters { @@ -101,20 +105,18 @@ export const ControlsPanel = ({ saveStory, createStory }: ControlsPanelProps) => return ( - - - + {showSaveFromUI && } ); diff --git a/code/core/src/controls/components/SaveStory.tsx b/code/core/src/controls/components/SaveStory.tsx index dd392d5e125c..94c5b5c39d91 100644 --- a/code/core/src/controls/components/SaveStory.tsx +++ b/code/core/src/controls/components/SaveStory.tsx @@ -18,8 +18,9 @@ const highlight = keyframes({ const Container = styled.div({ containerType: 'size', - position: 'sticky', + position: 'absolute', bottom: 0, + width: '100%', height: 41, overflow: 'hidden', zIndex: 1, @@ -43,6 +44,7 @@ const Info = styled.div({ display: 'flex', flex: '99 0 auto', alignItems: 'center', + marginInlineStart: 7, marginInlineEnd: 10, gap: 6, }); diff --git a/code/core/src/controls/manager.tsx b/code/core/src/controls/manager.tsx index 2e87ff332eb6..ee1d849b6cdd 100644 --- a/code/core/src/controls/manager.tsx +++ b/code/core/src/controls/manager.tsx @@ -122,7 +122,7 @@ export default addons.register(ADDON_ID, (api) => { return null; } return ( - + ); From a232aeccfb57d673035c03e11c8c07f5e4c5a2df Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Wed, 10 Dec 2025 12:59:54 +0100 Subject: [PATCH 4/6] Emit 'openSurvey' event type when opening the IntentSurvey --- code/addons/onboarding/src/Onboarding.tsx | 10 ++++++++++ code/addons/onboarding/src/Survey.tsx | 10 +++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/code/addons/onboarding/src/Onboarding.tsx b/code/addons/onboarding/src/Onboarding.tsx index 8cc95a92ead7..5946440b9b04 100644 --- a/code/addons/onboarding/src/Onboarding.tsx +++ b/code/addons/onboarding/src/Onboarding.tsx @@ -113,6 +113,16 @@ export default function Onboarding({ [api, selectStory, userAgent] ); + useEffect(() => { + if (step === '6:IntentSurvey' && !hasCompletedSurvey) { + api.emit(ADDON_ONBOARDING_CHANNEL, { + from: 'onboarding', + type: 'openSurvey', + userAgent, + }); + } + }, [api, hasCompletedSurvey, step, userAgent]); + useEffect(() => { api.setQueryParams({ onboarding: 'true' }); selectStory('example-button--primary'); diff --git a/code/addons/onboarding/src/Survey.tsx b/code/addons/onboarding/src/Survey.tsx index 7bf5f4a43815..aed4ce529194 100644 --- a/code/addons/onboarding/src/Survey.tsx +++ b/code/addons/onboarding/src/Survey.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { type API } from 'storybook/manager-api'; import { ThemeProvider, convert } from 'storybook/theming'; @@ -12,6 +12,14 @@ export default function Survey({ api }: { api: API }) { // eslint-disable-next-line compat/compat const userAgent = globalThis?.navigator?.userAgent; + useEffect(() => { + api.emit(ADDON_ONBOARDING_CHANNEL, { + from: 'guide', + type: 'openSurvey', + userAgent, + }); + }, [api, userAgent]); + const disableOnboarding = useCallback(() => { // remove onboarding query parameter from current url const url = new URL(window.location.href); From 48778579064580763e09aaafc4a138255ce8b8f0 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Wed, 10 Dec 2025 15:19:06 +0100 Subject: [PATCH 5/6] Fix onboarding survey open state handling --- code/addons/onboarding/src/Onboarding.tsx | 7 ++----- code/addons/onboarding/src/Survey.tsx | 13 ++++++------- .../features/IntentSurvey/IntentSurvey.stories.tsx | 1 + .../src/features/IntentSurvey/IntentSurvey.tsx | 4 +++- .../components/components/Modal/Modal.styled.tsx | 1 + 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/code/addons/onboarding/src/Onboarding.tsx b/code/addons/onboarding/src/Onboarding.tsx index 5946440b9b04..f1b6250cd143 100644 --- a/code/addons/onboarding/src/Onboarding.tsx +++ b/code/addons/onboarding/src/Onboarding.tsx @@ -90,11 +90,7 @@ export default function Onboarding({ userAgent, }); } - // remove onboarding query parameter from current url - const url = new URL(window.location.href); - url.searchParams.set('onboarding', 'false'); - history.replaceState({}, '', url.href); - api.setQueryParams({ onboarding: 'false' }); + api.applyQueryParams({ onboarding: undefined }, { replace: true }); setEnabled(false); }, [api, setEnabled, userAgent] @@ -315,6 +311,7 @@ export default function Onboarding({ setStep('2:Controls')} /> ) : step === '6:IntentSurvey' ? ( disableOnboarding('6:IntentSurvey')} /> diff --git a/code/addons/onboarding/src/Survey.tsx b/code/addons/onboarding/src/Survey.tsx index aed4ce529194..4e4bb94d83b9 100644 --- a/code/addons/onboarding/src/Survey.tsx +++ b/code/addons/onboarding/src/Survey.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { type API } from 'storybook/manager-api'; import { ThemeProvider, convert } from 'storybook/theming'; @@ -12,6 +12,8 @@ export default function Survey({ api }: { api: API }) { // eslint-disable-next-line compat/compat const userAgent = globalThis?.navigator?.userAgent; + const [isOpen, setIsOpen] = useState(true); + useEffect(() => { api.emit(ADDON_ONBOARDING_CHANNEL, { from: 'guide', @@ -21,11 +23,8 @@ export default function Survey({ api }: { api: API }) { }, [api, userAgent]); const disableOnboarding = useCallback(() => { - // remove onboarding query parameter from current url - const url = new URL(window.location.href); - url.searchParams.set('onboarding', 'false'); - history.replaceState({}, '', url.href); - api.setQueryParams({ onboarding: 'false' }); + setIsOpen(false); + api.applyQueryParams({ onboarding: undefined }, { replace: true }); }, [api]); const complete = useCallback( @@ -49,7 +48,7 @@ export default function Survey({ api }: { api: API }) { return ( - + ); } diff --git a/code/addons/onboarding/src/features/IntentSurvey/IntentSurvey.stories.tsx b/code/addons/onboarding/src/features/IntentSurvey/IntentSurvey.stories.tsx index 3c98af8ad38c..2ec2107481e9 100644 --- a/code/addons/onboarding/src/features/IntentSurvey/IntentSurvey.stories.tsx +++ b/code/addons/onboarding/src/features/IntentSurvey/IntentSurvey.stories.tsx @@ -7,6 +7,7 @@ import { IntentSurvey } from './IntentSurvey'; const meta = { component: IntentSurvey, args: { + isOpen: true, onComplete: fn(), onDismiss: fn(), }, diff --git a/code/addons/onboarding/src/features/IntentSurvey/IntentSurvey.tsx b/code/addons/onboarding/src/features/IntentSurvey/IntentSurvey.tsx index 9f825a1b2e48..11780fd4c55d 100644 --- a/code/addons/onboarding/src/features/IntentSurvey/IntentSurvey.tsx +++ b/code/addons/onboarding/src/features/IntentSurvey/IntentSurvey.tsx @@ -65,9 +65,11 @@ const Checkbox = styled(Form.Checkbox)({ }); export const IntentSurvey = ({ + isOpen, onComplete, onDismiss, }: { + isOpen: boolean; onComplete: (formData: Record>) => void; onDismiss: () => void; }) => { @@ -172,7 +174,7 @@ export const IntentSurvey = ({ return ( { if (!isOpen) { diff --git a/code/core/src/components/components/Modal/Modal.styled.tsx b/code/core/src/components/components/Modal/Modal.styled.tsx index eb3ca76630e6..c5d31a4d8b5d 100644 --- a/code/core/src/components/components/Modal/Modal.styled.tsx +++ b/code/core/src/components/components/Modal/Modal.styled.tsx @@ -187,6 +187,7 @@ export const Close = ({ asChild, children, onClick, ...props }: CloseProps) => { return (