Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit c5ca8d6

Browse files
web: move panel components into blob page (#49190)
Based on the @philipp-spiess [work](https://github.com/sourcegraph/sourcegraph/pull/47904) with fixes related to CSS regressions. I created a separate branch to preserve commit history from the original PR with visual regressions and avoid resolving merge conflicts.
1 parent 0cb2ff8 commit c5ca8d6

File tree

9 files changed

+60
-98
lines changed

9 files changed

+60
-98
lines changed

client/web/src/LegacyLayout.tsx

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ import { FC, Suspense, useCallback, useLayoutEffect, useState } from 'react'
33
import classNames from 'classnames'
44
import { matchPath, useLocation, Route, Routes, Navigate } from 'react-router-dom'
55

6-
import { TabbedPanelContent } from '@sourcegraph/branded/src/components/panel/TabbedPanelContent'
76
import { useKeyboardShortcut } from '@sourcegraph/shared/src/keyboardShortcuts/useKeyboardShortcut'
87
import { Shortcut } from '@sourcegraph/shared/src/react-shortcuts'
98
import { useExperimentalFeatures } from '@sourcegraph/shared/src/settings/settings'
109
import { useTheme, Theme } from '@sourcegraph/shared/src/theme'
1110
import { lazyComponent } from '@sourcegraph/shared/src/util/lazyComponent'
12-
import { parseQueryAndHash } from '@sourcegraph/shared/src/util/url'
13-
import { FeedbackPrompt, LoadingSpinner, Panel, useLocalStorage } from '@sourcegraph/wildcard'
11+
import { FeedbackPrompt, LoadingSpinner, useLocalStorage } from '@sourcegraph/wildcard'
1412

1513
import { communitySearchContextsRoutes } from './communitySearchContexts/routes'
1614
import { AppRouterContainer } from './components/AppRouterContainer'
@@ -30,7 +28,6 @@ import { EnterprisePageRoutes, PageRoutes } from './routes.constants'
3028
import { parseSearchURLQuery } from './search'
3129
import { NotepadContainer } from './search/Notepad'
3230
import { SearchQueryStateObserver } from './SearchQueryStateObserver'
33-
import { parseBrowserRepoURL } from './util/url'
3431

3532
import styles from './storm/pages/LayoutPage/LayoutPage.module.scss'
3633

@@ -224,23 +221,16 @@ export const LegacyLayout: FC<LegacyLayoutProps> = props => {
224221
))}
225222
</Routes>
226223
</AppRouterContainer>
224+
{/**
225+
* The portal root is inside the suspense boundary so that it is hidden
226+
* when we navigate to the lazily loaded routes or other actions which trigger
227+
* the Suspense boundary to show the fallback UI. Existing children are not unmounted
228+
* until the promise is resolved.
229+
*
230+
* See: https://github.com/facebook/react/pull/15861
231+
*/}
232+
<div id="references-panel-react-portal" />
227233
</Suspense>
228-
{parseQueryAndHash(location.search, location.hash).viewState && location.pathname !== PageRoutes.SignIn && (
229-
<Panel
230-
className={styles.panel}
231-
position="bottom"
232-
defaultSize={350}
233-
storageKey="panel-size"
234-
ariaLabel="References panel"
235-
id="references-panel"
236-
>
237-
<TabbedPanelContent
238-
{...props}
239-
repoName={`git://${parseBrowserRepoURL(location.pathname).repoName}`}
240-
fetchHighlightedFileLineRanges={props.fetchHighlightedFileLineRanges}
241-
/>
242-
</Panel>
243-
)}
244234
<GlobalContributions
245235
key={3}
246236
extensionsController={props.extensionsController}

client/web/src/enterprise/batches/BatchChangeTabs.module.scss

Lines changed: 0 additions & 27 deletions
This file was deleted.

client/web/src/enterprise/batches/BatchChangeTabs.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ import React from 'react'
22

33
import { TabList, TabListProps, Tabs, TabsProps } from '@sourcegraph/wildcard'
44

5-
import styles from './BatchChangeTabs.module.scss'
6-
75
/** sourcegraph/wildcard `Tabs` with styling applied to prevent CLS on hovering the tabs. */
86
export const BatchChangeTabs: React.FunctionComponent<TabsProps> = props => (
9-
<Tabs className={styles.batchChangeTabs} lazy={true} {...props} />
7+
<Tabs size="medium" lazy={true} {...props} />
108
)
119

1210
/** sourcegraph/wildcard `TabsList` with BC visual styling applied. */

client/web/src/enterprise/batches/batch-spec/execute/workspaces/WorkspaceDetails.module.scss

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -108,28 +108,3 @@
108108
.step-output-container {
109109
background-color: var(--gray-10);
110110
}
111-
112-
.step-tabs {
113-
[data-reach-tab],
114-
[data-reach-tab]:hover,
115-
[data-reach-tab][data-selected] {
116-
:global(.text-content) {
117-
display: inline-flex;
118-
align-items: center;
119-
flex-direction: column;
120-
justify-content: center;
121-
122-
// ::after used here for avoids the CLS when the font-weight change (see: https://css-tricks.com/bold-on-hover-without-the-layout-shift/)
123-
&::after {
124-
content: attr(data-tab-content);
125-
height: 0;
126-
text-transform: capitalize;
127-
visibility: hidden; // a11y: avoid detection for voice over
128-
overflow: hidden;
129-
user-select: none;
130-
pointer-events: none;
131-
font-weight: 700;
132-
}
133-
}
134-
}
135-
}

client/web/src/enterprise/batches/batch-spec/execute/workspaces/WorkspaceDetails.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,8 +600,7 @@ const WorkspaceStep: React.FunctionComponent<React.PropsWithChildren<WorkspaceSt
600600
<CardBody>
601601
{!step.skipped && (
602602
<Tabs
603-
className={styles.stepTabs}
604-
size="small"
603+
size="medium"
605604
behavior="forceRender"
606605
onChange={index =>
607606
eventLogger.log(`batch_change_execution:workspace_tab_${tabsNames[index]}:clicked`)

client/web/src/repo/blob/BlobPage.module.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,14 @@
2424
box-shadow: var(--focus-box-shadow);
2525
}
2626
}
27+
28+
.panel {
29+
isolation: isolate;
30+
min-height: 6rem;
31+
max-height: calc(100% - 3rem);
32+
width: 100%;
33+
display: flex;
34+
flex-direction: column;
35+
background-color: var(--color-bg-1);
36+
bottom: 0;
37+
}

client/web/src/repo/blob/BlobPage.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import classNames from 'classnames'
44
import AlertCircleIcon from 'mdi-react/AlertCircleIcon'
55
import FileAlertIcon from 'mdi-react/FileAlertIcon'
66
import MapSearchIcon from 'mdi-react/MapSearchIcon'
7+
import { createPortal } from 'react-dom'
78
import { Navigate, useLocation, useNavigate } from 'react-router-dom'
89
import { Observable } from 'rxjs'
910
import { catchError, map, mapTo, startWith, switchMap } from 'rxjs/operators'
1011
import { Optional } from 'utility-types'
1112

1213
import { StreamingSearchResultsListProps } from '@sourcegraph/branded'
14+
import { TabbedPanelContent } from '@sourcegraph/branded/src/components/panel/TabbedPanelContent'
1315
import { asError, ErrorLike, isErrorLike } from '@sourcegraph/common'
1416
import {
1517
createActiveSpan,
@@ -33,6 +35,7 @@ import {
3335
ErrorMessage,
3436
Icon,
3537
LoadingSpinner,
38+
Panel,
3639
Text,
3740
useEventObservable,
3841
useObservable,
@@ -53,7 +56,7 @@ import { OwnConfigProps } from '../../own/OwnConfigProps'
5356
import { SearchStreamingProps } from '../../search'
5457
import { useNotepad } from '../../stores'
5558
import { basename } from '../../util/path'
56-
import { toTreeURL } from '../../util/url'
59+
import { parseBrowserRepoURL, toTreeURL } from '../../util/url'
5760
import { serviceKindDisplayNameAndIcon } from '../actions/GoToCodeHostAction'
5861
import { ToggleBlameAction } from '../actions/ToggleBlameAction'
5962
import { useBlameHunks } from '../blame/useBlameHunks'
@@ -579,6 +582,24 @@ export const BlobPage: React.FunctionComponent<BlobPageProps> = ({ className, ..
579582
/>
580583
</TraceSpanProvider>
581584
)}
585+
{parseQueryAndHash(location.search, location.hash).viewState &&
586+
createPortal(
587+
<Panel
588+
className={styles.panel}
589+
position="bottom"
590+
defaultSize={350}
591+
storageKey="panel-size"
592+
ariaLabel="References panel"
593+
id="references-panel"
594+
>
595+
<TabbedPanelContent
596+
{...props}
597+
repoName={`git://${parseBrowserRepoURL(location.pathname).repoName}`}
598+
fetchHighlightedFileLineRanges={props.fetchHighlightedFileLineRanges}
599+
/>
600+
</Panel>,
601+
document.querySelector('#references-panel-react-portal')!
602+
)}
582603
</div>
583604
)
584605
}

client/web/src/storm/pages/LayoutPage/LayoutPage.module.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@
2020
flex-direction: column;
2121
background-color: var(--color-bg-1);
2222
}
23+
24+
:global(#references-panel-react-portal) {
25+
display: contents;
26+
}

