Commit graph

819 commits

Author SHA1 Message Date
Danila Poyarkov 2fb6792aa9 fix(layout,typography): restore vertical gaps between control groups
- Layout: gap between the Resizing segmented control and the W/H size fields
- Typography: breathing room between OpenType feature toggle rows and above
  the Text formatting toolbar
2026-07-20 20:29:45 +03:00
Danila Poyarkov 142dbb9647 fix(typography): clear property grouping via spacing ratio
Within-group label→field stays 4px; between-group margin rises from 6px to
12px so each property reads as a distinct unit instead of merging into a
continuous column. Matches Figma's grouping structure without removing the
labels.
2026-07-20 18:30:50 +03:00
Danila Poyarkov cff46fbc50 fix(app): restore release validation coverage
- Keep the development MCP bridge alive until Vite shuts down
- Ignore empty host-font responses and cover current browser font policy
- Update interaction selectors, menu labels, resize accounting, and reviewed UI snapshots
2026-07-20 16:26:07 +03:00
Danila Poyarkov 49828cdac1 fix(ui): distinct field background at idle, not just on hover
Fields previously used a transparent idle fill (a misread of Figma, whose
inputs actually keep a visible fill at idle). Editable controls now read as
controls: idle fill #383838 (dark) / #f0f1f3 (light), one step up from the
panel, with a slightly stronger hover and the accent focus border.
2026-07-20 16:09:04 +03:00
Danila Poyarkov 25436249e4 fix(layout): consistent section add buttons and header descender clipping
- Move the Auto layout add/remove button from the section body into the
  section header actions, matching the Layout grid and every other section
- Drop leading-none on section titles so descenders ('g' in 'Layout grid')
  are not clipped by the 32px header band
2026-07-20 15:33:11 +03:00
Danila Poyarkov efa784a039 feat(layout): layout-grid editor section
Add a Layout grid section for frames/components with pattern (columns/rows/
grid), count, gutter/section size, and margin, plus visibility and remove
actions. The canvas already rendered layout grids from imported files; this
wires creation and editing through the standard panel list pattern with
undo support and icon+tooltip pattern options.
2026-07-20 15:09:28 +03:00
Danila Poyarkov 14d4a17a33 feat(layout): text auto-resize control in Layout section
Surface the engine's textAutoResize as a Resizing segmented control for
text nodes, mapping Figma's three modes: Auto width (WIDTH_AND_HEIGHT),
Auto height/wrap (HEIGHT), Fixed size (NONE). Icon + tooltip options match
the panel's segmented-control language. The engine already reflows text on
content changes; this wires the control to it with undo support.
2026-07-20 14:21:12 +03:00
Danila Poyarkov 965f206991 fix(a11y): add accessible names to icon-only buttons
Layer lock/visibility actions, toolbar tools, tool flyout triggers, and
the app UI toggle rendered icon-only buttons with no accessible name, so
screen readers and role-based selectors could not identify them. Each now
exposes an aria-label from the existing i18n/tool labels.
2026-07-18 10:37:26 +03:00
Danila Poyarkov f365f30f06 fix(ui): chrome polish — menubar contrast, menu/tab/tooltip type scale
- Menubar items render in surface text instead of muted (looked disabled),
  at the 11px UI scale
- Menu items, document tabs, and tooltips normalized to 11px to match the
  panel type scale; menu items use the 5px control radius
- Share button uses the control radius and 11px; presence popover drops its
  border for the floating shadow
2026-07-18 10:16:49 +03:00
Danila Poyarkov 3bfeef7c97 fix(ui): segmented control track no longer reads as a filled bar
The segmented-control root used the field recipe, so text-alignment and
vertical-alignment toggles rendered as one heavy dark bar. The root is now
transparent at idle with a hover wash, and only the active segment carries
the subtle fill — matching Figma's segmented-toggle appearance.
2026-07-18 09:56:47 +03:00
Danila Poyarkov 5d9645fead feat(ui): section header bands and dropdown polish
- Section headers become full 32px bands (title + trailing actions
  vertically centered) instead of an 11px line crammed against fields,
  giving each section a clear structural band like Figma
- Select dropdowns adopt the floating-surface elevation (12px radius, no
  border, deep shadow), 24px flush items, and scroll up/down buttons for
  long lists (blend modes)
