From c9cadf6fdd03a48d352e228bf2a6fdc8c9df645b Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Sun, 26 Jul 2026 11:15:57 +0300 Subject: [PATCH] fix(ui): expose auto-layout flow choices --- CHANGELOG.md | 2 +- packages/vue/src/i18n/locales/de/panels.json | 2 + packages/vue/src/i18n/locales/es/panels.json | 2 + packages/vue/src/i18n/locales/fr/panels.json | 2 + packages/vue/src/i18n/locales/it/panels.json | 2 + packages/vue/src/i18n/locales/ja/panels.json | 2 + packages/vue/src/i18n/locales/pl/panels.json | 2 + packages/vue/src/i18n/locales/ru/panels.json | 2 + .../vue/src/i18n/locales/zh-cn/panels.json | 2 + packages/vue/src/i18n/messages/panels.ts | 2 + .../LayoutSection/AutoLayoutControls.vue | 72 ++++++++++-------- .../properties/LayoutSection/FlexControls.vue | 2 +- .../LayoutSection/LayoutSection.vue | 26 ++++--- ...-position-appearance-openpencil-darwin.png | Bin 22134 -> 23704 bytes tests/e2e/editor/auto-layout/basic.spec.ts | 31 ++++++-- ...ut-freeform-controls-openpencil-darwin.png | Bin 0 -> 6177 bytes ...layout-size-controls-openpencil-darwin.png | Bin 9776 -> 11990 bytes .../instance-openpencil-darwin.png | Bin 26369 -> 26520 bytes .../single-rectangle-openpencil-darwin.png | Bin 19784 -> 20505 bytes .../text-selection-openpencil-darwin.png | Bin 28658 -> 28346 bytes tests/e2e/properties/shared-styles.spec.ts | 3 +- 21 files changed, 103 insertions(+), 51 deletions(-) create mode 100644 tests/e2e/editor/auto-layout/basic.spec.ts-snapshots/layout-freeform-controls-openpencil-darwin.png diff --git a/CHANGELOG.md b/CHANGELOG.md index a4be166a1..0ee04d9f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ ### Changed -- Group sizing and auto-layout controls into one contextual Design panel section, and use Figma’s current Layout guide terminology. +- Choose Freeform, vertical, horizontal, or grid flow directly from the contextual Layout section, with sizing grouped alongside it and current Layout guide terminology. - Redesign the editor chrome and Design panel with denser aligned controls, clearer selection and section states, improved menus and overlays, consistent light/dark theming, and better keyboard and screen-reader behavior. - Scale the Layers panel to documents with thousands of nodes through virtualized rows, faster incremental updates, stable expansion, range selection, and scroll-to-selection. - Resolve fonts before text appears, with language-aware CJK and Arabic fallback, character-specific remote subsets, and more reliable rendering as fonts load. diff --git a/packages/vue/src/i18n/locales/de/panels.json b/packages/vue/src/i18n/locales/de/panels.json index b2fa93952..928f01ee8 100644 --- a/packages/vue/src/i18n/locales/de/panels.json +++ b/packages/vue/src/i18n/locales/de/panels.json @@ -128,6 +128,8 @@ "multiplayerCursors": "Cursor anderer Teilnehmer", "direction": "Richtung", "flow": "Fluss", + "freeform": "Freiform", + "dimensions": "Abmessungen", "layoutHorizontal": "Horizontales Layout", "layoutVertical": "Vertikales Layout", "layoutGrid": "Rasterlayout", diff --git a/packages/vue/src/i18n/locales/es/panels.json b/packages/vue/src/i18n/locales/es/panels.json index d61dbd5ec..e36693967 100644 --- a/packages/vue/src/i18n/locales/es/panels.json +++ b/packages/vue/src/i18n/locales/es/panels.json @@ -142,6 +142,8 @@ "multiplayerCursors": "Cursores de otros participantes", "direction": "Dirección", "flow": "Flujo", + "freeform": "Forma libre", + "dimensions": "Dimensiones", "layoutHorizontal": "Diseño horizontal", "layoutVertical": "Diseño vertical", "layoutGrid": "Diseño de cuadrícula", diff --git a/packages/vue/src/i18n/locales/fr/panels.json b/packages/vue/src/i18n/locales/fr/panels.json index 63d8eab7c..c5a8c9ff6 100644 --- a/packages/vue/src/i18n/locales/fr/panels.json +++ b/packages/vue/src/i18n/locales/fr/panels.json @@ -128,6 +128,8 @@ "multiplayerCursors": "Curseurs des participants", "direction": "Direction", "flow": "Flux", + "freeform": "Forme libre", + "dimensions": "Dimensions", "layoutHorizontal": "Disposition horizontale", "layoutVertical": "Disposition verticale", "layoutGrid": "Disposition en grille", diff --git a/packages/vue/src/i18n/locales/it/panels.json b/packages/vue/src/i18n/locales/it/panels.json index 78b7d9fc9..f60e55c5d 100644 --- a/packages/vue/src/i18n/locales/it/panels.json +++ b/packages/vue/src/i18n/locales/it/panels.json @@ -128,6 +128,8 @@ "multiplayerCursors": "Cursori degli altri partecipanti", "direction": "Direzione", "flow": "Flusso", + "freeform": "Forma libera", + "dimensions": "Dimensioni", "layoutHorizontal": "Layout orizzontale", "layoutVertical": "Layout verticale", "layoutGrid": "Layout a griglia", diff --git a/packages/vue/src/i18n/locales/ja/panels.json b/packages/vue/src/i18n/locales/ja/panels.json index 78c3e235d..53694589d 100644 --- a/packages/vue/src/i18n/locales/ja/panels.json +++ b/packages/vue/src/i18n/locales/ja/panels.json @@ -142,6 +142,8 @@ "multiplayerCursors": "他の参加者のカーソル", "direction": "方向", "flow": "フロー", + "freeform": "フリーフォーム", + "dimensions": "寸法", "layoutHorizontal": "横方向レイアウト", "layoutVertical": "縦方向レイアウト", "layoutGrid": "グリッドレイアウト", diff --git a/packages/vue/src/i18n/locales/pl/panels.json b/packages/vue/src/i18n/locales/pl/panels.json index 89276ba13..165a3ec02 100644 --- a/packages/vue/src/i18n/locales/pl/panels.json +++ b/packages/vue/src/i18n/locales/pl/panels.json @@ -128,6 +128,8 @@ "multiplayerCursors": "Kursory innych uczestników", "direction": "Kierunek", "flow": "Przepływ", + "freeform": "Swobodny", + "dimensions": "Wymiary", "layoutHorizontal": "Układ poziomy", "layoutVertical": "Układ pionowy", "layoutGrid": "Układ siatki", diff --git a/packages/vue/src/i18n/locales/ru/panels.json b/packages/vue/src/i18n/locales/ru/panels.json index 03e97df19..768a786f4 100644 --- a/packages/vue/src/i18n/locales/ru/panels.json +++ b/packages/vue/src/i18n/locales/ru/panels.json @@ -128,6 +128,8 @@ "multiplayerCursors": "Курсоры участников", "direction": "Направление", "flow": "Поток", + "freeform": "Свободная", + "dimensions": "Размеры", "layoutHorizontal": "Горизонтальная раскладка", "layoutVertical": "Вертикальная раскладка", "layoutGrid": "Сетка", diff --git a/packages/vue/src/i18n/locales/zh-cn/panels.json b/packages/vue/src/i18n/locales/zh-cn/panels.json index 9d937bcd1..533f2443e 100644 --- a/packages/vue/src/i18n/locales/zh-cn/panels.json +++ b/packages/vue/src/i18n/locales/zh-cn/panels.json @@ -128,6 +128,8 @@ "multiplayerCursors": "协作光标", "direction": "方向", "flow": "流向", + "freeform": "自由布局", + "dimensions": "尺寸", "layoutHorizontal": "水平布局", "layoutVertical": "垂直布局", "layoutGrid": "网格布局", diff --git a/packages/vue/src/i18n/messages/panels.ts b/packages/vue/src/i18n/messages/panels.ts index 2aa8759c3..496efc84a 100644 --- a/packages/vue/src/i18n/messages/panels.ts +++ b/packages/vue/src/i18n/messages/panels.ts @@ -231,6 +231,8 @@ export const panelMessageDefaults = { multiplayerCursors: 'Multiplayer cursors', direction: 'Direction', flow: 'Flow', + freeform: 'Freeform', + dimensions: 'Dimensions', layoutHorizontal: 'Horizontal layout', layoutVertical: 'Vertical layout', layoutGrid: 'Grid layout', diff --git a/src/components/properties/LayoutSection/AutoLayoutControls.vue b/src/components/properties/LayoutSection/AutoLayoutControls.vue index f81daaa8d..aa4c7b8a3 100644 --- a/src/components/properties/LayoutSection/AutoLayoutControls.vue +++ b/src/components/properties/LayoutSection/AutoLayoutControls.vue @@ -4,46 +4,56 @@ import { computed } from 'vue' import { useI18n, useLayoutControlsContext } from '@open-pencil/vue' import IconButton from '@/components/ui/IconButton.vue' +import SegmentedControl from '@/components/ui/SegmentedControl.vue' +import Tip from '@/components/ui/Tip.vue' import type { LayoutMode } from '@open-pencil/scene-graph' const ctx = useLayoutControlsContext() const { panels } = useI18n() -const layoutModes = computed>(() => [ - { mode: 'HORIZONTAL', label: panels.value.layoutHorizontal }, - { mode: 'VERTICAL', label: panels.value.layoutVertical }, - { mode: 'GRID', label: panels.value.layoutGrid } +const layoutModes = computed>(() => [ + { value: 'NONE', label: panels.value.freeform }, + { value: 'VERTICAL', label: panels.value.layoutVertical }, + { value: 'HORIZONTAL', label: panels.value.layoutHorizontal }, + { value: 'GRID', label: panels.value.layoutGrid } ]) + +function setLayoutMode(mode: string) { + ctx.editor.setLayoutMode(ctx.node.id, mode as LayoutMode) +} diff --git a/src/components/properties/LayoutSection/FlexControls.vue b/src/components/properties/LayoutSection/FlexControls.vue index 68e49654c..5969a23b9 100644 --- a/src/components/properties/LayoutSection/FlexControls.vue +++ b/src/components/properties/LayoutSection/FlexControls.vue @@ -52,7 +52,7 @@ function alignmentCellClass(primary: LayoutAlign, counter: string) {