@nrbx/topbar-components 1.0.0 → 1.0.2
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/dropdown.luau +1 -1
- package/out/components/icon.d.ts +7 -1
- package/out/components/icon.luau +40 -16
- package/out/components/provider.luau +72 -3
- package/out/components/stylesheet.luau +1 -1
- package/out/context.luau +1 -1
- package/out/hooks/use-animateable-props.luau +1 -1
- package/out/hooks/use-gui-inset.luau +1 -1
- package/out/hooks/use-id.luau +1 -1
- package/out/hooks/use-voicechat-enabled.luau +1 -1
- package/out/init.luau +1 -1
- package/out/style.d.ts +6 -0
- package/out/style.luau +7 -1
- package/out/utilities/id-gen.luau +1 -1
- package/out/utilities/resolve-state-dependent.luau +1 -1
- package/out/utilities/springs.luau +1 -1
- package/out/utilities/types.luau +1 -1
- package/package.json +3 -3
package/out/components/icon.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from '@rbxts/react';
|
|
2
|
+
export type Dock = 'Left' | 'Center' | 'Right';
|
|
2
3
|
export interface IconProps extends React.PropsWithChildren {
|
|
3
4
|
backgroundTransparency?: StateDependent<number>;
|
|
4
5
|
backgroundColor?: StateDependent<Color3>;
|
|
@@ -24,6 +25,11 @@ export interface IconProps extends React.PropsWithChildren {
|
|
|
24
25
|
textAlignment?: StateDependent<Enum.TextXAlignment>;
|
|
25
26
|
richText?: StateDependent<boolean>;
|
|
26
27
|
toggleStateOnClick?: boolean;
|
|
28
|
+
dock?: Dock;
|
|
29
|
+
/** When true, renders as a non-interactive label (no clicks, no hovers, no state changes) */
|
|
30
|
+
static?: boolean;
|
|
31
|
+
/** When true, dulls the text and icon with a dimming overlay */
|
|
32
|
+
disabled?: boolean;
|
|
27
33
|
selected?: () => void;
|
|
28
34
|
deselected?: () => void;
|
|
29
35
|
hover?: () => void;
|
|
@@ -37,4 +43,4 @@ export type IconState = 'selected' | 'deselected';
|
|
|
37
43
|
export type StateDependent<T> = Record<IconState, T> | T;
|
|
38
44
|
export type FromStateDependent<T> = T extends StateDependent<infer U> ? U : T;
|
|
39
45
|
export type IconId = number;
|
|
40
|
-
export declare function Icon(
|
|
46
|
+
export declare function Icon(componentProps: IconProps): React.JSX.Element;
|
package/out/components/icon.luau
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
-- Compiled with roblox-ts
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local deepEquals = TS.import(script, TS.getModule(script, "@rbxts", "object-utils")).deepEquals
|
|
4
4
|
local _pretty_react_hooks = TS.import(script, TS.getModule(script, "@rbxts", "pretty-react-hooks").out)
|
|
@@ -24,18 +24,9 @@ local useId = TS.import(script, script.Parent.Parent, "hooks", "use-id").useId
|
|
|
24
24
|
local noop = TS.import(script, script.Parent.Parent, "style").noop
|
|
25
25
|
local stateful = TS.import(script, script.Parent.Parent, "utilities", "resolve-state-dependent").stateful
|
|
26
26
|
local ANIMATEABLE = { "backgroundColor", "backgroundTransparency", "imageColor", "imageTransparency" }
|
|
27
|
-
local function Icon(
|
|
28
|
-
local
|
|
29
|
-
local
|
|
30
|
-
["children"] = true,
|
|
31
|
-
}
|
|
32
|
-
local _rest = {}
|
|
33
|
-
for _k, _v in _param do
|
|
34
|
-
if not _extracted[_k] then
|
|
35
|
-
_rest[_k] = _v
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
local componentProps = _rest
|
|
27
|
+
local function Icon(componentProps)
|
|
28
|
+
local _binding = componentProps
|
|
29
|
+
local children = _binding.children
|
|
39
30
|
local inset = useGuiInset()
|
|
40
31
|
local location = useLocation()
|
|
41
32
|
local id = useId()
|
|
@@ -63,15 +54,24 @@ local function Icon(_param)
|
|
|
63
54
|
end
|
|
64
55
|
local props = _object_1
|
|
65
56
|
useMountEffect(function()
|
|
57
|
+
if props.static then
|
|
58
|
+
return nil
|
|
59
|
+
end
|
|
66
60
|
local _ = props.defaultState and not componentProps.forcedState and setState(props.defaultState)
|
|
67
61
|
end)
|
|
68
62
|
useEffect(function()
|
|
63
|
+
if props.static then
|
|
64
|
+
return nil
|
|
65
|
+
end
|
|
69
66
|
if not componentProps.forcedState then
|
|
70
67
|
return nil
|
|
71
68
|
end
|
|
72
69
|
setState(componentProps.forcedState)
|
|
73
70
|
end, { componentProps.forcedState })
|
|
74
71
|
useUpdateEffect(function()
|
|
72
|
+
if props.static then
|
|
73
|
+
return nil
|
|
74
|
+
end
|
|
75
75
|
props.stateChanged(currentState)
|
|
76
76
|
if currentState == "selected" then
|
|
77
77
|
location.iconSelected(id)
|
|
@@ -82,6 +82,9 @@ local function Icon(_param)
|
|
|
82
82
|
end
|
|
83
83
|
end, { currentState })
|
|
84
84
|
useUpdateEffect(function()
|
|
85
|
+
if props.static then
|
|
86
|
+
return nil
|
|
87
|
+
end
|
|
85
88
|
if currentState == "selected" and not (table.find(location.selectedIcons, id) ~= nil) then
|
|
86
89
|
setState("deselected")
|
|
87
90
|
end
|
|
@@ -135,6 +138,9 @@ local function Icon(_param)
|
|
|
135
138
|
local imagePos = stylesheet.sizing.imagePadding + imageSizeOff * -0.5
|
|
136
139
|
local textLabelPos = UDim2.new(0, if currentImage ~= "" and currentImage then imageSize + stylesheet.sizing.imagePadding * 2 else stylesheet.sizing.labelPadding, 0.5, 0)
|
|
137
140
|
useEffect(function()
|
|
141
|
+
if props.static then
|
|
142
|
+
return nil
|
|
143
|
+
end
|
|
138
144
|
if location.type ~= "dropdown" then
|
|
139
145
|
return nil
|
|
140
146
|
end
|
|
@@ -144,6 +150,9 @@ local function Icon(_param)
|
|
|
144
150
|
location.registerChild(id, _vector2 + _vector2_1)
|
|
145
151
|
end, { currentState, contentSize.Y, dropdownAnimating, iconSize })
|
|
146
152
|
useUnmountEffect(function()
|
|
153
|
+
if props.static then
|
|
154
|
+
return nil
|
|
155
|
+
end
|
|
147
156
|
if location.type ~= "dropdown" then
|
|
148
157
|
return nil
|
|
149
158
|
end
|
|
@@ -169,8 +178,13 @@ local function Icon(_param)
|
|
|
169
178
|
key = "IconWrapper",
|
|
170
179
|
}, React.createElement("textbutton", {
|
|
171
180
|
Size = UDim2.new(1, 0, 0, iconSize.Y),
|
|
181
|
+
Active = not props.static,
|
|
182
|
+
Selectable = not props.static,
|
|
172
183
|
Event = {
|
|
173
184
|
MouseButton1Click = function()
|
|
185
|
+
if props.static then
|
|
186
|
+
return nil
|
|
187
|
+
end
|
|
174
188
|
if stateful(props.toggleStateOnClick, currentState) then
|
|
175
189
|
setState(if currentState == "deselected" then "selected" else "deselected")
|
|
176
190
|
end
|
|
@@ -182,6 +196,9 @@ local function Icon(_param)
|
|
|
182
196
|
props.playSound(soundId)
|
|
183
197
|
end,
|
|
184
198
|
MouseButton2Click = function()
|
|
199
|
+
if props.static then
|
|
200
|
+
return nil
|
|
201
|
+
end
|
|
185
202
|
if props.onRightClick == noop then
|
|
186
203
|
return nil
|
|
187
204
|
end
|
|
@@ -192,8 +209,8 @@ local function Icon(_param)
|
|
|
192
209
|
end
|
|
193
210
|
props.playSound(soundId)
|
|
194
211
|
end,
|
|
195
|
-
MouseEnter = props.hover,
|
|
196
|
-
MouseLeave = props.unhover,
|
|
212
|
+
MouseEnter = if props.static then noop else props.hover,
|
|
213
|
+
MouseLeave = if props.static then noop else props.unhover,
|
|
197
214
|
},
|
|
198
215
|
Text = "",
|
|
199
216
|
BackgroundTransparency = props.backgroundTransparency,
|
|
@@ -230,7 +247,14 @@ local function Icon(_param)
|
|
|
230
247
|
}))), React.createElement("uicorner", {
|
|
231
248
|
key = "UICorner",
|
|
232
249
|
CornerRadius = if location.type == "dropdown" then stylesheet.dropdown.iconCornerRadius else stateful(props.cornerRadius, currentState),
|
|
233
|
-
})
|
|
250
|
+
}), props.disabled and (React.createElement("frame", {
|
|
251
|
+
key = "DisabledOverlay",
|
|
252
|
+
Size = UDim2.fromScale(1, 1),
|
|
253
|
+
BackgroundTransparency = stylesheet.sizing.disabledOverlayTransparency,
|
|
254
|
+
BackgroundColor3 = stylesheet.sizing.disabledOverlayColor,
|
|
255
|
+
BorderSizePixel = 0,
|
|
256
|
+
ZIndex = 10,
|
|
257
|
+
})))))
|
|
234
258
|
end
|
|
235
259
|
return {
|
|
236
260
|
Icon = Icon,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
-- Compiled with roblox-ts
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local _react = TS.import(script, TS.getModule(script, "@rbxts", "react"))
|
|
4
4
|
local React = _react
|
|
@@ -8,6 +8,36 @@ local LocationContext = _context.LocationContext
|
|
|
8
8
|
local useStylesheet = _context.useStylesheet
|
|
9
9
|
local useGuiInset = TS.import(script, script.Parent.Parent, "hooks", "use-gui-inset").useGuiInset
|
|
10
10
|
local useVoicechatEnabled = TS.import(script, script.Parent.Parent, "hooks", "use-voicechat-enabled").useVoicechatEnabled
|
|
11
|
+
local function sortByDock(children)
|
|
12
|
+
local left = {}
|
|
13
|
+
local center = {}
|
|
14
|
+
local right = {}
|
|
15
|
+
local li = 0
|
|
16
|
+
local ci = 0
|
|
17
|
+
local ri = 0
|
|
18
|
+
React.Children.forEach(children, function(child)
|
|
19
|
+
if child == nil then
|
|
20
|
+
return nil
|
|
21
|
+
end
|
|
22
|
+
local props = child.props
|
|
23
|
+
local _dock = props
|
|
24
|
+
if _dock ~= nil then
|
|
25
|
+
_dock = _dock.dock
|
|
26
|
+
end
|
|
27
|
+
local dock = _dock
|
|
28
|
+
if dock == "Center" then
|
|
29
|
+
center[ci + 1] = child
|
|
30
|
+
ci += 1
|
|
31
|
+
elseif dock == "Right" then
|
|
32
|
+
right[ri + 1] = child
|
|
33
|
+
ri += 1
|
|
34
|
+
else
|
|
35
|
+
left[li + 1] = child
|
|
36
|
+
li += 1
|
|
37
|
+
end
|
|
38
|
+
end)
|
|
39
|
+
return { left, center, right }
|
|
40
|
+
end
|
|
11
41
|
local function TopbarProvider(_param)
|
|
12
42
|
local selectionMode = _param.selectionMode
|
|
13
43
|
if selectionMode == nil then
|
|
@@ -22,6 +52,12 @@ local function TopbarProvider(_param)
|
|
|
22
52
|
local hasBetaLabel = gameVoiceChatEnabled and voiceChatEnabled
|
|
23
53
|
local leftPadding = if hasBetaLabel then stylesheet.paddingLeft + 16 else stylesheet.paddingLeft
|
|
24
54
|
local frameHeight = inset.Height - stylesheet.insetHeightOffset
|
|
55
|
+
local _binding = sortByDock(children)
|
|
56
|
+
local leftChildren = _binding[1]
|
|
57
|
+
local centerChildren = _binding[2]
|
|
58
|
+
local rightChildren = _binding[3]
|
|
59
|
+
local hasCenter = #centerChildren > 0
|
|
60
|
+
local hasRight = #rightChildren > 0
|
|
25
61
|
return React.createElement(LocationContext.Provider, {
|
|
26
62
|
value = {
|
|
27
63
|
type = "provider",
|
|
@@ -80,12 +116,45 @@ local function TopbarProvider(_param)
|
|
|
80
116
|
PaddingRight = UDim.new(0, stylesheet.paddingRight),
|
|
81
117
|
PaddingTop = UDim.new(0, stylesheet.paddingTop),
|
|
82
118
|
PaddingBottom = UDim.new(0, stylesheet.paddingBottom),
|
|
119
|
+
}), React.createElement("frame", {
|
|
120
|
+
key = "LeftDock",
|
|
121
|
+
BackgroundTransparency = 1,
|
|
122
|
+
AnchorPoint = Vector2.new(0, 0.5),
|
|
123
|
+
Position = UDim2.new(0, 0, 0.5, 0),
|
|
124
|
+
Size = UDim2.fromScale(0, 1),
|
|
125
|
+
AutomaticSize = Enum.AutomaticSize.X,
|
|
126
|
+
}, React.createElement("uilistlayout", {
|
|
127
|
+
FillDirection = Enum.FillDirection.Horizontal,
|
|
128
|
+
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
129
|
+
Padding = UDim.new(0, stylesheet.iconSpacing),
|
|
130
|
+
}), leftChildren), hasCenter and (React.createElement("frame", {
|
|
131
|
+
key = "CenterDock",
|
|
132
|
+
BackgroundTransparency = 1,
|
|
133
|
+
AnchorPoint = Vector2.new(0.5, 0.5),
|
|
134
|
+
Position = UDim2.new(0.5, 0, 0.5, 0),
|
|
135
|
+
Size = UDim2.fromScale(0, 1),
|
|
136
|
+
AutomaticSize = Enum.AutomaticSize.X,
|
|
137
|
+
}, React.createElement("uipadding", {
|
|
138
|
+
PaddingLeft = UDim.new(0, stylesheet.iconGroupSpacing),
|
|
139
|
+
PaddingRight = UDim.new(0, stylesheet.iconGroupSpacing),
|
|
140
|
+
}), React.createElement("uilistlayout", {
|
|
141
|
+
FillDirection = Enum.FillDirection.Horizontal,
|
|
142
|
+
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
143
|
+
Padding = UDim.new(0, stylesheet.iconSpacing),
|
|
144
|
+
}), centerChildren)), hasRight and (React.createElement("frame", {
|
|
145
|
+
key = "RightDock",
|
|
146
|
+
BackgroundTransparency = 1,
|
|
147
|
+
AnchorPoint = Vector2.new(1, 0.5),
|
|
148
|
+
Position = UDim2.new(1, 0, 0.5, 0),
|
|
149
|
+
Size = UDim2.fromScale(0, 1),
|
|
150
|
+
AutomaticSize = Enum.AutomaticSize.X,
|
|
151
|
+
}, React.createElement("uipadding", {
|
|
152
|
+
PaddingLeft = UDim.new(0, stylesheet.iconGroupSpacing),
|
|
83
153
|
}), React.createElement("uilistlayout", {
|
|
84
|
-
key = "UIListLayout",
|
|
85
154
|
FillDirection = Enum.FillDirection.Horizontal,
|
|
86
155
|
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
87
156
|
Padding = UDim.new(0, stylesheet.iconSpacing),
|
|
88
|
-
}),
|
|
157
|
+
}), rightChildren))))
|
|
89
158
|
end
|
|
90
159
|
return {
|
|
91
160
|
TopbarProvider = TopbarProvider,
|
package/out/context.luau
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
-- Compiled with roblox-ts
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local Object = TS.import(script, TS.getModule(script, "@rbxts", "object-utils"))
|
|
4
4
|
local _pretty_react_hooks = TS.import(script, TS.getModule(script, "@rbxts", "pretty-react-hooks").out)
|
package/out/hooks/use-id.luau
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
-- Compiled with roblox-ts
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local useMemo = TS.import(script, TS.getModule(script, "@rbxts", "react")).useMemo
|
|
4
4
|
local createIdGenerator = TS.import(script, script.Parent.Parent, "utilities", "id-gen").createIdGenerator
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
-- Compiled with roblox-ts
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local useAsyncEffect = TS.import(script, TS.getModule(script, "@rbxts", "pretty-react-hooks").out).useAsyncEffect
|
|
4
4
|
local useState = TS.import(script, TS.getModule(script, "@rbxts", "react")).useState
|
package/out/init.luau
CHANGED
package/out/style.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface Stylesheet {
|
|
|
21
21
|
sizeScale: Vector2;
|
|
22
22
|
/** Offset subtracted from the gui inset height */
|
|
23
23
|
insetHeightOffset: number;
|
|
24
|
+
/** Extra gap between left, center, and right icon groups (default 0) */
|
|
25
|
+
iconGroupSpacing: number;
|
|
24
26
|
};
|
|
25
27
|
/**
|
|
26
28
|
* Fine-grained sizing & layout overrides for icon internals.
|
|
@@ -43,6 +45,10 @@ export interface Stylesheet {
|
|
|
43
45
|
minLabelWidthPadding: number;
|
|
44
46
|
/** Fraction of icon height used for the text button label size (default 0.8) */
|
|
45
47
|
buttonLabelHeightFraction: number;
|
|
48
|
+
/** Transparency of the dimming overlay when an icon is disabled (0 = fully visible, 1 = fully hidden) */
|
|
49
|
+
disabledOverlayTransparency: number;
|
|
50
|
+
/** Color of the dimming overlay when an icon is disabled */
|
|
51
|
+
disabledOverlayColor: Color3;
|
|
46
52
|
};
|
|
47
53
|
/**
|
|
48
54
|
* Visual theming for the dropdown surface (background, border, position).
|
package/out/style.luau
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
-- Compiled with roblox-ts
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local SoundService = TS.import(script, TS.getModule(script, "@rbxts", "services")).SoundService
|
|
4
4
|
local function defaultPlaySound(id)
|
|
@@ -48,6 +48,9 @@ local DefaultStylesheet = {
|
|
|
48
48
|
defaultState = "deselected",
|
|
49
49
|
forcedState = "deselected",
|
|
50
50
|
toggleStateOnClick = true,
|
|
51
|
+
dock = "Left",
|
|
52
|
+
static = false,
|
|
53
|
+
disabled = false,
|
|
51
54
|
selected = noop,
|
|
52
55
|
deselected = noop,
|
|
53
56
|
stateChanged = noop,
|
|
@@ -85,6 +88,7 @@ local DefaultStylesheet = {
|
|
|
85
88
|
position = UDim2.fromScale(1, 0),
|
|
86
89
|
sizeScale = Vector2.new(1, 1),
|
|
87
90
|
insetHeightOffset = 0,
|
|
91
|
+
iconGroupSpacing = 0,
|
|
88
92
|
},
|
|
89
93
|
sizing = {
|
|
90
94
|
iconHeight = nil,
|
|
@@ -94,6 +98,8 @@ local DefaultStylesheet = {
|
|
|
94
98
|
textMeasurementWidth = 99999,
|
|
95
99
|
minLabelWidthPadding = 12,
|
|
96
100
|
buttonLabelHeightFraction = 0.8,
|
|
101
|
+
disabledOverlayTransparency = 0.55,
|
|
102
|
+
disabledOverlayColor = Color3.new(0, 0, 0),
|
|
97
103
|
},
|
|
98
104
|
dropdownTheme = {
|
|
99
105
|
backgroundColor = Color3.new(1, 1, 1),
|
package/out/utilities/types.luau
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
-- Compiled with roblox-ts
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
2
|
return nil
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nrbx/topbar-components",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"main": "out/init.lua",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "rbxtsc",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"keywords": [],
|
|
11
11
|
"author": "ninjaninja140",
|
|
12
12
|
"license": "MIT",
|
|
13
|
-
"description": "@rbxts/react component package mimicking topbar-plus",
|
|
13
|
+
"description": "@rbxts/react component package mimicking topbar-plus with extra functionality, forked from @rbxts/topbar-components",
|
|
14
14
|
"types": "out/index.d.ts",
|
|
15
15
|
"files": [
|
|
16
16
|
"out",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@rbxts/compiler-types": "^3.0.0-types.0",
|
|
31
31
|
"@rbxts/react": "^17.3.7-ts.2",
|
|
32
32
|
"@rbxts/types": "^1.0.925",
|
|
33
|
-
"roblox-ts": "
|
|
33
|
+
"roblox-ts": "^3.0.0",
|
|
34
34
|
"typescript": "^6.0.3"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|