@rbxts/uiblox 0.2.0-alpha.32 → 0.2.0-alpha.34
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/dateRange/components/DateRangePicker.d.ts +11 -0
- package/out/ui/packages/dateRange/components/DateRangePicker.luau +253 -0
- package/out/ui/packages/dateRange/dateRangeValue.d.ts +18 -0
- package/out/ui/packages/dateRange/dateRangeValue.luau +121 -0
- package/out/ui/packages/dateRange/index.d.ts +3 -0
- package/out/ui/packages/dateRange/init.luau +16 -0
- package/out/ui/packages/index.d.ts +2 -0
- package/out/ui/packages/init.luau +6 -0
- package/out/ui/packages/sparkline/components/Sparkline.d.ts +9 -0
- package/out/ui/packages/sparkline/components/Sparkline.luau +66 -0
- package/out/ui/packages/sparkline/index.d.ts +3 -0
- package/out/ui/packages/sparkline/init.luau +6 -0
- package/out/ui/packages/sparkline/sparklineLayout.d.ts +8 -0
- package/out/ui/packages/sparkline/sparklineLayout.luau +75 -0
- package/package.json +2 -2
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CustomizedProps } from "../../../../theme/index";
|
|
2
|
+
import { DateSpan } from "../dateRangeValue";
|
|
3
|
+
export interface DateRangePickerProps {
|
|
4
|
+
year: number;
|
|
5
|
+
month: number;
|
|
6
|
+
value: DateSpan;
|
|
7
|
+
onChange: (value: DateSpan) => void;
|
|
8
|
+
onMonthChange: (year: number, month: number) => void;
|
|
9
|
+
}
|
|
10
|
+
declare function DateRangePicker(props: CustomizedProps<Frame, DateRangePickerProps>): JSX.Element;
|
|
11
|
+
export default DateRangePicker;
|
|
@@ -0,0 +1,253 @@
|
|
|
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 useTheme = TS.import(script, script.Parent.Parent.Parent.Parent.Parent, "theme").useTheme
|
|
5
|
+
local SxHost = TS.import(script, script.Parent.Parent.Parent, "host").SxHost
|
|
6
|
+
local _dateRangeValue = TS.import(script, script.Parent.Parent, "dateRangeValue")
|
|
7
|
+
local dateStamp = _dateRangeValue.dateStamp
|
|
8
|
+
local daysInMonth = _dateRangeValue.daysInMonth
|
|
9
|
+
local formatStamp = _dateRangeValue.formatStamp
|
|
10
|
+
local orderSpan = _dateRangeValue.orderSpan
|
|
11
|
+
local shiftMonth = _dateRangeValue.shiftMonth
|
|
12
|
+
local weekday = _dateRangeValue.weekday
|
|
13
|
+
local MONTHS = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }
|
|
14
|
+
local WEEKDAYS = { "S", "M", "T", "W", "T", "F", "S" }
|
|
15
|
+
local function covers(stamp, value)
|
|
16
|
+
if value.start == nil then
|
|
17
|
+
return false
|
|
18
|
+
end
|
|
19
|
+
if value.finish == nil then
|
|
20
|
+
return stamp == value.start
|
|
21
|
+
end
|
|
22
|
+
local first = math.min(value.start, value.finish)
|
|
23
|
+
local last = math.max(value.start, value.finish)
|
|
24
|
+
return stamp >= first and stamp <= last
|
|
25
|
+
end
|
|
26
|
+
local function DateRangePicker(props)
|
|
27
|
+
local _binding = props
|
|
28
|
+
local year = _binding.year
|
|
29
|
+
local month = _binding.month
|
|
30
|
+
local value = _binding.value
|
|
31
|
+
local onChange = _binding.onChange
|
|
32
|
+
local onMonthChange = _binding.onMonthChange
|
|
33
|
+
local className = _binding.className
|
|
34
|
+
local sx = _binding.sx
|
|
35
|
+
local id = _binding.id
|
|
36
|
+
local ref = _binding.ref
|
|
37
|
+
local _binding_1 = useTheme()
|
|
38
|
+
local theme = _binding_1.theme
|
|
39
|
+
local lead = weekday(year, month, 1)
|
|
40
|
+
local count = daysInMonth(year, month)
|
|
41
|
+
local cells = {}
|
|
42
|
+
do
|
|
43
|
+
local index = 0
|
|
44
|
+
local _shouldIncrement = false
|
|
45
|
+
while true do
|
|
46
|
+
if _shouldIncrement then
|
|
47
|
+
index += 1
|
|
48
|
+
else
|
|
49
|
+
_shouldIncrement = true
|
|
50
|
+
end
|
|
51
|
+
if not (index < lead) then
|
|
52
|
+
break
|
|
53
|
+
end
|
|
54
|
+
local _arg0 = {
|
|
55
|
+
order = index,
|
|
56
|
+
}
|
|
57
|
+
table.insert(cells, _arg0)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
do
|
|
61
|
+
local day = 1
|
|
62
|
+
local _shouldIncrement = false
|
|
63
|
+
while true do
|
|
64
|
+
if _shouldIncrement then
|
|
65
|
+
day += 1
|
|
66
|
+
else
|
|
67
|
+
_shouldIncrement = true
|
|
68
|
+
end
|
|
69
|
+
if not (day <= count) then
|
|
70
|
+
break
|
|
71
|
+
end
|
|
72
|
+
local _arg0 = {
|
|
73
|
+
day = day,
|
|
74
|
+
stamp = dateStamp(year, month, day),
|
|
75
|
+
order = lead + day - 1,
|
|
76
|
+
}
|
|
77
|
+
table.insert(cells, _arg0)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
local pick = function(stamp)
|
|
81
|
+
if value.start == nil or value.finish ~= nil then
|
|
82
|
+
onChange({
|
|
83
|
+
start = stamp,
|
|
84
|
+
})
|
|
85
|
+
else
|
|
86
|
+
onChange(orderSpan(value.start, stamp))
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
local move = function(delta)
|
|
90
|
+
local shifted = shiftMonth(year, month, delta)
|
|
91
|
+
onMonthChange(shifted.year, shifted.month)
|
|
92
|
+
end
|
|
93
|
+
local _attributes = {
|
|
94
|
+
tag = "frame",
|
|
95
|
+
}
|
|
96
|
+
local _condition = id
|
|
97
|
+
if not (_condition ~= 0 and _condition == _condition and _condition ~= "" and _condition) then
|
|
98
|
+
_condition = "DateRangePicker"
|
|
99
|
+
end
|
|
100
|
+
_attributes.key = _condition
|
|
101
|
+
_attributes.hostRef = ref
|
|
102
|
+
_attributes.base = {
|
|
103
|
+
Size = UDim2.new(1, 0, 0, 0),
|
|
104
|
+
AutomaticSize = Enum.AutomaticSize.Y,
|
|
105
|
+
BackgroundColor3 = theme.palette.surface.paper,
|
|
106
|
+
BorderSizePixel = 0,
|
|
107
|
+
}
|
|
108
|
+
_attributes.className = className
|
|
109
|
+
_attributes.sx = sx
|
|
110
|
+
local _exp = React.createElement("uipadding", {
|
|
111
|
+
PaddingTop = UDim.new(0, 8),
|
|
112
|
+
PaddingBottom = UDim.new(0, 8),
|
|
113
|
+
PaddingLeft = UDim.new(0, 8),
|
|
114
|
+
PaddingRight = UDim.new(0, 8),
|
|
115
|
+
})
|
|
116
|
+
local _exp_1 = React.createElement("uilistlayout", {
|
|
117
|
+
FillDirection = Enum.FillDirection.Vertical,
|
|
118
|
+
Padding = UDim.new(0, 8),
|
|
119
|
+
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
120
|
+
})
|
|
121
|
+
local _exp_2 = React.createElement("textbutton", {
|
|
122
|
+
Text = "Prev",
|
|
123
|
+
Size = UDim2.fromOffset(56, 28),
|
|
124
|
+
BackgroundTransparency = 1,
|
|
125
|
+
BorderSizePixel = 0,
|
|
126
|
+
TextColor3 = theme.palette.text.secondary,
|
|
127
|
+
Font = theme.typography.fontFamilies.default,
|
|
128
|
+
TextSize = theme.typography.fontSizes.caption,
|
|
129
|
+
Event = {
|
|
130
|
+
Activated = function()
|
|
131
|
+
return move(-1)
|
|
132
|
+
end,
|
|
133
|
+
},
|
|
134
|
+
})
|
|
135
|
+
local _attributes_1 = {}
|
|
136
|
+
local _condition_1 = MONTHS[month]
|
|
137
|
+
if _condition_1 == nil then
|
|
138
|
+
_condition_1 = ""
|
|
139
|
+
end
|
|
140
|
+
_attributes_1.Text = `{_condition_1} {year}`
|
|
141
|
+
_attributes_1.AnchorPoint = Vector2.new(0.5, 0)
|
|
142
|
+
_attributes_1.Position = UDim2.fromScale(0.5, 0)
|
|
143
|
+
_attributes_1.Size = UDim2.fromOffset(140, 28)
|
|
144
|
+
_attributes_1.BackgroundTransparency = 1
|
|
145
|
+
_attributes_1.BorderSizePixel = 0
|
|
146
|
+
_attributes_1.TextColor3 = theme.palette.text.primary
|
|
147
|
+
_attributes_1.Font = theme.typography.fontFamilies.semibold
|
|
148
|
+
_attributes_1.TextSize = theme.typography.fontSizes.body
|
|
149
|
+
local _exp_3 = React.createElement("frame", {
|
|
150
|
+
Size = UDim2.new(1, 0, 0, 28),
|
|
151
|
+
BackgroundTransparency = 1,
|
|
152
|
+
BorderSizePixel = 0,
|
|
153
|
+
LayoutOrder = 0,
|
|
154
|
+
}, _exp_2, React.createElement("textlabel", _attributes_1), React.createElement("textbutton", {
|
|
155
|
+
Text = "Next",
|
|
156
|
+
AnchorPoint = Vector2.new(1, 0),
|
|
157
|
+
Position = UDim2.fromScale(1, 0),
|
|
158
|
+
Size = UDim2.fromOffset(56, 28),
|
|
159
|
+
BackgroundTransparency = 1,
|
|
160
|
+
BorderSizePixel = 0,
|
|
161
|
+
TextColor3 = theme.palette.text.secondary,
|
|
162
|
+
Font = theme.typography.fontFamilies.default,
|
|
163
|
+
TextSize = theme.typography.fontSizes.caption,
|
|
164
|
+
Event = {
|
|
165
|
+
Activated = function()
|
|
166
|
+
return move(1)
|
|
167
|
+
end,
|
|
168
|
+
},
|
|
169
|
+
}))
|
|
170
|
+
local _exp_4 = React.createElement("textlabel", {
|
|
171
|
+
Text = if value.start == nil then "Choose a start and finish" elseif value.finish == nil then formatStamp(value.start) else `{formatStamp(value.start)} – {formatStamp(value.finish)}`,
|
|
172
|
+
Size = UDim2.new(1, 0, 0, 16),
|
|
173
|
+
BackgroundTransparency = 1,
|
|
174
|
+
BorderSizePixel = 0,
|
|
175
|
+
TextXAlignment = Enum.TextXAlignment.Left,
|
|
176
|
+
TextColor3 = theme.palette.text.secondary,
|
|
177
|
+
Font = theme.typography.fontFamilies.default,
|
|
178
|
+
TextSize = theme.typography.fontSizes.caption,
|
|
179
|
+
LayoutOrder = 1,
|
|
180
|
+
})
|
|
181
|
+
local _exp_5 = React.createElement("uigridlayout", {
|
|
182
|
+
CellSize = UDim2.fromOffset(36, 28),
|
|
183
|
+
CellPadding = UDim2.fromOffset(4, 4),
|
|
184
|
+
FillDirectionMaxCells = 7,
|
|
185
|
+
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
186
|
+
})
|
|
187
|
+
-- ▼ ReadonlyArray.map ▼
|
|
188
|
+
local _newValue = table.create(#WEEKDAYS)
|
|
189
|
+
local _callback = function(label, index)
|
|
190
|
+
return React.createElement("textlabel", {
|
|
191
|
+
key = `week-{index}`,
|
|
192
|
+
Text = label,
|
|
193
|
+
LayoutOrder = index,
|
|
194
|
+
BackgroundTransparency = 1,
|
|
195
|
+
BorderSizePixel = 0,
|
|
196
|
+
TextColor3 = theme.palette.text.secondary,
|
|
197
|
+
Font = theme.typography.fontFamilies.default,
|
|
198
|
+
TextSize = theme.typography.fontSizes.caption,
|
|
199
|
+
})
|
|
200
|
+
end
|
|
201
|
+
for _k, _v in WEEKDAYS do
|
|
202
|
+
_newValue[_k] = _callback(_v, _k - 1, WEEKDAYS)
|
|
203
|
+
end
|
|
204
|
+
-- ▲ ReadonlyArray.map ▲
|
|
205
|
+
-- ▼ ReadonlyArray.map ▼
|
|
206
|
+
local _newValue_1 = table.create(#cells)
|
|
207
|
+
local _callback_1 = function(cell)
|
|
208
|
+
local stamp = cell.stamp
|
|
209
|
+
local chosen = stamp ~= nil and covers(stamp, value)
|
|
210
|
+
local endpoint = stamp ~= nil and (stamp == value.start or stamp == value.finish)
|
|
211
|
+
if stamp == nil or cell.day == nil then
|
|
212
|
+
return React.createElement("frame", {
|
|
213
|
+
key = `blank-{cell.order}`,
|
|
214
|
+
LayoutOrder = 10 + cell.order,
|
|
215
|
+
BackgroundTransparency = 1,
|
|
216
|
+
BorderSizePixel = 0,
|
|
217
|
+
})
|
|
218
|
+
end
|
|
219
|
+
return React.createElement("textbutton", {
|
|
220
|
+
key = `day-{stamp}`,
|
|
221
|
+
Text = tostring(cell.day),
|
|
222
|
+
LayoutOrder = 10 + cell.order,
|
|
223
|
+
BackgroundColor3 = if chosen then theme.palette.primary.main else theme.palette.surface.input,
|
|
224
|
+
BackgroundTransparency = if chosen and not endpoint then 0.55 else 0,
|
|
225
|
+
BorderSizePixel = 0,
|
|
226
|
+
TextColor3 = if endpoint then theme.palette.primary.on else theme.palette.text.primary,
|
|
227
|
+
Font = theme.typography.fontFamilies.default,
|
|
228
|
+
TextSize = theme.typography.fontSizes.body,
|
|
229
|
+
AutoButtonColor = false,
|
|
230
|
+
Event = {
|
|
231
|
+
Activated = function()
|
|
232
|
+
return pick(stamp)
|
|
233
|
+
end,
|
|
234
|
+
},
|
|
235
|
+
}, React.createElement("uicorner", {
|
|
236
|
+
CornerRadius = UDim.new(0, 4),
|
|
237
|
+
}))
|
|
238
|
+
end
|
|
239
|
+
for _k, _v in cells do
|
|
240
|
+
_newValue_1[_k] = _callback_1(_v, _k - 1, cells)
|
|
241
|
+
end
|
|
242
|
+
-- ▲ ReadonlyArray.map ▲
|
|
243
|
+
return React.createElement(SxHost, _attributes, _exp, _exp_1, _exp_3, _exp_4, React.createElement("frame", {
|
|
244
|
+
Size = UDim2.new(1, 0, 0, 248),
|
|
245
|
+
BackgroundTransparency = 1,
|
|
246
|
+
BorderSizePixel = 0,
|
|
247
|
+
LayoutOrder = 2,
|
|
248
|
+
}, _exp_5, _newValue, _newValue_1))
|
|
249
|
+
end
|
|
250
|
+
local default = DateRangePicker
|
|
251
|
+
return {
|
|
252
|
+
default = default,
|
|
253
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface DateSpan {
|
|
2
|
+
start?: number;
|
|
3
|
+
finish?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare function isLeapYear(year: number): boolean;
|
|
6
|
+
export declare function daysInMonth(year: number, month: number): number;
|
|
7
|
+
/** Sunday is 0. */
|
|
8
|
+
export declare function weekday(year: number, month: number, day: number): number;
|
|
9
|
+
export declare function dateStamp(year: number, month: number, day: number): number;
|
|
10
|
+
export declare function shiftMonth(year: number, month: number, delta: number): {
|
|
11
|
+
year: number;
|
|
12
|
+
month: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function orderSpan(first: number, second: number): DateSpan;
|
|
15
|
+
export declare function dayIndex(stamp: number): number;
|
|
16
|
+
export declare function nightsBetween(start: number, finish: number): number;
|
|
17
|
+
export declare function formatStamp(stamp: number): string;
|
|
18
|
+
export declare function formatSpan(value: DateSpan): string;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local MONTHS = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }
|
|
3
|
+
local MONTH_LENGTHS = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
|
4
|
+
local WEEKDAY_OFFSET = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }
|
|
5
|
+
local function isLeapYear(year)
|
|
6
|
+
return year % 4 == 0 and (year % 100 ~= 0 or year % 400 == 0)
|
|
7
|
+
end
|
|
8
|
+
local function daysInMonth(year, month)
|
|
9
|
+
if month == 2 and isLeapYear(year) then
|
|
10
|
+
return 29
|
|
11
|
+
end
|
|
12
|
+
local _condition = MONTH_LENGTHS[month]
|
|
13
|
+
if _condition == nil then
|
|
14
|
+
_condition = 30
|
|
15
|
+
end
|
|
16
|
+
return _condition
|
|
17
|
+
end
|
|
18
|
+
--* Sunday is 0.
|
|
19
|
+
local function weekday(year, month, day)
|
|
20
|
+
local adjusted = year
|
|
21
|
+
if month < 3 then
|
|
22
|
+
adjusted -= 1
|
|
23
|
+
end
|
|
24
|
+
local sum = adjusted + math.floor(adjusted / 4) - math.floor(adjusted / 100) + math.floor(adjusted / 400) + WEEKDAY_OFFSET[month] + day
|
|
25
|
+
return sum % 7
|
|
26
|
+
end
|
|
27
|
+
local function dateStamp(year, month, day)
|
|
28
|
+
return year * 10000 + month * 100 + day
|
|
29
|
+
end
|
|
30
|
+
local function shiftMonth(year, month, delta)
|
|
31
|
+
local index = year * 12 + (month - 1) + delta
|
|
32
|
+
local nextYear = math.floor(index / 12)
|
|
33
|
+
local remainder = index % 12
|
|
34
|
+
if remainder < 0 then
|
|
35
|
+
remainder += 12
|
|
36
|
+
nextYear -= 1
|
|
37
|
+
end
|
|
38
|
+
return {
|
|
39
|
+
year = nextYear,
|
|
40
|
+
month = remainder + 1,
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
local function orderSpan(first, second)
|
|
44
|
+
return if first <= second then {
|
|
45
|
+
start = first,
|
|
46
|
+
finish = second,
|
|
47
|
+
} else {
|
|
48
|
+
start = second,
|
|
49
|
+
finish = first,
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
local function dayIndex(stamp)
|
|
53
|
+
local year = math.floor(stamp / 10000)
|
|
54
|
+
local month = math.floor(stamp / 100) % 100
|
|
55
|
+
local day = stamp % 100
|
|
56
|
+
local index = day
|
|
57
|
+
do
|
|
58
|
+
local cursor = 1
|
|
59
|
+
local _shouldIncrement = false
|
|
60
|
+
while true do
|
|
61
|
+
if _shouldIncrement then
|
|
62
|
+
cursor += 1
|
|
63
|
+
else
|
|
64
|
+
_shouldIncrement = true
|
|
65
|
+
end
|
|
66
|
+
if not (cursor < year) then
|
|
67
|
+
break
|
|
68
|
+
end
|
|
69
|
+
index += if isLeapYear(cursor) then 366 else 365
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
do
|
|
73
|
+
local cursor = 1
|
|
74
|
+
local _shouldIncrement = false
|
|
75
|
+
while true do
|
|
76
|
+
if _shouldIncrement then
|
|
77
|
+
cursor += 1
|
|
78
|
+
else
|
|
79
|
+
_shouldIncrement = true
|
|
80
|
+
end
|
|
81
|
+
if not (cursor < month) then
|
|
82
|
+
break
|
|
83
|
+
end
|
|
84
|
+
index += daysInMonth(year, cursor)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
return index
|
|
88
|
+
end
|
|
89
|
+
local function nightsBetween(start, finish)
|
|
90
|
+
return math.abs(dayIndex(finish) - dayIndex(start))
|
|
91
|
+
end
|
|
92
|
+
local function formatStamp(stamp)
|
|
93
|
+
local month = math.floor(stamp / 100) % 100
|
|
94
|
+
local day = stamp % 100
|
|
95
|
+
local _condition = MONTHS[month]
|
|
96
|
+
if _condition == nil then
|
|
97
|
+
_condition = "Day"
|
|
98
|
+
end
|
|
99
|
+
return `{_condition} {day}`
|
|
100
|
+
end
|
|
101
|
+
local function formatSpan(value)
|
|
102
|
+
if value.start == nil then
|
|
103
|
+
return "Choose dates"
|
|
104
|
+
end
|
|
105
|
+
if value.finish == nil then
|
|
106
|
+
return formatStamp(value.start)
|
|
107
|
+
end
|
|
108
|
+
return `{formatStamp(value.start)} – {formatStamp(value.finish)}`
|
|
109
|
+
end
|
|
110
|
+
return {
|
|
111
|
+
isLeapYear = isLeapYear,
|
|
112
|
+
daysInMonth = daysInMonth,
|
|
113
|
+
weekday = weekday,
|
|
114
|
+
dateStamp = dateStamp,
|
|
115
|
+
shiftMonth = shiftMonth,
|
|
116
|
+
orderSpan = orderSpan,
|
|
117
|
+
dayIndex = dayIndex,
|
|
118
|
+
nightsBetween = nightsBetween,
|
|
119
|
+
formatStamp = formatStamp,
|
|
120
|
+
formatSpan = formatSpan,
|
|
121
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { default as DateRangePicker } from "./components/DateRangePicker";
|
|
2
|
+
export { DateRangePickerProps } from "./components/DateRangePicker";
|
|
3
|
+
export { DateSpan, dateStamp, dayIndex, daysInMonth, formatSpan, formatStamp, isLeapYear, nightsBetween, orderSpan, shiftMonth, weekday, } from "./dateRangeValue";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local exports = {}
|
|
4
|
+
exports.DateRangePicker = TS.import(script, script, "components", "DateRangePicker").default
|
|
5
|
+
local _dateRangeValue = TS.import(script, script, "dateRangeValue")
|
|
6
|
+
exports.dateStamp = _dateRangeValue.dateStamp
|
|
7
|
+
exports.dayIndex = _dateRangeValue.dayIndex
|
|
8
|
+
exports.daysInMonth = _dateRangeValue.daysInMonth
|
|
9
|
+
exports.formatSpan = _dateRangeValue.formatSpan
|
|
10
|
+
exports.formatStamp = _dateRangeValue.formatStamp
|
|
11
|
+
exports.isLeapYear = _dateRangeValue.isLeapYear
|
|
12
|
+
exports.nightsBetween = _dateRangeValue.nightsBetween
|
|
13
|
+
exports.orderSpan = _dateRangeValue.orderSpan
|
|
14
|
+
exports.shiftMonth = _dateRangeValue.shiftMonth
|
|
15
|
+
exports.weekday = _dateRangeValue.weekday
|
|
16
|
+
return exports
|
|
@@ -23,6 +23,8 @@ export * from "./fontEditor/index";
|
|
|
23
23
|
export * from "./loadingStroke/index";
|
|
24
24
|
export * from "./numberInput/index";
|
|
25
25
|
export * from "./numberRangeEditor/index";
|
|
26
|
+
export * from "./dateRange/index";
|
|
27
|
+
export * from "./sparkline/index";
|
|
26
28
|
export * from "./rectEditor/index";
|
|
27
29
|
export * from "./rayEditor/index";
|
|
28
30
|
export * from "./physicalPropertiesEditor/index";
|
|
@@ -76,6 +76,12 @@ end
|
|
|
76
76
|
for _k, _v in TS.import(script, script, "numberRangeEditor") or {} do
|
|
77
77
|
exports[_k] = _v
|
|
78
78
|
end
|
|
79
|
+
for _k, _v in TS.import(script, script, "dateRange") or {} do
|
|
80
|
+
exports[_k] = _v
|
|
81
|
+
end
|
|
82
|
+
for _k, _v in TS.import(script, script, "sparkline") or {} do
|
|
83
|
+
exports[_k] = _v
|
|
84
|
+
end
|
|
79
85
|
for _k, _v in TS.import(script, script, "rectEditor") or {} do
|
|
80
86
|
exports[_k] = _v
|
|
81
87
|
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CustomizedProps } from "../../../../theme/index";
|
|
2
|
+
export interface SparklineProps {
|
|
3
|
+
values: number[];
|
|
4
|
+
width?: number;
|
|
5
|
+
height?: number;
|
|
6
|
+
color?: Color3;
|
|
7
|
+
}
|
|
8
|
+
declare function Sparkline(props: CustomizedProps<Frame, SparklineProps>): JSX.Element;
|
|
9
|
+
export default Sparkline;
|
|
@@ -0,0 +1,66 @@
|
|
|
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 useTheme = TS.import(script, script.Parent.Parent.Parent.Parent.Parent, "theme").useTheme
|
|
5
|
+
local SxHost = TS.import(script, script.Parent.Parent.Parent, "host").SxHost
|
|
6
|
+
local sparklineLayout = TS.import(script, script.Parent.Parent, "sparklineLayout").sparklineLayout
|
|
7
|
+
local function Sparkline(props)
|
|
8
|
+
local _binding = props
|
|
9
|
+
local values = _binding.values
|
|
10
|
+
local width = _binding.width
|
|
11
|
+
if width == nil then
|
|
12
|
+
width = 120
|
|
13
|
+
end
|
|
14
|
+
local height = _binding.height
|
|
15
|
+
if height == nil then
|
|
16
|
+
height = 36
|
|
17
|
+
end
|
|
18
|
+
local color = _binding.color
|
|
19
|
+
local className = _binding.className
|
|
20
|
+
local sx = _binding.sx
|
|
21
|
+
local id = _binding.id
|
|
22
|
+
local ref = _binding.ref
|
|
23
|
+
local _binding_1 = useTheme()
|
|
24
|
+
local theme = _binding_1.theme
|
|
25
|
+
local segments = sparklineLayout(values, width, height)
|
|
26
|
+
local stroke = color or theme.palette.primary.main
|
|
27
|
+
local _attributes = {
|
|
28
|
+
tag = "frame",
|
|
29
|
+
}
|
|
30
|
+
local _condition = id
|
|
31
|
+
if not (_condition ~= 0 and _condition == _condition and _condition ~= "" and _condition) then
|
|
32
|
+
_condition = "Sparkline"
|
|
33
|
+
end
|
|
34
|
+
_attributes.key = _condition
|
|
35
|
+
_attributes.hostRef = ref
|
|
36
|
+
_attributes.base = {
|
|
37
|
+
Size = UDim2.fromOffset(width, height),
|
|
38
|
+
BackgroundTransparency = 1,
|
|
39
|
+
BorderSizePixel = 0,
|
|
40
|
+
ClipsDescendants = true,
|
|
41
|
+
}
|
|
42
|
+
_attributes.className = className
|
|
43
|
+
_attributes.sx = sx
|
|
44
|
+
-- ▼ ReadonlyArray.map ▼
|
|
45
|
+
local _newValue = table.create(#segments)
|
|
46
|
+
local _callback = function(segment, index)
|
|
47
|
+
return React.createElement("frame", {
|
|
48
|
+
key = `s-{index}`,
|
|
49
|
+
AnchorPoint = Vector2.new(0.5, 0.5),
|
|
50
|
+
Position = UDim2.fromOffset(segment.x, segment.y),
|
|
51
|
+
Size = UDim2.fromOffset(segment.length, 2),
|
|
52
|
+
Rotation = segment.rotation,
|
|
53
|
+
BackgroundColor3 = stroke,
|
|
54
|
+
BorderSizePixel = 0,
|
|
55
|
+
})
|
|
56
|
+
end
|
|
57
|
+
for _k, _v in segments do
|
|
58
|
+
_newValue[_k] = _callback(_v, _k - 1, segments)
|
|
59
|
+
end
|
|
60
|
+
-- ▲ ReadonlyArray.map ▲
|
|
61
|
+
return React.createElement(SxHost, _attributes, _newValue)
|
|
62
|
+
end
|
|
63
|
+
local default = Sparkline
|
|
64
|
+
return {
|
|
65
|
+
default = default,
|
|
66
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface SparkSegment {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
length: number;
|
|
5
|
+
rotation: number;
|
|
6
|
+
}
|
|
7
|
+
/** Line segments for a number series. Empty and single-point series draw nothing. */
|
|
8
|
+
export declare function sparklineLayout(values: number[], width: number, height: number, pad?: number): SparkSegment[];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
--* Line segments for a number series. Empty and single-point series draw nothing.
|
|
3
|
+
local function sparklineLayout(values, width, height, pad)
|
|
4
|
+
if pad == nil then
|
|
5
|
+
pad = 4
|
|
6
|
+
end
|
|
7
|
+
local count = #values
|
|
8
|
+
if count < 2 or width <= pad * 2 or height <= pad * 2 then
|
|
9
|
+
return {}
|
|
10
|
+
end
|
|
11
|
+
local min = values[1]
|
|
12
|
+
local max = values[1]
|
|
13
|
+
for _, value in values do
|
|
14
|
+
if value < min then
|
|
15
|
+
min = value
|
|
16
|
+
end
|
|
17
|
+
if value > max then
|
|
18
|
+
max = value
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
local span = math.max(max - min, 1)
|
|
22
|
+
local innerW = width - pad * 2
|
|
23
|
+
local innerH = height - pad * 2
|
|
24
|
+
local step = innerW / (count - 1)
|
|
25
|
+
local points = {}
|
|
26
|
+
do
|
|
27
|
+
local index = 0
|
|
28
|
+
local _shouldIncrement = false
|
|
29
|
+
while true do
|
|
30
|
+
if _shouldIncrement then
|
|
31
|
+
index += 1
|
|
32
|
+
else
|
|
33
|
+
_shouldIncrement = true
|
|
34
|
+
end
|
|
35
|
+
if not (index < count) then
|
|
36
|
+
break
|
|
37
|
+
end
|
|
38
|
+
local _arg0 = {
|
|
39
|
+
x = pad + index * step,
|
|
40
|
+
y = pad + (1 - (values[index + 1] - min) / span) * innerH,
|
|
41
|
+
}
|
|
42
|
+
table.insert(points, _arg0)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
local segments = {}
|
|
46
|
+
do
|
|
47
|
+
local index = 0
|
|
48
|
+
local _shouldIncrement = false
|
|
49
|
+
while true do
|
|
50
|
+
if _shouldIncrement then
|
|
51
|
+
index += 1
|
|
52
|
+
else
|
|
53
|
+
_shouldIncrement = true
|
|
54
|
+
end
|
|
55
|
+
if not (index < count - 1) then
|
|
56
|
+
break
|
|
57
|
+
end
|
|
58
|
+
local start = points[index + 1]
|
|
59
|
+
local finish = points[index + 2]
|
|
60
|
+
local dx = finish.x - start.x
|
|
61
|
+
local dy = finish.y - start.y
|
|
62
|
+
local _arg0 = {
|
|
63
|
+
x = (start.x + finish.x) / 2,
|
|
64
|
+
y = (start.y + finish.y) / 2,
|
|
65
|
+
length = math.sqrt(dx * dx + dy * dy),
|
|
66
|
+
rotation = math.deg(math.atan2(dy, dx)),
|
|
67
|
+
}
|
|
68
|
+
table.insert(segments, _arg0)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
return segments
|
|
72
|
+
end
|
|
73
|
+
return {
|
|
74
|
+
sparklineLayout = sparklineLayout,
|
|
75
|
+
}
|
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.34",
|
|
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/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/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": [
|