UNPKG

@discoveryjs/discovery

Version:

Frontend framework for rapid data (JSON) analysis, shareable serverless reports and dashboards

116 lines (107 loc) 4.34 kB
import { getBoundingRect, getOverflowParent } from '../../core/utils/layout.js'; let viewTreeScrollTopBeforeSelect = 0; const sidebarLeafBadges = [ { view: 'badge', when: 'view.data != parent.(view or viewRoot).data or "data" in view.config', data: { text: 'D' }, tooltip: 'text:"Data value was changed"' }, { view: 'badge', when: 'view.context != parent.(view or viewRoot).context', data: { text: 'C' }, tooltip: 'text:"Context value was changed"' } ]; function scrollIntoViewIfNeeded(element) { const viewportEl = getOverflowParent(element); const elementRect = getBoundingRect(element, viewportEl); const scrollMarginTop = 0; const scrollMarginLeft = 0; const { scrollTop, scrollLeft, clientWidth, clientHeight } = viewportEl; const viewportTop = scrollTop + scrollMarginTop; const viewportLeft = scrollLeft + scrollMarginLeft; const viewportRight = scrollLeft + clientWidth; const viewportBottom = scrollTop + clientHeight; const elementTop = scrollTop + elementRect.top; const elementLeft = scrollLeft + elementRect.left; const elementRight = elementLeft + elementRect.width; let scrollToTop = scrollTop; let scrollToLeft = scrollLeft; if (elementTop < viewportTop || elementTop > viewportBottom) { scrollToTop = elementTop - scrollMarginTop; } if (elementLeft < viewportLeft) { scrollToLeft = elementLeft - scrollMarginLeft; } else if (elementRight > viewportRight) { scrollToLeft = Math.max(elementLeft, scrollLeft - (elementRight - viewportRight)) - scrollMarginLeft; } viewportEl?.scrollTo(scrollToLeft, scrollToTop); } export function resetViewTreeScrollTopBeforeSelect() { viewTreeScrollTopBeforeSelect = 0; } export function viewTree(el, { selectTreeViewLeaf, detailsSidebarLeafExpanded }) { return { view: 'tree', when: '#.selectedView', data: '$[0]', className: 'sidebar', limitLines: false, itemConfig: { collapsible: '=not viewRoot', expanded: leaf => leaf.viewRoot || detailsSidebarLeafExpanded.has(leaf), onToggle: (state, _, leaf) => state ? detailsSidebarLeafExpanded.add(leaf) : detailsSidebarLeafExpanded.delete(leaf) }, item: { view: 'switch', content: [ { when: 'viewRoot', content: { view: 'block', className: 'view-root', content: 'text:viewRoot.name' } }, { when: '$ = #.selectedView', content: [ { view: 'block', className: [ data => data.view?.skipped ? 'skipped' : false, 'selected' ], content: 'text:view.config.view or "#root" | is string ?: "ƒn"', postRender(el_) { requestAnimationFrame(() => { el.querySelector('.sidebar').scrollTop = viewTreeScrollTopBeforeSelect; scrollIntoViewIfNeeded(el_); }); } }, ...sidebarLeafBadges ] }, { content: [ { view: 'link', className: data => data.view?.skipped ? 'skipped' : false, data: '{ text: view.config.view or "#root" | is string ?: "ƒn", href: false, view, self: $ }', onClick(_, data) { viewTreeScrollTopBeforeSelect = el.querySelector('.sidebar')?.scrollTop || 0; selectTreeViewLeaf(data.self); } }, ...sidebarLeafBadges ] } ] } }; }