Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/App/hooks/useLayoutMeasurements.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ const ATTRIBUTIONS_STACKED_CLASS = 'im-o-app__attributions--stacked'
const buttonHeight = (ref) => ref?.current?.offsetHeight ?? 0
const buttonWidth = (ref) => ref?.current?.offsetWidth ?? 0

// A top column whose children are all display:none (hiddenWhen buttons, or items hidden by a
// plugin's exclusive-control CSS) isn't :empty, so it keeps its trailing padding-bottom — which
// would push the side column below it down by a gap. Treat it as empty instead.
const topColHeight = (col) => {
const children = Array.from(col.children)
const isAllHidden = children.length > 0 && children.every(child => child.getClientRects().length === 0)
return isAllHidden ? 0 : col.offsetHeight
}

// Max of both sides, so centred content doesn't lean toward the emptier one.
const symmetricWidth = (left, right) => left || right ? Math.max(left, right) : 0

Expand Down Expand Up @@ -191,7 +200,7 @@ export function calculateLayout (layoutRefs, breakpoint) {
const { rise: attributionsLift } = applyAttributionsLayout({ appContainer, bottom, attributions, dividerGap, primaryGap })

// === Left container offsets ===
const leftOffsetTop = sideOffsetTop(topLeftCol.offsetHeight)
const leftOffsetTop = sideOffsetTop(topColHeight(topLeftCol))
const leftColumnHeight = bottom.offsetTop - leftOffsetTop - dividerGap
appContainer.style.setProperty('--left-offset-top', `${leftOffsetTop}px`)
appContainer.style.setProperty('--left-offset-bottom', `${main.offsetHeight - bottom.offsetTop + dividerGap}px`)
Expand All @@ -200,7 +209,7 @@ export function calculateLayout (layoutRefs, breakpoint) {
// === Right container offsets === (mirrors the left formula)
const bottomRightHeight = buttonHeight(bottomRightRef)
const bottomContainerPad = main.offsetHeight - bottom.offsetTop - bottom.offsetHeight
const rightOffsetTop = sideOffsetTop(topRightCol.offsetHeight)
const rightOffsetTop = sideOffsetTop(topColHeight(topRightCol))
const rightEffectiveBottom = bottom.offsetTop + bottom.offsetHeight - bottomRightHeight - attributionsLift
const rightColumnHeight = rightEffectiveBottom - rightOffsetTop - dividerGap
appContainer.style.setProperty('--right-offset-top', `${rightOffsetTop}px`)
Expand Down
16 changes: 16 additions & 0 deletions src/App/hooks/useLayoutMeasurements.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,22 @@ describe('useLayoutMeasurements', () => {
expect(layoutRefs.appContainerRef.current.style.setProperty).not.toHaveBeenCalled()
})

test('treats a top column whose children are all hidden as empty, ignoring its trailing padding', () => {
const { layoutRefs } = setup({ refs: { topRightCol: { offsetHeight: 10 }, top: { offsetTop: 15 } } })
// jsdom gives every element empty client rects, i.e. the same as display:none
appendChild(layoutRefs.topRightColRef.current)
renderHook(() => useLayoutMeasurements())
expect(layoutRefs.appContainerRef.current.style.setProperty).toHaveBeenCalledWith('--right-offset-top', '15px')
})

test('measures a top column normally when any child is rendered', () => {
const { layoutRefs } = setup({ refs: { topRightCol: { offsetHeight: 50 }, top: { offsetTop: 15 } } })
appendChild(layoutRefs.topRightColRef.current)
appendChild(layoutRefs.topRightColRef.current, { getClientRects: () => [{}] })
renderHook(() => useLayoutMeasurements())
expect(layoutRefs.appContainerRef.current.style.setProperty).toHaveBeenCalledWith('--right-offset-top', '65px')
})

test('calculates and sets all CSS custom properties', () => {
const { layoutRefs } = setup()
renderHook(() => useLayoutMeasurements())
Expand Down
17 changes: 11 additions & 6 deletions src/config/appConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ const keyboardBasePanelSlots = {
}

const buttonSlots = {
slot: 'top-right',
showLabel: false
}

const zoomButtonSlots = {
slot: 'right-top',
showLabel: false
}
Expand Down Expand Up @@ -81,9 +86,9 @@ export const defaultAppConfig = {
onClick: (_e, { mapProvider, appConfig }) => mapProvider.zoomIn(appConfig.zoomDelta),
excludeWhen: ({ appState, appConfig }) => !appConfig.enableZoomControls || appConfig.enableMapControls || appState.interfaceType === 'touch',
enableWhen: ({ mapState }) => !mapState.isAtMaxZoom,
mobile: buttonSlots,
tablet: buttonSlots,
desktop: buttonSlots
mobile: zoomButtonSlots,
tablet: zoomButtonSlots,
desktop: zoomButtonSlots
}, {
id: 'zoomOut',
group: { label: 'Zoom controls', slotOrder: 0 },
Expand All @@ -93,9 +98,9 @@ export const defaultAppConfig = {
onClick: (_e, { mapProvider, appConfig }) => mapProvider.zoomOut(appConfig.zoomDelta),
excludeWhen: ({ appState, appConfig }) => !appConfig.enableZoomControls || appConfig.enableMapControls || appState.interfaceType === 'touch',
enableWhen: ({ mapState }) => !mapState.isAtMinZoom,
mobile: buttonSlots,
tablet: buttonSlots,
desktop: buttonSlots
mobile: zoomButtonSlots,
tablet: zoomButtonSlots,
desktop: zoomButtonSlots
}, {
id: 'mapControls',
label: 'Map controls',
Expand Down
Loading