- Generate PNG previews for the selected component/default variant in the details dialog
- Revoke stale preview URLs and refresh on scene changes
- Assert the rendered preview image in assets e2e coverage
- Add a Figma-style component details dialog from local Assets
- Show preview, description, library key, documentation link, variant properties, and insert action
- Cover details metadata in the Assets panel e2e test
- Show imported library badges in the local Assets panel
- Display component descriptions and documentation links from Figma metadata
- Cover library metadata rendering in the Assets panel test
- Swap instance contents when changing variants instead of only updating componentId
- Recreate instance redo state without stale child IDs
- Insert assets into entered containers using local coordinates
- Fall back to Windows paths when URL parsing fails
- Insert component set assets using explicit default variant values
- Report duplicate variant value combinations in the assets panel
- Cover default insertion and conflict warnings in Playwright
- Add a left-sidebar Assets tab for local components and component sets
- Insert component set assets as instances of the default variant
- Showcase local component set insertion in the demo
- Cover search, empty state, standalone insert, and variant switching with Playwright
Show variant property dropdowns in the design panel when an instance
of a component set is selected. Switching a dropdown value finds the
matching variant component and updates the instance's componentId.
- VariantSection.vue with property dropdowns using AppSelect
- Bridge variant actions to the editor return object
- i18n for en, ru, zh-CN
Ref #239
Wire VariableScrubInput for minWidth, maxWidth, minHeight, maxHeight
in the size controls panel. Uses the after-variable slot to preserve
the existing select dropdown suffix alongside the variable binding UI.
- Add shared DOM event helpers to Vue SDK (inputValue, inputNumberValue,
blurTarget, selectTarget) in packages/vue/src/shared/dom-events.ts
- Export from @open-pencil/vue for app consumption
- Replace all template `as HTMLInputElement` casts with helper calls:
ColorPickerPanel fields, PickerSlider, GradientEditor, ColorInput,
CollabPanel, AppMenu, ScrubInputRoot
- Fix useInlineRename to use instanceof guards instead of casts
- Fix document name rename to accept Event directly
- Add lineHeight, letterSpacing, fontWeight, paragraphSpacing,
paragraphIndent to NumberBindingPath
- Wire lineHeight and letterSpacing inputs in TypographySection
to VariableScrubInput with variable binding support
- Reuse useInlineRename composable for collection and mode renaming
- Accept Event in useInlineRename.commit to eliminate template casts
- Remove HTMLInputElement casts from PagesPanel and LayerTree blur handlers
- Remove hand-rolled rename state from dialog composable
Core:
- Add addMode, removeMode, renameMode, setDefaultMode to SceneGraph
- Add editor actions with full undo: addMode, removeMode, renameMode,
setDefaultMode, duplicateMode, setActiveMode
Vue SDK:
- Wire all mode and collection actions through SDK helpers
- Add mode rename state to dialog composable
- Remove HTMLInputElement casts from commit handlers
UI:
- Mode management lives in the table column headers (Figma-style):
double-click to rename, right-click for context menu (rename,
duplicate, set as default, delete), + button after last mode column
- Collection ⋯ dropdown menu with rename and delete
- Use shared menu UI styles throughout
- i18n for en, ru, zh-CN
- Configure oxfmt custom import groups for workspace, app, package, and test aliases
- Keep type imports grouped with their matching source category instead of one global tail group
- Expand the format script to cover formatter config, Vite files, and scripts
- Replace one-off class props with typed ui objects
- Group renderless slot actions and remove DOM ref callback plumbing
- Make local font access and typography font loading explicit capability objects
- Deduplicate plugin data and relaunch data during .fig parsing/export
- Unify shared plugin data into the pluginData storage path
- Refactor shadow rendering and harden CanvasKit font provider teardown
- Expand engine and renderer coverage
- ScrubInput: skip scrub drag when pointerdown target is inside a button
- Size fields: always show chevron icon instead of hover-swap to prevent layout jump
- Variable picker: add right padding when no chevron follows, none when chevron present
The outer ScrubInput container captured all pointerdown events and
started a scrub drag, preventing embedded button clicks (like the
variable picker diamond icon) from ever reaching their handlers.
Now checks if the click target is inside a <button> before starting
the scrub.