client/web/src/storm/pages/LayoutPage/LayoutPage.tsx

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ import React, { Suspense, useCallback, useLayoutEffect, useState } from 'react'
33
import classNames from 'classnames'
44
import { Outlet, useLocation, Navigate, useMatches, useMatch } from 'react-router-dom'
55

6-
import { TabbedPanelContent } from '@sourcegraph/branded/src/components/panel/TabbedPanelContent'
76
import { useKeyboardShortcut } from '@sourcegraph/shared/src/keyboardShortcuts/useKeyboardShortcut'
87
import { Shortcut } from '@sourcegraph/shared/src/react-shortcuts'
98
import { useExperimentalFeatures } from '@sourcegraph/shared/src/settings/settings'
109
import { useTheme, Theme } from '@sourcegraph/shared/src/theme'
1110
import { lazyComponent } from '@sourcegraph/shared/src/util/lazyComponent'
12-
import { parseQueryAndHash } from '@sourcegraph/shared/src/util/url'
13-
import { FeedbackPrompt, LoadingSpinner, Panel, useLocalStorage } from '@sourcegraph/wildcard'
11+
import { FeedbackPrompt, LoadingSpinner, useLocalStorage } from '@sourcegraph/wildcard'
1412

1513
import { communitySearchContextsRoutes } from '../../../communitySearchContexts/routes'
1614
import { AppRouterContainer } from '../../../components/AppRouterContainer'
@@ -29,7 +27,6 @@ import { EnterprisePageRoutes, PageRoutes } from '../../../routes.constants'
2927
import { parseSearchURLQuery } from '../../../search'
3028
import { NotepadContainer } from '../../../search/Notepad'
3129
import { SearchQueryStateObserver } from '../../../SearchQueryStateObserver'
32-
import { parseBrowserRepoURL } from '../../../util/url'
3330

3431
import styles from './LayoutPage.module.scss'
3532

@@ -222,24 +219,18 @@ export const Layout: React.FC<LegacyLayoutProps> = props => {
222219
<AppRouterContainer>
223220
<Outlet />
224221
</AppRouterContainer>
222+
223+
{/**
224+
* The portal root is inside the suspense boundary so that it is hidden
225+
* when we navigate to the lazily loaded routes or other actions which trigger
226+
* the Suspense boundary to show the fallback UI. Existing children are not unmounted
227+
* until the promise is resolved.
228+
*
229+
* See: https://github.com/facebook/react/pull/15861
230+
*/}
231+
<div id="references-panel-react-portal" />
225232
</Suspense>
226233
</ErrorBoundary>
227-
{parseQueryAndHash(location.search, location.hash).viewState && location.pathname !== PageRoutes.SignIn && (
228-
<Panel
229-
className={styles.panel}
230-
position="bottom"
231-
defaultSize={350}
232-
storageKey="panel-size"
233-
ariaLabel="References panel"
234-
id="references-panel"
235-
>
236-
<TabbedPanelContent
237-
{...props}
238-
repoName={`git://${parseBrowserRepoURL(location.pathname).repoName}`}
239-
fetchHighlightedFileLineRanges={props.fetchHighlightedFileLineRanges}
240-
/>
241-
</Panel>
242-
)}
243234
{(isSearchNotebookListPage || (isSearchRelatedPage && !isSearchHomepage)) && (
244235
<NotepadContainer userId={props.authenticatedUser?.id} />
245236
)}

0 commit comments

Comments
 (0)