@nrbx/topbar-components 1.0.5 → 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,48 +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
- local _exp = `sortByDock child: hasProps={props ~= nil}`
31
- local _result = props
32
- if _result ~= nil then
33
- _result = _result.text
34
- end
35
- local _exp_1 = `text={_result}`
36
- local _result_1 = props
37
- if _result_1 ~= nil then
38
- _result_1 = _result_1.static
39
- end
40
- debugLog(_exp, _exp_1, `static={_result_1}`, `dock="{dockValue}"`, `→ {if dockValue == "Center" then "Center" elseif dockValue == "Right" then "Right" else "Left"}`)
41
- if dockValue == "Center" then
42
- center[ci + 1] = child
43
- ci += 1
44
- elseif dockValue == "Right" then
45
- right[ri + 1] = child
46
- ri += 1
47
- else
48
- left[li + 1] = child
49
- 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)
50
33
  end
51
- end)
52
- debugLog(`sortByDock totals: left={#left} center={#center} right={#right}`)
53
- 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
+ }
54
145
  end
55
146
  local function TopbarProvider(_param)
56
147
  local selectionMode = _param.selectionMode
@@ -63,18 +154,117 @@ local function TopbarProvider(_param)
63
154
  local inset = useGuiInset()
64
155
  local voiceChatEnabled = useVoicechatEnabled()
65
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
66
162
  local hasBetaLabel = gameVoiceChatEnabled and voiceChatEnabled
67
163
  local leftPadding = if hasBetaLabel then stylesheet.paddingLeft + 16 else stylesheet.paddingLeft
68
164
  local rawHeight = inset.Height - stylesheet.insetHeightOffset
69
165
  local frameHeight = if stylesheet.forceFrameHeight ~= nil then stylesheet.forceFrameHeight else rawHeight
70
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})`)
71
- local _binding = sortByDock(children)
72
- local leftChildren = _binding[1]
73
- local centerChildren = _binding[2]
74
- local rightChildren = _binding[3]
75
- local hasCenter = #centerChildren > 0
76
- local hasRight = #rightChildren > 0
77
- 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, {
78
268
  value = {
79
269
  type = "provider",
80
270
  selectedIcons = selectedIcons,
@@ -93,29 +283,29 @@ local function TopbarProvider(_param)
93
283
  end)
94
284
  end,
95
285
  iconDeselected = function(iconId)
96
- local _condition = selectionMode == "Single"
97
- if _condition then
286
+ local _condition_2 = selectionMode == "Single"
287
+ if _condition_2 then
98
288
  local _iconId = iconId
99
- _condition = table.find(selectedIcons, _iconId) ~= nil
289
+ _condition_2 = table.find(selectedIcons, _iconId) ~= nil
100
290
  end
101
- if _condition then
291
+ if _condition_2 then
102
292
  return setSelectedIcons({})
103
293
  end
104
294
  return setSelectedIcons(function(icons)
105
295
  -- ▼ ReadonlyArray.filter ▼
106
- local _newValue = {}
107
- local _callback = function(T)
296
+ local _newValue_1 = {}
297
+ local _callback_1 = function(T)
108
298
  return T ~= iconId
109
299
  end
110
300
  local _length = 0
111
301
  for _k, _v in icons do
112
- if _callback(_v, _k - 1, icons) == true then
302
+ if _callback_1(_v, _k - 1, icons) == true then
113
303
  _length += 1
114
- _newValue[_length] = _v
304
+ _newValue_1[_length] = _v
115
305
  end
116
306
  end
117
307
  -- ▲ ReadonlyArray.filter ▲
118
- return _newValue
308
+ return _newValue_1
119
309
  end)
120
310
  end,
121
311
  },
@@ -126,55 +316,9 @@ local function TopbarProvider(_param)
126
316
  Size = UDim2.fromOffset(inset.Width * stylesheet.sizeScale.X, frameHeight * stylesheet.sizeScale.Y),
127
317
  AnchorPoint = stylesheet.anchorPoint,
128
318
  Position = stylesheet.position,
129
- }, React.createElement("uipadding", {
130
- key = "UIPadding",
131
- PaddingLeft = UDim.new(0, leftPadding),
132
- PaddingRight = UDim.new(0, stylesheet.paddingRight),
133
- PaddingTop = UDim.new(0, stylesheet.paddingTop),
134
- PaddingBottom = UDim.new(0, stylesheet.paddingBottom),
135
- }), React.createElement("frame", {
136
- key = "LeftDock",
137
- BackgroundTransparency = 1,
138
- AnchorPoint = Vector2.new(0, 0.5),
139
- Position = UDim2.new(0, 0, 0.5, 0),
140
- Size = UDim2.fromScale(0, 1),
141
- AutomaticSize = Enum.AutomaticSize.X,
142
- }, React.createElement("uilistlayout", {
143
- FillDirection = Enum.FillDirection.Horizontal,
144
- SortOrder = Enum.SortOrder.LayoutOrder,
145
- Padding = UDim.new(0, stylesheet.iconSpacing),
146
- VerticalAlignment = Enum.VerticalAlignment.Center,
147
- }), leftChildren), hasCenter and (React.createElement("frame", {
148
- key = "CenterDock",
149
- BackgroundTransparency = 1,
150
- AnchorPoint = Vector2.new(0.5, 0.5),
151
- Position = UDim2.new(0.5, 0, 0.5, 0),
152
- Size = UDim2.fromScale(0, 1),
153
- AutomaticSize = Enum.AutomaticSize.X,
154
- }, React.createElement("uipadding", {
155
- PaddingLeft = UDim.new(0, stylesheet.iconGroupSpacing),
156
- PaddingRight = UDim.new(0, stylesheet.iconGroupSpacing),
157
- }), React.createElement("uilistlayout", {
158
- FillDirection = Enum.FillDirection.Horizontal,
159
- SortOrder = Enum.SortOrder.LayoutOrder,
160
- Padding = UDim.new(0, stylesheet.iconSpacing),
161
- VerticalAlignment = Enum.VerticalAlignment.Center,
162
- }), centerChildren)), hasRight and (React.createElement("frame", {
163
- key = "RightDock",
164
- BackgroundTransparency = 1,
165
- AnchorPoint = Vector2.new(1, 0.5),
166
- Position = UDim2.new(1, 0, 0.5, 0),
167
- Size = UDim2.fromScale(0, 1),
168
- AutomaticSize = Enum.AutomaticSize.X,
169
- }, React.createElement("uipadding", {
170
- PaddingLeft = UDim.new(0, stylesheet.iconGroupSpacing),
171
- }), React.createElement("uilistlayout", {
172
- FillDirection = Enum.FillDirection.Horizontal,
173
- SortOrder = Enum.SortOrder.LayoutOrder,
174
- Padding = UDim.new(0, stylesheet.iconSpacing),
175
- VerticalAlignment = Enum.VerticalAlignment.Center,
176
- }), rightChildren))))
319
+ }, _exp, _exp_3, _condition, _condition_1)))
177
320
  end
178
321
  return {
322
+ TopBarContainer = TopBarContainer,
179
323
  TopbarProvider = TopbarProvider,
180
324
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nrbx/topbar-components",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "main": "out/init.lua",
5
5
  "scripts": {
6
6
  "build": "rbxtsc",