@rbxts/centurion-ui 1.0.0-dev-d64d6ec → 1.0.0-dev-2d5383e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/components/suggestions/main-suggestion.d.ts +2 -1
- package/out/components/suggestions/main-suggestion.lua +2 -0
- package/out/components/suggestions/suggestions.lua +22 -19
- package/out/components/suggestions/util.d.ts +0 -3
- package/out/components/suggestions/util.lua +1 -52
- package/out/components/terminal/terminal-text-field.lua +46 -32
- package/package.json +2 -2
- package/out/hooks/use-debounce-source.d.ts +0 -11
- package/out/hooks/use-debounce-source.lua +0 -27
- package/out/hooks/use-motion.d.ts +0 -4
- package/out/hooks/use-motion.lua +0 -19
|
@@ -8,5 +8,6 @@ export interface MainSuggestionProps {
|
|
|
8
8
|
descriptionSize: Derivable<UDim2>;
|
|
9
9
|
badgeSize: Derivable<UDim2>;
|
|
10
10
|
errorSize: Derivable<UDim2>;
|
|
11
|
+
action?: (instance: Frame) => void;
|
|
11
12
|
}
|
|
12
|
-
export declare function MainSuggestion({ suggestion, currentText, size, titleSize, descriptionSize, badgeSize, errorSize, }: MainSuggestionProps): Vide.Node;
|
|
13
|
+
export declare function MainSuggestion({ suggestion, currentText, size, titleSize, descriptionSize, badgeSize, errorSize, action, }: MainSuggestionProps): Vide.Node;
|
|
@@ -25,8 +25,10 @@ local function MainSuggestion(_param)
|
|
|
25
25
|
local descriptionSize = _param.descriptionSize
|
|
26
26
|
local badgeSize = _param.badgeSize
|
|
27
27
|
local errorSize = _param.errorSize
|
|
28
|
+
local action = _param.action
|
|
28
29
|
local options = useAtom(interfaceOptions)
|
|
29
30
|
return Vide.jsx(Frame, {
|
|
31
|
+
action = action,
|
|
30
32
|
size = size,
|
|
31
33
|
backgroundColor = function()
|
|
32
34
|
return options().palette.background
|
|
@@ -5,6 +5,7 @@ local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
|
5
5
|
local Vide = _vide
|
|
6
6
|
local cleanup = _vide.cleanup
|
|
7
7
|
local derive = _vide.derive
|
|
8
|
+
local source = _vide.source
|
|
8
9
|
local spring = _vide.spring
|
|
9
10
|
local _text = TS.import(script, script.Parent.Parent.Parent, "constants", "text")
|
|
10
11
|
local SUGGESTION_TEXT_SIZE = _text.SUGGESTION_TEXT_SIZE
|
|
@@ -20,12 +21,18 @@ local Group = TS.import(script, script.Parent.Parent, "ui", "group").Group
|
|
|
20
21
|
local MainSuggestion = TS.import(script, script.Parent, "main-suggestion").MainSuggestion
|
|
21
22
|
local SuggestionList = TS.import(script, script.Parent, "suggestion-list").SuggestionList
|
|
22
23
|
local MAX_SUGGESTION_WIDTH = 180
|
|
23
|
-
local MAX_BADGE_WIDTH = 80
|
|
24
24
|
local PADDING = 8
|
|
25
25
|
local function Suggestions()
|
|
26
26
|
local options = useAtom(interfaceOptions)
|
|
27
27
|
local textPart = useAtom(currentTextPart)
|
|
28
28
|
local suggestion = useAtom(currentSuggestion)
|
|
29
|
+
local suggestionRef = source()
|
|
30
|
+
local offset = function(boundsState)
|
|
31
|
+
return function()
|
|
32
|
+
local bounds = boundsState()
|
|
33
|
+
return UDim2.new(0, bounds.X, 0, bounds.Y)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
29
36
|
local titleBounds = useTextBounds({
|
|
30
37
|
text = function()
|
|
31
38
|
local _result = suggestion()
|
|
@@ -132,33 +139,29 @@ local function Suggestions()
|
|
|
132
139
|
local height = titleBounds().Y + descriptionBounds().Y + errorBounds().Y
|
|
133
140
|
local padding = px(PADDING * 2)
|
|
134
141
|
if width == 0 or height == 0 then
|
|
135
|
-
|
|
142
|
+
local _result = suggestionRef()
|
|
143
|
+
if _result ~= nil then
|
|
144
|
+
_result = _result.AbsoluteSize.Y
|
|
145
|
+
end
|
|
146
|
+
local _condition = _result
|
|
147
|
+
if _condition == nil then
|
|
148
|
+
_condition = 0
|
|
149
|
+
end
|
|
150
|
+
return UDim2.fromOffset(0, _condition)
|
|
136
151
|
end
|
|
137
152
|
return UDim2.fromOffset(width + padding, height + padding)
|
|
138
153
|
end)
|
|
139
154
|
return Vide.jsx(Group, {
|
|
140
155
|
size = UDim2.fromScale(1, 1),
|
|
141
|
-
visible = currentSuggestion ~= nil,
|
|
142
156
|
}, Vide.jsx(MainSuggestion, {
|
|
143
157
|
suggestion = suggestion,
|
|
144
158
|
currentText = textPart,
|
|
145
159
|
size = spring(windowSize, 0.2),
|
|
146
|
-
titleSize =
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
local bounds = descriptionBounds()
|
|
152
|
-
return UDim2.fromOffset(bounds.X, bounds.Y)
|
|
153
|
-
end,
|
|
154
|
-
badgeSize = function()
|
|
155
|
-
local bounds = typeBadgeBounds()
|
|
156
|
-
return UDim2.fromOffset(bounds.X, bounds.Y)
|
|
157
|
-
end,
|
|
158
|
-
errorSize = function()
|
|
159
|
-
local bounds = errorBounds()
|
|
160
|
-
return UDim2.fromOffset(bounds.X, bounds.Y)
|
|
161
|
-
end,
|
|
160
|
+
titleSize = offset(titleBounds),
|
|
161
|
+
descriptionSize = offset(descriptionBounds),
|
|
162
|
+
badgeSize = offset(typeBadgeBounds),
|
|
163
|
+
errorSize = offset(errorBounds),
|
|
164
|
+
action = suggestionRef,
|
|
162
165
|
}), Vide.jsx(SuggestionList, {
|
|
163
166
|
suggestion = suggestion,
|
|
164
167
|
currentText = textPart,
|
|
@@ -1,4 +1 @@
|
|
|
1
|
-
import { InterfaceOptions, Suggestion } from "../../types";
|
|
2
|
-
import { SuggestionTextBounds } from "./types";
|
|
3
1
|
export declare function highlightMatching(color: Color3, text?: string, terminalText?: string): string;
|
|
4
|
-
export declare function getSuggestionTextBounds(options: InterfaceOptions, suggestion: Suggestion, titleTextSize: number, textSize: number, maxWidth: number, maxBadgeWidth: number): SuggestionTextBounds;
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
|
-
local TS = _G[script]
|
|
3
|
-
local TextService = TS.import(script, TS.getModule(script, "@rbxts", "services")).TextService
|
|
4
|
-
local TEXT_BOUNDS_PARAMS = Instance.new("GetTextBoundsParams")
|
|
5
|
-
TEXT_BOUNDS_PARAMS.RichText = true
|
|
6
|
-
local DEFAULT_BOUNDS = Vector2.new()
|
|
7
|
-
local prevColor
|
|
8
|
-
local prevColorHex
|
|
9
2
|
local function highlightMatching(color, text, terminalText)
|
|
10
3
|
if text == nil then
|
|
11
4
|
return ""
|
|
@@ -19,55 +12,11 @@ local function highlightMatching(color, text, terminalText)
|
|
|
19
12
|
if string.lower(terminalText) ~= string.lower(subText) then
|
|
20
13
|
return text
|
|
21
14
|
end
|
|
22
|
-
if prevColor ~= color then
|
|
23
|
-
prevColor = color
|
|
24
|
-
prevColorHex = color:ToHex()
|
|
25
|
-
end
|
|
26
15
|
local _text_1 = text
|
|
27
16
|
local _arg0 = #terminalText + 1
|
|
28
17
|
local unhighlightedText = string.sub(_text_1, _arg0)
|
|
29
|
-
return `<font color="#{
|
|
30
|
-
end
|
|
31
|
-
local function getSuggestionTextBounds(options, suggestion, titleTextSize, textSize, maxWidth, maxBadgeWidth)
|
|
32
|
-
-- Get title text bounds
|
|
33
|
-
TEXT_BOUNDS_PARAMS.Text = suggestion.title
|
|
34
|
-
TEXT_BOUNDS_PARAMS.Size = titleTextSize
|
|
35
|
-
TEXT_BOUNDS_PARAMS.Font = options.font.bold
|
|
36
|
-
local titleBounds = TextService:GetTextBoundsAsync(TEXT_BOUNDS_PARAMS)
|
|
37
|
-
-- Get description text bounds
|
|
38
|
-
TEXT_BOUNDS_PARAMS.Width = maxWidth
|
|
39
|
-
TEXT_BOUNDS_PARAMS.Size = textSize
|
|
40
|
-
TEXT_BOUNDS_PARAMS.Font = options.font.regular
|
|
41
|
-
local descriptionBounds = DEFAULT_BOUNDS
|
|
42
|
-
if suggestion.description ~= nil then
|
|
43
|
-
TEXT_BOUNDS_PARAMS.Text = suggestion.description
|
|
44
|
-
descriptionBounds = TextService:GetTextBoundsAsync(TEXT_BOUNDS_PARAMS)
|
|
45
|
-
end
|
|
46
|
-
local errorTextHeight = 0
|
|
47
|
-
local typeBadgeWidth = 0
|
|
48
|
-
if suggestion.type == "argument" then
|
|
49
|
-
-- Get error text bounds
|
|
50
|
-
if suggestion.error ~= nil then
|
|
51
|
-
local _condition = suggestion.error
|
|
52
|
-
if _condition == nil then
|
|
53
|
-
_condition = ""
|
|
54
|
-
end
|
|
55
|
-
TEXT_BOUNDS_PARAMS.Text = _condition
|
|
56
|
-
errorTextHeight = TextService:GetTextBoundsAsync(TEXT_BOUNDS_PARAMS).Y
|
|
57
|
-
end
|
|
58
|
-
-- Get type badge bounds
|
|
59
|
-
TEXT_BOUNDS_PARAMS.Text = suggestion.dataType
|
|
60
|
-
TEXT_BOUNDS_PARAMS.Width = maxBadgeWidth
|
|
61
|
-
typeBadgeWidth = TextService:GetTextBoundsAsync(TEXT_BOUNDS_PARAMS).X
|
|
62
|
-
end
|
|
63
|
-
return {
|
|
64
|
-
title = UDim2.fromOffset(titleBounds.X, titleBounds.Y),
|
|
65
|
-
description = UDim2.fromOffset(descriptionBounds.X, descriptionBounds.Y),
|
|
66
|
-
errorTextHeight = errorTextHeight,
|
|
67
|
-
typeBadgeWidth = typeBadgeWidth,
|
|
68
|
-
}
|
|
18
|
+
return `<font color="#{color:ToHex()}">{subText}</font>{unhighlightedText}`
|
|
69
19
|
end
|
|
70
20
|
return {
|
|
71
21
|
highlightMatching = highlightMatching,
|
|
72
|
-
getSuggestionTextBounds = getSuggestionTextBounds,
|
|
73
22
|
}
|
|
@@ -44,8 +44,8 @@ local function TerminalTextField(_param)
|
|
|
44
44
|
local ref = source()
|
|
45
45
|
local commandHistory = source({})
|
|
46
46
|
local commandHistoryIndex = source(nil)
|
|
47
|
-
local text = source("")
|
|
48
47
|
local suggestionText = source("")
|
|
48
|
+
local currentTextValue = ""
|
|
49
49
|
-- Focus text field when terminal becomes visible
|
|
50
50
|
effect(function()
|
|
51
51
|
if visible() then
|
|
@@ -69,9 +69,13 @@ local function TerminalTextField(_param)
|
|
|
69
69
|
if not up and historyIndex == nil then
|
|
70
70
|
return nil
|
|
71
71
|
end
|
|
72
|
+
local textBox = ref()
|
|
73
|
+
if textBox == nil then
|
|
74
|
+
return nil
|
|
75
|
+
end
|
|
72
76
|
local lastIndex = #history - 1
|
|
73
77
|
if not up and historyIndex == lastIndex then
|
|
74
|
-
|
|
78
|
+
textBox.Text = ""
|
|
75
79
|
suggestionText("")
|
|
76
80
|
commandHistoryIndex(nil)
|
|
77
81
|
return nil
|
|
@@ -82,13 +86,10 @@ local function TerminalTextField(_param)
|
|
|
82
86
|
end
|
|
83
87
|
local newIndex = math.clamp(_condition + (if up then -1 else 1), 0, lastIndex)
|
|
84
88
|
local newText = history[newIndex + 1]
|
|
85
|
-
|
|
89
|
+
textBox.Text = newText
|
|
90
|
+
textBox.CursorPosition = #newText + 1
|
|
86
91
|
suggestionText("")
|
|
87
92
|
commandHistoryIndex(newIndex)
|
|
88
|
-
local textBox = ref()
|
|
89
|
-
if textBox ~= nil then
|
|
90
|
-
textBox.CursorPosition = #newText + 1
|
|
91
|
-
end
|
|
92
93
|
end
|
|
93
94
|
local suggestionConnection = subscribe(currentSuggestion, function(suggestion)
|
|
94
95
|
if suggestion == nil then
|
|
@@ -101,10 +102,18 @@ local function TerminalTextField(_param)
|
|
|
101
102
|
suggestionText(suggestion.title)
|
|
102
103
|
return nil
|
|
103
104
|
end
|
|
105
|
+
local _currentText = ref()
|
|
106
|
+
if _currentText ~= nil then
|
|
107
|
+
_currentText = _currentText.Text
|
|
108
|
+
end
|
|
109
|
+
local currentText = _currentText
|
|
110
|
+
if currentText == nil then
|
|
111
|
+
return nil
|
|
112
|
+
end
|
|
104
113
|
-- Command suggestions
|
|
105
114
|
if suggestion.type == "command" then
|
|
106
115
|
local suggestionStartIndex = (if not atNextPart then #textParts[#textParts] else 0) + 1
|
|
107
|
-
suggestionText(
|
|
116
|
+
suggestionText(currentText .. string.sub(suggestion.title, suggestionStartIndex))
|
|
108
117
|
return nil
|
|
109
118
|
end
|
|
110
119
|
-- Argument suggestions
|
|
@@ -113,7 +122,7 @@ local function TerminalTextField(_param)
|
|
|
113
122
|
if suggestion.type ~= "argument" or command == nil or argIndex == nil then
|
|
114
123
|
return nil
|
|
115
124
|
end
|
|
116
|
-
local newText =
|
|
125
|
+
local newText = currentText
|
|
117
126
|
if atNextPart and argIndex == commandArgIndex() then
|
|
118
127
|
newText ..= suggestion.title
|
|
119
128
|
elseif not (#suggestion.others == 0) then
|
|
@@ -162,7 +171,7 @@ local function TerminalTextField(_param)
|
|
|
162
171
|
if suggestion == nil then
|
|
163
172
|
return nil
|
|
164
173
|
end
|
|
165
|
-
local currentText =
|
|
174
|
+
local currentText = textBox.Text
|
|
166
175
|
local atNextPart = string.sub(currentText, -1) == " "
|
|
167
176
|
if commandPath == nil then
|
|
168
177
|
local suggestionTitle = suggestion.title
|
|
@@ -208,7 +217,7 @@ local function TerminalTextField(_param)
|
|
|
208
217
|
newText ..= " "
|
|
209
218
|
end
|
|
210
219
|
suggestionText("")
|
|
211
|
-
|
|
220
|
+
textBox.Text = newText
|
|
212
221
|
textBox.CursorPosition = #newText + 1
|
|
213
222
|
return nil
|
|
214
223
|
end
|
|
@@ -232,7 +241,7 @@ local function TerminalTextField(_param)
|
|
|
232
241
|
if _condition_1 then
|
|
233
242
|
suggestionText("")
|
|
234
243
|
local newText = `{currentText} `
|
|
235
|
-
|
|
244
|
+
textBox.Text = newText
|
|
236
245
|
textBox.CursorPosition = #newText + 1
|
|
237
246
|
return nil
|
|
238
247
|
end
|
|
@@ -244,7 +253,7 @@ local function TerminalTextField(_param)
|
|
|
244
253
|
if argIndex == nil or commandArgs == nil then
|
|
245
254
|
return nil
|
|
246
255
|
end
|
|
247
|
-
local newText =
|
|
256
|
+
local newText = currentText
|
|
248
257
|
local otherSuggestion = suggestion.others[1]
|
|
249
258
|
local _newText = newText
|
|
250
259
|
local _exp = #newText
|
|
@@ -262,7 +271,7 @@ local function TerminalTextField(_param)
|
|
|
262
271
|
newText ..= " "
|
|
263
272
|
end
|
|
264
273
|
suggestionText("")
|
|
265
|
-
|
|
274
|
+
textBox.Text = newText
|
|
266
275
|
textBox.CursorPosition = #newText + 1
|
|
267
276
|
end)
|
|
268
277
|
return Vide.jsx(Frame, {
|
|
@@ -283,22 +292,6 @@ local function TerminalTextField(_param)
|
|
|
283
292
|
}), Vide.jsx(TextField, {
|
|
284
293
|
action = ref,
|
|
285
294
|
size = UDim2.fromScale(1, 1),
|
|
286
|
-
text = function()
|
|
287
|
-
local value = text()
|
|
288
|
-
-- Remove line breaks
|
|
289
|
-
if (string.match(value, "[\n\r]")) ~= nil then
|
|
290
|
-
value = (string.gsub(value, "[\n\r]", ""))
|
|
291
|
-
end
|
|
292
|
-
-- Remove all tabs from text input - we use these for autocompletion
|
|
293
|
-
if (string.match(value, "\t")) ~= nil then
|
|
294
|
-
value = (string.gsub(value, "\t", ""))
|
|
295
|
-
end
|
|
296
|
-
local _result = onTextChange
|
|
297
|
-
if _result ~= nil then
|
|
298
|
-
_result(value)
|
|
299
|
-
end
|
|
300
|
-
return value
|
|
301
|
-
end,
|
|
302
295
|
textSize = function()
|
|
303
296
|
return px(TEXT_SIZE)
|
|
304
297
|
end,
|
|
@@ -339,15 +332,36 @@ local function TerminalTextField(_param)
|
|
|
339
332
|
if _result ~= nil then
|
|
340
333
|
_result(currentText)
|
|
341
334
|
end
|
|
335
|
+
textBox.Text = ""
|
|
342
336
|
textBox:CaptureFocus()
|
|
343
|
-
text("")
|
|
344
337
|
end,
|
|
345
338
|
TextChanged = function(currentText)
|
|
339
|
+
local textBox = ref()
|
|
340
|
+
if textBox == nil then
|
|
341
|
+
return nil
|
|
342
|
+
end
|
|
346
343
|
local historyIndex = commandHistoryIndex()
|
|
347
344
|
if historyIndex ~= nil and currentText ~= commandHistory()[historyIndex + 1] then
|
|
348
345
|
commandHistoryIndex(nil)
|
|
349
346
|
end
|
|
350
|
-
|
|
347
|
+
-- Remove line breaks
|
|
348
|
+
local value = currentText
|
|
349
|
+
if (string.match(value, "[\n\r]")) ~= nil then
|
|
350
|
+
value = (string.gsub(value, "[\n\r]", ""))
|
|
351
|
+
end
|
|
352
|
+
-- Remove all tabs from text input - we use these for autocompletion
|
|
353
|
+
if (string.match(value, "\t")) ~= nil then
|
|
354
|
+
value = (string.gsub(value, "\t", ""))
|
|
355
|
+
end
|
|
356
|
+
textBox.Text = value
|
|
357
|
+
if currentTextValue == value then
|
|
358
|
+
return nil
|
|
359
|
+
end
|
|
360
|
+
currentTextValue = value
|
|
361
|
+
local _result = onTextChange
|
|
362
|
+
if _result ~= nil then
|
|
363
|
+
_result(value)
|
|
364
|
+
end
|
|
351
365
|
end,
|
|
352
366
|
},
|
|
353
367
|
zIndex = 2,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rbxts/centurion-ui",
|
|
3
3
|
"description": "Terminal UI for the Centurion command framework",
|
|
4
|
-
"version": "1.0.0-dev-
|
|
4
|
+
"version": "1.0.0-dev-2d5383e",
|
|
5
5
|
"author": "paradoxuum",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "out/init.lua",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dev": "shx rm -rf out && rbxtsc -w"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@rbxts/centurion": "^1.0.0-dev-
|
|
35
|
+
"@rbxts/centurion": "^1.0.0-dev-2d5383e",
|
|
36
36
|
"@rbxts/compiler-types": "2.3.0-types.1",
|
|
37
37
|
"@rbxts/types": "^1.0.794",
|
|
38
38
|
"roblox-ts": "2.3.0-dev-26ec859",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { DebounceOptions } from "@rbxts/set-timeout";
|
|
2
|
-
export interface UseDebounceOptions extends DebounceOptions {
|
|
3
|
-
/**
|
|
4
|
-
* The amount of time to wait before the first call.
|
|
5
|
-
*/
|
|
6
|
-
wait?: number;
|
|
7
|
-
}
|
|
8
|
-
export declare function useDebounceSource<T>(initialValue: T, options?: UseDebounceOptions): {
|
|
9
|
-
get: () => T;
|
|
10
|
-
set: (value: T) => T;
|
|
11
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
|
-
local TS = _G[script]
|
|
3
|
-
local debounce = TS.import(script, TS.getModule(script, "@rbxts", "set-timeout").out).debounce
|
|
4
|
-
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
5
|
-
local cleanup = _vide.cleanup
|
|
6
|
-
local source = _vide.source
|
|
7
|
-
local function useDebounceSource(initialValue, options)
|
|
8
|
-
if options == nil then
|
|
9
|
-
options = {}
|
|
10
|
-
end
|
|
11
|
-
local state = source(initialValue)
|
|
12
|
-
local update = debounce(state, options.wait, options)
|
|
13
|
-
cleanup(function()
|
|
14
|
-
update.cancel()
|
|
15
|
-
end)
|
|
16
|
-
return {
|
|
17
|
-
get = function()
|
|
18
|
-
return state()
|
|
19
|
-
end,
|
|
20
|
-
set = function(value)
|
|
21
|
-
return update(value)
|
|
22
|
-
end,
|
|
23
|
-
}
|
|
24
|
-
end
|
|
25
|
-
return {
|
|
26
|
-
useDebounceSource = useDebounceSource,
|
|
27
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { MotionGoal } from "@rbxts/ripple";
|
|
2
|
-
type NonStrict<T> = T extends number ? number : T;
|
|
3
|
-
export declare function useMotion<T extends MotionGoal>(initialValue: NonStrict<T>): LuaTuple<[import("@rbxts/vide").Source<NonStrict<T>>, import("@rbxts/ripple").Motion<NonStrict<T>>]>;
|
|
4
|
-
export {};
|
package/out/hooks/use-motion.lua
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
|
-
local TS = _G[script]
|
|
3
|
-
local createMotion = TS.import(script, TS.getModule(script, "@rbxts", "ripple").src).createMotion
|
|
4
|
-
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
5
|
-
local cleanup = _vide.cleanup
|
|
6
|
-
local source = _vide.source
|
|
7
|
-
local function useMotion(initialValue)
|
|
8
|
-
local motion = createMotion(initialValue)
|
|
9
|
-
local state = source(initialValue)
|
|
10
|
-
motion:onStep(state)
|
|
11
|
-
motion:start()
|
|
12
|
-
cleanup(function()
|
|
13
|
-
motion:stop()
|
|
14
|
-
end)
|
|
15
|
-
return state, motion
|
|
16
|
-
end
|
|
17
|
-
return {
|
|
18
|
-
useMotion = useMotion,
|
|
19
|
-
}
|