@rbxts/uiblox 0.2.0-alpha.0 → 0.2.0-alpha.1

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.
Files changed (55) hide show
  1. package/README.md +40 -26
  2. package/out/theme/constants/NumberConstants.d.ts +1 -1
  3. package/out/theme/constants/NumberConstants.luau +3 -4
  4. package/out/theme/interfaces/typography/FontSizes.d.ts +1 -1
  5. package/out/theme/interfaces/typography/FontSizes.luau +7 -7
  6. package/out/theme/styles/utilities/index.d.ts +1 -1
  7. package/out/theme/styles/utilities/init.luau +3 -1
  8. package/out/theme/styles/utilities/resolveStyle.d.ts +32 -0
  9. package/out/theme/styles/utilities/resolveStyle.luau +66 -0
  10. package/out/ui/packages/appBar/components/AppBar.d.ts +10 -0
  11. package/out/ui/packages/appBar/components/AppBar.luau +77 -0
  12. package/out/ui/packages/appBar/components/AppBar.styles.d.ts +6 -0
  13. package/out/ui/packages/appBar/components/AppBar.styles.luau +66 -0
  14. package/out/ui/packages/appBar/index.d.ts +3 -0
  15. package/out/ui/packages/appBar/init.luau +5 -0
  16. package/out/ui/packages/autocomplete/components/Autocomplete.luau +2 -0
  17. package/out/ui/packages/bottomNavigation/components/BottomNavigation.d.ts +10 -0
  18. package/out/ui/packages/bottomNavigation/components/BottomNavigation.luau +86 -0
  19. package/out/ui/packages/bottomNavigation/components/BottomNavigation.styles.d.ts +2 -0
  20. package/out/ui/packages/bottomNavigation/components/BottomNavigation.styles.luau +58 -0
  21. package/out/ui/packages/bottomNavigation/index.d.ts +2 -0
  22. package/out/ui/packages/bottomNavigation/init.luau +5 -0
  23. package/out/ui/packages/button/components/Button.styles.luau +0 -6
  24. package/out/ui/packages/button/components/buttonLook.d.ts +2 -2
  25. package/out/ui/packages/checkbox/components/checkboxLook.d.ts +1 -1
  26. package/out/ui/packages/fab/components/Fab.d.ts +13 -0
  27. package/out/ui/packages/fab/components/Fab.luau +128 -0
  28. package/out/ui/packages/fab/components/Fab.styles.d.ts +7 -0
  29. package/out/ui/packages/fab/components/Fab.styles.luau +40 -0
  30. package/out/ui/packages/fab/components/fabSize.d.ts +3 -0
  31. package/out/ui/packages/fab/components/fabSize.luau +29 -0
  32. package/out/ui/packages/fab/index.d.ts +3 -0
  33. package/out/ui/packages/fab/init.luau +8 -0
  34. package/out/ui/packages/icon/components/Icon.styles.luau +4 -4
  35. package/out/ui/packages/iconButton/components/IconButton.styles.luau +4 -4
  36. package/out/ui/packages/index.d.ts +3 -0
  37. package/out/ui/packages/init.luau +9 -0
  38. package/out/ui/packages/input/components/Input.d.ts +2 -0
  39. package/out/ui/packages/input/components/Input.luau +63 -26
  40. package/out/ui/packages/input/components/Input.styles.luau +6 -2
  41. package/out/ui/packages/numberInput/components/NumberInput.d.ts +2 -0
  42. package/out/ui/packages/numberInput/components/NumberInput.luau +4 -0
  43. package/out/ui/packages/select/components/Select.d.ts +1 -0
  44. package/out/ui/packages/select/components/Select.luau +26 -3
  45. package/out/ui/packages/select/components/Select.styles.luau +2 -2
  46. package/out/ui/packages/sidebar/components/Sidebar.styles.luau +2 -2
  47. package/out/ui/packages/splitPane/components/splitLook.d.ts +1 -1
  48. package/out/ui/packages/stateMatrix.luau +528 -426
  49. package/out/ui/packages/switch/components/switchLook.d.ts +3 -3
  50. package/out/ui/packages/tabs/components/Tabs.styles.luau +1 -1
  51. package/out/ui/packages/treeView/components/TreeView.luau +3 -3
  52. package/out/ui/packages/treeView/components/TreeView.styles.luau +3 -3
  53. package/package.json +2 -2
  54. package/out/theme/styles/utilities/interaction.d.ts +0 -13
  55. package/out/theme/styles/utilities/interaction.luau +0 -68
