Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455import type { EditorView, Rect } from '@codemirror/view'
const BOTTOM_CHROME_BREATHING_ROOM_PX = 16const BOTTOM_CHROME_SELECTORS = ['.formatting-toolbar']
type RectLike = Pick<Rect, 'left' | 'right' | 'top' | 'bottom'>
function horizontallyOverlaps(a: RectLike, b: RectLike): boolean { return a.left < b.right && b.left < a.right}
function verticallyOverlaps(a: RectLike, b: RectLike): boolean { return a.top < b.bottom && b.top < a.bottom}
export function computeBottomChromeScrollMarginFromRects( scrollerRect: RectLike, chromeRects: RectLike[], breathingRoomPx = BOTTOM_CHROME_BREATHING_ROOM_PX,): number { const overlappingTops = chromeRects .filter((rect) => horizontallyOverlaps(scrollerRect, rect) && verticallyOverlaps(scrollerRect, rect)) .map((rect) => rect.top)
if (overlappingTops.length === 0) return 0 return Math.ceil(scrollerRect.bottom - Math.min(...overlappingTops) + breathingRoomPx)}
function visibleElementRect(el: Element): DOMRect | null { const style = getComputedStyle(el) if (style.display === 'none' || style.visibility === 'hidden') return null
const rect = el.getBoundingClientRect() if (rect.width <= 0 || rect.height <= 0) return null return rect}
export function computeBottomChromeScrollMargin(view: EditorView, root: ParentNode = document): Partial<Rect> | null { const scrollerDomRect = view.scrollDOM.getBoundingClientRect() const viewport = window.visualViewport const visibleBottom = viewport ? viewport.offsetTop + viewport.height : window.innerHeight const scrollerRect = { left: scrollerDomRect.left, right: scrollerDomRect.right, top: scrollerDomRect.top, bottom: Math.min(scrollerDomRect.bottom, visibleBottom), } const chromeRects = BOTTOM_CHROME_SELECTORS.flatMap((selector) => Array.from(root.querySelectorAll(selector), visibleElementRect).filter((rect): rect is DOMRect => rect !== null) )
const bottom = computeBottomChromeScrollMarginFromRects(scrollerRect, chromeRects) return bottom > 0 ? { bottom } : null}