- Font-settings gear trigger drops its hardcoded dark bg+border for the
  ghost icon-button recipe
- Segmented-control active state uses neutral hover fill instead of the
  blue-grey selection color
2026-07-18 09:41:32 +03:00
Danila Poyarkov f1af81962c feat(ui): shadow-elevation for floating surfaces and blend-mode fit
- Menus, popovers, dialogs, tooltips, and the toolbar drop the hard 1px
  border for the established deep floating shadow (0 8px 30px /40%) and a
  unified rounded-xl, so overlays read as floating rather than outlined
- Appearance section pairs Blend mode with Opacity on a 7fr/5fr grid so
  'Pass through' no longer truncates at the denser 24px control height
- Normalize AppSelect text to 11px to match the panel type scale
2026-07-18 08:51:28 +03:00
Danila Poyarkov d8952eb515 refactor(ui): replace sizing design tokens with plain utilities
Drop the spacing/radius sizing tokens (--spacing-control, --spacing-panel-*,
--radius-panel) and their generated classes (h-control, px-panel-x, gap-panel,
rounded-panel, etc.) in favor of direct Tailwind utilities (h-6, px-3, gap-1.5,
rounded). Color tokens are kept since they drive dark/light theming.

Behavior-preserving: 24px controls, 5px radius, identical computed layout.
2026-07-18 08:35:32 +03:00
Danila Poyarkov 708152e33f fix(canvas): rulers follow the active theme
Rulers stayed dark in light theme because the canvas ruler theme was only
pushed to the editor store at theme-apply time, before any editor existed,
and the renderer fell back to a hardcoded dark color.

- Push the ruler theme to the active editor whenever it registers or the
  theme changes, via a reactive active-store ref (keeps the no-browser-
  globals-in-core boundary intact)
- Refresh the light ruler palette for proper contrast on the light canvas
2026-07-18 08:12:58 +03:00
Danila Poyarkov 64b7a106db feat(ui): accent underline indicator for properties tabs
- Selected Design/Code/AI tab now shows an accent underline instead of
  only a weight/color change, giving a clear active affordance
- Normalize tab text to 11px to match the panel type scale
2026-07-18 07:45:15 +03:00
Danila Poyarkov 55965ac556 feat(ui): confident selection and consistent panel headers
- Layer/page rows use the unified accent selection, 5px radius, airier
  1.5 padding, and 11px labels
- Panel headers (Layers, Assets, Pages) drop the uppercase tracked style
  for a single 11px/semibold/surface dialect matching section headers
- Segmented control md size uses 11px to match the rest of the panel
2026-07-18 07:40:06 +03:00
Danila Poyarkov 828a1a7ae4 refactor(ui): single field recipe and 11px panel typography
- input tone=default now uses panelFieldBase so every input shares the
  transparent-idle / hover-fill / accent-focus recipe (fixes divergent
  black inputs with stuck accent border, e.g. AI provider setup)
- Normalize field/select/number-field text to 11px; paint-field uses the
  shared transparent field recipe instead of bg-input + undefined shadow
- NumberField root sets 11px so the container no longer inherits body 13px
2026-07-18 07:37:28 +03:00
Danila Poyarkov a170a780da feat(ui): unify accent tokens and transparent-idle field colors
- Unify all blues to a single accent: panel-focus and panel-selected now
  derive from the brand accent instead of one-off #4c8dff / #0d64d8
- Make panel-field transparent at idle (hover/focus fill) for a quieter,
  Figma-grade properties panel; panel-field-hover becomes the intent fill
