@rbxts/react-clean-ui 1.0.38 → 1.1.0
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/Decorator/Corners.luau +5 -1
- package/out/Components/Decorator/Padding.luau +1 -1
- package/out/Components/Input/Checkbox.luau +1 -1
- package/out/Components/Input/Input.luau +11 -21
- package/out/Components/Input/Input.validation.d.ts +1 -0
- package/out/Components/Input/Input.validation.luau +21 -0
- package/out/Components/Layout/Accordion.d.ts +3 -3
- package/out/Components/Layout/Accordion.luau +68 -17
- package/out/Components/Layout/Fieldset.luau +40 -6
- package/out/Components/Layout/Group.luau +30 -8
- package/out/Components/Layout/HStack.luau +1 -0
- package/out/Components/Layout/Row.luau +43 -9
- package/out/Components/Layout/Scroller.luau +19 -4
- package/out/Components/Layout/Tabs.d.ts +4 -2
- package/out/Components/Layout/Tabs.luau +11 -9
- package/out/Components/Navigation/Menu.luau +2 -0
- package/out/Components/Surface/Box.luau +21 -27
- package/out/Components/Surface/Card.d.ts +6 -2
- package/out/Components/Surface/Card.luau +93 -55
- package/out/Helpers/spacing.helper.d.ts +3 -2
- package/out/Helpers/spacing.helper.luau +102 -18
- package/out/Interfaces/css.types.d.ts +2 -0
- package/out/Interfaces/css.types.luau +4 -0
- package/out/Interfaces/index.d.ts +4 -4
- package/out/Interfaces/init.luau +0 -12
- package/out/Theme/theme.template.d.ts +14 -3
- package/out/Theme/themes/wooden.theme.luau +113 -2
- package/package.json +2 -2
|
@@ -6,8 +6,12 @@ local function Corners(props)
|
|
|
6
6
|
if props.radius == nil then
|
|
7
7
|
return nil
|
|
8
8
|
end
|
|
9
|
+
local radius = SizeHelper:toUDim(props.radius)
|
|
10
|
+
if radius.Scale == 0 and radius.Offset == 0 then
|
|
11
|
+
return nil
|
|
12
|
+
end
|
|
9
13
|
return React.createElement("uicorner", {
|
|
10
|
-
CornerRadius =
|
|
14
|
+
CornerRadius = radius,
|
|
11
15
|
})
|
|
12
16
|
end
|
|
13
17
|
return {
|
|
@@ -5,7 +5,7 @@ local CleanThemeContext = TS.import(script, script.Parent.Parent.Parent, "Contex
|
|
|
5
5
|
local SpacingHelper = TS.import(script, script.Parent.Parent.Parent, "Helpers").SpacingHelper
|
|
6
6
|
local function Padding(props)
|
|
7
7
|
local theme = React.useContext(CleanThemeContext)
|
|
8
|
-
local padding =
|
|
8
|
+
local padding = SpacingHelper:GetResolvedPadding(theme, props)
|
|
9
9
|
return React.createElement("uipadding", {
|
|
10
10
|
PaddingTop = UDim.new(0, padding.top),
|
|
11
11
|
PaddingBottom = UDim.new(0, padding.bottom),
|
|
@@ -83,7 +83,7 @@ local function Checkbox(props)
|
|
|
83
83
|
_attributes_1.Transparency = _condition_2
|
|
84
84
|
_attributes_1.Color = ColorHelper:getIntentColors(theme, if checked then props["intent-checked"] or "success" else props["intent-unchecked"] or "primary", "default", theme.components.checkbox.intents).borderColor
|
|
85
85
|
return React.createElement("imagebutton", _attributes, _exp, React.createElement("uistroke", _attributes_1), React.createElement(Padding, {
|
|
86
|
-
resolvedPadding = SpacingHelper:GetResolvedPadding(theme, props, theme.components.checkbox.spacing),
|
|
86
|
+
resolvedPadding = SpacingHelper:GetResolvedPadding(theme, props, theme.components.checkbox.spacing, theme.components.checkbox.padding),
|
|
87
87
|
}), React.createElement(Icon, {
|
|
88
88
|
scale = props.scale,
|
|
89
89
|
icon = if checked then props["icon-checked"] or "check" else props["icon-unchecked"],
|
|
@@ -12,7 +12,9 @@ local _Decorator = TS.import(script, script.Parent.Parent, "Decorator")
|
|
|
12
12
|
local Corners = _Decorator.Corners
|
|
13
13
|
local Padding = _Decorator.Padding
|
|
14
14
|
local FieldsetContext = TS.import(script, script.Parent.Parent, "Layout").FieldsetContext
|
|
15
|
-
local
|
|
15
|
+
local _Input_validation = TS.import(script, script.Parent, "Input.validation")
|
|
16
|
+
local resolveClampedText = _Input_validation.resolveClampedText
|
|
17
|
+
local resolveValidatedText = _Input_validation.resolveValidatedText
|
|
16
18
|
local function Input(props)
|
|
17
19
|
local theme = React.useContext(CleanThemeContext)
|
|
18
20
|
local fieldset = React.useContext(FieldsetContext)
|
|
@@ -117,26 +119,14 @@ local function Input(props)
|
|
|
117
119
|
end
|
|
118
120
|
end
|
|
119
121
|
_object.FocusLost = function(rbx, enterPressed, inputThatCausedFocusLoss)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
clamped = props.max
|
|
129
|
-
end
|
|
130
|
-
if clamped ~= number then
|
|
131
|
-
local clampedText = tostring(clamped)
|
|
132
|
-
ref.current.Text = clampedText
|
|
133
|
-
lastValidText.current = clampedText
|
|
134
|
-
setValue(clampedText)
|
|
135
|
-
local _result = props.onChange
|
|
136
|
-
if _result ~= nil then
|
|
137
|
-
_result(clampedText)
|
|
138
|
-
end
|
|
139
|
-
end
|
|
122
|
+
local clampedText = resolveClampedText(props.validation, rbx.Text, props.min, props.max)
|
|
123
|
+
if clampedText ~= nil then
|
|
124
|
+
ref.current.Text = clampedText
|
|
125
|
+
lastValidText.current = clampedText
|
|
126
|
+
setValue(clampedText)
|
|
127
|
+
local _result = props.onChange
|
|
128
|
+
if _result ~= nil then
|
|
129
|
+
_result(clampedText)
|
|
140
130
|
end
|
|
141
131
|
end
|
|
142
132
|
local _result = props.Event
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { InputProps } from "./Input";
|
|
2
2
|
export declare const CHARACTER_ALLOW_LIST_PATTERNS: Partial<Record<NonNullable<InputProps["validation"]>, string>>;
|
|
3
3
|
export declare function resolveValidatedText(validation: InputProps["validation"], candidateText: string, lastValidText: string): string;
|
|
4
|
+
export declare function resolveClampedText(validation: InputProps["validation"], text: string, min: number | undefined, max: number | undefined): string | undefined;
|
|
@@ -15,7 +15,28 @@ local function resolveValidatedText(validation, candidateText, lastValidText)
|
|
|
15
15
|
end
|
|
16
16
|
return candidateText
|
|
17
17
|
end
|
|
18
|
+
local function resolveClampedText(validation, text, min, max)
|
|
19
|
+
if validation ~= "Number" and validation ~= "Int" then
|
|
20
|
+
return nil
|
|
21
|
+
end
|
|
22
|
+
local number = tonumber(text)
|
|
23
|
+
if number == nil then
|
|
24
|
+
return nil
|
|
25
|
+
end
|
|
26
|
+
local clamped = number
|
|
27
|
+
if min ~= nil and clamped < min then
|
|
28
|
+
clamped = min
|
|
29
|
+
end
|
|
30
|
+
if max ~= nil and clamped > max then
|
|
31
|
+
clamped = max
|
|
32
|
+
end
|
|
33
|
+
if clamped == number then
|
|
34
|
+
return nil
|
|
35
|
+
end
|
|
36
|
+
return tostring(clamped)
|
|
37
|
+
end
|
|
18
38
|
return {
|
|
19
39
|
resolveValidatedText = resolveValidatedText,
|
|
40
|
+
resolveClampedText = resolveClampedText,
|
|
20
41
|
CHARACTER_ALLOW_LIST_PATTERNS = CHARACTER_ALLOW_LIST_PATTERNS,
|
|
21
42
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import React from "@rbxts/react";
|
|
2
|
-
import { IconName, ScalableElementProps } from "../../Interfaces";
|
|
2
|
+
import { IconName, PaddingProps, ScalableElementProps } from "../../Interfaces";
|
|
3
3
|
interface AccordionItemProps {
|
|
4
4
|
children?: React.ReactNode;
|
|
5
5
|
value: string;
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
}
|
|
8
8
|
declare function AccordionItem(_props: AccordionItemProps): undefined;
|
|
9
|
-
interface AccordionHeaderProps {
|
|
9
|
+
interface AccordionHeaderProps extends PaddingProps {
|
|
10
10
|
children?: React.ReactNode | string;
|
|
11
11
|
icon?: IconName;
|
|
12
12
|
text?: string;
|
|
13
13
|
}
|
|
14
14
|
declare function AccordionHeader(_props: AccordionHeaderProps): undefined;
|
|
15
|
-
interface AccordionContentProps {
|
|
15
|
+
interface AccordionContentProps extends PaddingProps {
|
|
16
16
|
children?: React.ReactNode;
|
|
17
17
|
text?: string;
|
|
18
18
|
}
|
|
@@ -5,6 +5,7 @@ local useTween = TS.import(script, TS.getModule(script, "@rbxts", "react-ripple"
|
|
|
5
5
|
local CleanThemeContext = TS.import(script, script.Parent.Parent.Parent, "Contexts").CleanThemeContext
|
|
6
6
|
local _Helpers = TS.import(script, script.Parent.Parent.Parent, "Helpers")
|
|
7
7
|
local ColorHelper = _Helpers.ColorHelper
|
|
8
|
+
local CssHelper = _Helpers.CssHelper
|
|
8
9
|
local SizeHelper = _Helpers.SizeHelper
|
|
9
10
|
local SpacingHelper = _Helpers.SpacingHelper
|
|
10
11
|
local TypographyHelper = _Helpers.TypographyHelper
|
|
@@ -75,7 +76,7 @@ local function AccordionHeaderVisual(props)
|
|
|
75
76
|
return props.header.children
|
|
76
77
|
end
|
|
77
78
|
local _exp = React.createElement(Padding, {
|
|
78
|
-
resolvedPadding = SpacingHelper:GetResolvedPadding(theme,
|
|
79
|
+
resolvedPadding = SpacingHelper:GetResolvedPadding(theme, props.header, theme.components.accordion.header.spacing, theme.components.accordion.header.padding),
|
|
79
80
|
})
|
|
80
81
|
local _exp_1 = props.header.icon ~= nil and React.createElement(Icon, {
|
|
81
82
|
icon = props.header.icon,
|
|
@@ -117,6 +118,43 @@ local function RenderedAccordionItem(props)
|
|
|
117
118
|
local height, heightTween = useTween(0, {
|
|
118
119
|
duration = props.duration,
|
|
119
120
|
})
|
|
121
|
+
local contentRef = React.useRef()
|
|
122
|
+
local onContentSizeRef = React.useRef()
|
|
123
|
+
onContentSizeRef.current = function(instance)
|
|
124
|
+
if props.open then
|
|
125
|
+
heightTween:setGoal(instance.AbsoluteSize.Y, {
|
|
126
|
+
duration = props.duration,
|
|
127
|
+
})
|
|
128
|
+
if props.duration == 0 then
|
|
129
|
+
heightTween:setPosition(instance.AbsoluteSize.Y)
|
|
130
|
+
end
|
|
131
|
+
heightTween:start()
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
React.useEffect(function()
|
|
135
|
+
local frame = contentRef.current
|
|
136
|
+
if not frame then
|
|
137
|
+
return nil
|
|
138
|
+
end
|
|
139
|
+
-- Some renderers (e.g. the browser-based Loom scene preview) don't back
|
|
140
|
+
-- this ref with an instance that supports property-changed signals, so
|
|
141
|
+
-- guard the subscription instead of throwing and losing height tracking.
|
|
142
|
+
local conn
|
|
143
|
+
pcall(function()
|
|
144
|
+
conn = frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
|
|
145
|
+
local _result = onContentSizeRef.current
|
|
146
|
+
if _result ~= nil then
|
|
147
|
+
_result(frame)
|
|
148
|
+
end
|
|
149
|
+
end)
|
|
150
|
+
end)
|
|
151
|
+
return function()
|
|
152
|
+
local _result = conn
|
|
153
|
+
if _result ~= nil then
|
|
154
|
+
_result:Disconnect()
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end, { mounted })
|
|
120
158
|
React.useEffect(function()
|
|
121
159
|
if props.open then
|
|
122
160
|
setMounted(true)
|
|
@@ -148,6 +186,9 @@ local function RenderedAccordionItem(props)
|
|
|
148
186
|
local defaultColors = ColorHelper:getIntentColors(theme, "primary", if props.disabled then "disabled" else "default", theme.components.accordion.header.intents)
|
|
149
187
|
local hoverColors = ColorHelper:getIntentColors(theme, "primary", "hover", theme.components.accordion.header.intents)
|
|
150
188
|
local focusColors = ColorHelper:getIntentColors(theme, "primary", "focus", theme.components.accordion.header.intents)
|
|
189
|
+
local defaultBackgroundImage = CssHelper:resolveBackgroundImage(defaultColors.backgroundImage)
|
|
190
|
+
local hoverBackgroundImage = CssHelper:resolveBackgroundImage(hoverColors.backgroundImage)
|
|
191
|
+
local focusBackgroundImage = CssHelper:resolveBackgroundImage(focusColors.backgroundImage)
|
|
151
192
|
local _condition = not props.first
|
|
152
193
|
if _condition then
|
|
153
194
|
local _attributes = {
|
|
@@ -169,7 +210,6 @@ local function RenderedAccordionItem(props)
|
|
|
169
210
|
AutoButtonColor = false,
|
|
170
211
|
AutomaticSize = Enum.AutomaticSize.Y,
|
|
171
212
|
Size = UDim2.fromScale(1, 0),
|
|
172
|
-
ImageTransparency = 1,
|
|
173
213
|
BackgroundColor3 = defaultColors.backgroundColor,
|
|
174
214
|
}
|
|
175
215
|
local _left = "BackgroundTransparency"
|
|
@@ -179,6 +219,13 @@ local function RenderedAccordionItem(props)
|
|
|
179
219
|
end
|
|
180
220
|
_object[_left] = _condition_1
|
|
181
221
|
_object.BorderSizePixel = 0
|
|
222
|
+
_object.Image = defaultBackgroundImage.Image
|
|
223
|
+
_object.ImageColor3 = defaultBackgroundImage.ImageColor3
|
|
224
|
+
_object.ImageTransparency = defaultBackgroundImage.ImageTransparency
|
|
225
|
+
_object.ScaleType = defaultBackgroundImage.ScaleType
|
|
226
|
+
_object.SliceCenter = defaultBackgroundImage.SliceCenter
|
|
227
|
+
_object.SliceScale = defaultBackgroundImage.SliceScale
|
|
228
|
+
_object.TileSize = defaultBackgroundImage.TileSize
|
|
182
229
|
_object.Event = {
|
|
183
230
|
Activated = props.onActivate,
|
|
184
231
|
}
|
|
@@ -192,6 +239,13 @@ local function RenderedAccordionItem(props)
|
|
|
192
239
|
_condition_2 = 0
|
|
193
240
|
end
|
|
194
241
|
_object_1[_left_1] = _condition_2
|
|
242
|
+
_object_1.Image = hoverBackgroundImage.Image
|
|
243
|
+
_object_1.ImageColor3 = hoverBackgroundImage.ImageColor3
|
|
244
|
+
_object_1.ImageTransparency = hoverBackgroundImage.ImageTransparency
|
|
245
|
+
_object_1.ScaleType = hoverBackgroundImage.ScaleType
|
|
246
|
+
_object_1.SliceCenter = hoverBackgroundImage.SliceCenter
|
|
247
|
+
_object_1.SliceScale = hoverBackgroundImage.SliceScale
|
|
248
|
+
_object_1.TileSize = hoverBackgroundImage.TileSize
|
|
195
249
|
_attributes.hover = _object_1
|
|
196
250
|
local _object_2 = {
|
|
197
251
|
BackgroundColor3 = focusColors.backgroundColor,
|
|
@@ -202,6 +256,13 @@ local function RenderedAccordionItem(props)
|
|
|
202
256
|
_condition_3 = 0
|
|
203
257
|
end
|
|
204
258
|
_object_2[_left_2] = _condition_3
|
|
259
|
+
_object_2.Image = focusBackgroundImage.Image
|
|
260
|
+
_object_2.ImageColor3 = focusBackgroundImage.ImageColor3
|
|
261
|
+
_object_2.ImageTransparency = focusBackgroundImage.ImageTransparency
|
|
262
|
+
_object_2.ScaleType = focusBackgroundImage.ScaleType
|
|
263
|
+
_object_2.SliceCenter = focusBackgroundImage.SliceCenter
|
|
264
|
+
_object_2.SliceScale = focusBackgroundImage.SliceScale
|
|
265
|
+
_object_2.TileSize = focusBackgroundImage.TileSize
|
|
205
266
|
_attributes.focus = _object_2
|
|
206
267
|
return React.createElement(Container, {
|
|
207
268
|
width = "100%",
|
|
@@ -226,25 +287,13 @@ local function RenderedAccordionItem(props)
|
|
|
226
287
|
return _exp + _arg0
|
|
227
288
|
end),
|
|
228
289
|
}, React.createElement("frame", {
|
|
290
|
+
ref = contentRef,
|
|
229
291
|
BackgroundColor3 = theme.components.accordion.content.backgroundColor,
|
|
230
292
|
BackgroundTransparency = theme.components.accordion.content.backgroundTransparency,
|
|
231
293
|
Size = UDim2.fromScale(1, 0),
|
|
232
294
|
AutomaticSize = Enum.AutomaticSize.Y,
|
|
233
|
-
Change = {
|
|
234
|
-
AbsoluteSize = function(instance)
|
|
235
|
-
if props.open then
|
|
236
|
-
heightTween:setGoal(instance.AbsoluteSize.Y, {
|
|
237
|
-
duration = props.duration,
|
|
238
|
-
})
|
|
239
|
-
if props.duration == 0 then
|
|
240
|
-
heightTween:setPosition(instance.AbsoluteSize.Y)
|
|
241
|
-
end
|
|
242
|
-
heightTween:start()
|
|
243
|
-
end
|
|
244
|
-
end,
|
|
245
|
-
},
|
|
246
295
|
}, React.createElement(Padding, {
|
|
247
|
-
resolvedPadding = SpacingHelper:GetResolvedPadding(theme,
|
|
296
|
+
resolvedPadding = SpacingHelper:GetResolvedPadding(theme, props.contentProps, theme.components.accordion.content.spacing, theme.components.accordion.content.padding),
|
|
248
297
|
}), if props.contentText ~= nil then React.createElement(Text, {
|
|
249
298
|
text = props.contentText,
|
|
250
299
|
}) else props.content)))))
|
|
@@ -264,6 +313,7 @@ local Accordion = React.forwardRef(function(props, ref)
|
|
|
264
313
|
return nil
|
|
265
314
|
end
|
|
266
315
|
local header
|
|
316
|
+
local contentProps
|
|
267
317
|
local contentText
|
|
268
318
|
local content
|
|
269
319
|
React.Children.forEach(item.props.children, function(itemChild)
|
|
@@ -274,7 +324,7 @@ local Accordion = React.forwardRef(function(props, ref)
|
|
|
274
324
|
header = itemChild.props
|
|
275
325
|
end
|
|
276
326
|
if itemChild.type == AccordionContent and content == nil then
|
|
277
|
-
|
|
327
|
+
contentProps = itemChild.props
|
|
278
328
|
contentText = contentProps.text
|
|
279
329
|
content = contentProps.children
|
|
280
330
|
end
|
|
@@ -292,6 +342,7 @@ local Accordion = React.forwardRef(function(props, ref)
|
|
|
292
342
|
end
|
|
293
343
|
_object[_left] = _condition
|
|
294
344
|
_object.header = header
|
|
345
|
+
_object.contentProps = contentProps or {}
|
|
295
346
|
_object.contentText = contentText
|
|
296
347
|
_object.content = content
|
|
297
348
|
table.insert(parsed, _object)
|
|
@@ -45,6 +45,45 @@ local Fieldset = React.forwardRef(function(props, ref)
|
|
|
45
45
|
labelActivated:Destroy()
|
|
46
46
|
end
|
|
47
47
|
end, {})
|
|
48
|
+
local containerRef = React.useRef()
|
|
49
|
+
local setContainerRef = function(instance)
|
|
50
|
+
containerRef.current = instance
|
|
51
|
+
local _ref = ref
|
|
52
|
+
if type(_ref) == "function" then
|
|
53
|
+
ref(instance)
|
|
54
|
+
else
|
|
55
|
+
local _condition = ref ~= nil
|
|
56
|
+
if _condition then
|
|
57
|
+
local _ref_1 = ref
|
|
58
|
+
_condition = type(_ref_1) == "table"
|
|
59
|
+
end
|
|
60
|
+
if _condition then
|
|
61
|
+
ref.current = instance
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
React.useEffect(function()
|
|
66
|
+
local frame = containerRef.current
|
|
67
|
+
if not frame then
|
|
68
|
+
return nil
|
|
69
|
+
end
|
|
70
|
+
-- Some renderers (e.g. the browser-based Loom scene preview) don't
|
|
71
|
+
-- back this ref with an instance that supports property-changed
|
|
72
|
+
-- signals, so guard the subscription instead of throwing and
|
|
73
|
+
-- losing breakpoint width tracking.
|
|
74
|
+
local conn
|
|
75
|
+
pcall(function()
|
|
76
|
+
conn = frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
|
|
77
|
+
return setWidth(frame.AbsoluteSize.X)
|
|
78
|
+
end)
|
|
79
|
+
end)
|
|
80
|
+
return function()
|
|
81
|
+
local _result = conn
|
|
82
|
+
if _result ~= nil then
|
|
83
|
+
_result:Disconnect()
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end, {})
|
|
48
87
|
local fieldsetContext = React.useMemo(function()
|
|
49
88
|
local _object = {}
|
|
50
89
|
local _left = "disabled"
|
|
@@ -68,12 +107,7 @@ local Fieldset = React.forwardRef(function(props, ref)
|
|
|
68
107
|
return React.createElement(FieldsetContext.Provider, {
|
|
69
108
|
value = fieldsetContext,
|
|
70
109
|
}, React.createElement(Container, {
|
|
71
|
-
ref =
|
|
72
|
-
Change = {
|
|
73
|
-
AbsoluteSize = function(instance)
|
|
74
|
-
setWidth(instance.AbsoluteSize.X)
|
|
75
|
-
end,
|
|
76
|
-
},
|
|
110
|
+
ref = setContainerRef,
|
|
77
111
|
}, React.createElement(HStack, {
|
|
78
112
|
Wraps = wrap,
|
|
79
113
|
valign = "Center",
|
|
@@ -34,9 +34,7 @@ local function GroupElement(props)
|
|
|
34
34
|
_result_1 = _result_1.removeElement
|
|
35
35
|
end
|
|
36
36
|
React.useEffect(_exp, { enabled, _result_1 })
|
|
37
|
-
|
|
38
|
-
return props.children
|
|
39
|
-
end
|
|
37
|
+
local elementRef = React.useRef()
|
|
40
38
|
local _result_2 = props.padding
|
|
41
39
|
if _result_2 ~= nil then
|
|
42
40
|
_result_2 = _result_2.left
|
|
@@ -71,14 +69,38 @@ local function GroupElement(props)
|
|
|
71
69
|
_condition_4 = 0
|
|
72
70
|
end
|
|
73
71
|
local verticalPadding = _condition_3 + _condition_4
|
|
72
|
+
React.useEffect(function()
|
|
73
|
+
if not enabled then
|
|
74
|
+
return nil
|
|
75
|
+
end
|
|
76
|
+
local frame = elementRef.current
|
|
77
|
+
if not frame or not context then
|
|
78
|
+
return nil
|
|
79
|
+
end
|
|
80
|
+
-- Some renderers (e.g. the browser-based Loom scene preview) don't
|
|
81
|
+
-- back this ref with an instance that supports property-changed
|
|
82
|
+
-- signals, so guard the subscription instead of throwing and
|
|
83
|
+
-- losing size reporting.
|
|
84
|
+
local conn
|
|
85
|
+
pcall(function()
|
|
86
|
+
conn = frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
|
|
87
|
+
context.reportSize(id, Vector2.new(frame.AbsoluteSize.X + horizontalPadding, frame.AbsoluteSize.Y + verticalPadding))
|
|
88
|
+
end)
|
|
89
|
+
end)
|
|
90
|
+
return function()
|
|
91
|
+
local _result_6 = conn
|
|
92
|
+
if _result_6 ~= nil then
|
|
93
|
+
_result_6:Disconnect()
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end, { enabled, context, id, horizontalPadding, verticalPadding })
|
|
97
|
+
if not enabled then
|
|
98
|
+
return props.children
|
|
99
|
+
end
|
|
74
100
|
return React.createElement("frame", {
|
|
101
|
+
ref = elementRef,
|
|
75
102
|
BackgroundTransparency = 1,
|
|
76
103
|
AutomaticSize = Enum.AutomaticSize.XY,
|
|
77
|
-
Change = {
|
|
78
|
-
AbsoluteSize = function(instance)
|
|
79
|
-
context.reportSize(id, Vector2.new(instance.AbsoluteSize.X + horizontalPadding, instance.AbsoluteSize.Y + verticalPadding))
|
|
80
|
-
end,
|
|
81
|
-
},
|
|
82
104
|
}, props.children)
|
|
83
105
|
end
|
|
84
106
|
local function getMaxVector2(map)
|
|
@@ -11,6 +11,7 @@ local function HStack(props)
|
|
|
11
11
|
VerticalAlignment = props.valign,
|
|
12
12
|
Padding = props.Padding or UDim.new(0, math.ceil(SpacingHelper:GetPadding(theme, props.spacing) / 2)),
|
|
13
13
|
Wraps = if props.Wraps == nil then true else props.Wraps,
|
|
14
|
+
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
14
15
|
Change = props.Change,
|
|
15
16
|
Event = props.Event,
|
|
16
17
|
}), props.children)
|
|
@@ -13,6 +13,48 @@ local Row = React.forwardRef(function(props, ref)
|
|
|
13
13
|
local width, setWidth = React.useState(0)
|
|
14
14
|
local breakpoints = props.breakpoints or theme.breakpoints
|
|
15
15
|
local padding = UDim.new(0, SpacingHelper:GetPadding(theme, props.spacing))
|
|
16
|
+
local rowRef = React.useRef()
|
|
17
|
+
local setRowRef = function(instance)
|
|
18
|
+
rowRef.current = instance
|
|
19
|
+
local _ref = ref
|
|
20
|
+
if type(_ref) == "function" then
|
|
21
|
+
ref(instance)
|
|
22
|
+
else
|
|
23
|
+
local _condition = ref ~= nil
|
|
24
|
+
if _condition then
|
|
25
|
+
local _ref_1 = ref
|
|
26
|
+
_condition = type(_ref_1) == "table"
|
|
27
|
+
end
|
|
28
|
+
if _condition then
|
|
29
|
+
ref.current = instance
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
React.useEffect(function()
|
|
34
|
+
local frame = rowRef.current
|
|
35
|
+
if not frame then
|
|
36
|
+
return nil
|
|
37
|
+
end
|
|
38
|
+
-- Some renderers (e.g. the browser-based Loom scene preview) don't
|
|
39
|
+
-- back this ref with an instance that supports property-changed
|
|
40
|
+
-- signals, so guard the subscription instead of throwing and
|
|
41
|
+
-- losing breakpoint width tracking.
|
|
42
|
+
local conn
|
|
43
|
+
pcall(function()
|
|
44
|
+
conn = frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
|
|
45
|
+
local nextWidth = frame.AbsoluteSize.X
|
|
46
|
+
setWidth(function(currentWidth)
|
|
47
|
+
return if currentWidth == nextWidth then currentWidth else nextWidth
|
|
48
|
+
end)
|
|
49
|
+
end)
|
|
50
|
+
end)
|
|
51
|
+
return function()
|
|
52
|
+
local _result = conn
|
|
53
|
+
if _result ~= nil then
|
|
54
|
+
_result:Disconnect()
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end, {})
|
|
16
58
|
local _exp = React.createElement("uilistlayout", {
|
|
17
59
|
FillDirection = Enum.FillDirection.Horizontal,
|
|
18
60
|
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
@@ -43,18 +85,10 @@ local Row = React.forwardRef(function(props, ref)
|
|
|
43
85
|
_object.breakpoint = BreakpointHelper:getBreakpoint(width, breakpoints)
|
|
44
86
|
_attributes.value = _object
|
|
45
87
|
return React.createElement("frame", {
|
|
46
|
-
ref =
|
|
88
|
+
ref = setRowRef,
|
|
47
89
|
Size = UDim2.fromScale(1, 1),
|
|
48
90
|
AutomaticSize = Enum.AutomaticSize.Y,
|
|
49
91
|
BackgroundTransparency = 1,
|
|
50
|
-
Change = {
|
|
51
|
-
AbsoluteSize = function(instance)
|
|
52
|
-
local nextWidth = instance.AbsoluteSize.X
|
|
53
|
-
setWidth(function(currentWidth)
|
|
54
|
-
return if currentWidth == nextWidth then currentWidth else nextWidth
|
|
55
|
-
end)
|
|
56
|
-
end,
|
|
57
|
-
},
|
|
58
92
|
}, _exp, React.createElement(RowContext.Provider, _attributes, props.children))
|
|
59
93
|
end)
|
|
60
94
|
return {
|
|
@@ -19,11 +19,26 @@ local function Scroller(props)
|
|
|
19
19
|
setIsScrolling(frame.AbsoluteCanvasSize.Y > frame.AbsoluteWindowSize.Y)
|
|
20
20
|
end
|
|
21
21
|
updateScrolling()
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
-- Some renderers (e.g. the browser-based Loom scene preview) don't back
|
|
23
|
+
-- this ref with an instance that supports property-changed signals, so
|
|
24
|
+
-- guard the subscription instead of throwing and losing overflow tracking.
|
|
25
|
+
local canvasConn
|
|
26
|
+
local windowConn
|
|
27
|
+
pcall(function()
|
|
28
|
+
canvasConn = frame:GetPropertyChangedSignal("AbsoluteCanvasSize"):Connect(updateScrolling)
|
|
29
|
+
end)
|
|
30
|
+
pcall(function()
|
|
31
|
+
windowConn = frame:GetPropertyChangedSignal("AbsoluteWindowSize"):Connect(updateScrolling)
|
|
32
|
+
end)
|
|
24
33
|
return function()
|
|
25
|
-
canvasConn
|
|
26
|
-
|
|
34
|
+
local _result = canvasConn
|
|
35
|
+
if _result ~= nil then
|
|
36
|
+
_result:Disconnect()
|
|
37
|
+
end
|
|
38
|
+
local _result_1 = windowConn
|
|
39
|
+
if _result_1 ~= nil then
|
|
40
|
+
_result_1:Disconnect()
|
|
41
|
+
end
|
|
27
42
|
end
|
|
28
43
|
end, {})
|
|
29
44
|
local spacing = SpacingHelper:GetPadding(theme, props.spacing)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from "@rbxts/react";
|
|
2
|
-
import { ScalableElementProps } from "../../Interfaces";
|
|
2
|
+
import { PaddingProps, ScalableElementProps } from "../../Interfaces";
|
|
3
|
+
import { CssBackgroundImage } from "../../Theme";
|
|
3
4
|
interface TabProps {
|
|
4
5
|
children?: React.ReactNode;
|
|
5
6
|
}
|
|
6
7
|
declare function Tab(_props: TabProps): undefined;
|
|
7
|
-
interface TabTitleProps {
|
|
8
|
+
interface TabTitleProps extends PaddingProps {
|
|
8
9
|
text: string;
|
|
9
10
|
}
|
|
10
11
|
declare function TabTitle(_props: TabTitleProps): undefined;
|
|
@@ -13,6 +14,7 @@ interface TabContentProps {
|
|
|
13
14
|
}
|
|
14
15
|
declare function TabContent(props: TabContentProps): undefined;
|
|
15
16
|
interface TabsProps extends ScalableElementProps {
|
|
17
|
+
backgroundImage?: CssBackgroundImage;
|
|
16
18
|
}
|
|
17
19
|
type TabsComponent = React.ForwardRefExoticComponent<TabsProps & React.RefAttributes<ImageLabel>> & {
|
|
18
20
|
Tab: typeof Tab;
|
|
@@ -46,9 +46,9 @@ local function TabButtonContent(props)
|
|
|
46
46
|
end
|
|
47
47
|
local intent = ColorHelper:getIntentColors(theme, "primary", _result_1, theme.components.tabs.button.intents)
|
|
48
48
|
return React.createElement(React.Fragment, nil, React.createElement(Corners, {
|
|
49
|
-
radius = theme.components.tabs.
|
|
49
|
+
radius = theme.components.tabs.list.cornerRadius,
|
|
50
50
|
}), React.createElement(Padding, {
|
|
51
|
-
resolvedPadding = SpacingHelper:GetResolvedPadding(theme,
|
|
51
|
+
resolvedPadding = SpacingHelper:GetResolvedPadding(theme, props, theme.components.tabs.button.spacing, theme.components.tabs.button.padding),
|
|
52
52
|
}), React.createElement(BoxShadow, {
|
|
53
53
|
value = intent.boxShadow,
|
|
54
54
|
}), React.createElement(Text, {
|
|
@@ -117,11 +117,13 @@ local Tabs = React.forwardRef(function(props, ref)
|
|
|
117
117
|
radius = theme.components.tabs.list.cornerRadius,
|
|
118
118
|
})
|
|
119
119
|
local _exp_1 = React.createElement(Padding, {
|
|
120
|
-
resolvedPadding = SpacingHelper:GetResolvedPadding(theme, {}, theme.components.tabs.list.spacing),
|
|
120
|
+
resolvedPadding = SpacingHelper:GetResolvedPadding(theme, {}, theme.components.tabs.list.spacing, theme.components.tabs.list.padding),
|
|
121
121
|
})
|
|
122
122
|
-- ▼ ReadonlyArray.map ▼
|
|
123
123
|
local _newValue = table.create(#tabs)
|
|
124
124
|
local _callback = function(tab, index)
|
|
125
|
+
local _attributes_1 = table.clone(tab.title)
|
|
126
|
+
setmetatable(_attributes_1, nil)
|
|
125
127
|
return React.createElement(HoverButton, {
|
|
126
128
|
isSelected = selected == index,
|
|
127
129
|
default = {
|
|
@@ -166,9 +168,7 @@ local Tabs = React.forwardRef(function(props, ref)
|
|
|
166
168
|
SliceScale = buttonFocusBackgroundImage.SliceScale,
|
|
167
169
|
TileSize = buttonFocusBackgroundImage.TileSize,
|
|
168
170
|
},
|
|
169
|
-
}, React.createElement(TabButtonContent,
|
|
170
|
-
text = tab.title.text,
|
|
171
|
-
}))
|
|
171
|
+
}, React.createElement(TabButtonContent, _attributes_1))
|
|
172
172
|
end
|
|
173
173
|
for _k, _v in tabs do
|
|
174
174
|
_newValue[_k] = _callback(_v, _k - 1, tabs)
|
|
@@ -181,16 +181,18 @@ local Tabs = React.forwardRef(function(props, ref)
|
|
|
181
181
|
Color = theme.components.tabs.borderColor,
|
|
182
182
|
})
|
|
183
183
|
local _exp_4 = React.createElement(Padding, {
|
|
184
|
-
resolvedPadding = SpacingHelper:GetResolvedPadding(theme, {}, theme.components.tabs.spacing),
|
|
184
|
+
resolvedPadding = SpacingHelper:GetResolvedPadding(theme, {}, theme.components.tabs.spacing, theme.components.tabs.padding),
|
|
185
185
|
})
|
|
186
186
|
local _exp_5 = React.createElement(Corners, {
|
|
187
|
-
radius = theme.components.tabs.
|
|
187
|
+
radius = theme.components.tabs.cornerRadius,
|
|
188
188
|
})
|
|
189
189
|
local _result = selectedTab
|
|
190
190
|
if _result ~= nil then
|
|
191
191
|
_result = _result.content
|
|
192
192
|
end
|
|
193
|
-
return React.createElement(VStack, nil, _exp_2, React.createElement(Container,
|
|
193
|
+
return React.createElement(VStack, nil, _exp_2, React.createElement(Container, {
|
|
194
|
+
backgroundImage = props.backgroundImage or theme.components.tabs.backgroundImage,
|
|
195
|
+
}, _exp_3, _exp_4, _exp_5, _result))
|
|
194
196
|
end)
|
|
195
197
|
Tabs.Title = TabTitle
|
|
196
198
|
Tabs.Tab = Tab
|
|
@@ -40,6 +40,7 @@ local Menu = React.forwardRef(function(props, ref)
|
|
|
40
40
|
valign = "Center",
|
|
41
41
|
}, React.createElement(Button, {
|
|
42
42
|
icon = "bars",
|
|
43
|
+
LayoutOrder = 1,
|
|
43
44
|
Event = {
|
|
44
45
|
Activated = function()
|
|
45
46
|
setCollapsed(not collapsed)
|
|
@@ -48,6 +49,7 @@ local Menu = React.forwardRef(function(props, ref)
|
|
|
48
49
|
}), not collapsed and React.createElement(Text, {
|
|
49
50
|
text = props.title,
|
|
50
51
|
variant = "heading",
|
|
52
|
+
LayoutOrder = 2,
|
|
51
53
|
}))), React.createElement(FlexItem, {
|
|
52
54
|
mode = "Fill",
|
|
53
55
|
}, React.createElement(Scroller, {
|