Skip to content

Home › Utilities

Layout ​

Flux's layout helpers (Flux.padding, Flux.corner, Flux.stroke, Flux.list, Flux.grid, Flux.flex, Flux.gradient, Flux.aspectRatio, Flux.sizeConstraint, Flux.textSizeConstraint) are concise, strictly typed wrappers that return standard Roblox layout and modifier instances directly inside a children table:

luau
Flux.new "Frame" {
    Size = UDim2.fromOffset(300, 0),
    AutomaticSize = Enum.AutomaticSize.Y,

    Flux.padding(16),
    Flux.corner(12),
    Flux.list { gap = 8 },

    Flux.new "TextLabel" { Text = "First" },
    Flux.new "TextLabel" { Text = "Second" },
}

Three conventions apply across every helper:

  • Bare numbers are offset pixels. Flux.padding(8) and gap = 8 become UDim.new(0, 8). Pass a UDim explicitly when you want scale.
  • Friendly strings instead of Enums. direction = "x", align = "center", Flux.flex("fill") are strictly typed and accept raw EnumItems as well.
  • Any argument can be reactive. Pass a Signal, Computed, or function () -> T anywhere a static value is accepted.

padding ​

Flux.padding(value) returns a UIPadding. Accepts a single length for all sides, a { top, bottom, left, right, x, y } table, or a reactive source yielding a length or { top, bottom, left, right } struct:

luau
Flux.padding(8)                      -- all four sides (8 px)
Flux.padding { x = 16, y = 8 }       -- horizontal / vertical
Flux.padding { top = 8, left = 16 }  -- individual sides
Flux.padding(function()
    return 8 * Flux.Responsive.scale()
end)

corner ​

Flux.corner(radius?) returns a UICorner. Pass offset pixels, a UDim, or a per-corner table { topLeft, topRight, bottomLeft, bottomRight, top, bottom, left, right, radius }. Omit the argument for the engine default (8 px):

luau
Flux.corner()                        -- default 8 px rounding
Flux.corner(12)                      -- CornerRadius = UDim.new(0, 12)
Flux.corner(UDim.new(0.5, 0))        -- pill / circle
Flux.corner { top = 12, bottom = 0 } -- round only the top corners

stroke ​

Flux.stroke(config?) returns a UIStroke:

luau
Flux.stroke {
    thickness = 2,        -- px
    color = accentColor,  -- static or reactive Color3
    transparency = 0.25,
    mode = "border",      -- "contextual" (default) | "border"
    joins = "round",      -- "round" (default) | "bevel" | "miter"
    position = "inner",   -- "outer" (default) | "center" | "inner"
    offset = 0,           -- border offset in px or UDim
}

list ​

Flux.list(config?) returns a UIListLayout with SortOrder = LayoutOrder and flexbox-style align (cross-axis) and justify (main-axis) options:

luau
Flux.list {
    gap = 8,             -- spacing between items (px or UDim)
    direction = "x",     -- "x" (horizontal) | "y" (vertical, default)
    align = "center",    -- cross-axis alignment
    justify = "between", -- main-axis alignment/distribution
    wraps = true,
    lineAlign = "start", -- "automatic" | "start" | "center" | "end" | "stretch"
}

align and justify accept:

  • "start" | "center" | "end": align items along the axis.
  • "between" | "around" | "evenly": distribute free space (UIFlexAlignment).
  • "stretch" | "fill": stretch items to fill the axis.

When direction is reactive, align and justify automatically re-route to their new axes when direction flips. Use horizontalAlign and verticalAlign to pin a specific axis directly.

grid ​

Flux.grid(config?) returns a UIGridLayout. cell and gap accept a number (square offset px), Vector2 (offset px), or UDim2:

luau
Flux.grid {
    cell = Vector2.new(100, 100), -- CellSize
    gap = 8,                      -- CellPadding
    fill = "x",                   -- "x" (default) | "y"
    align = "center",             -- HorizontalAlignment ("start" | "center" | "end")
    justify = "center",           -- VerticalAlignment ("start" | "center" | "end")
    maxCells = 4,                 -- FillDirectionMaxCells
}

flex ​

Flux.flex(mode?) returns a UIFlexItem for children inside a UIListLayout. mode defaults to "fill" ("fill" | "grow" | "shrink" | "none"):

luau
Flux.new "Frame" {
    Flux.list { direction = "x", gap = 8 },

    Flux.new "TextLabel" { Text = "Fixed" },
    Flux.new "Frame" { Flux.flex() }, -- expands to fill remaining space
}

gradient ​

Flux.gradient(config?) returns a UIGradient. color and transparency accept a single value, an array of stops spread evenly from 0 to 1, or a ColorSequence / NumberSequence:

luau
Flux.gradient {
    color = { Color3.fromRGB(80, 140, 255), Color3.fromRGB(160, 80, 255) },
    transparency = { 0, 0.25 },
    rotation = 45,
}

Constraints ​

aspectRatio ​

Flux.aspectRatio(ratio, aspectType?, dominantAxis?) returns a UIAspectRatioConstraint:

luau
Flux.aspectRatio(16 / 9)
Flux.aspectRatio(1, "scale", "height") -- aspectType: "fit" | "scale", dominantAxis: "width" | "height"

sizeConstraint ​

Flux.sizeConstraint(config?) returns a UISizeConstraint. Set whole Vector2 bounds with min / max or single-axis bounds with minWidth, minHeight, maxWidth, and maxHeight:

luau
Flux.sizeConstraint {
    minWidth = 200,
    maxWidth = 600,
    maxHeight = 400,
}

textSizeConstraint ​

Flux.textSizeConstraint(config?) returns a UITextSizeConstraint bounding text size between min and max pixels:

luau
Flux.textSizeConstraint { min = 12, max = 28 }