mirror of
https://github.com/centau/vide.git
synced 2026-08-20 23:01:37 +00:00
Add tag() action for CollectionService tags
Adds a built-in `vide.tag()` action that wraps `Instance:AddTag()` / `Instance:RemoveTag()` so tags can be applied through `create()` props. It accepts a static string or array of strings, or a reactive source returning either. The reactive variant diffs the previous and new tag sets so only the delta is applied. All tags added by the action are removed when the surrounding scope is destroyed. Includes mock support for `AddTag`/`RemoveTag`/`HasTag`/`GetTags`, tests, API reference docs, and a closing note in the actions tutorial. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
19eaeb424f
commit
18c1d02d43
7 changed files with 276 additions and 0 deletions
117
test/tests.luau
117
test/tests.luau
|
|
@ -24,6 +24,7 @@ local vide = require "../../vide"
|
|||
local spring = vide.spring
|
||||
local action = vide.action
|
||||
local changed = vide.changed
|
||||
local tag = vide.tag
|
||||
local apply = vide.apply
|
||||
local step = vide.step
|
||||
local graph = require "../../vide/src/graph"
|
||||
|
|
@ -2340,6 +2341,122 @@ TEST("changed()", wrap_root(function()
|
|||
end
|
||||
end))
|
||||
|
||||
TEST("tag()", wrap_root(function()
|
||||
do CASE "apply single tag"
|
||||
local frame = create "Frame" {
|
||||
tag("MyTag")
|
||||
}
|
||||
|
||||
CHECK(frame:HasTag("MyTag"))
|
||||
CHECK(#frame:GetTags() == 1)
|
||||
end
|
||||
|
||||
do CASE "apply multiple tags"
|
||||
local frame = create "Frame" {
|
||||
tag({ "A", "B", "C" })
|
||||
}
|
||||
|
||||
CHECK(frame:HasTag("A"))
|
||||
CHECK(frame:HasTag("B"))
|
||||
CHECK(frame:HasTag("C"))
|
||||
CHECK(#frame:GetTags() == 3)
|
||||
end
|
||||
|
||||
do CASE "compose multiple tag() actions"
|
||||
local frame = create "Frame" {
|
||||
tag("A"),
|
||||
tag("B")
|
||||
}
|
||||
|
||||
CHECK(frame:HasTag("A"))
|
||||
CHECK(frame:HasTag("B"))
|
||||
end
|
||||
|
||||
do CASE "remove tags on scope destroy"
|
||||
local _, frame, destroy = root(function(destroy)
|
||||
return create "Frame" {
|
||||
tag({ "A", "B" })
|
||||
}, destroy
|
||||
end)
|
||||
|
||||
CHECK(frame:HasTag("A"))
|
||||
CHECK(frame:HasTag("B"))
|
||||
|
||||
destroy()
|
||||
|
||||
CHECK(not frame:HasTag("A"))
|
||||
CHECK(not frame:HasTag("B"))
|
||||
end
|
||||
|
||||
do CASE "reactive single tag"
|
||||
local current = source("A")
|
||||
|
||||
local frame = create "Frame" {
|
||||
tag(current)
|
||||
}
|
||||
|
||||
CHECK(frame:HasTag("A"))
|
||||
CHECK(#frame:GetTags() == 1)
|
||||
|
||||
current("B")
|
||||
|
||||
CHECK(not frame:HasTag("A"))
|
||||
CHECK(frame:HasTag("B"))
|
||||
CHECK(#frame:GetTags() == 1)
|
||||
end
|
||||
|
||||
do CASE "reactive multiple tags"
|
||||
local current = source({ "A", "B" })
|
||||
|
||||
local frame = create "Frame" {
|
||||
tag(current)
|
||||
}
|
||||
|
||||
CHECK(frame:HasTag("A"))
|
||||
CHECK(frame:HasTag("B"))
|
||||
CHECK(#frame:GetTags() == 2)
|
||||
|
||||
-- preserve "A", remove "B", add "C"
|
||||
current({ "A", "C" })
|
||||
|
||||
CHECK(frame:HasTag("A"))
|
||||
CHECK(not frame:HasTag("B"))
|
||||
CHECK(frame:HasTag("C"))
|
||||
CHECK(#frame:GetTags() == 2)
|
||||
end
|
||||
|
||||
do CASE "reactive tag removed on scope destroy"
|
||||
local _, frame, destroy = root(function(destroy)
|
||||
local current = source("A")
|
||||
return create "Frame" {
|
||||
tag(current)
|
||||
}, destroy
|
||||
end)
|
||||
|
||||
CHECK(frame:HasTag("A"))
|
||||
|
||||
destroy()
|
||||
|
||||
CHECK(not frame:HasTag("A"))
|
||||
CHECK(#frame:GetTags() == 0)
|
||||
end
|
||||
|
||||
do CASE "reactive tag derived from source"
|
||||
local name = source("hello")
|
||||
|
||||
local frame = create "Frame" {
|
||||
tag(function() return "prefix-" .. name() end)
|
||||
}
|
||||
|
||||
CHECK(frame:HasTag("prefix-hello"))
|
||||
|
||||
name("world")
|
||||
|
||||
CHECK(not frame:HasTag("prefix-hello"))
|
||||
CHECK(frame:HasTag("prefix-world"))
|
||||
end
|
||||
end))
|
||||
|
||||
TEST("batch()", wrap_root(function()
|
||||
do CASE "evaluation deferred"
|
||||
local a = source(0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue