|
@@ -1,13 +1,10 @@
|
|
|
import { debounce } from 'lodash'
|
|
import { debounce } from 'lodash'
|
|
|
|
|
|
|
|
-export const positionItems = debounce(
|
|
|
|
|
- (
|
|
|
|
|
- element: HTMLDivElement,
|
|
|
|
|
- containerElement: HTMLDivElement,
|
|
|
|
|
- previousFocusedItemIndex: number
|
|
|
|
|
- ) => {
|
|
|
|
|
- const scrollRect = containerElement.getBoundingClientRect()
|
|
|
|
|
|
|
+const COLLAPSED_HEADER_HEIGHT = 75
|
|
|
|
|
+const OFFSET_FOR_ENTRIES_ABOVE = 70
|
|
|
|
|
|
|
|
|
|
+export const positionItems = debounce(
|
|
|
|
|
+ (element: HTMLDivElement, previousFocusedItemIndex: number) => {
|
|
|
const items = Array.from(
|
|
const items = Array.from(
|
|
|
element.querySelectorAll<HTMLDivElement>('.review-panel-entry')
|
|
element.querySelectorAll<HTMLDivElement>('.review-panel-entry')
|
|
|
)
|
|
)
|
|
@@ -21,19 +18,25 @@ export const positionItems = debounce(
|
|
|
let focusedItemIndex = items.findIndex(item =>
|
|
let focusedItemIndex = items.findIndex(item =>
|
|
|
item.classList.contains('review-panel-entry-focused')
|
|
item.classList.contains('review-panel-entry-focused')
|
|
|
)
|
|
)
|
|
|
|
|
+ if (focusedItemIndex === -1) {
|
|
|
|
|
+ // if entry was not focused manually
|
|
|
|
|
+ // check if there is an entry in selection and use that as the focused item
|
|
|
|
|
+ focusedItemIndex = items.findIndex(item =>
|
|
|
|
|
+ item.classList.contains('review-panel-entry-highlighted')
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
if (focusedItemIndex === -1) {
|
|
if (focusedItemIndex === -1) {
|
|
|
focusedItemIndex = previousFocusedItemIndex
|
|
focusedItemIndex = previousFocusedItemIndex
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // TODO: editorPadding?
|
|
|
|
|
- const topDiff = scrollRect.top - 80
|
|
|
|
|
-
|
|
|
|
|
const focusedItem = items[focusedItemIndex]
|
|
const focusedItem = items[focusedItemIndex]
|
|
|
if (!focusedItem) {
|
|
if (!focusedItem) {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
- const focusedItemTop = Number(focusedItem.dataset.top)
|
|
|
|
|
- focusedItem.style.top = `${focusedItemTop + topDiff}px`
|
|
|
|
|
|
|
+
|
|
|
|
|
+ const focusedItemTop = getTopPosition(focusedItem, focusedItemIndex === 0)
|
|
|
|
|
+
|
|
|
|
|
+ focusedItem.style.top = `${focusedItemTop}px`
|
|
|
focusedItem.style.visibility = 'visible'
|
|
focusedItem.style.visibility = 'visible'
|
|
|
const focusedItemRect = focusedItem.getBoundingClientRect()
|
|
const focusedItemRect = focusedItem.getBoundingClientRect()
|
|
|
|
|
|
|
@@ -42,12 +45,12 @@ export const positionItems = debounce(
|
|
|
for (let i = focusedItemIndex - 1; i >= 0; i--) {
|
|
for (let i = focusedItemIndex - 1; i >= 0; i--) {
|
|
|
const item = items[i]
|
|
const item = items[i]
|
|
|
const rect = item.getBoundingClientRect()
|
|
const rect = item.getBoundingClientRect()
|
|
|
- let top = Number(item.dataset.top)
|
|
|
|
|
|
|
+ let top = getTopPosition(item, i === 0)
|
|
|
const bottom = top + rect.height
|
|
const bottom = top + rect.height
|
|
|
if (bottom > topLimit) {
|
|
if (bottom > topLimit) {
|
|
|
top = topLimit - rect.height - 10
|
|
top = topLimit - rect.height - 10
|
|
|
}
|
|
}
|
|
|
- item.style.top = `${top + topDiff}px`
|
|
|
|
|
|
|
+ item.style.top = `${top}px`
|
|
|
item.style.visibility = 'visible'
|
|
item.style.visibility = 'visible'
|
|
|
topLimit = top
|
|
topLimit = top
|
|
|
}
|
|
}
|
|
@@ -57,11 +60,11 @@ export const positionItems = debounce(
|
|
|
for (let i = focusedItemIndex + 1; i < items.length; i++) {
|
|
for (let i = focusedItemIndex + 1; i < items.length; i++) {
|
|
|
const item = items[i]
|
|
const item = items[i]
|
|
|
const rect = item.getBoundingClientRect()
|
|
const rect = item.getBoundingClientRect()
|
|
|
- let top = Number(item.dataset.top)
|
|
|
|
|
|
|
+ let top = getTopPosition(item, false)
|
|
|
if (top < bottomLimit) {
|
|
if (top < bottomLimit) {
|
|
|
top = bottomLimit + 10
|
|
top = bottomLimit + 10
|
|
|
}
|
|
}
|
|
|
- item.style.top = `${top + topDiff}px`
|
|
|
|
|
|
|
+ item.style.top = `${top}px`
|
|
|
item.style.visibility = 'visible'
|
|
item.style.visibility = 'visible'
|
|
|
bottomLimit = top + rect.height
|
|
bottomLimit = top + rect.height
|
|
|
}
|
|
}
|
|
@@ -75,3 +78,8 @@ export const positionItems = debounce(
|
|
|
100,
|
|
100,
|
|
|
{ leading: false, trailing: true, maxWait: 1000 }
|
|
{ leading: false, trailing: true, maxWait: 1000 }
|
|
|
)
|
|
)
|
|
|
|
|
+
|
|
|
|
|
+function getTopPosition(item: HTMLDivElement, isFirstEntry: boolean) {
|
|
|
|
|
+ const offset = isFirstEntry ? 0 : OFFSET_FOR_ENTRIES_ABOVE
|
|
|
|
|
+ return Math.max(COLLAPSED_HEADER_HEIGHT + offset, Number(item.dataset.top))
|
|
|
|
|
+}
|