From f2c4aba78f2149ded7cdb0b2503cf41c61c2ae76 Mon Sep 17 00:00:00 2001 From: Steffen Wilking Date: Tue, 11 Jul 2023 17:59:37 +0200 Subject: [PATCH 1/3] Hide keyboard shortcuts from menu when shortcuts are disabled --- code/ui/manager/src/containers/menu.tsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/code/ui/manager/src/containers/menu.tsx b/code/ui/manager/src/containers/menu.tsx index a387cb24d5f3..4dd8ab8ae477 100644 --- a/code/ui/manager/src/containers/menu.tsx +++ b/code/ui/manager/src/containers/menu.tsx @@ -71,6 +71,12 @@ export const useMenu = ( const whatsNewNotificationsEnabled = state.whatsNewData?.status === 'SUCCESS' && !state.disableWhatsNewNotifications; const isWhatsNewUnread = api.isWhatsNewUnread(); + + const separatorStyle = useMemo( + () => ({ borderBottom: `4px solid ${theme.appBorderColor}` }), + [theme.appBorderColor] + ); + const whatsNew = useMemo( () => ({ id: 'whats-new', @@ -79,8 +85,9 @@ export const useMenu = ( right: whatsNewNotificationsEnabled && isWhatsNewUnread && ( Check it out ), + style: { ...(enableShortcuts ? {} : separatorStyle) }, }), - [api, whatsNewNotificationsEnabled, isWhatsNewUnread] + [api, whatsNewNotificationsEnabled, isWhatsNewUnread, enableShortcuts, separatorStyle] ); const shortcuts = useMemo( @@ -89,11 +96,9 @@ export const useMenu = ( title: 'Keyboard shortcuts', onClick: () => api.navigateToSettingsPage('/settings/shortcuts'), right: enableShortcuts ? : null, - style: { - borderBottom: `4px solid ${theme.appBorderColor}`, - }, + style: { ...(enableShortcuts ? separatorStyle : {}) }, }), - [api, enableShortcuts, shortcutKeys.shortcutsPage, theme.appBorderColor] + [api, enableShortcuts, shortcutKeys.shortcutsPage, separatorStyle] ); const sidebarToggle = useMemo( @@ -231,7 +236,7 @@ export const useMenu = ( () => [ about, ...(state.whatsNewData?.status === 'SUCCESS' ? [whatsNew] : []), - shortcuts, + ...(enableShortcuts ? [shortcuts] : []), sidebarToggle, toolbarToogle, addonsToggle, @@ -262,6 +267,7 @@ export const useMenu = ( next, collapse, getAddonsShortcuts, + enableShortcuts, ] ); }; From bd3e662f04612bf8d570ffc07a8da1bbb523cdc4 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Wed, 25 Jun 2025 08:38:02 +0200 Subject: [PATCH 2/3] Add icon to keyboard shortcuts item and improve label for addons panel toggle --- code/core/src/manager/container/Menu.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/core/src/manager/container/Menu.tsx b/code/core/src/manager/container/Menu.tsx index 0d494af1a057..b61dcc06c472 100644 --- a/code/core/src/manager/container/Menu.tsx +++ b/code/core/src/manager/container/Menu.tsx @@ -4,7 +4,7 @@ import React, { useCallback, useMemo } from 'react'; import { Badge } from 'storybook/internal/components'; import { STORIES_COLLAPSE_ALL } from 'storybook/internal/core-events'; -import { CheckIcon, InfoIcon, ShareAltIcon, WandIcon } from '@storybook/icons'; +import { CheckIcon, CommandIcon, InfoIcon, ShareAltIcon, WandIcon } from '@storybook/icons'; import type { API, State } from 'storybook/manager-api'; import { shortcutToHumanString } from 'storybook/manager-api'; @@ -103,6 +103,7 @@ export const useMenu = ( title: 'Keyboard shortcuts', onClick: () => api.changeSettingsTab('shortcuts'), right: enableShortcuts ? : null, + icon: , }), [api, enableShortcuts, shortcutKeys.shortcutsPage] ); @@ -134,7 +135,7 @@ export const useMenu = ( const addonsToggle = useMemo( () => ({ id: 'A', - title: 'Show addons', + title: 'Show addons panel', onClick: () => api.togglePanel(), active: isPanelShown, right: enableShortcuts ? : null, From 2ced0e9cb774ddb480ffb59b2d27cc45eb98f395 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Wed, 25 Jun 2025 11:00:38 +0200 Subject: [PATCH 3/3] Refactor menu stories and add keyboard shortcuts story --- .../components/sidebar/Menu.stories.tsx | 63 +++++++++++++++++-- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/code/core/src/manager/components/sidebar/Menu.stories.tsx b/code/core/src/manager/components/sidebar/Menu.stories.tsx index 6a1c4dcfeb83..600e3afd8366 100644 --- a/code/core/src/manager/components/sidebar/Menu.stories.tsx +++ b/code/core/src/manager/components/sidebar/Menu.stories.tsx @@ -56,13 +56,13 @@ export const Expanded: Story = { globals: { sb_theme: 'light' }, render: () => { const menu = useMenu( - { whatsNewData: { status: 'SUCCESS', disableWhatsNewNotifications: false } } as State, + { whatsNewData: undefined } as State, { // @ts-expect-error (Converted from ts-ignore) getShortcutKeys: () => ({}), getAddonsShortcuts: () => ({}), versionUpdateAvailable: () => false, - isWhatsNewUnread: () => true, + isWhatsNewUnread: () => false, getDocsUrl: () => 'https://storybook.js.org/docs/', }, false, @@ -73,7 +73,7 @@ export const Expanded: Story = { ); return ( - + ); }, @@ -96,14 +96,27 @@ export const Expanded: Story = { ], }; -export const ExpandedWithoutWhatsNew: Story = { +export const ExpandedWithShortcuts: Story = { ...Expanded, render: () => { const menu = useMenu( { whatsNewData: undefined } as State, { // @ts-expect-error (invalid) - getShortcutKeys: () => ({}), + getShortcutKeys: () => ({ + shortcutsPage: ['⌘', '⇧​', ','], + toggleNav: ['⌥', 'S'], + togglePanel: ['⌥', 'A'], + toolbar: ['⌥', 'T'], + panelPosition: ['⌥', 'D'], + fullScreen: ['⌥', 'F'], + search: ['⌥', 'K'], + prevComponent: ['⌥', '↑'], + nextComponent: ['⌥', '↓'], + prevStory: ['⌥', '←'], + nextStory: ['⌥', '→'], + collapseAll: ['⌥', '⇧', '↑'], + }), getAddonsShortcuts: () => ({}), versionUpdateAvailable: () => false, isWhatsNewUnread: () => false, @@ -113,7 +126,7 @@ export const ExpandedWithoutWhatsNew: Story = { false, false, false, - false + true ); return ( @@ -133,3 +146,41 @@ export const ExpandedWithoutWhatsNew: Story = { await expect(releaseNotes).not.toBeInTheDocument(); }, }; + +export const ExpandedWithWhatsNew: Story = { + ...Expanded, + render: () => { + const menu = useMenu( + { whatsNewData: { status: 'SUCCESS', disableWhatsNewNotifications: false } } as State, + { + // @ts-expect-error (invalid) + getShortcutKeys: () => ({}), + getAddonsShortcuts: () => ({}), + versionUpdateAvailable: () => false, + isWhatsNewUnread: () => true, + getDocsUrl: () => 'https://storybook.js.org/docs/', + }, + false, + false, + false, + false, + false + ); + + return ( + + + + ); + }, + play: async (context) => { + const canvas = within(context.canvasElement); + await new Promise((res) => { + setTimeout(res, 500); + }); + // @ts-expect-error (non strict) + await Expanded.play(context); + const releaseNotes = await canvas.queryByText(/What's new/); + await expect(releaseNotes).not.toBeInTheDocument(); + }, +};