Focused and selected states for ReviewPanelEntry (#21354)

GitOrigin-RevId: 41e5ed1110d71eae51cbbde1e874dda133d666c8
This commit is contained in:
Domagoj Kriskovic 2024-10-25 15:05:44 +02:00 committed by Copybot
parent db23262611
commit 29c5bc8206
4 changed files with 29 additions and 7 deletions

View file

@ -38,6 +38,7 @@ export const ReviewPanelEntry: FC<{
const state = useCodeMirrorStateContext()
const view = useCodeMirrorViewContext()
const { openDocId, getCurrentDocId } = useEditorManagerContext()
const [selected, setSelected] = useState(false)
const [focused, setFocused] = useState(false)
const { setReviewPanelOpen } = useLayoutContext()
@ -49,6 +50,8 @@ export const ReviewPanelEntry: FC<{
const focusHandler = useCallback(
event => {
setFocused(true)
if (
event.target instanceof HTMLButtonElement ||
event.target instanceof HTMLLinkElement ||
@ -59,7 +62,7 @@ export const ReviewPanelEntry: FC<{
return
}
setFocused(true)
setSelected(true)
if (!selectLineOnFocus) {
return
@ -97,7 +100,10 @@ export const ReviewPanelEntry: FC<{
<div
onMouseDown={openReviewPanel} // Using onMouseDown rather than onClick to guarantee that it fires before onFocus
onFocus={focusHandler}
onBlur={() => setFocused(false)}
onBlur={() => {
setSelected(false)
setFocused(false)
}}
onMouseEnter={() => {
if (hoverRanges) {
view.dispatch(highlightRanges(op))
@ -113,7 +119,15 @@ export const ReviewPanelEntry: FC<{
className={classNames(
'review-panel-entry',
{
// 'selected' is used to manually select an entry
// useful if the range is within range and you want to show the one outside the viewport
// it is not enough to just check isSelectionWithinOp for that
'review-panel-entry-selected': selected,
// 'focused' is set even when an entry was clicked but not selected (like clicking on a menu option)
// used to set z-index above other entries (since entries are not ordered the same way visually and in the DOM)
'review-panel-entry-focused': focused,
// 'highlighted' is set if the selection is within op but that doesn't necessarily mean it should be selected
// multiple entries can be highlighted at the same time
'review-panel-entry-highlighted': highlighted,
'review-panel-entry-disabled': disabled,
},

View file

@ -26,14 +26,14 @@ export const positionItems = debounce(
if (activeItemIndex === -1) {
// if there is no action available
// check if there is a focused entry
// check if there is manually selected entry
activeItemIndex = items.findIndex(item =>
item.classList.contains('review-panel-entry-focused')
item.classList.contains('review-panel-entry-selected')
)
}
if (activeItemIndex === -1) {
// if entry was not focused manually
// if entry was not selected manually
// check if there is an entry in selection and use that as the focused item
activeItemIndex = items.findIndex(item =>
item.classList.contains('review-panel-entry-highlighted')

View file

@ -51,7 +51,7 @@
gap: @spacing-04;
}
.review-panel-entry.review-panel-entry-focused,
.review-panel-entry.review-panel-entry-selected,
.review-panel-entry.review-panel-entry-highlighted {
margin-left: @spacing-01;
border: 1px solid @blue-50;
@ -61,6 +61,10 @@
0px 2px 4px rgba(30, 37, 48, 0.08);
}
.review-panel-entry.review-panel-entry-focused {
z-index: 2;
}
.review-panel-entry-header {
display: flex;
justify-content: space-between;

View file

@ -56,7 +56,7 @@
gap: var(--spacing-04);
}
.review-panel-entry.review-panel-entry-focused,
.review-panel-entry.review-panel-entry-selected,
.review-panel-entry.review-panel-entry-highlighted {
margin-left: var(--spacing-01);
border: 1px solid var(--border-active);
@ -64,6 +64,10 @@
@include shadow-md;
}
.review-panel-entry.review-panel-entry-focused {
z-index: 2;
}
.review-panel-entry-header {
display: flex;
justify-content: space-between;