Skip to content

offsetX / offsetY do not work #59

@SamuelBrucksch

Description

@SamuelBrucksch

Library Version

1.1.2

React Native Version

0.79.x

React Version

19.x

Expo Version

53

Minimal Reproduction

Summary: offsetX/offsetY Not Working in Voltra

Issue

The Voltra documentation states that offsetX and offsetY style properties should provide relative positioning (fine-tune individual element positions after alignment). However, these properties have no effect when used.

Root Causes Found

1. StyleConverter doesn't read offsetX/offsetY

In node_modules/voltra/ios/ui/Style/StyleConverter.swift (lines 18-26), the position parsing only reads left and top:

// Position parsing (offsetX/offsetY -> CGPoint)
var position: CGPoint?
if let offsetX = JSStyleParser.number(js["left"]), let offsetY = JSStyleParser.number(js["top"]) {
  position = CGPoint(x: offsetX, y: offsetY)
} else if let offsetX = JSStyleParser.number(js["left"]) {
  position = CGPoint(x: offsetX, y: 0)
} else if let offsetY = JSStyleParser.number(js["left"]) {
  position = CGPoint(x: 0, y: offsetY)
}

The comment says "offsetX/offsetY" but the code reads js["left"] and js["top"] instead of js["offsetX"] and js["offsetY"].

2. Wrong SwiftUI modifier used

In node_modules/voltra/ios/ui/Style/CompositeStyle.swift (lines 21-22), the position is applied using SwiftUI's .position() modifier:

.voltraIfLet(layout.position) { content, position in
  content.position(x: position.x, y: position.y)
}

SwiftUI's .position(x:y:) is absolute positioning - it places the view's center at the specified coordinates within its parent's coordinate space.

For relative positioning as documented, it should use SwiftUI's .offset(x:y:) modifier instead, which moves the view relative to its natural position.

Evidence of Intent

The short name mappings in node_modules/voltra/ios/shared/ShortNames.swift (lines 103-104) show these were intended to work:

"ox": "offsetX",
"oy": "offsetY",

Required Fixes

  1. Change StyleConverter.swift to read js["offsetX"] and js["offsetY"] instead of (or in addition to) js["left"] and js["top"]
  2. Change CompositeStyle.swift to use .offset(x:y:) instead of .position(x:y:) for relative positioning
  3. Update TypeScript types in styles/types.d.ts to include offsetX and offsetY properties

Workaround

Currently, using marginTop: -10 can achieve a similar visual effect for relative offset.

Additional Information (Optional)

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions