fix(app): polish variable dialog states
- Restore the empty collection call to action\n- Fill the table width and prevent variable type hint clipping\n- Let dialogs and popup menus handle Escape before editor shortcuts
This commit is contained in:
parent
e0d8efb2a4
commit
429a7e5ae2
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 ||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ import type { VariableType } from '@open-pencil/scene-graph'
|
|||
const open = defineModel<boolean>('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"
|
||||
>
|
||||
<DialogTitle class="sr-only">{{ dialogs.localVariables }}</DialogTitle>
|
||||
<div v-if="!ctx.hasCollections" class="flex flex-1 flex-col">
|
||||
<div v-if="!ctx.hasCollections.value" class="flex flex-1 flex-col">
|
||||
<div class="flex shrink-0 items-center justify-between border-b border-border px-4 py-3">
|
||||
<h2 class="text-sm font-semibold text-surface">{{ dialogs.localVariables }}</h2>
|
||||
<DialogClose
|
||||
:aria-label="dialogs.close"
|
||||
class="flex size-6 cursor-pointer items-center justify-center rounded border-none bg-transparent text-muted hover:bg-hover hover:text-surface"
|
||||
>
|
||||
<icon-lucide-x class="size-4" />
|
||||
|
|
@ -235,6 +237,7 @@ function resizeHandleClass(resizing: boolean) {
|
|||
</button>
|
||||
</Tip>
|
||||
<DialogClose
|
||||
:aria-label="dialogs.close"
|
||||
class="flex size-6 cursor-pointer items-center justify-center rounded border-none bg-transparent text-muted hover:bg-hover hover:text-surface"
|
||||
>
|
||||
<icon-lucide-x class="size-4" />
|
||||
|
|
@ -250,7 +253,7 @@ function resizeHandleClass(resizing: boolean) {
|
|||
>
|
||||
<div class="flex-1 overflow-auto">
|
||||
<table
|
||||
class="w-full border-collapse"
|
||||
class="w-full min-w-full border-collapse"
|
||||
:style="{ width: `${ctx.table.getCenterTotalSize()}px` }"
|
||||
>
|
||||
<thead class="sticky top-0 z-10 bg-panel">
|
||||
|
|
@ -395,7 +398,7 @@ function resizeHandleClass(resizing: boolean) {
|
|||
side="top"
|
||||
:side-offset="8"
|
||||
align="end"
|
||||
:class="menuCls.content"
|
||||
:class="addVariableMenuCls.content"
|
||||
>
|
||||
<DropdownMenuItem
|
||||
v-for="item in variableTypes"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { expect, test, useEditorSetup } from '#tests/e2e/fixtures'
|
||||
import { expectDefined } from '#tests/helpers/assert'
|
||||
import { variablesAddTestId } from '#tests/helpers/test-ids'
|
||||
|
||||
const editor = useEditorSetup()
|
||||
|
|
@ -25,12 +26,31 @@ function openVariables() {
|
|||
.getByRole('button', { name: 'Open variables' })
|
||||
}
|
||||
|
||||
test('empty variables dialog offers to create a collection', async () => {
|
||||
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(
|
||||
|
|
|
|||
Loading…
Reference in a new issue