diff --git a/packages/runtime/example/box/index.html b/packages/runtime/example/box/index.html
new file mode 100644
index 00000000..6e16663c
--- /dev/null
+++ b/packages/runtime/example/box/index.html
@@ -0,0 +1,171 @@
+
+
+
+
+
+ meta-ui runtime example: box
+
+
+
+
+
+
+
diff --git a/packages/runtime/src/components/chakra-ui/Box.tsx b/packages/runtime/src/components/chakra-ui/Box.tsx
new file mode 100644
index 00000000..865490de
--- /dev/null
+++ b/packages/runtime/src/components/chakra-ui/Box.tsx
@@ -0,0 +1,317 @@
+import React from "react";
+import { createComponent } from "@meta-ui/core";
+import { Static, Type } from "@sinclair/typebox";
+import { Box as BaseBox } from "@chakra-ui/react";
+import { ComponentImplementation } from "../../registry";
+import Slot from "../_internal/Slot";
+import { useExpression } from "../../store";
+import { pick } from "lodash";
+
+const CssGlobals = Type.KeyOf(
+ Type.Object({
+ "-moz-initial": Type.String(),
+ inherit: Type.String(),
+ initial: Type.String(),
+ revert: Type.String(),
+ unset: Type.String(),
+ })
+);
+const LineStyle = Type.KeyOf(
+ Type.Object({
+ dashed: Type.String(),
+ dotted: Type.String(),
+ double: Type.String(),
+ groove: Type.String(),
+ hidden: Type.String(),
+ inset: Type.String(),
+ none: Type.String(),
+ outset: Type.String(),
+ ridge: Type.String(),
+ solid: Type.String(),
+ })
+);
+const TextAlign = Type.Union([
+ CssGlobals,
+ Type.KeyOf(
+ Type.Object({
+ center: Type.String(),
+ end: Type.String(),
+ justify: Type.String(),
+ left: Type.String(),
+ "match-parent": Type.String(),
+ right: Type.String(),
+ start: Type.String(),
+ })
+ ),
+]);
+const TextTransForm = Type.Union([
+ CssGlobals,
+ Type.KeyOf(
+ Type.Object({
+ capitalize: Type.String(),
+ "full-size-kana": Type.String(),
+ "full-width": Type.String(),
+ lowercase: Type.String(),
+ none: Type.String(),
+ uppercase: Type.String(),
+ })
+ ),
+]);
+const Overflow = Type.Union([
+ CssGlobals,
+ Type.KeyOf(
+ Type.Object({
+ "-moz-hidden-unscrollable": Type.String(),
+ auto: Type.String(),
+ clip: Type.String(),
+ hidden: Type.String(),
+ scroll: Type.String(),
+ visible: Type.String(),
+ })
+ ),
+]);
+const FlexWrap = Type.Union([
+ CssGlobals,
+ Type.KeyOf(
+ Type.Object({
+ nowrap: Type.String(),
+ wrap: Type.String(),
+ "wrap-reverse": Type.String(),
+ })
+ ),
+]);
+const FlexDirection = Type.Union([
+ CssGlobals,
+ Type.KeyOf(
+ Type.Object({
+ column: Type.String(),
+ "column-reverse": Type.String(),
+ row: Type.String(),
+ "row-reverse": Type.String(),
+ })
+ ),
+]);
+const Position = Type.Union([
+ CssGlobals,
+ Type.KeyOf(
+ Type.Object({
+ "-webkit-sticky": Type.String(),
+ absolute: Type.String(),
+ fixed: Type.String(),
+ relative: Type.String(),
+ static: Type.String(),
+ sticky: Type.String(),
+ })
+ ),
+]);
+const WordBreak = Type.Union([
+ CssGlobals,
+ Type.KeyOf(
+ Type.Object({
+ "break-all": Type.String(),
+ "break-word": Type.String(),
+ "keep-all": Type.String(),
+ normal: Type.String(),
+ })
+ ),
+]);
+const WhiteSpace = Type.Union([
+ CssGlobals,
+ Type.KeyOf(
+ Type.Object({
+ "-moz-pre-wrap": Type.String(),
+ "break-spaces": Type.String(),
+ normal: Type.String(),
+ nowrap: Type.String(),
+ pre: Type.String(),
+ "pre-line": Type.String(),
+ "pre-wrap": Type.String(),
+ })
+ ),
+]);
+const BoxSizing = Type.Union([
+ CssGlobals,
+ Type.KeyOf(
+ Type.Object({
+ "border-box": Type.String(),
+ "content-box": Type.String(),
+ })
+ ),
+]);
+const PointerEvent = Type.Union([
+ CssGlobals,
+ Type.KeyOf(
+ Type.Object({
+ all: Type.String(),
+ auto: Type.String(),
+ fill: Type.String(),
+ none: Type.String(),
+ painted: Type.String(),
+ stroke: Type.String(),
+ visible: Type.String(),
+ visibleFill: Type.String(),
+ visiblePainted: Type.String(),
+ visibleStroke: Type.String(),
+ })
+ ),
+]);
+
+const StyleSchema = Type.Partial(
+ Type.Object({
+ // Margin and padding
+ m: Type.Union([Type.String(), Type.Number(), Type.Array(Type.Number())]),
+ mt: Type.Union([Type.String(), Type.Number()]),
+ mr: Type.Union([Type.String(), Type.Number()]),
+ mb: Type.Union([Type.String(), Type.Number()]),
+ ml: Type.Union([Type.String(), Type.Number()]),
+ mx: Type.Union([Type.String(), Type.Number(), Type.Array(Type.Number())]),
+ my: Type.Union([Type.String(), Type.Number(), Type.Array(Type.Number())]),
+ p: Type.Union([Type.String(), Type.Number(), Type.Array(Type.Number())]),
+ pt: Type.Union([Type.String(), Type.Number()]),
+ pr: Type.Union([Type.String(), Type.Number()]),
+ pb: Type.Union([Type.String(), Type.Number()]),
+ pl: Type.Union([Type.String(), Type.Number()]),
+ px: Type.Union([Type.String(), Type.Number(), Type.Array(Type.Number())]),
+ py: Type.Union([Type.String(), Type.Number(), Type.Array(Type.Number())]),
+ // Color and background color
+ color: Type.String(),
+ bgColor: Type.String(),
+ opacity: Type.Union([Type.String(), Type.Number()]),
+ // Gradient
+ bgGradient: Type.String(),
+ bgClip: Type.String(),
+ // Typography
+ fontFamily: Type.String(),
+ fontSize: Type.Union([Type.String(), Type.Number()]),
+ fontWeight: Type.Union([Type.String(), Type.Number()]),
+ lineHeight: Type.Union([Type.String(), Type.Number()]),
+ letterSpacing: Type.Union([Type.String(), Type.Number()]),
+ textAlign: TextAlign,
+ fontStyle: Type.String(),
+ textTransform: TextTransForm,
+ textDecoration: Type.Union([Type.String(), Type.Number()]),
+ // Layout, width and height
+ w: Type.Union([Type.String(), Type.Number()]),
+ h: Type.Union([Type.String(), Type.Number()]),
+ minW: Type.Union([Type.String(), Type.Number()]),
+ maxW: Type.Union([Type.String(), Type.Number()]),
+ minH: Type.Union([Type.String(), Type.Number()]),
+ maxH: Type.Union([Type.String(), Type.Number()]),
+ display: Type.String(),
+ verticalAlign: Type.String(),
+ overflow: Type.String(),
+ overflowX: Overflow,
+ overflowY: Overflow,
+ // Flexbox
+ alignItems: Type.String(),
+ alignContent: Type.String(),
+ justifyItems: Type.String(),
+ justifyContent: Type.String(),
+ flexWrap: FlexWrap,
+ flexDirection: FlexDirection,
+ flex: Type.Union([Type.String(), Type.Number()]),
+ flexGrow: Type.Union([CssGlobals, Type.Number()]),
+ flexShrink: Type.Union([CssGlobals, Type.Number()]),
+ flexBasis: Type.Union([Type.String(), Type.Number()]),
+ justifySelf: Type.String(),
+ alignSelf: Type.String(),
+ order: Type.Union([CssGlobals, Type.Number()]),
+ // Background
+ bg: Type.String(),
+ bgImage: Type.String(),
+ bgSize: Type.Union([Type.String(), Type.Number()]),
+ bgPosition: Type.Union([Type.String(), Type.Number()]),
+ bgRepeat: Type.String(),
+ bgAttachment: Type.String(),
+ // Borders
+ border: Type.Union([Type.String(), Type.Number()]),
+ borderWidth: Type.Union([Type.String(), Type.Number()]),
+ borderStyle: Type.String(),
+ borderColor: Type.String(),
+ borderTop: Type.Union([Type.String(), Type.Number()]),
+ borderTopWidth: Type.Union([Type.String(), Type.Number()]),
+ borderTopStyle: Type.Union([CssGlobals, LineStyle]),
+ borderTopColor: Type.String(),
+ borderRight: Type.Union([Type.String(), Type.Number()]),
+ borderRightWidth: Type.Union([Type.String(), Type.Number()]),
+ borderRightStyle: Type.Union([CssGlobals, LineStyle]),
+ borderRightColor: Type.String(),
+ borderBottom: Type.Union([Type.String(), Type.Number()]),
+ borderBottomWidth: Type.Union([Type.String(), Type.Number()]),
+ borderBottomStyle: Type.Union([CssGlobals, LineStyle]),
+ borderBottomColor: Type.String(),
+ borderLeft: Type.Union([Type.String(), Type.Number()]),
+ borderLeftWidth: Type.Union([Type.String(), Type.Number()]),
+ borderLeftStyle: Type.Union([CssGlobals, LineStyle]),
+ borderLeftColor: Type.String(),
+ borderX: Type.Union([Type.String(), Type.Number()]),
+ borderY: Type.Union([Type.String(), Type.Number()]),
+ // Border Radius
+ borderRadius: Type.Union([Type.String(), Type.Number()]),
+ borderTopLeftRadius: Type.Union([Type.String(), Type.Number()]),
+ borderTopRightRadius: Type.Union([Type.String(), Type.Number()]),
+ borderBottomRightRadius: Type.Union([Type.String(), Type.Number()]),
+ borderBottomLeftRadius: Type.Union([Type.String(), Type.Number()]),
+ // Position
+ pos: Position,
+ top: Type.Union([Type.String(), Type.Number()]),
+ right: Type.Union([Type.String(), Type.Number()]),
+ bottom: Type.Union([Type.String(), Type.Number()]),
+ left: Type.Union([Type.String(), Type.Number()]),
+ zIndex: Type.Union([Type.String(), Type.Number()]),
+ // Shadow
+ textShadow: Type.Union([Type.String(), Type.Number()]),
+ boxShadow: Type.Union([Type.String(), Type.Number()]),
+ // Other
+ whiteSpace: WhiteSpace,
+ pointerEvents: PointerEvent,
+ wordBreak: WordBreak,
+ textOverflow: Type.String(),
+ boxSizing: BoxSizing,
+ cursor: Type.String(),
+ })
+);
+const StyleProps = Object.keys(StyleSchema.properties);
+
+const Box: ComponentImplementation> = ({
+ slotsMap,
+ ...restProps
+}) => {
+ const styleProps = pick(restProps, StyleProps);
+ Object.entries(styleProps).forEach((item) => {
+ const key = item[0] as keyof typeof styleProps;
+ const value = item[1];
+ if (typeof value === "string" && value.startsWith("{{")) {
+ const raw = useExpression(value);
+ styleProps[key] = raw;
+ }
+ });
+
+ return (
+
+
+
+ );
+};
+
+export default {
+ ...createComponent({
+ version: "chakra_ui/v1",
+ metadata: {
+ name: "box",
+ description: "chakra-ui box",
+ },
+ spec: {
+ properties: Object.entries(StyleSchema.properties).map(
+ ([key, value]) => ({
+ name: key,
+ ...value,
+ })
+ ),
+ acceptTraits: [],
+ state: {},
+ methods: [],
+ },
+ }),
+ impl: Box,
+};
diff --git a/packages/runtime/src/registry.tsx b/packages/runtime/src/registry.tsx
index ae9d9c7c..ac0e0842 100644
--- a/packages/runtime/src/registry.tsx
+++ b/packages/runtime/src/registry.tsx
@@ -12,6 +12,7 @@ import ChakraUIButton from "./components/chakra-ui/Button";
import ChakraUITabs from "./components/chakra-ui/Tabs";
import ChakraUITable from "./components/chakra-ui/Table";
import ChakraUIInput from "./components/chakra-ui/Input";
+import ChakraUIBox from "./components/chakra-ui/Box";
// traits
import CoreState from "./traits/core/state";
import CoreEvent from "./traits/core/event";
@@ -106,6 +107,7 @@ registry.registerComponent(ChakraUIButton);
registry.registerComponent(ChakraUITabs);
registry.registerComponent(ChakraUITable);
registry.registerComponent(ChakraUIInput);
+registry.registerComponent(ChakraUIBox);
registry.registerTrait(CoreState);
registry.registerTrait(CoreEvent);