refactor(kiwi)!: drop the colorVariableBinding paint field

`fig.kiwi` never defined the field, so nothing Figma writes carries one
and nothing OpenPencil writes has since `colorVar` replaced it. What
remained were readers kept so that files written by earlier OpenPencil
builds still restored their bindings — a compatibility path the project
does not keep before 1.0.

The field, the `VariableBinding` type and both readers are gone.
Reopening one of those files leaves the paint's colour unbound; binding
it again records it the way Figma does.
This commit is contained in:
Danila Poyarkov 2026-10-01 23:47:51 +04:00 committed by GitHub
parent 8528a917c0
commit d1159a7d07
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 6 additions and 14 deletions

View file

@ -4,6 +4,7 @@
### Breaking changes
- `VariableBinding` and the `colorVariableBinding` paint field are gone from `@open-pencil/core`, `@open-pencil/core/kiwi`, and the Kiwi `Paint` type. `fig.kiwi` never defined the field, so only `.fig` files OpenPencil itself wrote before `colorVar` contain one; reopening such a file leaves the paint's colour unbound, and binding it again records it the way Figma does.
- `encodeNodeChangeWithVariables`, `encodePaintWithVariableBinding`, and `encodeVarint` are removed from `@open-pencil/core` and `@open-pencil/core/kiwi`. They spliced a colour-variable binding into encoded bytes because the field had no schema entry; exports now write `colorVar`, which `fig.kiwi` defines, so nothing needs them. `parseVariableId` is unchanged.
- The desktop app now requires macOS 13 or later; the web app supports Chrome 111, Edge 111, Firefox 128, and Safari 16.4 or later.
- `.fig` reading moved to one reader, so the previous importer's exports are gone. `importNodeChanges` (`@open-pencil/core` and `@open-pencil/core/kiwi`) and `importClipboardNodes` (`@open-pencil/fig/clipboard`) are replaced by `parseFigFile` and `parseFigmaClipboard`; `populateLazyFigImportRoots` and `populateAllLazyFigImportRoots` (`@open-pencil/core/kiwi`) are replaced by `populateFigPage` and `populateAllFigPages` on `@open-pencil/core/io/formats/fig`; `populateAndApplyOverrides` (`@open-pencil/fig/instance-overrides`) is replaced by `interpretInstance` with `materializeInstance`. `FIG_PACKAGE_STATUS` now reads `document-reader`, and `assertFigPackageReady()` is gone, because `@open-pencil/fig` reads an archive into a SceneGraph itself rather than directing callers to Core.

View file

@ -341,7 +341,6 @@ export {
type Color as KiwiColor,
type Paint as KiwiPaint,
type Effect as KiwiEffect,
type VariableBinding,
type ParentIndex,
type FigmaMessage,
MESSAGE_TYPES,

View file

@ -19,7 +19,6 @@ export {
type Color,
type Paint,
type Effect,
type VariableBinding,
type VariableAnyValue,
type VariableDataEntry,
type VariableConsumptionEntry,

View file

@ -185,7 +185,7 @@ function recordPaintBindingClaims(
if (!Array.isArray(paints)) return
let declared = false
for (const [index, paint] of paints.entries()) {
const alias = (paint as Paint).colorVar?.value?.alias ?? (paint as Paint).colorVariableBinding
const alias = (paint as Paint).colorVar?.value?.alias
if (!alias) continue
const field = `boundVariables/${scene}/${index}/color`
setInstanceOverride(

View file

@ -181,8 +181,8 @@ export function applyColorVariableBinding(
// An imported paint carries the binding it arrived with. Unbinding the field has to clear
// it, or the export hands Figma back a variable the document no longer references.
if (!variableId) {
if (!paint.colorVar && !paint.colorVariableBinding) return paint
const { colorVar: _unbound, colorVariableBinding: _legacy, ...unbound } = paint
if (!paint.colorVar) return paint
const { colorVar: _cleared, ...unbound } = paint
return unbound
}
return {

View file

@ -141,13 +141,11 @@ export function extractBoundVariables(nc: NodeChange): Record<string, string> {
}
}
nc.fillPaints?.forEach((paint, i) => {
const variableGuid =
paint.colorVariableBinding?.variableID ?? paint.colorVar?.value?.alias?.guid
const variableGuid = paint.colorVar?.value?.alias?.guid
if (variableGuid) bindings[`fills/${i}/color`] = guidToString(variableGuid)
})
nc.strokePaints?.forEach((paint, i) => {
const variableGuid =
paint.colorVariableBinding?.variableID ?? paint.colorVar?.value?.alias?.guid
const variableGuid = paint.colorVar?.value?.alias?.guid
if (variableGuid) bindings[`strokes/${i}/color`] = guidToString(variableGuid)
})
return bindings

View file

@ -105,10 +105,6 @@ export interface ParentIndex {
position: string
}
export interface VariableBinding {
variableID: GUID
}
export interface ImageSource {
hash: string | Uint8Array
name?: string
@ -150,7 +146,6 @@ export interface Paint {
density?: number
noiseSize?: Vector
customEffectId?: { guid?: GUID }
colorVariableBinding?: VariableBinding
colorVar?: {
value?: {
alias?: {