* 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
236 lines
5.3 KiB
TypeScript
236 lines
5.3 KiB
TypeScript
export type { GUID, Color, Vector, Matrix, Rect } from './types'
|
|
export { degToRad, radToDeg, rotatePoint, rotatedCorners, rotatedBBox } from './geometry'
|
|
|
|
export * from './constants'
|
|
|
|
export {
|
|
SceneGraph,
|
|
generateId,
|
|
type SceneNode,
|
|
type NodeType,
|
|
type Fill,
|
|
type FillType,
|
|
type Stroke,
|
|
type StrokeCap,
|
|
type StrokeJoin,
|
|
type MaskType,
|
|
type Effect,
|
|
type BlendMode,
|
|
type ImageScaleMode,
|
|
type GradientStop,
|
|
type GradientTransform,
|
|
type LayoutMode,
|
|
type LayoutSizing,
|
|
type LayoutAlign,
|
|
type LayoutCounterAlign,
|
|
type LayoutWrap,
|
|
type GridTrack,
|
|
type GridTrackSizing,
|
|
type GridPosition,
|
|
type ConstraintType,
|
|
type TextAutoResize,
|
|
type TextAlignVertical,
|
|
type TextCase,
|
|
type TextDecoration,
|
|
type ArcData,
|
|
type VectorNetwork,
|
|
type VectorVertex,
|
|
type VectorSegment,
|
|
type VectorRegion,
|
|
type GeometryPath,
|
|
type HandleMirroring,
|
|
type WindingRule,
|
|
type VariableType,
|
|
type VariableValue,
|
|
type Variable,
|
|
type VariableCollection,
|
|
type VariableCollectionMode,
|
|
type CharacterStyleOverride,
|
|
type StyleRun
|
|
} from './scene-graph'
|
|
|
|
export { FigmaAPI, FigmaNodeProxy, type FigmaFontName } from './figma-api'
|
|
export { ALL_TOOLS, defineTool, toolsToAI } from './tools'
|
|
export type { ToolDef, ParamDef, ParamType } from './tools'
|
|
export { executeRpcCommand, ALL_RPC_COMMANDS } from './rpc'
|
|
export type {
|
|
InfoResult, PageItem, TreeArgs, TreeResult, TreeNodeResult,
|
|
FindArgs, FindNodeResult, NodeArgs, NodeResult,
|
|
VariablesArgs, VariablesResult,
|
|
AnalyzeColorsArgs, AnalyzeColorsResult,
|
|
AnalyzeTypographyArgs, AnalyzeTypographyResult,
|
|
AnalyzeSpacingResult, SpacingValue,
|
|
AnalyzeClustersArgs, AnalyzeClustersResult, TypographyStyle
|
|
} from './rpc'
|
|
export { SkiaRenderer, type RenderOverlays } from './renderer/index'
|
|
export {
|
|
RenderProfiler,
|
|
FrameStats,
|
|
GPUTimer,
|
|
DrawCallCounter,
|
|
PhaseTimer,
|
|
CaptureStack,
|
|
toSpeedscopeJSON
|
|
} from './profiler'
|
|
export type { FrameCapture, NodeProfile } from './profiler'
|
|
export { computeLayout, computeAllLayouts, setTextMeasurer } from './layout'
|
|
export type { TextMeasurer } from './layout'
|
|
export { getCanvasKit, getGpuBackend, type CanvasKitOptions, type GpuBackend } from './canvaskit'
|
|
export {
|
|
collectFontKeys,
|
|
loadFont,
|
|
listFamilies,
|
|
initFontService,
|
|
getFontProvider,
|
|
isFontLoaded,
|
|
markFontLoaded,
|
|
ensureNodeFont,
|
|
ensureCJKFallback,
|
|
getCJKFallbackFamily,
|
|
styleToWeight,
|
|
weightToStyle
|
|
} from './fonts'
|
|
export {
|
|
parseColor,
|
|
normalizeColor,
|
|
colorToHex,
|
|
colorToHex8,
|
|
colorToHexRaw,
|
|
colorToRgba255,
|
|
colorToCSS,
|
|
colorToCSSCompact,
|
|
rgba255ToColor,
|
|
colorToFill,
|
|
colorDistance
|
|
} from './color'
|
|
export {
|
|
vectorNetworkToPath,
|
|
geometryBlobToPath,
|
|
decodeVectorNetworkBlob,
|
|
encodeVectorNetworkBlob,
|
|
computeVectorBounds
|
|
} from './vector'
|
|
export { computeSelectionBounds, computeSnap, type SnapGuide } from './snap'
|
|
export { UndoManager } from './undo'
|
|
export { TextEditor, type TextCaret, type TextEditorState } from './text-editor'
|
|
export {
|
|
getStyleAt,
|
|
applyStyleToRange,
|
|
removeStyleFromRange,
|
|
selectionHasStyle,
|
|
toggleBoldInRange,
|
|
toggleItalicInRange,
|
|
toggleDecorationInRange,
|
|
adjustRunsForInsert,
|
|
adjustRunsForDelete
|
|
} from './style-runs'
|
|
export { renderNodesToImage, renderThumbnail, computeContentBounds, type ExportFormat } from './render-image'
|
|
export {
|
|
renderNodesToSVG,
|
|
geometryBlobToSVGPath,
|
|
vectorNetworkToSVGPaths,
|
|
type SVGExportOptions
|
|
} from './svg-export'
|
|
export { svg, renderSVGNode, type SVGNode } from './svg-node'
|
|
export { exportFigFile } from './fig-export'
|
|
export {
|
|
FIG_KIWI_VERSION,
|
|
buildFigKiwi,
|
|
parseFigKiwiChunks,
|
|
decompressFigKiwiData,
|
|
decompressFigKiwiDataAsync,
|
|
sceneNodeToKiwi,
|
|
fractionalPosition,
|
|
mapToFigmaType
|
|
} from './kiwi-serialize'
|
|
|
|
export {
|
|
createElement,
|
|
renderTree,
|
|
renderJSX,
|
|
renderTreeNode,
|
|
buildComponent,
|
|
Frame,
|
|
Text,
|
|
Rectangle,
|
|
Ellipse,
|
|
Line,
|
|
Star,
|
|
Polygon,
|
|
Vector as VectorNode,
|
|
Group,
|
|
Section,
|
|
View,
|
|
Rect as RectNode,
|
|
Component as ComponentNode,
|
|
Instance as InstanceNode,
|
|
Page as PageNode,
|
|
INTRINSIC_ELEMENTS,
|
|
isTreeNode,
|
|
resolveToTree,
|
|
node,
|
|
type TreeNode,
|
|
type BaseProps,
|
|
type TextProps,
|
|
type StyleProps,
|
|
type RenderResult,
|
|
sceneNodeToJSX,
|
|
selectionToJSX,
|
|
type JSXFormat
|
|
} from './render'
|
|
export {
|
|
parseFigmaClipboard,
|
|
importClipboardNodes,
|
|
figmaNodesBounds,
|
|
parseOpenPencilClipboard,
|
|
buildFigmaClipboardHTML,
|
|
buildOpenPencilClipboardHTML,
|
|
prefetchFigmaSchema,
|
|
type TextPictureBuilder
|
|
} from './clipboard'
|
|
|
|
export { readFigFile, parseFigFile } from './kiwi/fig-file'
|
|
export { importNodeChanges } from './kiwi/fig-import'
|
|
export {
|
|
initCodec,
|
|
encodeMessage,
|
|
decodeMessage,
|
|
compress,
|
|
decompress,
|
|
getCompiledSchema,
|
|
getSchemaBytes,
|
|
createNodeChangesMessage,
|
|
createNodeChange,
|
|
parseVariableId,
|
|
encodePaintWithVariableBinding,
|
|
encodeNodeChangeWithVariables,
|
|
type NodeChange,
|
|
type GUID as KiwiGUID,
|
|
type Color as KiwiColor,
|
|
type Paint as KiwiPaint,
|
|
type Effect as KiwiEffect,
|
|
type VariableBinding,
|
|
type ParentIndex,
|
|
type FigmaMessage
|
|
} from './kiwi/codec'
|
|
|
|
export {
|
|
MESSAGE_TYPES,
|
|
NODE_TYPES,
|
|
NODE_PHASES,
|
|
BLEND_MODES,
|
|
PAINT_TYPES,
|
|
PROTOCOL_VERSION,
|
|
KIWI,
|
|
SESSION_ID,
|
|
ZSTD_MAGIC,
|
|
buildMultiplayerUrl,
|
|
isZstdCompressed,
|
|
hasFigWireHeader,
|
|
skipFigWireHeader,
|
|
isKiwiMessage,
|
|
getKiwiMessageType,
|
|
parseVarint,
|
|
FIG_WIRE_MAGIC
|
|
} from './kiwi/protocol'
|