@rbxts/uiblox 0.2.0-alpha.30 → 0.2.0-alpha.32

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.
@@ -5,5 +5,5 @@ export { applyVariants, CompoundVariant } from "./variants";
5
5
  export { default as componentStyles } from "./componentStyles";
6
6
  export { resolveResponsive, Responsive } from "../../../hooks/breakpoints";
7
7
  export { clearStyleCaches, createStyleCache, styleDepsKey } from "./styleCache";
8
- export { resolveSx, resolvePaletteToken, PaletteToken, ResolvedSx, SxColor, SxInput } from "./resolveSx";
8
+ export { resolveSx, resolvePaletteToken, PaletteToken, ResolvedSx, SxColor, SxGradient, SxInput } from "./resolveSx";
9
9
  export { interactionStyle, InteractionSlots, InteractionState, resolveStyle, StyleSelectorKey, StyleState, StyleWithSelectors, } from "./resolveStyle";
@@ -33,6 +33,11 @@ interface SxTheme {
33
33
  };
34
34
  }
35
35
  export type SxColor = PaletteToken | Color3;
36
+ /** Evenly spaced color stops on a UIGradient child. */
37
+ export interface SxGradient {
38
+ colors: SxColor[];
39
+ rotation?: number;
40
+ }
36
41
  /** CSS-like shorthands + pass-through Instance props. No CSS string parser. */
