update expectations, add warnings

This commit is contained in:
Michael Freno
2025-12-14 12:06:57 -05:00
parent 8613859408
commit 190c1b27bd
3 changed files with 87 additions and 4 deletions

View File

@@ -1310,6 +1310,20 @@ function Element.new(props)
end end
-- Handle positioning properties for elements without parent -- Handle positioning properties for elements without parent
-- Warn if CSS positioning properties are used without absolute positioning
if (props.top or props.bottom or props.left or props.right) and not self._explicitlyAbsolute then
local properties = {}
if props.top then table.insert(properties, "top") end
if props.bottom then table.insert(properties, "bottom") end
if props.left then table.insert(properties, "left") end
if props.right then table.insert(properties, "right") end
Element._ErrorHandler:warn("Element", "LAY_011", {
element = self.id or "unnamed",
positioning = self._originalPositioning or "relative",
properties = table.concat(properties, ", "),
})
end
-- Handle top positioning with units -- Handle top positioning with units
if props.top then if props.top then
local isCalc = Element._Calc and Element._Calc.isCalc(props.top) local isCalc = Element._Calc and Element._Calc.isCalc(props.top)
@@ -1484,6 +1498,18 @@ function Element.new(props)
local baseX = self.parent.x + self.parent.padding.left local baseX = self.parent.x + self.parent.padding.left
local baseY = self.parent.y + self.parent.padding.top local baseY = self.parent.y + self.parent.padding.top
-- Warn if explicit x/y is set on a child that will be positioned by flex layout
-- This position will be overridden unless the child has positioning="absolute"
local parentWillUseFlex = self.parent.positioning ~= "grid"
local childIsRelative = self.positioning ~= "absolute" or not self._explicitlyAbsolute
if parentWillUseFlex and childIsRelative and (props.x or props.y) then
Element._ErrorHandler:warn("Element", "LAY_008", {
element = self.id or "unnamed",
parent = self.parent.id or "unnamed",
properties = (props.x and props.y) and "x, y" or (props.x and "x" or "y"),
})
end
if props.x then if props.x then
local isCalc = Element._Calc and Element._Calc.isCalc(props.x) local isCalc = Element._Calc and Element._Calc.isCalc(props.x)
if type(props.x) == "string" or isCalc then if type(props.x) == "string" or isCalc then
@@ -1554,6 +1580,20 @@ function Element.new(props)
end end
-- Handle positioning properties BEFORE adding to parent (so they're available during layout) -- Handle positioning properties BEFORE adding to parent (so they're available during layout)
-- Warn if CSS positioning properties are used without absolute positioning
if (props.top or props.bottom or props.left or props.right) and not self._explicitlyAbsolute then
local properties = {}
if props.top then table.insert(properties, "top") end
if props.bottom then table.insert(properties, "bottom") end
if props.left then table.insert(properties, "left") end
if props.right then table.insert(properties, "right") end
Element._ErrorHandler:warn("Element", "LAY_011", {
element = self.id or "unnamed",
positioning = self._originalPositioning or "relative",
properties = table.concat(properties, ", "),
})
end
-- Handle top positioning with units -- Handle top positioning with units
if props.top then if props.top then
local isCalc = Element._Calc and Element._Calc.isCalc(props.top) local isCalc = Element._Calc and Element._Calc.isCalc(props.top)
@@ -1662,6 +1702,15 @@ function Element.new(props)
Element._utils.validateEnum(props.justifySelf, Element._utils.enums.JustifySelf, "justifySelf") Element._utils.validateEnum(props.justifySelf, Element._utils.enums.JustifySelf, "justifySelf")
end end
-- Warn if grid properties are set with flex positioning
if props.gridRows or props.gridColumns or props.gridTemplateRows or props.gridTemplateColumns then
Element._ErrorHandler:warn("Element", "LAY_010", {
element = self.id or "unnamed",
positioning = "flex",
properties = "gridRows/gridColumns/gridTemplate*",
})
end
self.flexDirection = props.flexDirection or Element._utils.enums.FlexDirection.HORIZONTAL self.flexDirection = props.flexDirection or Element._utils.enums.FlexDirection.HORIZONTAL
self.flexWrap = props.flexWrap or Element._utils.enums.FlexWrap.NOWRAP self.flexWrap = props.flexWrap or Element._utils.enums.FlexWrap.NOWRAP
self.justifyContent = props.justifyContent or Element._utils.enums.JustifyContent.FLEX_START self.justifyContent = props.justifyContent or Element._utils.enums.JustifyContent.FLEX_START
@@ -1672,6 +1721,15 @@ function Element.new(props)
-- Grid container properties -- Grid container properties
if self.positioning == Element._utils.enums.Positioning.GRID then if self.positioning == Element._utils.enums.Positioning.GRID then
-- Warn if flex properties are set with grid positioning
if props.flexDirection or props.flexWrap or props.justifyContent then
Element._ErrorHandler:warn("Element", "LAY_009", {
element = self.id or "unnamed",
positioning = "grid",
properties = "flexDirection/flexWrap/justifyContent",
})
end
self.gridRows = props.gridRows or 1 self.gridRows = props.gridRows or 1
self.gridColumns = props.gridColumns or 1 self.gridColumns = props.gridColumns or 1
self.alignItems = props.alignItems or Element._utils.enums.AlignItems.STRETCH self.alignItems = props.alignItems or Element._utils.enums.AlignItems.STRETCH

