Skip to content

Commit

Permalink
feat(#50): ✨ Make measurment panel tabbable
Browse files Browse the repository at this point in the history
  • Loading branch information
mariewah committed Nov 4, 2025
1 parent 3a99955 commit 5e34abd
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 29 deletions.
75 changes: 48 additions & 27 deletions src/Accessibility/makeMenuTabbable.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export function makeMenuTabbable() {
makePanelsTabbable()
makeElevationControlTabbable()
makeAcceptedFilteringTabbable()
makeMeasurementsTabbable()
makeAppearancePanelTabbable()
makeToolsPanelTabbable()
}
Expand Down Expand Up @@ -134,15 +135,15 @@ function makeAcceptedFilteringTabbable() {
*/
function makeAppearancePanelTabbable() {
// Make EDL checkbox tabbable and keyboard clickable
const edlCheckbox = document.getElementById('chkEDLEnabled');
const edlCheckbox = document.getElementById('chkEDLEnabled')
if (edlCheckbox) {
edlCheckbox.tabIndex = 0
edlCheckbox.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
edlCheckbox.click();
e.preventDefault()
edlCheckbox.click()
}
});
})
}

// Make background buttons tabbable and keyboard clickable
Expand Down Expand Up @@ -174,27 +175,27 @@ function makeAppearancePanelTabbable() {
})

// Make box checkbox tabbable and keyboard clickable
const boxCheckbox = document.getElementById('show_bounding_box');
const boxCheckbox = document.getElementById('show_bounding_box')
if (boxCheckbox) {
boxCheckbox.tabIndex = 0
boxCheckbox.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
boxCheckbox.click();
e.preventDefault()
boxCheckbox.click()
}
});
})
}

// Make lock view checkbox tabbable and keyboard clickable
const lockViewCheckBox = document.getElementById('set_freeze');
const lockViewCheckBox = document.getElementById('set_freeze')
if (lockViewCheckBox) {
lockViewCheckBox.tabIndex = 0
lockViewCheckBox.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
lockViewCheckBox.click();
e.preventDefault()
lockViewCheckBox.click()
}
});
})
}
}

Expand All @@ -203,9 +204,7 @@ function makeAppearancePanelTabbable() {
*/
function makeToolsPanelTabbable() {
// Make clipping tools tabbable and keyboard clickable
const clippingTools = document.querySelectorAll(
'#clipping_tools img'
)
const clippingTools = document.querySelectorAll('#clipping_tools img')
clippingTools.forEach((img, index) => {
// Hide unsupported tool
if (index === 2) {
Expand All @@ -222,9 +221,7 @@ function makeToolsPanelTabbable() {
})

// Make clip task buttons tabbable and keyboard clickable
const clipTaskButtons = document.querySelectorAll(
'#cliptask_options label'
)
const clipTaskButtons = document.querySelectorAll('#cliptask_options label')
clipTaskButtons.forEach((label) => {
label.tabIndex = 0
label.addEventListener('keydown', (e) => {
Expand All @@ -250,13 +247,11 @@ function makeToolsPanelTabbable() {
})

// Hide camera projection options as they are not supported
const cameraProjection = document.getElementById('camera_projection_options');
const cameraProjection = document.getElementById('camera_projection_options')
if (cameraProjection) cameraProjection.hidden = true

// Make navigation tools tabbable and keyboard clickable
const navigationTools = document.querySelectorAll(
'#navigation img'
)
const navigationTools = document.querySelectorAll('#navigation img')
const renderArea = document.querySelector('#potree_render_area')
// Keep wrapper focusable as a fallback target (doesn't change tab order elsewhere)
if (renderArea && !renderArea.hasAttribute('tabindex')) {
Expand All @@ -275,15 +270,21 @@ function makeToolsPanelTabbable() {
const target = renderArea
if (pv) {
const src = (img.getAttribute && img.getAttribute('src')) || ''
const title = img.getAttribute && (img.getAttribute('title') || img.getAttribute('data-i18n') || '')
const title =
img.getAttribute &&
(img.getAttribute('title') || img.getAttribute('data-i18n') || '')
const key = (src + ' ' + title).toLowerCase()

if (key.includes('earth')) {
pv.setControls(pv.earthControls)
} else if (key.includes('heli') || key.includes('helicopter')) {
pv.setControls(pv.fpControls)
if (pv.fpControls) pv.fpControls.lockElevation = true
} else if (key.includes('fps') || key.includes('flight') || key.includes('flight_control')) {
} else if (
key.includes('fps') ||
key.includes('flight') ||
key.includes('flight_control')
) {
pv.setControls(pv.fpControls)
if (pv.fpControls) pv.fpControls.lockElevation = false
} else if (key.includes('orbit')) {
Expand All @@ -292,18 +293,38 @@ function makeToolsPanelTabbable() {

const dom = pv && pv.renderer && pv.renderer.domElement
if (dom) {
if (!dom.hasAttribute('tabindex')) dom.setAttribute('tabindex', '-1')
if (!dom.hasAttribute('tabindex'))
dom.setAttribute('tabindex', '-1')
dom.focus()
} else if (target) {
// conservative fallback
if (!target.hasAttribute('tabindex')) target.setAttribute('tabindex', '0')
if (!target.hasAttribute('tabindex'))
target.setAttribute('tabindex', '0')
target.focus()
}
} else if (target) {
if (!target.hasAttribute('tabindex')) target.setAttribute('tabindex', '0')
if (!target.hasAttribute('tabindex'))
target.setAttribute('tabindex', '0')
target.focus()
}
}
})
})
}

function makeMeasurementsTabbable() {
// Select every tool inside the measurement tools host
const tools = document.querySelectorAll(
'#measurement_tools_host .tool-with-label'
)
tools.forEach((tool) => {
tool.tabIndex = 0
tool.setAttribute('role', 'button')
tool.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
tool.click()
}
})
})
}
6 changes: 4 additions & 2 deletions src/potreeViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export async function createPotreeViewer(

viewer.loadGUI(() => {
viewer.setLanguage('en')
//remove the header with language information
$('#sidebar_header').remove()
$('#menu_filters').remove()
viewer.toggleSidebar()

Expand Down Expand Up @@ -127,11 +129,11 @@ export async function createPotreeViewer(
// Apply runtime overrides for the 2D Profile tool
init2DProfileOverride(viewer)

makeMenuTabbable()

initMeasurementsPanel(viewer)
initAnnotationsPanel(viewer)
initMiniMap(viewer)

makeMenuTabbable()
})

// Initialize camera position and target point (manually chosen)
Expand Down

0 comments on commit 5e34abd

Please sign in to comment.