forked from eclipse-cdt-cloud/vscode-peripheral-inspector
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Propagate value updates back to the data provider and tracker - Simplify column declaration and provide dedicated 'edit' property -- Always render the expander on the first column - Provide edit renderer for text value changes (more are part of eclipse-cdt-cloud#22) Refactor: - Convert some utility functions to React components - Convert thenable to promises Closes eclipse-cdt-cloud#16 Co-authored-by: Haydar Metin <[email protected]>
- Loading branch information
1 parent
05718b2
commit 53bb8fe
Showing
21 changed files
with
438 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2024 Arm Limited and others | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*********************************************************************/ | ||
|
||
import React from 'react'; | ||
|
||
|
||
export interface CodiconProps { | ||
icon: string; | ||
} | ||
|
||
export const Codicon: React.FC<CodiconProps> = ({ icon }) => { | ||
return <i className={`codicon codicon-${icon}`} style={{ marginRight: '0.5rem' }}></i>; | ||
|
||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2024 Arm Limited and others | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*********************************************************************/ | ||
|
||
import { classNames } from 'primereact/utils'; | ||
import React from 'react'; | ||
|
||
export interface ToggleItem { | ||
expanded?: boolean | undefined; | ||
leaf?: boolean | undefined; | ||
} | ||
|
||
export interface ExpandToggleProps { | ||
item: ToggleItem; | ||
depth?: number; | ||
} | ||
|
||
export const ExpandToggle: React.FC<ExpandToggleProps> = ({ item, depth = 0 }) => { | ||
return <div | ||
style={{ marginLeft: `${depth * 8}px` }} | ||
className={ | ||
classNames('tree-toggler-container', 'codicon', { | ||
'codicon-chevron-down': item.expanded, | ||
'codicon-chevron-right': !item.expanded && !item.leaf, | ||
})} />; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2024 Arm Limited and others | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*********************************************************************/ | ||
|
||
import React, { HTMLAttributes } from 'react'; | ||
import Markdown from 'react-markdown'; | ||
import remarkGfm from 'remark-gfm'; | ||
import { Tooltip, TooltipContent, TooltipTrigger } from '../../tooltip/tooltip'; | ||
import { AsTreeTableCellProps, AsTreeTableCell } from './TreeTableCell'; | ||
import { createHighlightedText } from './utils'; | ||
import { classNames } from 'primereact/utils'; | ||
|
||
export interface LabelProps extends AsTreeTableCellProps, HTMLAttributes<HTMLElement> { | ||
} | ||
|
||
const Label: React.FC<LabelProps> = React.forwardRef<HTMLDivElement, LabelProps>(({ row: _r, cell, expander: _e, ...props }, ref) => { | ||
const text = createHighlightedText(cell.value, cell.highlight); | ||
const label = <div {...props} ref={ref} className={classNames('tree-label', props.className)}> | ||
{text} | ||
</div>; | ||
|
||
if (cell.tooltip === undefined) { | ||
return label; | ||
} | ||
|
||
return <Tooltip> | ||
<TooltipTrigger>{label}</TooltipTrigger> | ||
<TooltipContent><Markdown className="markdown" remarkPlugins={[remarkGfm]}>{cell.tooltip}</Markdown></TooltipContent> | ||
</Tooltip>; | ||
}); | ||
|
||
export const LabelCell = AsTreeTableCell<LabelProps>(Label); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2024 Arm Limited and others | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*********************************************************************/ | ||
|
||
import './text-field-cell.css'; | ||
|
||
import { ReactWrapperProps } from '@microsoft/fast-react-wrapper'; | ||
import { TextField } from '@vscode/webview-ui-toolkit'; | ||
import { VSCodeTextField } from '@vscode/webview-ui-toolkit/react'; | ||
import React from 'react'; | ||
import { CDTTreeItem, CDTTreeTableColumn } from '../types'; | ||
import { AsEditable, EditableComponentProps, EditableComponentRef, AsTreeTableCell } from './TreeTableCell'; | ||
|
||
export type VSCodeTextFieldComponent = React.Component<ReactWrapperProps<TextField, { onChange: unknown; onInput: unknown; }>, unknown, unknown> & TextField; | ||
|
||
const KEY_CHANGE_VALUE = [ | ||
'Enter' | ||
]; | ||
|
||
const KEY_UNSELECT = [ | ||
'ArrowUp', | ||
'ArrowDown', | ||
'PageDown', | ||
'PageUp', | ||
'Escape' | ||
]; | ||
|
||
export interface TextFielCellProps extends EditableComponentProps { | ||
row: CDTTreeItem; | ||
cell: CDTTreeTableColumn; | ||
} | ||
|
||
const TextFieldComponent = React.forwardRef<EditableComponentRef, TextFielCellProps>(({ row, cell, ...props }, ref) => { | ||
const textFieldRef = React.useRef<VSCodeTextFieldComponent>(null); | ||
|
||
React.useImperativeHandle(ref, () => ({ | ||
focus: () => { | ||
textFieldRef.current?.control.select(); | ||
} | ||
})); | ||
|
||
const onKeyDown = (event: React.KeyboardEvent) => { | ||
event.stopPropagation(); | ||
|
||
if (KEY_CHANGE_VALUE.includes(event.key)) { | ||
const element = event.currentTarget as HTMLInputElement; | ||
props.onSubmitValue(element.value); | ||
} | ||
if (KEY_UNSELECT.includes(event.key)) { | ||
props.onCancelEdit(); | ||
} | ||
}; | ||
|
||
|
||
return <VSCodeTextField | ||
ref={textFieldRef} | ||
className='text-field-cell' | ||
id={`${row.id}-text-field`} | ||
initialValue={cell.value} | ||
value={cell.value} | ||
onKeyDown={event => onKeyDown(event)} | ||
onClick={event => event.stopPropagation()} | ||
onBlur={props.onCancelEdit} | ||
/>; | ||
}); | ||
|
||
export const TextFieldCell = AsEditable(AsTreeTableCell(TextFieldComponent)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2024 Arm Limited and others | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*********************************************************************/ | ||
|
||
import React, { ComponentType, HTMLAttributes } from 'react'; | ||
import { CDTTreeItem, CDTTreeTableColumn, CTDTreeMessengerType, CTDTreeWebviewContext } from '../types'; | ||
import { Codicon } from './Codicon'; | ||
import { ExpandToggle } from './Expander'; | ||
import { useCDTTreeContext } from '../tree-context'; | ||
import { LabelCell } from './LabelCell'; | ||
import { classNames } from 'primereact/utils'; | ||
|
||
export interface AsTreeTableCellProps { | ||
row: CDTTreeItem; | ||
cell: CDTTreeTableColumn; | ||
expander?: boolean; | ||
cellProps?: HTMLAttributes<HTMLElement>; | ||
} | ||
|
||
export const AsTreeTableCell = <P extends AsTreeTableCellProps>(Component: ComponentType<P>) => { | ||
const AsTreeTableCell = React.forwardRef<HTMLElement, P & AsTreeTableCellProps>((props, ref) => { | ||
const { cellProps, ...componentProps } = props; | ||
const { row, cell, expander } = componentProps; | ||
return ( | ||
<div {...cellProps} className={classNames('treetable-node', 'treetable-cell', cellProps?.className)} | ||
{...CTDTreeWebviewContext.create({ webviewSection: 'tree-item', cdtTreeItemId: row.id, cdtTreeItemPath: row.path, context: row.options?.contextValue })} | ||
> | ||
{expander && <ExpandToggle item={row} depth={row.path.length ?? 1} />} | ||
{cell.icon && <Codicon icon={cell.icon} />} | ||
<Component {...componentProps as P} ref={ref} /> | ||
</div> | ||
); | ||
}); | ||
return AsTreeTableCell; | ||
}; | ||
|
||
|
||
export interface AsEditableTreeTableCellProps extends AsTreeTableCellProps { | ||
field: string; | ||
} | ||
|
||
export interface EditableComponentRef { | ||
focus: () => void; | ||
} | ||
|
||
export interface EditableComponentProps { | ||
onCancelEdit: () => void; | ||
onSubmitValue: (value: string) => void; | ||
labelProps?: HTMLAttributes<HTMLElement>; | ||
} | ||
|
||
export const AsEditable = <P extends EditableComponentProps>(EditComponent: ComponentType<P>): React.FC<Omit<P, 'onSubmitValue' | 'onCancelEdit'> & AsEditableTreeTableCellProps> => { | ||
return (props) => { | ||
const [isEditMode, setEditMode] = React.useState(false); | ||
const editComponent = React.useRef<EditableComponentRef>(null); | ||
const treeContext = useCDTTreeContext(); | ||
const { labelProps, cell, row, expander, field } = props; | ||
|
||
React.useEffect(() => { | ||
if (isEditMode && editComponent.current) { | ||
editComponent.current.focus(); | ||
} | ||
}, [isEditMode]); | ||
|
||
const onStartEdit = (event: React.MouseEvent) => { | ||
setEditMode(true); | ||
event.stopPropagation(); | ||
}; | ||
|
||
const onCancelEdit = () => { | ||
setEditMode(false); | ||
}; | ||
|
||
const onSubmitValue = (value: string) => { | ||
treeContext.notify(CTDTreeMessengerType.changeValue, { | ||
field, | ||
item: row, | ||
value | ||
}); | ||
setEditMode(false); | ||
}; | ||
|
||
return isEditMode | ||
? <EditComponent | ||
{...(props as unknown as P)} | ||
ref={editComponent} | ||
onCancelEdit={onCancelEdit} | ||
onSubmitValue={onSubmitValue} | ||
/> | ||
: <LabelCell cellProps={{ className: 'editable' }} className='editable' cell={cell} row={row} expander={expander} {...labelProps} onDoubleClick={onStartEdit} onClick={() => { /* capture so no expansion */ }} />; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2024 Arm Limited and others | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*********************************************************************/ | ||
|
||
.text-field-cell { | ||
display: flex; | ||
align-items: center; | ||
background: var(--vscode-active-background); | ||
color: var(--vscode-foreground); | ||
border: var(--vscode-border); | ||
font-family: var(--vscode-editor-font-family); | ||
font-size: 13px; | ||
height: 22px; | ||
line-height: 22px; | ||
padding: 0; | ||
--input-height: 22px; | ||
} | ||
|
||
.p-treetable .p-treetable-tbody .treetable-cell.editable:hover .tree-label { | ||
text-decoration: underline dotted var(--vscode-foreground); | ||
text-underline-offset: 4px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -107,3 +107,7 @@ | |
overflow: hidden; | ||
align-items: center; | ||
} | ||
|
||
.tree-node :first-child { | ||
flex-grow: 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.