@rbxts/uiblox 0.2.0-alpha.34 → 0.2.0-alpha.36
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/ui/packages/index.d.ts +1 -0
- package/out/ui/packages/init.luau +3 -0
- package/out/ui/packages/reorder/index.d.ts +2 -0
- package/out/ui/packages/reorder/init.luau +14 -0
- package/out/ui/packages/reorder/reorder.d.ts +24 -0
- package/out/ui/packages/reorder/reorder.luau +178 -0
- package/out/ui/packages/reorder/useReorderDrag.d.ts +15 -0
- package/out/ui/packages/reorder/useReorderDrag.luau +129 -0
- package/out/ui/packages/table/components/Table.d.ts +15 -2
- package/out/ui/packages/table/components/Table.luau +125 -38
- package/out/ui/packages/table/components/tableColumns.d.ts +26 -0
- package/out/ui/packages/table/components/tableColumns.luau +92 -0
- package/out/ui/packages/table/index.d.ts +2 -1
- package/package.json +2 -2
|
@@ -11,6 +11,7 @@ export * from "./layout/index";
|
|
|
11
11
|
export * from "./preloader/index";
|
|
12
12
|
export * from "./progressBar/index";
|
|
13
13
|
export * from "./scroll/index";
|
|
14
|
+
export * from "./reorder/index";
|
|
14
15
|
export * from "./shadow/index";
|
|
15
16
|
export * from "./sidebar/index";
|
|
16
17
|
export * from "./toast/index";
|
|
@@ -40,6 +40,9 @@ end
|
|
|
40
40
|
for _k, _v in TS.import(script, script, "scroll") or {} do
|
|
41
41
|
exports[_k] = _v
|
|
42
42
|
end
|
|
43
|
+
for _k, _v in TS.import(script, script, "reorder") or {} do
|
|
44
|
+
exports[_k] = _v
|
|
45
|
+
end
|
|
43
46
|
for _k, _v in TS.import(script, script, "shadow") or {} do
|
|
44
47
|
exports[_k] = _v
|
|
45
48
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local exports = {}
|
|
4
|
+
local _reorder = TS.import(script, script, "reorder")
|
|
5
|
+
exports.hitRect = _reorder.hitRect
|
|
6
|
+
exports.isReorderMove = _reorder.isReorderMove
|
|
7
|
+
exports.isReorderPress = _reorder.isReorderPress
|
|
8
|
+
exports.isReorderRelease = _reorder.isReorderRelease
|
|
9
|
+
exports.passedDragThreshold = _reorder.passedDragThreshold
|
|
10
|
+
exports.placeItem = _reorder.placeItem
|
|
11
|
+
exports.REORDER_THRESHOLD = _reorder.REORDER_THRESHOLD
|
|
12
|
+
exports.transferId = _reorder.transferId
|
|
13
|
+
exports.useReorderDrag = TS.import(script, script, "useReorderDrag").useReorderDrag
|
|
14
|
+
return exports
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const REORDER_THRESHOLD = 6;
|
|
2
|
+
export interface DragRect {
|
|
3
|
+
id: string;
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function isReorderPress(kind: Enum.UserInputType): boolean;
|
|
10
|
+
export declare function isReorderMove(kind: Enum.UserInputType): boolean;
|
|
11
|
+
export declare function isReorderRelease(kind: Enum.UserInputType): boolean;
|
|
12
|
+
export declare function passedDragThreshold(startX: number, startY: number, x: number, y: number, threshold?: number): boolean;
|
|
13
|
+
/** Smallest rect containing the point wins, so a card beats the column behind it. */
|
|
14
|
+
export declare function hitRect(rects: readonly DragRect[], x: number, y: number): string | undefined;
|
|
15
|
+
/** Final index after the move. Out-of-range or a no-op returns a copy. */
|
|
16
|
+
export declare function placeItem<T extends defined>(items: readonly T[], from: number, to: number): T[];
|
|
17
|
+
/**
|
|
18
|
+
* Insert `id` at `index` in `dest` and remove it from `source`.
|
|
19
|
+
* The same list uses placeItem, where index is the final index.
|
|
20
|
+
*/
|
|
21
|
+
export declare function transferId(source: readonly string[], dest: readonly string[], id: string, index: number): {
|
|
22
|
+
source: string[];
|
|
23
|
+
dest: string[];
|
|
24
|
+
};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local REORDER_THRESHOLD = 6
|
|
3
|
+
local function isReorderPress(kind)
|
|
4
|
+
return kind == Enum.UserInputType.MouseButton1 or kind == Enum.UserInputType.Touch
|
|
5
|
+
end
|
|
6
|
+
local function isReorderMove(kind)
|
|
7
|
+
return kind == Enum.UserInputType.MouseMovement or kind == Enum.UserInputType.Touch
|
|
8
|
+
end
|
|
9
|
+
local function isReorderRelease(kind)
|
|
10
|
+
return kind == Enum.UserInputType.MouseButton1 or kind == Enum.UserInputType.Touch
|
|
11
|
+
end
|
|
12
|
+
local function passedDragThreshold(startX, startY, x, y, threshold)
|
|
13
|
+
if threshold == nil then
|
|
14
|
+
threshold = REORDER_THRESHOLD
|
|
15
|
+
end
|
|
16
|
+
local dx = x - startX
|
|
17
|
+
local dy = y - startY
|
|
18
|
+
return dx * dx + dy * dy >= threshold * threshold
|
|
19
|
+
end
|
|
20
|
+
--* Smallest rect containing the point wins, so a card beats the column behind it.
|
|
21
|
+
local function hitRect(rects, x, y)
|
|
22
|
+
local best
|
|
23
|
+
local bestArea = math.huge
|
|
24
|
+
for _, rect in rects do
|
|
25
|
+
if x < rect.x or y < rect.y or x > rect.x + rect.width or y > rect.y + rect.height then
|
|
26
|
+
continue
|
|
27
|
+
end
|
|
28
|
+
local area = rect.width * rect.height
|
|
29
|
+
if area < bestArea then
|
|
30
|
+
best = rect
|
|
31
|
+
bestArea = area
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
local _result = best
|
|
35
|
+
if _result ~= nil then
|
|
36
|
+
_result = _result.id
|
|
37
|
+
end
|
|
38
|
+
return _result
|
|
39
|
+
end
|
|
40
|
+
--* Final index after the move. Out-of-range or a no-op returns a copy.
|
|
41
|
+
local function placeItem(items, from, to)
|
|
42
|
+
local listed = {}
|
|
43
|
+
for _, item in items do
|
|
44
|
+
table.insert(listed, item)
|
|
45
|
+
end
|
|
46
|
+
local count = #listed
|
|
47
|
+
if from < 0 or to < 0 or from >= count or to >= count or from == to then
|
|
48
|
+
return listed
|
|
49
|
+
end
|
|
50
|
+
local moved = listed[from + 1]
|
|
51
|
+
if from < to then
|
|
52
|
+
do
|
|
53
|
+
local index = from
|
|
54
|
+
local _shouldIncrement = false
|
|
55
|
+
while true do
|
|
56
|
+
if _shouldIncrement then
|
|
57
|
+
index += 1
|
|
58
|
+
else
|
|
59
|
+
_shouldIncrement = true
|
|
60
|
+
end
|
|
61
|
+
if not (index < to) then
|
|
62
|
+
break
|
|
63
|
+
end
|
|
64
|
+
listed[index + 1] = listed[index + 2]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
else
|
|
68
|
+
do
|
|
69
|
+
local index = from
|
|
70
|
+
local _shouldIncrement = false
|
|
71
|
+
while true do
|
|
72
|
+
if _shouldIncrement then
|
|
73
|
+
index -= 1
|
|
74
|
+
else
|
|
75
|
+
_shouldIncrement = true
|
|
76
|
+
end
|
|
77
|
+
if not (index > to) then
|
|
78
|
+
break
|
|
79
|
+
end
|
|
80
|
+
listed[index + 1] = listed[index]
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
listed[to + 1] = moved
|
|
85
|
+
return listed
|
|
86
|
+
end
|
|
87
|
+
local function indexOfId(ids, id)
|
|
88
|
+
for index = 0, #ids - 1 do
|
|
89
|
+
if ids[index + 1] == id then
|
|
90
|
+
return index
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
return -1
|
|
94
|
+
end
|
|
95
|
+
--[[
|
|
96
|
+
*
|
|
97
|
+
* Insert `id` at `index` in `dest` and remove it from `source`.
|
|
98
|
+
* The same list uses placeItem, where index is the final index.
|
|
99
|
+
|
|
100
|
+
]]
|
|
101
|
+
local function transferId(source, dest, id, index)
|
|
102
|
+
if source == dest then
|
|
103
|
+
local placed = placeItem(source, indexOfId(source, id), math.clamp(index, 0, math.max(0, #source - 1)))
|
|
104
|
+
return {
|
|
105
|
+
source = placed,
|
|
106
|
+
dest = placed,
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
local nextSource = {}
|
|
110
|
+
local found = false
|
|
111
|
+
for _, item in source do
|
|
112
|
+
if item == id then
|
|
113
|
+
found = true
|
|
114
|
+
else
|
|
115
|
+
table.insert(nextSource, item)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
local nextDest = {}
|
|
119
|
+
for _, item in dest do
|
|
120
|
+
table.insert(nextDest, item)
|
|
121
|
+
end
|
|
122
|
+
if not found then
|
|
123
|
+
return {
|
|
124
|
+
source = nextSource,
|
|
125
|
+
dest = nextDest,
|
|
126
|
+
}
|
|
127
|
+
end
|
|
128
|
+
local at = math.clamp(math.floor(index), 0, #nextDest)
|
|
129
|
+
local inserted = {}
|
|
130
|
+
do
|
|
131
|
+
local cursor = 0
|
|
132
|
+
local _shouldIncrement = false
|
|
133
|
+
while true do
|
|
134
|
+
if _shouldIncrement then
|
|
135
|
+
cursor += 1
|
|
136
|
+
else
|
|
137
|
+
_shouldIncrement = true
|
|
138
|
+
end
|
|
139
|
+
if not (cursor < at) then
|
|
140
|
+
break
|
|
141
|
+
end
|
|
142
|
+
local _arg0 = nextDest[cursor + 1]
|
|
143
|
+
table.insert(inserted, _arg0)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
local _id = id
|
|
147
|
+
table.insert(inserted, _id)
|
|
148
|
+
do
|
|
149
|
+
local cursor = at
|
|
150
|
+
local _shouldIncrement = false
|
|
151
|
+
while true do
|
|
152
|
+
if _shouldIncrement then
|
|
153
|
+
cursor += 1
|
|
154
|
+
else
|
|
155
|
+
_shouldIncrement = true
|
|
156
|
+
end
|
|
157
|
+
if not (cursor < #nextDest) then
|
|
158
|
+
break
|
|
159
|
+
end
|
|
160
|
+
local _arg0 = nextDest[cursor + 1]
|
|
161
|
+
table.insert(inserted, _arg0)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
return {
|
|
165
|
+
source = nextSource,
|
|
166
|
+
dest = inserted,
|
|
167
|
+
}
|
|
168
|
+
end
|
|
169
|
+
return {
|
|
170
|
+
isReorderPress = isReorderPress,
|
|
171
|
+
isReorderMove = isReorderMove,
|
|
172
|
+
isReorderRelease = isReorderRelease,
|
|
173
|
+
passedDragThreshold = passedDragThreshold,
|
|
174
|
+
hitRect = hitRect,
|
|
175
|
+
placeItem = placeItem,
|
|
176
|
+
transferId = transferId,
|
|
177
|
+
REORDER_THRESHOLD = REORDER_THRESHOLD,
|
|
178
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DragRect } from "./reorder";
|
|
2
|
+
export interface ReorderDragState {
|
|
3
|
+
active: boolean;
|
|
4
|
+
id?: string;
|
|
5
|
+
overId?: string;
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ReorderDragHandle {
|
|
10
|
+
drag: ReorderDragState;
|
|
11
|
+
begin: (id: string, input: InputObject) => boolean;
|
|
12
|
+
cancel: () => void;
|
|
13
|
+
suppressClick: () => boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function useReorderDrag(onDrop: (fromId: string, overId?: string) => void, getRects: () => readonly DragRect[]): ReorderDragHandle;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _react = TS.import(script, TS.getModule(script, "@rbxts", "react"))
|
|
4
|
+
local useEffect = _react.useEffect
|
|
5
|
+
local useRef = _react.useRef
|
|
6
|
+
local useState = _react.useState
|
|
7
|
+
local UserInputService = TS.import(script, TS.getModule(script, "@rbxts", "services")).UserInputService
|
|
8
|
+
local _reorder = TS.import(script, script.Parent, "reorder")
|
|
9
|
+
local hitRect = _reorder.hitRect
|
|
10
|
+
local isReorderMove = _reorder.isReorderMove
|
|
11
|
+
local isReorderPress = _reorder.isReorderPress
|
|
12
|
+
local isReorderRelease = _reorder.isReorderRelease
|
|
13
|
+
local passedDragThreshold = _reorder.passedDragThreshold
|
|
14
|
+
local rest = function()
|
|
15
|
+
return {
|
|
16
|
+
active = false,
|
|
17
|
+
x = 0,
|
|
18
|
+
y = 0,
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
local function useReorderDrag(onDrop, getRects)
|
|
22
|
+
local drag, setDrag = useState(rest())
|
|
23
|
+
local tracking = useRef({
|
|
24
|
+
down = false,
|
|
25
|
+
active = false,
|
|
26
|
+
x = 0,
|
|
27
|
+
y = 0,
|
|
28
|
+
startX = 0,
|
|
29
|
+
startY = 0,
|
|
30
|
+
})
|
|
31
|
+
local onDropRef = useRef(onDrop)
|
|
32
|
+
local rectsRef = useRef(getRects)
|
|
33
|
+
local took = useRef(false)
|
|
34
|
+
onDropRef.current = onDrop
|
|
35
|
+
rectsRef.current = getRects
|
|
36
|
+
local clear = function(drop)
|
|
37
|
+
local current = tracking.current
|
|
38
|
+
tracking.current = {
|
|
39
|
+
down = false,
|
|
40
|
+
active = false,
|
|
41
|
+
x = 0,
|
|
42
|
+
y = 0,
|
|
43
|
+
startX = 0,
|
|
44
|
+
startY = 0,
|
|
45
|
+
}
|
|
46
|
+
setDrag(rest())
|
|
47
|
+
if drop and current.active and current.id ~= nil then
|
|
48
|
+
took.current = true
|
|
49
|
+
onDropRef.current(current.id, current.overId)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
useEffect(function()
|
|
53
|
+
local changed = UserInputService.InputChanged:Connect(function(input)
|
|
54
|
+
local current = tracking.current
|
|
55
|
+
if not current.down or not isReorderMove(input.UserInputType) then
|
|
56
|
+
return nil
|
|
57
|
+
end
|
|
58
|
+
local x = input.Position.X
|
|
59
|
+
local y = input.Position.Y
|
|
60
|
+
local active = current.active or passedDragThreshold(current.startX, current.startY, x, y)
|
|
61
|
+
local overId = if active then hitRect(rectsRef.current(), x, y) else nil
|
|
62
|
+
local _object = table.clone(current)
|
|
63
|
+
setmetatable(_object, nil)
|
|
64
|
+
_object.active = active
|
|
65
|
+
_object.x = x
|
|
66
|
+
_object.y = y
|
|
67
|
+
_object.overId = overId
|
|
68
|
+
tracking.current = _object
|
|
69
|
+
if active then
|
|
70
|
+
setDrag({
|
|
71
|
+
active = true,
|
|
72
|
+
id = current.id,
|
|
73
|
+
overId = overId,
|
|
74
|
+
x = x,
|
|
75
|
+
y = y,
|
|
76
|
+
})
|
|
77
|
+
end
|
|
78
|
+
end)
|
|
79
|
+
local ended = UserInputService.InputEnded:Connect(function(input)
|
|
80
|
+
if not tracking.current.down or not isReorderRelease(input.UserInputType) then
|
|
81
|
+
return nil
|
|
82
|
+
end
|
|
83
|
+
clear(true)
|
|
84
|
+
end)
|
|
85
|
+
local began = UserInputService.InputBegan:Connect(function(input)
|
|
86
|
+
if input.KeyCode == Enum.KeyCode.Escape then
|
|
87
|
+
clear(false)
|
|
88
|
+
end
|
|
89
|
+
end)
|
|
90
|
+
return function()
|
|
91
|
+
changed:Disconnect()
|
|
92
|
+
ended:Disconnect()
|
|
93
|
+
began:Disconnect()
|
|
94
|
+
end
|
|
95
|
+
end, {})
|
|
96
|
+
return {
|
|
97
|
+
drag = drag,
|
|
98
|
+
begin = function(id, input)
|
|
99
|
+
if not isReorderPress(input.UserInputType) then
|
|
100
|
+
return false
|
|
101
|
+
end
|
|
102
|
+
local x = input.Position.X
|
|
103
|
+
local y = input.Position.Y
|
|
104
|
+
tracking.current = {
|
|
105
|
+
down = true,
|
|
106
|
+
active = false,
|
|
107
|
+
id = id,
|
|
108
|
+
x = x,
|
|
109
|
+
y = y,
|
|
110
|
+
startX = x,
|
|
111
|
+
startY = y,
|
|
112
|
+
}
|
|
113
|
+
return true
|
|
114
|
+
end,
|
|
115
|
+
cancel = function()
|
|
116
|
+
return clear(false)
|
|
117
|
+
end,
|
|
118
|
+
suppressClick = function()
|
|
119
|
+
if not took.current then
|
|
120
|
+
return false
|
|
121
|
+
end
|
|
122
|
+
took.current = false
|
|
123
|
+
return true
|
|
124
|
+
end,
|
|
125
|
+
}
|
|
126
|
+
end
|
|
127
|
+
return {
|
|
128
|
+
useReorderDrag = useReorderDrag,
|
|
129
|
+
}
|
|
@@ -1,9 +1,22 @@
|
|
|
1
|
+
import React from "@rbxts/react";
|
|
1
2
|
import { CustomizedProps } from "../../../../theme/index";
|
|
3
|
+
import { TableAlign, TableSortDirection } from "./tableColumns";
|
|
4
|
+
export interface TableColumn {
|
|
5
|
+
header: string | React.ReactNode;
|
|
6
|
+
width?: number | UDim;
|
|
7
|
+
flex?: number;
|
|
8
|
+
align?: TableAlign;
|
|
9
|
+
sortable?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export type TableCell = string | React.ReactNode;
|
|
2
12
|
export interface TableProps {
|
|
3
|
-
columns: string
|
|
4
|
-
rows:
|
|
13
|
+
columns: Array<string | TableColumn>;
|
|
14
|
+
rows: Array<Array<TableCell>>;
|
|
5
15
|
selected?: number;
|
|
6
16
|
dense?: boolean;
|
|
17
|
+
sortColumn?: number;
|
|
18
|
+
sortDirection?: TableSortDirection;
|
|
19
|
+
onSort?: (column: number) => void;
|
|
7
20
|
onRowActivated?: (index: number) => void;
|
|
8
21
|
}
|
|
9
22
|
declare function Table(props: CustomizedProps<Frame, TableProps>): JSX.Element;
|
|
@@ -2,15 +2,33 @@
|
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
local React = TS.import(script, TS.getModule(script, "@rbxts", "react"))
|
|
4
4
|
local cx = TS.import(script, script.Parent.Parent.Parent.Parent.Parent, "theme").cx
|
|
5
|
-
local rowSelected = TS.import(script, script.Parent, "rowSelected").rowSelected
|
|
6
5
|
local SxHost = TS.import(script, script.Parent.Parent.Parent, "host").SxHost
|
|
6
|
+
local rowSelected = TS.import(script, script.Parent, "rowSelected").rowSelected
|
|
7
|
+
local _tableColumns = TS.import(script, script.Parent, "tableColumns")
|
|
8
|
+
local canSort = _tableColumns.canSort
|
|
9
|
+
local columnSizes = _tableColumns.columnSizes
|
|
10
|
+
local headerText = _tableColumns.headerText
|
|
11
|
+
local isTextCell = _tableColumns.isTextCell
|
|
12
|
+
local resolveColumn = _tableColumns.resolveColumn
|
|
7
13
|
local useTableStyles = TS.import(script, script.Parent, "Table.styles").default
|
|
14
|
+
local function textAlign(align)
|
|
15
|
+
if align == "center" then
|
|
16
|
+
return Enum.TextXAlignment.Center
|
|
17
|
+
end
|
|
18
|
+
if align == "right" then
|
|
19
|
+
return Enum.TextXAlignment.Right
|
|
20
|
+
end
|
|
21
|
+
return Enum.TextXAlignment.Left
|
|
22
|
+
end
|
|
8
23
|
local function Table(props)
|
|
9
24
|
local _binding = props
|
|
10
25
|
local columns = _binding.columns
|
|
11
26
|
local rows = _binding.rows
|
|
12
27
|
local selected = _binding.selected
|
|
13
28
|
local dense = _binding.dense
|
|
29
|
+
local sortColumn = _binding.sortColumn
|
|
30
|
+
local sortDirection = _binding.sortDirection
|
|
31
|
+
local onSort = _binding.onSort
|
|
14
32
|
local onRowActivated = _binding.onRowActivated
|
|
15
33
|
local className = _binding.className
|
|
16
34
|
local sx = _binding.sx
|
|
@@ -19,7 +37,17 @@ local function Table(props)
|
|
|
19
37
|
local styles = useTableStyles({
|
|
20
38
|
dense = dense,
|
|
21
39
|
})
|
|
22
|
-
|
|
40
|
+
-- ▼ ReadonlyArray.map ▼
|
|
41
|
+
local _newValue = table.create(#columns)
|
|
42
|
+
local _callback = function(column)
|
|
43
|
+
return resolveColumn(column)
|
|
44
|
+
end
|
|
45
|
+
for _k, _v in columns do
|
|
46
|
+
_newValue[_k] = _callback(_v, _k - 1, columns)
|
|
47
|
+
end
|
|
48
|
+
-- ▲ ReadonlyArray.map ▲
|
|
49
|
+
local resolved = _newValue
|
|
50
|
+
local sizes = columnSizes(resolved)
|
|
23
51
|
local _attributes = {
|
|
24
52
|
tag = "frame",
|
|
25
53
|
}
|
|
@@ -52,27 +80,72 @@ local function Table(props)
|
|
|
52
80
|
setmetatable(_attributes_5, nil)
|
|
53
81
|
local _exp_3 = React.createElement("uilistlayout", _attributes_5)
|
|
54
82
|
-- ▼ ReadonlyArray.map ▼
|
|
55
|
-
local
|
|
56
|
-
local
|
|
57
|
-
local
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
83
|
+
local _newValue_1 = table.create(#resolved)
|
|
84
|
+
local _callback_1 = function(column, index)
|
|
85
|
+
local size = sizes[index + 1]
|
|
86
|
+
local box = UDim2.new(size.scale, size.offset, 0, 0)
|
|
87
|
+
local align = textAlign(column.align)
|
|
88
|
+
local active = sortColumn == index and column.sortable
|
|
89
|
+
local _header = column.header
|
|
90
|
+
local label = if type(_header) == "string" then headerText(column.header, active, sortDirection) else nil
|
|
91
|
+
local clickable = canSort(column.sortable, onSort ~= nil)
|
|
92
|
+
if clickable then
|
|
93
|
+
local _attributes_6 = {
|
|
94
|
+
key = `h-{index}`,
|
|
95
|
+
}
|
|
96
|
+
for _k, _v in (cx(styles.cell, styles.headerCell)) do
|
|
97
|
+
_attributes_6[_k] = _v
|
|
98
|
+
end
|
|
99
|
+
local _condition_1 = label
|
|
100
|
+
if _condition_1 == nil then
|
|
101
|
+
_condition_1 = ""
|
|
102
|
+
end
|
|
103
|
+
_attributes_6.Text = _condition_1
|
|
104
|
+
_attributes_6.Size = box
|
|
105
|
+
_attributes_6.TextXAlignment = align
|
|
106
|
+
_attributes_6.AutoButtonColor = false
|
|
107
|
+
_attributes_6.LayoutOrder = index
|
|
108
|
+
_attributes_6.Event = {
|
|
109
|
+
Activated = function()
|
|
110
|
+
local _result = onSort
|
|
111
|
+
if _result ~= nil then
|
|
112
|
+
_result = _result(index)
|
|
113
|
+
end
|
|
114
|
+
return _result
|
|
115
|
+
end,
|
|
116
|
+
}
|
|
117
|
+
return React.createElement("textbutton", _attributes_6, label == nil and (column.header))
|
|
62
118
|
end
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
119
|
+
if label ~= nil then
|
|
120
|
+
local _attributes_6 = {
|
|
121
|
+
key = `h-{index}`,
|
|
122
|
+
}
|
|
123
|
+
for _k, _v in cx(styles.cell, styles.headerCell) do
|
|
124
|
+
_attributes_6[_k] = _v
|
|
125
|
+
end
|
|
126
|
+
_attributes_6.Text = label
|
|
127
|
+
_attributes_6.Size = box
|
|
128
|
+
_attributes_6.TextXAlignment = align
|
|
129
|
+
_attributes_6.LayoutOrder = index
|
|
130
|
+
return React.createElement("textlabel", _attributes_6)
|
|
131
|
+
end
|
|
132
|
+
return React.createElement("frame", {
|
|
133
|
+
key = `h-{index}`,
|
|
134
|
+
Size = box,
|
|
135
|
+
AutomaticSize = Enum.AutomaticSize.Y,
|
|
136
|
+
BackgroundTransparency = 1,
|
|
137
|
+
BorderSizePixel = 0,
|
|
138
|
+
LayoutOrder = index,
|
|
139
|
+
}, column.header)
|
|
67
140
|
end
|
|
68
|
-
for _k, _v in
|
|
69
|
-
|
|
141
|
+
for _k, _v in resolved do
|
|
142
|
+
_newValue_1[_k] = _callback_1(_v, _k - 1, resolved)
|
|
70
143
|
end
|
|
71
144
|
-- ▲ ReadonlyArray.map ▲
|
|
72
|
-
local _exp_4 = React.createElement("frame", _attributes_3, _exp_2, _exp_3, React.createElement(React.Fragment, nil,
|
|
145
|
+
local _exp_4 = React.createElement("frame", _attributes_3, _exp_2, _exp_3, React.createElement(React.Fragment, nil, _newValue_1))
|
|
73
146
|
-- ▼ ReadonlyArray.map ▼
|
|
74
|
-
local
|
|
75
|
-
local
|
|
147
|
+
local _newValue_2 = table.create(#rows)
|
|
148
|
+
local _callback_2 = function(cells, rowIndex)
|
|
76
149
|
local _attributes_6 = {
|
|
77
150
|
key = `r-{rowIndex}`,
|
|
78
151
|
}
|
|
@@ -96,34 +169,48 @@ local function Table(props)
|
|
|
96
169
|
setmetatable(_attributes_8, nil)
|
|
97
170
|
local _exp_6 = React.createElement("uilistlayout", _attributes_8)
|
|
98
171
|
-- ▼ ReadonlyArray.map ▼
|
|
99
|
-
local
|
|
100
|
-
local
|
|
101
|
-
local
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
_attributes_9
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
172
|
+
local _newValue_3 = table.create(#resolved)
|
|
173
|
+
local _callback_3 = function(column, colIndex)
|
|
174
|
+
local size = sizes[colIndex + 1]
|
|
175
|
+
local box = UDim2.new(size.scale, size.offset, 0, 0)
|
|
176
|
+
local value = cells[colIndex + 1]
|
|
177
|
+
if isTextCell(value) then
|
|
178
|
+
local _attributes_9 = {
|
|
179
|
+
key = `c-{rowIndex}-{colIndex}`,
|
|
180
|
+
}
|
|
181
|
+
for _k, _v in styles.cell do
|
|
182
|
+
_attributes_9[_k] = _v
|
|
183
|
+
end
|
|
184
|
+
local _condition_1 = value
|
|
185
|
+
if _condition_1 == nil then
|
|
186
|
+
_condition_1 = ""
|
|
187
|
+
end
|
|
188
|
+
_attributes_9.Text = _condition_1
|
|
189
|
+
_attributes_9.Size = box
|
|
190
|
+
_attributes_9.TextXAlignment = textAlign(column.align)
|
|
191
|
+
_attributes_9.LayoutOrder = colIndex
|
|
192
|
+
return React.createElement("textlabel", _attributes_9)
|
|
110
193
|
end
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
194
|
+
return React.createElement("frame", {
|
|
195
|
+
key = `c-{rowIndex}-{colIndex}`,
|
|
196
|
+
Size = box,
|
|
197
|
+
AutomaticSize = Enum.AutomaticSize.Y,
|
|
198
|
+
BackgroundTransparency = 1,
|
|
199
|
+
BorderSizePixel = 0,
|
|
200
|
+
LayoutOrder = colIndex,
|
|
201
|
+
}, value)
|
|
115
202
|
end
|
|
116
|
-
for _k, _v in
|
|
117
|
-
|
|
203
|
+
for _k, _v in resolved do
|
|
204
|
+
_newValue_3[_k] = _callback_3(_v, _k - 1, resolved)
|
|
118
205
|
end
|
|
119
206
|
-- ▲ ReadonlyArray.map ▲
|
|
120
|
-
return React.createElement("textbutton", _attributes_6, _exp_5, _exp_6, React.createElement(React.Fragment, nil,
|
|
207
|
+
return React.createElement("textbutton", _attributes_6, _exp_5, _exp_6, React.createElement(React.Fragment, nil, _newValue_3))
|
|
121
208
|
end
|
|
122
209
|
for _k, _v in rows do
|
|
123
|
-
|
|
210
|
+
_newValue_2[_k] = _callback_2(_v, _k - 1, rows)
|
|
124
211
|
end
|
|
125
212
|
-- ▲ ReadonlyArray.map ▲
|
|
126
|
-
return React.createElement(SxHost, _attributes, _exp, _exp_1, _exp_4, React.createElement(React.Fragment, nil,
|
|
213
|
+
return React.createElement(SxHost, _attributes, _exp, _exp_1, _exp_4, React.createElement(React.Fragment, nil, _newValue_2))
|
|
127
214
|
end
|
|
128
215
|
local default = Table
|
|
129
216
|
return {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type TableAlign = "left" | "center" | "right";
|
|
2
|
+
export type TableSortDirection = "asc" | "desc";
|
|
3
|
+
export interface TableColumnSpec {
|
|
4
|
+
header: unknown;
|
|
5
|
+
width?: number | UDim;
|
|
6
|
+
flex?: number;
|
|
7
|
+
align?: TableAlign;
|
|
8
|
+
sortable?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface ResolvedColumn {
|
|
11
|
+
header: unknown;
|
|
12
|
+
width?: number | UDim;
|
|
13
|
+
flex?: number;
|
|
14
|
+
align: TableAlign;
|
|
15
|
+
sortable: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface ColumnSize {
|
|
18
|
+
scale: number;
|
|
19
|
+
offset: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function resolveColumn(column: string | TableColumnSpec): ResolvedColumn;
|
|
22
|
+
/** Scale/offset for each column. Number widths are scales. Flex shares whatever scale is left. */
|
|
23
|
+
export declare function columnSizes(columns: ReadonlyArray<Pick<ResolvedColumn, "width" | "flex">>): ColumnSize[];
|
|
24
|
+
export declare function isTextCell(value: unknown): value is string | undefined;
|
|
25
|
+
export declare function canSort(sortable: boolean | undefined, hasHandler: boolean): boolean;
|
|
26
|
+
export declare function headerText(label: string, active: boolean, direction?: TableSortDirection): string;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local function resolveColumn(column)
|
|
3
|
+
local _column = column
|
|
4
|
+
if type(_column) == "string" then
|
|
5
|
+
return {
|
|
6
|
+
header = column,
|
|
7
|
+
align = "left",
|
|
8
|
+
sortable = false,
|
|
9
|
+
}
|
|
10
|
+
end
|
|
11
|
+
return {
|
|
12
|
+
header = column.header,
|
|
13
|
+
width = column.width,
|
|
14
|
+
flex = column.flex,
|
|
15
|
+
align = column.align or "left",
|
|
16
|
+
sortable = column.sortable == true,
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
--* Scale/offset for each column. Number widths are scales. Flex shares whatever scale is left.
|
|
20
|
+
local function columnSizes(columns)
|
|
21
|
+
local fixed = 0
|
|
22
|
+
local flexTotal = 0
|
|
23
|
+
for _, column in columns do
|
|
24
|
+
local width = column.width
|
|
25
|
+
if type(width) == "number" then
|
|
26
|
+
fixed += width
|
|
27
|
+
elseif width ~= nil then
|
|
28
|
+
fixed += width.Scale
|
|
29
|
+
else
|
|
30
|
+
local _condition = column.flex
|
|
31
|
+
if _condition == nil then
|
|
32
|
+
_condition = 1
|
|
33
|
+
end
|
|
34
|
+
flexTotal += _condition
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
local remain = math.max(0, 1 - fixed)
|
|
38
|
+
local sizes = {}
|
|
39
|
+
for _, column in columns do
|
|
40
|
+
local width = column.width
|
|
41
|
+
if type(width) == "number" then
|
|
42
|
+
local _arg0 = {
|
|
43
|
+
scale = width,
|
|
44
|
+
offset = 0,
|
|
45
|
+
}
|
|
46
|
+
table.insert(sizes, _arg0)
|
|
47
|
+
elseif width ~= nil then
|
|
48
|
+
local _arg0 = {
|
|
49
|
+
scale = width.Scale,
|
|
50
|
+
offset = width.Offset,
|
|
51
|
+
}
|
|
52
|
+
table.insert(sizes, _arg0)
|
|
53
|
+
else
|
|
54
|
+
local _condition = column.flex
|
|
55
|
+
if _condition == nil then
|
|
56
|
+
_condition = 1
|
|
57
|
+
end
|
|
58
|
+
local flex = _condition
|
|
59
|
+
local share = if flexTotal > 0 then (flex / flexTotal) * remain else 0
|
|
60
|
+
local _arg0 = {
|
|
61
|
+
scale = share,
|
|
62
|
+
offset = 0,
|
|
63
|
+
}
|
|
64
|
+
table.insert(sizes, _arg0)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
return sizes
|
|
68
|
+
end
|
|
69
|
+
local function isTextCell(value)
|
|
70
|
+
local _value = value
|
|
71
|
+
local _condition = type(_value) == "string"
|
|
72
|
+
if not _condition then
|
|
73
|
+
_condition = value == nil
|
|
74
|
+
end
|
|
75
|
+
return _condition
|
|
76
|
+
end
|
|
77
|
+
local function canSort(sortable, hasHandler)
|
|
78
|
+
return sortable == true and hasHandler
|
|
79
|
+
end
|
|
80
|
+
local function headerText(label, active, direction)
|
|
81
|
+
if not active then
|
|
82
|
+
return label
|
|
83
|
+
end
|
|
84
|
+
return if direction == "desc" then `{label} ↓` else `{label} ↑`
|
|
85
|
+
end
|
|
86
|
+
return {
|
|
87
|
+
resolveColumn = resolveColumn,
|
|
88
|
+
columnSizes = columnSizes,
|
|
89
|
+
isTextCell = isTextCell,
|
|
90
|
+
canSort = canSort,
|
|
91
|
+
headerText = headerText,
|
|
92
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rbxts/uiblox",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.36",
|
|
4
4
|
"description": "UI Library and theming for roblox-ts projects",
|
|
5
5
|
"main": "out/init.luau",
|
|
6
6
|
"packageManager": "pnpm@11.3.0",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"build": "rbxtsc",
|
|
9
9
|
"watch": "rbxtsc -w",
|
|
10
10
|
"pack:check": "node scripts/pack-check.mjs",
|
|
11
|
-
"test": "node scripts/no-internal-refs.check.mjs && node scripts/import-case.check.mjs && node --experimental-strip-types scripts/theme-scope.check.mjs && node --experimental-strip-types scripts/style-types.check.mjs && node --experimental-strip-types scripts/style-cache.check.mjs && node --experimental-strip-types scripts/style-variants.check.mjs && node --experimental-strip-types scripts/component-styles.check.mjs && node --experimental-strip-types scripts/interaction-styles.check.mjs && node --experimental-strip-types scripts/resolve-style.check.mjs && node --experimental-strip-types scripts/resolve-sx.check.mjs && node --experimental-strip-types scripts/sx-prop.check.mjs && node --experimental-strip-types scripts/style-system.check.mjs && node --experimental-strip-types scripts/host-sx.check.mjs && node --experimental-strip-types scripts/density.check.mjs && node --experimental-strip-types scripts/styles.check.mjs && node --experimental-strip-types scripts/contrast.check.mjs && node --experimental-strip-types scripts/primitives.check.mjs && node scripts/state-matrix-registers.check.mjs && node --experimental-strip-types scripts/paper.check.mjs && node --experimental-strip-types scripts/list-item.check.mjs && node --experimental-strip-types scripts/slider.check.mjs && node --experimental-strip-types scripts/input.check.mjs && node --experimental-strip-types scripts/menu.check.mjs && node --experimental-strip-types scripts/guard.check.mjs && node --experimental-strip-types scripts/breakpoints.check.mjs && node --experimental-strip-types scripts/viewport-observer.check.mjs && node --experimental-strip-types scripts/focus-trap.check.mjs && node --experimental-strip-types scripts/select-typeahead.check.mjs && node --experimental-strip-types scripts/select-groups.check.mjs && node --experimental-strip-types scripts/select-multi.check.mjs && node --experimental-strip-types scripts/select-polish.check.mjs && node --experimental-strip-types scripts/reduced-motion.check.mjs && node --experimental-strip-types scripts/card.check.mjs && node --experimental-strip-types scripts/chip.check.mjs && node --experimental-strip-types scripts/badge.check.mjs && node --experimental-strip-types scripts/avatar.check.mjs && node --experimental-strip-types scripts/imageList.check.mjs && node --experimental-strip-types scripts/drawer.check.mjs && node --experimental-strip-types scripts/breadcrumbs.check.mjs && node --experimental-strip-types scripts/pagination.check.mjs && node --experimental-strip-types scripts/stepper.check.mjs && node --experimental-strip-types scripts/accordion.check.mjs && node --experimental-strip-types scripts/snackbar.check.mjs && node --experimental-strip-types scripts/table.check.mjs && node --experimental-strip-types scripts/autocomplete.check.mjs && node --experimental-strip-types scripts/field-loading.check.mjs && node --experimental-strip-types scripts/fab.check.mjs && node --experimental-strip-types scripts/appbar.check.mjs && node --experimental-strip-types scripts/bottom-navigation.check.mjs && node --experimental-strip-types scripts/alert.check.mjs && node --experimental-strip-types scripts/toggle-button.check.mjs && node --experimental-strip-types scripts/link.check.mjs && node --experimental-strip-types scripts/rating.check.mjs && node --experimental-strip-types scripts/stack.check.mjs && node --experimental-strip-types scripts/flex-item.check.mjs && node --experimental-strip-types scripts/grid.check.mjs && node --experimental-strip-types scripts/speed-dial.check.mjs && node --experimental-strip-types scripts/form-text.check.mjs && node --experimental-strip-types scripts/box.check.mjs && node --experimental-strip-types scripts/scroll-view.check.mjs && node --experimental-strip-types scripts/image-list.check.mjs && node --experimental-strip-types scripts/radio-group.check.mjs && node --experimental-strip-types scripts/container.check.mjs && node --experimental-strip-types scripts/divider.check.mjs && node --experimental-strip-types scripts/markdown.check.mjs && node --experimental-strip-types scripts/switch.check.mjs && node --experimental-strip-types scripts/tabs.check.mjs && node --experimental-strip-types scripts/dialog.check.mjs && node --experimental-strip-types scripts/backdrop.check.mjs && node --experimental-strip-types scripts/cframe-editor.check.mjs && node --experimental-strip-types scripts/enum-picker.check.mjs && node --experimental-strip-types scripts/number-range.check.mjs && node --experimental-strip-types scripts/date-range.check.mjs && node --experimental-strip-types scripts/sparkline.check.mjs && node --experimental-strip-types scripts/rect-editor.check.mjs && node --experimental-strip-types scripts/asset-field.check.mjs && node --experimental-strip-types scripts/gradient-editor.check.mjs && node --experimental-strip-types scripts/ray-editor.check.mjs && node --experimental-strip-types scripts/physical-properties.check.mjs && node --experimental-strip-types scripts/brickcolor-picker.check.mjs",
|
|
11
|
+
"test": "node scripts/no-internal-refs.check.mjs && node scripts/import-case.check.mjs && node --experimental-strip-types scripts/theme-scope.check.mjs && node --experimental-strip-types scripts/style-types.check.mjs && node --experimental-strip-types scripts/style-cache.check.mjs && node --experimental-strip-types scripts/style-variants.check.mjs && node --experimental-strip-types scripts/component-styles.check.mjs && node --experimental-strip-types scripts/interaction-styles.check.mjs && node --experimental-strip-types scripts/resolve-style.check.mjs && node --experimental-strip-types scripts/resolve-sx.check.mjs && node --experimental-strip-types scripts/sx-prop.check.mjs && node --experimental-strip-types scripts/style-system.check.mjs && node --experimental-strip-types scripts/host-sx.check.mjs && node --experimental-strip-types scripts/density.check.mjs && node --experimental-strip-types scripts/styles.check.mjs && node --experimental-strip-types scripts/contrast.check.mjs && node --experimental-strip-types scripts/primitives.check.mjs && node scripts/state-matrix-registers.check.mjs && node --experimental-strip-types scripts/paper.check.mjs && node --experimental-strip-types scripts/list-item.check.mjs && node --experimental-strip-types scripts/slider.check.mjs && node --experimental-strip-types scripts/input.check.mjs && node --experimental-strip-types scripts/menu.check.mjs && node --experimental-strip-types scripts/guard.check.mjs && node --experimental-strip-types scripts/breakpoints.check.mjs && node --experimental-strip-types scripts/viewport-observer.check.mjs && node --experimental-strip-types scripts/focus-trap.check.mjs && node --experimental-strip-types scripts/select-typeahead.check.mjs && node --experimental-strip-types scripts/select-groups.check.mjs && node --experimental-strip-types scripts/select-multi.check.mjs && node --experimental-strip-types scripts/select-polish.check.mjs && node --experimental-strip-types scripts/reduced-motion.check.mjs && node --experimental-strip-types scripts/card.check.mjs && node --experimental-strip-types scripts/chip.check.mjs && node --experimental-strip-types scripts/badge.check.mjs && node --experimental-strip-types scripts/avatar.check.mjs && node --experimental-strip-types scripts/imageList.check.mjs && node --experimental-strip-types scripts/drawer.check.mjs && node --experimental-strip-types scripts/breadcrumbs.check.mjs && node --experimental-strip-types scripts/pagination.check.mjs && node --experimental-strip-types scripts/stepper.check.mjs && node --experimental-strip-types scripts/accordion.check.mjs && node --experimental-strip-types scripts/snackbar.check.mjs && node --experimental-strip-types scripts/table.check.mjs && node --experimental-strip-types scripts/table-columns.check.mjs && node --experimental-strip-types scripts/reorder.check.mjs && node --experimental-strip-types scripts/autocomplete.check.mjs && node --experimental-strip-types scripts/field-loading.check.mjs && node --experimental-strip-types scripts/fab.check.mjs && node --experimental-strip-types scripts/appbar.check.mjs && node --experimental-strip-types scripts/bottom-navigation.check.mjs && node --experimental-strip-types scripts/alert.check.mjs && node --experimental-strip-types scripts/toggle-button.check.mjs && node --experimental-strip-types scripts/link.check.mjs && node --experimental-strip-types scripts/rating.check.mjs && node --experimental-strip-types scripts/stack.check.mjs && node --experimental-strip-types scripts/flex-item.check.mjs && node --experimental-strip-types scripts/grid.check.mjs && node --experimental-strip-types scripts/speed-dial.check.mjs && node --experimental-strip-types scripts/form-text.check.mjs && node --experimental-strip-types scripts/box.check.mjs && node --experimental-strip-types scripts/scroll-view.check.mjs && node --experimental-strip-types scripts/image-list.check.mjs && node --experimental-strip-types scripts/radio-group.check.mjs && node --experimental-strip-types scripts/container.check.mjs && node --experimental-strip-types scripts/divider.check.mjs && node --experimental-strip-types scripts/markdown.check.mjs && node --experimental-strip-types scripts/switch.check.mjs && node --experimental-strip-types scripts/tabs.check.mjs && node --experimental-strip-types scripts/dialog.check.mjs && node --experimental-strip-types scripts/backdrop.check.mjs && node --experimental-strip-types scripts/cframe-editor.check.mjs && node --experimental-strip-types scripts/enum-picker.check.mjs && node --experimental-strip-types scripts/number-range.check.mjs && node --experimental-strip-types scripts/date-range.check.mjs && node --experimental-strip-types scripts/sparkline.check.mjs && node --experimental-strip-types scripts/rect-editor.check.mjs && node --experimental-strip-types scripts/asset-field.check.mjs && node --experimental-strip-types scripts/gradient-editor.check.mjs && node --experimental-strip-types scripts/ray-editor.check.mjs && node --experimental-strip-types scripts/physical-properties.check.mjs && node --experimental-strip-types scripts/brickcolor-picker.check.mjs",
|
|
12
12
|
"prepublishOnly": "pnpm build"
|
|
13
13
|
},
|
|
14
14
|
"keywords": [
|