Roact with Style | Feedback Greatly Appreciated

Roact with Style

A module that provides a simple way to apply style rules for Roact elements

Roact with Style (the module simply called Style) intends to create a simple way of applying style rules to a Roact element or tree. The inspiration for Style is that, although Roact is a very robust way of creating a user interface, the process of creating something visually appealing is involved at best and despair-inducing at worst.

Thus, Style was born from my strong desire to do less work!
The GitHub Repository contains the relevant code, documentation, and a couple of small examples.

Here’s a full example of a very basic menu (also in the repository) below.

local Player = game:GetService("Players").LocalPlayer

local Roact = require(Roact)
local Style = require(Style)

-- Create a new style that defaults to a darker look for the elements
local DarkMode = Style.new("DarkMode", {
    -- Set Global color values for a dark scheme
    Global = {
        BackgroundColor3 = Color3.new(0.1, 0.1, 0.1),
        TextColor3 = Color3.new(0.9, 0.9, 0.9)
    },
    -- Set placeholder text for TextLabels
    TextLabel = {
        Text = "DarkTextLabel",
        Size = UDim2.fromOffset(200, 50)
    },
    -- Set properties of a close button using tag CloseButton
    CloseButton = {
        BackgroundColor3 = Color3.new(1, 0.2, 0.2),
        Size = UDim2.fromOffset(50, 50),
        TextScaled = true,
        Text = "X"
    }
})

-- A basic menu using Roact
local Menu = Roact.Component:extend("Menu")
function Menu:init()
    self.visible, self.updateVisible = Roact.createBinding(true)
end
function Menu:render()
    return Roact.createElement("ScreenGui", {}, {
        Roact.createElement("Frame", {
            Size = UDim2.new(1, -100, 1, -100),
            AnchorPoint = Vector2.new(0.5, 0.5),
            Position = UDim2.fromScale(0.5, 0.5),
            Visible = self.visible
        }, {
            Roact.createElement("TextLabel"),
            Roact.createElement("TextButton", {
                AnchorPoint = Vector2.new(1, 0),
                Position = UDim2.fromScale(1, 0),
                Tag = "CloseButton",
                [Roact.Event.Activated] = function()
                    self.updateVisible(false)
                end
            })
        }),
        Roact.createElement("TextButton", {
            AnchorPoint = Vector2.new(0, 1),
            Position = UDim2.fromScale(0, 1),
            Size = UDim2.fromOffset(200, 50),
            Text = "Toggle Visible",
            [Roact.Event.Activated] = function()
                self.updateVisible(not self.visible:getValue())
            end
        })
    })
end

local DarkMenu = DarkMode:apply(Roact.createElement(Menu))

Roact.mount(DarkMenu, Player.PlayerGui, "Dark Menu")


Admittedly, I’m not super experienced with Roact yet, which is why I decided to post in Help and Feedback instead of Community Resources.I plan to use this in my projects going forward, so any feedback would be greatly appreciated!

At the moment, I’m trying to figure out how I can make changes such that changing styles or integrating multiple styles at once would be easier, as right now my current solution is basically “Override all the properties!”

4 Likes

So the normal way to do this without any modules, pure Roact is through their context system here: Context - Roact Documentation

(Disclaimer: I have never used Roact, but I am a React developer, which Roact is inspired by).

If you can find a way to integrate your module to useContext on applied tags/et cetera, this could turn out to be a useful module where state can determine the theming of UI (Without having all the extra code that comes with a user themselves using useContext, as it is pretty complex at first glance).

2 Likes