fix(kiwi): preserve input badge avatar swaps

This commit is contained in:
Danila Poyarkov 2026-04-25 22:08:45 +03:00
parent 6c6671bb7a
commit a42da8ab16
4 changed files with 44 additions and 15 deletions

View file

@ -650,7 +650,7 @@ export function renderText(r: SkiaRenderer, canvas: Canvas, node: SceneNode): vo
}
if (r.fontsLoaded && r.fontProvider) {
const paragraph = r.buildParagraph(node, r.fillPaint.getColor())
const paragraphY = node.fontSize < 13 ? 0 : -1
const paragraphY = -1
canvas.drawParagraph(paragraph, 0, paragraphY)
paragraph.delete()
} else if (r.textFont) {

View file

@ -1,5 +1,5 @@
import { copyGeometryPaths } from '../../scene-graph/copy'
import { resolveGeometryPaths } from '../convert'
import { convertLetterSpacing, convertLineHeight, resolveGeometryPaths } from '../convert'
import { resolveOverrideTarget } from './resolve'
import { buildClonesMap } from './sync'
@ -105,13 +105,23 @@ function resolveSizeOnlyPosition(
return withinParent ? { x: source.x, y: source.y } : { x: 0, y: 0 }
}
function buildDsdTextUpdates(d: DerivedSymbolOverride): Partial<SceneNode> {
const updates: Partial<SceneNode> = {}
if (d.fontSize !== undefined) updates.fontSize = d.fontSize
if (d.lineHeight !== undefined) updates.lineHeight = convertLineHeight(d.lineHeight, d.fontSize)
if (d.letterSpacing !== undefined) {
updates.letterSpacing = convertLetterSpacing(d.letterSpacing, d.fontSize)
}
return updates
}
function buildDsdLayoutUpdates(
ctx: OverrideContext,
visibleSiblingCount: Map<string, number>,
d: DerivedSymbolOverride,
target: SceneNode
): { updates: Partial<SceneNode>; hasSize: boolean } {
const updates: Partial<SceneNode> = {}
const updates: Partial<SceneNode> = buildDsdTextUpdates(d)
const figmaDerivedLayout: NonNullable<SceneNode['figmaDerivedLayout']> = {}
if (d.size) {

View file

@ -48,23 +48,32 @@ function findPropRefs(
* means "reset to the component's initialValue default". This is distinct
* from `{boolValue: false}` which is an explicit false.
*/
function resolveAssignmentValue(
ctx: OverrideContext,
assignment: ComponentPropAssignment,
key: string,
resolveDefaults: boolean
): ComponentPropValue {
if (!isEmptyPropValue(assignment.value)) return assignment.value
const variableValue = assignment.varValue?.value
if (variableValue?.symbolIdValue?.guid) return { guidValue: variableValue.symbolIdValue.guid }
if (variableValue?.boolValue !== undefined) return { boolValue: variableValue.boolValue }
if (variableValue?.textValue !== undefined) return { textValue: variableValue.textValue }
return resolveDefaults ? (ctx.propDefaults.get(key) ?? assignment.value) : assignment.value
}
function assignmentsToValueMap(
ctx: OverrideContext,
assignments: ComponentPropAssignment[],
resolveDefaults = false
): Map<string, ComponentPropValue> {
const valueByDef = new Map<string, ComponentPropValue>()
for (const a of assignments) {
if (!a.defID) continue
const key = guidToString(a.defID)
if (resolveDefaults && isEmptyPropValue(a.value)) {
const def = ctx.propDefaults.get(key)
if (def) {
valueByDef.set(key, def)
continue
}
}
valueByDef.set(key, a.value)
for (const assignment of assignments) {
if (!assignment.defID) continue
const key = guidToString(assignment.defID)
valueByDef.set(key, resolveAssignmentValue(ctx, assignment, key, resolveDefaults))
}
return valueByDef
}

View file

@ -1,6 +1,6 @@
import type { SceneGraph } from '../../scene-graph'
import type { Matrix, Vector } from '../../types'
import type { GUID } from '../codec'
import type { GUID, NodeChange } from '../codec'
export interface SymbolOverride {
guidPath?: { guids?: GUID[] }
@ -28,12 +28,22 @@ export type ComponentPropValue = {
export interface ComponentPropAssignment {
defID?: GUID
value: ComponentPropValue
varValue?: {
value?: {
boolValue?: boolean
textValue?: string
symbolIdValue?: { guid?: GUID }
}
}
}
export interface DerivedSymbolOverride {
guidPath?: { guids?: GUID[] }
size?: Vector
transform?: Matrix
fontSize?: number
lineHeight?: NodeChange['lineHeight']
letterSpacing?: NodeChange['letterSpacing']
fillGeometry?: Array<{ windingRule?: string; commandsBlob?: number }>
strokeGeometry?: Array<{ windingRule?: string; commandsBlob?: number }>
}