37
42
  export type SxInput = {
38
43
  width?: Responsive<number | UDim | UDim2>;
@@ -73,6 +78,7 @@ export type SxInput = {
73
78
  visible?: Responsive<boolean>;
74
79
  zIndex?: Responsive<number>;
75
80
  z?: Responsive<number>;
81
+ gradient?: Responsive<SxGradient>;
76
82
  _hover?: SxInput;
77
83
  _pressed?: SxInput;
78
84
  _focus?: SxInput;
@@ -101,6 +107,10 @@ export interface ResolvedSx {
101
107
  CornerRadius: UDim;
102
108
  };
103
109
  gap?: number;
110
+ gradient?: {
111
+ Color: ColorSequence;
112
+ Rotation: number;
113
+ };
104
114
  }
105
115
  /**
106
116
  * Maps sx shorthands / tokens → Instance props (+ UIPadding / UICorner / gap helpers).
@@ -106,7 +106,9 @@ local SHORTHAND = {
106
106
  visible = true,
107
107
  zIndex = true,
108
108
  z = true,
109
+ gradient = true,
109
110
  }
111
+ --* Evenly spaced color stops on a UIGradient child.
110
112
  --* CSS-like shorthands + pass-through Instance props. No CSS string parser.
111
113
  local function pick(value, width)
112
114
  if value == nil then
@@ -440,6 +442,46 @@ local function resolveSx(theme, sx, width)
440
442
  if zIndex ~= nil then
441
443
  root.ZIndex = zIndex
442
444
  end
445
+ local gradientVal = pick(sx.gradient, width)
446
+ local gradient
447
+ if gradientVal ~= nil and #gradientVal.colors > 0 then
448
+ local _exp = gradientVal.colors
449
+ -- ▼ ReadonlyArray.map ▼
450
+ local _newValue = table.create(#_exp)
451
+ local _callback = function(token)
452
+ return resolvePaletteToken(theme.palette, token)
453
+ end
454
+ for _k, _v in _exp do
455
+ _newValue[_k] = _callback(_v, _k - 1, _exp)
456
+ end
457
+ -- ▲ ReadonlyArray.map ▲
458
+ local stops = _newValue
459
+ local last = math.max(#stops - 1, 1)
460
+ -- ▼ ReadonlyArray.map ▼
461
+ local _newValue_1 = table.create(#stops)
462
+ local _callback_1 = function(color, index)
463
+ return ColorSequenceKeypoint.new(if #stops == 1 then 0 else index / last, color)
464
+ end
465
+ for _k, _v in stops do
466
+ _newValue_1[_k] = _callback_1(_v, _k - 1, stops)
467
+ end
468
+ -- ▲ ReadonlyArray.map ▲
469
+ local keypoints = _newValue_1
470
+ if #stops == 1 then
471
+ local _colorSequenceKeypoint = ColorSequenceKeypoint.new(1, stops[1])
472
+ table.insert(keypoints, _colorSequenceKeypoint)
473
+ end
474
+ local _object = {
475
+ Color = ColorSequence.new(keypoints),
476
+ }
477
+ local _left = "Rotation"
478
+ local _condition_4 = gradientVal.rotation
479
+ if _condition_4 == nil then
480
+ _condition_4 = 0
481
+ end
482
+ _object[_left] = _condition_4
483
+ gradient = _object
484
+ end
443
485
  for key, raw in pairs(sx) do
444
486
  local name = key
445
487
  if SHORTHAND[name] == true then
@@ -471,6 +513,9 @@ local function resolveSx(theme, sx, width)
471
513
  if gap ~= nil then
472
514
  resolved.gap = gap
473
515
  end
516
+ if gradient ~= nil then
517
+ resolved.gradient = gradient
518
+ end
474
519
  return resolved
475
520
  end
476
521
  return {
@@ -1,8 +1,9 @@
1
1
  import React, { PropsWithChildren } from "@rbxts/react";
2
2
  import { WriteableStyle } from "../styles/index";
3
+ import { SxInput } from "../styles/utilities/resolveSx";
3
4
  export interface CommonProps<T extends Instance> extends PropsWithChildren {
4
5
  className?: WriteableStyle<T>;
5
- sx?: WriteableStyle<T>;
6
+ sx?: WriteableStyle<T> & SxInput;
6
7
  component?: T;
7
8
  id?: React.Key;
8
9
  ref?: React.Ref<T>;
@@ -161,6 +161,7 @@ local function SxHost(props)
161
161
  local painted = {}
162
162
  local hasPad = false
163
163
  local hasCorner = false
164
+ local hasGradient = false
164
165
  for _, node in nodes do
165
166
  if not React.isValidElement(node) then
166
167
  continue
@@ -172,6 +173,9 @@ local function SxHost(props)
172
173
  if kind == "uicorner" then
173
174
  hasCorner = true
174
175
  end
176
+ if kind == "uigradient" then
177
+ hasGradient = true
178
+ end
175
179
  local patch = if kind ~= nil then layoutGapPatch(kind, elementProps(node), paint.gap) else nil
176
180
  local _arg0 = if patch ~= nil then React.cloneElement(node, patch) else node
177
181
  table.insert(painted, _arg0)
@@ -184,6 +188,10 @@ local function SxHost(props)
184
188
  local _arg0 = React.createElement("uicorner", paint.corner)
185
189
  table.insert(painted, _arg0)
186
190
  end
191
+ if not hasGradient and paint.gradient ~= nil then
192
+ local _arg0 = React.createElement("uigradient", paint.gradient)
193
+ table.insert(painted, _arg0)
194
+ end
187
195
  local _object_2 = table.clone(paint.props)
188
196
  setmetatable(_object_2, nil)
189
197
  for _k, _v in rest do
@@ -6,6 +6,7 @@ export interface HostPaint {
6
6
  };
7
7
  padding?: ResolvedSx["padding"];
8
8
  corner?: ResolvedSx["corner"];
9
+ gradient?: ResolvedSx["gradient"];
9
10
  gap?: number;
10
11
  }
11
12
  export declare function paintHostStyle(theme: Parameters<typeof resolveSx>[0], base: object | undefined, className: object | undefined, sx: SxInput | undefined, width: number | undefined, state: StyleState | undefined): HostPaint;
@@ -25,6 +25,7 @@ local function paintHostStyle(theme, base, className, sx, width, state)
25
25
  props = resolveStyle(merged, state or {}),
26
26
  padding = resolved.padding,
27
27
  corner = resolved.corner,
28
+ gradient = resolved.gradient,
28
29
  gap = resolved.gap,
29
30
  }
30
31
  end
@@ -10,6 +10,12 @@ export interface MarkdownEditorProps {
10
10
  onFullscreenChange?: (fullscreen: boolean) => void;
11
11
  preview?: (value: string) => React.Element;
12
12
  placeholder?: string;
13
+ resizable?: boolean;
14
+ height?: number;
15
+ defaultHeight?: number;
16
+ minHeight?: number;
17
+ maxHeight?: number;
18
+ onHeightChange?: (height: number) => void;
13
19
  }
14
20
  declare function MarkdownEditor(props: CustomizedProps<Frame, MarkdownEditorProps>): JSX.Element;
15
21
  export default MarkdownEditor;
@@ -13,6 +13,7 @@ local Icons = TS.import(script, script.Parent.Parent.Parent.Parent, "enums").Ico
13
13
  local ToggleButtonGroup = TS.import(script, script.Parent.Parent.Parent, "toggleButton").ToggleButtonGroup
14
14
  local htmlToMarkdown = TS.import(script, script.Parent.Parent, "htmlToMarkdown").htmlToMarkdown
15
15
  local Markdown = TS.import(script, script.Parent, "Markdown").default
16
+ local clampEditorHeight = TS.import(script, script.Parent, "markdownEditorHeight").clampEditorHeight
16
17
  local useMarkdownEditorStyles = TS.import(script, script.Parent, "MarkdownEditor.styles").default
17
18
  local MODE_OPTIONS = { {
18
19
  label = "Split",
@@ -41,6 +42,24 @@ local function MarkdownEditor(props)
41
42
  if placeholder == nil then
42
43
  placeholder = "Write markdown…"
43
44
  end
45
+ local resizable = _binding.resizable
46
+ if resizable == nil then
47
+ resizable = false
48
+ end
49
+ local heightProp = _binding.height
50
+ local defaultHeight = _binding.defaultHeight
51
+ if defaultHeight == nil then
52
+ defaultHeight = 360
53
+ end
54
+ local minHeight = _binding.minHeight
55
+ if minHeight == nil then
56
+ minHeight = 200
57
+ end
58
+ local maxHeight = _binding.maxHeight
59
+ if maxHeight == nil then
60
+ maxHeight = 720
61
+ end
62
+ local onHeightChange = _binding.onHeightChange
44
63
  local className = _binding.className
45
64
  local sx = _binding.sx
46
65
  local id = _binding.id
@@ -51,13 +70,22 @@ local function MarkdownEditor(props)
51
70
  local fullscreenState, setFullscreenState = useState(false)
52
71
  local draft, setDraft = useState(value)
53
72
  local htmlDraft, setHtmlDraft = useState(nil)
73
+ local heightState, setHeightState = useState(defaultHeight)
74
+ local dragging, setDragging = useState(false)
54
75
  local focused = useRef(false)
76
+ local dragStart = useRef(0)
77
+ local heightStart = useRef(0)
55
78
  local mode = modeProp or modeState
56
79
  local _condition = fullscreenProp
57
80
  if _condition == nil then
58
81
  _condition = fullscreenState
59
82
  end
60
83
  local fullscreen = _condition
84
+ local _condition_1 = heightProp
85
+ if _condition_1 == nil then
86
+ _condition_1 = heightState
87
+ end
88
+ local height = clampEditorHeight(_condition_1, minHeight, maxHeight)
61
89
  local compact = theme.density == "compact"
62
90
  local styles = useMarkdownEditorStyles({
63
91
  fullscreen = fullscreen,
@@ -86,6 +114,18 @@ local function MarkdownEditor(props)
86
114
  _result(fullNext)
87
115
  end
88
116
  end
117
+ local setHeight = function(requested)
118
+ local clamped = clampEditorHeight(requested, minHeight, maxHeight)
119
+ if heightProp == nil then
120
+ setHeightState(clamped)
121
+ end
122
+ if clamped ~= height then
123
+ local _result = onHeightChange
124
+ if _result ~= nil then
125
+ _result(clamped)
126
+ end
127
+ end
128
+ end
89
129
  local showEdit = mode == "split" or mode == "edit"
90
130
  local showPreview = mode == "split" or mode == "preview"
91
131
  local previewNode = if preview ~= nil then preview(value) else React.createElement(Markdown, {
@@ -94,13 +134,16 @@ local function MarkdownEditor(props)
94
134
  local _attributes = {
95
135
  tag = "frame",
96
136
  }
97
- local _condition_1 = id
98
- if not (_condition_1 ~= 0 and _condition_1 == _condition_1 and _condition_1 ~= "" and _condition_1) then
99
- _condition_1 = "MarkdownEditor"
137
+ local _condition_2 = id
138
+ if not (_condition_2 ~= 0 and _condition_2 == _condition_2 and _condition_2 ~= "" and _condition_2) then
139
+ _condition_2 = "MarkdownEditor"
100
140
  end
101
- _attributes.key = _condition_1
141
+ _attributes.key = _condition_2
102
142
  _attributes.hostRef = ref
103
- _attributes.base = styles.root
143
+ local _object = table.clone(styles.root)
144
+ setmetatable(_object, nil)
145
+ _object.Size = if resizable and not fullscreen then UDim2.new(1, 0, 0, height) else UDim2.fromScale(1, 1)
146
+ _attributes.base = _object
104
147
  _attributes.className = className
105
148
  _attributes.sx = sx
106
149
  local _attributes_1 = table.clone(styles.corner)
@@ -109,21 +152,27 @@ local function MarkdownEditor(props)
109
152
  local _attributes_2 = table.clone(styles.stroke)
110
153
  setmetatable(_attributes_2, nil)
111
154
  local _exp_1 = React.createElement("uistroke", _attributes_2)
112
- local _attributes_3 = table.clone(styles.layout)
113
- setmetatable(_attributes_3, nil)
114
- local _exp_2 = React.createElement("uilistlayout", _attributes_3)
115
- local _attributes_4 = {
155
+ local _attributes_3 = {
156
+ key = "Content",
157
+ }
158
+ for _k, _v in styles.content do
159
+ _attributes_3[_k] = _v
160
+ end
161
+ local _attributes_4 = table.clone(styles.layout)
162
+ setmetatable(_attributes_4, nil)
163
+ local _exp_2 = React.createElement("uilistlayout", _attributes_4)
164
+ local _attributes_5 = {
116
165
  key = "Toolbar",
117
166
  }
118
167
  for _k, _v in styles.toolbar do
119
- _attributes_4[_k] = _v
168
+ _attributes_5[_k] = _v
120
169
  end
121
- local _attributes_5 = table.clone(styles.toolbarPad)
122
- setmetatable(_attributes_5, nil)
123
- local _exp_3 = React.createElement("uipadding", _attributes_5)
124
- local _attributes_6 = table.clone(styles.toolbarRow)
170
+ local _attributes_6 = table.clone(styles.toolbarPad)
125
171
  setmetatable(_attributes_6, nil)
126
- local _exp_4 = React.createElement("frame", _attributes_4, _exp_3, React.createElement("uilistlayout", _attributes_6), React.createElement(ToggleButtonGroup, {
172
+ local _exp_3 = React.createElement("uipadding", _attributes_6)
173
+ local _attributes_7 = table.clone(styles.toolbarRow)
174
+ setmetatable(_attributes_7, nil)
175
+ local _exp_4 = React.createElement("frame", _attributes_5, _exp_3, React.createElement("uilistlayout", _attributes_7), React.createElement(ToggleButtonGroup, {
127
176
  value = mode,
128
177
  options = MODE_OPTIONS,
129
178
  size = if compact then "small" else "medium",
@@ -231,37 +280,37 @@ local function MarkdownEditor(props)
231
280
  return setHtmlDraft(nil)
232
281
  end,
233
282
  }))))
234
- local _attributes_7 = {
283
+ local _attributes_8 = {
235
284
  key = "Body",
236
285
  }
237
286
  for _k, _v in styles.body do
238
- _attributes_7[_k] = _v
287
+ _attributes_8[_k] = _v
239
288
  end
240
- _attributes_7.LayoutOrder = 3
241
- local _condition_2 = mode == "split"
242
- if _condition_2 then
243
- local _attributes_8 = table.clone(styles.split)
244
- setmetatable(_attributes_8, nil)
245
- _condition_2 = React.createElement("uilistlayout", _attributes_8)
246
- end
247
- local _condition_3 = showEdit
289
+ _attributes_8.LayoutOrder = 3
290
+ local _condition_3 = mode == "split"
248
291
  if _condition_3 then
249
- local _attributes_8 = {
292
+ local _attributes_9 = table.clone(styles.split)
293
+ setmetatable(_attributes_9, nil)
294
+ _condition_3 = React.createElement("uilistlayout", _attributes_9)
295
+ end
296
+ local _condition_4 = showEdit
297
+ if _condition_4 then
298
+ local _attributes_9 = {
250
299
  key = "EditPane",
251
300
  }
252
301
  for _k, _v in (if mode == "split" then styles.pane else styles.paneFull) do
253
- _attributes_8[_k] = _v
302
+ _attributes_9[_k] = _v
254
303
  end
255
- _attributes_8.LayoutOrder = 1
256
- local _attributes_9 = {
304
+ _attributes_9.LayoutOrder = 1
305
+ local _attributes_10 = {
257
306
  key = "Editor",
258
307
  }
259
308
  for _k, _v in styles.editor do
260
- _attributes_9[_k] = _v
309
+ _attributes_10[_k] = _v
261
310
  end
262
- _attributes_9.Text = draft
263
- _attributes_9.PlaceholderText = placeholder
264
- _attributes_9.Change = {
311
+ _attributes_10.Text = draft
312
+ _attributes_10.PlaceholderText = placeholder
313
+ _attributes_10.Change = {
265
314
  Text = function(rbx)
266
315
  setDraft(rbx.Text)
267
316
  if focused.current and rbx.Text ~= value then
@@ -269,7 +318,7 @@ local function MarkdownEditor(props)
269
318
  end
270
319
  end,
271
320
  }
272
- _attributes_9.Event = {
321
+ _attributes_10.Event = {
273
322
  Focused = function()
274
323
  focused.current = true
275
324
  end,
@@ -279,35 +328,104 @@ local function MarkdownEditor(props)
279
328
  onChange(rbx.Text)
280
329
  end,
281
330
  }
282
- local _attributes_10 = table.clone(styles.editorPad)
283
- setmetatable(_attributes_10, nil)
284
- _condition_3 = (React.createElement("frame", _attributes_8, React.createElement("textbox", _attributes_9, React.createElement("uipadding", _attributes_10))))
331
+ local _attributes_11 = table.clone(styles.editorPad)
332
+ setmetatable(_attributes_11, nil)
333
+ _condition_4 = (React.createElement("frame", _attributes_9, React.createElement("textbox", _attributes_10, React.createElement("uipadding", _attributes_11))))
285
334
  end
286
- local _condition_4 = mode == "split"
287
- if _condition_4 then
288
- local _attributes_8 = {
335
+ local _condition_5 = mode == "split"
336
+ if _condition_5 then
337
+ local _attributes_9 = {
289
338
  key = "SplitRule",
290
339
  }
291
340
  for _k, _v in styles.divider do
292
- _attributes_8[_k] = _v
341
+ _attributes_9[_k] = _v
293
342
  end
294
- _condition_4 = React.createElement("frame", _attributes_8)
343
+ _condition_5 = React.createElement("frame", _attributes_9)
295
344
  end
296
- local _condition_5 = showPreview
297
- if _condition_5 then
298
- local _attributes_8 = {
345
+ local _condition_6 = showPreview
346
+ if _condition_6 then
347
+ local _attributes_9 = {
299
348
  key = "PreviewPane",
300
349
  }
301
350
  for _k, _v in styles.previewScroll do
302
- _attributes_8[_k] = _v
351
+ _attributes_9[_k] = _v
303
352
  end
304
- _attributes_8.Size = if mode == "split" then UDim2.fromScale(0.5, 1) else UDim2.fromScale(1, 1)
305
- _attributes_8.LayoutOrder = 3
306
- local _attributes_9 = table.clone(styles.previewPad)
307
- setmetatable(_attributes_9, nil)
308
- _condition_5 = (React.createElement("scrollingframe", _attributes_8, React.createElement("uipadding", _attributes_9), previewNode))
353
+ _attributes_9.Size = if mode == "split" then UDim2.fromScale(0.5, 1) else UDim2.fromScale(1, 1)
354
+ _attributes_9.LayoutOrder = 3
355
+ local _attributes_10 = table.clone(styles.previewPad)
356
+ setmetatable(_attributes_10, nil)
357
+ _condition_6 = (React.createElement("scrollingframe", _attributes_9, React.createElement("uipadding", _attributes_10), previewNode))
358
+ end
359
+ local _exp_6 = React.createElement("frame", _attributes_3, _exp_2, _exp_4, _exp_5, React.createElement("frame", _attributes_8, _condition_3, _condition_4, _condition_5, _condition_6))
360
+ local _condition_7 = resizable and not fullscreen
361
+ if _condition_7 then
362
+ local _attributes_9 = {
363
+ key = "ResizeGrip",
364
+ }
365
+ for _k, _v in styles.resizeGrip do
366
+ _attributes_9[_k] = _v
367
+ end
368
+ _attributes_9.Text = ""
369
+ _attributes_9.Active = true
370
+ _attributes_9.Selectable = true
371
+ _attributes_9.Event = {
372
+ InputBegan = function(_, input)
373
+ if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
374
+ dragStart.current = input.Position.Y
375
+ heightStart.current = height
376
+ setDragging(true)
377
+ elseif input.KeyCode == Enum.KeyCode.Up then
378
+ setHeight(height - 16)
379
+ elseif input.KeyCode == Enum.KeyCode.Down then
380
+ setHeight(height + 16)
381
+ end
382
+ end,
383
+ }
384
+ local _attributes_10 = {
385
+ key = "Long",
386
+ }
387
+ for _k, _v in styles.resizeMark do
388
+ _attributes_10[_k] = _v
389
+ end
390
+ _attributes_10.Position = UDim2.fromOffset(4, 14)
391
+ _attributes_10.Size = UDim2.fromOffset(12, 2)
392
+ local _exp_7 = React.createElement("frame", _attributes_10)
393
+ local _attributes_11 = {
394
+ key = "Short",
395
+ }
396
+ for _k, _v in styles.resizeMark do
397
+ _attributes_11[_k] = _v
398
+ end
399
+ _attributes_11.Position = UDim2.fromOffset(10, 10)
400
+ _attributes_11.Size = UDim2.fromOffset(6, 2)
401
+ _condition_7 = (React.createElement("textbutton", _attributes_9, _exp_7, React.createElement("frame", _attributes_11)))
402
+ end
403
+ local _condition_8 = dragging
404
+ if _condition_8 then
405
+ local _attributes_9 = {
406
+ key = "ResizeOverlay",
407
+ }
408
+ for _k, _v in styles.resizeOverlay do
409
+ _attributes_9[_k] = _v
410
+ end
411
+ _attributes_9.Event = {
412
+ InputChanged = function(_, input)
413
+ if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
414
+ setHeight(heightStart.current + input.Position.Y - dragStart.current)
415
+ end
416
+ end,
417
+ InputEnded = function(_, input)
418
+ if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
419
+ setDragging(false)
420
+ end
421
+ end,
422
+ MouseLeave = function()
423
+ return setDragging(false)
424
+ end,
425
+ }
426
+ _condition_8 = (React.createElement("frame", _attributes_9))
309
427
  end
310
- return React.createElement(SxHost, _attributes, _exp, _exp_1, _exp_2, _exp_4, _exp_5, React.createElement("frame", _attributes_7, _condition_2, _condition_3, _condition_4, _condition_5))
428
+ return React.createElement(SxHost, _attributes, _exp, _exp_1, _exp_6, _condition_7, _condition_8)
311
429
  end
312
430
  local default = MarkdownEditor
313
431
  return {
@@ -13,6 +13,11 @@ local useMarkdownEditorStyles = componentStyles("MarkdownEditor", function(theme
13
13
  BackgroundColor3 = theme.palette.surface.paper,
14
14
  BorderSizePixel = 0,
15
15
  },
16
+ content = {
17
+ Size = UDim2.fromScale(1, 1),
18
+ BackgroundTransparency = 1,
19
+ BorderSizePixel = 0,
20
+ },
16
21
  corner = {
17
22
  CornerRadius = UDim.new(0, theme.shape.borderRadius),
18
23
  },
@@ -124,6 +129,30 @@ local useMarkdownEditorStyles = componentStyles("MarkdownEditor", function(theme
124
129
  BorderSizePixel = 0,
125
130
  LayoutOrder = 2,
126
131
  }
132
+ _object.resizeGrip = {
133
+ AnchorPoint = Vector2.new(1, 1),
134
+ Position = UDim2.fromScale(1, 1),
135
+ Size = UDim2.fromOffset(22, 22),
136
+ BackgroundColor3 = theme.palette.surface.elevated,
137
+ BackgroundTransparency = 0.15,
138
+ BorderSizePixel = 0,
139
+ AutoButtonColor = false,
140
+ ZIndex = 20,
141
+ }
142
+ _object.resizeMark = {
143
+ AnchorPoint = Vector2.new(0.5, 0.5),
144
+ BackgroundColor3 = theme.palette.text.secondary,
145
+ BorderSizePixel = 0,
146
+ Rotation = -45,
147
+ ZIndex = 21,
148
+ }
149
+ _object.resizeOverlay = {
150
+ Size = UDim2.fromScale(1, 1),
151
+ BackgroundTransparency = 1,
152
+ BorderSizePixel = 0,
153
+ Active = true,
154
+ ZIndex = 30,
155
+ }
127
156
  return createStyles(_object)
128
157
  end)
129
158
  local default = useMarkdownEditorStyles
@@ -0,0 +1 @@
1
+ export declare function clampEditorHeight(value: number, min?: number, max?: number): number;
@@ -0,0 +1,13 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local function clampEditorHeight(value, min, max)
3
+ if min == nil then
4
+ min = 200
5
+ end
6
+ if max == nil then
7
+ max = 720
8
+ end
9
+ return math.clamp(value, math.min(min, max), math.max(min, max))
10
+ end
11
+ return {
12
+ clampEditorHeight = clampEditorHeight,
13
+ }
@@ -0,0 +1,7 @@
1
+ import React from "@rbxts/react";
2
+ import { CustomizedProps } from "../../../../theme/index";
3
+ export interface ScrollViewProps {
4
+ children?: React.ReactNode;
5
+ }
6
+ declare function ScrollView(props: CustomizedProps<ScrollingFrame, ScrollViewProps>): JSX.Element;
7
+ export default ScrollView;
@@ -0,0 +1,42 @@
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 function ScrollView(props)
7
+ local _binding = props
8
+ local children = _binding.children
9
+ local className = _binding.className
10
+ local sx = _binding.sx
11
+ local id = _binding.id
12
+ local ref = _binding.ref
13
+ local _binding_1 = useTheme()
14
+ local theme = _binding_1.theme
15
+ local root = {
16
+ Size = UDim2.fromScale(1, 1),
17
+ BackgroundTransparency = 1,
18
+ BorderSizePixel = 0,
19
+ CanvasSize = UDim2.fromScale(0, 0),
20
+ AutomaticCanvasSize = Enum.AutomaticSize.Y,
21
+ ScrollingDirection = Enum.ScrollingDirection.Y,
22
+ ScrollBarThickness = theme.spacing.calc(0.5),
23
+ ScrollBarImageColor3 = theme.palette.text.secondary,
24
+ }
25
+ local _attributes = {
26
+ tag = "scrollingframe",
27
+ }
28
+ local _condition = id
29
+ if not (_condition ~= 0 and _condition == _condition and _condition ~= "" and _condition) then
30
+ _condition = "ScrollView"
31
+ end
32
+ _attributes.key = _condition
33
+ _attributes.hostRef = ref
34
+ _attributes.base = root
35
+ _attributes.className = className
36
+ _attributes.sx = sx
37
+ return React.createElement(SxHost, _attributes, children)
38
+ end
39
+ local default = ScrollView
40
+ return {
41
+ default = default,
42
+ }
@@ -1,2 +1,4 @@
1
+ export { default as ScrollView } from "./components/ScrollView";
2
+ export { ScrollViewProps } from "./components/ScrollView";
1
3
  export { useDragScroll } from "./useDragScroll";
2
4
  export type { DragScrollHandle } from "./useDragScroll";
@@ -1,5 +1,6 @@
1
1
  -- Compiled with roblox-ts v3.0.0
2
2
  local TS = _G[script]
3
3
  local exports = {}
4
+ exports.ScrollView = TS.import(script, script, "components", "ScrollView").default
4
5
  exports.useDragScroll = TS.import(script, script, "useDragScroll").useDragScroll
5
6
  return exports
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/uiblox",
3
- "version": "0.2.0-alpha.30",
3
+ "version": "0.2.0-alpha.32",
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/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/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/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": [