Is it possible to create a `createCustomAction$`?

@nksaraf is it technically possible to create a custom createCustomAction$ function that builds on createServerAction$ or server$? This would allow library authors to keep the API simple, making the code more concise. Specifically, I would like to provide a SolidStart integration for my form library Modular Forms to enable the creation of progressively enhanced forms. Below is a code example.
import { createServerForm$, Field, zodForm } from "@modular-forms/solid";
import { z } from "zod";
import { TextInput, Button } from "~/components";

const loginSchema = z.object({
email: z
.string()
.min(1, "Please enter your email.")
.email("The email address is badly formatted."),
password: z
.string()
.min(1, "Please enter your password.")
.min(8, "You password must have 8 characters or more."),
});

export default function LoginRoute() {
const [loginForm, Form] = createServerForm$<z.infer<typeof loginSchema>>({
validate: zodForm(loginSchema),
onSubmit: async (values) => {
// Your code
},
});

return (
<Form>
<Field of={loginForm} name="email">
{(field) => (
<TextInput
{...field.props}
type="email"
label="Email"
value={field.value}
error={field.error}
required
/>
)}
</Field>
<Field of={loginForm} name="password">
{(field) => (
<TextInput
{...field.props}
type="password"
label="Password"
value={field.value}
error={field.error}
required
/>
)}
</Field>
<Button type="submit">Login</Button>
</Form>
);
}
import { createServerForm$, Field, zodForm } from "@modular-forms/solid";
import { z } from "zod";
import { TextInput, Button } from "~/components";

const loginSchema = z.object({
email: z
.string()
.min(1, "Please enter your email.")
.email("The email address is badly formatted."),
password: z
.string()
.min(1, "Please enter your password.")
.min(8, "You password must have 8 characters or more."),
});

export default function LoginRoute() {
const [loginForm, Form] = createServerForm$<z.infer<typeof loginSchema>>({
validate: zodForm(loginSchema),
onSubmit: async (values) => {
// Your code
},
});

return (
<Form>
<Field of={loginForm} name="email">
{(field) => (
<TextInput
{...field.props}
type="email"
label="Email"
value={field.value}
error={field.error}
required
/>
)}
</Field>
<Field of={loginForm} name="password">
{(field) => (
<TextInput
{...field.props}
type="password"
label="Password"
value={field.value}
error={field.error}
required
/>
)}
</Field>
<Button type="submit">Login</Button>
</Form>
);
}
5 Replies
nksaraf
nksaraf17mo ago
We want to have an API for this we didnt have example cases yet but lots of things to consider.. around user understand of what to expect with a function like that
Fabian Hiller
Fabian Hiller17mo ago
I understand. That means it's not possible at the moment, right?
nksaraf
nksaraf17mo ago
not without changes you can also write a vite plugin that does the appropriate tranform to server$ calls so its composable that way
Fabian Hiller
Fabian Hiller16mo ago
By when do you plan to provide the API for this? Depending on that, I would rather wait. @nksaraf is there any news on this?
nksaraf
nksaraf16mo ago
Not yet.. we're still figuring out how to expose this