mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore: sources tab render polish (#32055)
This commit is contained in:
parent
69287f26bc
commit
80e014f4b6
@ -63,6 +63,6 @@ export const LogTab: React.FunctionComponent<{
|
|||||||
<span className='log-list-duration'>{entry.time}</span>
|
<span className='log-list-duration'>{entry.time}</span>
|
||||||
{entry.message}
|
{entry.message}
|
||||||
</div>}
|
</div>}
|
||||||
noHighlightOnHover={true}
|
notSelectable={true}
|
||||||
/>;
|
/>;
|
||||||
};
|
};
|
||||||
|
@ -29,3 +29,9 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.source-tab-file-name div {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
@ -95,6 +95,7 @@ export const SourceTab: React.FunctionComponent<{
|
|||||||
}, [onOpenExternally, location]);
|
}, [onOpenExternally, location]);
|
||||||
|
|
||||||
const showStackFrames = (stack?.length ?? 0) > 1;
|
const showStackFrames = (stack?.length ?? 0) > 1;
|
||||||
|
const shortFileName = getFileName(fileName);
|
||||||
|
|
||||||
return <SplitView
|
return <SplitView
|
||||||
sidebarSize={200}
|
sidebarSize={200}
|
||||||
@ -102,8 +103,10 @@ export const SourceTab: React.FunctionComponent<{
|
|||||||
sidebarHidden={!showStackFrames}
|
sidebarHidden={!showStackFrames}
|
||||||
main={<div className='vbox' data-testid='source-code'>
|
main={<div className='vbox' data-testid='source-code'>
|
||||||
{ fileName && <Toolbar>
|
{ fileName && <Toolbar>
|
||||||
<span className='source-tab-file-name'>{fileName}</span>
|
<div className='source-tab-file-name' title={fileName}>
|
||||||
<CopyToClipboard description='Copy filename' value={getFileName(fileName)}/>
|
<div>{shortFileName}</div>
|
||||||
|
</div>
|
||||||
|
<CopyToClipboard description='Copy filename' value={shortFileName}/>
|
||||||
{location && <ToolbarButton icon='link-external' title='Open in VS Code' onClick={openExternally}></ToolbarButton>}
|
{location && <ToolbarButton icon='link-external' title='Open in VS Code' onClick={openExternally}></ToolbarButton>}
|
||||||
</Toolbar> }
|
</Toolbar> }
|
||||||
<CodeMirrorWrapper text={source.content || ''} language='javascript' highlight={highlight} revealLine={targetLine} readOnly={true} lineNumbers={true} />
|
<CodeMirrorWrapper text={source.content || ''} language='javascript' highlight={highlight} revealLine={targetLine} readOnly={true} lineNumbers={true} />
|
||||||
|
@ -121,7 +121,7 @@ export function GridView<T>(model: GridViewProps<T>) {
|
|||||||
onIconClicked={model.onIconClicked}
|
onIconClicked={model.onIconClicked}
|
||||||
noItemsMessage={model.noItemsMessage}
|
noItemsMessage={model.noItemsMessage}
|
||||||
dataTestId={model.dataTestId}
|
dataTestId={model.dataTestId}
|
||||||
noHighlightOnHover={model.noHighlightOnHover}
|
notSelectable={model.notSelectable}
|
||||||
></ListView>
|
></ListView>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
|
@ -34,6 +34,10 @@
|
|||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-view-content.not-selectable > .list-view-entry {
|
||||||
|
cursor: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
.list-view-entry.highlighted:not(.selected) {
|
.list-view-entry.highlighted:not(.selected) {
|
||||||
background-color: var(--vscode-list-inactiveSelectionBackground) !important;
|
background-color: var(--vscode-list-inactiveSelectionBackground) !important;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import './listView.css';
|
import './listView.css';
|
||||||
|
import { clsx } from '@web/uiUtils';
|
||||||
|
|
||||||
export type ListViewProps<T> = {
|
export type ListViewProps<T> = {
|
||||||
name: string,
|
name: string,
|
||||||
@ -36,7 +37,7 @@ export type ListViewProps<T> = {
|
|||||||
onIconClicked?: (item: T, index: number) => void,
|
onIconClicked?: (item: T, index: number) => void,
|
||||||
noItemsMessage?: string,
|
noItemsMessage?: string,
|
||||||
dataTestId?: string,
|
dataTestId?: string,
|
||||||
noHighlightOnHover?: boolean,
|
notSelectable?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
const scrollPositions = new Map<string, number>();
|
const scrollPositions = new Map<string, number>();
|
||||||
@ -60,7 +61,7 @@ export function ListView<T>({
|
|||||||
onIconClicked,
|
onIconClicked,
|
||||||
noItemsMessage,
|
noItemsMessage,
|
||||||
dataTestId,
|
dataTestId,
|
||||||
noHighlightOnHover,
|
notSelectable,
|
||||||
}: ListViewProps<T>) {
|
}: ListViewProps<T>) {
|
||||||
const itemListRef = React.useRef<HTMLDivElement>(null);
|
const itemListRef = React.useRef<HTMLDivElement>(null);
|
||||||
const [highlightedItem, setHighlightedItem] = React.useState<any>();
|
const [highlightedItem, setHighlightedItem] = React.useState<any>();
|
||||||
@ -85,9 +86,9 @@ export function ListView<T>({
|
|||||||
itemListRef.current.scrollTop = scrollPositions.get(name) || 0;
|
itemListRef.current.scrollTop = scrollPositions.get(name) || 0;
|
||||||
}, [name]);
|
}, [name]);
|
||||||
|
|
||||||
return <div className={`list-view vbox ` + name + '-list-view' } role={items.length > 0 ? 'list' : undefined} data-testid={dataTestId || (name + '-list')}>
|
return <div className={clsx(`list-view vbox`, name + '-list-view')} role={items.length > 0 ? 'list' : undefined} data-testid={dataTestId || (name + '-list')}>
|
||||||
<div
|
<div
|
||||||
className='list-view-content'
|
className={clsx('list-view-content', notSelectable && 'not-selectable')}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onKeyDown={event => {
|
onKeyDown={event => {
|
||||||
if (selectedItem && event.key === 'Enter') {
|
if (selectedItem && event.key === 'Enter') {
|
||||||
@ -134,18 +135,19 @@ export function ListView<T>({
|
|||||||
>
|
>
|
||||||
{noItemsMessage && items.length === 0 && <div className='list-view-empty'>{noItemsMessage}</div>}
|
{noItemsMessage && items.length === 0 && <div className='list-view-empty'>{noItemsMessage}</div>}
|
||||||
{items.map((item, index) => {
|
{items.map((item, index) => {
|
||||||
const selectedSuffix = selectedItem === item ? ' selected' : '';
|
|
||||||
const highlightedSuffix = !noHighlightOnHover && highlightedItem === item ? ' highlighted' : '';
|
|
||||||
const errorSuffix = isError?.(item, index) ? ' error' : '';
|
|
||||||
const warningSuffix = isWarning?.(item, index) ? ' warning' : '';
|
|
||||||
const infoSuffix = isInfo?.(item, index) ? ' info' : '';
|
|
||||||
const indentation = indent?.(item, index) || 0;
|
const indentation = indent?.(item, index) || 0;
|
||||||
const rendered = render(item, index);
|
const rendered = render(item, index);
|
||||||
return <div
|
return <div
|
||||||
key={id?.(item, index) || index}
|
key={id?.(item, index) || index}
|
||||||
onDoubleClick={() => onAccepted?.(item, index)}
|
onDoubleClick={() => onAccepted?.(item, index)}
|
||||||
role='listitem'
|
role='listitem'
|
||||||
className={'list-view-entry' + selectedSuffix + highlightedSuffix + errorSuffix + warningSuffix + infoSuffix}
|
className={clsx(
|
||||||
|
'list-view-entry',
|
||||||
|
selectedItem === item && 'selected',
|
||||||
|
!notSelectable && highlightedItem === item && 'highlighted',
|
||||||
|
isError?.(item, index) && 'error',
|
||||||
|
isWarning?.(item, index) && 'warning',
|
||||||
|
isInfo?.(item, index) && 'info')}
|
||||||
onClick={() => onSelected?.(item, index)}
|
onClick={() => onSelected?.(item, index)}
|
||||||
onMouseEnter={() => setHighlightedItem(item)}
|
onMouseEnter={() => setHighlightedItem(item)}
|
||||||
onMouseLeave={() => setHighlightedItem(undefined)}
|
onMouseLeave={() => setHighlightedItem(undefined)}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user