mirror of
https://github.com/enso-org/enso.git
synced 2024-11-27 06:32:30 +03:00
Fix table viz context menu (#9820)
Fixes #9700 [Screencast from 2024-04-30 15-09-17.webm](https://github.com/enso-org/enso/assets/3919101/a11ae875-7e2f-4c84-8d91-33aa1ca8bdbd) # Important Notes During implementation, I discovered a bug that the context menu wasn't hidden by click at background (or node) - all because of preventDefault, as it turned out.
This commit is contained in:
parent
07b720a90a
commit
0186ed1961
@ -104,9 +104,9 @@ const nodeShortType = computed(() =>
|
||||
@pointerup.stop
|
||||
@click.stop
|
||||
>
|
||||
<div class="resizer-right" v-on="resizeRight.stop.events"></div>
|
||||
<div class="resizer-bottom" v-on="resizeBottom.stop.events"></div>
|
||||
<div class="resizer-bottom-right" v-on="resizeBottomRight.stop.events"></div>
|
||||
<div class="resizer-right" v-on="resizeRight.events"></div>
|
||||
<div class="resizer-bottom" v-on="resizeBottom.events"></div>
|
||||
<div class="resizer-bottom-right" v-on="resizeBottomRight.events"></div>
|
||||
<SmallPlusButton
|
||||
v-if="config.isCircularMenuVisible"
|
||||
class="below-viz"
|
||||
|
@ -117,6 +117,7 @@ const agGridOptions: Ref<GridOptions & Required<Pick<GridOptions, 'defaultColDef
|
||||
onColumnResized: lockColumnSize,
|
||||
suppressFieldDotNotation: true,
|
||||
enableRangeSelection: true,
|
||||
popupParent: document.body,
|
||||
})
|
||||
|
||||
const isRowCountSelectorVisible = computed(() => rowCount.value >= 1000)
|
||||
@ -410,6 +411,7 @@ onMounted(() => {
|
||||
origValidateLicense.call(this)
|
||||
}
|
||||
}
|
||||
// TODO: consider using Vue component instead: https://ag-grid.com/vue-data-grid/getting-started/
|
||||
new Grid(tableNode.value!, agGridOptions.value)
|
||||
updateColumnWidths()
|
||||
})
|
||||
|
@ -4,7 +4,7 @@ import { assert } from '@/util/assert'
|
||||
import { Rect } from '@/util/data/rect'
|
||||
import { Vec2 } from '@/util/data/vec2'
|
||||
import { isPointer, pointerButtonToEventInfo, type BindingInfo } from '@/util/shortcuts'
|
||||
import { expect, test, vi } from 'vitest'
|
||||
import { beforeAll, expect, test, vi } from 'vitest'
|
||||
import { proxyRefs, ref, type Ref } from 'vue'
|
||||
|
||||
function selectionWithMockData(sceneMousePos?: Ref<Vec2>) {
|
||||
@ -104,7 +104,7 @@ test.each`
|
||||
dragCase(new Vec2(area.right, area.top), new Vec2(area.left, area.bottom))
|
||||
})
|
||||
|
||||
// There is no PointerEvent class in jsdom (yet).
|
||||
// See https://github.com/thymikee/jest-preset-angular/issues/245#issuecomment-576296325
|
||||
class MockPointerEvent extends MouseEvent {
|
||||
readonly pointerId: number
|
||||
constructor(type: string, options: MouseEventInit & { currentTarget?: Element | undefined }) {
|
||||
@ -116,6 +116,10 @@ class MockPointerEvent extends MouseEvent {
|
||||
}
|
||||
}
|
||||
|
||||
beforeAll(() => {
|
||||
;(window as any).PointerEvent = MockPointerEvent
|
||||
})
|
||||
|
||||
function mockPointerEvent(type: string, pos: Vec2, binding: BindingInfo): PointerEvent {
|
||||
const modifiersSet = new Set(binding.modifiers)
|
||||
assert(isPointer(binding.key))
|
||||
|
@ -305,7 +305,7 @@ export function usePointer(
|
||||
|
||||
if (trackedElement != null && initialGrabPos != null && lastPos != null) {
|
||||
if (handler(computePosition(e, initialGrabPos, lastPos), e, 'stop') !== false) {
|
||||
e.preventDefault()
|
||||
e.stopImmediatePropagation()
|
||||
}
|
||||
|
||||
lastPos = null
|
||||
@ -317,7 +317,7 @@ export function usePointer(
|
||||
function doMove(e: PointerEvent) {
|
||||
if (trackedElement != null && initialGrabPos != null && lastPos != null) {
|
||||
if (handler(computePosition(e, initialGrabPos, lastPos), e, 'move') !== false) {
|
||||
e.preventDefault()
|
||||
e.stopImmediatePropagation()
|
||||
}
|
||||
lastPos = new Vec2(e.clientX, e.clientY)
|
||||
}
|
||||
@ -339,7 +339,7 @@ export function usePointer(
|
||||
initialGrabPos = new Vec2(e.clientX, e.clientY)
|
||||
lastPos = initialGrabPos
|
||||
if (handler(computePosition(e, initialGrabPos, lastPos), e, 'start') !== false) {
|
||||
e.preventDefault()
|
||||
e.stopImmediatePropagation()
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -362,24 +362,8 @@ export function usePointer(
|
||||
},
|
||||
}
|
||||
|
||||
const stopEvents = {
|
||||
pointerdown(e: PointerEvent) {
|
||||
e.stopImmediatePropagation()
|
||||
events.pointerdown(e)
|
||||
},
|
||||
pointerup(e: PointerEvent) {
|
||||
e.stopImmediatePropagation()
|
||||
events.pointerup(e)
|
||||
},
|
||||
pointermove(e: PointerEvent) {
|
||||
e.stopImmediatePropagation()
|
||||
events.pointermove(e)
|
||||
},
|
||||
}
|
||||
|
||||
return proxyRefs({
|
||||
events,
|
||||
stop: { events: stopEvents },
|
||||
dragging,
|
||||
})
|
||||
}
|
||||
|
@ -3,7 +3,13 @@ import {
|
||||
defineKeybinds,
|
||||
normalizedKeyboardSegmentLookup,
|
||||
} from '@/util/shortcuts'
|
||||
import { expect, test, vi, type MockInstance } from 'vitest'
|
||||
import { beforeAll, expect, test, vi, type MockInstance } from 'vitest'
|
||||
|
||||
// See https://github.com/thymikee/jest-preset-angular/issues/245#issuecomment-576296325
|
||||
class MockPointerEvent extends MouseEvent {}
|
||||
beforeAll(() => {
|
||||
;(window as any).PointerEvent = MockPointerEvent
|
||||
})
|
||||
|
||||
test.each([
|
||||
{ keybind: 'A', expected: { modifiers: [], key: 'A' } },
|
||||
|
@ -415,7 +415,10 @@ export function defineKeybinds<
|
||||
}
|
||||
if (handled && stopAndPrevent) {
|
||||
event.stopImmediatePropagation()
|
||||
event.preventDefault()
|
||||
// We don't prevent default on PointerEvents, because it may prevent emitting
|
||||
// mousedown/mouseup events, on which external libraries may rely (like AGGrid for hiding
|
||||
// context menu).
|
||||
if (!(event instanceof PointerEvent)) event.preventDefault()
|
||||
}
|
||||
return handled
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user