fix(editor): close padding editor on canvas click
This commit is contained in:
parent
9537f35a27
commit
b46295a7bb
|
|
@ -201,6 +201,35 @@ const noVueStyleBlocks = {
|
|||
}
|
||||
}
|
||||
|
||||
const noDocumentQuerySelectorInVue = {
|
||||
meta: {
|
||||
docs: {
|
||||
description: 'Disallow document.querySelector in Vue components — use template refs or composables'
|
||||
}
|
||||
},
|
||||
create(context) {
|
||||
const file = normalizedFilename(context)
|
||||
if (!file.endsWith('.vue')) return {}
|
||||
|
||||
return {
|
||||
CallExpression(node) {
|
||||
const callee = node.callee
|
||||
if (callee?.type !== 'MemberExpression') return
|
||||
if (callee.object?.type !== 'Identifier' || callee.object.name !== 'document') return
|
||||
if (callee.property?.type !== 'Identifier') return
|
||||
if (callee.property.name !== 'querySelector' && callee.property.name !== 'querySelectorAll') {
|
||||
return
|
||||
}
|
||||
context.report({
|
||||
node,
|
||||
message:
|
||||
'Do not query the document from Vue components. Use template refs, component APIs, or a composable.'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const noDirectSelectionToolStateMutation = {
|
||||
meta: {
|
||||
docs: {
|
||||
|
|
@ -1257,6 +1286,7 @@ const plugin = {
|
|||
'no-inline-named-types': noInlineNamedTypes,
|
||||
'no-structuredclone-scene-arrays': noStructuredCloneSceneArrays,
|
||||
'no-vue-style-blocks': noVueStyleBlocks,
|
||||
'no-document-query-selector-in-vue': noDocumentQuerySelectorInVue,
|
||||
'no-direct-selection-tool-state-mutation': noDirectSelectionToolStateMutation,
|
||||
'no-math-random': noMathRandom,
|
||||
'no-hand-rolled-color': noHandRolledColor,
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@
|
|||
],
|
||||
"open-pencil/no-structuredclone-scene-arrays": "error",
|
||||
"open-pencil/no-vue-style-blocks": "error",
|
||||
"open-pencil/no-document-query-selector-in-vue": "error",
|
||||
"open-pencil/no-direct-selection-tool-state-mutation": "error",
|
||||
"open-pencil/no-math-random": "error",
|
||||
"open-pencil/no-hand-rolled-color": "error",
|
||||
|
|
|
|||
|
|
@ -148,6 +148,10 @@ export function useCanvasInput(
|
|||
}
|
||||
|
||||
function onMouseDown(e: MouseEvent) {
|
||||
const paddingEdit = autoLayoutPaddingEdit.value
|
||||
if (paddingEdit) {
|
||||
commitAutoLayoutPaddingEdit(paddingEdit.value)
|
||||
}
|
||||
if (!editor.state.editingTextId) canvasRef.value?.focus()
|
||||
editor.setHoveredNode(null)
|
||||
const { sx, sy, cx, cy } = getCoords(e)
|
||||
|
|
|
|||
|
|
@ -10,10 +10,19 @@ export function createProfilerActions(editor: Editor) {
|
|||
return { x: window.innerWidth / 2, y: window.innerHeight / 2 }
|
||||
}
|
||||
|
||||
function viewportCanvasCenter() {
|
||||
const canvas = document.querySelector<HTMLCanvasElement>('[data-test-id="canvas-element"]')
|
||||
if (canvas) {
|
||||
const rect = canvas.getBoundingClientRect()
|
||||
return { x: rect.width / 2, y: rect.height / 2 }
|
||||
}
|
||||
return { x: window.innerWidth / 2, y: window.innerHeight / 2 }
|
||||
}
|
||||
|
||||
function toggleProfiler() {
|
||||
editor.renderer?.profiler.toggle()
|
||||
editor.requestRepaint()
|
||||
}
|
||||
|
||||
return { viewportScreenCenter, toggleProfiler }
|
||||
return { viewportScreenCenter, viewportCanvasCenter, toggleProfiler }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,12 +144,8 @@ function openDetails(asset: LocalAsset) {
|
|||
}
|
||||
|
||||
function insertionPoint(component: SceneNode, parentId: string) {
|
||||
const canvas = document.querySelector<HTMLElement>('[data-test-id="canvas-area"]')
|
||||
const rect = canvas?.getBoundingClientRect()
|
||||
const center = editor.screenToCanvas(
|
||||
(rect?.width ?? window.innerWidth) / 2,
|
||||
(rect?.height ?? window.innerHeight) / 2
|
||||
)
|
||||
const canvasCenter = editor.viewportCanvasCenter()
|
||||
const center = editor.screenToCanvas(canvasCenter.x, canvasCenter.y)
|
||||
const parentOffset =
|
||||
parentId === editor.state.currentPageId
|
||||
? { x: 0, y: 0 }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, nextTick, ref, watch, type Component } from 'vue'
|
||||
import { computed, ref, type Component } from 'vue'
|
||||
import {
|
||||
AUTO_LAYOUT_PADDING_EDITOR_OFFSET_X,
|
||||
AUTO_LAYOUT_PADDING_EDITOR_OFFSET_Y
|
||||
|
|
@ -97,16 +97,6 @@ const paddingEditorIcon = computed(() => {
|
|||
return edit ? paddingSideIcons[edit.side] : IconLucidePanelTop
|
||||
})
|
||||
|
||||
watch(autoLayoutPaddingEdit, async (edit) => {
|
||||
if (!edit) return
|
||||
await nextTick()
|
||||
const input = document.querySelector<HTMLInputElement>(
|
||||
'[data-test-id="auto-layout-padding-editor"] input'
|
||||
)
|
||||
input?.focus()
|
||||
input?.select()
|
||||
})
|
||||
|
||||
const cursor = computed(() => toolCursor(store.state.activeTool, cursorOverride.value))
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ const { modelValue, min, max, step, icon, label, suffix, sensitivity, placeholde
|
|||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: number]
|
||||
'editing-change': [editing: boolean]
|
||||
commit: [value: number, previous: number]
|
||||
}>()
|
||||
|
||||
|
|
@ -38,7 +39,12 @@ defineOptions({ inheritAttrs: false })
|
|||
:placeholder="placeholder"
|
||||
@update:model-value="emit('update:modelValue', $event)"
|
||||
@commit="(val: number, prev: number) => emit('commit', val, prev)"
|
||||
@editing-change="store.state.scrubInputFocused = $event"
|
||||
@editing-change="
|
||||
(editing: boolean) => {
|
||||
store.state.scrubInputFocused = editing
|
||||
emit('editing-change', editing)
|
||||
}
|
||||
"
|
||||
>
|
||||
<div
|
||||
v-bind="attrs"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@ import { expect, test, type Page } from '@playwright/test'
|
|||
|
||||
import { CanvasHelper } from '#tests/helpers/canvas'
|
||||
|
||||
async function clickCanvas(page: Page, x: number, y: number) {
|
||||
const canvas = page.locator('[data-test-id="canvas-element"]')
|
||||
const box = await canvas.boundingBox()
|
||||
if (!box) throw new Error('Canvas has no bounding box')
|
||||
await page.mouse.click(box.x + x, box.y + y)
|
||||
}
|
||||
|
||||
async function dblclickCanvas(page: Page, x: number, y: number) {
|
||||
const canvas = page.locator('[data-test-id="canvas-element"]')
|
||||
const box = await canvas.boundingBox()
|
||||
|
|
@ -85,6 +92,25 @@ test('double-clicking an auto-layout padding handle opens a scrub editor', async
|
|||
canvas.assertNoErrors()
|
||||
})
|
||||
|
||||
test('clicking the canvas closes the auto-layout padding editor', async ({ page }) => {
|
||||
await page.goto('/')
|
||||
const canvas = new CanvasHelper(page)
|
||||
await canvas.waitForInit()
|
||||
await canvas.clearCanvas()
|
||||
|
||||
await setupAutoLayoutFrame(page)
|
||||
await canvas.waitForRender()
|
||||
|
||||
await canvas.hover(300, 130)
|
||||
await dblclickCanvas(page, 300, 130)
|
||||
const editor = page.locator('[data-test-id="auto-layout-padding-editor"]')
|
||||
await expect(editor).toBeVisible()
|
||||
|
||||
await clickCanvas(page, 80, 80)
|
||||
await expect(editor).toHaveCount(0)
|
||||
canvas.assertNoErrors()
|
||||
})
|
||||
|
||||
test('auto-layout padding editor follows canvas pan while open', async ({ page }) => {
|
||||
await page.goto('/')
|
||||
const canvas = new CanvasHelper(page)
|
||||
|
|
|
|||
Loading…
Reference in a new issue