@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.
@@ -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
- return UDim2.fromOffset(0, px(SUGGESTION_TITLE_TEXT_SIZE) + padding)
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 = function()
147
- local bounds = titleBounds()
148
- return UDim2.fromOffset(bounds.X, bounds.Y)
149
- end,
150
- descriptionSize = function()
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="#{prevColorHex}">{subText}</font>{unhighlightedText}`
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
- text("")
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
- text(newText)
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(text() .. string.sub(suggestion.title, suggestionStartIndex))
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 = text()
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 = text()
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
- text(newText)
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
- text(newText)
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 = text()
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
- text(newText)
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
- text(currentText)
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-d64d6ec",
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-d64d6ec",
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 {};
@@ -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
- }