Skip to main content

Utility

Aether provides different utility functions to help with usage of the library.

getPlacementPosition

This is useful for when you have a value with a Placement type and need to extract the side and/or the alignment.

local Aether = require(path.to.aether)

local side, alignment = Aether.getPlacementPosition("top-start")
print(side, alignment) -- "top" "start"

local side, alignment = Aether.getPlacementPosition("bottom")
print(side, alignment) -- "bottom" "nil"

getOppositePlacement

Returns the opposite side part of a given placement.

The opposite sides are as follows:

  • "top" - "bottom"
  • "bottom" - "top"
  • "left" - ""right"
  • "right" - "left"
local Aether = require(path.to.aether)

local placement = Aether.getOppositePlacement("top-start")
print(placement) -- "bottom-start"

getOppositeAlignmentPlacement

Returns the opposite alignment part of a given placement.

The opposite alignments are as follows:

  • "start" - "end"
  • "end" - "start"
local Aether = require(path.to.aether)

local placement = Aether.getOppositeAlignmentPlacement("top-start")
print(placement) -- "top-end"

getExpandedPlacements

Provides all possible alternative values for a given placement, excluding the initial placement itself.

local Aether = require(path.to.aether)

local placements = Aether.getExpandedPlacements("top-start")
print(placements) -- "{ "top-end", "bottom-start", "bottom-end" }"

getOppositeAxisPlacements

Returns all of the possible placements from the opposite axis of a given placement.

The following parameters can be passed:

placement

The placement to extract from.

flipAlignment

When the given placement has an alignment and this is set to true, the returned placements will include the opposite alignment placements as well.

direction

The alignment to start from. This affects the order of placements.

For example, when the side of the placement is set to top or bottom, and the direction is set to start, the opposite side order becomes [left, right]. Conversely, a direction of end or none results in [right, left].

note

When rtl is set to true, the resulting value is flipped to the opposite end of its usual direction.

rtl

When set to true, right-to-left calculations will be used instead.

Example

local Aether = require(path.to.aether)

local placements = Aether.getOppositeAxisPlacements("top-start", true, "start")

-- Since flipAlignment is `true`, we have an extra two values that are both opposite alignments.
-- The direction is also "start", so the order is [left, right].

print(placements) -- { "left-start", "bottom-start", "left-end", "bottom-end" }

getAlignmentSides

Returns the two possible sides of a given placement, listed in order as the main side followed by the cross (opposite) side.

The following parameters can be passed:

placement

The placement to extract from.

rects

The element rects to use. Typically, this will be the rects value provided by middleware.

rtl

Default value: false

When set to true, right-to-left calculations will be used instead.

Example

local Aether = require(path.to.aether)

-- Lets say "rects" is derived from `state.rects` via middleware.
local main, cross = Aether.getAlignmentSides("top-start", rects)

print(main, cross) -- - "bottom", "top";
note

The length (dimension) of the elements provided via rects is considered during the process, based on the axis variant of the given placement's alignment.

If the reference element's length exceeds that of the target element, the main side is flipped to its opposite direction, making the cross side its counterpart.

getElementBoundingRect

Returns the BoundingRect of a given element, with extra calculations to get the precise area.

The following parameters can be passed:

element

The element to calculate the rect for. This can be a virtual element.

includeScale

When set to true, the ancestor UIScale's will be accounted for in the calculation. I.e., values will be scaled down based on the final factor.

offsetParent

The element to calculate relative to. When includeScale is set to true, the ancestor UIScale's of this element will be considered instead of the given element. Note that offsetParent is typically just the Parent property of the element, and it also doesn't have to necessarily be accessed off of element itself.

cache

The lifecycle cache

getElementRects

Takes in the elements and returns the element Rect objects.

The following parameters can be passed:

reference

The x and y values of a reference Rect should be its coordinates relative to the floating element’s Parent element if required rather than the screen.

target

Both x and y are not relevant initially, so you can set these both of these to 0.

cache

The lifecycle cache

getClippingRect

Returns the Rect (relative to the screen) whose outside bounds will clip the given element. For instance, the screen itself.

The following parameters can be passed:

element

The GuiObject to calculate the clipping rect for.

boundary

The boundary to use.

rootBoundary

The root boundary to use.

cache

The lifecycle cache

getScale

Returns the scale of the given element.

The scale of an element is the factor of each ancestor UIScale that affects it.

element

The element to check

cache

The lifecycle cache

getOffsetParent

Returns the "offset" parent of the given element.

The "offset" parent is the first valid parent of the given element. Most of the time,this is just the Parent value, but there are cases where a Folder instance may be used. Because of that, this is useful for being safe.

element

The element to get the parent from.

getLayerElement

Returns the contaning LayerCollector instance of the given element, if one exists.

element

The element to retrieve from.

convertOffsetParentRectToRelativeRect

Converts the given rect into a rect that is relative to that of the given offset parent.

rect

The rect to go off of.

offsetParent

The offset parent element.

cache

The lifecycle cache

isElement

Determines if the passed value is a GuiObject.

local Aether = require(path.to.aether)

local reference = Instance.new("Frame")

print(Aether.isElement(reference)) -- true

unwrapElement

Used for unwrapping an element into its GuiObject form, if viable. For example, extracting the contextElement from a virtual element when present.

If the element is already a GuiObject then that will be returned.

local Aether = require(path.to.aether)

local reference = Instance.new("Frame")

print(Aether.unwrapElement(reference)) -- Frame

local contextElement = Instance.new("TextLabel")
local reference: Aether.VirtualElement = {
getBoundingRect = function()
return ...
end,

contextElement = contextElement,
}

print(Aether.unwrapElement(reference)) -- TextLabel

convertRectToBoundingRect

Converts a Rect into its BoundingRect form.

local Aether = require(path.to.aether)

local rect: Aether.Rect = {
x = 5,
y = 10,
width = 15,
height = 20,
}

local result = Aether.convertRectToBoundingRect(rect)

--[[
Resulting BoundingRect:

x: 5,
y: 10,
width: 15,
height: 15,
left: 5,
top: 10,
left: 5,
right: 20,
bottom: 30,
]]

isSameRect

Returns true if two Rect objects are the same (i.e., the same values).

local Aether = require(path.to.aether)

local one: Aether.Rect = {
x = 0,
y = 0,
width = 0,
height = 0,
}

local two: Aether.Rect = {
x = 0,
y = 0,
width = 10,
height = 10,
}

print(isSameRect(one, one)) -- "true"
print(isSameRect(one, two)) -- "false"

read

Allows you to evaluate middleware input when it is derivable, being able to take advantage of passing the lifecycle.

local Aether = require(path.to.aether)

local function middleware(input: Aether.Derivable<number>): Aether.Middleware
return {
name = "middleware",
run = function(state)
local value = Aether.read(input, state)
-- ...
end
}
end

getPaddingObject

This is used for converting a Padding value into a usable SideObject.

local Aether = require(path.to.aether)

local padding = Aether.getPaddingObject(5)

--[[
The padding value will be:

top: 5,
bottom: 5,
left: 5,
right: 5,
]]

local padding = Aether.getPaddingObject({
top = 5,
bottom = 5,
})

--[[
The padding value will be:

top: 5,
bottom: 5,
left: 0,
right: 0,
]]
note

When providing a SideObject value, any omitted sides are automatically evaluated as 0.