@nrbx/topbar-components 1.0.4 → 1.0.6
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/provider.d.ts +6 -1
- package/out/components/provider.luau +249 -95
- package/package.json +1 -1
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import React from '@rbxts/react';
|
|
2
|
+
import type { Dock } from './icon';
|
|
2
3
|
export type SelectionMode = 'Single' | 'Multiple';
|
|
4
|
+
interface ContainerProps extends React.PropsWithChildren {
|
|
5
|
+
dock: Dock;
|
|
6
|
+
}
|
|
7
|
+
export declare function TopBarContainer({ dock, children }: ContainerProps): React.JSX.Element;
|
|
3
8
|
interface ProviderProps extends React.PropsWithChildren {
|
|
4
9
|
selectionMode?: SelectionMode;
|
|
5
10
|
gameVoiceChatEnabled?: boolean;
|
|
6
11
|
}
|
|
7
|
-
export declare function TopbarProvider({ selectionMode, gameVoiceChatEnabled, children }: ProviderProps): React.JSX.Element;
|
|
12
|
+
export declare function TopbarProvider({ selectionMode, gameVoiceChatEnabled, children, }: ProviderProps): React.JSX.Element;
|
|
8
13
|
export {};
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local _react = TS.import(script, TS.getModule(script, "@rbxts", "react"))
|
|
4
4
|
local React = _react
|
|
5
|
+
local createContext = _react.createContext
|
|
6
|
+
local useContext = _react.useContext
|
|
7
|
+
local useEffect = _react.useEffect
|
|
8
|
+
local useMemo = _react.useMemo
|
|
5
9
|
local useState = _react.useState
|
|
6
10
|
local _context = TS.import(script, script.Parent.Parent, "context")
|
|
7
11
|
local LocationContext = _context.LocationContext
|
|
@@ -9,38 +13,135 @@ local useStylesheet = _context.useStylesheet
|
|
|
9
13
|
local useGuiInset = TS.import(script, script.Parent.Parent, "hooks", "use-gui-inset").useGuiInset
|
|
10
14
|
local useVoicechatEnabled = TS.import(script, script.Parent.Parent, "hooks", "use-voicechat-enabled").useVoicechatEnabled
|
|
11
15
|
local debugLog = TS.import(script, script.Parent.Parent, "utilities", "debug").debugLog
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
local dockValue = _dockValue
|
|
30
|
-
debugLog(`sortByDock child: hasProps={props ~= nil}`, `dock="{dockValue}"`, `→ {if dockValue == "Center" then "Center" elseif dockValue == "Right" then "Right" else "Left"}`)
|
|
31
|
-
if dockValue == "Center" then
|
|
32
|
-
center[ci + 1] = child
|
|
33
|
-
ci += 1
|
|
34
|
-
elseif dockValue == "Right" then
|
|
35
|
-
right[ri + 1] = child
|
|
36
|
-
ri += 1
|
|
37
|
-
else
|
|
38
|
-
left[li + 1] = child
|
|
39
|
-
li += 1
|
|
16
|
+
-- ── Dock registry — containers register their children by dock ──────────────
|
|
17
|
+
local DockRegistryContext = createContext(nil)
|
|
18
|
+
local function useDockRegistry()
|
|
19
|
+
return useContext(DockRegistryContext)
|
|
20
|
+
end
|
|
21
|
+
-- ── TopBarContainer ─────────────────────────────────────────────────────────
|
|
22
|
+
local function TopBarContainer(_param)
|
|
23
|
+
local dock = _param.dock
|
|
24
|
+
local children = _param.children
|
|
25
|
+
local registry = useDockRegistry()
|
|
26
|
+
local id = useMemo(function()
|
|
27
|
+
return math.random()
|
|
28
|
+
end, {})
|
|
29
|
+
useEffect(function()
|
|
30
|
+
registry:register(dock, id, children)
|
|
31
|
+
return function()
|
|
32
|
+
return registry:unregister(dock, id)
|
|
40
33
|
end
|
|
41
|
-
end)
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
end, {})
|
|
35
|
+
return React.createElement(React.Fragment)
|
|
36
|
+
end
|
|
37
|
+
-- ── Provider ────────────────────────────────────────────────────────────────
|
|
38
|
+
local function useDockNodes()
|
|
39
|
+
local leftNodes, setLeftNodes = useState({})
|
|
40
|
+
local centerNodes, setCenterNodes = useState({})
|
|
41
|
+
local rightNodes, setRightNodes = useState({})
|
|
42
|
+
local registry = useMemo(function()
|
|
43
|
+
return {
|
|
44
|
+
register = function(dock, id, element)
|
|
45
|
+
local entry = {
|
|
46
|
+
id = id,
|
|
47
|
+
element = element,
|
|
48
|
+
}
|
|
49
|
+
debugLog(`DockRegistry: register id={id} dock="{dock}"`)
|
|
50
|
+
if dock == "Center" then
|
|
51
|
+
setCenterNodes(function(prev)
|
|
52
|
+
local _array = {}
|
|
53
|
+
local _length = #_array
|
|
54
|
+
local _prevLength = #prev
|
|
55
|
+
table.move(prev, 1, _prevLength, _length + 1, _array)
|
|
56
|
+
_length += _prevLength
|
|
57
|
+
_array[_length + 1] = entry
|
|
58
|
+
return _array
|
|
59
|
+
end)
|
|
60
|
+
elseif dock == "Right" then
|
|
61
|
+
setRightNodes(function(prev)
|
|
62
|
+
local _array = {}
|
|
63
|
+
local _length = #_array
|
|
64
|
+
local _prevLength = #prev
|
|
65
|
+
table.move(prev, 1, _prevLength, _length + 1, _array)
|
|
66
|
+
_length += _prevLength
|
|
67
|
+
_array[_length + 1] = entry
|
|
68
|
+
return _array
|
|
69
|
+
end)
|
|
70
|
+
else
|
|
71
|
+
setLeftNodes(function(prev)
|
|
72
|
+
local _array = {}
|
|
73
|
+
local _length = #_array
|
|
74
|
+
local _prevLength = #prev
|
|
75
|
+
table.move(prev, 1, _prevLength, _length + 1, _array)
|
|
76
|
+
_length += _prevLength
|
|
77
|
+
_array[_length + 1] = entry
|
|
78
|
+
return _array
|
|
79
|
+
end)
|
|
80
|
+
end
|
|
81
|
+
end,
|
|
82
|
+
unregister = function(dock, id)
|
|
83
|
+
debugLog(`DockRegistry: unregister id={id} dock="{dock}"`)
|
|
84
|
+
if dock == "Center" then
|
|
85
|
+
setCenterNodes(function(prev)
|
|
86
|
+
-- ▼ ReadonlyArray.filter ▼
|
|
87
|
+
local _newValue = {}
|
|
88
|
+
local _callback = function(e)
|
|
89
|
+
return e.id ~= id
|
|
90
|
+
end
|
|
91
|
+
local _length = 0
|
|
92
|
+
for _k, _v in prev do
|
|
93
|
+
if _callback(_v, _k - 1, prev) == true then
|
|
94
|
+
_length += 1
|
|
95
|
+
_newValue[_length] = _v
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
-- ▲ ReadonlyArray.filter ▲
|
|
99
|
+
return _newValue
|
|
100
|
+
end)
|
|
101
|
+
elseif dock == "Right" then
|
|
102
|
+
setRightNodes(function(prev)
|
|
103
|
+
-- ▼ ReadonlyArray.filter ▼
|
|
104
|
+
local _newValue = {}
|
|
105
|
+
local _callback = function(e)
|
|
106
|
+
return e.id ~= id
|
|
107
|
+
end
|
|
108
|
+
local _length = 0
|
|
109
|
+
for _k, _v in prev do
|
|
110
|
+
if _callback(_v, _k - 1, prev) == true then
|
|
111
|
+
_length += 1
|
|
112
|
+
_newValue[_length] = _v
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
-- ▲ ReadonlyArray.filter ▲
|
|
116
|
+
return _newValue
|
|
117
|
+
end)
|
|
118
|
+
else
|
|
119
|
+
setLeftNodes(function(prev)
|
|
120
|
+
-- ▼ ReadonlyArray.filter ▼
|
|
121
|
+
local _newValue = {}
|
|
122
|
+
local _callback = function(e)
|
|
123
|
+
return e.id ~= id
|
|
124
|
+
end
|
|
125
|
+
local _length = 0
|
|
126
|
+
for _k, _v in prev do
|
|
127
|
+
if _callback(_v, _k - 1, prev) == true then
|
|
128
|
+
_length += 1
|
|
129
|
+
_newValue[_length] = _v
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
-- ▲ ReadonlyArray.filter ▲
|
|
133
|
+
return _newValue
|
|
134
|
+
end)
|
|
135
|
+
end
|
|
136
|
+
end,
|
|
137
|
+
}
|
|
138
|
+
end, {})
|
|
139
|
+
return {
|
|
140
|
+
registry = registry,
|
|
141
|
+
leftNodes = leftNodes,
|
|
142
|
+
centerNodes = centerNodes,
|
|
143
|
+
rightNodes = rightNodes,
|
|
144
|
+
}
|
|
44
145
|
end
|
|
45
146
|
local function TopbarProvider(_param)
|
|
46
147
|
local selectionMode = _param.selectionMode
|
|
@@ -53,18 +154,117 @@ local function TopbarProvider(_param)
|
|
|
53
154
|
local inset = useGuiInset()
|
|
54
155
|
local voiceChatEnabled = useVoicechatEnabled()
|
|
55
156
|
local stylesheet = useStylesheet().provider
|
|
157
|
+
local _binding = useDockNodes()
|
|
158
|
+
local registry = _binding.registry
|
|
159
|
+
local leftNodes = _binding.leftNodes
|
|
160
|
+
local centerNodes = _binding.centerNodes
|
|
161
|
+
local rightNodes = _binding.rightNodes
|
|
56
162
|
local hasBetaLabel = gameVoiceChatEnabled and voiceChatEnabled
|
|
57
163
|
local leftPadding = if hasBetaLabel then stylesheet.paddingLeft + 16 else stylesheet.paddingLeft
|
|
58
164
|
local rawHeight = inset.Height - stylesheet.insetHeightOffset
|
|
59
165
|
local frameHeight = if stylesheet.forceFrameHeight ~= nil then stylesheet.forceFrameHeight else rawHeight
|
|
60
166
|
debugLog(`TopbarProvider frame: inset.Height={inset.Height}, inset.Width={inset.Width}`, `insetHeightOffset={stylesheet.insetHeightOffset}`, `rawHeight={rawHeight}`, `forceFrameHeight={stylesheet.forceFrameHeight}`, `finalHeight={frameHeight}`, `sizeScale=({stylesheet.sizeScale.X}, {stylesheet.sizeScale.Y})`)
|
|
61
|
-
local
|
|
62
|
-
local
|
|
63
|
-
local
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
167
|
+
local hasCenter = #centerNodes > 0
|
|
168
|
+
local hasRight = #rightNodes > 0
|
|
169
|
+
local _exp = React.createElement("uipadding", {
|
|
170
|
+
key = "UIPadding",
|
|
171
|
+
PaddingLeft = UDim.new(0, leftPadding),
|
|
172
|
+
PaddingRight = UDim.new(0, stylesheet.paddingRight),
|
|
173
|
+
PaddingTop = UDim.new(0, stylesheet.paddingTop),
|
|
174
|
+
PaddingBottom = UDim.new(0, stylesheet.paddingBottom),
|
|
175
|
+
})
|
|
176
|
+
local _exp_1 = React.createElement("uilistlayout", {
|
|
177
|
+
FillDirection = Enum.FillDirection.Horizontal,
|
|
178
|
+
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
179
|
+
Padding = UDim.new(0, stylesheet.iconSpacing),
|
|
180
|
+
VerticalAlignment = Enum.VerticalAlignment.Center,
|
|
181
|
+
})
|
|
182
|
+
local _exp_2 = children
|
|
183
|
+
-- ▼ ReadonlyArray.map ▼
|
|
184
|
+
local _newValue = table.create(#leftNodes)
|
|
185
|
+
local _callback = function(entry)
|
|
186
|
+
return React.createElement(React.Fragment, {
|
|
187
|
+
key = entry.id,
|
|
188
|
+
}, entry.element)
|
|
189
|
+
end
|
|
190
|
+
for _k, _v in leftNodes do
|
|
191
|
+
_newValue[_k] = _callback(_v, _k - 1, leftNodes)
|
|
192
|
+
end
|
|
193
|
+
-- ▲ ReadonlyArray.map ▲
|
|
194
|
+
local _exp_3 = React.createElement("frame", {
|
|
195
|
+
key = "LeftDock",
|
|
196
|
+
BackgroundTransparency = 1,
|
|
197
|
+
AnchorPoint = Vector2.new(0, 0.5),
|
|
198
|
+
Position = UDim2.new(0, 0, 0.5, 0),
|
|
199
|
+
Size = UDim2.fromScale(0, 1),
|
|
200
|
+
AutomaticSize = Enum.AutomaticSize.X,
|
|
201
|
+
}, _exp_1, _exp_2, _newValue)
|
|
202
|
+
local _condition = hasCenter
|
|
203
|
+
if _condition then
|
|
204
|
+
local _exp_4 = React.createElement("uipadding", {
|
|
205
|
+
PaddingLeft = UDim.new(0, stylesheet.iconGroupSpacing),
|
|
206
|
+
PaddingRight = UDim.new(0, stylesheet.iconGroupSpacing),
|
|
207
|
+
})
|
|
208
|
+
local _exp_5 = React.createElement("uilistlayout", {
|
|
209
|
+
FillDirection = Enum.FillDirection.Horizontal,
|
|
210
|
+
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
211
|
+
Padding = UDim.new(0, stylesheet.iconSpacing),
|
|
212
|
+
VerticalAlignment = Enum.VerticalAlignment.Center,
|
|
213
|
+
})
|
|
214
|
+
-- ▼ ReadonlyArray.map ▼
|
|
215
|
+
local _newValue_1 = table.create(#centerNodes)
|
|
216
|
+
local _callback_1 = function(entry)
|
|
217
|
+
return React.createElement(React.Fragment, {
|
|
218
|
+
key = entry.id,
|
|
219
|
+
}, entry.element)
|
|
220
|
+
end
|
|
221
|
+
for _k, _v in centerNodes do
|
|
222
|
+
_newValue_1[_k] = _callback_1(_v, _k - 1, centerNodes)
|
|
223
|
+
end
|
|
224
|
+
-- ▲ ReadonlyArray.map ▲
|
|
225
|
+
_condition = (React.createElement("frame", {
|
|
226
|
+
key = "CenterDock",
|
|
227
|
+
BackgroundTransparency = 1,
|
|
228
|
+
AnchorPoint = Vector2.new(0.5, 0.5),
|
|
229
|
+
Position = UDim2.new(0.5, 0, 0.5, 0),
|
|
230
|
+
Size = UDim2.fromScale(0, 1),
|
|
231
|
+
AutomaticSize = Enum.AutomaticSize.X,
|
|
232
|
+
}, _exp_4, _exp_5, _newValue_1))
|
|
233
|
+
end
|
|
234
|
+
local _condition_1 = hasRight
|
|
235
|
+
if _condition_1 then
|
|
236
|
+
local _exp_4 = React.createElement("uipadding", {
|
|
237
|
+
PaddingLeft = UDim.new(0, stylesheet.iconGroupSpacing),
|
|
238
|
+
})
|
|
239
|
+
local _exp_5 = React.createElement("uilistlayout", {
|
|
240
|
+
FillDirection = Enum.FillDirection.Horizontal,
|
|
241
|
+
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
242
|
+
Padding = UDim.new(0, stylesheet.iconSpacing),
|
|
243
|
+
VerticalAlignment = Enum.VerticalAlignment.Center,
|
|
244
|
+
})
|
|
245
|
+
-- ▼ ReadonlyArray.map ▼
|
|
246
|
+
local _newValue_1 = table.create(#rightNodes)
|
|
247
|
+
local _callback_1 = function(entry)
|
|
248
|
+
return React.createElement(React.Fragment, {
|
|
249
|
+
key = entry.id,
|
|
250
|
+
}, entry.element)
|
|
251
|
+
end
|
|
252
|
+
for _k, _v in rightNodes do
|
|
253
|
+
_newValue_1[_k] = _callback_1(_v, _k - 1, rightNodes)
|
|
254
|
+
end
|
|
255
|
+
-- ▲ ReadonlyArray.map ▲
|
|
256
|
+
_condition_1 = (React.createElement("frame", {
|
|
257
|
+
key = "RightDock",
|
|
258
|
+
BackgroundTransparency = 1,
|
|
259
|
+
AnchorPoint = Vector2.new(1, 0.5),
|
|
260
|
+
Position = UDim2.new(1, 0, 0.5, 0),
|
|
261
|
+
Size = UDim2.fromScale(0, 1),
|
|
262
|
+
AutomaticSize = Enum.AutomaticSize.X,
|
|
263
|
+
}, _exp_4, _exp_5, _newValue_1))
|
|
264
|
+
end
|
|
265
|
+
return React.createElement(DockRegistryContext.Provider, {
|
|
266
|
+
value = registry,
|
|
267
|
+
}, React.createElement(LocationContext.Provider, {
|
|
68
268
|
value = {
|
|
69
269
|
type = "provider",
|
|
70
270
|
selectedIcons = selectedIcons,
|
|
@@ -83,29 +283,29 @@ local function TopbarProvider(_param)
|
|
|
83
283
|
end)
|
|
84
284
|
end,
|
|
85
285
|
iconDeselected = function(iconId)
|
|
86
|
-
local
|
|
87
|
-
if
|
|
286
|
+
local _condition_2 = selectionMode == "Single"
|
|
287
|
+
if _condition_2 then
|
|
88
288
|
local _iconId = iconId
|
|
89
|
-
|
|
289
|
+
_condition_2 = table.find(selectedIcons, _iconId) ~= nil
|
|
90
290
|
end
|
|
91
|
-
if
|
|
291
|
+
if _condition_2 then
|
|
92
292
|
return setSelectedIcons({})
|
|
93
293
|
end
|
|
94
294
|
return setSelectedIcons(function(icons)
|
|
95
295
|
-- ▼ ReadonlyArray.filter ▼
|
|
96
|
-
local
|
|
97
|
-
local
|
|
296
|
+
local _newValue_1 = {}
|
|
297
|
+
local _callback_1 = function(T)
|
|
98
298
|
return T ~= iconId
|
|
99
299
|
end
|
|
100
300
|
local _length = 0
|
|
101
301
|
for _k, _v in icons do
|
|
102
|
-
if
|
|
302
|
+
if _callback_1(_v, _k - 1, icons) == true then
|
|
103
303
|
_length += 1
|
|
104
|
-
|
|
304
|
+
_newValue_1[_length] = _v
|
|
105
305
|
end
|
|
106
306
|
end
|
|
107
307
|
-- ▲ ReadonlyArray.filter ▲
|
|
108
|
-
return
|
|
308
|
+
return _newValue_1
|
|
109
309
|
end)
|
|
110
310
|
end,
|
|
111
311
|
},
|
|
@@ -116,55 +316,9 @@ local function TopbarProvider(_param)
|
|
|
116
316
|
Size = UDim2.fromOffset(inset.Width * stylesheet.sizeScale.X, frameHeight * stylesheet.sizeScale.Y),
|
|
117
317
|
AnchorPoint = stylesheet.anchorPoint,
|
|
118
318
|
Position = stylesheet.position,
|
|
119
|
-
},
|
|
120
|
-
key = "UIPadding",
|
|
121
|
-
PaddingLeft = UDim.new(0, leftPadding),
|
|
122
|
-
PaddingRight = UDim.new(0, stylesheet.paddingRight),
|
|
123
|
-
PaddingTop = UDim.new(0, stylesheet.paddingTop),
|
|
124
|
-
PaddingBottom = UDim.new(0, stylesheet.paddingBottom),
|
|
125
|
-
}), React.createElement("frame", {
|
|
126
|
-
key = "LeftDock",
|
|
127
|
-
BackgroundTransparency = 1,
|
|
128
|
-
AnchorPoint = Vector2.new(0, 0.5),
|
|
129
|
-
Position = UDim2.new(0, 0, 0.5, 0),
|
|
130
|
-
Size = UDim2.fromScale(0, 1),
|
|
131
|
-
AutomaticSize = Enum.AutomaticSize.X,
|
|
132
|
-
}, React.createElement("uilistlayout", {
|
|
133
|
-
FillDirection = Enum.FillDirection.Horizontal,
|
|
134
|
-
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
135
|
-
Padding = UDim.new(0, stylesheet.iconSpacing),
|
|
136
|
-
VerticalAlignment = Enum.VerticalAlignment.Center,
|
|
137
|
-
}), leftChildren), hasCenter and (React.createElement("frame", {
|
|
138
|
-
key = "CenterDock",
|
|
139
|
-
BackgroundTransparency = 1,
|
|
140
|
-
AnchorPoint = Vector2.new(0.5, 0.5),
|
|
141
|
-
Position = UDim2.new(0.5, 0, 0.5, 0),
|
|
142
|
-
Size = UDim2.fromScale(0, 1),
|
|
143
|
-
AutomaticSize = Enum.AutomaticSize.X,
|
|
144
|
-
}, React.createElement("uipadding", {
|
|
145
|
-
PaddingLeft = UDim.new(0, stylesheet.iconGroupSpacing),
|
|
146
|
-
PaddingRight = UDim.new(0, stylesheet.iconGroupSpacing),
|
|
147
|
-
}), React.createElement("uilistlayout", {
|
|
148
|
-
FillDirection = Enum.FillDirection.Horizontal,
|
|
149
|
-
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
150
|
-
Padding = UDim.new(0, stylesheet.iconSpacing),
|
|
151
|
-
VerticalAlignment = Enum.VerticalAlignment.Center,
|
|
152
|
-
}), centerChildren)), hasRight and (React.createElement("frame", {
|
|
153
|
-
key = "RightDock",
|
|
154
|
-
BackgroundTransparency = 1,
|
|
155
|
-
AnchorPoint = Vector2.new(1, 0.5),
|
|
156
|
-
Position = UDim2.new(1, 0, 0.5, 0),
|
|
157
|
-
Size = UDim2.fromScale(0, 1),
|
|
158
|
-
AutomaticSize = Enum.AutomaticSize.X,
|
|
159
|
-
}, React.createElement("uipadding", {
|
|
160
|
-
PaddingLeft = UDim.new(0, stylesheet.iconGroupSpacing),
|
|
161
|
-
}), React.createElement("uilistlayout", {
|
|
162
|
-
FillDirection = Enum.FillDirection.Horizontal,
|
|
163
|
-
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
164
|
-
Padding = UDim.new(0, stylesheet.iconSpacing),
|
|
165
|
-
VerticalAlignment = Enum.VerticalAlignment.Center,
|
|
166
|
-
}), rightChildren))))
|
|
319
|
+
}, _exp, _exp_3, _condition, _condition_1)))
|
|
167
320
|
end
|
|
168
321
|
return {
|
|
322
|
+
TopBarContainer = TopBarContainer,
|
|
169
323
|
TopbarProvider = TopbarProvider,
|
|
170
324
|
}
|