@rbxts/centurion-ui 1.0.5 → 1.0.7
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/LICENSE.md +21 -0
- package/out/app/init.luau +1 -30
- package/out/components/history/history-line.d.ts +1 -2
- package/out/components/history/history-line.luau +7 -4
- package/out/components/history/history-list.d.ts +4 -4
- package/out/components/history/history-list.luau +30 -23
- package/out/components/suggestions/main-suggestion.d.ts +2 -6
- package/out/components/suggestions/main-suggestion.luau +108 -55
- package/out/components/suggestions/suggestions.luau +6 -117
- package/out/components/terminal/terminal-text-field/terminal-text-field.luau +8 -0
- package/out/components/terminal/terminal.luau +22 -10
- package/out/components/ui/scrolling-frame.luau +1 -0
- package/out/components/ui/text-field.luau +1 -1
- package/out/components/ui/text.d.ts +0 -1
- package/out/components/ui/text.luau +1 -1
- package/package.json +8 -9
- package/out/hooks/use-history.d.ts +0 -2
- package/out/hooks/use-history.luau +0 -54
- package/out/hooks/use-text-bounds.d.ts +0 -9
- package/out/hooks/use-text-bounds.luau +0 -50
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 paradox
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/out/app/init.luau
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
-- Compiled with roblox-ts v3.0.0
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local CenturionType = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out).CenturionType
|
|
4
|
-
local
|
|
5
|
-
local ContentProvider = _services.ContentProvider
|
|
6
|
-
local Players = _services.Players
|
|
4
|
+
local Players = TS.import(script, TS.getModule(script, "@rbxts", "services")).Players
|
|
7
5
|
local mount = TS.import(script, TS.getModule(script, "@rbxts", "vide").src).mount
|
|
8
6
|
local DEFAULT_INTERFACE_OPTIONS = TS.import(script, script.Parent, "constants", "options").DEFAULT_INTERFACE_OPTIONS
|
|
9
7
|
local DefaultPalette = TS.import(script, script.Parent, "palette").DefaultPalette
|
|
@@ -14,8 +12,6 @@ local CenturionApp = TS.import(script, script, "centurion-app").CenturionApp
|
|
|
14
12
|
local CenturionUI = {}
|
|
15
13
|
do
|
|
16
14
|
local _container = CenturionUI
|
|
17
|
-
local MAX_PRELOAD_ATTEMPTS = 3
|
|
18
|
-
local PRELOAD_ATTEMPT_INTERVAL = 3
|
|
19
15
|
--[[
|
|
20
16
|
*
|
|
21
17
|
* Returns whether the terminal UI is visible.
|
|
@@ -77,31 +73,6 @@ do
|
|
|
77
73
|
registerCommands(client.registry)
|
|
78
74
|
end
|
|
79
75
|
updateOptions(options)
|
|
80
|
-
-- Attempt to preload font
|
|
81
|
-
task.spawn(function()
|
|
82
|
-
local _result = options.font
|
|
83
|
-
if _result ~= nil then
|
|
84
|
-
_result = _result.regular
|
|
85
|
-
end
|
|
86
|
-
local _condition = _result
|
|
87
|
-
if _condition == nil then
|
|
88
|
-
_condition = DEFAULT_INTERFACE_OPTIONS.font.regular
|
|
89
|
-
end
|
|
90
|
-
local fontFamily = _condition.Family
|
|
91
|
-
local attempts = 0
|
|
92
|
-
while attempts < MAX_PRELOAD_ATTEMPTS do
|
|
93
|
-
ContentProvider:PreloadAsync({ fontFamily }, function(_, status)
|
|
94
|
-
if status == Enum.AssetFetchStatus.Success then
|
|
95
|
-
attempts = MAX_PRELOAD_ATTEMPTS
|
|
96
|
-
end
|
|
97
|
-
end)
|
|
98
|
-
if attempts == MAX_PRELOAD_ATTEMPTS then
|
|
99
|
-
break
|
|
100
|
-
end
|
|
101
|
-
task.wait(PRELOAD_ATTEMPT_INTERVAL)
|
|
102
|
-
attempts += 1
|
|
103
|
-
end
|
|
104
|
-
end)
|
|
105
76
|
mount(function()
|
|
106
77
|
return CenturionApp(client)
|
|
107
78
|
end, Players.LocalPlayer:WaitForChild("PlayerGui"))
|
|
@@ -2,9 +2,8 @@ import { HistoryEntry } from "@rbxts/centurion";
|
|
|
2
2
|
import Vide, { Derivable } from "@rbxts/vide";
|
|
3
3
|
interface HistoryLineProps {
|
|
4
4
|
data: HistoryEntry;
|
|
5
|
-
size?: Derivable<UDim2>;
|
|
6
5
|
position?: Derivable<UDim2>;
|
|
7
6
|
order?: Derivable<number>;
|
|
8
7
|
}
|
|
9
|
-
export declare function HistoryLine({ data,
|
|
8
|
+
export declare function HistoryLine({ data, position, order }: HistoryLineProps): Vide.Node;
|
|
10
9
|
export {};
|
|
@@ -13,7 +13,6 @@ local Text = TS.import(script, script.Parent.Parent, "ui", "text").Text
|
|
|
13
13
|
local TextField = TS.import(script, script.Parent.Parent, "ui", "text-field").TextField
|
|
14
14
|
local function HistoryLine(_param)
|
|
15
15
|
local data = _param.data
|
|
16
|
-
local size = _param.size
|
|
17
16
|
local position = _param.position
|
|
18
17
|
local order = _param.order
|
|
19
18
|
local date = derive(function()
|
|
@@ -22,7 +21,8 @@ local function HistoryLine(_param)
|
|
|
22
21
|
return `<b>{dateParts[1]}</b> {dateParts[2]}`
|
|
23
22
|
end)
|
|
24
23
|
return Vide.jsx(Group, {
|
|
25
|
-
|
|
24
|
+
automaticSize = "Y",
|
|
25
|
+
size = UDim2.fromScale(1, 0),
|
|
26
26
|
position = position,
|
|
27
27
|
layoutOrder = order,
|
|
28
28
|
}, Vide.jsx(Frame, {
|
|
@@ -58,11 +58,14 @@ local function HistoryLine(_param)
|
|
|
58
58
|
return UDim.new(0, px(4))
|
|
59
59
|
end,
|
|
60
60
|
})), Vide.jsx(TextField, {
|
|
61
|
+
automaticSize = "Y",
|
|
61
62
|
anchor = Vector2.new(1, 0),
|
|
62
63
|
size = function()
|
|
63
|
-
return UDim2.new(1, -px(84),
|
|
64
|
+
return UDim2.new(1, -px(84), 0, 0)
|
|
65
|
+
end,
|
|
66
|
+
position = function()
|
|
67
|
+
return UDim2.new(1, 0, 0, px(2))
|
|
64
68
|
end,
|
|
65
|
-
position = UDim2.fromScale(1, 0),
|
|
66
69
|
text = data.text,
|
|
67
70
|
textSize = function()
|
|
68
71
|
return px(HISTORY_TEXT_SIZE)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { HistoryEntry } from "@rbxts/centurion";
|
|
1
2
|
import Vide, { Derivable } from "@rbxts/vide";
|
|
2
|
-
import { HistoryData } from "../../types";
|
|
3
3
|
interface HistoryListProps {
|
|
4
|
-
|
|
4
|
+
entries: Derivable<HistoryEntry[]>;
|
|
5
5
|
size?: Derivable<UDim2>;
|
|
6
6
|
position?: Derivable<UDim2>;
|
|
7
|
-
maxHeight?: Derivable<number>;
|
|
8
7
|
scrollingEnabled?: Derivable<boolean>;
|
|
8
|
+
onContentSizeChanged?: (size: Vector2) => void;
|
|
9
9
|
}
|
|
10
|
-
export declare function HistoryList({
|
|
10
|
+
export declare function HistoryList({ entries, size, position, scrollingEnabled, onContentSizeChanged, }: HistoryListProps): Vide.Node;
|
|
11
11
|
export {};
|
|
@@ -2,50 +2,50 @@
|
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
4
4
|
local Vide = _vide
|
|
5
|
-
local derive = _vide.derive
|
|
6
5
|
local For = _vide.For
|
|
7
6
|
local read = _vide.read
|
|
7
|
+
local source = _vide.source
|
|
8
8
|
local px = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-px").px
|
|
9
9
|
local options = TS.import(script, script.Parent.Parent.Parent, "store").options
|
|
10
10
|
local ScrollingFrame = TS.import(script, script.Parent.Parent, "ui", "scrolling-frame").ScrollingFrame
|
|
11
11
|
local HistoryLine = TS.import(script, script.Parent, "history-line").HistoryLine
|
|
12
12
|
local function HistoryList(_param)
|
|
13
|
-
local
|
|
13
|
+
local entries = _param.entries
|
|
14
14
|
local size = _param.size
|
|
15
15
|
local position = _param.position
|
|
16
|
-
local
|
|
17
|
-
local
|
|
18
|
-
|
|
19
|
-
end)
|
|
20
|
-
local exceedsMaxHeight = derive(function()
|
|
21
|
-
return maxHeight ~= nil and height() > read(maxHeight)
|
|
22
|
-
end)
|
|
16
|
+
local scrollingEnabled = _param.scrollingEnabled
|
|
17
|
+
local onContentSizeChanged = _param.onContentSizeChanged
|
|
18
|
+
local ref = source()
|
|
23
19
|
return Vide.jsx(ScrollingFrame, {
|
|
20
|
+
automaticCanvasSize = "Y",
|
|
24
21
|
size = size,
|
|
25
22
|
position = position,
|
|
26
|
-
canvasSize =
|
|
27
|
-
|
|
28
|
-
end,
|
|
29
|
-
canvasPosition = function()
|
|
30
|
-
return Vector2.new(0, height())
|
|
31
|
-
end,
|
|
23
|
+
canvasSize = UDim2.new(),
|
|
24
|
+
action = ref,
|
|
32
25
|
scrollBarColor = function()
|
|
33
26
|
return options().palette.subtext
|
|
34
27
|
end,
|
|
28
|
+
scrollingEnabled = scrollingEnabled,
|
|
35
29
|
scrollBarThickness = function()
|
|
36
|
-
return if
|
|
37
|
-
end,
|
|
38
|
-
scrollingEnabled = function()
|
|
39
|
-
return exceedsMaxHeight()
|
|
30
|
+
return if read(scrollingEnabled) then 10 else 0
|
|
40
31
|
end,
|
|
32
|
+
scrollingDirection = "Y",
|
|
33
|
+
native = {
|
|
34
|
+
AbsoluteCanvasSizeChanged = function(rbx)
|
|
35
|
+
local frame = ref()
|
|
36
|
+
if frame == nil then
|
|
37
|
+
return nil
|
|
38
|
+
end
|
|
39
|
+
frame.CanvasPosition = Vector2.new(0, rbx.Y)
|
|
40
|
+
end,
|
|
41
|
+
},
|
|
41
42
|
}, Vide.jsx(For, {
|
|
42
43
|
each = function()
|
|
43
|
-
return read(
|
|
44
|
+
return read(entries)
|
|
44
45
|
end,
|
|
45
|
-
}, function(
|
|
46
|
+
}, function(entry, index)
|
|
46
47
|
return Vide.jsx(HistoryLine, {
|
|
47
|
-
|
|
48
|
-
data = line.entry,
|
|
48
|
+
data = entry,
|
|
49
49
|
order = index,
|
|
50
50
|
})
|
|
51
51
|
end), Vide.jsx("uilistlayout", {
|
|
@@ -53,6 +53,13 @@ local function HistoryList(_param)
|
|
|
53
53
|
return UDim.new(0, px(8))
|
|
54
54
|
end,
|
|
55
55
|
SortOrder = "LayoutOrder",
|
|
56
|
+
AbsoluteContentSizeChanged = function(rbx)
|
|
57
|
+
local _result = onContentSizeChanged
|
|
58
|
+
if _result ~= nil then
|
|
59
|
+
_result = _result(rbx)
|
|
60
|
+
end
|
|
61
|
+
return _result
|
|
62
|
+
end,
|
|
56
63
|
}))
|
|
57
64
|
end
|
|
58
65
|
return {
|
|
@@ -3,11 +3,7 @@ import { Suggestion } from "../../types";
|
|
|
3
3
|
export interface MainSuggestionProps {
|
|
4
4
|
suggestion: Derivable<Suggestion | undefined>;
|
|
5
5
|
currentText?: Derivable<string | undefined>;
|
|
6
|
-
size: Derivable<UDim2>;
|
|
7
|
-
titleSize: Derivable<UDim2>;
|
|
8
|
-
descriptionSize: Derivable<UDim2>;
|
|
9
|
-
badgeSize: Derivable<UDim2>;
|
|
10
|
-
errorSize: Derivable<UDim2>;
|
|
11
6
|
action?: (instance: Frame) => void;
|
|
7
|
+
onSizeChanged?: (size: UDim2) => void;
|
|
12
8
|
}
|
|
13
|
-
export declare function MainSuggestion({ suggestion, currentText,
|
|
9
|
+
export declare function MainSuggestion({ suggestion, currentText, action, onSizeChanged, }: MainSuggestionProps): Vide.Node;
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
4
4
|
local Vide = _vide
|
|
5
|
+
local derive = _vide.derive
|
|
5
6
|
local read = _vide.read
|
|
7
|
+
local source = _vide.source
|
|
6
8
|
local spring = _vide.spring
|
|
7
9
|
local _text = TS.import(script, script.Parent.Parent.Parent, "constants", "text")
|
|
8
10
|
local SUGGESTION_TEXT_SIZE = _text.SUGGESTION_TEXT_SIZE
|
|
@@ -14,20 +16,49 @@ local options = _store.options
|
|
|
14
16
|
local Frame = TS.import(script, script.Parent.Parent, "ui", "frame").Frame
|
|
15
17
|
local Padding = TS.import(script, script.Parent.Parent, "ui", "padding").Padding
|
|
16
18
|
local Text = TS.import(script, script.Parent.Parent, "ui", "text").Text
|
|
17
|
-
local Badge = TS.import(script, script.Parent, "badge").Badge
|
|
18
19
|
local highlightMatching = TS.import(script, script.Parent, "util").highlightMatching
|
|
20
|
+
local MAX_WIDTH = 180
|
|
19
21
|
local function MainSuggestion(_param)
|
|
20
22
|
local suggestion = _param.suggestion
|
|
21
23
|
local currentText = _param.currentText
|
|
22
|
-
local size = _param.size
|
|
23
|
-
local titleSize = _param.titleSize
|
|
24
|
-
local descriptionSize = _param.descriptionSize
|
|
25
|
-
local badgeSize = _param.badgeSize
|
|
26
|
-
local errorSize = _param.errorSize
|
|
27
24
|
local action = _param.action
|
|
25
|
+
local onSizeChanged = _param.onSizeChanged
|
|
26
|
+
local titleBounds = source(Vector2.new())
|
|
27
|
+
local descriptionBounds = source(Vector2.new())
|
|
28
|
+
local errorBounds = source(Vector2.new())
|
|
29
|
+
local badgeBounds = source(Vector2.new())
|
|
30
|
+
local errorText = derive(function()
|
|
31
|
+
local currentSuggestion = read(suggestion)
|
|
32
|
+
local _result = currentSuggestion
|
|
33
|
+
if _result ~= nil then
|
|
34
|
+
_result = _result.type
|
|
35
|
+
end
|
|
36
|
+
return if _result == "argument" then currentSuggestion.error else nil
|
|
37
|
+
end)
|
|
38
|
+
local windowSize = derive(function()
|
|
39
|
+
if read(suggestion) == nil then
|
|
40
|
+
local size = UDim2.new()
|
|
41
|
+
local _result = onSizeChanged
|
|
42
|
+
if _result ~= nil then
|
|
43
|
+
_result(size)
|
|
44
|
+
end
|
|
45
|
+
return size
|
|
46
|
+
end
|
|
47
|
+
local titleSize = read(titleBounds)
|
|
48
|
+
local descriptionSize = read(descriptionBounds)
|
|
49
|
+
local errorSize = read(errorBounds)
|
|
50
|
+
local width = math.max(titleSize.X, descriptionSize.X, errorSize.X) + badgeBounds().X
|
|
51
|
+
local height = titleSize.Y + descriptionSize.Y + errorSize.Y
|
|
52
|
+
local size = UDim2.fromOffset(width + px(8) * 2, height + px(8) * 2)
|
|
53
|
+
local _result = onSizeChanged
|
|
54
|
+
if _result ~= nil then
|
|
55
|
+
_result(size)
|
|
56
|
+
end
|
|
57
|
+
return size
|
|
58
|
+
end)
|
|
28
59
|
return Vide.jsx(Frame, {
|
|
29
60
|
action = action,
|
|
30
|
-
size =
|
|
61
|
+
size = spring(windowSize, 0.2),
|
|
31
62
|
backgroundColor = function()
|
|
32
63
|
return options().palette.background
|
|
33
64
|
end,
|
|
@@ -53,29 +84,6 @@ local function MainSuggestion(_param)
|
|
|
53
84
|
all = function()
|
|
54
85
|
return UDim.new(0, px(8))
|
|
55
86
|
end,
|
|
56
|
-
}), Vide.jsx(Badge, {
|
|
57
|
-
color = function()
|
|
58
|
-
return options().palette.highlight
|
|
59
|
-
end,
|
|
60
|
-
text = function()
|
|
61
|
-
local currentSuggestion = read(suggestion)
|
|
62
|
-
return if currentSuggestion ~= nil and currentSuggestion.type == "argument" then currentSuggestion.dataType else ""
|
|
63
|
-
end,
|
|
64
|
-
textColor = function()
|
|
65
|
-
return options().palette.surface
|
|
66
|
-
end,
|
|
67
|
-
textSize = function()
|
|
68
|
-
return px(SUGGESTION_TEXT_SIZE)
|
|
69
|
-
end,
|
|
70
|
-
visible = function()
|
|
71
|
-
local currentSuggestion = read(suggestion)
|
|
72
|
-
return currentSuggestion ~= nil and currentSuggestion.type == "argument"
|
|
73
|
-
end,
|
|
74
|
-
anchor = Vector2.new(1, 0),
|
|
75
|
-
position = UDim2.fromScale(1, 0),
|
|
76
|
-
size = spring(function()
|
|
77
|
-
return UDim2.fromOffset(read(badgeSize).X.Offset + px(4), px(SUGGESTION_TITLE_TEXT_SIZE))
|
|
78
|
-
end, 0.2),
|
|
79
87
|
}), Vide.jsx(Text, {
|
|
80
88
|
text = function()
|
|
81
89
|
local currentSuggestion = read(suggestion)
|
|
@@ -108,7 +116,14 @@ local function MainSuggestion(_param)
|
|
|
108
116
|
return options().font.bold
|
|
109
117
|
end,
|
|
110
118
|
richText = true,
|
|
111
|
-
size =
|
|
119
|
+
size = function()
|
|
120
|
+
return UDim2.fromOffset(titleBounds().X, px(SUGGESTION_TITLE_TEXT_SIZE))
|
|
121
|
+
end,
|
|
122
|
+
native = {
|
|
123
|
+
TextBoundsChanged = function(bounds)
|
|
124
|
+
return titleBounds(bounds)
|
|
125
|
+
end,
|
|
126
|
+
},
|
|
112
127
|
}), Vide.jsx(Text, {
|
|
113
128
|
text = function()
|
|
114
129
|
local _result = read(suggestion)
|
|
@@ -134,21 +149,21 @@ local function MainSuggestion(_param)
|
|
|
134
149
|
position = function()
|
|
135
150
|
return UDim2.fromOffset(0, px(SUGGESTION_TITLE_TEXT_SIZE))
|
|
136
151
|
end,
|
|
137
|
-
size =
|
|
152
|
+
size = function()
|
|
153
|
+
return UDim2.fromOffset(px(MAX_WIDTH), math.max(descriptionBounds().Y, px(SUGGESTION_TEXT_SIZE)))
|
|
154
|
+
end,
|
|
155
|
+
native = {
|
|
156
|
+
TextBoundsChanged = function(rbx)
|
|
157
|
+
return descriptionBounds(rbx)
|
|
158
|
+
end,
|
|
159
|
+
},
|
|
138
160
|
}), Vide.jsx(Text, {
|
|
139
161
|
text = function()
|
|
140
|
-
local
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
local _condition = currentSuggestion.error
|
|
144
|
-
if _condition == nil then
|
|
145
|
-
_condition = ""
|
|
146
|
-
end
|
|
147
|
-
_result = _condition
|
|
148
|
-
else
|
|
149
|
-
_result = ""
|
|
162
|
+
local _condition = errorText()
|
|
163
|
+
if _condition == nil then
|
|
164
|
+
_condition = ""
|
|
150
165
|
end
|
|
151
|
-
return
|
|
166
|
+
return _condition
|
|
152
167
|
end,
|
|
153
168
|
textColor = function()
|
|
154
169
|
return options().palette.error
|
|
@@ -157,22 +172,60 @@ local function MainSuggestion(_param)
|
|
|
157
172
|
return px(SUGGESTION_TEXT_SIZE)
|
|
158
173
|
end,
|
|
159
174
|
textTransparency = spring(function()
|
|
160
|
-
|
|
161
|
-
local _result = currentSuggestion
|
|
162
|
-
if _result ~= nil then
|
|
163
|
-
_result = _result.type
|
|
164
|
-
end
|
|
165
|
-
local _condition = _result == "argument"
|
|
166
|
-
if _condition then
|
|
167
|
-
_condition = currentSuggestion.error ~= nil
|
|
168
|
-
end
|
|
169
|
-
return if _condition then 0 else 1
|
|
175
|
+
return if errorText() ~= nil then 0 else 1
|
|
170
176
|
end, 0.2),
|
|
171
177
|
textXAlignment = "Left",
|
|
178
|
+
textWrapped = true,
|
|
179
|
+
automaticSize = "Y",
|
|
172
180
|
anchor = Vector2.new(0, 1),
|
|
173
181
|
position = UDim2.fromScale(0, 1),
|
|
174
|
-
size =
|
|
175
|
-
|
|
182
|
+
size = function()
|
|
183
|
+
return UDim2.fromOffset(px(MAX_WIDTH), 0)
|
|
184
|
+
end,
|
|
185
|
+
native = {
|
|
186
|
+
TextBoundsChanged = function(bounds)
|
|
187
|
+
errorBounds(if errorText() ~= nil then bounds else Vector2.zero)
|
|
188
|
+
end,
|
|
189
|
+
},
|
|
190
|
+
}), Vide.jsx(Frame, {
|
|
191
|
+
backgroundColor = function()
|
|
192
|
+
return options().palette.highlight
|
|
193
|
+
end,
|
|
194
|
+
cornerRadius = function()
|
|
195
|
+
return UDim.new(0, px(4))
|
|
196
|
+
end,
|
|
197
|
+
clipsDescendants = true,
|
|
198
|
+
visible = function()
|
|
199
|
+
local currentSuggestion = read(suggestion)
|
|
200
|
+
return currentSuggestion ~= nil and currentSuggestion.type == "argument"
|
|
201
|
+
end,
|
|
202
|
+
anchor = Vector2.new(1, 0),
|
|
203
|
+
position = UDim2.fromScale(1, 0),
|
|
204
|
+
size = spring(function()
|
|
205
|
+
return UDim2.fromOffset(badgeBounds().X + px(4), px(SUGGESTION_TITLE_TEXT_SIZE))
|
|
206
|
+
end, 0.2),
|
|
207
|
+
}, Vide.jsx(Text, {
|
|
208
|
+
text = function()
|
|
209
|
+
local currentSuggestion = read(suggestion)
|
|
210
|
+
return if currentSuggestion ~= nil and currentSuggestion.type == "argument" then currentSuggestion.dataType else ""
|
|
211
|
+
end,
|
|
212
|
+
textColor = function()
|
|
213
|
+
return options().palette.surface
|
|
214
|
+
end,
|
|
215
|
+
textSize = function()
|
|
216
|
+
return px(SUGGESTION_TEXT_SIZE)
|
|
217
|
+
end,
|
|
218
|
+
textXAlignment = "Center",
|
|
219
|
+
font = function()
|
|
220
|
+
return options().font.bold
|
|
221
|
+
end,
|
|
222
|
+
size = UDim2.fromScale(1, 1),
|
|
223
|
+
native = {
|
|
224
|
+
TextBoundsChanged = function(bounds)
|
|
225
|
+
return badgeBounds(bounds)
|
|
226
|
+
end,
|
|
227
|
+
},
|
|
228
|
+
})))
|
|
176
229
|
end
|
|
177
230
|
return {
|
|
178
231
|
MainSuggestion = MainSuggestion,
|
|
@@ -7,107 +7,17 @@ local cleanup = _vide.cleanup
|
|
|
7
7
|
local derive = _vide.derive
|
|
8
8
|
local source = _vide.source
|
|
9
9
|
local spring = _vide.spring
|
|
10
|
-
local
|
|
11
|
-
local SUGGESTION_TEXT_SIZE = _text.SUGGESTION_TEXT_SIZE
|
|
12
|
-
local SUGGESTION_TITLE_TEXT_SIZE = _text.SUGGESTION_TITLE_TEXT_SIZE
|
|
10
|
+
local SUGGESTION_TEXT_SIZE = TS.import(script, script.Parent.Parent.Parent, "constants", "text").SUGGESTION_TEXT_SIZE
|
|
13
11
|
local px = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-px").px
|
|
14
|
-
local useTextBounds = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-text-bounds").useTextBounds
|
|
15
12
|
local _store = TS.import(script, script.Parent.Parent.Parent, "store")
|
|
16
13
|
local currentSuggestion = _store.currentSuggestion
|
|
17
14
|
local currentTextPart = _store.currentTextPart
|
|
18
|
-
local options = _store.options
|
|
19
15
|
local Group = TS.import(script, script.Parent.Parent, "ui", "group").Group
|
|
20
16
|
local MainSuggestion = TS.import(script, script.Parent, "main-suggestion").MainSuggestion
|
|
21
17
|
local SuggestionList = TS.import(script, script.Parent, "suggestion-list").SuggestionList
|
|
22
|
-
local MAX_SUGGESTION_WIDTH = 180
|
|
23
18
|
local PADDING = 8
|
|
24
19
|
local function Suggestions()
|
|
25
|
-
local
|
|
26
|
-
local offset = function(boundsState)
|
|
27
|
-
return function()
|
|
28
|
-
local bounds = boundsState()
|
|
29
|
-
return UDim2.new(0, bounds.X, 0, bounds.Y)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
local titleBounds = useTextBounds({
|
|
33
|
-
text = function()
|
|
34
|
-
local _result = currentSuggestion()
|
|
35
|
-
if _result ~= nil then
|
|
36
|
-
_result = _result.title
|
|
37
|
-
end
|
|
38
|
-
return _result
|
|
39
|
-
end,
|
|
40
|
-
font = function()
|
|
41
|
-
return options().font.bold
|
|
42
|
-
end,
|
|
43
|
-
size = function()
|
|
44
|
-
return px(SUGGESTION_TITLE_TEXT_SIZE)
|
|
45
|
-
end,
|
|
46
|
-
})
|
|
47
|
-
local descriptionBounds = useTextBounds({
|
|
48
|
-
text = function()
|
|
49
|
-
local _result = currentSuggestion()
|
|
50
|
-
if _result ~= nil then
|
|
51
|
-
_result = _result.description
|
|
52
|
-
end
|
|
53
|
-
return _result
|
|
54
|
-
end,
|
|
55
|
-
font = function()
|
|
56
|
-
return options().font.regular
|
|
57
|
-
end,
|
|
58
|
-
size = function()
|
|
59
|
-
return px(SUGGESTION_TEXT_SIZE)
|
|
60
|
-
end,
|
|
61
|
-
width = function()
|
|
62
|
-
return px(MAX_SUGGESTION_WIDTH)
|
|
63
|
-
end,
|
|
64
|
-
})
|
|
65
|
-
local typeBadgeBounds = useTextBounds({
|
|
66
|
-
text = function()
|
|
67
|
-
local suggestion = currentSuggestion()
|
|
68
|
-
local _result = suggestion
|
|
69
|
-
if _result ~= nil then
|
|
70
|
-
_result = _result.type
|
|
71
|
-
end
|
|
72
|
-
if _result == "command" then
|
|
73
|
-
return nil
|
|
74
|
-
end
|
|
75
|
-
local _result_1 = suggestion
|
|
76
|
-
if _result_1 ~= nil then
|
|
77
|
-
_result_1 = _result_1.dataType
|
|
78
|
-
end
|
|
79
|
-
return _result_1
|
|
80
|
-
end,
|
|
81
|
-
font = function()
|
|
82
|
-
return options().font.bold
|
|
83
|
-
end,
|
|
84
|
-
size = function()
|
|
85
|
-
return px(SUGGESTION_TEXT_SIZE)
|
|
86
|
-
end,
|
|
87
|
-
})
|
|
88
|
-
local errorBounds = useTextBounds({
|
|
89
|
-
text = function()
|
|
90
|
-
local suggestion = currentSuggestion()
|
|
91
|
-
local _result = suggestion
|
|
92
|
-
if _result ~= nil then
|
|
93
|
-
_result = _result.type
|
|
94
|
-
end
|
|
95
|
-
if _result == "command" then
|
|
96
|
-
return nil
|
|
97
|
-
end
|
|
98
|
-
local _result_1 = suggestion
|
|
99
|
-
if _result_1 ~= nil then
|
|
100
|
-
_result_1 = _result_1.error
|
|
101
|
-
end
|
|
102
|
-
return _result_1
|
|
103
|
-
end,
|
|
104
|
-
font = function()
|
|
105
|
-
return options().font.regular
|
|
106
|
-
end,
|
|
107
|
-
size = function()
|
|
108
|
-
return px(SUGGESTION_TEXT_SIZE)
|
|
109
|
-
end,
|
|
110
|
-
})
|
|
20
|
+
local mainSize = source(UDim2.new())
|
|
111
21
|
local listBoundsParams = Instance.new("GetTextBoundsParams")
|
|
112
22
|
listBoundsParams.RichText = true
|
|
113
23
|
cleanup(listBoundsParams)
|
|
@@ -130,39 +40,18 @@ local function Suggestions()
|
|
|
130
40
|
local height = #suggestions * px(SUGGESTION_TEXT_SIZE + 6) + (#suggestions - 1) * px(4) + px(8)
|
|
131
41
|
return Vector2.new(width, height)
|
|
132
42
|
end)
|
|
133
|
-
local windowSize = derive(function()
|
|
134
|
-
local width = math.max(titleBounds().X, descriptionBounds().X, errorBounds().X, listBounds().X) + typeBadgeBounds().X
|
|
135
|
-
local height = titleBounds().Y + descriptionBounds().Y + errorBounds().Y
|
|
136
|
-
local padding = px(PADDING * 2)
|
|
137
|
-
if width == 0 or height == 0 then
|
|
138
|
-
local _result = suggestionRef()
|
|
139
|
-
if _result ~= nil then
|
|
140
|
-
_result = _result.AbsoluteSize.Y
|
|
141
|
-
end
|
|
142
|
-
local _condition = _result
|
|
143
|
-
if _condition == nil then
|
|
144
|
-
_condition = 0
|
|
145
|
-
end
|
|
146
|
-
return UDim2.fromOffset(0, _condition)
|
|
147
|
-
end
|
|
148
|
-
return UDim2.fromOffset(width + padding, height + padding)
|
|
149
|
-
end)
|
|
150
43
|
return Vide.jsx(Group, {
|
|
151
|
-
|
|
44
|
+
automaticSize = "XY",
|
|
45
|
+
size = UDim2.fromOffset(0, 0),
|
|
152
46
|
}, Vide.jsx(MainSuggestion, {
|
|
153
47
|
suggestion = currentSuggestion,
|
|
154
48
|
currentText = currentTextPart,
|
|
155
|
-
|
|
156
|
-
titleSize = offset(titleBounds),
|
|
157
|
-
descriptionSize = offset(descriptionBounds),
|
|
158
|
-
badgeSize = offset(typeBadgeBounds),
|
|
159
|
-
errorSize = offset(errorBounds),
|
|
160
|
-
action = suggestionRef,
|
|
49
|
+
onSizeChanged = mainSize,
|
|
161
50
|
}), Vide.jsx(SuggestionList, {
|
|
162
51
|
suggestion = currentSuggestion,
|
|
163
52
|
currentText = currentTextPart,
|
|
164
53
|
size = spring(function()
|
|
165
|
-
return UDim2.
|
|
54
|
+
return UDim2.new(0, math.max(listBounds().X, mainSize().X.Offset), 0, listBounds().Y)
|
|
166
55
|
end, 0.3),
|
|
167
56
|
}), Vide.jsx("uilistlayout", {
|
|
168
57
|
Padding = function()
|
|
@@ -243,6 +243,14 @@ local function TerminalTextField(_param)
|
|
|
243
243
|
_result(value)
|
|
244
244
|
end
|
|
245
245
|
end,
|
|
246
|
+
ReturnPressedFromOnScreenKeyboard = function()
|
|
247
|
+
local textBox = ref()
|
|
248
|
+
if textBox == nil then
|
|
249
|
+
return nil
|
|
250
|
+
end
|
|
251
|
+
task.wait()
|
|
252
|
+
textBox:ReleaseFocus(true)
|
|
253
|
+
end,
|
|
246
254
|
},
|
|
247
255
|
zIndex = 2,
|
|
248
256
|
}), Vide.jsx(Text, {
|
|
@@ -10,7 +10,7 @@ local source = _vide.source
|
|
|
10
10
|
local spring = _vide.spring
|
|
11
11
|
local HISTORY_TEXT_SIZE = TS.import(script, script.Parent.Parent.Parent, "constants", "text").HISTORY_TEXT_SIZE
|
|
12
12
|
local useClient = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-client").useClient
|
|
13
|
-
local
|
|
13
|
+
local useEvent = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-event").useEvent
|
|
14
14
|
local px = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-px").px
|
|
15
15
|
local _store = TS.import(script, script.Parent.Parent.Parent, "store")
|
|
16
16
|
local commandArgIndex = _store.commandArgIndex
|
|
@@ -41,7 +41,20 @@ local TRAILING_SPACE_PATTERN = "(%s+)$"
|
|
|
41
41
|
local function Terminal()
|
|
42
42
|
local client = useClient()
|
|
43
43
|
local missingArgs = source({})
|
|
44
|
-
local history =
|
|
44
|
+
local history = source(client.dispatcher:getHistory())
|
|
45
|
+
local historyHeight = source(0)
|
|
46
|
+
useEvent(client.dispatcher.historyUpdated, function(entries)
|
|
47
|
+
local _array = {}
|
|
48
|
+
local _length = #_array
|
|
49
|
+
table.move(entries, 1, #entries, _length + 1, _array)
|
|
50
|
+
return history(_array)
|
|
51
|
+
end)
|
|
52
|
+
local maxHeight = derive(function()
|
|
53
|
+
return px(MAX_HEIGHT)
|
|
54
|
+
end)
|
|
55
|
+
local scrollingEnabled = derive(function()
|
|
56
|
+
return historyHeight() > maxHeight()
|
|
57
|
+
end)
|
|
45
58
|
local terminalTextParts = derive(function()
|
|
46
59
|
return splitString(terminalText(), " ", true)
|
|
47
60
|
end)
|
|
@@ -56,13 +69,11 @@ local function Terminal()
|
|
|
56
69
|
end)
|
|
57
70
|
local terminalHeight = derive(function()
|
|
58
71
|
local padding = px.ceil(TEXT_FIELD_HEIGHT + 16)
|
|
59
|
-
if #history()
|
|
72
|
+
if #history() == 0 then
|
|
60
73
|
return padding
|
|
61
74
|
end
|
|
62
|
-
local
|
|
63
|
-
|
|
64
|
-
local clampedHeight = if isClamped then px(MAX_HEIGHT) else totalHeight
|
|
65
|
-
return math.ceil(padding + clampedHeight)
|
|
75
|
+
local clampedHeight = if scrollingEnabled() then maxHeight() else historyHeight()
|
|
76
|
+
return math.ceil(padding + clampedHeight + px(8))
|
|
66
77
|
end)
|
|
67
78
|
return Vide.jsx(Frame, {
|
|
68
79
|
size = spring(function()
|
|
@@ -97,9 +108,10 @@ local function Terminal()
|
|
|
97
108
|
size = function()
|
|
98
109
|
return UDim2.new(1, 0, 1, -px(TEXT_FIELD_HEIGHT + 8))
|
|
99
110
|
end,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
entries = history,
|
|
112
|
+
scrollingEnabled = scrollingEnabled,
|
|
113
|
+
onContentSizeChanged = function(size)
|
|
114
|
+
historyHeight(size.Y)
|
|
103
115
|
end,
|
|
104
116
|
}), Vide.jsx(TerminalTextField, {
|
|
105
117
|
anchor = Vector2.new(0, 1),
|
|
@@ -28,6 +28,7 @@ local function ScrollingFrame(props)
|
|
|
28
28
|
_attributes.ZIndex = props.zIndex
|
|
29
29
|
_attributes.LayoutOrder = props.layoutOrder
|
|
30
30
|
_attributes.BorderSizePixel = 0
|
|
31
|
+
_attributes.action = props.action
|
|
31
32
|
local _attribute = props.native
|
|
32
33
|
if _attribute then
|
|
33
34
|
for _k, _v in _attribute do
|
|
@@ -25,7 +25,7 @@ local function TextField(props)
|
|
|
25
25
|
TextYAlignment = props.textYAlignment,
|
|
26
26
|
TextScaled = props.textScaled,
|
|
27
27
|
RichText = props.richText,
|
|
28
|
-
AutomaticSize = props.
|
|
28
|
+
AutomaticSize = props.automaticSize,
|
|
29
29
|
AutoLocalize = function()
|
|
30
30
|
return options().autoLocalize
|
|
31
31
|
end,
|
|
@@ -12,7 +12,6 @@ export interface TextProps<T extends Instance = TextLabel> extends FrameProps<T>
|
|
|
12
12
|
textTruncate?: InferEnumNames<Enum.TextTruncate>;
|
|
13
13
|
textScaled?: Derivable<boolean>;
|
|
14
14
|
textHeight?: Derivable<number>;
|
|
15
|
-
textAutoResize?: "X" | "Y" | "XY";
|
|
16
15
|
richText?: Derivable<boolean>;
|
|
17
16
|
}
|
|
18
17
|
export declare function Text(props: TextProps): Vide.Node;
|
|
@@ -28,7 +28,7 @@ local function Text(props)
|
|
|
28
28
|
LineHeight = props.textHeight,
|
|
29
29
|
RichText = props.richText,
|
|
30
30
|
Size = props.size,
|
|
31
|
-
AutomaticSize = props.
|
|
31
|
+
AutomaticSize = props.automaticSize,
|
|
32
32
|
AutoLocalize = function()
|
|
33
33
|
return options().autoLocalize
|
|
34
34
|
end,
|
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.
|
|
4
|
+
"version": "1.0.7",
|
|
5
5
|
"author": "paradoxuum",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "out/init.lua",
|
|
@@ -26,25 +26,24 @@
|
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
|
-
"scripts": {
|
|
30
|
-
"prepack": "yarn build",
|
|
31
|
-
"build": "shx rm -rf out && rbxtsc --verbose",
|
|
32
|
-
"dev": "shx rm -rf out && rbxtsc -w"
|
|
33
|
-
},
|
|
34
29
|
"devDependencies": {
|
|
35
|
-
"@rbxts/centurion": "^1.0.1",
|
|
36
30
|
"@rbxts/compiler-types": "3.0.0-types.0",
|
|
37
31
|
"@rbxts/types": "^1.0.813",
|
|
38
32
|
"roblox-ts": "3.0.0",
|
|
39
33
|
"shx": "^0.3.4",
|
|
40
|
-
"typescript": "5.5.3"
|
|
34
|
+
"typescript": "5.5.3",
|
|
35
|
+
"@rbxts/centurion": "^1.0.1"
|
|
41
36
|
},
|
|
42
37
|
"dependencies": {
|
|
43
38
|
"@rbxts/services": "^1.5.5",
|
|
44
39
|
"@rbxts/set-timeout": "^1.1.2",
|
|
45
|
-
"@rbxts/vide": "^0.5.
|
|
40
|
+
"@rbxts/vide": "^0.5.3"
|
|
46
41
|
},
|
|
47
42
|
"peerDependencies": {
|
|
48
43
|
"@rbxts/centurion": "^1.0.1"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "shx rm -rf out && rbxtsc --verbose",
|
|
47
|
+
"dev": "shx rm -rf out && rbxtsc -w"
|
|
49
48
|
}
|
|
50
49
|
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
-- Compiled with roblox-ts v3.0.0
|
|
2
|
-
local TS = _G[script]
|
|
3
|
-
local TextService = TS.import(script, TS.getModule(script, "@rbxts", "services")).TextService
|
|
4
|
-
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
5
|
-
local cleanup = _vide.cleanup
|
|
6
|
-
local derive = _vide.derive
|
|
7
|
-
local source = _vide.source
|
|
8
|
-
local HISTORY_TEXT_SIZE = TS.import(script, script.Parent.Parent, "constants", "text").HISTORY_TEXT_SIZE
|
|
9
|
-
local options = TS.import(script, script.Parent.Parent, "store").options
|
|
10
|
-
local useClient = TS.import(script, script.Parent, "use-client").useClient
|
|
11
|
-
local useEvent = TS.import(script, script.Parent, "use-event").useEvent
|
|
12
|
-
local px = TS.import(script, script.Parent, "use-px").px
|
|
13
|
-
local function useHistory()
|
|
14
|
-
local client = useClient()
|
|
15
|
-
local history = source(client.dispatcher:getHistory())
|
|
16
|
-
useEvent(client.dispatcher.historyUpdated, function(entries)
|
|
17
|
-
local _array = {}
|
|
18
|
-
local _length = #_array
|
|
19
|
-
table.move(entries, 1, #entries, _length + 1, _array)
|
|
20
|
-
return history(_array)
|
|
21
|
-
end)
|
|
22
|
-
local textBoundsParams = Instance.new("GetTextBoundsParams")
|
|
23
|
-
textBoundsParams.Width = math.huge
|
|
24
|
-
textBoundsParams.RichText = true
|
|
25
|
-
cleanup(function()
|
|
26
|
-
textBoundsParams:Destroy()
|
|
27
|
-
end)
|
|
28
|
-
return derive(function()
|
|
29
|
-
local entries = history()
|
|
30
|
-
local historySize = #entries
|
|
31
|
-
local totalHeight = if historySize > 0 then px(8) + (historySize - 1) * px(8) else 0
|
|
32
|
-
textBoundsParams.Size = HISTORY_TEXT_SIZE
|
|
33
|
-
textBoundsParams.Font = options().font.regular
|
|
34
|
-
local historyLines = {}
|
|
35
|
-
for _, entry in entries do
|
|
36
|
-
textBoundsParams.Text = entry.text
|
|
37
|
-
local textSize = TextService:GetTextBoundsAsync(textBoundsParams)
|
|
38
|
-
local lineHeight = px(textSize.Y + 4)
|
|
39
|
-
totalHeight += lineHeight
|
|
40
|
-
local _arg0 = {
|
|
41
|
-
entry = entry,
|
|
42
|
-
height = lineHeight,
|
|
43
|
-
}
|
|
44
|
-
table.insert(historyLines, _arg0)
|
|
45
|
-
end
|
|
46
|
-
return {
|
|
47
|
-
lines = historyLines,
|
|
48
|
-
height = totalHeight,
|
|
49
|
-
}
|
|
50
|
-
end)
|
|
51
|
-
end
|
|
52
|
-
return {
|
|
53
|
-
useHistory = useHistory,
|
|
54
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Derivable } from "@rbxts/vide";
|
|
2
|
-
interface TextBoundsProps {
|
|
3
|
-
text: Derivable<string | undefined>;
|
|
4
|
-
font?: Derivable<Font>;
|
|
5
|
-
size?: Derivable<number>;
|
|
6
|
-
width?: Derivable<number>;
|
|
7
|
-
}
|
|
8
|
-
export declare function useTextBounds({ text, font, size, width }: TextBoundsProps): () => Vector2;
|
|
9
|
-
export {};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
-- Compiled with roblox-ts v3.0.0
|
|
2
|
-
local TS = _G[script]
|
|
3
|
-
local TextService = TS.import(script, TS.getModule(script, "@rbxts", "services")).TextService
|
|
4
|
-
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
5
|
-
local cleanup = _vide.cleanup
|
|
6
|
-
local effect = _vide.effect
|
|
7
|
-
local read = _vide.read
|
|
8
|
-
local source = _vide.source
|
|
9
|
-
local getBounds = TS.Promise.promisify(function(params)
|
|
10
|
-
return TextService:GetTextBoundsAsync(params)
|
|
11
|
-
end)
|
|
12
|
-
local function useTextBounds(_param)
|
|
13
|
-
local text = _param.text
|
|
14
|
-
local font = _param.font
|
|
15
|
-
local size = _param.size
|
|
16
|
-
local width = _param.width
|
|
17
|
-
local bounds = source(Vector2.zero)
|
|
18
|
-
local params = Instance.new("GetTextBoundsParams")
|
|
19
|
-
params.RichText = true
|
|
20
|
-
cleanup(params)
|
|
21
|
-
effect(function()
|
|
22
|
-
local textValue = read(text)
|
|
23
|
-
if textValue == nil then
|
|
24
|
-
bounds(Vector2.zero)
|
|
25
|
-
return nil
|
|
26
|
-
end
|
|
27
|
-
params.Text = textValue
|
|
28
|
-
local fontValue = read(font)
|
|
29
|
-
local sizeValue = read(size)
|
|
30
|
-
local widthValue = read(width)
|
|
31
|
-
if fontValue ~= nil then
|
|
32
|
-
params.Font = fontValue
|
|
33
|
-
end
|
|
34
|
-
if sizeValue ~= nil then
|
|
35
|
-
params.Size = sizeValue
|
|
36
|
-
end
|
|
37
|
-
if widthValue ~= nil then
|
|
38
|
-
params.Width = widthValue
|
|
39
|
-
end
|
|
40
|
-
getBounds(params):andThen(function(value)
|
|
41
|
-
return bounds(value)
|
|
42
|
-
end):catch(function()
|
|
43
|
-
return bounds(Vector2.zero)
|
|
44
|
-
end)
|
|
45
|
-
end)
|
|
46
|
-
return bounds
|
|
47
|
-
end
|
|
48
|
-
return {
|
|
49
|
-
useTextBounds = useTextBounds,
|
|
50
|
-
}
|