@lattice-ui/select 0.3.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/README.md +23 -0
- package/out/Select/SelectContent.d.ts +3 -0
- package/out/Select/SelectContent.luau +268 -0
- package/out/Select/SelectGroup.d.ts +3 -0
- package/out/Select/SelectGroup.luau +22 -0
- package/out/Select/SelectItem.d.ts +3 -0
- package/out/Select/SelectItem.luau +124 -0
- package/out/Select/SelectLabel.d.ts +3 -0
- package/out/Select/SelectLabel.luau +26 -0
- package/out/Select/SelectPortal.d.ts +3 -0
- package/out/Select/SelectPortal.luau +33 -0
- package/out/Select/SelectRoot.d.ts +3 -0
- package/out/Select/SelectRoot.luau +201 -0
- package/out/Select/SelectSeparator.d.ts +3 -0
- package/out/Select/SelectSeparator.luau +22 -0
- package/out/Select/SelectTrigger.d.ts +3 -0
- package/out/Select/SelectTrigger.luau +72 -0
- package/out/Select/SelectValue.d.ts +3 -0
- package/out/Select/SelectValue.luau +47 -0
- package/out/Select/context.d.ts +3 -0
- package/out/Select/context.luau +10 -0
- package/out/Select/types.d.ts +84 -0
- package/out/Select/types.luau +2 -0
- package/out/index.d.ts +22 -0
- package/out/init.luau +34 -0
- package/package.json +26 -0
- package/src/Select/SelectContent.tsx +297 -0
- package/src/Select/SelectGroup.tsx +19 -0
- package/src/Select/SelectItem.tsx +132 -0
- package/src/Select/SelectLabel.tsx +27 -0
- package/src/Select/SelectPortal.tsx +28 -0
- package/src/Select/SelectRoot.tsx +124 -0
- package/src/Select/SelectSeparator.tsx +19 -0
- package/src/Select/SelectTrigger.tsx +89 -0
- package/src/Select/SelectValue.tsx +42 -0
- package/src/Select/context.ts +6 -0
- package/src/Select/types.ts +96 -0
- package/src/index.ts +59 -0
- package/tsconfig.json +16 -0
- package/tsconfig.typecheck.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# @lattice-ui/select
|
|
2
|
+
|
|
3
|
+
Headless single-select primitives built for Roblox UI.
|
|
4
|
+
|
|
5
|
+
## Exports
|
|
6
|
+
|
|
7
|
+
- `Select`
|
|
8
|
+
- `Select.Root`
|
|
9
|
+
- `Select.Trigger`
|
|
10
|
+
- `Select.Value`
|
|
11
|
+
- `Select.Portal`
|
|
12
|
+
- `Select.Content`
|
|
13
|
+
- `Select.Item`
|
|
14
|
+
- `Select.Group`
|
|
15
|
+
- `Select.Label`
|
|
16
|
+
- `Select.Separator`
|
|
17
|
+
|
|
18
|
+
## Notes
|
|
19
|
+
|
|
20
|
+
- Single value only in this release.
|
|
21
|
+
- Supports controlled/uncontrolled `value` and `open`.
|
|
22
|
+
- Content uses dismissable-layer semantics (outside pointer / escape dismiss).
|
|
23
|
+
- Item navigation uses roving focus and includes typeahead matching.
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _core = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out)
|
|
4
|
+
local React = _core.React
|
|
5
|
+
local Slot = _core.Slot
|
|
6
|
+
local RovingFocusGroup = TS.import(script, TS.getModule(script, "@lattice-ui", "focus").out).RovingFocusGroup
|
|
7
|
+
local _layer = TS.import(script, TS.getModule(script, "@lattice-ui", "layer").out)
|
|
8
|
+
local DismissableLayer = _layer.DismissableLayer
|
|
9
|
+
local Presence = _layer.Presence
|
|
10
|
+
local usePopper = TS.import(script, TS.getModule(script, "@lattice-ui", "popper").out).usePopper
|
|
11
|
+
local useSelectContext = TS.import(script, script.Parent, "context").useSelectContext
|
|
12
|
+
local GuiService = game:GetService("GuiService")
|
|
13
|
+
local UserInputService = game:GetService("UserInputService")
|
|
14
|
+
local digitKeyMap = {
|
|
15
|
+
Zero = "0",
|
|
16
|
+
One = "1",
|
|
17
|
+
Two = "2",
|
|
18
|
+
Three = "3",
|
|
19
|
+
Four = "4",
|
|
20
|
+
Five = "5",
|
|
21
|
+
Six = "6",
|
|
22
|
+
Seven = "7",
|
|
23
|
+
Eight = "8",
|
|
24
|
+
Nine = "9",
|
|
25
|
+
}
|
|
26
|
+
local function toGuiObject(instance)
|
|
27
|
+
if not instance or not instance:IsA("GuiObject") then
|
|
28
|
+
return nil
|
|
29
|
+
end
|
|
30
|
+
return instance
|
|
31
|
+
end
|
|
32
|
+
local function toSearchCharacter(keyCode)
|
|
33
|
+
if keyCode == Enum.KeyCode.Space then
|
|
34
|
+
return " "
|
|
35
|
+
end
|
|
36
|
+
local digitCharacter = digitKeyMap[keyCode.Name]
|
|
37
|
+
if digitCharacter ~= nil then
|
|
38
|
+
return digitCharacter
|
|
39
|
+
end
|
|
40
|
+
if #keyCode.Name == 1 then
|
|
41
|
+
return string.lower(keyCode.Name)
|
|
42
|
+
end
|
|
43
|
+
return nil
|
|
44
|
+
end
|
|
45
|
+
local function startsWithIgnoreCase(value, query)
|
|
46
|
+
if #query == 0 then
|
|
47
|
+
return false
|
|
48
|
+
end
|
|
49
|
+
local normalizedValue = string.lower(value)
|
|
50
|
+
return string.sub(normalizedValue, 1, #query) == query
|
|
51
|
+
end
|
|
52
|
+
local function findCurrentIndex(items, selectedObject)
|
|
53
|
+
if not selectedObject then
|
|
54
|
+
return -1
|
|
55
|
+
end
|
|
56
|
+
-- ▼ ReadonlyArray.findIndex ▼
|
|
57
|
+
local _callback = function(item)
|
|
58
|
+
local node = item.getNode()
|
|
59
|
+
if not node then
|
|
60
|
+
return false
|
|
61
|
+
end
|
|
62
|
+
return selectedObject == node or selectedObject:IsDescendantOf(node)
|
|
63
|
+
end
|
|
64
|
+
local _result = -1
|
|
65
|
+
for _i, _v in items do
|
|
66
|
+
if _callback(_v, _i - 1, items) == true then
|
|
67
|
+
_result = _i - 1
|
|
68
|
+
break
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
-- ▲ ReadonlyArray.findIndex ▲
|
|
72
|
+
return _result
|
|
73
|
+
end
|
|
74
|
+
local function findTypeaheadMatch(items, query, startIndex)
|
|
75
|
+
local itemCount = #items
|
|
76
|
+
if itemCount == 0 then
|
|
77
|
+
return -1
|
|
78
|
+
end
|
|
79
|
+
do
|
|
80
|
+
local attempts = 0
|
|
81
|
+
local _shouldIncrement = false
|
|
82
|
+
while true do
|
|
83
|
+
if _shouldIncrement then
|
|
84
|
+
attempts += 1
|
|
85
|
+
else
|
|
86
|
+
_shouldIncrement = true
|
|
87
|
+
end
|
|
88
|
+
if not (attempts < itemCount) then
|
|
89
|
+
break
|
|
90
|
+
end
|
|
91
|
+
local candidateIndex = (startIndex + attempts) % itemCount
|
|
92
|
+
local candidate = items[candidateIndex + 1]
|
|
93
|
+
if not candidate or candidate.getDisabled() then
|
|
94
|
+
continue
|
|
95
|
+
end
|
|
96
|
+
if startsWithIgnoreCase(candidate.getTextValue(), query) then
|
|
97
|
+
return candidateIndex
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
return -1
|
|
102
|
+
end
|
|
103
|
+
local function focusItem(item)
|
|
104
|
+
if not item then
|
|
105
|
+
return nil
|
|
106
|
+
end
|
|
107
|
+
local node = item.getNode()
|
|
108
|
+
if not node or not node.Selectable then
|
|
109
|
+
return nil
|
|
110
|
+
end
|
|
111
|
+
GuiService.SelectedObject = node
|
|
112
|
+
end
|
|
113
|
+
local function SelectContentImpl(props)
|
|
114
|
+
local selectContext = useSelectContext()
|
|
115
|
+
local popper = usePopper({
|
|
116
|
+
anchorRef = selectContext.triggerRef,
|
|
117
|
+
contentRef = selectContext.contentRef,
|
|
118
|
+
placement = props.placement,
|
|
119
|
+
offset = props.offset,
|
|
120
|
+
padding = props.padding,
|
|
121
|
+
enabled = props.enabled,
|
|
122
|
+
})
|
|
123
|
+
local setContentRef = React.useCallback(function(instance)
|
|
124
|
+
selectContext.contentRef.current = toGuiObject(instance)
|
|
125
|
+
end, { selectContext.contentRef })
|
|
126
|
+
local searchRef = React.useRef("")
|
|
127
|
+
local searchTimestampRef = React.useRef(0)
|
|
128
|
+
React.useEffect(function()
|
|
129
|
+
if not props.enabled then
|
|
130
|
+
return nil
|
|
131
|
+
end
|
|
132
|
+
local orderedItems = selectContext.getOrderedItems()
|
|
133
|
+
-- ▼ ReadonlyArray.find ▼
|
|
134
|
+
local _callback = function(item)
|
|
135
|
+
return item.value == selectContext.value and not item.getDisabled()
|
|
136
|
+
end
|
|
137
|
+
local _result
|
|
138
|
+
for _i, _v in orderedItems do
|
|
139
|
+
if _callback(_v, _i - 1, orderedItems) == true then
|
|
140
|
+
_result = _v
|
|
141
|
+
break
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
-- ▲ ReadonlyArray.find ▲
|
|
145
|
+
local selectedItem = _result
|
|
146
|
+
focusItem(selectedItem)
|
|
147
|
+
end, { props.enabled, selectContext, selectContext.value })
|
|
148
|
+
React.useEffect(function()
|
|
149
|
+
if not props.enabled then
|
|
150
|
+
return nil
|
|
151
|
+
end
|
|
152
|
+
searchRef.current = ""
|
|
153
|
+
searchTimestampRef.current = 0
|
|
154
|
+
local connection = UserInputService.InputBegan:Connect(function(inputObject, gameProcessedEvent)
|
|
155
|
+
if gameProcessedEvent then
|
|
156
|
+
return nil
|
|
157
|
+
end
|
|
158
|
+
if inputObject.UserInputType ~= Enum.UserInputType.Keyboard then
|
|
159
|
+
return nil
|
|
160
|
+
end
|
|
161
|
+
local contentNode = selectContext.contentRef.current
|
|
162
|
+
local selectedObject = GuiService.SelectedObject
|
|
163
|
+
if not contentNode or not selectedObject or not selectedObject:IsDescendantOf(contentNode) then
|
|
164
|
+
return nil
|
|
165
|
+
end
|
|
166
|
+
local searchCharacter = toSearchCharacter(inputObject.KeyCode)
|
|
167
|
+
if searchCharacter == nil then
|
|
168
|
+
return nil
|
|
169
|
+
end
|
|
170
|
+
local now = os.clock()
|
|
171
|
+
local shouldResetQuery = now - searchTimestampRef.current > 0.8
|
|
172
|
+
local nextQuery = if shouldResetQuery then searchCharacter else `{searchRef.current}{searchCharacter}`
|
|
173
|
+
searchRef.current = nextQuery
|
|
174
|
+
searchTimestampRef.current = now
|
|
175
|
+
local orderedItems = selectContext.getOrderedItems()
|
|
176
|
+
local currentIndex = findCurrentIndex(orderedItems, selectedObject)
|
|
177
|
+
local startIndex = if currentIndex >= 0 then currentIndex + 1 else 0
|
|
178
|
+
local matchIndex = findTypeaheadMatch(orderedItems, string.lower(nextQuery), startIndex)
|
|
179
|
+
if matchIndex < 0 then
|
|
180
|
+
return nil
|
|
181
|
+
end
|
|
182
|
+
local matchedItem = orderedItems[matchIndex + 1]
|
|
183
|
+
focusItem(matchedItem)
|
|
184
|
+
end)
|
|
185
|
+
return function()
|
|
186
|
+
connection:Disconnect()
|
|
187
|
+
end
|
|
188
|
+
end, { props.enabled, selectContext })
|
|
189
|
+
local contentNode = if props.asChild then ((function()
|
|
190
|
+
local child = props.children
|
|
191
|
+
if not React.isValidElement(child) then
|
|
192
|
+
error("[SelectContent] `asChild` requires a child element.")
|
|
193
|
+
end
|
|
194
|
+
return React.createElement(Slot, {
|
|
195
|
+
AnchorPoint = popper.anchorPoint,
|
|
196
|
+
Position = popper.position,
|
|
197
|
+
Visible = props.visible,
|
|
198
|
+
ref = setContentRef,
|
|
199
|
+
}, child)
|
|
200
|
+
end)()) else (React.createElement("frame", {
|
|
201
|
+
AnchorPoint = popper.anchorPoint,
|
|
202
|
+
BackgroundTransparency = 1,
|
|
203
|
+
BorderSizePixel = 0,
|
|
204
|
+
Position = popper.position,
|
|
205
|
+
Size = UDim2.fromOffset(0, 0),
|
|
206
|
+
Visible = props.visible,
|
|
207
|
+
ref = setContentRef,
|
|
208
|
+
}, props.children))
|
|
209
|
+
return React.createElement(DismissableLayer, {
|
|
210
|
+
enabled = props.enabled,
|
|
211
|
+
modal = false,
|
|
212
|
+
onDismiss = props.onDismiss,
|
|
213
|
+
onEscapeKeyDown = props.onEscapeKeyDown,
|
|
214
|
+
onInteractOutside = props.onInteractOutside,
|
|
215
|
+
onPointerDownOutside = props.onPointerDownOutside,
|
|
216
|
+
}, React.createElement(RovingFocusGroup, {
|
|
217
|
+
active = props.enabled,
|
|
218
|
+
autoFocus = "first",
|
|
219
|
+
loop = selectContext.loop,
|
|
220
|
+
orientation = "vertical",
|
|
221
|
+
}, contentNode))
|
|
222
|
+
end
|
|
223
|
+
local function SelectContent(props)
|
|
224
|
+
local selectContext = useSelectContext()
|
|
225
|
+
local open = selectContext.open
|
|
226
|
+
local forceMount = props.forceMount == true
|
|
227
|
+
local handleDismiss = React.useCallback(function()
|
|
228
|
+
selectContext.setOpen(false)
|
|
229
|
+
end, { selectContext })
|
|
230
|
+
if not open and not forceMount then
|
|
231
|
+
return nil
|
|
232
|
+
end
|
|
233
|
+
if forceMount then
|
|
234
|
+
return React.createElement(SelectContentImpl, {
|
|
235
|
+
asChild = props.asChild,
|
|
236
|
+
enabled = open,
|
|
237
|
+
offset = props.offset,
|
|
238
|
+
onDismiss = handleDismiss,
|
|
239
|
+
onEscapeKeyDown = props.onEscapeKeyDown,
|
|
240
|
+
onInteractOutside = props.onInteractOutside,
|
|
241
|
+
onPointerDownOutside = props.onPointerDownOutside,
|
|
242
|
+
padding = props.padding,
|
|
243
|
+
placement = props.placement,
|
|
244
|
+
visible = open,
|
|
245
|
+
}, props.children)
|
|
246
|
+
end
|
|
247
|
+
return React.createElement(Presence, {
|
|
248
|
+
exitFallbackMs = 0,
|
|
249
|
+
present = open,
|
|
250
|
+
render = function(state)
|
|
251
|
+
return React.createElement(SelectContentImpl, {
|
|
252
|
+
asChild = props.asChild,
|
|
253
|
+
enabled = state.isPresent,
|
|
254
|
+
offset = props.offset,
|
|
255
|
+
onDismiss = handleDismiss,
|
|
256
|
+
onEscapeKeyDown = props.onEscapeKeyDown,
|
|
257
|
+
onInteractOutside = props.onInteractOutside,
|
|
258
|
+
onPointerDownOutside = props.onPointerDownOutside,
|
|
259
|
+
padding = props.padding,
|
|
260
|
+
placement = props.placement,
|
|
261
|
+
visible = state.isPresent,
|
|
262
|
+
}, props.children)
|
|
263
|
+
end,
|
|
264
|
+
})
|
|
265
|
+
end
|
|
266
|
+
return {
|
|
267
|
+
SelectContent = SelectContent,
|
|
268
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _core = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out)
|
|
4
|
+
local React = _core.React
|
|
5
|
+
local Slot = _core.Slot
|
|
6
|
+
local function SelectGroup(props)
|
|
7
|
+
if props.asChild then
|
|
8
|
+
local child = props.children
|
|
9
|
+
if not child then
|
|
10
|
+
error("[SelectGroup] `asChild` requires a child element.")
|
|
11
|
+
end
|
|
12
|
+
return React.createElement(Slot, nil, child)
|
|
13
|
+
end
|
|
14
|
+
return React.createElement("frame", {
|
|
15
|
+
BackgroundTransparency = 1,
|
|
16
|
+
BorderSizePixel = 0,
|
|
17
|
+
Size = UDim2.fromOffset(220, 108),
|
|
18
|
+
}, props.children)
|
|
19
|
+
end
|
|
20
|
+
return {
|
|
21
|
+
SelectGroup = SelectGroup,
|
|
22
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _core = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out)
|
|
4
|
+
local React = _core.React
|
|
5
|
+
local Slot = _core.Slot
|
|
6
|
+
local RovingFocusItem = TS.import(script, TS.getModule(script, "@lattice-ui", "focus").out).RovingFocusItem
|
|
7
|
+
local useSelectContext = TS.import(script, script.Parent, "context").useSelectContext
|
|
8
|
+
local nextItemId = 0
|
|
9
|
+
local nextItemOrder = 0
|
|
10
|
+
local function toGuiObject(instance)
|
|
11
|
+
if not instance or not instance:IsA("GuiObject") then
|
|
12
|
+
return nil
|
|
13
|
+
end
|
|
14
|
+
return instance
|
|
15
|
+
end
|
|
16
|
+
local function SelectItem(props)
|
|
17
|
+
local selectContext = useSelectContext()
|
|
18
|
+
local itemRef = React.useRef()
|
|
19
|
+
local disabled = selectContext.disabled or props.disabled == true
|
|
20
|
+
local _condition = props.textValue
|
|
21
|
+
if _condition == nil then
|
|
22
|
+
_condition = props.value
|
|
23
|
+
end
|
|
24
|
+
local textValue = _condition
|
|
25
|
+
local disabledRef = React.useRef(disabled)
|
|
26
|
+
local textValueRef = React.useRef(textValue)
|
|
27
|
+
React.useEffect(function()
|
|
28
|
+
disabledRef.current = disabled
|
|
29
|
+
end, { disabled })
|
|
30
|
+
React.useEffect(function()
|
|
31
|
+
textValueRef.current = textValue
|
|
32
|
+
end, { textValue })
|
|
33
|
+
local itemIdRef = React.useRef(0)
|
|
34
|
+
if itemIdRef.current == 0 then
|
|
35
|
+
nextItemId += 1
|
|
36
|
+
itemIdRef.current = nextItemId
|
|
37
|
+
end
|
|
38
|
+
local itemOrderRef = React.useRef(0)
|
|
39
|
+
if itemOrderRef.current == 0 then
|
|
40
|
+
nextItemOrder += 1
|
|
41
|
+
itemOrderRef.current = nextItemOrder
|
|
42
|
+
end
|
|
43
|
+
React.useEffect(function()
|
|
44
|
+
return selectContext.registerItem({
|
|
45
|
+
id = itemIdRef.current,
|
|
46
|
+
value = props.value,
|
|
47
|
+
order = itemOrderRef.current,
|
|
48
|
+
getNode = function()
|
|
49
|
+
return itemRef.current
|
|
50
|
+
end,
|
|
51
|
+
getDisabled = function()
|
|
52
|
+
return disabledRef.current
|
|
53
|
+
end,
|
|
54
|
+
getTextValue = function()
|
|
55
|
+
return textValueRef.current
|
|
56
|
+
end,
|
|
57
|
+
})
|
|
58
|
+
end, { props.value, selectContext })
|
|
59
|
+
local setItemRef = React.useCallback(function(instance)
|
|
60
|
+
itemRef.current = toGuiObject(instance)
|
|
61
|
+
end, {})
|
|
62
|
+
local handleSelect = React.useCallback(function()
|
|
63
|
+
if disabled then
|
|
64
|
+
return nil
|
|
65
|
+
end
|
|
66
|
+
selectContext.setValue(props.value)
|
|
67
|
+
selectContext.setOpen(false)
|
|
68
|
+
end, { disabled, props.value, selectContext })
|
|
69
|
+
local handleInputBegan = React.useCallback(function(_rbx, inputObject)
|
|
70
|
+
if disabled then
|
|
71
|
+
return nil
|
|
72
|
+
end
|
|
73
|
+
local keyCode = inputObject.KeyCode
|
|
74
|
+
if keyCode ~= Enum.KeyCode.Return and keyCode ~= Enum.KeyCode.Space then
|
|
75
|
+
return nil
|
|
76
|
+
end
|
|
77
|
+
selectContext.setValue(props.value)
|
|
78
|
+
selectContext.setOpen(false)
|
|
79
|
+
end, { disabled, props.value, selectContext })
|
|
80
|
+
local eventHandlers = React.useMemo(function()
|
|
81
|
+
return {
|
|
82
|
+
Activated = handleSelect,
|
|
83
|
+
InputBegan = handleInputBegan,
|
|
84
|
+
}
|
|
85
|
+
end, { handleInputBegan, handleSelect })
|
|
86
|
+
if props.asChild then
|
|
87
|
+
local child = props.children
|
|
88
|
+
if not child then
|
|
89
|
+
error("[SelectItem] `asChild` requires a child element.")
|
|
90
|
+
end
|
|
91
|
+
return React.createElement(RovingFocusItem, {
|
|
92
|
+
asChild = true,
|
|
93
|
+
disabled = disabled,
|
|
94
|
+
}, React.createElement(Slot, {
|
|
95
|
+
Active = not disabled,
|
|
96
|
+
Event = eventHandlers,
|
|
97
|
+
Selectable = not disabled,
|
|
98
|
+
ref = setItemRef,
|
|
99
|
+
}, child))
|
|
100
|
+
end
|
|
101
|
+
return React.createElement(RovingFocusItem, {
|
|
102
|
+
asChild = true,
|
|
103
|
+
disabled = disabled,
|
|
104
|
+
}, React.createElement("textbutton", {
|
|
105
|
+
Active = not disabled,
|
|
106
|
+
AutoButtonColor = false,
|
|
107
|
+
BackgroundColor3 = Color3.fromRGB(47, 53, 68),
|
|
108
|
+
BorderSizePixel = 0,
|
|
109
|
+
Event = eventHandlers,
|
|
110
|
+
Selectable = not disabled,
|
|
111
|
+
Size = UDim2.fromOffset(220, 32),
|
|
112
|
+
Text = textValue,
|
|
113
|
+
TextColor3 = if disabled then Color3.fromRGB(134, 141, 156) else Color3.fromRGB(234, 239, 247),
|
|
114
|
+
TextSize = 15,
|
|
115
|
+
TextXAlignment = Enum.TextXAlignment.Left,
|
|
116
|
+
ref = setItemRef,
|
|
117
|
+
}, React.createElement("uipadding", {
|
|
118
|
+
PaddingLeft = UDim.new(0, 10),
|
|
119
|
+
PaddingRight = UDim.new(0, 10),
|
|
120
|
+
}), props.children))
|
|
121
|
+
end
|
|
122
|
+
return {
|
|
123
|
+
SelectItem = SelectItem,
|
|
124
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _core = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out)
|
|
4
|
+
local React = _core.React
|
|
5
|
+
local Slot = _core.Slot
|
|
6
|
+
local function SelectLabel(props)
|
|
7
|
+
if props.asChild then
|
|
8
|
+
local child = props.children
|
|
9
|
+
if not child then
|
|
10
|
+
error("[SelectLabel] `asChild` requires a child element.")
|
|
11
|
+
end
|
|
12
|
+
return React.createElement(Slot, nil, child)
|
|
13
|
+
end
|
|
14
|
+
return React.createElement("textlabel", {
|
|
15
|
+
BackgroundTransparency = 1,
|
|
16
|
+
BorderSizePixel = 0,
|
|
17
|
+
Size = UDim2.fromOffset(220, 20),
|
|
18
|
+
Text = "Label",
|
|
19
|
+
TextColor3 = Color3.fromRGB(168, 176, 191),
|
|
20
|
+
TextSize = 13,
|
|
21
|
+
TextXAlignment = Enum.TextXAlignment.Left,
|
|
22
|
+
}, props.children)
|
|
23
|
+
end
|
|
24
|
+
return {
|
|
25
|
+
SelectLabel = SelectLabel,
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local React = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out).React
|
|
4
|
+
local _layer = TS.import(script, TS.getModule(script, "@lattice-ui", "layer").out)
|
|
5
|
+
local Portal = _layer.Portal
|
|
6
|
+
local PortalProvider = _layer.PortalProvider
|
|
7
|
+
local usePortalContext = _layer.usePortalContext
|
|
8
|
+
local function SelectPortalWithOverrides(props)
|
|
9
|
+
local portalContext = usePortalContext()
|
|
10
|
+
local container = props.container or portalContext.container
|
|
11
|
+
local _condition = props.displayOrderBase
|
|
12
|
+
if _condition == nil then
|
|
13
|
+
_condition = portalContext.displayOrderBase
|
|
14
|
+
end
|
|
15
|
+
local displayOrderBase = _condition
|
|
16
|
+
return React.createElement(PortalProvider, {
|
|
17
|
+
container = container,
|
|
18
|
+
displayOrderBase = displayOrderBase,
|
|
19
|
+
}, React.createElement(Portal, nil, props.children))
|
|
20
|
+
end
|
|
21
|
+
local function SelectPortal(props)
|
|
22
|
+
local hasOverrides = props.container ~= nil or props.displayOrderBase ~= nil
|
|
23
|
+
if hasOverrides then
|
|
24
|
+
return React.createElement(SelectPortalWithOverrides, {
|
|
25
|
+
container = props.container,
|
|
26
|
+
displayOrderBase = props.displayOrderBase,
|
|
27
|
+
}, props.children)
|
|
28
|
+
end
|
|
29
|
+
return React.createElement(Portal, nil, props.children)
|
|
30
|
+
end
|
|
31
|
+
return {
|
|
32
|
+
SelectPortal = SelectPortal,
|
|
33
|
+
}
|