Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ The format is based on [Keep a Changelog][kac], and this project adheres to

## [Unreleased]

### Added
- Added `useRefs`

## [0.4.3] - 2024-01-31

### Added
Expand Down
26 changes: 25 additions & 1 deletion src/Runtime.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type StackFrame = {
discriminator: string | number,
}

type RefTable = { [string]: Instance }

local stack: { StackFrame } = {}

local recentErrors = {}
Expand Down Expand Up @@ -269,7 +271,7 @@ end
`useInstance` returns the `ref` table that is passed to it. You can use this to create references to objects
you want to update in the widget body.
]=]
function Runtime.useInstance(creator: () -> Instance): Instance
function Runtime.useInstance(creator: (ref: RefTable) -> Instance): Instance
local node = stack[#stack].node
local parentFrame = Runtime.nearestStackFrameWithInstance()

Expand All @@ -279,6 +281,8 @@ function Runtime.useInstance(creator: () -> Instance): Instance
node.refs = {}
local instance, container = creator(node.refs)

table.freeze(node.refs)

if instance ~= nil then
instance.Parent = parent
node.instance = instance
Expand All @@ -297,6 +301,26 @@ function Runtime.useInstance(creator: () -> Instance): Instance
return node.refs
end

--[=[
@within Plasma
@return { [string]: Instance } -- Returns the `ref` table
@tag hooks

Returns the `ref` table that is attached to the current `useInstance` call.

This hook can only be used inside `useInstance` and will error if done otherwise. You can use this instead
of the `ref` parameter if you're using nested functions that returns instances and don't want
to pass the table to a descendant via prop drilling.
]=]
function Runtime.useRefs(): RefTable
local node = stack[#stack].node
if node.refs == nil or table.isfrozen(node.refs) then
error("Runtime.useRefs cannot be used outside Runtime.useInstance", 2)
end

return node.refs
end

function Runtime.nearestStackFrameWithInstance(): StackFrame?
for i = #stack - 1, 1, -1 do
local frame = stack[i]
Expand Down
1 change: 1 addition & 0 deletions src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ return {
widget = Runtime.widget,
useState = Runtime.useState,
useInstance = Runtime.useInstance,
useRefs = Runtime.useRefs,
useEffect = Runtime.useEffect,
useKey = Runtime.useKey,
setEventCallback = Runtime.setEventCallback,
Expand Down