- Denser controls: --spacing-control 26px -> 24px, radius-panel 4px -> 5px
- Neutralize panel-selected-muted (de-blued) for inactive-pane selection
- Mirror the same structure in the light theme
2026-07-18 07:24:50 +03:00
Danila Poyarkov 1f22aa3207 fix(app): align layer rows and icon menus
- Let virtualized Layer rows fill the panel width\n- Remove extra root indentation while preserving hierarchy depth\n- Keep icon menu labels beside their icons\n- Refresh reviewed panel snapshots
2026-07-18 05:56:36 +03:00
Danila Poyarkov 33d6a1efd1 fix(app): align property item subcontrols
- Keep Fill and Effects settings inside their shared content rails\n- Use panel spacing tokens instead of ad-hoc offsets\n- Preserve selection when Escape dismisses overlays\n- Label the Font settings trigger for assistive technology
2026-07-18 05:44:52 +03:00
Danila Poyarkov 429a7e5ae2 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
2026-07-18 05:25:40 +03:00
Danila Poyarkov e0d8efb2a4
Merge pull request #411 from open-pencil/figma-paste-images
fix(clipboard): fetch pasted Figma images on desktop
2026-07-18 05:04:49 +03:00
Sadko 665e28cbaa
Merge branch 'master' into master 2026-07-17 22:03:09 -04:00
Danila Poyarkov c2812ba136 fix(tauri): preserve request and abort semantics
- Serialize bodies from the normalized Request, including Request inputs\n- Consume late transport failures after an already-aborted signal\n- Handle pre-aborted clipboard test requests
2026-07-18 05:02:51 +03:00
Danila Poyarkov d7a27a894c fix(app): preserve compact paint field sizing
- Keep embedded number fields from crowding color values\n- Cover paint-row geometry in property-panel E2E tests\n- Refresh the reviewed typography panel snapshot for visible variable actions
2026-07-18 04:57:48 +03:00
Danila Poyarkov 45d8cd51f5 Merge branch 'master' into review-pr-410-current 2026-07-18 04:40:38 +03:00
Danila Poyarkov a3127e716b refactor(tauri): share HTTP abort handling
- Make the desktop HTTP adapter honor standard AbortSignal cancellation
- Use AbortSignal.timeout directly for Figma batch and image requests
- Cover resolved, pre-aborted, and in-flight abort behavior
2026-07-18 04:40:15 +03:00
Danila Poyarkov 585b80d023 Merge remote-tracking branch 'origin/master' into review-pr-411-current 2026-07-18 04:36:06 +03:00
Danila Poyarkov fc5cc2d4b8 fix(app): align variable-enabled panel fields
- Keep Apply variable actions visible with restrained hover treatment
- Preserve the shared 26px NumberField height in column layouts
- Anchor variable pickers to their trigger instead of the zero-size contents wrapper
- Cover control dimensions, action visibility, and popover placement end to end
2026-07-18 04:35:52 +03:00
Danila Poyarkov 798a3c2b2c fix(editor): harden opacity shortcuts
- Match numeric keypad input by generated key so NumLock-off navigation remains available
- Coalesce buffered opacity updates into one undo interaction
- Add end-to-end coverage for digit composition, modifiers, and undo
2026-07-18 04:22:38 +03:00
Danila Poyarkov b08e199c85 fix(clipboard): finalize paste before image fetch
- Complete placement and undo registration before awaiting image hydration
- Bound Figma image requests with timeouts and use shared Tauri detection
- Localize missing-image notifications and cover stalled requests
2026-07-18 04:22:38 +03:00
Danila Poyarkov c8bbdbbb46 Merge branch 'master' into review-pr-411-current 2026-07-18 04:00:57 +03:00
Sadko d78f4bb64e
Merge branch 'open-pencil:master' into master 2026-07-17 17:28:32 -04:00
Danila Poyarkov 0abbb839cb refactor(app): finish visual state theming
- Theme Variables, collaboration, presence, and provider status states\n- Expose semantic default, resizing, following, connection, and tone attributes\n- Remove the final dynamic-state allowlist and document enforced Vue template rules
2026-07-18 00:23:38 +03:00
Danila Poyarkov 69e39cc59e refactor(app): theme toolbar editing states
- Share typed toolbar slots across desktop, mobile, flyout, and action controls\n- Theme alignment cells, fill tabs, and gradient stop states\n- Expose semantic active and disabled state and retire migrated allowlist entries
2026-07-18 00:07:49 +03:00
Sadko 0809f26c8e
Merge branch 'master' into master 2026-07-17 16:56:39 -04:00
Danila Poyarkov 3e750383c0 test(app): add panel UI guardrails
- Lock representative property and Layer Tree states with visual snapshots\n- Cover keyboard tab order and keyboard activation for panel controls\n- Reject template-time UI hooks and raw SVG app icons through parsed Vue ASTs
2026-07-17 23:53:06 +03:00
Sadko 1a82f84ba5
Merge branch 'open-pencil:master' into master 2026-07-17 15:44:35 -04:00
Danila Poyarkov 0bf74a418f feat(text): deepen typography controls
- Add case, justification, vertical alignment, truncation, max-lines, and OpenType controls

- Apply visual text case and measured vertical offsets in CanvasKit rendering

- Preserve nullable preview values, shared text styles, font demand, and .fig metadata

- Add panel, engine, and canvas visual coverage
2026-07-17 22:40:52 +03:00
Sadko 80b103f408
Merge branch 'master' into master 2026-07-17 15:11:00 -04:00
Danila Poyarkov 0bd5afe784 feat(editor): add paint blend mode controls
- Expose localized blend mode selects for fills and expanded effects

- Reuse PropertyList batching for shared-style detachment and mixed-selection undo

- Share Appearance, Fill, and Effects blend mode options

- Add focused E2E and panel visual coverage
2026-07-17 22:10:27 +03:00
Sadko 1151383de0
Merge branch 'open-pencil:master' into master 2026-07-17 15:09:35 -04:00
sadkodev d58cf0b9e9
test(keyboard): add unit tests for opacity buffer logic
Extract opacityFromBuffer as a pure function in core/editor and test
it directly. Covers Figma semantics: 0→100%, 5→50%, 28→28%, 00→0%,
100→100%, clamp at 100%, NaN guard. Refactor the keyboard handler to
reuse the shared function instead of inlining the buffer math.
2026-07-17 15:00:10 -04:00
Danila Poyarkov 23645d5a2d feat(editor): add component property controls
- Model typed component definitions, references, assignments, and preferred swap values

- Add SDK-owned variant, text, boolean, and nested instance-swap controls with mixed-selection undo

- Preserve assignments across variant changes and component synchronization

- Round-trip component property metadata through .fig import and export
2026-07-17 21:59:49 +03:00
sadkodev 1ca1cbc896
refactor(keyboard): deduplicate opacity binding handler
Collapse the duplicated Digit/Numpad opacity bindings into a single
OPACITY_CODES array with one shared run handler. Digit value is
extracted via code.slice(-1), which works for both Digit0-9 and
Numpad0-9.
2026-07-17 14:49:00 -04:00
sadkodev b5de980632
fix(keyboard): treat single 0 as 100% opacity
Figma treats pressing 0 alone as 100% opacity, not 0%. The single-digit
decena rule (n * 10) would produce 0 * 10 = 0% for 0, which is wrong.
Add an explicit check: buffer '0' applies 100%, all other single
digits apply n * 10, and multi-digit buffers apply the literal value.
2026-07-17 14:41:36 -04:00
sadkodev 9d88c4f045
fix(keyboard): apply opacity immediately on each keypress
Replace the 400ms apply-timeout with immediate application on every
digit press. A separate 800ms reset timer clears the buffer between
sequences so digits typed in quick succession still compose (28→28%,
00→0%, 100→100%) but single digits no longer have a perceptible delay.
2026-07-17 14:26:45 -04:00
sadkodev 0300cb521b
refactor(keyboard): address review feedback on opacity shortcuts
- Move setOpacity to core editor action (packages/core/src/editor/nodes.ts)
  so it is testable directly without duplicating logic in tests
- Replace external window listener with tinykeys bindings in
  registerKeyboardShortcuts, reusing shared input/focus guards
- Add 20 bindings for Digit0-9 and Numpad0-9 with modifier guards
- Implement Figma-style multi-digit buffer: 2→20%, 28→28%, 00→0%, 100→100%
  with 400ms timeout and auto-apply at 3 digits
- Simplify selection.setOpacity command to delegate to editor.setOpacity
- Rewrite unit tests to call editor.setOpacity directly
- Add ofetch to dependencies (was imported but missing from package.json)
- Update CHANGELOG
2026-07-17 14:09:46 -04:00
Sadko bec41bd0d4
Merge branch 'open-pencil:master' into master 2026-07-17 14:08:31 -04:00
Danila Poyarkov 51fccb74d3 refactor(app): theme editor navigation states
- Move Pages and TabBar state styling into typed Tailwind Variants themes

- Reuse the segmented control contract for Layers and Assets navigation

- Add light and dark Storybook state coverage and remove migrated architecture allowlist entries
2026-07-17 21:03:35 +03:00