Material UI with Yup
This example uses form-please/preset-mui. Material UI renders the controls
and structural slots. Yup validates the form through Standard Schema.
Install the preset peers
npm install form-please react-hook-form @mui/material @emotion/react @emotion/styled yupCreate a kit in application code:
import { } from "form-please/preset-mui"
const = ({
: { : "Attach slides" },
})The application owns ThemeProvider and its theme. The live example follows
the documentation site's light and dark mode.
Try the conference proposal
Change the session to Workshop and set experience below three years to see the cross-field Yup rule. Edit the title or abstract to see Yup transforms in the submitted output.
Runtime flow
kit.useForm receives the definition, default values, and submit callback.
kit.AutoForm renders the binding. The React Hook Form resolver parses the Yup
schema once and returns its transformed output to a successful submit.
Copy the example
"use client"
import type { } from "@mui/material"
import {
,
,
,
,
,
} from "@mui/material"
import type { , } from "form-please"
import { } from "form-please/preset-mui"
import { , , } from "react"
import * as from "yup"
const = ()
const = {
: "Accessibility",
: "Architecture",
: "Forms",
: "Performance",
} as
type = keyof typeof
const =
.({
:
.()
.(() => .trim())
.(8, "Use at least 8 characters")
.("Enter a proposal title"),
:
.()
.("Enter a valid email address")
.("Enter a contact email"),
:
.<"talk" | "workshop">()
.(["talk", "workshop"])
.(),
:
.(
.<>()
.(.() as [])
.(),
)
.(1, "Choose at least one topic")
.(),
: .().().(1).(5).(),
: .().(),
:
.()
.(/^\d{4}-\d{2}-\d{2}$/, "Choose a date")
.("Choose a date"),
:
.()
.(/^\d{2}:\d{2}$/, "Choose a start time")
.("Choose a start time"),
:
.()
.(() => .trim())
.(40, "Use at least 40 characters")
.("Enter an abstract"),
: .<File>().(),
:
.()
.([true], "Confirm that you can attend")
.(),
})
.(
"workshop-experience",
"Workshops need at least three years of speaker experience",
function () {
if (. === "workshop" && . < 3) {
return this.({
: "Workshops need at least three years of experience",
: "experience",
})
}
return true
},
)
type = <typeof >
type = <typeof >
const = .(, {
: [
{
: "section",
: "proposal",
: "Conference proposal",
:
"Describe the session, schedule it, and confirm the speaker details.",
: 12,
: {
: { : "100%" },
: { : "start" },
},
: [
{
: "field",
: "title",
: "text",
: "Proposal title",
: true,
: 7,
: {
: "Designing forms people can finish",
: { : "background.paper" },
},
},
{
: "field",
: "email",
: "email",
: "Contact email",
: true,
: 5,
: {
: "email",
: "speaker@example.com",
: { : "background.paper" },
},
},
{
: "field",
: "format",
: "radio",
: "Session format",
: true,
: 6,
: [
{ : "talk", : "Talk" },
{ : "workshop", : "Workshop" },
],
: {
: true,
: { : 56 },
},
},
{
: "field",
: "topics",
: "autocomplete-multiple",
: "Topics",
: true,
: 6,
: .() as [],
: {
: () => [ as ],
: { : "Search topics" },
: { : "background.paper" },
},
},
{
: "field",
: "experience",
: "slider",
: "Speaker experience",
: "Years presenting to professional audiences.",
: 6,
: {
: true,
: 5,
: 1,
: 1,
: { : "border-box", : 1, : 1 },
: "auto",
},
},
{
: "field",
: "remote",
: "switch",
: "Remote session",
:
"Enable this when the speaker will not attend in person.",
: 6,
: { : "secondary" },
},
{
: "field",
: "date",
: "date",
: "Preferred date",
: true,
: 3,
: { : { : "background.paper" } },
},
{
: "field",
: "time",
: "time",
: "Start time",
: true,
: 3,
: { : { : "background.paper" } },
},
{
: "field",
: "slides",
: "file",
: "Draft slides",
: "Optional PDF, up to the application's upload limit.",
: 6,
: {
: { : "secondary" },
: { : "application/pdf,.pdf" },
: { : "flex-start" },
},
},
{
: "field",
: "abstract",
: "textarea",
: "Abstract",
: true,
: "full",
: {
: 4,
: "Explain what attendees will learn.",
: { : "background.paper" },
},
},
{
: "field",
: "agreement",
: "checkbox",
: "I can attend at the selected date and time",
: true,
: "full",
: { : "secondary", : { : 0.5 } },
},
],
},
],
})
const = {
: "Designing forms people can finish",
: "speaker@example.com",
: "talk",
: ["forms"],
: 4,
: false,
: "2027-09-17",
: "10:30",
:
"A practical session about form architecture, clear validation, and accessible interaction patterns.",
: ,
: true,
} satisfies
export function () {
const = ()
const [, ] = (false)
const = (
() =>
({
: { , : { : "#7c3aed" } },
: { : 12 },
}),
[],
)
const [, ] = <>()
const = .(, {
,
({ }) {
()
},
})
(() => (true), [])
let = "Submit the proposal to validate it with Yup."
if ( !== ) {
const = ..(() => []).(", ")
= `${.} is ready for review. Topics: ${}.`
}
return (
< ={}>
<
="Material UI with Yup conference example"
="section"
={}
={{ : 3, : { : 2, : 3 } }}
="outlined"
>
<. ={}>
<.>Submit proposal</.>
</.>
< ={{ : 2 }}>
< ="polite" ="output" ="body2">
{}
</>
</>
</>
</>
)
}
function (): {
const [, ] = <>("light")
(() => {
const = .
const = () => {
if (.. === "dark") {
("dark")
return
}
("light")
}
()
const = new ()
.(, {
: ["data-vocs-theme"],
: true,
})
return () => .()
}, [])
return
}Read Form kits for the adapter contract. Read the API reference for the preset factory.