diff --git a/CHANGELOG.md b/CHANGELOG.md index 0517d60de..179bb5fa8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ ### Fixes +- Restore the Variables dialog empty state, full-width table layout, unclipped type menu, and expected Escape handling in dialogs and popup menus. - Pin the patched `websocket-driver` release used through Trystero/Firebase collaboration to resolve a critical protocol-length advisory. - Preserve unrelated Figma prototype, library, export, and raw metadata when editing modeled `.fig` fields, while still overriding stale field-specific payloads. - Make canvas text rendering demand missing font faces and verify CJK/Arabic fallback coverage from CanvasKit shaping results instead of coarse script predictions. diff --git a/src/app/shell/keyboard/registry.ts b/src/app/shell/keyboard/registry.ts index a9706c83e..8bb08aff2 100644 --- a/src/app/shell/keyboard/registry.ts +++ b/src/app/shell/keyboard/registry.ts @@ -52,7 +52,10 @@ function opacityBindings(): ShortcutDefinition[] { function shouldIgnoreShortcut(event: KeyboardEvent, options: KeyboardShortcutOptions) { return ( - (event.target instanceof Element && event.target.closest('[data-picker-content]') !== null) || + (event.target instanceof Element && + event.target.closest( + '[data-picker-content], [role="dialog"], [role="listbox"], [role="menu"]' + ) !== null) || isEditing(event) || options.inputFocused.value || !!options.store.state.editingTextId || diff --git a/src/components/variables/VariablesDialog.vue b/src/components/variables/VariablesDialog.vue index 19989c195..f2bd90a66 100644 --- a/src/components/variables/VariablesDialog.vue +++ b/src/components/variables/VariablesDialog.vue @@ -46,6 +46,7 @@ import type { VariableType } from '@open-pencil/scene-graph' const open = defineModel('open', { default: false }) const cls = useDialogUI({ content: 'flex h-[75vh] w-[800px] max-w-[90vw] flex-col' }) const menuCls = useMenuUI({ content: 'w-40' }) +const addVariableMenuCls = useMenuUI({ content: 'w-48' }) const variableTable = tv(variableTableTheme) const tableStyles = variableTable() @@ -128,10 +129,11 @@ function resizeHandleClass(resizing: boolean) { :class="cls.content" > {{ dialogs.localVariables }} -
+

{{ dialogs.localVariables }}

@@ -235,6 +237,7 @@ function resizeHandleClass(resizing: boolean) { @@ -250,7 +253,7 @@ function resizeHandleClass(resizing: boolean) { >
@@ -395,7 +398,7 @@ function resizeHandleClass(resizing: boolean) { side="top" :side-offset="8" align="end" - :class="menuCls.content" + :class="addVariableMenuCls.content" > { + await openVariables().click() + + const dialog = editor.page.getByTestId('variables-dialog') + await expect(dialog).toBeVisible() + await expect(dialog.getByText('No variable collections')).toBeVisible() + await expect(dialog.getByRole('button', { name: 'Create collection' })).toBeVisible() + await editor.page.keyboard.press('Escape') + await expect(dialog).toBeHidden() +}) + test('variables dialog opens', async () => { await createColorVariable('primary-color') await openVariables().click() - await expect(editor.page.getByTestId('variables-dialog')).toBeVisible() + const dialog = editor.page.getByTestId('variables-dialog') + await expect(dialog).toBeVisible() await expect(editor.page.locator('[data-default="true"]')).toHaveCount(1) + const table = dialog.locator('table') + const tableBox = expectDefined(await table.boundingBox(), 'variables table bounds') + const scrollerBox = expectDefined( + await table.locator('..').boundingBox(), + 'table scroller bounds' + ) + expect(tableBox.width).toBeGreaterThanOrEqual(scrollerBox.width) editor.canvas.assertNoErrors() }) @@ -55,6 +75,17 @@ test('add variable menu creates non-color variable types', async () => { await editor.page.getByTestId('variables-search-input').fill('') await editor.canvas.waitForRender() + await editor.page.getByTestId('variables-add-variable').click() + const numberOption = editor.page.getByTestId(variablesAddTestId('FLOAT')) + const numberHint = numberOption.getByText('Sizes, spacing, opacity') + await expect(numberHint).toBeVisible() + expect(await numberHint.evaluate((element) => element.scrollWidth <= element.clientWidth)).toBe( + true + ) + await editor.page.keyboard.press('Escape') + await expect(numberOption).toBeHidden() + await expect(editor.page.getByTestId('variables-dialog')).toBeVisible() + await editor.page.getByTestId('variables-add-variable').click() await editor.page.getByTestId(variablesAddTestId('FLOAT')).click() await expect(