mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
Update docs
This commit is contained in:
parent
97096f8aff
commit
85b1127551
15 changed files with 200 additions and 298 deletions
|
|
@ -53,17 +53,9 @@ export default defineConfig({
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: "Control Flow WIP",
|
text: "Advanced Reactivity",
|
||||||
items: [
|
items: [
|
||||||
{ text: "switch", link: "/tut/control-flow/switch.md" },
|
{ text: "Reactive Scopes", link: "/tut/advanced/reactive-scoping.md"}
|
||||||
{ text: "indexes", link: "/tut/control-flow/indexes.md" },
|
|
||||||
{ text: "values", link: "/tut/control-flow/values.md" },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: "Advanced Reactivity WIP",
|
|
||||||
items: [
|
|
||||||
{ text: "reactive-scopes", link: "/tut/reactive-scoping.md"}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,33 @@
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
## show()
|
||||||
|
|
||||||
|
Shows one of two components depending on an input source.
|
||||||
|
|
||||||
|
- **Type**
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function show<T>(source: () -> unknown, component: () -> T): () -> T?
|
||||||
|
function show<T, U>(source: () -> unknown, component: () -> T, fallback: () -> U): () -> T | U
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Details**
|
||||||
|
|
||||||
|
Returns a source holding an instance of the currently shown component.
|
||||||
|
|
||||||
|
When the input source changes from a falsey to a truthy value, the
|
||||||
|
component will be reran under a new reactive scope. If it changes from a
|
||||||
|
truthy to falsey value, the reactive scope the component was created in will
|
||||||
|
be destroyed, and the returned source will output `nil`, or a fallback
|
||||||
|
component if given.
|
||||||
|
|
||||||
|
The fallback component is also ran under a new reactive scope, and destroyed
|
||||||
|
when the input source switches back to truthy.
|
||||||
|
|
||||||
## switch()
|
## switch()
|
||||||
|
|
||||||
Changes object based on a source and a mapping table.
|
Shows one of a set of components depending on an input source and a mapping table.
|
||||||
|
|
||||||
- **Type**
|
- **Type**
|
||||||
|
|
||||||
|
|
@ -14,12 +38,14 @@ Changes object based on a source and a mapping table.
|
||||||
|
|
||||||
- **Details**
|
- **Details**
|
||||||
|
|
||||||
The mapped function is ran in a new reactive scope that is destroyed when
|
Returns a source holding an instance of the currently shown component.
|
||||||
the source changes and maps to a different function.
|
|
||||||
|
|
||||||
::: warning
|
When the input source changes, the new value will be used to lookup a given
|
||||||
Mapped functions cannot yield.
|
mapping table to get a component, which will be ran under a new reactive
|
||||||
:::
|
scope. If the input source changes, the reactive scope the component was
|
||||||
|
created in will be destroyed, and a new component created under a new
|
||||||
|
reactive scope. If no component is found for an input value, the switch will
|
||||||
|
output `nil`.
|
||||||
|
|
||||||
- **Example**
|
- **Example**
|
||||||
|
|
||||||
|
|
@ -51,24 +77,26 @@ Maps each index in a table source to an object.
|
||||||
|
|
||||||
- **Details**
|
- **Details**
|
||||||
|
|
||||||
|
Returns a source holding an array of instances currently shown.
|
||||||
|
|
||||||
|
When the input source changes, each *index* in the new table is compared with
|
||||||
|
the last input table.
|
||||||
|
|
||||||
|
- For any new index, the `transform` function is ran under a new reactive
|
||||||
|
scope to produce a new instance.
|
||||||
|
- For any removed index, the reactive scope for that index is destroyed.
|
||||||
|
- Unchanged indexes are untouched.
|
||||||
|
|
||||||
The transform function is called only ever *once* for each index in the
|
The transform function is called only ever *once* for each index in the
|
||||||
source table. The first argument is a source containing the index's value
|
source table.
|
||||||
and the second argument is just the index.
|
|
||||||
|
|
||||||
Anytime a new index is added, the transform function will be called again
|
1. First argument is a *source containing the index's value*.
|
||||||
for that new index.
|
2. Second argument is the *index itself*.
|
||||||
|
|
||||||
Anytime an existing index value changes, the transform function is not rerun,
|
Anytime an existing index's value changes, the transform function is not
|
||||||
instead the source value for that index will update, causing anything
|
rerun, instead the source value for that index will update, causing anything
|
||||||
depending on it to update too.
|
depending on it to update too.
|
||||||
|
|
||||||
Returns a state containing an array of all objects returned by the
|
|
||||||
transform.
|
|
||||||
|
|
||||||
::: warning
|
|
||||||
`transform()` cannot yield.
|
|
||||||
:::
|
|
||||||
|
|
||||||
- **Example**
|
- **Example**
|
||||||
|
|
||||||
The intended purpose of this function is to map each index in a table to
|
The intended purpose of this function is to map each index in a table to
|
||||||
|
|
@ -85,14 +113,12 @@ Maps each index in a table source to an object.
|
||||||
local displays = indexes(items, function(item, i)
|
local displays = indexes(items, function(item, i)
|
||||||
return ItemDisplay {
|
return ItemDisplay {
|
||||||
Name = function()
|
Name = function()
|
||||||
return item().name
|
return i .. ": " .. item().name
|
||||||
end,
|
end,
|
||||||
|
|
||||||
Image = function()
|
Image = function()
|
||||||
return "rbxassetid://" .. item().icon
|
return "rbxassetid://" .. item().icon
|
||||||
end,
|
end,
|
||||||
|
|
||||||
LayoutOrder = i
|
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
```
|
```
|
||||||
|
|
@ -111,28 +137,31 @@ Maps each value in a table source to an object.
|
||||||
|
|
||||||
- **Details**
|
- **Details**
|
||||||
|
|
||||||
The transform function is called only ever *once* for each value in the
|
Returns a source holding an array of instances currently shown.
|
||||||
source table. The first argument is the index's value and
|
|
||||||
the second argument is a source containing the index.
|
|
||||||
|
|
||||||
Anytime a new value is added, the transform function will be called again
|
When the input source changes, each *value* in the new table is compared with
|
||||||
for that new value.
|
the last input table. Similar to `indexes()` but for values instead of indexes.
|
||||||
|
|
||||||
|
- For any new value, the `transform` function is ran under a new reactive
|
||||||
|
scope to produce a new instance.
|
||||||
|
- For any removed value, the reactive scope for that value is destroyed.
|
||||||
|
- Unchanged values are untouched.
|
||||||
|
|
||||||
|
The transform function is only ever called *once* for each value in the
|
||||||
|
source table.
|
||||||
|
|
||||||
|
1. First argument is the *value itself*.
|
||||||
|
2. Second argument is a *source containing the value's index*.
|
||||||
|
|
||||||
Anytime an existing value's index changes, the transform function is not
|
Anytime an existing value's index changes, the transform function is not
|
||||||
rerun, instead the source index for that value will update, causing anything
|
rerun, instead the source index for that value will update, causing anything
|
||||||
depending on it to update too.
|
depending on it to update too.
|
||||||
|
|
||||||
Returns a state containing an array of all objects returned by the
|
|
||||||
transform.
|
|
||||||
|
|
||||||
::: warning
|
::: warning
|
||||||
`transform()` cannot yield.
|
Having primitive values in the input source table can cause unexpected
|
||||||
:::
|
behavior, as duplicate values can result in multiple tranforms being ran for
|
||||||
|
a single value, meaning there can be multiple source indexes bound to the
|
||||||
::: warning
|
same UI element. Strict mode has checks for this.
|
||||||
Having primitive values in the source table can cause unexpected behavior,
|
|
||||||
as duplicate primitives can result in multiple index sources being bound
|
|
||||||
to the same UI element.
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
- **Example**
|
- **Example**
|
||||||
|
|
@ -150,11 +179,11 @@ Maps each value in a table source to an object.
|
||||||
|
|
||||||
local displays = values(items, function(item, i)
|
local displays = values(items, function(item, i)
|
||||||
return ItemDisplay {
|
return ItemDisplay {
|
||||||
Name = item.Name
|
Name = function()
|
||||||
|
return i() .. ": " .. item.Name
|
||||||
|
end
|
||||||
|
|
||||||
Image = "rbxassetid://" .. item.icon,
|
Image = "rbxassetid://" .. item.icon,
|
||||||
|
|
||||||
LayoutOrder = i
|
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
```
|
```
|
||||||
|
|
@ -181,6 +210,9 @@ Maps each value in a table source to an object.
|
||||||
|
|
||||||
In most cases, both functions will appear to have the same behavior.
|
In most cases, both functions will appear to have the same behavior.
|
||||||
The main difference is performance, picking the right function to use can
|
The main difference is performance, picking the right function to use can
|
||||||
result in less property updates and less re-renders.
|
result in less property updates and less re-renders. One case to note is
|
||||||
|
that `values()` works nicely when animating re-ordering of instances, since
|
||||||
|
the value is not destroyed when indexes are changed, and the source index
|
||||||
|
can easily be put through a spring.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -24,20 +24,6 @@ Runs a callback anytime a reactive scope is re-ran.
|
||||||
end)
|
end)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua
|
|
||||||
local data = source(1)
|
|
||||||
|
|
||||||
derive(function()
|
|
||||||
local label = create "TextLabel" { Text = data() }
|
|
||||||
|
|
||||||
cleanup(function()
|
|
||||||
label:Destroy()
|
|
||||||
end)
|
|
||||||
|
|
||||||
return label
|
|
||||||
end)
|
|
||||||
```
|
|
||||||
|
|
||||||
## untrack()
|
## untrack()
|
||||||
|
|
||||||
Runs a given function where any sources read will not track its reactive scope.
|
Runs a given function where any sources read will not track its reactive scope.
|
||||||
|
|
@ -70,4 +56,14 @@ Runs a given function where any sources read will not track its reactive scope.
|
||||||
print(sum()) -- 2
|
print(sum()) -- 2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## read()
|
||||||
|
|
||||||
|
Utility used to read a value that is either a primitive or a source.
|
||||||
|
|
||||||
|
- **Type**
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function read<T>(value: T | () -> T): T
|
||||||
|
```
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ Strict mode is library-wide and can get set by doing:
|
||||||
vide.strict = true
|
vide.strict = true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
It is automatically enabled when Vide is first required and not running in O2
|
||||||
|
optimization level.
|
||||||
|
|
||||||
Strict mode is designed to help the development process by adding safety checks
|
Strict mode is designed to help the development process by adding safety checks
|
||||||
and identifying improper usage.
|
and identifying improper usage.
|
||||||
|
|
||||||
|
|
@ -15,8 +18,9 @@ Currently, strict mode will:
|
||||||
2. Run effects twice when a source updates.
|
2. Run effects twice when a source updates.
|
||||||
3. Throw an error if yields occur where they are not allowed.
|
3. Throw an error if yields occur where they are not allowed.
|
||||||
4. Checks for `indexes()` and `values()` returning primitive values.
|
4. Checks for `indexes()` and `values()` returning primitive values.
|
||||||
5. Checks for duplicate nested properties at same depth.
|
5. Checks for `values()` input having duplicate values.
|
||||||
6. Better error reporting and stack traces + creation traces of property bindings.
|
6. Checks for duplicate nested properties at same depth.
|
||||||
|
7. Better error reporting and stack traces + creation traces of property bindings.
|
||||||
|
|
||||||
By rerunning sources and effects, any side-effects are made more apparent.
|
By rerunning sources and effects, any side-effects are made more apparent.
|
||||||
This also helps ensure that cleanups are being handled correctly.
|
This also helps ensure that cleanups are being handled correctly.
|
||||||
|
|
@ -29,4 +33,5 @@ recording and better emitting stack traces where errors occur, particularly
|
||||||
when binding properties to sources.
|
when binding properties to sources.
|
||||||
|
|
||||||
It is recommend to develop UI with strict mode and to disable it when pushing to
|
It is recommend to develop UI with strict mode and to disable it when pushing to
|
||||||
production.
|
production. In Roblox, production code compiles at O2 by default, so you don't
|
||||||
|
need to worry about disabling strict mode unless you have manually enabled it.
|
||||||
|
|
|
||||||
0
docs/tut/control-flow/1-intro.md
Normal file
0
docs/tut/control-flow/1-intro.md
Normal file
1
docs/tut/control-flow/2-show.md
Normal file
1
docs/tut/control-flow/2-show.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
# show()
|
||||||
1
docs/tut/control-flow/3-switch.md
Normal file
1
docs/tut/control-flow/3-switch.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
# switch()
|
||||||
1
docs/tut/control-flow/4-indexes.md
Normal file
1
docs/tut/control-flow/4-indexes.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
# indexes()
|
||||||
1
docs/tut/control-flow/5-values.md
Normal file
1
docs/tut/control-flow/5-values.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
# values()
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
# Control Flow
|
|
||||||
|
|
||||||
Vide has specific functions for dealing with sources that store a table value.
|
|
||||||
|
|
||||||
Often, you will have a table of values that will be displayed in a similar
|
|
||||||
manner. Rather than manually looping over each value to generate a corresponding
|
|
||||||
UI element, Vide provides functions `indexes()` and `values()` to do this for
|
|
||||||
you.
|
|
||||||
|
|
||||||
`indexes()` maps each *index* in a table to a UI element.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local names = source { "a", "b", "c" }
|
|
||||||
|
|
||||||
local elements = indexes(names, function(name, i)
|
|
||||||
return create "TextLabel" {
|
|
||||||
Text = function()
|
|
||||||
return "Name: " .. name()
|
|
||||||
end,
|
|
||||||
|
|
||||||
LayoutOrder = i
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
```
|
|
||||||
|
|
||||||
What happens here is the given callback is only ever ran *once* for each index
|
|
||||||
in the table. The callback receives two arguments, a *source* containing the
|
|
||||||
index's value and then the index itself.
|
|
||||||
|
|
||||||
Anytime the value at a corresponding index changes, the source for that index
|
|
||||||
value is updated, causing the UI element depending on it to update too.
|
|
||||||
|
|
||||||
`values()` behaves similarly, except it maps each *value* in a table to a UI
|
|
||||||
element.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
type Item = {
|
|
||||||
Name: string,
|
|
||||||
Icon: number
|
|
||||||
}
|
|
||||||
|
|
||||||
local items = source({} :: Array<Item>)
|
|
||||||
|
|
||||||
local elements = values(items, function(item, i)
|
|
||||||
return create "ImageLabel" {
|
|
||||||
Image = "rbxassetid://" .. item.Icon,
|
|
||||||
LayoutOrder = i
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
```
|
|
||||||
|
|
||||||
The callback is again only ever ran *once* for each value in the table. The
|
|
||||||
callback receives two arguments, a value in the table and then a *source*
|
|
||||||
containing the value's corresponding index.
|
|
||||||
|
|
||||||
Any time a value in a table changes index, the source for that value is updated,
|
|
||||||
causing the UI element position to change.
|
|
||||||
|
|
||||||
In certain cases `values()` can cause less recalculation and rerenders than
|
|
||||||
`indexes()` like when items are re-arranged and shifted within a table.
|
|
||||||
|
|
||||||
It is important that each value in a table is unique when using `values()`,
|
|
||||||
and for this reason always using `indexes()` if a table contains primitive
|
|
||||||
values.
|
|
||||||
|
|
||||||
Both `indexes()` and `values()` return an array of all mapped UI elements.
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
# Control Flow
|
|
||||||
|
|
||||||
Vide has specific functions for dealing with sources that store a table value.
|
|
||||||
|
|
||||||
Often, you will have a table of values that will be displayed in a similar
|
|
||||||
manner. Rather than manually looping over each value to generate a corresponding
|
|
||||||
UI element, Vide provides functions `indexes()` and `values()` to do this for
|
|
||||||
you.
|
|
||||||
|
|
||||||
`indexes()` maps each *index* in a table to a UI element.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local names = source { "a", "b", "c" }
|
|
||||||
|
|
||||||
local elements = indexes(names, function(name, i)
|
|
||||||
return create "TextLabel" {
|
|
||||||
Text = function()
|
|
||||||
return "Name: " .. name()
|
|
||||||
end,
|
|
||||||
|
|
||||||
LayoutOrder = i
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
```
|
|
||||||
|
|
||||||
What happens here is the given callback is only ever ran *once* for each index
|
|
||||||
in the table. The callback receives two arguments, a *source* containing the
|
|
||||||
index's value and then the index itself.
|
|
||||||
|
|
||||||
Anytime the value at a corresponding index changes, the source for that index
|
|
||||||
value is updated, causing the UI element depending on it to update too.
|
|
||||||
|
|
||||||
`values()` behaves similarly, except it maps each *value* in a table to a UI
|
|
||||||
element.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
type Item = {
|
|
||||||
Name: string,
|
|
||||||
Icon: number
|
|
||||||
}
|
|
||||||
|
|
||||||
local items = source({} :: Array<Item>)
|
|
||||||
|
|
||||||
local elements = values(items, function(item, i)
|
|
||||||
return create "ImageLabel" {
|
|
||||||
Image = "rbxassetid://" .. item.Icon,
|
|
||||||
LayoutOrder = i
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
```
|
|
||||||
|
|
||||||
The callback is again only ever ran *once* for each value in the table. The
|
|
||||||
callback receives two arguments, a value in the table and then a *source*
|
|
||||||
containing the value's corresponding index.
|
|
||||||
|
|
||||||
Any time a value in a table changes index, the source for that value is updated,
|
|
||||||
causing the UI element position to change.
|
|
||||||
|
|
||||||
In certain cases `values()` can cause less recalculation and rerenders than
|
|
||||||
`indexes()` like when items are re-arranged and shifted within a table.
|
|
||||||
|
|
||||||
It is important that each value in a table is unique when using `values()`,
|
|
||||||
and for this reason always using `indexes()` if a table contains primitive
|
|
||||||
values.
|
|
||||||
|
|
||||||
Both `indexes()` and `values()` return an array of all mapped UI elements.
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
# Control Flow
|
|
||||||
|
|
||||||
Vide has specific functions for dealing with sources that store a table value.
|
|
||||||
|
|
||||||
Often, you will have a table of values that will be displayed in a similar
|
|
||||||
manner. Rather than manually looping over each value to generate a corresponding
|
|
||||||
UI element, Vide provides functions `indexes()` and `values()` to do this for
|
|
||||||
you.
|
|
||||||
|
|
||||||
`indexes()` maps each *index* in a table to a UI element.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local names = source { "a", "b", "c" }
|
|
||||||
|
|
||||||
local elements = indexes(names, function(name, i)
|
|
||||||
return create "TextLabel" {
|
|
||||||
Text = function()
|
|
||||||
return "Name: " .. name()
|
|
||||||
end,
|
|
||||||
|
|
||||||
LayoutOrder = i
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
```
|
|
||||||
|
|
||||||
What happens here is the given callback is only ever ran *once* for each index
|
|
||||||
in the table. The callback receives two arguments, a *source* containing the
|
|
||||||
index's value and then the index itself.
|
|
||||||
|
|
||||||
Anytime the value at a corresponding index changes, the source for that index
|
|
||||||
value is updated, causing the UI element depending on it to update too.
|
|
||||||
|
|
||||||
`values()` behaves similarly, except it maps each *value* in a table to a UI
|
|
||||||
element.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
type Item = {
|
|
||||||
Name: string,
|
|
||||||
Icon: number
|
|
||||||
}
|
|
||||||
|
|
||||||
local items = source({} :: Array<Item>)
|
|
||||||
|
|
||||||
local elements = values(items, function(item, i)
|
|
||||||
return create "ImageLabel" {
|
|
||||||
Image = "rbxassetid://" .. item.Icon,
|
|
||||||
LayoutOrder = i
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
```
|
|
||||||
|
|
||||||
The callback is again only ever ran *once* for each value in the table. The
|
|
||||||
callback receives two arguments, a value in the table and then a *source*
|
|
||||||
containing the value's corresponding index.
|
|
||||||
|
|
||||||
Any time a value in a table changes index, the source for that value is updated,
|
|
||||||
causing the UI element position to change.
|
|
||||||
|
|
||||||
In certain cases `values()` can cause less recalculation and rerenders than
|
|
||||||
`indexes()` like when items are re-arranged and shifted within a table.
|
|
||||||
|
|
||||||
It is important that each value in a table is unique when using `values()`,
|
|
||||||
and for this reason always using `indexes()` if a table contains primitive
|
|
||||||
values.
|
|
||||||
|
|
||||||
Both `indexes()` and `values()` return an array of all mapped UI elements.
|
|
||||||
|
|
@ -5,5 +5,27 @@ be set with `vide.strict = true` once when you first require Vide. Strict mode
|
||||||
will add extra safety checks and emit better error traces, particularly when
|
will add extra safety checks and emit better error traces, particularly when
|
||||||
errors occur in property bindings.
|
errors occur in property bindings.
|
||||||
|
|
||||||
|
Strict mode will run derived sources and effects twice each time they update.
|
||||||
|
This is to help identify improper cleanup of side-effects and ensure that pure
|
||||||
|
computations are actually pure.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local source = vide.source
|
||||||
|
local effect = vide.effect
|
||||||
|
|
||||||
|
vide.strict = true
|
||||||
|
|
||||||
|
local count = source(0)
|
||||||
|
|
||||||
|
local ran = 0
|
||||||
|
effect(function()
|
||||||
|
ran += 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
print(ran) -- 2
|
||||||
|
count(1)
|
||||||
|
print(ran) -- 4
|
||||||
|
```
|
||||||
|
|
||||||
A full list of what strict mode will do can be found
|
A full list of what strict mode will do can be found
|
||||||
[here](../../api/strict-mode).
|
[here](../../api/strict-mode).
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,105 @@
|
||||||
# Control Flow
|
# Control Flow
|
||||||
|
|
||||||
Eventually you will need a way to dynamically create and destroy UI elements
|
Eventually you will need a way to dynamically create and destroy UI elements
|
||||||
resulting from state changes. Vide provides functions to help you do this,
|
resulting from source updates. Vide provides functions to help you do this,
|
||||||
known as *control flow* functions.
|
known as *control flow* functions.
|
||||||
|
|
||||||
These functions return a new source, which holds the instances to be displayed.
|
These functions return new sources, which hold the instances to be displayed.
|
||||||
These sources can be assigned as children, meaning the displayed children
|
These sources can be assigned as children, meaning the displayed children
|
||||||
will update when the input source updates.
|
will update when the input source updates.
|
||||||
|
|
||||||
One of these functions is `switch()`, used to conditionally show one of a set of
|
Control flow functions are special, because they run their components in a new
|
||||||
components.
|
reactive scope, which can be destroyed independently of the reactive scope that
|
||||||
|
called the control flow function itself. This means that parts of your app can
|
||||||
|
be independently created then destroyed and cleaned.
|
||||||
|
|
||||||
|
## show()
|
||||||
|
|
||||||
|
The most basic control flow function is `show()`, which is used to conditionally
|
||||||
|
show a component.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local source = vide.source
|
||||||
|
local show = vide.show
|
||||||
|
|
||||||
|
local function JoinMenu()
|
||||||
|
local joined = source(false)
|
||||||
|
|
||||||
|
local function JoinButton()
|
||||||
|
return Button {
|
||||||
|
Activated = function() joined(true) end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return create "Frame" {
|
||||||
|
show(function() return not joined() end, JoinButton)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
This will make a button to join if you have not joined already.
|
||||||
|
|
||||||
|
You can also pass a third argument, a fallback to show if the condition is falsey.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local function JoinMenu()
|
||||||
|
local joined = source(false)
|
||||||
|
|
||||||
|
local function JoinButton()
|
||||||
|
return Button {
|
||||||
|
Activated = function() joined(true) end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function LeaveButton()
|
||||||
|
return Button {
|
||||||
|
Activated = function() joined(false) end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return create "Frame" {
|
||||||
|
show(joined, LeaveButton, JoinButton)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## switch()
|
||||||
|
|
||||||
|
Similar to `show()`, `switch()`, also condtionally displays one instance at a
|
||||||
|
time. It is more flexible since it can show one of many components, based on a
|
||||||
|
table used to map a source value to a component.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
local vide = require(vide)
|
|
||||||
local source = vide.source
|
local source = vide.source
|
||||||
local switch = vide.switch
|
local switch = vide.switch
|
||||||
|
|
||||||
local function ToggleButton(p: {
|
local function JoinMenu()
|
||||||
Text: string,
|
local joined = source(false)
|
||||||
Toggle: (boolean) -> boolean
|
|
||||||
})
|
local function JoinButton()
|
||||||
return create "TextButton" {
|
return Button {
|
||||||
Size = UDim2.fromOffset(300, 300),
|
Activated = function() joined(true) end
|
||||||
Text = p.Text,
|
|
||||||
Activated = function()
|
|
||||||
p.Toggle(not p.Toggle())
|
|
||||||
end
|
|
||||||
}
|
}
|
||||||
end
|
|
||||||
|
|
||||||
local loggedIn = source(false)
|
|
||||||
|
|
||||||
local function LoginMenu()
|
|
||||||
return Frame {
|
|
||||||
switch(loggedIn) {
|
|
||||||
[true] = function()
|
|
||||||
return ToggleButton { Text = "Log out", Toggle = loggedIn }
|
|
||||||
end,
|
|
||||||
|
|
||||||
[false] = function()
|
|
||||||
return ToggleButton { Text = "Log in", Toggle = loggedIn }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function LeaveButton()
|
||||||
|
return Button {
|
||||||
|
Activated = function() joined(false) end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return create "Frame" {
|
||||||
|
switch(joined) {
|
||||||
|
[true] = LeaveButton,
|
||||||
|
[false] = JoinButton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
mount(function() return create "ScreenGui" { LoginMenu {} } end, game.StarterGui)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Above is an example of using a switch to create a login menu. Each time
|
Above is an example of using a switch to create a join menu. Each time
|
||||||
`loggedIn` toggles, the current button will be destroyed, and a new button
|
`joined` toggles, the current button will be destroyed, and a new button
|
||||||
created, which the text to represent the current action, to log in or log out.
|
created, which the text to represent the current action, to join or leave.
|
||||||
|
|
||||||
The callbacks given to control flow functions are ran in a new reactive-scope,
|
The callbacks given to control flow functions are ran in a new reactive-scope,
|
||||||
so any cleanups registered will be ran when the input is changed and a new
|
so any cleanups registered will be ran when the input is changed and a new
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue