@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.
@@ -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
- local function sortByDock(children)
13
- local left = {}
14
- local center = {}
15
- local right = {}
16
- local li = 0
17
- local ci = 0
18
- local ri = 0
19
- React.Children.forEach(children, function(child)
20
- if child == nil then
21
- return nil
22
- end
23
- local childObj = child
24
- local props = childObj.props
25
- local _dockValue = props
26
- if _dockValue ~= nil then
27
- _dockValue = _dockValue.dock
28
- end
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
- debugLog(`sortByDock totals: left={#left} center={#center} right={#right}`)
43
- return { left, center, right }
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 _binding = sortByDock(children)
62
- local leftChildren = _binding[1]
63
- local centerChildren = _binding[2]
64
- local rightChildren = _binding[3]
65
- local hasCenter = #centerChildren > 0
66
- local hasRight = #rightChildren > 0
67
- return React.createElement(LocationContext.Provider, {
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 _condition = selectionMode == "Single"
87
- if _condition then
286
+ local _condition_2 = selectionMode == "Single"
287
+ if _condition_2 then
88
288
  local _iconId = iconId
89
- _condition = table.find(selectedIcons, _iconId) ~= nil
289
+ _condition_2 = table.find(selectedIcons, _iconId) ~= nil
90
290
  end
91
- if _condition then
291
+ if _condition_2 then
92
292
  return setSelectedIcons({})
93
293
  end
94
294
  return setSelectedIcons(function(icons)
95
295
  -- ▼ ReadonlyArray.filter ▼
96
- local _newValue = {}
97
- local _callback = function(T)
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 _callback(_v, _k - 1, icons) == true then
302
+ if _callback_1(_v, _k - 1, icons) == true then
103
303
  _length += 1
104
- _newValue[_length] = _v
304
+ _newValue_1[_length] = _v
105
305
  end
106
306
  end
107
307
  -- ▲ ReadonlyArray.filter ▲
108
- return _newValue
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
- }, React.createElement("uipadding", {
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nrbx/topbar-components",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "main": "out/init.lua",
5
5
  "scripts": {
6
6
  "build": "rbxtsc",