@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.
Files changed (45) hide show
  1. package/out/density/DensityProvider.d.ts +4 -0
  2. package/out/density/DensityProvider.luau +62 -0
  3. package/out/density/density.d.ts +12 -0
  4. package/out/density/density.luau +99 -0
  5. package/out/density/types.d.ts +12 -0
  6. package/out/density/types.luau +2 -0
  7. package/out/index.d.ts +12 -0
  8. package/out/init.luau +17 -0
  9. package/out/layout/Row.d.ts +3 -0
  10. package/out/layout/Row.luau +13 -0
  11. package/out/layout/Stack.d.ts +3 -0
  12. package/out/layout/Stack.luau +117 -0
  13. package/out/layout/space.d.ts +11 -0
  14. package/out/layout/space.luau +94 -0
  15. package/out/layout/types.d.ts +29 -0
  16. package/out/layout/types.luau +2 -0
  17. package/out/surface/surface.d.ts +10 -0
  18. package/out/surface/surface.luau +48 -0
  19. package/out/surface/surfacePrimitive.d.ts +17 -0
  20. package/out/surface/surfacePrimitive.luau +55 -0
  21. package/out/system/SystemProvider.d.ts +4 -0
  22. package/out/system/SystemProvider.luau +43 -0
  23. package/out/system/baseThemeContext.d.ts +2 -0
  24. package/out/system/baseThemeContext.luau +10 -0
  25. package/out/system/systemThemeContext.d.ts +2 -0
  26. package/out/system/systemThemeContext.luau +10 -0
  27. package/out/system/types.d.ts +26 -0
  28. package/out/system/types.luau +2 -0
  29. package/package.json +20 -0
  30. package/src/density/DensityProvider.tsx +61 -0
  31. package/src/density/density.ts +102 -0
  32. package/src/density/types.ts +15 -0
  33. package/src/index.ts +22 -0
  34. package/src/layout/Row.tsx +7 -0
  35. package/src/layout/Stack.tsx +133 -0
  36. package/src/layout/space.ts +101 -0
  37. package/src/layout/types.ts +34 -0
  38. package/src/surface/surface.ts +45 -0
  39. package/src/surface/surfacePrimitive.tsx +59 -0
  40. package/src/system/SystemProvider.tsx +47 -0
  41. package/src/system/baseThemeContext.ts +5 -0
  42. package/src/system/systemThemeContext.ts +5 -0
  43. package/src/system/types.ts +29 -0
  44. package/tsconfig.json +16 -0
  45. package/tsconfig.typecheck.json +25 -0
@@ -0,0 +1,4 @@
1
+ import { React } from "@lattice-ui/core";
2
+ import type { DensityContextValue, DensityProviderProps } from "./types";
3
+ export declare function DensityProvider(props: DensityProviderProps): React.JSX.Element;
4
+ export declare function useDensity(): DensityContextValue;
@@ -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
+ };
@@ -0,0 +1,2 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ return nil
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,3 @@
1
+ import { React } from "@lattice-ui/core";
2
+ import type { RowProps } from "./types";
3
+ export declare function Row(props: RowProps): React.JSX.Element;
@@ -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,3 @@
1
+ import { React } from "@lattice-ui/core";
2
+ import type { StackProps } from "./types";
3
+ export declare function Stack(props: StackProps): React.JSX.Element;
@@ -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,2 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ return nil
@@ -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;