forked from rojo-rbx/rojo
Dynamic theming. Closes #241.
Upgrades to Roact master and introduces dynamic theme switching. We branch on the theme name in order to try to use Rojo's brand colors instead of Studio's. I kind of winged it with these colors and we might want to choose slightly nicer dark theme colors in the future. I also took the opportunity to reorganize the color naming scheme since it didn't really work for dark theme.
This commit is contained in:
Submodule plugin/modules/roact updated: b1db3f82a2...f7d2f1ce1d
@@ -13,6 +13,7 @@ local Version = require(Plugin.Version)
|
||||
local preloadAssets = require(Plugin.preloadAssets)
|
||||
local strict = require(Plugin.strict)
|
||||
|
||||
local Theme = require(Plugin.Components.Theme)
|
||||
local ConnectPanel = require(Plugin.Components.ConnectPanel)
|
||||
local ConnectingPanel = require(Plugin.Components.ConnectingPanel)
|
||||
local ConnectionActivePanel = require(Plugin.Components.ConnectionActivePanel)
|
||||
@@ -199,9 +200,11 @@ function App:render()
|
||||
}
|
||||
end
|
||||
|
||||
return Roact.createElement(Roact.Portal, {
|
||||
target = self.dockWidget,
|
||||
}, children)
|
||||
return Roact.createElement(Theme.StudioProvider, nil, {
|
||||
UI = Roact.createElement(Roact.Portal, {
|
||||
target = self.dockWidget,
|
||||
}, children),
|
||||
})
|
||||
end
|
||||
|
||||
function App:didMount()
|
||||
|
||||
@@ -4,8 +4,8 @@ local Plugin = Rojo.Plugin
|
||||
local Roact = require(Rojo.Roact)
|
||||
|
||||
local Config = require(Plugin.Config)
|
||||
local Theme = require(Plugin.Theme)
|
||||
|
||||
local Theme = require(Plugin.Components.Theme)
|
||||
local Panel = require(Plugin.Components.Panel)
|
||||
local FitList = require(Plugin.Components.FitList)
|
||||
local FitText = require(Plugin.Components.FitText)
|
||||
@@ -26,136 +26,138 @@ end
|
||||
function ConnectPanel:render()
|
||||
local startSession = self.props.startSession
|
||||
|
||||
return e(Panel, nil, {
|
||||
Layout = e("UIListLayout", {
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
}),
|
||||
return Theme.with(function(theme)
|
||||
return e(Panel, nil, {
|
||||
Layout = e("UIListLayout", {
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
}),
|
||||
|
||||
Inputs = e(FitList, {
|
||||
containerProps = {
|
||||
BackgroundTransparency = 1,
|
||||
LayoutOrder = 1,
|
||||
},
|
||||
layoutProps = {
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
Padding = UDim.new(0, 8),
|
||||
},
|
||||
paddingProps = {
|
||||
PaddingTop = UDim.new(0, 20),
|
||||
PaddingBottom = UDim.new(0, 10),
|
||||
PaddingLeft = UDim.new(0, 24),
|
||||
PaddingRight = UDim.new(0, 24),
|
||||
},
|
||||
}, {
|
||||
Address = e(FitList, {
|
||||
Inputs = e(FitList, {
|
||||
containerProps = {
|
||||
LayoutOrder = 1,
|
||||
BackgroundTransparency = 1,
|
||||
LayoutOrder = 1,
|
||||
},
|
||||
layoutProps = {
|
||||
Padding = UDim.new(0, 4),
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
Padding = UDim.new(0, 8),
|
||||
},
|
||||
paddingProps = {
|
||||
PaddingTop = UDim.new(0, 20),
|
||||
PaddingBottom = UDim.new(0, 10),
|
||||
PaddingLeft = UDim.new(0, 24),
|
||||
PaddingRight = UDim.new(0, 24),
|
||||
},
|
||||
}, {
|
||||
Label = e(FitText, {
|
||||
Kind = "TextLabel",
|
||||
LayoutOrder = 1,
|
||||
BackgroundTransparency = 1,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
Font = Theme.TitleFont,
|
||||
TextSize = 20,
|
||||
Text = "Address",
|
||||
TextColor3 = Theme.PrimaryColor,
|
||||
Address = e(FitList, {
|
||||
containerProps = {
|
||||
LayoutOrder = 1,
|
||||
BackgroundTransparency = 1,
|
||||
},
|
||||
layoutProps = {
|
||||
Padding = UDim.new(0, 4),
|
||||
},
|
||||
}, {
|
||||
Label = e(FitText, {
|
||||
Kind = "TextLabel",
|
||||
LayoutOrder = 1,
|
||||
BackgroundTransparency = 1,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
Font = theme.TitleFont,
|
||||
TextSize = 20,
|
||||
Text = "Address",
|
||||
TextColor3 = theme.Text1,
|
||||
}),
|
||||
|
||||
Input = e(FormTextInput, {
|
||||
layoutOrder = 2,
|
||||
width = UDim.new(0, 220),
|
||||
value = self.state.address,
|
||||
placeholderValue = Config.defaultHost,
|
||||
onValueChange = function(newValue)
|
||||
self:setState({
|
||||
address = newValue,
|
||||
})
|
||||
end,
|
||||
}),
|
||||
}),
|
||||
|
||||
Input = e(FormTextInput, {
|
||||
layoutOrder = 2,
|
||||
width = UDim.new(0, 220),
|
||||
value = self.state.address,
|
||||
placeholderValue = Config.defaultHost,
|
||||
onValueChange = function(newValue)
|
||||
self:setState({
|
||||
address = newValue,
|
||||
})
|
||||
end,
|
||||
Port = e(FitList, {
|
||||
containerProps = {
|
||||
LayoutOrder = 2,
|
||||
BackgroundTransparency = 1,
|
||||
},
|
||||
layoutProps = {
|
||||
Padding = UDim.new(0, 4),
|
||||
},
|
||||
}, {
|
||||
Label = e(FitText, {
|
||||
Kind = "TextLabel",
|
||||
LayoutOrder = 1,
|
||||
BackgroundTransparency = 1,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
Font = theme.TitleFont,
|
||||
TextSize = 20,
|
||||
Text = "Port",
|
||||
TextColor3 = theme.Text1,
|
||||
}),
|
||||
|
||||
Input = e(FormTextInput, {
|
||||
layoutOrder = 2,
|
||||
width = UDim.new(0, 80),
|
||||
value = self.state.port,
|
||||
placeholderValue = Config.defaultPort,
|
||||
onValueChange = function(newValue)
|
||||
self:setState({
|
||||
port = newValue,
|
||||
})
|
||||
end,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
||||
Port = e(FitList, {
|
||||
Buttons = e(FitList, {
|
||||
fitAxes = "Y",
|
||||
containerProps = {
|
||||
BackgroundTransparency = 1,
|
||||
LayoutOrder = 2,
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 0, 0),
|
||||
},
|
||||
layoutProps = {
|
||||
Padding = UDim.new(0, 4),
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Right,
|
||||
Padding = UDim.new(0, 8),
|
||||
},
|
||||
paddingProps = {
|
||||
PaddingTop = UDim.new(0, 0),
|
||||
PaddingBottom = UDim.new(0, 20),
|
||||
PaddingLeft = UDim.new(0, 24),
|
||||
PaddingRight = UDim.new(0, 24),
|
||||
},
|
||||
}, {
|
||||
Label = e(FitText, {
|
||||
Kind = "TextLabel",
|
||||
LayoutOrder = 1,
|
||||
BackgroundTransparency = 1,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
Font = Theme.TitleFont,
|
||||
TextSize = 20,
|
||||
Text = "Port",
|
||||
TextColor3 = Theme.PrimaryColor,
|
||||
}),
|
||||
|
||||
Input = e(FormTextInput, {
|
||||
e(FormButton, {
|
||||
layoutOrder = 2,
|
||||
width = UDim.new(0, 80),
|
||||
value = self.state.port,
|
||||
placeholderValue = Config.defaultPort,
|
||||
onValueChange = function(newValue)
|
||||
self:setState({
|
||||
port = newValue,
|
||||
})
|
||||
text = "Connect",
|
||||
onClick = function()
|
||||
if startSession ~= nil then
|
||||
local address = self.state.address
|
||||
if address:len() == 0 then
|
||||
address = Config.defaultHost
|
||||
end
|
||||
|
||||
local port = self.state.port
|
||||
if port:len() == 0 then
|
||||
port = Config.defaultPort
|
||||
end
|
||||
|
||||
startSession(address, port)
|
||||
end
|
||||
end,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
||||
Buttons = e(FitList, {
|
||||
fitAxes = "Y",
|
||||
containerProps = {
|
||||
BackgroundTransparency = 1,
|
||||
LayoutOrder = 2,
|
||||
Size = UDim2.new(1, 0, 0, 0),
|
||||
},
|
||||
layoutProps = {
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Right,
|
||||
Padding = UDim.new(0, 8),
|
||||
},
|
||||
paddingProps = {
|
||||
PaddingTop = UDim.new(0, 0),
|
||||
PaddingBottom = UDim.new(0, 20),
|
||||
PaddingLeft = UDim.new(0, 24),
|
||||
PaddingRight = UDim.new(0, 24),
|
||||
},
|
||||
}, {
|
||||
e(FormButton, {
|
||||
layoutOrder = 2,
|
||||
text = "Connect",
|
||||
onClick = function()
|
||||
if startSession ~= nil then
|
||||
local address = self.state.address
|
||||
if address:len() == 0 then
|
||||
address = Config.defaultHost
|
||||
end
|
||||
|
||||
local port = self.state.port
|
||||
if port:len() == 0 then
|
||||
port = Config.defaultPort
|
||||
end
|
||||
|
||||
startSession(address, port)
|
||||
end
|
||||
end,
|
||||
}),
|
||||
}),
|
||||
})
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return ConnectPanel
|
||||
@@ -2,8 +2,7 @@ local Roact = require(script:FindFirstAncestor("Rojo").Roact)
|
||||
|
||||
local Plugin = script:FindFirstAncestor("Plugin")
|
||||
|
||||
local Theme = require(Plugin.Theme)
|
||||
|
||||
local Theme = require(Plugin.Components.Theme)
|
||||
local Panel = require(Plugin.Components.Panel)
|
||||
local FitText = require(Plugin.Components.FitText)
|
||||
|
||||
@@ -12,23 +11,25 @@ local e = Roact.createElement
|
||||
local ConnectingPanel = Roact.Component:extend("ConnectingPanel")
|
||||
|
||||
function ConnectingPanel:render()
|
||||
return e(Panel, nil, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
Padding = UDim.new(0, 8),
|
||||
}),
|
||||
return Theme.with(function(theme)
|
||||
return e(Panel, nil, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
Padding = UDim.new(0, 8),
|
||||
}),
|
||||
|
||||
Text = e(FitText, {
|
||||
Padding = Vector2.new(12, 6),
|
||||
Font = Theme.ButtonFont,
|
||||
TextSize = 18,
|
||||
Text = "Connecting...",
|
||||
TextColor3 = Theme.PrimaryColor,
|
||||
BackgroundTransparency = 1,
|
||||
}),
|
||||
})
|
||||
Text = e(FitText, {
|
||||
Padding = Vector2.new(12, 6),
|
||||
Font = theme.ButtonFont,
|
||||
TextSize = 18,
|
||||
Text = "Connecting...",
|
||||
TextColor3 = theme.Text1,
|
||||
BackgroundTransparency = 1,
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return ConnectingPanel
|
||||
@@ -2,8 +2,7 @@ local Roact = require(script:FindFirstAncestor("Rojo").Roact)
|
||||
|
||||
local Plugin = script:FindFirstAncestor("Plugin")
|
||||
|
||||
local Theme = require(Plugin.Theme)
|
||||
|
||||
local Theme = require(Plugin.Components.Theme)
|
||||
local Panel = require(Plugin.Components.Panel)
|
||||
local FitText = require(Plugin.Components.FitText)
|
||||
local FormButton = require(Plugin.Components.FormButton)
|
||||
@@ -15,32 +14,34 @@ local ConnectionActivePanel = Roact.Component:extend("ConnectionActivePanel")
|
||||
function ConnectionActivePanel:render()
|
||||
local stopSession = self.props.stopSession
|
||||
|
||||
return e(Panel, nil, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
Padding = UDim.new(0, 8),
|
||||
}),
|
||||
return Theme.with(function(theme)
|
||||
return e(Panel, nil, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
Padding = UDim.new(0, 8),
|
||||
}),
|
||||
|
||||
Text = e(FitText, {
|
||||
Padding = Vector2.new(12, 6),
|
||||
Font = Theme.ButtonFont,
|
||||
TextSize = 18,
|
||||
Text = "Connected to Live-Sync Server",
|
||||
TextColor3 = Theme.PrimaryColor,
|
||||
BackgroundTransparency = 1,
|
||||
}),
|
||||
Text = e(FitText, {
|
||||
Padding = Vector2.new(12, 6),
|
||||
Font = theme.ButtonFont,
|
||||
TextSize = 18,
|
||||
Text = "Connected to Live-Sync Server",
|
||||
TextColor3 = theme.Text1,
|
||||
BackgroundTransparency = 1,
|
||||
}),
|
||||
|
||||
DisconnectButton = e(FormButton, {
|
||||
layoutOrder = 2,
|
||||
text = "Disconnect",
|
||||
secondary = true,
|
||||
onClick = function()
|
||||
stopSession()
|
||||
end,
|
||||
}),
|
||||
})
|
||||
DisconnectButton = e(FormButton, {
|
||||
layoutOrder = 2,
|
||||
text = "Disconnect",
|
||||
secondary = true,
|
||||
onClick = function()
|
||||
stopSession()
|
||||
end,
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return ConnectionActivePanel
|
||||
@@ -2,8 +2,7 @@ local Roact = require(script:FindFirstAncestor("Rojo").Roact)
|
||||
|
||||
local Plugin = script:FindFirstAncestor("Plugin")
|
||||
|
||||
local Theme = require(Plugin.Theme)
|
||||
|
||||
local Theme = require(Plugin.Components.Theme)
|
||||
local Panel = require(Plugin.Components.Panel)
|
||||
local FitText = require(Plugin.Components.FitText)
|
||||
local FitScrollingFrame = require(Plugin.Components.FitScrollingFrame)
|
||||
@@ -20,50 +19,52 @@ function ErrorPanel:render()
|
||||
local errorMessage = self.props.errorMessage
|
||||
local onDismiss = self.props.onDismiss
|
||||
|
||||
return e(Panel, nil, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
Padding = UDim.new(0, 8),
|
||||
}),
|
||||
|
||||
ErrorContainer = e(FitScrollingFrame, {
|
||||
containerProps = {
|
||||
BackgroundTransparency = 1,
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(1, -HOR_PADDING * 2, 1, -BUTTON_HEIGHT),
|
||||
Position = UDim2.new(0, HOR_PADDING, 0, 0),
|
||||
ScrollBarImageColor3 = Theme.PrimaryColor,
|
||||
VerticalScrollBarInset = Enum.ScrollBarInset.ScrollBar,
|
||||
ScrollingDirection = Enum.ScrollingDirection.Y,
|
||||
},
|
||||
}, {
|
||||
Text = e(FitText, {
|
||||
Size = UDim2.new(1, 0, 0, 0),
|
||||
|
||||
LayoutOrder = 1,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextYAlignment = Enum.TextYAlignment.Top,
|
||||
FitAxis = "Y",
|
||||
Font = Theme.ButtonFont,
|
||||
TextSize = 18,
|
||||
Text = errorMessage,
|
||||
TextWrap = true,
|
||||
TextColor3 = Theme.PrimaryColor,
|
||||
BackgroundTransparency = 1,
|
||||
return Theme.with(function(theme)
|
||||
return e(Panel, nil, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
Padding = UDim.new(0, 8),
|
||||
}),
|
||||
}),
|
||||
|
||||
DismissButton = e(FormButton, {
|
||||
layoutOrder = 2,
|
||||
text = "Dismiss",
|
||||
secondary = true,
|
||||
onClick = function()
|
||||
onDismiss()
|
||||
end,
|
||||
}),
|
||||
})
|
||||
ErrorContainer = e(FitScrollingFrame, {
|
||||
containerProps = {
|
||||
BackgroundTransparency = 1,
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(1, -HOR_PADDING * 2, 1, -BUTTON_HEIGHT),
|
||||
Position = UDim2.new(0, HOR_PADDING, 0, 0),
|
||||
ScrollBarImageColor3 = theme.Text1,
|
||||
VerticalScrollBarInset = Enum.ScrollBarInset.ScrollBar,
|
||||
ScrollingDirection = Enum.ScrollingDirection.Y,
|
||||
},
|
||||
}, {
|
||||
Text = e(FitText, {
|
||||
Size = UDim2.new(1, 0, 0, 0),
|
||||
|
||||
LayoutOrder = 1,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextYAlignment = Enum.TextYAlignment.Top,
|
||||
FitAxis = "Y",
|
||||
Font = theme.ButtonFont,
|
||||
TextSize = 18,
|
||||
Text = errorMessage,
|
||||
TextWrap = true,
|
||||
TextColor3 = theme.Text1,
|
||||
BackgroundTransparency = 1,
|
||||
}),
|
||||
}),
|
||||
|
||||
DismissButton = e(FormButton, {
|
||||
layoutOrder = 2,
|
||||
text = "Dismiss",
|
||||
secondary = true,
|
||||
onClick = function()
|
||||
onDismiss()
|
||||
end,
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return ErrorPanel
|
||||
@@ -4,7 +4,7 @@ local Plugin = Rojo.Plugin
|
||||
local Roact = require(Rojo.Roact)
|
||||
|
||||
local Assets = require(Plugin.Assets)
|
||||
local Theme = require(Plugin.Theme)
|
||||
local Theme = require(Plugin.Components.Theme)
|
||||
local FitList = require(Plugin.Components.FitList)
|
||||
local FitText = require(Plugin.Components.FitText)
|
||||
|
||||
@@ -20,43 +20,45 @@ local function FormButton(props)
|
||||
local textColor
|
||||
local backgroundColor
|
||||
|
||||
if props.secondary then
|
||||
textColor = Theme.AccentColor
|
||||
backgroundColor = Theme.SecondaryColor
|
||||
else
|
||||
textColor = Theme.SecondaryColor
|
||||
backgroundColor = Theme.AccentColor
|
||||
end
|
||||
return Theme.with(function(theme)
|
||||
if props.secondary then
|
||||
textColor = theme.Brand1
|
||||
backgroundColor = theme.Background2
|
||||
else
|
||||
textColor = theme.TextOnAccent
|
||||
backgroundColor = theme.Brand1
|
||||
end
|
||||
|
||||
return e(FitList, {
|
||||
containerKind = "ImageButton",
|
||||
containerProps = {
|
||||
LayoutOrder = layoutOrder,
|
||||
BackgroundTransparency = 1,
|
||||
Image = RoundBox.asset,
|
||||
ImageRectOffset = RoundBox.offset,
|
||||
ImageRectSize = RoundBox.size,
|
||||
SliceCenter = RoundBox.center,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
ImageColor3 = backgroundColor,
|
||||
return e(FitList, {
|
||||
containerKind = "ImageButton",
|
||||
containerProps = {
|
||||
LayoutOrder = layoutOrder,
|
||||
BackgroundTransparency = 1,
|
||||
Image = RoundBox.asset,
|
||||
ImageRectOffset = RoundBox.offset,
|
||||
ImageRectSize = RoundBox.size,
|
||||
SliceCenter = RoundBox.center,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
ImageColor3 = backgroundColor,
|
||||
|
||||
[Roact.Event.Activated] = function()
|
||||
if onClick ~= nil then
|
||||
onClick()
|
||||
end
|
||||
end,
|
||||
},
|
||||
}, {
|
||||
Text = e(FitText, {
|
||||
Kind = "TextLabel",
|
||||
Text = text,
|
||||
TextSize = 18,
|
||||
TextColor3 = textColor,
|
||||
Font = Theme.ButtonFont,
|
||||
Padding = Vector2.new(16, 8),
|
||||
BackgroundTransparency = 1,
|
||||
}),
|
||||
})
|
||||
[Roact.Event.Activated] = function()
|
||||
if onClick ~= nil then
|
||||
onClick()
|
||||
end
|
||||
end,
|
||||
},
|
||||
}, {
|
||||
Text = e(FitText, {
|
||||
Kind = "TextLabel",
|
||||
Text = text,
|
||||
TextSize = 18,
|
||||
TextColor3 = textColor,
|
||||
Font = theme.ButtonFont,
|
||||
Padding = Vector2.new(16, 8),
|
||||
BackgroundTransparency = 1,
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return FormButton
|
||||
@@ -4,7 +4,7 @@ local Plugin = Rojo.Plugin
|
||||
local Roact = require(Rojo.Roact)
|
||||
|
||||
local Assets = require(Plugin.Assets)
|
||||
local Theme = require(Plugin.Theme)
|
||||
local Theme = require(Plugin.Components.Theme)
|
||||
|
||||
local e = Roact.createElement
|
||||
|
||||
@@ -35,46 +35,48 @@ function FormTextInput:render()
|
||||
shownPlaceholder = placeholderValue
|
||||
end
|
||||
|
||||
return e("ImageLabel", {
|
||||
LayoutOrder = layoutOrder,
|
||||
Image = RoundBox.asset,
|
||||
ImageRectOffset = RoundBox.offset,
|
||||
ImageRectSize = RoundBox.size,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
SliceCenter = RoundBox.center,
|
||||
ImageColor3 = Theme.SecondaryColor,
|
||||
Size = UDim2.new(width.Scale, width.Offset, 0, TEXT_SIZE + PADDING * 2),
|
||||
BackgroundTransparency = 1,
|
||||
}, {
|
||||
InputInner = e("TextBox", {
|
||||
return Theme.with(function(theme)
|
||||
return e("ImageLabel", {
|
||||
LayoutOrder = layoutOrder,
|
||||
Image = RoundBox.asset,
|
||||
ImageRectOffset = RoundBox.offset,
|
||||
ImageRectSize = RoundBox.size,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
SliceCenter = RoundBox.center,
|
||||
ImageColor3 = theme.Background2,
|
||||
Size = UDim2.new(width.Scale, width.Offset, 0, TEXT_SIZE + PADDING * 2),
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, -PADDING * 2, 1, -PADDING * 2),
|
||||
Position = UDim2.new(0.5, 0, 0.5, 0),
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
Font = Theme.InputFont,
|
||||
ClearTextOnFocus = false,
|
||||
TextXAlignment = Enum.TextXAlignment.Center,
|
||||
TextSize = TEXT_SIZE,
|
||||
Text = value,
|
||||
PlaceholderText = shownPlaceholder,
|
||||
PlaceholderColor3 = Theme.LightTextColor,
|
||||
TextColor3 = Theme.PrimaryColor,
|
||||
}, {
|
||||
InputInner = e("TextBox", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, -PADDING * 2, 1, -PADDING * 2),
|
||||
Position = UDim2.new(0.5, 0, 0.5, 0),
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
Font = theme.InputFont,
|
||||
ClearTextOnFocus = false,
|
||||
TextXAlignment = Enum.TextXAlignment.Center,
|
||||
TextSize = TEXT_SIZE,
|
||||
Text = value,
|
||||
PlaceholderText = shownPlaceholder,
|
||||
PlaceholderColor3 = theme.Text2,
|
||||
TextColor3 = theme.Text1,
|
||||
|
||||
[Roact.Change.Text] = function(rbx)
|
||||
onValueChange(rbx.Text)
|
||||
end,
|
||||
[Roact.Event.Focused] = function()
|
||||
self:setState({
|
||||
focused = true,
|
||||
})
|
||||
end,
|
||||
[Roact.Event.FocusLost] = function()
|
||||
self:setState({
|
||||
focused = false,
|
||||
})
|
||||
end,
|
||||
}),
|
||||
})
|
||||
[Roact.Change.Text] = function(rbx)
|
||||
onValueChange(rbx.Text)
|
||||
end,
|
||||
[Roact.Event.Focused] = function()
|
||||
self:setState({
|
||||
focused = true,
|
||||
})
|
||||
end,
|
||||
[Roact.Event.FocusLost] = function()
|
||||
self:setState({
|
||||
focused = false,
|
||||
})
|
||||
end,
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return FormTextInput
|
||||
@@ -3,6 +3,7 @@ local Roact = require(script:FindFirstAncestor("Rojo").Roact)
|
||||
local Plugin = script:FindFirstAncestor("Plugin")
|
||||
|
||||
local RojoFooter = require(Plugin.Components.RojoFooter)
|
||||
local Theme = require(Plugin.Components.Theme)
|
||||
|
||||
local e = Roact.createElement
|
||||
|
||||
@@ -13,22 +14,25 @@ function Panel:init()
|
||||
end
|
||||
|
||||
function Panel:render()
|
||||
return e("Frame", {
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
BackgroundTransparency = 1,
|
||||
}, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
}),
|
||||
|
||||
Body = e("Frame", {
|
||||
Size = UDim2.new(0, 360, 1, -32),
|
||||
return Theme.with(function(theme)
|
||||
return e("Frame", {
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
BackgroundTransparency = 1,
|
||||
}, self.props[Roact.Children]),
|
||||
}, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
}),
|
||||
|
||||
Footer = e(RojoFooter),
|
||||
})
|
||||
Body = e("Frame", {
|
||||
Size = UDim2.new(0, 360, 1, -32),
|
||||
BackgroundColor3 = theme.Background1,
|
||||
BorderSizePixel = 0,
|
||||
}, self.props[Roact.Children]),
|
||||
|
||||
Footer = e(RojoFooter),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return Panel
|
||||
@@ -6,7 +6,7 @@ local Roact = require(Rojo.Roact)
|
||||
local Config = require(Plugin.Config)
|
||||
local Version = require(Plugin.Version)
|
||||
local Assets = require(Plugin.Assets)
|
||||
local Theme = require(Plugin.Theme)
|
||||
local Theme = require(Plugin.Components.Theme)
|
||||
|
||||
local e = Roact.createElement
|
||||
|
||||
@@ -18,50 +18,53 @@ function RojoFooter:init()
|
||||
end
|
||||
|
||||
function RojoFooter:render()
|
||||
return e("Frame", {
|
||||
LayoutOrder = 3,
|
||||
Size = UDim2.new(1, 0, 0, 32),
|
||||
BackgroundColor3 = Theme.SecondaryColor,
|
||||
BorderSizePixel = 0,
|
||||
}, {
|
||||
Padding = e("UIPadding", {
|
||||
PaddingTop = UDim.new(0, 4),
|
||||
PaddingBottom = UDim.new(0, 4),
|
||||
PaddingLeft = UDim.new(0, 8),
|
||||
PaddingRight = UDim.new(0, 8),
|
||||
}),
|
||||
|
||||
LogoContainer = e("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
|
||||
Size = UDim2.new(0, 0, 0, 32),
|
||||
return Theme.with(function(theme)
|
||||
return e("Frame", {
|
||||
LayoutOrder = 3,
|
||||
Size = UDim2.new(1, 0, 0, 32),
|
||||
BackgroundColor3 = theme.Background2,
|
||||
BorderSizePixel = 0,
|
||||
ZIndex = 2,
|
||||
}, {
|
||||
Logo = e("ImageLabel", {
|
||||
Image = Assets.Images.Logo,
|
||||
Size = UDim2.new(0, 80, 0, 40),
|
||||
ScaleType = Enum.ScaleType.Fit,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 1, -10),
|
||||
AnchorPoint = Vector2.new(0, 1),
|
||||
Padding = e("UIPadding", {
|
||||
PaddingTop = UDim.new(0, 4),
|
||||
PaddingBottom = UDim.new(0, 4),
|
||||
PaddingLeft = UDim.new(0, 8),
|
||||
PaddingRight = UDim.new(0, 8),
|
||||
}),
|
||||
}),
|
||||
|
||||
Version = e("TextLabel", {
|
||||
Position = UDim2.new(1, 0, 0, 0),
|
||||
Size = UDim2.new(0, 0, 1, 0),
|
||||
AnchorPoint = Vector2.new(1, 0),
|
||||
Font = Theme.TitleFont,
|
||||
TextSize = 18,
|
||||
Text = Version.display(Config.version),
|
||||
TextXAlignment = Enum.TextXAlignment.Right,
|
||||
TextColor3 = Theme.LightTextColor,
|
||||
BackgroundTransparency = 1,
|
||||
LogoContainer = e("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
|
||||
[Roact.Change.AbsoluteSize] = function(rbx)
|
||||
self.setFooterVersionSize(rbx.AbsoluteSize)
|
||||
end,
|
||||
}),
|
||||
})
|
||||
Size = UDim2.new(0, 0, 0, 32),
|
||||
}, {
|
||||
Logo = e("ImageLabel", {
|
||||
Image = Assets.Images.Logo,
|
||||
Size = UDim2.new(0, 80, 0, 40),
|
||||
ScaleType = Enum.ScaleType.Fit,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 1, -10),
|
||||
AnchorPoint = Vector2.new(0, 1),
|
||||
}),
|
||||
}),
|
||||
|
||||
Version = e("TextLabel", {
|
||||
Position = UDim2.new(1, 0, 0, 0),
|
||||
Size = UDim2.new(0, 0, 1, 0),
|
||||
AnchorPoint = Vector2.new(1, 0),
|
||||
Font = theme.TitleFont,
|
||||
TextSize = 18,
|
||||
Text = Version.display(Config.version),
|
||||
TextXAlignment = Enum.TextXAlignment.Right,
|
||||
TextColor3 = theme.Text2,
|
||||
BackgroundTransparency = 1,
|
||||
|
||||
[Roact.Change.AbsoluteSize] = function(rbx)
|
||||
self.setFooterVersionSize(rbx.AbsoluteSize)
|
||||
end,
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return RojoFooter
|
||||
104
plugin/src/Components/Theme.lua
Normal file
104
plugin/src/Components/Theme.lua
Normal file
@@ -0,0 +1,104 @@
|
||||
--[[
|
||||
Theming system taking advantage of Roact's new context API.
|
||||
|
||||
Doesn't use colors provided by Studio and instead just branches on theme
|
||||
name. This isn't exactly best practice.
|
||||
]]
|
||||
|
||||
local Studio = settings():GetService("Studio")
|
||||
|
||||
local Rojo = script:FindFirstAncestor("Rojo")
|
||||
|
||||
local Roact = require(Rojo.Roact)
|
||||
local Log = require(Rojo.Log)
|
||||
|
||||
local strict = require(script.Parent.Parent.strict)
|
||||
|
||||
local lightTheme = strict("Theme", {
|
||||
ButtonFont = Enum.Font.GothamSemibold,
|
||||
InputFont = Enum.Font.Code,
|
||||
TitleFont = Enum.Font.GothamBold,
|
||||
MainFont = Enum.Font.Gotham,
|
||||
|
||||
Brand1 = Color3.fromRGB(225, 56, 53),
|
||||
|
||||
Text1 = Color3.fromRGB(64, 64, 64),
|
||||
Text2 = Color3.fromRGB(160, 160, 160),
|
||||
TextOnAccent = Color3.fromRGB(235, 235, 235),
|
||||
|
||||
Background1 = Color3.fromRGB(255, 255, 255),
|
||||
Background2 = Color3.fromRGB(235, 235, 235),
|
||||
})
|
||||
|
||||
local darkTheme = strict("Theme", {
|
||||
ButtonFont = Enum.Font.GothamSemibold,
|
||||
InputFont = Enum.Font.Code,
|
||||
TitleFont = Enum.Font.GothamBold,
|
||||
MainFont = Enum.Font.Gotham,
|
||||
|
||||
Brand1 = Color3.fromRGB(225, 56, 53),
|
||||
|
||||
Text1 = Color3.fromRGB(235, 235, 235),
|
||||
Text2 = Color3.fromRGB(200, 200, 200),
|
||||
TextOnAccent = Color3.fromRGB(235, 235, 235),
|
||||
|
||||
Background1 = Color3.fromRGB(48, 48, 48),
|
||||
Background2 = Color3.fromRGB(64, 64, 64),
|
||||
})
|
||||
|
||||
local Context = Roact.createContext(lightTheme)
|
||||
|
||||
local StudioProvider = Roact.Component:extend("StudioProvider")
|
||||
|
||||
-- Pull the current theme from Roblox Studio and update state with it.
|
||||
function StudioProvider:updateTheme()
|
||||
local studioTheme = Studio.Theme
|
||||
|
||||
if studioTheme.Name == "Light" then
|
||||
self:setState({
|
||||
theme = lightTheme,
|
||||
})
|
||||
elseif studioTheme.Name == "Dark" then
|
||||
self:setState({
|
||||
theme = darkTheme,
|
||||
})
|
||||
else
|
||||
Log.warn("Unexpected theme '{}'' -- falling back to light theme!", studioTheme.Name)
|
||||
|
||||
self:setState({
|
||||
theme = lightTheme,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function StudioProvider:init()
|
||||
self:updateTheme()
|
||||
end
|
||||
|
||||
function StudioProvider:render()
|
||||
return Roact.createElement(Context.Provider, {
|
||||
value = self.state.theme,
|
||||
}, self.props[Roact.Children])
|
||||
end
|
||||
|
||||
function StudioProvider:didMount()
|
||||
self.connection = Studio.ThemeChanged:Connect(function()
|
||||
self:updateTheme()
|
||||
end)
|
||||
end
|
||||
|
||||
function StudioProvider:willUnmount()
|
||||
self.connection:Disconnect()
|
||||
end
|
||||
|
||||
local function with(callback)
|
||||
return Roact.createElement(Context.Consumer, {
|
||||
render = callback,
|
||||
})
|
||||
end
|
||||
|
||||
return {
|
||||
StudioProvider = StudioProvider,
|
||||
Consumer = Context.Consumer,
|
||||
with = with,
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
local strict = require(script.Parent.strict)
|
||||
|
||||
return strict("Theme", {
|
||||
ButtonFont = Enum.Font.GothamSemibold,
|
||||
InputFont = Enum.Font.Code,
|
||||
TitleFont = Enum.Font.GothamBold,
|
||||
MainFont = Enum.Font.Gotham,
|
||||
|
||||
AccentColor = Color3.fromRGB(225, 56, 53),
|
||||
AccentLightColor = Color3.fromRGB(255, 146, 145),
|
||||
PrimaryColor = Color3.fromRGB(64, 64, 64),
|
||||
SecondaryColor = Color3.fromRGB(235, 235, 235),
|
||||
LightTextColor = Color3.fromRGB(160, 160, 160),
|
||||
})
|
||||
@@ -19,7 +19,7 @@ local app = Roact.createElement(App, {
|
||||
plugin = plugin,
|
||||
})
|
||||
|
||||
local tree = Roact.mount(app, game:GetService("CoreGui"), "Rojo UI")
|
||||
local tree = Roact.mount(app, nil, "Rojo UI")
|
||||
|
||||
plugin.Unloading:Connect(function()
|
||||
Roact.unmount(tree)
|
||||
|
||||
Reference in New Issue
Block a user