@rbxts/react-clean-ui 1.0.38 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,15 +9,14 @@ local BoxShadow = _Decorator.BoxShadow
9
9
  local Container = TS.import(script, script.Parent.Parent, "Layout").Container
10
10
  local _Helpers = TS.import(script, script.Parent.Parent.Parent, "Helpers")
11
11
  local SizeHelper = _Helpers.SizeHelper
12
- local CssHelper = _Helpers.CssHelper
12
+ local SpacingHelper = _Helpers.SpacingHelper
13
13
  local Box = React.forwardRef(function(props, ref)
14
14
  local theme = React.useContext(CleanThemeContext)
15
- local paddingSourceProps = props
16
- local hasCustomPadding = paddingSourceProps.top ~= nil or paddingSourceProps.bottom ~= nil or paddingSourceProps.left ~= nil or paddingSourceProps.right ~= nil or paddingSourceProps.spacing ~= nil or paddingSourceProps.padding ~= nil or paddingSourceProps.resolvedPadding ~= nil
17
- local themePadding = theme.components.box.padding
18
- local paddingProps = if not hasCustomPadding and themePadding ~= nil then {
19
- resolvedPadding = CssHelper:parseCssQuad(themePadding),
20
- } else paddingSourceProps
15
+ local _condition = props["border-thickness"]
16
+ if _condition == nil then
17
+ _condition = theme.components.box.borderThickness
18
+ end
19
+ local borderThickness = _condition
21
20
  local _attributes = {
22
21
  ref = ref,
23
22
  }
@@ -26,31 +25,26 @@ local Box = React.forwardRef(function(props, ref)
26
25
  end
27
26
  _attributes.Size = SizeHelper:GetSize(props, UDim2.fromScale(1, 1))
28
27
  _attributes.AutomaticSize = SizeHelper:GetAutoSize(props)
29
- local _condition = props.BackgroundTransparency
30
- if _condition == nil then
31
- _condition = theme.components.box.backgroundTransparency
28
+ local _condition_1 = props.BackgroundTransparency
29
+ if _condition_1 == nil then
30
+ _condition_1 = theme.components.box.backgroundTransparency
32
31
  end
33
- _attributes.BackgroundTransparency = _condition
32
+ _attributes.BackgroundTransparency = _condition_1
34
33
  _attributes.BackgroundColor3 = props.BackgroundColor3 or theme.components.box.backgroundColor
35
34
  _attributes.ZIndex = props.ZIndex
36
35
  _attributes.Event = props.Event
37
36
  _attributes.backgroundImage = props["background-image"] or theme.components.box.backgroundImage
38
- local _attributes_1 = {}
39
- local _condition_1 = props["border-thickness"]
40
- if _condition_1 == nil then
41
- _condition_1 = theme.components.box.borderThickness
42
- end
43
- _attributes_1.Thickness = _condition_1
44
- _attributes_1.BorderStrokePosition = Enum.BorderStrokePosition.Inner
45
- _attributes_1.Color = props["border-color"] or theme.components.box.borderColor
46
- local _exp = React.createElement("uistroke", _attributes_1)
47
- local _attributes_2 = table.clone(props)
48
- setmetatable(_attributes_2, nil)
49
- _attributes_2.value = theme.components.box.boxShadow
50
- local _exp_1 = React.createElement(BoxShadow, _attributes_2)
51
- local _attributes_3 = table.clone(paddingProps)
52
- setmetatable(_attributes_3, nil)
53
- return React.createElement(Container, _attributes, _exp, _exp_1, React.createElement(Padding, _attributes_3), React.createElement(Corners, {
37
+ local _exp = borderThickness > 0 and (React.createElement("uistroke", {
38
+ Thickness = borderThickness,
39
+ BorderStrokePosition = Enum.BorderStrokePosition.Inner,
40
+ Color = props["border-color"] or theme.components.box.borderColor,
41
+ }))
42
+ local _attributes_1 = table.clone(props)
43
+ setmetatable(_attributes_1, nil)
44
+ _attributes_1.value = theme.components.box.boxShadow
45
+ return React.createElement(Container, _attributes, _exp, React.createElement(BoxShadow, _attributes_1), React.createElement(Padding, {
46
+ resolvedPadding = SpacingHelper:GetResolvedPadding(theme, props, theme.components.box.spacing, theme.components.box.padding),
47
+ }), React.createElement(Corners, {
54
48
  radius = theme.components.box.cornerRadius,
55
49
  }), props.children)
56
50
  end)
@@ -1,9 +1,11 @@
1
1
  import React from "@rbxts/react";
2
2
  import { BoxProps } from "./Box";
3
- import { IntentElementProps, PositionElementProps, ZIndexElementProps } from "../../Interfaces";
4
- interface CardHeaderProps extends IntentElementProps, PositionElementProps, ZIndexElementProps {
3
+ import { CssPadding, IntentElementProps, PositionElementProps, ResolvedPadding, SpacedElementProps, ZIndexElementProps } from "../../Interfaces";
4
+ interface CardHeaderProps extends IntentElementProps, PositionElementProps, ZIndexElementProps, SpacedElementProps {
5
5
  children?: React.ReactNode;
6
6
  overlay?: boolean;
7
+ padding?: CssPadding;
8
+ resolvedPadding?: ResolvedPadding;
7
9
  }
8
10
  export declare const CardHeader: React.ForwardRefExoticComponent<CardHeaderProps & React.RefAttributes<ImageLabel>>;
9
11
  interface CardBodyProps extends BoxProps {
@@ -11,6 +13,8 @@ interface CardBodyProps extends BoxProps {
11
13
  export declare const CardBody: React.ForwardRefExoticComponent<Omit<CardBodyProps, "ref"> & React.RefAttributes<ImageLabel>>;
12
14
  interface CardFooterProps extends BoxProps, IntentElementProps {
13
15
  overlay?: boolean;
16
+ padding?: CssPadding;
17
+ resolvedPadding?: ResolvedPadding;
14
18
  }
15
19
  export declare const CardFooter: React.ForwardRefExoticComponent<Omit<CardFooterProps, "ref"> & React.RefAttributes<ImageLabel>>;
16
20
  interface CardProps extends BoxProps, IntentElementProps {
@@ -159,7 +159,7 @@ local CardHeader = React.forwardRef(function(props, ref)
159
159
  local theme = React.useContext(CleanThemeContext)
160
160
  local card = React.useContext(CardContext)
161
161
  local intent = ColorHelper:getIntentColors(theme, props.intent or card.intent or "primary", "default", theme.components.card.header.intents)
162
- local padding = SpacingHelper:ResolveNumberPadding(SpacingHelper:GetPadding(theme, "md", theme.components.card.header.spacing))
162
+ local padding = SpacingHelper:GetResolvedPadding(theme, props, theme.components.card.header.spacing, theme.components.card.header.padding, "md")
163
163
  local corners = CssHelper:parseCssSize(theme.components.card.cornerRadius)
164
164
  local _binding = resolveOverlayPosition(props, theme.components.card.header.position)
165
165
  local overlay = _binding.overlay
@@ -207,39 +207,15 @@ local CardHeader = React.forwardRef(function(props, ref)
207
207
  end)
208
208
  local CardBody = React.forwardRef(function(props, ref)
209
209
  local theme = React.useContext(CleanThemeContext)
210
- -- Mirrors Box.tsx's own padding resolution (CardBody wraps its
211
- -- children in a Container, not a Box, so it doesn't get Box's
212
- -- automatic `box.padding` application for free) apply the card
213
- -- body's own theme padding only when the caller hasn't set explicit
214
- -- padding props. `card.body.padding`, when set, is an intentional
215
- -- full-override escape hatch and wins wholesale over everything
216
- -- below. Absent that, top/bottom fall back to the same generic
217
- -- md-scale default Header/Footer use for their own padding (NOT
218
- -- `box.padding`'s top/bottom) — CardBody's bottom padding stacks
219
- -- directly against an in-flow CardFooter's own top padding (the
220
- -- VStack's spacing is "None"), so inheriting `box.padding`'s
221
- -- vertical values here would double them up with Footer's/Header's
222
- -- own padding. Left/right still inherit `box.padding` since nothing
223
- -- else contributes horizontal padding at that seam.
210
+ -- Unified 4-tier padding resolution (see SpacingHelper.GetResolvedPadding):
211
+ -- `card.body.spacing` (tier 2) overrides the global spacing map per
212
+ -- scale key, falling back to it for any key it doesn't define, and
213
+ -- `card.body.padding` (tier 3) overrides the scale-based tiers
214
+ -- entirely at the active key. CardBody wraps its children in a
215
+ -- Container, not a Box, so it doesn't get Box's automatic
216
+ -- `box.padding` application for free this resolves independently
217
+ -- against `theme.components.card.body`'s own tiers.
224
218
  local paddingSourceProps = props
225
- local hasCustomPadding = paddingSourceProps.top ~= nil or paddingSourceProps.bottom ~= nil or paddingSourceProps.left ~= nil or paddingSourceProps.right ~= nil or paddingSourceProps.spacing ~= nil or paddingSourceProps.padding ~= nil or paddingSourceProps.resolvedPadding ~= nil
226
- local _bodyThemePadding = theme.components.card.body
227
- if _bodyThemePadding ~= nil then
228
- _bodyThemePadding = _bodyThemePadding.padding
229
- end
230
- local bodyThemePadding = _bodyThemePadding
231
- local boxThemePadding = theme.components.box.padding
232
- local mdPadding = SpacingHelper:GetPadding(theme, "md")
233
- local paddingProps = if hasCustomPadding then paddingSourceProps elseif bodyThemePadding ~= nil then {
234
- resolvedPadding = CssHelper:parseCssQuad(bodyThemePadding),
235
- } else {
236
- resolvedPadding = {
237
- top = mdPadding,
238
- bottom = mdPadding,
239
- left = if boxThemePadding ~= nil then CssHelper:parseCssQuad(boxThemePadding).left else mdPadding,
240
- right = if boxThemePadding ~= nil then CssHelper:parseCssQuad(boxThemePadding).right else mdPadding,
241
- },
242
- }
243
219
  local _attributes = {
244
220
  ref = ref,
245
221
  Size = SizeHelper:GetSize(props, UDim2.fromScale(0, 0)),
@@ -248,15 +224,23 @@ local CardBody = React.forwardRef(function(props, ref)
248
224
  _attributes[_k] = _v
249
225
  end
250
226
  _attributes.AutomaticSize = Enum.AutomaticSize.XY
251
- local _attributes_1 = table.clone(paddingProps)
252
- setmetatable(_attributes_1, nil)
227
+ local _attributes_1 = {}
228
+ local _result = theme.components.card.body
229
+ if _result ~= nil then
230
+ _result = _result.spacing
231
+ end
232
+ local _result_1 = theme.components.card.body
233
+ if _result_1 ~= nil then
234
+ _result_1 = _result_1.padding
235
+ end
236
+ _attributes_1.resolvedPadding = SpacingHelper:GetResolvedPadding(theme, paddingSourceProps, _result, _result_1)
253
237
  return React.createElement(FlexItem, nil, React.createElement(Container, _attributes, React.createElement(Padding, _attributes_1), props.children))
254
238
  end)
255
239
  local CardFooter = React.forwardRef(function(props, ref)
256
240
  local theme = React.useContext(CleanThemeContext)
257
241
  local card = React.useContext(CardContext)
258
242
  local intent = ColorHelper:getIntentColors(theme, props.intent or card.intent or "primary", "default", theme.components.card.footer.intents)
259
- local padding = SpacingHelper:ResolveNumberPadding(SpacingHelper:GetPadding(theme, "md", theme.components.card.footer.spacing))
243
+ local padding = SpacingHelper:GetResolvedPadding(theme, props, theme.components.card.footer.spacing, theme.components.card.footer.padding, "md")
260
244
  local corners = CssHelper:parseCssSize(theme.components.card.cornerRadius)
261
245
  local _binding = resolveOverlayPosition(props, theme.components.card.footer.position)
262
246
  local overlay = _binding.overlay
@@ -396,6 +380,41 @@ local Card = React.forwardRef(function(props, ref)
396
380
  local overlayHeader = _binding.overlayHeader
397
381
  local overlayFooter = _binding.overlayFooter
398
382
  local hasOverlay = overlayHeader ~= nil or overlayFooter ~= nil
383
+ React.useEffect(function()
384
+ if not hasOverlay then
385
+ return nil
386
+ end
387
+ local frame = overlayWrapperRef.current
388
+ if not frame then
389
+ return nil
390
+ end
391
+ -- Some renderers (e.g. the browser-based Loom scene preview) don't
392
+ -- back this ref with an instance that supports property-changed
393
+ -- signals, so guard the subscription instead of throwing and
394
+ -- losing overlay clearance tracking.
395
+ local positionConn
396
+ local sizeConn
397
+ pcall(function()
398
+ positionConn = frame:GetPropertyChangedSignal("AbsolutePosition"):Connect(function()
399
+ return setWrapperAbsoluteY(frame.AbsolutePosition.Y)
400
+ end)
401
+ end)
402
+ pcall(function()
403
+ sizeConn = frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
404
+ return setWrapperAbsoluteSize(frame.AbsoluteSize)
405
+ end)
406
+ end)
407
+ return function()
408
+ local _result = positionConn
409
+ if _result ~= nil then
410
+ _result:Disconnect()
411
+ end
412
+ local _result_1 = sizeConn
413
+ if _result_1 ~= nil then
414
+ _result_1:Disconnect()
415
+ end
416
+ end
417
+ end, { hasOverlay })
399
418
  -- How far the overlay header's bottom edge extends past the
400
419
  -- wrapper's (i.e. the Box's) top edge — 0 when there's no overlap
401
420
  -- (e.g. a small/no theme offset) or nothing has been measured yet.
@@ -428,27 +447,54 @@ local Card = React.forwardRef(function(props, ref)
428
447
  _result = props
429
448
  end
430
449
  local boxProps = _result
431
- -- When an overlay header and/or footer measurably overlaps into the
432
- -- Box (headerClearance/footerClearance > 0), reserve that much extra
433
- -- top/bottom padding via resolvedPaddingthis takes over Box's own
434
- -- outer padding, which is harmless since Card always forces
435
- -- spacing="None" on Box below anyway (so it was always 0/0/0/0 until
436
- -- now).
450
+ -- When there's no footer at all, footerClearance is always 0 (there's
451
+ -- nothing to measure an overlap against), so fall back to the Box's
452
+ -- own explicit theme.components.box.padding bottom insetif the
453
+ -- theme sets one as a floor instead. This keeps content clear of a
454
+ -- themed Box's decorative border image (e.g. wooden's wood-frame art,
455
+ -- which needs a real bottom inset) even when there's no footer to
456
+ -- reserve that space via measured overlap. Themes that don't set an
457
+ -- explicit box padding (GetExplicitPadding returns undefined) resolve
458
+ -- this floor to 0, so behavior there is unchanged. When a footer IS
459
+ -- present, footerClearance (its real measured overlap) is used as-is
460
+ -- exactly as before — this floor never applies then, since the
461
+ -- footer's own overlap already reserves whatever space it needs.
437
462
  local _result_1
438
- if headerClearance > 0 or footerClearance > 0 then
463
+ if overlayFooter == nil then
464
+ local _result_2 = SpacingHelper:GetExplicitPadding(theme.components.box.padding, theme.default.spacing)
465
+ if _result_2 ~= nil then
466
+ _result_2 = _result_2.bottom
467
+ end
468
+ local _condition = _result_2
469
+ if _condition == nil then
470
+ _condition = 0
471
+ end
472
+ _result_1 = _condition
473
+ else
474
+ _result_1 = 0
475
+ end
476
+ local explicitBoxBottomFloor = _result_1
477
+ -- When an overlay header and/or footer measurably overlaps into the
478
+ -- Box (headerClearance/footerClearance > 0), or the footer-absent
479
+ -- floor above is nonzero, reserve that much extra top/bottom padding
480
+ -- via resolvedPadding — this takes over Box's own outer padding,
481
+ -- which is otherwise 0/0/0/0 since Card always forces spacing="None"
482
+ -- on Box below.
483
+ local _result_2
484
+ if headerClearance > 0 or footerClearance > 0 or explicitBoxBottomFloor > 0 then
439
485
  local _object = table.clone(boxProps)
440
486
  setmetatable(_object, nil)
441
487
  _object.resolvedPadding = {
442
488
  top = headerClearance,
443
- bottom = footerClearance,
489
+ bottom = math.max(footerClearance, explicitBoxBottomFloor),
444
490
  left = 0,
445
491
  right = 0,
446
492
  }
447
- _result_1 = _object
493
+ _result_2 = _object
448
494
  else
449
- _result_1 = boxProps
495
+ _result_2 = boxProps
450
496
  end
451
- local boxPropsWithOverlayClearance = _result_1
497
+ local boxPropsWithOverlayClearance = _result_2
452
498
  local _attributes = table.clone(boxPropsWithOverlayClearance)
453
499
  setmetatable(_attributes, nil)
454
500
  _attributes.ref = ref
@@ -489,14 +535,6 @@ local Card = React.forwardRef(function(props, ref)
489
535
  AnchorPoint = SizeHelper:GetAnchor(wrapperPositionProps),
490
536
  ZIndex = props.ZIndex,
491
537
  LayoutOrder = props.LayoutOrder,
492
- Change = {
493
- AbsolutePosition = function(instance)
494
- return setWrapperAbsoluteY(instance.AbsolutePosition.Y)
495
- end,
496
- AbsoluteSize = function(instance)
497
- return setWrapperAbsoluteSize(instance.AbsoluteSize)
498
- end,
499
- },
500
538
  }, cardBox, overlayHeader, overlayFooter)) else cardBox
501
539
  local isCentered = props.center == true and props.Position == nil and props.AnchorPoint == nil
502
540
  return React.createElement(CardContext.Provider, {
@@ -1,7 +1,8 @@
1
- import { PaddingProps, ResolvedPadding, ScaleSize, ScaleSizeValue } from "../Interfaces";
1
+ import { PaddingProps, ResolvedPadding, ScaleSize, ScaleSizeValue, ScaledCssPadding } from "../Interfaces";
2
2
  import { ThemeTemplate } from "../Theme";
3
3
  export declare class SpacingHelper {
4
- static GetResolvedPadding(theme: ThemeTemplate, props: PaddingProps, component?: ScaleSizeValue<number>): ResolvedPadding;
5
4
  static GetPadding(theme: ThemeTemplate, spacing?: ScaleSize | "None", component?: ScaleSizeValue<number>): number;
5
+ static GetResolvedPadding(theme: ThemeTemplate, props: PaddingProps, componentSpacing?: ScaleSizeValue<number>, componentPadding?: ScaledCssPadding, defaultSpacing?: ScaleSize): ResolvedPadding;
6
+ static GetExplicitPadding(componentPadding: ScaledCssPadding | undefined, key: ScaleSize): ResolvedPadding | undefined;
6
7
  static ResolveNumberPadding(value: number): ResolvedPadding;
7
8
  }
@@ -1,4 +1,6 @@
1
1
  -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local CssHelper = TS.import(script, script.Parent, "css.helper").CssHelper
2
4
  local SpacingHelper
3
5
  do
4
6
  SpacingHelper = setmetatable({}, {
@@ -13,35 +15,117 @@ do
13
15
  end
14
16
  function SpacingHelper:constructor()
15
17
  end
16
- function SpacingHelper:GetResolvedPadding(theme, props, component)
17
- local amount = self:GetPadding(theme, props.spacing, component)
18
- return {
19
- top = if props.top then self:GetPadding(theme, props.top) else amount,
20
- bottom = if props.bottom then self:GetPadding(theme, props.bottom) else amount,
21
- left = if props.left then self:GetPadding(theme, props.left) else amount,
22
- right = if props.right then self:GetPadding(theme, props.right) else amount,
23
- }
24
- end
25
18
  function SpacingHelper:GetPadding(theme, spacing, component)
26
19
  if spacing == "None" then
27
20
  return 0
28
21
  end
29
- local resolveSpacing = if spacing ~= nil then spacing else theme.default.spacing
30
- local _result
31
- if component ~= nil then
32
- local _condition = component[resolveSpacing]
22
+ local key = spacing or theme.default.spacing
23
+ local _result = component
24
+ if _result ~= nil then
25
+ _result = _result[key]
26
+ end
27
+ local _condition = _result
28
+ if _condition == nil then
29
+ _condition = theme.spacing[key]
33
30
  if _condition == nil then
34
31
  _condition = 0
35
32
  end
36
- _result = _condition
33
+ end
34
+ return _condition
35
+ end
36
+ function SpacingHelper:GetResolvedPadding(theme, props, componentSpacing, componentPadding, defaultSpacing)
37
+ if props.resolvedPadding ~= nil then
38
+ return props.resolvedPadding
39
+ end
40
+ local isNone = props.spacing == "None"
41
+ local key = if props.spacing ~= nil and props.spacing ~= "None" then props.spacing else (defaultSpacing or theme.default.spacing)
42
+ -- tier 3: a scale-indexed map picks the quad for the active key
43
+ -- (falling through to tiers 1/2 if that key isn't defined in the
44
+ -- map); a plain quad applies regardless of key.
45
+ local _result
46
+ if isNone or componentPadding == nil then
47
+ _result = nil
48
+ else
49
+ local _componentPadding = componentPadding
50
+ _result = if type(_componentPadding) == "table" then componentPadding[key] else componentPadding
51
+ end
52
+ local quadForKey = _result
53
+ local base = if quadForKey ~= nil then CssHelper:parseCssQuad(quadForKey) else self:ResolveNumberPadding(if isNone then 0 else self:GetPadding(theme, key, componentSpacing))
54
+ local instanceQuad = if props.padding ~= nil then CssHelper:parseCssQuad(props.padding) else nil
55
+ local _object = {}
56
+ local _left = "top"
57
+ local _result_1
58
+ if props.top ~= nil then
59
+ _result_1 = self:GetPadding(theme, props.top, componentSpacing)
37
60
  else
38
- local _condition = theme.spacing[resolveSpacing]
61
+ local _result_2 = instanceQuad
62
+ if _result_2 ~= nil then
63
+ _result_2 = _result_2.top
64
+ end
65
+ local _condition = _result_2
39
66
  if _condition == nil then
40
- _condition = 0
67
+ _condition = base.top
68
+ end
69
+ _result_1 = _condition
70
+ end
71
+ _object[_left] = _result_1
72
+ local _left_1 = "bottom"
73
+ local _result_2
74
+ if props.bottom ~= nil then
75
+ _result_2 = self:GetPadding(theme, props.bottom, componentSpacing)
76
+ else
77
+ local _result_3 = instanceQuad
78
+ if _result_3 ~= nil then
79
+ _result_3 = _result_3.bottom
80
+ end
81
+ local _condition = _result_3
82
+ if _condition == nil then
83
+ _condition = base.bottom
84
+ end
85
+ _result_2 = _condition
86
+ end
87
+ _object[_left_1] = _result_2
88
+ local _left_2 = "left"
89
+ local _result_3
90
+ if props.left ~= nil then
91
+ _result_3 = self:GetPadding(theme, props.left, componentSpacing)
92
+ else
93
+ local _result_4 = instanceQuad
94
+ if _result_4 ~= nil then
95
+ _result_4 = _result_4.left
96
+ end
97
+ local _condition = _result_4
98
+ if _condition == nil then
99
+ _condition = base.left
41
100
  end
42
- _result = _condition
101
+ _result_3 = _condition
102
+ end
103
+ _object[_left_2] = _result_3
104
+ local _left_3 = "right"
105
+ local _result_4
106
+ if props.right ~= nil then
107
+ _result_4 = self:GetPadding(theme, props.right, componentSpacing)
108
+ else
109
+ local _result_5 = instanceQuad
110
+ if _result_5 ~= nil then
111
+ _result_5 = _result_5.right
112
+ end
113
+ local _condition = _result_5
114
+ if _condition == nil then
115
+ _condition = base.right
116
+ end
117
+ _result_4 = _condition
118
+ end
119
+ _object[_left_3] = _result_4
120
+ return _object
121
+ end
122
+ function SpacingHelper:GetExplicitPadding(componentPadding, key)
123
+ if componentPadding == nil then
124
+ return nil
43
125
  end
44
- return _result
126
+ local _componentPadding = componentPadding
127
+ local quad = if type(_componentPadding) == "table" then componentPadding[key] else componentPadding
128
+ return if quad ~= nil then CssHelper:parseCssQuad(quad) else nil
45
129
  end
46
130
  function SpacingHelper:ResolveNumberPadding(value)
47
131
  return {
@@ -1,3 +1,4 @@
1
+ import { ScaleSizeValue } from "./responsive.types";
1
2
  export type CssUnit = "px" | "%";
2
3
  export type CssSize = "Auto" | number | `${number}` | `${number}${CssUnit}`;
3
4
  export type CssCalcSize = CssSize | `${number}% - ${number}px` | `${number}% + ${number}px`;
@@ -25,4 +26,5 @@ export type CssBoxShadow = {
25
26
  transparency: number;
26
27
  };
27
28
  export type CssPadding = CssQuad;
29
+ export type ScaledCssPadding = CssPadding | ScaleSizeValue<CssPadding>;
28
30
  export type ResponsiveCssSize = CssSize | CssBreakpointSize;
@@ -15,3 +15,7 @@
15
15
  -- absolute pixel corner coordinates for Rect.new(minX, minY, maxX, maxY)-style slicing,
16
16
  -- e.g. Roblox's SliceCenter — not a CSS border-image-slice edge-inset shorthand, since
17
17
  -- Roblox has no intrinsic-image-size equivalent to derive corners from an inset alone
18
+ -- A CssPadding quad, or a scale-key-indexed map of quads (e.g. a component's
19
+ -- theme.components.X.padding tier, which can pick a different quad shape per
20
+ -- spacing scale key the same way theme.components.X.spacing does for the
21
+ -- numeric tier).
@@ -1,5 +1,5 @@
1
- export * from './css.types';
1
+ export type * from './css.types';
2
2
  export * from './responsive.types';
3
- export * from './element.props';
4
- export * from './semantics';
5
- export * from './icon';
3
+ export type * from './element.props';
4
+ export type * from './semantics';
5
+ export type * from './icon';
@@ -1,19 +1,7 @@
1
1
  -- Compiled with roblox-ts v3.0.0
2
2
  local TS = _G[script]
3
3
  local exports = {}
4
- for _k, _v in TS.import(script, script, "css.types") or {} do
5
- exports[_k] = _v
6
- end
7
4
  for _k, _v in TS.import(script, script, "responsive.types") or {} do
8
5
  exports[_k] = _v
9
6
  end
10
- for _k, _v in TS.import(script, script, "element.props") or {} do
11
- exports[_k] = _v
12
- end
13
- for _k, _v in TS.import(script, script, "semantics") or {} do
14
- exports[_k] = _v
15
- end
16
- for _k, _v in TS.import(script, script, "icon") or {} do
17
- exports[_k] = _v
18
- end
19
7
  return exports
@@ -1,4 +1,4 @@
1
- import { CssShadow, CssSize, CssPadding, Breakpoint, BreakpointValue, ScaleSizeValue, ScaleSize, Intent, IconSet, TextVariant, PositionElementProps, CssBoxShadow } from "../Interfaces/";
1
+ import { CssShadow, CssSize, ScaledCssPadding, Breakpoint, BreakpointValue, ScaleSizeValue, ScaleSize, Intent, IconSet, TextVariant, PositionElementProps, CssBoxShadow } from "../Interfaces/";
2
2
  import { TypographyStyle, ScaledTypographyStyle, IntentScheme, IntentColors, InlineIntentColors, CssBackgroundImage, CssPosition } from "./theme.style";
3
3
  export interface ThemeTemplate {
4
4
  colors: {
@@ -48,7 +48,8 @@ export interface ThemeTemplate {
48
48
  borderColor: Color3;
49
49
  borderThickness: number;
50
50
  cornerRadius: CssSize;
51
- padding?: CssPadding;
51
+ spacing?: ScaleSizeValue<number>;
52
+ padding?: ScaledCssPadding;
52
53
  boxShadow?: CssShadow;
53
54
  backgroundImage?: CssBackgroundImage;
54
55
  intents?: Partial<Record<Intent, InlineIntentColors>>;
@@ -89,14 +90,17 @@ export interface ThemeTemplate {
89
90
  cornerRadius: CssSize;
90
91
  intents?: Partial<Record<Intent, InlineIntentColors>>;
91
92
  spacing?: ScaleSizeValue<number>;
93
+ padding?: ScaledCssPadding;
92
94
  backgroundImage?: CssBackgroundImage;
93
95
  };
94
96
  tabs: {
95
97
  borderColor: Color3;
96
98
  backgroundColor: Color3;
99
+ backgroundImage?: CssBackgroundImage;
97
100
  borderThickness: number;
98
101
  cornerRadius: CssSize;
99
102
  spacing?: ScaleSizeValue<number>;
103
+ padding?: ScaledCssPadding;
100
104
  list: {
101
105
  borderColor?: Color3;
102
106
  backgroundColor?: Color3;
@@ -104,12 +108,14 @@ export interface ThemeTemplate {
104
108
  borderThickness: number;
105
109
  cornerRadius: CssSize;
106
110
  spacing?: ScaleSizeValue<number>;
111
+ padding?: ScaledCssPadding;
107
112
  backgroundImage?: CssBackgroundImage;
108
113
  };
109
114
  button: {
110
115
  borderThickness: number;
111
116
  cornerRadius: CssSize;
112
117
  spacing?: ScaleSizeValue<number>;
118
+ padding?: ScaledCssPadding;
113
119
  boxShadow?: CssShadow;
114
120
  typography?: Partial<TypographyStyle> | ScaledTypographyStyle;
115
121
  intents?: Partial<Record<Intent, InlineIntentColors>>;
@@ -122,6 +128,7 @@ export interface ThemeTemplate {
122
128
  spacing?: ScaleSizeValue<number>;
123
129
  header: {
124
130
  spacing?: ScaleSizeValue<number>;
131
+ padding?: ScaledCssPadding;
125
132
  typography?: Partial<TypographyStyle> | ScaledTypographyStyle;
126
133
  intents?: Partial<Record<Intent, InlineIntentColors>>;
127
134
  indicatorSize: number;
@@ -129,6 +136,7 @@ export interface ThemeTemplate {
129
136
  };
130
137
  content: {
131
138
  spacing?: ScaleSizeValue<number>;
139
+ padding?: ScaledCssPadding;
132
140
  backgroundColor: Color3;
133
141
  backgroundTransparency: number;
134
142
  };
@@ -142,17 +150,20 @@ export interface ThemeTemplate {
142
150
  header: {
143
151
  borderThickness?: number;
144
152
  spacing?: ScaleSizeValue<number>;
153
+ padding?: ScaledCssPadding;
145
154
  intents?: Partial<Record<Intent, InlineIntentColors>>;
146
155
  position?: CssPosition;
147
156
  };
148
157
  footer: {
149
158
  borderThickness?: number;
150
159
  spacing?: ScaleSizeValue<number>;
160
+ padding?: ScaledCssPadding;
151
161
  intents?: Partial<Record<Intent, InlineIntentColors>>;
152
162
  position?: CssPosition;
153
163
  };
154
164
  body?: {
155
- padding?: CssPadding;
165
+ spacing?: ScaleSizeValue<number>;
166
+ padding?: ScaledCssPadding;
156
167
  };
157
168
  };
158
169
  slider: {