From eaa8fe06551bea3656c3553bb321357f63c76d47 Mon Sep 17 00:00:00 2001 From: sindri <33976067+isarsindri@users.noreply.github.com> Date: Mon, 2 Mar 2026 13:41:22 +0100 Subject: [PATCH] Enhance Menu component with Slider example and SliderProps (slider.luau) --- docs/tut/crash-course/3-components.md | 139 ++++++++++++++++++++++---- 1 file changed, 122 insertions(+), 17 deletions(-) diff --git a/docs/tut/crash-course/3-components.md b/docs/tut/crash-course/3-components.md index 0b803ca..aead305 100644 --- a/docs/tut/crash-course/3-components.md +++ b/docs/tut/crash-course/3-components.md @@ -1,4 +1,4 @@ -# Components +image# Components Vide encourages separating different parts of your UI into functions called *components*. @@ -36,30 +36,135 @@ return Button ```luau [Menu.luau] local create = vide.create +local source = vide.source +local effect = vide.effect local Button = require(Button) +local Slider = require(Slider) + +local fov = source(70) + +effect(function() + local cam = workspace.CurrentCamera + if cam then + cam.FieldOfView = fov() + end +end) local function Menu() - return create "ScreenGui" { - Button { - Position = UDim2.fromOffset(200, 200), - Text = "back", - Activated = function() - print "go to previous page" - end - }, + return create "ScreenGui" { + Button { + Position = UDim2.fromOffset(200, 200), + Text = "back", + Activated = function() + print "go to previous page" + end + }, - Button { - Position = UDim2.fromOffset(400, 200), - Text = "next", - Activated = function() - print "go to next page" - end - } - } + Button { + Position = UDim2.fromOffset(400, 200), + Text = "next", + Activated = function() + print "go to next page" + end + }, + + -- Settings menu panel (example usage of Slider component) + create "Frame" { + AnchorPoint = Vector2.new(0, 1), + Position = UDim2.fromOffset(24, 560), + Size = UDim2.fromOffset(560, 220), + BackgroundTransparency = 0.1, + + create "UICorner" { CornerRadius = UDim.new(0, 16) }, + create "UIPadding" { + PaddingTop = UDim.new(0, 16), + PaddingBottom = UDim.new(0, 16), + PaddingLeft = UDim.new(0, 16), + PaddingRight = UDim.new(0, 16), + }, + + create "UIListLayout" { + Padding = UDim.new(0, 14), + HorizontalAlignment = Enum.HorizontalAlignment.Center, + SortOrder = Enum.SortOrder.LayoutOrder, + }, + + create "TextLabel" { + LayoutOrder = 0, + BackgroundTransparency = 1, + Size = UDim2.fromOffset(528, 28), + TextXAlignment = Enum.TextXAlignment.Left, + TextSize = 20, + Text = "Settings", + }, + + Slider { + layoutOrder = 1, + label = "Camera FOV", + min = 60, + max = 90, + step = 1, + value = fov, + format = function(v) + return string.format("%d", math.floor(v + 0.5)) + end, + }, + }, + } end + +return Menu ``` +```luau [slider.luau] +l-- Example of a component that wraps the built-in slider component. +-- This keeps a consistent "component(props) -> Instance" style. + +local source = vide.source + +export type SliderTheme = { + trackColor: Color3?, + trackTransparency: number?, + fillColor: Color3?, + fillTransparency: number?, + knobColor: Color3?, + knobTransparency: number?, + strokeColor: Color3?, + strokeTransparency: number?, + cornerRadius: number?, + knobRadius: number?, +} + +export type SliderProps = { + -- required + value: source.source, + + -- range + min: number?, + max: number?, + step: number?, + + -- text + label: string?, + format: ((number) -> string)?, + onChanged: ((number) -> ())?, + + -- layout + size: UDim2?, + position: UDim2?, + anchorPoint: Vector2?, + layoutOrder: number?, + + -- style + theme: SliderTheme?, +} + +local function Slider(props: SliderProps) + return vide.slider(props) +end + +return Slider ::: A single parameter `props` is used to pass properties to the component.