From 6b283b0eee7ffca5dd696b69933fcf888f0b02aa Mon Sep 17 00:00:00 2001 From: Deva Chandragiri <122866331+Devazc@users.noreply.github.com> Date: Wed, 5 Apr 2023 15:45:49 +0530 Subject: [PATCH 01/37] Add failure notification to Discord Add failure notification to Markdown Links Check workflow. --- .github/workflows/cron-weekly.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/cron-weekly.yml b/.github/workflows/cron-weekly.yml index 8dafd4e99c27..de3b0ed8e044 100644 --- a/.github/workflows/cron-weekly.yml +++ b/.github/workflows/cron-weekly.yml @@ -17,3 +17,16 @@ jobs: # output full HTTP info for broken links use-verbose-mode: 'yes' config-file: '.github/workflows/markdown-link-check-config.json' + + # Notify to Discord channel on failure + - name: Send Discord message + uses: DiscordBotName/SendMessageAction@v1 + if: failure() + with: + webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} + message: "Markdown Links Check failed for branch ${{ github.event.pull_request.head.ref }}" + + + + + From 415dda8a7a922929705723f34a4b881fb496c623 Mon Sep 17 00:00:00 2001 From: Deva Chandragiri <122866331+Devazc@users.noreply.github.com> Date: Wed, 5 Apr 2023 15:48:37 +0530 Subject: [PATCH 02/37] Add failure notification to Discord Add failure notification to Markdown Links Check workflow. --- .github/workflows/cron-weekly.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/cron-weekly.yml b/.github/workflows/cron-weekly.yml index de3b0ed8e044..b2bcc9bf2de3 100644 --- a/.github/workflows/cron-weekly.yml +++ b/.github/workflows/cron-weekly.yml @@ -25,8 +25,3 @@ jobs: with: webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} message: "Markdown Links Check failed for branch ${{ github.event.pull_request.head.ref }}" - - - - - From 9fe42c92da72ab01b71cae9aa9fd102497220fa1 Mon Sep 17 00:00:00 2001 From: Deva Chandragiri <122866331+Devazc@users.noreply.github.com> Date: Thu, 6 Apr 2023 12:52:15 +0530 Subject: [PATCH 03/37] Add Discord Notification sends a message to the #monitoring channel on Discord. --- .github/workflows/cron-weekly.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cron-weekly.yml b/.github/workflows/cron-weekly.yml index b2bcc9bf2de3..1528147aedd0 100644 --- a/.github/workflows/cron-weekly.yml +++ b/.github/workflows/cron-weekly.yml @@ -16,12 +16,9 @@ jobs: use-quiet-mode: 'yes' # output full HTTP info for broken links use-verbose-mode: 'yes' - config-file: '.github/workflows/markdown-link-check-config.json' - + config-file: '.github/workflows/markdown-link-check-config.json' # Notify to Discord channel on failure - - name: Send Discord message - uses: DiscordBotName/SendMessageAction@v1 - if: failure() - with: - webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} - message: "Markdown Links Check failed for branch ${{ github.event.pull_request.head.ref }}" + - name: Send Discord Notification + if: failure() # Only run this step if previous steps failed + run: | + curl -H "Content-Type: application/json" -X POST -d '{"content":"The Markdown Links Check workflow has failed in the repository: [storybook]"}' [webhook-url] From 0bc34d476039dee665165ba0ec8c64e3962cfdf1 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 28 Nov 2023 16:13:44 +0100 Subject: [PATCH 04/37] Update cron-weekly.yml --- .github/workflows/cron-weekly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cron-weekly.yml b/.github/workflows/cron-weekly.yml index 1528147aedd0..898d10ace803 100644 --- a/.github/workflows/cron-weekly.yml +++ b/.github/workflows/cron-weekly.yml @@ -21,4 +21,4 @@ jobs: - name: Send Discord Notification if: failure() # Only run this step if previous steps failed run: | - curl -H "Content-Type: application/json" -X POST -d '{"content":"The Markdown Links Check workflow has failed in the repository: [storybook]"}' [webhook-url] + curl -H "Content-Type: application/json" -X POST -d '{"content":"The Markdown Links Check workflow has failed in the repository: [storybook]"}' ${{ secrets.DISCORD_MONITORING_URL }} From ffc35e8ca5d4b3cf952fe10c57df903f353b03da Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Tue, 23 Jan 2024 15:20:29 +0100 Subject: [PATCH 05/37] upgrade boxen in the CLI --- code/lib/cli/package.json | 2 +- code/yarn.lock | 45 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index e20980c8e631..4fd6f7101cd5 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -96,7 +96,7 @@ "@types/cross-spawn": "^6.0.2", "@types/prompts": "^2.0.9", "@types/util-deprecate": "^1.0.0", - "boxen": "^5.1.2", + "boxen": "^7.1.1", "slash": "^5.0.0", "strip-json-comments": "^3.1.1", "typescript": "^5.3.2" diff --git a/code/yarn.lock b/code/yarn.lock index 658e3dd2ca3c..6cd5aeb1e985 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5431,7 +5431,7 @@ __metadata: "@types/util-deprecate": "npm:^1.0.0" "@yarnpkg/fslib": "npm:2.10.3" "@yarnpkg/libzip": "npm:2.3.0" - boxen: "npm:^5.1.2" + boxen: "npm:^7.1.1" chalk: "npm:^4.1.0" commander: "npm:^6.2.1" cross-spawn: "npm:^7.0.3" @@ -9385,7 +9385,7 @@ __metadata: languageName: node linkType: hard -"ansi-align@npm:^3.0.0": +"ansi-align@npm:^3.0.0, ansi-align@npm:^3.0.1": version: 3.0.1 resolution: "ansi-align@npm:3.0.1" dependencies: @@ -10416,6 +10416,22 @@ __metadata: languageName: node linkType: hard +"boxen@npm:^7.1.1": + version: 7.1.1 + resolution: "boxen@npm:7.1.1" + dependencies: + ansi-align: "npm:^3.0.1" + camelcase: "npm:^7.0.1" + chalk: "npm:^5.2.0" + cli-boxes: "npm:^3.0.0" + string-width: "npm:^5.1.2" + type-fest: "npm:^2.13.0" + widest-line: "npm:^4.0.1" + wrap-ansi: "npm:^8.1.0" + checksum: 3a9891dc98ac40d582c9879e8165628258e2c70420c919e70fff0a53ccc7b42825e73cda6298199b2fbc1f41f5d5b93b492490ad2ae27623bed3897ddb4267f8 + languageName: node + linkType: hard + "bplist-parser@npm:^0.2.0": version: 0.2.0 resolution: "bplist-parser@npm:0.2.0" @@ -11143,6 +11159,13 @@ __metadata: languageName: node linkType: hard +"camelcase@npm:^7.0.1": + version: 7.0.1 + resolution: "camelcase@npm:7.0.1" + checksum: 3adfc9a0e96d51b3a2f4efe90a84dad3e206aaa81dfc664f1bd568270e1bf3b010aad31f01db16345b4ffe1910e16ab411c7273a19a859addd1b98ef7cf4cfbd + languageName: node + linkType: hard + "can-symlink@npm:^1.0.0": version: 1.0.0 resolution: "can-symlink@npm:1.0.0" @@ -11200,7 +11223,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:5.3.0, chalk@npm:^5.0.0, chalk@npm:^5.3.0": +"chalk@npm:5.3.0, chalk@npm:^5.0.0, chalk@npm:^5.2.0, chalk@npm:^5.3.0": version: 5.3.0 resolution: "chalk@npm:5.3.0" checksum: 8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09 @@ -11451,6 +11474,13 @@ __metadata: languageName: node linkType: hard +"cli-boxes@npm:^3.0.0": + version: 3.0.0 + resolution: "cli-boxes@npm:3.0.0" + checksum: 4db3e8fbfaf1aac4fb3a6cbe5a2d3fa048bee741a45371b906439b9ffc821c6e626b0f108bdcd3ddf126a4a319409aedcf39a0730573ff050fdd7b6731e99fb9 + languageName: node + linkType: hard + "cli-cursor@npm:3.1.0, cli-cursor@npm:^3.1.0": version: 3.1.0 resolution: "cli-cursor@npm:3.1.0" @@ -29725,6 +29755,15 @@ __metadata: languageName: node linkType: hard +"widest-line@npm:^4.0.1": + version: 4.0.1 + resolution: "widest-line@npm:4.0.1" + dependencies: + string-width: "npm:^5.0.1" + checksum: 7da9525ba45eaf3e4ed1a20f3dcb9b85bd9443962450694dae950f4bdd752839747bbc14713522b0b93080007de8e8af677a61a8c2114aa553ad52bde72d0f9c + languageName: node + linkType: hard + "wildcard@npm:^2.0.0": version: 2.0.1 resolution: "wildcard@npm:2.0.1" From 62165696ed87e2b3b99f4d0ff31b8c5d72dc7ca7 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 25 Jan 2024 12:48:35 +0100 Subject: [PATCH 06/37] un-memoize getTabs to always get up-to-date tabs from addons registry --- code/ui/manager/src/components/preview/Preview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ui/manager/src/components/preview/Preview.tsx b/code/ui/manager/src/components/preview/Preview.tsx index 3130cccb3c19..724a56ef32ea 100644 --- a/code/ui/manager/src/components/preview/Preview.tsx +++ b/code/ui/manager/src/components/preview/Preview.tsx @@ -45,7 +45,7 @@ const createCanvasTab = (): Addon_BaseType => ({ const useTabs = (getElements: API['getElements'], entry: PreviewProps['entry']) => { const canvasTab = useMemo(() => createCanvasTab(), []); - const tabsFromConfig = useMemo(() => getTabs(getElements), [getElements]); + const tabsFromConfig = getTabs(getElements); return useMemo(() => { if (entry?.type === 'story' && entry.parameters) { From d6d958330be6f5294db384d3d19fedf202807216 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 26 Jan 2024 14:59:32 +0100 Subject: [PATCH 07/37] add tab= query parameter --- code/lib/manager-api/src/modules/url.ts | 12 ++++ .../src/components/preview/Preview.tsx | 58 ++++++++++++------- .../src/components/preview/Toolbar.tsx | 31 +++++----- 3 files changed, 65 insertions(+), 36 deletions(-) diff --git a/code/lib/manager-api/src/modules/url.ts b/code/lib/manager-api/src/modules/url.ts index e9431f04a1f5..8896ab272899 100644 --- a/code/lib/manager-api/src/modules/url.ts +++ b/code/lib/manager-api/src/modules/url.ts @@ -144,6 +144,12 @@ export interface SubAPI { * @returns {void} */ setQueryParams: (input: QueryParams) => void; + /** + * Set the query parameters for the current URL & navigates. + * @param {QueryParams} input - An object containing the query parameters to set. + * @returns {void} + */ + applyQueryParams: (input: QueryParams) => void; } export const init: ModuleFn = (moduleArgs) => { @@ -188,6 +194,12 @@ export const init: ModuleFn = (moduleArgs) => { provider.channel?.emit(UPDATE_QUERY_PARAMS, update); } }, + applyQueryParams(input) { + const { path, queryParams } = api.getUrlState(); + + navigateTo(path, { ...queryParams, ...input } as any); + api.setQueryParams(input); + }, navigateUrl(url, options) { navigate(url, { plain: true, ...options }); }, diff --git a/code/ui/manager/src/components/preview/Preview.tsx b/code/ui/manager/src/components/preview/Preview.tsx index 724a56ef32ea..365d85674c45 100644 --- a/code/ui/manager/src/components/preview/Preview.tsx +++ b/code/ui/manager/src/components/preview/Preview.tsx @@ -8,7 +8,7 @@ import type { Addon_BaseType } from '@storybook/types'; import { PREVIEW_BUILDER_PROGRESS, SET_CURRENT_STORY } from '@storybook/core-events'; import { Loader } from '@storybook/components'; -import { Location } from '@storybook/router'; +import { Location, Route } from '@storybook/router'; import * as S from './utils/components'; import { ZoomProvider, ZoomConsumer } from './tools/zoom'; @@ -81,20 +81,22 @@ const Preview = React.memo(function Preview(props) { useEffect(() => { if (entry && viewMode) { // Don't emit the event on first ("real") render, only when entry changes - if (storyId !== previousStoryId.current) { - previousStoryId.current = storyId; + if (storyId === previousStoryId.current) { + return; + } - if (viewMode.match(/docs|story/)) { - const { refId, id } = entry; - api.emit(SET_CURRENT_STORY, { - storyId: id, - viewMode, - options: { target: refId }, - }); - } + previousStoryId.current = storyId; + + if (viewMode.match(/docs|story/)) { + const { refId, id } = entry; + api.emit(SET_CURRENT_STORY, { + storyId: id, + viewMode, + options: { target: refId }, + }); } } - }, [entry, viewMode]); + }, [entry, viewMode, storyId, api]); return ( @@ -113,16 +115,28 @@ const Preview = React.memo(function Preview(props) { tabs={visibleTabsInToolbar} /> - - {tabs.map(({ render: Render, match, ...t }, i) => { - // @ts-expect-error (Converted from ts-ignore) - const key = t.id || t.key || i; - return ( - - {(lp) => } - - ); - })} + ({ + customQueryParams: api.getQueryParam('tab'), + })} + > + {({ customQueryParams: x }) => { + console.log(api.getQueryParam('tab')); + console.log(x); + const tabId = api.getQueryParam('tab'); + const tabContent = tabs.find((tab) => tab.id === tabId)?.render; + + console.log('LOG: tabbs', { tabContent, tabs, tabId }); + return ( + <> + + {tabContent && tabContent({ active: true })} + + ); + }} + diff --git a/code/ui/manager/src/components/preview/Toolbar.tsx b/code/ui/manager/src/components/preview/Toolbar.tsx index b09d8f3e2a57..34e297b207c5 100644 --- a/code/ui/manager/src/components/preview/Toolbar.tsx +++ b/code/ui/manager/src/components/preview/Toolbar.tsx @@ -73,12 +73,10 @@ export const fullScreenTool: Addon_BaseType = { }, }; -const tabsMapper = ({ state }: Combo) => ({ - viewMode: state.docsOnly, - storyId: state.storyId, +const tabsMapper = ({ api, state }: Combo) => ({ + navigate: api.navigate, path: state.path, - location: state.location, - refId: state.refId, + applyQueryParams: api.applyQueryParams, }); export const createTabsTool = (tabs: Addon_BaseType[]): Addon_BaseType => ({ @@ -91,16 +89,21 @@ export const createTabsTool = (tabs: Addon_BaseType[]): Addon_BaseType => ({ {tabs - .filter((p) => !p.hidden) - .map((t, index) => { - const to = t.route(rp); - const isActive = rp.path === to; + .filter(({ hidden }) => !hidden) + .map((tab, index) => { + const tabIdToApply = tab.id === 'canvas' ? undefined : tab.id; + const isActive = rp.path.includes(`tab=${tab.id}`); return ( - - - {t.title as any} - - + { + rp.applyQueryParams({ tab: tabIdToApply }); + }} + key={tab.id || `tab-${index}`} + > + {tab.title as any} + ); })} From 1d84cd9b4b8a189ea06d30c9b9cab5bcae09339a Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Sat, 27 Jan 2024 00:05:18 +0100 Subject: [PATCH 08/37] make tabs work with a queryParam --- code/ui/manager/src/App.tsx | 4 +- .../manager/src/components/layout/Layout.tsx | 15 +- .../src/components/preview/Preview.tsx | 90 ++++------- .../src/components/preview/Toolbar.tsx | 148 +++++++----------- .../src/components/preview/Wrappers.tsx | 6 +- .../src/components/preview/utils/types.tsx | 9 +- code/ui/manager/src/container/Preview.tsx | 74 ++++++++- code/ui/manager/src/container/Sidebar.tsx | 8 +- code/ui/manager/src/index.tsx | 7 +- 9 files changed, 186 insertions(+), 175 deletions(-) diff --git a/code/ui/manager/src/App.tsx b/code/ui/manager/src/App.tsx index 394016ff5708..22f3a9b072ee 100644 --- a/code/ui/manager/src/App.tsx +++ b/code/ui/manager/src/App.tsx @@ -16,15 +16,17 @@ type Props = { managerLayoutState: ComponentProps['managerLayoutState']; setManagerLayoutState: ComponentProps['setManagerLayoutState']; pages: Addon_PageType[]; + hasTab: boolean; }; -export const App = ({ managerLayoutState, setManagerLayoutState, pages }: Props) => { +export const App = ({ managerLayoutState, setManagerLayoutState, pages, hasTab }: Props) => { const { setMobileAboutOpen } = useLayout(); return ( <> { viewMode: API_ViewMode; + showPanel: boolean; } export type LayoutState = InternalLayoutState & ManagerLayoutState; @@ -25,6 +26,7 @@ interface Props { slotSidebar?: React.ReactNode; slotPanel?: React.ReactNode; slotPages?: React.ReactNode; + hasTab: boolean; } const MINIMUM_CONTENT_WIDTH_PX = 100; @@ -44,10 +46,12 @@ const useLayoutSyncingState = ({ managerLayoutState, setManagerLayoutState, isDesktop, + hasTab, }: { managerLayoutState: Props['managerLayoutState']; setManagerLayoutState: Props['setManagerLayoutState']; isDesktop: boolean; + hasTab: boolean; }) => { // ref to keep track of previous managerLayoutState, to check if the props change const prevManagerLayoutStateRef = React.useRef(managerLayoutState); @@ -95,7 +99,7 @@ const useLayoutSyncingState = ({ const isPagesShown = managerLayoutState.viewMode !== 'story' && managerLayoutState.viewMode !== 'docs'; - const isPanelShown = managerLayoutState.viewMode === 'story'; + const isPanelShown = managerLayoutState.viewMode === 'story' && !hasTab; const { panelResizerRef, sidebarResizerRef } = useDragging({ setState: setInternalDraggingSizeState, @@ -119,7 +123,7 @@ const useLayoutSyncingState = ({ }; }; -export const Layout = ({ managerLayoutState, setManagerLayoutState, ...slots }: Props) => { +export const Layout = ({ managerLayoutState, setManagerLayoutState, hasTab, ...slots }: Props) => { const { isDesktop, isMobile } = useLayout(); const { @@ -132,7 +136,7 @@ export const Layout = ({ managerLayoutState, setManagerLayoutState, ...slots }: showPages, showPanel, isDragging, - } = useLayoutSyncingState({ managerLayoutState, setManagerLayoutState, isDesktop }); + } = useLayoutSyncingState({ managerLayoutState, setManagerLayoutState, isDesktop, hasTab }); return ( {showPages && {slots.slotPages}} @@ -172,7 +177,7 @@ export const Layout = ({ managerLayoutState, setManagerLayoutState, ...slots }: }; const LayoutContainer = styled.div( - ({ navSize, rightPanelWidth, bottomPanelHeight, viewMode, panelPosition }) => { + ({ navSize, rightPanelWidth, bottomPanelHeight, viewMode, panelPosition, showPanel }) => { return { width: '100%', height: ['100vh', '100dvh'], // This array is a special Emotion syntax to set a fallback if 100dvh is not supported @@ -186,7 +191,7 @@ const LayoutContainer = styled.div( gridTemplateColumns: `minmax(0, ${navSize}px) minmax(${MINIMUM_CONTENT_WIDTH_PX}px, 1fr) minmax(0, ${rightPanelWidth}px)`, gridTemplateRows: `1fr minmax(0, ${bottomPanelHeight}px)`, gridTemplateAreas: (() => { - if (viewMode === 'docs') { + if (viewMode === 'docs' || !showPanel) { // remove panel in docs viewMode return `"sidebar content content" "sidebar content content"`; diff --git a/code/ui/manager/src/components/preview/Preview.tsx b/code/ui/manager/src/components/preview/Preview.tsx index 365d85674c45..dfb5b2277747 100644 --- a/code/ui/manager/src/components/preview/Preview.tsx +++ b/code/ui/manager/src/components/preview/Preview.tsx @@ -3,24 +3,20 @@ import React, { Fragment, useMemo, useEffect, useRef, useState } from 'react'; import { Helmet } from 'react-helmet-async'; import { global } from '@storybook/global'; -import { type API, Consumer, type Combo, merge, addons, types } from '@storybook/manager-api'; -import type { Addon_BaseType } from '@storybook/types'; +import { Consumer, type Combo, merge, addons, types } from '@storybook/manager-api'; +import type { Addon_BaseType, Addon_WrapperType } from '@storybook/types'; import { PREVIEW_BUILDER_PROGRESS, SET_CURRENT_STORY } from '@storybook/core-events'; import { Loader } from '@storybook/components'; -import { Location, Route } from '@storybook/router'; import * as S from './utils/components'; import { ZoomProvider, ZoomConsumer } from './tools/zoom'; -import { defaultWrappers, ApplyWrappers } from './Wrappers'; +import { ApplyWrappers } from './Wrappers'; import { ToolbarComp } from './Toolbar'; import { FramesRenderer } from './FramesRenderer'; import type { PreviewProps } from './utils/types'; -const getWrappers = (getFn: API['getElements']) => Object.values(getFn(types.PREVIEW)); -const getTabs = (getFn: API['getElements']) => Object.values(getFn(types.TAB)); - const canvasMapper = ({ state, api }: Combo) => ({ storyId: state.storyId, refId: state.refId, @@ -31,10 +27,9 @@ const canvasMapper = ({ state, api }: Combo) => ({ entry: api.getData(state.storyId, state.refId), previewInitialized: state.previewInitialized, refs: state.refs, - active: !!(state.viewMode && state.viewMode.match(/^(story|docs)$/)), }); -const createCanvasTab = (): Addon_BaseType => ({ +export const createCanvasTab = (): Addon_BaseType => ({ id: 'canvas', type: types.TAB, title: 'Canvas', @@ -43,19 +38,6 @@ const createCanvasTab = (): Addon_BaseType => ({ render: () => null, }); -const useTabs = (getElements: API['getElements'], entry: PreviewProps['entry']) => { - const canvasTab = useMemo(() => createCanvasTab(), []); - const tabsFromConfig = getTabs(getElements); - - return useMemo(() => { - if (entry?.type === 'story' && entry.parameters) { - return filterTabs([canvasTab, ...tabsFromConfig], entry.parameters); - } - - return [canvasTab, ...tabsFromConfig]; - }, [entry, ...tabsFromConfig]); -}; - const Preview = React.memo(function Preview(props) { const { api, @@ -67,14 +49,17 @@ const Preview = React.memo(function Preview(props) { description, baseUrl, withLoader = true, + tools, + toolsExtra, + tabs, + wrappers, + tabId, } = props; - const { getElements } = api; - const tabs = useTabs(getElements, entry); + const tabContent = tabs.find((tab) => tab.id === tabId)?.render; const shouldScale = viewMode === 'story'; - const { showToolbar, showTabs = true } = options; - const visibleTabsInToolbar = showTabs ? tabs : []; + const { showToolbar } = options; const previousStoryId = useRef(storyId); @@ -109,34 +94,16 @@ const Preview = React.memo(function Preview(props) { - ({ - customQueryParams: api.getQueryParam('tab'), - })} - > - {({ customQueryParams: x }) => { - console.log(api.getQueryParam('tab')); - console.log(x); - const tabId = api.getQueryParam('tab'); - const tabContent = tabs.find((tab) => tab.id === tabId)?.render; - - console.log('LOG: tabbs', { tabContent, tabs, tabId }); - return ( - <> - - {tabContent && tabContent({ active: true })} - - ); - }} - + {tabContent && {tabContent({ active: true })}} + @@ -146,10 +113,13 @@ const Preview = React.memo(function Preview(props) { export { Preview }; -const Canvas: FC<{ withLoader: boolean; baseUrl: string; children?: never }> = ({ - baseUrl, - withLoader, -}) => { +const Canvas: FC<{ + withLoader: boolean; + baseUrl: string; + children?: never; + active: boolean; + wrappers: Addon_WrapperType[]; +}> = ({ baseUrl, withLoader, active, wrappers }) => { return ( {({ @@ -160,15 +130,9 @@ const Canvas: FC<{ withLoader: boolean; baseUrl: string; children?: never }> = ( refId, viewMode, queryParams, - getElements, previewInitialized, - active, }) => { const id = 'canvas'; - const wrappers = useMemo( - () => [...defaultWrappers, ...getWrappers(getElements)], - [getElements, ...defaultWrappers] - ); const [progress, setProgress] = useState(undefined); useEffect(() => { @@ -196,7 +160,7 @@ const Canvas: FC<{ withLoader: boolean; baseUrl: string; children?: never }> = ( {({ value: scale }) => { return ( <> - {withLoader && isLoading && ( + {active && withLoader && isLoading && ( @@ -233,7 +197,7 @@ const Canvas: FC<{ withLoader: boolean; baseUrl: string; children?: never }> = ( ); }; -function filterTabs(panels: Addon_BaseType[], parameters: Record) { +export function filterTabs(panels: Addon_BaseType[], parameters: Record) { const { previewTabs } = addons.getConfig(); const parametersTabs = parameters ? parameters.previewTabs : undefined; diff --git a/code/ui/manager/src/components/preview/Toolbar.tsx b/code/ui/manager/src/components/preview/Toolbar.tsx index 34e297b207c5..934087058525 100644 --- a/code/ui/manager/src/components/preview/Toolbar.tsx +++ b/code/ui/manager/src/components/preview/Toolbar.tsx @@ -122,76 +122,61 @@ export const defaultToolsExtra: Addon_BaseType[] = [ copyTool, ]; -const useTools = ( - getElements: API['getElements'], - tabs: Addon_BaseType[], - viewMode: PreviewProps['viewMode'], - entry: PreviewProps['entry'], - location: PreviewProps['location'], - path: PreviewProps['path'] -) => { - const toolsFromConfig = useMemo( - () => getTools(getElements), - [getElements, getTools(getElements).length] - ); - const toolsExtraFromConfig = useMemo(() => getToolsExtra(getElements), [getElements]); - - const tools = useMemo( - () => [...defaultTools, ...toolsFromConfig], - [defaultTools, toolsFromConfig] - ); - const toolsExtra = useMemo( - () => [...defaultToolsExtra, ...toolsExtraFromConfig], - [defaultToolsExtra, toolsExtraFromConfig] - ); - - return useMemo(() => { - return ['story', 'docs'].includes(entry?.type) - ? filterTools(tools, toolsExtra, tabs, { - viewMode, - entry, - location, - path, - }) - : { left: tools, right: toolsExtra }; - }, [viewMode, entry, location, path, tools, toolsExtra, tabs]); -}; - export interface ToolData { isShown: boolean; tabs: Addon_BaseType[]; + tools: Addon_BaseType[]; + tabId: string; + toolsExtra: Addon_BaseType[]; api: API; - entry: LeafEntry; } -export const ToolRes: FunctionComponent = React.memo( - function ToolRes({ api, entry, tabs, isShown, location, path, viewMode }) { - const { left, right } = useTools(api.getElements, tabs, viewMode, entry, location, path); - - return left || right ? ( - - - - - - - - - - - ) : null; - } -); - -export const ToolbarComp = React.memo(function ToolbarComp(props) { - return ( - - {({ location, path, viewMode }) => } - - ); +export const ToolbarComp = React.memo(function ToolbarComp({ + isShown, + tools, + toolsExtra, + tabs, + tabId, + api, +}) { + console.log({ tabs, tools, toolsExtra }); + return tabs || tools || toolsExtra ? ( + + + + {tabs.length > 1 ? ( + + + {tabs.map((tab, index) => { + return ( + { + api.applyQueryParams({ tab: tab.id === 'canvas' ? undefined : tab.id }); + }} + key={tab.id || `tab-${index}`} + > + {tab.title as any} + + ); + })} + + + + ) : null} + + + + + + + + ) : null; }); export const Tools = React.memo<{ list: Addon_BaseType[] }>(function Tools({ list }) { + console.log({ list }); return ( <> {list.filter(Boolean).map(({ render: Render, id, ...t }, index) => ( @@ -202,55 +187,36 @@ export const Tools = React.memo<{ list: Addon_BaseType[] }>(function Tools({ lis ); }); -function toolbarItemHasBeenExcluded(item: Partial, entry: LeafEntry) { - const parameters = entry.type === 'story' && entry.prepared ? entry.parameters : {}; +function toolbarItemHasBeenExcluded(item: Partial, entry: LeafEntry | undefined) { + const parameters = entry?.type === 'story' && entry?.prepared ? entry?.parameters : {}; const toolbarItemsFromStoryParameters = 'toolbar' in parameters ? parameters.toolbar : undefined; const { toolbar: toolbarItemsFromAddonsConfig } = addons.getConfig(); const toolbarItems = merge(toolbarItemsFromAddonsConfig, toolbarItemsFromStoryParameters); - return toolbarItems ? !!toolbarItems[item.id]?.hidden : false; + return toolbarItems ? !!toolbarItems[item?.id]?.hidden : false; } -export function filterTools( +export function filterToolsSide( tools: Addon_BaseType[], - toolsExtra: Addon_BaseType[], - tabs: Addon_BaseType[], - { - viewMode, - entry, - location, - path, - }: { - viewMode: State['viewMode']; - entry: PreviewProps['entry']; - location: State['location']; - path: State['path']; - } + entry: PreviewProps['entry'], + viewMode: State['viewMode'], + location: State['location'], + path: State['path'] ) { - const toolsLeft = [ - menuTool, - tabs.filter((p) => !p.hidden).length > 1 && createTabsTool(tabs), - ...tools, - ]; - const toolsRight = [...toolsExtra]; - const filter = (item: Partial) => item && (!item.match || item.match({ - storyId: entry.id, - refId: entry.refId, + storyId: entry?.id, + refId: entry?.refId, viewMode, location, path, })) && !toolbarItemHasBeenExcluded(item, entry); - const left = toolsLeft.filter(filter); - const right = toolsRight.filter(filter); - - return { left, right }; + return tools.filter(filter); } const Toolbar = styled.div<{ shown: boolean }>(({ theme, shown }) => ({ diff --git a/code/ui/manager/src/components/preview/Wrappers.tsx b/code/ui/manager/src/components/preview/Wrappers.tsx index 80640a9875fa..b5c1319c753b 100644 --- a/code/ui/manager/src/components/preview/Wrappers.tsx +++ b/code/ui/manager/src/components/preview/Wrappers.tsx @@ -29,7 +29,11 @@ export const defaultWrappers: Addon_WrapperType[] = [ id: 'iframe-wrapper', type: Addon_TypesEnum.PREVIEW, render: (p) => ( -