mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
Initial commit
This commit is contained in:
commit
cb002f4f27
50 changed files with 4666 additions and 0 deletions
37
docs/api/animation.md
Normal file
37
docs/api/animation.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Animation API
|
||||
|
||||
## spring()
|
||||
|
||||
Returns a new state with a dynamically animated value of the source.
|
||||
|
||||
- **Type**
|
||||
|
||||
```lua
|
||||
function spring<T>(
|
||||
source: () -> T & Animatable,
|
||||
period: number = 1,
|
||||
damping_ratio: number = 1
|
||||
): () -> T
|
||||
|
||||
type Animatable = number | CFrame | Color3 | UDim | UDim2 | Vector2 | Vector3
|
||||
```
|
||||
|
||||
- **Details**
|
||||
|
||||
The output state value is updated every frame based on the source state
|
||||
value.
|
||||
|
||||
The change is physically simulated according to a
|
||||
[spring](https://en.wikipedia.org/wiki/Simple_harmonic_motion).
|
||||
|
||||
`period` is the amount of time in seconds it takes for the spring to
|
||||
complete one full oscillation.
|
||||
|
||||
`damping_ratio` is the amount of resistance applied to the spring.
|
||||
|
||||
- \>1 = Overdamped (not currently supported).
|
||||
- 1 = Critically damped - reaches target without any overshoot.
|
||||
- <1 = Underdamped - reaches target with some overshoot.
|
||||
- 0 = Undamped - never stabilizes, oscillates forever.
|
||||
|
||||
Velocity is conserved between source state updates for smooth animation.
|
||||
79
docs/api/creation.md
Normal file
79
docs/api/creation.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# Element Creation API
|
||||
|
||||
<br/>
|
||||
|
||||
## create()
|
||||
|
||||
Creates a new UI element, applying any given properties.
|
||||
|
||||
- ### Type
|
||||
|
||||
```lua
|
||||
function create(class: string): (Properties) -> Instance
|
||||
function create(instance: Instace): (Properties) -> Instance
|
||||
|
||||
type Properties = Map<string|number, any>
|
||||
```
|
||||
|
||||
- ### Details
|
||||
|
||||
The function can take either a `string` or an `Instance` as its first argument.
|
||||
|
||||
- If given a `string`, a new instance with the same class name will be created.
|
||||
- If given an `Instance`, a new instance that is a clone of the given instance
|
||||
will be created.
|
||||
|
||||
This returns another function that is used to apply any properties to the new
|
||||
instance.
|
||||
|
||||
- ### Property setting rules
|
||||
|
||||
- If a table value is another table, that nested table is processed so that
|
||||
any properties inside that table are also applied to the instance just
|
||||
like the outer table.
|
||||
- If a table index is a string:
|
||||
- If its value is a function then it will either bind that property to
|
||||
a state or connect it if the property type is a `RBXScriptSignal`.
|
||||
- If the value is not a function then the property will be set to that
|
||||
value.
|
||||
- If a table index is a number:
|
||||
- If its value is a function then it will parent any instances returned by
|
||||
that function as children.
|
||||
- If its value is an instance then it will be parented to the instance.
|
||||
|
||||
- ### Example
|
||||
|
||||
Basic element creation.
|
||||
|
||||
```lua
|
||||
local frame = create "Frame" {
|
||||
Name = "NewFrame",
|
||||
Position = UDim2.fromScale(1, 0)
|
||||
}
|
||||
```
|
||||
|
||||
A component using property nesting/grouping.
|
||||
|
||||
```lua
|
||||
type Layout = {
|
||||
Layout = {
|
||||
Position: UDim2?,
|
||||
Size: UDim2?,
|
||||
AnchorPoint: Vector2?
|
||||
}
|
||||
}
|
||||
|
||||
type Children = {
|
||||
Children = Array<Instance>
|
||||
}
|
||||
|
||||
function Background(props: Layout & Children & {
|
||||
Color: Color3
|
||||
})
|
||||
return create "Frame" {
|
||||
BackgroundColor3 = Color,
|
||||
props.Layout,
|
||||
props.Children
|
||||
}
|
||||
end
|
||||
```
|
||||
250
docs/api/reactivity-core.md
Normal file
250
docs/api/reactivity-core.md
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
# Reactivity API: Core
|
||||
|
||||
<br/>
|
||||
|
||||
## source()
|
||||
|
||||
Creates a new source state with the given value.
|
||||
|
||||
- **Type**
|
||||
|
||||
```lua
|
||||
function source<T>(value: T): (T?) -> T
|
||||
```
|
||||
|
||||
- **Details**
|
||||
|
||||
Calling the returned state with no arguments will return its stored value,
|
||||
calling with arguments will set a new value.
|
||||
|
||||
Reading from the state from within any reactive scope will cause changes
|
||||
to that state to be tracked and anything depending on it to update.
|
||||
|
||||
- **Example**
|
||||
|
||||
```lua
|
||||
local count = source(0)
|
||||
|
||||
count() -- 0
|
||||
|
||||
count(count() + 1) -- 1
|
||||
```
|
||||
|
||||
## watch()
|
||||
|
||||
Runs a callback on state change.
|
||||
|
||||
- **Type**
|
||||
|
||||
```lua
|
||||
function watch(callback: () -> ()): Unwatch
|
||||
|
||||
type Unwatch = () -> ()
|
||||
```
|
||||
|
||||
- **Details**
|
||||
|
||||
The callback is ran immediately to determine what states are referenced.
|
||||
|
||||
Any time a state referenced in the callback is changed, the callback will be
|
||||
reran.
|
||||
|
||||
Also returns a function that when called, stops the watcher immediately.
|
||||
|
||||
::: warning
|
||||
`callback()` cannot yield.
|
||||
:::
|
||||
|
||||
- **Example**
|
||||
|
||||
```lua
|
||||
local state = wrap(1)
|
||||
|
||||
watch(function()
|
||||
print(state.Value)
|
||||
end)
|
||||
|
||||
-- prints 1
|
||||
|
||||
state.Value += 1
|
||||
|
||||
-- prints 2
|
||||
```
|
||||
|
||||
## derive()
|
||||
|
||||
Derives a new state from existing states.
|
||||
|
||||
- **Type**
|
||||
|
||||
```lua
|
||||
function derive<T>(source: () -> T): () -> T
|
||||
```
|
||||
|
||||
- **Details**
|
||||
|
||||
The derived state will have its value recalculated when any source state it
|
||||
derives from is updated.
|
||||
|
||||
Anytime its value is recalculated it is also cached, subsequent calls will
|
||||
retun this cached value until it recalculates again.
|
||||
|
||||
Takes a callback that is immediately run to determine what states are being
|
||||
referenced.
|
||||
|
||||
::: warning
|
||||
`source()` cannot yield.
|
||||
:::
|
||||
|
||||
- **Example**
|
||||
|
||||
```lua
|
||||
local count = wrap(0)
|
||||
local text = derive(function() return `count: {count()}` end)
|
||||
|
||||
text() -- "count: 0"
|
||||
|
||||
count(1)
|
||||
|
||||
text() -- "count: 1"
|
||||
```
|
||||
|
||||
## indexes()
|
||||
|
||||
Maps each index in a table to an object.
|
||||
|
||||
- **Type**
|
||||
|
||||
```lua
|
||||
function indexes<KI, VI, VO>(
|
||||
source: () -> Map<KI, VI>,
|
||||
transform: (value: () -> VI, index: KI) -> VO
|
||||
): Array<VO>
|
||||
|
||||
- **Details**
|
||||
|
||||
The transform function is called only ever *once* for each index in the
|
||||
source table. The first argument is a state containing the index's value and
|
||||
the second argument is just the index.
|
||||
|
||||
Anytime a new index is added, the transform function will be called again for
|
||||
that new index.
|
||||
|
||||
Anytime an existing index value changes, the transform function is not rerun,
|
||||
instead the passed state for that index will update, causing anything
|
||||
depending on it to update too.
|
||||
|
||||
Returns a state containing an array of all objects returned by the transform.
|
||||
|
||||
::: warning
|
||||
`transform()` cannot yield.
|
||||
:::
|
||||
|
||||
- **Example**
|
||||
|
||||
The intended purpose of this function is to map each index in a table to
|
||||
a UI element.
|
||||
|
||||
```lua
|
||||
type Item = {
|
||||
name: string,
|
||||
icon: number
|
||||
}
|
||||
|
||||
local items = source {} :: () -> Array<Item>
|
||||
|
||||
local displays = indexes(numbers, function(item, i)
|
||||
return ItemDisplay {
|
||||
Name = function()
|
||||
return item().name
|
||||
end,
|
||||
|
||||
Image = function()
|
||||
return "rbxassetid://" .. item().icon
|
||||
end,
|
||||
|
||||
LayoutOrder = i
|
||||
}
|
||||
end)
|
||||
```
|
||||
|
||||
## values()
|
||||
|
||||
Maps each value in a table to an object.
|
||||
|
||||
- **Type**
|
||||
|
||||
```lua
|
||||
function values<KI, VI, VO>(
|
||||
source: () -> Map<KI, VI>,
|
||||
transform: (value: VI, index: () -> KI) -> VO
|
||||
): Array<VO>
|
||||
|
||||
- **Details**
|
||||
|
||||
The transform function is called only ever *once* for each value in the
|
||||
source table. The first argument is the index's value and
|
||||
the second argument is a state containing the index.
|
||||
|
||||
Anytime a new value is added, the transform function will be called again
|
||||
for that new value.
|
||||
|
||||
Anytime an existing value's index changes, the transform function is not
|
||||
rerun, instead the passed state for that value will update, causing anything
|
||||
depending on it to update too.
|
||||
|
||||
Returns a state containing an array of all objects returned by the transform.
|
||||
|
||||
::: warning
|
||||
`transform()` cannot yield.
|
||||
:::
|
||||
|
||||
- **Example**
|
||||
|
||||
The intended purpose of this function is to map each value in a table to
|
||||
a UI element.
|
||||
|
||||
```lua
|
||||
type Item = {
|
||||
name: string,
|
||||
icon: number
|
||||
}
|
||||
|
||||
local items = source {} :: () -> Array<Item>
|
||||
|
||||
local displays = values(numbers, function(item, i)
|
||||
return ItemDisplay {
|
||||
Name = item.Name
|
||||
|
||||
Image = "rbxassetid://" .. item.icon,
|
||||
|
||||
LayoutOrder = i
|
||||
}
|
||||
end)
|
||||
```
|
||||
|
||||
- **Extra**
|
||||
|
||||
When should you use `indexes()` and `values()`?
|
||||
|
||||
`values()` should be used when you have a fixed set of objects where the
|
||||
same objects can be re-arranged in the source table. It maps a value to a
|
||||
UI element.
|
||||
|
||||
e.g.
|
||||
- List of all players.
|
||||
- Inventory of items.
|
||||
- Chat message history.
|
||||
- Toast notifications.
|
||||
|
||||
`indexes()` should be used in other cases, especially when your source table
|
||||
has primitive value. It maps an index to a UI element.
|
||||
|
||||
e.g.
|
||||
- List of character or weapon stats.
|
||||
|
||||
In most cases, both functions will appear to have the same behavior.
|
||||
The main difference is performance, picking the right function to use can
|
||||
result in less property updates and less re-renders.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
25
docs/api/reactivity-utility.md
Normal file
25
docs/api/reactivity-utility.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Reactivity API: Utility
|
||||
|
||||
## cleanup()
|
||||
|
||||
Runs a callback anytime a reactive scope is re-ran.
|
||||
|
||||
- **Type**
|
||||
|
||||
```lua
|
||||
function cleanup(callback: () -> ())
|
||||
```
|
||||
|
||||
- **Example**
|
||||
|
||||
```lua
|
||||
local data = source(1)
|
||||
|
||||
watch(function()
|
||||
local label = create "TextLabel" { Text = data }
|
||||
|
||||
cleanup(function()
|
||||
label:Destroy()
|
||||
end)
|
||||
end)
|
||||
```
|
||||
25
docs/api/strict-mode.md
Normal file
25
docs/api/strict-mode.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Strict Mode
|
||||
|
||||
Vide has a special mode called "strict mode" which is used for debugging.
|
||||
|
||||
The purpose of strict mode is to help ensure stateful code is *pure*
|
||||
(deterministic and free from side effects) or if there are side-effects, that
|
||||
they are cleaned up correctly.
|
||||
|
||||
Vide is set to strict by doing:
|
||||
|
||||
```lua
|
||||
local vide = require(path_to_vide)
|
||||
vide.strict = true
|
||||
```
|
||||
|
||||
What strict mode will do:
|
||||
|
||||
1. Run derived callbacks twice when re-evaluating.
|
||||
2. Run watcher callbacks twice when a state changes.
|
||||
3. Throw an error if yields occur where they are not allowed.
|
||||
4. Checks for `map()` returning primitive values.
|
||||
5. Better error reporting and stack traces.
|
||||
|
||||
It is recommend to develop UI with strict mode and to disable it when pushing to
|
||||
production.
|
||||
Loading…
Add table
Add a link
Reference in a new issue