diff --git a/docs/tut/crash-course/2-creation.md b/docs/tut/crash-course/2-creation.md index 71a231a..ebfc922 100644 --- a/docs/tut/crash-course/2-creation.md +++ b/docs/tut/crash-course/2-creation.md @@ -44,7 +44,6 @@ To connect to an event, just set the event property name to a function. All event arguments are passed into the function. - ```lua create "TextButton" { Activated = function() @@ -53,8 +52,6 @@ create "TextButton" { } ``` -## Summary - In short: - String keys = properties diff --git a/docs/tut/crash-course/4-state.md b/docs/tut/crash-course/4-state.md index e66f417..e4bdb3a 100644 --- a/docs/tut/crash-course/4-state.md +++ b/docs/tut/crash-course/4-state.md @@ -1,6 +1,9 @@ # [State](./index.md) -State in Vide are special objects that store data. +State in Vide are the core of reactivity in Vide. + +State contain values that can change, and when they do change, automatically +update anything that is using it. A state object in Vide can be created using [`source()`](../../api/reactivity-core.md#source). @@ -10,14 +13,14 @@ local source = vide.source ``` ```lua --- create a new source local count = source(0) +``` --- set source value -count(10) +The value of a state can be set by calling it with an argument, and can be read +by calling it with no arguments. --- get source value -print(count()) -- "10" +```lua +count(count() + 1) -- increment count state by 1 ``` Below is an example of a counter component that has state. @@ -27,11 +30,11 @@ local function Counter() local count = source(0) return create "TextButton" { - Text = count + Text = count, Activated = function() count(count() + 1) - end, + end } end ``` diff --git a/docs/tut/crash-course/5-derived-state.md b/docs/tut/crash-course/5-derived-state.md index c649758..9fa89c2 100644 --- a/docs/tut/crash-course/5-derived-state.md +++ b/docs/tut/crash-course/5-derived-state.md @@ -3,6 +3,10 @@ You can create new state from existing states. This is known as *deriving state*. +A function that wraps a state effectively becomes a state. If a state used +inside a function is updated, the whole function can be re-ran to recompute +its value. + ```lua local count = source(0) @@ -15,12 +19,14 @@ create "TextLabel" { } ``` -Assigning a non-event property a function will bind that property to that -function, anytime a state being read from inside that function is changed, the -function will be re-ran and the property value updated. - Sometimes when using expensive computations to derive state, you only want to -recalculate it when a source state has changed. +recalculate it once when a source state has changed + +If you wrap a source state with a regular function, its value will be recomputed +every time you call that function. +[`derive()`](../../api/reactivity-core.md#derive) accepts a functions whose +return value will be cached, so that subsequent calls of this derived state +will return the same cached value until one of its source states have changed. ```lua local derive = vide.derive @@ -38,18 +44,17 @@ local factorial = derive(function() end) ``` -`derive()` will cache and return the same value until a source state has -changed, where it will recompute and cache a new value. +This can improve performance for expensive calculations. ```lua create "TextLabel" { Text = function() - return "factorial: " .. factorial() + return "factorial squared: " .. factorial() * factorial() end } -count(3) -- displays "factorial: 6" -count(4) -- displays "factorial: 24" +count(3) -- displays "factorial squared: 36" +count(4) -- displays "factorial squared: 576" ``` -------------------------------------------------------------------------------- diff --git a/docs/tut/crash-course/7-property-groups.md b/docs/tut/crash-course/7-property-groups.md index 65ee8c6..09c22c9 100644 --- a/docs/tut/crash-course/7-property-groups.md +++ b/docs/tut/crash-course/7-property-groups.md @@ -1,8 +1,43 @@ # [Property Groups](./index.md) -When a key is assigned a table, Vide does not attempt to assign it to a -property, instead, the table is iterated and processed just like the nesting -table. +Often when creating components from existing components, you can find yourself +repetitively passing through properties such as size or position. + +```lua +function Background(props: { + Color: Color3, + AnchorPoint: UDim2, + Position: UDim2, + Size: UDim2 +}) + return create "Frame" { + Color = props.Color + AnchorPoint = props.AnchorPoint, + Position = props.Position, + Size = props.Size + } +end + +function Menu(props: { + Color = props.Color + AnchorPoint: UDim2, + Position: UDim2, + Size: UDim2 +}) + return Background { + Color = props.COlor, + AnchorPoint = props.AnchorPoint, + Position = props.Position, + Size = props.Size + } +end +``` + +One way this can be avoided is by using *property nesting*. In Vide, passign a +table value inside `props` has special semantics. Any key with a table value is +not assigned like a property, instead the table is iterated and processed just +like the outer table is. Any properties in the nested table will be assigned +to the instance just the same. Below is an example of how you can use this to pass groups of similar properties together such as position and size, while also using typechecking. @@ -16,48 +51,36 @@ type Layout = { } } -local function Button(args: Layout & { - Text: string, - Callback: () -> () -}) - local count = source(0) - - return create "TextButton" { - Text = args.Text - Activated = args.Callback, - Layout = args.Layout +function Background(props: Layout & { Color: Color3 }) + return create "Frame" { + Color = props.Color, + props.Layout } end -Button { - Text = "Click me!", - - Callback = function() - print "clicked me!" - end, - - Layout = { - Position = UDim2.new(), - Size = UDim2.new() +function Menu(props: Layout & { Color: Color3 }) + return Background { + Color = props.Color, + Layout = props.Layout } -} +end ``` -Here the button component is assigned a position and size as if you passed those -properties directly. +Here we created a nested group with the key `Layout` that can accept +layout-related properties. Any name could be chosen for the key. +This allows us to write much more concise syntax that is also typecheckable. -The same can be done for properties such as children. +The same can be done for properties such as children to pass table of instances. ```lua type Children = { Children = Array } -local function List(args: Children & Layout) +local function List(props: Children & Layout) return create "Frame" { - Layout = args.Layout, - Children = args.Children, - + props.Layout, + props.Children, create "UIListLayout" {} } end @@ -68,7 +91,8 @@ List { }, Children = { - create "TextLabel" { Text = "1" } + create "TextLabel" { Text = "1" }, + create "TextLabel" { Text = "2" } } } ```