@@ -0,0 +1,128 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local _react = TS.import(script, TS.getModule(script, "@rbxts", "react"))
4
+ local React = _react
5
+ local useEffect = _react.useEffect
6
+ local useState = _react.useState
7
+ local useTheme = TS.import(script, script.Parent.Parent.Parent.Parent.Parent, "theme").useTheme
8
+ local canActivate = TS.import(script, script.Parent.Parent.Parent, "button", "components", "activation").canActivate
9
+ local CircularProgress = TS.import(script, script.Parent.Parent.Parent, "circularProgress").CircularProgress
10
+ local Shadow = TS.import(script, script.Parent.Parent.Parent, "shadow").Shadow
11
+ local fabIconPixels = TS.import(script, script.Parent, "fabSize").fabIconPixels
12
+ local useFabStyles = TS.import(script, script.Parent, "Fab.styles").default
13
+ local function Fab(props)
14
+ local _binding = props
15
+ local icon = _binding.icon
16
+ local size = _binding.size
17
+ if size == nil then
18
+ size = "medium"
19
+ end
20
+ local disabled = _binding.disabled
21
+ local loading = _binding.loading
22
+ if loading == nil then
23
+ loading = false
24
+ end
25
+ local reducedMotion = _binding.reducedMotion
26
+ local onClick = _binding.onClick
27
+ local className = _binding.className
28
+ local sx = _binding.sx
29
+ local id = _binding.id
30
+ local ref = _binding.ref
31
+ local active = canActivate(disabled, loading)
32
+ local styles = useFabStyles({
33
+ size = size,
34
+ disabled = not active,
35
+ })
36
+ local _binding_1 = useTheme()
37
+ local theme = _binding_1.theme
38
+ local hovering, setHovering = useState(false)
39
+ local focused, setFocused = useState(false)
40
+ local iconPx = fabIconPixels(size)
41
+ useEffect(function()
42
+ if active then
43
+ return nil
44
+ end
45
+ setHovering(false)
46
+ setFocused(false)
47
+ end, { active })
48
+ local _attributes = {}
49
+ local _condition = id
50
+ if not (_condition ~= 0 and _condition == _condition and _condition ~= "" and _condition) then
51
+ _condition = "Fab"
52
+ end
53
+ _attributes.key = _condition
54
+ _attributes.ref = ref
55
+ for _k, _v in styles.root do
56
+ _attributes[_k] = _v
57
+ end
58
+ if className then
59
+ for _k, _v in className do
60
+ _attributes[_k] = _v
61
+ end
62
+ end
63
+ if sx then
64
+ for _k, _v in sx do
65
+ _attributes[_k] = _v
66
+ end
67
+ end
68
+ _attributes.Active = active
69
+ _attributes.Selectable = active
70
+ _attributes.BackgroundTransparency = if not active then 0.5 elseif hovering or focused then 0.15 else 0
71
+ _attributes.Event = {
72
+ Activated = function()
73
+ if active and onClick then
74
+ onClick()
75
+ end
76
+ end,
77
+ MouseEnter = function()
78
+ if active then
79
+ setHovering(true)
80
+ end
81
+ end,
82
+ MouseLeave = function()
83
+ return setHovering(false)
84
+ end,
85
+ SelectionGained = function()
86
+ if active then
87
+ setFocused(true)
88
+ end
89
+ end,
90
+ SelectionLost = function()
91
+ return setFocused(false)
92
+ end,
93
+ }
94
+ local _attributes_1 = table.clone(styles.corner)
95
+ setmetatable(_attributes_1, nil)
96
+ local _exp = React.createElement("uicorner", _attributes_1)
97
+ local _exp_1 = React.createElement(Shadow)
98
+ local _result
99
+ if loading then
100
+ _result = (React.createElement(CircularProgress, {
101
+ size = iconPx,
102
+ thickness = 2,
103
+ color = theme.palette.primary.on,
104
+ reducedMotion = reducedMotion,
105
+ className = {
106
+ AnchorPoint = Vector2.new(0.5, 0.5),
107
+ Position = UDim2.fromScale(0.5, 0.5),
108
+ },
109
+ }))
110
+ else
111
+ local _attributes_2 = {
112
+ key = "Icon",
113
+ }
114
+ for _k, _v in styles.icon do
115
+ _attributes_2[_k] = _v
116
+ end
117
+ _attributes_2.Size = UDim2.fromOffset(iconPx, iconPx)
118
+ _attributes_2.AnchorPoint = Vector2.new(0.5, 0.5)
119
+ _attributes_2.Position = UDim2.fromScale(0.5, 0.5)
120
+ _attributes_2.Image = tostring(icon)
121
+ _result = (React.createElement("imagelabel", _attributes_2))
122
+ end
123
+ return React.createElement("textbutton", _attributes, _exp, _exp_1, _result)
124
+ end
125
+ local default = Fab
126
+ return {
127
+ default = default,
128
+ }
@@ -0,0 +1,7 @@
1
+ import { FabSize } from "./fabSize";
2
+ export interface FabStyleProps {
3
+ size?: FabSize;
4
+ disabled?: boolean;
5
+ }
6
+ declare const useFabStyles: (props: FabStyleProps) => import("../../../../theme/index").ClassNameMap<string>;
7
+ export default useFabStyles;
@@ -0,0 +1,40 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local _theme = TS.import(script, script.Parent.Parent.Parent.Parent.Parent, "theme")
4
+ local componentStyles = _theme.componentStyles
5
+ local createStyles = _theme.createStyles
6
+ local fabPixels = TS.import(script, script.Parent, "fabSize").fabPixels
7
+ local useFabStyles = componentStyles("Fab", function(theme, _param)
8
+ local size = _param.size
9
+ if size == nil then
10
+ size = "medium"
11
+ end
12
+ local disabled = _param.disabled
13
+ local diameter = fabPixels(size)
14
+ return createStyles({
15
+ root = {
16
+ Size = UDim2.fromOffset(diameter, diameter),
17
+ BackgroundColor3 = theme.palette.primary.main,
18
+ BackgroundTransparency = if disabled then 0.5 else 0,
19
+ BorderSizePixel = 0,
20
+ AutoButtonColor = false,
21
+ Text = "",
22
+ ZIndex = 12000,
23
+ },
24
+ corner = {
25
+ CornerRadius = UDim.new(1, 0),
26
+ },
27
+ icon = {
28
+ Size = UDim2.fromScale(1, 1),
29
+ BackgroundTransparency = 1,
30
+ BorderSizePixel = 0,
31
+ ScaleType = Enum.ScaleType.Fit,
32
+ ImageColor3 = theme.palette.primary.on,
33
+ ImageTransparency = if disabled then 0.5 else 0,
34
+ },
35
+ })
36
+ end)
37
+ local default = useFabStyles
38
+ return {
39
+ default = default,
40
+ }
@@ -0,0 +1,3 @@
1
+ export type FabSize = "small" | "medium" | "large";
2
+ export declare function fabPixels(size?: FabSize): 40 | 64 | 56;
3
+ export declare function fabIconPixels(size?: FabSize): 18 | 24 | 28;
@@ -0,0 +1,29 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local function fabPixels(size)
3
+ if size == nil then
4
+ size = "medium"
5
+ end
6
+ if size == "small" then
7
+ return 40
8
+ end
9
+ if size == "large" then
10
+ return 64
11
+ end
12
+ return 56
13
+ end
14
+ local function fabIconPixels(size)
15
+ if size == nil then
16
+ size = "medium"
17
+ end
18
+ if size == "small" then
19
+ return 18
20
+ end
21
+ if size == "large" then
22
+ return 28
23
+ end
24
+ return 24
25
+ end
26
+ return {
27
+ fabPixels = fabPixels,
28
+ fabIconPixels = fabIconPixels,
29
+ }
@@ -0,0 +1,3 @@
1
+ export { default as Fab } from "./components/Fab";
2
+ export { FabProps } from "./components/Fab";
3
+ export { FabSize, fabPixels, fabIconPixels } from "./components/fabSize";
@@ -0,0 +1,8 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local exports = {}
4
+ exports.Fab = TS.import(script, script, "components", "Fab").default
5
+ local _fabSize = TS.import(script, script, "components", "fabSize")
6
+ exports.fabPixels = _fabSize.fabPixels
7
+ exports.fabIconPixels = _fabSize.fabIconPixels
8
+ return exports
@@ -9,10 +9,10 @@ local useIconStyles = componentStyles("Icon", function(theme, props)
9
9
  local size = _binding.size
10
10
  repeat
11
11
  if size == "xxs" then
12
- return UDim2.new(0, theme.spacing.calc(0.5), 0, theme.spacing.calc(0.5))
12
+ return UDim2.new(0, theme.spacing.calc(1), 0, theme.spacing.calc(1))
13
13
  end
14
14
  if size == "xs" then
15
- return UDim2.new(0, theme.spacing.calc(1), 0, theme.spacing.calc(1))
15
+ return UDim2.new(0, theme.spacing.calc(1.5), 0, theme.spacing.calc(1.5))
16
16
  end
17
17
  if size == "sm" then
18
18
  return UDim2.new(0, theme.spacing.calc(2), 0, theme.spacing.calc(2))
@@ -21,10 +21,10 @@ local useIconStyles = componentStyles("Icon", function(theme, props)
21
21
  return UDim2.new(0, theme.spacing.calc(3), 0, theme.spacing.calc(3))
22
22
  end
23
23
  if size == "lg" then
24
- return UDim2.new(0, theme.spacing.calc(6), 0, theme.spacing.calc(6))
24
+ return UDim2.new(0, theme.spacing.calc(4), 0, theme.spacing.calc(4))
25
25
  end
26
26
  if size == "xl" then
27
- return UDim2.new(0, theme.spacing.calc(8), 0, theme.spacing.calc(8))
27
+ return UDim2.new(0, theme.spacing.calc(5), 0, theme.spacing.calc(5))
28
28
  end
29
29
  return UDim2.new(0, theme.spacing.calc(2), 0, theme.spacing.calc(2))
30
30
  until true
@@ -9,10 +9,10 @@ local useIconButtonStyles = componentStyles("IconButton", function(theme, props)
9
9
  local size = _binding.size
10
10
  repeat
11
11
  if size == "xxs" then
12
- return UDim2.new(0, theme.spacing.calc(0.5), 0, theme.spacing.calc(0.5))
12
+ return UDim2.new(0, theme.spacing.calc(1), 0, theme.spacing.calc(1))
13
13
  end
14
14
  if size == "xs" then
15
- return UDim2.new(0, theme.spacing.calc(1), 0, theme.spacing.calc(1))
15
+ return UDim2.new(0, theme.spacing.calc(1.5), 0, theme.spacing.calc(1.5))
16
16
  end
17
17
  if size == "sm" then
18
18
  return UDim2.new(0, theme.spacing.calc(2), 0, theme.spacing.calc(2))
@@ -21,10 +21,10 @@ local useIconButtonStyles = componentStyles("IconButton", function(theme, props)
21
21
  return UDim2.new(0, theme.spacing.calc(3), 0, theme.spacing.calc(3))
22
22
  end
23
23
  if size == "lg" then
24
- return UDim2.new(0, theme.spacing.calc(6), 0, theme.spacing.calc(6))
24
+ return UDim2.new(0, theme.spacing.calc(4), 0, theme.spacing.calc(4))
25
25
  end
26
26
  if size == "xl" then
27
- return UDim2.new(0, theme.spacing.calc(8), 0, theme.spacing.calc(8))
27
+ return UDim2.new(0, theme.spacing.calc(5), 0, theme.spacing.calc(5))
28
28
  end
29
29
  return UDim2.new(0, theme.spacing.calc(2), 0, theme.spacing.calc(2))
30
30
  until true
@@ -47,6 +47,9 @@ export * from "./accordion/index";
47
47
  export * from "./snackbar/index";
48
48
  export * from "./table/index";
49
49
  export * from "./autocomplete/index";
50
+ export * from "./fab/index";
51
+ export * from "./appBar/index";
52
+ export * from "./bottomNavigation/index";
50
53
  export * from "./listItem/index";
51
54
  export * from "./menu/index";
52
55
  export * from "./motion/index";
@@ -148,6 +148,15 @@ end
148
148
  for _k, _v in TS.import(script, script, "autocomplete") or {} do
149
149
  exports[_k] = _v
150
150
  end
151
+ for _k, _v in TS.import(script, script, "fab") or {} do
152
+ exports[_k] = _v
153
+ end
154
+ for _k, _v in TS.import(script, script, "appBar") or {} do
155
+ exports[_k] = _v
156
+ end
157
+ for _k, _v in TS.import(script, script, "bottomNavigation") or {} do
158
+ exports[_k] = _v
159
+ end
151
160
  for _k, _v in TS.import(script, script, "listItem") or {} do
152
161
  exports[_k] = _v
153
162
  end
@@ -5,6 +5,7 @@ export type DefaultInputComponent = Frame;
5
5
  export interface InputProps {
6
6
  color?: InputColor;
7
7
  disabled?: boolean;
8
+ loading?: boolean;
8
9
  hasError?: boolean;
9
10
  helperText?: string;
10
11
  margin?: InputMargin;
@@ -15,6 +16,7 @@ export interface InputProps {
15
16
  rounded?: boolean;
16
17
  clearsTextOnFocus?: boolean;
17
18
  size?: ControlSize;
19
+ reducedMotion?: boolean;
18
20
  startAdornment?: React.Element;
19
21
  endAdornment?: React.Element;
20
22
  onTextChanged?: (text: string) => void;
@@ -5,7 +5,12 @@ local React = _react
5
5
  local useEffect = _react.useEffect
6
6
  local useRef = _react.useRef
7
7
  local useState = _react.useState
8
- local cx = TS.import(script, script.Parent.Parent.Parent.Parent.Parent, "theme").cx
8
+ local _theme = TS.import(script, script.Parent.Parent.Parent.Parent.Parent, "theme")
9
+ local cx = _theme.cx
10
+ local useTheme = _theme.useTheme
11
+ local canActivate = TS.import(script, script.Parent.Parent.Parent, "button", "components", "activation").canActivate
12
+ local spinnerPixels = TS.import(script, script.Parent.Parent.Parent, "button", "components", "buttonLook").spinnerPixels
13
+ local CircularProgress = TS.import(script, script.Parent.Parent.Parent, "circularProgress").CircularProgress
9
14
  local Divider = TS.import(script, script.Parent.Parent.Parent, "divider").Divider
10
15
  local Orientations = TS.import(script, script.Parent.Parent.Parent.Parent, "enums").Orientations
11
16
  local useInputStyles = TS.import(script, script.Parent, "Input.styles").default
@@ -31,6 +36,10 @@ local function Input(props)
31
36
  if disabled == nil then
32
37
  disabled = false
33
38
  end
39
+ local loading = _binding.loading
40
+ if loading == nil then
41
+ loading = false
42
+ end
34
43
  local hasError = _binding.hasError
35
44
  if hasError == nil then
36
45
  hasError = false
@@ -39,6 +48,8 @@ local function Input(props)
39
48
  if rounded == nil then
40
49
  rounded = false
41
50
  end
51
+ local size = _binding.size
52
+ local reducedMotion = _binding.reducedMotion
42
53
  local startAdornment = _binding.startAdornment
43
54
  local endAdornment = _binding.endAdornment
44
55
  local onTextChanged = _binding.onTextChanged
@@ -58,23 +69,27 @@ local function Input(props)
58
69
  end
59
70
  local draft, setDraft = useState(_condition)
60
71
  local focused, setFocused = useState(false)
72
+ local _binding_1 = useTheme()
73
+ local theme = _binding_1.theme
74
+ local editable = canActivate(disabled, loading)
75
+ local endSlotContent = if loading then nil else endAdornment
61
76
  local _object = table.clone(props)
62
77
  setmetatable(_object, nil)
63
78
  _object.focused = focused
64
- local _binding_1 = useInputStyles(_object)
65
- local root = _binding_1.root
66
- local font = _binding_1.font
67
- local margin = _binding_1.margin
68
- local shell = _binding_1.shell
69
- local box = _binding_1.box
70
- local startSlot = _binding_1.startSlot
71
- local endSlot = _binding_1.endSlot
72
- local helper = _binding_1.helper
73
- local errorColorFrame = _binding_1.errorColorFrame
74
- local errorColorText = _binding_1.errorColorText
75
- local divider = _binding_1.divider
76
- local corner = _binding_1.corner
77
- local stroke = _binding_1.stroke
79
+ local _binding_2 = useInputStyles(_object)
80
+ local root = _binding_2.root
81
+ local font = _binding_2.font
82
+ local margin = _binding_2.margin
83
+ local shell = _binding_2.shell
84
+ local box = _binding_2.box
85
+ local startSlot = _binding_2.startSlot
86
+ local endSlot = _binding_2.endSlot
87
+ local helper = _binding_2.helper
88
+ local errorColorFrame = _binding_2.errorColorFrame
89
+ local errorColorText = _binding_2.errorColorText
90
+ local divider = _binding_2.divider
91
+ local corner = _binding_2.corner
92
+ local stroke = _binding_2.stroke
78
93
  useEffect(function()
79
94
  setDraft(function(current)
80
95
  return syncInputDraft(focusedRef.current, text, current)
@@ -145,7 +160,8 @@ local function Input(props)
145
160
  for _k, _v in box do
146
161
  _attributes_3[_k] = _v
147
162
  end
148
- _attributes_3.Active = not disabled
163
+ _attributes_3.Active = editable
164
+ _attributes_3.TextEditable = editable
149
165
  _attributes_3.Text = draft
150
166
  _attributes_3.PlaceholderText = placeholder
151
167
  for _k, _v in cx(hasError and errorColorText) do
@@ -153,6 +169,9 @@ local function Input(props)
153
169
  end
154
170
  _attributes_3.Change = {
155
171
  Text = function(rbx)
172
+ if not editable then
173
+ return nil
174
+ end
156
175
  setDraft(rbx.Text)
157
176
  if focusedRef.current and onInput then
158
177
  onInput(rbx.Text)
@@ -161,6 +180,9 @@ local function Input(props)
161
180
  }
162
181
  _attributes_3.Event = {
163
182
  Focused = function()
183
+ if not editable then
184
+ return nil
185
+ end
164
186
  focusedRef.current = true
165
187
  entered.current = false
166
188
  setFocused(true)
@@ -169,7 +191,7 @@ local function Input(props)
169
191
  end
170
192
  end,
171
193
  ReturnPressedFromOnScreenKeyboard = function(rbx)
172
- if entered.current or not onEnterPressed then
194
+ if not editable or entered.current or not onEnterPressed then
173
195
  return nil
174
196
  end
175
197
  entered.current = true
@@ -179,10 +201,10 @@ local function Input(props)
179
201
  focusedRef.current = false
180
202
  setFocused(false)
181
203
  local committed = rbx.Text
182
- if onTextChanged then
204
+ if editable and onTextChanged then
183
205
  onTextChanged(committed)
184
206
  end
185
- if enterPressed and not entered.current and onEnterPressed then
207
+ if editable and enterPressed and not entered.current and onEnterPressed then
186
208
  onEnterPressed(committed)
187
209
  end
188
210
  entered.current = false
@@ -197,7 +219,7 @@ local function Input(props)
197
219
  end,
198
220
  }
199
221
  local _exp = React.createElement("textbox", _attributes_3)
200
- local _condition_5 = endAdornment ~= nil
222
+ local _condition_5 = loading
201
223
  if _condition_5 then
202
224
  local _attributes_4 = {
203
225
  key = "End",
@@ -205,16 +227,31 @@ local function Input(props)
205
227
  for _k, _v in endSlot do
206
228
  _attributes_4[_k] = _v
207
229
  end
208
- _condition_5 = (React.createElement("frame", _attributes_4, adornmentAlign(), endAdornment))
230
+ _condition_5 = (React.createElement("frame", _attributes_4, adornmentAlign(), React.createElement(CircularProgress, {
231
+ size = spinnerPixels(size),
232
+ thickness = 2,
233
+ color = theme.palette.text.secondary,
234
+ reducedMotion = reducedMotion,
235
+ })))
236
+ end
237
+ local _condition_6 = endSlotContent ~= nil
238
+ if _condition_6 then
239
+ local _attributes_4 = {
240
+ key = "End",
241
+ }
242
+ for _k, _v in endSlot do
243
+ _attributes_4[_k] = _v
244
+ end
245
+ _condition_6 = (React.createElement("frame", _attributes_4, adornmentAlign(), endSlotContent))
209
246
  end
210
- local _exp_1 = React.createElement("frame", _attributes_2, _condition_2, _condition_3, _condition_4, _exp, _condition_5)
247
+ local _exp_1 = React.createElement("frame", _attributes_2, _condition_2, _condition_3, _condition_4, _exp, _condition_5, _condition_6)
211
248
  local _exp_2 = variant == "standard" and (React.createElement(Divider, {
212
249
  padding = 0,
213
250
  orientation = Orientations.Horizontal,
214
251
  className = cx(divider, hasError and errorColorFrame),
215
252
  }))
216
- local _condition_6 = helperText ~= nil
217
- if _condition_6 then
253
+ local _condition_7 = helperText ~= nil
254
+ if _condition_7 then
218
255
  local _attributes_4 = {
219
256
  key = "HelperText",
220
257
  }
@@ -228,9 +265,9 @@ local function Input(props)
228
265
  _attributes_4[_k] = _v
229
266
  end
230
267
  _attributes_4.Text = helperText
231
- _condition_6 = (React.createElement("textlabel", _attributes_4))
268
+ _condition_7 = (React.createElement("textlabel", _attributes_4))
232
269
  end
233
- return React.createElement("frame", _attributes, React.createElement("frame", _attributes_1, _exp_1, _exp_2, _condition_6))
270
+ return React.createElement("frame", _attributes, React.createElement("frame", _attributes_1, _exp_1, _exp_2, _condition_7))
234
271
  end
235
272
  local default = Input
236
273
  return {
@@ -20,7 +20,7 @@ local useInputStyles = componentStyles("Input", function(theme, _param)
20
20
  end
21
21
  local width = _param.width
22
22
  if width == nil then
23
- width = UDim.new(0, theme.spacing.calc(8))
23
+ width = UDim.new(0, theme.spacing.calc(12))
24
24
  end
25
25
  local helperText = _param.helperText
26
26
  local clearsTextOnFocus = _param.clearsTextOnFocus
@@ -29,6 +29,10 @@ local useInputStyles = componentStyles("Input", function(theme, _param)
29
29
  end
30
30
  local startAdornment = _param.startAdornment
31
31
  local endAdornment = _param.endAdornment
32
+ local loading = _param.loading
33
+ if loading == nil then
34
+ loading = false
35
+ end
32
36
  local focused = _param.focused
33
37
  if focused == nil then
34
38
  focused = false
@@ -40,7 +44,7 @@ local useInputStyles = componentStyles("Input", function(theme, _param)
40
44
  local size = _param.size
41
45
  local metrics = controlMetrics(theme.density, size)
42
46
  local hasStart = startAdornment ~= nil
43
- local hasEnd = endAdornment ~= nil
47
+ local hasEnd = endAdornment ~= nil or loading
44
48
  local icon = metrics.icon
45
49
  local gap = theme.padding.calc(1)
46
50
  local insets = inputInsets(hasStart, hasEnd, icon, gap)
@@ -6,9 +6,11 @@ export interface NumberInputProps {
6
6
  max?: number;
7
7
  step?: number;
8
8
  disabled?: boolean;
9
+ loading?: boolean;
9
10
  placeholder?: string;
10
11
  width?: UDim;
11
12
  size?: ControlSize;
13
+ reducedMotion?: boolean;
12
14
  }
13
15
  declare function NumberInput(props: CustomizedProps<Frame, NumberInputProps>): JSX.Element;
14
16
  export default NumberInput;
@@ -11,9 +11,11 @@ local function NumberInput(props)
11
11
  local max = _binding.max
12
12
  local step = _binding.step
13
13
  local disabled = _binding.disabled
14
+ local loading = _binding.loading
14
15
  local placeholder = _binding.placeholder
15
16
  local width = _binding.width
16
17
  local size = _binding.size
18
+ local reducedMotion = _binding.reducedMotion
17
19
  local className = _binding.className
18
20
  local id = _binding.id
19
21
  local ref = _binding.ref
@@ -29,7 +31,9 @@ local function NumberInput(props)
29
31
  _attributes.placeholder = placeholder
30
32
  _attributes.width = width
31
33
  _attributes.disabled = disabled
34
+ _attributes.loading = loading
32
35
  _attributes.size = size
36
+ _attributes.reducedMotion = reducedMotion
33
37
  _attributes.onTextChanged = function(text)
34
38
  local committed = parseNumberDraft(text, min, max, step)
35
39
  if committed ~= nil and committed ~= value then
@@ -6,6 +6,7 @@ export interface SelectProps<T> {
6
6
  options: ChoiceOption<T>[];
7
7
  onChange: (value: T) => void;
8
8
  disabled?: boolean;
9
+ loading?: boolean;
9
10
  placeholder?: string;
10
11
  searchable?: boolean;
11
12
  reducedMotion?: boolean;
@@ -14,6 +14,8 @@ local controlMetrics = _theme.controlMetrics
14
14
  local cx = _theme.cx
15
15
  local useTheme = _theme.useTheme
16
16
  local canActivate = TS.import(script, script.Parent.Parent.Parent, "button", "components", "activation").canActivate
17
+ local spinnerPixels = TS.import(script, script.Parent.Parent.Parent, "button", "components", "buttonLook").spinnerPixels
18
+ local CircularProgress = TS.import(script, script.Parent.Parent.Parent, "circularProgress").CircularProgress
17
19
  local Input = TS.import(script, script.Parent.Parent.Parent, "input").Input
18
20
  local playProperty = TS.import(script, script.Parent.Parent.Parent, "motion").playProperty
19
21
  local Popup = TS.import(script, script.Parent.Parent.Parent, "popup").Popup
@@ -42,6 +44,10 @@ local function Select(props)
42
44
  local options = _binding.options
43
45
  local onChange = _binding.onChange
44
46
  local disabled = _binding.disabled
47
+ local loading = _binding.loading
48
+ if loading == nil then
49
+ loading = false
50
+ end
45
51
  local placeholder = _binding.placeholder
46
52
  if placeholder == nil then
47
53
  placeholder = ""
@@ -60,7 +66,7 @@ local function Select(props)
60
66
  local _binding_1 = useTheme()
61
67
  local theme = _binding_1.theme
62
68
  local row = controlMetrics(theme.density, size).height
63
- local active = canActivate(disabled)
69
+ local active = canActivate(disabled, loading)
64
70
  local anchor, setAnchor = useState()
65
71
  local open, setOpen = useState(false)
66
72
  local held, setHeld = useState(false)
@@ -218,6 +224,12 @@ local function Select(props)
218
224
  setHeld(true)
219
225
  end
220
226
  end, { shown })
227
+ useEffect(function()
228
+ if loading and open then
229
+ setOpen(false)
230
+ setQuery("")
231
+ end
232
+ end, { loading, open })
221
233
  useEffect(function()
222
234
  local menu = menuRef.current
223
235
  if not menu or not held then
@@ -305,7 +317,9 @@ local function Select(props)
305
317
  return onKey(input, true)
306
318
  end,
307
319
  }
308
- local _attributes_2 = table.clone(styles.padding)
320
+ local _attributes_2 = table.clone(cx(styles.padding, loading and {
321
+ PaddingRight = UDim.new(0, theme.padding.calc(1.5) + spinnerPixels(size) + theme.padding.calc(1)),
322
+ }))
309
323
  setmetatable(_attributes_2, nil)
310
324
  local _exp = React.createElement("uipadding", _attributes_2)
311
325
  local _attributes_3 = table.clone(styles.corner)
@@ -313,7 +327,16 @@ local function Select(props)
313
327
  local _exp_1 = React.createElement("uicorner", _attributes_3)
314
328
  local _attributes_4 = table.clone(cx(styles.stroke, focused and styles.focusStroke))
315
329
  setmetatable(_attributes_4, nil)
316
- local _exp_2 = React.createElement("textbutton", _attributes_1, _exp, _exp_1, React.createElement("uistroke", _attributes_4))
330
+ local _exp_2 = React.createElement("textbutton", _attributes_1, _exp, _exp_1, React.createElement("uistroke", _attributes_4), loading and (React.createElement(CircularProgress, {
331
+ size = spinnerPixels(size),
332
+ thickness = 2,
333
+ color = theme.palette.text.secondary,
334
+ reducedMotion = reducedMotion,
335
+ className = {
336
+ AnchorPoint = Vector2.new(1, 0.5),
337
+ Position = UDim2.new(1, -theme.padding.calc(1), 0.5, 0),
338
+ },
339
+ })))
317
340
  local _condition_1 = (shown or held)
318
341
  if _condition_1 then
319
342
  local _attributes_5 = {
@@ -9,7 +9,7 @@ local useSelectStyles = componentStyles("Select", function(theme, _param)
9
9
  local metrics = controlMetrics(theme.density, size)
10
10
  return createStyles({
11
11
  root = {
12
- Size = UDim2.fromOffset(theme.spacing.calc(8), metrics.height),
12
+ Size = UDim2.fromOffset(theme.spacing.calc(12), metrics.height),
13
13
  BackgroundTransparency = 1,
14
14
  BorderSizePixel = 0,
15
15
  },
@@ -38,7 +38,7 @@ local useSelectStyles = componentStyles("Select", function(theme, _param)
38
38
  ZIndex = 20001,
39
39
  },
40
40
  search = {
41
- Size = UDim2.new(1, 0, 0, theme.spacing.calc(2)),
41
+ Size = UDim2.new(1, 0, 0, metrics.height),
42
42
  BackgroundTransparency = 1,
43
43
  ZIndex = 20002,
44
44
  },