This has been replaced with
default-props
. See the project page here:
A small utility module for creating React/Roact components with default props.
withDefaultProps is already setup for React. If you'd like to use this module
with Roact, swap out local ReactChildren = "children"
for local ReactChildren = React.Children
.
Use [Roact.Children] = { ... }
if you want to specify default children on an object, rather than children = { ... }
.
Functional defaults also support Roact Hooks.
local Button = default.TextButton (function(props, hooks)
local hovered, setHovered = hooks.useState(false)
return {
BackgroundTransparency = hovered and 0.5 or 0,
[Roact.Event.MouseEnter] = function()
setHovered(true)
end,
[Roact.Event.MouseLeave] = function()
setHovered(false)
end,
}
end)
return Hooks.new(Roact)(Button)
The cx
utility function provides a way to select values given a condition.
cx
accepts an array of inputs, in the format of { value, condition }
.
This ensures that results are evaluated in the order specified.
To specify a default value, include a raw value in your conditions array. It does not need to be the first value within the array, but only the first non-table value found will be considered.
local cx = default.cx
local Button = default.TextButton (function(props, hooks)
local hovered, setHovered = hooks.useState(false)
local pressed, setPressed = hooks.useState(false)
return {
BackgroundColor3 = cx {
-- We want "pressed" to take priority over "hovered"
{ Color3.fromHex("#ededed"), pressed },
{ Color3.fromHex("#dedeff"), hovered },
Color3.new(1, 1, 1),
},
[Roact.Event.InputBegan] = function(_, input: InputObject)
if input.UserInputType == Enum.UserInputType.MouseMovement then
setHovered(true)
elseif input.UserInputType.Name:match("^MouseButton%d+$") then
setPressed(true)
end
end,
[Roact.Event.InputEnded] = function(_, input: InputObject)
if input.UserInputType == Enum.UserInputType.MouseMovement then
setHovered(false)
setPressed(false)
elseif input.UserInputType.Name:match("^MouseButton%d+$") then
setPressed(false)
end
end,
}
end)
local React = require(path.to.ReactOrRoact)
local default = require(path.to.withDefaultProps)
local Padding = default.UIPadding {
PaddingTop = UDim.new(0, 8),
PaddingRight = UDim.new(0, 12),
PaddingBottom = UDim.new(0, 8),
PaddingLeft = UDim.new(0, 12),
}
local Corners = default.UICorner {
CornerRadius = UDim.new(0, 4),
}
local Button = default.TextButton {
BackgroundColor3 = Color3.new(1, 1, 1),
TextColor3 = Color3.fromHex("#1a1a1a"),
FontFace = Font.fromEnum(Enum.Font.GothamBold),
children = {
Padding = React.createElement(Padding),
Corners = React.createElement(Corners),
},
}
-- Extend the Button component by overriding props
local PrimaryButton = default(Button) {
BackgroundColor3 = Color3.fromHex("#00a2ff"),
TextColor3 = Color3.fromHex("#fafafa"),
}
-- Pass a function to access props in the defaults
-- Note that this will disable merging props with defaults
local AltButton = default.TextButton (function(props)
return {
BackgroundColor3 = props.primary and Color3.fromHex("#00a2ff") or Color3.new(1, 1, 1),
TextColor3 = props.primary and Color3.fromHex("#fafafa") or Color3.fromHex("#1a1a1a"),
FontFace = Font.fromEnum(Enum.Font.GothamBold),
Text = props.Text,
children = {
Padding = React.createElement(Padding),
Corners = React.createElement(Corners),
},
}
end)
local function App()
return React.createElement("Frame", {
BackgroundColor3 = Color3.new(0, 0, 0),
Size = UDim2.fromScale(1, 1),
}, {
Button = React.createElement(Button, {
Text = "Hello, world!",
}),
PrimaryButton = React.createElement(PrimaryButton, {
Text = "Hello, world!",
}),
AltButtonDefault = React.createElement(AltButton, {
Text = "Hello, world!",
}),
AltButtonPrimary = React.createElement(AltButton, {
Text = "Hello, world!",
primary = true,
}),
})
end
Feature flags enable access to unstable or experimental features.
Allows props to be merged with the result of defaultProps when defaultProps is a function by removing props that can't be applied when the component is a Roblox Instance. This may cause performance issues.
Because invalid Instance props are removed, we can now pass props like "primary" to the TextButton without it causing errors. It also means we don't need to specify the Text property within the defaultProps return table.
local Button = default.TextButton (function(props)
return {
AutomaticSize = Enum.AutomaticSize.XY,
AutoButtonColor = false,
BackgroundColor3 = props.primary and Color3.fromHex("#00a2ff") or Color3.new(1, 1, 1),
TextColor3 = props.primary and Color3.fromHex("#fafafa") or Color3.new(),
FontFace = Font.fromEnum(Enum.Font.GothamBold),
TextSize = 14,
children = {
Corners = React.createElement(Corners),
Padding = React.createElement(Padding),
},
}
end)
local function App()
return React.createElement("Frame", {}, {
AcceptButton = React.createElement(Button, {
primary = true,
Text = "Accept",
}),
DeclineButton = React.createElement(Button, {
primary = true, -- Keep it "primary" to apply the white text color
BackgroundColor3 = Color3.fromHex("#ff0037"), -- Override the background color
Text = "Decline",
}),
CancelButton = React.createElement(Button, {
Text = "Cancel",
}),
})
end
Merges signals into a single function and returns the output of each callback as a tuple.
local Button = default.TextButton {
[React.Event.Activated] = function()
print("Button clicked.")
end,
}
local function App()
return React.createElement(Button, {
Text = "Click me!",
[React.Event.Activated] = function()
print("Hello, world!")
end,
})
end
Upon clicking the button, "Button clicked." followed by "Hello, world!" is displayed in the output.