-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Typesafe config / no code component definitions #56
Comments
@pawel-commerce-studio - @r00dY said I should share this here for you. You can see docs on the repo above - and I have published the package too but it's a work in progress so don't count on it working great yet! |
Hey @timoconnellaus ! I went through the code only, but this looks really exciting. I also wanted to do something similar, but more in a Sanity-like way, but this Zod-like style also looks cool. I will try to play with it soon too! |
@pawel-commerce-studio - I pushed quite a big update. It's a lot better now! Includes these:
|
@pawel-commerce-studio @r00dY - A sneak peak of what I'm close to finishing This is type safe top-to-bottom - it works like this: define baseConfig
define your easyblocks types
define your no code component definitions
The final result is you can build no code components in a completely type safe way - change a type on a widget, get lint errors in your styles function Here's a simple example const productWidget = eb.externalWidget({
zodType: z.object({ productId: z.string() }),
component: (props) => {
return <>{props.id}</>;
},
type: "shopify",
callback: async ({ externalData, externalDataId }) => {
return {
a: { type: "text", value: { productId: "asb" } },
b: { type: "text", value: { productId: "asb" } },
};
},
});
// ....
const banner = definition({
schema: schema({
size: group({
height: numberProp().defaultValue(10),
width: numberProp().defaultValue(10),
}),
product: externalCustom("product"),
}),
styles: ({ values }) => {
const { height, width, product } = values;
return {};
},
}); This is the type of the product when you hover in VSCode Here's the full exampleimport { z } from "zod";
import { eb } from "./eb";
// DEVICES
const devices = eb
// initially set to default devices
.devices({
sm: eb.device().hidden(true), // change properties
})
.mainDevice("md"); // we can set the main device
// WIDGETS
const urlWidget = eb
.inlineWidget({
zodType: z.object({ val: z.string() }),
defaultValue: { val: "" },
component: (props) => {
return <>{props.value.val}</>;
},
})
.label("URL");
const urlWidgetTwo = eb
.inlineWidget({
zodType: z.object({ two: z.string() }),
defaultValue: { two: "" },
component: (props) => {
return <>{props.value.two}</>;
},
})
.label("URL2");
const colorWidget = eb.tokenWidget({
zodType: z.string(),
defaultValue: "#000000",
component: (props) => {
return <>{props.value}</>;
},
});
const productWidget = eb.externalWidget({
zodType: z.object({ productId: z.string() }),
component: (props) => {
return <>{props.id}</>;
},
type: "shopify",
callback: async ({ externalData, externalDataId }) => {
return {
a: { type: "text", value: { productId: "asb" } },
b: { type: "text", value: { productId: "asb" } },
};
},
});
const widgets = eb.widgets({
inline: {
url: urlWidget,
urlTwo: urlWidgetTwo,
},
token: {
color: colorWidget,
},
external: {
product: productWidget,
},
});
// TOKENS
const colorTokens = eb
.colorTokens({
blue: eb.colorToken({ $res: true, xs: "#0000FF", xl: "#0000FF" }),
red: eb.colorToken("red"),
})
.default("blue");
const customToken = eb
.customTokens({
zodType: z.string(),
tokens: {
big: eb.customToken("big"),
small: eb.customToken("small"),
},
})
.default("big");
const customToken2 = eb
.customTokens({
zodType: z.number(),
tokens: {
big: eb.customToken(10),
small: eb.customToken(5),
},
})
.default("big");
const tokens = eb.tokens({
standard: {
color: colorTokens,
},
custom: {
size: customToken,
size2: customToken2,
},
});
// Base Config
// This config sets up tokens and widgets whose types need to be available when setting up easyblocks types
const { inlineType, externalType, tokenType, baseConfigWithTypes } =
eb.baseConfig({
devices: devices,
widgets,
tokens,
});
const urlType = inlineType("url").defaultValue({ val: "www.google.com" });
const colorType = tokenType("color").customValueWidget("color");
const productType = externalType(["product"]);
// Now we add the types to the base config - we now have everything we need to set up definitions
// in a type safe way
const {
definition,
schema,
stringProp,
numberProp,
inlineCustom,
tokenCustom,
externalCustom,
group,
} = baseConfigWithTypes({
inlineTypes: {
url: urlType,
},
tokenTypes: {
color: colorType,
},
externalTypes: {
product: productType,
},
});
export const s = schema({
size: group({
height: numberProp().defaultValue(10),
width: numberProp().defaultValue(10),
}),
title: stringProp().defaultValue("Banner"),
url: inlineCustom("url"),
color: tokenCustom("color"),
product: externalCustom("product"),
});
const banner = definition({
schema: schema({
size: group({
height: numberProp().defaultValue(10),
width: numberProp().defaultValue(10),
}),
title: stringProp().defaultValue("Banner"),
url: inlineCustom("url"),
color: tokenCustom("color"),
product: externalCustom("product"),
}),
styles: ({ values }) => {
const { height, width, title, url, color, product } = values;
return {};
},
}); |
This repo is the POC of typesafe of config / no code component definitions using zod style notiations
https://github.com/timoconnellaus/eb
The text was updated successfully, but these errors were encountered: