@lattice-ui/system 0.1.1
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/density/DensityProvider.d.ts +4 -0
- package/out/density/DensityProvider.luau +62 -0
- package/out/density/density.d.ts +12 -0
- package/out/density/density.luau +99 -0
- package/out/density/types.d.ts +12 -0
- package/out/density/types.luau +2 -0
- package/out/index.d.ts +12 -0
- package/out/init.luau +17 -0
- package/out/layout/Row.d.ts +3 -0
- package/out/layout/Row.luau +13 -0
- package/out/layout/Stack.d.ts +3 -0
- package/out/layout/Stack.luau +117 -0
- package/out/layout/space.d.ts +11 -0
- package/out/layout/space.luau +94 -0
- package/out/layout/types.d.ts +29 -0
- package/out/layout/types.luau +2 -0
- package/out/surface/surface.d.ts +10 -0
- package/out/surface/surface.luau +48 -0
- package/out/surface/surfacePrimitive.d.ts +17 -0
- package/out/surface/surfacePrimitive.luau +55 -0
- package/out/system/SystemProvider.d.ts +4 -0
- package/out/system/SystemProvider.luau +43 -0
- package/out/system/baseThemeContext.d.ts +2 -0
- package/out/system/baseThemeContext.luau +10 -0
- package/out/system/systemThemeContext.d.ts +2 -0
- package/out/system/systemThemeContext.luau +10 -0
- package/out/system/types.d.ts +26 -0
- package/out/system/types.luau +2 -0
- package/package.json +20 -0
- package/src/density/DensityProvider.tsx +61 -0
- package/src/density/density.ts +102 -0
- package/src/density/types.ts +15 -0
- package/src/index.ts +22 -0
- package/src/layout/Row.tsx +7 -0
- package/src/layout/Stack.tsx +133 -0
- package/src/layout/space.ts +101 -0
- package/src/layout/types.ts +34 -0
- package/src/surface/surface.ts +45 -0
- package/src/surface/surfacePrimitive.tsx +59 -0
- package/src/system/SystemProvider.tsx +47 -0
- package/src/system/baseThemeContext.ts +5 -0
- package/src/system/systemThemeContext.ts +5 -0
- package/src/system/types.ts +29 -0
- package/tsconfig.json +16 -0
- package/tsconfig.typecheck.json +25 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _core = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out)
|
|
4
|
+
local createStrictContext = _core.createStrictContext
|
|
5
|
+
local React = _core.React
|
|
6
|
+
local useControllableState = _core.useControllableState
|
|
7
|
+
local ThemeProvider = TS.import(script, TS.getModule(script, "@lattice-ui", "style").out).ThemeProvider
|
|
8
|
+
local useSystemBaseThemeContext = TS.import(script, script.Parent.Parent, "system", "baseThemeContext").useSystemBaseThemeContext
|
|
9
|
+
local SystemThemeContextProvider = TS.import(script, script.Parent.Parent, "system", "systemThemeContext").SystemThemeContextProvider
|
|
10
|
+
local applyDensity = TS.import(script, script.Parent, "density").applyDensity
|
|
11
|
+
local _binding = createStrictContext("DensityProvider")
|
|
12
|
+
local DensityContextProvider = _binding[1]
|
|
13
|
+
local useDensityContext = _binding[2]
|
|
14
|
+
local DEFAULT_DENSITY = "comfortable"
|
|
15
|
+
local function DensityProvider(props)
|
|
16
|
+
local _binding_1 = useSystemBaseThemeContext()
|
|
17
|
+
local baseTheme = _binding_1.baseTheme
|
|
18
|
+
local setBaseTheme = _binding_1.setBaseTheme
|
|
19
|
+
local _binding_2 = useControllableState({
|
|
20
|
+
value = props.density,
|
|
21
|
+
defaultValue = props.defaultDensity or DEFAULT_DENSITY,
|
|
22
|
+
onChange = props.onDensityChange,
|
|
23
|
+
})
|
|
24
|
+
local densityValue = _binding_2[1]
|
|
25
|
+
local setDensityValue = _binding_2[2]
|
|
26
|
+
-- Read-path contract: resolvedTheme is derived from baseTheme + current density.
|
|
27
|
+
local resolvedTheme = React.useMemo(function()
|
|
28
|
+
return applyDensity(baseTheme, densityValue)
|
|
29
|
+
end, { baseTheme, densityValue })
|
|
30
|
+
local setDensity = React.useCallback(function(nextDensity)
|
|
31
|
+
setDensityValue(nextDensity)
|
|
32
|
+
end, { setDensityValue })
|
|
33
|
+
local densityContextValue = React.useMemo(function()
|
|
34
|
+
return {
|
|
35
|
+
density = densityValue,
|
|
36
|
+
setDensity = setDensity,
|
|
37
|
+
}
|
|
38
|
+
end, { densityValue, setDensity })
|
|
39
|
+
local systemThemeContextValue = React.useMemo(function()
|
|
40
|
+
return {
|
|
41
|
+
theme = resolvedTheme,
|
|
42
|
+
baseTheme = baseTheme,
|
|
43
|
+
density = densityValue,
|
|
44
|
+
setBaseTheme = setBaseTheme,
|
|
45
|
+
setDensity = setDensity,
|
|
46
|
+
}
|
|
47
|
+
end, { baseTheme, densityValue, resolvedTheme, setBaseTheme, setDensity })
|
|
48
|
+
return React.createElement(DensityContextProvider, {
|
|
49
|
+
value = densityContextValue,
|
|
50
|
+
}, React.createElement(SystemThemeContextProvider, {
|
|
51
|
+
value = systemThemeContextValue,
|
|
52
|
+
}, React.createElement(ThemeProvider, {
|
|
53
|
+
theme = resolvedTheme,
|
|
54
|
+
}, props.children)))
|
|
55
|
+
end
|
|
56
|
+
local function useDensity()
|
|
57
|
+
return useDensityContext()
|
|
58
|
+
end
|
|
59
|
+
return {
|
|
60
|
+
DensityProvider = DensityProvider,
|
|
61
|
+
useDensity = useDensity,
|
|
62
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Theme } from "@lattice-ui/style";
|
|
2
|
+
import type { DensityToken } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* M1 limitation: density is a pure theme transformer.
|
|
5
|
+
* It does not create layout or child instances.
|
|
6
|
+
*/
|
|
7
|
+
export declare function applyDensity(theme: Theme, token: DensityToken): Theme;
|
|
8
|
+
/**
|
|
9
|
+
* M1 limitation: this helper only returns a theme transformer.
|
|
10
|
+
* It does not modify instance graphs or perform runtime layout composition.
|
|
11
|
+
*/
|
|
12
|
+
export declare function density(token: DensityToken): (theme: Theme) => Theme;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local DENSITY_SCALES = {
|
|
3
|
+
compact = {
|
|
4
|
+
space = 0.85,
|
|
5
|
+
radius = 0.9,
|
|
6
|
+
typography = 0.92,
|
|
7
|
+
},
|
|
8
|
+
comfortable = {
|
|
9
|
+
space = 1,
|
|
10
|
+
radius = 1,
|
|
11
|
+
typography = 1,
|
|
12
|
+
},
|
|
13
|
+
spacious = {
|
|
14
|
+
space = 1.15,
|
|
15
|
+
radius = 1.1,
|
|
16
|
+
typography = 1.08,
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
local function scaleNonNegative(value, factor)
|
|
20
|
+
return math.max(0, math.round(value * factor))
|
|
21
|
+
end
|
|
22
|
+
local function scaleTextSize(value, factor)
|
|
23
|
+
return math.max(10, math.round(value * factor))
|
|
24
|
+
end
|
|
25
|
+
local function scaleSpace(theme, factor)
|
|
26
|
+
return {
|
|
27
|
+
[0] = scaleNonNegative(theme.space[0], factor),
|
|
28
|
+
[2] = scaleNonNegative(theme.space[2], factor),
|
|
29
|
+
[4] = scaleNonNegative(theme.space[4], factor),
|
|
30
|
+
[6] = scaleNonNegative(theme.space[6], factor),
|
|
31
|
+
[8] = scaleNonNegative(theme.space[8], factor),
|
|
32
|
+
[10] = scaleNonNegative(theme.space[10], factor),
|
|
33
|
+
[12] = scaleNonNegative(theme.space[12], factor),
|
|
34
|
+
[14] = scaleNonNegative(theme.space[14], factor),
|
|
35
|
+
[16] = scaleNonNegative(theme.space[16], factor),
|
|
36
|
+
[20] = scaleNonNegative(theme.space[20], factor),
|
|
37
|
+
[24] = scaleNonNegative(theme.space[24], factor),
|
|
38
|
+
[32] = scaleNonNegative(theme.space[32], factor),
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
local function scaleRadius(theme, factor)
|
|
42
|
+
return {
|
|
43
|
+
none = scaleNonNegative(theme.radius.none, factor),
|
|
44
|
+
sm = scaleNonNegative(theme.radius.sm, factor),
|
|
45
|
+
md = scaleNonNegative(theme.radius.md, factor),
|
|
46
|
+
lg = scaleNonNegative(theme.radius.lg, factor),
|
|
47
|
+
xl = scaleNonNegative(theme.radius.xl, factor),
|
|
48
|
+
full = scaleNonNegative(theme.radius.full, factor),
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
local function scaleTypography(theme, factor)
|
|
52
|
+
return {
|
|
53
|
+
labelSm = {
|
|
54
|
+
font = theme.typography.labelSm.font,
|
|
55
|
+
textSize = scaleTextSize(theme.typography.labelSm.textSize, factor),
|
|
56
|
+
},
|
|
57
|
+
bodyMd = {
|
|
58
|
+
font = theme.typography.bodyMd.font,
|
|
59
|
+
textSize = scaleTextSize(theme.typography.bodyMd.textSize, factor),
|
|
60
|
+
},
|
|
61
|
+
titleMd = {
|
|
62
|
+
font = theme.typography.titleMd.font,
|
|
63
|
+
textSize = scaleTextSize(theme.typography.titleMd.textSize, factor),
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
end
|
|
67
|
+
--[[
|
|
68
|
+
*
|
|
69
|
+
* M1 limitation: density is a pure theme transformer.
|
|
70
|
+
* It does not create layout or child instances.
|
|
71
|
+
|
|
72
|
+
]]
|
|
73
|
+
local function applyDensity(theme, token)
|
|
74
|
+
local scale = DENSITY_SCALES[token]
|
|
75
|
+
local _object = {}
|
|
76
|
+
local _left = "colors"
|
|
77
|
+
local _object_1 = table.clone(theme.colors)
|
|
78
|
+
setmetatable(_object_1, nil)
|
|
79
|
+
_object[_left] = _object_1
|
|
80
|
+
_object.space = scaleSpace(theme, scale.space)
|
|
81
|
+
_object.radius = scaleRadius(theme, scale.radius)
|
|
82
|
+
_object.typography = scaleTypography(theme, scale.typography)
|
|
83
|
+
return _object
|
|
84
|
+
end
|
|
85
|
+
--[[
|
|
86
|
+
*
|
|
87
|
+
* M1 limitation: this helper only returns a theme transformer.
|
|
88
|
+
* It does not modify instance graphs or perform runtime layout composition.
|
|
89
|
+
|
|
90
|
+
]]
|
|
91
|
+
local function density(token)
|
|
92
|
+
return function(theme)
|
|
93
|
+
return applyDensity(theme, token)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
return {
|
|
97
|
+
applyDensity = applyDensity,
|
|
98
|
+
density = density,
|
|
99
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type React from "@rbxts/react";
|
|
2
|
+
export type DensityToken = "compact" | "comfortable" | "spacious";
|
|
3
|
+
export type DensityProviderProps = {
|
|
4
|
+
density?: DensityToken;
|
|
5
|
+
defaultDensity?: DensityToken;
|
|
6
|
+
onDensityChange?: (next: DensityToken) => void;
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
};
|
|
9
|
+
export type DensityContextValue = {
|
|
10
|
+
density: DensityToken;
|
|
11
|
+
setDensity: (next: DensityToken) => void;
|
|
12
|
+
};
|
package/out/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { DensityProvider, useDensity } from "./density/DensityProvider";
|
|
2
|
+
export { applyDensity, density } from "./density/density";
|
|
3
|
+
export type { DensityContextValue, DensityProviderProps, DensityToken } from "./density/types";
|
|
4
|
+
export { Row } from "./layout/Row";
|
|
5
|
+
export { Stack } from "./layout/Stack";
|
|
6
|
+
export type { LayoutDirection, RowProps, SpaceToken, SpaceValue, StackAlign, StackAutoSize, StackJustify, StackPadding, StackProps, } from "./layout/types";
|
|
7
|
+
export type { SurfaceToken } from "./surface/surface";
|
|
8
|
+
export { surface } from "./surface/surface";
|
|
9
|
+
export type { SurfaceProps } from "./surface/surfacePrimitive";
|
|
10
|
+
export { Surface } from "./surface/surfacePrimitive";
|
|
11
|
+
export { SystemProvider, useSystemTheme } from "./system/SystemProvider";
|
|
12
|
+
export type { SystemProviderProps, SystemThemeContextValue } from "./system/types";
|
package/out/init.luau
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local exports = {}
|
|
4
|
+
local _DensityProvider = TS.import(script, script, "density", "DensityProvider")
|
|
5
|
+
exports.DensityProvider = _DensityProvider.DensityProvider
|
|
6
|
+
exports.useDensity = _DensityProvider.useDensity
|
|
7
|
+
local _density = TS.import(script, script, "density", "density")
|
|
8
|
+
exports.applyDensity = _density.applyDensity
|
|
9
|
+
exports.density = _density.density
|
|
10
|
+
exports.Row = TS.import(script, script, "layout", "Row").Row
|
|
11
|
+
exports.Stack = TS.import(script, script, "layout", "Stack").Stack
|
|
12
|
+
exports.surface = TS.import(script, script, "surface", "surface").surface
|
|
13
|
+
exports.Surface = TS.import(script, script, "surface", "surfacePrimitive").Surface
|
|
14
|
+
local _SystemProvider = TS.import(script, script, "system", "SystemProvider")
|
|
15
|
+
exports.SystemProvider = _SystemProvider.SystemProvider
|
|
16
|
+
exports.useSystemTheme = _SystemProvider.useSystemTheme
|
|
17
|
+
return exports
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local React = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out).React
|
|
4
|
+
local Stack = TS.import(script, script.Parent, "Stack").Stack
|
|
5
|
+
local function Row(props)
|
|
6
|
+
local _attributes = table.clone(props)
|
|
7
|
+
setmetatable(_attributes, nil)
|
|
8
|
+
_attributes.direction = "horizontal"
|
|
9
|
+
return React.createElement(Stack, _attributes)
|
|
10
|
+
end
|
|
11
|
+
return {
|
|
12
|
+
Row = Row,
|
|
13
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local React = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out).React
|
|
4
|
+
local _style = TS.import(script, TS.getModule(script, "@lattice-ui", "style").out)
|
|
5
|
+
local mergeGuiProps = _style.mergeGuiProps
|
|
6
|
+
local resolveSx = _style.resolveSx
|
|
7
|
+
local useTheme = _style.useTheme
|
|
8
|
+
local _space = TS.import(script, script.Parent, "space")
|
|
9
|
+
local resolvePadding = _space.resolvePadding
|
|
10
|
+
local resolveSpace = _space.resolveSpace
|
|
11
|
+
local function toHorizontalAlignment(value)
|
|
12
|
+
repeat
|
|
13
|
+
local _fallthrough = false
|
|
14
|
+
if value == "center" then
|
|
15
|
+
return Enum.HorizontalAlignment.Center
|
|
16
|
+
end
|
|
17
|
+
if value == "end" then
|
|
18
|
+
return Enum.HorizontalAlignment.Right
|
|
19
|
+
end
|
|
20
|
+
if value == "start" then
|
|
21
|
+
end
|
|
22
|
+
return Enum.HorizontalAlignment.Left
|
|
23
|
+
until true
|
|
24
|
+
end
|
|
25
|
+
local function toVerticalAlignment(value)
|
|
26
|
+
repeat
|
|
27
|
+
local _fallthrough = false
|
|
28
|
+
if value == "center" then
|
|
29
|
+
return Enum.VerticalAlignment.Center
|
|
30
|
+
end
|
|
31
|
+
if value == "end" then
|
|
32
|
+
return Enum.VerticalAlignment.Bottom
|
|
33
|
+
end
|
|
34
|
+
if value == "start" then
|
|
35
|
+
end
|
|
36
|
+
return Enum.VerticalAlignment.Top
|
|
37
|
+
until true
|
|
38
|
+
end
|
|
39
|
+
local function toAutomaticSize(autoSize, direction)
|
|
40
|
+
if autoSize == nil or autoSize == false then
|
|
41
|
+
return Enum.AutomaticSize.None
|
|
42
|
+
end
|
|
43
|
+
if autoSize == true then
|
|
44
|
+
return if direction == "vertical" then Enum.AutomaticSize.Y else Enum.AutomaticSize.X
|
|
45
|
+
end
|
|
46
|
+
repeat
|
|
47
|
+
if autoSize == "x" then
|
|
48
|
+
return Enum.AutomaticSize.X
|
|
49
|
+
end
|
|
50
|
+
if autoSize == "y" then
|
|
51
|
+
return Enum.AutomaticSize.Y
|
|
52
|
+
end
|
|
53
|
+
if autoSize == "xy" then
|
|
54
|
+
return Enum.AutomaticSize.XY
|
|
55
|
+
end
|
|
56
|
+
return Enum.AutomaticSize.None
|
|
57
|
+
until true
|
|
58
|
+
end
|
|
59
|
+
local function Stack(props)
|
|
60
|
+
local direction = props.direction or "vertical"
|
|
61
|
+
local _condition = props.gap
|
|
62
|
+
if _condition == nil then
|
|
63
|
+
_condition = 0
|
|
64
|
+
end
|
|
65
|
+
local gap = _condition
|
|
66
|
+
local align = props.align or "start"
|
|
67
|
+
local justify = props.justify or "start"
|
|
68
|
+
local autoSize = props.autoSize
|
|
69
|
+
local sx = props.sx
|
|
70
|
+
local children = props.children
|
|
71
|
+
local asChild = props.asChild
|
|
72
|
+
if asChild ~= nil then
|
|
73
|
+
error("[Stack] `asChild` is not supported in M3.")
|
|
74
|
+
end
|
|
75
|
+
local restProps = {}
|
|
76
|
+
for rawKey, value in pairs(props) do
|
|
77
|
+
if not (type(rawKey) == "string") then
|
|
78
|
+
continue
|
|
79
|
+
end
|
|
80
|
+
if rawKey == "direction" or rawKey == "gap" or rawKey == "align" or rawKey == "justify" or rawKey == "autoSize" or rawKey == "sx" or rawKey == "asChild" or rawKey == "padding" or rawKey == "paddingX" or rawKey == "paddingY" or rawKey == "paddingTop" or rawKey == "paddingRight" or rawKey == "paddingBottom" or rawKey == "paddingLeft" or rawKey == "children" then
|
|
81
|
+
continue
|
|
82
|
+
end
|
|
83
|
+
restProps[rawKey] = value
|
|
84
|
+
end
|
|
85
|
+
local _binding = useTheme()
|
|
86
|
+
local theme = _binding.theme
|
|
87
|
+
local sxProps = resolveSx(sx, theme)
|
|
88
|
+
local baseProps = {
|
|
89
|
+
BackgroundTransparency = 1,
|
|
90
|
+
BorderSizePixel = 0,
|
|
91
|
+
AutomaticSize = toAutomaticSize(autoSize, direction),
|
|
92
|
+
}
|
|
93
|
+
local mergedProps = mergeGuiProps(baseProps, sxProps, restProps)
|
|
94
|
+
local resolvedGap = resolveSpace(theme, gap)
|
|
95
|
+
local padding = resolvePadding(theme, props)
|
|
96
|
+
local hasPadding = padding.top > 0 or padding.right > 0 or padding.bottom > 0 or padding.left > 0
|
|
97
|
+
local vertical = direction == "vertical"
|
|
98
|
+
local horizontalAlignment = if vertical then toHorizontalAlignment(align) else toHorizontalAlignment(justify)
|
|
99
|
+
local verticalAlignment = if vertical then toVerticalAlignment(justify) else toVerticalAlignment(align)
|
|
100
|
+
local _attributes = table.clone(mergedProps)
|
|
101
|
+
setmetatable(_attributes, nil)
|
|
102
|
+
return React.createElement("frame", _attributes, React.createElement("uilistlayout", {
|
|
103
|
+
FillDirection = if vertical then Enum.FillDirection.Vertical else Enum.FillDirection.Horizontal,
|
|
104
|
+
HorizontalAlignment = horizontalAlignment,
|
|
105
|
+
Padding = UDim.new(0, resolvedGap),
|
|
106
|
+
SortOrder = Enum.SortOrder.LayoutOrder,
|
|
107
|
+
VerticalAlignment = verticalAlignment,
|
|
108
|
+
}), if hasPadding then (React.createElement("uipadding", {
|
|
109
|
+
PaddingBottom = UDim.new(0, padding.bottom),
|
|
110
|
+
PaddingLeft = UDim.new(0, padding.left),
|
|
111
|
+
PaddingRight = UDim.new(0, padding.right),
|
|
112
|
+
PaddingTop = UDim.new(0, padding.top),
|
|
113
|
+
})) else nil, children)
|
|
114
|
+
end
|
|
115
|
+
return {
|
|
116
|
+
Stack = Stack,
|
|
117
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Theme } from "@lattice-ui/style";
|
|
2
|
+
import type { SpaceValue, StackPadding } from "./types";
|
|
3
|
+
type ResolvedPadding = {
|
|
4
|
+
top: number;
|
|
5
|
+
right: number;
|
|
6
|
+
bottom: number;
|
|
7
|
+
left: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function resolveSpace(theme: Theme, value?: SpaceValue): number;
|
|
10
|
+
export declare function resolvePadding(theme: Theme, value: StackPadding): ResolvedPadding;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local function spaceTokenValue(theme, value)
|
|
3
|
+
repeat
|
|
4
|
+
if value == 0 then
|
|
5
|
+
return theme.space[0]
|
|
6
|
+
end
|
|
7
|
+
if value == 2 then
|
|
8
|
+
return theme.space[2]
|
|
9
|
+
end
|
|
10
|
+
if value == 4 then
|
|
11
|
+
return theme.space[4]
|
|
12
|
+
end
|
|
13
|
+
if value == 6 then
|
|
14
|
+
return theme.space[6]
|
|
15
|
+
end
|
|
16
|
+
if value == 8 then
|
|
17
|
+
return theme.space[8]
|
|
18
|
+
end
|
|
19
|
+
if value == 10 then
|
|
20
|
+
return theme.space[10]
|
|
21
|
+
end
|
|
22
|
+
if value == 12 then
|
|
23
|
+
return theme.space[12]
|
|
24
|
+
end
|
|
25
|
+
if value == 14 then
|
|
26
|
+
return theme.space[14]
|
|
27
|
+
end
|
|
28
|
+
if value == 16 then
|
|
29
|
+
return theme.space[16]
|
|
30
|
+
end
|
|
31
|
+
if value == 20 then
|
|
32
|
+
return theme.space[20]
|
|
33
|
+
end
|
|
34
|
+
if value == 24 then
|
|
35
|
+
return theme.space[24]
|
|
36
|
+
end
|
|
37
|
+
if value == 32 then
|
|
38
|
+
return theme.space[32]
|
|
39
|
+
end
|
|
40
|
+
return nil
|
|
41
|
+
until true
|
|
42
|
+
end
|
|
43
|
+
local function clampSpace(value)
|
|
44
|
+
return math.max(0, value)
|
|
45
|
+
end
|
|
46
|
+
local function resolveSpace(theme, value)
|
|
47
|
+
if value == nil then
|
|
48
|
+
return 0
|
|
49
|
+
end
|
|
50
|
+
local tokenValue = spaceTokenValue(theme, value)
|
|
51
|
+
if tokenValue ~= nil then
|
|
52
|
+
return clampSpace(tokenValue)
|
|
53
|
+
end
|
|
54
|
+
return clampSpace(value)
|
|
55
|
+
end
|
|
56
|
+
local function resolvePadding(theme, value)
|
|
57
|
+
local base = resolveSpace(theme, value.padding)
|
|
58
|
+
local top = base
|
|
59
|
+
local right = base
|
|
60
|
+
local bottom = base
|
|
61
|
+
local left = base
|
|
62
|
+
if value.paddingX ~= nil then
|
|
63
|
+
local axis = resolveSpace(theme, value.paddingX)
|
|
64
|
+
left = axis
|
|
65
|
+
right = axis
|
|
66
|
+
end
|
|
67
|
+
if value.paddingY ~= nil then
|
|
68
|
+
local axis = resolveSpace(theme, value.paddingY)
|
|
69
|
+
top = axis
|
|
70
|
+
bottom = axis
|
|
71
|
+
end
|
|
72
|
+
if value.paddingTop ~= nil then
|
|
73
|
+
top = resolveSpace(theme, value.paddingTop)
|
|
74
|
+
end
|
|
75
|
+
if value.paddingRight ~= nil then
|
|
76
|
+
right = resolveSpace(theme, value.paddingRight)
|
|
77
|
+
end
|
|
78
|
+
if value.paddingBottom ~= nil then
|
|
79
|
+
bottom = resolveSpace(theme, value.paddingBottom)
|
|
80
|
+
end
|
|
81
|
+
if value.paddingLeft ~= nil then
|
|
82
|
+
left = resolveSpace(theme, value.paddingLeft)
|
|
83
|
+
end
|
|
84
|
+
return {
|
|
85
|
+
top = top,
|
|
86
|
+
right = right,
|
|
87
|
+
bottom = bottom,
|
|
88
|
+
left = left,
|
|
89
|
+
}
|
|
90
|
+
end
|
|
91
|
+
return {
|
|
92
|
+
resolveSpace = resolveSpace,
|
|
93
|
+
resolvePadding = resolvePadding,
|
|
94
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Sx, Theme } from "@lattice-ui/style";
|
|
2
|
+
import type React from "@rbxts/react";
|
|
3
|
+
export type LayoutDirection = "vertical" | "horizontal";
|
|
4
|
+
export type StackAlign = "start" | "center" | "end";
|
|
5
|
+
export type StackJustify = "start" | "center" | "end";
|
|
6
|
+
export type StackAutoSize = boolean | "x" | "y" | "xy";
|
|
7
|
+
export type SpaceToken = keyof Theme["space"];
|
|
8
|
+
export type SpaceValue = SpaceToken | number;
|
|
9
|
+
export type StackPadding = {
|
|
10
|
+
padding?: SpaceValue;
|
|
11
|
+
paddingX?: SpaceValue;
|
|
12
|
+
paddingY?: SpaceValue;
|
|
13
|
+
paddingTop?: SpaceValue;
|
|
14
|
+
paddingRight?: SpaceValue;
|
|
15
|
+
paddingBottom?: SpaceValue;
|
|
16
|
+
paddingLeft?: SpaceValue;
|
|
17
|
+
};
|
|
18
|
+
type StyleProps = React.Attributes & Record<string, unknown>;
|
|
19
|
+
export type StackProps = {
|
|
20
|
+
direction?: LayoutDirection;
|
|
21
|
+
gap?: SpaceValue;
|
|
22
|
+
align?: StackAlign;
|
|
23
|
+
justify?: StackJustify;
|
|
24
|
+
autoSize?: StackAutoSize;
|
|
25
|
+
sx?: Sx<StyleProps>;
|
|
26
|
+
children?: React.ReactNode;
|
|
27
|
+
} & StackPadding & StyleProps;
|
|
28
|
+
export type RowProps = Omit<StackProps, "direction">;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Sx } from "@lattice-ui/style";
|
|
2
|
+
type GuiPropRecord = Record<string, unknown>;
|
|
3
|
+
export type SurfaceToken = "surface" | "elevated" | "sunken" | "overlay";
|
|
4
|
+
/**
|
|
5
|
+
* Props-only surface helper.
|
|
6
|
+
* Use this when you only want host props (including host border props).
|
|
7
|
+
* It does not create child instances like UICorner/UIStroke/shadow nodes.
|
|
8
|
+
*/
|
|
9
|
+
export declare function surface<Props extends GuiPropRecord>(token: SurfaceToken): Sx<Props>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local function asSxProps(value)
|
|
3
|
+
return value
|
|
4
|
+
end
|
|
5
|
+
--[[
|
|
6
|
+
*
|
|
7
|
+
* Props-only surface helper.
|
|
8
|
+
* Use this when you only want host props (including host border props).
|
|
9
|
+
* It does not create child instances like UICorner/UIStroke/shadow nodes.
|
|
10
|
+
|
|
11
|
+
]]
|
|
12
|
+
local function surface(token)
|
|
13
|
+
return function(theme)
|
|
14
|
+
repeat
|
|
15
|
+
if token == "surface" then
|
|
16
|
+
return asSxProps({
|
|
17
|
+
BackgroundColor3 = theme.colors.surface,
|
|
18
|
+
BorderColor3 = theme.colors.border,
|
|
19
|
+
BorderSizePixel = 1,
|
|
20
|
+
})
|
|
21
|
+
end
|
|
22
|
+
if token == "elevated" then
|
|
23
|
+
return asSxProps({
|
|
24
|
+
BackgroundColor3 = theme.colors.surfaceElevated,
|
|
25
|
+
BorderColor3 = theme.colors.border,
|
|
26
|
+
BorderSizePixel = 1,
|
|
27
|
+
})
|
|
28
|
+
end
|
|
29
|
+
if token == "sunken" then
|
|
30
|
+
return asSxProps({
|
|
31
|
+
BackgroundColor3 = theme.colors.background,
|
|
32
|
+
BorderColor3 = theme.colors.border,
|
|
33
|
+
BorderSizePixel = 1,
|
|
34
|
+
})
|
|
35
|
+
end
|
|
36
|
+
if token == "overlay" then
|
|
37
|
+
return asSxProps({
|
|
38
|
+
BackgroundColor3 = theme.colors.overlay,
|
|
39
|
+
BackgroundTransparency = 0.35,
|
|
40
|
+
BorderSizePixel = 0,
|
|
41
|
+
})
|
|
42
|
+
end
|
|
43
|
+
until true
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
return {
|
|
47
|
+
surface = surface,
|
|
48
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { React } from "@lattice-ui/core";
|
|
2
|
+
import type { Sx } from "@lattice-ui/style";
|
|
3
|
+
import type { SurfaceToken } from "./surface";
|
|
4
|
+
type StyleProps = React.Attributes & Record<string, unknown>;
|
|
5
|
+
export type SurfaceProps = {
|
|
6
|
+
tone?: SurfaceToken;
|
|
7
|
+
sx?: Sx<StyleProps>;
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
} & StyleProps;
|
|
10
|
+
/**
|
|
11
|
+
* Decorated surface host primitive.
|
|
12
|
+
* Unlike `surface()`, this renders instance-graph decoration via UICorner/UIStroke.
|
|
13
|
+
* Host border props are not the canonical border representation here.
|
|
14
|
+
* `asChild` is intentionally not supported in this milestone.
|
|
15
|
+
*/
|
|
16
|
+
export declare function Surface(props: SurfaceProps): React.JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local React = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out).React
|
|
4
|
+
local _style = TS.import(script, TS.getModule(script, "@lattice-ui", "style").out)
|
|
5
|
+
local mergeGuiProps = _style.mergeGuiProps
|
|
6
|
+
local resolveSx = _style.resolveSx
|
|
7
|
+
local useTheme = _style.useTheme
|
|
8
|
+
local surface = TS.import(script, script.Parent, "surface").surface
|
|
9
|
+
--[[
|
|
10
|
+
*
|
|
11
|
+
* Decorated surface host primitive.
|
|
12
|
+
* Unlike `surface()`, this renders instance-graph decoration via UICorner/UIStroke.
|
|
13
|
+
* Host border props are not the canonical border representation here.
|
|
14
|
+
* `asChild` is intentionally not supported in this milestone.
|
|
15
|
+
|
|
16
|
+
]]
|
|
17
|
+
local function Surface(props)
|
|
18
|
+
local tone = props.tone or "surface"
|
|
19
|
+
local sx = props.sx
|
|
20
|
+
local children = props.children
|
|
21
|
+
local asChild = props.asChild
|
|
22
|
+
if asChild ~= nil then
|
|
23
|
+
error("[Surface] `asChild` is not supported in M2.")
|
|
24
|
+
end
|
|
25
|
+
local restProps = {}
|
|
26
|
+
for rawKey, value in pairs(props) do
|
|
27
|
+
if not (type(rawKey) == "string") then
|
|
28
|
+
continue
|
|
29
|
+
end
|
|
30
|
+
if rawKey == "tone" or rawKey == "sx" or rawKey == "children" or rawKey == "asChild" then
|
|
31
|
+
continue
|
|
32
|
+
end
|
|
33
|
+
restProps[rawKey] = value
|
|
34
|
+
end
|
|
35
|
+
local _binding = useTheme()
|
|
36
|
+
local theme = _binding.theme
|
|
37
|
+
local toneProps = resolveSx(surface(tone), theme)
|
|
38
|
+
local sxProps = resolveSx(sx, theme)
|
|
39
|
+
local baseProps = if tone == "overlay" then toneProps else mergeGuiProps(toneProps, {
|
|
40
|
+
BorderSizePixel = 0,
|
|
41
|
+
})
|
|
42
|
+
local mergedProps = mergeGuiProps(baseProps, sxProps, restProps)
|
|
43
|
+
local decorated = tone ~= "overlay"
|
|
44
|
+
local _attributes = table.clone(mergedProps)
|
|
45
|
+
setmetatable(_attributes, nil)
|
|
46
|
+
return React.createElement("frame", _attributes, if decorated then React.createElement("uicorner", {
|
|
47
|
+
CornerRadius = UDim.new(0, theme.radius.lg),
|
|
48
|
+
}) else nil, if decorated then React.createElement("uistroke", {
|
|
49
|
+
Color = theme.colors.border,
|
|
50
|
+
Thickness = 1,
|
|
51
|
+
}) else nil, children)
|
|
52
|
+
end
|
|
53
|
+
return {
|
|
54
|
+
Surface = Surface,
|
|
55
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { React } from "@lattice-ui/core";
|
|
2
|
+
import type { SystemProviderProps, SystemThemeContextValue } from "./types";
|
|
3
|
+
export declare function SystemProvider(props: SystemProviderProps): React.JSX.Element;
|
|
4
|
+
export declare function useSystemTheme(): SystemThemeContextValue;
|