View File

@@ -105,6 +105,30 @@ local ErrorCodes = {
description = "Grid layout error", description = "Grid layout error",
suggestion = "Check grid template columns/rows and item placement", suggestion = "Check grid template columns/rows and item placement",
}, },
LAY_008 = {
code = "FLEXLOVE_LAY_008",
category = "LAY",
description = "Explicit position will be ignored by flex layout",
suggestion = "Remove x/y properties (flex layout controls position), OR set positioning='absolute' with left/top/right/bottom properties. Additionally, you can use margin/padding for positional offsets in flex layouts.",
},
LAY_009 = {
code = "FLEXLOVE_LAY_009",
category = "LAY",
description = "Flex layout properties ignored with grid positioning",
suggestion = "Remove flexDirection/justifyContent/alignItems properties, or change positioning to 'flex' or 'relative'",
},
LAY_010 = {
code = "FLEXLOVE_LAY_010",
category = "LAY",
description = "Grid layout properties ignored without grid positioning",
suggestion = "Set positioning='grid' to use grid layout properties, or remove grid properties",
},
LAY_011 = {
code = "FLEXLOVE_LAY_011",
category = "LAY",
description = "CSS positioning properties ignored",
suggestion = "Set positioning='absolute' to use top/bottom/left/right properties",
},
-- Rendering Errors (REN_001 - REN_099) -- Rendering Errors (REN_001 - REN_099)
REN_001 = { REN_001 = {

View File

@@ -490,10 +490,11 @@ function TestElementPositioning:test_nested_element_positions()
luaunit.assertNotNil(parent) luaunit.assertNotNil(parent)
luaunit.assertNotNil(child) luaunit.assertNotNil(child)
-- Child positions are absolute in FlexLove, not relative to parent -- Parent uses default flex layout (positioning="relative" is default)
-- So child.x = parent.x + relative_x = 100 + 20 = 120 -- Flex layout controls child position, ignoring explicit x/y offsets on relative children
luaunit.assertEquals(child.x, 120) -- Child is positioned at parent's content area (parent.x + padding.left)
luaunit.assertEquals(child.y, 130) luaunit.assertEquals(child.x, 100)
luaunit.assertEquals(child.y, 100)
end end
function TestElementPositioning:test_absolute_positioning_with_top_left() function TestElementPositioning:test_absolute_positioning_with_top_left()