* Switch to @open-pencil/yoga-layout with CSS Grid support Use our fork (open-pencil/yoga, grid branch) which cherry-picks the upstream CSS Grid PRs (#1893–#1898) onto current main. The JS bindings are ported from the old embind approach to the new wasm_bridge.c API. npm:@open-pencil/yoga-layout alias keeps all imports as 'yoga-layout'. Also handle FinalizationRegistry change (upstream #1908) — node.free() no longer exists, nodes are garbage collected automatically. * Add CSS Grid layout mode Scene graph: - LayoutMode gains 'GRID' option alongside HORIZONTAL/VERTICAL - GridTrack type (sizing: FIXED/FR/AUTO, value) for track definitions - GridPosition type (column, row, columnSpan, rowSpan) for children - New node props: gridTemplateColumns/Rows, gridColumnGap, gridRowGap, gridPosition Layout engine: - buildGridTree() sets Display.Grid and maps GridTrack[] to Yoga's setGridTemplateColumns/Rows API with FR/Points/Auto track types - Grid children use gridPosition for column/row placement with span - Flex layout path unchanged Store: - setLayoutMode('GRID') auto-creates NxM track grid based on child count (sqrt heuristic), defaults to 1fr tracks UI (LayoutSection.vue): - Grid button (grid-2x2 icon) added to flow direction row - Columns/Rows track editors: ScrubInput for value + AppSelect for sizing mode (Fill fr / Fixed px / Auto), add/remove buttons - Separate column gap and row gap ScrubInputs - Wrap button hidden when grid is active - Flex alignment grid hidden when grid is active Kiwi serialization skips GRID mode for now (no .fig codec support). * Add grid layout integration tests 12 new test scenarios covering: - Basic 2x2 grid, fixed columns, mixed fr/fixed, unequal fr weights - Column gap, row gap, both gaps combined - Padding offsets - Explicit gridPosition placement, column span, row span - Absolute children skipped - Hidden children collapsed - Nested grid inside flex parent (computeAllLayouts) Also fix: grid frames as children of flex parents now correctly use Display.Grid via configureChildAsGrid() instead of falling through to configureChildAsAutoLayout() which set FlexDirection. * Deduplicate grid yoga configuration Extract configureAsGrid() and createGridChildNode() shared by buildGridTree (root-level grid) and configureChildAsGrid (grid nested inside flex parent). * Add grid layout to changelog * Add grid support to JSX and Tailwind CSS export OpenPencil format: grid → columns/rows/columnGap/rowGap props, child colStart/rowStart/colSpan/rowSpan. Tailwind format: grid grid-cols-N grid-rows-N gap-x-* gap-y-*, mixed tracks use arbitrary values (grid-cols-[200px_1fr_auto]), child col-start-*/row-start-*/col-span-*/row-span-*. Both formats: padding emitted for grid frames (shared with flex), flex-only props (justify/items/wrap/gap) scoped to isFlex. * Remove duplicate gridTrackToTw, use shared formatTrack Also drop unused GridTrackSizing import from LayoutSection.vue. * Fix grid icon: use layout-grid instead of grid-2x2 unplugin-icons can't resolve icon names with digits after hyphens (grid-2x2 → grid2x2 which doesn't exist). * Polish layout UI and fix auto-layout behavior - Replace text labels with compact icons: ↔/↕ for gap, ☐ for uniform padding, T/R/B/L for per-side padding - Direction-aware gap icon: ↕ for vertical, ↔ for horizontal - Pin +/− padding toggle button right of gap input - Fix alignment grid axes for vertical layout (transpose primary/counter) - Fix grid switch: set FIXED sizing, compute frame size from children - Remove hardcoded white fill from Shift+A wrap - Auto-detect horizontal vs vertical from selection bounds * Add flex-to-grid switch integration test Verify HUG frame expands and children are placed in 2x2 grid when switching from vertical flex to grid layout. * Update changelog for grid layout
124 lines
8.8 KiB
TypeScript
124 lines
8.8 KiB
TypeScript
/* eslint-disable */
|
|
// @ts-nocheck
|
|
// biome-ignore lint: disable
|
|
// oxlint-disable
|
|
// ------
|
|
// Generated by unplugin-vue-components
|
|
// Read more: https://github.com/vuejs/core/pull/3399
|
|
|
|
export {}
|
|
|
|
/* prettier-ignore */
|
|
declare module 'vue' {
|
|
export interface GlobalComponents {
|
|
APIKeySetup: typeof import('./src/components/chat/APIKeySetup.vue')['default']
|
|
AppearanceSection: typeof import('./src/components/properties/AppearanceSection.vue')['default']
|
|
AppMenu: typeof import('./src/components/AppMenu.vue')['default']
|
|
AppSelect: typeof import('./src/components/AppSelect.vue')['default']
|
|
AppToast: typeof import('./src/components/AppToast.vue')['default']
|
|
CanvasContextMenu: typeof import('./src/components/CanvasContextMenu.vue')['default']
|
|
ChatInput: typeof import('./src/components/chat/ChatInput.vue')['default']
|
|
ChatMessage: typeof import('./src/components/chat/ChatMessage.vue')['default']
|
|
ChatPanel: typeof import('./src/components/ChatPanel.vue')['default']
|
|
CodePanel: typeof import('./src/components/CodePanel.vue')['default']
|
|
CollabPanel: typeof import('./src/components/CollabPanel.vue')['default']
|
|
ColorInput: typeof import('./src/components/ColorInput.vue')['default']
|
|
ColorPicker: typeof import('./src/components/ColorPicker.vue')['default']
|
|
DesignPanel: typeof import('./src/components/DesignPanel.vue')['default']
|
|
EditorCanvas: typeof import('./src/components/EditorCanvas.vue')['default']
|
|
EffectsSection: typeof import('./src/components/properties/EffectsSection.vue')['default']
|
|
ExportSection: typeof import('./src/components/properties/ExportSection.vue')['default']
|
|
FillPicker: typeof import('./src/components/FillPicker.vue')['default']
|
|
FillSection: typeof import('./src/components/properties/FillSection.vue')['default']
|
|
FontPicker: typeof import('./src/components/FontPicker.vue')['default']
|
|
HsvColorArea: typeof import('./src/components/HsvColorArea.vue')['default']
|
|
IconLucideALargeSmall: typeof import('~icons/lucide/a-large-small')['default']
|
|
IconLucideAlertTriangle: typeof import('~icons/lucide/alert-triangle')['default']
|
|
IconLucideAlignCenter: typeof import('~icons/lucide/align-center')['default']
|
|
IconLucideAlignHorizontalDistributeCenter: typeof import('~icons/lucide/align-horizontal-distribute-center')['default']
|
|
IconLucideAlignHorizontalJustifyCenter: typeof import('~icons/lucide/align-horizontal-justify-center')['default']
|
|
IconLucideAlignHorizontalJustifyEnd: typeof import('~icons/lucide/align-horizontal-justify-end')['default']
|
|
IconLucideAlignHorizontalJustifyStart: typeof import('~icons/lucide/align-horizontal-justify-start')['default']
|
|
IconLucideAlignLeft: typeof import('~icons/lucide/align-left')['default']
|
|
IconLucideAlignRight: typeof import('~icons/lucide/align-right')['default']
|
|
IconLucideAlignVerticalJustifyCenter: typeof import('~icons/lucide/align-vertical-justify-center')['default']
|
|
IconLucideAlignVerticalJustifyEnd: typeof import('~icons/lucide/align-vertical-justify-end')['default']
|
|
IconLucideAlignVerticalJustifyStart: typeof import('~icons/lucide/align-vertical-justify-start')['default']
|
|
IconLucideArrowDown: typeof import('~icons/lucide/arrow-down')['default']
|
|
IconLucideArrowRight: typeof import('~icons/lucide/arrow-right')['default']
|
|
IconLucideBaseline: typeof import('~icons/lucide/baseline')['default']
|
|
IconLucideBetweenHorizontalEnd: typeof import('~icons/lucide/between-horizontal-end')['default']
|
|
IconLucideBetweenHorizontalStart: typeof import('~icons/lucide/between-horizontal-start')['default']
|
|
IconLucideBetweenVerticalEnd: typeof import('~icons/lucide/between-vertical-end')['default']
|
|
IconLucideBetweenVerticalStart: typeof import('~icons/lucide/between-vertical-start')['default']
|
|
IconLucideBlend: typeof import('~icons/lucide/blend')['default']
|
|
IconLucideBold: typeof import('~icons/lucide/bold')['default']
|
|
IconLucideBot: typeof import('~icons/lucide/bot')['default']
|
|
IconLucideCheck: typeof import('~icons/lucide/check')['default']
|
|
IconLucideChevronDown: typeof import('~icons/lucide/chevron-down')['default']
|
|
IconLucideChevronRight: typeof import('~icons/lucide/chevron-right')['default']
|
|
IconLucideCode: typeof import('~icons/lucide/code')['default']
|
|
IconLucideCopy: typeof import('~icons/lucide/copy')['default']
|
|
IconLucideEye: typeof import('~icons/lucide/eye')['default']
|
|
IconLucideEyeOff: typeof import('~icons/lucide/eye-off')['default']
|
|
IconLucideFile: typeof import('~icons/lucide/file')['default']
|
|
IconLucideFlipHorizontal: typeof import('~icons/lucide/flip-horizontal')['default']
|
|
IconLucideFlipVertical: typeof import('~icons/lucide/flip-vertical')['default']
|
|
IconLucideFolderPlus: typeof import('~icons/lucide/folder-plus')['default']
|
|
IconLucideImage: typeof import('~icons/lucide/image')['default']
|
|
IconLucideItalic: typeof import('~icons/lucide/italic')['default']
|
|
IconLucideKeyRound: typeof import('~icons/lucide/key-round')['default']
|
|
IconLucideLayers: typeof import('~icons/lucide/layers')['default']
|
|
IconLucideLayoutGrid: typeof import('~icons/lucide/layout-grid')['default']
|
|
IconLucideLink: typeof import('~icons/lucide/link')['default']
|
|
IconLucideLoaderCircle: typeof import('~icons/lucide/loader-circle')['default']
|
|
IconLucideMenu: typeof import('~icons/lucide/menu')['default']
|
|
IconLucideMessageCircle: typeof import('~icons/lucide/message-circle')['default']
|
|
IconLucideMinus: typeof import('~icons/lucide/minus')['default']
|
|
IconLucideMoveHorizontal: typeof import('~icons/lucide/move-horizontal')['default']
|
|
IconLucideMoveVertical: typeof import('~icons/lucide/move-vertical')['default']
|
|
IconLucidePlus: typeof import('~icons/lucide/plus')['default']
|
|
IconLucideRadius: typeof import('~icons/lucide/radius')['default']
|
|
IconLucideRedo2: typeof import('~icons/lucide/redo2')['default']
|
|
IconLucideRotateCcw: typeof import('~icons/lucide/rotate-ccw')['default']
|
|
IconLucideRotateCw: typeof import('~icons/lucide/rotate-cw')['default']
|
|
IconLucideSearch: typeof import('~icons/lucide/search')['default']
|
|
IconLucideSend: typeof import('~icons/lucide/send')['default']
|
|
IconLucideSettings2: typeof import('~icons/lucide/settings2')['default']
|
|
IconLucideShare2: typeof import('~icons/lucide/share2')['default']
|
|
IconLucideSidebar: typeof import('~icons/lucide/sidebar')['default']
|
|
IconLucideSlidersHorizontal: typeof import('~icons/lucide/sliders-horizontal')['default']
|
|
IconLucideSpace: typeof import('~icons/lucide/space')['default']
|
|
IconLucideSparkles: typeof import('~icons/lucide/sparkles')['default']
|
|
IconLucideSquare: typeof import('~icons/lucide/square')['default']
|
|
IconLucideStrikethrough: typeof import('~icons/lucide/strikethrough')['default']
|
|
IconLucideTriangleAlert: typeof import('~icons/lucide/triangle-alert')['default']
|
|
IconLucideUnderline: typeof import('~icons/lucide/underline')['default']
|
|
IconLucideUndo2: typeof import('~icons/lucide/undo2')['default']
|
|
IconLucideUnlink: typeof import('~icons/lucide/unlink')['default']
|
|
IconLucideUsers: typeof import('~icons/lucide/users')['default']
|
|
IconLucideWrapText: typeof import('~icons/lucide/wrap-text')['default']
|
|
IconLucideX: typeof import('~icons/lucide/x')['default']
|
|
LayersPanel: typeof import('./src/components/LayersPanel.vue')['default']
|
|
LayerTree: typeof import('./src/components/LayerTree.vue')['default']
|
|
LayoutSection: typeof import('./src/components/properties/LayoutSection.vue')['default']
|
|
MobileDrawer: typeof import('./src/components/MobileDrawer.vue')['default']
|
|
MobileHud: typeof import('./src/components/MobileHud.vue')['default']
|
|
NodeContextMenuContent: typeof import('./src/components/NodeContextMenuContent.vue')['default']
|
|
PageSection: typeof import('./src/components/properties/PageSection.vue')['default']
|
|
PagesPanel: typeof import('./src/components/PagesPanel.vue')['default']
|
|
PositionSection: typeof import('./src/components/properties/PositionSection.vue')['default']
|
|
PropertiesPanel: typeof import('./src/components/PropertiesPanel.vue')['default']
|
|
RouterLink: typeof import('vue-router')['RouterLink']
|
|
RouterView: typeof import('vue-router')['RouterView']
|
|
SafariBanner: typeof import('./src/components/SafariBanner.vue')['default']
|
|
ScrubInput: typeof import('./src/components/ScrubInput.vue')['default']
|
|
StrokeSection: typeof import('./src/components/properties/StrokeSection.vue')['default']
|
|
TabBar: typeof import('./src/components/TabBar.vue')['default']
|
|
Toolbar: typeof import('./src/components/Toolbar.vue')['default']
|
|
TypographySection: typeof import('./src/components/properties/TypographySection.vue')['default']
|
|
VariablesDialog: typeof import('./src/components/VariablesDialog.vue')['default']
|
|
VariablesSection: typeof import('./src/components/properties/VariablesSection.vue')['default']
|
|
}
|
|
}
|