diff --git a/src/Checkbox.lua b/src/Checkbox.lua index d8872e3..995f1ce 100644 --- a/src/Checkbox.lua +++ b/src/Checkbox.lua @@ -8,6 +8,17 @@ local INDICATOR_IMAGE = "rbxassetid://6652838434" Checkbox.Indeterminate = "Indeterminate" +Checkbox.Alignment = { + Left = "Left", + Right = "Right", +} + +Checkbox.defaultProps = { + LayoutOrder = 0, + Disabled = false, + Alignment = Checkbox.Alignment.Left, +} + function Checkbox:init() self:setState({ Hover = false }) self.onInputBegan = function(_, inputObject) @@ -46,6 +57,15 @@ function Checkbox:render() backModifier = Enum.StudioStyleGuideModifier.Selected end + local boxPositionX = 0 + local textPositionX = 1 + local textAlign = Enum.TextXAlignment.Left + if self.props.Alignment == Checkbox.Alignment.Right then + boxPositionX = 1 + textPositionX = 0 + textAlign = Enum.TextXAlignment.Right + end + return withTheme(function(theme) local rectOffset = Vector2.new(0, 0) if self.props.Value == Checkbox.Indeterminate then @@ -64,6 +84,7 @@ function Checkbox:render() return Roact.createElement("Frame", { Size = UDim2.new(1, 0, 0, 23), BackgroundTransparency = 1, + LayoutOrder = self.props.LayoutOrder, }, { Padding = Roact.createElement("UIPadding", { PaddingLeft = UDim.new(0, 5), @@ -80,6 +101,8 @@ function Checkbox:render() [Roact.Event.Activated] = self.onActivated, }), Box = Roact.createElement("ImageLabel", { + AnchorPoint = Vector2.new(boxPositionX, 0), + Position = UDim2.fromScale(boxPositionX, 0), BackgroundColor3 = theme:GetColor(Enum.StudioStyleGuideColor.CheckedFieldBackground, backModifier), BorderColor3 = theme:GetColor(Enum.StudioStyleGuideColor.CheckedFieldBorder, mainModifier), Size = UDim2.fromOffset(13, 13), @@ -91,9 +114,10 @@ function Checkbox:render() }), Label = self.props.Label and Roact.createElement("TextLabel", { BackgroundTransparency = 1, - Position = UDim2.fromOffset(19, -1), + AnchorPoint = Vector2.new(textPositionX, 0), + Position = UDim2.fromScale(textPositionX, 0), Size = UDim2.new(1, -19, 1, 0), - TextXAlignment = Enum.TextXAlignment.Left, + TextXAlignment = textAlign, TextTruncate = Enum.TextTruncate.AtEnd, Text = self.props.Label, Font = Enum.Font.SourceSans, diff --git a/src/Checkbox.story.lua b/src/Checkbox.story.lua index 994326c..b8cbf2c 100644 --- a/src/Checkbox.story.lua +++ b/src/Checkbox.story.lua @@ -11,7 +11,8 @@ function Wrapper:render() return Roact.createElement(Checkbox, { Value = self.state.Value, Disabled = false, - Label = "Checkbox.Label", + Label = "Lorem ipsum dolor sit amet", + Alignment = Checkbox.Alignment.Left, OnActivated = function() local was = self.state.Value if was == true then diff --git a/src/TextInput.lua b/src/TextInput.lua new file mode 100644 index 0000000..a2fbac4 --- /dev/null +++ b/src/TextInput.lua @@ -0,0 +1,114 @@ +local Vendor = script.Parent.Parent +local Roact = require(Vendor.Roact) + +local withTheme = require(script.Parent.withTheme) +local TextInput = Roact.Component:extend("TextInput") + +local PLACEHOLDER_TEXT_COLOR = Color3.fromRGB(102, 102, 102) -- works for both themes + +local function joinDictionaries(...) + local out = {} + for i = 1, select("#", ...) do + for key, val in pairs(select(i, ...)) do + out[key] = val + end + end + return out +end + +local noop = function() +end + +TextInput.defaultProps = { + LayoutOrder = 0, + Disabled = false, + Text = "", + PlaceholderText = "", + ClearTextOnFocus = true, + OnFocused = noop, + OnFocusLost = noop, + OnChanged = noop, +} + +function TextInput:init() + self:setState({ + Hover = false, + Focused = false, + }) + self.onInputBegan = function(_, inputObject) + if self.props.Disabled then + return + elseif inputObject.UserInputType == Enum.UserInputType.MouseMovement then + self:setState({ Hover = true }) + end + end + self.onInputEnded = function(_, inputObject) + if self.props.Disabled then + return + elseif inputObject.UserInputType == Enum.UserInputType.MouseMovement then + self:setState({ Hover = false }) + end + end + self.onFocused = function() + self:setState({ Focused = true }) + self.props.OnFocused() + end + self.onFocusLost = function(_, enterPressed, inputObject) + self:setState({ Focused = false }) + self.props.OnFocusLost(enterPressed, inputObject) + end + self.onChanged = function(rbx) + self.props.OnChanged(rbx.Text) + end +end + +function TextInput:render() + local padding = Roact.createElement("UIPadding", { + PaddingLeft = UDim.new(0, 5), + PaddingRight = UDim.new(0, 5), + }) + local mainModifier = Enum.StudioStyleGuideModifier.Default + local borderModifier = Enum.StudioStyleGuideModifier.Default + if self.props.Disabled then + mainModifier = Enum.StudioStyleGuideModifier.Disabled + borderModifier = Enum.StudioStyleGuideModifier.Disabled + elseif self.state.Focused then + borderModifier = Enum.StudioStyleGuideModifier.Selected + elseif self.state.Hover then + borderModifier = Enum.StudioStyleGuideModifier.Hover + end + return withTheme(function(theme) + local textFieldProps = { + Size = UDim2.new(1, -5, 0, 21), -- temp + BackgroundColor3 = theme:GetColor(Enum.StudioStyleGuideColor.InputFieldBackground, mainModifier), + BorderColor3 = theme:GetColor(Enum.StudioStyleGuideColor.InputFieldBorder, borderModifier), + BorderMode = Enum.BorderMode.Inset, + LayoutOrder = self.props.LayoutOrder, + Font = Enum.Font.SourceSans, + Text = self.props.Text, + TextSize = 14, + TextColor3 = theme:GetColor(Enum.StudioStyleGuideColor.MainText, mainModifier), + TextXAlignment = Enum.TextXAlignment.Left, + } + return self.props.Disabled + and Roact.createElement("TextLabel", textFieldProps, { Padding = padding }) + or Roact.createElement( + "TextBox", + joinDictionaries(textFieldProps, { + PlaceholderText = self.props.PlaceholderText, + PlaceholderColor3 = PLACEHOLDER_TEXT_COLOR, + ClearTextOnFocus = self.props.ClearTextOnFocus, + [Roact.Event.Focused] = self.onFocused, + [Roact.Event.FocusLost] = self.onFocusLost, + [Roact.Event.InputBegan] = self.onInputBegan, + [Roact.Event.InputEnded] = self.onInputEnded, + [Roact.Change.Text] = self.onChanged, + }), + { + Padding = padding, + } + ) + end) +end + +return TextInput diff --git a/src/TextInput.story.lua b/src/TextInput.story.lua new file mode 100644 index 0000000..bba4383 --- /dev/null +++ b/src/TextInput.story.lua @@ -0,0 +1,44 @@ +local Vendor = script.Parent.Parent +local Roact = require(Vendor.Roact) + +local TextInput = require(script.Parent.TextInput) +local Checkbox = require(script.Parent.Checkbox) + +local Wrapper = Roact.Component:extend("TestWrapper") + +function Wrapper:init() + self:setState({ + Disabled = false, + }) +end + +function Wrapper:render() + return Roact.createFragment({ + Layout = Roact.createElement("UIListLayout", { + Padding = UDim.new(0, 5), + SortOrder = Enum.SortOrder.LayoutOrder, + FillDirection = Enum.FillDirection.Vertical, + }), + Input = Roact.createElement(TextInput, { + LayoutOrder = 0, + PlaceholderText = "Placeholder text", + Disabled = self.state.Disabled, + }), + Checkbox = Roact.createElement(Checkbox, { + LayoutOrder = 1, + Value = not self.state.Disabled, + Label = "Enable input", + OnActivated = function() + self:setState({ Disabled = not self.state.Disabled }) + end, + }), + }) +end + +return function(target) + local element = Roact.createElement(Wrapper) + local handle = Roact.mount(element, target) + return function() + Roact.unmount(handle) + end +end diff --git a/stylua.toml b/stylua.toml new file mode 100644 index 0000000..4ee8cf6 --- /dev/null +++ b/stylua.toml @@ -0,0 +1 @@ +column_width = 100 \ No newline at end of file