diff --git a/moonwave.toml b/moonwave.toml index 8f684a4..743ddb6 100644 --- a/moonwave.toml +++ b/moonwave.toml @@ -31,6 +31,7 @@ classes = [ "IconText", "Heading", "SwapInput", + "Slider", ] [docusaurus] diff --git a/samples/SettingsMenu/SettingsMenu.story.luau b/samples/SettingsMenu/SettingsMenu.story.luau index 3dc3615..2820ba9 100644 --- a/samples/SettingsMenu/SettingsMenu.story.luau +++ b/samples/SettingsMenu/SettingsMenu.story.luau @@ -13,29 +13,28 @@ local Components = { SettingsMenu = SettingsMenu, } -return function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) - local Theme = Themer.Theme:now() +return { + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) + local Theme = Themer.Theme:now() - Scope:Frame { - Parent = Parent, - Padding = Scope:Computed(function(Use) - return UDim.new(0, Use(Theme.StrokeThickness["1"])) - end), - ListEnabled = true, - ListFillDirection = Enum.FillDirection.Horizontal, - - [Children] = { - Scope:SettingsMenu {}, - Themer.Theme:is(BitCave):during(function() - return Scope:SettingsMenu { - Size = UDim2.fromOffset(380, 0), - } + Scope:Frame { + Parent = Props.target, + Padding = Scope:Computed(function(Use) + return UDim.new(0, Use(Theme.StrokeThickness["1"])) end), - }, - } + ListEnabled = true, + ListFillDirection = Enum.FillDirection.Horizontal, - return function() - Scope:doCleanup() - end -end + [Children] = { + Scope:SettingsMenu {}, + Themer.Theme:is(BitCave):during(function() + return Scope:SettingsMenu { + Size = UDim2.fromOffset(380, 0), + } + end), + }, + } + end, + fusion = Fusion, +} diff --git a/samples/SettingsMenu/init.luau b/samples/SettingsMenu/init.luau index db6113e..445b0e9 100644 --- a/samples/SettingsMenu/init.luau +++ b/samples/SettingsMenu/init.luau @@ -70,6 +70,9 @@ return function(Scope: Fusion.Scope, Props: Props) PlaceholderText = "Nickname", CharacterLimit = 20, }, + Scope:Slider { + Unit = 1 / 8, + }, }, }, Scope:Button { diff --git a/samples/Testing/ContextualPalette.story.luau b/samples/Testing/ContextualPalette.story.luau index 7b9e4ab..4cbce9a 100644 --- a/samples/Testing/ContextualPalette.story.luau +++ b/samples/Testing/ContextualPalette.story.luau @@ -46,32 +46,35 @@ local function Palette(Scope: Fusion.Scope, _: any) } end -return function(Parent: GuiObject) - local Scope = Fusion.scoped(Fusion, Components, { - Palette = Palette, - }) +return { + story = function(Props) + local Scope = Fusion.scoped(Fusion, Components, { + Palette = Palette, + }) - local AnotherTheme = Themer.NewTheme(Scope, { - Colors = { - Info = { Main = Util.Colors.Blue["600"] }, - }, - }) + local AnotherTheme = Themer.NewTheme(Scope, { + Colors = { + Info = { Main = Util.Colors.Blue["600"] }, + }, + }) - Scope:Base { - Parent = Parent, - ListEnabled = true, - ListFillDirection = Enum.FillDirection.Horizontal, - BackgroundTransparency = 1, + Scope:Base { + Parent = Props.target, + ListEnabled = true, + ListFillDirection = Enum.FillDirection.Horizontal, + BackgroundTransparency = 1, - [Children] = { - Scope:Palette {}, - Themer.Theme:is(AnotherTheme):during(function() - return Scope:Palette {} - end), - }, - } + [Children] = { + Scope:Palette {}, + Themer.Theme:is(AnotherTheme):during(function() + return Scope:Palette {} + end), + }, + } - return function() - Scope:doCleanup() - end -end + return function() + Scope:doCleanup() + end + end, + fusion = Fusion, +} diff --git a/src/Components/Avatar.story.luau b/src/Components/Avatar.story.luau index 0fc2cd7..08a739f 100644 --- a/src/Components/Avatar.story.luau +++ b/src/Components/Avatar.story.luau @@ -19,8 +19,8 @@ local INDICATOR_COLORS = { Util.Colors.Red["500"], Util.Colors.Green["400"], Util.Colors.Orange["500"], Util.Colors.Stone["600"] } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() local IndicatorColor = Scope:Value(INDICATOR_COLORS[2]) @@ -45,7 +45,7 @@ return { }) Scope:Frame { - Parent = Parent, + Parent = Props.target, Padding = Scope:Computed(function(Use) return UDim.new(0, Use(Theme.StrokeThickness["4"])) end), @@ -101,9 +101,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Badge.story.luau b/src/Components/Badge.story.luau index cd0c9ae..9eb70ae 100644 --- a/src/Components/Badge.story.luau +++ b/src/Components/Badge.story.luau @@ -18,8 +18,8 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() local NotificationCount = Scope:Value(0) @@ -42,7 +42,7 @@ return { }) Scope:Frame { - Parent = Parent, + Parent = Props.target, ListEnabled = true, ListPadding = Scope:Computed(function(Use) return UDim.new(0, Use(Theme.Spacing["0.5"])) @@ -94,9 +94,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Base.story.luau b/src/Components/Base.story.luau index 9ec73f2..67ba05c 100644 --- a/src/Components/Base.story.luau +++ b/src/Components/Base.story.luau @@ -4,15 +4,14 @@ local Themer = require(OnyxUI.Themer) local Components = require(OnyxUI.Components) local Children = Fusion.Children -local Scoped = Fusion.scoped return { - story = function(Parent: GuiObject) + story = function(Props) local Theme = Themer.Theme:now() - local Scope = Scoped(Fusion, Components) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) Scope:Base { - Parent = Parent, + Parent = Props.target, ListEnabled = true, Padding = Scope:Computed(function(Use) return UDim.new(0, Use(Theme.StrokeThickness["4"])) @@ -106,9 +105,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Button.story.luau b/src/Components/Button.story.luau index 94cd5e4..8bbd082 100644 --- a/src/Components/Button.story.luau +++ b/src/Components/Button.story.luau @@ -16,13 +16,12 @@ local Components = { } return { - clipsDescendants = false, - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, ListEnabled = true, ListPadding = Scope:Computed(function(Use) return UDim.new(0, Use(Theme.Spacing["0.5"])) @@ -108,9 +107,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Card.story.luau b/src/Components/Card.story.luau index 961ca3c..f0b92cb 100644 --- a/src/Components/Card.story.luau +++ b/src/Components/Card.story.luau @@ -18,12 +18,12 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, Size = UDim2.fromOffset(300, 0), AutomaticSize = Enum.AutomaticSize.Y, ListEnabled = true, @@ -61,9 +61,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Checkbox.story.luau b/src/Components/Checkbox.story.luau index 6799f70..183607d 100644 --- a/src/Components/Checkbox.story.luau +++ b/src/Components/Checkbox.story.luau @@ -15,12 +15,12 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, Padding = Scope:Computed(function(Use) return UDim.new(0, Use(Theme.StrokeThickness["1"])) end), @@ -49,9 +49,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Divider.story.luau b/src/Components/Divider.story.luau index c8d0ca3..c7d1cc6 100644 --- a/src/Components/Divider.story.luau +++ b/src/Components/Divider.story.luau @@ -16,12 +16,12 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, Size = UDim2.fromOffset(300, 0), AutomaticSize = Enum.AutomaticSize.Y, ListEnabled = true, @@ -42,9 +42,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Heading.story.luau b/src/Components/Heading.story.luau index 963555d..b925e8d 100644 --- a/src/Components/Heading.story.luau +++ b/src/Components/Heading.story.luau @@ -16,12 +16,12 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, ListEnabled = true, ListPadding = Scope:Computed(function(Use) return UDim.new(0, Use(Theme.Spacing["0.5"])) @@ -29,7 +29,7 @@ return { [Children] = { Scope:Heading { - Parent = Parent, + Parent = Props.target, Text = "Heading", }, Scope:Text { @@ -37,9 +37,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Icon.story.luau b/src/Components/Icon.story.luau index 465e990..5d487e2 100644 --- a/src/Components/Icon.story.luau +++ b/src/Components/Icon.story.luau @@ -9,16 +9,13 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) Scope:Icon { - Parent = Parent, + Parent = Props.target, Image = "rbxassetid://11560341132", } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/IconButton.story.luau b/src/Components/IconButton.story.luau index d42e922..232e468 100644 --- a/src/Components/IconButton.story.luau +++ b/src/Components/IconButton.story.luau @@ -15,12 +15,12 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, Padding = Scope:Computed(function(Use) return UDim.new(0, Use(Theme.StrokeThickness["1"])) end), @@ -63,9 +63,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/IconText.story.luau b/src/Components/IconText.story.luau index eab3e97..827e245 100644 --- a/src/Components/IconText.story.luau +++ b/src/Components/IconText.story.luau @@ -9,11 +9,11 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) Scope:IconText { - Parent = Parent, + Parent = Props.target, Content = { "Here's a shop icon: ", "rbxassetid://75029721407761", @@ -23,9 +23,6 @@ return { ". Now you can easily have both text and icons!", }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Image.story.luau b/src/Components/Image.story.luau index fce798f..0dbde1f 100644 --- a/src/Components/Image.story.luau +++ b/src/Components/Image.story.luau @@ -14,12 +14,12 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, AutomaticSize = Enum.AutomaticSize.XY, ListEnabled = true, ListFillDirection = Enum.FillDirection.Horizontal, @@ -37,9 +37,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/MenuFrame.story.luau b/src/Components/MenuFrame.story.luau index 7dbe590..4514515 100644 --- a/src/Components/MenuFrame.story.luau +++ b/src/Components/MenuFrame.story.luau @@ -16,12 +16,12 @@ local Components = { } return { - story = function(Parent: GuiObject, _Props) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, Padding = Scope:Computed(function(Use) return UDim.new(0, Use(Theme.StrokeThickness["1"])) end), @@ -30,7 +30,7 @@ return { [Children] = { Scope:MenuFrame { - Parent = Parent, + Parent = Props.target, Size = UDim2.fromOffset(300, 200), AutomaticSize = Enum.AutomaticSize.None, @@ -42,9 +42,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/NumberSpinner.story.luau b/src/Components/NumberSpinner.story.luau index 82d03cd..6d1ade1 100644 --- a/src/Components/NumberSpinner.story.luau +++ b/src/Components/NumberSpinner.story.luau @@ -14,8 +14,8 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local RandomNumber = Scope:Value(0) local RandomDecimalNumber = Scope:Value(0) @@ -46,7 +46,7 @@ return { }) Scope:Frame { - Parent = Parent, + Parent = Props.target, Size = UDim2.fromOffset(300, 0), AutomaticSize = Enum.AutomaticSize.Y, ListEnabled = true, @@ -68,9 +68,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/ProgressBar.story.luau b/src/Components/ProgressBar.story.luau index 9c8ca2b..15d3e1e 100644 --- a/src/Components/ProgressBar.story.luau +++ b/src/Components/ProgressBar.story.luau @@ -19,8 +19,8 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() local Progress = Scope:Value(0) @@ -40,7 +40,7 @@ return { }) Scope:Frame { - Parent = Parent, + Parent = Props.target, ListEnabled = true, ListHorizontalFlex = Enum.UIFlexAlignment.Fill, ListPadding = Scope:Computed(function(Use) @@ -198,9 +198,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Scroller.story.luau b/src/Components/Scroller.story.luau index 3af42db..0c6e7ab 100644 --- a/src/Components/Scroller.story.luau +++ b/src/Components/Scroller.story.luau @@ -9,18 +9,15 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) Scope:Scroller { - Parent = Parent, + Parent = Props.target, Size = UDim2.fromOffset(200, 200), CanvasSize = UDim2.new(UDim.new(1, 0), UDim.new(0, 1000)), AutomaticCanvasSize = Enum.AutomaticSize.None, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Slider.luau b/src/Components/Slider.luau new file mode 100644 index 0000000..6431040 --- /dev/null +++ b/src/Components/Slider.luau @@ -0,0 +1,225 @@ +--[=[ + @class Slider + + For draggable linear selection. +]=] + +local OnyxUI = script.Parent.Parent + +local Fusion = require(OnyxUI.Parent.Fusion) +local Themer = require(OnyxUI.Themer) +local Util = require(OnyxUI.Util) +local ColorUtils = require(OnyxUI.Parent.ColorUtils) + +local InnerScope = Fusion.innerScope +local Children = Fusion.Children +local Out = Fusion.Out +local OnEvent = Fusion.OnEvent + +local BaseButton = require(script.Parent.BaseButton) +local Components = { + BaseButton = BaseButton, +} + +function RoundByUnit(Number, Factor) + return math.floor(Number / Factor + 0.5) * Factor +end + +local DISABLED_BACKGROUND_TRANSPARENCY = 0.925 + +export type Props = BaseButton.Props & { + Value: Fusion.UsedAs?, + Disabled: Fusion.UsedAs?, + Unit: Fusion.UsedAs?, + Color: Fusion.UsedAs?, +} + +--[=[ + @within Slider + @interface SliderProps + + @field ... FrameProps + @field Value Fusion.UsedAs? + @field Disabled Fusion.UsedAs? + @field Unit Fusion.UsedAs? + @field Color Fusion.UsedAs? +]=] +return function(Scope: Fusion.Scope, Props: Props) + local Scope = InnerScope(Scope, Fusion, Util, Components) + local Theme = Themer.Theme:now() + + local Unit = Util.Fallback(Props.Unit, 1 / 100) + local Value = Scope:EnsureValue(RoundByUnit(Util.Fallback(Props.Value, 1), Fusion.peek(Unit))) + local Color = Util.Fallback(Props.Color, Theme.Colors.Primary.Main) + local Disabled = Util.Fallback(Props.Disabled, false) + local IsHovering = Scope:EnsureValue(Util.Fallback(Props.IsHovering, false)) + local IsHolding = Scope:EnsureValue(Util.Fallback(Props.IsHolding, false)) + + local DragDetector = Scope:Value(nil) + local AbsoluteSize = Scope:Value(Vector2.new()) + local AbsolutePosition = Scope:Value(Vector2.new()) + + local EffectiveColor = Scope:Computed(function(Use) + if Use(Disabled) then + return Use(Theme.Colors.BaseContent.Main) + else + if Use(IsHolding) then + return ColorUtils.Emphasize(Use(Color), Use(Theme.Emphasis.Regular)) + elseif Use(IsHovering) then + return ColorUtils.Emphasize(Use(Color), Use(Theme.Emphasis.Light)) + else + return Use(Color) + end + end + end) + + local function ProcessDrag(Position: Vector2) + local AbsoluteSizeValue = Fusion.peek(AbsoluteSize) + local AbsolutePositionValue = Fusion.peek(AbsolutePosition) + local UnitValue = Fusion.peek(Unit) + + local RelativePosition = Position.X - AbsolutePositionValue.X + + Value:set(RoundByUnit(math.clamp(RelativePosition / AbsoluteSizeValue.X, 0, 1), UnitValue)) + end + + local Slider = Scope:BaseButton(Util.CombineProps(Props, { + Name = script.Name, + CornerRadius = Scope:Computed(function(Use) + return UDim.new(0, Use(Theme.CornerRadius.Full)) + end), + Size = Scope:Computed(function(Use) + return UDim2.fromOffset(0, Use(Theme.TextSize["1"])) + end), + AutomaticSize = Enum.AutomaticSize.Y, + Disabled = Disabled, + IsHovering = IsHovering, + + [Children] = { + DragDetector, + Scope:Hydrate(Scope:Frame { + Name = "Progress", + CornerRadius = Scope:Computed(function(Use) + return UDim.new(0, Use(Theme.CornerRadius.Full)) + end), + BackgroundTransparency = 0, + BackgroundColor3 = Theme.Colors.Neutral.Main, + Size = Scope:Computed(function(Use) + return UDim2.new(UDim.new(1, 0), UDim.new(0, Use(Theme.TextSize["0.75"]))) + end), + FlexMode = Enum.UIFlexMode.Fill, + + [Children] = { + Scope:Frame { + Name = "Progress", + Size = Scope:Computed(function(Use) + local ValueValue = Use(Value) + return UDim2.fromScale(ValueValue, 1) + end), + BackgroundTransparency = Scope:Computed(function(Use) + if Use(Disabled) then + return DISABLED_BACKGROUND_TRANSPARENCY + else + return 0 + end + end), + BackgroundColor3 = Scope:Spring( + EffectiveColor, + Theme.SpringSpeed["1"], + Theme.SpringDampening["1"] + ), + CornerRadius = Scope:Computed(function(Use) + return UDim.new(0, Use(Theme.CornerRadius.Full)) + end), + AutomaticSize = Enum.AutomaticSize.None, + + [Children] = { + Scope:Frame { + Name = "Ball", + AspectRatio = 1, + AnchorPoint = Scope:Computed(function(Use) + local ValueValue = Use(Value) + return Vector2.new(ValueValue, 0.5) + end), + Position = UDim2.fromScale(1, 0.5), + Size = Scope:Computed(function(Use) + local Offset = Use(Theme.TextSize["1"]) + return UDim2.fromOffset(Offset, Offset) + end), + BackgroundTransparency = 0, + BackgroundColor3 = Scope:Computed(function(Use) + if Use(Disabled) then + return Use(Theme.Colors.Neutral.Main) + else + return Use(Theme.Colors.BaseContent.Main) + end + end), + CornerRadius = Scope:Computed(function(Use) + return UDim.new(0, Use(Theme.CornerRadius.Full)) + end), + StrokeEnabled = true, + StrokeColor = Theme.Colors.Neutral.Main, + StrokeThickness = Theme.StrokeThickness["1"], + AutomaticSize = Enum.AutomaticSize.None, + + [Children] = { + Scope:Frame { + Name = "SmallBall", + AspectRatio = 1, + AnchorPoint = Vector2.new(0.5, 0.5), + Position = UDim2.fromScale(0.5, 0.5), + Size = Scope:Computed(function(Use) + local Offset = Use(Theme.TextSize["0.75"]) + return UDim2.fromOffset(Offset, Offset) + end), + BackgroundTransparency = 0, + BackgroundColor3 = Scope:Spring( + Scope:Computed(function(Use) + if Use(Disabled) then + return Use(Theme.Colors.Neutral.Dark) + else + return Use(EffectiveColor) + end + end), + Theme.SpringSpeed["1"], + Theme.SpringDampening["1"] + ), + CornerRadius = Scope:Computed(function(Use) + return UDim.new(0, Use(Theme.CornerRadius.Full)) + end), + AutomaticSize = Enum.AutomaticSize.None, + }, + }, + }, + }, + }, + }, + }) { + [Out "AbsoluteSize"] = AbsoluteSize, + [Out "AbsolutePosition"] = AbsolutePosition, + }, + }, + })) + + DragDetector:set(Scope:New "UIDragDetector" { + DragStyle = Enum.UIDragDetectorDragStyle.Scriptable, + DragAxis = Vector2.new(1, 0), + BoundingUI = Slider, + Enabled = Scope:Computed(function(Use) + return not Use(Disabled) + end), + + [OnEvent "DragContinue"] = function(Position: Vector2) + ProcessDrag(Position) + end, + [OnEvent "DragStart"] = function(Position: Vector2) + ProcessDrag(Position) + IsHolding:set(true) + end, + [OnEvent "DragEnd"] = function() + IsHolding:set(false) + end, + }) + + return Slider +end diff --git a/src/Components/Slider.story.luau b/src/Components/Slider.story.luau new file mode 100644 index 0000000..b0f7f74 --- /dev/null +++ b/src/Components/Slider.story.luau @@ -0,0 +1,53 @@ +local OnyxUI = script.Parent.Parent +local Fusion = require(OnyxUI.Parent.Fusion) +local Util = require(OnyxUI.Util) +local Themer = require(OnyxUI.Themer) + +local Scoped = Fusion.scoped +local Children = Fusion.Children + +local Components = { + Slider = require(OnyxUI.Components.Slider), + Frame = require(OnyxUI.Components.Frame), +} + +return { + story = function(Props) + local Scope = Scoped(Fusion, Util, Components) + local Theme = Themer.Theme:now() + + Scope:Frame { + Parent = Props.target, + Size = Scope:Computed(function(Use) + return UDim2.fromOffset(Use(Theme.Spacing["16"]), 0) + end), + AutomaticSize = Enum.AutomaticSize.Y, + Padding = Scope:Computed(function(Use) + return UDim.new(0, Use(Theme.StrokeThickness["1"])) + end), + ListEnabled = true, + ListPadding = Scope:Computed(function(Use) + return UDim.new(0, Use(Theme.Spacing["1"])) + end), + ListHorizontalFlex = Enum.UIFlexAlignment.Fill, + + [Children] = { + Scope:Slider {}, + Scope:Slider { + Value = 1 / 10, + Unit = 1 / 10, + Color = Util.Colors.Cyan["500"], + }, + Scope:Slider { + Value = 1 / 4, + Unit = 1 / 4, + Color = Util.Colors.Fuchsia["500"], + }, + Scope:Slider { + Disabled = true, + }, + }, + } + end, + fusion = Fusion, +} diff --git a/src/Components/SwapInput.story.luau b/src/Components/SwapInput.story.luau index 6f0723c..4899499 100644 --- a/src/Components/SwapInput.story.luau +++ b/src/Components/SwapInput.story.luau @@ -12,12 +12,12 @@ local Components = { } return { - story = function(Parent: GuiObject) + story = function(Props) local Scope = Scoped(Fusion, Util, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, Size = Scope:Computed(function(Use) return UDim2.fromOffset(Use(Theme.Spacing["16"]), 0) end), @@ -45,9 +45,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/SwitchInput.story.luau b/src/Components/SwitchInput.story.luau index a0f3386..47a8d55 100644 --- a/src/Components/SwitchInput.story.luau +++ b/src/Components/SwitchInput.story.luau @@ -14,12 +14,12 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, Padding = Scope:Computed(function(Use) return UDim.new(0, Use(Theme.StrokeThickness["1"])) end), @@ -35,9 +35,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/Text.story.luau b/src/Components/Text.story.luau index dedcd33..b48d9ef 100644 --- a/src/Components/Text.story.luau +++ b/src/Components/Text.story.luau @@ -9,16 +9,13 @@ local Components = { } return { - story = function(Parent: GuiObject) + story = function(Props) local Scope = Scoped(Fusion, Util, Components) Scope:Text { - Parent = Parent, + Parent = Props.target, Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/TextArea.story.luau b/src/Components/TextArea.story.luau index 2caebc7..1263e3c 100644 --- a/src/Components/TextArea.story.luau +++ b/src/Components/TextArea.story.luau @@ -14,12 +14,12 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, Size = UDim2.fromOffset(250, 0), AutomaticSize = Enum.AutomaticSize.Y, ListEnabled = true, @@ -51,9 +51,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/TextInput.story.luau b/src/Components/TextInput.story.luau index 3ae5311..6f1c250 100644 --- a/src/Components/TextInput.story.luau +++ b/src/Components/TextInput.story.luau @@ -14,12 +14,12 @@ local Components = { } return { - story = function(Parent: GuiObject) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, Size = UDim2.fromOffset(250, 0), AutomaticSize = Enum.AutomaticSize.Y, ListEnabled = true, @@ -47,9 +47,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/TitleBar.story.luau b/src/Components/TitleBar.story.luau index 7e3dc79..8efa0de 100644 --- a/src/Components/TitleBar.story.luau +++ b/src/Components/TitleBar.story.luau @@ -14,12 +14,12 @@ local Components = { } return { - story = function(Parent: GuiObject, _Props) - local Scope = Scoped(Fusion, Components) + story = function(Props) + local Scope = Fusion.innerScope(Props.scope, Fusion, Components) local Theme = Themer.Theme:now() Scope:Frame { - Parent = Parent, + Parent = Props.target, Padding = Scope:Computed(function(Use) return UDim.new(0, Use(Theme.StrokeThickness["1"])) end), @@ -39,9 +39,6 @@ return { }, }, } - - return function() - Scope:doCleanup() - end end, + fusion = Fusion, } diff --git a/src/Components/init.luau b/src/Components/init.luau index 2c035d9..7a2356b 100644 --- a/src/Components/init.luau +++ b/src/Components/init.luau @@ -28,6 +28,7 @@ local Components = { TextArea = require(script.TextArea), TitleBar = require(script.TitleBar), SwapInput = require(script.SwapInput), + Slider = require(script.Slider), } task.spawn(function() diff --git a/wally.toml b/wally.toml index 77d6031..0f221e9 100644 --- a/wally.toml +++ b/wally.toml @@ -1,7 +1,7 @@ [package] name = "imavafe/onyx-ui" description = "Quick, quality UI for Fusion" -version = "0.5.0" +version = "0.5.1" license = "MIT" authors = ["Avafe"]