diff --git a/runtime/src/main.zig b/runtime/src/main.zig index 9ef449b1..132a001a 100644 --- a/runtime/src/main.zig +++ b/runtime/src/main.zig @@ -973,7 +973,7 @@ fn buildNode(ui: *WidgetUi, model: *const Model, id: tree_mod.NodeId, is_root: b .style = .{ .background = retained.background, .foreground = retained.text_color, - .radius = if (retained.radius > 0) retained.radius else null, + .radius = if (retained.radius >= 0) retained.radius else null, .border = retained.border_color, .stroke_width = retained.border_width, .quiet_hover = true, @@ -2252,6 +2252,25 @@ test "painted row lowering preserves flex wrap on the inner layout node" { try std.testing.expect(built.root.children[0].layout.flex_wrap); } +test "painted boxes without a rounded utility project square corners, not the theme radius" { + var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena_state.deinit(); + var model: Model = .{}; + const unset = try model.tree.createNode(.stack); + try model.tree.setBackground(unset, native_sdk.canvas.Color.rgb8(20, 30, 40)); + const zero = try model.tree.createNode(.stack); + try model.tree.setBackground(zero, native_sdk.canvas.Color.rgb8(20, 30, 40)); + try model.tree.setNumberProp(zero, "radius", 0); + + var ui = WidgetUi.init(arena_state.allocator()); + const built_unset = try ui.finalize(buildNodeForTest(&ui, &model, unset, true)); + try std.testing.expectEqual(native_sdk.canvas.WidgetKind.panel, built_unset.root.kind); + try std.testing.expectEqual(@as(?f32, 0), built_unset.root.style.radius); + var zero_ui = WidgetUi.init(arena_state.allocator()); + const built_zero = try zero_ui.finalize(buildNodeForTest(&zero_ui, &model, zero, true)); + try std.testing.expectEqual(@as(?f32, 0), built_zero.root.style.radius); +} + test "panel lowers to a painted box around a column so children stack vertically" { var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); diff --git a/sdk/CONTRACT.md b/sdk/CONTRACT.md index 656540c6..c377d3b6 100644 --- a/sdk/CONTRACT.md +++ b/sdk/CONTRACT.md @@ -149,6 +149,7 @@ utility. | `gap-N`, `gap-[Npx]` | flex gap | | `rounded`, `rounded-{md,lg,xl,2xl,3xl,full}`, `rounded-[Npx]` | corner radius | | `rounded-{t,r,b,l,tl,tr,br,bl}[-{md,lg,xl,2xl,3xl,full}]`, arbitrary `[Npx]` | selected corner radii; later classes win per corner | +| no `rounded-*` utility, or `rounded-[0px]` | square corners; a painted box never inherits the native theme radius | | `border`, `border-N`, `border-[Npx]` | border width in pixels; width-only utilities default to `#E5E7EBFF` (gray-200) | | `border-[#rgb/#rrggbb/#rrggbbaa]`, optional `/NN` alpha suffix | border color; color alone does not create width | | `bg-`, `text-`, `border-` + Tailwind v4 named color (`red-50` through `taupe-950`, `white`, `black`, `transparent`), optional `/NN` | official v4.3.3 palette converted from OKLCH to the runtime's sRGB8 wire format; alpha multiplies the named color's alpha |